From 4e94c026050ea5cebacdcedee3588e536f5209a4 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Wed, 28 Jan 2026 03:03:14 +1100 Subject: [PATCH 1/5] bugfix: Prevent dead units from repeatedly dealing crash damage on collision with non-buildings --- .../Source/GameLogic/Object/Update/PhysicsUpdate.cpp | 5 +++++ .../Source/GameLogic/Object/Update/PhysicsUpdate.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index a56790b941f..47cddc721ba 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -1260,7 +1260,12 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 else { // fall into a nonbuilding -- whatever. if we're a vehicle, quietly do a little damage. +#if RETAIL_COMPATIBLE_CRC if (obj->isKindOf(KINDOF_VEHICLE)) +#else + // TheSuperHackers @bugfix Stubbjax 28/01/2026 Prevent dead units from repeatedly dealing damage. + if (obj->isKindOf(KINDOF_VEHICLE) && !obj->isEffectivelyDead()) +#endif { TheWeaponStore->createAndFireTempWeapon(getPhysicsBehaviorModuleData()->m_vehicleCrashesIntoNonBuildingWeaponTemplate, obj, obj->getPosition()); } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index ccc57226348..b9695d22789 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -1385,7 +1385,12 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 else { // fall into a nonbuilding -- whatever. if we're a vehicle, quietly do a little damage. +#if RETAIL_COMPATIBLE_CRC if (obj->isKindOf(KINDOF_VEHICLE)) +#else + // TheSuperHackers @bugfix Stubbjax 28/01/2026 Prevent dead units from repeatedly dealing damage. + if (obj->isKindOf(KINDOF_VEHICLE) && !obj->isEffectivelyDead()) +#endif { TheWeaponStore->createAndFireTempWeapon(getPhysicsBehaviorModuleData()->m_vehicleCrashesIntoNonBuildingWeaponTemplate, obj, obj->getPosition()); } From 5d8644bc7400fdb72d1c53683f1543e10752bbf5 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Sun, 19 Apr 2026 21:51:58 +1000 Subject: [PATCH 2/5] bugfix: Only apply non-building crash damage to collided objects --- .../GameLogic/Object/Update/PhysicsUpdate.cpp | 19 ++++++++++++++----- .../GameLogic/Object/Update/PhysicsUpdate.cpp | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index 47cddc721ba..32a956a255a 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -1260,14 +1260,23 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 else { // fall into a nonbuilding -- whatever. if we're a vehicle, quietly do a little damage. -#if RETAIL_COMPATIBLE_CRC if (obj->isKindOf(KINDOF_VEHICLE)) -#else - // TheSuperHackers @bugfix Stubbjax 28/01/2026 Prevent dead units from repeatedly dealing damage. - if (obj->isKindOf(KINDOF_VEHICLE) && !obj->isEffectivelyDead()) -#endif { +#if RETAIL_COMPATIBLE_CRC TheWeaponStore->createAndFireTempWeapon(getPhysicsBehaviorModuleData()->m_vehicleCrashesIntoNonBuildingWeaponTemplate, obj, obj->getPosition()); +#else + // TheSuperHackers @bugfix Stubbjax 19/04/2026 Prevent non-building collisions from repeatedly dealing collateral damage to other objects. + const WeaponTemplate* weaponTemplate = getPhysicsBehaviorModuleData()->m_vehicleCrashesIntoNonBuildingWeaponTemplate; + WeaponBonus nullBonus; + + DamageInfo damageInfo; + damageInfo.in.m_damageType = weaponTemplate->getDamageType(); + damageInfo.in.m_deathType = weaponTemplate->getDeathType(); + damageInfo.in.m_sourceID = obj->getID(); + damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); + + other->attemptDamage(&damageInfo); +#endif } } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index b9695d22789..b416636aa57 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -1385,14 +1385,23 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 else { // fall into a nonbuilding -- whatever. if we're a vehicle, quietly do a little damage. -#if RETAIL_COMPATIBLE_CRC if (obj->isKindOf(KINDOF_VEHICLE)) -#else - // TheSuperHackers @bugfix Stubbjax 28/01/2026 Prevent dead units from repeatedly dealing damage. - if (obj->isKindOf(KINDOF_VEHICLE) && !obj->isEffectivelyDead()) -#endif { +#if RETAIL_COMPATIBLE_CRC TheWeaponStore->createAndFireTempWeapon(getPhysicsBehaviorModuleData()->m_vehicleCrashesIntoNonBuildingWeaponTemplate, obj, obj->getPosition()); +#else + // TheSuperHackers @bugfix Stubbjax 19/04/2026 Prevent non-building collisions from repeatedly dealing collateral damage to other objects. + const WeaponTemplate* weaponTemplate = getPhysicsBehaviorModuleData()->m_vehicleCrashesIntoNonBuildingWeaponTemplate; + WeaponBonus nullBonus; + + DamageInfo damageInfo; + damageInfo.in.m_damageType = weaponTemplate->getDamageType(); + damageInfo.in.m_deathType = weaponTemplate->getDeathType(); + damageInfo.in.m_sourceID = obj->getID(); + damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); + + other->attemptDamage(&damageInfo); +#endif } } } From 854065b7a67a5a1bdc1b4f553c39917f3d88577d Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Sun, 17 May 2026 21:38:12 +1000 Subject: [PATCH 3/5] tweak: Add null checks --- .../GameLogic/Object/Update/PhysicsUpdate.cpp | 21 +++++++++++-------- .../GameLogic/Object/Update/PhysicsUpdate.cpp | 21 +++++++++++-------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index 32a956a255a..37c349615b5 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -1267,15 +1267,18 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 #else // TheSuperHackers @bugfix Stubbjax 19/04/2026 Prevent non-building collisions from repeatedly dealing collateral damage to other objects. const WeaponTemplate* weaponTemplate = getPhysicsBehaviorModuleData()->m_vehicleCrashesIntoNonBuildingWeaponTemplate; - WeaponBonus nullBonus; - - DamageInfo damageInfo; - damageInfo.in.m_damageType = weaponTemplate->getDamageType(); - damageInfo.in.m_deathType = weaponTemplate->getDeathType(); - damageInfo.in.m_sourceID = obj->getID(); - damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); - - other->attemptDamage(&damageInfo); + if (weaponTemplate != nullptr) + { + WeaponBonus nullBonus; + + DamageInfo damageInfo; + damageInfo.in.m_damageType = weaponTemplate->getDamageType(); + damageInfo.in.m_deathType = weaponTemplate->getDeathType(); + damageInfo.in.m_sourceID = obj->getID(); + damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); + + other->attemptDamage(&damageInfo); + } #endif } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index b416636aa57..d66cb0597fd 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -1392,15 +1392,18 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 #else // TheSuperHackers @bugfix Stubbjax 19/04/2026 Prevent non-building collisions from repeatedly dealing collateral damage to other objects. const WeaponTemplate* weaponTemplate = getPhysicsBehaviorModuleData()->m_vehicleCrashesIntoNonBuildingWeaponTemplate; - WeaponBonus nullBonus; - - DamageInfo damageInfo; - damageInfo.in.m_damageType = weaponTemplate->getDamageType(); - damageInfo.in.m_deathType = weaponTemplate->getDeathType(); - damageInfo.in.m_sourceID = obj->getID(); - damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); - - other->attemptDamage(&damageInfo); + if (weaponTemplate != nullptr) + { + WeaponBonus nullBonus; + + DamageInfo damageInfo; + damageInfo.in.m_damageType = weaponTemplate->getDamageType(); + damageInfo.in.m_deathType = weaponTemplate->getDeathType(); + damageInfo.in.m_sourceID = obj->getID(); + damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); + + other->attemptDamage(&damageInfo); + } #endif } } From a11c4da5174f539cc3309424c24a0e5a54b2f377 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Sun, 17 May 2026 21:38:22 +1000 Subject: [PATCH 4/5] tweak: Attempt to fire effects --- .../GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp | 2 ++ .../GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index 37c349615b5..1b82f34bd26 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -34,6 +34,7 @@ #include "Common/PerfTimer.h" #include "Common/ThingTemplate.h" #include "Common/Xfer.h" +#include "GameClient/FXList.h" #include "GameLogic/GameLogic.h" #include "GameLogic/Module/AIUpdate.h" #include "GameLogic/Module/BodyModule.h" @@ -1278,6 +1279,7 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); other->attemptDamage(&damageInfo); + FXList::doFXObj(weaponTemplate->getFireFX(obj->getVeterancyLevel()), obj); } #endif } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index d66cb0597fd..1c715f97a90 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -34,6 +34,7 @@ #include "Common/PerfTimer.h" #include "Common/ThingTemplate.h" #include "Common/Xfer.h" +#include "GameClient/FXList.h" #include "GameLogic/GameLogic.h" #include "GameLogic/Module/AIUpdate.h" #include "GameLogic/Module/BodyModule.h" @@ -1403,6 +1404,7 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); other->attemptDamage(&damageInfo); + FXList::doFXObj(weaponTemplate->getFireFX(obj->getVeterancyLevel()), obj); } #endif } From fd6d974e09145f89fb3e9e8b7de0a97fc3a805a8 Mon Sep 17 00:00:00 2001 From: Stubbjax Date: Sun, 17 May 2026 21:49:53 +1000 Subject: [PATCH 5/5] tweak: Assign source player mask --- .../GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp | 2 ++ .../GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index 1b82f34bd26..13b1fe8c344 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -32,6 +32,7 @@ #define NO_DEBUG_CRC #include "Common/PerfTimer.h" +#include "Common/Player.h" #include "Common/ThingTemplate.h" #include "Common/Xfer.h" #include "GameClient/FXList.h" @@ -1276,6 +1277,7 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 damageInfo.in.m_damageType = weaponTemplate->getDamageType(); damageInfo.in.m_deathType = weaponTemplate->getDeathType(); damageInfo.in.m_sourceID = obj->getID(); + damageInfo.in.m_sourcePlayerMask = obj->getControllingPlayer() ? obj->getControllingPlayer()->getPlayerMask() : 0; damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); other->attemptDamage(&damageInfo); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp index 1c715f97a90..10b09f534cb 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/PhysicsUpdate.cpp @@ -32,6 +32,7 @@ #define NO_DEBUG_CRC #include "Common/PerfTimer.h" +#include "Common/Player.h" #include "Common/ThingTemplate.h" #include "Common/Xfer.h" #include "GameClient/FXList.h" @@ -1401,6 +1402,7 @@ void PhysicsBehavior::onCollide( Object *other, const Coord3D *loc, const Coord3 damageInfo.in.m_damageType = weaponTemplate->getDamageType(); damageInfo.in.m_deathType = weaponTemplate->getDeathType(); damageInfo.in.m_sourceID = obj->getID(); + damageInfo.in.m_sourcePlayerMask = obj->getControllingPlayer() ? obj->getControllingPlayer()->getPlayerMask() : 0; damageInfo.in.m_amount = weaponTemplate->getPrimaryDamage(nullBonus); other->attemptDamage(&damageInfo);