diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 515840bed..9b7419009 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -38,6 +38,7 @@ #include "Formulas.h" #include "WaypointMovementGenerator.h" #include "InstanceData.h" +#include "InstanceSaveMgr.h" #include "BattleGroundMgr.h" #include "Spell.h" #include "Util.h" @@ -1269,7 +1270,8 @@ bool Creature::LoadFromDB(uint32 guidlow, Map *map) m_isDeadByDefault = data->is_dead; m_deathState = m_isDeadByDefault ? DEAD : ALIVE; - m_respawnTime = sObjectMgr.GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId()); + m_respawnTime = map->GetInstanceSave()->GetCreatureRespawnTime(m_DBTableGuid); + if(m_respawnTime > time(NULL)) // not ready to respawn { m_deathState = DEAD; @@ -1283,7 +1285,8 @@ bool Creature::LoadFromDB(uint32 guidlow, Map *map) else if(m_respawnTime) // respawn time set but expired { m_respawnTime = 0; - sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); + + GetMap()->GetInstanceSave()->SaveCreatureRespawnTime(m_DBTableGuid, 0); } uint32 curhealth = data->curhealth; @@ -1358,7 +1361,10 @@ void Creature::DeleteFromDB() return; } - sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); + // FIXME: this not safe for another map copies can be + if (InstanceSave* save = sInstanceSaveMgr.GetInstanceSave(GetMapId(), GetInstanceId())) + save->SaveCreatureRespawnTime(m_DBTableGuid, 0); + sObjectMgr.DeleteCreatureData(m_DBTableGuid); WorldDatabase.BeginTransaction(); @@ -1516,7 +1522,7 @@ void Creature::Respawn() if (IsDespawned()) { if (m_DBTableGuid) - sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(), 0); + GetMap()->GetInstanceSave()->SaveCreatureRespawnTime(m_DBTableGuid, 0); m_respawnTime = time(NULL); // respawn at next tick } } @@ -1815,9 +1821,9 @@ void Creature::SaveRespawnTime() return; if(m_respawnTime > time(NULL)) // dead (no corpse) - sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime); + GetMap()->GetInstanceSave()->SaveCreatureRespawnTime(m_DBTableGuid, m_respawnTime); else if (m_corpseDecayTimer > 0) // dead (corpse) - sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), time(NULL) + m_respawnDelay + m_corpseDecayTimer / IN_MILLISECONDS); + GetMap()->GetInstanceSave()->SaveCreatureRespawnTime(m_DBTableGuid, time(NULL) + m_respawnDelay + m_corpseDecayTimer / IN_MILLISECONDS); } bool Creature::IsOutOfThreatArea(Unit* pVictim) const diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index d381d9748..456f75652 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -32,6 +32,7 @@ #include "GridNotifiersImpl.h" #include "CellImpl.h" #include "InstanceData.h" +#include "InstanceSaveMgr.h" #include "BattleGround.h" #include "BattleGroundAV.h" #include "Util.h" @@ -596,13 +597,14 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map) { m_spawnedByDefault = true; m_respawnDelayTime = data->spawntimesecs; - m_respawnTime = sObjectMgr.GetGORespawnTime(m_DBTableGuid, map->GetInstanceId()); + + m_respawnTime = map->GetInstanceSave()->GetGORespawnTime(m_DBTableGuid); // ready to respawn - if(m_respawnTime && m_respawnTime <= time(NULL)) + if (m_respawnTime && m_respawnTime <= time(NULL)) { m_respawnTime = 0; - sObjectMgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); + map->GetInstanceSave()->SaveGORespawnTime(m_DBTableGuid, 0); } } else @@ -618,7 +620,10 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map) void GameObject::DeleteFromDB() { - sObjectMgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); + // FIXME: this can be not safe in case multiply loaded instance copies + if (InstanceSave* save = sInstanceSaveMgr.GetInstanceSave(GetMapId(), GetInstanceId())) + save->SaveGORespawnTime(m_DBTableGuid, 0); + sObjectMgr.DeleteGOData(m_DBTableGuid); WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); WorldDatabase.PExecuteLog("DELETE FROM game_event_gameobject WHERE guid = '%u'", m_DBTableGuid); @@ -671,7 +676,7 @@ Unit* GameObject::GetOwner() const void GameObject::SaveRespawnTime() { if(m_respawnTime > time(NULL) && m_spawnedByDefault) - sObjectMgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime); + GetMap()->GetInstanceSave()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime); } bool GameObject::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const @@ -714,7 +719,7 @@ void GameObject::Respawn() if(m_spawnedByDefault && m_respawnTime > 0) { m_respawnTime = time(NULL); - sObjectMgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); + GetMap()->GetInstanceSave()->SaveGORespawnTime(m_DBTableGuid, 0); } } diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index e35b14a72..2344fbc33 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -110,10 +110,28 @@ void InstanceSave::DeleteFromDB() InstanceSaveManager::DeleteInstanceFromDB(GetInstanceId()); } +void InstanceSave::DeleteRespawnTimes() +{ + // possible reset for instanceable map only + if (!m_instanceid) + return; + + m_goRespawnTimes.clear(); + m_creatureRespawnTimes.clear(); + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", m_instanceid); + CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", m_instanceid); + CharacterDatabase.CommitTransaction(); +} + /* true if the instance save is still valid */ bool InstanceSave::UnloadIfEmpty() { - if (m_playerList.empty() && m_groupList.empty() && !m_usedByMap) + // prevent unload if any bounded groups or online bounded player still exists + // also prevent unload if respawn data still exist (will not prevent reset by scheduler) + if (m_playerList.empty() && m_groupList.empty() && !m_usedByMap && + m_creatureRespawnTimes.empty() && m_goRespawnTimes.empty()) { sInstanceSaveMgr.RemoveInstanceSave(GetMapId(), GetInstanceId()); return false; @@ -122,6 +140,50 @@ bool InstanceSave::UnloadIfEmpty() return true; } +void InstanceSave::SaveCreatureRespawnTime(uint32 loguid, time_t t) +{ + SetCreatureRespawnTime(loguid, t); + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u' AND instance = '%u'", loguid, m_instanceid); + if(t > sWorld.GetGameTime()) + CharacterDatabase.PExecute("INSERT INTO creature_respawn VALUES ( '%u', '" UI64FMTD "', '%u' )", loguid, uint64(t), m_instanceid); + CharacterDatabase.CommitTransaction(); +} + +void InstanceSave::SaveGORespawnTime(uint32 loguid, time_t t) +{ + SetGORespawnTime(loguid, t); + + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, m_instanceid); + if(t > sWorld.GetGameTime()) + CharacterDatabase.PExecute("INSERT INTO gameobject_respawn VALUES ( '%u', '" UI64FMTD "', '%u' )", loguid, uint64(t), m_instanceid); + CharacterDatabase.CommitTransaction(); +} + +void InstanceSave::SetCreatureRespawnTime( uint32 loguid, time_t t ) +{ + if (t > sWorld.GetGameTime()) + m_creatureRespawnTimes[loguid] = t; + else + { + m_creatureRespawnTimes.erase(loguid); + UnloadIfEmpty(); + } +} + +void InstanceSave::SetGORespawnTime( uint32 loguid, time_t t ) +{ + if (t > sWorld.GetGameTime()) + m_goRespawnTimes[loguid] = t; + else + { + m_goRespawnTimes.erase(loguid); + UnloadIfEmpty(); + } +} + //== InstanceResetScheduler functions ====================== uint32 InstanceResetScheduler::GetMaxResetTimeFor(MapDifficulty const* mapDiff) @@ -486,9 +548,10 @@ void InstanceSaveManager::DeleteInstanceFromDB(uint32 instanceid) CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'", instanceid); CharacterDatabase.PExecute("DELETE FROM character_instance WHERE instance = '%u'", instanceid); CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", instanceid); + CharacterDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", instanceid); + CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", instanceid); CharacterDatabase.CommitTransaction(); } - // respawn times should be deleted only when the map gets unloaded } void InstanceSaveManager::RemoveInstanceSave(uint32 mapId, uint32 instanceId) @@ -654,8 +717,6 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId) if (iMap->IsDungeon()) ((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY); - else - sObjectMgr.DeleteRespawnTimeForInstance(instanceId);// even if map is not loaded } void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeLeft) @@ -739,3 +800,122 @@ void InstanceSaveManager::_CleanupExpiredInstancesAtTime( time_t t ) { _DelHelper(CharacterDatabase, "id, map, instance.difficulty", "instance", "LEFT JOIN instance_reset ON mapid = map AND instance.difficulty = instance_reset.difficulty WHERE (instance.resettime < '"UI64FMTD"' AND instance.resettime > '0') OR (NOT instance_reset.resettime IS NULL AND instance_reset.resettime < '"UI64FMTD"')", (uint64)t, (uint64)t); } + +void InstanceSaveManager::LoadCreatureRespawnTimes() +{ + // remove outdated data + CharacterDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())"); + + uint32 count = 0; + + QueryResult *result = CharacterDatabase.Query("SELECT guid, respawntime, instance FROM creature_respawn"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outString(">> Loaded 0 creature respawn time."); + return; + } + + barGoLink bar((int)result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 loguid = fields[0].GetUInt32(); + uint64 respawn_time = fields[1].GetUInt64(); + uint32 instanceId = fields[2].GetUInt32(); + + CreatureData const* data = sObjectMgr.GetCreatureData(loguid); + if (!data) + continue; + + MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid); + if (!mapEntry || (mapEntry->Instanceable() != (instanceId != 0))) + continue; + + // instances loaded early and respawn data must exist only for existed instances (save loaded) or non-instanced maps + InstanceSave* save = instanceId + ? GetInstanceSave(data->mapid, instanceId) + : AddInstanceSave(data->mapid, 0, REGULAR_DIFFICULTY, 0, false, true); + + if (!save) + continue; + + save->SetCreatureRespawnTime(loguid, time_t(respawn_time)); + + ++count; + + } while (result->NextRow()); + + delete result; + + sLog.outString(">> Loaded %u creature respawn times", count); + sLog.outString(); +} + +void InstanceSaveManager::LoadGameobjectRespawnTimes() +{ + // remove outdated data + CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())"); + + uint32 count = 0; + + QueryResult *result = CharacterDatabase.Query("SELECT guid, respawntime, instance FROM gameobject_respawn"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outString(">> Loaded 0 gameobject respawn time."); + return; + } + + barGoLink bar((int)result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 loguid = fields[0].GetUInt32(); + uint64 respawn_time = fields[1].GetUInt64(); + uint32 instanceId = fields[2].GetUInt32(); + + + GameObjectData const* data = sObjectMgr.GetGOData(loguid); + if (!data) + continue; + + MapEntry const* mapEntry = sMapStore.LookupEntry(data->mapid); + if (!mapEntry || (mapEntry->Instanceable() != (instanceId != 0))) + continue; + + // instances loaded early and respawn data must exist only for existed instances (save loaded) or non-instanced maps + InstanceSave* save = instanceId + ? GetInstanceSave(data->mapid, instanceId) + : AddInstanceSave(data->mapid, 0, REGULAR_DIFFICULTY, 0, false, true); + + if (!save) + continue; + + save->SetGORespawnTime(loguid, time_t(respawn_time)); + + ++count; + + } while (result->NextRow()); + + delete result; + + sLog.outString(">> Loaded %u gameobject respawn times", count); + sLog.outString(); +} diff --git a/src/game/InstanceSaveMgr.h b/src/game/InstanceSaveMgr.h index f3ec4afb3..9df58aa5c 100644 --- a/src/game/InstanceSaveMgr.h +++ b/src/game/InstanceSaveMgr.h @@ -36,6 +36,8 @@ struct MapDifficulty; class Player; class Group; +class InstanceSaveManager; + /* Holds the information necessary for creating a new map for an existing instance Is referenced in three cases: @@ -45,6 +47,7 @@ class Group; */ class InstanceSave { + friend class InstanceSaveManager; public: /* Created either when: - any new instance is being generated @@ -105,7 +108,26 @@ class InstanceSave UnloadIfEmpty(); } + void DeleteRespawnTimes(); + time_t GetCreatureRespawnTime(uint32 loguid) const + { + RespawnTimes::const_iterator itr = m_creatureRespawnTimes.find(loguid); + return itr != m_creatureRespawnTimes.end() ? itr->second : 0; + } + void SaveCreatureRespawnTime(uint32 loguid, time_t t); + time_t GetGORespawnTime(uint32 loguid) const + { + RespawnTimes::const_iterator itr = m_goRespawnTimes.find(loguid); + return itr != m_goRespawnTimes.end() ? itr->second : 0; + } + void SaveGORespawnTime(uint32 loguid, time_t t); + private: + void SetCreatureRespawnTime(uint32 loguid, time_t t); + void SetGORespawnTime(uint32 loguid, time_t t); + + private: + typedef UNORDERED_MAP RespawnTimes; typedef std::list PlayerListType; typedef std::list GroupListType; @@ -113,14 +135,18 @@ class InstanceSave /* the only reason the instSave-object links are kept is because the object-instSave links need to be broken at reset time TODO: maybe it's enough to just store the number of players/groups */ - PlayerListType m_playerList; - GroupListType m_groupList; + PlayerListType m_playerList; // lock InstanceSave from unload + GroupListType m_groupList; // lock InstanceSave from unload time_t m_resetTime; uint32 m_instanceid; uint32 m_mapid; Difficulty m_difficulty; bool m_canReset; - bool m_usedByMap; // true when instance map loaded + bool m_usedByMap; // true when instance map loaded, lock InstanceSave from unload + + // persistent data + RespawnTimes m_creatureRespawnTimes; // // lock InstanceSave from unload, for example for temporary bound dungeon unload delay + RespawnTimes m_goRespawnTimes; // lock InstanceSave from unload, for example for temporary bound dungeon unload delay }; enum ResetEventType @@ -149,8 +175,6 @@ struct InstanceResetEvent bool operator == (const InstanceResetEvent& e) { return e.mapid == mapid && e.difficulty == difficulty && e.instanceId == instanceId; } }; -class InstanceSaveManager; - class InstanceResetScheduler { public: // constructors @@ -198,9 +222,13 @@ class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton InstanceSaveHashMap; - InstanceSave *GetInstanceSave(uint32 mapId, uint32 InstanceId); - // called by scheduler void _ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeleft); void _ResetInstance(uint32 mapid, uint32 instanceId); diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index c3d40bbbc..c876456e9 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -553,14 +553,13 @@ bool ChatHandler::HandleGonameCommand(char* args) // if no bind exists, create a solo bind if (!gBind) { - if (InstanceSave *save = target->GetMap()->GetInstanceSave()) - { - // if player is group leader then we need add group bind - if (group && group->IsLeader(_player->GetObjectGuid())) - group->BindToInstance(save, !save->CanReset()); - else - _player->BindToInstance(save, !save->CanReset()); - } + InstanceSave *save = target->GetMap()->GetInstanceSave(); + + // if player is group leader then we need add group bind + if (group && group->IsLeader(_player->GetObjectGuid())) + group->BindToInstance(save, !save->CanReset()); + else + _player->BindToInstance(save, !save->CanReset()); } } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 208f391ae..99ec402c2 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1431,11 +1431,8 @@ bool InstanceMap::Add(Player *player) pGroup->GetId(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty()); - if (GetInstanceSave()) - sLog.outError("MapSave players: %d, group count: %d", + sLog.outError("MapSave players: %d, group count: %d", GetInstanceSave()->GetPlayerCount(), GetInstanceSave()->GetGroupCount()); - else - sLog.outError("MapSave NULL"); if (groupBind->save) sLog.outError("GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount()); @@ -1589,7 +1586,7 @@ void InstanceMap::UnloadAll(bool pForce) } if(m_resetAfterUnload == true) - sObjectMgr.DeleteRespawnTimeForInstance(GetInstanceId()); + GetInstanceSave()->DeleteRespawnTimes(); Map::UnloadAll(pForce); } diff --git a/src/game/Map.h b/src/game/Map.h index e0e817fbb..552ee76f9 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -187,6 +187,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); } bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); } + // can't be NULL for loaded map InstanceSave* GetInstanceSave() const { return m_instanceSave; } void AddObjectToRemoveList(WorldObject *obj); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 56174f1a9..bc020ea6f 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1618,90 +1618,6 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data } } -void ObjectMgr::LoadCreatureRespawnTimes() -{ - // remove outdated data - CharacterDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())"); - - uint32 count = 0; - - QueryResult *result = CharacterDatabase.Query("SELECT guid, respawntime, instance FROM creature_respawn"); - - if(!result) - { - barGoLink bar(1); - - bar.step(); - - sLog.outString(); - sLog.outString(">> Loaded 0 creature respawn time."); - return; - } - - barGoLink bar((int)result->GetRowCount()); - - do - { - Field *fields = result->Fetch(); - bar.step(); - - uint32 loguid = fields[0].GetUInt32(); - uint64 respawn_time = fields[1].GetUInt64(); - uint32 instance = fields[2].GetUInt32(); - - mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = time_t(respawn_time); - - ++count; - } while (result->NextRow()); - - delete result; - - sLog.outString( ">> Loaded %lu creature respawn times", (unsigned long)mCreatureRespawnTimes.size() ); - sLog.outString(); -} - -void ObjectMgr::LoadGameobjectRespawnTimes() -{ - // remove outdated data - CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())"); - - uint32 count = 0; - - QueryResult *result = CharacterDatabase.Query("SELECT guid, respawntime, instance FROM gameobject_respawn"); - - if(!result) - { - barGoLink bar(1); - - bar.step(); - - sLog.outString(); - sLog.outString(">> Loaded 0 gameobject respawn time."); - return; - } - - barGoLink bar((int)result->GetRowCount()); - - do - { - Field *fields = result->Fetch(); - bar.step(); - - uint32 loguid = fields[0].GetUInt32(); - uint64 respawn_time = fields[1].GetUInt64(); - uint32 instance = fields[2].GetUInt32(); - - mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = time_t(respawn_time); - - ++count; - } while (result->NextRow()); - - delete result; - - sLog.outString( ">> Loaded %lu gameobject respawn times", (unsigned long)mGORespawnTimes.size() ); - sLog.outString(); -} - // name must be checked to correctness (if received) before call this function uint64 ObjectMgr::GetPlayerGUIDByName(std::string name) const { @@ -6840,17 +6756,6 @@ void ObjectMgr::LoadWeatherZoneChances() sLog.outString(">> Loaded %u weather definitions", count); } -void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t) -{ - mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)] = t; - - CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance); - if(t) - CharacterDatabase.PExecute("INSERT INTO creature_respawn VALUES ( '%u', '" UI64FMTD "', '%u' )", loguid, uint64(t), instance); - CharacterDatabase.CommitTransaction(); -} - void ObjectMgr::DeleteCreatureData(uint32 guid) { // remove mapid*cellid -> guid_set map @@ -6861,45 +6766,6 @@ void ObjectMgr::DeleteCreatureData(uint32 guid) mCreatureDataMap.erase(guid); } -void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t) -{ - mGORespawnTimes[MAKE_PAIR64(loguid,instance)] = t; - - CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE guid = '%u' AND instance = '%u'", loguid, instance); - if(t) - CharacterDatabase.PExecute("INSERT INTO gameobject_respawn VALUES ( '%u', '" UI64FMTD "', '%u' )", loguid, uint64(t), instance); - CharacterDatabase.CommitTransaction(); -} - -void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance) -{ - RespawnTimes::iterator next; - - for(RespawnTimes::iterator itr = mGORespawnTimes.begin(); itr != mGORespawnTimes.end(); itr = next) - { - next = itr; - ++next; - - if (PAIR64_HIPART(itr->first)==instance) - mGORespawnTimes.erase(itr); - } - - for(RespawnTimes::iterator itr = mCreatureRespawnTimes.begin(); itr != mCreatureRespawnTimes.end(); itr = next) - { - next = itr; - ++next; - - if (PAIR64_HIPART(itr->first)==instance) - mCreatureRespawnTimes.erase(itr); - } - - CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", instance); - CharacterDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", instance); - CharacterDatabase.CommitTransaction(); -} - void ObjectMgr::DeleteGOData(uint32 guid) { // remove mapid*cellid -> guid_set map diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 0703e9737..ed55fe4bb 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -102,9 +102,6 @@ struct CellObjectGuids typedef UNORDERED_MAP CellObjectGuidsMap; typedef UNORDERED_MAP MapObjectGuids; -typedef UNORDERED_MAP RespawnTimes; - - // mangos string ranges #define MIN_MANGOS_STRING_ID 1 // 'mangos_string' #define MAX_MANGOS_STRING_ID 2000000000 @@ -648,14 +645,12 @@ class ObjectMgr void LoadCreatureLocales(); void LoadCreatureTemplates(); void LoadCreatures(); - void LoadCreatureRespawnTimes(); void LoadCreatureAddons(); void LoadCreatureModelInfo(); void LoadCreatureModelRace(); void LoadEquipmentTemplates(); void LoadGameObjectLocales(); void LoadGameobjects(); - void LoadGameobjectRespawnTimes(); void LoadItemConverts(); void LoadItemPrototypes(); void LoadItemRequiredTarget(); @@ -878,12 +873,6 @@ class ObjectMgr void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance); void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid); - time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance) { return mCreatureRespawnTimes[MAKE_PAIR64(loguid,instance)]; } - void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t); - time_t GetGORespawnTime(uint32 loguid, uint32 instance) { return mGORespawnTimes[MAKE_PAIR64(loguid,instance)]; } - void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t); - void DeleteRespawnTimeForInstance(uint32 instance); - // grid objects void AddCreatureToGrid(uint32 guid, CreatureData const* data); void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data); @@ -1153,8 +1142,6 @@ class ObjectMgr MangosStringLocaleMap mMangosStringLocaleMap; GossipMenuItemsLocaleMap mGossipMenuItemsLocaleMap; PointOfInterestLocaleMap mPointOfInterestLocaleMap; - RespawnTimes mCreatureRespawnTimes; - RespawnTimes mGORespawnTimes; // Storage for Conditions. First element (index 0) is reserved for zero-condition (nothing required) typedef std::vector ConditionStore; diff --git a/src/game/PoolManager.cpp b/src/game/PoolManager.cpp index 86f57381a..2059ce2aa 100644 --- a/src/game/PoolManager.cpp +++ b/src/game/PoolManager.cpp @@ -21,6 +21,7 @@ #include "ObjectGuid.h" #include "ProgressBar.h" #include "Log.h" +#include "InstanceSaveMgr.h" #include "MapManager.h" #include "World.h" #include "Policies/SingletonImp.h" @@ -400,7 +401,7 @@ void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) // for not loaded grid just update respawn time (avoid work for instances until implemented support) else if(!instantly) { - sObjectMgr.SaveCreatureRespawnTime(obj->guid, 0 /*map->GetInstanceId()*/, time(NULL) + data->spawntimesecs); + map->GetInstanceSave()->SaveCreatureRespawnTime(obj->guid, time(NULL) + data->spawntimesecs); } } } @@ -452,7 +453,7 @@ void PoolGroup::Spawn1Object(PoolObject* obj, bool instantly) { // for spawned by default object only if (data->spawntimesecs >= 0) - sObjectMgr.SaveGORespawnTime(obj->guid, 0 /*map->GetInstanceId()*/, time(NULL) + data->spawntimesecs); + map->GetInstanceSave()->SaveGORespawnTime(obj->guid, time(NULL) + data->spawntimesecs); } } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 22c70599e..0767e0686 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -882,9 +882,8 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa // the reset time is set but not added to the scheduler // until the players leave the instance time_t resettime = cVictim->GetRespawnTimeEx() + 2 * HOUR; - if (InstanceSave *save = m->GetInstanceSave()) - if (save->GetResetTime() < resettime) - save->SetResetTime(resettime); + if (m->GetInstanceSave()->GetResetTime() < resettime) + m->GetInstanceSave()->SetResetTime(resettime); } } } diff --git a/src/game/World.cpp b/src/game/World.cpp index cf56ec5b2..e0d0bd30b 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1042,13 +1042,13 @@ void World::SetInitialWorldSettings() sLog.outString(); sLog.outString( "Loading Creature Respawn Data..." ); // must be after PackInstances() - sObjectMgr.LoadCreatureRespawnTimes(); + sInstanceSaveMgr.LoadCreatureRespawnTimes(); sLog.outString( "Loading Gameobject Data..." ); sObjectMgr.LoadGameobjects(); sLog.outString( "Loading Gameobject Respawn Data..." ); // must be after PackInstances() - sObjectMgr.LoadGameobjectRespawnTimes(); + sInstanceSaveMgr.LoadGameobjectRespawnTimes(); sLog.outString( "Loading Objects Pooling Data..."); sPoolMgr.LoadFromDB(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b576606b1..4bba02a1d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11122" + #define REVISION_NR "11123" #endif // __REVISION_NR_H__