Skip to content

Commit

Permalink
fix(Script/BlackTemple): teleport position with fatal attraction (aze…
Browse files Browse the repository at this point in the history
…rothcore#19971)

* fix(Script/BlackTemple): teleport position with fatal attraction

* fix codestyle

* try a new way by keeping a random teleport

* remove the old fixed position

* improve the dest selection

* raycast around the new position for check a valid dest

* fix codestyle

* revert the old changes

* refactor to remove the while loop

* few refactor

* Revert "few refactor"

This reverts commit fb7613d.

* .

* add a los check

* new improvement with stairs cases & console errors

* fix disableWarning option

* Update boss_mother_shahraz.cpp

* Update boss_mother_shahraz.cpp

* Update boss_mother_shahraz.cpp

* Update boss_mother_shahraz.cpp

* Update boss_mother_shahraz.cpp
  • Loading branch information
Grimdhex authored Sep 28, 2024
1 parent c2a0d8c commit 8bf3595
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
14 changes: 8 additions & 6 deletions src/server/game/Entities/Object/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2725,17 +2725,17 @@ bool WorldObject::GetClosePoint(float& x, float& y, float& z, float size, float
return true;
}

Position WorldObject::GetNearPosition(float dist, float angle)
Position WorldObject::GetNearPosition(float dist, float angle, bool disableWarning)
{
Position pos = GetPosition();
MovePosition(pos, dist, angle);
MovePosition(pos, dist, angle, disableWarning);
return pos;
}

Position WorldObject::GetRandomNearPosition(float radius)
Position WorldObject::GetRandomNearPosition(float radius, bool disableWarning)
{
Position pos = GetPosition();
MovePosition(pos, radius * (float) rand_norm(), (float) rand_norm() * static_cast<float>(2 * M_PI));
MovePosition(pos, radius * (float) rand_norm(), (float) rand_norm() * static_cast<float>(2 * M_PI), disableWarning);
return pos;
}

Expand Down Expand Up @@ -2773,7 +2773,7 @@ void WorldObject::GetChargeContactPoint(WorldObject const* obj, float& x, float&
return (m_valuesCount > UNIT_FIELD_COMBATREACH) ? m_floatValues[UNIT_FIELD_COMBATREACH] : DEFAULT_WORLD_OBJECT_SIZE * GetObjectScale();
}

void WorldObject::MovePosition(Position& pos, float dist, float angle)
void WorldObject::MovePosition(Position& pos, float dist, float angle, bool disableWarning)
{
angle += GetOrientation();
float destx, desty, destz, ground, floor;
Expand All @@ -2783,7 +2783,9 @@ void WorldObject::MovePosition(Position& pos, float dist, float angle)
// Prevent invalid coordinates here, position is unchanged
if (!Acore::IsValidMapCoord(destx, desty))
{
LOG_FATAL("entities.object", "WorldObject::MovePosition invalid coordinates X: {} and Y: {} were passed!", destx, desty);
if (!disableWarning)
LOG_FATAL("entities.object", "WorldObject::MovePosition invalid coordinates X: {} and Y: {} were passed!", destx, desty);

return;
}

Expand Down
6 changes: 3 additions & 3 deletions src/server/game/Entities/Object/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,13 +420,13 @@ class WorldObject : public Object, public WorldLocation
void GetNearPoint(WorldObject const* searcher, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle, float controlZ = 0, Position const* startPos = nullptr) const;
void GetVoidClosePoint(float& x, float& y, float& z, float size, float distance2d = 0, float relAngle = 0, float controlZ = 0) const;
bool GetClosePoint(float& x, float& y, float& z, float size, float distance2d = 0, float angle = 0, WorldObject const* forWho = nullptr, bool force = false) const;
void MovePosition(Position& pos, float dist, float angle);
Position GetNearPosition(float dist, float angle);
void MovePosition(Position& pos, float dist, float angle, bool disableWarning = false);
Position GetNearPosition(float dist, float angle, bool disableWarning = false);
void MovePositionToFirstCollision(Position& pos, float dist, float angle);
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY);
Position GetFirstCollisionPosition(float destX, float destY, float destZ);
Position GetFirstCollisionPosition(float dist, float angle);
Position GetRandomNearPosition(float radius);
Position GetRandomNearPosition(float radius, bool disableWarning = false);

void GetContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d = CONTACT_DISTANCE) const;
void GetChargeContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d = CONTACT_DISTANCE) const;
Expand Down
50 changes: 49 additions & 1 deletion src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,17 @@ class spell_mother_shahraz_saber_lash_aura : public AuraScript
}
};

const Position validTeleportStairsPos[4] =
{
{966.87f, 184.45f, 192.84f},
{927.22f, 187.04f, 192.84f},
{922.54f, 110.09f, 192.84f},
{958.01f, 110.47f, 192.84f}
};

constexpr float minTeleportDist = 30.f;
constexpr float maxTeleportDist = 50.f;

class spell_mother_shahraz_fatal_attraction : public SpellScript
{
PrepareSpellScript(spell_mother_shahraz_fatal_attraction);
Expand All @@ -212,7 +223,44 @@ class spell_mother_shahraz_fatal_attraction : public SpellScript

void SetDest(SpellDestination& dest)
{
dest.Relocate(GetCaster()->GetRandomNearPosition(50.0f));
Position finalDest;

// Check if the boss is near stairs to avoid players falling through the platform with random teleports.
if(GetCaster()->GetPositionY() < 194.f)
finalDest = validTeleportStairsPos[urand(0, 3)];
else
{
finalDest = GetCaster()->GetNearPosition(frand(minTeleportDist, maxTeleportDist), static_cast<float>(rand_norm()) * static_cast<float>(2 * M_PI), true);

// Maybe not necessary but just in case to avoid LOS issues with an object
if(!GetCaster()->IsWithinLOS(finalDest.GetPositionX(), finalDest.GetPositionY(), finalDest.GetPositionZ()))
finalDest = GetCaster()->GetNearPosition(frand(minTeleportDist, maxTeleportDist), static_cast<float>(rand_norm()) * static_cast<float>(2 * M_PI), true);

/* @note: To avoid teleporting players near a walls, we will define a safe area.
* As the boss have an area boudary around y: 320.f. We will limit the safe area to this value, avoiding wird issues.
* x limit: 932.f/960.f | y limit: 224.f/320.f
*/
if (finalDest.m_positionX < 932.f)
finalDest.m_positionX = 932.f;
else if (finalDest.m_positionX > 960.f)
finalDest.m_positionX = 960.f;

if (finalDest.m_positionY < 224.f)
finalDest.m_positionY = 224.f;
else if (finalDest.m_positionY > 320.f)
finalDest.m_positionY = 320.f;

// After relocate a finalDest outside the safe area, we need to recheck the distance with the boss
if (GetCaster()->GetExactDist2d(finalDest) < minTeleportDist)
{
if (finalDest.m_positionX == 932.f || finalDest.m_positionX == 960.f)
finalDest.m_positionY = finalDest.m_positionY + (minTeleportDist - GetCaster()->GetExactDist2d(finalDest));
else if (finalDest.m_positionY == 224.f || finalDest.m_positionY == 320.f)
finalDest.m_positionX = finalDest.m_positionX + (minTeleportDist - GetCaster()->GetExactDist2d(finalDest));
}
}

dest.Relocate(finalDest);
}

void HandleTeleportUnits(SpellEffIndex /*effIndex*/)
Expand Down

0 comments on commit 8bf3595

Please sign in to comment.