From e30d474aa6854e29c16128afbbaa82e0bc05aa42 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Tue, 29 Oct 2019 19:24:52 +0100 Subject: [PATCH] Core/Transports: handle GO_STATE_TRANSPORT_ACTIVE properly now and clarified some code in transport position update handling --- .../game/Entities/Transport/Transport.cpp | 119 +++++++----------- .../game/Entities/Transport/Transport.h | 8 +- src/server/game/Miscellaneous/SharedDefines.h | 2 +- 3 files changed, 50 insertions(+), 79 deletions(-) diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index d620cb6a211..4a158b9c9a9 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -35,7 +35,7 @@ Transport::Transport() : GameObject(), _passengerTeleportItr(_passengers.begin()), _currentTransportTime(0), _destinationStopFrameTime(0), - _alignmentTransportTime(0), _lastStopFrameTime(0), _isDynamicTransport(false), _initialRelocate(false) + _lastStopFrameTime(0), _expectedTravelTime(0), _isDynamicTransport(false), _initialRelocate(false) { m_updateFlag |= UPDATEFLAG_TRANSPORT | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION; } @@ -310,67 +310,43 @@ void Transport::Update(uint32 diff) } else { - if (GetGoState() == GO_STATE_TRANSPORT_ACTIVE) + // Waiting at our last destination. Do nothing. + if (GetCurrentTransportTime() == GetDestinationStopFrameTime()) + return; + + uint32 lastStopFrameTime = GetLastStopFrameTime(); + uint32 currentTransportTime = GetCurrentTransportTime(); + uint32 destinationStopFrameTime = GetDestinationStopFrameTime(); + switch (GetGoState()) { - // waiting at it's destination for state change, do nothing - if (GetCurrentTransportTime() == GetDestinationStopFrameTime()) - return; - - // GOState has changed before previous state was reached, move to new destination immediately - if (GetCurrentTransportTime() < GetDestinationStopFrameTime()) - SetCurrentTransportTime(0); - else if (GetCurrentTransportTime() + diff < GetTransportPeriod()) - SetCurrentTransportTime(GetCurrentTransportTime() + diff); - else - SetCurrentTransportTime(0); - } - else - { - // waiting at it's destination for state change, do nothing - if (GetCurrentTransportTime() == GetDestinationStopFrameTime()) - return; - - int32 currentTime = GetCurrentTransportTime(); - int32 destinationTime = GetDestinationStopFrameTime(); - bool backwardsMovement = destinationTime < currentTime; - - if (!backwardsMovement) - { - // GOState has changed before previous state was reached, move to new destination immediately - if (currentTime > destinationTime) - SetCurrentTransportTime(destinationTime); - else if (int32(currentTime + diff) < destinationTime) - SetCurrentTransportTime(currentTime + diff); - else - { - SetCurrentTransportTime(destinationTime); - SetAlignmentTransportTime(0); - } - } - else + case GO_STATE_ACTIVE: + case GO_STATE_READY: + case GO_STATE_ACTIVE_ALTERNATIVE: + break; + default: { + /* + These states handle the stop frame movement of transports + Transports with GO_STATE_TRANSPORT_ACTIVE move with 50% of the passed travel time to stop frame 0 + Transports with GO_STATE_TRANSPORT_STOPPED + frame index move to the provided stop frame using time diffs between + the last frame and the target frame to reach their destination + */ + + // Keeping our transport synch with the reduced travel time. uint32 timeDiff = diff; - // Skipping multiple stop frames while moving to frame 0. Align the steps to the travel time. - if (uint32 alignmentTime = GetAlightmentTransportTime()) - { - float alignmentPercentage = (float)alignmentTime / GetLastStopFrameTime(); - timeDiff += diff * alignmentPercentage; - } + if (float alignmentPercentage = (float)lastStopFrameTime / GetExpectedTravelTime()) + timeDiff *= alignmentPercentage; - // GOState has changed before previous state was reached, move to new destination immediately - if (currentTime < destinationTime) - currentTime = destinationTime; - else if (int32(currentTime - timeDiff) > destinationTime) - currentTime -= timeDiff; - else - { - currentTime = destinationTime; - SetAlignmentTransportTime(0); - } + bool backwardsMovement = destinationStopFrameTime < lastStopFrameTime; + uint32 transportTime = backwardsMovement ? + std::max(destinationStopFrameTime, currentTransportTime - timeDiff) : + std::min(destinationStopFrameTime, currentTransportTime + timeDiff); - SetCurrentTransportTime(currentTime); + SetCurrentTransportTime(transportTime); + break; } } + m_goValue.Transport.PathProgress = getMSTime() + GetCurrentTransportTime(); } @@ -496,14 +472,14 @@ void Transport::SetTransportState(GOState state, uint32 stopFrame /*= 0*/) ASSERT(m_goInfo->type == GAMEOBJECT_TYPE_TRANSPORT); uint32 stopTimer = 0; - uint32 backwardsTimer = 0; - + uint32 currentStopFrameTime = GetCurrentTransportTime(); if (state == GO_STATE_TRANSPORT_ACTIVE) { if (GetGoState() >= GO_STATE_TRANSPORT_STOPPED) { - stopTimer = m_goValue.Transport.StopFrames->at(GetGoState() - GO_STATE_TRANSPORT_STOPPED); - SetPeriod(stopTimer); + stopTimer = currentStopFrameTime / 2; + SetPeriod(getMSTime() + stopTimer); + SetExpectedTravelTime(stopTimer); } } else @@ -512,28 +488,23 @@ void Transport::SetTransportState(GOState state, uint32 stopFrame /*= 0*/) ASSERT(stopFrame < m_goValue.Transport.StopFrames->size()); stopTimer = m_goValue.Transport.StopFrames->at(stopFrame); + bool backwards = stopTimer < currentStopFrameTime; - // Handling backwards movement. According to retail tests, a transport that returns to stop frame 0 is using the time between frame 0 and 1 - if (!stopTimer) - backwardsTimer = m_goValue.Transport.StopFrames->at(stopFrame + 1); - - // forward movement. target frame time - current frame time - if (GetCurrentTransportTime() < stopTimer) - SetPeriod(getMSTime() + stopTimer - GetCurrentTransportTime()); - else if (backwardsTimer) - SetPeriod(getMSTime() + backwardsTimer); - else - SetPeriod(getMSTime() + GetCurrentTransportTime() - stopTimer); + uint32 travelTime = 0; + if (stopTimer) + travelTime = backwards ? currentStopFrameTime - stopTimer : stopTimer - currentStopFrameTime; + else if (m_goValue.Transport.StopFrames->size() >= stopFrame + 2) // Returning to stop frame with 0 ms. Using the travel time between the 0ms and the next frame + travelTime = m_goValue.Transport.StopFrames->at(stopFrame + 1); + // Transport destinations are sent as msTime + travel time from frame A to B + SetPeriod(getMSTime() + travelTime); + SetExpectedTravelTime(travelTime); state = GOState(GO_STATE_TRANSPORT_STOPPED + stopFrame); } m_goValue.Transport.PathProgress = getMSTime() + stopTimer; SetDestinationStopFrameTime(stopTimer); - SetLastStopFrameTime(GetCurrentTransportTime()); - if (GetCurrentTransportTime() > backwardsTimer) - SetAlignmentTransportTime(backwardsTimer); - + SetLastStopFrameTime(currentStopFrameTime); SetGoState(state); } diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 97a74faa581..e02cabafd8e 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -72,12 +72,12 @@ class TC_GAME_API Transport : public GameObject, public TransportBase void SetCurrentTransportTime(uint32 time) { _currentTransportTime = time; } uint32 GetCurrentTransportTime() const { return _currentTransportTime; } - void SetAlignmentTransportTime(uint32 time) { _alignmentTransportTime = time; } - uint32 GetAlightmentTransportTime() const { return _alignmentTransportTime; } - void SetLastStopFrameTime(uint32 time) { _lastStopFrameTime = time; } uint32 GetLastStopFrameTime() const { return _lastStopFrameTime; } + void SetExpectedTravelTime(uint32 time) { _expectedTravelTime = time; } + uint32 GetExpectedTravelTime() const { return _expectedTravelTime; } + protected: void UpdatePassengerPositions(PassengerSet& passengers); @@ -86,8 +86,8 @@ class TC_GAME_API Transport : public GameObject, public TransportBase uint32 _destinationStopFrameTime; uint32 _currentTransportTime; - uint32 _alignmentTransportTime; uint32 _lastStopFrameTime; + uint32 _expectedTravelTime; bool _isDynamicTransport; bool _initialRelocate; }; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index fe579ca8911..34da25848ab 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -1821,7 +1821,7 @@ enum GOState : uint8 GO_STATE_ACTIVE = 0, // show in world as used and not reset (closed door open) GO_STATE_READY = 1, // show in world as ready (closed door close) GO_STATE_ACTIVE_ALTERNATIVE = 2, // show in world as used in alt way and not reset (closed door open by cannon fire) - GO_STATE_TRANSPORT_ACTIVE = 24, // transport exclusive: transport may always move + GO_STATE_TRANSPORT_ACTIVE = 24, // transport exclusive: transport moves to first stop frame GO_STATE_TRANSPORT_STOPPED = 25 // transport exclusive: transport is going to stop at provided stop frame };