From 2b28804040d2c09972fddfeb294ae3f09ae112cd Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Mon, 16 Sep 2024 14:24:17 +0800 Subject: [PATCH 1/5] random anims --- docs/New-or-Enhanced-Logics.md | 39 ++++++++++++------- src/Ext/Anim/Hooks.AnimCreateUnit.cpp | 13 ++++--- src/Ext/AnimType/Body.cpp | 1 + src/Ext/AnimType/Body.h | 2 +- src/Ext/Techno/Body.Update.cpp | 18 ++++++--- src/Ext/TechnoType/Body.cpp | 1 + src/Ext/TechnoType/Body.h | 2 +- src/Ext/TerrainType/Body.cpp | 9 ++++- src/Ext/TerrainType/Body.h | 2 +- src/Ext/WarheadType/Body.cpp | 2 + src/Ext/WarheadType/Body.h | 4 +- src/Ext/WarheadType/Detonate.cpp | 9 ++++- src/New/Entity/ShieldClass.cpp | 30 ++++++++++---- .../Affiliated/PassengerDeletionTypeClass.cpp | 1 + .../Affiliated/PassengerDeletionTypeClass.h | 2 +- src/New/Type/ShieldTypeClass.cpp | 2 + src/New/Type/ShieldTypeClass.h | 4 +- 17 files changed, 97 insertions(+), 44 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index f42cf5bb76..7d2c07b1f5 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -289,8 +289,10 @@ IdleAnimDamaged.ConditionYellow= ; Animation IdleAnimDamaged.ConditionRed= ; Animation IdleAnim.OfflineAction=Hides ; AttachedAnimFlag (None, Hides, Temporal, Paused or PausedTemporal) IdleAnim.TemporalAction=Hides ; AttachedAnimFlag (None, Hides, Temporal, Paused or PausedTemporal) -BreakAnim= ; Animation -HitAnim= ; Animation +BreakAnim= ; list of Animation +BreakAnims= ; list of Animation, overrides BreakAnim +HitAnim= ; list of Animation +HitAnims= ; list of Animation, overrides HitAnim HitFlash=false ; boolean HitFlash.FixedSize= ; integer HitFlash.Red=true ; boolean @@ -315,8 +317,10 @@ ShieldType=SOMESHIELDTYPE ; ShieldType; none by default [SOMEWARHEAD] ; WarheadType Shield.Penetrate=false ; boolean Shield.Break=false ; boolean -Shield.BreakAnim= ; Animation -Shield.HitAnim= ; Animation +Shield.BreakAnim= ; list of Animation +Shield.BreakAnims= ; list of Animation, overrides Shield.BreakAnim +Shield.HitAnim= ; list of Animation +Shield.HitAnims= ; list of Animation, overrides Shield.HitAnim Shield.SkipHitAnim=false ; boolean Shield.HitFlash=true ; boolean Shield.BreakWeapon= ; WeaponType @@ -372,8 +376,8 @@ Shield.InheritStateOnReplace=false ; boolean - `Bouncer=true` and `IsMeteor=true` animations can exhibit irregular behaviour when used as `IdleAnim` and should be avoided. - `IdleAnim.OfflineAction` indicates what happens to the animation when the shield is in a low power state. - `IdleAnim.TemporalAction` indicates what happens to the animation when the shield is attacked by temporal weapons. -- `BreakAnim`, if set, will be played when the shield has been broken. -- `HitAnim`, if set, will be played when the shield is attacked, similar to `WeaponNullifyAnim` for Iron Curtain. +- `BreakAnim(s)`, if set, will be played when the shield has been broken. If more than one animation is listed, a random one is selected. If both are set, `BreakAnims` will override `BreakAnim`. +- `HitAnim(s)`, if set, will be played when the shield is attacked, similar to `WeaponNullifyAnim` for Iron Curtain. If more than one animation is listed, a random one is selected. If both are set, `HitAnims` will override `HitAnim`. - `HitFlash`, if set to true, makes it so that a light flash is generated when the shield is attacked by a Warhead unless it has `Shield.HitFlash=false`. Size of the flash is determined by damage dealt, unless `HitFlash.FixedSize` is set to a number, in which case that value is used instead (range of values that produces visible effect are increments of 4 from 81 to 252, anything higher or below does not have effect). Color can be customized via `HitFlash.Red/Green/Blue`. If `HitFlash.Black` is set to true, the generated flash will be black regardless of other color settings. - `BreakWeapon`, if set, will be fired at the TechnoType once the shield breaks. - `AbsorbPercent` controls the percentage of damage that will be absorbed by the shield. Defaults to 1.0, meaning full damage absorption. @@ -394,8 +398,8 @@ Shield.InheritStateOnReplace=false ; boolean - Warheads have new options that interact with shields. Note that all of these that do not by their very nature require ability to target the shield (such as modifiers like `Shield.Break` or removing / attaching) still require Warhead `Verses` to affect the target unless `EffectsRequireVerses` is set to false on the Warhead. - `Shield.Penetrate` allows the warhead ignore the shield and always deal full damage to the TechnoType itself. It also allows targeting the TechnoType as if shield doesn't exist. - `Shield.Break` allows the warhead to always break shields of TechnoTypes. This is done before damage is dealt. - - `Shield.BreakAnim` will be displayed instead of ShieldType `BreakAnim` if the shield is broken by the Warhead, either through damage or `Shield.Break`. - - `Shield.HitAnim` will be displayed instead of ShieldType `HitAnim` if set when Warhead hits the shield. + - `Shield.BreakAnim(s)` will be displayed instead of ShieldType `BreakAnim(s)` if the shield is broken by the Warhead, either through damage or `Shield.Break`. If more than one animation is listed, a random one is selected. If both are set, `Shield.BreakAnims` will override `Shield.BreakAnim`. + - `Shield.HitAnim(s)` will be displayed instead of ShieldType `HitAnim(s)` if set when Warhead hits the shield. If more than one animation is listed, a random one is selected. If both are set, `Shield.HitAnims` will override `Shield.HitAnim`. - If `Shield.SkipHitAnim` is set to true, no hit anim is shown when the Warhead damages the shield whatsoever. - `Shield.BreakWeapon` will be fired instead of ShieldType `BreakWeapon` if the shield is broken by the Warhead, either through damage or `Shield.Break`. - `Shield.AbsorbPercent` overrides the `AbsorbPercent` value set in the ShieldType that is being damaged. @@ -431,7 +435,7 @@ Shield.InheritStateOnReplace=false ; boolean - `CreateUnit.AlwaysSpawnOnGround`, if set to true, ensures the vehicle will be created on the cell at ground level even if animation is in air. If set to false, jumpjet units spawned on ground will take off automatically after being spawned regardless. - `CreateUnit.SpawnParachutedInAir`, if set to true, makes it so that the vehicle is created with a parachute if it is spawned in air. Has no effect if `CreateUnit.AlwaysSpawnOnGround` is set to true. - `CreateUnit.ConsiderPathfinding`, if set to true, will consider whether or not the cell where the animation is located is occupied by other objects or impassable to the vehicle being created and will attempt to find a nearby cell that is not. Otherwise the vehicle will be created at the animation's location despite these obstacles if possible. - - `CreateUnit.SpawnAnim` can be used to play another animation at created unit's location after it has appeared. This animation has same owner and invoker as the parent animation. + - `CreateUnit.SpawnAnim(s)` can be used to play another animation at created unit's location after it has appeared. This animation has same owner and invoker as the parent animation. If more than one animation is listed, a random one is selected. If both are set, `CreateUnit.SpawnAnims` will override `CreateUnit.SpawnAnim`. - `CreateUnit.SpawnHeight` can be set to override the animation's height when determining where to spawn the created unit. Has no effect if `CreateUnit.AlwaysSpawnOnGround` is set to true. In `artmd.ini`: @@ -449,7 +453,8 @@ CreateUnit.InheritTurretFacings=false ; boolean CreateUnit.AlwaysSpawnOnGround=false ; boolean CreateUnit.SpawnParachutedInAir=false ; boolean CreateUnit.ConsiderPathfinding=false ; boolean -CreateUnit.SpawnAnim= ; Animation +CreateUnit.SpawnAnim= ; list of Animation +CreateUnit.SpawnAnims= ; list of Animation, overrides CreateUnit.SpawnAnim CreareUnit.SpawnHeight= ; integer, height in leptons ``` @@ -907,7 +912,7 @@ Spawner.AttackImmediately=false ; boolean - `PassengerDeletion.SoylentMultiplier` is a direct multiplier applied to the refunded amount of credits. - `PassengerDeletion.SoylentAllowedHouses` determines which houses passengers can belong to be eligible for refunding. - `PassengerDeletion.DisplaySoylent` can be set to true to display the amount of credits refunded on the transport. `PassengerDeletion.DisplaySoylentToHouses` determines which houses can see this and `PassengerDeletion.DisplaySoylentOffset` can be used to adjust the display offset. - - `PassengerDeletion.ReportSound` and `PassengerDeletion.Anim` can be used to specify a sound and animation to play when a passenger is erased, respectively. + - `PassengerDeletion.ReportSound` and `PassengerDeletion.Anim(s)` can be used to specify a sound and animation to play when a passenger is erased, respectively. If more than one animation is listed, a random one is selected. If both are set, `PassengerDeletion.Anims` will override `PassengerDeletion.Anim`. In `rulesmd.ini`: ```ini @@ -926,7 +931,8 @@ PassengerDeletion.DisplaySoylent=false ; boolean PassengerDeletion.DisplaySoylentToHouses=All ; Affected House Enumeration (none|owner/self|allies/ally|team|enemies/enemy|all) PassengerDeletion.DisplaySoylentOffset=0,0 ; X,Y, pixels relative to default PassengerDeletion.ReportSound= ; Sound -PassengerDeletion.Anim= ; Animation +PassengerDeletion.Anim= ; list of Animation +PassengerDeletion.Anims= ; list of Animation, overrides PassengerDeletion.Anim ``` ### Automatic passenger owner change to match transport owner @@ -1109,7 +1115,7 @@ 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 this option is not set, the self-destruction logic will not be enabled. `AutoDeath.VanishAnimation(s)` 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. If both are set, `AutoDeath.VanishAnimations` will override `AutoDeath.VanishAnimation`. ```{note} 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+**. @@ -1121,7 +1127,8 @@ In `rulesmd.ini`: ```ini [SOMETECHNO] ; TechnoType AutoDeath.Behavior= ; enumeration (kill | vanish | sell), default not set -AutoDeath.VanishAnimation ; Animation +AutoDeath.VanishAnimation= ; list of Animation +AutoDeath.VanishAnimations= ; list of Animation, overrides AutoDeath.VanishAnimation AutoDeath.OnAmmoDepletion=no ; boolean AutoDeath.AfterDelay=0 ; positive integer AutoDeath.TechnosDontExist= ; list of TechnoType names @@ -1279,11 +1286,13 @@ Convert.ComputerToHuman = ; TechnoType ### Destroy animation & sound - You can now specify a destroy animation and sound for a TerrainType that are played when it is destroyed. + - If more than one animation is listed in `DestroyAnim(s)`, a random one is selected. If both are set, `DestroyAnims` will override `DestroyAnim`. In `rulesmd.ini`: ```ini [SOMETERRAINTYPE] ; TerrainType -DestroyAnim= ; Animation +DestroyAnim= ; list of Animation +DestroyAnims= ; list of Animation, overrides DestroyAnim DestroySound= ; Sound ``` diff --git a/src/Ext/Anim/Hooks.AnimCreateUnit.cpp b/src/Ext/Anim/Hooks.AnimCreateUnit.cpp index 8a2fc3d2d0..3621b45a21 100644 --- a/src/Ext/Anim/Hooks.AnimCreateUnit.cpp +++ b/src/Ext/Anim/Hooks.AnimCreateUnit.cpp @@ -144,14 +144,17 @@ DEFINE_HOOK(0x424932, AnimClass_AI_CreateUnit_ActualAffects, 0x6) if (success) { - if (auto const pAnimType = pTypeExt->CreateUnit_SpawnAnim) + if (!pTypeExt->CreateUnit_SpawnAnim.empty()) { - if (auto const pAnim = GameCreate(pAnimType, location)) + if (auto const pAnimType = pTypeExt->CreateUnit_SpawnAnim[ScenarioClass::Instance->Random.RandomRanged(0, pTypeExt->CreateUnit_SpawnAnim.size() - 1)]) { - AnimExt::SetAnimOwnerHouseKind(pAnim, pInvokerHouse, nullptr, false, true); + if (auto const pAnim = GameCreate(pAnimType, location)) + { + AnimExt::SetAnimOwnerHouseKind(pAnim, pInvokerHouse, nullptr, false, true); - if (auto const pAnimExt = AnimExt::ExtMap.Find(pAnim)) - pAnimExt->SetInvoker(pInvoker, pInvokerHouse); + if (auto const pAnimExt = AnimExt::ExtMap.Find(pAnim)) + pAnimExt->SetInvoker(pInvoker, pInvokerHouse); + } } } diff --git a/src/Ext/AnimType/Body.cpp b/src/Ext/AnimType/Body.cpp index 71a4c7d95d..a250494931 100644 --- a/src/Ext/AnimType/Body.cpp +++ b/src/Ext/AnimType/Body.cpp @@ -97,6 +97,7 @@ void AnimTypeExt::ExtData::LoadFromINIFile(CCINIClass* pINI) this->CreateUnit_SpawnParachutedInAir.Read(exINI, pID, "CreateUnit.SpawnParachutedInAir"); this->CreateUnit_ConsiderPathfinding.Read(exINI, pID, "CreateUnit.ConsiderPathfinding"); this->CreateUnit_SpawnAnim.Read(exINI, pID, "CreateUnit.SpawnAnim"); + this->CreateUnit_SpawnAnim.Read(exINI, pID, "CreateUnit.SpawnAnims"); this->CreateUnit_SpawnHeight.Read(exINI, pID, "CreateUnit.SpawnHeight"); this->XDrawOffset.Read(exINI, pID, "XDrawOffset"); this->HideIfNoOre_Threshold.Read(exINI, pID, "HideIfNoOre.Threshold"); diff --git a/src/Ext/AnimType/Body.h b/src/Ext/AnimType/Body.h index ad5047ec48..315eae2ae9 100644 --- a/src/Ext/AnimType/Body.h +++ b/src/Ext/AnimType/Body.h @@ -30,7 +30,7 @@ class AnimTypeExt Valueable CreateUnit_AlwaysSpawnOnGround; Valueable CreateUnit_SpawnParachutedInAir; Valueable CreateUnit_ConsiderPathfinding; - Valueable CreateUnit_SpawnAnim; + ValueableVector CreateUnit_SpawnAnim; Nullable CreateUnit_SpawnHeight; Valueable XDrawOffset; Valueable HideIfNoOre_Threshold; diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index 4adfa8df6b..3af7a942d4 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -136,7 +136,10 @@ bool TechnoExt::ExtData::CheckDeathConditions(bool isInLimbo) // Self-destruction must be enabled const auto howToDie = pTypeExt->AutoDeath_Behavior.Get(); - const auto pVanishAnim = pTypeExt->AutoDeath_VanishAnimation; + AnimTypeClass* pVanishAnim = nullptr; + + if (!pTypeExt->AutoDeath_VanishAnimation.empty()) + pVanishAnim = pTypeExt->AutoDeath_VanishAnimation[ScenarioClass::Instance->Random.RandomRanged(0, pTypeExt->AutoDeath_VanishAnimation.size() - 1)]; // Death if no ammo if (pType->Ammo > 0 && pThis->Ammo <= 0 && pTypeExt->AutoDeath_OnAmmoDepletion) @@ -283,11 +286,16 @@ void TechnoExt::ExtData::EatPassengers() if (pDelType->ReportSound >= 0) VocClass::PlayAt(pDelType->ReportSound.Get(), pThis->GetCoords(), nullptr); - if (const auto pAnimType = pDelType->Anim.Get()) + if (!pDelType->Anim.empty()) { - auto const pAnim = GameCreate(pAnimType, pThis->Location); - pAnim->SetOwnerObject(pThis); - pAnim->Owner = pThis->Owner; + if (auto const pAnimType = pDelType->Anim[ScenarioClass::Instance->Random.RandomRanged(0, pDelType->Anim.size() - 1)]) + { + if (auto const pAnim = GameCreate(pAnimType, pThis->Location)) + { + pAnim->SetOwnerObject(pThis); + pAnim->Owner = pThis->Owner; + } + } } // Check if there is money refund diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index aef8425b07..483d9822c5 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -164,6 +164,7 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->AutoDeath_Behavior.Read(exINI, pSection, "AutoDeath.Behavior"); this->AutoDeath_VanishAnimation.Read(exINI, pSection, "AutoDeath.VanishAnimation"); + this->AutoDeath_VanishAnimation.Read(exINI, pSection, "AutoDeath.VanishAnimations"); this->AutoDeath_OnAmmoDepletion.Read(exINI, pSection, "AutoDeath.OnAmmoDepletion"); this->AutoDeath_AfterDelay.Read(exINI, pSection, "AutoDeath.AfterDelay"); this->AutoDeath_TechnosDontExist.Read(exINI, pSection, "AutoDeath.TechnosDontExist"); diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index b390188549..b341c502ae 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -67,7 +67,7 @@ class TechnoTypeExt Valueable Ammo_DeployUnlockMaximumAmount; Nullable AutoDeath_Behavior; - Valueable AutoDeath_VanishAnimation; + ValueableVector AutoDeath_VanishAnimation; Valueable AutoDeath_OnAmmoDepletion; Valueable AutoDeath_AfterDelay; ValueableVector AutoDeath_TechnosDontExist; diff --git a/src/Ext/TerrainType/Body.cpp b/src/Ext/TerrainType/Body.cpp index c0a655f609..077259c65b 100644 --- a/src/Ext/TerrainType/Body.cpp +++ b/src/Ext/TerrainType/Body.cpp @@ -5,6 +5,7 @@ #include #include +#include #include TerrainTypeExt::ExtContainer TerrainTypeExt::ExtMap; @@ -23,8 +24,11 @@ void TerrainTypeExt::ExtData::PlayDestroyEffects(const CoordStruct& coords) { VocClass::PlayIndexAtPos(this->DestroySound, coords); - if (auto const pAnimType = this->DestroyAnim) - GameCreate(pAnimType, coords); + if (!this->DestroyAnim.empty()) + { + if (auto const pAnimType = this->DestroyAnim[ScenarioClass::Instance->Random.RandomRanged(0, this->DestroyAnim.size() - 1)]) + GameCreate(pAnimType, coords); + } } void TerrainTypeExt::Remove(TerrainClass* pTerrain) @@ -78,6 +82,7 @@ void TerrainTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->SpawnsTiberium_CellsPerAnim.Read(exINI, pSection, "SpawnsTiberium.CellsPerAnim"); this->DestroyAnim.Read(exINI, pSection, "DestroyAnim"); + this->DestroyAnim.Read(exINI, pSection, "DestroyAnims"); this->DestroySound.Read(exINI, pSection, "DestroySound"); this->MinimapColor.Read(exINI, pSection, "MinimapColor"); diff --git a/src/Ext/TerrainType/Body.h b/src/Ext/TerrainType/Body.h index 560b603549..8951d69838 100644 --- a/src/Ext/TerrainType/Body.h +++ b/src/Ext/TerrainType/Body.h @@ -21,7 +21,7 @@ class TerrainTypeExt Valueable SpawnsTiberium_Range; Valueable> SpawnsTiberium_GrowthStage; Valueable> SpawnsTiberium_CellsPerAnim; - Valueable DestroyAnim; + ValueableVector DestroyAnim; ValueableIdx DestroySound; Nullable MinimapColor; Valueable IsPassable; diff --git a/src/Ext/WarheadType/Body.cpp b/src/Ext/WarheadType/Body.cpp index 281a42af65..f4831f1fb3 100644 --- a/src/Ext/WarheadType/Body.cpp +++ b/src/Ext/WarheadType/Body.cpp @@ -196,7 +196,9 @@ void WarheadTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->Shield_Penetrate.Read(exINI, pSection, "Shield.Penetrate"); this->Shield_Break.Read(exINI, pSection, "Shield.Break"); this->Shield_BreakAnim.Read(exINI, pSection, "Shield.BreakAnim"); + this->Shield_BreakAnim.Read(exINI, pSection, "Shield.BreakAnims"); this->Shield_HitAnim.Read(exINI, pSection, "Shield.HitAnim"); + this->Shield_HitAnim.Read(exINI, pSection, "Shield.HitAnims"); this->Shield_SkipHitAnim.Read(exINI, pSection, "Shield.SkipHitAnim"); this->Shield_HitFlash.Read(exINI, pSection, "Shield.HitFlash"); this->Shield_BreakWeapon.Read(exINI, pSection, "Shield.BreakWeapon"); diff --git a/src/Ext/WarheadType/Body.h b/src/Ext/WarheadType/Body.h index 90b9968f7d..a6ec9e7e9b 100644 --- a/src/Ext/WarheadType/Body.h +++ b/src/Ext/WarheadType/Body.h @@ -69,8 +69,8 @@ class WarheadTypeExt Valueable Shield_Penetrate; Valueable Shield_Break; - Valueable Shield_BreakAnim; - Valueable Shield_HitAnim; + ValueableVector Shield_BreakAnim; + ValueableVector Shield_HitAnim; Valueable Shield_SkipHitAnim; Valueable Shield_HitFlash; Nullable Shield_BreakWeapon; diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 356e1426a1..00f57ceab9 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -253,7 +253,14 @@ void WarheadTypeExt::ExtData::ApplyShieldModifiers(TechnoClass* pTarget, TechnoE }; if (this->Shield_Break && pTargetExt->Shield->IsActive() && isShieldTypeEligible(this->Shield_Break_Types.GetElements(this->Shield_AffectTypes))) - pTargetExt->Shield->BreakShield(this->Shield_BreakAnim, this->Shield_BreakWeapon); + { + AnimTypeClass* pAnimType = nullptr; + + if (!this->Shield_BreakAnim.empty()) + pAnimType = this->Shield_BreakAnim[ScenarioClass::Instance->Random.RandomRanged(0, this->Shield_BreakAnim.size() - 1)]; + + pTargetExt->Shield->BreakShield(pAnimType, this->Shield_BreakWeapon); + } if (this->Shield_Respawn_Duration > 0 && isShieldTypeEligible(this->Shield_Respawn_Types.GetElements(this->Shield_AffectTypes))) { diff --git a/src/New/Entity/ShieldClass.cpp b/src/New/Entity/ShieldClass.cpp index 4d105f7809..13be87dc94 100644 --- a/src/New/Entity/ShieldClass.cpp +++ b/src/New/Entity/ShieldClass.cpp @@ -231,7 +231,12 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args) int actualResidueDamage = Math::max(0, int((double)(originalShieldDamage - this->HP) / GeneralUtils::GetWarheadVersusArmor(args->WH, this->GetArmorType()))); //only absord percentage damage - this->BreakShield(pWHExt->Shield_BreakAnim, pWHExt->Shield_BreakWeapon.Get(nullptr)); + AnimTypeClass* pAnimType = nullptr; + + if (!pWHExt->Shield_BreakAnim.empty()) + pAnimType = pWHExt->Shield_BreakAnim[ScenarioClass::Instance->Random.RandomRanged(0, pWHExt->Shield_BreakAnim.size() - 1)]; + + this->BreakShield(pAnimType, pWHExt->Shield_BreakWeapon.Get(nullptr)); return this->Type->AbsorbOverDamage ? healthDamage : actualResidueDamage + healthDamage; } @@ -260,7 +265,14 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args) } if (!pWHExt->Shield_SkipHitAnim) - this->WeaponNullifyAnim(pWHExt->Shield_HitAnim); + { + AnimTypeClass* pAnimType = nullptr; + + if (!pWHExt->Shield_HitAnim.empty()) + pAnimType = pWHExt->Shield_HitAnim[ScenarioClass::Instance->Random.RandomRanged(0, pWHExt->Shield_HitAnim.size() - 1)]; + + this->WeaponNullifyAnim(pAnimType); + } this->HP = -residueDamage; @@ -324,10 +336,11 @@ void ShieldClass::WeaponNullifyAnim(AnimTypeClass* pHitAnim) if (this->AreAnimsHidden) return; - const auto pAnimType = pHitAnim ? pHitAnim : this->Type->HitAnim; + if (!pHitAnim && !this->Type->HitAnim.empty()) + pHitAnim = this->Type->HitAnim[ScenarioClass::Instance->Random.RandomRanged(0, this->Type->HitAnim.size() - 1)]; - if (pAnimType) - GameCreate(pAnimType, this->Techno->GetCoords()); + if (pHitAnim) + GameCreate(pHitAnim, this->Techno->GetCoords()); } bool ShieldClass::CanBeTargeted(WeaponTypeClass* pWeapon) const @@ -680,11 +693,12 @@ void ShieldClass::BreakShield(AnimTypeClass* pBreakAnim, WeaponTypeClass* pBreak if (!this->AreAnimsHidden) { - const auto pAnimType = pBreakAnim ? pBreakAnim : this->Type->BreakAnim; + if (!pBreakAnim && !this->Type->BreakAnim.empty()) + pBreakAnim = this->Type->BreakAnim[ScenarioClass::Instance->Random.RandomRanged(0, this->Type->BreakAnim.size() - 1)]; - if (pAnimType) + if (pBreakAnim) { - if (auto const pAnim = GameCreate(pAnimType, this->Techno->Location)) + if (auto const pAnim = GameCreate(pBreakAnim, this->Techno->Location)) { pAnim->SetOwnerObject(this->Techno); pAnim->Owner = this->Techno->Owner; diff --git a/src/New/Type/Affiliated/PassengerDeletionTypeClass.cpp b/src/New/Type/Affiliated/PassengerDeletionTypeClass.cpp index 0493a427fb..30a8400865 100644 --- a/src/New/Type/Affiliated/PassengerDeletionTypeClass.cpp +++ b/src/New/Type/Affiliated/PassengerDeletionTypeClass.cpp @@ -53,6 +53,7 @@ void PassengerDeletionTypeClass::LoadFromINI(CCINIClass* pINI, const char* pSect this->DisplaySoylentOffset.Read(exINI, pSection, "PassengerDeletion.DisplaySoylentOffset"); this->ReportSound.Read(exINI, pSection, "PassengerDeletion.ReportSound"); this->Anim.Read(exINI, pSection, "PassengerDeletion.Anim"); + this->Anim.Read(exINI, pSection, "PassengerDeletion.Anims"); } #pragma region(save/load) diff --git a/src/New/Type/Affiliated/PassengerDeletionTypeClass.h b/src/New/Type/Affiliated/PassengerDeletionTypeClass.h index ee2aded116..1c79a9a702 100644 --- a/src/New/Type/Affiliated/PassengerDeletionTypeClass.h +++ b/src/New/Type/Affiliated/PassengerDeletionTypeClass.h @@ -28,7 +28,7 @@ class PassengerDeletionTypeClass Valueable DisplaySoylentToHouses; Valueable DisplaySoylentOffset; ValueableIdx ReportSound; - Valueable Anim; + ValueableVector Anim; void LoadFromINI(CCINIClass* pINI, const char* pSection); bool Load(PhobosStreamReader& stm, bool registerForChange); diff --git a/src/New/Type/ShieldTypeClass.cpp b/src/New/Type/ShieldTypeClass.cpp index f913e64476..7e935aaf8b 100644 --- a/src/New/Type/ShieldTypeClass.cpp +++ b/src/New/Type/ShieldTypeClass.cpp @@ -69,7 +69,9 @@ void ShieldTypeClass::LoadFromINI(CCINIClass* pINI) this->IdleAnimDamaged.Read(exINI, pSection, "IdleAnimDamaged.%s"); this->BreakAnim.Read(exINI, pSection, "BreakAnim"); + this->BreakAnim.Read(exINI, pSection, "BreakAnims"); this->HitAnim.Read(exINI, pSection, "HitAnim"); + this->HitAnim.Read(exINI, pSection, "HitAnims"); this->HitFlash.Read(exINI, pSection, "HitFlash"); this->HitFlash_FixedSize.Read(exINI, pSection, "HitFlash.FixedSize"); this->HitFlash_Red.Read(exINI, pSection, "HitFlash.Red"); diff --git a/src/New/Type/ShieldTypeClass.h b/src/New/Type/ShieldTypeClass.h index 2dfc4d5e59..f3df109e2d 100644 --- a/src/New/Type/ShieldTypeClass.h +++ b/src/New/Type/ShieldTypeClass.h @@ -29,8 +29,8 @@ class ShieldTypeClass final : public Enumerable Valueable IdleAnim_TemporalAction; Damageable IdleAnim; Damageable IdleAnimDamaged; - Valueable BreakAnim; - Valueable HitAnim; + ValueableVector BreakAnim; + ValueableVector HitAnim; Valueable HitFlash; Nullable HitFlash_FixedSize; Valueable HitFlash_Red; From 0f30f2d96a812fb5323c46a7d6f5c6bf0261e69d Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Tue, 24 Sep 2024 16:53:20 +0800 Subject: [PATCH 2/5] random anims --- YRpp | 2 +- src/Ext/Anim/Body.cpp | 37 +++++++++++++++++++++++ src/Ext/Anim/Body.h | 2 ++ src/Ext/Anim/Hooks.AnimCreateUnit.cpp | 15 ++-------- src/Ext/Techno/Body.Update.cpp | 36 +++++----------------- src/Ext/Techno/Body.h | 2 +- src/Ext/TerrainType/Body.cpp | 8 ++--- src/Ext/WarheadType/Detonate.cpp | 9 +----- src/New/Entity/ShieldClass.cpp | 43 ++++++++------------------- src/New/Entity/ShieldClass.h | 4 +-- 10 files changed, 67 insertions(+), 91 deletions(-) diff --git a/YRpp b/YRpp index d107962d13..b08060737e 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit d107962d130d898132c182540a2c218f23548b2f +Subproject commit b08060737e9358f9660d3435888b61066fe62aa2 diff --git a/src/Ext/Anim/Body.cpp b/src/Ext/Anim/Body.cpp index 9fb253a058..e46aa215d5 100644 --- a/src/Ext/Anim/Body.cpp +++ b/src/Ext/Anim/Body.cpp @@ -189,6 +189,43 @@ void AnimExt::HandleDebrisImpact(AnimTypeClass* pExpireAnim, AnimTypeClass* pWak } } +AnimClass* AnimExt::CreateRandomAnim(std::vector AnimList, CoordStruct coords, TechnoClass* pTechno, HouseClass* pHouse, bool invoker) +{ + if (!AnimList.empty()) + { + if (auto const pAnimType = AnimList[ScenarioClass::Instance->Random.RandomRanged(0, AnimList.size() - 1)]) + { + if (auto const pAnim = GameCreate(pAnimType, coords)) + { + if (pTechno) + { + pAnim->SetOwnerObject(pTechno); + pAnim->Owner = pHouse ? pHouse : pTechno->Owner; + + if (invoker) + { + if (auto const pAnimExt = AnimExt::ExtMap.Find(pAnim)) + { + if (pHouse) + pAnimExt->SetInvoker(pTechno, pHouse); + else + pAnimExt->SetInvoker(pTechno); + } + } + } + else if (pHouse) + { + pAnim->Owner = pHouse; + } + + return pAnim; + } + } + } + + return nullptr; +} + // ============================= // load / save diff --git a/src/Ext/Anim/Body.h b/src/Ext/Anim/Body.h index 975779040e..70b52cc3e3 100644 --- a/src/Ext/Anim/Body.h +++ b/src/Ext/Anim/Body.h @@ -80,4 +80,6 @@ class AnimExt static void InvalidateTechnoPointers(TechnoClass* pTechno); static void InvalidateParticleSystemPointers(ParticleSystemClass* pParticleSystem); + + static AnimClass* CreateRandomAnim(std::vector AnimList, CoordStruct coords, TechnoClass* pTechno = nullptr, HouseClass* pHouse = nullptr, bool invoker = false); }; diff --git a/src/Ext/Anim/Hooks.AnimCreateUnit.cpp b/src/Ext/Anim/Hooks.AnimCreateUnit.cpp index 3621b45a21..80b74ca4cf 100644 --- a/src/Ext/Anim/Hooks.AnimCreateUnit.cpp +++ b/src/Ext/Anim/Hooks.AnimCreateUnit.cpp @@ -144,19 +144,8 @@ DEFINE_HOOK(0x424932, AnimClass_AI_CreateUnit_ActualAffects, 0x6) if (success) { - if (!pTypeExt->CreateUnit_SpawnAnim.empty()) - { - if (auto const pAnimType = pTypeExt->CreateUnit_SpawnAnim[ScenarioClass::Instance->Random.RandomRanged(0, pTypeExt->CreateUnit_SpawnAnim.size() - 1)]) - { - if (auto const pAnim = GameCreate(pAnimType, location)) - { - AnimExt::SetAnimOwnerHouseKind(pAnim, pInvokerHouse, nullptr, false, true); - - if (auto const pAnimExt = AnimExt::ExtMap.Find(pAnim)) - pAnimExt->SetInvoker(pInvoker, pInvokerHouse); - } - } - } + if (auto const pAnim = AnimExt::CreateRandomAnim(pTypeExt->CreateUnit_SpawnAnim, location, pInvoker, pInvokerHouse, true)) + AnimExt::SetAnimOwnerHouseKind(pAnim, pInvokerHouse, nullptr, false, true); if (pTechno->HasTurret() && pExt->FromDeathUnit && pExt->DeathUnitHasTurret && pTypeExt->CreateUnit_InheritTurretFacings) { diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index 3af7a942d4..69c8f3376f 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -136,15 +136,11 @@ bool TechnoExt::ExtData::CheckDeathConditions(bool isInLimbo) // Self-destruction must be enabled const auto howToDie = pTypeExt->AutoDeath_Behavior.Get(); - AnimTypeClass* pVanishAnim = nullptr; - - if (!pTypeExt->AutoDeath_VanishAnimation.empty()) - pVanishAnim = pTypeExt->AutoDeath_VanishAnimation[ScenarioClass::Instance->Random.RandomRanged(0, pTypeExt->AutoDeath_VanishAnimation.size() - 1)]; // Death if no ammo if (pType->Ammo > 0 && pThis->Ammo <= 0 && pTypeExt->AutoDeath_OnAmmoDepletion) { - TechnoExt::KillSelf(pThis, howToDie, pVanishAnim, isInLimbo); + TechnoExt::KillSelf(pThis, howToDie, pTypeExt->AutoDeath_VanishAnimation, isInLimbo); return true; } @@ -157,7 +153,7 @@ bool TechnoExt::ExtData::CheckDeathConditions(bool isInLimbo) } else if (this->AutoDeathTimer.Completed()) { - TechnoExt::KillSelf(pThis, howToDie, pVanishAnim, isInLimbo); + TechnoExt::KillSelf(pThis, howToDie, pTypeExt->AutoDeath_VanishAnimation, isInLimbo); return true; } } @@ -186,7 +182,7 @@ bool TechnoExt::ExtData::CheckDeathConditions(bool isInLimbo) { if (!existTechnoTypes(pTypeExt->AutoDeath_TechnosDontExist, pTypeExt->AutoDeath_TechnosDontExist_Houses, !pTypeExt->AutoDeath_TechnosDontExist_Any, pTypeExt->AutoDeath_TechnosDontExist_AllowLimboed)) { - TechnoExt::KillSelf(pThis, howToDie, pVanishAnim, isInLimbo); + TechnoExt::KillSelf(pThis, howToDie, pTypeExt->AutoDeath_VanishAnimation, isInLimbo); return true; } @@ -197,7 +193,7 @@ bool TechnoExt::ExtData::CheckDeathConditions(bool isInLimbo) { if (existTechnoTypes(pTypeExt->AutoDeath_TechnosExist, pTypeExt->AutoDeath_TechnosExist_Houses, pTypeExt->AutoDeath_TechnosExist_Any, pTypeExt->AutoDeath_TechnosExist_AllowLimboed)) { - TechnoExt::KillSelf(pThis, howToDie, pVanishAnim, isInLimbo); + TechnoExt::KillSelf(pThis, howToDie, pTypeExt->AutoDeath_VanishAnimation, isInLimbo); return true; } @@ -286,17 +282,7 @@ void TechnoExt::ExtData::EatPassengers() if (pDelType->ReportSound >= 0) VocClass::PlayAt(pDelType->ReportSound.Get(), pThis->GetCoords(), nullptr); - if (!pDelType->Anim.empty()) - { - if (auto const pAnimType = pDelType->Anim[ScenarioClass::Instance->Random.RandomRanged(0, pDelType->Anim.size() - 1)]) - { - if (auto const pAnim = GameCreate(pAnimType, pThis->Location)) - { - pAnim->SetOwnerObject(pThis); - pAnim->Owner = pThis->Owner; - } - } - } + AnimExt::CreateRandomAnim(pDelType->Anim, pThis->Location, pThis); // Check if there is money refund if (pDelType->Soylent && @@ -694,7 +680,7 @@ void TechnoExt::ApplyMindControlRangeLimit(TechnoClass* pThis) } } -void TechnoExt::KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, AnimTypeClass* pVanishAnimation, bool isInLimbo) +void TechnoExt::KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, std::vector pVanishAnimation, bool isInLimbo) { if (isInLimbo) { @@ -715,15 +701,7 @@ void TechnoExt::KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, Anim case AutoDeathBehavior::Vanish: { - if (pVanishAnimation) - { - if (auto const pAnim = GameCreate(pVanishAnimation, pThis->GetCoords())) - { - auto const pAnimExt = AnimExt::ExtMap.Find(pAnim); - pAnim->Owner = pThis->Owner; - pAnimExt->SetInvoker(pThis); - } - } + AnimExt::CreateRandomAnim(pVanishAnimation, pThis->GetCoords(), pThis, nullptr, true); pThis->KillPassengers(pThis); pThis->Stun(); diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index 0a90b4f688..99fcb80661 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -143,7 +143,7 @@ class TechnoExt static CoordStruct GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound); static void ChangeOwnerMissionFix(FootClass* pThis); - static void KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, AnimTypeClass* pVanishAnimation, bool isInLimbo = false); + static void KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, std::vector pVanishAnimation, bool isInLimbo = false); static void TransferMindControlOnDeploy(TechnoClass* pTechnoFrom, TechnoClass* pTechnoTo); static void ApplyMindControlRangeLimit(TechnoClass* pThis); static void ObjectKilledBy(TechnoClass* pThis, TechnoClass* pKiller); diff --git a/src/Ext/TerrainType/Body.cpp b/src/Ext/TerrainType/Body.cpp index 077259c65b..0eca5de4f2 100644 --- a/src/Ext/TerrainType/Body.cpp +++ b/src/Ext/TerrainType/Body.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -23,12 +24,7 @@ int TerrainTypeExt::ExtData::GetCellsPerAnim() void TerrainTypeExt::ExtData::PlayDestroyEffects(const CoordStruct& coords) { VocClass::PlayIndexAtPos(this->DestroySound, coords); - - if (!this->DestroyAnim.empty()) - { - if (auto const pAnimType = this->DestroyAnim[ScenarioClass::Instance->Random.RandomRanged(0, this->DestroyAnim.size() - 1)]) - GameCreate(pAnimType, coords); - } + AnimExt::CreateRandomAnim(this->DestroyAnim, coords); } void TerrainTypeExt::Remove(TerrainClass* pTerrain) diff --git a/src/Ext/WarheadType/Detonate.cpp b/src/Ext/WarheadType/Detonate.cpp index 00f57ceab9..356e1426a1 100644 --- a/src/Ext/WarheadType/Detonate.cpp +++ b/src/Ext/WarheadType/Detonate.cpp @@ -253,14 +253,7 @@ void WarheadTypeExt::ExtData::ApplyShieldModifiers(TechnoClass* pTarget, TechnoE }; if (this->Shield_Break && pTargetExt->Shield->IsActive() && isShieldTypeEligible(this->Shield_Break_Types.GetElements(this->Shield_AffectTypes))) - { - AnimTypeClass* pAnimType = nullptr; - - if (!this->Shield_BreakAnim.empty()) - pAnimType = this->Shield_BreakAnim[ScenarioClass::Instance->Random.RandomRanged(0, this->Shield_BreakAnim.size() - 1)]; - - pTargetExt->Shield->BreakShield(pAnimType, this->Shield_BreakWeapon); - } + pTargetExt->Shield->BreakShield(this->Shield_BreakAnim, this->Shield_BreakWeapon); if (this->Shield_Respawn_Duration > 0 && isShieldTypeEligible(this->Shield_Respawn_Types.GetElements(this->Shield_AffectTypes))) { diff --git a/src/New/Entity/ShieldClass.cpp b/src/New/Entity/ShieldClass.cpp index 13be87dc94..74a22a6084 100644 --- a/src/New/Entity/ShieldClass.cpp +++ b/src/New/Entity/ShieldClass.cpp @@ -231,12 +231,7 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args) int actualResidueDamage = Math::max(0, int((double)(originalShieldDamage - this->HP) / GeneralUtils::GetWarheadVersusArmor(args->WH, this->GetArmorType()))); //only absord percentage damage - AnimTypeClass* pAnimType = nullptr; - - if (!pWHExt->Shield_BreakAnim.empty()) - pAnimType = pWHExt->Shield_BreakAnim[ScenarioClass::Instance->Random.RandomRanged(0, pWHExt->Shield_BreakAnim.size() - 1)]; - - this->BreakShield(pAnimType, pWHExt->Shield_BreakWeapon.Get(nullptr)); + this->BreakShield(pWHExt->Shield_BreakAnim, pWHExt->Shield_BreakWeapon.Get(nullptr)); return this->Type->AbsorbOverDamage ? healthDamage : actualResidueDamage + healthDamage; } @@ -265,14 +260,7 @@ int ShieldClass::ReceiveDamage(args_ReceiveDamage* args) } if (!pWHExt->Shield_SkipHitAnim) - { - AnimTypeClass* pAnimType = nullptr; - - if (!pWHExt->Shield_HitAnim.empty()) - pAnimType = pWHExt->Shield_HitAnim[ScenarioClass::Instance->Random.RandomRanged(0, pWHExt->Shield_HitAnim.size() - 1)]; - - this->WeaponNullifyAnim(pAnimType); - } + this->WeaponNullifyAnim(pWHExt->Shield_HitAnim); this->HP = -residueDamage; @@ -331,16 +319,15 @@ void ShieldClass::ResponseAttack() } } -void ShieldClass::WeaponNullifyAnim(AnimTypeClass* pHitAnim) +void ShieldClass::WeaponNullifyAnim(std::vector pHitAnim) { if (this->AreAnimsHidden) return; - if (!pHitAnim && !this->Type->HitAnim.empty()) - pHitAnim = this->Type->HitAnim[ScenarioClass::Instance->Random.RandomRanged(0, this->Type->HitAnim.size() - 1)]; + if (pHitAnim.empty()) + pHitAnim = this->Type->HitAnim; - if (pHitAnim) - GameCreate(pHitAnim, this->Techno->GetCoords()); + AnimExt::CreateRandomAnim(pHitAnim, this->Techno->GetCoords(), this->Techno); } bool ShieldClass::CanBeTargeted(WeaponTypeClass* pWeapon) const @@ -664,7 +651,8 @@ void ShieldClass::SelfHealing() } else if (this->HP <= 0) { - this->BreakShield(); + std::vector nothing; + this->BreakShield(nothing); } } } @@ -681,7 +669,7 @@ int ShieldClass::GetPercentageAmount(double iStatus) return (int)trunc(iStatus); } -void ShieldClass::BreakShield(AnimTypeClass* pBreakAnim, WeaponTypeClass* pBreakWeapon) +void ShieldClass::BreakShield(std::vector pBreakAnim, WeaponTypeClass* pBreakWeapon) { this->HP = 0; @@ -693,17 +681,10 @@ void ShieldClass::BreakShield(AnimTypeClass* pBreakAnim, WeaponTypeClass* pBreak if (!this->AreAnimsHidden) { - if (!pBreakAnim && !this->Type->BreakAnim.empty()) - pBreakAnim = this->Type->BreakAnim[ScenarioClass::Instance->Random.RandomRanged(0, this->Type->BreakAnim.size() - 1)]; + if (!pBreakAnim.empty()) + pBreakAnim = this->Type->BreakAnim; - if (pBreakAnim) - { - if (auto const pAnim = GameCreate(pBreakAnim, this->Techno->Location)) - { - pAnim->SetOwnerObject(this->Techno); - pAnim->Owner = this->Techno->Owner; - } - } + AnimExt::CreateRandomAnim(pBreakAnim, this->Techno->Location, this->Techno); } const auto pWeaponType = pBreakWeapon ? pBreakWeapon : this->Type->BreakWeapon; diff --git a/src/New/Entity/ShieldClass.h b/src/New/Entity/ShieldClass.h index 74ab5bea2e..c18a765318 100644 --- a/src/New/Entity/ShieldClass.h +++ b/src/New/Entity/ShieldClass.h @@ -20,7 +20,7 @@ class ShieldClass int ReceiveDamage(args_ReceiveDamage* args); bool CanBeTargeted(WeaponTypeClass* pWeapon) const; bool CanBePenetrated(WarheadTypeClass* pWarhead) const; - void BreakShield(AnimTypeClass* pBreakAnim = nullptr, WeaponTypeClass* pBreakWeapon = nullptr); + void BreakShield(std::vector pBreakAnim, WeaponTypeClass* pBreakWeapon = nullptr); void SetRespawn(int duration, double amount, int rate, bool resetTimer); void SetSelfHealing(int duration, double amount, int rate, bool restartInCombat, int restartInCombatDelay, bool resetTimer); @@ -67,7 +67,7 @@ class ShieldClass void UpdateIdleAnim(); AnimTypeClass* GetIdleAnimType(); - void WeaponNullifyAnim(AnimTypeClass* pHitAnim = nullptr); + void WeaponNullifyAnim(std::vector pHitAnim); void ResponseAttack(); void CloakCheck(); From e68e6365fc7d339337b25c3701fc80798a273bf5 Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Tue, 8 Apr 2025 01:09:16 +0800 Subject: [PATCH 3/5] fix BreakAnim --- docs/New-or-Enhanced-Logics.md | 2 +- src/Ext/Techno/Body.Update.cpp | 2 +- src/Ext/Techno/Body.h | 2 +- src/Ext/TechnoType/Body.cpp | 2 +- src/Ext/TechnoType/Body.h | 2 +- src/New/Entity/ShieldClass.cpp | 6 +++--- src/New/Entity/ShieldClass.h | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 6d016b19ca..58dbd0cb77 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -470,7 +470,7 @@ CreateUnit.AlwaysSpawnOnGround=false ; boolean CreateUnit.SpawnParachutedInAir=false ; boolean CreateUnit.ConsiderPathfinding=false ; boolean CreateUnit.SpawnAnim= ; list of Animation -CreareUnit.SpawnHeight= ; integer, height in leptons +CreateUnit.SpawnHeight= ; integer, height in leptons ``` ```{note} diff --git a/src/Ext/Techno/Body.Update.cpp b/src/Ext/Techno/Body.Update.cpp index 9e95d42f2e..1c6a5d048d 100644 --- a/src/Ext/Techno/Body.Update.cpp +++ b/src/Ext/Techno/Body.Update.cpp @@ -749,7 +749,7 @@ void TechnoExt::ExtData::ApplyMindControlRangeLimit() } } -void TechnoExt::KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, std::vector pVanishAnimation, bool isInLimbo) +void TechnoExt::KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, const std::vector& pVanishAnimation, bool isInLimbo) { if (isInLimbo) { diff --git a/src/Ext/Techno/Body.h b/src/Ext/Techno/Body.h index 1130c66aaa..a2929a7bca 100644 --- a/src/Ext/Techno/Body.h +++ b/src/Ext/Techno/Body.h @@ -182,7 +182,7 @@ class TechnoExt static CoordStruct GetSimpleFLH(InfantryClass* pThis, int weaponIndex, bool& FLHFound); static void ChangeOwnerMissionFix(FootClass* pThis); - static void KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, std::vector pVanishAnimation, bool isInLimbo = false); + static void KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, const std::vector& pVanishAnimation, bool isInLimbo = false); static void ObjectKilledBy(TechnoClass* pThis, TechnoClass* pKiller); static void UpdateSharedAmmo(TechnoClass* pThis); static double GetCurrentSpeedMultiplier(FootClass* pThis); diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index 64d1d235d1..9f3c7b4c43 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -113,7 +113,7 @@ TechnoTypeClass* TechnoTypeExt::GetTechnoType(ObjectTypeClass* pType) return nullptr; } -TechnoClass* TechnoTypeExt::CreateUnit(TechnoTypeClass* pType, CoordStruct location, DirType facing, DirType* secondaryFacing, HouseClass* pOwner, std::vector pSpawnAnimType, +TechnoClass* TechnoTypeExt::CreateUnit(TechnoTypeClass* pType, CoordStruct location, DirType facing, DirType* secondaryFacing, HouseClass* pOwner, const std::vector& pSpawnAnimType, TechnoClass* pInvoker, HouseClass* pInvokerHouse, int spawnHeight, bool alwaysOnGround, bool checkPathfinding, bool parachuteIfInAir, Mission mission, Mission* missionAI) { auto const rtti = pType->WhatAmI(); diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index 06b4b3e050..f89f95a5ef 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -602,7 +602,7 @@ class TechnoTypeExt static TechnoTypeClass* GetTechnoType(ObjectTypeClass* pType); static TechnoClass* CreateUnit(TechnoTypeClass* pType, CoordStruct location, DirType facing, DirType* secondaryFacing, HouseClass* pOwner, - std::vector pSpawnAnimType, TechnoClass* pInvoker = nullptr, HouseClass* pInvokerHouse = nullptr, int spawnHeight = -1, + const std::vector& pSpawnAnimType, TechnoClass* pInvoker = nullptr, HouseClass* pInvokerHouse = nullptr, int spawnHeight = -1, bool alwaysOnGround = false, bool checkPathfinding = false, bool parachuteIfInAir = false, Mission mission = Mission::Guard, Mission* missionAI = nullptr); // Ares 0.A diff --git a/src/New/Entity/ShieldClass.cpp b/src/New/Entity/ShieldClass.cpp index 6f6809849e..e753133432 100644 --- a/src/New/Entity/ShieldClass.cpp +++ b/src/New/Entity/ShieldClass.cpp @@ -322,7 +322,7 @@ void ShieldClass::ResponseAttack() } } -void ShieldClass::WeaponNullifyAnim(std::vector pHitAnim) +void ShieldClass::WeaponNullifyAnim(std::vector& pHitAnim) { if (this->AreAnimsHidden) return; @@ -672,7 +672,7 @@ int ShieldClass::GetPercentageAmount(double iStatus) return (int)std::trunc(iStatus); } -void ShieldClass::BreakShield(std::vector pBreakAnim, WeaponTypeClass* pBreakWeapon) +void ShieldClass::BreakShield(std::vector& pBreakAnim, WeaponTypeClass* pBreakWeapon) { this->HP = 0; @@ -684,7 +684,7 @@ void ShieldClass::BreakShield(std::vector pBreakAnim, WeaponType if (!this->AreAnimsHidden) { - if (!pBreakAnim.empty()) + if (pBreakAnim.empty()) pBreakAnim = this->Type->BreakAnim; AnimExt::CreateRandomAnim(pBreakAnim, this->Techno->Location, this->Techno, nullptr, true, true); diff --git a/src/New/Entity/ShieldClass.h b/src/New/Entity/ShieldClass.h index 1c0d255d54..30b694ea8c 100644 --- a/src/New/Entity/ShieldClass.h +++ b/src/New/Entity/ShieldClass.h @@ -20,7 +20,7 @@ class ShieldClass int ReceiveDamage(args_ReceiveDamage* args); bool CanBeTargeted(WeaponTypeClass* pWeapon) const; bool CanBePenetrated(WarheadTypeClass* pWarhead) const; - void BreakShield(std::vector pBreakAnim, WeaponTypeClass* pBreakWeapon = nullptr); + void BreakShield(std::vector& pBreakAnim, WeaponTypeClass* pBreakWeapon = nullptr); void SetRespawn(int duration, double amount, int rate, bool resetTimer); void SetSelfHealing(int duration, double amount, int rate, bool restartInCombat, int restartInCombatDelay, bool resetTimer); @@ -92,7 +92,7 @@ class ShieldClass void UpdateIdleAnim(); AnimTypeClass* GetIdleAnimType(); - void WeaponNullifyAnim(std::vector pHitAnim); + void WeaponNullifyAnim(std::vector& pHitAnim); void ResponseAttack(); void CloakCheck(); From 535d40d6977d38e9917f1f47dfc5045a9da28d30 Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Tue, 8 Apr 2025 22:22:32 +0800 Subject: [PATCH 4/5] warp and promotion anim --- docs/Fixed-or-Improved-Logics.md | 7 ++++--- docs/New-or-Enhanced-Logics.md | 8 ++++---- .../LC_MESSAGES/Fixed-or-Improved-Logics.po | 12 +++++------ .../LC_MESSAGES/New-or-Enhanced-Logics.po | 16 +++++++-------- src/Ext/Rules/Body.h | 4 ++-- src/Ext/Techno/Hooks.cpp | 20 ++++++------------- src/Ext/TechnoType/Body.h | 6 +++--- src/Ext/TechnoType/Hooks.Teleport.cpp | 18 ++++++++++++++--- 8 files changed, 48 insertions(+), 43 deletions(-) diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 6cd9a6577e..e901d1c35c 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -785,13 +785,14 @@ TargetZoneScanType=same ; target zone scan enumeration (same|any|inrange) - You can now specify Teleport/Chrono Locomotor settings per TechnoType to override default rules values. Unfilled values default to values in `[General]`. - Only applicable to Techno that have Teleport/Chrono Locomotor attached. +- If more than one animation is listed in `WarpOut`, `WarpIn` or `WarpAway`, a random one is selected. In `rulesmd.ini`: ```ini [SOMETECHNO] ; TechnoType -WarpOut= ; Anim (played when Techno warping out), default to [General] WarpOut -WarpIn= ; Anim (played when Techno warping in), default to [General] WarpIn -WarpAway= ; Anim (played when Techno chronowarped by chronosphere), default to [General] WarpOut +WarpOut= ; list of Animation (played when Techno warping out), default to [General] WarpOut +WarpIn= ; list of Animation (played when Techno warping in), default to [General] WarpIn +WarpAway= ; list of Animation (played when Techno chronowarped by chronosphere), default to [General] WarpOut ChronoTrigger= ; boolean, if yes then delay varies by distance, if no it is a constant ChronoDistanceFactor= ; integer, amount to divide the distance to destination by to get the warped out delay ChronoMinimumDelay= ; integer, the minimum delay for teleporting, no matter how short the distance diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index 58dbd0cb77..ec60beb63e 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -1545,15 +1545,15 @@ Promote.IncludeSpawns=false ; boolean ### Promotion animation - You can now specify an animation on the unit or structure promotion. - - `Promote.VeteranAnimation` is used when unit or structure is promoted to veteran. - - `Promote.EliteAnimation` is used when unit or structure is promoted to elite. + - `Promote.VeteranAnimation` is used when unit or structure is promoted to veteran. If more than one animation is listed, a random one is selected. + - `Promote.EliteAnimation` is used when unit or structure is promoted to elite. If more than one animation is listed, a random one is selected. - If `Promote.EliteAnimation` is not defined, `Promote.VeteranAnimation` will play instead when unit or structure is promoted to elite. In `rulesmd.ini`: ```ini [AudioVisual] -Promote.VeteranAnimation= ; AnimationType -Promote.EliteAnimation= ; AnimationType +Promote.VeteranAnimation= ; list of Animation +Promote.EliteAnimation= ; list of Animation ``` ### Raise alert when technos are taking damage diff --git a/docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po b/docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po index 120a9af273..db4b1904fd 100644 --- a/docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po +++ b/docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po @@ -3151,11 +3151,11 @@ msgstr "仅对使用超时空运动方式的科技类型有效。" #: ../../Fixed-or-Improved-Logics.md:790 msgid "" "[SOMETECHNO] ; TechnoType\n" -"WarpOut= ; Anim (played when Techno warping out), default " +"WarpOut= ; list of Animation (played when Techno warping out), default " "to [General] WarpOut\n" -"WarpIn= ; Anim (played when Techno warping in), default " +"WarpIn= ; list of Animation (played when Techno warping in), default " "to [General] WarpIn\n" -"WarpAway= ; Anim (played when Techno chronowarped by " +"WarpAway= ; list of Animation (played when Techno chronowarped by " "chronosphere), default to [General] WarpOut\n" "ChronoTrigger= ; boolean, if yes then delay varies by distance, " "if no it is a constant\n" @@ -3168,11 +3168,11 @@ msgid "" "ChronoDelay= ; integer, delay after teleport for chronosphere\n" msgstr "" "[SOMETECHNO] ; TechnoType\n" -"WarpOut= ; Anim (played when Techno warping out), default " +"WarpOut= ; list of Animation (played when Techno warping out), default " "to [General] WarpOut\n" -"WarpIn= ; Anim (played when Techno warping in), default " +"WarpIn= ; list of Animation (played when Techno warping in), default " "to [General] WarpIn\n" -"WarpAway= ; Anim (played when Techno chronowarped by " +"WarpAway= ; list of Animation (played when Techno chronowarped by " "chronosphere), default to [General] WarpOut\n" "ChronoTrigger= ; boolean, if yes then delay varies by distance, " "if no it is a constant\n" diff --git a/docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po b/docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po index 0493b739b8..43b2342e02 100644 --- a/docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po +++ b/docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po @@ -5848,14 +5848,14 @@ msgstr "现在你可以在单位或建筑升级时播放指定动画。" #: ../../New-or-Enhanced-Logics.md:1548 msgid "" "`Promote.VeteranAnimation` is used when unit or structure is promoted to " -"veteran." -msgstr "`Promote.VeteranAnimation` 用于单位或建筑升级为老兵时。" +"veteran. If more than one animation is listed, a random one is selected." +msgstr "`Promote.VeteranAnimation` 用于单位或建筑升级为老兵时。如果列出了多个动画,则将随机选择一个。" #: ../../New-or-Enhanced-Logics.md:1549 msgid "" "`Promote.EliteAnimation` is used when unit or structure is promoted to " -"elite." -msgstr "`Promote.EliteAnimation` 用于单位或建筑升级为精英时。" +"elite. If more than one animation is listed, a random one is selected." +msgstr "`Promote.EliteAnimation` 用于单位或建筑升级为精英时。如果列出了多个动画,则将随机选择一个。" #: ../../New-or-Enhanced-Logics.md:1550 msgid "" @@ -5866,12 +5866,12 @@ msgstr "如果未定义 `Promote.EliteAnimation` 则使用 `Promote.VeteranAnima #: ../../New-or-Enhanced-Logics.md:1553 msgid "" "[AudioVisual]\n" -"Promote.VeteranAnimation= ; AnimationType\n" -"Promote.EliteAnimation= ; AnimationType\n" +"Promote.VeteranAnimation= ; list of Animation\n" +"Promote.EliteAnimation= ; list of Animation\n" msgstr "" "[AudioVisual]\n" -"Promote.VeteranAnimation= ; AnimationType\n" -"Promote.EliteAnimation= ; AnimationType\n" +"Promote.VeteranAnimation= ; list of Animation\n" +"Promote.EliteAnimation= ; list of Animation\n" #: ../../New-or-Enhanced-Logics.md:1559 msgid "Raise alert when technos are taking damage" diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index b4a5d764c2..f019519858 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -155,8 +155,8 @@ class RulesExt Valueable DrawInsignia_AdjustPos_Buildings; Nullable DrawInsignia_AdjustPos_BuildingsAnchor; Valueable DrawInsignia_AdjustPos_Units; - Valueable Promote_VeteranAnimation; - Valueable Promote_EliteAnimation; + ValueableVector Promote_VeteranAnimation; + ValueableVector Promote_EliteAnimation; Valueable DamageOwnerMultiplier; Valueable DamageAlliesMultiplier; diff --git a/src/Ext/Techno/Hooks.cpp b/src/Ext/Techno/Hooks.cpp index 80f3c891e3..a8ec4a2c49 100644 --- a/src/Ext/Techno/Hooks.cpp +++ b/src/Ext/Techno/Hooks.cpp @@ -111,23 +111,15 @@ DEFINE_HOOK(0x6F9FA9, TechnoClass_AI_PromoteAnim, 0x6) auto aresProcess = [pThis]() { return (pThis->GetTechnoType()->Turret) ? 0x6F9FB7 : 0x6FA054; }; - if (!RulesExt::Global()->Promote_VeteranAnimation && !RulesExt::Global()->Promote_EliteAnimation) + if (!RulesExt::Global()->Promote_VeteranAnimation.size() && !RulesExt::Global()->Promote_EliteAnimation.size()) return aresProcess(); if (pThis->CurrentRanking != pThis->Veterancy.GetRemainingLevel() && pThis->CurrentRanking != Rank::Invalid && (pThis->Veterancy.GetRemainingLevel() != Rank::Rookie)) { - AnimClass* promAnim = nullptr; - if (pThis->Veterancy.GetRemainingLevel() == Rank::Veteran && RulesExt::Global()->Promote_VeteranAnimation) - promAnim = GameCreate(RulesExt::Global()->Promote_VeteranAnimation, pThis->GetCenterCoords()); - else if (RulesExt::Global()->Promote_EliteAnimation) - promAnim = GameCreate(RulesExt::Global()->Promote_EliteAnimation, pThis->GetCenterCoords()); - - if (promAnim) - { - promAnim->SetOwnerObject(pThis); - AnimExt::SetAnimOwnerHouseKind(promAnim, pThis->Owner, nullptr, false, true); - AnimExt::ExtMap.Find(promAnim)->SetInvoker(pThis); - } + if (pThis->Veterancy.GetRemainingLevel() == Rank::Veteran && RulesExt::Global()->Promote_VeteranAnimation.size() > 0) + AnimExt::CreateRandomAnim(RulesExt::Global()->Promote_VeteranAnimation, pThis->GetCenterCoords(), pThis, pThis->Owner, true); + else if (RulesExt::Global()->Promote_EliteAnimation.size() > 0) + AnimExt::CreateRandomAnim(RulesExt::Global()->Promote_EliteAnimation, pThis->GetCenterCoords(), pThis, pThis->Owner, true); } return aresProcess(); @@ -738,4 +730,4 @@ DEFINE_HOOK(0x4B3DF0, LocomotionClass_Process_DamagedSpeedMultiplier, 0x6)// Dri __asm fmul multiplier; return R->Origin() + 0x6; -} \ No newline at end of file +} diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index f89f95a5ef..02ef2281c0 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -94,9 +94,9 @@ class TechnoTypeExt NullableIdx VoiceCreated; NullableIdx VoicePickup; // Used by carryalls instead of VoiceMove if set. - Nullable WarpOut; - Nullable WarpIn; - Nullable WarpAway; + ValueableVector WarpOut; + ValueableVector WarpIn; + ValueableVector WarpAway; Nullable ChronoTrigger; Nullable ChronoDistanceFactor; Nullable ChronoMinimumDelay; diff --git a/src/Ext/TechnoType/Hooks.Teleport.cpp b/src/Ext/TechnoType/Hooks.Teleport.cpp index 172285ec95..943a12c234 100644 --- a/src/Ext/TechnoType/Hooks.Teleport.cpp +++ b/src/Ext/TechnoType/Hooks.Teleport.cpp @@ -19,7 +19,11 @@ DEFINE_HOOK(0x7193F6, TeleportLocomotionClass_ILocomotion_Process_WarpoutAnim, 0 { GET_LOCO(ESI); - if (auto pWarpOut = pExt->WarpOut.Get(RulesClass::Instance->WarpOut)) + if (pExt->WarpOut.size() > 0) + { + AnimExt::CreateRandomAnim(pExt->WarpOut, pLinked->Location, nullptr, pLinked->Owner); + } + else if (auto const pWarpOut = RulesClass::Instance->WarpOut) { auto const pAnim = GameCreate(pWarpOut, pLinked->Location); AnimExt::SetAnimOwnerHouseKind(pAnim, pLinked->Owner, nullptr, false, true); @@ -74,7 +78,11 @@ DEFINE_HOOK(0x719742, TeleportLocomotionClass_ILocomotion_Process_WarpInAnim, 0x { GET_LOCO(ESI); - if (auto pWarpIn = pExt->WarpIn.Get(RulesClass::Instance->WarpIn)) + if (pExt->WarpIn.size() > 0) + { + AnimExt::CreateRandomAnim(pExt->WarpIn, pLinked->Location, nullptr, pLinked->Owner); + } + else if (auto const pWarpIn = RulesClass::Instance->WarpIn) { auto const pAnim = GameCreate(pWarpIn, pLinked->Location); AnimExt::SetAnimOwnerHouseKind(pAnim, pLinked->Owner, nullptr, false, true); @@ -96,7 +104,11 @@ DEFINE_HOOK(0x719827, TeleportLocomotionClass_ILocomotion_Process_WarpAway, 0x5) { GET_LOCO(ESI); - if (auto pWarpAway = pExt->WarpAway.Get(RulesClass::Instance->WarpOut)) + if (pExt->WarpAway.size() > 0) + { + AnimExt::CreateRandomAnim(pExt->WarpAway, pLinked->Location, nullptr, pLinked->Owner); + } + else if (auto const pWarpAway = RulesClass::Instance->WarpOut) { auto const pAnim = GameCreate(pWarpAway, pLinked->Location); AnimExt::SetAnimOwnerHouseKind(pAnim, pLinked->Owner, nullptr, false, true); From 38bf7b1b98a120119946bfdec8b970da915f9674 Mon Sep 17 00:00:00 2001 From: Coronia <2217891145@qq.com> Date: Wed, 7 May 2025 16:52:57 +0800 Subject: [PATCH 5/5] fixes --- .../LC_MESSAGES/Fixed-or-Improved-Logics.po | 4 ++-- src/Ext/TerrainType/Body.cpp | 1 - src/New/Entity/ShieldClass.cpp | 16 ++++------------ src/New/Entity/ShieldClass.h | 4 ++-- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po b/docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po index db4b1904fd..c05379b908 100644 --- a/docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po +++ b/docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po @@ -1772,7 +1772,7 @@ msgid "" "ExplodeOnWater=false ; boolean\n" "Warhead.Detonate=false ; boolean\n" "WakeAnim= ; list of Animation\n" -"SplashAnims= ; List of AnimationTypes\n" +"SplashAnims= ; list of Animation\n" "SplashAnims.PickRandom=false ; boolean\n" "ExtraShadow=true ; boolean\n" msgstr "" @@ -1780,7 +1780,7 @@ msgstr "" "ExplodeOnWater=false ; boolean\n" "Warhead.Detonate=false ; boolean\n" "WakeAnim= ; list of Animation\n" -"SplashAnims= ; List of AnimationTypes\n" +"SplashAnims= ; list of Animation\n" "SplashAnims.PickRandom=false ; boolean\n" "ExtraShadow=true ; boolean\n" diff --git a/src/Ext/TerrainType/Body.cpp b/src/Ext/TerrainType/Body.cpp index 0bd91cdcdc..acdb714c01 100644 --- a/src/Ext/TerrainType/Body.cpp +++ b/src/Ext/TerrainType/Body.cpp @@ -6,7 +6,6 @@ #include #include -#include #include TerrainTypeExt::ExtContainer TerrainTypeExt::ExtMap; diff --git a/src/New/Entity/ShieldClass.cpp b/src/New/Entity/ShieldClass.cpp index e753133432..35fe17e86a 100644 --- a/src/New/Entity/ShieldClass.cpp +++ b/src/New/Entity/ShieldClass.cpp @@ -322,15 +322,12 @@ void ShieldClass::ResponseAttack() } } -void ShieldClass::WeaponNullifyAnim(std::vector& pHitAnim) +void ShieldClass::WeaponNullifyAnim(const std::vector& pHitAnim) { if (this->AreAnimsHidden) return; - if (pHitAnim.empty()) - pHitAnim = this->Type->HitAnim; - - AnimExt::CreateRandomAnim(pHitAnim, this->Techno->GetCoords(), this->Techno, nullptr, true, true); + AnimExt::CreateRandomAnim((pHitAnim.empty() ? this->Type->HitAnim : pHitAnim), this->Techno->GetCoords(), this->Techno, nullptr, true, true); } bool ShieldClass::CanBeTargeted(WeaponTypeClass* pWeapon) const @@ -672,7 +669,7 @@ int ShieldClass::GetPercentageAmount(double iStatus) return (int)std::trunc(iStatus); } -void ShieldClass::BreakShield(std::vector& pBreakAnim, WeaponTypeClass* pBreakWeapon) +void ShieldClass::BreakShield(const std::vector& pBreakAnim, WeaponTypeClass* pBreakWeapon) { this->HP = 0; @@ -683,12 +680,7 @@ void ShieldClass::BreakShield(std::vector& pBreakAnim, WeaponTyp this->KillAnim(); if (!this->AreAnimsHidden) - { - if (pBreakAnim.empty()) - pBreakAnim = this->Type->BreakAnim; - - AnimExt::CreateRandomAnim(pBreakAnim, this->Techno->Location, this->Techno, nullptr, true, true); - } + AnimExt::CreateRandomAnim(pBreakAnim.empty() ? this->Type->BreakAnim : pBreakAnim, this->Techno->Location, this->Techno, nullptr, true, true); const auto pWeaponType = pBreakWeapon ? pBreakWeapon : this->Type->BreakWeapon; this->LastBreakFrame = Unsorted::CurrentFrame; diff --git a/src/New/Entity/ShieldClass.h b/src/New/Entity/ShieldClass.h index 30b694ea8c..372e6d5d50 100644 --- a/src/New/Entity/ShieldClass.h +++ b/src/New/Entity/ShieldClass.h @@ -20,7 +20,7 @@ class ShieldClass int ReceiveDamage(args_ReceiveDamage* args); bool CanBeTargeted(WeaponTypeClass* pWeapon) const; bool CanBePenetrated(WarheadTypeClass* pWarhead) const; - void BreakShield(std::vector& pBreakAnim, WeaponTypeClass* pBreakWeapon = nullptr); + void BreakShield(const std::vector& pBreakAnim, WeaponTypeClass* pBreakWeapon = nullptr); void SetRespawn(int duration, double amount, int rate, bool resetTimer); void SetSelfHealing(int duration, double amount, int rate, bool restartInCombat, int restartInCombatDelay, bool resetTimer); @@ -92,7 +92,7 @@ class ShieldClass void UpdateIdleAnim(); AnimTypeClass* GetIdleAnimType(); - void WeaponNullifyAnim(std::vector& pHitAnim); + void WeaponNullifyAnim(const std::vector& pHitAnim); void ResponseAttack(); void CloakCheck();