From 16f1ddb61c1cd30da09d00dec6536a86f405be48 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Wed, 19 Nov 2025 03:27:05 +1100 Subject: [PATCH 1/3] bugfix: Undetected mines can now be approached when using a disarm weapon --- Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 8 ++++++++ .../Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 79913a7c7d9..4e4a8498945 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -2596,7 +2596,15 @@ StateReturnType AIAttackApproachTargetState::updateInternal() { if( victim->testStatus( OBJECT_STATUS_STEALTHED ) && !victim->testStatus( OBJECT_STATUS_DETECTED ) ) { +#if RETAIL_COMPATIBLE_CRC return STATE_FAILURE; // If obj is stealthed, can no longer approach. +#else + Bool isTargetingMine = weapon && weapon->getDamageType() == DAMAGE_DISARM && + (victim->isKindOf(KINDOF_MINE)); + + if (!isTargetingMine) + return STATE_FAILURE; // If obj is stealthed, can no longer approach - unless we're targeting a mine! +#endif } ai->setCurrentVictim(victim); // Attacking an object. diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 6988747599d..487c1068f36 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -2682,7 +2682,15 @@ StateReturnType AIAttackApproachTargetState::updateInternal() } if( victim->testStatus( OBJECT_STATUS_STEALTHED ) && !victim->testStatus( OBJECT_STATUS_DETECTED ) && !victim->testStatus( OBJECT_STATUS_DISGUISED ) ) { +#if RETAIL_COMPATIBLE_CRC return STATE_FAILURE; // If obj is stealthed, can no longer approach. +#else + Bool isTargetingMine = weapon && weapon->getDamageType() == DAMAGE_DISARM && + (victim->isKindOf(KINDOF_MINE) || victim->isKindOf(KINDOF_BOOBY_TRAP) || victim->isKindOf(KINDOF_DEMOTRAP)); + + if (!isTargetingMine) + return STATE_FAILURE; // If obj is stealthed, can no longer approach - unless we're targeting a mine! +#endif } ai->setCurrentVictim(victim); // Attacking an object. From 2e1705f380077fb46ee1d7e2feae3eed4e09ff86 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Mon, 22 Dec 2025 09:45:46 +1100 Subject: [PATCH 2/3] tweak: Assign constants --- Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 2 +- GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 4e4a8498945..a2d44d17e32 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -2599,7 +2599,7 @@ StateReturnType AIAttackApproachTargetState::updateInternal() #if RETAIL_COMPATIBLE_CRC return STATE_FAILURE; // If obj is stealthed, can no longer approach. #else - Bool isTargetingMine = weapon && weapon->getDamageType() == DAMAGE_DISARM && + const Bool isTargetingMine = weapon && weapon->getDamageType() == DAMAGE_DISARM && (victim->isKindOf(KINDOF_MINE)); if (!isTargetingMine) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 487c1068f36..2530651915c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -2685,7 +2685,7 @@ StateReturnType AIAttackApproachTargetState::updateInternal() #if RETAIL_COMPATIBLE_CRC return STATE_FAILURE; // If obj is stealthed, can no longer approach. #else - Bool isTargetingMine = weapon && weapon->getDamageType() == DAMAGE_DISARM && + const Bool isTargetingMine = weapon && weapon->getDamageType() == DAMAGE_DISARM && (victim->isKindOf(KINDOF_MINE) || victim->isKindOf(KINDOF_BOOBY_TRAP) || victim->isKindOf(KINDOF_DEMOTRAP)); if (!isTargetingMine) From 59b50427bcb546d03ab2d22aed19702221378407 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Sat, 3 Jan 2026 12:34:45 +1100 Subject: [PATCH 3/3] docs: Update comments --- Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 6 ++++-- GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index a2d44d17e32..53e6fea55f9 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -2596,14 +2596,16 @@ StateReturnType AIAttackApproachTargetState::updateInternal() { if( victim->testStatus( OBJECT_STATUS_STEALTHED ) && !victim->testStatus( OBJECT_STATUS_DETECTED ) ) { + // If obj is stealthed, can no longer approach. + // TheSuperHackers @bugfix Stubbjax 19/11/2025 Except when disarming stealthed mines. #if RETAIL_COMPATIBLE_CRC - return STATE_FAILURE; // If obj is stealthed, can no longer approach. + return STATE_FAILURE; #else const Bool isTargetingMine = weapon && weapon->getDamageType() == DAMAGE_DISARM && (victim->isKindOf(KINDOF_MINE)); if (!isTargetingMine) - return STATE_FAILURE; // If obj is stealthed, can no longer approach - unless we're targeting a mine! + return STATE_FAILURE; #endif } ai->setCurrentVictim(victim); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 2530651915c..099a8df7fb6 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -2682,14 +2682,16 @@ StateReturnType AIAttackApproachTargetState::updateInternal() } if( victim->testStatus( OBJECT_STATUS_STEALTHED ) && !victim->testStatus( OBJECT_STATUS_DETECTED ) && !victim->testStatus( OBJECT_STATUS_DISGUISED ) ) { + // If obj is stealthed, can no longer approach. + // TheSuperHackers @bugfix Stubbjax 19/11/2025 Except when disarming stealthed mines or traps. #if RETAIL_COMPATIBLE_CRC - return STATE_FAILURE; // If obj is stealthed, can no longer approach. + return STATE_FAILURE; #else const Bool isTargetingMine = weapon && weapon->getDamageType() == DAMAGE_DISARM && (victim->isKindOf(KINDOF_MINE) || victim->isKindOf(KINDOF_BOOBY_TRAP) || victim->isKindOf(KINDOF_DEMOTRAP)); if (!isTargetingMine) - return STATE_FAILURE; // If obj is stealthed, can no longer approach - unless we're targeting a mine! + return STATE_FAILURE; #endif } ai->setCurrentVictim(victim);