From e9a99ba215cea58adfba5e417e53cdbeddb533f2 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Sat, 20 Sep 2025 01:48:54 +1000 Subject: [PATCH 1/4] bugfix: Battle Bus can no longer be subdued indefinitely --- .../Source/GameLogic/Object/Body/UndeadBody.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp index 05b968d322..f4650663e0 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp @@ -87,6 +87,14 @@ void UndeadBody::attemptDamage( DamageInfo *damageInfo ) { damageInfo->in.m_amount = min( damageInfo->in.m_amount, getHealth() - 1 ); shouldStartSecondLife = TRUE; + +#if !RETAIL_COMPATIBLE_CRC + if (isSubdued()) + { + const UndeadBodyModuleData* data = getUndeadBodyModuleData(); + internalAddSubdualDamage(data->m_secondLifeMaxHealth - getCurrentSubdualDamageAmount()); + } +#endif } ActiveBody::attemptDamage(damageInfo); From 9c1629015ad68f9c4dcf2f46c62974b7df860489 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Sat, 20 Sep 2025 21:37:42 +1000 Subject: [PATCH 2/4] bugfix: Apply fix for all cases of max health changes --- .../Source/GameLogic/Object/Body/ActiveBody.cpp | 6 ++++++ .../Source/GameLogic/Object/Body/UndeadBody.cpp | 8 -------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp index 0808282786..15b395e7c8 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp @@ -929,6 +929,12 @@ void ActiveBody::setMaxHealth( Real maxHealth, MaxHealthChangeType healthChangeT internalChangeHealth(m_maxHealth - m_currentHealth); break; } + +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @bugfix Stubbjax 20/09/2025 Prevent indefinite subdue status when internally shifting health across the threshold. + if (isSubdued()) + internalAddSubdualDamage(m_maxHealth - getCurrentSubdualDamageAmount()); +#endif } // diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp index f4650663e0..05b968d322 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp @@ -87,14 +87,6 @@ void UndeadBody::attemptDamage( DamageInfo *damageInfo ) { damageInfo->in.m_amount = min( damageInfo->in.m_amount, getHealth() - 1 ); shouldStartSecondLife = TRUE; - -#if !RETAIL_COMPATIBLE_CRC - if (isSubdued()) - { - const UndeadBodyModuleData* data = getUndeadBodyModuleData(); - internalAddSubdualDamage(data->m_secondLifeMaxHealth - getCurrentSubdualDamageAmount()); - } -#endif } ActiveBody::attemptDamage(damageInfo); From 25c541db115594b1d4a19be6527749e245b06bdf Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Wed, 24 Sep 2025 15:58:58 +1000 Subject: [PATCH 3/4] tweak: Cleaner solution --- .../Source/GameLogic/Object/Body/ActiveBody.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp index 15b395e7c8..e468c5cf3e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp @@ -494,7 +494,7 @@ void ActiveBody::attemptDamage( DamageInfo *damageInfo ) Bool wasSubdued = isSubdued(); internalAddSubdualDamage(amount); - Bool nowSubdued = isSubdued(); + Bool nowSubdued = m_maxHealth <= m_currentSubdualDamage; alreadyHandled = TRUE; allowModifier = FALSE; @@ -929,12 +929,6 @@ void ActiveBody::setMaxHealth( Real maxHealth, MaxHealthChangeType healthChangeT internalChangeHealth(m_maxHealth - m_currentHealth); break; } - -#if !RETAIL_COMPATIBLE_CRC - // TheSuperHackers @bugfix Stubbjax 20/09/2025 Prevent indefinite subdue status when internally shifting health across the threshold. - if (isSubdued()) - internalAddSubdualDamage(m_maxHealth - getCurrentSubdualDamageAmount()); -#endif } // @@ -1319,7 +1313,12 @@ void ActiveBody::onSubdualChange( Bool isNowSubdued ) //------------------------------------------------------------------------------------------------- Bool ActiveBody::isSubdued() const { +#if RETAIL_COMPATIBLE_CRC return m_maxHealth <= m_currentSubdualDamage; +#else + // TheSuperHackers @bugfix Stubbjax 20/09/2025 Prevent indefinite subdue status when internally shifting health across the threshold. + return getObject()->isDisabledByType(DISABLED_SUBDUED); +#endif } //------------------------------------------------------------------------------------------------- From 61197eba8418dad54e7d03df5e86d591f5aa12a1 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Wed, 24 Sep 2025 17:48:43 +1000 Subject: [PATCH 4/4] docs: Update comment --- .../GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp index e468c5cf3e..f0fea0540e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp @@ -492,6 +492,8 @@ void ActiveBody::attemptDamage( DamageInfo *damageInfo ) if( !canBeSubdued() ) return; + // TheSuperHackers @bugfix Stubbjax 20/09/2025 The isSubdued() function now directly checks status instead + // of health to prevent indefinite subdue status when internally shifting health across the threshold. Bool wasSubdued = isSubdued(); internalAddSubdualDamage(amount); Bool nowSubdued = m_maxHealth <= m_currentSubdualDamage; @@ -1316,7 +1318,6 @@ Bool ActiveBody::isSubdued() const #if RETAIL_COMPATIBLE_CRC return m_maxHealth <= m_currentSubdualDamage; #else - // TheSuperHackers @bugfix Stubbjax 20/09/2025 Prevent indefinite subdue status when internally shifting health across the threshold. return getObject()->isDisabledByType(DISABLED_SUBDUED); #endif }