fix(Script/BlackTemple): teleport position with fatal attraction (#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 fb7613d5cc5a19df01bbcf41ef5c982119ee9685. * . * 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
This commit is contained in:
@@ -2725,17 +2725,17 @@ bool WorldObject::GetClosePoint(float& x, float& y, float& z, float size, float
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position WorldObject::GetNearPosition(float dist, float angle)
|
Position WorldObject::GetNearPosition(float dist, float angle, bool disableWarning)
|
||||||
{
|
{
|
||||||
Position pos = GetPosition();
|
Position pos = GetPosition();
|
||||||
MovePosition(pos, dist, angle);
|
MovePosition(pos, dist, angle, disableWarning);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position WorldObject::GetRandomNearPosition(float radius)
|
Position WorldObject::GetRandomNearPosition(float radius, bool disableWarning)
|
||||||
{
|
{
|
||||||
Position pos = GetPosition();
|
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;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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();
|
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();
|
angle += GetOrientation();
|
||||||
float destx, desty, destz, ground, floor;
|
float destx, desty, destz, ground, floor;
|
||||||
@@ -2783,7 +2783,9 @@ void WorldObject::MovePosition(Position& pos, float dist, float angle)
|
|||||||
// Prevent invalid coordinates here, position is unchanged
|
// Prevent invalid coordinates here, position is unchanged
|
||||||
if (!Acore::IsValidMapCoord(destx, desty))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -420,13 +420,13 @@ public:
|
|||||||
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 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;
|
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;
|
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);
|
void MovePosition(Position& pos, float dist, float angle, bool disableWarning = false);
|
||||||
Position GetNearPosition(float dist, float angle);
|
Position GetNearPosition(float dist, float angle, bool disableWarning = false);
|
||||||
void MovePositionToFirstCollision(Position& pos, float dist, float angle);
|
void MovePositionToFirstCollision(Position& pos, float dist, float angle);
|
||||||
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY);
|
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY);
|
||||||
Position GetFirstCollisionPosition(float destX, float destY, float destZ);
|
Position GetFirstCollisionPosition(float destX, float destY, float destZ);
|
||||||
Position GetFirstCollisionPosition(float dist, float angle);
|
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 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;
|
void GetChargeContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d = CONTACT_DISTANCE) const;
|
||||||
|
|||||||
@@ -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
|
class spell_mother_shahraz_fatal_attraction : public SpellScript
|
||||||
{
|
{
|
||||||
PrepareSpellScript(spell_mother_shahraz_fatal_attraction);
|
PrepareSpellScript(spell_mother_shahraz_fatal_attraction);
|
||||||
@@ -212,7 +223,44 @@ class spell_mother_shahraz_fatal_attraction : public SpellScript
|
|||||||
|
|
||||||
void SetDest(SpellDestination& dest)
|
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*/)
|
void HandleTeleportUnits(SpellEffIndex /*effIndex*/)
|
||||||
|
|||||||
Reference in New Issue
Block a user