diff options
author | Rat <none@none> | 2010-06-05 23:40:08 +0200 |
---|---|---|
committer | Rat <none@none> | 2010-06-05 23:40:08 +0200 |
commit | 75b80d9f5b02a643c983b2fb1ededed79fd5d133 (patch) | |
tree | ebd1c2cc12a2715909dd04c1ed147a260c6ceb14 /src/server/game/Instances/InstanceData.cpp | |
parent | 6a9357b13d7ea6bd7d77dbfc6587af9028caa401 (diff) |
rearranged core files
--HG--
branch : trunk
Diffstat (limited to 'src/server/game/Instances/InstanceData.cpp')
-rw-r--r-- | src/server/game/Instances/InstanceData.cpp | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/src/server/game/Instances/InstanceData.cpp b/src/server/game/Instances/InstanceData.cpp new file mode 100644 index 00000000000..214c5ca2327 --- /dev/null +++ b/src/server/game/Instances/InstanceData.cpp @@ -0,0 +1,380 @@ +/* + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "InstanceData.h" +#include "Database/DatabaseEnv.h" +#include "Map.h" +#include "Player.h" +#include "GameObject.h" +#include "Creature.h" +#include "CreatureAI.h" +#include "Log.h" + +void InstanceData::SaveToDB() +{ + std::string data = GetSaveData(); + if (data.empty()) + return; + CharacterDatabase.escape_string(data); + CharacterDatabase.PExecute("UPDATE instance SET data = '%s' WHERE id = '%d'", data.c_str(), instance->GetInstanceId()); +} + +void InstanceData::HandleGameObject(uint64 GUID, bool open, GameObject *go) +{ + if (!go) + go = instance->GetGameObject(GUID); + if (go) + go->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY); + else + debug_log("TSCR: InstanceData: HandleGameObject failed"); +} + +bool InstanceData::IsEncounterInProgress() const +{ + for (std::vector<BossInfo>::const_iterator itr = bosses.begin(); itr != bosses.end(); ++itr) + if (itr->state == IN_PROGRESS) + return true; + + return false; +} + +void InstanceData::LoadMinionData(const MinionData *data) +{ + while (data->entry) + { + if (data->bossId < bosses.size()) + minions.insert(std::make_pair(data->entry, MinionInfo(&bosses[data->bossId]))); + + ++data; + } + sLog.outDebug("InstanceData::LoadMinionData: %u minions loaded.", doors.size()); +} + +void InstanceData::LoadDoorData(const DoorData *data) +{ + while (data->entry) + { + if (data->bossId < bosses.size()) + doors.insert(std::make_pair(data->entry, DoorInfo(&bosses[data->bossId], data->type, BoundaryType(data->boundary)))); + + ++data; + } + sLog.outDebug("InstanceData::LoadDoorData: %u doors loaded.", doors.size()); +} + +void InstanceData::UpdateMinionState(Creature *minion, EncounterState state) +{ + switch (state) + { + case NOT_STARTED: + if (!minion->isAlive()) + minion->Respawn(); + else if (minion->isInCombat()) + minion->AI()->EnterEvadeMode(); + break; + case IN_PROGRESS: + if (!minion->isAlive()) + minion->Respawn(); + else if (!minion->getVictim()) + minion->AI()->DoZoneInCombat(); + break; + } +} + +void InstanceData::UpdateDoorState(GameObject *door) +{ + DoorInfoMap::iterator lower = doors.lower_bound(door->GetEntry()); + DoorInfoMap::iterator upper = doors.upper_bound(door->GetEntry()); + if (lower == upper) + return; + + bool open = true; + for (DoorInfoMap::iterator itr = lower; itr != upper; ++itr) + { + if (itr->second.type == DOOR_TYPE_ROOM) + { + if (itr->second.bossInfo->state == IN_PROGRESS) + { + open = false; + break; + } + } + else if (itr->second.type == DOOR_TYPE_PASSAGE) + { + if (itr->second.bossInfo->state != DONE) + { + open = false; + break; + } + } + } + + door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY); + //sLog.outError("Door %u is %s.", door->GetEntry(), open ? "opened" : "closed"); +} + +void InstanceData::AddDoor(GameObject *door, bool add) +{ + DoorInfoMap::iterator lower = doors.lower_bound(door->GetEntry()); + DoorInfoMap::iterator upper = doors.upper_bound(door->GetEntry()); + if (lower == upper) + return; + + for (DoorInfoMap::iterator itr = lower; itr != upper; ++itr) + { + if (add) + { + itr->second.bossInfo->door[itr->second.type].insert(door); + switch (itr->second.boundary) + { + default: + case BOUNDARY_NONE: + break; + case BOUNDARY_N: + case BOUNDARY_S: + itr->second.bossInfo->boundary[itr->second.boundary] = door->GetPositionX(); + break; + case BOUNDARY_E: + case BOUNDARY_W: + itr->second.bossInfo->boundary[itr->second.boundary] = door->GetPositionY(); + break; + case BOUNDARY_NW: + case BOUNDARY_SE: + itr->second.bossInfo->boundary[itr->second.boundary] = door->GetPositionX() + door->GetPositionY(); + break; + case BOUNDARY_NE: + case BOUNDARY_SW: + itr->second.bossInfo->boundary[itr->second.boundary] = door->GetPositionX() - door->GetPositionY(); + break; + } + } + else + itr->second.bossInfo->door[itr->second.type].erase(door); + } + + if (add) + UpdateDoorState(door); +} + +void InstanceData::AddMinion(Creature *minion, bool add) +{ + MinionInfoMap::iterator itr = minions.find(minion->GetEntry()); + if (itr == minions.end()) + return; + + if (add) + itr->second.bossInfo->minion.insert(minion); + else + itr->second.bossInfo->minion.erase(minion); +} + +bool InstanceData::SetBossState(uint32 id, EncounterState state) +{ + if (id < bosses.size()) + { + BossInfo *bossInfo = &bosses[id]; + if (bossInfo->state == TO_BE_DECIDED) // loading + { + bossInfo->state = state; + //sLog.outError("Inialize boss %u state as %u.", id, (uint32)state); + return false; + } + else + { + if (bossInfo->state == state) + return false; + + if (state == DONE) + for (MinionSet::iterator i = bossInfo->minion.begin(); i != bossInfo->minion.end(); ++i) + if ((*i)->isWorldBoss() && (*i)->isAlive()) + return false; + + bossInfo->state = state; + SaveToDB(); + } + + for (uint32 type = 0; type < MAX_DOOR_TYPES; ++type) + for (DoorSet::iterator i = bossInfo->door[type].begin(); i != bossInfo->door[type].end(); ++i) + UpdateDoorState(*i); + + for (MinionSet::iterator i = bossInfo->minion.begin(); i != bossInfo->minion.end(); ++i) + UpdateMinionState(*i, state); + + return true; + } + return false; +} + +std::string InstanceData::LoadBossState(const char * data) +{ + if (!data) + return NULL; + std::istringstream loadStream(data); + uint32 buff; + uint32 bossId = 0; + for (std::vector<BossInfo>::iterator i = bosses.begin(); i != bosses.end(); ++i, ++bossId) + { + loadStream >> buff; + if (buff < TO_BE_DECIDED) + SetBossState(bossId, (EncounterState)buff); + } + return loadStream.str(); +} + +std::string InstanceData::GetBossSaveData() +{ + std::ostringstream saveStream; + for (std::vector<BossInfo>::iterator i = bosses.begin(); i != bosses.end(); ++i) + saveStream << (uint32)i->state << " "; + return saveStream.str(); +} + +void InstanceData::DoUseDoorOrButton(uint64 uiGuid, uint32 uiWithRestoreTime, bool bUseAlternativeState) +{ + if (!uiGuid) + return; + + GameObject* pGo = instance->GetGameObject(uiGuid); + + if (pGo) + { + if (pGo->GetGoType() == GAMEOBJECT_TYPE_DOOR || pGo->GetGoType() == GAMEOBJECT_TYPE_BUTTON) + { + if (pGo->getLootState() == GO_READY) + pGo->UseDoorOrButton(uiWithRestoreTime,bUseAlternativeState); + else if (pGo->getLootState() == GO_ACTIVATED) + pGo->ResetDoorOrButton(); + } + else + error_log("SD2: Script call DoUseDoorOrButton, but gameobject entry %u is type %u.",pGo->GetEntry(),pGo->GetGoType()); + } +} + +void InstanceData::DoRespawnGameObject(uint64 uiGuid, uint32 uiTimeToDespawn) +{ + if (GameObject* pGo = instance->GetGameObject(uiGuid)) + { + //not expect any of these should ever be handled + if (pGo->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE || pGo->GetGoType() == GAMEOBJECT_TYPE_DOOR || + pGo->GetGoType() == GAMEOBJECT_TYPE_BUTTON || pGo->GetGoType() == GAMEOBJECT_TYPE_TRAP) + return; + + if (pGo->isSpawned()) + return; + + pGo->SetRespawnTime(uiTimeToDespawn); + } +} + +void InstanceData::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData) +{ + Map::PlayerList const& lPlayers = instance->GetPlayers(); + + if (!lPlayers.isEmpty()) + { + for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr) + if (Player *pPlayer = itr->getSource()) + pPlayer->SendUpdateWorldState(uiStateId, uiStateData); + } + else + debug_log("TSCR: DoUpdateWorldState attempt send data but no players in map."); +} + +// Send Notify to all players in instance +void InstanceData::DoSendNotifyToInstance(const char *format, ...) +{ + InstanceMap::PlayerList const &PlayerList = instance->GetPlayers(); + InstanceMap::PlayerList::const_iterator i; + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player *pPlayer = i->getSource()) + if (WorldSession *pSession = pPlayer->GetSession()) + pSession->SendNotification(format); +} + +// Complete Achievement for all players in instance +void InstanceData::DoCompleteAchievement(uint32 achievement) +{ + AchievementEntry const* pAE = GetAchievementStore()->LookupEntry(achievement); + Map::PlayerList const &PlayerList = instance->GetPlayers(); + + if (!pAE) + { + error_log("TSCR: DoCompleteAchievement called for not existing achievement %u", achievement); + return; + } + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player *pPlayer = i->getSource()) + pPlayer->CompletedAchievement(pAE); +} + +// Update Achievement Criteria for all players in instance +void InstanceData::DoUpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time) +{ + Map::PlayerList const &PlayerList = instance->GetPlayers(); + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player *pPlayer = i->getSource()) + pPlayer->UpdateAchievementCriteria(type, miscvalue1, miscvalue2, unit, time); +} + +// Start timed achievement for all players in instance +void InstanceData::DoStartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) +{ + Map::PlayerList const &PlayerList = instance->GetPlayers(); + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player *pPlayer = i->getSource()) + pPlayer->GetAchievementMgr().StartTimedAchievement(type, entry); +} + +// Stop timed achievement for all players in instance +void InstanceData::DoStopTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) +{ + Map::PlayerList const &PlayerList = instance->GetPlayers(); + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player *pPlayer = i->getSource()) + pPlayer->GetAchievementMgr().RemoveTimedAchievement(type, entry); +} + +// Remove Auras due to Spell on all players in instance +void InstanceData::DoRemoveAurasDueToSpellOnPlayers(uint32 spell) +{ + Map::PlayerList const &PlayerList = instance->GetPlayers(); + + if (!PlayerList.isEmpty()) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player* pPlayer = i->getSource()) + pPlayer->RemoveAurasDueToSpell(spell); +} + +bool InstanceData::CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/ /*= NULL*/, uint32 /*miscvalue1*/ /*= 0*/) +{ + sLog.outError("Achievement system call InstanceData::CheckAchievementCriteriaMeet but instance script for map %u not have implementation for achievement criteria %u", + instance->GetId(),criteria_id); + return false; +} |