diff --git a/CREDITS.md b/CREDITS.md index 41f07e59b0..2f2f9830f8 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -437,6 +437,7 @@ This page lists all the individual contributions to the project by their author. - Fix the bug that Locomotor warhead won't stop working when firer (except for vehicle) stop firing - Fix the bug that hover vehicle will sink if destroyed on bridge - Customize squid grapple animation + - 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 0ed79088c9..651d846563 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2366,6 +2366,36 @@ 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 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. + - `PenetratesTransport.DamageMultiplier` is multiplier of damage on passenger. + - `PenetratesTransport.CleanSound` will play when all passengers has been killed. + +In `rulesmd.ini` +```ini +[SOMEWARHEAD] ; WarheadType +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 +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 494f81dde2..4808867dd9 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -428,6 +428,7 @@ New: - [Units can customize the attack voice that plays when using more weapons](New-or-Enhanced-Logics.md#multi-voiceattack) (by FlyStar) - Customize squid grapple animation (by NetsuNegi) - [Auto deploy for GI-like infantry](Fixed-or-Improved-Logics.md#auto-deploy-for-gi-like-infantry) (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 6ce4e6d426..512f083cb9 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -289,6 +289,8 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->AttackMove_StopWhenTargetAcquired.Read(exINI, GameStrings::General, "AttackMove.StopWhenTargetAcquired"); this->Parasite_GrappleAnim.Read(exINI, GameStrings::AudioVisual, "Parasite.GrappleAnim"); + + this->PenetratesTransport_Level.Read(exINI, GameStrings::CombatDamage, "PenetratesTransport.Level"); this->AINormalTargetingDelay.Read(exINI, GameStrings::General, "AINormalTargetingDelay"); this->PlayerNormalTargetingDelay.Read(exINI, GameStrings::General, "PlayerNormalTargetingDelay"); @@ -554,6 +556,7 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->AttackMove_StopWhenTargetAcquired) .Process(this->Parasite_GrappleAnim) .Process(this->InfantryAutoDeploy) + .Process(this->PenetratesTransport_Level) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index bef203036e..ce18a96f5c 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -246,6 +246,8 @@ class RulesExt Nullable AttackMove_StopWhenTargetAcquired; NullableIdx Parasite_GrappleAnim; + + Valueable PenetratesTransport_Level; // cache tint color int TintColorIronCurtain; @@ -449,7 +451,10 @@ class RulesExt , AttackMove_StopWhenTargetAcquired { } , Parasite_GrappleAnim {} + , InfantryAutoDeploy { false } + + , PenetratesTransport_Level { 10 } { } virtual ~ExtData() = default; diff --git a/src/Ext/Techno/Hooks.ReceiveDamage.cpp b/src/Ext/Techno/Hooks.ReceiveDamage.cpp index 66a06fe8a6..38e9ab8f7f 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,28 @@ 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 }; + + GET(UnitClass*, pThis, ESI); + + if (pThis->Transporter) + return SkipExplode; + + R->EAX(pThis->GetHeight()); + return ContinueCheck; +} diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index f32b4669f9..34e930bea9 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -955,7 +955,12 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->AttackMove_StopWhenTargetAcquired.Read(exINI, pSection, "AttackMove.StopWhenTargetAcquired"); this->AttackMove_PursuitTarget.Read(exINI, pSection, "AttackMove.PursuitTarget"); - this->InfantryAutoDeploy.Read(exINI, pSection, "InfantryAutoDeploy"); + this->InfantryAutoDeploy.Read(exINI, pSection, "InfantryAutoDeploy"); + + 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"); @@ -1580,6 +1585,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 75d46d3169..a8ea0e7657 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -407,6 +407,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; @@ -775,6 +780,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 5c0adbd0ef..2c9bd4aaf5 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -301,6 +301,13 @@ 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_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); @@ -356,6 +363,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) || this->AttachEffects.RemoveGroups.size() > 0 || this->BuildingSell || this->BuildingUndeploy + || this->PenetratesTransport_Level > 0 ); char tempBuffer[32]; @@ -528,6 +536,13 @@ 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_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 9c37b3c875..fefbe8619b 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -187,6 +187,13 @@ class WarheadTypeExt Valueable AffectsAbovePercent; Valueable AffectsNeutral; + 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 Valueable AffectsEnemies; @@ -373,6 +380,13 @@ class WarheadTypeExt , AffectsAbovePercent { 0.0 } , AffectsNeutral { true } + , PenetratesTransport_Level { 0 } + , PenetratesTransport_PassThrough { 1.0 } + , PenetratesTransport_FatalRate { 0.0 } + , PenetratesTransport_DamageMultiplier { 1.0 } + , PenetratesTransport_DamageAll { false } + , PenetratesTransport_CleanSound { -1 } + , AffectsEnemies { true } , AffectsOwner {} , EffectsRequireVerses { true } @@ -426,13 +440,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 db76b2ab08..9aa41545bc 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 const 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 const 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); @@ -650,3 +653,138 @@ 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 auto transporterCoords = pTarget->GetCoords(); + const int distance = static_cast(coords.DistanceFrom(transporterCoords)); + 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); + const auto passengerType = passenger->GetTechnoType(); + + 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(&applyDamage, distance, pWH, pInvoker, true, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } + } + + passenger = nextPassenger; + isFirst = false; + } + } + else + { + const int adjustedDamage = static_cast(std::ceil(damage * this->PenetratesTransport_DamageMultiplier * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); + + while (passenger) + { + const auto nextPassenger = abstract_cast(passenger->NextObject); + + 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) + { + 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; + } + + 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) + { + int applyDamage = passengerType->Strength; + + if (passenger->ReceiveDamage(&applyDamage, distance, pWH, pInvoker, true, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } + } + else + { + int adjustedDamage = static_cast(std::ceil(damage * this->PenetratesTransport_DamageMultiplier * pTargetTypeExt->PenetratesTransport_DamageMultiplier)); + + if (passenger->ReceiveDamage(&adjustedDamage, distance, pWH, pInvoker, false, true, pInvokerHouse) == DamageState::NowDead && isFirst && pTargetType->Gunner && pTargetFoot) + { + pTargetFoot->RemoveGunner(passenger); + gunnerRemoved = true; + } + } + } + + passenger = passengers.GetFirstPassenger(); + + if (passenger) + { + if (gunnerRemoved) + pTargetFoot->ReceiveGunner(passenger); + } + else + { + const int cleanSound = this->PenetratesTransport_CleanSound; + + if (cleanSound != -1) + VocClass::PlayAt(cleanSound, transporterCoords); + } +} 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.