diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 75 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.h | 10 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h | 21 | ||||
-rw-r--r-- | src/server/game/Globals/AreaTriggerDataStore.cpp | 157 | ||||
-rw-r--r-- | src/server/game/Globals/AreaTriggerDataStore.h | 6 | ||||
-rw-r--r-- | src/server/game/Grids/ObjectGridLoader.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Grids/ObjectGridLoader.h | 3 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.h | 2 |
10 files changed, 269 insertions, 23 deletions
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index c5d50dc9ed6..19807a7a5b2 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -27,6 +27,7 @@ #include "Log.h" #include "Object.h" #include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "PhasingHandler.h" #include "Player.h" #include "ScriptMgr.h" @@ -38,10 +39,13 @@ #include "UpdateData.h" #include <G3D/AABox.h> -AreaTrigger::AreaTrigger() : WorldObject(false), MapObject(), _aurEff(nullptr), +AreaTrigger::AreaTrigger() : WorldObject(false), MapObject(), + _targetGuid(), _aurEff(nullptr), _duration(0), _totalDuration(0), _timeSinceCreated(0), _previousCheckOrientation(std::numeric_limits<float>::infinity()), - _isRemoved(false), _reachedDestination(true), _lastSplineIndex(0), _movementTime(0), - _areaTriggerMiscTemplate(nullptr), _ai() + _isRemoved(false), _rollPitchYaw(), _targetRollPitchYaw(), _polygonVertices(), _spline(), + _reachedDestination(true), _lastSplineIndex(0), _movementTime(0), + _orbitInfo(), _areaTriggerMiscTemplate(nullptr), _insideUnits(), _ai(), + _areaTriggerTemplate(nullptr) { m_objectType |= TYPEMASK_AREATRIGGER; m_objectTypeId = TYPEID_AREATRIGGER; @@ -104,6 +108,8 @@ bool AreaTrigger::Create(uint32 spellMiscId, Unit* caster, Unit* target, SpellIn return false; } + _areaTriggerTemplate = _areaTriggerMiscTemplate->Template; + Object::_Create(ObjectGuid::Create<HighGuid::AreaTrigger>(GetMapId(), GetTemplate()->Id, caster->GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>())); SetEntry(GetTemplate()->Id); @@ -212,11 +218,59 @@ AreaTrigger* AreaTrigger::CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Un return at; } +bool AreaTrigger::LoadFromDB(uint32 spawnId, Map* map, bool /*addToMap*/, bool /*allowDuplicate*/) +{ + AreaTriggerServerPosition const* position = sAreaTriggerDataStore->GetAreaTriggerServerPosition(spawnId); + if (!position) + return false; + + AreaTriggerTemplate const* areaTriggerTemplate = sAreaTriggerDataStore->GetAreaTriggerServerTemplate(position->Id); + if (!areaTriggerTemplate) + return false; + + return CreateServer(map, areaTriggerTemplate, *position); +} + +bool AreaTrigger::CreateServer(Map* map, AreaTriggerTemplate const* areaTriggerTemplate, AreaTriggerServerPosition const& position) +{ + SetMap(map); + Relocate(position.Location); + if (!IsPositionValid()) + { + TC_LOG_ERROR("entities.areatrigger", "AreaTriggerServer (id %u) not created. Invalid coordinates (X: %f Y: %f)", areaTriggerTemplate->Id, GetPositionX(), GetPositionY()); + return false; + } + + _areaTriggerTemplate = areaTriggerTemplate; + + Object::_Create(ObjectGuid::Create<HighGuid::AreaTrigger>(GetMapId(), + areaTriggerTemplate->Id, GetMap()->GenerateLowGuid<HighGuid::AreaTrigger>())); + + SetEntry(areaTriggerTemplate->Id); + + SetObjectScale(1.0f); + + if (position.PhaseId || position.PhaseGroup || position.PhaseUseFlags) + PhasingHandler::InitDbPhaseShift(GetPhaseShift(), position.PhaseUseFlags, position.PhaseId, position.PhaseGroup); + + UpdateShape(); + + AI_Initialize(); + + return true; +} + void AreaTrigger::Update(uint32 diff) { WorldObject::Update(diff); _timeSinceCreated += diff; + if (IsServerSide()) + { + UpdateTargetList(); + return; + } + // "If" order matter here, Orbit > Attached > Splines if (HasOrbit()) { @@ -430,7 +484,7 @@ void AreaTrigger::HandleUnitEnterExit(std::list<Unit*> const& newTargetList) AreaTriggerTemplate const* AreaTrigger::GetTemplate() const { - return _areaTriggerMiscTemplate->Template; + return _areaTriggerTemplate; } uint32 AreaTrigger::GetScriptId() const @@ -581,11 +635,13 @@ bool UnitFitToActionRequirement(Unit* unit, Unit* caster, AreaTriggerAction cons void AreaTrigger::DoActions(Unit* unit) { - if (Unit* caster = GetCaster()) + Unit* caster = IsServerSide() ? unit : GetCaster(); + + if (caster) { for (AreaTriggerAction const& action : GetTemplate()->Actions) { - if (UnitFitToActionRequirement(unit, caster, action)) + if (IsServerSide() || UnitFitToActionRequirement(unit, caster, action)) { switch (action.ActionType) { @@ -595,6 +651,13 @@ void AreaTrigger::DoActions(Unit* unit) case AREATRIGGER_ACTION_ADDAURA: caster->AddAura(action.Param, unit); break; + case AREATRIGGER_ACTION_TELEPORT: + { + if (WorldSafeLocsEntry const* safeLoc = sObjectMgr->GetWorldSafeLoc(action.Param)) + if (Player* player = caster->ToPlayer()) + player->TeleportTo(safeLoc->Loc); + break; + } default: break; } diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index a9e1a54ed0f..90c0a6dbd46 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -61,8 +61,14 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge AreaTriggerAI* AI() { return _ai.get(); } + bool IsServerSide() const { return _areaTriggerTemplate->IsServerSide; } + + bool IsNeverVisibleFor(WorldObject const* /*seer*/) const override { return IsServerSide(); } + private: bool Create(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, SpellCastVisual spellVisual, ObjectGuid const& castId, AuraEffect const* aurEff); + bool CreateServer(Map* map, AreaTriggerTemplate const* areaTriggerTemplate, AreaTriggerServerPosition const& position); + public: static AreaTrigger* CreateAreaTrigger(uint32 spellMiscId, Unit* caster, Unit* target, SpellInfo const* spell, Position const& pos, int32 duration, SpellCastVisual spellVisual, ObjectGuid const& castId = ObjectGuid::Empty, AuraEffect const* aurEff = nullptr); @@ -105,6 +111,8 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge UF::UpdateField<UF::AreaTriggerData, 0, TYPEID_AREATRIGGER> m_areaTriggerData; + bool LoadFromDB(uint32 spawnId, Map* map, bool addToMap, bool allowDuplicate); + protected: void _UpdateDuration(int32 newDuration); float GetProgress() const; @@ -154,6 +162,8 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge GuidUnorderedSet _insideUnits; std::unique_ptr<AreaTriggerAI> _ai; + + AreaTriggerTemplate const* _areaTriggerTemplate; }; #endif diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp index 4072089d275..9632aac39d1 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp @@ -33,6 +33,7 @@ AreaTriggerTemplate::AreaTriggerTemplate() Flags = 0; ScriptId = 0; MaxSearchRadius = 0.0f; + IsServerSide = false; memset(DefaultDatas.Data, 0, sizeof(DefaultDatas.Data)); } diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h index 7b8ec39b3f0..abd94935a13 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h @@ -55,9 +55,10 @@ enum AreaTriggerTypes enum AreaTriggerActionTypes { - AREATRIGGER_ACTION_CAST = 0, - AREATRIGGER_ACTION_ADDAURA = 1, - AREATRIGGER_ACTION_MAX = 2 + AREATRIGGER_ACTION_CAST = 0, + AREATRIGGER_ACTION_ADDAURA = 1, + AREATRIGGER_ACTION_TELEPORT = 2, + AREATRIGGER_ACTION_MAX = 3 }; enum AreaTriggerActionUserTypes @@ -71,6 +72,19 @@ enum AreaTriggerActionUserTypes AREATRIGGER_ACTION_USER_MAX = 6 }; +struct AreaTriggerServerPosition +{ + uint64 SpawnId; + uint32 Id; + bool IsServer; + WorldLocation Location; + uint32 PhaseId; + uint32 PhaseGroup; + uint8 PhaseUseFlags; + + AreaTriggerServerPosition() : SpawnId(0), Id(0), IsServer(false), Location(), PhaseId(0), PhaseGroup(0), PhaseUseFlags(0) { } +}; + struct AreaTriggerAction { uint32 Param; @@ -146,6 +160,7 @@ public: std::vector<TaggedPosition<Position::XY>> PolygonVertices; std::vector<TaggedPosition<Position::XY>> PolygonVerticesTarget; std::vector<AreaTriggerAction> Actions; + bool IsServerSide; union { diff --git a/src/server/game/Globals/AreaTriggerDataStore.cpp b/src/server/game/Globals/AreaTriggerDataStore.cpp index 57caf8b4b51..7ea4c57774c 100644 --- a/src/server/game/Globals/AreaTriggerDataStore.cpp +++ b/src/server/game/Globals/AreaTriggerDataStore.cpp @@ -16,20 +16,88 @@ */ #include "AreaTriggerDataStore.h" +#include "AreaTrigger.h" #include "AreaTriggerTemplate.h" #include "DatabaseEnv.h" #include "DB2Stores.h" #include "Log.h" +#include "MapManager.h" #include "ObjectMgr.h" #include "Timer.h" #include <cmath> +struct AreaTriggerTemplateKey +{ + uint32 Id; + bool IsServer; + + AreaTriggerTemplateKey(uint32 id, bool isServer) : Id(id), IsServer(isServer) { } +}; + +bool operator ==(AreaTriggerTemplateKey const& A, AreaTriggerTemplateKey const& B) +{ + return A.Id == B.Id && A.IsServer == B.IsServer; +} + +namespace std +{ + template <> + struct hash<AreaTriggerTemplateKey> + { + std::size_t operator()(AreaTriggerTemplateKey const& value) const + { + size_t hashVal = 0; + Trinity::hash_combine(hashVal, value.Id); + Trinity::hash_combine(hashVal, value.IsServer); + return hashVal; + } + }; +} + namespace { - std::unordered_map<uint32, AreaTriggerTemplate> _areaTriggerTemplateStore; + typedef std::unordered_map<uint32/*cell_id*/, std::set<ObjectGuid::LowType>> CellAreaTriggersMap; + typedef std::unordered_map<uint32/*mapId*/, CellAreaTriggersMap> MapAreaTriggersMap; + typedef std::unordered_map<uint32, AreaTriggerServerPosition> AreaTriggerSpawnMap; + typedef std::unordered_map<AreaTriggerTemplateKey, AreaTriggerTemplate> AreaTriggerTemplateMap; + + MapAreaTriggersMap _areaTriggersGrid; + AreaTriggerSpawnMap _areaTriggerSpawnMap; + AreaTriggerTemplateMap _areaTriggerTemplateMap; std::unordered_map<uint32, AreaTriggerMiscTemplate> _areaTriggerTemplateSpellMisc; } +AreaTriggerTemplate const* AreaTriggerDataStore::GetAreaTriggerServerTemplate(uint32 areaTriggerId) const +{ + auto itr = _areaTriggerTemplateMap.find(AreaTriggerTemplateKey(areaTriggerId, true)); + if (itr != _areaTriggerTemplateMap.end()) + return &itr->second; + + return nullptr; +} + +std::set<ObjectGuid::LowType> const* AreaTriggerDataStore::GetAreaTriggersForMapAndCell(uint32 mapId, uint32 cellId) const +{ + MapAreaTriggersMap::iterator iterMap = _areaTriggersGrid.find(mapId); + if (iterMap == _areaTriggersGrid.end()) + return nullptr; + + CellAreaTriggersMap::iterator iterCell = iterMap->second.find(cellId); + if (iterCell == iterMap->second.end()) + return nullptr; + + return &(iterCell->second); +} + +AreaTriggerServerPosition const* AreaTriggerDataStore::GetAreaTriggerServerPosition(uint32 spawnId) const +{ + AreaTriggerSpawnMap::iterator iter = _areaTriggerSpawnMap.find(spawnId); + if (iter == _areaTriggerSpawnMap.end()) + return nullptr; + + return &(iter->second); +} + void AreaTriggerDataStore::LoadAreaTriggerTemplates() { uint32 oldMSTime = getMSTime(); @@ -63,6 +131,16 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() continue; } + if (actionType == AREATRIGGER_ACTION_TELEPORT) + { + WorldSafeLocsEntry const* safeLoc = sObjectMgr->GetWorldSafeLoc(action.Param); + if (!safeLoc) + { + TC_LOG_ERROR("sql.sql", "Table `areatrigger_template_actions` has invalid entry (%u) with TargetType=Teleport and Param (%u) not a valid world safe loc entry", areaTriggerId, action.Param); + continue; + } + } + action.TargetType = AreaTriggerActionUserTypes(targetType); action.ActionType = AreaTriggerActionTypes(actionType); @@ -113,8 +191,8 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger templates splines. DB table `spell_areatrigger_splines` is empty."); } - // 0 1 2 3 4 5 6 7 8 9 - if (QueryResult templates = WorldDatabase.Query("SELECT Id, Type, Flags, Data0, Data1, Data2, Data3, Data4, Data5, ScriptName FROM `areatrigger_template`")) + // 0 1 2 3 4 5 6 7 8 9 10 + if (QueryResult templates = WorldDatabase.Query("SELECT Id, IsServer, Type, Flags, Data0, Data1, Data2, Data3, Data4, Data5, ScriptName FROM `areatrigger_template`")) { do { @@ -122,7 +200,8 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() AreaTriggerTemplate areaTriggerTemplate; areaTriggerTemplate.Id = fields[0].GetUInt32(); - uint8 type = fields[1].GetUInt8(); + bool isServer = fields[1].GetUInt8() == 1; + uint8 type = fields[2].GetUInt8(); if (type >= AREATRIGGER_TYPE_MAX) { @@ -131,22 +210,78 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() } areaTriggerTemplate.Type = static_cast<AreaTriggerTypes>(type); - areaTriggerTemplate.Flags = fields[2].GetUInt32(); + areaTriggerTemplate.Flags = fields[3].GetUInt32(); + + if (isServer && areaTriggerTemplate.Flags != 0) + { + TC_LOG_ERROR("sql.sql", "Table `areatrigger_template` has listed server-side areatrigger (Id: %u) with none-zero flags", areaTriggerTemplate.Id); + continue; + } for (uint8 i = 0; i < MAX_AREATRIGGER_ENTITY_DATA; ++i) - areaTriggerTemplate.DefaultDatas.Data[i] = fields[3 + i].GetFloat(); + areaTriggerTemplate.DefaultDatas.Data[i] = fields[4 + i].GetFloat(); - areaTriggerTemplate.ScriptId = sObjectMgr->GetScriptId(fields[9].GetString()); + areaTriggerTemplate.ScriptId = sObjectMgr->GetScriptId(fields[10].GetString()); areaTriggerTemplate.PolygonVertices = std::move(verticesByAreaTrigger[areaTriggerTemplate.Id]); areaTriggerTemplate.PolygonVerticesTarget = std::move(verticesTargetByAreaTrigger[areaTriggerTemplate.Id]); areaTriggerTemplate.Actions = std::move(actionsByAreaTrigger[areaTriggerTemplate.Id]); + areaTriggerTemplate.IsServerSide = isServer; areaTriggerTemplate.InitMaxSearchRadius(); - _areaTriggerTemplateStore[areaTriggerTemplate.Id] = areaTriggerTemplate; + _areaTriggerTemplateMap[AreaTriggerTemplateKey(areaTriggerTemplate.Id, isServer)] = areaTriggerTemplate; } while (templates->NextRow()); } + // Load area trigger positions (to put them on the server) + // 0 1 2 3 4 5 6 7 8 9 10 + if (QueryResult templates = WorldDatabase.Query("SELECT SpawnId, Id, IsServer, MapId, PosX, PosY, PosZ, PhaseId, PhaseGroup, PhaseUseFlags, Comment FROM `areatrigger_positions`")) + { + do + { + Field* fields = templates->Fetch(); + + AreaTriggerServerPosition position; + position.SpawnId = fields[0].GetUInt64(); + position.Id = fields[1].GetUInt32(); + position.IsServer = fields[2].GetUInt8() == 1; + uint32 mapId = fields[3].GetUInt32(); + + float posX = fields[4].GetFloat(); + float posY = fields[5].GetFloat(); + float posZ = fields[6].GetFloat(); + position.Location = WorldLocation(mapId, posX, posY, posZ); + + if (!MapManager::IsValidMapCoord(position.Location)) + { + TC_LOG_ERROR("sql.sql", "Table `areatrigger_srv_position` has listed an invalid position: Id: %u, IsServer: %d. MapId {%d}, Position {%f, %f, %f}", + position.Id, position.IsServer, mapId, posX, posY, posZ); + continue; + } + + position.PhaseId = fields[7].GetUInt32(); + position.PhaseGroup = fields[8].GetUInt32(); + position.PhaseUseFlags = fields[9].GetUInt8(); + + auto iter = _areaTriggerTemplateMap.find(AreaTriggerTemplateKey(position.Id, position.IsServer)); + if (iter == _areaTriggerTemplateMap.end()) + { + TC_LOG_ERROR("sql.sql", "Table `areatrigger_srv_position` has listed areatrigger that doesn't exist: Id: %u, IsServer: %d", + position.Id, position.IsServer); + continue; + } + + // Add the trigger to a map::cell map, which is later used by GridLoader to query + CellCoord cellCoord = Trinity::ComputeCellCoord(position.Location.GetPositionX(), position.Location.GetPositionY()); + auto iterMap = _areaTriggersGrid.insert(MapAreaTriggersMap::value_type(mapId, CellAreaTriggersMap())); + auto iterCell = iterMap.first->second.insert(CellAreaTriggersMap::value_type(cellCoord.GetId(), CellGuidSet())); + iterCell.first->second.insert(position.SpawnId); + + // add the position to the map + _areaTriggerSpawnMap[position.SpawnId] = position; + } while (templates->NextRow()); + } + // 0 1 2 3 4 5 6 7 8 9 10 if (QueryResult areatriggerSpellMiscs = WorldDatabase.Query("SELECT SpellMiscId, AreaTriggerId, MoveCurveId, ScaleCurveId, MorphCurveId, FacingCurveId, AnimId, AnimKitId, DecalPropertiesId, TimeToTarget, TimeToTargetScale FROM `spell_areatrigger`")) { @@ -246,13 +381,13 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() TC_LOG_INFO("server.loading", ">> Loaded 0 AreaTrigger templates circular movement infos. DB table `spell_areatrigger_circular` is empty."); } - TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " spell areatrigger templates in %u ms.", _areaTriggerTemplateStore.size(), GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " spell areatrigger templates in %u ms.", _areaTriggerTemplateMap.size(), GetMSTimeDiffToNow(oldMSTime)); } AreaTriggerTemplate const* AreaTriggerDataStore::GetAreaTriggerTemplate(uint32 areaTriggerId) const { - auto itr = _areaTriggerTemplateStore.find(areaTriggerId); - if (itr != _areaTriggerTemplateStore.end()) + auto itr = _areaTriggerTemplateMap.find(AreaTriggerTemplateKey(areaTriggerId, false)); + if (itr != _areaTriggerTemplateMap.end()) return &itr->second; return nullptr; diff --git a/src/server/game/Globals/AreaTriggerDataStore.h b/src/server/game/Globals/AreaTriggerDataStore.h index b0e4cb40d55..dd925656f94 100644 --- a/src/server/game/Globals/AreaTriggerDataStore.h +++ b/src/server/game/Globals/AreaTriggerDataStore.h @@ -19,15 +19,21 @@ #define AreaTriggerDataStore_h__ #include "Define.h" +#include "ObjectGuid.h" +#include <set> class AreaTriggerTemplate; class AreaTriggerMiscTemplate; +struct AreaTriggerServerPosition; class TC_GAME_API AreaTriggerDataStore { public: void LoadAreaTriggerTemplates(); + std::set<ObjectGuid::LowType> const* GetAreaTriggersForMapAndCell(uint32 mapId, uint32 cellId) const; + AreaTriggerServerPosition const* GetAreaTriggerServerPosition(uint32 spawnId) const; + AreaTriggerTemplate const* GetAreaTriggerServerTemplate(uint32 id) const; AreaTriggerTemplate const* GetAreaTriggerTemplate(uint32 areaTriggerId) const; AreaTriggerMiscTemplate const* GetAreaTriggerMiscTemplate(uint32 spellMiscValue) const; diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp index bf33abacea5..9ab947aac18 100644 --- a/src/server/game/Grids/ObjectGridLoader.cpp +++ b/src/server/game/Grids/ObjectGridLoader.cpp @@ -17,6 +17,7 @@ #include "ObjectGridLoader.h" #include "AreaTrigger.h" +#include "AreaTriggerDataStore.h" #include "CellImpl.h" #include "Conversation.h" #include "Corpse.h" @@ -124,7 +125,9 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T> T* obj = new T; // Don't spawn at all if there's a respawn time - if ((obj->GetTypeId() == TYPEID_UNIT && !map->GetCreatureRespawnTime(*i_guid)) || (obj->GetTypeId() == TYPEID_GAMEOBJECT && !map->GetGORespawnTime(*i_guid))) + if ((obj->GetTypeId() == TYPEID_UNIT && !map->GetCreatureRespawnTime(*i_guid)) || + (obj->GetTypeId() == TYPEID_GAMEOBJECT && !map->GetGORespawnTime(*i_guid)) || + (obj->GetTypeId() == TYPEID_AREATRIGGER)) { ObjectGuid::LowType guid = *i_guid; //TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: %s for (guid: %u) Loading", table, guid); @@ -175,7 +178,7 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T> } } -void ObjectGridLoader::Visit(GameObjectMapType &m) +void ObjectGridLoader::Visit(GameObjectMapType& m) { CellCoord cellCoord = i_cell.GetCellCoord(); CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetDifficultyID(), cellCoord.GetId()); @@ -189,6 +192,15 @@ void ObjectGridLoader::Visit(CreatureMapType &m) LoadHelper(cell_guids.creatures, cellCoord, m, i_creatures, i_map); } +void ObjectGridLoader::Visit(AreaTriggerMapType &m) +{ + CellCoord cellCoord = i_cell.GetCellCoord(); + CellGuidSet const* areaTriggers = sAreaTriggerDataStore->GetAreaTriggersForMapAndCell(i_map->GetId(), cellCoord.GetId()); + if (!areaTriggers) + return; + LoadHelper(*areaTriggers, cellCoord, m, i_areaTriggers, i_map); +} + void ObjectWorldLoader::Visit(CorpseMapType& /*m*/) { CellCoord cellCoord = i_cell.GetCellCoord(); diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h index a0638d1069a..c33f372697c 100644 --- a/src/server/game/Grids/ObjectGridLoader.h +++ b/src/server/game/Grids/ObjectGridLoader.h @@ -37,9 +37,9 @@ class TC_GAME_API ObjectGridLoader void Visit(GameObjectMapType &m); void Visit(CreatureMapType &m); + void Visit(AreaTriggerMapType &m); void Visit(CorpseMapType &) const { } void Visit(DynamicObjectMapType&) const { } - void Visit(AreaTriggerMapType &) const { } void Visit(ConversationMapType &) const { } void LoadN(void); @@ -53,6 +53,7 @@ class TC_GAME_API ObjectGridLoader uint32 i_gameObjects; uint32 i_creatures; uint32 i_corpses; + uint32 i_areaTriggers; }; //Stop the creatures before unloading the NGrid diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 46113830f7f..14d0502de18 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -16,6 +16,7 @@ */ #include "Map.h" +#include "AreaTriggerDataStore.h" #include "Battleground.h" #include "CellImpl.h" #include "CharacterPackets.h" diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index e4765c44bec..eb5adbca73f 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -25,6 +25,7 @@ class AccountMgr; class AreaTrigger; class AreaTriggerAI; +class AreaTriggerTemplate; class AuctionHouseObject; class Aura; class AuraScript; @@ -449,6 +450,7 @@ class TC_GAME_API AreaTriggerScript : public ScriptObject // Called when the area trigger is activated by a player. virtual bool OnTrigger(Player* /*player*/, AreaTriggerEntry const* /*trigger*/, bool /*entered*/) { return false; } + virtual bool OnTriggerServer(Player* /*player*/, AreaTriggerTemplate const* /*triggerTemplate*/, bool /*entered*/) { return false; } }; class TC_GAME_API OnlyOnceAreaTriggerScript : public AreaTriggerScript |