From 3e3d8aa2e32c12a4ff684da99ae93b14bc5eee64 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:54:54 +0200 Subject: [PATCH 1/4] Fixed prior incorrect fallthrough behavior. --- .../Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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..4c001836f53 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2609,7 +2609,7 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) return; } - FALLTHROUGH; + goto defaultCase; // cannot fall through to get to the default case! #endif case AICMD_ENTER: @@ -2619,9 +2619,10 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) 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); From 55758544a6943a68e9be5479226a1df6e3b51980 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:59:11 +0200 Subject: [PATCH 2/4] Inlined function 'isParkedAt'. --- .../Include/GameLogic/Module/JetAIUpdate.h | 1 - .../Object/Update/AIUpdate/JetAIUpdate.cpp | 29 +++++-------------- 2 files changed, 7 insertions(+), 23 deletions(-) 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/JetAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp index 4c001836f53..afcb6b4deed 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) { @@ -2614,10 +2596,13 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) case AICMD_ENTER: case AICMD_GET_REPAIRED: - - // if we're already parked at the airfield in question, just ignore. - if (isParkedAt(parms->m_obj)) - return; + if (parms->m_obj && !getObject()->isKindOf(KINDOF_PRODUCED_AT_HELIPAD)) + { + Object* airfield; + ParkingPlaceBehaviorInterface* pp = getPP(getObject()->getProducerID(), &airfield); + if (pp != nullptr && airfield != nullptr && airfield == parms->m_obj) + return; + } FALLTHROUGH; // else fall through to the default case! From 11ac52a524fc5e21a3c43a365c31ac68ad5ce992 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:05:15 +0200 Subject: [PATCH 3/4] Fixed repair command bugs for helis and chinooks. --- .../GameLogic/Module/ChinookAIUpdate.h | 1 + .../Update/AIUpdate/ChinookAIUpdate.cpp | 20 ++++++++++++++++++- .../Object/Update/AIUpdate/JetAIUpdate.cpp | 6 ++++++ 3 files changed, 26 insertions(+), 1 deletion(-) 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/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 afcb6b4deed..74651971a0f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2596,7 +2596,13 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) 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; ParkingPlaceBehaviorInterface* pp = getPP(getObject()->getProducerID(), &airfield); From 25c1a6233e37978db27b9dcc3fe9fc7ed3de4667 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:05:58 +0200 Subject: [PATCH 4/4] Small refactor. --- .../Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 74651971a0f..d379c6ed195 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2604,9 +2604,9 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) if (parms->m_obj) #endif { - Object* airfield; + Object* airfield = nullptr; ParkingPlaceBehaviorInterface* pp = getPP(getObject()->getProducerID(), &airfield); - if (pp != nullptr && airfield != nullptr && airfield == parms->m_obj) + if (pp != nullptr && airfield == parms->m_obj) return; }