aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-09-11 22:10:24 +0200
committerShauren <shauren.trinity@gmail.com>2025-09-11 22:10:24 +0200
commitdac548a305c1509240ff6a923ccce8359c98915a (patch)
tree3d650106ecc4f2303b77939b14652ab2bbdf0ac5 /src
parentb6acd368e0bca632d8742c9b5d0ef7f385cf1318 (diff)
Core/AreaTriggers: Refactor AreaTriggerShapeInfo to use std::variant instead of union
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp78
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp73
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h165
-rw-r--r--src/server/game/Globals/AreaTriggerDataStore.cpp59
4 files changed, 211 insertions, 164 deletions
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
index 50edf530586..c7242c87ba7 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
+++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
@@ -962,79 +962,73 @@ uint32 AreaTrigger::GetFaction() const
void AreaTrigger::SetShape(AreaTriggerShapeInfo const& shape)
{
- auto areaTriggerData = m_values.ModifyValue(&AreaTrigger::m_areaTriggerData);
-
- switch (shape.Type)
+ std::visit([this]<typename ShapeType>(ShapeType const& shapeData)
{
- case AreaTriggerShapeType::Sphere:
+ auto areaTriggerData = m_values.ModifyValue(&AreaTrigger::m_areaTriggerData);
+
+ if constexpr (std::is_same_v<ShapeType, AreaTriggerShapeInfo::Sphere>)
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeType), 0);
auto sphere = areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeData, UF::VariantCase<UF::AreaTriggerSphere>);
- SetUpdateFieldValue(sphere.ModifyValue(&UF::AreaTriggerSphere::Radius), shape.SphereDatas.Radius);
- SetUpdateFieldValue(sphere.ModifyValue(&UF::AreaTriggerSphere::RadiusTarget), shape.SphereDatas.RadiusTarget);
- break;
+ SetUpdateFieldValue(sphere.ModifyValue(&UF::AreaTriggerSphere::Radius), shapeData.Radius);
+ SetUpdateFieldValue(sphere.ModifyValue(&UF::AreaTriggerSphere::RadiusTarget), shapeData.RadiusTarget);
}
- case AreaTriggerShapeType::Box:
+ else if constexpr (std::is_same_v<ShapeType, AreaTriggerShapeInfo::Box>)
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeType), 1);
auto box = areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeData, UF::VariantCase<UF::AreaTriggerBox>);
- SetUpdateFieldValue(box.ModifyValue(&UF::AreaTriggerBox::Extents), { shape.BoxDatas.Extents[0], shape.BoxDatas.Extents[1], shape.BoxDatas.Extents[2] });
- SetUpdateFieldValue(box.ModifyValue(&UF::AreaTriggerBox::ExtentsTarget), { shape.BoxDatas.ExtentsTarget[0], shape.BoxDatas.ExtentsTarget[1], shape.BoxDatas.ExtentsTarget[2] });
- break;
+ SetUpdateFieldValue(box.ModifyValue(&UF::AreaTriggerBox::Extents), shapeData.Extents);
+ SetUpdateFieldValue(box.ModifyValue(&UF::AreaTriggerBox::ExtentsTarget), shapeData.ExtentsTarget);
}
- case AreaTriggerShapeType::Polygon:
+ else if constexpr (std::is_same_v<ShapeType, AreaTriggerShapeInfo::Polygon>)
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeType), 3);
auto polygon = areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeData, UF::VariantCase<UF::AreaTriggerPolygon>);
auto vertices = polygon.ModifyValue(&UF::AreaTriggerPolygon::Vertices);
ClearDynamicUpdateFieldValues(vertices);
- for (TaggedPosition<XY> const& vertex : shape.PolygonVertices)
+ for (TaggedPosition<XY> const& vertex : shapeData.PolygonVertices)
AddDynamicUpdateFieldValue(vertices) = vertex;
auto verticesTarget = polygon.ModifyValue(&UF::AreaTriggerPolygon::VerticesTarget);
ClearDynamicUpdateFieldValues(verticesTarget);
- for (TaggedPosition<XY> const& vertex : shape.PolygonVerticesTarget)
+ for (TaggedPosition<XY> const& vertex : shapeData.PolygonVerticesTarget)
AddDynamicUpdateFieldValue(verticesTarget) = vertex;
- SetUpdateFieldValue(polygon.ModifyValue(&UF::AreaTriggerPolygon::Height), shape.PolygonDatas.Height);
- SetUpdateFieldValue(polygon.ModifyValue(&UF::AreaTriggerPolygon::HeightTarget), shape.PolygonDatas.HeightTarget);
- break;
+ SetUpdateFieldValue(polygon.ModifyValue(&UF::AreaTriggerPolygon::Height), shapeData.Height);
+ SetUpdateFieldValue(polygon.ModifyValue(&UF::AreaTriggerPolygon::HeightTarget), shapeData.HeightTarget);
}
- case AreaTriggerShapeType::Cylinder:
+ else if constexpr (std::is_same_v<ShapeType, AreaTriggerShapeInfo::Cylinder>)
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeType), 4);
auto cylinder = areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeData, UF::VariantCase<UF::AreaTriggerCylinder>);
- SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::Radius), shape.CylinderDatas.Radius);
- SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::RadiusTarget), shape.CylinderDatas.RadiusTarget);
- SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::Height), shape.CylinderDatas.Height);
- SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::HeightTarget), shape.CylinderDatas.HeightTarget);
- SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::LocationZOffset), shape.CylinderDatas.LocationZOffset);
- SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::LocationZOffsetTarget), shape.CylinderDatas.LocationZOffsetTarget);
- break;
+ SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::Radius), shapeData.Radius);
+ SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::RadiusTarget), shapeData.RadiusTarget);
+ SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::Height), shapeData.Height);
+ SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::HeightTarget), shapeData.HeightTarget);
+ SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::LocationZOffset), shapeData.LocationZOffset);
+ SetUpdateFieldValue(cylinder.ModifyValue(&UF::AreaTriggerCylinder::LocationZOffsetTarget), shapeData.LocationZOffsetTarget);
}
- case AreaTriggerShapeType::Disk:
+ else if constexpr (std::is_same_v<ShapeType, AreaTriggerShapeInfo::Disk>)
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeType), 7);
auto disk = areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeData, UF::VariantCase<UF::AreaTriggerDisk>);
- SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::InnerRadius), shape.DiskDatas.InnerRadius);
- SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::InnerRadiusTarget), shape.DiskDatas.InnerRadiusTarget);
- SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::OuterRadius), shape.DiskDatas.OuterRadius);
- SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::OuterRadiusTarget), shape.DiskDatas.OuterRadiusTarget);
- SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::Height), shape.DiskDatas.Height);
- SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::HeightTarget), shape.DiskDatas.HeightTarget);
- SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::LocationZOffset), shape.DiskDatas.LocationZOffset);
- SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::LocationZOffsetTarget), shape.DiskDatas.LocationZOffsetTarget);
- break;
+ SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::InnerRadius), shapeData.InnerRadius);
+ SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::InnerRadiusTarget), shapeData.InnerRadiusTarget);
+ SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::OuterRadius), shapeData.OuterRadius);
+ SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::OuterRadiusTarget), shapeData.OuterRadiusTarget);
+ SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::Height), shapeData.Height);
+ SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::HeightTarget), shapeData.HeightTarget);
+ SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::LocationZOffset), shapeData.LocationZOffset);
+ SetUpdateFieldValue(disk.ModifyValue(&UF::AreaTriggerDisk::LocationZOffsetTarget), shapeData.LocationZOffsetTarget);
}
- case AreaTriggerShapeType::BoundedPlane:
+ else if constexpr (std::is_same_v<ShapeType, AreaTriggerShapeInfo::BoundedPlane>)
{
SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeType), 8);
auto boundedPlane = areaTriggerData.ModifyValue(&UF::AreaTriggerData::ShapeData, UF::VariantCase<UF::AreaTriggerBoundedPlane>);
- SetUpdateFieldValue(boundedPlane.ModifyValue(&UF::AreaTriggerBoundedPlane::Extents), { shape.BoundedPlaneDatas.Extents[0], shape.BoundedPlaneDatas.Extents[1] });
- SetUpdateFieldValue(boundedPlane.ModifyValue(&UF::AreaTriggerBoundedPlane::ExtentsTarget), { shape.BoundedPlaneDatas.ExtentsTarget[0], shape.BoundedPlaneDatas.ExtentsTarget[1] });
- break;
+ SetUpdateFieldValue(boundedPlane.ModifyValue(&UF::AreaTriggerBoundedPlane::Extents), shapeData.Extents);
+ SetUpdateFieldValue(boundedPlane.ModifyValue(&UF::AreaTriggerBoundedPlane::ExtentsTarget), shapeData.ExtentsTarget);
}
- default:
- break;
- }
+ else
+ static_assert(Trinity::dependant_false_v<ShapeType>, "Unsupported shape type");
+ }, shape.Data);
}
float AreaTrigger::GetMaxSearchRadius() const
diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp
index 4f4a078c78a..24cfdf89c95 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp
+++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.cpp
@@ -17,51 +17,54 @@
#include "AreaTriggerTemplate.h"
#include <algorithm>
-#include <cstring>
#include <cmath>
-AreaTriggerShapeInfo::AreaTriggerShapeInfo()
+float AreaTriggerShapeInfo::Sphere::GetMaxSearchRadius() const
{
- Type = AreaTriggerShapeType::Max;
- memset(DefaultDatas.Data, 0, sizeof(DefaultDatas.Data));
+ return std::max(Radius, RadiusTarget);
}
-float AreaTriggerShapeInfo::GetMaxSearchRadius() const
+float AreaTriggerShapeInfo::Box::GetMaxSearchRadius() const
+{
+ return std::sqrt(std::max(
+ Extents.Pos.GetPositionX() * Extents.Pos.GetPositionX() + Extents.Pos.GetPositionY() * Extents.Pos.GetPositionY(),
+ ExtentsTarget.Pos.GetPositionX() * ExtentsTarget.Pos.GetPositionX() + ExtentsTarget.Pos.GetPositionY() * ExtentsTarget.Pos.GetPositionY()));
+}
+
+float AreaTriggerShapeInfo::Polygon::GetMaxSearchRadius() const
{
- switch (Type)
- {
- case AreaTriggerShapeType::Sphere:
- return std::max(SphereDatas.Radius, SphereDatas.RadiusTarget);
- case AreaTriggerShapeType::Box:
- return std::sqrt(std::max(
- BoxDatas.Extents[0] * BoxDatas.Extents[0] + BoxDatas.Extents[1] * BoxDatas.Extents[1],
- BoxDatas.ExtentsTarget[0] * BoxDatas.ExtentsTarget[0] + BoxDatas.ExtentsTarget[1] * BoxDatas.ExtentsTarget[1]));
- case AreaTriggerShapeType::Polygon:
- {
- Position center(0.0f, 0.0f);
- float maxSearchRadius = 0.0f;
+ Position center(0.0f, 0.0f);
+ float maxSearchRadius = 0.0f;
+
+ for (TaggedPosition<Position::XY> const& vertex : PolygonVertices)
+ maxSearchRadius = std::max(maxSearchRadius, center.GetExactDist2d(vertex));
+
+ for (TaggedPosition<Position::XY> const& vertex : PolygonVerticesTarget)
+ maxSearchRadius = std::max(maxSearchRadius, center.GetExactDist2d(vertex));
+
+ return maxSearchRadius;
+}
- for (TaggedPosition<Position::XY> const& vertex : PolygonVertices)
- maxSearchRadius = std::max(maxSearchRadius, center.GetExactDist2d(vertex));
+float AreaTriggerShapeInfo::Cylinder::GetMaxSearchRadius() const
+{
+ return std::max(Radius, RadiusTarget);
+}
- for (TaggedPosition<Position::XY> const& vertex : PolygonVerticesTarget)
- maxSearchRadius = std::max(maxSearchRadius, center.GetExactDist2d(vertex));
+float AreaTriggerShapeInfo::Disk::GetMaxSearchRadius() const
+{
+ return std::max(OuterRadius, OuterRadiusTarget);
+}
- return maxSearchRadius;
- }
- case AreaTriggerShapeType::Cylinder:
- return std::max(CylinderDatas.Radius, CylinderDatas.RadiusTarget);
- case AreaTriggerShapeType::Disk:
- return std::max(DiskDatas.OuterRadius, DiskDatas.OuterRadiusTarget);
- case AreaTriggerShapeType::BoundedPlane:
- return std::sqrt(std::max(
- BoundedPlaneDatas.Extents[0] * BoundedPlaneDatas.Extents[0] / 4 + BoundedPlaneDatas.Extents[1] * BoundedPlaneDatas.Extents[1] / 4,
- BoundedPlaneDatas.ExtentsTarget[0] * BoundedPlaneDatas.ExtentsTarget[0] / 4 + BoundedPlaneDatas.ExtentsTarget[1] * BoundedPlaneDatas.ExtentsTarget[1] / 4));
- default:
- break;
- }
+float AreaTriggerShapeInfo::BoundedPlane::GetMaxSearchRadius() const
+{
+ return std::sqrt(std::max(
+ Extents.Pos.GetPositionX() * Extents.Pos.GetPositionX() / 4 + Extents.Pos.GetPositionY() * Extents.Pos.GetPositionY() / 4,
+ ExtentsTarget.Pos.GetPositionX() * ExtentsTarget.Pos.GetPositionX() / 4 + ExtentsTarget.Pos.GetPositionY() * ExtentsTarget.Pos.GetPositionY() / 4));
+}
- return 0.0f;
+float AreaTriggerShapeInfo::GetMaxSearchRadius() const
+{
+ return std::visit([&](auto const& data) { return data.GetMaxSearchRadius(); }, Data);
}
AreaTriggerTemplate::AreaTriggerTemplate() = default;
diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
index d6a10f50364..9d2cdb9de97 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
+++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
@@ -95,80 +95,107 @@ struct AreaTriggerAction
struct AreaTriggerShapeInfo
{
- AreaTriggerShapeInfo();
-
- bool IsSphere() const { return Type == AreaTriggerShapeType::Sphere; }
- bool IsBox() const { return Type == AreaTriggerShapeType::Box; }
- bool IsPolygon() const { return Type == AreaTriggerShapeType::Polygon; }
- bool IsCylinder() const { return Type == AreaTriggerShapeType::Cylinder; }
- bool IsDisk() const { return Type == AreaTriggerShapeType::Disk; }
- bool IsBoundedPlane() const { return Type == AreaTriggerShapeType::BoundedPlane; }
- float GetMaxSearchRadius() const;
+ struct Sphere
+ {
+ Sphere()
+ : Radius(0.0f), RadiusTarget(0.0f) { }
+ explicit Sphere(std::array<float, MAX_AREATRIGGER_ENTITY_DATA> const& raw)
+ : Radius(raw[0]), RadiusTarget(raw[1]) { }
+
+ float Radius;
+ float RadiusTarget;
+
+ float GetMaxSearchRadius() const;
+ };
+
+ struct Box
+ {
+ Box()
+ : Extents(), ExtentsTarget() { }
+ explicit Box(std::array<float, MAX_AREATRIGGER_ENTITY_DATA> const& raw)
+ : Extents(raw[0], raw[1], raw[2]), ExtentsTarget(raw[3], raw[4], raw[5]) { }
+
+ TaggedPosition<Position::XYZ> Extents;
+ TaggedPosition<Position::XYZ> ExtentsTarget;
+
+ float GetMaxSearchRadius() const;
+ };
+
+ struct Polygon
+ {
+ Polygon()
+ : PolygonVertices(), PolygonVerticesTarget(), Height(0.0f), HeightTarget(0.0f) { }
+ explicit Polygon(std::array<float, MAX_AREATRIGGER_ENTITY_DATA> const& raw)
+ : PolygonVertices(), PolygonVerticesTarget(), Height(raw[0]), HeightTarget(raw[1]) { }
- AreaTriggerShapeType Type;
+ std::vector<TaggedPosition<Position::XY>> PolygonVertices;
+ std::vector<TaggedPosition<Position::XY>> PolygonVerticesTarget;
+ float Height;
+ float HeightTarget;
- std::vector<TaggedPosition<Position::XY>> PolygonVertices;
- std::vector<TaggedPosition<Position::XY>> PolygonVerticesTarget;
+ float GetMaxSearchRadius() const;
+ };
+
+ struct Cylinder
+ {
+ Cylinder()
+ : Radius(0.0f), RadiusTarget(0.0f), Height(0.0f), HeightTarget(0.0f), LocationZOffset(0.0f), LocationZOffsetTarget(0.0f) { }
+ explicit Cylinder(std::array<float, MAX_AREATRIGGER_ENTITY_DATA> const& raw)
+ : Radius(raw[0]), RadiusTarget(raw[1]), Height(raw[2]), HeightTarget(raw[3]), LocationZOffset(raw[4]), LocationZOffsetTarget(raw[5]) { }
+
+ float Radius;
+ float RadiusTarget;
+ float Height;
+ float HeightTarget;
+ float LocationZOffset;
+ float LocationZOffsetTarget;
+
+ float GetMaxSearchRadius() const;
+ };
+
+ struct Disk
+ {
+ Disk()
+ : InnerRadius(0.0f), InnerRadiusTarget(0.0f), OuterRadius(0.0f), OuterRadiusTarget(0.0f),
+ Height(0.0f), HeightTarget(0.0f), LocationZOffset(0.0f), LocationZOffsetTarget(0.0f) { }
+ explicit Disk(std::array<float, MAX_AREATRIGGER_ENTITY_DATA> const& raw)
+ : InnerRadius(raw[0]), InnerRadiusTarget(raw[1]), OuterRadius(raw[2]), OuterRadiusTarget(raw[3]),
+ Height(raw[4]), HeightTarget(raw[5]), LocationZOffset(raw[6]), LocationZOffsetTarget(raw[7]) { }
+
+ float InnerRadius;
+ float InnerRadiusTarget;
+ float OuterRadius;
+ float OuterRadiusTarget;
+ float Height;
+ float HeightTarget;
+ float LocationZOffset;
+ float LocationZOffsetTarget;
+
+ float GetMaxSearchRadius() const;
+ };
- union
+ struct BoundedPlane
{
- struct
- {
- float Data[MAX_AREATRIGGER_ENTITY_DATA];
- } DefaultDatas;
-
- // AreaTriggerShapeType::Sphere
- struct
- {
- float Radius;
- float RadiusTarget;
- } SphereDatas;
-
- // AreaTriggerShapeType::Box
- struct
- {
- float Extents[3];
- float ExtentsTarget[3];
- } BoxDatas;
-
- // AreaTriggerShapeType::Polygon
- struct
- {
- float Height;
- float HeightTarget;
- } PolygonDatas;
-
- // AreaTriggerShapeType::Cylinder
- struct
- {
- float Radius;
- float RadiusTarget;
- float Height;
- float HeightTarget;
- float LocationZOffset;
- float LocationZOffsetTarget;
- } CylinderDatas;
-
- // AreaTriggerShapeType::Disk
- struct
- {
- float InnerRadius;
- float InnerRadiusTarget;
- float OuterRadius;
- float OuterRadiusTarget;
- float Height;
- float HeightTarget;
- float LocationZOffset;
- float LocationZOffsetTarget;
- } DiskDatas;
-
- // AreaTriggerShapeType::BoundedPlane
- struct
- {
- float Extents[2];
- float ExtentsTarget[2];
- } BoundedPlaneDatas;
+ BoundedPlane()
+ : Extents(), ExtentsTarget() { }
+ explicit BoundedPlane(std::array<float, MAX_AREATRIGGER_ENTITY_DATA> const& raw)
+ : Extents(raw[0], raw[1]), ExtentsTarget(raw[2], raw[3]) { }
+
+ TaggedPosition<Position::XY> Extents;
+ TaggedPosition<Position::XY> ExtentsTarget;
+
+ float GetMaxSearchRadius() const;
};
+
+ std::variant<Sphere, Box, Polygon, Cylinder, Disk, BoundedPlane> Data;
+
+ bool IsSphere() const { return std::holds_alternative<Sphere>(Data); }
+ bool IsBox() const { return std::holds_alternative<Box>(Data); }
+ bool IsPolygon() const { return std::holds_alternative<Polygon>(Data); }
+ bool IsCylinder() const { return std::holds_alternative<Cylinder>(Data); }
+ bool IsDisk() const { return std::holds_alternative<Disk>(Data); }
+ bool IsBoundedPlane() const { return std::holds_alternative<BoundedPlane>(Data); }
+ float GetMaxSearchRadius() const;
};
struct AreaTriggerOrbitInfo
diff --git a/src/server/game/Globals/AreaTriggerDataStore.cpp b/src/server/game/Globals/AreaTriggerDataStore.cpp
index d5c19690afb..67d9132a2a2 100644
--- a/src/server/game/Globals/AreaTriggerDataStore.cpp
+++ b/src/server/game/Globals/AreaTriggerDataStore.cpp
@@ -196,7 +196,7 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates()
continue;
}
- if (shape >= AreaTriggerShapeType::Max)
+ if (shape == AreaTriggerShapeType::Unk || shape >= AreaTriggerShapeType::Max)
{
TC_LOG_ERROR("sql.sql", "Table `areatrigger_create_properties` has listed AreaTriggerCreatePropertiesId (Id: {}, IsCustom: {}) with invalid shape {}.",
createPropertiesId.Id, uint32(createPropertiesId.IsCustom), uint32(shape));
@@ -237,30 +237,53 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates()
createProperties.TimeToTargetScale = fields[13].GetUInt32();
createProperties.Speed = fields[14].GetFloat();
- createProperties.Shape.Type = shape;
+ std::array<float, MAX_AREATRIGGER_ENTITY_DATA> shapeData = { };
for (uint8 i = 0; i < MAX_AREATRIGGER_ENTITY_DATA; ++i)
- createProperties.Shape.DefaultDatas.Data[i] = fields[16 + i].GetFloat();
+ shapeData[i] = fields[16 + i].GetFloat();
- createProperties.ScriptId = sObjectMgr->GetScriptId(fields[24].GetString());
-
- if (shape == AreaTriggerShapeType::Polygon)
+ switch (shape)
{
- if (createProperties.Shape.PolygonDatas.Height <= 0.0f)
+ case AreaTriggerShapeType::Sphere:
+ createProperties.Shape.Data.emplace<AreaTriggerShapeInfo::Sphere>(shapeData);
+ break;
+ case AreaTriggerShapeType::Box:
+ createProperties.Shape.Data.emplace<AreaTriggerShapeInfo::Box>(shapeData);
+ break;
+ case AreaTriggerShapeType::Polygon:
{
- createProperties.Shape.PolygonDatas.Height = 1.0f;
- if (createProperties.Shape.PolygonDatas.HeightTarget <= 0.0f)
- createProperties.Shape.PolygonDatas.HeightTarget = 1.0f;
+ AreaTriggerShapeInfo::Polygon& polygon = createProperties.Shape.Data.emplace<AreaTriggerShapeInfo::Polygon>(shapeData);
+ if (polygon.Height <= 0.0f)
+ {
+ polygon.Height = 1.0f;
+ if (polygon.HeightTarget <= 0.0f)
+ polygon.HeightTarget = 1.0f;
+ }
+ if (std::vector<TaggedPosition<Position::XY>>* vertices = Trinity::Containers::MapGetValuePtr(verticesByCreateProperties, createProperties.Id))
+ polygon.PolygonVertices = std::move(*vertices);
+ if (std::vector<TaggedPosition<Position::XY>>* vertices = Trinity::Containers::MapGetValuePtr(verticesTargetByCreateProperties, createProperties.Id))
+ polygon.PolygonVerticesTarget = std::move(*vertices);
+ if (!polygon.PolygonVerticesTarget.empty() && polygon.PolygonVertices.size() != polygon.PolygonVerticesTarget.size())
+ {
+ 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: {})).",
+ createPropertiesId.Id, uint32(createPropertiesId.IsCustom));
+ polygon.PolygonVerticesTarget.clear();
+ }
+ break;
}
+ case AreaTriggerShapeType::Cylinder:
+ createProperties.Shape.Data.emplace<AreaTriggerShapeInfo::Cylinder>(shapeData);
+ break;
+ case AreaTriggerShapeType::Disk:
+ createProperties.Shape.Data.emplace<AreaTriggerShapeInfo::Disk>(shapeData);
+ break;
+ case AreaTriggerShapeType::BoundedPlane:
+ createProperties.Shape.Data.emplace<AreaTriggerShapeInfo::BoundedPlane>(shapeData);
+ break;
+ default:
+ break;
}
- createProperties.Shape.PolygonVertices = std::move(verticesByCreateProperties[createProperties.Id]);
- createProperties.Shape.PolygonVerticesTarget = std::move(verticesTargetByCreateProperties[createProperties.Id]);
- if (!createProperties.Shape.PolygonVerticesTarget.empty() && createProperties.Shape.PolygonVertices.size() != createProperties.Shape.PolygonVerticesTarget.size())
- {
- 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: {})).",
- createPropertiesId.Id, uint32(createPropertiesId.IsCustom));
- createProperties.Shape.PolygonVerticesTarget.clear();
- }
+ createProperties.ScriptId = sObjectMgr->GetScriptId(fields[24].GetString());
if (std::vector<Position>* spline = Trinity::Containers::MapGetValuePtr(splinesByCreateProperties, createProperties.Id))
createProperties.Movement = std::move(*spline);