mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/AreaTriggers: Implementation for sever side area triggers
- Spawn GridLoader to spawn area triggers correctly now - Removed SAI completely - Removed remnants of smart scripts. Created different issue for it - Calling InitDbPhaseShift and not InDbPhaseShift - changed SpawnId to uint64 rather than uint32 - not using CellGuidSet typedef as to not include ObjectMgr.h in the header
This commit is contained in:
45
sql/updates/world/master/2021_01_30_00_world_mage_tower.sql
Normal file
45
sql/updates/world/master/2021_01_30_00_world_mage_tower.sql
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
ALTER TABLE `areatrigger_template`
|
||||
DROP PRIMARY KEY,
|
||||
ADD COLUMN `IsServer` tinyint(1) NOT NULL AFTER `Id`,
|
||||
ADD PRIMARY KEY (`Id`, `IsServer`);
|
||||
|
||||
ALTER TABLE `areatrigger_template_actions`
|
||||
DROP PRIMARY KEY,
|
||||
ADD COLUMN `IsServer` tinyint(1) NOT NULL AFTER `AreaTriggerId`,
|
||||
ADD PRIMARY KEY (`AreaTriggerId`, `IsServer`);
|
||||
|
||||
CREATE TABLE `areatrigger_positions` (
|
||||
`SpawnId` int(12) unsigned NOT NULL,
|
||||
`Id` int(10) unsigned NOT NULL,
|
||||
`IsServer` tinyint(1) NOT NULL,
|
||||
`MapId` int(10) NOT NULL,
|
||||
`PosX` float NOT NULL,
|
||||
`PosY` float NOT NULL,
|
||||
`PosZ` float NOT NULL,
|
||||
`PhaseId` int(10) DEFAULT 0,
|
||||
`PhaseGroup` int(10) DEFAULT 0,
|
||||
`PhaseUseFlags` tinyint(3) DEFAULT 0,
|
||||
`Comment` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`SpawnId`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
DELETE FROM `areatrigger_positions` WHERE `SpawnId` IN (1, 2);
|
||||
INSERT INTO `areatrigger_positions` (`SpawnId`, `Id`, `IsServer`, `MapId`, `PosX`, `PosY`, `PosZ`, `PhaseId`, `PhaseGroup`, `PhaseUseFlags`, `Comment`) VALUES
|
||||
(1, 1, 1, 0, -9015.774, 877.223, 148.61871, 0, 0, 0, 'Stormwind Mage Portal Entrance'),
|
||||
(2, 2, 1, 0, -8999.866, 864.13995, 65.88978, 0, 0, 0, 'Stormwind Mage Portal Exit');
|
||||
|
||||
DELETE FROM `areatrigger_template` WHERE `Id` in (1, 2) AND `IsServer` = 1;
|
||||
INSERT INTO `areatrigger_template` (`Id`, `IsServer`, `Type`, `Flags`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `ScriptName`, `VerifiedBuild`) VALUES
|
||||
(1, 1, 1, 0, 1.2597655, 1.2792665, 3.7021635, 0, 0, 0, '', 0),
|
||||
(2, 1, 1, 0, 1.2597655, 1.2792665, 3.7021635, 0, 0, 0, '', 0);
|
||||
|
||||
|
||||
DELETE FROM `areatrigger_template_actions` WHERE `AreaTriggerId` IN (1, 2) AND `IsServer` = 1;
|
||||
INSERT INTO `areatrigger_template_actions` (`AreaTriggerId`, `IsServer`, `ActionType`, `ActionParam`, `TargetType`) VALUES
|
||||
(1, 1, 2, 3631, 5),
|
||||
(2, 1, 2, 3630, 5);
|
||||
|
||||
|
||||
UPDATE `world_safe_locs` SET LocX=-9014.864258, LocY=874.324890, LocZ=148.618713 WHERE `id` = 3630;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -33,6 +33,7 @@ AreaTriggerTemplate::AreaTriggerTemplate()
|
||||
Flags = 0;
|
||||
ScriptId = 0;
|
||||
MaxSearchRadius = 0.0f;
|
||||
IsServerSide = false;
|
||||
|
||||
memset(DefaultDatas.Data, 0, sizeof(DefaultDatas.Data));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "Map.h"
|
||||
#include "AreaTriggerDataStore.h"
|
||||
#include "Battleground.h"
|
||||
#include "CellImpl.h"
|
||||
#include "CharacterPackets.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
|
||||
|
||||
Reference in New Issue
Block a user