diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ChinookAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ChinookAIUpdate.h index 45b6a9c657e..85e0652b809 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ChinookAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/ChinookAIUpdate.h @@ -125,6 +125,7 @@ class ChinookAIUpdate : public SupplyTruckAIUpdate void private___TellPortableStructureToAttackWithMe( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); + ObjectID getAirfieldForHealing() const { return m_airfieldForHealing; } private: diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index 0120cd2a48f..de23938d370 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -140,7 +140,6 @@ class JetAIUpdate : public AIUpdateInterface void positionLockon(); virtual Bool getTreatAsAircraftForLocoDistToGoal() const override; - Bool isParkedAt(const Object* obj) const; private: 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 6c92290ae2d..d317c1f58cd 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp @@ -1293,7 +1293,11 @@ void ChinookAIUpdate::aiDoCommand(const AICommandParms* parms) #else // TheSuperHackers @bugfix Stubbjax 31/10/2025 Don't leave healing state for evacuation commands. if (parms->m_cmd != AICMD_EVACUATE && parms->m_cmd != AICMD_EXIT) - setAirfieldForHealing(INVALID_ID); + { + // TheSuperHackers @bugfix Caball009 12/08/2026 Don't leave healing state if chinook is already repairing at this airfield. + if (!(parms->m_cmd == AICMD_GET_REPAIRED && parms->m_obj->getID() == getAirfieldForHealing())) + setAirfieldForHealing(INVALID_ID); + } #endif if (!isAllowedToRespondToAiCommands(parms)) @@ -1370,6 +1374,20 @@ void ChinookAIUpdate::aiDoCommand(const AICommandParms* parms) } break; +#if !RETAIL_COMPATIBLE_CRC + case AICMD_GET_REPAIRED: + { + // TheSuperHackers @bugfix Caball009 12/08/2026 Don't process command if chinook is already repairing at this airfield. + if (parms->m_obj->getID() == getAirfieldForHealing()) + { + passItThru = false; + break; + } + + FALLTHROUGH; + } +#endif + default: { if (m_flightStatus != CHINOOK_FLYING) 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 7bf9abfdd6a..d379c6ed195 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2527,24 +2527,6 @@ void JetAIUpdate::privateGetRepaired( Object *repairDepot, CommandSourceType cmd } -//------------------------------------------------------------------------------------------------- -Bool JetAIUpdate::isParkedAt(const Object* obj) const -{ - if (!getFlag(ALLOW_AIR_LOCO) && - !getObject()->isKindOf(KINDOF_PRODUCED_AT_HELIPAD) && - obj != nullptr) - { - Object* airfield; - ParkingPlaceBehaviorInterface* pp = getPP(getObject()->getProducerID(), &airfield); - if (pp != nullptr && airfield != nullptr && airfield == obj) - { - return true; - } - } - - return false; -} - //------------------------------------------------------------------------------------------------- void JetAIUpdate::aiDoCommand(const AICommandParms* parms) { @@ -2609,19 +2591,29 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) return; } - FALLTHROUGH; + goto defaultCase; // cannot fall through to get to the default case! #endif case AICMD_ENTER: case AICMD_GET_REPAIRED: + // if we're already located at the airfield in question, just ignore. + // TheSuperHackers @bugfix Caball009 12/08/2026 This applies to units produced at the helipad now as well. +#if RETAIL_COMPATIBLE_CRC + if (parms->m_obj && !getObject()->isKindOf(KINDOF_PRODUCED_AT_HELIPAD)) +#else + if (parms->m_obj) +#endif + { + Object* airfield = nullptr; + ParkingPlaceBehaviorInterface* pp = getPP(getObject()->getProducerID(), &airfield); + if (pp != nullptr && airfield == parms->m_obj) + return; + } - // if we're already parked at the airfield in question, just ignore. - if (isParkedAt(parms->m_obj)) - return; - - FALLTHROUGH; // else fall thru to the default case! + FALLTHROUGH; // else fall through to the default case! default: + defaultCase: { // nuke any existing pending cmd m_mostRecentCommand.store(*parms);