From b8ea7df8c64e0f9ee617f43569aae06b923a8688 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 28 Oct 2024 12:26:15 +0100 Subject: [PATCH 01/10] Initial commit - Warheads can now modify ammo of the affected objects. In rulesmd.ini: [SOMEWARHEAD] ; Warhead AmmoModifier=0 ; integer --- CREDITS.md | 1 + docs/New-or-Enhanced-Logics.md | 10 ++++++++++ docs/Whats-New.md | 1 + src/Ext/WarheadType/Body.cpp | 5 +++++ src/Ext/WarheadType/Body.h | 5 +++++ src/Ext/WarheadType/Detonate.cpp | 29 +++++++++++++++++++++++++++++ 6 files changed, 51 insertions(+) diff --git a/CREDITS.md b/CREDITS.md index 84e88ce0fb..0d1f8f6ea7 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -134,6 +134,7 @@ This page lists all the individual contributions to the project by their author. - Customizable FLH when infantry is prone or deployed - Initial strength for cloned infantry - Map Events 604 & 605 for checking if a specific Techno enters in a cell + - Modify Ammo on impact - **Starkku**: - Misc. minor bugfixes & improvements - AI script actions: diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 54b7b58d3c..d9ce4fc56a 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -1579,6 +1579,16 @@ LaunchSW.DisplayMoney.Houses=all ; Affected House Enumeration (none|owner/self| LaunchSW.DisplayMoney.Offset=0,0 ; X,Y, pixels relative to default ``` +### Modify Ammo on impact + +- Warheads can now modify ammo of the affected objects. + +In `rulesmd.ini`: +```ini +[SOMEWARHEAD] ; Warhead +AmmoModifier=0 ; integer +``` + ### Parasite removal - By default if unit takes negative damage from a Warhead (before `Verses` are calculated), any parasites infecting it are removed and deleted. This behaviour can now be customized to disable the removal for negative damage, or enable it for any arbitrary warhead. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index a0265a6137..c23bebba25 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -466,6 +466,7 @@ New: - `Scorch` / `Flamer` fire animation customization (by Starkku) - Warheads parasite removal customization (by Starkku) - Allow infantry to use land sequences in water (by Starkku) +- Modify Ammo on impact (by FS-21) Vanilla fixes: - Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy) diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 5a5e2febef..e868969c8b 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -318,6 +318,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) || this->AttachEffects.AttachTypes.size() > 0 || this->AttachEffects.RemoveTypes.size() > 0 || this->AttachEffects.RemoveGroups.size() > 0 + || this->AmmoModifier ); char tempBuffer[32]; @@ -357,6 +358,8 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) else this->SpawnsCrate_Weights.push_back(weight); } + + this->AmmoModifier.Read(exINI, pSection, "AmmoModifier"); } template @@ -499,6 +502,8 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->PossibleCellSpreadDetonate) .Process(this->Reflected) .Process(this->DamageAreaTarget) + + .Process(this->AmmoModifier) ; } diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index b5331a9ada..9b69b444f9 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -167,6 +167,8 @@ class WarheadTypeExt bool PossibleCellSpreadDetonate; TechnoClass* DamageAreaTarget; + Valueable AmmoModifier; + private: Valueable Shield_Respawn_Rate_InMinutes; Valueable Shield_SelfHealing_Rate_InMinutes; @@ -316,6 +318,8 @@ class WarheadTypeExt , RemainingAnimCreationInterval { 0 } , PossibleCellSpreadDetonate { false } , DamageAreaTarget {} + + , AmmoModifier { 0 } { } void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget); @@ -350,6 +354,7 @@ class WarheadTypeExt void ApplyShieldModifiers(TechnoClass* pTarget, TechnoExt::ExtData* pTargetExt); void ApplyAttachEffects(TechnoClass* pTarget, HouseClass* pInvokerHouse, TechnoClass* pInvoker); double GetCritChance(TechnoClass* pFirer) const; + void ApplyAmmoModifier(TechnoClass* pTarget, HouseClass* pInvokerHouse, BulletExt::ExtData* pBulletExt = nullptr); }; class ExtContainer final : public Container diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index b0884359ce..55de9b66f3 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -164,6 +165,9 @@ void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* if (this->Crit_CurrentChance > 0.0 && (!this->Crit_SuppressWhenIntercepted || !bulletWasIntercepted)) this->ApplyCrit(pHouse, pTarget, pOwner, pTargetExt); + if (this->AmmoModifier != 0) + ApplyAmmoModifier(pTarget, pHouse, pBulletExt); + if (this->Convert_Pairs.size() > 0) this->ApplyConvert(pHouse, pTarget); @@ -501,3 +505,28 @@ double WarheadTypeExt::ExtData::GetCritChance(TechnoClass* pFirer) const return critChance + extraChance; } + +void WarheadTypeExt::ExtData::ApplyAmmoModifier(TechnoClass* pTarget, HouseClass* pInvokerHouse, BulletExt::ExtData* pBulletExt) +{ + if (!pTarget) + return; + + auto const pWeapon = pBulletExt ? pBulletExt->OwnerObject()->WeaponType : nullptr; + + if (pWeapon) + { + auto const pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon); + + if (!EnumFunctions::IsTechnoEligible(pTarget, pWeaponExt->CanTarget) + || (pInvokerHouse && !EnumFunctions::CanTargetHouse(pWeaponExt->CanTargetHouses, pInvokerHouse, pTarget->Owner))) + { + return; + } + } + + int maxAmmo = pTarget->GetTechnoType()->Ammo; + int newCurrentAmmo = this->AmmoModifier + pTarget->Ammo; + + newCurrentAmmo = newCurrentAmmo < 0 ? 0 : newCurrentAmmo; + pTarget->Ammo = newCurrentAmmo > maxAmmo ? maxAmmo : newCurrentAmmo; +} From 8a1b4b1e3b8d118b9aa2cd7b5a57dcc4f2cafa90 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 28 Oct 2024 23:16:00 +0100 Subject: [PATCH 02/10] Add missing code --- src/Ext/WarheadType/Body.h | 2 +- src/Ext/WarheadType/Detonate.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index 9b69b444f9..8be228f7fd 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -347,7 +347,7 @@ class WarheadTypeExt void InterceptBullets(TechnoClass* pOwner, WeaponTypeClass* pWeapon, 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, TechnoClass* pOwner = nullptr, bool bulletWasIntercepted = false, BulletExt::ExtData* pBulletExt = nullptr); void ApplyRemoveDisguise(HouseClass* pHouse, TechnoClass* pTarget); void ApplyRemoveMindControl(TechnoClass* pTarget); void ApplyCrit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* Owner, TechnoExt::ExtData* pTargetExt); diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 55de9b66f3..552ffff1d5 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -124,7 +124,7 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, if (cellSpread) { for (auto pTarget : Helpers::Alex::getCellSpreadItems(coords, cellSpread, true)) - this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted); + this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted, pBulletExt); } else if (pBullet) { @@ -133,7 +133,7 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, // 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) - this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted); + this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted, pBulletExt); } } else if (this->DamageAreaTarget) @@ -144,7 +144,7 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, } } -void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner, bool bulletWasIntercepted) +void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner, bool bulletWasIntercepted, BulletExt::ExtData* pBulletExt) { if (!pTarget || pTarget->InLimbo || !pTarget->IsAlive || !pTarget->Health || pTarget->IsSinking) return; From 97bdd8692f3f13a8ee2ebf8843a10e2cb1021546 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Fri, 30 May 2025 11:03:44 +0200 Subject: [PATCH 03/10] Applied feedback --- src/Ext/WarheadType/Detonate.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 47c48ba70d..86341446fd 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -656,22 +656,6 @@ double WarheadTypeExt::ExtData::GetCritChance(TechnoClass* pFirer) const void WarheadTypeExt::ExtData::ApplyAmmoModifier(TechnoClass* pTarget, HouseClass* pInvokerHouse, BulletExt::ExtData* pBulletExt) { - if (!pTarget) - return; - - auto const pWeapon = pBulletExt ? pBulletExt->OwnerObject()->WeaponType : nullptr; - - if (pWeapon) - { - auto const pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon); - - if (!EnumFunctions::IsTechnoEligible(pTarget, pWeaponExt->CanTarget) - || (pInvokerHouse && !EnumFunctions::CanTargetHouse(pWeaponExt->CanTargetHouses, pInvokerHouse, pTarget->Owner))) - { - return; - } - } - int maxAmmo = pTarget->GetTechnoType()->Ammo; int newCurrentAmmo = this->AmmoModifier + pTarget->Ammo; From 54cba0dc3c789d0b01c08b923a54f7db646b7992 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Sun, 6 Jul 2025 17:37:18 +0200 Subject: [PATCH 04/10] Applied feedback Made requested changes: - Removed obsolete code not used anymore. - Renamed tag from AmmoModifier to Ammo --- YRpp | 2 +- src/Ext/WarheadType/Body.cpp | 6 +++--- src/Ext/WarheadType/Body.h | 8 ++++---- src/Ext/WarheadType/Detonate.cpp | 15 +++++++-------- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/YRpp b/YRpp index 4ce57fba70..3e4db25bb7 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 4ce57fba70936c8fbda1d7eeafc53298174615a2 +Subproject commit 3e4db25bb775d44ec896392bcded614628452c2d diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 56ae9aaa92..cf3a6e8560 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -329,7 +329,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) || this->AttachEffects.RemoveGroups.size() > 0 || this->BuildingSell || this->BuildingUndeploy - || this->AmmoModifier + || this->Ammo ); char tempBuffer[32]; @@ -370,7 +370,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->SpawnsCrate_Weights.push_back(weight); } - this->AmmoModifier.Read(exINI, pSection, "AmmoModifier"); + this->Ammo.Read(exINI, pSection, "Ammo"); } template @@ -544,7 +544,7 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->CanKill) - .Process(this->AmmoModifier) + .Process(this->Ammo) ; } diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index 6a8bb9f851..a3eaf99e1b 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -197,7 +197,7 @@ class WarheadTypeExt Valueable CanKill; - Valueable AmmoModifier; + Valueable Ammo; private: Valueable Shield_Respawn_Rate_InMinutes; @@ -379,7 +379,7 @@ class WarheadTypeExt , KillWeapon_Affects { AffectedTarget::All } , KillWeapon_OnFirer_Affects { AffectedTarget::All } - , AmmoModifier { 0 } + , Ammo { 0 } { } void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget); @@ -407,7 +407,7 @@ class WarheadTypeExt void InterceptBullets(TechnoClass* pOwner, WeaponTypeClass* pWeapon, 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, BulletExt::ExtData* pBulletExt = nullptr); + void DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner = nullptr, bool bulletWasIntercepted = false); void ApplyRemoveDisguise(HouseClass* pHouse, TechnoClass* pTarget); void ApplyRemoveMindControl(TechnoClass* pTarget); void ApplyCrit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* Owner); @@ -415,7 +415,7 @@ class WarheadTypeExt void ApplyAttachEffects(TechnoClass* pTarget, HouseClass* pInvokerHouse, TechnoClass* pInvoker); void ApplyBuildingUndeploy(TechnoClass* pTarget); double GetCritChance(TechnoClass* pFirer) const; - void ApplyAmmoModifier(TechnoClass* pTarget, HouseClass* pInvokerHouse, BulletExt::ExtData* pBulletExt = nullptr); + void ApplyAmmoModifier(TechnoClass* pTarget); }; class ExtContainer final : public Container diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 5eb04594fd..e2f7bfa253 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -173,7 +172,7 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, if (cellSpread) { for (auto pTarget : Helpers::Alex::getCellSpreadItems(coords, cellSpread, true)) - this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted, pBulletExt); + this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted); } else if (pBullet) { @@ -182,7 +181,7 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, // 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) - this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted, pBulletExt); + this->DetonateOnOneUnit(pHouse, pTarget, pOwner, bulletWasIntercepted); } } else if (this->DamageAreaTarget) @@ -193,7 +192,7 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, } } -void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner, bool bulletWasIntercepted, BulletExt::ExtData* pBulletExt) +void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner, bool bulletWasIntercepted) { if (!pTarget || pTarget->InLimbo || !pTarget->IsAlive || !pTarget->Health || pTarget->IsSinking || pTarget->BeingWarpedOut) return; @@ -212,8 +211,8 @@ void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* if (this->Crit_CurrentChance > 0.0 && (!this->Crit_SuppressWhenIntercepted || !bulletWasIntercepted)) this->ApplyCrit(pHouse, pTarget, pOwner); - if (this->AmmoModifier != 0) - ApplyAmmoModifier(pTarget, pHouse, pBulletExt); + if (this->Ammo != 0) + this->ApplyAmmoModifier(pTarget); if (this->Convert_Pairs.size() > 0) this->ApplyConvert(pHouse, pTarget); @@ -655,10 +654,10 @@ double WarheadTypeExt::ExtData::GetCritChance(TechnoClass* pFirer) const return critChance + extraChance; } -void WarheadTypeExt::ExtData::ApplyAmmoModifier(TechnoClass* pTarget, HouseClass* pInvokerHouse, BulletExt::ExtData* pBulletExt) +void WarheadTypeExt::ExtData::ApplyAmmoModifier(TechnoClass* pTarget) { int maxAmmo = pTarget->GetTechnoType()->Ammo; - int newCurrentAmmo = this->AmmoModifier + pTarget->Ammo; + int newCurrentAmmo = this->Ammo + pTarget->Ammo; newCurrentAmmo = newCurrentAmmo < 0 ? 0 : newCurrentAmmo; pTarget->Ammo = newCurrentAmmo > maxAmmo ? maxAmmo : newCurrentAmmo; From 63b775d7d5c4cd7e37ad2b2846822d64ae692b8f Mon Sep 17 00:00:00 2001 From: FS-21 Date: Sun, 6 Jul 2025 17:42:42 +0200 Subject: [PATCH 05/10] Updated adoc --- 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 6fe70cf3b3..ce52443a4d 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2132,7 +2132,7 @@ LaunchSW.DisplayMoney.Offset=0,0 ; X,Y, pixels relative to default In `rulesmd.ini`: ```ini [SOMEWARHEAD] ; Warhead -AmmoModifier=0 ; integer +Ammo=0 ; integer ``` ### Parasite removal From 2765cca5d2055d3128c118e0a0f3e5602475342f Mon Sep 17 00:00:00 2001 From: Noble_Fish <1065703286@qq.com> Date: Mon, 17 Aug 2026 16:24:30 +0800 Subject: [PATCH 06/10] mplementation of rebase against diff and fix/improve/rewrite docs The handling of merge conflicts is simply a disaster --- CREDITS.md | 1 + docs/New-or-Enhanced-Logics.md | 14 ++++++++++++++ docs/Whats-New.md | 1 + src/Ext/WarheadType/Body.cpp | 5 +++++ src/Ext/WarheadType/Body.h | 5 +++++ src/Ext/WarheadType/Detonate.cpp | 12 ++++++++++++ 6 files changed, 38 insertions(+) diff --git a/CREDITS.md b/CREDITS.md index 4e95706f1c..2fbeb1c54a 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -160,6 +160,7 @@ This page lists all the individual contributions to the project by their author. - Linked superweapons - Unit & infantry auto-conversion on ammo change - Restore the ScriptType action#24 `Play speech` from Tiberian Sun + - Modify ammo on impact - **Starkku**: - Misc. minor bugfixes & improvements - AI script actions: diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 2266f70d42..b68dfcbce6 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -3058,6 +3058,20 @@ LaunchSW.DisplayMoney.Offset=0,0 ; X,Y, pixels relative to default Due to the nature of some superweapon types, not all superweapons are suitable for launch. **Please use with caution!** ``` +### Modify ammo on impact + +- When this warhead detonates, it increases the ammo of affected targets by the set amount; a negative value decreases it. + +In `rulesmd.ini`: +```ini +[SOMEWARHEAD] ; WarheadType +Ammo=0 ; integer +``` + +```{note} +This will not raise the ammo above the maximum defined by `[TechnoType] -> Ammo=`, nor below 0. +``` + ### Parasite removal - By default if unit takes negative damage from a Warhead (before `Verses` are calculated), any parasites infecting it are removed and deleted. This behaviour can now be customized to disable the removal for negative damage, or enable it for any arbitrary warhead. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index efdb5675bb..02cc8862e4 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -419,6 +419,7 @@ HideShakeEffects=false ; boolean :open: #### New: +- [Modify ammo on impact](New-or-Enhanced-Logics.md#modify-ammo-on-impact) (by FS-21) #### Vanilla fixes: - Fixed the bug where a building with `Factory=BuildingType` owned by the AI did not play `ProductionAnim` when placing a produced building (by Noble_Fish) diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index a279347c60..b47ee2d8d3 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -514,6 +514,7 @@ void WarheadTypeExt::LoadFromINIFile(CCINIClass* const pINI) || this->ReturnWarhead || this->PenetratesTransport_Level > 0 || this->Taunt + || this->Ammo ); char tempBuffer[32]; @@ -553,6 +554,8 @@ void WarheadTypeExt::LoadFromINIFile(CCINIClass* const pINI) else this->SpawnsCrate_Weights.push_back(weight); } + + this->Ammo.Read(exINI, pSection, "Ammo"); } template @@ -816,6 +819,8 @@ void WarheadTypeExt::Serialize(T& Stm) .Process(this->PossibleCellSpreadDetonate) .Process(this->Reflected) .Process(this->DamageAreaTarget) + + .Process(this->Ammo) ; } diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index 880101e6e5..e1f9ddd320 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -270,6 +270,8 @@ class WarheadTypeExt final : public AbstractTypeExt Valueable PreventPassengerEscape; Valueable PreventOccupantEscape; + Valueable Ammo; + // Ares tags // http://ares-developers.github.io/Ares-docs/new/warheads/general.html Valueable AffectsEnemies; @@ -567,6 +569,8 @@ class WarheadTypeExt final : public AbstractTypeExt , PreventCrewEscape { false } , PreventPassengerEscape { false } , PreventOccupantEscape { false } + + , Ammo { 0 } { } void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget); @@ -608,6 +612,7 @@ class WarheadTypeExt final : public AbstractTypeExt void ApplyReturnWarhead(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* Owner); void ApplyPenetratesTransport(TechnoClass* pTarget, TechnoClass* pInvoker, HouseClass* pInvokerHouse, const CoordStruct& coords, int damage, int distance); double GetCritChance(TechnoClass* pFirer) const; + void ApplyAmmoModifier(TechnoClass* pTarget); public: class ExtContainer final : public Container diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 1fe0f66fff..36234def33 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -210,6 +210,9 @@ void WarheadTypeExt::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, if (this->ChangeOwner) this->ApplyOwnerChange(pHouse, pTarget); + if (this->Ammo != 0) + this->ApplyAmmoModifier(pTarget); + // These can change the target's techno types if (this->Convert_Pairs.size() > 0) this->ApplyConvert(pHouse, pTarget); @@ -908,3 +911,12 @@ void WarheadTypeExt::ApplyPenetratesTransport(TechnoClass* pTarget, TechnoClass* VocClass::PlayAt(cleanSound, transporterCoords); } } + +void WarheadTypeExt::ExtData::ApplyAmmoModifier(TechnoClass* pTarget) +{ + int maxAmmo = pTarget->GetTechnoType()->Ammo; + int newCurrentAmmo = this->Ammo + pTarget->Ammo; + + newCurrentAmmo = newCurrentAmmo < 0 ? 0 : newCurrentAmmo; + pTarget->Ammo = newCurrentAmmo > maxAmmo ? maxAmmo : newCurrentAmmo; +} From 84812673998084862f4ec65eeaa8e9ffcd0ed609 Mon Sep 17 00:00:00 2001 From: Noble_Fish <1065703286@qq.com> Date: Mon, 17 Aug 2026 16:35:22 +0800 Subject: [PATCH 07/10] Update YRpp --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index ad950ad2e6..8531d82713 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit ad950ad2e68982594533f1bc80eea662937ec056 +Subproject commit 8531d82713dab0b2d3f1bd9bf24209474b49a69a From d20a9cce248688a8bd734d95d3557812db88f856 Mon Sep 17 00:00:00 2001 From: Noble_Fish <1065703286@qq.com> Date: Mon, 17 Aug 2026 16:45:36 +0800 Subject: [PATCH 08/10] Fix read order issues (standardization) --- src/Ext/WarheadType/Body.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index b47ee2d8d3..bfeb3a3da5 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -449,6 +449,8 @@ void WarheadTypeExt::LoadFromINIFile(CCINIClass* const pINI) this->PreventPassengerEscape.Read(exINI, pSection, "PreventPassengerEscape"); this->PreventOccupantEscape.Read(exINI, pSection, "PreventOccupantEscape"); + this->Ammo.Read(exINI, pSection, "Ammo"); + // Convert.From & Convert.To TypeConvertGroup::Parse(this->Convert_Pairs, exINI, pSection, AffectedHouse::All); @@ -554,8 +556,6 @@ void WarheadTypeExt::LoadFromINIFile(CCINIClass* const pINI) else this->SpawnsCrate_Weights.push_back(weight); } - - this->Ammo.Read(exINI, pSection, "Ammo"); } template @@ -737,7 +737,7 @@ void WarheadTypeExt::Serialize(T& Stm) .Process(this->Parasite_DisableParticleSystem) .Process(this->Parasite_CullingTarget) .Process(this->Parasite_GrappleAnim) - + .Process(this->JumpjetTurnRate) .Process(this->JumpjetSpeed) .Process(this->JumpjetClimb) From 4ee47b036df8366cc1d2c2f316abede3adf8fca7 Mon Sep 17 00:00:00 2001 From: Noble_Fish <1065703286@qq.com> Date: Mon, 17 Aug 2026 17:08:20 +0800 Subject: [PATCH 09/10] doc for ApplyPerTargetEffectsOnDetonate --- docs/New-or-Enhanced-Logics.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index b68dfcbce6..709f5c2ef6 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -3255,6 +3255,7 @@ Taunt=false ; boolean - [`ReverseEngineer`](#reverse-engineer-warhead) - [Modify shield](#shields) - [Modify attach-effects](#attached-effects) + - [Modify ammo on impact](New-or-Enhanced-Logics.md#modify-ammo-on-impact) - [Critical hits](#chance-based-extra-damage-or-warhead-detonation--critical-hits) - Due to technical reasons, `Crit.SuppressWhenIntercepted=false` and `Crit.ApplyChancePerTarget=true` will forced to be used. From 6a21a0686cd3e6e57e12ab9e3c59d04e510ffad9 Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Wed, 19 Aug 2026 17:08:48 +0800 Subject: [PATCH 10/10] tweak --- src/Ext/WarheadType/Detonate.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 36234def33..3cb8be8874 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -210,9 +210,6 @@ void WarheadTypeExt::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, if (this->ChangeOwner) this->ApplyOwnerChange(pHouse, pTarget); - if (this->Ammo != 0) - this->ApplyAmmoModifier(pTarget); - // These can change the target's techno types if (this->Convert_Pairs.size() > 0) this->ApplyConvert(pHouse, pTarget); @@ -221,6 +218,9 @@ void WarheadTypeExt::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* pTarget, this->ApplyBuildingUndeploy(pTarget); // Other one time effects + if (this->Ammo != 0) + this->ApplyAmmoModifier(pTarget); + if (this->RemoveDisguise) this->ApplyRemoveDisguise(pTarget); @@ -494,7 +494,8 @@ HouseClass* WarheadTypeExt::ApplyRemoveMindControl(HouseClass* pHouse, TechnoCla void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget) { const bool isMindControl = this->ChangeOwner_SetAsMindControl; - const bool isImmune = (isMindControl && pTarget->GetTechnoType()->ImmuneToPsionics) || pTarget->IsMindControlled(); + const auto pType = pTarget->GetTechnoType(); + const bool isImmune = (isMindControl && pType->ImmuneToPsionics) || pTarget->IsMindControlled(); if (!isImmune) { @@ -512,7 +513,7 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* if (isBld) location.Z += static_cast(pTarget)->Type->Height * Unsorted::LevelHeight; else - location.Z += pTarget->GetTechnoType()->MindControlRingOffset; + location.Z += pType->MindControlRingOffset; if (const auto pOwnerAnim = GameCreate(pAnimType, location)) { @@ -914,7 +915,7 @@ void WarheadTypeExt::ApplyPenetratesTransport(TechnoClass* pTarget, TechnoClass* void WarheadTypeExt::ExtData::ApplyAmmoModifier(TechnoClass* pTarget) { - int maxAmmo = pTarget->GetTechnoType()->Ammo; + const int maxAmmo = pTarget->GetTechnoType()->Ammo; int newCurrentAmmo = this->Ammo + pTarget->Ammo; newCurrentAmmo = newCurrentAmmo < 0 ? 0 : newCurrentAmmo;