diff --git a/CREDITS.md b/CREDITS.md index 838c670fad..ef39b08f42 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -144,6 +144,7 @@ This page lists all the individual contributions to the project by their author. - Map Events 604 & 605 for checking if a specific Techno enters in a cell - Warhead that can not kill - `Pips.HideIfNoStrength` and `SelfHealing.EnabledBy` additions for shields + - Unit & infantry auto-conversion on ammo change - **Starkku**: - Misc. minor bugfixes & improvements - AI script actions: diff --git a/YRpp b/YRpp index 4ce57fba70..4e67ea43a1 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 4ce57fba70936c8fbda1d7eeafc53298174615a2 +Subproject commit 4e67ea43a108570ae2bebc5fb0bbd75dfce23221 diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 5b9c9df410..3b0bebdbe0 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -1700,6 +1700,27 @@ HarvesterDumpAmount=0.0 ; float point value HarvesterDumpAmount= ; float point value ``` +### Unit & infantry auto-conversion on ammo change + +- Units & infantry can now be converted into another unit by ammo count. +- `Ammo.AutoConvertMinimumAmount` determines the minimal number of ammo at which a unit converts automatically after the ammo update. +- `Ammo.AutoConvertMaximumAmount` determines the maximum number of ammo at which a unit converts automatically after the ammo update. +- `Ammo.AutoConvertType` specify the new techno after the conversion. This unit must be of the same type of the original (vehicle -> vehicle or infantry -> infantry). +- Setting a negative number will disable ammo count check. + +In `rulesmd.ini`: +```ini +[SOMETECHNO] ; InfantryType or VehicleType +Ammo.AutoConvertMinimumAmount=-1 ; integer +Ammo.AutoConvertMaximumAmount=-1 ; integer +Ammo.AutoConvertType= ; InfantryType or VehicleType +``` + +```{warning} +This auto-conversion feature requires [Ares](https://github.com/Ares-Developers/Ares). +Aircrafts weren't tested but if Ares supported them then this feature should work on them too. +``` + ## Veinholes & Weeds ### Veinholes diff --git a/docs/Whats-New.md b/docs/Whats-New.md index f59fcc7537..565baa8a61 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -389,6 +389,7 @@ New: - Customize whether `Crater=yes` animation would destroy tiberium (by TaranDahl) - Weapon target filtering by health percentage (by NetsuNegi) - Turretless vehicles with `Voxel=no` support use `FireUp` like infantry (by FlyStar) +- Unit & infantry auto-conversion on ammo change (by FS-21) 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/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index a44b938f9f..59d0ef8a8d 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -18,6 +18,7 @@ #include #include #include +#include // TechnoClass_AI_0x6F9E50 @@ -43,6 +44,7 @@ void TechnoExt::ExtData::OnEarlyUpdate() this->ApplyMindControlRangeLimit(); this->UpdateRecountBurst(); this->UpdateRearmInEMPState(); + this->AmmoAutoConvertActions(); } void TechnoExt::ExtData::ApplyInterceptor() @@ -123,6 +125,33 @@ void TechnoExt::ExtData::DepletedAmmoActions() pThis->QueueMission(Mission::Unload, true); } +void TechnoExt::ExtData::AmmoAutoConvertActions() +{ + const auto pThis = this->OwnerObject(); + const auto pTypeExt = this->TypeExtData; + + if (!pTypeExt || pThis->GetTechnoType()->Ammo <= 0) + return; + + const bool skipMinimum = pTypeExt->Ammo_AutoConvertMinimumAmount < 0; + const bool skipMaximum = pTypeExt->Ammo_AutoConvertMaximumAmount < 0; + + if (skipMinimum && skipMaximum) + return; + + if ((skipMinimum || pThis->Ammo >= pTypeExt->Ammo_AutoConvertMinimumAmount) // More than minimum + && (skipMaximum || pThis->Ammo <= pTypeExt->Ammo_AutoConvertMaximumAmount)) // Less than maximum + { + const auto pFoot = abstract_cast(pThis); + + if (!pFoot) + return; + + if (pTypeExt->Ammo_AutoConvertType.isset()) + TechnoExt::ConvertToType(pFoot, pTypeExt->Ammo_AutoConvertType); + } +} + // TODO : Merge into new AttachEffects bool TechnoExt::ExtData::CheckDeathConditions(bool isInLimbo) { diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index 7929f20229..b7e4c2ccfa 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -155,6 +155,8 @@ class TechnoExt UnitTypeClass* GetUnitTypeExtra() const; + void AmmoAutoConvertActions(); + virtual ~ExtData() override; virtual void InvalidatePointer(void* ptr, bool bRemoved) override { } virtual void LoadFromStream(PhobosStreamReader& Stm) override; diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index eac4ac744b..60797e9771 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -650,6 +650,10 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->FiringForceScatter.Read(exINI, pSection, "FiringForceScatter"); + this->Ammo_AutoConvertMinimumAmount.Read(exINI, pSection, "Ammo.AutoConvertMinimumAmount"); + this->Ammo_AutoConvertMaximumAmount.Read(exINI, pSection, "Ammo.AutoConvertMaximumAmount"); + this->Ammo_AutoConvertType.Read(exINI, pSection, "Ammo.AutoConvertType"); + // Ares 0.2 this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius"); @@ -1226,6 +1230,10 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) .Process(this->FallingDownDamage) .Process(this->FallingDownDamage_Water) + .Process(this->Ammo_AutoConvertMinimumAmount) + .Process(this->Ammo_AutoConvertMaximumAmount) + .Process(this->Ammo_AutoConvertType) + .Process(this->FiringForceScatter) .Process(this->FireUp) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index fe716e3cfb..046fe2d8fb 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -366,6 +366,10 @@ class TechnoTypeExt Valueable FallingDownDamage; Nullable FallingDownDamage_Water; + Valueable Ammo_AutoConvertMinimumAmount; + Valueable Ammo_AutoConvertMaximumAmount; + Nullable Ammo_AutoConvertType; + Valueable FiringForceScatter; Valueable FireUp; @@ -689,6 +693,10 @@ class TechnoTypeExt , FallingDownDamage { 1.0 } , FallingDownDamage_Water {} + , Ammo_AutoConvertMinimumAmount { -1 } + , Ammo_AutoConvertMaximumAmount { -1 } + , Ammo_AutoConvertType { nullptr } + , FiringForceScatter { true } , FireUp { -1 }