From c1b8daa6390cf00a07ef30e5de8061e158adb439 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 12 Sep 2025 00:58:27 +0200 Subject: Core/AreaTriggers: Implemented `SpeedIsTime` parameter for areatrigger splines and orbit --- sql/updates/world/master/2025_09_12_00_world.sql | 1 + src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 16 ++++++++-------- src/server/game/Entities/AreaTrigger/AreaTrigger.h | 6 +++--- .../game/Entities/AreaTrigger/AreaTriggerTemplate.h | 1 + src/server/game/Globals/AreaTriggerDataStore.cpp | 5 +++-- 5 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 sql/updates/world/master/2025_09_12_00_world.sql diff --git a/sql/updates/world/master/2025_09_12_00_world.sql b/sql/updates/world/master/2025_09_12_00_world.sql new file mode 100644 index 00000000000..a115f8bed17 --- /dev/null +++ b/sql/updates/world/master/2025_09_12_00_world.sql @@ -0,0 +1 @@ +ALTER TABLE `areatrigger_create_properties` ADD `SpeedIsTime` tinyint(1) unsigned NOT NULL DEFAULT '0' AFTER `Speed`; diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index c7242c87ba7..aac3e19c788 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -252,10 +252,10 @@ bool AreaTrigger::Create(AreaTriggerCreatePropertiesId areaTriggerCreateProperti else orbit.Center = pos; - this->InitOrbit(orbit, GetCreateProperties()->Speed); + this->InitOrbit(orbit, {}, GetCreateProperties()->SpeedIsTime); } else if constexpr (std::is_same_v) - this->InitSplineOffsets(movement); + this->InitSplineOffsets(movement, {}, GetCreateProperties()->SpeedIsTime); else if constexpr (std::is_same_v) this->SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::PathType), int32(AreaTriggerPathType::None)); else @@ -1195,7 +1195,7 @@ void AreaTrigger::UndoActions(Unit* unit) } } -void AreaTrigger::InitSplineOffsets(std::vector const& offsets, Optional overrideSpeed) +void AreaTrigger::InitSplineOffsets(std::vector const& offsets, Optional overrideSpeed /*= {}*/, bool speedIsTimeInSeconds /*= false*/) { float angleSin = std::sin(GetOrientation()); float angleCos = std::cos(GetOrientation()); @@ -1214,10 +1214,10 @@ void AreaTrigger::InitSplineOffsets(std::vector const& offsets, Option rotatedPoints[i].z += offset.GetPositionZ(); } - InitSplines(rotatedPoints, overrideSpeed); + InitSplines(rotatedPoints, overrideSpeed, speedIsTimeInSeconds); } -void AreaTrigger::InitSplines(std::vector const& splinePoints, Optional overrideSpeed) +void AreaTrigger::InitSplines(std::vector const& splinePoints, Optional overrideSpeed /*= {}*/, bool speedIsTimeInSeconds /*= false*/) { if (splinePoints.size() < 2) return; @@ -1230,7 +1230,7 @@ void AreaTrigger::InitSplines(std::vector const& splinePoints, Opt if (speed <= 0.0f) speed = 1.0f; - uint32 timeToTarget = spline->length() / speed * float(IN_MILLISECONDS); + uint32 timeToTarget = (speedIsTimeInSeconds ? speed : spline->length() / speed) * static_cast(IN_MILLISECONDS); auto areaTriggerData = m_values.ModifyValue(&AreaTrigger::m_areaTriggerData); SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::TimeToTarget), timeToTarget); @@ -1256,7 +1256,7 @@ uint32 AreaTrigger::GetElapsedTimeForMovement() const return 0; } -void AreaTrigger::InitOrbit(AreaTriggerOrbitInfo const& orbit, Optional overrideSpeed) +void AreaTrigger::InitOrbit(AreaTriggerOrbitInfo const& orbit, Optional overrideSpeed /*= {}*/, bool speedIsTimeInSeconds /*= false*/) { // Circular movement requires either a center position or an attached unit ASSERT(orbit.Center.has_value() || orbit.PathTarget.has_value()); @@ -1265,7 +1265,7 @@ void AreaTrigger::InitOrbit(AreaTriggerOrbitInfo const& orbit, Optional o if (speed <= 0.0f) speed = 1.0f; - uint32 timeToTarget = static_cast(orbit.Radius * 2.0f * static_cast(M_PI) * static_cast(IN_MILLISECONDS) / speed); + uint32 timeToTarget = (speedIsTimeInSeconds ? speed : static_cast(orbit.Radius * 2.0f * static_cast(M_PI) / speed)) * static_cast(IN_MILLISECONDS); auto areaTriggerData = m_values.ModifyValue(&AreaTrigger::m_areaTriggerData); SetUpdateFieldValue(areaTriggerData.ModifyValue(&UF::AreaTriggerData::TimeToTarget), timeToTarget); diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index a28cf2d0cfe..4773ea63181 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -180,13 +180,13 @@ class TC_GAME_API AreaTrigger final : public WorldObject, public GridObject const& offsets, Optional overrideSpeed = {}); - void InitSplines(std::vector const& splinePoints, Optional overrideSpeed = {}); + void InitSplineOffsets(std::vector const& offsets, Optional overrideSpeed = {}, bool speedIsTimeInSeconds = false); + void InitSplines(std::vector const& splinePoints, Optional overrideSpeed = {}, bool speedIsTimeInSeconds = false); bool HasSplines() const { return _spline != nullptr; } ::Movement::Spline const& GetSpline() const { return *_spline; } uint32 GetElapsedTimeForMovement() const; - void InitOrbit(AreaTriggerOrbitInfo const& orbit, Optional overrideSpeed = {}); + void InitOrbit(AreaTriggerOrbitInfo const& orbit, Optional overrideSpeed = {}, bool speedIsTimeInSeconds = false); bool HasOrbit() const { return m_areaTriggerData->PathData.Is(); } UF::AreaTriggerOrbit const& GetOrbit() const { return *m_areaTriggerData->PathData.Get(); } diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h index 9d2cdb9de97..50e471d23c9 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h +++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h @@ -251,6 +251,7 @@ public: AreaTriggerShapeInfo Shape; float Speed = 1.0f; + bool SpeedIsTime = false; using SplineInfo = std::vector; std::variant Movement; diff --git a/src/server/game/Globals/AreaTriggerDataStore.cpp b/src/server/game/Globals/AreaTriggerDataStore.cpp index c81af657b62..705dfff7084 100644 --- a/src/server/game/Globals/AreaTriggerDataStore.cpp +++ b/src/server/game/Globals/AreaTriggerDataStore.cpp @@ -169,13 +169,13 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() } if (QueryResult areatriggerCreateProperties = WorldDatabase.Query("SELECT Id, IsCustom, AreaTriggerId, IsAreatriggerCustom, Flags, " - "MoveCurveId, ScaleCurveId, MorphCurveId, FacingCurveId, AnimId, AnimKitId, DecalPropertiesId, SpellForVisuals, TimeToTargetScale, Speed, " + "MoveCurveId, ScaleCurveId, MorphCurveId, FacingCurveId, AnimId, AnimKitId, DecalPropertiesId, SpellForVisuals, TimeToTargetScale, Speed, SpeedIsTime, " "Shape, ShapeData0, ShapeData1, ShapeData2, ShapeData3, ShapeData4, ShapeData5, ShapeData6, ShapeData7, ScriptName FROM `areatrigger_create_properties`")) { do { DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(ResultSet, (Id)(IsCustom)(AreaTriggerId)(IsAreatriggerCustom)(Flags) - (MoveCurveId)(ScaleCurveId)(MorphCurveId)(FacingCurveId)(AnimId)(AnimKitId)(DecalPropertiesId)(SpellForVisuals)(TimeToTargetScale)(Speed) + (MoveCurveId)(ScaleCurveId)(MorphCurveId)(FacingCurveId)(AnimId)(AnimKitId)(DecalPropertiesId)(SpellForVisuals)(TimeToTargetScale)(Speed)(SpeedIsTime) (Shape)(ShapeData0)(ShapeData1)(ShapeData2)(ShapeData3)(ShapeData4)(ShapeData5)(ShapeData6)(ShapeData7)(ScriptName) ) fields { *areatriggerCreateProperties }; @@ -238,6 +238,7 @@ void AreaTriggerDataStore::LoadAreaTriggerTemplates() createProperties.TimeToTargetScale = fields.TimeToTargetScale().GetUInt32(); createProperties.Speed = fields.Speed().GetFloat(); + createProperties.SpeedIsTime = fields.SpeedIsTime().GetBool(); std::array shapeData = { -- cgit v1.2.3