From 55664e14f126fa0d570a77264629b819bab0d898 Mon Sep 17 00:00:00 2001 From: Fryone Date: Mon, 31 Jul 2023 01:07:23 +0300 Subject: [PATCH 01/12] initial commit added ownerchanger to warheads --- src/Ext/WarheadType/Body.cpp | 3 +++ src/Ext/WarheadType/Body.h | 3 +++ src/Ext/WarheadType/Detonate.cpp | 21 +++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index b61eb18296..590ae82c96 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -121,6 +121,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->AnimList_ShowOnZeroDamage.Read(exINI, pSection, "AnimList.ShowOnZeroDamage"); this->DecloakDamagedTargets.Read(exINI, pSection, "DecloakDamagedTargets"); this->ShakeIsLocal.Read(exINI, pSection, "ShakeIsLocal"); + this->ChangeOwner.Read(exINI, pSection, "IsOwnerChanger"); // Crits this->Crit_Chance.Read(exINI, pSection, "Crit.Chance"); @@ -268,6 +269,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) || this->Convert_Pairs.size() > 0 || this->InflictLocomotor || this->RemoveInflictedLocomotor + || this->ChangeOwner ); } @@ -290,6 +292,7 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->AnimList_ShowOnZeroDamage) .Process(this->DecloakDamagedTargets) .Process(this->ShakeIsLocal) + .Process(this->ChangeOwner) .Process(this->Crit_Chance) .Process(this->Crit_ApplyChancePerTarget) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index 56915fc222..5a1d96988c 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -35,6 +35,7 @@ class WarheadTypeExt Valueable AnimList_ShowOnZeroDamage; Valueable DecloakDamagedTargets; Valueable ShakeIsLocal; + Valueable ChangeOwner; Valueable Crit_Chance; Valueable Crit_ApplyChancePerTarget; @@ -137,6 +138,7 @@ class WarheadTypeExt , AnimList_ShowOnZeroDamage { false } , DecloakDamagedTargets { true } , ShakeIsLocal { false } + , ChangeOwner { false } , Crit_Chance { 0.0 } , Crit_ApplyChancePerTarget { false } @@ -227,6 +229,7 @@ class WarheadTypeExt void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget); void ApplyLocomotorInfliction(TechnoClass* pTarget); void ApplyLocomotorInflictionReset(TechnoClass* pTarget); + void ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget); public: void Detonate(TechnoClass* pOwner, HouseClass* pHouse, BulletExt::ExtData* pBullet, CoordStruct coords); diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 48c8b4d5a9..5c250d5e86 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -51,6 +51,12 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, if (this->SpySat) MapClass::Instance->Reveal(pHouse); + //if (this->ChangeOwner) + //{ + // const auto cell = CellClass::Coord2Cell(coords); + // + //} + if (this->TransactMoney) { pHouse->TransactMoney(this->TransactMoney); @@ -135,6 +141,9 @@ void WarheadTypeExt::ExtData::DetonateOnOneUnit(HouseClass* pHouse, TechnoClass* if (this->RemoveMindControl) this->ApplyRemoveMindControl(pHouse, pTarget); + if (this->ChangeOwner) + this->ApplyOwnerChange(pHouse, pTarget); + if (this->Crit_Chance && (!this->Crit_SuppressWhenIntercepted || !bulletWasIntercepted)) this->ApplyCrit(pHouse, pTarget, pOwner); @@ -247,6 +256,18 @@ void WarheadTypeExt::ExtData::ApplyRemoveDisguiseToInf(HouseClass* pHouse, Techn } } +void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget) +{ + auto const pExt = TechnoExt::ExtMap.Find(pTarget); + auto armorType = pTarget->GetTechnoType()->Armor; + + if (pExt->Shield && pExt->Shield->IsActive() && !pExt->Shield->CanBePenetrated(this->OwnerObject())) + armorType = pExt->Shield->GetArmorType(); + + if ((GeneralUtils::GetWarheadVersusArmor(this->OwnerObject(), armorType) != 0.0) && (!pTarget->IsMindControlled())) + pTarget->SetOwningHouse(pHouse, true); +} + void WarheadTypeExt::ExtData::ApplyCrit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner) { double dice; From 6b6f924a906ad12b2ebacb9b5de8dc7a0e91e9ad Mon Sep 17 00:00:00 2001 From: Fryone Date: Tue, 1 Aug 2023 13:23:25 +0300 Subject: [PATCH 02/12] Immunities (wip) Immunities update --- src/Ext/TechnoType/Body.cpp | 3 ++ src/Ext/TechnoType/Body.h | 4 +++ src/Ext/WarheadType/Body.cpp | 6 ++++ src/Ext/WarheadType/Body.h | 6 ++++ src/Ext/WarheadType/Detonate.cpp | 48 ++++++++++++++++++++++++++++++-- 5 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index fc7f293334..788c6a061e 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -253,6 +253,8 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->PipWrapAmmoPip.Read(exINI, pSection, "PipWrapAmmoPip"); this->AmmoPipSize.Read(exINI, pSection, "AmmoPipSize"); + this->ChangeOwnerImmunities.Read(exINI, pSection, "OwnerChangerImmunities"); + // Ares 0.2 this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius"); @@ -529,6 +531,7 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) .Process(this->EmptyAmmoPip) .Process(this->PipWrapAmmoPip) .Process(this->AmmoPipSize) + .Process(this->ChangeOwnerImmunities) ; } void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index 44446a346e..4afeaf687c 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -162,6 +162,8 @@ class TechnoTypeExt Valueable PipWrapAmmoPip; Nullable AmmoPipSize; + NullableVector ChangeOwnerImmunities; + struct LaserTrailDataEntry { ValueableIdx idxType; @@ -322,6 +324,8 @@ class TechnoTypeExt , EmptyAmmoPip { -1 } , PipWrapAmmoPip { 14 } , AmmoPipSize {} + + , ChangeOwnerImmunities {} { } virtual ~ExtData() = default; diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 590ae82c96..204edd30ae 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -122,6 +122,9 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->DecloakDamagedTargets.Read(exINI, pSection, "DecloakDamagedTargets"); this->ShakeIsLocal.Read(exINI, pSection, "ShakeIsLocal"); this->ChangeOwner.Read(exINI, pSection, "IsOwnerChanger"); + this->ChangeOwner_MindControl.Read(exINI, pSection, "IsOwnerChanger.SetAsMindControl"); + this->ChangeOwner_Anim.Read(exINI, pSection, "IsOwnerChanger.ControlAnim"); + this->ChangeOwner_Type.Read(exINI, pSection, "IsOwnerChanger.ControlType"); // Crits this->Crit_Chance.Read(exINI, pSection, "Crit.Chance"); @@ -293,6 +296,9 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->DecloakDamagedTargets) .Process(this->ShakeIsLocal) .Process(this->ChangeOwner) + .Process(this->ChangeOwner_MindControl) + .Process(this->ChangeOwner_Anim) + .Process(this->ChangeOwner_Type) .Process(this->Crit_Chance) .Process(this->Crit_ApplyChancePerTarget) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index 5a1d96988c..d9cb7eed7f 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -36,6 +36,9 @@ class WarheadTypeExt Valueable DecloakDamagedTargets; Valueable ShakeIsLocal; Valueable ChangeOwner; + Valueable ChangeOwner_MindControl; + Nullable ChangeOwner_Anim; + Valueable ChangeOwner_Type; Valueable Crit_Chance; Valueable Crit_ApplyChancePerTarget; @@ -139,6 +142,9 @@ class WarheadTypeExt , DecloakDamagedTargets { true } , ShakeIsLocal { false } , ChangeOwner { false } + , ChangeOwner_MindControl { false } + , ChangeOwner_Anim {} + , ChangeOwner_Type { 0 } , Crit_Chance { 0.0 } , Crit_ApplyChancePerTarget { false } diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 5c250d5e86..392248447c 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -259,13 +259,57 @@ void WarheadTypeExt::ExtData::ApplyRemoveDisguiseToInf(HouseClass* pHouse, Techn void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget) { auto const pExt = TechnoExt::ExtMap.Find(pTarget); + auto const pExtType = TechnoTypeExt::ExtMap.Find(pTarget->GetTechnoType()); auto armorType = pTarget->GetTechnoType()->Armor; if (pExt->Shield && pExt->Shield->IsActive() && !pExt->Shield->CanBePenetrated(this->OwnerObject())) armorType = pExt->Shield->GetArmorType(); - if ((GeneralUtils::GetWarheadVersusArmor(this->OwnerObject(), armorType) != 0.0) && (!pTarget->IsMindControlled())) - pTarget->SetOwningHouse(pHouse, true); + const auto pOwnerAnimType = this->ChangeOwner_Anim.Get(nullptr); + const int pOwnerControlType = this->ChangeOwner_Type; + NullableVector targetImmunities = pExtType->ChangeOwnerImmunities; + const bool isMindControl = this->ChangeOwner_MindControl; + const bool targetImmuneToPsionics = pTarget->GetTechnoType()->ImmuneToPsionics; + bool pImmune = (isMindControl && targetImmuneToPsionics); + + if(targetImmunities.size() > 0) + for(int i = 0; i < targetImmunities.size(); i++) + { + if(targetImmunities[i] == pOwnerControlType) + pImmune = true; + } + + if (!pImmune) + { + if ((GeneralUtils::GetWarheadVersusArmor(this->OwnerObject(), armorType) != 0.0) && (!pTarget->IsMindControlled())) + pTarget->SetOwningHouse(pHouse, true); + + if (pOwnerAnimType) + { + CoordStruct OwningAnimLocation = pTarget->Location; + if (isMindControl) + OwningAnimLocation.Z += pTarget->GetTechnoType()->MindControlRingOffset; + if (auto const pOwnerAnim = GameCreate(pOwnerAnimType, OwningAnimLocation)) + { + pOwnerAnim->Owner = pHouse; + if (isMindControl) + { + pTarget->MindControlRingAnim = pOwnerAnim; + pTarget->MindControlledByAUnit = true; + } + else + { + pOwnerAnim->SetOwnerObject(pTarget); + pOwnerAnim->Owner = pHouse; + } + } + } + else + { + if (isMindControl) + pTarget->MindControlledByAUnit = true; + } + } } void WarheadTypeExt::ExtData::ApplyCrit(HouseClass* pHouse, TechnoClass* pTarget, TechnoClass* pOwner) From f00d0e6cadbc9f3a72c5976eba1880921a02d17b Mon Sep 17 00:00:00 2001 From: Fryone Date: Tue, 1 Aug 2023 17:41:37 +0300 Subject: [PATCH 03/12] Docs and fixes --- CREDITS.md | 1 + docs/New-or-Enhanced-Logics.md | 17 +++++++++ docs/Whats-New.md | 1 + src/Ext/TechnoType/Body.cpp | 3 -- src/Ext/WarheadType/Body.cpp | 6 ++- src/Ext/WarheadType/Body.h | 6 ++- src/Ext/WarheadType/Detonate.cpp | 63 ++++++++++++++------------------ 7 files changed, 55 insertions(+), 42 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index 24ea6547d7..207b17bf30 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -284,6 +284,7 @@ This page lists all the individual contributions to the project by their author. - Vehicle voxel turret shadows & body multi-section shadows - **Fryone** - Customizable ElectricBolt Arcs + - Change target Owner on warhead impact - **Ares developers** - YRpp and Syringe which are used, save/load, project foundation and generally useful code from Ares - unfinished RadTypes code diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 21be597eb3..390a1e186b 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -1164,6 +1164,23 @@ In `rulesmd.ini`: NotHuman.DeathSequence= ; integer (1 to 5) ``` +### Change target Owner on impact + +- Warheads can now change targets owner to warhead's owner. +- `IsOwnerChanger.SetAsMindControl` sets control as PermanentMindControl, uses `MindControlRingOffset` for anim, respects `ImmuneToPsionics`. +- `IsOwnerChanger.AffectElites` sets if elite veterancy units can be affected to owner change. +- `IsOwnerChanger.HealthThreshold` sets target minimal health percentage to have owner changed. + +In `rulesmd.ini`: +```ini +[SOMEWARHEAD] ; Warhead +IsOwnerChanger = yes ; boolean +IsOwnerChanger.SetAsMindControl = no ; boolean +IsOwnerChanger.ControlAnim = SOMEANIM ; animation on target +IsOwnerChanger.AffectElites = yes ; boolean +IsOwnerChanger.HealthThreshold = 1.0 ; float +``` + ## Weapons ### AreaFire target customization diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 3e6ac41213..43b9c05e8f 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -326,6 +326,7 @@ New: - Digital display of HP and SP (by ststl, FlyStar, Saigyouji, JunJacobYoung) - PipScale pip size & ammo pip frame customization (by Starkku) - `AltPalette` lighting toggle (by Starkku) +- Change target Owner on warhead impact (by Fryone) 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/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index 788c6a061e..fc7f293334 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -253,8 +253,6 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->PipWrapAmmoPip.Read(exINI, pSection, "PipWrapAmmoPip"); this->AmmoPipSize.Read(exINI, pSection, "AmmoPipSize"); - this->ChangeOwnerImmunities.Read(exINI, pSection, "OwnerChangerImmunities"); - // Ares 0.2 this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius"); @@ -531,7 +529,6 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) .Process(this->EmptyAmmoPip) .Process(this->PipWrapAmmoPip) .Process(this->AmmoPipSize) - .Process(this->ChangeOwnerImmunities) ; } void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm) diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 204edd30ae..e7b33c3822 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -124,7 +124,8 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->ChangeOwner.Read(exINI, pSection, "IsOwnerChanger"); this->ChangeOwner_MindControl.Read(exINI, pSection, "IsOwnerChanger.SetAsMindControl"); this->ChangeOwner_Anim.Read(exINI, pSection, "IsOwnerChanger.ControlAnim"); - this->ChangeOwner_Type.Read(exINI, pSection, "IsOwnerChanger.ControlType"); + this->ChangeOwner_Threshold.Read(exINI, pSection, "IsOwnerChanger.HealthThreshold"); + this->ChangeOwner_AffectElites.Read(exINI, pSection, "IsOwnerChanger.AffectElites"); // Crits this->Crit_Chance.Read(exINI, pSection, "Crit.Chance"); @@ -298,7 +299,8 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->ChangeOwner) .Process(this->ChangeOwner_MindControl) .Process(this->ChangeOwner_Anim) - .Process(this->ChangeOwner_Type) + .Process(this->ChangeOwner_Threshold) + .Process(this->ChangeOwner_AffectElites) .Process(this->Crit_Chance) .Process(this->Crit_ApplyChancePerTarget) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index d9cb7eed7f..8988565b00 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -38,7 +38,8 @@ class WarheadTypeExt Valueable ChangeOwner; Valueable ChangeOwner_MindControl; Nullable ChangeOwner_Anim; - Valueable ChangeOwner_Type; + Valueable ChangeOwner_Threshold; + Valueable ChangeOwner_AffectElites; Valueable Crit_Chance; Valueable Crit_ApplyChancePerTarget; @@ -144,7 +145,8 @@ class WarheadTypeExt , ChangeOwner { false } , ChangeOwner_MindControl { false } , ChangeOwner_Anim {} - , ChangeOwner_Type { 0 } + , ChangeOwner_Threshold { 1.0 } + , ChangeOwner_AffectElites { true } , Crit_Chance { 0.0 } , Crit_ApplyChancePerTarget { false } diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 392248447c..27f71af37e 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -51,12 +51,6 @@ void WarheadTypeExt::ExtData::Detonate(TechnoClass* pOwner, HouseClass* pHouse, if (this->SpySat) MapClass::Instance->Reveal(pHouse); - //if (this->ChangeOwner) - //{ - // const auto cell = CellClass::Coord2Cell(coords); - // - //} - if (this->TransactMoney) { pHouse->TransactMoney(this->TransactMoney); @@ -258,56 +252,55 @@ void WarheadTypeExt::ExtData::ApplyRemoveDisguiseToInf(HouseClass* pHouse, Techn void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget) { - auto const pExt = TechnoExt::ExtMap.Find(pTarget); - auto const pExtType = TechnoTypeExt::ExtMap.Find(pTarget->GetTechnoType()); + const auto pExt = TechnoExt::ExtMap.Find(pTarget); auto armorType = pTarget->GetTechnoType()->Armor; if (pExt->Shield && pExt->Shield->IsActive() && !pExt->Shield->CanBePenetrated(this->OwnerObject())) armorType = pExt->Shield->GetArmorType(); const auto pOwnerAnimType = this->ChangeOwner_Anim.Get(nullptr); - const int pOwnerControlType = this->ChangeOwner_Type; - NullableVector targetImmunities = pExtType->ChangeOwnerImmunities; + const double ownerChangeHealthThreshold = this->ChangeOwner_Threshold; const bool isMindControl = this->ChangeOwner_MindControl; + const bool doesAffectElites = this->ChangeOwner_AffectElites; const bool targetImmuneToPsionics = pTarget->GetTechnoType()->ImmuneToPsionics; + bool pImmune = (isMindControl && targetImmuneToPsionics); + if(pTarget->GetHealthPercentage() > ownerChangeHealthThreshold) + pImmune = true; - if(targetImmunities.size() > 0) - for(int i = 0; i < targetImmunities.size(); i++) - { - if(targetImmunities[i] == pOwnerControlType) - pImmune = true; - } + if(!doesAffectElites && (pTarget->Veterancy.IsElite())) + pImmune = true; if (!pImmune) { if ((GeneralUtils::GetWarheadVersusArmor(this->OwnerObject(), armorType) != 0.0) && (!pTarget->IsMindControlled())) - pTarget->SetOwningHouse(pHouse, true); - - if (pOwnerAnimType) { - CoordStruct OwningAnimLocation = pTarget->Location; - if (isMindControl) - OwningAnimLocation.Z += pTarget->GetTechnoType()->MindControlRingOffset; - if (auto const pOwnerAnim = GameCreate(pOwnerAnimType, OwningAnimLocation)) + pTarget->SetOwningHouse(pHouse, true); + if (pOwnerAnimType) { - pOwnerAnim->Owner = pHouse; + CoordStruct OwningAnimLocation = pTarget->Location; if (isMindControl) + OwningAnimLocation.Z += pTarget->GetTechnoType()->MindControlRingOffset; + if (auto const pOwnerAnim = GameCreate(pOwnerAnimType, OwningAnimLocation)) { - pTarget->MindControlRingAnim = pOwnerAnim; - pTarget->MindControlledByAUnit = true; - } - else - { - pOwnerAnim->SetOwnerObject(pTarget); pOwnerAnim->Owner = pHouse; + if (isMindControl) + { + pTarget->MindControlRingAnim = pOwnerAnim; + pTarget->MindControlledByAUnit = true; + } + else + { + pOwnerAnim->SetOwnerObject(pTarget); + pOwnerAnim->Owner = pHouse; + } } } - } - else - { - if (isMindControl) - pTarget->MindControlledByAUnit = true; + else + { + if (isMindControl) + pTarget->MindControlledByAUnit = true; + } } } } From 723551e479dccb7e27d89957efa6dbeed32a992d Mon Sep 17 00:00:00 2001 From: Fryone Date: Fri, 23 Feb 2024 13:12:08 +0300 Subject: [PATCH 04/12] Update YRpp --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index b6cd27087f..dd9c4cf1d7 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit b6cd27087fb0e9f2a1c666f6d84f4377e1a16d02 +Subproject commit dd9c4cf1d742d0b6db6a5edd8d715b8dd15ce1b9 From 1770c6b6a1e930bf42e7775d28e3298cd870fae7 Mon Sep 17 00:00:00 2001 From: Fryone Date: Fri, 23 Feb 2024 21:25:41 +0300 Subject: [PATCH 05/12] Update Detonate.cpp --- src/Ext/WarheadType/Detonate.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 4fecbef8cb..e581f0e829 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -267,14 +267,9 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* const bool doesAffectElites = this->ChangeOwner_AffectElites; const bool targetImmuneToPsionics = pTarget->GetTechnoType()->ImmuneToPsionics; - bool pImmune = (isMindControl && targetImmuneToPsionics); - if(pTarget->GetHealthPercentage() > ownerChangeHealthThreshold) - pImmune = true; + bool isImmune = (isMindControl && targetImmuneToPsionics) || (pTarget->GetHealthPercentage() > ownerChangeHealthThreshold) || (!doesAffectElites && pTarget->Veterancy.IsElite()); - if(!doesAffectElites && (pTarget->Veterancy.IsElite())) - pImmune = true; - - if (!pImmune) + if (!isImmune) { if ((GeneralUtils::GetWarheadVersusArmor(this->OwnerObject(), armorType) != 0.0) && (!pTarget->IsMindControlled())) { From 30c3ee42b17dc7291d45b03bf8985823c38532c4 Mon Sep 17 00:00:00 2001 From: Fryone Date: Sat, 24 Feb 2024 11:00:58 +0300 Subject: [PATCH 06/12] fix permamc anim not following target --- src/Ext/WarheadType/Detonate.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index e581f0e829..a7f619b90b 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -266,6 +266,7 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* const bool isMindControl = this->ChangeOwner_MindControl; const bool doesAffectElites = this->ChangeOwner_AffectElites; const bool targetImmuneToPsionics = pTarget->GetTechnoType()->ImmuneToPsionics; + const bool isBld = pTarget->What_Am_I() == AbstractType::Building; bool isImmune = (isMindControl && targetImmuneToPsionics) || (pTarget->GetHealthPercentage() > ownerChangeHealthThreshold) || (!doesAffectElites && pTarget->Veterancy.IsElite()); @@ -278,8 +279,11 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* { CoordStruct OwningAnimLocation = pTarget->Location; if (isMindControl) - OwningAnimLocation.Z += pTarget->GetTechnoType()->MindControlRingOffset; - if (auto const pOwnerAnim = GameCreate(pOwnerAnimType, OwningAnimLocation)) + if (isBld) + OwningAnimLocation.Z += pTarget->GetTechnoType()->Height * Unsorted::LevelHeight; + else + OwningAnimLocation.Z += pTarget->GetTechnoType()->MindControlRingOffset; + if (auto pOwnerAnim = GameCreate(pOwnerAnimType, OwningAnimLocation, 0, 1)) { pOwnerAnim->Owner = pHouse; if (isMindControl) @@ -289,9 +293,11 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* } else { - pOwnerAnim->SetOwnerObject(pTarget); pOwnerAnim->Owner = pHouse; } + pOwnerAnim->SetOwnerObject(pTarget); + if (isBld) + pOwnerAnim->ZAdjust = -1024; } } else From 0b51abf2986a5911da0fbde6957b06c939d291ea Mon Sep 17 00:00:00 2001 From: Fryone Date: Sat, 24 Feb 2024 12:03:30 +0300 Subject: [PATCH 07/12] updated logic 'IsOwnerChanger.ControlAnim' -> changed to 'IsOwnerChanger.MindControlAnim' to use specifically as custom anim for permanent MC --- docs/New-or-Enhanced-Logics.md | 15 +++++++------- src/Ext/WarheadType/Body.cpp | 4 ++-- src/Ext/WarheadType/Body.h | 4 ++-- src/Ext/WarheadType/Detonate.cpp | 35 ++++++++++++-------------------- 4 files changed, 25 insertions(+), 33 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index ceb73140db..42d9c5d223 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -1205,18 +1205,19 @@ NotHuman.DeathSequence= ; integer (1 to 5) ### Change target Owner on impact - Warheads can now change targets owner to warhead's owner. -- `IsOwnerChanger.SetAsMindControl` sets control as PermanentMindControl, uses `MindControlRingOffset` for anim, respects `ImmuneToPsionics`. +- `IsOwnerChanger.SetAsMindControl` sets control as PermanentMindControl, uses `IsOwnerChanger.MindControlAnim` if set +or `MindControlRingOffset` for anim, respects `ImmuneToPsionics`. - `IsOwnerChanger.AffectElites` sets if elite veterancy units can be affected to owner change. - `IsOwnerChanger.HealthThreshold` sets target minimal health percentage to have owner changed. In `rulesmd.ini`: ```ini -[SOMEWARHEAD] ; Warhead -IsOwnerChanger = yes ; boolean -IsOwnerChanger.SetAsMindControl = no ; boolean -IsOwnerChanger.ControlAnim = SOMEANIM ; animation on target -IsOwnerChanger.AffectElites = yes ; boolean -IsOwnerChanger.HealthThreshold = 1.0 ; float +[SOMEWARHEAD] ; Warhead +IsOwnerChanger = yes ; boolean +IsOwnerChanger.SetAsMindControl = no ; boolean +IsOwnerChanger.MindControlAnim = SOMEANIM ; animation on target +IsOwnerChanger.AffectElites = yes ; boolean +IsOwnerChanger.HealthThreshold = 1.0 ; float ``` ## Weapons diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 864e776e62..6bf85b684c 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -129,7 +129,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->ApplyModifiersOnNegativeDamage.Read(exINI, pSection, "ApplyModifiersOnNegativeDamage"); this->ChangeOwner.Read(exINI, pSection, "IsOwnerChanger"); this->ChangeOwner_MindControl.Read(exINI, pSection, "IsOwnerChanger.SetAsMindControl"); - this->ChangeOwner_Anim.Read(exINI, pSection, "IsOwnerChanger.ControlAnim"); + this->ChangeOwner_MindAnim.Read(exINI, pSection, "IsOwnerChanger.MindControlAnim"); this->ChangeOwner_Threshold.Read(exINI, pSection, "IsOwnerChanger.HealthThreshold"); this->ChangeOwner_AffectElites.Read(exINI, pSection, "IsOwnerChanger.AffectElites"); @@ -278,7 +278,7 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->ApplyModifiersOnNegativeDamage) .Process(this->ChangeOwner) .Process(this->ChangeOwner_MindControl) - .Process(this->ChangeOwner_Anim) + .Process(this->ChangeOwner_MindAnim) .Process(this->ChangeOwner_Threshold) .Process(this->ChangeOwner_AffectElites) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index d4503ca08f..a48a42e21b 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -43,7 +43,7 @@ class WarheadTypeExt Valueable ApplyModifiersOnNegativeDamage; Valueable ChangeOwner; Valueable ChangeOwner_MindControl; - Nullable ChangeOwner_Anim; + Nullable ChangeOwner_MindAnim; Valueable ChangeOwner_Threshold; Valueable ChangeOwner_AffectElites; @@ -162,7 +162,7 @@ class WarheadTypeExt , ApplyModifiersOnNegativeDamage { false } , ChangeOwner { false } , ChangeOwner_MindControl { false } - , ChangeOwner_Anim {} + , ChangeOwner_MindAnim {} , ChangeOwner_Threshold { 1.0 } , ChangeOwner_AffectElites { true } diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index a7f619b90b..e7a8c064f0 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -261,9 +261,9 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* if (pExt->Shield && pExt->Shield->IsActive() && !pExt->Shield->CanBePenetrated(this->OwnerObject())) armorType = pExt->Shield->GetArmorType(); - const auto pOwnerAnimType = this->ChangeOwner_Anim.Get(nullptr); const double ownerChangeHealthThreshold = this->ChangeOwner_Threshold; const bool isMindControl = this->ChangeOwner_MindControl; + const auto pOwnerAnimType = this->ChangeOwner_MindAnim.Get(nullptr); const bool doesAffectElites = this->ChangeOwner_AffectElites; const bool targetImmuneToPsionics = pTarget->GetTechnoType()->ImmuneToPsionics; const bool isBld = pTarget->What_Am_I() == AbstractType::Building; @@ -275,36 +275,27 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* if ((GeneralUtils::GetWarheadVersusArmor(this->OwnerObject(), armorType) != 0.0) && (!pTarget->IsMindControlled())) { pTarget->SetOwningHouse(pHouse, true); - if (pOwnerAnimType) + if (isMindControl) { - CoordStruct OwningAnimLocation = pTarget->Location; - if (isMindControl) + pTarget->MindControlledByAUnit = true; + if (pOwnerAnimType) + { + CoordStruct OwningAnimLocation = pTarget->Location; if (isBld) - OwningAnimLocation.Z += pTarget->GetTechnoType()->Height * Unsorted::LevelHeight; + OwningAnimLocation.Z += specific_cast(pTarget)->Type->Height * Unsorted::LevelHeight; else OwningAnimLocation.Z += pTarget->GetTechnoType()->MindControlRingOffset; - if (auto pOwnerAnim = GameCreate(pOwnerAnimType, OwningAnimLocation, 0, 1)) - { - pOwnerAnim->Owner = pHouse; - if (isMindControl) - { - pTarget->MindControlRingAnim = pOwnerAnim; - pTarget->MindControlledByAUnit = true; - } - else + + if (auto pOwnerAnim = GameCreate(pOwnerAnimType, OwningAnimLocation, 0, 1)) { pOwnerAnim->Owner = pHouse; + pTarget->MindControlRingAnim = pOwnerAnim; + pOwnerAnim->SetOwnerObject(pTarget); + if (isBld) + pOwnerAnim->ZAdjust = -1024; } - pOwnerAnim->SetOwnerObject(pTarget); - if (isBld) - pOwnerAnim->ZAdjust = -1024; } } - else - { - if (isMindControl) - pTarget->MindControlledByAUnit = true; - } } } } From 23e760503aa4eb918c8933f9ac0e882783e4cf63 Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Tue, 16 Dec 2025 18:13:43 +0800 Subject: [PATCH 08/12] fix mind control anim --- src/Ext/WarheadType/Detonate.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index ab8de6a603..f6ecaaa170 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -487,19 +487,18 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* { pTarget->MindControlledByAUnit = true; - if (const auto pOwnerAnimType = this->ChangeOwner_MindControlAnim.Get()) + if (const auto pAnimType = this->ChangeOwner_MindControlAnim.Get()) { - CoordStruct OwningAnimLocation = pTarget->Location; + CoordStruct location = pTarget->Location; const bool isBld = pTarget->What_Am_I() == AbstractType::Building; if (isBld) - OwningAnimLocation.Z += static_cast(pTarget)->Type->Height * Unsorted::LevelHeight; + location.Z += static_cast(pTarget)->Type->Height * Unsorted::LevelHeight; else - OwningAnimLocation.Z += pTarget->GetTechnoType()->MindControlRingOffset; + location.Z += pTarget->GetTechnoType()->MindControlRingOffset; - if (const auto pOwnerAnim = GameCreate(pOwnerAnimType, OwningAnimLocation, 0, 1)) + if (const auto pOwnerAnim = GameCreate(pAnimType, location)) { - pOwnerAnim->Owner = pHouse; pTarget->MindControlRingAnim = pOwnerAnim; pOwnerAnim->SetOwnerObject(pTarget); From 4eeeff7909429db7877a6f5e097df20e63a9a42e Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Thu, 18 Dec 2025 23:03:55 +0800 Subject: [PATCH 09/12] remove ChangeOwner.AffectElites --- docs/New-or-Enhanced-Logics.md | 2 -- src/Ext/WarheadType/Body.cpp | 2 -- src/Ext/WarheadType/Body.h | 2 -- src/Ext/WarheadType/Detonate.cpp | 4 +--- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index bef8cf8110..33bd308f94 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2303,7 +2303,6 @@ If you set `Crit.Warhead` to the same Warhead it is defined on, or create a chai - Warheads can now change targets owner to warhead's owner. - `ChangeOwner.SetAsMindControl` makes the effect work like permanent mind control, which respects `ImmuneToPsionics`. - `ChangeOwner.MindControlAnim` determines the mind control anim of this effect, which respects `MindControlRingOffset`. -- `ChangeOwner.AffectElites` determines if elite units can be affected by owner change. In `rulesmd.ini`: ```ini @@ -2311,7 +2310,6 @@ In `rulesmd.ini`: ChangeOwner=false ; boolean ChangeOwner.SetAsMindControl=false ; boolean ChangeOwner.MindControlAnim= ; Animation -ChangeOwner.AffectElites=true ; boolean ``` ### Convert TechnoType on impact diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 7ba33cd230..f3ac271c5a 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -311,7 +311,6 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->ChangeOwner.Read(exINI, pSection, "ChangeOwner"); this->ChangeOwner_SetAsMindControl.Read(exINI, pSection, "ChangeOwner.SetAsMindControl"); this->ChangeOwner_MindControlAnim.Read(exINI, pSection, "ChangeOwner.MindControlAnim"); - this->ChangeOwner_AffectElites.Read(exINI, pSection, "ChangeOwner.AffectElites"); // Convert.From & Convert.To TypeConvertGroup::Parse(this->Convert_Pairs, exINI, pSection, AffectedHouse::All); @@ -608,7 +607,6 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->ChangeOwner) .Process(this->ChangeOwner_SetAsMindControl) .Process(this->ChangeOwner_MindControlAnim) - .Process(this->ChangeOwner_AffectElites) // Ares tags .Process(this->AffectsEnemies) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index b662d2c8a9..7602822032 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -215,7 +215,6 @@ class WarheadTypeExt Valueable ChangeOwner; Valueable ChangeOwner_SetAsMindControl; Nullable ChangeOwner_MindControlAnim; - Valueable ChangeOwner_AffectElites; // Ares tags // http://ares-developers.github.io/Ares-docs/new/warheads/general.html @@ -455,7 +454,6 @@ class WarheadTypeExt , ChangeOwner { false } , ChangeOwner_SetAsMindControl { false } , ChangeOwner_MindControlAnim {} - , ChangeOwner_AffectElites { true } { } void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget); diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index f6ecaaa170..1427873c5c 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -475,9 +475,7 @@ HouseClass* WarheadTypeExt::ExtData::ApplyRemoveMindControl(HouseClass* pHouse, void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget) { const bool isMindControl = this->ChangeOwner_SetAsMindControl; - const bool affectElites = this->ChangeOwner_AffectElites; - const bool isImmune = (isMindControl && pTarget->GetTechnoType()->ImmuneToPsionics) - || (!affectElites && pTarget->Veterancy.IsElite()) || pTarget->IsMindControlled(); + const bool isImmune = (isMindControl && pTarget->GetTechnoType()->ImmuneToPsionics) || pTarget->IsMindControlled(); if (!isImmune) { From e2d0c386b22e5b4bf00c58d977fdf19a810a0df8 Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Thu, 18 Dec 2025 23:05:22 +0800 Subject: [PATCH 10/12] remove ChangeOwnerImmunities --- src/Ext/TechnoType/Body.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index a8ad5e629d..8bc0d57d8c 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -372,8 +372,6 @@ class TechnoTypeExt Nullable RadarInvisibleToHouse; - NullableVector ChangeOwnerImmunities; - struct LaserTrailDataEntry { ValueableIdx idxType; @@ -854,8 +852,6 @@ class TechnoTypeExt , InfantryAutoDeploy {} , TurretResponse {} - - , ChangeOwnerImmunities {} { } virtual ~ExtData() = default; From 4541bacec0a5aa496c63aca9e6844023921ba0c0 Mon Sep 17 00:00:00 2001 From: Fryone Date: Sat, 20 Dec 2025 21:06:52 +0300 Subject: [PATCH 11/12] Added timed control - applied timed control if ChangeOwner.Duration is set - no faulty checks for now --- YRpp | 2 +- src/Ext/Techno/Body.Update.cpp | 13 +++++++++++++ src/Ext/Techno/Body.cpp | 4 +++- src/Ext/Techno/Body.h | 5 +++++ src/Ext/WarheadType/Body.cpp | 2 ++ src/Ext/WarheadType/Body.h | 2 ++ src/Ext/WarheadType/Detonate.cpp | 7 +++++++ 7 files changed, 33 insertions(+), 2 deletions(-) diff --git a/YRpp b/YRpp index dd9c4cf1d7..79783a3f48 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit dd9c4cf1d742d0b6db6a5edd8d715b8dd15ce1b9 +Subproject commit 79783a3f48308301a84f51c9156b12da07ef25f9 diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index 1be8e43495..fc51faa01d 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -43,6 +43,7 @@ void TechnoExt::ExtData::OnEarlyUpdate() this->ApplyMindControlRangeLimit(); this->UpdateRecountBurst(); this->UpdateRearmInEMPState(); + this->UpdateOwnerTimer(); if (this->AttackMoveFollowerTempCount) this->AttackMoveFollowerTempCount--; @@ -2136,3 +2137,15 @@ void TechnoExt::ExtData::UpdateTintValues() calculateTint(Drawing::RGB_To_Int(pShieldType->Tint_Color), static_cast(pShieldType->Tint_Intensity * 1000), pShieldType->Tint_VisibleToHouses); } } + +void TechnoExt::ExtData::UpdateOwnerTimer() +{ + auto const pThis = this->OwnerObject(); + + if (this->OwnerTimer.Completed()) + { + pThis->Owner = this->OwnerOriginalOwner->Defeated + ? HouseClass::FindNeutral() : this->OwnerOriginalOwner; + //this->OwnerOriginalOwner = NULL; + } +} diff --git a/src/Ext/Techno/Body.cpp b/src/Ext/Techno/Body.cpp index 8ddfcf20f1..0fb3bf6e38 100644 --- a/src/Ext/Techno/Body.cpp +++ b/src/Ext/Techno/Body.cpp @@ -840,7 +840,7 @@ bool TechnoExt::SimpleDeployerAllowedToDeploy(UnitClass* pThis, bool defaultValu const bool isLander = pType->DeployToLand && (isJumpjet || isHover); disallowedLandTypes = isLander ? (LandTypeFlags)(LandTypeFlags::Water | LandTypeFlags::Beach) : LandTypeFlags::None; } - + if (IsLandTypeInFlags(disallowedLandTypes, pThis->GetCell()->LandType)) return false; @@ -947,6 +947,8 @@ void TechnoExt::ExtData::Serialize(T& Stm) .Process(this->SpecialTracked) .Process(this->FallingDownTracked) .Process(this->JumpjetStraightAscend) + .Process(this->OwnerTimer) + .Process(this->OwnerOriginalOwner) ; } diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index 89ed549edf..eae66e1662 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -102,6 +102,8 @@ class TechnoExt bool FallingDownTracked; bool JumpjetStraightAscend; // Is set to true jumpjet units will ascend straight and do not adjust rotation or position during it. + CDTimerClass OwnerTimer; + HouseClass* OwnerOriginalOwner; ExtData(TechnoClass* OwnerObject) : Extension(OwnerObject) , TypeExtData { nullptr } @@ -169,6 +171,8 @@ class TechnoExt , SpecialTracked { false } , FallingDownTracked { false } , JumpjetStraightAscend { false } + , OwnerTimer {} + , OwnerOriginalOwner {} { } void OnEarlyUpdate(); @@ -207,6 +211,7 @@ class TechnoExt int ApplyForceWeaponInRange(AbstractClass* pTarget); void ResetDelayedFireTimer(); void UpdateTintValues(); + void UpdateOwnerTimer(); void AmmoAutoConvertActions(); diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index b9426577c7..58b9f27386 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -311,6 +311,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->ChangeOwner.Read(exINI, pSection, "ChangeOwner"); this->ChangeOwner_SetAsMindControl.Read(exINI, pSection, "ChangeOwner.SetAsMindControl"); this->ChangeOwner_MindControlAnim.Read(exINI, pSection, "ChangeOwner.MindControlAnim"); + this->ChangeOwner_Duration.Read(exINI, pSection, "ChangeOwner.Duration"); // Convert.From & Convert.To TypeConvertGroup::Parse(this->Convert_Pairs, exINI, pSection, AffectedHouse::All); @@ -607,6 +608,7 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->ChangeOwner) .Process(this->ChangeOwner_SetAsMindControl) .Process(this->ChangeOwner_MindControlAnim) + .Process(this->ChangeOwner_Duration) // Ares tags .Process(this->AffectsEnemies) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index 7602822032..b5d7775775 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -215,6 +215,7 @@ class WarheadTypeExt Valueable ChangeOwner; Valueable ChangeOwner_SetAsMindControl; Nullable ChangeOwner_MindControlAnim; + Nullable ChangeOwner_Duration; // Ares tags // http://ares-developers.github.io/Ares-docs/new/warheads/general.html @@ -454,6 +455,7 @@ class WarheadTypeExt , ChangeOwner { false } , ChangeOwner_SetAsMindControl { false } , ChangeOwner_MindControlAnim {} + , ChangeOwner_Duration {} { } void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget); diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 1427873c5c..39881a8a1a 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -479,6 +479,13 @@ void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* if (!isImmune) { + if(this->ChangeOwner_Duration) + { + auto const pTargetExt = TechnoExt::ExtMap.Find(pTarget); + pTargetExt->OwnerOriginalOwner = pTarget->Owner; + pTargetExt->OwnerTimer.Start(this->ChangeOwner_Duration); + } + pTarget->SetOwningHouse(pHouse, true); if (isMindControl) From e4593a780e4e1d8da402bad4bbc41599b7db9f4b Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Tue, 23 Dec 2025 00:27:04 +0800 Subject: [PATCH 12/12] update ChangeOwner.Duration --- YRpp | 2 +- docs/New-or-Enhanced-Logics.md | 13 +++++++++---- src/Ext/House/Hooks.cpp | 2 ++ src/Ext/Techno/Body.Update.cpp | 7 ++----- src/Ext/Techno/Body.cpp | 1 + src/Ext/Techno/Body.h | 2 ++ src/Ext/WarheadType/Body.cpp | 2 ++ src/Ext/WarheadType/Body.h | 2 ++ src/Ext/WarheadType/Detonate.cpp | 16 ++++++++++------ 9 files changed, 31 insertions(+), 16 deletions(-) diff --git a/YRpp b/YRpp index 79783a3f48..5af96790ce 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 79783a3f48308301a84f51c9156b12da07ef25f9 +Subproject commit 5af96790ce73e4ea068a390c60c124dccbc220e1 diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 33bd308f94..5d86d36bf7 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2303,13 +2303,18 @@ If you set `Crit.Warhead` to the same Warhead it is defined on, or create a chai - Warheads can now change targets owner to warhead's owner. - `ChangeOwner.SetAsMindControl` makes the effect work like permanent mind control, which respects `ImmuneToPsionics`. - `ChangeOwner.MindControlAnim` determines the mind control anim of this effect, which respects `MindControlRingOffset`. +- If `ChangeOwner.Duration` is set, the target will switch back to its original owner after these many frames has passed. Can't be used on effect with `ChangeOwner.SetAsMindControl=true`. + - If another house changing effect happens within the duration (f. ex. capture, mind control, other `ChangeOwner=true` warheads), this switchback of owner won't happen. + - `ChangeOwner.Duration.PreventChange` determines whether another change owner warhead effect can be applied to the target within the duration of current effect. In `rulesmd.ini`: ```ini -[SOMEWARHEAD] ; WarheadType -ChangeOwner=false ; boolean -ChangeOwner.SetAsMindControl=false ; boolean -ChangeOwner.MindControlAnim= ; Animation +[SOMEWARHEAD] ; WarheadType +ChangeOwner=false ; boolean +ChangeOwner.SetAsMindControl=false ; boolean +ChangeOwner.MindControlAnim= ; Animation +ChangeOwner.Duration= ; interger +ChangeOwner.Duration.PreventChange=false ; boolean ``` ### Convert TechnoType on impact diff --git a/src/Ext/House/Hooks.cpp b/src/Ext/House/Hooks.cpp index 2152239bd1..245290dbfa 100644 --- a/src/Ext/House/Hooks.cpp +++ b/src/Ext/House/Hooks.cpp @@ -314,6 +314,8 @@ DEFINE_HOOK(0x7015C9, TechnoClass_Captured_UpdateTracking, 0x6) pTrail->CurrentColor = pNewOwner->LaserColor; } + pExt->OwnerTimer.Stop(); + return 0; } diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index fc51faa01d..a0f66a0e20 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -2140,12 +2140,9 @@ void TechnoExt::ExtData::UpdateTintValues() void TechnoExt::ExtData::UpdateOwnerTimer() { - auto const pThis = this->OwnerObject(); - if (this->OwnerTimer.Completed()) { - pThis->Owner = this->OwnerOriginalOwner->Defeated - ? HouseClass::FindNeutral() : this->OwnerOriginalOwner; - //this->OwnerOriginalOwner = NULL; + this->OwnerObject()->SetOwningHouse(this->OwnerOriginalOwner); + this->ImmuneToChangeOwner = false; } } diff --git a/src/Ext/Techno/Body.cpp b/src/Ext/Techno/Body.cpp index 0fb3bf6e38..8f692693a4 100644 --- a/src/Ext/Techno/Body.cpp +++ b/src/Ext/Techno/Body.cpp @@ -949,6 +949,7 @@ void TechnoExt::ExtData::Serialize(T& Stm) .Process(this->JumpjetStraightAscend) .Process(this->OwnerTimer) .Process(this->OwnerOriginalOwner) + .Process(this->ImmuneToChangeOwner) ; } diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index eae66e1662..149d04e4b2 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -104,6 +104,7 @@ class TechnoExt bool JumpjetStraightAscend; // Is set to true jumpjet units will ascend straight and do not adjust rotation or position during it. CDTimerClass OwnerTimer; HouseClass* OwnerOriginalOwner; + bool ImmuneToChangeOwner; ExtData(TechnoClass* OwnerObject) : Extension(OwnerObject) , TypeExtData { nullptr } @@ -173,6 +174,7 @@ class TechnoExt , JumpjetStraightAscend { false } , OwnerTimer {} , OwnerOriginalOwner {} + , ImmuneToChangeOwner { false } { } void OnEarlyUpdate(); diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 58b9f27386..9fdb25f7e2 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -312,6 +312,7 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->ChangeOwner_SetAsMindControl.Read(exINI, pSection, "ChangeOwner.SetAsMindControl"); this->ChangeOwner_MindControlAnim.Read(exINI, pSection, "ChangeOwner.MindControlAnim"); this->ChangeOwner_Duration.Read(exINI, pSection, "ChangeOwner.Duration"); + this->ChangeOwner_Duration_PreventChange.Read(exINI, pSection, "ChangeOwner.Duration.PreventChange"); // Convert.From & Convert.To TypeConvertGroup::Parse(this->Convert_Pairs, exINI, pSection, AffectedHouse::All); @@ -609,6 +610,7 @@ void WarheadTypeExt::ExtData::Serialize(T& Stm) .Process(this->ChangeOwner_SetAsMindControl) .Process(this->ChangeOwner_MindControlAnim) .Process(this->ChangeOwner_Duration) + .Process(this->ChangeOwner_Duration_PreventChange) // Ares tags .Process(this->AffectsEnemies) diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index b5d7775775..2b5551cd0d 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -216,6 +216,7 @@ class WarheadTypeExt Valueable ChangeOwner_SetAsMindControl; Nullable ChangeOwner_MindControlAnim; Nullable ChangeOwner_Duration; + Valueable ChangeOwner_Duration_PreventChange; // Ares tags // http://ares-developers.github.io/Ares-docs/new/warheads/general.html @@ -456,6 +457,7 @@ class WarheadTypeExt , ChangeOwner_SetAsMindControl { false } , ChangeOwner_MindControlAnim {} , ChangeOwner_Duration {} + , ChangeOwner_Duration_PreventChange { false } { } void ApplyConvert(HouseClass* pHouse, TechnoClass* pTarget); diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 39881a8a1a..9a03ce84ee 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -474,19 +474,23 @@ HouseClass* WarheadTypeExt::ExtData::ApplyRemoveMindControl(HouseClass* pHouse, void WarheadTypeExt::ExtData::ApplyOwnerChange(HouseClass* pHouse, TechnoClass* pTarget) { + auto const pTargetExt = TechnoExt::ExtMap.Find(pTarget); const bool isMindControl = this->ChangeOwner_SetAsMindControl; - const bool isImmune = (isMindControl && pTarget->GetTechnoType()->ImmuneToPsionics) || pTarget->IsMindControlled(); + const bool isImmune = pTargetExt->ImmuneToChangeOwner || (isMindControl && pTarget->GetTechnoType()->ImmuneToPsionics) || pTarget->IsMindControlled(); if (!isImmune) { - if(this->ChangeOwner_Duration) + auto const pOwner = pTarget->Owner; + pTarget->SetOwningHouse(pHouse, true); + pTargetExt->OwnerOriginalOwner = pOwner; + + if (this->ChangeOwner_Duration && !isMindControl) { - auto const pTargetExt = TechnoExt::ExtMap.Find(pTarget); - pTargetExt->OwnerOriginalOwner = pTarget->Owner; pTargetExt->OwnerTimer.Start(this->ChangeOwner_Duration); - } - pTarget->SetOwningHouse(pHouse, true); + if (this->ChangeOwner_Duration_PreventChange) + pTargetExt->ImmuneToChangeOwner = true; + } if (isMindControl) {