From e668646546cbe1c939f23585be37bcba28b0d07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Fa=C5=82kowski?= Date: Wed, 23 Aug 2023 17:08:41 +0200 Subject: [PATCH] Fixed vehicle body not properly removed when destroyed during ramming --- Tactical/Soldier Control.cpp | 20 ++++++++++++++++++++ Tactical/Soldier Control.h | 8 ++++++++ TileEngine/structure.cpp | 4 ++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 9a594ee2f..271368d04 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -10700,6 +10700,22 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr return(ubCombinedLoss); } +void SOLDIERTYPE::SoldierTakeDelayedDamage(INT8 bHeight, INT16 sLifeDeduct, INT16 sBreathLoss, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage) +{ + delayedDamageFunction = [this, bHeight, sLifeDeduct, sBreathLoss, ubReason, ubAttacker, sSourceGrid, sSubsequent, fShowDamage]() + { + this->SoldierTakeDamage(bHeight, sLifeDeduct, sBreathLoss, ubReason, ubAttacker, sSourceGrid, sSubsequent, fShowDamage); + }; +} + +void SOLDIERTYPE::ResolveDelayedDamage() +{ + if (delayedDamageFunction) + { + delayedDamageFunction(); + delayedDamageFunction = nullptr; + } +} extern BOOLEAN IsMercSayingDialogue( UINT8 ubProfileID ); @@ -11499,6 +11515,8 @@ void SOLDIERTYPE::MoveMerc( FLOAT dMovementChange, FLOAT dAngle, BOOLEAN fCheckR // OK, set new position this->EVENT_InternalSetSoldierPosition( dXPos, dYPos, FALSE, FALSE, FALSE ); + this->ResolveDelayedDamage(); + // Flugente: drag people if ( currentlydragging ) { @@ -26234,4 +26252,6 @@ void SOLDIERTYPE::InitializeExtraData(void) this->ubQuickItemSlot = 0; this->usGrenadeItem = 0; + + this->delayedDamageFunction = nullptr; } diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index e02e1de0a..697456188 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -20,6 +20,7 @@ #include #include "GameSettings.h" // added by Flugente #include "Disease.h" // added by Flugente +#include #define PTR_CIVILIAN (pSoldier->bTeam == CIV_TEAM) #define PTR_CROUCHED (gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_CROUCH) @@ -1656,6 +1657,10 @@ class SOLDIERTYPE//last edited at version 102 UINT8 ubQuickItemSlot; UINT16 usGrenadeItem; + + // anv: resolve damage with delay, e.g. damage applied mid movement that would cause issues with world data if applied immediately + std::function delayedDamageFunction; + public: // CREATION FUNCTIONS BOOLEAN DeleteSoldier( void ); @@ -1719,6 +1724,9 @@ class SOLDIERTYPE//last edited at version 102 void ReviveSoldier( void ); UINT8 SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBreathDeduct, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage ); + // anv: resolve damage with delay, e.g. damage applied mid movement that would cause issues with world data if applied immediately + void SoldierTakeDelayedDamage(INT8 bHeight, INT16 sLifeDeduct, INT16 sBreathDeduct, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage); + void ResolveDelayedDamage(); // Palette functions for soldiers BOOLEAN CreateSoldierPalettes( void ); diff --git a/TileEngine/structure.cpp b/TileEngine/structure.cpp index 49264a512..1d8b2fc22 100644 --- a/TileEngine/structure.cpp +++ b/TileEngine/structure.cpp @@ -1914,10 +1914,10 @@ INT8 DamageStructure( STRUCTURE * pStructure, UINT8 ubDamage, UINT8 ubReason, IN //Since the structure is being damaged, set the map element that a structure is damaged gpWorldLevelData[ tmpgridno ].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED; - // handle structure revenge - damage to vehicle + // handle structure revenge - damage to vehicle - to be resolved after movement if ( ubOwner != NOBODY && MercPtrs[ubOwner] && !ARMED_VEHICLE( MercPtrs[ubOwner] ) ) { - MercPtrs[ ubOwner ]->SoldierTakeDamage( 0, Random(max(0,(ubBaseArmour-10)/5))+max(0,(ubBaseArmour-10)/5), 0, TAKE_DAMAGE_STRUCTURE_EXPLOSION, NOBODY, MercPtrs[ ubOwner ]->sGridNo, 0, TRUE ); + MercPtrs[ubOwner]->SoldierTakeDelayedDamage(0, Random(max(0,(ubBaseArmour-10)/5)) + max(0,(ubBaseArmour-10)/5), 0, TAKE_DAMAGE_STRUCTURE_EXPLOSION, NOBODY, MercPtrs[ ubOwner ]->sGridNo, 0, TRUE); } // recompile = TRUE means that we destroyed something