diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParkingPlaceBehavior.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParkingPlaceBehavior.h index 7b30d6010c..8e0c2d1988 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParkingPlaceBehavior.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ParkingPlaceBehavior.h @@ -140,6 +140,7 @@ class ParkingPlaceBehavior : public UpdateModule, virtual Bool reserveSpace(ObjectID id, Real parkingOffset, PPInfo* info); virtual void releaseSpace(ObjectID id); virtual Bool reserveRunway(ObjectID id, Bool forLanding); + Bool postponeRunwayReservation(UnsignedInt spaceIndex, Bool forLanding); virtual void releaseRunway(ObjectID id); virtual void calcPPInfo( ObjectID id, PPInfo *info ); virtual Int getRunwayCount() const { return m_runways.size(); } @@ -158,15 +159,16 @@ class ParkingPlaceBehavior : public UpdateModule, struct ParkingPlaceInfo { - Coord3D m_hangarStart; - Real m_hangarStartOrient; - Coord3D m_location; - Coord3D m_prep; - Real m_orientation; - Int m_runway; - ExitDoorType m_door; - ObjectID m_objectInSpace; - Bool m_reservedForExit; + Coord3D m_hangarStart; + Real m_hangarStartOrient; + Coord3D m_location; + Coord3D m_prep; + Real m_orientation; + Int m_runway; + ExitDoorType m_door; + ObjectID m_objectInSpace; + Bool m_reservedForExit; + Bool m_postponedRunwayReservationForTakeoff; ParkingPlaceInfo() { @@ -179,6 +181,7 @@ class ParkingPlaceBehavior : public UpdateModule, m_door = DOOR_NONE_AVAILABLE; m_objectInSpace = INVALID_ID; m_reservedForExit = false; + m_postponedRunwayReservationForTakeoff = false; } }; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/ParkingPlaceBehavior.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/ParkingPlaceBehavior.cpp index 74959f0b35..8d4b3ae19b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/ParkingPlaceBehavior.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/ParkingPlaceBehavior.cpp @@ -159,6 +159,7 @@ void ParkingPlaceBehavior::purgeDead() { it->m_objectInSpace = INVALID_ID; it->m_reservedForExit = false; + it->m_postponedRunwayReservationForTakeoff = false; if (pu) pu->setHoldDoorOpen(it->m_door, false); } @@ -430,6 +431,7 @@ void ParkingPlaceBehavior::releaseSpace(ObjectID id) { it->m_objectInSpace = INVALID_ID; it->m_reservedForExit = false; + it->m_postponedRunwayReservationForTakeoff = false; if (pu) pu->setHoldDoorOpen(it->m_door, false); } @@ -468,6 +470,29 @@ void ParkingPlaceBehavior::transferRunwayReservationToNextInLineForTakeoff(Objec } } +//------------------------------------------------------------------------------------------------- +Bool ParkingPlaceBehavior::postponeRunwayReservation(UnsignedInt spaceIndex, Bool forLanding) +{ + // TheSuperHackers @tweak Block the first attempt to reserve a runway for 'upper' space indices. + // This allows 'lower' space indices to reserve a runway first to ensure deterministic takeoff ordering. + + if (m_spaces.size() > m_runways.size() && spaceIndex >= m_runways.size()) + { + Bool& postponed = m_spaces[spaceIndex].m_postponedRunwayReservationForTakeoff; + if (forLanding) + { + postponed = false; + } + else if (!postponed) + { + postponed = true; + return true; + } + } + + return false; +} + //------------------------------------------------------------------------------------------------- Bool ParkingPlaceBehavior::reserveRunway(ObjectID id, Bool forLanding) { @@ -475,11 +500,16 @@ Bool ParkingPlaceBehavior::reserveRunway(ObjectID id, Bool forLanding) purgeDead(); Int runway = -1; - for (std::vector::iterator it = m_spaces.begin(); it != m_spaces.end(); ++it) + for (UnsignedInt i = 0; i < m_spaces.size(); ++i) { - if (it->m_objectInSpace == id) + if (m_spaces[i].m_objectInSpace == id) { - runway = it->m_runway; +#if !RETAIL_COMPATIBLE_CRC + if (deferUnsequencedRunwayReservationForTakeoff(i, forLanding)) + return false; +#endif + + runway = m_spaces[i].m_runway; break; } }