Skip to content

Commit 280b1c8

Browse files
committed
Fix some idiosyncracies with animation damage
- Adjust Damage.IsDealtByInvoker=true code path fallbacks for house dealing damage: InvokerHouse -> invoker's owner -> anim owner -> fallbacks mentioned in second bullet - Restore fallback for house dealing damage to use owner objects (attachee) or parent building's owning house if available, separately from invoker logic - Clarify some of the behaviour in docs
1 parent 71d1329 commit 280b1c8

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

docs/Fixed-or-Improved-Logics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ LandingDir= ; Direction type (integers from 0-255). Accepts negative values
328328

329329
- `Weapon` can be set to a WeaponType, to create a projectile and immediately detonate it instead of simply dealing `Damage` by `Warhead`. This allows weapon effects to be applied.
330330
- `Damage.Delay` determines delay between two applications of `Damage`. Requires `Damage` to be set to 1.0 or above. Value of 0 disables the delay. Keep in mind that this is measured in animation frames, not game frames. Depending on `Rate`, animation may or may not advance animation frames on every game frame.
331-
- `Damage.DealtByInvoker`, if set to true, makes any `Damage` dealt to be considered as coming from the animation's invoker (f.ex, firer of the weapon if it is Warhead `AnimList/SplashList` animation, the destroyed vehicle if it is `DestroyAnim` animation or the object the animation is attached to). If invoker has died or does not exist, the house the invoker belonged to is still used to deal damage and apply Phobos-introduced Warhead effects. Does not affect which house the `Damage` dealt by `Warhead` is dealt by.
331+
- `Damage.DealtByInvoker`, if set to true, makes any `Damage` dealt to be considered as coming from the animation's invoker (f.ex, firer of the weapon if it is Warhead `AnimList/SplashList` animation, the destroyed vehicle if it is `DestroyAnim` animation or the object the animation is attached to). If invoker has died or does not exist, the house the invoker belonged to is still used to deal damage and apply Phobos-introduced Warhead effects etc. If not set, the animation's owner house, or failing that, owning house of object it is attached to or the building it belongs to is used to deal the damage.
332332
- `Damage.ApplyFirepowerMult` determines whether or not firepower modifiers from the animation's invoker are applied on the damage dealt from this animation, if exists.
333333
- `Damage.ApplyOncePerLoop`, if set to true, makes `Damage` be dealt only once per animation loop (on single loop animations, only once, period) instead of on every frame or intervals defined by `Damage.Delay`. The frame on which it is dealt is determined by `Damage.Delay`, defaulting to after the first animation frame.
334334

src/Ext/Anim/Hooks.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ DEFINE_HOOK(0x42453E, AnimClass_AI_Damage, 0x6)
100100
const auto pExt = AnimExt::ExtMap.Find(pThis);
101101
pInvoker = pExt->Invoker;
102102

103-
if (pExt->InvokerHouse)
104-
pOwner = pExt->InvokerHouse;
105-
106103
if (!pInvoker)
107104
{
108105
if (pThis->OwnerObject)
@@ -111,16 +108,29 @@ DEFINE_HOOK(0x42453E, AnimClass_AI_Damage, 0x6)
111108
pInvoker = pExt->ParentBuilding;
112109
}
113110

111+
if (pExt->InvokerHouse)
112+
pOwner = pExt->InvokerHouse;
113+
114114
if (pInvoker)
115115
{
116-
if (!pOwner)
116+
if (!pExt->InvokerHouse)
117117
pOwner = pInvoker->Owner;
118118

119119
if (pTypeExt->Damage_ApplyFirepowerMult)
120120
appliedDamage = static_cast<int>(appliedDamage * pInvoker->FirepowerMultiplier * TechnoExt::ExtMap.Find(pInvoker)->AE.FirepowerMultiplier);
121121
}
122122
}
123123

124+
// Jun 29, 2025 - Starkku: Owner != Invoker. Previously OwnerObject / ParentBuilding fallback only existed for Warheads
125+
// but if we are unifying the approaches it needs to be available even without and separately from invoker.
126+
if (!pOwner)
127+
{
128+
if (pThis->OwnerObject)
129+
pOwner = pThis->OwnerObject->GetOwningHouse();
130+
else if (pThis->IsBuildingAnim)
131+
pOwner = AnimExt::ExtMap.Find(pThis)->ParentBuilding->Owner;
132+
}
133+
124134
if (pTypeExt->Weapon)
125135
{
126136
WeaponTypeExt::DetonateAt(pTypeExt->Weapon, pThis->GetCoords(), pInvoker, appliedDamage, pOwner);

0 commit comments

Comments
 (0)