From 7c2e086dc7ddc4516ce66cec1bc4c84cfcd449d4 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 12 Jul 2025 15:51:01 +0800 Subject: [PATCH 01/11] impl --- CREDITS.md | 1 + docs/New-or-Enhanced-Logics.md | 27 +++++++ docs/Whats-New.md | 1 + src/Ext/Rules/Body.cpp | 3 + src/Ext/Rules/Body.h | 4 + src/Ext/TechnoType/Body.cpp | 10 +++ src/Ext/TechnoType/Body.h | 10 +++ src/Ext/WarheadType/Body.cpp | 11 +++ src/Ext/WarheadType/Body.h | 13 +++- src/Ext/WarheadType/Detonate.cpp | 127 +++++++++++++++++++++++++++++-- 10 files changed, 198 insertions(+), 9 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index eac8c181be..15f70383e4 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -422,6 +422,7 @@ This page lists all the individual contributions to the project by their author. - Display banner improvement - Electric/RadBeam trail for laser tails - Ground line for select box + - Penetrates damage on transporter - **Apollo** - Translucent SHP drawing patches - **ststl**: - Customizable `ShowTimer` priority of superweapons diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 3ed3d3e47f..29e6358987 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2326,6 +2326,33 @@ In `rulesmd.ini`: RemoveParasite= ; boolean ``` +### Penetrates damage on transporter + +- Warheads can now damage passenger on impact. + - If `PenetratesTransport.Level` of warhead larger than `PenetratesTransport.Level` of target, it will enable penetrates damage logic on this impact. + - `PenetratesTransport.PassThrough` is the chance of penetration, actual chance will multiply by `PenetratesTransport.PassThroughMultiplier` of target. + - `PenetratesTransport.FatalRate` is the chance of one hit kill, actual change will multiply by `PenetratesTransport.FatalRateMultiplier` of target. + - `PenetratesTransport.DamageAll` control whether it will damage all passengers or random one passenger in transport. + - `PenetratesTransport.DamageMultiplier` is multiplier of damage on passenger. + +In `rulesmd.ini` +```ini +[SOMEWARHEAD] ; WarheadType +PenetratesTransport.Level=0 ; integer +PenetratesTransport.PassThrough=1.0 ; double +PenetratesTransport.FatalRate=0.0 ; double +PenetratesTransport.DamageAll=false ; boolean + +[SOMETECHNO] ; TechnoType +PenetratesTransport.Level= ; integer +PenetratesTransport.PassThroughMultiplier=1.0 ; double +PenetratesTransport.FatalRateMultiplier=1.0 ; double +PenetratesTransport.DamageMultiplier=1.0 ; double + +[CombatDamage] +PenetratesTransport.Level=10 ; integer, default value of technotype's penetrate level +``` + ### Remove disguise on impact - Warheads can now remove disguise from disguised spies or mirage tanks. This will work even if the disguised was acquired by default through `PermaDisguise`. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 9ca70ec3cb..ebc6515425 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -422,6 +422,7 @@ New: - Skip target scanning function calling for unarmed technos (by TaranDahl and solar-III) - Target scanning delay customization (by TaranDahl and solar-III) - Force techno targeting in distributed frames to improve performance (by TaranDahl) +- Penetrates damage on transporter (by NetsuNegi) Vanilla fixes: - Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya) diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 2dc595ebc5..037da18285 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -285,6 +285,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->AttackMove_IgnoreWeaponCheck.Read(exINI, GameStrings::General, "AttackMove.IgnoreWeaponCheck"); this->AttackMove_StopWhenTargetAcquired.Read(exINI, GameStrings::General, "AttackMove.StopWhenTargetAcquired"); + this->PenetratesTransport_Level.Read(exINI, GameStrings::CombatDamage, "PenetratesTransport.Level"); + this->AINormalTargetingDelay.Read(exINI, GameStrings::General, "AINormalTargetingDelay"); this->PlayerNormalTargetingDelay.Read(exINI, GameStrings::General, "PlayerNormalTargetingDelay"); this->AIGuardAreaTargetingDelay.Read(exINI, GameStrings::General, "AIGuardAreaTargetingDelay"); @@ -542,6 +544,7 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->TintColorBerserk) .Process(this->AttackMove_IgnoreWeaponCheck) .Process(this->AttackMove_StopWhenTargetAcquired) + .Process(this->PenetratesTransport_Level) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index c6cd697564..bf602a0193 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -241,6 +241,8 @@ class RulesExt Valueable AttackMove_IgnoreWeaponCheck; Nullable AttackMove_StopWhenTargetAcquired; + + Valueable PenetratesTransport_Level; // cache tint color int TintColorIronCurtain; @@ -437,6 +439,8 @@ class RulesExt , AttackMove_IgnoreWeaponCheck { false } , AttackMove_StopWhenTargetAcquired { } + + , PenetratesTransport_Level { 10 } { } virtual ~ExtData() = default; diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index 5b3f2c3989..4e6095e3de 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -912,6 +912,11 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->AttackMove_StopWhenTargetAcquired.Read(exINI, pSection, "AttackMove.StopWhenTargetAcquired"); this->AttackMove_PursuitTarget.Read(exINI, pSection, "AttackMove.PursuitTarget"); + this->PenetratesTransport_Level.Read(exINI, pSection, "PenetratesTransport.Level"); + this->PenetratesTransport_PassThroughMultiplier.Read(exINI, pSection, "PenetratesTransport.PassThroughMultiplier"); + this->PenetratesTransport_FatalRateMultiplier.Read(exINI, pSection, "PenetratesTransport.FatalRateMultiplier"); + this->PenetratesTransport_DamageMultiplier.Read(exINI, pSection, "PenetratesTransport.DamageMultiplier"); + // Ares 0.2 this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius"); @@ -1530,6 +1535,11 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) .Process(this->AttackMove_Follow_IfMindControlIsFull) .Process(this->AttackMove_StopWhenTargetAcquired) .Process(this->AttackMove_PursuitTarget) + + .Process(this->PenetratesTransport_Level) + .Process(this->PenetratesTransport_PassThroughMultiplier) + .Process(this->PenetratesTransport_FatalRateMultiplier) + .Process(this->PenetratesTransport_DamageMultiplier) .Process(this->MultiWeapon) .Process(this->MultiWeapon_IsSecondary) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index 98f9dbcfb8..3324f6e9cd 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -406,6 +406,11 @@ class TechnoTypeExt Nullable AttackMove_StopWhenTargetAcquired; Valueable AttackMove_PursuitTarget; + Nullable PenetratesTransport_Level; + Valueable PenetratesTransport_PassThroughMultiplier; + Valueable PenetratesTransport_FatalRateMultiplier; + Valueable PenetratesTransport_DamageMultiplier; + Valueable MultiWeapon; ValueableVector MultiWeapon_IsSecondary; Valueable MultiWeapon_SelectCount; @@ -767,6 +772,11 @@ class TechnoTypeExt , AttackMove_StopWhenTargetAcquired { } , AttackMove_PursuitTarget { false } + , PenetratesTransport_Level {} + , PenetratesTransport_PassThroughMultiplier { 1.0 } + , PenetratesTransport_FatalRateMultiplier { 1.0 } + , PenetratesTransport_DamageMultiplier { 1.0 } + , MultiWeapon { false } , MultiWeapon_IsSecondary {} , MultiWeapon_SelectCount { 2 } diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index b3561616f7..579550dae8 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -299,6 +299,11 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) if (this->AffectsAbovePercent > this->AffectsBelowPercent) Debug::Log("[Developer warning][%s] AffectsAbovePercent is bigger than AffectsBelowPercent, the warhead will never activate!\n", pSection); + this->PenetratesTransport_Level.Read(exINI, pSection, "PenetratesTransport.Level"); + this->PenetratesTransport_PassThrough.Read(exINI, pSection, "PenetratesTransport.PassThrough"); + this->PenetratesTransport_FatalRate.Read(exINI, pSection, "PenetratesTransport.FatalRate"); + this->PenetratesTransport_DamageAll.Read(exINI, pSection, "PenetratesTransport.DamageAll"); + // Convert.From & Convert.To TypeConvertGroup::Parse(this->Convert_Pairs, exINI, pSection, AffectedHouse::All); @@ -354,6 +359,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) || this->AttachEffects.RemoveGroups.size() > 0 || this->BuildingSell || this->BuildingUndeploy + || this->PenetratesTransport_Level > 0 ); char tempBuffer[32]; @@ -526,6 +532,11 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->AffectsNeutral) .Process(this->HealthCheck) + .Process(this->PenetratesTransport_Level) + .Process(this->PenetratesTransport_PassThrough) + .Process(this->PenetratesTransport_FatalRate) + .Process(this->PenetratesTransport_DamageAll) + .Process(this->InflictLocomotor) .Process(this->RemoveInflictedLocomotor) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index fc2ae2a31f..cf38fa82d9 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -186,6 +186,11 @@ class WarheadTypeExt Valueable AffectsAbovePercent; Valueable AffectsNeutral; + Valueable PenetratesTransport_Level; + Valueable PenetratesTransport_PassThrough; + Valueable PenetratesTransport_FatalRate; + Valueable PenetratesTransport_DamageAll; + // Ares tags // http://ares-developers.github.io/Ares-docs/new/warheads/general.html Valueable AffectsEnemies; @@ -371,6 +376,11 @@ class WarheadTypeExt , AffectsAbovePercent { 0.0 } , AffectsNeutral { true } + , PenetratesTransport_Level { 0 } + , PenetratesTransport_PassThrough { 1.0 } + , PenetratesTransport_FatalRate { 0.0 } + , PenetratesTransport_DamageAll { false } + , AffectsEnemies { true } , AffectsOwner {} , EffectsRequireVerses { true } @@ -424,13 +434,14 @@ class WarheadTypeExt void InterceptBullets(TechnoClass* pOwner, BulletClass* pInterceptor, const CoordStruct& coords); DamageAreaResult DamageAreaWithTarget(const CoordStruct& coords, int damage, TechnoClass* pSource, WarheadTypeClass* pWH, bool affectsTiberium, HouseClass* pSourceHouse, TechnoClass* pTarget); private: - void DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner = nullptr, bool bulletWasIntercepted = false); + void DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, const CoordStruct& coords, int damage, TechnoClass* pOwner = nullptr, bool bulletWasIntercepted = false); void ApplyRemoveDisguise(HouseClass* pHouse, TechnoClass* pTarget); void ApplyRemoveMindControl(TechnoClass* pTarget); void ApplyCrit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* Owner); void ApplyShieldModifiers(TechnoClass* pTarget); void ApplyAttachEffects(TechnoClass* pTarget, HouseClass* pInvokerHouse, TechnoClass* pInvoker); void ApplyBuildingUndeploy(TechnoClass* pTarget); + void ApplyPenetratesTransport(TechnoClass* pTarget, TechnoClass* pInvoker, HouseClass* pInvokerHouse, const CoordStruct& coords, int damage); double GetCritChance(TechnoClass* pFirer) const; }; diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index a463728f22..73c4b1abee 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -161,33 +161,33 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, AnimExt::ExtMap.Find(pAnim)->SetInvoker(pOwner, pHouse); } + const int damage = pBullet ? pBullet->Health : 0; const bool bulletWasIntercepted = pBulletExt && (pBulletExt->InterceptedStatus & InterceptedStatus::Intercepted); - const float cellSpread = this->OwnerObject()->CellSpread; - if (cellSpread) + if (const float cellSpread = this->OwnerObject()->CellSpread) { - for (auto pTarget : Helpers::Alex::getCellSpreadItems(coords, cellSpread, true)) - this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted); + for (const auto pTarget : Helpers::Alex::getCellSpreadItems(coords, cellSpread, true)) + this->DetonateOnOneUnit(pHouse, pTarget, coords, damage, pOwner, bulletWasIntercepted); } else if (pBullet) { - if (auto pTarget = abstract_cast(pBullet->Target)) + if (const auto pTarget = abstract_cast(pBullet->Target)) { // Jun 2, 2024 - Starkku: We should only detonate on the target if the bullet, at the moment of detonation is within acceptable distance of the target. // Ares uses 64 leptons / quarter of a cell as a tolerance, so for sake of consistency we're gonna do the same here. if (pBullet->DistanceFrom(pTarget) < Unsorted::LeptonsPerCell / 4.0) - this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted); + this->DetonateOnOneUnit(pHouse, pTarget, coords, damage, pOwner, bulletWasIntercepted); } } else if (this->DamageAreaTarget) { if (coords.DistanceFrom(this->DamageAreaTarget->GetCoords()) < Unsorted::LeptonsPerCell / 4.0) - this->DetonateOnOneUnit(pHouse, this->DamageAreaTarget, pOwner, bulletWasIntercepted); + this->DetonateOnOneUnit(pHouse, this->DamageAreaTarget, coords, damage, pOwner, bulletWasIntercepted); } } } -void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner, bool bulletWasIntercepted) +void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, const CoordStruct& coords, int damage, TechnoClass* pOwner, bool bulletWasIntercepted) { if (!pTarget || pTarget->InLimbo || !pTarget->IsAlive || !pTarget->Health || pTarget->IsSinking || pTarget->BeingWarpedOut) return; @@ -215,6 +215,9 @@ void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* if (this->BuildingSell || this->BuildingUndeploy) this->ApplyBuildingUndeploy(pTarget); + if (this->PenetratesTransport_Level > 0 && damage) + this->ApplyPenetratesTransport(pTarget, pOwner, pHouse, coords, damage); + #ifdef LOCO_TEST_WARHEADS if (this->InflictLocomotor) this->ApplyLocomotorInfliction(pTarget); @@ -641,3 +644,111 @@ double WarheadTypeExt::ExtData::GetCritChance(TechnoClass* pFirer) const return critChance + extraChance; } + +void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, TechnoClass* pInvoker, HouseClass* pInvokerHouse, const CoordStruct& coords, int damage) +{ + auto& passengers = pTarget->Passengers; + auto passenger = passengers.GetFirstPassenger(); + + if (!passenger) + return; + + const auto pTargetType = pTarget->GetTechnoType(); + const auto pTargetTypeExt = TechnoTypeExt::ExtMap.Find(pTargetType); + + if (this->PenetratesTransport_Level <= pTargetTypeExt->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) + return; + + const double passThrough = this->PenetratesTransport_PassThrough * pTargetTypeExt->PenetratesTransport_PassThroughMultiplier; + + if (passThrough < 1.0 && ScenarioClass::Instance->Random.RandomDouble() > passThrough) + return; + + const double fatalRate = this->PenetratesTransport_FatalRate * pTargetTypeExt->PenetratesTransport_FatalRateMultiplier; + const bool fatal = fatalRate > 0.0 && ScenarioClass::Instance->Random.RandomDouble() <= fatalRate; + const auto pTargetFoot = abstract_cast(pTarget); + const int distance = static_cast(coords.DistanceFrom(pTarget->GetCoords())); + const auto pWH = this->OwnerObject(); + bool gunnerRemoved = false; + + if (this->PenetratesTransport_DamageAll) + { + bool isFirst = true; + + if (fatal) + { + while (passenger) + { + const auto nextPassenger = abstract_cast(passenger->NextObject); + passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse); + + if (isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } + + passenger = nextPassenger; + isFirst = false; + } + } + else + { + const int adjustedDamage = static_cast(std::ceil(damage * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); + + while (passenger) + { + const auto nextPassenger = abstract_cast(passenger->NextObject); + int damage = adjustedDamage; + const auto damageResult = passenger->ReceiveDamage(&damage, distance, pWH, pInvoker, false, true, pInvokerHouse); + + if (damageResult == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } + + passenger = nextPassenger; + isFirst = false; + } + } + } + else + { + int poorBastardIdx = ScenarioClass::Instance->Random(0, passengers.NumPassengers - 1); + const bool isFirst = poorBastardIdx == 0; + + while (poorBastardIdx > 0 && abstract_cast(passenger->NextObject)) + { + passenger = static_cast(passenger->NextObject); + --poorBastardIdx; + } + + if (fatal) + { + passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse); + + if (isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } + } + else + { + int adjustedDamage = static_cast(std::ceil(damage * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); + const auto damageResult = passenger->ReceiveDamage(&adjustedDamage, distance, pWH, pInvoker, false, true, pInvokerHouse); + + if (damageResult == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } + } + } + + passenger = passengers.GetFirstPassenger(); + + if (passenger && gunnerRemoved) + pTargetFoot->ReceiveGunner(passenger); +} From 7f4dc6497c4c49ee344b7d7918b6aae64403938e Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 12 Jul 2025 15:56:15 +0800 Subject: [PATCH 02/11] docs align --- docs/New-or-Enhanced-Logics.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 29e6358987..f1355b74f0 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2337,20 +2337,20 @@ RemoveParasite= ; boolean In `rulesmd.ini` ```ini -[SOMEWARHEAD] ; WarheadType -PenetratesTransport.Level=0 ; integer -PenetratesTransport.PassThrough=1.0 ; double -PenetratesTransport.FatalRate=0.0 ; double -PenetratesTransport.DamageAll=false ; boolean - -[SOMETECHNO] ; TechnoType -PenetratesTransport.Level= ; integer +[SOMEWARHEAD] ; WarheadType +PenetratesTransport.Level=0 ; integer +PenetratesTransport.PassThrough=1.0 ; double +PenetratesTransport.FatalRate=0.0 ; double +PenetratesTransport.DamageAll=false ; boolean + +[SOMETECHNO] ; TechnoType +PenetratesTransport.Level= ; integer PenetratesTransport.PassThroughMultiplier=1.0 ; double -PenetratesTransport.FatalRateMultiplier=1.0 ; double -PenetratesTransport.DamageMultiplier=1.0 ; double +PenetratesTransport.FatalRateMultiplier=1.0 ; double +PenetratesTransport.DamageMultiplier=1.0 ; double [CombatDamage] -PenetratesTransport.Level=10 ; integer, default value of technotype's penetrate level +PenetratesTransport.Level=10 ; integer, default value of technotype's penetrate level ``` ### Remove disguise on impact From 0b8d25ff7bccec2a61d95b457b3c33abba9393d4 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 12 Jul 2025 15:59:13 +0800 Subject: [PATCH 03/11] update --- docs/New-or-Enhanced-Logics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index f1355b74f0..7db37c0d42 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2329,7 +2329,7 @@ RemoveParasite= ; boolean ### Penetrates damage on transporter - Warheads can now damage passenger on impact. - - If `PenetratesTransport.Level` of warhead larger than `PenetratesTransport.Level` of target, it will enable penetrates damage logic on this impact. + - If `PenetratesTransport.Level` of warhead larger than `PenetratesTransport.Level` of target, it will enable penetrates damage logic on target. - `PenetratesTransport.PassThrough` is the chance of penetration, actual chance will multiply by `PenetratesTransport.PassThroughMultiplier` of target. - `PenetratesTransport.FatalRate` is the chance of one hit kill, actual change will multiply by `PenetratesTransport.FatalRateMultiplier` of target. - `PenetratesTransport.DamageAll` control whether it will damage all passengers or random one passenger in transport. From 16d5b32bcdce0f6690a78949e17d7b8c063a42d8 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 12 Jul 2025 16:53:23 +0800 Subject: [PATCH 04/11] update --- docs/New-or-Enhanced-Logics.md | 3 +++ src/Ext/WarheadType/Body.cpp | 4 ++++ src/Ext/WarheadType/Body.h | 4 ++++ src/Ext/WarheadType/Detonate.cpp | 18 ++++++++++++++---- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 7db37c0d42..dac52a7ae6 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2334,6 +2334,7 @@ RemoveParasite= ; boolean - `PenetratesTransport.FatalRate` is the chance of one hit kill, actual change will multiply by `PenetratesTransport.FatalRateMultiplier` of target. - `PenetratesTransport.DamageAll` control whether it will damage all passengers or random one passenger in transport. - `PenetratesTransport.DamageMultiplier` is multiplier of damage on passenger. + - `PenetratesTransport.CleanSound` will play when all passengers has been killed. In `rulesmd.ini` ```ini @@ -2341,7 +2342,9 @@ In `rulesmd.ini` PenetratesTransport.Level=0 ; integer PenetratesTransport.PassThrough=1.0 ; double PenetratesTransport.FatalRate=0.0 ; double +PenetratesTransport.DamageMultiplier=1.0 ; double PenetratesTransport.DamageAll=false ; boolean +PenetratesTransport.CleanSound= ; sound entry [SOMETECHNO] ; TechnoType PenetratesTransport.Level= ; integer diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 579550dae8..f3f7290582 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -302,7 +302,9 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->PenetratesTransport_Level.Read(exINI, pSection, "PenetratesTransport.Level"); this->PenetratesTransport_PassThrough.Read(exINI, pSection, "PenetratesTransport.PassThrough"); this->PenetratesTransport_FatalRate.Read(exINI, pSection, "PenetratesTransport.FatalRate"); + this->PenetratesTransport_DamageMultiplier.Read(exINI, pSection, "PenetratesTransport.DamageMultiplier"); this->PenetratesTransport_DamageAll.Read(exINI, pSection, "PenetratesTransport.DamageAll"); + this->PenetratesTransport_CleanSound.Read(exINI, pSection, "PenetratesTransport.CleanSound"); // Convert.From & Convert.To TypeConvertGroup::Parse(this->Convert_Pairs, exINI, pSection, AffectedHouse::All); @@ -535,7 +537,9 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->PenetratesTransport_Level) .Process(this->PenetratesTransport_PassThrough) .Process(this->PenetratesTransport_FatalRate) + .Process(this->PenetratesTransport_DamageMultiplier) .Process(this->PenetratesTransport_DamageAll) + .Process(this->PenetratesTransport_CleanSound) .Process(this->InflictLocomotor) .Process(this->RemoveInflictedLocomotor) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index cf38fa82d9..cade8a2ca8 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -189,7 +189,9 @@ class WarheadTypeExt Valueable PenetratesTransport_Level; Valueable PenetratesTransport_PassThrough; Valueable PenetratesTransport_FatalRate; + Valueable PenetratesTransport_DamageMultiplier; Valueable PenetratesTransport_DamageAll; + ValueableIdx PenetratesTransport_CleanSound; // Ares tags // http://ares-developers.github.io/Ares-docs/new/warheads/general.html @@ -379,7 +381,9 @@ class WarheadTypeExt , PenetratesTransport_Level { 0 } , PenetratesTransport_PassThrough { 1.0 } , PenetratesTransport_FatalRate { 0.0 } + , PenetratesTransport_DamageMultiplier { 1.0 } , PenetratesTransport_DamageAll { false } + , PenetratesTransport_CleanSound { -1 } , AffectsEnemies { true } , AffectsOwner {} diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 73c4b1abee..4f2fccc45c 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -694,7 +694,7 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec } else { - const int adjustedDamage = static_cast(std::ceil(damage * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); + const int adjustedDamage = static_cast(std::ceil(damage * this->PenetratesTransport_DamageMultiplier * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); while (passenger) { @@ -736,7 +736,7 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec } else { - int adjustedDamage = static_cast(std::ceil(damage * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); + int adjustedDamage = static_cast(std::ceil(damage * this->PenetratesTransport_DamageMultiplier * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); const auto damageResult = passenger->ReceiveDamage(&adjustedDamage, distance, pWH, pInvoker, false, true, pInvokerHouse); if (damageResult == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) @@ -749,6 +749,16 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec passenger = passengers.GetFirstPassenger(); - if (passenger && gunnerRemoved) - pTargetFoot->ReceiveGunner(passenger); + if (passenger) + { + if (gunnerRemoved) + pTargetFoot->ReceiveGunner(passenger); + } + else + { + const int cleanSound = this->PenetratesTransport_CleanSound; + + if (cleanSound != -1) + VocClass::PlayAt(cleanSound, coords); + } } From 1745d24a8bfac3db2ceaf12f23010f4d38df3cb4 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 12 Jul 2025 17:50:08 +0800 Subject: [PATCH 05/11] update --- docs/New-or-Enhanced-Logics.md | 4 ++-- src/Ext/WarheadType/Detonate.cpp | 33 ++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index dac52a7ae6..0df59dbedc 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2329,9 +2329,9 @@ RemoveParasite= ; boolean ### Penetrates damage on transporter - Warheads can now damage passenger on impact. - - If `PenetratesTransport.Level` of warhead larger than `PenetratesTransport.Level` of target, it will enable penetrates damage logic on target. + - If `PenetratesTransport.Level` of warhead larger than `PenetratesTransport.Level` of target and it's passengers, it will enable penetrates damage logic on target. - `PenetratesTransport.PassThrough` is the chance of penetration, actual chance will multiply by `PenetratesTransport.PassThroughMultiplier` of target. - - `PenetratesTransport.FatalRate` is the chance of one hit kill, actual change will multiply by `PenetratesTransport.FatalRateMultiplier` of target. + - `PenetratesTransport.FatalRate` is the chance of one hit kill passenger, actual change will multiply by `PenetratesTransport.FatalRateMultiplier` of target. - `PenetratesTransport.DamageAll` control whether it will damage all passengers or random one passenger in transport. - `PenetratesTransport.DamageMultiplier` is multiplier of damage on passenger. - `PenetratesTransport.CleanSound` will play when all passengers has been killed. diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 4f2fccc45c..5f2c482aff 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -680,12 +680,14 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec while (passenger) { const auto nextPassenger = abstract_cast(passenger->NextObject); - passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse); - if (isFirst && pTargetType->Gunner && pTargetFoot) + if (this->PenetratesTransport_Level > TechnoTypeExt::ExtMap.Find(passenger->GetTechnoType())->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) { - pTargetFoot->RemoveGunner(passenger); - gunnerRemoved = true; + if (passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } } passenger = nextPassenger; @@ -699,13 +701,16 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec while (passenger) { const auto nextPassenger = abstract_cast(passenger->NextObject); - int damage = adjustedDamage; - const auto damageResult = passenger->ReceiveDamage(&damage, distance, pWH, pInvoker, false, true, pInvokerHouse); - if (damageResult == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + if (this->PenetratesTransport_Level > TechnoTypeExt::ExtMap.Find(passenger->GetTechnoType())->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) { - pTargetFoot->RemoveGunner(passenger); - gunnerRemoved = true; + int applyDamage = adjustedDamage; + + if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } } passenger = nextPassenger; @@ -724,11 +729,12 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec --poorBastardIdx; } + if (this->PenetratesTransport_Level <= TechnoTypeExt::ExtMap.Find(passenger->GetTechnoType())->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) + return; + if (fatal) { - passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse); - - if (isFirst && pTargetType->Gunner && pTargetFoot) + if (passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) { pTargetFoot->RemoveGunner(passenger); gunnerRemoved = true; @@ -737,9 +743,8 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec else { int adjustedDamage = static_cast(std::ceil(damage * this->PenetratesTransport_DamageMultiplier * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); - const auto damageResult = passenger->ReceiveDamage(&adjustedDamage, distance, pWH, pInvoker, false, true, pInvokerHouse); - if (damageResult == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + if (passenger->ReceiveDamage(&adjustedDamage, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) { pTargetFoot->RemoveGunner(passenger); gunnerRemoved = true; From a5e4be164cb3130a36ca67965bb0bc91ca3a7361 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 12 Jul 2025 17:52:18 +0800 Subject: [PATCH 06/11] update doc --- docs/New-or-Enhanced-Logics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 0df59dbedc..99c4422172 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2329,7 +2329,7 @@ RemoveParasite= ; boolean ### Penetrates damage on transporter - Warheads can now damage passenger on impact. - - If `PenetratesTransport.Level` of warhead larger than `PenetratesTransport.Level` of target and it's passengers, it will enable penetrates damage logic on target. + - If `PenetratesTransport.Level` of warhead larger than `PenetratesTransport.Level` of target and it's passengers, it will enable penetrates damage logic on passenger. - `PenetratesTransport.PassThrough` is the chance of penetration, actual chance will multiply by `PenetratesTransport.PassThroughMultiplier` of target. - `PenetratesTransport.FatalRate` is the chance of one hit kill passenger, actual change will multiply by `PenetratesTransport.FatalRateMultiplier` of target. - `PenetratesTransport.DamageAll` control whether it will damage all passengers or random one passenger in transport. From 52585e5820dda9323ba5165b12827de5f0c34c15 Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sat, 9 Aug 2025 19:51:04 +0800 Subject: [PATCH 07/11] update --- src/Ext/Techno/Hooks.ReceiveDamage.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Ext/Techno/Hooks.ReceiveDamage.cpp b/src/Ext/Techno/Hooks.ReceiveDamage.cpp index 66a06fe8a6..954e9058d6 100644 --- a/src/Ext/Techno/Hooks.ReceiveDamage.cpp +++ b/src/Ext/Techno/Hooks.ReceiveDamage.cpp @@ -234,6 +234,15 @@ DEFINE_HOOK(0x702672, TechnoClass_ReceiveDamage_RevengeWeapon, 0x5) return 0; } +DEFINE_HOOK(0x518434, InfantryClass_ReceiveDamage_SkipDeathAnim, 0x7) +{ + enum { SkipDeathAnim = 0x5185F1 }; + + GET(InfantryClass*, pThis, ESI); + + return pThis->Transporter ? SkipDeathAnim : 0; +} + // Issue #237 NotHuman additional animations support // Author: Otamaa DEFINE_HOOK(0x518505, InfantryClass_ReceiveDamage_NotHuman, 0x4) @@ -393,3 +402,16 @@ DEFINE_HOOK(0x701E18, TechnoClass_ReceiveDamage_ReflectDamage, 0x7) return 0; } + +DEFINE_HOOK(0x737E6E, UnitClass_ReceiveDamage_SkipExplode, 0xA) +{ + enum { ContinueCheck = 0x737E78, SkipExplode = 0x737F74 }; + + GET(UnitClass*, pThis, ESI); + + if (pThis->Transporter) + return SkipExplode; + + R->EAX(pThis->GetHeight()); + return ContinueCheck; +} From 33724f94af62618e29796e3b7125f8e9436120ba Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sun, 10 Aug 2025 00:34:00 +0800 Subject: [PATCH 08/11] update --- src/Ext/WarheadType/Detonate.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index daff31e846..63c9dd085d 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -676,7 +676,8 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec const double fatalRate = this->PenetratesTransport_FatalRate * pTargetTypeExt->PenetratesTransport_FatalRateMultiplier; const bool fatal = fatalRate > 0.0 && ScenarioClass::Instance->Random.RandomDouble() <= fatalRate; const auto pTargetFoot = abstract_cast(pTarget); - const int distance = static_cast(coords.DistanceFrom(pTarget->GetCoords())); + const auto transporterCoords = pTarget->GetCoords(); + const int distance = static_cast(coords.DistanceFrom(transporterCoords)); const auto pWH = this->OwnerObject(); bool gunnerRemoved = false; @@ -692,6 +693,8 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec if (this->PenetratesTransport_Level > TechnoTypeExt::ExtMap.Find(passenger->GetTechnoType())->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) { + passenger->SetLocation(transporterCoords); + if (passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) { pTargetFoot->RemoveGunner(passenger); @@ -713,6 +716,7 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec if (this->PenetratesTransport_Level > TechnoTypeExt::ExtMap.Find(passenger->GetTechnoType())->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) { + passenger->SetLocation(transporterCoords); int applyDamage = adjustedDamage; if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) @@ -741,6 +745,8 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec if (this->PenetratesTransport_Level <= TechnoTypeExt::ExtMap.Find(passenger->GetTechnoType())->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) return; + passenger->SetLocation(transporterCoords); + if (fatal) { if (passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) @@ -773,6 +779,6 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec const int cleanSound = this->PenetratesTransport_CleanSound; if (cleanSound != -1) - VocClass::PlayAt(cleanSound, coords); + VocClass::PlayAt(cleanSound, transporterCoords); } } From bfff6fdd95b441fc34f7b2f0703e01505f27260b Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sun, 10 Aug 2025 10:39:34 +0800 Subject: [PATCH 09/11] prevent debris and damaged particle --- src/Ext/Techno/Hooks.ReceiveDamage.cpp | 12 ++++++++++++ src/Misc/Hooks.BugFixes.cpp | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/Ext/Techno/Hooks.ReceiveDamage.cpp b/src/Ext/Techno/Hooks.ReceiveDamage.cpp index 954e9058d6..38e9ab8f7f 100644 --- a/src/Ext/Techno/Hooks.ReceiveDamage.cpp +++ b/src/Ext/Techno/Hooks.ReceiveDamage.cpp @@ -403,6 +403,18 @@ DEFINE_HOOK(0x701E18, TechnoClass_ReceiveDamage_ReflectDamage, 0x7) return 0; } +DEFINE_HOOK(0x702823, TechnoClass_ReceiveDamage_SkipDamagedParticle, 0x7) +{ + enum { SkipParticle = 0x702A25, RemoveParticle = 0x70283C, SpawnParticle = 0x702857 }; + + GET(TechnoClass*, pThis, ESI); + + if (pThis->Transporter) + return SkipParticle; + + return pThis->GetHealthPercentage() <= RulesClass::Instance->ConditionYellow ? SpawnParticle : RemoveParticle; +} + DEFINE_HOOK(0x737E6E, UnitClass_ReceiveDamage_SkipExplode, 0xA) { enum { ContinueCheck = 0x737E78, SkipExplode = 0x737F74 }; diff --git a/src/Misc/Hooks.BugFixes.cpp b/src/Misc/Hooks.BugFixes.cpp index 60028df29a..3e98398ab3 100644 --- a/src/Misc/Hooks.BugFixes.cpp +++ b/src/Misc/Hooks.BugFixes.cpp @@ -128,6 +128,9 @@ DEFINE_HOOK(0x702299, TechnoClass_ReceiveDamage_Debris, 0xA) GET(TechnoClass* const, pThis, ESI); + if (pThis->Transporter) + return SkipGameCode; + const auto pType = pThis->GetTechnoType(); // Fix the debris count to be in range of Min, Max instead of Min, Max-1. From f2029469871457e0518fe866ef45d299a5af03ea Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sun, 10 Aug 2025 22:40:39 +0800 Subject: [PATCH 10/11] try to fix fatal rate --- src/Ext/WarheadType/Detonate.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 63c9dd085d..fe7880c110 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -690,12 +690,14 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec while (passenger) { const auto nextPassenger = abstract_cast(passenger->NextObject); + const auto passengerType = passenger->GetTechnoType(); - if (this->PenetratesTransport_Level > TechnoTypeExt::ExtMap.Find(passenger->GetTechnoType())->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) + if (this->PenetratesTransport_Level > TechnoTypeExt::ExtMap.Find(passengerType)->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) { passenger->SetLocation(transporterCoords); + int applyDamage = passengerType->Strength; - if (passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) { pTargetFoot->RemoveGunner(passenger); gunnerRemoved = true; @@ -742,14 +744,18 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec --poorBastardIdx; } - if (this->PenetratesTransport_Level <= TechnoTypeExt::ExtMap.Find(passenger->GetTechnoType())->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) + const auto passengerType = passenger->GetTechnoType(); + + if (this->PenetratesTransport_Level <= TechnoTypeExt::ExtMap.Find(passengerType)->PenetratesTransport_Level.Get(RulesExt::Global()->PenetratesTransport_Level)) return; passenger->SetLocation(transporterCoords); if (fatal) { - if (passenger->ReceiveDamage(&passenger->Health, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + int applyDamage = passengerType->Strength; + + if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) { pTargetFoot->RemoveGunner(passenger); gunnerRemoved = true; From c45250604f23acc66bc7329762552227723be1dd Mon Sep 17 00:00:00 2001 From: NetsuNegi39 Date: Sun, 10 Aug 2025 23:26:50 +0800 Subject: [PATCH 11/11] update --- src/Ext/WarheadType/Detonate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index fe7880c110..9aa41545bc 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -697,7 +697,7 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec passenger->SetLocation(transporterCoords); int applyDamage = passengerType->Strength; - if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, true, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) { pTargetFoot->RemoveGunner(passenger); gunnerRemoved = true; @@ -755,7 +755,7 @@ void WarheadTypeExt::ExtData::ApplyPenetratesTransport(TechnoClass* pTarget, Tec { int applyDamage = passengerType->Strength; - if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, true, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) { pTargetFoot->RemoveGunner(passenger); gunnerRemoved = true;