diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp index 249f63b3958..65e0565cb3a 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp @@ -925,8 +925,8 @@ void OpenContain::exitObjectViaDoor( Object *exitObj, ExitDoorType exitDoor ) std::vector exitPath; exitPath.push_back(endPosition); exitPath.push_back(endPosition); // Do it twice, in case units stack up due to brief flying. jba. - if (m_rallyPointExists) { - exitPath.push_back(m_rallyPoint); + if (const Coord3D *rallyPoint = getRallyPoint()) { + exitPath.push_back(*rallyPoint); } if( ai ) @@ -1422,6 +1422,18 @@ const Coord3D *OpenContain::getRallyPoint() const if (m_rallyPointExists) return &m_rallyPoint; +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @bugfix arcticdolphin 02/03/2026 Use primary exit interface rally point if available. + if (getObject()) + { + ExitInterface *primaryExit = getObject()->getObjectExitInterface(); + if (primaryExit && primaryExit != static_cast(this)) + { + return primaryExit->getRallyPoint(); + } + } +#endif + return nullptr; } diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp index cb975592722..84c767244ea 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp @@ -1032,6 +1032,20 @@ UpdateSleepTime ChinookAIUpdate::update() // we're completely healed, so take off again pp->setHealee(getObject(), false); setMyState(TAKING_OFF, nullptr, nullptr, CMD_FROM_AI); + +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @bugfix arcticdolphin 02/03/2026 Move healed Chinook to rally point if present. + if (Object *airfield = TheGameLogic->findObjectByID( m_airfieldForHealing )) + { + if (ExitInterface *exitInterface = airfield->getObjectExitInterface()) + { + if (const Coord3D *rallyPoint = exitInterface->getRallyPoint()) + { + aiMoveToPosition( rallyPoint, CMD_FROM_AI ); + } + } + } +#endif } else { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp index 5d98395cc62..636b45ff7df 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -1776,6 +1776,20 @@ UpdateSleepTime JetAIUpdate::update() getStateMachine()->clear(); setLastCommandSource( CMD_FROM_AI ); getStateMachine()->setState( TAKING_OFF_AWAIT_CLEARANCE ); + +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @bugfix arcticdolphin 02/03/2026 Move healed helicopter to rally point if present. + if (Object *airfield = TheGameLogic->findObjectByID( jet->getProducerID() )) + { + if (ExitInterface *exitInterface = airfield->getObjectExitInterface()) + { + if (const Coord3D *rallyPoint = exitInterface->getRallyPoint()) + { + aiMoveToPosition( rallyPoint, CMD_FROM_AI ); + } + } + } +#endif } else { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp index 3f3a245f703..d2a741e441c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp @@ -1045,8 +1045,8 @@ void OpenContain::exitObjectViaDoor( Object *exitObj, ExitDoorType exitDoor ) std::vector exitPath; exitPath.push_back(endPosition); exitPath.push_back(endPosition); // Do it twice, in case units stack up due to brief flying. jba. - if (m_rallyPointExists) { - exitPath.push_back(m_rallyPoint); + if (const Coord3D *rallyPoint = getRallyPoint()) { + exitPath.push_back(*rallyPoint); } if( ai ) @@ -1609,6 +1609,18 @@ const Coord3D *OpenContain::getRallyPoint() const if (m_rallyPointExists) return &m_rallyPoint; +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @bugfix arcticdolphin 02/03/2026 Use primary exit interface rally point if available. + if (getObject()) + { + ExitInterface *primaryExit = getObject()->getObjectExitInterface(); + if (primaryExit && primaryExit != static_cast(this)) + { + return primaryExit->getRallyPoint(); + } + } +#endif + return nullptr; } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp index ecad2ae66fd..7623ed306fa 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp @@ -1094,6 +1094,20 @@ UpdateSleepTime ChinookAIUpdate::update() // we're completely healed, so take off again pp->setHealee(getObject(), false); setMyState(TAKING_OFF, nullptr, nullptr, CMD_FROM_AI); + +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @bugfix arcticdolphin 02/03/2026 Move healed Chinook to rally point if present. + if (Object *airfield = TheGameLogic->findObjectByID( m_airfieldForHealing )) + { + if (ExitInterface *exitInterface = airfield->getObjectExitInterface()) + { + if (const Coord3D *rallyPoint = exitInterface->getRallyPoint()) + { + aiMoveToPosition( rallyPoint, CMD_FROM_AI ); + } + } + } +#endif } else { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp index e90a815c303..35049511cf2 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -1998,6 +1998,20 @@ UpdateSleepTime JetAIUpdate::update() getStateMachine()->clear(); setLastCommandSource( CMD_FROM_AI ); getStateMachine()->setState( TAKING_OFF_AWAIT_CLEARANCE ); + +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @bugfix arcticdolphin 02/03/2026 Move healed helicopter to rally point if present. + if (Object *airfield = TheGameLogic->findObjectByID( jet->getProducerID() )) + { + if (ExitInterface *exitInterface = airfield->getObjectExitInterface()) + { + if (const Coord3D *rallyPoint = exitInterface->getRallyPoint()) + { + aiMoveToPosition( rallyPoint, CMD_FROM_AI ); + } + } + } +#endif } else {