OregonCore  revision fb2a440-git
Your Favourite TBC server
InstanceData.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "InstanceData.h"
19 #include "MapReference.h"
20 #include "Database/DatabaseEnv.h"
21 #include "Map.h"
22 #include "GameObject.h"
23 #include "Creature.h"
24 #include "CreatureAI.h"
25 #include "Player.h"
26 
28 {
29  std::string data = GetSaveData();
30  if (data.empty())
31  return;
33  CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%d'", data.c_str(), instance->GetInstanceId());
34 }
35 
37 {
38  if (!go)
39  go = instance->GetGameObject(GUID);
40  if (go)
42  else
43  debug_log("OSCR: InstanceData: HandleGameObject failed");
44 }
45 
47 {
48  for (std::vector<BossInfo>::const_iterator itr = bosses.begin(); itr != bosses.end(); ++itr)
49  if (itr->state == IN_PROGRESS)
50  return true;
51 
52  return false;
53 }
54 
56 {
57  while (data->entry)
58  {
59  if (data->bossId < bosses.size())
60  minions.insert(std::make_pair(data->entry, MinionInfo(&bosses[data->bossId])));
61 
62  ++data;
63  }
64  sLog.outDebug("InstanceData::LoadMinionData: %lu minions loaded.", doors.size());
65 }
66 
68 {
69  while (data->entry)
70  {
71  if (data->bossId < bosses.size())
72  doors.insert(std::make_pair(data->entry, DoorInfo(&bosses[data->bossId], data->type)));
73 
74  ++data;
75  }
76  sLog.outDebug("InstanceData::LoadDoorData: %lu doors loaded.", doors.size());
77 }
78 
80 {
81  switch (state)
82  {
83  case NOT_STARTED:
84  if (!minion->IsAlive())
85  minion->Respawn();
86  else if (minion->IsInCombat())
87  minion->AI()->EnterEvadeMode();
88  break;
89  case IN_PROGRESS:
90  if (!minion->IsAlive())
91  minion->Respawn();
92  else if (!minion->GetVictim())
93  minion->AI()->DoZoneInCombat();
94  default:
95  break;
96  }
97 }
98 
100 {
101  DoorInfoMap::iterator lower = doors.lower_bound(door->GetEntry());
102  DoorInfoMap::iterator upper = doors.upper_bound(door->GetEntry());
103  if (lower == upper)
104  return;
105 
106  bool open = true;
107  for (DoorInfoMap::iterator itr = lower; itr != upper; ++itr)
108  {
109  if (itr->second.type == DOOR_TYPE_ROOM)
110  {
111  if (itr->second.bossInfo->state == IN_PROGRESS)
112  {
113  open = false;
114  break;
115  }
116  }
117  else if (itr->second.type == DOOR_TYPE_PASSAGE)
118  {
119  if (itr->second.bossInfo->state != DONE)
120  {
121  open = false;
122  break;
123  }
124  }
125  }
126 
127  door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
128 }
129 
130 void InstanceData::AddDoor(GameObject* door, bool add)
131 {
132  DoorInfoMap::iterator lower = doors.lower_bound(door->GetEntry());
133  DoorInfoMap::iterator upper = doors.upper_bound(door->GetEntry());
134  if (lower == upper)
135  return;
136 
137  for (DoorInfoMap::iterator itr = lower; itr != upper; ++itr)
138  {
139  if (add)
140  itr->second.bossInfo->door[itr->second.type].insert(door);
141  else
142  itr->second.bossInfo->door[itr->second.type].erase(door);
143  }
144 
145  if (add)
146  UpdateDoorState(door);
147 }
148 
149 void InstanceData::AddMinion(Creature* minion, bool add)
150 {
151  MinionInfoMap::iterator itr = minions.find(minion->GetEntry());
152  if (itr == minions.end())
153  return;
154 
155  if (add)
156  itr->second.bossInfo->minion.insert(minion);
157  else
158  itr->second.bossInfo->minion.erase(minion);
159 }
160 
162 {
163  if (id < bosses.size())
164  {
165  BossInfo* bossInfo = &bosses[id];
166  if (bossInfo->state == TO_BE_DECIDED) // loading
167  {
168  bossInfo->state = state;
169  //sLog.outError("Inialize boss %u state as %u.", id, (uint32)state);
170  return false;
171  }
172  else
173  {
174  if (bossInfo->state == state)
175  return false;
176  bossInfo->state = state;
177  SaveToDB();
178  }
179 
180  for (uint32 type = 0; type < MAX_DOOR_TYPES; ++type)
181  for (DoorSet::iterator i = bossInfo->door[type].begin(); i != bossInfo->door[type].end(); ++i)
182  UpdateDoorState(*i);
183 
184  for (MinionSet::iterator i = bossInfo->minion.begin(); i != bossInfo->minion.end(); ++i)
185  UpdateMinionState(*i, state);
186 
187  return true;
188  }
189  return false;
190 }
191 
192 std::string InstanceData::LoadBossState(const char* data)
193 {
194  if (!data)
195  return NULL;
196  std::istringstream loadStream(data);
197  uint32 buff;
198  uint32 bossId = 0;
199  for (std::vector<BossInfo>::iterator i = bosses.begin(); i != bosses.end(); ++i, ++bossId)
200  {
201  loadStream >> buff;
202  if (buff < TO_BE_DECIDED)
203  SetBossState(bossId, (EncounterState)buff);
204  }
205  return loadStream.str();
206 }
207 
209 {
210  std::ostringstream saveStream;
211  for (std::vector<BossInfo>::iterator i = bosses.begin(); i != bosses.end(); ++i)
212  saveStream << (uint32)i->state << " ";
213  return saveStream.str();
214 }
215 
216 void InstanceData::DoUseDoorOrButton(uint64 uiGuid, uint32 uiWithRestoreTime, bool bUseAlternativeState)
217 {
218  if (!uiGuid)
219  return;
220 
221  GameObject* pGo = instance->GetGameObject(uiGuid);
222 
223  if (pGo)
224  {
226  {
227  if (pGo->getLootState() == GO_READY)
228  pGo->UseDoorOrButton(uiWithRestoreTime, bUseAlternativeState);
229  else if (pGo->getLootState() == GO_ACTIVATED)
230  pGo->ResetDoorOrButton();
231  }
232  else
233  error_log("OSCR: Script call DoUseDoorOrButton, but gameobject entry %u is type %u.", pGo->GetEntry(), pGo->GetGoType());
234  }
235 }
236 
237 void InstanceData::DoRespawnGameObject(uint64 uiGuid, uint32 uiTimeToDespawn)
238 {
239  if (GameObject* pGo = instance->GetGameObject(uiGuid))
240  {
241  //not expect any of these should ever be handled
242  if (pGo->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE || pGo->GetGoType() == GAMEOBJECT_TYPE_DOOR ||
243  pGo->GetGoType() == GAMEOBJECT_TYPE_BUTTON || pGo->GetGoType() == GAMEOBJECT_TYPE_TRAP)
244  return;
245 
246  if (pGo->isSpawned())
247  return;
248 
249  pGo->SetRespawnTime(uiTimeToDespawn);
250  }
251 }
252 
253 void InstanceData::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData)
254 {
255  Map::PlayerList const& lPlayers = instance->GetPlayers();
256 
257  if (!lPlayers.isEmpty())
258  {
259  for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
260  if (Player* pPlayer = itr->GetSource())
261  pPlayer->SendUpdateWorldState(uiStateId, uiStateData);
262  }
263  else
264  sLog.outDebug("OSCR: DoUpdateWorldState attempt send data but no players in map.");
265 }
266 
267 // Cast spell on all players in instance
269 {
270  Map::PlayerList const& PlayerList = instance->GetPlayers();
271 
272  if (!PlayerList.isEmpty())
273  for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
274  if (Player* player = i->GetSource())
275  player->CastSpell(player, spell, true);
276 }
virtual void EnterEvadeMode()
Definition: CreatureAI.cpp:219
void ResetDoorOrButton()
Definition: GameObject.cpp:945
LootState getLootState() const
Definition: GameObject.h:748
DoorType type
Definition: InstanceData.h:55
MinionInfoMap minions
Definition: InstanceData.h:170
void DoZoneInCombat(Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
Definition: CreatureAI.cpp:78
bool IsInCombat() const
Definition: Unit.h:1243
#define sLog
Log class singleton.
Definition: Log.h:187
unsigned long escape_string(char *to, const char *from, unsigned long length)
Definition: Database.cpp:212
virtual bool SetBossState(uint32 id, EncounterState state)
#define debug_log
Definition: Log.h:201
Map * instance
Definition: InstanceData.h:95
iterator begin()
Definition: MapRefManager.h:48
void HandleGameObject(uint64 GUID, bool open, GameObject *go=NULL)
uint32 entry
Definition: InstanceData.h:54
void DoUpdateWorldState(uint32 worldstateId, uint32 worldstateValue)
uint32 bossId
Definition: InstanceData.h:60
bool IsAlive() const
Definition: Unit.h:1336
Unit * GetVictim() const
Definition: Unit.h:1013
void DoRespawnGameObject(uint64 uiGuid, uint32 uiTimeToDespawn=MINUTE)
virtual std::string GetSaveData()
Definition: InstanceData.h:107
CreatureAI * AI() const
Definition: Creature.h:517
void LoadMinionData(const MinionData *data)
void AddDoor(GameObject *door, bool add)
uint32 bossId
Definition: InstanceData.h:54
bool isEmpty() const
Definition: LinkedList.h:97
bool PExecute(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:441
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=NULL)
Definition: GameObject.cpp:955
void SetGoState(GOState state)
ACE_UINT64 uint64
Definition: Define.h:70
PlayerList const & GetPlayers() const
Definition: Map.h:491
EncounterState state
Definition: InstanceData.h:66
void Respawn(bool force=false)
Definition: Creature.cpp:1651
#define error_log
Definition: Log.h:202
std::string LoadBossState(const char *data)
DoorInfoMap doors
Definition: InstanceData.h:169
GameobjectTypes GetGoType() const
Definition: GameObject.h:720
void DoCastSpellOnPlayers(uint32 spell)
MinionSet minion
Definition: InstanceData.h:68
void AddMinion(Creature *minion, bool add)
std::string GetBossSaveData()
std::vector< BossInfo > bosses
Definition: InstanceData.h:168
uint32 GetEntry() const
Definition: Object.h:192
DatabaseType CharacterDatabase
Accessor to the character database.
Definition: Main.cpp:54
void UpdateMinionState(Creature *minion, EncounterState state)
ACE_UINT32 uint32
Definition: Define.h:71
GameObject * GetGameObject(uint64 guid)
Definition: Map.cpp:2636
uint32 entry
Definition: InstanceData.h:60
void DoUseDoorOrButton(uint64 uiGuid, uint32 uiWithRestoreTime=0, bool bUseAlternativeState=false)
Definition: Player.h:922
uint32 GetInstanceId() const
Definition: Map.h:390
void LoadDoorData(const DoorData *data)
DoorSet door[MAX_DOOR_TYPES]
Definition: InstanceData.h:67
virtual bool IsEncounterInProgress() const
iterator end()
Definition: MapRefManager.h:52
void UpdateDoorState(GameObject *door)
EncounterState
Definition: InstanceData.h:35