From 06fa56b7b2e0d690bdfec8b9fced6eb6d5618a0c Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 28 Oct 2025 22:53:40 +1100 Subject: [PATCH 1/6] refactor: Remove redundant else conditions --- .../GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp | 6 ++++-- .../GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) 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 08258ee868..4f2599e01d 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2322,7 +2322,8 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) setFlag(HAS_PENDING_COMMAND, true); return; } - else if (parms->m_cmd == AICMD_IDLE && getStateMachine()->getCurrentStateID() == RELOAD_AMMO) + + if (parms->m_cmd == AICMD_IDLE && getStateMachine()->getCurrentStateID() == RELOAD_AMMO) { // uber-special-case... if we are told to idle, but are reloading ammo, ignore it for now, // since we're already doing "nothing" and responding to this will cease our reload... @@ -2330,7 +2331,8 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) setFlag(HAS_PENDING_COMMAND, true); return; } - else if (!getFlag(ALLOW_AIR_LOCO)) + + if (!getFlag(ALLOW_AIR_LOCO)) { switch (parms->m_cmd) { 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 5d5189ed68..488c9fbc1f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2549,7 +2549,8 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) setFlag(HAS_PENDING_COMMAND, true); return; } - else if (parms->m_cmd == AICMD_IDLE && getStateMachine()->getCurrentStateID() == RELOAD_AMMO) + + if (parms->m_cmd == AICMD_IDLE && getStateMachine()->getCurrentStateID() == RELOAD_AMMO) { // uber-special-case... if we are told to idle, but are reloading ammo, ignore it for now, // since we're already doing "nothing" and responding to this will cease our reload... @@ -2557,14 +2558,16 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) setFlag(HAS_PENDING_COMMAND, true); return; } - else if( parms->m_cmd == AICMD_IDLE && getObject()->isAirborneTarget() && !getObject()->isKindOf( KINDOF_PRODUCED_AT_HELIPAD ) ) + + if( parms->m_cmd == AICMD_IDLE && getObject()->isAirborneTarget() && !getObject()->isKindOf( KINDOF_PRODUCED_AT_HELIPAD ) ) { getStateMachine()->clear(); setLastCommandSource( CMD_FROM_AI ); getStateMachine()->setState( RETURNING_FOR_LANDING ); return; } - else if (!getFlag(ALLOW_AIR_LOCO)) + + if (!getFlag(ALLOW_AIR_LOCO)) { switch (parms->m_cmd) { From 17d61359c63caed834391f61f43531bd15b6a68f Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 28 Oct 2025 22:59:10 +1100 Subject: [PATCH 2/6] refactor: Add convenience function to determine whether to defer commands --- .../Include/GameLogic/Module/JetAIUpdate.h | 1 + .../Object/Update/AIUpdate/JetAIUpdate.cpp | 30 ++++++++++++------- .../Include/GameLogic/Module/JetAIUpdate.h | 1 + .../Object/Update/AIUpdate/JetAIUpdate.cpp | 30 ++++++++++++------- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index c1b5facba1..cfb41c33fa 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -131,6 +131,7 @@ class JetAIUpdate : public AIUpdateInterface void positionLockon(); virtual Bool getTreatAsAircraftForLocoDistToGoal() const; + virtual Bool shouldDeferCommand(const AICommandType commandType) const; ///< returns whether the specified command type should be deferred Bool isParkedAt(const Object* obj) const; private: 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 4f2599e01d..01cff70725 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2316,18 +2316,8 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) // note that we always store this, even if nothing will be "pending". m_mostRecentCommand.store(*parms); - if (getFlag(TAKEOFF_IN_PROGRESS) || getFlag(LANDING_IN_PROGRESS)) + if (shouldDeferCommand(parms->m_cmd)) { - // have to wait for takeoff or landing to complete, just store the sucker - setFlag(HAS_PENDING_COMMAND, true); - return; - } - - if (parms->m_cmd == AICMD_IDLE && getStateMachine()->getCurrentStateID() == RELOAD_AMMO) - { - // uber-special-case... if we are told to idle, but are reloading ammo, ignore it for now, - // since we're already doing "nothing" and responding to this will cease our reload... - // don't just return, tho, in case we were (say) reloading during a guard stint. setFlag(HAS_PENDING_COMMAND, true); return; } @@ -2383,6 +2373,24 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) AIUpdateInterface::aiDoCommand(parms); } +//------------------------------------------------------------------------------------------------- +Bool JetAIUpdate::shouldDeferCommand(const AICommandType commandType) const +{ + // Always defer commands received during takeoff or landing + if (getFlag(TAKEOFF_IN_PROGRESS) || getFlag(LANDING_IN_PROGRESS)) + return true; + + const StateID currentState = getStateMachine()->getCurrentStateID(); + + // uber-special-case... if we are told to idle, but are reloading ammo, ignore it for now, + // since we're already doing "nothing" and responding to this will cease our reload... + // don't just return, tho, in case we were (say) reloading during a guard stint. + if (commandType == AICMD_IDLE && currentState == RELOAD_AMMO) + return true; + + return false; +} + //------------------------------------------------------------------------------------------------- void JetAIUpdate::friend_setAllowAirLoco(Bool allowAirLoco) { diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index 1840d30a4b..bf393a127a 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -140,6 +140,7 @@ class JetAIUpdate : public AIUpdateInterface void positionLockon(); virtual Bool getTreatAsAircraftForLocoDistToGoal() const; + virtual Bool shouldDeferCommand(const AICommandType commandType) const; ///< returns whether the specified command type should be deferred 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 488c9fbc1f..fa9bcced50 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2543,18 +2543,8 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) // note that we always store this, even if nothing will be "pending". m_mostRecentCommand.store(*parms); - if (getFlag(TAKEOFF_IN_PROGRESS) || getFlag(LANDING_IN_PROGRESS)) + if (shouldDeferCommand(parms->m_cmd)) { - // have to wait for takeoff or landing to complete, just store the sucker - setFlag(HAS_PENDING_COMMAND, true); - return; - } - - if (parms->m_cmd == AICMD_IDLE && getStateMachine()->getCurrentStateID() == RELOAD_AMMO) - { - // uber-special-case... if we are told to idle, but are reloading ammo, ignore it for now, - // since we're already doing "nothing" and responding to this will cease our reload... - // don't just return, tho, in case we were (say) reloading during a guard stint. setFlag(HAS_PENDING_COMMAND, true); return; } @@ -2619,6 +2609,24 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) AIUpdateInterface::aiDoCommand(parms); } +//------------------------------------------------------------------------------------------------- +Bool JetAIUpdate::shouldDeferCommand(const AICommandType commandType) const +{ + // Always defer commands received during takeoff or landing + if (getFlag(TAKEOFF_IN_PROGRESS) || getFlag(LANDING_IN_PROGRESS)) + return true; + + const StateID currentState = getStateMachine()->getCurrentStateID(); + + // uber-special-case... if we are told to idle, but are reloading ammo, ignore it for now, + // since we're already doing "nothing" and responding to this will cease our reload... + // don't just return, tho, in case we were (say) reloading during a guard stint. + if (commandType == AICMD_IDLE && currentState == RELOAD_AMMO) + return true; + + return false; +} + //------------------------------------------------------------------------------------------------- void JetAIUpdate::friend_setAllowAirLoco(Bool allowAirLoco) { From 4d6ad253e37a98280337dc6e101c0cfee8cd1d0f Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 28 Oct 2025 23:06:36 +1100 Subject: [PATCH 3/6] refactor: Add convenience function to determine whether command requires takeoff --- .../Include/GameLogic/Module/JetAIUpdate.h | 1 + .../Object/Update/AIUpdate/JetAIUpdate.cpp | 58 +++++++++---------- .../Include/GameLogic/Module/JetAIUpdate.h | 1 + .../Object/Update/AIUpdate/JetAIUpdate.cpp | 58 +++++++++---------- 4 files changed, 58 insertions(+), 60 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index cfb41c33fa..f2b5940185 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -132,6 +132,7 @@ class JetAIUpdate : public AIUpdateInterface virtual Bool getTreatAsAircraftForLocoDistToGoal() const; virtual Bool shouldDeferCommand(const AICommandType commandType) const; ///< returns whether the specified command type should be deferred + virtual Bool commandRequiresTakeoff(const AICommandParms* parms) const; ///< returns whether the specified command requires takeoff Bool isParkedAt(const Object* obj) const; private: 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 01cff70725..c928e9df8e 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2322,38 +2322,16 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) return; } - if (!getFlag(ALLOW_AIR_LOCO)) + if (!getFlag(ALLOW_AIR_LOCO) && commandRequiresTakeoff(parms)) { - switch (parms->m_cmd) - { - case AICMD_IDLE: - case AICMD_BUSY: - case AICMD_FOLLOW_EXITPRODUCTION_PATH: - // don't need (or want) to take off for these - break; - - 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; - - FALLTHROUGH; // else fall thru to the default case! - - default: - { - // nuke any existing pending cmd - m_mostRecentCommand.store(*parms); - setFlag(HAS_PENDING_COMMAND, true); - - getStateMachine()->clear(); - setLastCommandSource( CMD_FROM_AI ); - getStateMachine()->setState( TAKING_OFF_AWAIT_CLEARANCE ); + // nuke any existing pending cmd + m_mostRecentCommand.store(*parms); + setFlag(HAS_PENDING_COMMAND, true); - return; - } - } + getStateMachine()->clear(); + setLastCommandSource(CMD_FROM_AI); + getStateMachine()->setState(TAKING_OFF_AWAIT_CLEARANCE); + return; } switch (parms->m_cmd) @@ -2391,6 +2369,26 @@ Bool JetAIUpdate::shouldDeferCommand(const AICommandType commandType) const return false; } +//------------------------------------------------------------------------------------------------- +Bool JetAIUpdate::commandRequiresTakeoff(const AICommandParms* parms) const +{ + switch (parms->m_cmd) + { + case AICMD_IDLE: + case AICMD_BUSY: + case AICMD_FOLLOW_EXITPRODUCTION_PATH: + return false; + + case AICMD_ENTER: + case AICMD_GET_REPAIRED: + // if we're already parked at the airfield in question, just ignore. + return !isParkedAt(parms->m_obj); + + default: + return true; + } +} + //------------------------------------------------------------------------------------------------- void JetAIUpdate::friend_setAllowAirLoco(Bool allowAirLoco) { diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index bf393a127a..83bc565c96 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -141,6 +141,7 @@ class JetAIUpdate : public AIUpdateInterface virtual Bool getTreatAsAircraftForLocoDistToGoal() const; virtual Bool shouldDeferCommand(const AICommandType commandType) const; ///< returns whether the specified command type should be deferred + virtual Bool commandRequiresTakeoff(const AICommandParms* parms) const; ///< returns whether the specified command requires takeoff 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 fa9bcced50..4ccc3e7fcc 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2557,38 +2557,16 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) return; } - if (!getFlag(ALLOW_AIR_LOCO)) + if (!getFlag(ALLOW_AIR_LOCO) && commandRequiresTakeoff(parms)) { - switch (parms->m_cmd) - { - case AICMD_IDLE: - case AICMD_BUSY: - case AICMD_FOLLOW_EXITPRODUCTION_PATH: - // don't need (or want) to take off for these - break; - - 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; - - FALLTHROUGH; // else fall thru to the default case! - - default: - { - // nuke any existing pending cmd - m_mostRecentCommand.store(*parms); - setFlag(HAS_PENDING_COMMAND, true); - - getStateMachine()->clear(); - setLastCommandSource( CMD_FROM_AI ); - getStateMachine()->setState( TAKING_OFF_AWAIT_CLEARANCE ); + // nuke any existing pending cmd + m_mostRecentCommand.store(*parms); + setFlag(HAS_PENDING_COMMAND, true); - return; - } - } + getStateMachine()->clear(); + setLastCommandSource(CMD_FROM_AI); + getStateMachine()->setState(TAKING_OFF_AWAIT_CLEARANCE); + return; } switch (parms->m_cmd) @@ -2627,6 +2605,26 @@ Bool JetAIUpdate::shouldDeferCommand(const AICommandType commandType) const return false; } +//------------------------------------------------------------------------------------------------- +Bool JetAIUpdate::commandRequiresTakeoff(const AICommandParms* parms) const +{ + switch (parms->m_cmd) + { + case AICMD_IDLE: + case AICMD_BUSY: + case AICMD_FOLLOW_EXITPRODUCTION_PATH: + return false; + + case AICMD_ENTER: + case AICMD_GET_REPAIRED: + // if we're already parked at the airfield in question, just ignore. + return !isParkedAt(parms->m_obj); + + default: + return true; + } +} + //------------------------------------------------------------------------------------------------- void JetAIUpdate::friend_setAllowAirLoco(Bool allowAirLoco) { From bc21970b901613f16b4f2aabcbfdbaa5f0a30407 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 28 Oct 2025 23:12:48 +1100 Subject: [PATCH 4/6] refactor: Add convenience function to determine whether command is a guard command --- .../Include/GameLogic/Module/JetAIUpdate.h | 1 + .../Object/Update/AIUpdate/JetAIUpdate.cpp | 28 +++++++++-------- .../Include/GameLogic/Module/JetAIUpdate.h | 1 + .../Object/Update/AIUpdate/JetAIUpdate.cpp | 30 ++++++++++--------- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index f2b5940185..c13ae733a1 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -133,6 +133,7 @@ class JetAIUpdate : public AIUpdateInterface virtual Bool getTreatAsAircraftForLocoDistToGoal() const; virtual Bool shouldDeferCommand(const AICommandType commandType) const; ///< returns whether the specified command type should be deferred virtual Bool commandRequiresTakeoff(const AICommandParms* parms) const; ///< returns whether the specified command requires takeoff + virtual Bool isGuardCommand(const AICommandType commandType) const; ///< returns whether the specified command type is a guard command Bool isParkedAt(const Object* obj) const; private: 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 c928e9df8e..e678a9aa4f 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2334,19 +2334,7 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) return; } - switch (parms->m_cmd) - { - case AICMD_GUARD_POSITION: - case AICMD_GUARD_OBJECT: - case AICMD_GUARD_AREA: - case AICMD_HUNT: - setFlag(ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD, true); - break; - default: - setFlag(ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD, false); - break; - } - + setFlag(ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD, isGuardCommand(parms->m_cmd)); setFlag(HAS_PENDING_COMMAND, false); AIUpdateInterface::aiDoCommand(parms); } @@ -2389,6 +2377,20 @@ Bool JetAIUpdate::commandRequiresTakeoff(const AICommandParms* parms) const } } +Bool JetAIUpdate::isGuardCommand(const AICommandType commandType) const +{ + switch (commandType) + { + case AICMD_GUARD_AREA: + case AICMD_GUARD_OBJECT: + case AICMD_GUARD_POSITION: + case AICMD_HUNT: + return true; + default: + return false; + } +} + //------------------------------------------------------------------------------------------------- void JetAIUpdate::friend_setAllowAirLoco(Bool allowAirLoco) { diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index 83bc565c96..a084b07a67 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -142,6 +142,7 @@ class JetAIUpdate : public AIUpdateInterface virtual Bool getTreatAsAircraftForLocoDistToGoal() const; virtual Bool shouldDeferCommand(const AICommandType commandType) const; ///< returns whether the specified command type should be deferred virtual Bool commandRequiresTakeoff(const AICommandParms* parms) const; ///< returns whether the specified command requires takeoff + virtual Bool isGuardCommand(const AICommandType commandType) const; ///< returns whether the specified command type is a guard command 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 4ccc3e7fcc..ad947561fa 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2569,20 +2569,7 @@ void JetAIUpdate::aiDoCommand(const AICommandParms* parms) return; } - switch (parms->m_cmd) - { - case AICMD_GUARD_POSITION: - case AICMD_GUARD_OBJECT: - case AICMD_GUARD_AREA: - case AICMD_HUNT: - case AICMD_GUARD_RETALIATE: - setFlag(ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD, true); - break; - default: - setFlag(ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD, false); - break; - } - + setFlag(ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD, isGuardCommand(parms->m_cmd)); setFlag(HAS_PENDING_COMMAND, false); AIUpdateInterface::aiDoCommand(parms); } @@ -2625,6 +2612,21 @@ Bool JetAIUpdate::commandRequiresTakeoff(const AICommandParms* parms) const } } +Bool JetAIUpdate::isGuardCommand(const AICommandType commandType) const +{ + switch (commandType) + { + case AICMD_GUARD_AREA: + case AICMD_GUARD_OBJECT: + case AICMD_GUARD_POSITION: + case AICMD_GUARD_RETALIATE: + case AICMD_HUNT: + return true; + default: + return false; + } +} + //------------------------------------------------------------------------------------------------- void JetAIUpdate::friend_setAllowAirLoco(Bool allowAirLoco) { From 5409558490a4ca950252745d41ab50bf423a3b67 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Tue, 28 Oct 2025 23:15:09 +1100 Subject: [PATCH 5/6] tweak: Defer guard commands during reload --- .../Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp | 5 +++++ .../Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp | 5 +++++ 2 files changed, 10 insertions(+) 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 e678a9aa4f..194f40a8d6 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2354,6 +2354,11 @@ Bool JetAIUpdate::shouldDeferCommand(const AICommandType commandType) const if (commandType == AICMD_IDLE && currentState == RELOAD_AMMO) return true; +#if !RETAIL_COMPATIBLE_CRC + if (isGuardCommand(commandType) && currentState == RELOAD_AMMO) + return true; +#endif + return false; } 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 ad947561fa..de77ec5c57 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2589,6 +2589,11 @@ Bool JetAIUpdate::shouldDeferCommand(const AICommandType commandType) const if (commandType == AICMD_IDLE && currentState == RELOAD_AMMO) return true; +#if !RETAIL_COMPATIBLE_CRC + if (isGuardCommand(commandType) && currentState == RELOAD_AMMO) + return true; +#endif + return false; } From 69a1be79dfd95cb3e7e2c46dd0def74728f103e8 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Wed, 29 Oct 2025 00:49:28 +1100 Subject: [PATCH 6/6] bugfix: Defer commands that require ammo during reload --- .../Include/GameLogic/Module/JetAIUpdate.h | 1 + .../Object/Update/AIUpdate/JetAIUpdate.cpp | 18 +++++++++++++++++- .../Include/GameLogic/Module/JetAIUpdate.h | 1 + .../Object/Update/AIUpdate/JetAIUpdate.cpp | 18 +++++++++++++++++- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index c13ae733a1..bcda7b4310 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -133,6 +133,7 @@ class JetAIUpdate : public AIUpdateInterface virtual Bool getTreatAsAircraftForLocoDistToGoal() const; virtual Bool shouldDeferCommand(const AICommandType commandType) const; ///< returns whether the specified command type should be deferred virtual Bool commandRequiresTakeoff(const AICommandParms* parms) const; ///< returns whether the specified command requires takeoff + virtual Bool commandRequiresAmmo(const AICommandType commandType) const; ///< returns whether the specified command type requires ammo virtual Bool isGuardCommand(const AICommandType commandType) const; ///< returns whether the specified command type is a guard command Bool isParkedAt(const Object* obj) const; 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 194f40a8d6..39de2c1b13 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2355,7 +2355,7 @@ Bool JetAIUpdate::shouldDeferCommand(const AICommandType commandType) const return true; #if !RETAIL_COMPATIBLE_CRC - if (isGuardCommand(commandType) && currentState == RELOAD_AMMO) + if (commandRequiresAmmo(commandType) && currentState == RELOAD_AMMO) return true; #endif @@ -2382,6 +2382,22 @@ Bool JetAIUpdate::commandRequiresTakeoff(const AICommandParms* parms) const } } +Bool JetAIUpdate::commandRequiresAmmo(const AICommandType commandType) const +{ + switch (commandType) + { + case AICMD_ATTACKMOVE_TO_POSITION: + case AICMD_ATTACK_AREA: + case AICMD_ATTACK_OBJECT: + case AICMD_ATTACK_POSITION: + case AICMD_ATTACK_TEAM: + case AICMD_FORCE_ATTACK_OBJECT: + return true; + default: + return isGuardCommand(commandType); + } +} + Bool JetAIUpdate::isGuardCommand(const AICommandType commandType) const { switch (commandType) diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index a084b07a67..10f93c8266 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -142,6 +142,7 @@ class JetAIUpdate : public AIUpdateInterface virtual Bool getTreatAsAircraftForLocoDistToGoal() const; virtual Bool shouldDeferCommand(const AICommandType commandType) const; ///< returns whether the specified command type should be deferred virtual Bool commandRequiresTakeoff(const AICommandParms* parms) const; ///< returns whether the specified command requires takeoff + virtual Bool commandRequiresAmmo(const AICommandType commandType) const; ///< returns whether the specified command type requires ammo virtual Bool isGuardCommand(const AICommandType commandType) const; ///< returns whether the specified command type is a guard command Bool isParkedAt(const Object* obj) const; 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 de77ec5c57..d894bd5ffb 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -2590,7 +2590,7 @@ Bool JetAIUpdate::shouldDeferCommand(const AICommandType commandType) const return true; #if !RETAIL_COMPATIBLE_CRC - if (isGuardCommand(commandType) && currentState == RELOAD_AMMO) + if (commandRequiresAmmo(commandType) && currentState == RELOAD_AMMO) return true; #endif @@ -2617,6 +2617,22 @@ Bool JetAIUpdate::commandRequiresTakeoff(const AICommandParms* parms) const } } +Bool JetAIUpdate::commandRequiresAmmo(const AICommandType commandType) const +{ + switch (commandType) + { + case AICMD_ATTACKMOVE_TO_POSITION: + case AICMD_ATTACK_AREA: + case AICMD_ATTACK_OBJECT: + case AICMD_ATTACK_POSITION: + case AICMD_ATTACK_TEAM: + case AICMD_FORCE_ATTACK_OBJECT: + return true; + default: + return isGuardCommand(commandType); + } +} + Bool JetAIUpdate::isGuardCommand(const AICommandType commandType) const { switch (commandType)