diff --git a/CREDITS.md b/CREDITS.md index 2adb1c7ce4..fe1acf4011 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -695,6 +695,7 @@ This page lists all the individual contributions to the project by their author. - Customize the step limit of the credits indicator - Disable the credits indicator smooth transition - Add `selling`, `undeploying` and `harvesting` conditions to `DiscardOn` + - Add a defining for AutoDeath on whether it can trigger when in Limbo state or as a passenger - **Ollerus**: - Build limit group enhancement - Customizable rocker amplitude diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index ec9ae2bdcc..2cb462d903 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -1978,12 +1978,20 @@ Both `InitialStrength` and `InitialStrength.Cloning` never surpass the type's `S - `vanish`: The object will be directly removed from the game peacefully instead of actually getting killed. - `sell`: If the object is a **building** with buildup, it will be sold instead of destroyed. - If this option is not set, the self-destruction logic will not be enabled. `AutoDeath.VanishAnimation` can be set to animation to play at object's location if `vanish` behaviour is chosen. If more than one animation is listed, a random one is selected. +- `AutoDeath.AllowLimboed` can be used to define whether AutoDeath is triggered when the unit is in limbo state. +- `AutoDeath.AllowPassenger` can be used to define whether the unit triggers AutoDeath when it is a passenger. - This logic also supports buildings delivered by [LimboDelivery](#limbodelivery). However in this case, all `AutoDeath.Behavior` values produce identical result where the building is simply deleted. +```{hint} +If the unit is a passenger in a transport with `OpenTopped=false`, then self-destruction will only be triggered when both `AutoDeath.AllowLimboed` and `AutoDeath.AllowPassenger` are `true`. +``` + In `rulesmd.ini`: ```ini [SOMETECHNO] ; TechnoType AutoDeath.Behavior= ; enumeration (kill | vanish | sell), default not set +AutoDeath.AllowLimboed=true ; boolean +AutoDeath.AllowPassenger=true ; boolean AutoDeath.VanishAnimation= ; List of AnimationTypes AutoDeath.OnAmmoDepletion=false ; boolean AutoDeath.OnOwnerChange=false ; boolean @@ -2004,6 +2012,10 @@ AutoDeath.TechnosExist.Houses=owner ; Affected House Enumeration (non Please notice that if the object is a unit which carries passengers, they will not be released even with the `kill` option **if you are not using Ares 3.0+**. ``` +```{note} +Currently, the scenario where the unit is a passenger in a transport with `OpenTopped=false` can only trigger AutoDeath when the owner changes. This may change in future. +``` + ### Low priority for deploy - You can now set lower priority for TechnoType deploying which means it will be excluded from deploy command if selected together with other units. This will not affect the cursor action which requires no other objects to be selected in the first place. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 2c98a36155..a69f6b4da5 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -606,6 +606,7 @@ HideShakeEffects=false ; boolean - [Customize the step limit of the credits indicator](User-Interface.md#customize-the-step-limit-of-the-credits-indicator) (by Noble_Fish) - [Disable the credits indicator smooth transition](User-Interface.md#disable-the-credits-indicator-smooth-transition) (by Noble_Fish) - Add `selling`, `undeploying` and `harvesting` conditions to `DiscardOn` (by Noble_Fish) +- Add a defining for AutoDeath on whether it can trigger when in Limbo state or as a passenger (by Noble_Fish) #### 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/House/Hooks.cpp b/src/Ext/House/Hooks.cpp index 1a0ea72a7a..f3926a2efd 100644 --- a/src/Ext/House/Hooks.cpp +++ b/src/Ext/House/Hooks.cpp @@ -214,16 +214,16 @@ DEFINE_HOOK(0x7015C9, TechnoClass_Captured_UpdateTracking, 0x6) auto const pExt = TechnoExt::ExtMap.Find(pThis); auto const pTypeExt = pExt->TypeExtData; + const bool isInLimbo = !pThis->IsInLogic && pThis->IsAlive; - if (pTypeExt->AutoDeath_Behavior.isset()) + if (pTypeExt->AutoDeath_Behavior.isset() && !(isInLimbo && !pTypeExt->AutoDeath_AllowLimboed) && !(pThis->Transporter && !pTypeExt->AutoDeath_AllowPassenger)) { const bool humanToComputer = pTypeExt->AutoDeath_OnOwnerChange_HumanToComputer.Get(pTypeExt->AutoDeath_OnOwnerChange); const bool computerToHuman = pTypeExt->AutoDeath_OnOwnerChange_ComputerToHuman.Get(pTypeExt->AutoDeath_OnOwnerChange); if (humanToComputer && computerToHuman) { - TechnoExt::KillSelf(pThis, pTypeExt->AutoDeath_Behavior, pTypeExt->AutoDeath_VanishAnimation, !pThis->IsInLogic && pThis->IsAlive); - return 0; + pExt->ShouldBeDead = true; } else if (humanToComputer || computerToHuman) { @@ -232,10 +232,7 @@ DEFINE_HOOK(0x7015C9, TechnoClass_Captured_UpdateTracking, 0x6) if (I_am_human != pNewOwner->IsControlledByHuman()) { if ((I_am_human && humanToComputer) || (!I_am_human && computerToHuman)) - { - TechnoExt::KillSelf(pThis, pTypeExt->AutoDeath_Behavior, pTypeExt->AutoDeath_VanishAnimation, !pThis->IsInLogic && pThis->IsAlive); - return 0; - } + pExt->ShouldBeDead = true; } } } diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index 1cb770f357..9f6ffaa484 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -282,11 +282,24 @@ bool TechnoExt::ExtData::CheckDeathConditions(bool isInLimbo) if (!pTypeExt->AutoDeath_Behavior.isset()) return false; + if (isInLimbo && !pTypeExt->AutoDeath_AllowLimboed) + return false; + auto const pThis = this->OwnerObject(); + if (pThis->Transporter && !pTypeExt->AutoDeath_AllowPassenger) + return false; + // Self-destruction must be enabled const auto howToDie = pTypeExt->AutoDeath_Behavior.Get(); + // You're already dead + if (this->ShouldBeDead) + { + TechnoExt::KillSelf(pThis, howToDie, pTypeExt->AutoDeath_VanishAnimation, isInLimbo); + return true; + } + // Death if no ammo if (pTypeExt->OwnerObject()->Ammo > 0 && pThis->Ammo <= 0 && pTypeExt->AutoDeath_OnAmmoDepletion) { diff --git a/src/Ext/Techno/Body.cpp b/src/Ext/Techno/Body.cpp index 8746ebcee6..f030202523 100644 --- a/src/Ext/Techno/Body.cpp +++ b/src/Ext/Techno/Body.cpp @@ -1342,6 +1342,7 @@ void TechnoExt::ExtData::Serialize(T& Stm) .Process(this->HoverShutdown) .Process(this->LastTargetCrd) .Process(this->LastTargetCrdClearTimer) + .Process(this->ShouldBeDead) ; } diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index bb31ec98a5..1ece802eb3 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -108,6 +108,7 @@ class TechnoExt bool HasDeployConverted; bool HasUndeployConverted; + bool ShouldBeDead; ExtData(TechnoClass* OwnerObject) : Extension(OwnerObject) , TypeExtData { nullptr } @@ -182,6 +183,7 @@ class TechnoExt , LastTargetCrdClearTimer {} , HasDeployConverted { false } , HasUndeployConverted { false } + , ShouldBeDead { false } { } void OnEarlyUpdate(); diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index d77b610154..781a616daf 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -792,6 +792,8 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->Ammo_DeployUnlockMaximumAmount.Read(exINI, pSection, "Ammo.DeployUnlockMaximumAmount"); this->AutoDeath_Behavior.Read(exINI, pSection, "AutoDeath.Behavior"); + this->AutoDeath_AllowLimboed.Read(exINI, pSection, "AutoDeath.AllowLimboed"); + this->AutoDeath_AllowPassenger.Read(exINI, pSection, "AutoDeath.AllowPassenger"); this->AutoDeath_VanishAnimation.Read(exINI, pSection, "AutoDeath.VanishAnimation"); this->AutoDeath_OnAmmoDepletion.Read(exINI, pSection, "AutoDeath.OnAmmoDepletion"); this->AutoDeath_OnOwnerChange.Read(exINI, pSection, "AutoDeath.OnOwnerChange"); @@ -1552,6 +1554,8 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) .Process(this->Ammo_DeployUnlockMaximumAmount) .Process(this->AutoDeath_Behavior) + .Process(this->AutoDeath_AllowLimboed) + .Process(this->AutoDeath_AllowPassenger) .Process(this->AutoDeath_VanishAnimation) .Process(this->AutoDeath_OnAmmoDepletion) .Process(this->AutoDeath_OnOwnerChange) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index 3237832272..c04b4ddbee 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -91,6 +91,8 @@ class TechnoTypeExt Valueable Ammo_DeployUnlockMaximumAmount; Nullable AutoDeath_Behavior; + Valueable AutoDeath_AllowLimboed; + Valueable AutoDeath_AllowPassenger; ValueableVector AutoDeath_VanishAnimation; Valueable AutoDeath_OnAmmoDepletion; Valueable AutoDeath_OnOwnerChange; @@ -647,6 +649,8 @@ class TechnoTypeExt , Ammo_DeployUnlockMaximumAmount { -1 } , AutoDeath_Behavior { } + , AutoDeath_AllowLimboed { true } + , AutoDeath_AllowPassenger { true } , AutoDeath_VanishAnimation {} , AutoDeath_OnAmmoDepletion { false } , AutoDeath_OnOwnerChange { false }