From 786a2c2042ecfd93cc2a61b3c789f5fddf714384 Mon Sep 17 00:00:00 2001 From: EricksOliveira Date: Fri, 14 Aug 2026 16:01:05 +0000 Subject: [PATCH] fix(Scripts/ICC): make the Lady Deathwhisper elevator wait 7s at each stop The elevator was driven by a free running 3000 ms tick that had nothing to do with the moment it actually reached an end of its path, so the time it stood still was uniformly random in [0, 3000] ms and a raid often could not board it. Count the dwell only while the transport is parked, so it always starts on arrival: rearm the timer while it is moving, and flip GOState once 7000 ms have passed at a stop. StaticTransport::Update clamps PathProgress to exactly 0 and GetPauseTime() and freezes there while GOState matches, so those comparisons detect "parked at a stop" exactly. The ride itself is untouched. The client renders it from TransportAnimation.dbc, so pause time and path progress are left alone and no SQL is needed. Closes #20324 Co-Authored-By: Claude Opus 5 --- .../instance_icecrown_citadel.cpp | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 9d5d5105a35cd0..a1fd7e24a80ea4 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -71,6 +71,9 @@ enum Say SAY_SOULS_LICH_KING_RAND_WHISPER = 5 }; +// How long the Lady Deathwhisper elevator stays motionless at each end of its cycle before departing again. +constexpr uint32 DARKWHISPER_ELEVATOR_DWELL_TIME = 7 * IN_MILLISECONDS; + BossBoundaryData const boundaries = { { DATA_LORD_MARROWGAR, new CircleBoundary(Position(-428.0f,2211.0f), 95.0) }, @@ -212,7 +215,7 @@ class instance_icecrown_citadel : public InstanceMapScript PutricideEventProgress = 0; LichKingHeroicAvailable = true; LichKingRandomWhisperTimer = 120 * IN_MILLISECONDS; - DarkwhisperElevatorTimer = 3000; + DarkwhisperElevatorTimer = DARKWHISPER_ELEVATOR_DWELL_TIME; SetHeaders(DataHeader); SetBossNumber(MAX_ENCOUNTERS); @@ -1664,21 +1667,28 @@ class instance_icecrown_citadel : public InstanceMapScript else LichKingRandomWhisperTimer -= diff; - if (DarkwhisperElevatorTimer <= diff) - { - DarkwhisperElevatorTimer = 3000; - if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE) - if (GameObject* elevator = instance->GetGameObject(LadyDeathwisperElevatorGUID)) - if (StaticTransport* trans = elevator->ToStaticTransport()) + if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE) + if (GameObject* elevator = instance->GetGameObject(LadyDeathwisperElevatorGUID)) + if (StaticTransport* trans = elevator->ToStaticTransport()) + { + // StaticTransport::Update clamps PathProgress to exactly 0 / GetPauseTime() and then freezes + // there while GOState matches, so these two comparisons detect "parked at a stop" exactly. + bool const atBottom = trans->GetGoState() == GO_STATE_READY && trans->GetPathProgress() == 0; + bool const atTop = trans->GetGoState() == GO_STATE_ACTIVE && + trans->GetPathProgress() == trans->GetPauseTime(); + + // Count the dwell down only while parked, so it always starts on arrival instead of on the + // phase of a free-running tick. Flipping GOState sends the transport towards the other end. + if (!atBottom && !atTop) + DarkwhisperElevatorTimer = DARKWHISPER_ELEVATOR_DWELL_TIME; + else if (DarkwhisperElevatorTimer <= diff) { - if (trans->GetGoState() == GO_STATE_READY && trans->GetPathProgress() == 0) - trans->SetGoState(GO_STATE_ACTIVE); - else if (trans->GetGoState() == GO_STATE_ACTIVE && trans->GetPathProgress() == trans->GetPauseTime()) - trans->SetGoState(GO_STATE_READY); + DarkwhisperElevatorTimer = DARKWHISPER_ELEVATOR_DWELL_TIME; + trans->SetGoState(atBottom ? GO_STATE_ACTIVE : GO_STATE_READY); } - } - else - DarkwhisperElevatorTimer -= diff; + else + DarkwhisperElevatorTimer -= diff; + } if (Events.Empty()) return;