45 typedef std::unordered_map<
uint32, std::set<ObjectGuid::LowType>> AtCellObjectGuidsMap;
46 typedef std::unordered_map<std::pair<
uint32 ,
Difficulty>, AtCellObjectGuidsMap> AtMapObjectGuids;
48 AtMapObjectGuids _areaTriggerSpawnsByLocation;
49 std::unordered_map<ObjectGuid::LowType, AreaTriggerSpawn> _areaTriggerSpawnsBySpawnId;
50 std::unordered_map<AreaTriggerId, AreaTriggerTemplate> _areaTriggerTemplateStore;
51 std::unordered_map<AreaTriggerCreatePropertiesId, AreaTriggerCreateProperties> _areaTriggerCreateProperties;
57 std::unordered_map<AreaTriggerCreatePropertiesId, std::vector<TaggedPosition<Position::XY>>> verticesByCreateProperties;
58 std::unordered_map<AreaTriggerCreatePropertiesId, std::vector<TaggedPosition<Position::XY>>> verticesTargetByCreateProperties;
59 std::unordered_map<AreaTriggerCreatePropertiesId, std::vector<Position>> splinesByCreateProperties;
60 std::unordered_map<AreaTriggerId, std::vector<AreaTriggerAction>> actionsByAreaTrigger;
63 if (
QueryResult templateActions =
WorldDatabase.Query(
"SELECT AreaTriggerId, IsCustom, ActionType, ActionParam, TargetType FROM `areatrigger_template_actions`"))
67 Field* templateActionFields = templateActions->Fetch();
77 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_template_actions` has invalid ActionType {} for AreaTriggerId ({},{}) and Param {}",
84 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_template_actions` has invalid TargetType {} for AreaTriggerId ({},{}) and Param {}",
93 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_template_actions` has invalid entry for AreaTriggerId ({},{}) with TargetType=Teleport and Param ({}) not a valid world safe loc entry",
102 actionsByAreaTrigger[areaTriggerId].push_back(action);
104 while (templateActions->NextRow());
108 TC_LOG_INFO(
"server.loading",
">> Loaded 0 AreaTrigger templates actions. DB table `areatrigger_template_actions` is empty.");
112 if (
QueryResult vertices =
WorldDatabase.Query(
"SELECT AreaTriggerCreatePropertiesId, IsCustom, Idx, VerticeX, VerticeY, VerticeTargetX, VerticeTargetY FROM `areatrigger_create_properties_polygon_vertex` ORDER BY `AreaTriggerCreatePropertiesId`, `IsCustom`, `Idx`"))
116 Field* verticeFields = vertices->Fetch();
119 verticesByCreateProperties[createPropertiesId].emplace_back(verticeFields[3].GetFloat(), verticeFields[4].GetFloat());
121 if (!verticeFields[5].IsNull() && !verticeFields[6].IsNull())
122 verticesTargetByCreateProperties[createPropertiesId].emplace_back(verticeFields[5].GetFloat(), verticeFields[6].GetFloat());
123 else if (verticeFields[5].IsNull() != verticeFields[6].IsNull())
124 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_create_properties_polygon_vertex` has listed invalid target vertices (AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {}), Index: {}).",
127 while (vertices->NextRow());
131 TC_LOG_INFO(
"server.loading",
">> Loaded 0 AreaTrigger polygon vertices. DB table `areatrigger_create_properties_polygon_vertex` is empty.");
135 if (
QueryResult splines =
WorldDatabase.Query(
"SELECT AreaTriggerCreatePropertiesId, IsCustom, X, Y, Z FROM `areatrigger_create_properties_spline_point` ORDER BY `AreaTriggerCreatePropertiesId`, `IsCustom`, `Idx`"))
139 Field* splineFields = splines->Fetch();
141 splinesByCreateProperties[createPropertiesId].emplace_back(splineFields[2].GetFloat(), splineFields[3].GetFloat(), splineFields[4].GetFloat());
143 while (splines->NextRow());
147 TC_LOG_INFO(
"server.loading",
">> Loaded 0 AreaTrigger splines. DB table `areatrigger_create_properties_spline_point` is empty.");
155 Field* fields = templates->Fetch();
161 areaTriggerTemplate.
Actions = std::move(actionsByAreaTrigger[areaTriggerTemplate.
Id]);
163 _areaTriggerTemplateStore[areaTriggerTemplate.
Id] = areaTriggerTemplate;
165 while (templates->NextRow());
169 if (
QueryResult areatriggerCreateProperties =
WorldDatabase.Query(
"SELECT Id, IsCustom, AreaTriggerId, IsAreatriggerCustom, Flags, "
171 "MoveCurveId, ScaleCurveId, MorphCurveId, FacingCurveId, AnimId, AnimKitId, DecalPropertiesId, TimeToTarget, TimeToTargetScale, "
173 "Shape, ShapeData0, ShapeData1, ShapeData2, ShapeData3, ShapeData4, ShapeData5, ShapeData6, ShapeData7, ScriptName FROM `areatrigger_create_properties`"))
179 Field* fields = areatriggerCreateProperties->Fetch();
181 createProperties.
Id = createPropertiesId;
190 if (areaTriggerId.
Id && !createProperties.
Template)
192 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_create_properties` references invalid AreaTrigger (Id: {}, IsCustom: {}) for AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {})",
199 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_create_properties` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with invalid shape {}.",
204#define VALIDATE_AND_SET_CURVE(Curve, Value) \
205 createProperties.Curve = Value; \
206 if (createProperties.Curve && !sCurveStore.LookupEntry(createProperties.Curve)) \
208 TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties` has listed AreaTrigger (Id: {}, IsCustom: {}) for AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with invalid " #Curve " ({}), set to 0!", \
209 areaTriggerId.Id, uint32(areaTriggerId.IsCustom), createPropertiesId.Id, uint32(createPropertiesId.IsCustom), createProperties.Curve); \
210 createProperties.Curve = 0; \
218#undef VALIDATE_AND_SET_CURVE
248 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_create_properties_polygon_vertex` has invalid target vertices, either all or none vertices must have a corresponding target vertex (AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {})).",
253 createProperties.
SplinePoints = std::move(splinesByCreateProperties[createProperties.
Id]);
255 _areaTriggerCreateProperties[createProperties.
Id] = createProperties;
257 while (areatriggerCreateProperties->NextRow());
261 TC_LOG_INFO(
"server.loading",
">> Loaded 0 AreaTrigger create properties. DB table `areatrigger_create_properties` is empty.");
265 if (
QueryResult circularMovementInfos =
WorldDatabase.Query(
"SELECT AreaTriggerCreatePropertiesId, IsCustom, StartDelay, CircleRadius, BlendFromRadius, InitialAngle, ZOffset, CounterClockwise, CanLoop FROM `areatrigger_create_properties_orbit`"))
269 Field* circularMovementInfoFields = circularMovementInfos->Fetch();
273 if (!createProperties)
275 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger_create_properties_orbit` reference invalid AreaTriggerCreatePropertiesId: (Id: {}, IsCustom: {})", createPropertiesId.
Id,
uint32(createPropertiesId.
IsCustom));
283#define VALIDATE_AND_SET_FLOAT(Float, Value) \
284 createProperties->OrbitInfo->Float = Value; \
285 if (!std::isfinite(createProperties->OrbitInfo->Float)) \
287 TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties_orbit` has listed areatrigger (AreaTriggerCreatePropertiesId: {}, IsCustom: {}) with invalid " #Float " ({}), set to 0!", \
288 createPropertiesId.Id, uint32(createPropertiesId.IsCustom), createProperties->OrbitInfo->Float); \
289 createProperties->OrbitInfo->Float = 0.0f; \
297#undef VALIDATE_AND_SET_FLOAT
299 createProperties->
OrbitInfo->CounterClockwise = circularMovementInfoFields[7].
GetBool();
300 createProperties->
OrbitInfo->CanLoop = circularMovementInfoFields[8].
GetBool();
302 while (circularMovementInfos->NextRow());
306 TC_LOG_INFO(
"server.loading",
">> Loaded 0 AreaTrigger templates circular movement infos. DB table `areatrigger_create_properties_orbit` is empty.");
309 TC_LOG_INFO(
"server.loading",
">> Loaded {} spell areatrigger templates in {} ms.", _areaTriggerTemplateStore.size(),
GetMSTimeDiffToNow(oldMSTime));
315 std::unordered_map<uint32, std::set<Difficulty>> spawnMasks;
317 spawnMasks[mapDifficulty->MapID].insert(
Difficulty(mapDifficulty->DifficultyID));
321 if (
QueryResult templates =
WorldDatabase.Query(
"SELECT SpawnId, AreaTriggerCreatePropertiesId, IsCustom, MapId, SpawnDifficulties, PosX, PosY, PosZ, Orientation, PhaseUseFlags, PhaseId, PhaseGroup, SpellForVisuals, ScriptName FROM `areatrigger`"))
325 Field* fields = templates->Fetch();
329 WorldLocation location(fields[3].GetUInt32(), fields[5].GetFloat(), fields[6].GetFloat(), fields[7].GetFloat(), fields[8].GetFloat());
332 if (!createProperties)
334 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) that doesn't exist for SpawnId " UI64FMTD,
341 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with non - zero flags",
348 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with curve values",
355 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with time to target values",
362 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with orbit info",
369 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with splines",
376 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger` has listed an invalid position: SpawnId: {}, MapId {}, Position {{}}",
381 std::vector<Difficulty> difficulties =
sObjectMgr->ParseSpawnDifficulties(fields[4].GetStringView(),
"areatrigger", spawnId, location.
GetMapId(), spawnMasks[location.
GetMapId()]);
382 if (difficulties.empty())
384 TC_LOG_DEBUG(
"sql.sql",
"Table `areatrigger` has areatrigger (GUID: {}) that is not spawned in any difficulty, skipped.", spawnId);
391 spawn.
Id = createPropertiesId;
398 if (!fields[12].IsNull())
403 TC_LOG_ERROR(
"sql.sql",
"Table `areatrigger` has areatrigger (GUID: {}) with invalid SpellForVisual {}, set to none.", spawnId, *spawn.
SpellForVisuals);
414 _areaTriggerSpawnsByLocation[{ spawn.
mapId, difficulty }][cellCoord.
GetId()].insert(spawnId);
415 }
while (templates->NextRow());
418 TC_LOG_INFO(
"server.loading",
">> Loaded {} areatrigger spawns in {} ms.", _areaTriggerSpawnsBySpawnId.size(),
GetMSTimeDiffToNow(oldMSTime));
#define VALIDATE_AND_SET_CURVE(Curve, Value)
#define VALIDATE_AND_SET_FLOAT(Float, Value)
AreaTriggerCreatePropertiesFlag
#define MAX_AREATRIGGER_ENTITY_DATA
@ AREATRIGGER_ACTION_TELEPORT
AreaTriggerActionUserTypes
@ AREATRIGGER_ACTION_USER_MAX
DB2Storage< MapDifficultyEntry > sMapDifficultyStore("MapDifficulty.db2", &MapDifficultyLoadInfo::Instance)
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
EnumFlag< AreaTriggerCreatePropertiesFlag > Flags
AreaTriggerCreatePropertiesId Id
Optional< AreaTriggerOrbitInfo > OrbitInfo
AreaTriggerTemplate const * Template
AreaTriggerShapeInfo Shape
std::vector< Position > SplinePoints
AreaTriggerTemplate const * GetAreaTriggerTemplate(AreaTriggerId const &areaTriggerId) const
AreaTriggerCreateProperties const * GetAreaTriggerCreateProperties(AreaTriggerCreatePropertiesId const &areaTriggerCreatePropertiesId) const
std::set< ObjectGuid::LowType > const * GetAreaTriggersForMapAndCell(uint32 mapId, Difficulty difficulty, uint32 cellId) const
void LoadAreaTriggerSpawns()
void LoadAreaTriggerTemplates()
AreaTriggerSpawn const * GetAreaTriggerSpawn(ObjectGuid::LowType spawnId) const
static AreaTriggerDataStore * Instance()
std::vector< AreaTriggerAction > Actions
EnumFlag< AreaTriggerFlag > Flags
Class used to access individual fields of database query result.
static bool IsValidMapCoord(uint32 mapid, float x, float y)
constexpr uint32 GetMapId() const
auto MapGetValuePtr(M &map, typename M::key_type const &key)
void hash_combine(std::size_t &seed, T const &val)
CellCoord ComputeCellCoord(float x, float y)
AreaTriggerActionTypes ActionType
AreaTriggerActionUserTypes TargetType
std::vector< TaggedPosition< Position::XY > > PolygonVertices
AreaTriggerShapeType Type
std::vector< TaggedPosition< Position::XY > > PolygonVerticesTarget
struct AreaTriggerShapeInfo::@199::@204 PolygonDatas
struct AreaTriggerShapeInfo::@199::@201 DefaultDatas
float Data[MAX_AREATRIGGER_ENTITY_DATA]
Optional< int32 > SpellForVisuals
AreaTriggerCreatePropertiesId Id
constexpr float GetPositionX() const
constexpr float GetPositionY() const
std::string ToString() const
constexpr void Relocate(float x, float y)
std::size_t operator()(AreaTriggerId const &value) const noexcept