diff options
Diffstat (limited to 'src')
87 files changed, 1314 insertions, 1212 deletions
diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index ac61d455b4c..f835206aba5 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -95,7 +95,7 @@ namespace FactorySelector // select NullCreatureAI if not another cases ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key(); - TC_LOG_DEBUG("scripts", "Creature %s (%s DB GUID: " UI64FMTD ") is using AI type: %s.", creature->GetName().c_str(), creature->GetGUID().ToString().c_str(), creature->GetDBTableGUIDLow(), ainame.c_str()); + TC_LOG_DEBUG("scripts", "Creature %s (%s DB GUID: " UI64FMTD ") is using AI type: %s.", creature->GetName().c_str(), creature->GetGUID().ToString().c_str(), creature->GetSpawnId(), ainame.c_str()); return (ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature)); } diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index d59f0130c9c..f3520820f30 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3470,14 +3470,14 @@ void SmartScript::GetScript() SmartAIEventList e; if (me) { - e = sSmartScriptMgr->GetScript(-((int32)me->GetDBTableGUIDLow()), mScriptType); + e = sSmartScriptMgr->GetScript(-((int32)me->GetSpawnId()), mScriptType); if (e.empty()) e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType); FillScript(e, me, NULL); } else if (go) { - e = sSmartScriptMgr->GetScript(-((int32)go->GetDBTableGUIDLow()), mScriptType); + e = sSmartScriptMgr->GetScript(-((int32)go->GetSpawnId()), mScriptType); if (e.empty()) e = sSmartScriptMgr->GetScript((int32)go->GetEntry(), mScriptType); FillScript(e, go, NULL); @@ -3667,5 +3667,12 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry) Unit* SmartScript::GetLastInvoker() { - return ObjectAccessor::FindUnit(mLastInvoker); + WorldObject* lookupRoot = me; + if (!lookupRoot) + lookupRoot = go; + + if (lookupRoot) + return ObjectAccessor::GetUnit(*lookupRoot, mLastInvoker); + + return ObjectAccessor::FindPlayer(mLastInvoker); } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index f13bcf3050b..0233d1aa7d0 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -118,7 +118,7 @@ class SmartScript smart = false; if (!smart) - TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: " UI64FMTD " Entry: %u) is not using SmartAI, action called by Creature (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(c ? c->GetDBTableGUIDLow() : UI64LIT(0)), c ? c->GetEntry() : 0, uint64(me ? me->GetDBTableGUIDLow() : UI64LIT(0)), me ? me->GetEntry() : 0); + TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: " UI64FMTD " Entry: %u) is not using SmartAI, action called by Creature (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(c ? c->GetSpawnId() : UI64LIT(0)), c ? c->GetEntry() : 0, uint64(me ? me->GetSpawnId() : UI64LIT(0)), me ? me->GetEntry() : 0); return smart; } @@ -132,7 +132,7 @@ class SmartScript if (!go || go->GetAIName() != "SmartGameObjectAI") smart = false; if (!smart) - TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: " UI64FMTD " Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(g ? g->GetDBTableGUIDLow() : UI64LIT(0)), g ? g->GetEntry() : 0, uint64(go ? go->GetDBTableGUIDLow() : UI64LIT(0)), go ? go->GetEntry() : 0); + TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: " UI64FMTD " Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: " UI64FMTD " Entry: %u) skipped to prevent crash.", uint64(g ? g->GetSpawnId() : UI64LIT(0)), g ? g->GetEntry() : 0, uint64(go ? go->GetSpawnId() : UI64LIT(0)), go ? go->GetEntry() : 0); return smart; } @@ -211,20 +211,27 @@ class SmartScript void OnReset(); void ResetBaseObject() { - if (!meOrigGUID.IsEmpty()) + WorldObject* lookupRoot = me; + if (!lookupRoot) + lookupRoot = go; + + if (lookupRoot) { - if (Creature* m = HashMapHolder<Creature>::Find(meOrigGUID)) + if (!meOrigGUID.IsEmpty()) { - me = m; - go = NULL; + if (Creature* m = ObjectAccessor::GetCreature(*lookupRoot, meOrigGUID)) + { + me = m; + go = NULL; + } } - } - if (!goOrigGUID.IsEmpty()) - { - if (GameObject* o = HashMapHolder<GameObject>::Find(goOrigGUID)) + if (!goOrigGUID.IsEmpty()) { - me = NULL; - go = o; + if (GameObject* o = ObjectAccessor::GetGameObject(*lookupRoot, goOrigGUID)) + { + me = NULL; + go = o; + } } } goOrigGUID.Clear(); diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index dc1b666a921..fbd49acaf0b 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -793,7 +793,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl } Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), map, PHASEMASK_NORMAL, entry, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, PHASEMASK_NORMAL, entry, x, y, z, o)) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Can't create creature entry: %u", entry); delete creature; @@ -829,7 +829,7 @@ GameObject* Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z // Create gameobject GameObject* go = new GameObject; - if (!go->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), entry, map, PHASEMASK_NORMAL, x, y, z, o, 0, 0, 0, 0, 100, GO_STATE_READY)) + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, PHASEMASK_NORMAL, x, y, z, o, 0, 0, 0, 0, 100, GO_STATE_READY)) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Cannot create gameobject template %u! Battlefield not created!", entry); delete go; diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 922bf4fed36..c6c46c48f50 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1335,7 +1335,7 @@ void Battleground::BuildPvPLogDataPacket(WorldPackets::Battleground::PVPLogData& playerData.HealingDone = score.second->HealingDone; score.second->BuildObjectivesBlock(playerData.Stats); - if (Player* player = ObjectAccessor::GetObjectInMap(playerData.PlayerGUID, GetBgMap(), (Player*)nullptr)) + if (Player* player = ObjectAccessor::GetPlayer(GetBgMap(), playerData.PlayerGUID)) { playerData.IsInWorld = true; playerData.PrimaryTalentTree = player->GetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID); @@ -1445,7 +1445,7 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created // So we must create it specific for this instance GameObject* go = new GameObject; - if (!go->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), entry, GetBgMap(), + if (!go->Create(GetBgMap()->GenerateLowGuid<HighGuid::GameObject>(), entry, GetBgMap(), PHASEMASK_NORMAL, x, y, z, o, rotation0, rotation1, rotation2, rotation3, 100, goState)) { TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: %u) for BG (map: %u, instance id: %u)!", @@ -1589,7 +1589,7 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), map, PHASEMASK_NORMAL, entry, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, PHASEMASK_NORMAL, entry, x, y, z, o)) { TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: cannot create creature (entry: %u) for BG (map: %u, instance id: %u)!", entry, m_MapId, m_InstanceID); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index 8ea632a1dba..8376c3e4584 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -304,7 +304,7 @@ Creature* BattlegroundAV::AddAVCreature(uint16 cinfoid, uint16 type) if (!isStatic && ((cinfoid >= AV_NPC_A_GRAVEDEFENSE0 && cinfoid <= AV_NPC_A_GRAVEDEFENSE3) || (cinfoid >= AV_NPC_H_GRAVEDEFENSE0 && cinfoid <= AV_NPC_H_GRAVEDEFENSE3))) { - CreatureData &data = sObjectMgr->NewOrExistCreatureData(creature->GetDBTableGUIDLow()); + CreatureData &data = sObjectMgr->NewOrExistCreatureData(creature->GetSpawnId()); data.spawndist = 5; } //else spawndist will be 15, so creatures move maximum=10 diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index e9e4bbb2a9c..4a96c6a99c0 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -119,7 +119,7 @@ void BattlegroundEY::PostUpdateImpl(uint32 diff) void BattlegroundEY::GetPlayerPositionData(std::vector<WorldPackets::Battleground::BattlegroundPlayerPosition>* positions) const { - if (Player* player = ObjectAccessor::GetObjectInMap(m_FlagKeeper, GetBgMap(), (Player*)nullptr)) + if (Player* player = ObjectAccessor::GetPlayer(GetBgMap(), m_FlagKeeper)) { WorldPackets::Battleground::BattlegroundPlayerPosition position; position.Guid = player->GetGUID(); @@ -176,7 +176,7 @@ void BattlegroundEY::CheckSomeoneJoinedPoint() GameObject* obj = NULL; for (uint8 i = 0; i < EY_POINTS_MAX; ++i) { - obj = HashMapHolder<GameObject>::Find(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); + obj = GetBgMap()->GetGameObject(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); if (obj) { uint8 j = 0; @@ -216,7 +216,7 @@ void BattlegroundEY::CheckSomeoneLeftPoint() GameObject* obj = NULL; for (uint8 i = 0; i < EY_POINTS_MAX; ++i) { - obj = HashMapHolder<GameObject>::Find(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); + obj = GetBgMap()->GetGameObject(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); if (obj) { uint8 j = 0; @@ -603,7 +603,7 @@ void BattlegroundEY::RespawnFlagAfterDrop() { RespawnFlag(true); - GameObject* obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID()); + GameObject* obj = GetBgMap()->GetGameObject(GetDroppedFlagGUID()); if (obj) obj->Delete(); else diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 040905a32d4..2c11bd149fd 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -195,7 +195,7 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff) void BattlegroundWS::GetPlayerPositionData(std::vector<WorldPackets::Battleground::BattlegroundPlayerPosition>* positions) const { - if (Player* player = ObjectAccessor::GetObjectInMap(m_FlagKeepers[TEAM_ALLIANCE], GetBgMap(), (Player*)nullptr)) + if (Player* player = ObjectAccessor::GetPlayer(GetBgMap(), m_FlagKeepers[TEAM_ALLIANCE])) { WorldPackets::Battleground::BattlegroundPlayerPosition position; position.Guid = player->GetGUID(); @@ -206,7 +206,7 @@ void BattlegroundWS::GetPlayerPositionData(std::vector<WorldPackets::Battlegroun positions->push_back(position); } - if (Player* player = ObjectAccessor::GetObjectInMap(m_FlagKeepers[TEAM_HORDE], GetBgMap(), (Player*)nullptr)) + if (Player* player = ObjectAccessor::GetPlayer(GetBgMap(), m_FlagKeepers[TEAM_HORDE])) { WorldPackets::Battleground::BattlegroundPlayerPosition position; position.Guid = player->GetGUID(); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 5fc7240cb9c..babbbbce153 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -301,10 +301,10 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) switch (object->GetTypeId()) { case TYPEID_UNIT: - condMeets &= object->ToCreature()->GetDBTableGUIDLow() == ConditionValue3; + condMeets &= object->ToCreature()->GetSpawnId() == ConditionValue3; break; case TYPEID_GAMEOBJECT: - condMeets &= object->ToGameObject()->GetDBTableGUIDLow() == ConditionValue3; + condMeets &= object->ToGameObject()->GetSpawnId() == ConditionValue3; break; default: break; diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index 8850392a13e..426d47f88d3 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -15,7 +15,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ObjectAccessor.h" #include "Unit.h" #include "SpellInfo.h" #include "Log.h" @@ -41,7 +40,7 @@ void AreaTrigger::AddToWorld() ///- Register the AreaTrigger for guid lookup and for caster if (!IsInWorld()) { - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<AreaTrigger>(GetGUID(), this); WorldObject::AddToWorld(); } } @@ -52,7 +51,7 @@ void AreaTrigger::RemoveFromWorld() if (IsInWorld()) { WorldObject::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + GetMap()->GetObjectsStore().Remove<AreaTrigger>(GetGUID()); } } diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 6be200b8887..4294eb57dbd 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -48,7 +48,7 @@ void Corpse::AddToWorld() { ///- Register the corpse for guid lookup if (!IsInWorld()) - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<Corpse>(GetGUID(), this); Object::AddToWorld(); } @@ -57,7 +57,7 @@ void Corpse::RemoveFromWorld() { ///- Remove the corpse from the accessor if (IsInWorld()) - sObjectAccessor->RemoveObject(this); + GetMap()->GetObjectsStore().Remove<Corpse>(GetGUID()); Object::RemoveFromWorld(); } @@ -89,7 +89,7 @@ bool Corpse::Create(ObjectGuid::LowType guidlow, Player* owner) Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(GetMapId(), 0, guidlow)); SetPhaseMask(owner->GetPhaseMask(), false); - SetObjectScale(1); + SetObjectScale(1.0f); SetGuidValue(CORPSE_FIELD_OWNER, owner->GetGUID()); _gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY()); @@ -107,7 +107,6 @@ void Corpse::SaveToDB() uint16 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE); - stmt->setUInt64(index++, GetGUID().GetCounter()); // corpseGuid stmt->setUInt64(index++, GetOwnerGUID().GetCounter()); // guid stmt->setFloat (index++, GetPositionX()); // posX stmt->setFloat (index++, GetPositionY()); // posY @@ -129,11 +128,8 @@ void Corpse::SaveToDB() { index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE_PHASES); - stmt->setUInt32(index++, GetGUID().GetCounter()); // Guid (corpse's) - stmt->setUInt32(index++, phaseId); // PhaseId stmt->setUInt32(index++, GetOwnerGUID().GetCounter()); // OwnerGuid - stmt->setUInt32(index++, uint32(m_time)); // Time - stmt->setUInt8(index++, GetType()); // CorpseType + stmt->setUInt32(index++, phaseId); // PhaseId trans->Append(stmt); } @@ -156,36 +152,19 @@ void Corpse::DeleteBonesFromWorld() void Corpse::DeleteFromDB(SQLTransaction& trans) { - PreparedStatement* stmt = NULL; - if (GetType() == CORPSE_BONES) - { - // Only specific bones - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE); - stmt->setUInt32(0, GetGUID().GetCounter()); - trans->Append(stmt); - - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_PHASES); - stmt->setUInt32(0, GetGUID().GetCounter()); - trans->Append(stmt); - } - else - { - // all corpses (not bones) - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_CORPSES); - stmt->setUInt32(0, GetOwnerGUID().GetCounter()); - trans->Append(stmt); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE); + stmt->setUInt64(0, GetOwnerGUID().GetCounter()); + trans->Append(stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_CORPSES_PHASES); - stmt->setUInt32(0, GetOwnerGUID().GetCounter()); - trans->Append(stmt); - } + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_PHASES); + stmt->setUInt64(0, GetOwnerGUID().GetCounter()); + trans->Append(stmt); } bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields) { - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, corpseGuid, guid FROM corpse WHERE corpseType <> 0 + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse float posX = fields[0].GetFloat(); float posY = fields[1].GetFloat(); @@ -195,13 +174,14 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields) Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(mapId, 0, guid)); + SetObjectScale(1.0f); SetUInt32Value(CORPSE_FIELD_DISPLAY_ID, fields[5].GetUInt32()); _LoadIntoDataField(fields[6].GetCString(), CORPSE_FIELD_ITEM, EQUIPMENT_SLOT_END); SetUInt32Value(CORPSE_FIELD_BYTES_1, fields[7].GetUInt32()); SetUInt32Value(CORPSE_FIELD_BYTES_2, fields[8].GetUInt32()); SetUInt32Value(CORPSE_FIELD_FLAGS, fields[9].GetUInt8()); SetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS, fields[10].GetUInt8()); - SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Create<HighGuid::Player>(fields[15].GetUInt64())); + SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Create<HighGuid::Player>(fields[14].GetUInt64())); m_time = time_t(fields[11].GetUInt32()); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index db294de4bd5..ce7eadcae2b 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -147,7 +147,7 @@ Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(), m_groupLootTimer(0), m_PlayerDamageReq(0), _pickpocketLootRestore(0), m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE), -m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(UI64LIT(0)), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), +m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(UI64LIT(0)), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(NULL), m_creatureData(NULL), m_waypointID(0), m_path_id(0), m_formation(NULL) { @@ -185,7 +185,11 @@ void Creature::AddToWorld() { if (GetZoneScript()) GetZoneScript()->OnCreatureCreate(this); - sObjectAccessor->AddObject(this); + + GetMap()->GetObjectsStore().Insert<Creature>(GetGUID(), this); + if (m_spawnId) + GetMap()->GetCreatureBySpawnIdStore().insert(std::make_pair(m_spawnId, this)); + Unit::AddToWorld(); SearchFormation(); AIM_Initialize(); @@ -200,10 +204,15 @@ void Creature::RemoveFromWorld() { if (GetZoneScript()) GetZoneScript()->OnCreatureRemove(this); + if (m_formation) sFormationMgr->RemoveCreatureFromGroup(m_formation, this); + Unit::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + + if (m_spawnId) + Trinity::Containers::MultimapErasePair(GetMap()->GetCreatureBySpawnIdStore(), m_spawnId, this); + GetMap()->GetObjectsStore().Remove<Creature>(GetGUID()); } } @@ -222,7 +231,7 @@ void Creature::SearchFormation() if (IsSummon()) return; - ObjectGuid::LowType lowguid = GetDBTableGUIDLow(); + ObjectGuid::LowType lowguid = GetSpawnId(); if (!lowguid) return; @@ -474,7 +483,7 @@ void Creature::Update(uint32 diff) if (!allowed) // Will be rechecked on next Update call break; - ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::Creature>(GetMapId(), GetEntry(), m_DBTableGuid); + ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::Creature>(GetMapId(), GetEntry(), m_spawnId); time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid); if (!linkedRespawntime) // Can respawn Respawn(); @@ -936,7 +945,7 @@ void Creature::SaveToDB() { // this should only be used when the creature has already been loaded // preferably after adding to map, because mapid may not be valid otherwise - CreatureData const* data = sObjectMgr->GetCreatureData(m_DBTableGuid); + CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId); if (!data) { TC_LOG_ERROR("entities.unit", "Creature::SaveToDB failed, cannot get creature data!"); @@ -950,10 +959,10 @@ void Creature::SaveToDB() void Creature::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask) { // update in loaded data - if (!m_DBTableGuid) - m_DBTableGuid = GetGUID().GetCounter(); + if (!m_spawnId) + m_spawnId = sObjectMgr->GenerateCreatureSpawnId(); - CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_DBTableGuid); + CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId); uint32 displayId = GetNativeDisplayId(); uint32 npcflag = GetUInt32Value(UNIT_NPC_FLAGS); @@ -1020,13 +1029,13 @@ void Creature::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask) SQLTransaction trans = WorldDatabase.BeginTransaction(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); - stmt->setUInt64(0, m_DBTableGuid); + stmt->setUInt64(0, m_spawnId); trans->Append(stmt); uint8 index = 0; stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE); - stmt->setUInt64(index++, m_DBTableGuid); + stmt->setUInt64(index++, m_spawnId); stmt->setUInt32(index++, GetEntry()); stmt->setUInt16(index++, uint16(mapid)); stmt->setUInt32(index++, spawnMask); @@ -1225,26 +1234,17 @@ bool Creature::CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, Creatu return true; } -bool Creature::LoadCreatureFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap) +bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap) { - CreatureData const* data = sObjectMgr->GetCreatureData(guid); - + CreatureData const* data = sObjectMgr->GetCreatureData(spawnId); if (!data) { - TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") not found in table `creature`, can't load. ", guid); + TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") not found in table `creature`, can't load. ", spawnId); return false; } - m_DBTableGuid = guid; - if (map->GetInstanceId() == 0) - { - if (map->GetCreature(ObjectGuid::Create<HighGuid::Creature>(data->mapid, data->id, guid))) - return false; - } - else - guid = sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(); - - if (!Create(guid, map, data->phaseMask, data->id, data->posX, data->posY, data->posZ, data->orientation, data)) + m_spawnId = spawnId; + if (!Create(map->GenerateLowGuid<HighGuid::Creature>(), map, data->phaseMask, data->id, data->posX, data->posY, data->posZ, data->orientation, data)) return false; //We should set first home position, because then AI calls home movement @@ -1255,7 +1255,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType guid, Map* map, bool addTo m_respawnDelay = data->spawntimesecs; m_deathState = ALIVE; - m_respawnTime = GetMap()->GetCreatureRespawnTime(m_DBTableGuid); + m_respawnTime = GetMap()->GetCreatureRespawnTime(m_spawnId); if (m_respawnTime) // respawn on Update { m_deathState = DEAD; @@ -1293,7 +1293,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType guid, Map* map, bool addTo m_creatureData = data; - loot.SetGUID(ObjectGuid::Create<HighGuid::LootObject>(data->mapid, data->id, sObjectMgr->GetGenerator<HighGuid::LootObject>()->Generate())); + loot.SetGUID(ObjectGuid::Create<HighGuid::LootObject>(data->mapid, data->id, GetMap()->GenerateLowGuid<HighGuid::LootObject>())); if (addToMap && !GetMap()->AddToMap(this)) return false; @@ -1352,31 +1352,31 @@ bool Creature::hasInvolvedQuest(uint32 quest_id) const void Creature::DeleteFromDB() { - if (!m_DBTableGuid) + if (!m_spawnId) { TC_LOG_ERROR("entities.unit", "Trying to delete not saved %s!", GetGUID().ToString().c_str()); return; } - GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid); - sObjectMgr->DeleteCreatureData(m_DBTableGuid); + GetMap()->RemoveCreatureRespawnTime(m_spawnId); + sObjectMgr->DeleteCreatureData(m_spawnId); SQLTransaction trans = WorldDatabase.BeginTransaction(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); - stmt->setUInt64(0, m_DBTableGuid); + stmt->setUInt64(0, m_spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON); - stmt->setUInt64(0, m_DBTableGuid); + stmt->setUInt64(0, m_spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_CREATURE); - stmt->setUInt64(0, m_DBTableGuid); + stmt->setUInt64(0, m_spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP); - stmt->setUInt64(0, m_DBTableGuid); + stmt->setUInt64(0, m_spawnId); trans->Append(stmt); WorldDatabase.CommitTransaction(trans); @@ -1568,8 +1568,8 @@ void Creature::Respawn(bool force) if (getDeathState() == DEAD) { - if (m_DBTableGuid) - GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid); + if (m_spawnId) + GetMap()->RemoveCreatureRespawnTime(m_spawnId); TC_LOG_DEBUG("entities.unit", "Respawning creature %s (%s)", GetName().c_str(), GetGUID().ToString().c_str()); @@ -1602,9 +1602,9 @@ void Creature::Respawn(bool force) TriggerJustRespawned = true;//delay event to next tick so all creatures are created on the map before processing } - uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool<Creature>(GetDBTableGUIDLow()) : 0; + uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<Creature>(GetSpawnId()) : 0; if (poolid) - sPoolMgr->UpdatePool<Creature>(poolid, GetDBTableGUIDLow()); + sPoolMgr->UpdatePool<Creature>(poolid, GetSpawnId()); //Re-initialize reactstate that could be altered by movementgenerators InitializeReactState(); @@ -2018,10 +2018,10 @@ bool Creature::_IsTargetAcceptable(const Unit* target) const void Creature::SaveRespawnTime() { - if (IsSummon() || !m_DBTableGuid || (m_creatureData && !m_creatureData->dbData)) + if (IsSummon() || !m_spawnId || (m_creatureData && !m_creatureData->dbData)) return; - GetMap()->SaveCreatureRespawnTime(m_DBTableGuid, m_respawnTime); + GetMap()->SaveCreatureRespawnTime(m_spawnId, m_respawnTime); } // this should not be called by petAI or @@ -2053,9 +2053,9 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const CreatureAddon const* Creature::GetCreatureAddon() const { - if (m_DBTableGuid) + if (m_spawnId) { - if (CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(m_DBTableGuid)) + if (CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(m_spawnId)) return addon; } @@ -2132,7 +2132,7 @@ bool Creature::LoadCreaturesAddon(bool reload) if (HasAura(*itr)) { if (!reload) - TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD " Entry: %u) has duplicate aura (spell %u) in `auras` field.", GetDBTableGUIDLow(), GetEntry(), *itr); + TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD " Entry: %u) has duplicate aura (spell %u) in `auras` field.", GetSpawnId(), GetEntry(), *itr); continue; } @@ -2212,9 +2212,9 @@ time_t Creature::GetRespawnTimeEx() const void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, float* dist) const { - if (m_DBTableGuid) + if (m_spawnId) { - if (CreatureData const* data = sObjectMgr->GetCreatureData(GetDBTableGUIDLow())) + if (CreatureData const* data = sObjectMgr->GetCreatureData(GetSpawnId())) { x = data->posX; y = data->posY; diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index fe72b67b1fe..adab2ea38bb 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -477,7 +477,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void SelectLevel(); void LoadEquipment(int8 id = 1, bool force = false); - ObjectGuid::LowType GetDBTableGUIDLow() const { return m_DBTableGuid; } + ObjectGuid::LowType GetSpawnId() const { return m_spawnId; } void Update(uint32 time) override; // overwrited Unit::Update void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr, float* dist =nullptr) const; @@ -561,8 +561,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void setDeathState(DeathState s) override; // override virtual Unit::setDeathState - bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadCreatureFromDB(guid, map, false); } - bool LoadCreatureFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true); + bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map) { return LoadCreatureFromDB(spawnId, map, false); } + bool LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap = true); void SaveToDB(); // overriden in Pet virtual void SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask); @@ -720,7 +720,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void RegenerateHealth(); void Regenerate(Powers power); MovementGeneratorType m_defaultMovementType; - ObjectGuid::LowType m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid + ObjectGuid::LowType m_spawnId; ///< For new or temporary creatures is 0 for saved it is lowguid uint8 m_equipmentId; int8 m_originalEquipmentId; // can be -1 diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index 086b307c1c2..00e11ca9ef7 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -56,7 +56,7 @@ void FormationMgr::AddCreatureToGroup(ObjectGuid::LowType leaderGuid, Creature* void FormationMgr::RemoveCreatureFromGroup(CreatureGroup* group, Creature* member) { - TC_LOG_DEBUG("entities.unit", "Deleting member pointer to GUID: " UI64FMTD " from group " UI64FMTD, group->GetId(), member->GetDBTableGUIDLow()); + TC_LOG_DEBUG("entities.unit", "Deleting member pointer to GUID: " UI64FMTD " from group " UI64FMTD, group->GetId(), member->GetSpawnId()); group->RemoveMember(member); if (group->isEmpty()) @@ -145,13 +145,13 @@ void CreatureGroup::AddMember(Creature* member) TC_LOG_DEBUG("entities.unit", "CreatureGroup::AddMember: Adding %s.", member->GetGUID().ToString().c_str()); //Check if it is a leader - if (member->GetDBTableGUIDLow() == m_groupID) + if (member->GetSpawnId() == m_groupID) { TC_LOG_DEBUG("entities.unit", "%s is formation leader. Adding group.", member->GetGUID().ToString().c_str()); m_leader = member; } - m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetDBTableGUIDLow())->second; + m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetSpawnId())->second; member->SetFormation(this); } @@ -166,7 +166,7 @@ void CreatureGroup::RemoveMember(Creature* member) void CreatureGroup::MemberAttackStart(Creature* member, Unit* target) { - uint8 groupAI = sFormationMgr->CreatureGroupMap[member->GetDBTableGUIDLow()]->groupAI; + uint8 groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()]->groupAI; if (!groupAI) return; diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index 6792044cb34..5f2bd4915de 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -54,7 +54,7 @@ void DynamicObject::AddToWorld() ///- Register the dynamicObject for guid lookup and for caster if (!IsInWorld()) { - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<DynamicObject>(GetGUID(), this); WorldObject::AddToWorld(); BindToCaster(); } @@ -77,7 +77,7 @@ void DynamicObject::RemoveFromWorld() UnbindFromCaster(); WorldObject::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + GetMap()->GetObjectsStore().Remove<DynamicObject>(GetGUID()); } } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index b8bd9c35f35..852269855df 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -57,7 +57,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_goInfo = NULL; m_goData = NULL; - m_DBTableGuid = UI64LIT(0); + m_spawnId = UI64LIT(0); m_rotation = 0; m_groupLootTimer = 0; @@ -131,7 +131,9 @@ void GameObject::AddToWorld() if (m_zoneScript) m_zoneScript->OnGameObjectCreate(this); - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<GameObject>(GetGUID(), this); + if (m_spawnId) + GetMap()->GetGameObjectBySpawnIdStore().insert(std::make_pair(m_spawnId, this)); // The state can be changed after GameObject::Create but before GameObject::AddToWorld bool toggledState = GetGoType() == GAMEOBJECT_TYPE_CHEST ? getLootState() == GO_READY : (GetGoState() == GO_STATE_READY || IsTransport()); @@ -160,8 +162,12 @@ void GameObject::RemoveFromWorld() if (m_model) if (GetMap()->ContainsGameObjectModel(*m_model)) GetMap()->RemoveGameObjectModel(*m_model); + WorldObject::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + + if (m_spawnId) + Trinity::Containers::MultimapErasePair(GetMap()->GetGameObjectBySpawnIdStore(), m_spawnId, this); + GetMap()->GetObjectsStore().Remove<GameObject>(GetGUID()); } } @@ -433,7 +439,7 @@ void GameObject::Update(uint32 diff) time_t now = time(NULL); if (m_respawnTime <= now) // timer expired { - ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::GameObject>(GetMapId(), GetEntry(), m_DBTableGuid); + ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::GameObject>(GetMapId(), GetEntry(), m_spawnId); time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid); if (linkedRespawntime) // Can't respawn, the master is dead { @@ -489,9 +495,9 @@ void GameObject::Update(uint32 diff) } // Respawn timer - uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool<GameObject>(GetDBTableGUIDLow()) : 0; + uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<GameObject>(GetSpawnId()) : 0; if (poolid) - sPoolMgr->UpdatePool<GameObject>(poolid, GetDBTableGUIDLow()); + sPoolMgr->UpdatePool<GameObject>(poolid, GetSpawnId()); else GetMap()->AddToMap(this); } @@ -730,9 +736,9 @@ void GameObject::Delete() SetGoState(GO_STATE_READY); SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); - uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool<GameObject>(GetDBTableGUIDLow()) : 0; + uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<GameObject>(GetSpawnId()) : 0; if (poolid) - sPoolMgr->UpdatePool<GameObject>(poolid, GetDBTableGUIDLow()); + sPoolMgr->UpdatePool<GameObject>(poolid, GetSpawnId()); else AddObjectToRemoveList(); } @@ -781,7 +787,7 @@ void GameObject::SaveToDB() { // this should only be used when the gameobject has already been loaded // preferably after adding to map, because mapid may not be valid otherwise - GameObjectData const* data = sObjectMgr->GetGOData(m_DBTableGuid); + GameObjectData const* data = sObjectMgr->GetGOData(m_spawnId); if (!data) { TC_LOG_ERROR("misc", "GameObject::SaveToDB failed, cannot get gameobject data!"); @@ -798,11 +804,11 @@ void GameObject::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask) if (!goI) return; - if (!m_DBTableGuid) - m_DBTableGuid = GetGUID().GetCounter(); + if (!m_spawnId) + m_spawnId = sObjectMgr->GenerateGameObjectSpawnId(); // update in loaded data (changing data only in this place) - GameObjectData& data = sObjectMgr->NewGOData(m_DBTableGuid); + GameObjectData& data = sObjectMgr->NewGOData(m_spawnId); // data->guid = guid must not be updated at save data.id = GetEntry(); @@ -828,11 +834,11 @@ void GameObject::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask) uint8 index = 0; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT); - stmt->setUInt64(0, m_DBTableGuid); + stmt->setUInt64(0, m_spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_GAMEOBJECT); - stmt->setUInt64(index++, m_DBTableGuid); + stmt->setUInt64(index++, m_spawnId); stmt->setUInt32(index++, GetEntry()); stmt->setUInt16(index++, uint16(mapid)); stmt->setUInt8(index++, spawnMask); @@ -852,13 +858,12 @@ void GameObject::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask) WorldDatabase.CommitTransaction(trans); } -bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap) +bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap) { - GameObjectData const* data = sObjectMgr->GetGOData(guid); - + GameObjectData const* data = sObjectMgr->GetGOData(spawnId); if (!data) { - TC_LOG_ERROR("sql.sql", "Gameobject (GUID: " UI64FMTD ") not found in table `gameobject`, can't load. ", guid); + TC_LOG_ERROR("sql.sql", "Gameobject (GUID: " UI64FMTD ") not found in table `gameobject`, can't load. ", spawnId); return false; } @@ -879,11 +884,8 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool a GOState go_state = data->go_state; uint32 artKit = data->artKit; - m_DBTableGuid = guid; - if (map->GetInstanceId() != 0) - guid = sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(); - - if (!Create(guid, entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit)) + m_spawnId = spawnId; + if (!Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit)) return false; if (data->phaseid) @@ -909,13 +911,13 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool a else { m_respawnDelayTime = data->spawntimesecs; - m_respawnTime = GetMap()->GetGORespawnTime(m_DBTableGuid); + m_respawnTime = GetMap()->GetGORespawnTime(m_spawnId); // ready to respawn if (m_respawnTime && m_respawnTime <= time(NULL)) { m_respawnTime = 0; - GetMap()->RemoveGORespawnTime(m_DBTableGuid); + GetMap()->RemoveGORespawnTime(m_spawnId); } } } @@ -936,18 +938,18 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool a void GameObject::DeleteFromDB() { - GetMap()->RemoveGORespawnTime(m_DBTableGuid); - sObjectMgr->DeleteGOData(m_DBTableGuid); + GetMap()->RemoveGORespawnTime(m_spawnId); + sObjectMgr->DeleteGOData(m_spawnId); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT); - stmt->setUInt64(0, m_DBTableGuid); + stmt->setUInt64(0, m_spawnId); WorldDatabase.Execute(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_EVENT_GAMEOBJECT); - stmt->setUInt64(0, m_DBTableGuid); + stmt->setUInt64(0, m_spawnId); WorldDatabase.Execute(stmt); } @@ -1015,7 +1017,7 @@ Unit* GameObject::GetOwner() const void GameObject::SaveRespawnTime() { if (m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault) - GetMap()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime); + GetMap()->SaveGORespawnTime(m_spawnId, m_respawnTime); } bool GameObject::IsNeverVisible() const @@ -1072,7 +1074,7 @@ void GameObject::Respawn() if (m_spawnedByDefault && m_respawnTime > 0) { m_respawnTime = time(NULL); - GetMap()->RemoveGORespawnTime(m_DBTableGuid); + GetMap()->RemoveGORespawnTime(m_spawnId); } } @@ -1197,7 +1199,7 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = f void GameObject::SetGoArtKit(uint8 kit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, kit); - GameObjectData* data = const_cast<GameObjectData*>(sObjectMgr->GetGOData(m_DBTableGuid)); + GameObjectData* data = const_cast<GameObjectData*>(sObjectMgr->GetGOData(m_spawnId)); if (data) data->artKit = kit; } @@ -1390,7 +1392,7 @@ void GameObject::Use(Unit* user) if (info->goober.eventID) { - TC_LOG_DEBUG("maps.script", "Goober ScriptStart id %u for GO entry %u (GUID " UI64FMTD ").", info->goober.eventID, GetEntry(), GetDBTableGUIDLow()); + TC_LOG_DEBUG("maps.script", "Goober ScriptStart id %u for GO entry %u (GUID " UI64FMTD ").", info->goober.eventID, GetEntry(), GetSpawnId()); GetMap()->ScriptsStart(sEventScripts, info->goober.eventID, player, this); EventInform(info->goober.eventID, user); } @@ -2373,9 +2375,9 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /* = NULL*/) const { - if (m_DBTableGuid) + if (m_spawnId) { - if (GameObjectData const* data = sObjectMgr->GetGOData(GetDBTableGUIDLow())) + if (GameObjectData const* data = sObjectMgr->GetGOData(GetSpawnId())) { x = data->posX; y = data->posY; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index f254936608f..ee429c95475 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -887,7 +887,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map bool IsDynTransport() const; bool IsDestructibleBuilding() const; - ObjectGuid::LowType GetDBTableGUIDLow() const { return m_DBTableGuid; } + ObjectGuid::LowType GetSpawnId() const { return m_spawnId; } void UpdateRotationFields(float rotation2 = 0.0f, float rotation3 = 0.0f); @@ -896,8 +896,8 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map void SaveToDB(); void SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask); - bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); } - bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true); + bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map) { return LoadGameObjectFromDB(spawnId, map, false); } + bool LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap = true); void DeleteFromDB(); void SetOwnerGUID(ObjectGuid owner) @@ -1090,7 +1090,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map typedef std::map<uint32, ObjectGuid> ChairSlotAndUser; ChairSlotAndUser ChairListSlots; - ObjectGuid::LowType m_DBTableGuid; ///< For new or temporary gameobjects is 0 for saved it is lowguid + ObjectGuid::LowType m_spawnId; ///< For new or temporary gameobjects is 0 for saved it is lowguid GameObjectTemplate const* m_goInfo; GameObjectData const* m_goData; GameObjectValue m_goValue; diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 5d6be5e8c2a..50994df7831 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1050,7 +1050,7 @@ Item* Item::CreateItem(uint32 itemEntry, uint32 count, Player const* player) ASSERT(count != 0, "proto->Stackable == 0 but checked at loading already"); Item* item = NewItemOrBag(proto); - if (item->Create(sObjectMgr->GetGenerator<HighGuid::Item>()->Generate(), itemEntry, player)) + if (item->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), itemEntry, player)) { item->SetCount(count); return item; @@ -1168,6 +1168,18 @@ void Item::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player* data->append(fieldBuffer); } +void Item::AddToObjectUpdate() +{ + if (Player* owner = GetOwner()) + owner->GetMap()->AddUpdateObject(this); +} + +void Item::RemoveFromObjectUpdate() +{ + if (Player* owner = GetOwner()) + owner->GetMap()->RemoveUpdateObject(this); +} + void Item::SaveRefundDataToDB() { SQLTransaction trans = CharacterDatabase.BeginTransaction(); diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index ffd4872a2e8..c204cbb1f17 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -406,6 +406,8 @@ class Item : public Object void BuildUpdate(UpdateDataMapType&) override; void BuildDynamicValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; + void AddToObjectUpdate() override; + void RemoveFromObjectUpdate() override; uint32 GetScriptId() const { return GetTemplate()->ScriptId; } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index a4a2b965f3e..68650bdff59 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -95,14 +95,12 @@ Object::~Object() if (isType(TYPEMASK_ITEM)) TC_LOG_FATAL("misc", "Item slot %u", ((Item*)this)->GetSlot()); ASSERT(false); - RemoveFromWorld(); } if (m_objectUpdated) { TC_LOG_FATAL("misc", "Object::~Object %s deleted but still in update list!!", GetGUID().ToString().c_str()); ASSERT(false); - sObjectAccessor->RemoveUpdateObject(this); } delete[] m_uint32Values; @@ -159,7 +157,8 @@ void Object::AddToWorld() m_inWorld = true; // synchronize values mirror with values array (changes will send in updatecreate opcode any way - ClearUpdateMask(true); + ASSERT(!m_objectUpdated); + ClearUpdateMask(false); } void Object::RemoveFromWorld() @@ -822,6 +821,15 @@ void Object::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player data->append(fieldBuffer); } +void Object::AddToObjectUpdateIfNeeded() +{ + if (m_inWorld && !m_objectUpdated) + { + AddToObjectUpdate(); + m_objectUpdated = true; + } +} + void Object::ClearUpdateMask(bool remove) { _changesMask.Clear(); @@ -832,7 +840,7 @@ void Object::ClearUpdateMask(bool remove) if (m_objectUpdated) { if (remove) - sObjectAccessor->RemoveUpdateObject(this); + RemoveFromObjectUpdate(); m_objectUpdated = false; } } @@ -982,11 +990,7 @@ void Object::SetInt32Value(uint16 index, int32 value) m_int32Values[index] = value; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -999,11 +1003,7 @@ void Object::SetUInt32Value(uint16 index, uint32 value) m_uint32Values[index] = value; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1025,11 +1025,7 @@ void Object::SetUInt64Value(uint16 index, uint64 value) _changesMask.SetBit(index); _changesMask.SetBit(index + 1); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1044,12 +1040,7 @@ bool Object::AddGuidValue(uint16 index, ObjectGuid const& value) _changesMask.SetBit(index + 2); _changesMask.SetBit(index + 3); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } - + AddToObjectUpdateIfNeeded(); return true; } @@ -1067,12 +1058,7 @@ bool Object::RemoveGuidValue(uint16 index, ObjectGuid const& value) _changesMask.SetBit(index + 2); _changesMask.SetBit(index + 3); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } - + AddToObjectUpdateIfNeeded(); return true; } @@ -1088,11 +1074,7 @@ void Object::SetFloatValue(uint16 index, float value) m_floatValues[index] = value; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1112,11 +1094,7 @@ void Object::SetByteValue(uint16 index, uint8 offset, uint8 value) m_uint32Values[index] |= uint32(uint32(value) << (offset * 8)); _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1136,11 +1114,7 @@ void Object::SetUInt16Value(uint16 index, uint8 offset, uint16 value) m_uint32Values[index] |= uint32(uint32(value) << (offset * 16)); _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1155,11 +1129,7 @@ void Object::SetGuidValue(uint16 index, ObjectGuid const& value) _changesMask.SetBit(index + 2); _changesMask.SetBit(index + 3); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1238,11 +1208,7 @@ void Object::SetFlag(uint16 index, uint32 newFlag) m_uint32Values[index] = newval; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1259,11 +1225,7 @@ void Object::RemoveFlag(uint16 index, uint32 oldFlag) m_uint32Values[index] = newval; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1303,11 +1265,7 @@ void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag) m_uint32Values[index] |= uint32(uint32(newFlag) << (offset * 8)); _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1326,11 +1284,7 @@ void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag) m_uint32Values[index] &= ~uint32(uint32(oldFlag) << (offset * 8)); _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1405,11 +1359,7 @@ void Object::AddDynamicValue(uint16 index, uint32 value) mask.SetBit(values.size() - 1); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } void Object::RemoveDynamicValue(uint16 index, uint32 /*value*/) @@ -1428,11 +1378,7 @@ void Object::ClearDynamicValue(uint16 index) _dynamicChangesMask.SetBit(index); _dynamicChangesArrayMask[index].SetCount(0); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1450,11 +1396,7 @@ void Object::SetDynamicValue(uint16 index, uint8 offset, uint32 value) _dynamicChangesMask.SetBit(index); _dynamicChangesArrayMask[index].SetBit(offset); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -2334,11 +2276,7 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj) const void Object::ForceValuesUpdateAtIndex(uint32 i) { _changesMask.SetBit(i); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } void WorldObject::SendMessageToSet(WorldPacket const* data, bool self) @@ -2486,7 +2424,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert break; } - if (!summon->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), this, 0, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) + if (!summon->Create(GenerateLowGuid<HighGuid::Creature>(), this, 0, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) { delete summon; return NULL; @@ -2583,7 +2521,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float Map* map = GetMap(); GameObject* go = new GameObject(); - if (!go->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), entry, map, GetPhaseMask(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY)) + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, GetPhaseMask(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY)) { delete go; return NULL; @@ -3292,6 +3230,16 @@ void WorldObject::BuildUpdate(UpdateDataMapType& data_map) ClearUpdateMask(false); } +void WorldObject::AddToObjectUpdate() +{ + GetMap()->AddUpdateObject(this); +} + +void WorldObject::RemoveFromObjectUpdate() +{ + GetMap()->RemoveUpdateObject(this); +} + ObjectGuid WorldObject::GetTransGUID() const { if (GetTransport()) diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index ab0c6f0da70..04d5f306076 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -246,6 +246,10 @@ class Object uint16 _fieldNotifyFlags; + virtual void AddToObjectUpdate() = 0; + virtual void RemoveFromObjectUpdate() = 0; + void AddToObjectUpdateIfNeeded(); + bool m_objectUpdated; private: @@ -730,6 +734,8 @@ class WorldObject : public Object, public WorldLocation void DestroyForNearbyPlayers(); virtual void UpdateObjectVisibility(bool forced = true); void BuildUpdate(UpdateDataMapType&) override; + void AddToObjectUpdate() override; + void RemoveFromObjectUpdate() override; //relocation and visibility system functions void AddToNotify(uint16 f) { m_notifyflags |= f;} diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index 1f9ca9736a2..4d607e59d1b 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -90,6 +90,22 @@ std::string ObjectGuid::ToString() const return str.str(); } +ObjectGuid ObjectGuid::Global(HighGuid type, LowType counter) +{ + return ObjectGuid(uint64(uint64(type) << 58), counter); +} + +ObjectGuid ObjectGuid::RealmSpecific(HighGuid type, LowType counter) +{ + return ObjectGuid(uint64(uint64(type) << 58 | uint64(realmHandle.Index) << 42), counter); +} + +ObjectGuid ObjectGuid::MapSpecific(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, LowType counter) +{ + return ObjectGuid(uint64((uint64(type) << 58) | (uint64(realmHandle.Index & 0x1FFF) << 42) | (uint64(mapId & 0x1FFF) << 29) | (uint64(entry & 0x7FFFFF) << 6) | (uint64(subType) & 0x3F)), + uint64((uint64(serverId & 0xFFFFFF) << 40) | (counter & UI64LIT(0xFFFFFFFFFF)))); +} + std::vector<uint8> ObjectGuid::GetRawValue() const { std::vector<uint8> raw(16); @@ -121,17 +137,6 @@ void PackedGuid::Set(ObjectGuid const& guid) _packedGuid.put(1, highMask); } -template<HighGuid high> -ObjectGuid::LowType ObjectGuidGenerator<high>::Generate() -{ - if (_nextGuid >= ObjectGuid::GetMaxCounter(high) - 1) - { - TC_LOG_ERROR("", "%s guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high)); - World::StopNow(ERROR_EXIT_CODE); - } - return _nextGuid++; -} - ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid) { buf << guid.WriteAsPacked(); @@ -167,89 +172,11 @@ std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid) return stream; } -class GuidFormat -{ -public: - inline static ObjectGuid Global(HighGuid type, ObjectGuid::LowType counter) - { - return ObjectGuid(uint64(uint64(type) << 58), counter); - } - - inline static ObjectGuid RealmSpecific(HighGuid type, ObjectGuid::LowType counter) - { - return ObjectGuid(uint64(uint64(type) << 58 | uint64(realmHandle.Index) << 42), counter); - } - - inline static ObjectGuid MapSpecific(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, ObjectGuid::LowType counter) - { - return ObjectGuid(uint64((uint64(type) << 58) | (uint64(realmHandle.Index & 0x1FFF) << 42) | (uint64(mapId & 0x1FFF) << 29) | (uint64(entry & 0x7FFFFF) << 6) | (uint64(subType) & 0x3F)), - uint64((uint64(serverId & 0xFFFFFF) << 40) | (counter & UI64LIT(0xFFFFFFFFFF)))); - } -}; - -#define GLOBAL_GUID_CREATE(highguid) template<> ObjectGuid ObjectGuid::Create<highguid>(LowType counter) { return GuidFormat::Global(highguid, counter); } -#define REALM_GUID_CREATE(highguid) template<> ObjectGuid ObjectGuid::Create<highguid>(LowType counter) { return GuidFormat::RealmSpecific(highguid, counter); } -#define MAP_GUID_CREATE(highguid) template<> ObjectGuid ObjectGuid::Create<highguid>(uint16 mapId, uint32 entry, LowType counter) { return GuidFormat::MapSpecific(highguid, 0, mapId, 0, entry, counter); } - -GLOBAL_GUID_CREATE(HighGuid::Uniq) -GLOBAL_GUID_CREATE(HighGuid::Party) -GLOBAL_GUID_CREATE(HighGuid::WowAccount) -GLOBAL_GUID_CREATE(HighGuid::BNetAccount) -GLOBAL_GUID_CREATE(HighGuid::GMTask) -GLOBAL_GUID_CREATE(HighGuid::RaidGroup) -GLOBAL_GUID_CREATE(HighGuid::Spell) -GLOBAL_GUID_CREATE(HighGuid::Mail) -GLOBAL_GUID_CREATE(HighGuid::UserRouter) -GLOBAL_GUID_CREATE(HighGuid::PVPQueueGroup) -GLOBAL_GUID_CREATE(HighGuid::UserClient) -GLOBAL_GUID_CREATE(HighGuid::UniqueUserClient) -GLOBAL_GUID_CREATE(HighGuid::BattlePet) -REALM_GUID_CREATE(HighGuid::Player) -REALM_GUID_CREATE(HighGuid::Item) // This is not exactly correct, there are 2 more unknown parts in highguid: (high >> 10 & 0xFF), (high >> 18 & 0xFFFFFF) -REALM_GUID_CREATE(HighGuid::Transport) -REALM_GUID_CREATE(HighGuid::Guild) -MAP_GUID_CREATE(HighGuid::Conversation) -MAP_GUID_CREATE(HighGuid::Creature) -MAP_GUID_CREATE(HighGuid::Vehicle) -MAP_GUID_CREATE(HighGuid::Pet) -MAP_GUID_CREATE(HighGuid::GameObject) -MAP_GUID_CREATE(HighGuid::DynamicObject) -MAP_GUID_CREATE(HighGuid::AreaTrigger) -MAP_GUID_CREATE(HighGuid::Corpse) -MAP_GUID_CREATE(HighGuid::LootObject) -MAP_GUID_CREATE(HighGuid::SceneObject) -MAP_GUID_CREATE(HighGuid::Scenario) -MAP_GUID_CREATE(HighGuid::AIGroup) -MAP_GUID_CREATE(HighGuid::DynamicDoor) -MAP_GUID_CREATE(HighGuid::Vignette) -MAP_GUID_CREATE(HighGuid::CallForHelp) -MAP_GUID_CREATE(HighGuid::AIResource) -MAP_GUID_CREATE(HighGuid::AILock) -MAP_GUID_CREATE(HighGuid::AILockTicket) - ObjectGuid const ObjectGuid::Empty = ObjectGuid(); ObjectGuid const ObjectGuid::TradeItem = ObjectGuid::Create<HighGuid::Uniq>(uint64(10)); -template<HighGuid type> -ObjectGuid ObjectGuid::Create(LowType /*counter*/) +void ObjectGuidGeneratorBase::HandleCounterOverflow(HighGuid high) { - static_assert(type == HighGuid::Count, "This guid type cannot be constructed using Create(LowType counter)."); + TC_LOG_ERROR("misc", "%s guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high)); + World::StopNow(ERROR_EXIT_CODE); } - -template<HighGuid type> -ObjectGuid ObjectGuid::Create(uint16 /*mapId*/, uint32 /*entry*/, LowType /*counter*/) -{ - static_assert(type == HighGuid::Count, "This guid type cannot be constructed using Create(uint16 mapId, uint32 entry, LowType counter)."); -} - -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::Player>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::Creature>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::Pet>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::Vehicle>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::Item>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::GameObject>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::DynamicObject>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::Corpse>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::LootObject>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::AreaTrigger>::Generate(); -template ObjectGuid::LowType ObjectGuidGenerator<HighGuid::Transport>::Generate(); diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index 72fda2feb5e..281bc170c3a 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -22,7 +22,7 @@ #include "Common.h" #include "ByteBuffer.h" #include <boost/functional/hash.hpp> - +#include <type_traits> #include <functional> #include <unordered_set> @@ -109,9 +109,76 @@ enum class HighGuid Count, }; +template<HighGuid high> +struct ObjectGuidTraits +{ + static bool const Global = false; + static bool const RealmSpecific = false; + static bool const MapSpecific = false; +}; + +#define GUID_TRAIT_GLOBAL(highguid) \ + template<> struct ObjectGuidTraits<highguid> \ + { \ + static bool const Global = true; \ + static bool const RealmSpecific = false; \ + static bool const MapSpecific = false; \ + }; + +#define GUID_TRAIT_REALM_SPECIFIC(highguid) \ + template<> struct ObjectGuidTraits<highguid> \ + { \ + static bool const Global = false; \ + static bool const RealmSpecific = true; \ + static bool const MapSpecific = false; \ + }; + +#define GUID_TRAIT_MAP_SPECIFIC(highguid) \ + template<> struct ObjectGuidTraits<highguid> \ + { \ + static bool const Global = false; \ + static bool const RealmSpecific = false; \ + static bool const MapSpecific = true; \ + }; + +GUID_TRAIT_GLOBAL(HighGuid::Uniq) +GUID_TRAIT_GLOBAL(HighGuid::Party) +GUID_TRAIT_GLOBAL(HighGuid::WowAccount) +GUID_TRAIT_GLOBAL(HighGuid::BNetAccount) +GUID_TRAIT_GLOBAL(HighGuid::GMTask) +GUID_TRAIT_GLOBAL(HighGuid::RaidGroup) +GUID_TRAIT_GLOBAL(HighGuid::Spell) +GUID_TRAIT_GLOBAL(HighGuid::Mail) +GUID_TRAIT_GLOBAL(HighGuid::UserRouter) +GUID_TRAIT_GLOBAL(HighGuid::PVPQueueGroup) +GUID_TRAIT_GLOBAL(HighGuid::UserClient) +GUID_TRAIT_GLOBAL(HighGuid::UniqueUserClient) +GUID_TRAIT_GLOBAL(HighGuid::BattlePet) +GUID_TRAIT_REALM_SPECIFIC(HighGuid::Player) +GUID_TRAIT_REALM_SPECIFIC(HighGuid::Item) // This is not exactly correct, there are 2 more unknown parts in highguid: (high >> 10 & 0xFF), (high >> 18 & 0xFFFFFF) +GUID_TRAIT_REALM_SPECIFIC(HighGuid::Transport) +GUID_TRAIT_REALM_SPECIFIC(HighGuid::Guild) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Conversation) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Creature) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Vehicle) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Pet) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::GameObject) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::DynamicObject) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::AreaTrigger) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Corpse) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::LootObject) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::SceneObject) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Scenario) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::AIGroup) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::DynamicDoor) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Vignette) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::CallForHelp) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::AIResource) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::AILock) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::AILockTicket) + class ObjectGuid; class PackedGuid; -class GuidFormat; struct PackedGuidReader { @@ -126,7 +193,6 @@ class ObjectGuid friend std::ostream& operator<<(std::ostream& stream, ObjectGuid const& guid); friend ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid); friend class PackedGuid; - friend class GuidFormat; public: static ObjectGuid const Empty; @@ -135,10 +201,13 @@ class ObjectGuid typedef uint64 LowType; template<HighGuid type> - static ObjectGuid Create(LowType counter); + static typename std::enable_if<ObjectGuidTraits<type>::Global, ObjectGuid>::type Create(LowType counter) { return Global(type, counter); } template<HighGuid type> - static ObjectGuid Create(uint16 mapId, uint32 entry, LowType counter); + static typename std::enable_if<ObjectGuidTraits<type>::RealmSpecific, ObjectGuid>::type Create(LowType counter) { return RealmSpecific(type, counter); } + + template<HighGuid type> + static typename std::enable_if<ObjectGuidTraits<type>::MapSpecific, ObjectGuid>::type Create(uint16 mapId, uint32 entry, LowType counter) { return MapSpecific(type, 0, mapId, 0, entry, counter); } ObjectGuid() : _low(0), _high(0) { } ObjectGuid(ObjectGuid const&) = default; @@ -253,6 +322,10 @@ class ObjectGuid bool HasEntry() const { return HasEntry(GetHigh()); } + static ObjectGuid Global(HighGuid type, LowType counter); + static ObjectGuid RealmSpecific(HighGuid type, LowType counter); + static ObjectGuid MapSpecific(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, LowType counter); + ObjectGuid(uint64 high, uint64 low) : _low(low), _high(high) { } explicit ObjectGuid(uint32 const&) = delete; // no implementation, used to catch wrong type assignment @@ -288,18 +361,32 @@ class PackedGuid ByteBuffer _packedGuid; }; -template<HighGuid high> -class ObjectGuidGenerator +class ObjectGuidGeneratorBase { - public: - explicit ObjectGuidGenerator(ObjectGuid::LowType start = UI64LIT(1)) : _nextGuid(start) { } +public: + ObjectGuidGeneratorBase(ObjectGuid::LowType start = UI64LIT(1)) : _nextGuid(start) { } - void Set(uint64 val) { _nextGuid = val; } - ObjectGuid::LowType Generate(); - ObjectGuid::LowType GetNextAfterMaxUsed() const { return _nextGuid; } + virtual void Set(uint64 val) { _nextGuid = val; } + virtual ObjectGuid::LowType Generate() = 0; + ObjectGuid::LowType GetNextAfterMaxUsed() const { return _nextGuid; } - private: - uint64 _nextGuid; +protected: + static void HandleCounterOverflow(HighGuid high); + uint64 _nextGuid; +}; + +template<HighGuid high> +class ObjectGuidGenerator : public ObjectGuidGeneratorBase +{ +public: + explicit ObjectGuidGenerator(ObjectGuid::LowType start = UI64LIT(1)) : ObjectGuidGeneratorBase(start) { } + + ObjectGuid::LowType Generate() override + { + if (_nextGuid >= ObjectGuid::GetMaxCounter(high) - 1) + HandleCounterOverflow(high); + return _nextGuid++; + } }; ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index dbb8c99d7c9..f91986ddbfd 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -69,7 +69,7 @@ void Pet::AddToWorld() if (!IsInWorld()) { ///- Register the pet for guid lookup - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<Pet>(GetGUID(), this); Unit::AddToWorld(); AIM_Initialize(); } @@ -93,7 +93,7 @@ void Pet::RemoveFromWorld() { ///- Don't call the function for Creature, normal mobs + totems go in a different storage Unit::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + GetMap()->GetObjectsStore().Remove<Pet>(GetGUID()); } } @@ -177,7 +177,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c } Map* map = owner->GetMap(); - if (!Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, petEntry)) + if (!Create(map->GenerateLowGuid<HighGuid::Pet>(), map, petEntry)) return false; CopyPhaseFrom(owner); @@ -778,7 +778,7 @@ bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner) bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map) { TC_LOG_DEBUG("entities.pet", "Pet::CreateBaseForTamed"); - if (!Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, cinfo->Entry)) + if (!Create(map->GenerateLowGuid<HighGuid::Pet>(), map, cinfo->Entry)) return false; setPowerType(POWER_FOCUS); @@ -1808,7 +1808,7 @@ bool Pet::Create(ObjectGuid::LowType guidlow, Map* map, uint32 Entry) Object::_Create(ObjectGuid::Create<HighGuid::Pet>(map->GetId(), Entry, guidlow)); - m_DBTableGuid = guidlow; + m_spawnId = guidlow; m_originalEntry = Entry; if (!InitEntry(Entry)) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 81e0cbd2e66..d7e48947600 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4560,6 +4560,14 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe stmt->setUInt64(0, guid); trans->Append(stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE); + stmt->setUInt64(0, guid); + trans->Append(stmt); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE_PHASES); + stmt->setUInt64(0, guid); + trans->Append(stmt); + CharacterDatabase.CommitTransaction(trans); sWorld->DeleteCharacterInfo(playerguid); @@ -4805,7 +4813,7 @@ void Player::CreateCorpse() Corpse* corpse = new Corpse((m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE); SetPvPDeath(false); - if (!corpse->Create(sObjectMgr->GetGenerator<HighGuid::Corpse>()->Generate(), this)) + if (!corpse->Create(GetMap()->GenerateLowGuid<HighGuid::Corpse>(), this)) { delete corpse; return; @@ -13699,7 +13707,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool VendorItemData const* vendorItems = creature->GetVendorItems(); if (!vendorItems || vendorItems->Empty()) { - TC_LOG_ERROR("sql.sql", "Creature %s (%s DB GUID: " UI64FMTD ") has UNIT_NPC_FLAG_VENDOR set but has an empty trading item list.", creature->GetName().c_str(), creature->GetGUID().ToString().c_str(), creature->GetDBTableGUIDLow()); + TC_LOG_ERROR("sql.sql", "Creature %s (%s DB GUID: " UI64FMTD ") has UNIT_NPC_FLAG_VENDOR set but has an empty trading item list.", creature->GetName().c_str(), creature->GetGUID().ToString().c_str(), creature->GetSpawnId()); canTalk = false; } break; @@ -13888,7 +13896,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men break; } case GOSSIP_OPTION_OUTDOORPVP: - sOutdoorPvPMgr->HandleGossipOption(this, source->GetGUID(), gossipListId); + sOutdoorPvPMgr->HandleGossipOption(this, source->ToCreature(), gossipListId); break; case GOSSIP_OPTION_SPIRITHEALER: if (isDead()) @@ -16840,8 +16848,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) ObjectGuid transGUID = ObjectGuid::Create<HighGuid::Transport>(transLowGUID); Transport* transport = NULL; - if (GameObject* go = HashMapHolder<GameObject>::Find(transGUID)) - transport = go->ToTransport(); + if (Transport* go = HashMapHolder<Transport>::Find(transGUID)) + transport = go; if (transport) { @@ -23333,7 +23341,7 @@ void Player::UpdateForQuestWorldObjects() { if (itr->IsGameObject()) { - if (GameObject* obj = HashMapHolder<GameObject>::Find(*itr)) + if (GameObject* obj = ObjectAccessor::GetGameObject(*this, *itr)) obj->BuildValuesUpdateBlockForPlayer(&udata, this); } else if (itr->IsCreatureOrVehicle()) @@ -26280,8 +26288,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy Map* map = GetMap(); uint32 pet_number = sObjectMgr->GeneratePetNumber(); - - if (!pet->Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, entry)) + if (!pet->Create(map->GenerateLowGuid<HighGuid::Pet>(), map, entry)) { TC_LOG_ERROR("misc", "no such creature entry %u", entry); delete pet; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 454a9317c8e..81497029e55 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -104,6 +104,7 @@ bool Transport::Create(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, void Transport::CleanupsBeforeDelete(bool finalCleanup /*= true*/) { + HashMapHolder<Transport>::Remove(this); UnloadStaticPassengers(); while (!_passengers.empty()) { @@ -456,7 +457,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu pos.GetPosition(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); - if (!summon->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), map, 0, entry, x, y, z, o, nullptr, vehId)) + if (!summon->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, 0, entry, x, y, z, o, nullptr, vehId)) { delete summon; return NULL; diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 89356307b2f..c2f298beeb7 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -147,7 +147,7 @@ void Vehicle::Reset(bool evading /*= false*/) if (GetBase()->GetTypeId() != TYPEID_UNIT) return; - TC_LOG_DEBUG("entities.vehicle", "Vehicle::Reset (Entry: %u, %s, DBGuid: " UI64FMTD ")", GetCreatureEntry(), _me->GetGUID().ToString().c_str(), _me->ToCreature()->GetDBTableGUIDLow()); + TC_LOG_DEBUG("entities.vehicle", "Vehicle::Reset (Entry: %u, %s, DBGuid: " UI64FMTD ")", GetCreatureEntry(), _me->GetGUID().ToString().c_str(), _me->ToCreature()->GetSpawnId()); ApplyAllImmunities(); InstallAllAccessories(evading); @@ -407,7 +407,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) TC_LOG_DEBUG("entities.vehicle", "Unit %s scheduling enter vehicle (entry: %u, vehicleId: %u, %s (dbguid: " UI64FMTD ") on seat %d", unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->ID, _me->GetGUID().ToString().c_str(), - uint64(_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetDBTableGUIDLow() : UI64LIT(0)), (int32)seatId); + uint64(_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetSpawnId() : UI64LIT(0)), (int32)seatId); // The seat selection code may kick other passengers off the vehicle. // While the validity of the following may be arguable, it is possible that when such a passenger diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index efb38cf2777..00d6afdd6e4 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -919,7 +919,7 @@ void GameEventMgr::LoadFromDB() uint32 GameEventMgr::GetNPCFlag(Creature* cr) { uint32 mask = 0; - ObjectGuid::LowType guid = cr->GetDBTableGUIDLow(); + ObjectGuid::LowType guid = cr->GetSpawnId(); for (ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr) { @@ -1117,25 +1117,34 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id) void GameEventMgr::UpdateEventNPCFlags(uint16 event_id) { + std::unordered_map<uint32, std::unordered_set<ObjectGuid::LowType>> creaturesByMap; + // go through the creatures whose npcflags are changed in the event for (NPCFlagList::iterator itr = mGameEventNPCFlags[event_id].begin(); itr != mGameEventNPCFlags[event_id].end(); ++itr) - { // get the creature data from the low guid to get the entry, to be able to find out the whole guid if (CreatureData const* data = sObjectMgr->GetCreatureData(itr->first)) + creaturesByMap[data->mapid].insert(itr->first); + + for (auto const& p : creaturesByMap) + { + sMapMgr->DoForAllMapsWithMapId(p.first, [this, &p](Map* map) { - Creature* cr = HashMapHolder<Creature>::Find(ObjectGuid::Create<HighGuid::Creature>(data->mapid, data->id, itr->first)); - // if we found the creature, modify its npcflag - if (cr) + for (auto& spawnId : p.second) { - uint32 npcflag = GetNPCFlag(cr); - if (const CreatureTemplate* ci = cr->GetCreatureTemplate()) - npcflag |= ci->npcflag; - cr->SetUInt32Value(UNIT_NPC_FLAGS, npcflag); - // reset gossip options, since the flag change might have added / removed some - //cr->ResetGossipOptions(); + auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(spawnId); + for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr) + { + Creature* creature = itr->second; + uint32 npcflag = GetNPCFlag(creature); + if (CreatureTemplate const* creatureTemplate = creature->GetCreatureTemplate()) + npcflag |= creatureTemplate->npcflag; + + creature->SetUInt32Value(UNIT_NPC_FLAGS, npcflag); + // reset gossip options, since the flag change might have added / removed some + //cr->ResetGossipOptions(); + } } - // if we didn't find it, then the npcflag will be updated when the creature is loaded - } + }); } } @@ -1254,8 +1263,12 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) { sObjectMgr->RemoveCreatureFromGrid(*itr, data); - if (Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid::Create<HighGuid::Creature>(data->mapid, data->id, *itr), (Creature*)NULL)) - creature->AddObjectToRemoveList(); + sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr](Map* map) + { + auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(*itr); + for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr) + itr->second->AddObjectToRemoveList(); + }); } } @@ -1276,8 +1289,12 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) { sObjectMgr->RemoveGameobjectFromGrid(*itr, data); - if (GameObject* pGameobject = ObjectAccessor::GetObjectInWorld(ObjectGuid::Create<HighGuid::GameObject>(data->mapid, data->id, *itr), (GameObject*)NULL)) - pGameobject->AddObjectToRemoveList(); + sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr](Map* map) + { + auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(*itr); + for (auto itr = gameobjectBounds.first; itr != gameobjectBounds.second; ++itr) + itr->second->AddObjectToRemoveList(); + }); } } if (internal_event_id < 0 || internal_event_id >= int32(mGameEventPoolIds.size())) @@ -1302,53 +1319,43 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate) continue; // Update if spawned - Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid::Create<HighGuid::Creature>(data->mapid, data->id, itr->first), (Creature*)NULL); - if (creature) + sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr, activate](Map* map) { - if (activate) + auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(itr->first); + for (auto itr2 = creatureBounds.first; itr2 != creatureBounds.second; ++itr2) { - itr->second.equipement_id_prev = creature->GetCurrentEquipmentId(); - itr->second.modelid_prev = creature->GetDisplayId(); - creature->LoadEquipment(itr->second.equipment_id, true); - if (itr->second.modelid > 0 && itr->second.modelid_prev != itr->second.modelid && - sObjectMgr->GetCreatureModelInfo(itr->second.modelid)) + Creature* creature = itr2->second; + if (activate) { - creature->SetDisplayId(itr->second.modelid); - creature->SetNativeDisplayId(itr->second.modelid); + itr->second.equipement_id_prev = creature->GetCurrentEquipmentId(); + itr->second.modelid_prev = creature->GetDisplayId(); + creature->LoadEquipment(itr->second.equipment_id, true); + if (itr->second.modelid > 0 && itr->second.modelid_prev != itr->second.modelid && + sObjectMgr->GetCreatureModelInfo(itr->second.modelid)) + { + creature->SetDisplayId(itr->second.modelid); + creature->SetNativeDisplayId(itr->second.modelid); + } } - } - else - { - creature->LoadEquipment(itr->second.equipement_id_prev, true); - if (itr->second.modelid_prev > 0 && itr->second.modelid_prev != itr->second.modelid && - sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev)) + else { - creature->SetDisplayId(itr->second.modelid_prev); - creature->SetNativeDisplayId(itr->second.modelid_prev); + creature->LoadEquipment(itr->second.equipement_id_prev, true); + if (itr->second.modelid_prev > 0 && itr->second.modelid_prev != itr->second.modelid && + sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev)) + { + creature->SetDisplayId(itr->second.modelid_prev); + creature->SetNativeDisplayId(itr->second.modelid_prev); + } } } - } - else // If not spawned - { - CreatureData const* data2 = sObjectMgr->GetCreatureData(itr->first); - if (data2 && activate) - { - CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(data2->id); - uint32 displayID = ObjectMgr::ChooseDisplayId(cinfo, data2); - sObjectMgr->GetCreatureModelRandomGender(&displayID); - - if (data2->equipmentId == 0) - itr->second.equipement_id_prev = 0; ///@todo: verify this line - else if (data2->equipmentId != -1) - itr->second.equipement_id_prev = data->equipmentId; - itr->second.modelid_prev = displayID; - } - } + }); + // now last step: put in data - // just to have write access to it CreatureData& data2 = sObjectMgr->NewOrExistCreatureData(itr->first); if (activate) { + itr->second.modelid_prev = data2.displayid; + itr->second.equipement_id_prev = data2.equipmentId; data2.displayid = itr->second.modelid; data2.equipmentId = itr->second.equipment_id; } @@ -1598,24 +1605,43 @@ void GameEventMgr::SendWorldStateUpdate(Player* player, uint16 event_id) } } -void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate) +class GameEventAIHookWorker { - //! Iterate over every supported source type (creature and gameobject) - //! Not entirely sure how this will affect units in non-loaded grids. +public: + GameEventAIHookWorker(uint16 eventId, bool activate) : _eventId(eventId), _activate(activate) { } + + void Visit(std::unordered_map<ObjectGuid, Creature*>& creatureMap) { - boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Creature>::GetLock()); - HashMapHolder<Creature>::MapType const& m = ObjectAccessor::GetCreatures(); - for (HashMapHolder<Creature>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter) - if (iter->second->IsInWorld()) - iter->second->AI()->sOnGameEvent(activate, event_id); + for (auto const& p : creatureMap) + if (p.second->IsInWorld() && p.second->IsAIEnabled) + p.second->AI()->sOnGameEvent(_activate, _eventId); } + + void Visit(std::unordered_map<ObjectGuid, GameObject*>& gameObjectMap) { - boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<GameObject>::GetLock()); - HashMapHolder<GameObject>::MapType const& m = ObjectAccessor::GetGameObjects(); - for (HashMapHolder<GameObject>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter) - if (iter->second->IsInWorld()) - iter->second->AI()->OnGameEvent(activate, event_id); + for (auto const& p : gameObjectMap) + if (p.second->IsInWorld()) + p.second->AI()->OnGameEvent(_activate, _eventId); } + + template<class T> + void Visit(std::unordered_map<ObjectGuid, T*>&) { } + +private: + uint16 _eventId; + bool _activate; +}; + +void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate) +{ + //! Iterate over every supported source type (creature and gameobject) + //! Not entirely sure how this will affect units in non-loaded grids. + sMapMgr->DoForAllMaps([event_id, activate](Map* map) + { + GameEventAIHookWorker worker(event_id, activate); + TypeContainerVisitor<GameEventAIHookWorker, MapStoredObjectTypesContainer> visitor(worker); + visitor.Visit(map->GetObjectsStore()); + }); } uint16 GameEventMgr::GetEventIdForQuest(Quest const* quest) const diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 44e7271ca70..474b608a846 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -36,6 +36,7 @@ #include "Opcodes.h" #include "Pet.h" #include "Player.h" +#include "Transport.h" #include "Vehicle.h" #include "World.h" #include "WorldPacket.h" @@ -46,42 +47,7 @@ ObjectAccessor::ObjectAccessor() { } ObjectAccessor::~ObjectAccessor() { } -template<class T> T* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, ObjectGuid guid, T* /*fake*/) -{ - T* obj = HashMapHolder<T>::Find(guid); - if (!obj || obj->GetMapId() != mapid) - return NULL; - - CellCoord p = Trinity::ComputeCellCoord(x, y); - if (!p.IsCoordValid()) - { - TC_LOG_ERROR("misc", "ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord); - return NULL; - } - - CellCoord q = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY()); - if (!q.IsCoordValid()) - { - TC_LOG_ERROR("misc", "ObjectAccessor::GetObjecInWorld: object (%s) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUID().ToString().c_str(), obj->GetPositionX(), obj->GetPositionY(), q.x_coord, q.y_coord); - return NULL; - } - - int32 dx = int32(p.x_coord) - int32(q.x_coord); - int32 dy = int32(p.y_coord) - int32(q.y_coord); - - if (dx > -2 && dx < 2 && dy > -2 && dy < 2) - return obj; - else - return NULL; -} - -Player* ObjectAccessor::GetObjectInWorld(ObjectGuid guid, Player* /*typeSpecifier*/) -{ - Player* player = HashMapHolder<Player>::Find(guid); - return player && player->IsInWorld() ? player : NULL; -} - -WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid guid) +WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid const& guid) { switch (guid.GetHigh()) { @@ -98,7 +64,7 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid gui } } -Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid guid, uint32 typemask) +Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid const& guid, uint32 typemask) { switch (guid.GetHigh()) { @@ -140,56 +106,67 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid gui return NULL; } -Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, ObjectGuid guid) +Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Corpse*)NULL); + return u.GetMap()->GetCorpse(guid); } -GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, ObjectGuid guid) +GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (GameObject*)NULL); + return u.GetMap()->GetGameObject(guid); } -Transport* ObjectAccessor::GetTransport(WorldObject const& u, ObjectGuid guid) +Transport* ObjectAccessor::GetTransport(WorldObject const& u, ObjectGuid const& guid) { - if (!guid.IsMOTransport()) - return NULL; + return u.GetMap()->GetTransport(guid); +} - GameObject* go = GetGameObject(u, guid); - return go ? go->ToTransport() : NULL; +DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, ObjectGuid const& guid) +{ + return u.GetMap()->GetDynamicObject(guid); } -DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, ObjectGuid guid) +AreaTrigger* ObjectAccessor::GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (DynamicObject*)NULL); + return u.GetMap()->GetAreaTrigger(guid); } -AreaTrigger* ObjectAccessor::GetAreaTrigger(WorldObject const& u, ObjectGuid guid) +Unit* ObjectAccessor::GetUnit(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (AreaTrigger*)NULL); + if (guid.IsPlayer()) + return GetPlayer(u, guid); + + if (guid.IsPet()) + return GetPet(u, guid); + + return GetCreature(u, guid); } -Unit* ObjectAccessor::GetUnit(WorldObject const& u, ObjectGuid guid) +Creature* ObjectAccessor::GetCreature(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Unit*)NULL); + return u.GetMap()->GetCreature(guid); } -Creature* ObjectAccessor::GetCreature(WorldObject const& u, ObjectGuid guid) +Pet* ObjectAccessor::GetPet(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Creature*)NULL); + return u.GetMap()->GetPet(guid); } -Pet* ObjectAccessor::GetPet(WorldObject const& u, ObjectGuid guid) +Player* ObjectAccessor::GetPlayer(Map const* m, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Pet*)NULL); + if (Player* player = HashMapHolder<Player>::Find(guid)) + if (player->IsInWorld() && player->GetMap() == m) + return player; + + return nullptr; } -Player* ObjectAccessor::GetPlayer(WorldObject const& u, ObjectGuid guid) +Player* ObjectAccessor::GetPlayer(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Player*)NULL); + return GetPlayer(u.GetMap(), guid); } -Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, ObjectGuid guid) +Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, ObjectGuid const& guid) { if (guid.IsPet()) return GetPet(u, guid); @@ -200,26 +177,17 @@ Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, Object return NULL; } -Pet* ObjectAccessor::FindPet(ObjectGuid guid) -{ - return GetObjectInWorld(guid, (Pet*)NULL); -} - -Player* ObjectAccessor::FindPlayer(ObjectGuid guid) +Player* ObjectAccessor::FindPlayer(ObjectGuid const& guid) { - return GetObjectInWorld(guid, (Player*)NULL); + Player* player = HashMapHolder<Player>::Find(guid); + return player && player->IsInWorld() ? player : nullptr; } -Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid guid) +Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid const& guid) { return HashMapHolder<Player>::Find(guid); } -Unit* ObjectAccessor::FindUnit(ObjectGuid guid) -{ - return GetObjectInWorld(guid, (Unit*)NULL); -} - Player* ObjectAccessor::FindPlayerByName(std::string const& name) { boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock()); @@ -267,7 +235,7 @@ void ObjectAccessor::SaveAllPlayers() itr->second->SaveToDB(); } -Corpse* ObjectAccessor::GetCorpseForPlayerGUID(ObjectGuid guid) +Corpse* ObjectAccessor::GetCorpseForPlayerGUID(ObjectGuid const& guid) { boost::shared_lock<boost::shared_mutex> lock(_corpseLock); @@ -299,7 +267,6 @@ void ObjectAccessor::RemoveCorpse(Corpse* corpse) } } else - corpse->RemoveFromWorld(); // Critical section @@ -359,7 +326,7 @@ void ObjectAccessor::AddCorpsesToGrid(GridCoord const& gridpair, GridType& grid, } } -Corpse* ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid player_guid, bool insignia /*=false*/) +Corpse* ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid const& player_guid, bool insignia /*=false*/) { Corpse* corpse = GetCorpseForPlayerGUID(player_guid); if (!corpse) @@ -398,12 +365,11 @@ Corpse* ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid player_guid, bool insi bones->SetUInt32Value(i, corpse->GetUInt32Value(i)); bones->SetGridCoord(corpse->GetGridCoord()); - // bones->m_time = m_time; // don't overwrite time - // bones->m_type = m_type; // don't overwrite type bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation()); bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES); bones->SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Empty); + bones->SetGuidValue(OBJECT_FIELD_DATA, corpse->GetGuidValue(OBJECT_FIELD_DATA)); for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) { @@ -439,27 +405,6 @@ void ObjectAccessor::RemoveOldCorpses() } } -void ObjectAccessor::Update(uint32 /*diff*/) -{ - UpdateDataMapType update_players; - - while (!i_objects.empty()) - { - Object* obj = *i_objects.begin(); - ASSERT(obj && obj->IsInWorld()); - i_objects.erase(i_objects.begin()); - obj->BuildUpdate(update_players); - } - - WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 - for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) - { - iter->second.BuildPacket(&packet); - iter->first->GetSession()->SendPacket(&packet); - packet.clear(); // clean the string - } -} - void ObjectAccessor::UnloadAll() { for (Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr) @@ -475,17 +420,5 @@ template <class T> typename HashMapHolder<T>::MapType HashMapHolder<T>::_objectM template <class T> boost::shared_mutex HashMapHolder<T>::_lock; /// Global definitions for the hashmap storage - template class HashMapHolder<Player>; -template class HashMapHolder<Pet>; -template class HashMapHolder<GameObject>; -template class HashMapHolder<DynamicObject>; -template class HashMapHolder<Creature>; -template class HashMapHolder<Corpse>; - -template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, ObjectGuid guid, Player* /*fake*/); -template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, ObjectGuid guid, Pet* /*fake*/); -template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, ObjectGuid guid, Creature* /*fake*/); -template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, ObjectGuid guid, Corpse* /*fake*/); -template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, ObjectGuid guid, GameObject* /*fake*/); -template DynamicObject* ObjectAccessor::GetObjectInWorld<DynamicObject>(uint32 mapid, float x, float y, ObjectGuid guid, DynamicObject* /*fake*/); +template class HashMapHolder<Transport>; diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index 47fc7aa6cef..e4c1ac3aa41 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -30,7 +30,6 @@ #include "UpdateData.h" #include "Object.h" - class Creature; class Corpse; class Unit; @@ -46,6 +45,9 @@ template <class T> class HashMapHolder { public: + static_assert(std::is_same<Player, T>::value + || std::is_same<Transport, T>::value, + "Only Player and Transport can be registered in global HashMapHolder"); typedef std::unordered_map<ObjectGuid, T*> MapType; @@ -100,78 +102,28 @@ class ObjectAccessor return &instance; } - template<class T> static T* GetObjectInOrOutOfWorld(ObjectGuid guid, T* /*typeSpecifier*/) - { - return HashMapHolder<T>::Find(guid); - } - - static Unit* GetObjectInOrOutOfWorld(ObjectGuid guid, Unit* /*typeSpecifier*/) - { - if (guid.IsPlayer()) - return (Unit*)GetObjectInOrOutOfWorld(guid, (Player*)NULL); - - if (guid.IsPet()) - return (Unit*)GetObjectInOrOutOfWorld(guid, (Pet*)NULL); - - return (Unit*)GetObjectInOrOutOfWorld(guid, (Creature*)NULL); - } - - // returns object if is in world - template<class T> static T* GetObjectInWorld(ObjectGuid guid, T* /*typeSpecifier*/) - { - return HashMapHolder<T>::Find(guid); - } - - // Player may be not in world while in ObjectAccessor - static Player* GetObjectInWorld(ObjectGuid guid, Player* /*typeSpecifier*/); - - static Unit* GetObjectInWorld(ObjectGuid guid, Unit* /*typeSpecifier*/) - { - if (guid.IsPlayer()) - return (Unit*)GetObjectInWorld(guid, (Player*)NULL); - - if (guid.IsPet()) - return (Unit*)GetObjectInWorld(guid, (Pet*)NULL); - - return (Unit*)GetObjectInWorld(guid, (Creature*)NULL); - } - - // returns object if is in map - template<class T> static T* GetObjectInMap(ObjectGuid guid, Map* map, T* /*typeSpecifier*/) - { - ASSERT(map); - if (T * obj = GetObjectInWorld(guid, (T*)NULL)) - if (obj->GetMap() == map) - return obj; - return NULL; - } - - template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, ObjectGuid guid, T* /*fake*/); - // these functions return objects only if in map of specified object - static WorldObject* GetWorldObject(WorldObject const&, ObjectGuid); - static Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid, uint32 typemask); - static Corpse* GetCorpse(WorldObject const& u, ObjectGuid guid); - static GameObject* GetGameObject(WorldObject const& u, ObjectGuid guid); - static Transport* GetTransport(WorldObject const& u, ObjectGuid guid); - static DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid guid); - static AreaTrigger* GetAreaTrigger(WorldObject const& u, ObjectGuid guid); - static Unit* GetUnit(WorldObject const&, ObjectGuid guid); - static Creature* GetCreature(WorldObject const& u, ObjectGuid guid); - static Pet* GetPet(WorldObject const&, ObjectGuid guid); - static Player* GetPlayer(WorldObject const&, ObjectGuid guid); - static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid); + static WorldObject* GetWorldObject(WorldObject const&, ObjectGuid const&); + static Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask); + static Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid); + static GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid); + static Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid); + static DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid); + static AreaTrigger* GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid); + static Unit* GetUnit(WorldObject const&, ObjectGuid const& guid); + static Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid); + static Pet* GetPet(WorldObject const&, ObjectGuid const& guid); + static Player* GetPlayer(Map const*, ObjectGuid const& guid); + static Player* GetPlayer(WorldObject const&, ObjectGuid const& guid); + static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid const&); // these functions return objects if found in whole world // ACCESS LIKE THAT IS NOT THREAD SAFE - static Pet* FindPet(ObjectGuid); - static Player* FindPlayer(ObjectGuid); - static Creature* FindCreature(ObjectGuid); - static Unit* FindUnit(ObjectGuid); + static Player* FindPlayer(ObjectGuid const&); static Player* FindPlayerByName(std::string const& name); // this returns Player even if he is not in world, for example teleporting - static Player* FindConnectedPlayer(ObjectGuid); + static Player* FindConnectedPlayer(ObjectGuid const&); static Player* FindConnectedPlayerByName(std::string const& name); // when using this, you must use the hashmapholder's lock @@ -180,18 +132,6 @@ class ObjectAccessor return HashMapHolder<Player>::GetContainer(); } - // when using this, you must use the hashmapholder's lock - static HashMapHolder<Creature>::MapType const& GetCreatures() - { - return HashMapHolder<Creature>::GetContainer(); - } - - // when using this, you must use the hashmapholder's lock - static HashMapHolder<GameObject>::MapType const& GetGameObjects() - { - return HashMapHolder<GameObject>::GetContainer(); - } - template<class T> static void AddObject(T* object) { HashMapHolder<T>::Insert(object); @@ -205,42 +145,24 @@ class ObjectAccessor static void SaveAllPlayers(); //non-static functions - void AddUpdateObject(Object* obj) - { - std::lock_guard<std::mutex> lock(_objectLock); - i_objects.insert(obj); - } - - void RemoveUpdateObject(Object* obj) - { - std::lock_guard<std::mutex> lock(_objectLock); - i_objects.erase(obj); - } //Thread safe - Corpse* GetCorpseForPlayerGUID(ObjectGuid guid); + Corpse* GetCorpseForPlayerGUID(ObjectGuid const& guid); void RemoveCorpse(Corpse* corpse); void AddCorpse(Corpse* corpse); void AddCorpsesToGrid(GridCoord const& gridpair, GridType& grid, Map* map); - Corpse* ConvertCorpseForPlayer(ObjectGuid player_guid, bool insignia = false); + Corpse* ConvertCorpseForPlayer(ObjectGuid const& player_guid, bool insignia = false); //Thread unsafe - void Update(uint32 diff); void RemoveOldCorpses(); void UnloadAll(); private: - static void _buildChangeObjectForPlayer(WorldObject*, UpdateDataMapType&); - static void _buildPacket(Player*, Object*, UpdateDataMapType&); - void _update(); - typedef std::unordered_map<ObjectGuid, Corpse*> Player2CorpsesMapType; typedef std::unordered_map<Player*, UpdateData>::value_type UpdateDataValueType; - std::set<Object*> i_objects; Player2CorpsesMapType i_player2corpse; - std::mutex _objectLock; boost::shared_mutex _corpseLock; }; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 390962b1a0e..6beae09bb20 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -239,24 +239,6 @@ bool SpellClickInfo::IsFitToRequirements(Unit const* clicker, Unit const* clicke return true; } -template<> ObjectGuidGenerator<HighGuid::Player>* ObjectMgr::GetGenerator() { return &_playerGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::Creature>* ObjectMgr::GetGenerator() { return &_creatureGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::Pet>* ObjectMgr::GetGenerator() { return &_petGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::Vehicle>* ObjectMgr::GetGenerator() { return &_vehicleGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::Item>* ObjectMgr::GetGenerator() { return &_itemGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::GameObject>* ObjectMgr::GetGenerator() { return &_gameObjectGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::DynamicObject>* ObjectMgr::GetGenerator() { return &_dynamicObjectGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::Corpse>* ObjectMgr::GetGenerator() { return &_corpseGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::LootObject>* ObjectMgr::GetGenerator() { return &_lootObjectGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::AreaTrigger>* ObjectMgr::GetGenerator() { return &_areaTriggerGuidGenerator; } -template<> ObjectGuidGenerator<HighGuid::Transport>* ObjectMgr::GetGenerator() { return &_moTransportGuidGenerator; } - -template<HighGuid type> -ObjectGuidGenerator<type>* ObjectMgr::GetGenerator() -{ - return nullptr; -} - ObjectMgr::ObjectMgr(): _auctionId(1), _equipmentSetGuid(1), @@ -264,6 +246,8 @@ ObjectMgr::ObjectMgr(): _mailId(1), _hiPetNumber(1), _voidItemId(1), + _creatureSpawnId(1), + _gameObjectSpawnId(1), DBCLocaleIndex(LOCALE_enUS) { for (uint8 i = 0; i < MAX_CLASSES; ++i) @@ -1903,7 +1887,7 @@ ObjectGuid::LowType ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, fl if (!map) return UI64LIT(0); - ObjectGuid::LowType guid = GetGenerator<HighGuid::GameObject>()->Generate(); + ObjectGuid::LowType guid = GenerateGameObjectSpawnId(); GameObjectData& data = NewGOData(guid); data.id = entry; data.mapid = mapId; @@ -1943,39 +1927,6 @@ ObjectGuid::LowType ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, fl return guid; } -bool ObjectMgr::MoveCreData(ObjectGuid::LowType guid, uint32 mapId, const Position& pos) -{ - CreatureData& data = NewOrExistCreatureData(guid); - if (!data.id) - return false; - - RemoveCreatureFromGrid(guid, &data); - if (data.posX == pos.GetPositionX() && data.posY == pos.GetPositionY() && data.posZ == pos.GetPositionZ()) - return true; - data.posX = pos.GetPositionX(); - data.posY = pos.GetPositionY(); - data.posZ = pos.GetPositionZ(); - data.orientation = pos.GetOrientation(); - AddCreatureToGrid(guid, &data); - - // Spawn if necessary (loaded grids only) - if (Map* map = sMapMgr->CreateBaseMap(mapId)) - { - // We use spawn coords to spawn - if (!map->Instanceable() && map->IsGridLoaded(data.posX, data.posY)) - { - Creature* creature = new Creature(); - if (!creature->LoadCreatureFromDB(guid, map)) - { - TC_LOG_ERROR("misc", "MoveCreData: Cannot add creature guid " UI64FMTD " to map", guid); - delete creature; - return false; - } - } - } - return true; -} - ObjectGuid::LowType ObjectMgr::AddCreData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay /*= 0*/) { CreatureTemplate const* cInfo = GetCreatureTemplate(entry); @@ -1984,8 +1935,11 @@ ObjectGuid::LowType ObjectMgr::AddCreData(uint32 entry, uint32 mapId, float x, f uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats CreatureBaseStats const* stats = GetCreatureBaseStats(level, cInfo->unit_class); + Map* map = sMapMgr->CreateBaseMap(mapId); + if (!map) + return UI64LIT(0); - ObjectGuid::LowType guid = GetGenerator<HighGuid::Creature>()->Generate(); + ObjectGuid::LowType guid = GenerateCreatureSpawnId(); CreatureData& data = NewOrExistCreatureData(guid); data.id = entry; data.mapid = mapId; @@ -2010,19 +1964,15 @@ ObjectGuid::LowType ObjectMgr::AddCreData(uint32 entry, uint32 mapId, float x, f AddCreatureToGrid(guid, &data); - // Spawn if necessary (loaded grids only) - if (Map* map = sMapMgr->CreateBaseMap(mapId)) + // We use spawn coords to spawn + if (!map->Instanceable() && !map->IsRemovalGrid(x, y)) { - // We use spawn coords to spawn - if (!map->Instanceable() && !map->IsRemovalGrid(x, y)) + Creature* creature = new Creature(); + if (!creature->LoadCreatureFromDB(guid, map)) { - Creature* creature = new Creature(); - if (!creature->LoadCreatureFromDB(guid, map)) - { - TC_LOG_ERROR("misc", "AddCreature: Cannot add creature entry %u to map", entry); - delete creature; - return UI64LIT(0); - } + TC_LOG_ERROR("misc", "AddCreature: Cannot add creature entry %u to map", entry); + delete creature; + return UI64LIT(0); } } @@ -6263,29 +6213,21 @@ void ObjectMgr::SetHighestGuids() { QueryResult result = CharacterDatabase.Query("SELECT MAX(guid) FROM characters"); if (result) - _playerGuidGenerator.Set((*result)[0].GetUInt64() + 1); - - result = WorldDatabase.Query("SELECT MAX(guid) FROM creature"); - if (result) - _creatureGuidGenerator.Set((*result)[0].GetUInt64() + 1); + GetGuidSequenceGenerator<HighGuid::Player>().Set((*result)[0].GetUInt64() + 1); result = CharacterDatabase.Query("SELECT MAX(guid) FROM item_instance"); if (result) - _itemGuidGenerator.Set((*result)[0].GetUInt64() + 1); + GetGuidSequenceGenerator<HighGuid::Item>().Set((*result)[0].GetUInt64() + 1); // Cleanup other tables from nonexistent guids ( >= _hiItemGuid) - CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", _itemGuidGenerator.GetNextAfterMaxUsed()); // One-time query - CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", _itemGuidGenerator.GetNextAfterMaxUsed()); // One-time query - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", _itemGuidGenerator.GetNextAfterMaxUsed()); // One-time query - CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", _itemGuidGenerator.GetNextAfterMaxUsed()); // One-time query - - result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject"); - if (result) - _gameObjectGuidGenerator.Set((*result)[0].GetUInt64() + 1); + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query result = WorldDatabase.Query("SELECT MAX(guid) FROM transports"); if (result) - _moTransportGuidGenerator.Set((*result)[0].GetUInt64() + 1); + GetGuidSequenceGenerator<HighGuid::Transport>().Set((*result)[0].GetUInt64() + 1); result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse"); if (result) @@ -6295,10 +6237,6 @@ void ObjectMgr::SetHighestGuids() if (result) _mailId = (*result)[0].GetUInt32()+1; - result = CharacterDatabase.Query("SELECT MAX(corpseGuid) FROM corpse"); - if (result) - _corpseGuidGenerator.Set((*result)[0].GetUInt64() + 1); - result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team"); if (result) sArenaTeamMgr->SetNextArenaTeamId((*result)[0].GetUInt32()+1); @@ -6318,6 +6256,14 @@ void ObjectMgr::SetHighestGuids() result = CharacterDatabase.Query("SELECT MAX(itemId) from character_void_storage"); if (result) _voidItemId = (*result)[0].GetUInt64()+1; + + result = WorldDatabase.Query("SELECT MAX(guid) FROM creature"); + if (result) + _creatureSpawnId = (*result)[0].GetUInt64() + 1; + + result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject"); + if (result) + _gameObjectSpawnId = (*result)[0].GetUInt64() + 1; } uint32 ObjectMgr::GenerateAuctionID() @@ -6350,6 +6296,36 @@ uint32 ObjectMgr::GenerateMailID() return _mailId++; } +uint32 ObjectMgr::GeneratePetNumber() +{ + return ++_hiPetNumber; +} + +uint64 ObjectMgr::GenerateVoidStorageItemId() +{ + return ++_voidItemId; +} + +uint64 ObjectMgr::GenerateCreatureSpawnId() +{ + if (_creatureSpawnId >= uint64(0xFFFFFFFFFFFFFFFELL)) + { + TC_LOG_ERROR("misc", "Creature spawn id overflow!! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + return _creatureSpawnId++; +} + +uint64 ObjectMgr::GenerateGameObjectSpawnId() +{ + if (_gameObjectSpawnId >= uint64(0xFFFFFFFFFFFFFFFELL)) + { + TC_LOG_ERROR("misc", "Creature spawn id overflow!! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + return _gameObjectSpawnId++; +} + void ObjectMgr::LoadGameObjectLocales() { uint32 oldMSTime = getMSTime(); @@ -6734,77 +6710,6 @@ std::string ObjectMgr::GeneratePetName(uint32 entry) return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1)); } -uint32 ObjectMgr::GeneratePetNumber() -{ - return ++_hiPetNumber; -} - -uint64 ObjectMgr::GenerateVoidStorageItemId() -{ - return ++_voidItemId; -} - -void ObjectMgr::LoadCorpses() -{ - uint32 oldMSTime = getMSTime(); - - std::unordered_map<uint32, std::list<uint32>> phases; - - // 0 1 - // SELECT Guid, PhaseId FROM corpse_phases - PreparedQueryResult phaseResult = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_PHASES)); - if (phaseResult) - { - do - { - Field* fields = phaseResult->Fetch(); - uint32 guid = fields[0].GetUInt32(); - uint32 phaseId = fields[1].GetUInt32(); - - phases[guid].push_back(phaseId); - - } while (phaseResult->NextRow()); - } - - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, corpseGuid, guid FROM corpse WHERE corpseType <> 0 - PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES)); - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 corpses. DB table `corpse` is empty."); - return; - } - - uint32 count = 0; - do - { - Field* fields = result->Fetch(); - uint32 guid = fields[14].GetUInt32(); - CorpseType type = CorpseType(fields[12].GetUInt8()); - if (type >= MAX_CORPSE_TYPE) - { - TC_LOG_ERROR("misc", "Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type); - continue; - } - - Corpse* corpse = new Corpse(type); - if (!corpse->LoadCorpseFromDB(guid, fields)) - { - delete corpse; - continue; - } - - for (auto phaseId : phases[guid]) - corpse->SetInPhase(phaseId, false, true); - - sObjectAccessor->AddCorpse(corpse); - ++count; - } - while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u corpses in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - void ObjectMgr::LoadReputationRewardRate() { uint32 oldMSTime = getMSTime(); @@ -9028,7 +8933,7 @@ VehicleAccessoryList const* ObjectMgr::GetVehicleAccessoryList(Vehicle* veh) con if (Creature* cre = veh->GetBase()->ToCreature()) { // Give preference to GUID-based accessories - VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetDBTableGUIDLow()); + VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId()); if (itr != _vehicleAccessoryStore.end()) return &itr->second; } @@ -9302,4 +9207,4 @@ void ObjectMgr::LoadCreatureQuestItems() while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u creature quest items in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -}
\ No newline at end of file +} diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index f9bdeadc620..d55492ac0f1 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -36,12 +36,13 @@ #include "ObjectAccessor.h" #include "ObjectDefines.h" #include "VehicleDefines.h" +#include "ConditionMgr.h" +#include "DB2Stores.h" #include <string> #include <map> #include <limits> -#include "ConditionMgr.h" #include <functional> -#include "DB2Stores.h" +#include <memory> class Item; struct AccessRequirement; @@ -1015,7 +1016,6 @@ class ObjectMgr void LoadExplorationBaseXP(); void LoadPetNames(); void LoadPetNumber(); - void LoadCorpses(); void LoadFishingBaseSkillLevel(); void LoadReputationRewardRate(); @@ -1056,13 +1056,21 @@ class ObjectMgr CreatureBaseStats const* GetCreatureBaseStats(uint8 level, uint8 unitClass); void SetHighestGuids(); + template<HighGuid type> - ObjectGuidGenerator<type>* GetGenerator(); + inline ObjectGuidGeneratorBase& GetGenerator() + { + static_assert(ObjectGuidTraits<type>::Global || ObjectGuidTraits<type>::RealmSpecific, "Only global guid can be generated in ObjectMgr context"); + return GetGuidSequenceGenerator<type>(); + } + uint32 GenerateAuctionID(); uint64 GenerateEquipmentSetGuid(); uint32 GenerateMailID(); uint32 GeneratePetNumber(); uint64 GenerateVoidStorageItemId(); + uint64 GenerateCreatureSpawnId(); + uint64 GenerateGameObjectSpawnId(); typedef std::multimap<int32, uint32> ExclusiveQuestGroups; typedef std::pair<ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator> ExclusiveQuestGroupsBounds; @@ -1198,7 +1206,6 @@ class ObjectMgr void RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const* data); ObjectGuid::LowType AddGOData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0, float rotation0 = 0, float rotation1 = 0, float rotation2 = 0, float rotation3 = 0); ObjectGuid::LowType AddCreData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0); - bool MoveCreData(ObjectGuid::LowType guid, uint32 map, const Position& pos); // reserved names void LoadReservedPlayersNames(); @@ -1331,7 +1338,7 @@ class ObjectMgr } CharacterTemplateContainer const& GetCharacterTemplates() const { return _characterTemplateStore; } - CharacterTemplate const* GetCharacterTemplate(uint32 id) const + CharacterTemplate const* GetCharacterTemplate(uint32 id) const { auto itr = _characterTemplateStore.find(id); if (itr != _characterTemplateStore.end()) @@ -1348,19 +1355,21 @@ class ObjectMgr uint32 _mailId; uint32 _hiPetNumber; uint64 _voidItemId; + uint64 _creatureSpawnId; + uint64 _gameObjectSpawnId; // first free low guid for selected guid type - ObjectGuidGenerator<HighGuid::Player> _playerGuidGenerator; - ObjectGuidGenerator<HighGuid::Creature> _creatureGuidGenerator; - ObjectGuidGenerator<HighGuid::Pet> _petGuidGenerator; - ObjectGuidGenerator<HighGuid::Vehicle> _vehicleGuidGenerator; - ObjectGuidGenerator<HighGuid::Item> _itemGuidGenerator; - ObjectGuidGenerator<HighGuid::GameObject> _gameObjectGuidGenerator; - ObjectGuidGenerator<HighGuid::DynamicObject> _dynamicObjectGuidGenerator; - ObjectGuidGenerator<HighGuid::Corpse> _corpseGuidGenerator; - ObjectGuidGenerator<HighGuid::LootObject> _lootObjectGuidGenerator; - ObjectGuidGenerator<HighGuid::AreaTrigger> _areaTriggerGuidGenerator; - ObjectGuidGenerator<HighGuid::Transport> _moTransportGuidGenerator; + template<HighGuid high> + inline ObjectGuidGeneratorBase& GetGuidSequenceGenerator() + { + auto itr = _guidGenerators.find(high); + if (itr == _guidGenerators.end()) + itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first; + + return *itr->second; + } + + std::map<HighGuid, std::unique_ptr<ObjectGuidGeneratorBase>> _guidGenerators; QuestMap _questTemplates; diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h index 4f3e774ea56..3b9b0b73633 100644 --- a/src/server/game/Grids/GridDefines.h +++ b/src/server/game/Grids/GridDefines.h @@ -59,6 +59,7 @@ class AreaTrigger; // Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case) typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes; typedef TYPELIST_5(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger) AllGridObjectTypes; +typedef TYPELIST_6(Creature, GameObject, DynamicObject, Pet, Corpse, AreaTrigger) AllMapStoredObjectTypes; typedef GridRefManager<Corpse> CorpseMapType; typedef GridRefManager<Creature> CreatureMapType; @@ -83,6 +84,7 @@ typedef NGrid<MAX_NUMBER_OF_CELLS, Player, AllWorldObjectTypes, AllGridObjectTyp typedef TypeMapContainer<AllGridObjectTypes> GridTypeMapContainer; typedef TypeMapContainer<AllWorldObjectTypes> WorldTypeMapContainer; +typedef TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid> MapStoredObjectTypesContainer; template<uint32 LIMIT> struct CoordPair diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 0936f8ff753..8a5386684bb 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -742,7 +742,7 @@ namespace Trinity GameObjectWithDbGUIDCheck(WorldObject const& /*obj*/, ObjectGuid::LowType db_guid) : i_db_guid(db_guid) { } bool operator()(GameObject const* go) const { - return go->GetDBTableGUIDLow() == i_db_guid; + return go->GetSpawnId() == i_db_guid; } private: ObjectGuid::LowType i_db_guid; @@ -855,7 +855,7 @@ namespace Trinity CreatureWithDbGUIDCheck(WorldObject const* /*obj*/, ObjectGuid::LowType lowguid) : i_lowguid(lowguid) { } bool operator()(Creature* u) { - return u->GetDBTableGUIDLow() == i_lowguid; + return u->GetSpawnId() == i_lowguid; } private: ObjectGuid::LowType i_lowguid; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index d7d08508230..c73aeb3a719 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -960,7 +960,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) //roll for over-threshold item if it's one-player loot if (item->GetQuality() >= uint32(m_lootThreshold)) { - ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>()->Generate()); + ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate()); Roll* r = new Roll(newitemGUID, *i); //a vector is filled with only near party members @@ -1044,7 +1044,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) continue; } - ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>()->Generate()); + ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate()); Roll* r = new Roll(newitemGUID, *i); //a vector is filled with only near party members @@ -1105,7 +1105,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) //roll for over-threshold item if it's one-player loot if (item->GetQuality() >= uint32(m_lootThreshold)) { - ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>()->Generate()); + ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate()); Roll* r = new Roll(newitemGUID, *i); for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) @@ -1180,7 +1180,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) continue; item = sObjectMgr->GetItemTemplate(i->itemid); - ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>()->Generate()); + ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate()); Roll* r = new Roll(newitemGUID, *i); for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index ea859bc7b08..e7818a841aa 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -671,7 +671,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, WorldPac Player newChar(this); newChar.GetMotionMaster()->Initialize(); - if (!newChar.Create(sObjectMgr->GetGenerator<HighGuid::Player>()->Generate(), createInfo)) + if (!newChar.Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo)) { // Player not create (race/class/etc problem?) newChar.CleanupsBeforeDelete(); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 10231167b01..b8ac779887b 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -612,7 +612,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPackets::Mail::MailCreateTextIt } Item* bodyItem = new Item; // This is not bag and then can be used new Item. - if (!bodyItem->Create(sObjectMgr->GetGenerator<HighGuid::Item>()->Generate(), MAIL_BODY_ITEM_TEMPLATE, player)) + if (!bodyItem->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), MAIL_BODY_ITEM_TEMPLATE, player)) { delete bodyItem; return; diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index a682c82aa37..7f1782ea1f0 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -594,7 +594,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) recvData >> name; recvData >> isdeclined; - Pet* pet = ObjectAccessor::FindPet(petguid); + Pet* pet = ObjectAccessor::GetPet(*_player, petguid); // check it! if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET || !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) || diff --git a/src/server/game/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp index a7cee1e25b9..b4c9513a238 100644 --- a/src/server/game/Handlers/ReferAFriendHandler.cpp +++ b/src/server/game/Handlers/ReferAFriendHandler.cpp @@ -24,7 +24,7 @@ void WorldSession::HandleGrantLevel(WorldPackets::RaF::GrantLevel& grantLevel) { - Player* target = ObjectAccessor::GetObjectInWorld(grantLevel.Target, _player); + Player* target = ObjectAccessor::GetPlayer(*_player, grantLevel.Target); // check cheating uint8 levels = _player->GetGrantableLevels(); @@ -64,7 +64,7 @@ void WorldSession::HandleGrantLevel(WorldPackets::RaF::GrantLevel& grantLevel) void WorldSession::HandleAcceptGrantLevel(WorldPackets::RaF::AcceptLevelGrant& acceptLevelGrant) { - Player* other = ObjectAccessor::GetObjectInWorld(acceptLevelGrant.Granter, _player); + Player* other = ObjectAccessor::GetPlayer(*_player, acceptLevelGrant.Granter); if (!(other && other->GetSession())) return; diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 52e50ba5fe9..2cfa14164fe 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -508,7 +508,7 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPacket& recvData) recvData.read_skip<uint32>(); // DisplayId ? // Get unit for which data is needed by client - Unit* unit = ObjectAccessor::GetObjectInWorld(guid, (Unit*)NULL); + Unit* unit = ObjectAccessor::GetUnit(*_player, guid); if (!unit) return; diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index c45358efa11..c729057468b 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -558,7 +558,10 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId) ((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY); if (iMap) + { iMap->DeleteRespawnTimes(); + iMap->DeleteCorpseData(); + } else Map::DeleteRespawnTimesInDB(mapid, instanceId); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 8c34e37976c..be1956efc79 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -178,11 +178,11 @@ class InstanceScript : public ZoneScript inline Creature* GetCreature(uint32 type) { - return ObjectAccessor::GetObjectInMap<Creature>(GetObjectGuid(type), instance, nullptr); + return instance->GetCreature(GetObjectGuid(type)); } inline GameObject* GetGameObject(uint32 type) { - return ObjectAccessor::GetObjectInMap<GameObject>(GetObjectGuid(type), instance, nullptr); + return instance->GetGameObject(GetObjectGuid(type)); } // Called when a player successfully enters the instance. diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c2bec063223..ebfdaaf3b73 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -392,7 +392,7 @@ template<> void Map::DeleteFromWorld(Player* player) { sObjectAccessor->RemoveObject(player); - sObjectAccessor->RemoveUpdateObject(player); /// @todo I do not know why we need this, it should be removed in ~Object anyway + RemoveUpdateObject(player); /// @todo I do not know why we need this, it should be removed in ~Object anyway delete player; } @@ -698,6 +698,8 @@ void Map::Update(const uint32 t_diff) obj->Update(t_diff); } + SendObjectUpdates(); + ///- Process necessary scripts if (!m_scriptSchedule.empty()) { @@ -2591,6 +2593,27 @@ inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y) i_grids[x][y] = grid; } +void Map::SendObjectUpdates() +{ + UpdateDataMapType update_players; + + while (!_updateObjects.empty()) + { + Object* obj = *_updateObjects.begin(); + ASSERT(obj && obj->IsInWorld()); + _updateObjects.erase(_updateObjects.begin()); + obj->BuildUpdate(update_players); + } + + WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 + for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) + { + iter->second.BuildPacket(&packet); + iter->first->GetSession()->SendPacket(&packet); + packet.clear(); // clean the string + } +} + void Map::DelayedUpdate(const uint32 t_diff) { RemoveAllObjectsInRemoveList(); @@ -2775,7 +2798,7 @@ void Map::AddToActive(Creature* c) AddToActiveHelper(c); // also not allow unloading spawn grid to prevent creating creature clone at load - if (!c->IsPet() && c->GetDBTableGUIDLow()) + if (!c->IsPet() && c->GetSpawnId()) { float x, y, z; c->GetRespawnPosition(x, y, z); @@ -2806,7 +2829,7 @@ void Map::RemoveFromActive(Creature* c) RemoveFromActiveHelper(c); // also allow unloading spawn grid - if (!c->IsPet() && c->GetDBTableGUIDLow()) + if (!c->IsPet() && c->GetSpawnId()) { float x, y, z; c->GetRespawnPosition(x, y, z); @@ -3188,8 +3211,11 @@ void InstanceMap::UnloadAll() { ASSERT(!HavePlayers()); - if (m_resetAfterUnload == true) + if (m_resetAfterUnload) + { DeleteRespawnTimes(); + DeleteCorpseData(); + } Map::UnloadAll(); } @@ -3330,17 +3356,37 @@ void BattlegroundMap::RemoveAllPlayers() player->TeleportTo(player->GetBattlegroundEntryPoint()); } -Creature* Map::GetCreature(ObjectGuid guid) +AreaTrigger* Map::GetAreaTrigger(ObjectGuid const& guid) +{ + return _objectsStore.Find<AreaTrigger>(guid); +} + +Corpse* Map::GetCorpse(ObjectGuid const& guid) { - return ObjectAccessor::GetObjectInMap(guid, this, (Creature*)NULL); + return _objectsStore.Find<Corpse>(guid); } -GameObject* Map::GetGameObject(ObjectGuid guid) +Creature* Map::GetCreature(ObjectGuid const& guid) { - return ObjectAccessor::GetObjectInMap(guid, this, (GameObject*)NULL); + return _objectsStore.Find<Creature>(guid); } -Transport* Map::GetTransport(ObjectGuid guid) +DynamicObject* Map::GetDynamicObject(ObjectGuid const& guid) +{ + return _objectsStore.Find<DynamicObject>(guid); +} + +GameObject* Map::GetGameObject(ObjectGuid const& guid) +{ + return _objectsStore.Find<GameObject>(guid); +} + +Pet* Map::GetPet(ObjectGuid const& guid) +{ + return _objectsStore.Find<Pet>(guid); +} + +Transport* Map::GetTransport(ObjectGuid const& guid) { if (!guid.IsMOTransport()) return NULL; @@ -3349,11 +3395,6 @@ Transport* Map::GetTransport(ObjectGuid guid) return go ? go->ToTransport() : NULL; } -DynamicObject* Map::GetDynamicObject(ObjectGuid guid) -{ - return ObjectAccessor::GetObjectInMap(guid, this, (DynamicObject*)NULL); -} - void Map::UpdateIteratorBack(Player* player) { if (m_mapRefIter == player->GetMapRef()) @@ -3490,6 +3531,72 @@ time_t Map::GetLinkedRespawnTime(ObjectGuid guid) const return time_t(0); } +void Map::LoadCorpseData() +{ + std::unordered_map<uint64, std::unordered_set<uint32>> phases; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_PHASES); + stmt->setUInt32(0, GetId()); + + // 0 1 + // SELECT OwnerGuid, PhaseId FROM corpse_phases cp LEFT JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ? + PreparedQueryResult phaseResult = CharacterDatabase.Query(stmt); + if (phaseResult) + { + do + { + Field* fields = phaseResult->Fetch(); + uint64 guid = fields[0].GetUInt64(); + uint32 phaseId = fields[1].GetUInt32(); + + phases[guid].insert(phaseId); + + } while (phaseResult->NextRow()); + } + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES); + stmt->setUInt32(0, GetId()); + + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ? + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) + return; + + uint32 count = 0; + do + { + Field* fields = result->Fetch(); + CorpseType type = CorpseType(fields[12].GetUInt8()); + ObjectGuid::LowType guid = fields[14].GetUInt64(); + if (type >= MAX_CORPSE_TYPE || type == CORPSE_BONES) + { + TC_LOG_ERROR("misc", "Corpse (guid: " UI64FMTD ") have wrong corpse type (%u), not loading.", guid, type); + continue; + } + + Corpse* corpse = new Corpse(type); + if (!corpse->LoadCorpseFromDB(GenerateLowGuid<HighGuid::Corpse>(), fields)) + { + delete corpse; + continue; + } + + for (auto phaseId : phases[guid]) + corpse->SetInPhase(phaseId, false, true); + + sObjectAccessor->AddCorpse(corpse); + ++count; + } while (result->NextRow()); +} + +void Map::DeleteCorpseData() +{ + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSES_FROM_MAP); + stmt->setUInt32(0, GetId()); + CharacterDatabase.Execute(stmt); +} + void Map::SendZoneDynamicInfo(Player* player) { uint32 zoneId = GetZoneId(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 1e6f6d45b80..86310bdb67e 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -34,6 +34,7 @@ #include <bitset> #include <list> +#include <memory> class Unit; class WorldPacket; @@ -444,10 +445,21 @@ class Map : public GridRefManager<NGridType> TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0); void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL); - Creature* GetCreature(ObjectGuid guid); - GameObject* GetGameObject(ObjectGuid guid); - Transport* GetTransport(ObjectGuid guid); - DynamicObject* GetDynamicObject(ObjectGuid guid); + AreaTrigger* GetAreaTrigger(ObjectGuid const& guid); + Corpse* GetCorpse(ObjectGuid const& guid); + Creature* GetCreature(ObjectGuid const& guid); + DynamicObject* GetDynamicObject(ObjectGuid const& guid); + GameObject* GetGameObject(ObjectGuid const& guid); + Pet* GetPet(ObjectGuid const& guid); + Transport* GetTransport(ObjectGuid const& guid); + + MapStoredObjectTypesContainer& GetObjectsStore() { return _objectsStore; } + + typedef std::unordered_multimap<ObjectGuid::LowType, Creature*> CreatureBySpawnIdContainer; + CreatureBySpawnIdContainer& GetCreatureBySpawnIdStore() { return _creatureBySpawnIdStore; } + + typedef std::unordered_multimap<ObjectGuid::LowType, GameObject*> GameObjectBySpawnIdContainer; + GameObjectBySpawnIdContainer& GetGameObjectBySpawnIdStore() { return _gameobjectBySpawnIdStore; } MapInstanced* ToMapInstanced() { if (Instanceable()) return reinterpret_cast<MapInstanced*>(this); return NULL; } MapInstanced const* ToMapInstanced() const { if (Instanceable()) return reinterpret_cast<MapInstanced const*>(this); return NULL; } @@ -496,6 +508,8 @@ class Map : public GridRefManager<NGridType> void RemoveGORespawnTime(ObjectGuid::LowType dbGuid); void LoadRespawnTimes(); void DeleteRespawnTimes(); + void LoadCorpseData(); + void DeleteCorpseData(); static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId); @@ -510,6 +524,23 @@ class Map : public GridRefManager<NGridType> void UpdateAreaDependentAuras(); + template<HighGuid high> + inline ObjectGuid::LowType GenerateLowGuid() + { + static_assert(ObjectGuidTraits<high>::MapSpecific, "Only map specific guid can be generated in Map context"); + return GetGuidSequenceGenerator<high>().Generate(); + } + + void AddUpdateObject(Object* obj) + { + _updateObjects.insert(obj); + } + + void RemoveUpdateObject(Object* obj) + { + _updateObjects.erase(obj); + } + private: void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); @@ -564,6 +595,8 @@ class Map : public GridRefManager<NGridType> void UpdateActiveCells(const float &x, const float &y, const uint32 t_diff); + void SendObjectUpdates(); + protected: void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } @@ -656,6 +689,23 @@ class Map : public GridRefManager<NGridType> ZoneDynamicInfoMap _zoneDynamicInfo; uint32 _defaultLight; + + template<HighGuid high> + inline ObjectGuidGeneratorBase& GetGuidSequenceGenerator() + { + auto itr = _guidGenerators.find(high); + if (itr == _guidGenerators.end()) + itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first; + + return *itr->second; + } + + std::map<HighGuid, std::unique_ptr<ObjectGuidGeneratorBase>> _guidGenerators; + MapStoredObjectTypesContainer _objectsStore; + CreatureBySpawnIdContainer _creatureBySpawnIdStore; + GameObjectBySpawnIdContainer _gameobjectBySpawnIdStore; + + std::unordered_set<Object*> _updateObjects; }; enum InstanceResetMethod diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index cc0c99adc99..c48b616788e 100644 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -212,6 +212,7 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save, ASSERT(map->IsDungeon()); map->LoadRespawnTimes(); + map->LoadCorpseData(); bool load_data = save != NULL; map->CreateInstanceData(load_data); diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index d49bde4415d..e18a98e8429 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -81,6 +81,7 @@ Map* MapManager::CreateBaseMap(uint32 id) { map = new Map(id, i_gridCleanUpDelay, 0, DIFFICULTY_NONE); map->LoadRespawnTimes(); + map->LoadCorpseData(); } i_maps[id] = map; @@ -253,8 +254,6 @@ void MapManager::Update(uint32 diff) for (iter = i_maps.begin(); iter != i_maps.end(); ++iter) iter->second->DelayedUpdate(uint32(i_timer.GetCurrent())); - sObjectAccessor->Update(uint32(i_timer.GetCurrent())); - i_timer.SetCurrent(0); } diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index dc6c0bb642f..98bc1e0ad22 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -21,6 +21,7 @@ #include "Object.h" #include "Map.h" +#include "MapInstanced.h" #include "GridStates.h" #include "MapUpdater.h" @@ -125,7 +126,13 @@ class MapManager MapUpdater * GetMapUpdater() { return &m_updater; } - private: + template<typename Worker> + void DoForAllMaps(Worker&& worker); + + template<typename Worker> + void DoForAllMapsWithMapId(uint32 mapId, Worker&& worker); + +private: typedef std::unordered_map<uint32, Map*> MapMapType; typedef std::vector<bool> InstanceIds; @@ -150,5 +157,45 @@ class MapManager uint32 _nextInstanceId; MapUpdater m_updater; }; + +template<typename Worker> +void MapManager::DoForAllMaps(Worker&& worker) +{ + std::lock_guard<std::mutex> lock(_mapsLock); + + for (auto& mapPair : i_maps) + { + Map* map = mapPair.second; + if (MapInstanced* mapInstanced = map->ToMapInstanced()) + { + MapInstanced::InstancedMaps& instances = mapInstanced->GetInstancedMaps(); + for (auto& instancePair : instances) + worker(instancePair.second); + } + else + worker(map); + } +} + +template<typename Worker> +inline void MapManager::DoForAllMapsWithMapId(uint32 mapId, Worker&& worker) +{ + std::lock_guard<std::mutex> lock(_mapsLock); + + auto itr = i_maps.find(mapId); + if (itr != i_maps.end()) + { + Map* map = itr->second; + if (MapInstanced* mapInstanced = map->ToMapInstanced()) + { + MapInstanced::InstancedMaps& instances = mapInstanced->GetInstancedMaps(); + for (auto& p : instances) + worker(p.second); + } + else + worker(map); + } +} + #define sMapMgr MapManager::instance() #endif diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index 015665d6430..8f9d65e749b 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -384,7 +384,7 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid float o = tInfo->keyFrames.begin()->InitialOrientation; // initialize the gameobject base - ObjectGuid::LowType guidLow = guid ? guid : sObjectMgr->GetGenerator<HighGuid::Transport>()->Generate(); + ObjectGuid::LowType guidLow = guid ? guid : sObjectMgr->GetGenerator<HighGuid::Transport>().Generate(); if (!trans->Create(guidLow, entry, mapId, x, y, z, o, 255)) { delete trans; @@ -414,7 +414,7 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript(); // Passengers will be loaded once a player is near - + HashMapHolder<Transport>::Insert(trans); trans->GetMap()->AddToMap<Transport>(trans); return trans; } diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 0222087c168..47e8f18810c 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -42,7 +42,7 @@ void WaypointMovementGenerator<Creature>::LoadPath(Creature* creature) if (!i_path) { // No path id found for entry - TC_LOG_ERROR("sql.sql", "WaypointMovementGenerator::LoadPath: creature %s (%s DB GUID: " UI64FMTD ") doesn't have waypoint path id: %u", creature->GetName().c_str(), creature->GetGUID().ToString().c_str(), creature->GetDBTableGUIDLow(), path_id); + TC_LOG_ERROR("sql.sql", "WaypointMovementGenerator::LoadPath: creature %s (%s DB GUID: " UI64FMTD ") doesn't have waypoint path id: %u", creature->GetName().c_str(), creature->GetGUID().ToString().c_str(), creature->GetSpawnId(), path_id); return; } diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index 6667672aee0..0343e92c506 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -49,7 +49,7 @@ class DefenseMessageBuilder }; OPvPCapturePoint::OPvPCapturePoint(OutdoorPvP* pvp): - m_capturePointGUID(), m_capturePoint(NULL), m_maxValue(0.0f), m_minValue(0.0f), m_maxSpeed(0), + m_capturePointSpawnId(), m_capturePoint(NULL), m_maxValue(0.0f), m_minValue(0.0f), m_maxSpeed(0), m_value(0), m_team(TEAM_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL), m_State(OBJECTIVESTATE_NEUTRAL), m_neutralValuePct(0), m_PvP(pvp) { } @@ -85,31 +85,23 @@ void OPvPCapturePoint::SendChangePhase() SendUpdateWorldState(m_capturePoint->GetGOInfo()->controlZone.worldstate3, m_neutralValuePct); } -void OPvPCapturePoint::AddGO(uint32 type, uint32 mapId, ObjectGuid::LowType guid, uint32 entry /*= 0*/) +void OPvPCapturePoint::AddGO(uint32 type, ObjectGuid::LowType guid) { - if (!entry) - { - GameObjectData const* data = sObjectMgr->GetGOData(guid); - if (!data) - return; - entry = data->id; - } + GameObjectData const* data = sObjectMgr->GetGOData(guid); + if (!data) + return; - m_Objects[type] = ObjectGuid::Create<HighGuid::GameObject>(mapId, entry, guid); + m_Objects[type] = guid; m_ObjectTypes[m_Objects[type]] = type; } -void OPvPCapturePoint::AddCre(uint32 type, uint32 mapId, ObjectGuid::LowType guid, uint32 entry /*= 0*/) +void OPvPCapturePoint::AddCre(uint32 type, ObjectGuid::LowType guid) { - if (!entry) - { - CreatureData const* data = sObjectMgr->GetCreatureData(guid); - if (!data) - return; - entry = data->id; - } + CreatureData const* data = sObjectMgr->GetCreatureData(guid); + if (!data) + return; - m_Creatures[type] = ObjectGuid::Create<HighGuid::Creature>(mapId, entry, guid); + m_Creatures[type] = guid; m_CreatureTypes[m_Creatures[type]] = type; } @@ -117,7 +109,7 @@ bool OPvPCapturePoint::AddObject(uint32 type, uint32 entry, uint32 map, float x, { if (ObjectGuid::LowType guid = sObjectMgr->AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3)) { - AddGO(type, map, guid, entry); + AddGO(type, guid); return true; } @@ -128,7 +120,7 @@ bool OPvPCapturePoint::AddCreature(uint32 type, uint32 entry, uint32 map, float { if (ObjectGuid::LowType guid = sObjectMgr->AddCreData(entry, map, x, y, z, o, spawntimedelay)) { - AddCre(type, map, guid, entry); + AddCre(type, guid); return true; } @@ -147,8 +139,8 @@ bool OPvPCapturePoint::SetCapturePointData(uint32 entry, uint32 map, float x, fl return false; } - m_capturePointGUID = ObjectGuid::Create<HighGuid::GameObject>(map, entry, sObjectMgr->AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3)); - if (!m_capturePointGUID) + m_capturePointSpawnId = sObjectMgr->AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3); + if (!m_capturePointSpawnId) return false; // get the needed values from goinfo @@ -162,24 +154,23 @@ bool OPvPCapturePoint::SetCapturePointData(uint32 entry, uint32 map, float x, fl bool OPvPCapturePoint::DelCreature(uint32 type) { - if (!m_Creatures[type]) + ObjectGuid::LowType spawnId = m_Creatures[type]; + if (!spawnId) { TC_LOG_DEBUG("outdoorpvp", "opvp creature type %u was already deleted", type); return false; } - Creature* cr = HashMapHolder<Creature>::Find(m_Creatures[type]); - if (!cr) + auto bounds = m_PvP->GetMap()->GetCreatureBySpawnIdStore().equal_range(spawnId); + for (auto itr = bounds.first; itr != bounds.second; ++itr) { - // can happen when closing the core - m_Creatures[type].Clear(); - return false; + // Don't save respawn time + itr->second->SetRespawnTime(0); + itr->second->RemoveCorpse(); + itr->second->AddObjectToRemoveList(); } + TC_LOG_DEBUG("outdoorpvp", "deleting opvp creature type %u", type); - ObjectGuid::LowType guid = cr->GetDBTableGUIDLow(); - // Don't save respawn time - cr->SetRespawnTime(0); - cr->RemoveCorpse(); // explicit removal from map // beats me why this is needed, but with the recent removal "cleanup" some creatures stay in the map if "properly" deleted // so this is a big fat workaround, if AddObjectToRemoveList and DoDelayedMovesAndRemoves worked correctly, this wouldn't be needed @@ -187,15 +178,14 @@ bool OPvPCapturePoint::DelCreature(uint32 type) // map->Remove(cr, false); // delete respawn time for this creature PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); - stmt->setUInt64(0, guid); - stmt->setUInt16(1, cr->GetMapId()); + stmt->setUInt64(0, spawnId); + stmt->setUInt16(1, m_PvP->GetMap()->GetId()); stmt->setUInt32(2, 0); // instance id, always 0 for world maps CharacterDatabase.Execute(stmt); - cr->AddObjectToRemoveList(); - sObjectMgr->DeleteCreatureData(guid); + sObjectMgr->DeleteCreatureData(spawnId); m_CreatureTypes[m_Creatures[type]] = 0; - m_Creatures[type].Clear(); + m_Creatures[type] = 0; return true; } @@ -204,25 +194,25 @@ bool OPvPCapturePoint::DelObject(uint32 type) if (!m_Objects[type]) return false; - GameObject* obj = HashMapHolder<GameObject>::Find(m_Objects[type]); - if (!obj) + ObjectGuid::LowType spawnId = m_Objects[type]; + auto bounds = m_PvP->GetMap()->GetGameObjectBySpawnIdStore().equal_range(spawnId); + for (auto itr = bounds.first; itr != bounds.second; ++itr) { - m_Objects[type].Clear(); - return false; + // Don't save respawn time + itr->second->SetRespawnTime(0); + itr->second->Delete(); } - ObjectGuid::LowType guid = obj->GetDBTableGUIDLow(); - obj->SetRespawnTime(0); // not save respawn time - obj->Delete(); - sObjectMgr->DeleteGOData(guid); + + sObjectMgr->DeleteGOData(spawnId); m_ObjectTypes[m_Objects[type]] = 0; - m_Objects[type].Clear(); + m_Objects[type] = 0; return true; } bool OPvPCapturePoint::DelCapturePoint() { - sObjectMgr->DeleteGOData(m_capturePointGUID.GetCounter()); - m_capturePointGUID.Clear(); + sObjectMgr->DeleteGOData(m_capturePointSpawnId); + m_capturePointSpawnId = 0; if (m_capturePoint) { @@ -235,9 +225,9 @@ bool OPvPCapturePoint::DelCapturePoint() void OPvPCapturePoint::DeleteSpawns() { - for (std::map<uint32, ObjectGuid>::iterator i = m_Objects.begin(); i != m_Objects.end(); ++i) + for (std::map<uint32, ObjectGuid::LowType>::iterator i = m_Objects.begin(); i != m_Objects.end(); ++i) DelObject(i->first); - for (std::map<uint32, ObjectGuid>::iterator i = m_Creatures.begin(); i != m_Creatures.end(); ++i) + for (std::map<uint32, ObjectGuid::LowType>::iterator i = m_Creatures.begin(); i != m_Creatures.end(); ++i) DelCreature(i->first); DelCapturePoint(); } @@ -252,7 +242,7 @@ void OutdoorPvP::DeleteSpawns() m_capturePoints.clear(); } -OutdoorPvP::OutdoorPvP() : m_TypeId(0), m_sendUpdate(true) { } +OutdoorPvP::OutdoorPvP() : m_TypeId(0), m_sendUpdate(true), m_map(nullptr) { } OutdoorPvP::~OutdoorPvP() { @@ -512,19 +502,19 @@ bool OPvPCapturePoint::HandleCustomSpell(Player* player, uint32 /*spellId*/, Gam return true; } -bool OutdoorPvP::HandleOpenGo(Player* player, ObjectGuid guid) +bool OutdoorPvP::HandleOpenGo(Player* player, GameObject* go) { for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - if (itr->second->HandleOpenGo(player, guid) >= 0) + if (itr->second->HandleOpenGo(player, go) >= 0) return true; return false; } -bool OutdoorPvP::HandleGossipOption(Player* player, ObjectGuid guid, uint32 id) +bool OutdoorPvP::HandleGossipOption(Player* player, Creature* creature, uint32 id) { for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - if (itr->second->HandleGossipOption(player, guid, id)) + if (itr->second->HandleGossipOption(player, creature, id)) return true; return false; @@ -548,13 +538,12 @@ bool OutdoorPvP::HandleDropFlag(Player* player, uint32 id) return false; } -int32 OPvPCapturePoint::HandleOpenGo(Player* /*player*/, ObjectGuid guid) +int32 OPvPCapturePoint::HandleOpenGo(Player* /*player*/, GameObject* go) { - std::map<ObjectGuid, uint32>::iterator itr = m_ObjectTypes.find(guid); + std::map<ObjectGuid::LowType, uint32>::iterator itr = m_ObjectTypes.find(go->GetSpawnId()); if (itr != m_ObjectTypes.end()) - { return itr->second; - } + return -1; } @@ -569,16 +558,16 @@ void OutdoorPvP::BroadcastPacket(WorldPacket const* data) const void OutdoorPvP::AddCapturePoint(OPvPCapturePoint* cp) { - OPvPCapturePointMap::iterator i = m_capturePoints.find(cp->m_capturePointGUID); + OPvPCapturePointMap::iterator i = m_capturePoints.find(cp->m_capturePointSpawnId); if (i != m_capturePoints.end()) { - TC_LOG_ERROR("outdoorpvp", "OutdoorPvP::AddCapturePoint: CapturePoint %s already exists!", cp->m_capturePointGUID.ToString().c_str()); + TC_LOG_ERROR("outdoorpvp", "OutdoorPvP::AddCapturePoint: CapturePoint " UI64FMTD " already exists!", cp->m_capturePointSpawnId); delete i->second; } - m_capturePoints[cp->m_capturePointGUID] = cp; + m_capturePoints[cp->m_capturePointSpawnId] = cp; } -OPvPCapturePoint* OutdoorPvP::GetCapturePoint(ObjectGuid guid) const +OPvPCapturePoint* OutdoorPvP::GetCapturePoint(ObjectGuid::LowType guid) const { OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.find(guid); if (itr != m_capturePoints.end()) @@ -624,7 +613,7 @@ void OutdoorPvP::OnGameObjectCreate(GameObject* go) if (go->GetGoType() != GAMEOBJECT_TYPE_CONTROL_ZONE) return; - if (OPvPCapturePoint *cp = GetCapturePoint(go->GetGUID())) + if (OPvPCapturePoint *cp = GetCapturePoint(go->GetSpawnId())) cp->m_capturePoint = go; } @@ -633,7 +622,7 @@ void OutdoorPvP::OnGameObjectRemove(GameObject* go) if (go->GetGoType() != GAMEOBJECT_TYPE_CONTROL_ZONE) return; - if (OPvPCapturePoint *cp = GetCapturePoint(go->GetGUID())) + if (OPvPCapturePoint *cp = GetCapturePoint(go->GetSpawnId())) cp->m_capturePoint = NULL; } @@ -653,3 +642,12 @@ void OutdoorPvP::BroadcastWorker(Worker& _worker, uint32 zoneId) if (player->GetZoneId() == zoneId) _worker(player); } + +void OutdoorPvP::SetMapFromZone(uint32 zone) +{ + AreaTableEntry const* areaTable = GetAreaEntryByAreaID(zone); + ASSERT(areaTable); + Map* map = sMapMgr->CreateBaseMap(areaTable->MapID); + ASSERT(!map->Instanceable()); + m_map = map; +} diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index 1b7b086fd29..cb86f1e9056 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -109,7 +109,7 @@ class OPvPCapturePoint virtual bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go); - virtual int32 HandleOpenGo(Player* player, ObjectGuid guid); + virtual int32 HandleOpenGo(Player* player, GameObject* go); // returns true if the state of the objective has changed, in this case, the OutdoorPvP must send a world state ui update. virtual bool Update(uint32 diff); @@ -120,7 +120,7 @@ class OPvPCapturePoint virtual void SendChangePhase(); - virtual bool HandleGossipOption(Player* /*player*/, ObjectGuid /*guid*/, uint32 /*gossipId*/) { return false; } + virtual bool HandleGossipOption(Player* /*player*/, Creature* /*guid*/, uint32 /*gossipId*/) { return false; } virtual bool CanTalkTo(Player* /*player*/, Creature* /*creature*/, GossipMenuItems const& /*gso*/) { return false; } @@ -128,12 +128,12 @@ class OPvPCapturePoint virtual void DeleteSpawns(); - ObjectGuid m_capturePointGUID; + ObjectGuid::LowType m_capturePointSpawnId; GameObject* m_capturePoint; - void AddGO(uint32 type, uint32 mapId, ObjectGuid::LowType guid, uint32 entry = 0); - void AddCre(uint32 type, uint32 mapId, ObjectGuid::LowType guid, uint32 entry = 0); + void AddGO(uint32 type, ObjectGuid::LowType guid); + void AddCre(uint32 type, ObjectGuid::LowType guid); bool SetCapturePointData(uint32 entry, uint32 map, float x, float y, float z, float o = 0, float rotation0 = 0, float rotation1 = 0, float rotation2 = 0, float rotation3 = 0); @@ -178,10 +178,10 @@ class OPvPCapturePoint // map to store the various gameobjects and creatures spawned by the objective // type, guid - std::map<uint32, ObjectGuid> m_Objects; - std::map<uint32, ObjectGuid> m_Creatures; - std::map<ObjectGuid, uint32> m_ObjectTypes; - std::map<ObjectGuid, uint32> m_CreatureTypes; + std::map<uint32, ObjectGuid::LowType> m_Objects; + std::map<uint32, ObjectGuid::LowType> m_Creatures; + std::map<ObjectGuid::LowType, uint32> m_ObjectTypes; + std::map<ObjectGuid::LowType, uint32> m_CreatureTypes; }; // base class for specific outdoor pvp handlers @@ -200,7 +200,7 @@ class OutdoorPvP : public ZoneScript // deletes all gos/creatures spawned by the pvp void DeleteSpawns(); - typedef std::map<ObjectGuid/*guid*/, OPvPCapturePoint*> OPvPCapturePointMap; + typedef std::map<ObjectGuid::LowType/*spawnId*/, OPvPCapturePoint*> OPvPCapturePointMap; virtual void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates & /*packet*/) { } @@ -211,7 +211,7 @@ class OutdoorPvP : public ZoneScript virtual bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go); // called on go use - virtual bool HandleOpenGo(Player* player, ObjectGuid guid); + virtual bool HandleOpenGo(Player* player, GameObject* go); // setup stuff virtual bool SetupOutdoorPvP() {return true;} @@ -240,7 +240,7 @@ class OutdoorPvP : public ZoneScript virtual bool HandleDropFlag(Player* player, uint32 spellId); - virtual bool HandleGossipOption(Player* player, ObjectGuid guid, uint32 gossipid); + virtual bool HandleGossipOption(Player* player, Creature* creature, uint32 gossipid); virtual bool CanTalkTo(Player* player, Creature* c, GossipMenuItems const& gso); @@ -261,6 +261,8 @@ class OutdoorPvP : public ZoneScript void SendDefenseMessage(uint32 zoneId, uint32 id); + Map* GetMap() const { return m_map; } + protected: // the map of the objectives belonging to this outdoorpvp @@ -284,7 +286,7 @@ class OutdoorPvP : public ZoneScript void AddCapturePoint(OPvPCapturePoint* cp); - OPvPCapturePoint * GetCapturePoint(ObjectGuid guid) const; + OPvPCapturePoint* GetCapturePoint(ObjectGuid::LowType guid) const; void RegisterZone(uint32 zoneid); @@ -294,6 +296,11 @@ class OutdoorPvP : public ZoneScript template<class Worker> void BroadcastWorker(Worker& _worker, uint32 zoneId); + + // Hack to store map because this code is just shit + void SetMapFromZone(uint32 zone); + + Map* m_map; }; #endif /*OUTDOOR_PVP_H_*/ diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp index 62440eab44e..b07d21436b2 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -181,21 +181,21 @@ ZoneScript* OutdoorPvPMgr::GetZoneScript(uint32 zoneId) return NULL; } -bool OutdoorPvPMgr::HandleOpenGo(Player* player, ObjectGuid guid) +bool OutdoorPvPMgr::HandleOpenGo(Player* player, GameObject* go) { for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr) { - if ((*itr)->HandleOpenGo(player, guid)) + if ((*itr)->HandleOpenGo(player, go)) return true; } return false; } -void OutdoorPvPMgr::HandleGossipOption(Player* player, ObjectGuid guid, uint32 gossipid) +void OutdoorPvPMgr::HandleGossipOption(Player* player, Creature* creature, uint32 gossipid) { for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr) { - if ((*itr)->HandleGossipOption(player, guid, gossipid)) + if ((*itr)->HandleGossipOption(player, creature, gossipid)) return; } } diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h index 4f03dd37fac..542aad0ef0d 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h @@ -70,7 +70,7 @@ class OutdoorPvPMgr bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go); // handle custom go if registered - bool HandleOpenGo(Player* player, ObjectGuid guid); + bool HandleOpenGo(Player* player, GameObject* go); ZoneScript* GetZoneScript(uint32 zoneId); @@ -78,7 +78,7 @@ class OutdoorPvPMgr void Update(uint32 diff); - void HandleGossipOption(Player* player, ObjectGuid guid, uint32 gossipid); + void HandleGossipOption(Player* player, Creature* creature, uint32 gossipid); bool CanTalkTo(Player* player, Creature* creature, GossipMenuItems const& gso); diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 9f8a9f8686b..15f378e138a 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -221,8 +221,13 @@ void PoolGroup<Creature>::Despawn1Object(uint64 guid) { sObjectMgr->RemoveCreatureFromGrid(guid, data); - if (Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid::Create<HighGuid::Creature>(data->mapid, data->id, guid), (Creature*)NULL)) - creature->AddObjectToRemoveList(); + Map* map = sMapMgr->CreateBaseMap(data->mapid); + if (!map->Instanceable()) + { + auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(guid); + for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr) + itr->second->AddObjectToRemoveList(); + } } } @@ -234,8 +239,13 @@ void PoolGroup<GameObject>::Despawn1Object(uint64 guid) { sObjectMgr->RemoveGameobjectFromGrid(guid, data); - if (GameObject* pGameobject = ObjectAccessor::GetObjectInWorld(ObjectGuid::Create<HighGuid::GameObject>(data->mapid, data->id, guid), (GameObject*)NULL)) - pGameobject->AddObjectToRemoveList(); + Map* map = sMapMgr->CreateBaseMap(data->mapid); + if (!map->Instanceable()) + { + auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(guid); + for (auto itr = gameobjectBounds.first; itr != gameobjectBounds.second; ++itr) + itr->second->AddObjectToRemoveList(); + } } } @@ -507,20 +517,16 @@ void PoolGroup<Quest>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint64 // Method that does the respawn job on the specified creature template <> -void PoolGroup<Creature>::ReSpawn1Object(PoolObject* obj) +void PoolGroup<Creature>::ReSpawn1Object(PoolObject* /*obj*/) { - if (CreatureData const* data = sObjectMgr->GetCreatureData(obj->guid)) - if (Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid::Create<HighGuid::Creature>(data->mapid, data->id, obj->guid), (Creature*)NULL)) - creature->GetMap()->AddToMap(creature); + // Creature is still on map, nothing to do } // Method that does the respawn job on the specified gameobject template <> -void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* obj) +void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* /*obj*/) { - if (GameObjectData const* data = sObjectMgr->GetGOData(obj->guid)) - if (GameObject* pGameobject = ObjectAccessor::GetObjectInWorld(ObjectGuid::Create<HighGuid::GameObject>(data->mapid, data->id, obj->guid), (GameObject*)NULL)) - pGameobject->GetMap()->AddToMap(pGameobject); + // GameObject is still on map, nothing to do } // Nothing to do for a child Pool diff --git a/src/server/game/Scripting/MapScripts.cpp b/src/server/game/Scripting/MapScripts.cpp index 8797caf2cf7..1db3dbb9f93 100644 --- a/src/server/game/Scripting/MapScripts.cpp +++ b/src/server/game/Scripting/MapScripts.cpp @@ -321,26 +321,23 @@ void Map::ScriptsProcess() break; case HighGuid::Creature: case HighGuid::Vehicle: - source = HashMapHolder<Creature>::Find(step.sourceGUID); + source = GetCreature(step.sourceGUID); break; case HighGuid::Pet: - source = HashMapHolder<Pet>::Find(step.sourceGUID); + source = GetPet(step.sourceGUID); break; case HighGuid::Player: source = HashMapHolder<Player>::Find(step.sourceGUID); break; case HighGuid::GameObject: - source = HashMapHolder<GameObject>::Find(step.sourceGUID); + source = GetGameObject(step.sourceGUID); break; case HighGuid::Corpse: - source = HashMapHolder<Corpse>::Find(step.sourceGUID); + source = GetCorpse(step.sourceGUID); break; case HighGuid::Transport: - { - GameObject* go = HashMapHolder<GameObject>::Find(step.sourceGUID); - source = go ? go->ToTransport() : NULL; + source = GetTransport(step.sourceGUID); break; - } default: TC_LOG_ERROR("scripts", "%s source with unsupported high guid %s.", step.script->GetDebugInfo().c_str(), step.sourceGUID.ToString().c_str()); @@ -355,26 +352,23 @@ void Map::ScriptsProcess() { case HighGuid::Creature: case HighGuid::Vehicle: - target = HashMapHolder<Creature>::Find(step.targetGUID); + target = GetCreature(step.targetGUID); break; case HighGuid::Pet: - target = HashMapHolder<Pet>::Find(step.targetGUID); + target = GetPet(step.targetGUID); break; case HighGuid::Player: target = HashMapHolder<Player>::Find(step.targetGUID); break; case HighGuid::GameObject: - target = HashMapHolder<GameObject>::Find(step.targetGUID); + target = GetGameObject(step.targetGUID); break; case HighGuid::Corpse: - target = HashMapHolder<Corpse>::Find(step.targetGUID); + target = GetCorpse(step.targetGUID); break; case HighGuid::Transport: - { - GameObject* go = HashMapHolder<GameObject>::Find(step.targetGUID); - target = go ? go->ToTransport() : NULL; + target = GetTransport(step.targetGUID); break; - } default: TC_LOG_ERROR("scripts", "%s target with unsupported high guid %s.", step.script->GetDebugInfo().c_str(), step.targetGUID.ToString().c_str()); @@ -827,7 +821,11 @@ void Map::ScriptsProcess() else //check hashmap holders { if (CreatureData const* data = sObjectMgr->GetCreatureData(step.script->CallScript.CreatureEntry)) - cTarget = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, ObjectGuid::Create<HighGuid::Creature>(data->mapid, data->id, uint64(step.script->CallScript.CreatureEntry)), cTarget); + { + auto creatureBounds = _creatureBySpawnIdStore.equal_range(step.script->CallScript.CreatureEntry); + if (creatureBounds.first != creatureBounds.second) + cTarget = creatureBounds.first->second; + } } if (!cTarget) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 58ff14b9579..c3247b41b35 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1112,9 +1112,6 @@ void Aura::UnregisterSingleTarget() { ASSERT(m_isSingleTarget); Unit* caster = GetCaster(); - /// @todo find a better way to do this. - if (!caster) - caster = ObjectAccessor::GetObjectInOrOutOfWorld(GetCasterGUID(), (Unit*)NULL); ASSERT(caster); caster->GetSingleCastAuras().remove(this); SetIsSingleTarget(false); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 194467ccadf..e8da248160b 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2301,7 +2301,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) uint8 mask = target->effectMask; Unit* unit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID); - if (!unit) + if (!unit && target->targetGUID.IsPlayer()) // only players may be targeted across maps { uint8 farMask = 0; // create far target mask @@ -2312,14 +2312,15 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (!farMask) return; + // find unit in world - unit = ObjectAccessor::FindUnit(target->targetGUID); + unit = ObjectAccessor::FindPlayer(target->targetGUID); if (!unit) return; // do far effects on the unit // can't use default call because of threading, do stuff as fast as possible - for(SpellEffectInfo const* effect : GetEffects()) + for (SpellEffectInfo const* effect : GetEffects()) if (effect && (farMask & (1 << effect->EffectIndex))) HandleEffects(unit, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET); return; @@ -3507,7 +3508,7 @@ void Spell::_handle_finish_phase() if (m_caster->m_extraAttacks && HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) { - if (Unit* victim = ObjectAccessor::FindUnit(m_targets.GetOrigUnitTargetGUID())) + if (Unit* victim = ObjectAccessor::GetUnit(*m_caster, m_targets.GetOrigUnitTargetGUID())) m_caster->HandleProcExtraAttackFor(victim); else m_caster->m_extraAttacks = 0; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 06be95f3c26..372ff5faba8 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1604,7 +1604,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex) if (!caster->IsInWorld()) return; DynamicObject* dynObj = new DynamicObject(false); - if (!dynObj->CreateDynamicObject(sObjectMgr->GetGenerator<HighGuid::DynamicObject>()->Generate(), caster, m_spellInfo, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL)) + if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL)) { delete dynObj; return; @@ -1808,7 +1808,7 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype) /// @todo possible must be moved to loot release (in different from linked triggering) if (gameObjTarget->GetGOInfo()->chest.triggeredEvent) { - TC_LOG_DEBUG("spells", "Chest ScriptStart id %u for GO " UI64FMTD, gameObjTarget->GetGOInfo()->chest.triggeredEvent, gameObjTarget->GetDBTableGUIDLow()); + TC_LOG_DEBUG("spells", "Chest ScriptStart id %u for GO " UI64FMTD, gameObjTarget->GetGOInfo()->chest.triggeredEvent, gameObjTarget->GetSpawnId()); player->GetMap()->ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->chest.triggeredEvent, player, gameObjTarget); } @@ -1877,7 +1877,7 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex) /// @todo Add script for spell 41920 - Filling, becouse server it freze when use this spell // handle outdoor pvp object opening, return true if go was registered for handling // these objects must have been spawned by outdoorpvp! - else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget->GetGUID())) + else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget)) return; lockId = goInfo->GetLockId(); guid = gameObjTarget->GetGUID(); @@ -2426,7 +2426,7 @@ void Spell::EffectAddFarsight(SpellEffIndex /*effIndex*/) return; DynamicObject* dynObj = new DynamicObject(true); - if (!dynObj->CreateDynamicObject(sObjectMgr->GetGenerator<HighGuid::DynamicObject>()->Generate(), m_caster, m_spellInfo, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) + if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) { delete dynObj; return; @@ -3212,7 +3212,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) Map* map = target->GetMap(); - if (!pGameObj->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), gameobject_id, map, + if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { delete pGameObj; @@ -3239,7 +3239,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) if (uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry()) { GameObject* linkedGO = new GameObject; - if (linkedGO->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), linkedEntry, map, + if (linkedGO->Create(map->GenerateLowGuid<HighGuid::GameObject>(), linkedEntry, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { linkedGO->CopyPhaseFrom(m_caster); @@ -3865,7 +3865,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) uint32 gameobject_id = effectInfo->MiscValue; Map* map = m_caster->GetMap(); - if (!pGameObj->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), gameobject_id, + if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, 0, m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2, m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2, @@ -4244,7 +4244,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); Map* map = m_caster->GetMap(); - if (!go->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), go_id, map, + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), go_id, map, 0, x, y, z, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete go; @@ -4881,7 +4881,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) GameObject* pGameObj = new GameObject; - if (!pGameObj->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), name_id, cMap, + if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, 0, fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { delete pGameObj; @@ -4949,7 +4949,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) if (uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry()) { GameObject* linkedGO = new GameObject; - if (linkedGO->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), linkedEntry, cMap, + if (linkedGO->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), linkedEntry, cMap, 0, fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { linkedGO->CopyPhaseFrom(m_caster); @@ -5766,7 +5766,7 @@ void Spell::EffectCreateAreaTrigger(SpellEffIndex /*effIndex*/) uint32 triggerEntry = effectInfo->MiscValue; AreaTrigger * areaTrigger = new AreaTrigger; - if (!areaTrigger->CreateAreaTrigger(sObjectMgr->GetGenerator<HighGuid::AreaTrigger>()->Generate(), triggerEntry, GetCaster(), GetSpellInfo(), pos)) + if (!areaTrigger->CreateAreaTrigger(GetCaster()->GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>(), triggerEntry, GetCaster(), GetSpellInfo(), pos)) delete areaTrigger; } diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 5497f4cc0e3..71719c19b3a 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -417,19 +417,19 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s // make sure the same guid doesn't already exist and is safe to use bool incHighest = true; - if (guid && guid < sObjectMgr->GetGenerator<HighGuid::Player>()->GetNextAfterMaxUsed()) + if (guid && guid < sObjectMgr->GetGenerator<HighGuid::Player>().GetNextAfterMaxUsed()) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_GUID); stmt->setUInt64(0, guid); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) - guid = sObjectMgr->GetGenerator<HighGuid::Player>()->GetNextAfterMaxUsed(); // use first free if exists + guid = sObjectMgr->GetGenerator<HighGuid::Player>().GetNextAfterMaxUsed(); // use first free if exists else incHighest = false; } else - guid = sObjectMgr->GetGenerator<HighGuid::Player>()->GetNextAfterMaxUsed(); + guid = sObjectMgr->GetGenerator<HighGuid::Player>().GetNextAfterMaxUsed(); // normalize the name if specified and check if it exists if (!normalizePlayerName(name)) @@ -464,7 +464,7 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s uint8 playerClass = 0; uint8 level = 1; - ObjectGuid::LowType itemLowGuidOffset = sObjectMgr->GetGenerator<HighGuid::Item>()->GetNextAfterMaxUsed(); + ObjectGuid::LowType itemLowGuidOffset = sObjectMgr->GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed(); SQLTransaction trans = CharacterDatabase.BeginTransaction(); while (!feof(fin)) @@ -683,11 +683,11 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s // in case of name conflict player has to rename at login anyway sWorld->AddCharacterInfo(ObjectGuid::Create<HighGuid::Player>(guid), name, gender, race, playerClass, level, false); - sObjectMgr->GetGenerator<HighGuid::Item>()->Set(sObjectMgr->GetGenerator<HighGuid::Item>()->GetNextAfterMaxUsed() + items.size()); + sObjectMgr->GetGenerator<HighGuid::Item>().Set(sObjectMgr->GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed() + items.size()); sObjectMgr->_mailId += mails.size(); if (incHighest) - sObjectMgr->GetGenerator<HighGuid::Player>()->Generate(); + sObjectMgr->GetGenerator<HighGuid::Player>().Generate(); fclose(fin); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 05f75358a7b..94f13abfb6c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1476,15 +1476,6 @@ void World::SetInitialWorldSettings() LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmHandle.Index); // One-time query - ///- Remove the bones (they should not exist in DB though) and old corpses after a restart - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CORPSES); - stmt->setUInt32(0, 3 * DAY); - CharacterDatabase.Execute(stmt); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CORPSE_PHASES); - stmt->setUInt32(0, 3 * DAY); - CharacterDatabase.Execute(stmt); - ///- Load the DBC files TC_LOG_INFO("server.loading", "Initialize data stores..."); LoadDBCStores(m_dataPath); @@ -1743,9 +1734,6 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading pet level stats..."); sObjectMgr->LoadPetLevelInfo(); - TC_LOG_INFO("server.loading", "Loading Player Corpses..."); - sObjectMgr->LoadCorpses(); - TC_LOG_INFO("server.loading", "Loading Player level dependent mail rewards..."); sObjectMgr->LoadMailLevelRewards(); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index bfc61ad9f78..ecd98595723 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -504,7 +504,7 @@ public: return false; handler->PSendSysMessage("Loot recipient for creature %s (%s, DB GUID " UI64FMTD ") is %s", - target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetDBTableGUIDLow(), + target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetSpawnId(), target->hasLootRecipient() ? (target->GetLootRecipient() ? target->GetLootRecipient()->GetName().c_str() : "offline") : "no loot recipient"); return true; } @@ -931,7 +931,7 @@ public: Map* map = handler->GetSession()->GetPlayer()->GetMap(); - if (!v->Create(sObjectMgr->GetGenerator<HighGuid::Vehicle>()->Generate(), map, handler->GetSession()->GetPlayer()->GetPhaseMask(), entry, x, y, z, o, nullptr, id)) + if (!v->Create(map->GenerateLowGuid<HighGuid::Vehicle>(), map, handler->GetSession()->GetPlayer()->GetPhaseMask(), entry, x, y, z, o, nullptr, id)) { delete v; return false; diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index cae6765ad3e..c12c9b5d43e 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -143,16 +143,6 @@ public: Transport* transport = NULL; - if (Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid::Create<HighGuid::Creature>(mapId, id, guid), (Creature*)NULL)) - { - x = creature->GetPositionX(); - y = creature->GetPositionY(); - z = creature->GetPositionZ(); - o = creature->GetOrientation(); - mapId = creature->GetMapId(); - transport = creature->GetTransport(); - } - if (!MapManager::IsValidMapCoord(mapId, x, y, z, o) || sObjectMgr->IsTransportMap(mapId)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapId); diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 7d356949d48..ef52f6ebd95 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -150,7 +150,7 @@ public: Map* map = player->GetMap(); GameObject* object = new GameObject; - ObjectGuid::LowType guidLow = sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(); + ObjectGuid::LowType guidLow = map->GenerateLowGuid<HighGuid::GameObject>(); if (!object->Create(guidLow, objectInfo->entry, map, 0, x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 9ee32d0c6e5..5dc1696057e 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -262,7 +262,7 @@ public: if (Transport* trans = chr->GetTransport()) { - ObjectGuid::LowType guid = sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(); + ObjectGuid::LowType guid = map->GenerateLowGuid<HighGuid::Creature>(); CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid); data.id = id; data.phaseMask = chr->GetPhaseMask(); @@ -280,7 +280,7 @@ public: } Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), map, chr->GetPhaseMask(), id, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, chr->GetPhaseMask(), id, x, y, z, o)) { delete creature; return false; @@ -288,7 +288,7 @@ public: creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); - ObjectGuid::LowType db_guid = creature->GetDBTableGUIDLow(); + ObjectGuid::LowType db_guid = creature->GetSpawnId(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells() // current "creature" variable is deleted and created fresh new, otherwise old values might trigger asserts or cause undefined behavior @@ -395,7 +395,7 @@ public: else { // obtain real GUID for DB operations - lowGuid = creature->GetDBTableGUIDLow(); + lowGuid = creature->GetSpawnId(); } int wait = waitStr ? atoi(waitStr) : 0; @@ -738,7 +738,7 @@ public: std::string curRespawnDelayStr = secsToTimeString(uint64(curRespawnDelay), true); std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), true); - handler->PSendSysMessage(LANG_NPCINFO_CHAR, target->GetDBTableGUIDLow(), target->GetGUID().ToString().c_str(), faction, npcflags, Entry, displayid, nativeid); + handler->PSendSysMessage(LANG_NPCINFO_CHAR, target->GetSpawnId(), target->GetGUID().ToString().c_str(), faction, npcflags, Entry, displayid, nativeid); handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); handler->PSendSysMessage(LANG_NPCINFO_EQUIPMENT, target->GetCurrentEquipmentId(), target->GetOriginalEquipmentId()); handler->PSendSysMessage(LANG_NPCINFO_HEALTH, target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); @@ -863,12 +863,12 @@ public: } else { - lowguid = creature->GetDBTableGUIDLow(); + lowguid = creature->GetSpawnId(); } } else { - lowguid = creature->GetDBTableGUIDLow(); + lowguid = creature->GetSpawnId(); } float x = handler->GetSession()->GetPlayer()->GetPositionX(); @@ -878,7 +878,7 @@ public: if (creature) { - if (CreatureData const* data = sObjectMgr->GetCreatureData(creature->GetDBTableGUIDLow())) + if (CreatureData const* data = sObjectMgr->GetCreatureData(creature->GetSpawnId())) { const_cast<CreatureData*>(data)->posX = x; const_cast<CreatureData*>(data)->posY = y; @@ -1022,7 +1022,7 @@ public: creature = handler->getSelectedCreature(); if (!creature || creature->IsPet()) return false; - lowguid = creature->GetDBTableGUIDLow(); + lowguid = creature->GetSpawnId(); } else // case .setmovetype #creature_guid $move_type (with selected creature) { @@ -1046,7 +1046,7 @@ public: } else { - lowguid = creature->GetDBTableGUIDLow(); + lowguid = creature->GetSpawnId(); } } @@ -1174,7 +1174,7 @@ public: ObjectGuid::LowType guidLow = UI64LIT(0); if (creature) - guidLow = creature->GetDBTableGUIDLow(); + guidLow = creature->GetSpawnId(); else return false; @@ -1223,7 +1223,7 @@ public: ObjectGuid::LowType guidLow = UI64LIT(0); if (creature) - guidLow = creature->GetDBTableGUIDLow(); + guidLow = creature->GetSpawnId(); else return false; @@ -1487,14 +1487,14 @@ public: ObjectGuid::LowType leaderGUID = strtoull(args, nullptr, 10); Creature* creature = handler->getSelectedCreature(); - if (!creature || !creature->GetDBTableGUIDLow()) + if (!creature || !creature->GetSpawnId()) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } - ObjectGuid::LowType lowguid = creature->GetDBTableGUIDLow(); + ObjectGuid::LowType lowguid = creature->GetSpawnId(); if (creature->GetFormation()) { handler->PSendSysMessage("Selected creature is already member of group " UI64FMTD, creature->GetFormation()->GetId()); @@ -1547,21 +1547,21 @@ public: return false; } - if (!creature->GetDBTableGUIDLow()) + if (!creature->GetSpawnId()) { handler->PSendSysMessage("Selected %s isn't in creature table", creature->GetGUID().ToString().c_str()); handler->SetSentErrorMessage(true); return false; } - if (!sObjectMgr->SetCreatureLinkedRespawn(creature->GetDBTableGUIDLow(), linkguid)) + if (!sObjectMgr->SetCreatureLinkedRespawn(creature->GetSpawnId(), linkguid)) { handler->PSendSysMessage("Selected creature can't link with guid '" UI64FMTD "'", linkguid); handler->SetSentErrorMessage(true); return false; } - handler->PSendSysMessage("LinkGUID '" UI64FMTD "' added to creature with DBTableGUID: '" UI64FMTD "'", linkguid, creature->GetDBTableGUIDLow()); + handler->PSendSysMessage("LinkGUID '" UI64FMTD "' added to creature with DBTableGUID: '" UI64FMTD "'", linkguid, creature->GetSpawnId()); return true; } diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index a4e0ce3af61..358b6fff085 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -179,7 +179,7 @@ public: return true; } - guidLow = target->GetDBTableGUIDLow(); + guidLow = target->GetSpawnId(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_ADDON_BY_GUID); @@ -246,7 +246,7 @@ public: return true; } - ObjectGuid::LowType guidLow = target->GetDBTableGUIDLow(); + ObjectGuid::LowType guidLow = target->GetSpawnId(); if (!guidLow) { handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target is not saved to DB."); @@ -674,7 +674,7 @@ public: } // re-create Creature* wpCreature2 = new Creature(); - if (!wpCreature2->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), map, chr->GetPhaseMask(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) + if (!wpCreature2->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, chr->GetPhaseMask(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; @@ -687,7 +687,7 @@ public: wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); /// @todo Should we first use "Create" then use "LoadFromDB"? - if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map)) + if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetSpawnId(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; @@ -894,7 +894,7 @@ public: float o = chr->GetOrientation(); Creature* wpCreature = new Creature(); - if (!wpCreature->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), map, chr->GetPhaseMask(), id, x, y, z, o)) + if (!wpCreature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, chr->GetPhaseMask(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; @@ -912,7 +912,7 @@ public: wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); - if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map)) + if (!wpCreature->LoadCreatureFromDB(wpCreature->GetSpawnId(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; @@ -958,7 +958,7 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), map, chr->GetPhaseMask(), id, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, chr->GetPhaseMask(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; @@ -968,7 +968,7 @@ public: creature->CopyPhaseFrom(chr); creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); - if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) + if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; @@ -1009,7 +1009,7 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GetGenerator<HighGuid::Creature>()->Generate(), map, chr->GetPhaseMask(), id, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Creature>(), map, chr->GetPhaseMask(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; @@ -1019,7 +1019,7 @@ public: creature->CopyPhaseFrom(chr); creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); - if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) + if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index 21214b62345..6e1c15ca909 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -376,7 +376,7 @@ class boss_prince_keleseth_icc : public CreatureScript void InitializeAI() override { - if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow())) + if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetSpawnId())) if (data->curhealth) _spawnHealth = data->curhealth; @@ -591,7 +591,7 @@ class boss_prince_taldaram_icc : public CreatureScript void InitializeAI() override { - if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow())) + if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetSpawnId())) if (data->curhealth) _spawnHealth = data->curhealth; @@ -815,7 +815,7 @@ class boss_prince_valanar_icc : public CreatureScript void InitializeAI() override { - if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow())) + if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetSpawnId())) if (data->curhealth) _spawnHealth = data->curhealth; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp index 432a61b6279..816895684f1 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -492,7 +492,7 @@ public: _caster->CastSpell(_caster, _spellId, true); _caster->GetTransport()->AddObjectToRemoveList(); - if (GameObject* go = HashMapHolder<GameObject>::Find(_otherTransport)) + if (Transport* go = HashMapHolder<Transport>::Find(_otherTransport)) go->AddObjectToRemoveList(); return true; @@ -764,9 +764,8 @@ class npc_gunship : public CreatureScript if (isVictory) { - if (GameObject* go = HashMapHolder<GameObject>::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) - if (Transport* otherTransport = go->ToTransport()) - otherTransport->EnableMovement(true); + if (Transport* otherTransport = HashMapHolder<Transport>::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) + otherTransport->EnableMovement(true); me->GetTransport()->EnableMovement(true); @@ -1029,9 +1028,8 @@ class npc_high_overlord_saurfang_igb : public CreatureScript if (Transport* orgrimsHammer = me->GetTransport()) orgrimsHammer->SummonPassenger(NPC_TELEPORT_PORTAL, OrgrimsHammerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, NULL, 21000); - if (GameObject* go = HashMapHolder<GameObject>::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) - if (Transport* skybreaker = go->ToTransport()) - skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, NULL, 23000); + if (Transport* skybreaker = HashMapHolder<Transport>::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) + skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, NULL, 23000); _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6000); _events.ScheduleEvent(EVENT_ADDS, 60000); @@ -1302,9 +1300,8 @@ class npc_muradin_bronzebeard_igb : public CreatureScript if (Transport* skybreaker = me->GetTransport()) skybreaker->SummonPassenger(NPC_TELEPORT_PORTAL, SkybreakerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, NULL, 21000); - if (GameObject* go = HashMapHolder<GameObject>::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) - if (Transport* orgrimsHammer = go->ToTransport()) - orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, NULL, 23000); + if (Transport* orgrimsHammer = HashMapHolder<Transport>::Find(_instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) + orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, NULL, 23000); _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6000); _events.ScheduleEvent(EVENT_ADDS, 60000); @@ -1448,9 +1445,8 @@ struct npc_gunship_boarding_addAI : public gunship_npc_AI if (!myTransport) return; - if (GameObject* go = HashMapHolder<GameObject>::Find(Instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) - if (Transport* destTransport = go->ToTransport()) - destTransport->CalculatePassengerPosition(x, y, z, &o); + if (Transport* destTransport = HashMapHolder<Transport>::Find(Instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE))) + destTransport->CalculatePassengerPosition(x, y, z, &o); float angle = frand(0, float(M_PI) * 2.0f); x += 2.0f * std::cos(angle); @@ -2346,7 +2342,7 @@ class spell_igb_gunship_fall_teleport : public SpellScriptLoader void SelectTransport(WorldObject*& target) { if (InstanceScript* instance = target->GetInstanceScript()) - target = HashMapHolder<GameObject>::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)); + target = HashMapHolder<Transport>::Find(instance->GetGuidData(DATA_ICECROWN_GUNSHIP_BATTLE)); } void RelocateDest(SpellEffIndex /*effIndex*/) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 5a2376b8266..7bd1dee15ca 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -647,7 +647,7 @@ class npc_spinestalker : public CreatureScript // Increase add count if (!me->isDead()) { - _instance->SetGuidData(DATA_SINDRAGOSA_FROSTWYRMS, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetDBTableGUIDLow())); // this cannot be in Reset because reset also happens on evade + _instance->SetGuidData(DATA_SINDRAGOSA_FROSTWYRMS, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetSpawnId())); // this cannot be in Reset because reset also happens on evade Reset(); } } @@ -670,7 +670,7 @@ class npc_spinestalker : public CreatureScript void JustRespawned() override { ScriptedAI::JustRespawned(); - _instance->SetGuidData(DATA_SINDRAGOSA_FROSTWYRMS, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetDBTableGUIDLow())); // this cannot be in Reset because reset also happens on evade + _instance->SetGuidData(DATA_SINDRAGOSA_FROSTWYRMS, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetSpawnId())); // this cannot be in Reset because reset also happens on evade } void JustDied(Unit* /*killer*/) override @@ -783,7 +783,7 @@ class npc_rimefang : public CreatureScript // Increase add count if (!me->isDead()) { - _instance->SetGuidData(DATA_SINDRAGOSA_FROSTWYRMS, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetDBTableGUIDLow())); // this cannot be in Reset because reset also happens on evade + _instance->SetGuidData(DATA_SINDRAGOSA_FROSTWYRMS, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetSpawnId())); // this cannot be in Reset because reset also happens on evade Reset(); } } @@ -806,7 +806,7 @@ class npc_rimefang : public CreatureScript void JustRespawned() override { ScriptedAI::JustRespawned(); - _instance->SetGuidData(DATA_SINDRAGOSA_FROSTWYRMS, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetDBTableGUIDLow())); // this cannot be in Reset because reset also happens on evade + _instance->SetGuidData(DATA_SINDRAGOSA_FROSTWYRMS, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetSpawnId())); // this cannot be in Reset because reset also happens on evade } void JustDied(Unit* /*killer*/) override @@ -950,7 +950,7 @@ class npc_sindragosa_trash : public CreatureScript if (!me->isDead()) { if (me->GetEntry() == NPC_FROSTWING_WHELP) - _instance->SetGuidData(_frostwyrmId, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetDBTableGUIDLow())); // this cannot be in Reset because reset also happens on evade + _instance->SetGuidData(_frostwyrmId, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetSpawnId())); // this cannot be in Reset because reset also happens on evade Reset(); } } @@ -973,7 +973,7 @@ class npc_sindragosa_trash : public CreatureScript // Increase add count if (me->GetEntry() == NPC_FROSTWING_WHELP) - _instance->SetGuidData(_frostwyrmId, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetDBTableGUIDLow())); // this cannot be in Reset because reset also happens on evade + _instance->SetGuidData(_frostwyrmId, ObjectGuid::Create<HighGuid::Creature>(631, me->GetEntry(), me->GetSpawnId())); // this cannot be in Reset because reset also happens on evade } void SetData(uint32 type, uint32 data) override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index b8f2c9c5a4f..c04d53079c5 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -156,7 +156,7 @@ class RisenArchmageCheck bool operator()(Creature* creature) { return creature->IsAlive() && creature->GetEntry() == NPC_RISEN_ARCHMAGE && - creature->GetDBTableGUIDLow() && !creature->IsInCombat(); + creature->GetSpawnId() && !creature->IsInCombat(); } }; @@ -244,7 +244,7 @@ class ValithriaDespawner : public BasicEvent creature->DespawnOrUnsummon(); return; case NPC_RISEN_ARCHMAGE: - if (!creature->GetDBTableGUIDLow()) + if (!creature->GetSpawnId()) { creature->DespawnOrUnsummon(); return; @@ -297,7 +297,7 @@ class boss_valithria_dreamwalker : public CreatureScript void InitializeAI() override { - if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow())) + if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetSpawnId())) if (data->curhealth) _spawnHealth = data->curhealth; @@ -712,7 +712,7 @@ class npc_risen_archmage : public CreatureScript void EnterCombat(Unit* /*target*/) override { me->FinishSpell(CURRENT_CHANNELED_SPELL, false); - if (me->GetDBTableGUIDLow() && _canCallEnterCombat) + if (me->GetSpawnId() && _canCallEnterCombat) { std::list<Creature*> archmages; RisenArchmageCheck check; @@ -750,7 +750,7 @@ class npc_risen_archmage : public CreatureScript void UpdateAI(uint32 diff) override { if (!me->IsInCombat()) - if (me->GetDBTableGUIDLow()) + if (me->GetSpawnId()) if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) DoCast(me, SPELL_CORRUPTION); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 91702f3a0da..30b797bf98d 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -545,7 +545,7 @@ class npc_highlord_tirion_fordring_lh : public CreatureScript case EVENT_MURADIN_RUN: case EVENT_SAURFANG_RUN: if (Creature* factionNPC = ObjectAccessor::GetCreature(*me, _factionNPC)) - factionNPC->GetMotionMaster()->MovePath(factionNPC->GetDBTableGUIDLow() * 10, false); + factionNPC->GetMotionMaster()->MovePath(factionNPC->GetSpawnId() * 10, false); me->setActive(false); _damnedKills = 3; break; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 594ac140094..aee14edd0c3 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -419,14 +419,14 @@ class instance_icecrown_citadel : public InstanceMapScript if (creature->AI()->GetData(1/*DATA_FROSTWYRM_OWNER*/) == DATA_SPINESTALKER) { - SpinestalkerTrash.erase(creature->GetDBTableGUIDLow()); + SpinestalkerTrash.erase(creature->GetSpawnId()); if (SpinestalkerTrash.empty()) if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID)) spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM); } else { - RimefangTrash.erase(creature->GetDBTableGUIDLow()); + RimefangTrash.erase(creature->GetSpawnId()); if (RimefangTrash.empty()) if (Creature* spinestalk = instance->GetCreature(RimefangGUID)) spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM); @@ -441,7 +441,7 @@ class instance_icecrown_citadel : public InstanceMapScript if (GetBossState(DATA_SINDRAGOSA) == DONE) return; - FrostwyrmGUIDs.erase(creature->GetDBTableGUIDLow()); + FrostwyrmGUIDs.erase(creature->GetSpawnId()); if (FrostwyrmGUIDs.empty()) { instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY()); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 46fb538d576..79a7c5cb772 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -74,7 +74,7 @@ public: void SpawnGameObject(uint32 entry, Position& pos) { GameObject* go = new GameObject; - if (!go->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), entry, instance, + if (!go->Create(instance->GenerateLowGuid<HighGuid::GameObject>(), entry, instance, PHASEMASK_NORMAL, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0, 0, 0, 0, 120, GO_STATE_READY)) { diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp index 438ac9b67ec..f0be400f9c6 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp @@ -15,6 +15,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "MapManager.h" #include "ScriptMgr.h" #include "OutdoorPvPHP.h" #include "OutdoorPvP.h" @@ -64,6 +65,8 @@ bool OutdoorPvPHP::SetupOutdoorPvP() { m_AllianceTowersControlled = 0; m_HordeTowersControlled = 0; + SetMapFromZone(OutdoorPvPHPBuffZones[0]); + // add the zones affected by the pvp buff for (int i = 0; i < OutdoorPvPHPBuffZonesNum; ++i) RegisterZone(OutdoorPvPHPBuffZones[i]); @@ -238,16 +241,14 @@ void OPvPCapturePointHP::ChangeState() break; } - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[m_TowerType]); - if (flag) - { - flag->SetGoArtKit(artkit); - } - if (flag2) - { - flag2->SetGoArtKit(artkit2); - } + Map* map = sMapMgr->FindMap(530, 0); + auto bounds = map->GetGameObjectBySpawnIdStore().equal_range(m_capturePointSpawnId); + for (auto itr = bounds.first; itr != bounds.second; ++itr) + itr->second->SetGoArtKit(artkit); + + bounds = map->GetGameObjectBySpawnIdStore().equal_range(m_Objects[m_TowerType]); + for (auto itr = bounds.first; itr != bounds.second; ++itr) + itr->second->SetGoArtKit(artkit2); // send world state update if (field) diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp index 258ff9ef631..1fb5a218f88 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp @@ -15,6 +15,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "MapManager.h" #include "ScriptMgr.h" #include "OutdoorPvPNA.h" #include "Player.h" @@ -43,7 +44,7 @@ void OutdoorPvPNA::HandleKillImpl(Player* player, Unit* killed) uint32 OPvPCapturePointNA::GetAliveGuardsCount() { uint32 cnt = 0; - for (std::map<uint32, ObjectGuid>::iterator itr = m_Creatures.begin(); itr != m_Creatures.end(); ++itr) + for (std::map<uint32, ObjectGuid::LowType>::iterator itr = m_Creatures.begin(); itr != m_Creatures.end(); ++itr) { switch (itr->first) { @@ -62,10 +63,13 @@ uint32 OPvPCapturePointNA::GetAliveGuardsCount() case NA_NPC_GUARD_13: case NA_NPC_GUARD_14: case NA_NPC_GUARD_15: - if (Creature const* const cr = HashMapHolder<Creature>::Find(itr->second)) - if (cr->IsAlive()) + { + auto bounds = m_PvP->GetMap()->GetCreatureBySpawnIdStore().equal_range(itr->second); + for (auto itr2 = bounds.first; itr2 != bounds.second; ++itr2) + if (itr2->second->IsAlive()) ++cnt; break; + } default: break; } @@ -186,6 +190,7 @@ bool OutdoorPvPNA::SetupOutdoorPvP() { // m_TypeId = OUTDOOR_PVP_NA; _MUST_ be set in ctor, because of spawns cleanup // add the zones affected by the pvp buff + SetMapFromZone(NA_BUFF_ZONE); RegisterZone(NA_BUFF_ZONE); // halaa @@ -372,9 +377,9 @@ bool OPvPCapturePointNA::HandleCustomSpell(Player* player, uint32 spellId, GameO return false; } -int32 OPvPCapturePointNA::HandleOpenGo(Player* player, ObjectGuid guid) +int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go) { - int32 retval = OPvPCapturePoint::HandleOpenGo(player, guid); + int32 retval = OPvPCapturePoint::HandleOpenGo(player, go); if (retval >= 0) { const go_type * gos = NULL; @@ -567,11 +572,9 @@ void OPvPCapturePointNA::ChangeState() break; } - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - if (flag) - { - flag->SetGoArtKit(artkit); - } + auto bounds = sMapMgr->FindMap(530, 0)->GetGameObjectBySpawnIdStore().equal_range(m_capturePointSpawnId); + for (auto itr = bounds.first; itr != bounds.second; ++itr) + itr->second->SetGoArtKit(artkit); UpdateHalaaWorldState(); } diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h index a3c254ea6a5..c2dd71ce7cf 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.h @@ -269,7 +269,7 @@ class OPvPCapturePointNA : public OPvPCapturePoint bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go); - int32 HandleOpenGo(Player* player, ObjectGuid guid) override; + int32 HandleOpenGo(Player* player, GameObject* go) override; uint32 GetAliveGuardsCount(); uint32 GetControllingFaction() const; diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp index 6496b54dd82..233f1151b4e 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp @@ -58,6 +58,8 @@ void OutdoorPvPSI::UpdateWorldState() bool OutdoorPvPSI::SetupOutdoorPvP() { + SetMapFromZone(OutdoorPvPSIBuffZones[0]); + for (uint8 i = 0; i < OutdoorPvPSIBuffZonesNum; ++i) RegisterZone(OutdoorPvPSIBuffZones[i]); return true; @@ -166,7 +168,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) return true; } - if (!go->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0, 0, 0, 100, GO_STATE_READY)) + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0, 0, 0, 100, GO_STATE_READY)) { delete go; return true; @@ -202,7 +204,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) return true; } - if (!go->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0, 0, 0, 100, GO_STATE_READY)) + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), SI_SILITHYST_MOUND, map, player->GetPhaseMask(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), 0, 0, 0, 0, 100, GO_STATE_READY)) { delete go; return true; diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp index af0c824006a..12c77ad556e 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp @@ -15,6 +15,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "MapManager.h" #include "ScriptMgr.h" #include "OutdoorPvPTF.h" #include "OutdoorPvPMgr.h" @@ -224,6 +225,8 @@ bool OutdoorPvPTF::SetupOutdoorPvP() second_digit = 0; first_digit = 0; + SetMapFromZone(OutdoorPvPTFBuffZones[0]); + // add the zones affected by the pvp buff for (uint8 i = 0; i < OutdoorPvPTFBuffZonesNum; ++i) RegisterZone(OutdoorPvPTFBuffZones[i]); @@ -307,9 +310,9 @@ void OPvPCapturePointTF::ChangeState() break; } - GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID); - if (flag) - flag->SetGoArtKit(artkit); + auto bounds = sMapMgr->FindMap(530, 0)->GetGameObjectBySpawnIdStore().equal_range(m_capturePointSpawnId); + for (auto itr = bounds.first; itr != bounds.second; ++itr) + itr->second->SetGoArtKit(artkit); UpdateTowerState(); } diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp index c1b2712d29d..6ac1362d9d8 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp @@ -15,6 +15,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "MapManager.h" #include "ScriptMgr.h" #include "OutdoorPvPZM.h" #include "ObjectMgr.h" @@ -151,6 +152,8 @@ bool OutdoorPvPZM::SetupOutdoorPvP() m_AllianceTowersControlled = 0; m_HordeTowersControlled = 0; + SetMapFromZone(OutdoorPvPZMBuffZones[0]); + // add the zones affected by the pvp buff for (uint8 i = 0; i < OutdoorPvPZMBuffZonesNum; ++i) RegisterZone(OutdoorPvPZMBuffZones[i]); @@ -181,9 +184,9 @@ bool OPvPCapturePointZM_GraveYard::Update(uint32 /*diff*/) return retval; } -int32 OPvPCapturePointZM_GraveYard::HandleOpenGo(Player* player, ObjectGuid guid) +int32 OPvPCapturePointZM_GraveYard::HandleOpenGo(Player* player, GameObject* go) { - int32 retval = OPvPCapturePoint::HandleOpenGo(player, guid); + int32 retval = OPvPCapturePoint::HandleOpenGo(player, go); if (retval >= 0) { if (player->HasAura(ZM_BATTLE_STANDARD_A) && m_GraveYardState != ZM_GRAVEYARD_A) @@ -297,8 +300,7 @@ void OPvPCapturePointZM_GraveYard::SetBeaconState(uint32 controlling_faction) bool OPvPCapturePointZM_GraveYard::CanTalkTo(Player* player, Creature* c, GossipMenuItems const& /*gso*/) { - ObjectGuid guid = c->GetGUID(); - std::map<ObjectGuid, uint32>::iterator itr = m_CreatureTypes.find(guid); + std::map<ObjectGuid::LowType, uint32>::iterator itr = m_CreatureTypes.find(c->GetSpawnId()); if (itr != m_CreatureTypes.end()) { if (itr->second == ZM_ALLIANCE_FIELD_SCOUT && player->GetTeam() == ALLIANCE && m_BothControllingFaction == ALLIANCE && !m_FlagCarrierGUID && m_GraveYardState != ZM_GRAVEYARD_A) @@ -309,25 +311,22 @@ bool OPvPCapturePointZM_GraveYard::CanTalkTo(Player* player, Creature* c, Gossip return false; } -bool OPvPCapturePointZM_GraveYard::HandleGossipOption(Player* player, ObjectGuid guid, uint32 /*gossipid*/) +bool OPvPCapturePointZM_GraveYard::HandleGossipOption(Player* player, Creature* creature, uint32 /*gossipid*/) { - std::map<ObjectGuid, uint32>::iterator itr = m_CreatureTypes.find(guid); + std::map<ObjectGuid::LowType, uint32>::iterator itr = m_CreatureTypes.find(creature->GetSpawnId()); if (itr != m_CreatureTypes.end()) { - Creature* cr = HashMapHolder<Creature>::Find(guid); - if (!cr) - return true; // if the flag is already taken, then return if (!m_FlagCarrierGUID.IsEmpty()) return true; if (itr->second == ZM_ALLIANCE_FIELD_SCOUT) { - cr->CastSpell(player, ZM_BATTLE_STANDARD_A, true); + creature->CastSpell(player, ZM_BATTLE_STANDARD_A, true); m_FlagCarrierGUID = player->GetGUID(); } else if (itr->second == ZM_HORDE_FIELD_SCOUT) { - cr->CastSpell(player, ZM_BATTLE_STANDARD_H, true); + creature->CastSpell(player, ZM_BATTLE_STANDARD_H, true); m_FlagCarrierGUID = player->GetGUID(); } UpdateTowerState(); diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h index 76e4cc71d1f..d8863b026d9 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPZM.h @@ -192,11 +192,11 @@ class OPvPCapturePointZM_GraveYard : public OPvPCapturePoint void UpdateTowerState(); - int32 HandleOpenGo(Player* player, ObjectGuid guid) override; + int32 HandleOpenGo(Player* player, GameObject* go) override; void SetBeaconState(uint32 controlling_team); // not good atm - bool HandleGossipOption(Player* player, ObjectGuid guid, uint32 gossipid) override; + bool HandleGossipOption(Player* player, Creature* creature, uint32 gossipid) override; bool HandleDropFlag(Player* player, uint32 spellId) override; diff --git a/src/server/shared/Containers.h b/src/server/shared/Containers.h index 5dee18cb752..685acea05e3 100644 --- a/src/server/shared/Containers.h +++ b/src/server/shared/Containers.h @@ -92,6 +92,19 @@ namespace Trinity return false; } + + template<class K, class V, template<class, class, class...> class M, class... Rest> + void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value) + { + auto range = multimap.equal_range(key); + for (auto itr = range.first; itr != range.second;) + { + if (itr->second == value) + itr = multimap.erase(itr); + else + ++itr; + } + } } //! namespace Containers } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index c7a63911a4c..6c18a0e76ee 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -338,16 +338,13 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC); // Corpse - PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH); - PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CORPSE_PHASES, "SELECT Guid, PhaseId FROM corpse_phases", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE Guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_CORPSES_PHASES, "DELETE FROM corpse_phases WHERE OwnerGuid = ? AND CorpseType <> 0", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_OLD_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE CorpseType = 0 OR Time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CORPSE_PHASES, "INSERT INTO corpse_phases (Guid, PhaseId, OwnerGuid, Time, CorpseType) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, guid FROM corpse WHERE mapId = ?", CONNECTION_SYNCH); + PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CORPSES_FROM_MAP, "DELETE cp, c FROM corpse_phases cp INNER JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_CORPSE_PHASES, "SELECT cp.OwnerGuid, cp.PhaseId FROM corpse_phases cp LEFT JOIN corpse c ON cp.OwnerGuid = c.guid WHERE c.mapId = ?", CONNECTION_SYNCH); + PrepareStatement(CHAR_INS_CORPSE_PHASES, "INSERT INTO corpse_phases (OwnerGuid, PhaseId) VALUES (?, ?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_DEL_CORPSE_PHASES, "DELETE FROM corpse_phases WHERE OwnerGuid = ?", CONNECTION_ASYNC); // Creature respawn PrepareStatement(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index b6897204b6a..ed3b6dd8098 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -294,13 +294,10 @@ enum CharacterDatabaseStatements CHAR_SEL_CORPSES, CHAR_INS_CORPSE, CHAR_DEL_CORPSE, - CHAR_DEL_PLAYER_CORPSES, - CHAR_DEL_OLD_CORPSES, + CHAR_DEL_CORPSES_FROM_MAP, CHAR_SEL_CORPSE_PHASES, - CHAR_DEL_CORPSE_PHASES, - CHAR_DEL_PLAYER_CORPSES_PHASES, - CHAR_DEL_OLD_CORPSE_PHASES, CHAR_INS_CORPSE_PHASES, + CHAR_DEL_CORPSE_PHASES, CHAR_SEL_CREATURE_RESPAWNS, CHAR_REP_CREATURE_RESPAWN, diff --git a/src/server/shared/Dynamic/TypeContainer.h b/src/server/shared/Dynamic/TypeContainer.h index 2165945d119..9b264fdea7f 100644 --- a/src/server/shared/Dynamic/TypeContainer.h +++ b/src/server/shared/Dynamic/TypeContainer.h @@ -25,6 +25,7 @@ */ #include <map> +#include <unordered_map> #include <vector> #include "Define.h" #include "Dynamic/TypeList.h" @@ -35,54 +36,41 @@ * By itself its meaningless but collaborate along with TypeContainers, * it become the most powerfully container in the whole system. */ -template<class OBJECT> struct ContainerMapList +template<class OBJECT> +struct ContainerMapList { //std::map<OBJECT_HANDLE, OBJECT *> _element; GridRefManager<OBJECT> _element; }; -template<> struct ContainerMapList<TypeNull> /* nothing is in type null */ +template<> +struct ContainerMapList<TypeNull> /* nothing is in type null */ { }; -template<class H, class T> struct ContainerMapList<TypeList<H, T> > + +template<class H, class T> +struct ContainerMapList<TypeList<H, T> > { ContainerMapList<H> _elements; ContainerMapList<T> _TailElements; }; -/* - * @class ContaierArrayList is a multi-type container for - * array of elements. - */ -template<class OBJECT> struct ContainerArrayList +template<class OBJECT, class KEY_TYPE> +struct ContainerUnorderedMap { - std::vector<OBJECT> _element; + std::unordered_map<KEY_TYPE, OBJECT*> _element; }; -// termination condition -template<> struct ContainerArrayList<TypeNull> { }; -// recursion -template<class H, class T> struct ContainerArrayList<TypeList<H, T> > +template<class KEY_TYPE> +struct ContainerUnorderedMap<TypeNull, KEY_TYPE> { - ContainerArrayList<H> _elements; - ContainerArrayList<T> _TailElements; }; -/* - * @class ContainerList is a simple list of different types of elements - * - */ -template<class OBJECT> struct ContainerList +template<class H, class T, class KEY_TYPE> +struct ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE> { - OBJECT _element; -}; - -/* TypeNull is underfined */ -template<> struct ContainerList<TypeNull> { }; -template<class H, class T> struct ContainerList<TypeList<H, T> > -{ - ContainerList<H> _elements; - ContainerMapList<T> _TailElements; + ContainerUnorderedMap<H, KEY_TYPE> _elements; + ContainerUnorderedMap<T, KEY_TYPE> _TailElements; }; #include "TypeContainerFunctions.h" @@ -101,14 +89,16 @@ class TypeMapContainer template<class SPECIFIC_TYPE> size_t Count() const { return Trinity::Count(i_elements, (SPECIFIC_TYPE*)NULL); } /// inserts a specific object into the container - template<class SPECIFIC_TYPE> bool insert(SPECIFIC_TYPE *obj) + template<class SPECIFIC_TYPE> + bool insert(SPECIFIC_TYPE *obj) { SPECIFIC_TYPE* t = Trinity::Insert(i_elements, obj); return (t != NULL); } /// Removes the object from the container, and returns the removed object - //template<class SPECIFIC_TYPE> bool remove(SPECIFIC_TYPE* obj) + //template<class SPECIFIC_TYPE> + //bool remove(SPECIFIC_TYPE* obj) //{ // SPECIFIC_TYPE* t = Trinity::Remove(i_elements, obj); // return (t != NULL); @@ -120,5 +110,34 @@ class TypeMapContainer private: ContainerMapList<OBJECT_TYPES> i_elements; }; -#endif +template<class OBJECT_TYPES, class KEY_TYPE> +class TypeUnorderedMapContainer +{ +public: + template<class SPECIFIC_TYPE> + bool Insert(KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + return Trinity::Insert(_elements, handle, obj); + } + + template<class SPECIFIC_TYPE> + bool Remove(KEY_TYPE const& handle) + { + return Trinity::Remove(_elements, handle, (SPECIFIC_TYPE*)NULL); + } + + template<class SPECIFIC_TYPE> + SPECIFIC_TYPE* Find(KEY_TYPE const& handle) + { + return Trinity::Find(_elements, handle, (SPECIFIC_TYPE*)NULL); + } + + ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE>& GetElements() { return _elements; } + ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> const& GetElements() const { return _elements; } + +private: + ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> _elements; +}; + +#endif diff --git a/src/server/shared/Dynamic/TypeContainerFunctions.h b/src/server/shared/Dynamic/TypeContainerFunctions.h index a89f5bd10d4..4a841cfda56 100644 --- a/src/server/shared/Dynamic/TypeContainerFunctions.h +++ b/src/server/shared/Dynamic/TypeContainerFunctions.h @@ -28,60 +28,164 @@ #include "Define.h" #include "Dynamic/TypeList.h" #include <map> +#include <unordered_map> namespace Trinity { + // Helpers + // Insert helpers + template<class SPECIFIC_TYPE, class KEY_TYPE> + bool Insert(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + auto i = elements._element.find(handle); + if (i == elements._element.end()) + { + elements._element[handle] = obj; + return true; + } + else + { + ASSERT(i->second == obj, "Object with certain key already in but objects are different!"); + return false; + } + } + + template<class SPECIFIC_TYPE, class KEY_TYPE> + bool Insert(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class T> + bool Insert(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T> + bool Insert(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + bool ret = Insert(elements._elements, handle, obj); + return ret ? ret : Insert(elements._TailElements, handle, obj); + } + + // Find helpers + template<class SPECIFIC_TYPE, class KEY_TYPE> + SPECIFIC_TYPE* Find(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + auto i = elements._element.find(handle); + if (i == elements._element.end()) + return nullptr; + else + return i->second; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE> + SPECIFIC_TYPE* Find(ContainerUnorderedMap<TypeNull, KEY_TYPE> const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return nullptr; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class T> + SPECIFIC_TYPE* Find(ContainerUnorderedMap<T, KEY_TYPE> const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return nullptr; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T> + SPECIFIC_TYPE* Find(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + SPECIFIC_TYPE* ret = Find(elements._elements, handle, (SPECIFIC_TYPE*)nullptr); + return ret ? ret : Find(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr); + } + + // Erase helpers + template<class SPECIFIC_TYPE, class KEY_TYPE> + bool Remove(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + elements._element.erase(handle); + return true; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE> + bool Remove(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class T> + bool Remove(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T> + bool Remove(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + bool ret = Remove(elements._elements, handle, (SPECIFIC_TYPE*)nullptr); + return ret ? ret : Remove(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr); + } + /* ContainerMapList Helpers */ // count functions - template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE* /*fake*/) + template<class SPECIFIC_TYPE> + size_t Count(ContainerMapList<SPECIFIC_TYPE> const& elements, SPECIFIC_TYPE* /*fake*/) { return elements._element.getSize(); } - template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE* /*fake*/) + template<class SPECIFIC_TYPE> + size_t Count(ContainerMapList<TypeNull> const& /*elements*/, SPECIFIC_TYPE* /*fake*/) { return 0; } - template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE* /*fake*/) + template<class SPECIFIC_TYPE, class T> + size_t Count(ContainerMapList<T> const& /*elements*/, SPECIFIC_TYPE* /*fake*/) { return 0; } - template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake) + template<class SPECIFIC_TYPE, class T> + size_t Count(ContainerMapList<TypeList<SPECIFIC_TYPE, T>> const& elements, SPECIFIC_TYPE* fake) { return Count(elements._elements, fake); } - template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake) + template<class SPECIFIC_TYPE, class H, class T> + size_t Count(ContainerMapList<TypeList<H, T>> const& elements, SPECIFIC_TYPE* fake) { return Count(elements._TailElements, fake); } // non-const insert functions - template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE *obj) + template<class SPECIFIC_TYPE> + SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE>& elements, SPECIFIC_TYPE* obj) { //elements._element[hdl] = obj; obj->AddToGrid(elements._element); return obj; } - template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/) + template<class SPECIFIC_TYPE> + SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull>& /*elements*/, SPECIFIC_TYPE* /*obj*/) { - return NULL; + return nullptr; } // this is a missed - template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Insert(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/) + template<class SPECIFIC_TYPE, class T> + SPECIFIC_TYPE* Insert(ContainerMapList<T>& /*elements*/, SPECIFIC_TYPE* /*obj*/) { - return NULL; // a missed + return nullptr; // a missed } // Recursion - template<class SPECIFIC_TYPE, class H, class T> SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE *obj) + template<class SPECIFIC_TYPE, class H, class T> + SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T>>& elements, SPECIFIC_TYPE* obj) { - SPECIFIC_TYPE* t= Insert(elements._elements, obj); - return (t != NULL ? t : Insert(elements._TailElements, obj)); + SPECIFIC_TYPE* t = Insert(elements._elements, obj); + return (t != nullptr ? t : Insert(elements._TailElements, obj)); } //// non-const remove method @@ -93,20 +197,20 @@ namespace Trinity //template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/) //{ - // return NULL; + // return nullptr; //} //// this is a missed //template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Remove(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/) //{ - // return NULL; // a missed + // return nullptr; // a missed //} //template<class SPECIFIC_TYPE, class T, class H> SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T> > &elements, SPECIFIC_TYPE *obj) //{ // // The head element is bad // SPECIFIC_TYPE* t = Remove(elements._elements, obj); - // return ( t != NULL ? t : Remove(elements._TailElements, obj) ); + // return (t != nullptr ? t : Remove(elements._TailElements, obj)); //} } #endif diff --git a/src/server/shared/Dynamic/TypeContainerVisitor.h b/src/server/shared/Dynamic/TypeContainerVisitor.h index 514b52d3dfe..e10a2331e25 100644 --- a/src/server/shared/Dynamic/TypeContainerVisitor.h +++ b/src/server/shared/Dynamic/TypeContainerVisitor.h @@ -37,21 +37,6 @@ template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYP v.Visit(c); } -// terminate condition for container list -template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerList<TypeNull> &/*c*/) { } - -template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerList<T> &c) -{ - v.Visit(c._element); -} - -// recursion for container list -template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerList<TypeList<H, T> > &c) -{ - VisitorHelper(v, c._elements); - VisitorHelper(v, c._TailElements); -} - // terminate condition container map list template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerMapList<TypeNull> &/*c*/) { } @@ -67,23 +52,31 @@ template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, Contain VisitorHelper(v, c._TailElements); } -// array list -template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<T> &c) +// for TypeMapContainer +template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c) { - v.Visit(c._element); + VisitorHelper(v, c.GetElements()); } -template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerArrayList<TypeNull> &/*c*/) { } +// TypeUnorderedMapContainer +template<class VISITOR, class KEY_TYPE> +void VisitorHelper(VISITOR& /*v*/, ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*c*/) { } + +template<class VISITOR, class KEY_TYPE, class T> +void VisitorHelper(VISITOR& v, ContainerUnorderedMap<T, KEY_TYPE>& c) +{ + v.Visit(c._element); +} -// recursion -template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<TypeList<H, T> > &c) +template<class VISITOR, class KEY_TYPE, class H, class T> +void VisitorHelper(VISITOR& v, ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& c) { VisitorHelper(v, c._elements); VisitorHelper(v, c._TailElements); } -// for TypeMapContainer -template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c) +template<class VISITOR, class OBJECT_TYPES, class KEY_TYPE> +void VisitorHelper(VISITOR& v, TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>& c) { VisitorHelper(v, c.GetElements()); } diff --git a/src/server/shared/Dynamic/TypeList.h b/src/server/shared/Dynamic/TypeList.h index f1ccca9b043..f0355929700 100644 --- a/src/server/shared/Dynamic/TypeList.h +++ b/src/server/shared/Dynamic/TypeList.h @@ -40,5 +40,6 @@ struct TypeList #define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3) > #define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4) > #define TYPELIST_5(T1, T2, T3, T4, T5) TypeList<T1, TYPELIST_4(T2, T3, T4, T5) > +#define TYPELIST_6(T1, T2, T3, T4, T5, T6) TypeList<T1, TYPELIST_5(T2, T3, T4, T5, T6) > #endif diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index a1e8ba74514..d4a6915894d 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -272,10 +272,10 @@ extern int main(int argc, char** argv) sWorldSocketMgr.StopNetwork(); sInstanceSaveMgr->Unload(); + sOutdoorPvPMgr->Die(); // unload it before MapManager sMapMgr->UnloadAll(); // unload all grids (including locked in memory) sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world sScriptMgr->Unload(); - sOutdoorPvPMgr->Die(); // set server offline LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmHandle.Index); |