diff --git a/CREDITS.md b/CREDITS.md index 4e95706f1c..f74e2b55db 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -442,6 +442,7 @@ This page lists all the individual contributions to the project by their author. - Fix an issue where `OmniFire` was ineffective on buildings with `Turret=yes` - Fix an issue where setting a production building as `Primary` could cause it to enter an unload state - SkipMapSelect Enhancement + - Ares' `KeepAlive` adds global tags - **NetsuNegi**: - Forbidding parallel AI queues by type - Jumpjet crash speed fix when crashing onto building diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index f2fc1322b0..ff8d45e319 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -386,6 +386,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - `ProjectileRange` now has weapon range modifiers applied to it if greater than 0 and unless `ProjectileRange.ApplyModifiers` is set to false on the WeaponType. - Allowed customizing the default value of `[Warhead] -> PreventScatter` via `[CombatDamage] -> Warhead.PreventScatter`. - Allowed `SW.ShowCameo` and `SW.ManualFire` to work independently of `SW.AutoFire`. +- Ares' `KeepAlive` adds global tags. ## Newly added global settings @@ -541,6 +542,11 @@ In `rulesmd.ini`: ```ini [General] DefaultToGuardArea=false ; boolean +KeepAlive.Buildings=true ; boolean +KeepAlive.Defenses=true ; boolean +KeepAlive.Infantry=false ; boolean +KeepAlive.Units=false ; boolean +KeepAlive.Aircraft=false ; boolean [CombatDamage] Warhead.PreventScatter=false ; boolean diff --git a/docs/Whats-New.md b/docs/Whats-New.md index efdb5675bb..38db9d6dea 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -428,6 +428,7 @@ HideShakeEffects=false ; boolean #### Fixes / interactions with other extensions: - Allowed `SW.ShowCameo` and `SW.ManualFire` to work independently of `SW.AutoFire` (by Noble_Fish) +- Ares' `KeepAlive` adds global tags (by FlyStar) ``` diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 3d8447cb91..5ca0495370 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -610,6 +610,12 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->ReadyToNextMission_MovingCheck.Read(exINI, GameStrings::General, "ReadyToNextMission.MovingCheck"); this->Warhead_PreventScatter.Read(exINI, GameStrings::CombatDamage, "Warhead.PreventScatter"); + + this->KeepAlive_Infantry.Read(exINI, GameStrings::General, "KeepAlive.Infantry"); + this->KeepAlive_Units.Read(exINI, GameStrings::General, "KeepAlive.Units"); + this->KeepAlive_Aircraft.Read(exINI, GameStrings::General, "KeepAlive.Aircraft"); + this->KeepAlive_Buildings.Read(exINI, GameStrings::General, "KeepAlive.Buildings"); + this->KeepAlive_Defenses.Read(exINI, GameStrings::General, "KeepAlive.Defenses"); this->ProjectileRange_ApplyModifiers.Read(exINI, GameStrings::CombatDamage, "ProjectileRange.ApplyModifiers"); @@ -1090,6 +1096,11 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->ReadyToNextMission_MovingCheck) .Process(this->Warhead_PreventScatter) .Process(this->ProjectileRange_ApplyModifiers) + .Process(this->KeepAlive_Infantry) + .Process(this->KeepAlive_Units) + .Process(this->KeepAlive_Aircraft) + .Process(this->KeepAlive_Buildings) + .Process(this->KeepAlive_Defenses) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index 808521c38f..df77ce69ba 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -534,6 +534,12 @@ class RulesExt Valueable NoAlphaImageOnBuildup; Valueable Warhead_PreventScatter; + + Valueable KeepAlive_Infantry; + Valueable KeepAlive_Units; + Valueable KeepAlive_Aircraft; + Valueable KeepAlive_Buildings; + Valueable KeepAlive_Defenses; Valueable ProjectileRange_ApplyModifiers; @@ -1009,6 +1015,12 @@ class RulesExt , Warhead_PreventScatter { false } , ProjectileRange_ApplyModifiers { true } + + , KeepAlive_Infantry { false } + , KeepAlive_Units { false } + , KeepAlive_Aircraft { false } + , KeepAlive_Buildings { true } + , KeepAlive_Defenses { true } { } virtual ~ExtData() = default; diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index b903cd3e35..9f76a2f170 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -1206,6 +1206,7 @@ void TechnoTypeExt::LoadFromINIFile(CCINIClass* const pINI) // Ares 3.0 this->Unsellable.Read(exINI, pSection, "Unsellable"); + this->KeepAlive.Read(exINI, pSection, "KeepAlive"); if (pThis->Gunner) { @@ -1804,6 +1805,7 @@ void TechnoTypeExt::Serialize(T& Stm) .Process(this->JumpjetClimbIgnoreBuilding) .Process(this->Unsellable) + .Process(this->KeepAlive) .Process(this->ExtraThreat_Enabled) .Process(this->ExtraThreat_IsThreat) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index e4ee3ab3e7..01f5586b55 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -438,7 +438,8 @@ class TechnoTypeExt : public ObjectTypeExt Valueable Convert_Health_BelowPercent; Nullable Convert_Health; - Nullable Unsellable; // Ares 3.0 + Nullable Unsellable; // Ares 3.0 + Nullable KeepAlive; // Ares 3.0 TechnoTypeExt(TechnoTypeClass* OwnerObject) : ObjectTypeExt(OwnerObject) , HealthBar_Hide { false } @@ -814,6 +815,7 @@ class TechnoTypeExt : public ObjectTypeExt , JumpjetClimbIgnoreBuilding {} , Unsellable {} + , KeepAlive {} , ExtraThreat_Enabled { false } , ExtraThreat_IsThreat {} diff --git a/src/Misc/Hooks.Ares.cpp b/src/Misc/Hooks.Ares.cpp index 3e25b9f366..a232481964 100644 --- a/src/Misc/Hooks.Ares.cpp +++ b/src/Misc/Hooks.Ares.cpp @@ -177,6 +177,75 @@ static bool __fastcall ParadropPlaneUnlimbo(AircraftClass* pThis, void* _, const #pragma endregion +#pragma region AresKeepAlive + +struct AresHouseExt +{ + char _[0x18]; + int KeepAliveTechnos; + int KeepAliveBuildings; +}; + +static bool __fastcall AresHouseExt_UpdateKeepAlive(AresHouseExt* pExt_Ares, void*, TechnoClass* const pTechno, const AbstractType rtti, const bool add) +{ + bool keepAlive = false; + bool result = false; + auto const pTypeExt = TechnoExt::Fetch(pTechno)->TypeExtData; + auto const pType = pTypeExt->OwnerObject(); + + if (!pType->Insignificant && !pType->DontScore) + { + switch (rtti) + { + case AbstractType::Infantry: + { + keepAlive = RulesExt::Global()->KeepAlive_Infantry; + break; + } + case AbstractType::Unit: + { + keepAlive = RulesExt::Global()->KeepAlive_Units; + break; + } + case AbstractType::Aircraft: + { + keepAlive = RulesExt::Global()->KeepAlive_Aircraft; + break; + } + case AbstractType::Building: + { + auto const pBuildingType = static_cast(pType); + + if (pBuildingType->BuildCat == BuildCat::Combat) + keepAlive = RulesExt::Global()->KeepAlive_Defenses; + else + keepAlive = RulesExt::Global()->KeepAlive_Buildings; + + break; + } + default: + { + break; + } + } + + result = true; + } + + if (pTypeExt->KeepAlive.Get(keepAlive)) + { + const int number = add ? 1 : -1; + pExt_Ares->KeepAliveTechnos += number; + + if (rtti == AbstractType::Building) + pExt_Ares->KeepAliveBuildings += number; + } + + return result; +} + +#pragma endregion + DEFINE_HOOK(0x440580, BuildingClass_Unlimbo_UnitDeliveryFix, 0x5) { if (UnitDeliveryTemp::Placing) @@ -312,6 +381,9 @@ void Apply_Ares3_0_Patches() Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x39635, AresHelper::AresBaseAddress + 0x39664); // Decouple SW.ManualFire from SW.AutoFire - Ares' SidebarClass_ProcessCameoClick_SuperWeapons Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x34DD0, AresHelper::AresBaseAddress + 0x34DD9); + + // Ares' `KeepAlive` adds global tags. + Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x21F70, GET_OFFSET(AresHouseExt_UpdateKeepAlive)); } void Apply_Ares3_0p1_Patches() @@ -430,4 +502,7 @@ void Apply_Ares3_0p1_Patches() Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x3A0B5, AresHelper::AresBaseAddress + 0x3A0E4); // Decouple SW.ManualFire from SW.AutoFire - Ares' SidebarClass_ProcessCameoClick_SuperWeapons Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x35810, AresHelper::AresBaseAddress + 0x35819); + + // Ares' `KeepAlive` adds global tags. + Patch::Apply_LJMP(AresHelper::AresBaseAddress + 0x229F0, GET_OFFSET(AresHouseExt_UpdateKeepAlive)); }