diff options
Diffstat (limited to 'src/server/game')
60 files changed, 997 insertions, 1013 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(); |
