Summary
When the Overlord tank has a Gatling Cannon upgrade and the player issues a force-attack on empty terrain (no units, no buildings — just ground), the Gatling Cannon disappears from the Overlord. Because the upgrade slot is consumed, the Gatling cannot be re-built.
This does not affect:
- Normal attacks against actual targets (units, buildings) — Gatling fires correctly
- Propaganda Tower upgrade — never disappears regardless of force-attack
- BattleBunker upgrade — unaffected
Steps to Reproduce
- Build an Overlord tank (China faction)
- Apply the Gatling Cannon upgrade
- Select the Overlord
- Force-attack (
A + click) on an empty area of terrain with no targets
- Gatling Cannon disappears
Root Cause Analysis
The Gatling Cannon's AI enters the following state chain when force-attacking empty terrain:
aiAttackPosition
→ AI_ATTACK_POSITION (AIAttackState)
→ AttackStateMachine::AIM_AT_TARGET
→ outOfWeaponRange → CHASE_TARGET
→ ContinueState (KINDOF_PORTABLE_STRUCTURE + KINDOF_CAN_ATTACK special case)
→ EXIT_MACHINE_WITH_FAILURE
→ STATE_FAILURE → AI_EXIT_INSTANTLY
→ AIExitInstantlyState::onEnter()
→ goalExitInterface->exitObjectViaDoor(obj, DOOR_1) ← Gatling ejected here
The key issue is in AttackStateMachine constructor (AIStates.cpp): when the attacker is both KINDOF_PORTABLE_STRUCTURE and KINDOF_CAN_ATTACK, CHASE_TARGET is a ContinueState that always fails — this is intentional (portables can't move), but it causes AI_EXIT_INSTANTLY to be triggered.
The Propaganda Tower never hits this path because it has no attack weapons and never enters attack states — its healing works via PropagandaTowerBehavior area scan.
Attempted Fixes
Two guards were added to OverlordContain (commits 93de21fe6, 689b38e78):
isSpecificRiderFreeToExit() — blocks AIExitState (normal exit via reserveDoorForExit). Works.
exitObjectViaDoor() — meant to block AIExitInstantlyState which calls exitObjectViaDoor(DOOR_1) directly, bypassing reserveDoorForExit. Did not resolve the issue.
The exact bypass mechanism when exitObjectViaDoor override is in place is not yet identified. Possible unexplored paths:
removeFromContain() called directly from a different code path
getContainExitInterface() returning a different ExitInterface in this context
- A different trigger (not
AI_EXIT_INSTANTLY) causing the removal
Affected Files
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OverlordContain.cpp
GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp (AttackStateMachine, AIExitInstantlyState)
Workaround
None currently. Avoid force-attacking empty terrain with an Overlord that has the Gatling Cannon upgrade.
Platform
macOS (POSIX port). Behavior on original Windows/VC6 build is unknown — the locomotor-based DISABLED_HELD mechanism may have prevented the issue naturally on that platform.
Summary
When the Overlord tank has a Gatling Cannon upgrade and the player issues a force-attack on empty terrain (no units, no buildings — just ground), the Gatling Cannon disappears from the Overlord. Because the upgrade slot is consumed, the Gatling cannot be re-built.
This does not affect:
Steps to Reproduce
A+ click) on an empty area of terrain with no targetsRoot Cause Analysis
The Gatling Cannon's AI enters the following state chain when force-attacking empty terrain:
The key issue is in
AttackStateMachineconstructor (AIStates.cpp): when the attacker is bothKINDOF_PORTABLE_STRUCTUREandKINDOF_CAN_ATTACK, CHASE_TARGET is aContinueStatethat always fails — this is intentional (portables can't move), but it causesAI_EXIT_INSTANTLYto be triggered.The Propaganda Tower never hits this path because it has no attack weapons and never enters attack states — its healing works via
PropagandaTowerBehaviorarea scan.Attempted Fixes
Two guards were added to
OverlordContain(commits93de21fe6,689b38e78):isSpecificRiderFreeToExit()— blocksAIExitState(normal exit viareserveDoorForExit). Works.exitObjectViaDoor()— meant to blockAIExitInstantlyStatewhich callsexitObjectViaDoor(DOOR_1)directly, bypassingreserveDoorForExit. Did not resolve the issue.The exact bypass mechanism when
exitObjectViaDooroverride is in place is not yet identified. Possible unexplored paths:removeFromContain()called directly from a different code pathgetContainExitInterface()returning a different ExitInterface in this contextAI_EXIT_INSTANTLY) causing the removalAffected Files
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OverlordContain.cppGeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp(AttackStateMachine, AIExitInstantlyState)Workaround
None currently. Avoid force-attacking empty terrain with an Overlord that has the Gatling Cannon upgrade.
Platform
macOS (POSIX port). Behavior on original Windows/VC6 build is unknown — the locomotor-based
DISABLED_HELDmechanism may have prevented the issue naturally on that platform.