From d3446aed99ff0b86dbbae67655160dddbde68b2e Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 23 Apr 2026 12:43:11 +0200 Subject: [PATCH] Core/Misc: Apply random position selection improvements from ed2a08dc707808caaf5f4b876620dcb510706f96 to WorldObject::GetRandomPoint and WorldObject::GetRandomNearPosition Signed-off-by: luis --- src/server/game/Entities/Object/Object.cpp | 41 ++++++++----------- src/server/game/Entities/Object/Object.h | 3 +- .../instance_culling_of_stratholme.cpp | 5 +-- .../KulTiras/WaycrestManor/waycrest_manor.cpp | 5 +-- .../AzjolNerub/AzjolNerub/boss_anubarak.cpp | 13 ++---- .../Northrend/Naxxramas/boss_kelthuzad.cpp | 12 +----- 6 files changed, 23 insertions(+), 56 deletions(-) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 97fddf919..0876aba61 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -685,32 +685,23 @@ bool WorldObject::isInBack(WorldObject const* target, float arc) const return !HasInArc(2 * float(M_PI) - arc, target); } -void WorldObject::GetRandomPoint(Position const& pos, float distance, float& rand_x, float& rand_y, float& rand_z) const -{ - if (!distance) - { - pos.GetPosition(rand_x, rand_y, rand_z); - return; - } - - // angle to face `obj` to `this` - float angle = rand_norm() * static_cast(2 * M_PI); - float new_dist = rand_norm() + rand_norm(); - new_dist = distance * (new_dist > 1 ? new_dist - 2 : new_dist); - - rand_x = pos.m_positionX + new_dist * std::cos(angle); - rand_y = pos.m_positionY + new_dist * std::sin(angle); - rand_z = pos.m_positionZ; - - Trinity::NormalizeMapCoord(rand_x); - Trinity::NormalizeMapCoord(rand_y); - UpdateGroundPositionZ(rand_x, rand_y, rand_z); // update to LOS height if available -} - -Position WorldObject::GetRandomPoint(Position const& srcPos, float distance) const +Position WorldObject::GetRandomPoint(Position const& srcPos, float distance, float minDistance /*= 0.0f*/) const { float x, y, z; - GetRandomPoint(srcPos, distance, x, y, z); + srcPos.GetPosition(x, y, z); + if (distance) + { + // angle to face `obj` to `this` + float angle = rand_norm() * static_cast(2 * M_PI); + float new_dist = minDistance + (distance - minDistance) * std::sqrt(rand_norm()); + + x += new_dist * std::cos(angle); + y += new_dist * std::sin(angle); + + Trinity::NormalizeMapCoord(x); + Trinity::NormalizeMapCoord(y); + UpdateGroundPositionZ(x, y, z); // update to LOS height if available + } return Position(x, y, z, GetOrientation()); } @@ -2808,7 +2799,7 @@ Position WorldObject::GetFirstCollisionPosition(float dist, float angle) Position WorldObject::GetRandomNearPosition(float radius) { Position pos = GetPosition(); - MovePosition(pos, radius * rand_norm(), rand_norm() * static_cast(2 * M_PI)); + MovePosition(pos, radius * std::sqrt(rand_norm()), rand_norm() * static_cast(2 * M_PI)); return pos; } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index f2a4bef39..4704c0253 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -304,8 +304,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation void UpdateGroundPositionZ(float x, float y, float &z) const; void UpdateAllowedPositionZ(float x, float y, float &z, float* groundZ = nullptr) const; - void GetRandomPoint(Position const& srcPos, float distance, float& rand_x, float& rand_y, float& rand_z) const; - Position GetRandomPoint(Position const& srcPos, float distance) const; + Position GetRandomPoint(Position const& srcPos, float distance, float minDistance = 0.0f) const; uint32 GetInstanceId() const { return m_InstanceId; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp index 2ccf5686a..30fc63a57 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp @@ -403,10 +403,7 @@ class instance_culling_of_stratholme : public InstanceMapScript if (player->GetGUID() == guid || !player->IsGameMaster()) { player->CombatStop(true); - constexpr float offsetDist = 10.0f; - float myAngle = rand_norm() * static_cast(2.0f * M_PI); - Position myTarget(target.GetPositionX() + std::sin(myAngle) * offsetDist, target.GetPositionY() + std::sin(myAngle) * offsetDist, target.GetPositionZ(), myAngle + M_PI); - player->NearTeleportTo(myTarget); + player->NearTeleportTo(player->GetRandomPoint(target, 10.0f)); } } break; diff --git a/src/server/scripts/KulTiras/WaycrestManor/waycrest_manor.cpp b/src/server/scripts/KulTiras/WaycrestManor/waycrest_manor.cpp index 444508cdb..c748a7106 100644 --- a/src/server/scripts/KulTiras/WaycrestManor/waycrest_manor.cpp +++ b/src/server/scripts/KulTiras/WaycrestManor/waycrest_manor.cpp @@ -211,10 +211,7 @@ class spell_waycrest_manor_wildfire : public AuraScript { static constexpr Position CircleCenterPos = { -422.13f, -258.28f, 233.8286f, 0.0f }; - Position randomPos = CircleCenterPos; - GetTarget()->MovePosition(randomPos, 30.0f * rand_norm(), rand_norm() * static_cast(2 * M_PI)); - - return randomPos; + return GetTarget()->GetRandomPoint(CircleCenterPos, 30.0f); } Position GetRandomPositionInRectangle() diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp index c4eaeef3d..1343d6ac8 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp @@ -455,14 +455,6 @@ struct npc_anubarak_anub_ar_assassin : public npc_anubarak_pet_template { npc_anubarak_anub_ar_assassin(Creature* creature) : npc_anubarak_pet_template(creature, false){ } - Position GetRandomPositionAround(Creature* anubarak) - { - static float DISTANCE_MIN = 10.0f; - static float DISTANCE_MAX = 30.0f; - double angle = rand_norm() * 2.0 * M_PI; - return { anubarak->GetPositionX() + (float)(frand(DISTANCE_MIN, DISTANCE_MAX)*std::sin(angle)), anubarak->GetPositionY() + (float)(frand(DISTANCE_MIN, DISTANCE_MAX)*std::cos(angle)), anubarak->GetPositionZ() }; - } - void InitializeAI() override { npc_anubarak_pet_template::InitializeAI(); @@ -470,9 +462,10 @@ struct npc_anubarak_anub_ar_assassin : public npc_anubarak_pet_template if (Creature* anubarak = _instance->GetCreature(DATA_ANUBARAK)) { Position jumpTo; + uint32 attempts = 0; do - jumpTo = GetRandomPositionAround(anubarak); - while (!CreatureAI::IsInBounds(*boundary, &jumpTo)); + jumpTo = anubarak->GetRandomPoint(anubarak->GetPosition(), 10.f, 30.0f); + while (!CreatureAI::IsInBounds(*boundary, &jumpTo) && attempts < 10); me->GetMotionMaster()->MoveJump(EVENT_JUMP, jumpTo, 24.0f, 20.0f, 30.0f); DoCastSelf(SPELL_ASSASSIN_VISUAL, true); } diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index a36f99be4..b57ac5baa 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -156,16 +156,6 @@ static inline Position const& GetRandomMinionSpawnPoint() return minionSpawnPoints[urand(0, nMinionSpawnPoints - 1)]; } -// uniformly distribute on the circle -static Position GetRandomPositionOnCircle(Position const& center, float radius) -{ - float angle = float(M_PI * rand_norm() * 2.0); - float relDistance = rand_norm() + rand_norm(); - if (relDistance > 1) - relDistance = 1 - relDistance; - return Position(center.GetPositionX() + std::sin(angle) * relDistance * radius, center.GetPositionY() + std::cos(angle) * relDistance * radius, center.GetPositionZ()); -} - class KelThuzadCharmedPlayerAI : public SimpleCharmedPlayerAI { public: @@ -664,7 +654,7 @@ struct npc_kelthuzad_minionAI : public ScriptedAI if (_movementTimer <= diff) { _movementTimer = 0; - me->GetMotionMaster()->MovePoint(MOVEMENT_MINION_RANDOM, GetRandomPositionOnCircle(_home, 3.0f)); + me->GetMotionMaster()->MovePoint(MOVEMENT_MINION_RANDOM, me->GetRandomPoint(_home, 3.0f)); } else _movementTimer -= diff;