Skip to content

Commit 4dd3c7d

Browse files
committed
optimize PointerGotInvalid for AE & shield
1 parent 1f842e1 commit 4dd3c7d

File tree

7 files changed

+107
-43
lines changed

7 files changed

+107
-43
lines changed

src/Ext/Anim/Body.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ void AnimExt::ExtData::Serialize(T& Stm)
405405
.Process(this->AttachedSystem)
406406
.Process(this->ParentBuilding)
407407
.Process(this->IsTechnoTrailerAnim)
408+
.Process(this->IsAttachedEffectAnim)
409+
.Process(this->IsShieldIdleAnim)
408410
;
409411
}
410412

src/Ext/Anim/Body.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class AnimExt
2828
ParticleSystemClass* AttachedSystem;
2929
BuildingClass* ParentBuilding; // Only set on building anims, used for tinting the anims etc. especially when not on same cell as building
3030
bool IsTechnoTrailerAnim;
31+
bool IsAttachedEffectAnim;
32+
bool IsShieldIdleAnim;
3133

3234
ExtData(AnimClass* OwnerObject) : Extension<AnimClass>(OwnerObject)
3335
, DeathUnitFacing { 0 }
@@ -39,6 +41,8 @@ class AnimExt
3941
, AttachedSystem {}
4042
, ParentBuilding {}
4143
, IsTechnoTrailerAnim { false }
44+
, IsAttachedEffectAnim { false }
45+
, IsShieldIdleAnim { false }
4246
{ }
4347

4448
void SetInvoker(TechnoClass* pInvoker);

src/Ext/Techno/Body.Update.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1696,6 +1696,7 @@ void TechnoExt::ExtData::UpdateSelfOwnedAttachEffects()
16961696
std::vector<std::unique_ptr<AttachEffectClass>>::iterator it;
16971697
std::vector<WeaponTypeClass*> expireWeapons;
16981698
bool markForRedraw = false;
1699+
bool altered = false;
16991700

17001701
// Delete ones on old type and not on current.
17011702
for (it = this->AttachedEffects.begin(); it != this->AttachedEffects.end(); )
@@ -1715,6 +1716,7 @@ void TechnoExt::ExtData::UpdateSelfOwnedAttachEffects()
17151716

17161717
markForRedraw |= pType->HasTint();
17171718
it = this->AttachedEffects.erase(it);
1719+
altered = true;
17181720
}
17191721
else
17201722
{
@@ -1733,7 +1735,7 @@ void TechnoExt::ExtData::UpdateSelfOwnedAttachEffects()
17331735
// Add new ones.
17341736
const int count = AttachEffectClass::Attach(pThis, pThis->Owner, pThis, pThis, pTypeExt->AttachEffects);
17351737

1736-
if (!count)
1738+
if (altered && !count)
17371739
this->RecalculateStatMultipliers();
17381740

17391741
if (markForRedraw)

src/Ext/Techno/Body.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ void TechnoExt::ExtData::Serialize(T& Stm)
619619
.Process(this->TiberiumEater_Timer)
620620
.Process(this->AirstrikeTargetingMe)
621621
.Process(this->FiringAnimationTimer)
622+
.Process(this->AttachedEffectInvokerCount)
622623
;
623624
}
624625

src/Ext/Techno/Body.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class TechnoExt
5858
DWORD LastTargetID;
5959
int AccumulatedGattlingValue;
6060
bool ShouldUpdateGattlingValue;
61+
int AttachedEffectInvokerCount;
6162

6263
// Used for Passengers.SyncOwner.RevertOnExit instead of TechnoClass::InitialOwner / OriginallyOwnedByHouse,
6364
// as neither is guaranteed to point to the house the TechnoClass had prior to entering transport and cannot be safely overridden.
@@ -118,6 +119,7 @@ class TechnoExt
118119
, TiberiumEater_Timer {}
119120
, AirstrikeTargetingMe { nullptr }
120121
, FiringAnimationTimer {}
122+
, AttachedEffectInvokerCount { 0 }
121123
{ }
122124

123125
void OnEarlyUpdate();

src/New/Entity/AttachEffectClass.cpp

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,16 @@ AttachEffectClass::AttachEffectClass(AttachEffectTypeClass* pType, TechnoClass*
5151
if (this->InitialDelay <= 0)
5252
this->HasInitialized = true;
5353

54-
this->Duration = this->DurationOverride != 0 ? this->DurationOverride : this->Type->Duration;
54+
this->Duration = this->DurationOverride != 0 ? this->DurationOverride : pType->Duration;
5555

56-
if (this->Type->Duration_ApplyFirepowerMult && this->Duration > 0 && pInvoker)
56+
if (pType->Duration_ApplyFirepowerMult && this->Duration > 0 && pInvoker)
5757
this->Duration = Math::max(static_cast<int>(this->Duration * pInvoker->FirepowerMultiplier * TechnoExt::ExtMap.Find(pInvoker)->AE.FirepowerMultiplier), 0);
5858

59-
if (this->Type->Duration_ApplyArmorMultOnTarget && this->Duration > 0) // count its own ArmorMultiplier as well
60-
this->Duration = Math::max(static_cast<int>(this->Duration / pTechno->ArmorMultiplier / TechnoExt::ExtMap.Find(pTechno)->AE.ArmorMultiplier / this->Type->ArmorMultiplier), 0);
59+
if (pType->Duration_ApplyArmorMultOnTarget && this->Duration > 0) // count its own ArmorMultiplier as well
60+
this->Duration = Math::max(static_cast<int>(this->Duration / pTechno->ArmorMultiplier / TechnoExt::ExtMap.Find(pTechno)->AE.ArmorMultiplier / pType->ArmorMultiplier), 0);
61+
62+
if (pInvoker)
63+
TechnoExt::ExtMap.Find(pInvoker)->AttachedEffectInvokerCount++;
6164

6265
AttachEffectClass::Array.emplace_back(this);
6366
}
@@ -70,25 +73,50 @@ AttachEffectClass::~AttachEffectClass()
7073
AttachEffectClass::Array.erase(it);
7174

7275
this->KillAnim();
76+
77+
if (this->Invoker)
78+
TechnoExt::ExtMap.Find(this->Invoker)->AttachedEffectInvokerCount--;
7379
}
7480

7581
void AttachEffectClass::PointerGotInvalid(void* ptr, bool removed)
7682
{
7783
auto const abs = static_cast<AbstractClass*>(ptr);
78-
auto const absType = abs->WhatAmI();
7984

80-
if (absType == AbstractType::Anim)
85+
if (auto const pAnim = abstract_cast<AnimClass*, true>(abs))
8186
{
82-
for (auto pEffect : AttachEffectClass::Array)
87+
if (auto const pAnimExt = AnimExt::ExtMap.Find(pAnim))
8388
{
84-
if (ptr == pEffect->Animation)
85-
pEffect->Animation = nullptr;
89+
if (pAnimExt->IsAttachedEffectAnim)
90+
{
91+
for (auto const pEffect : AttachEffectClass::Array)
92+
{
93+
if (pAnim == pEffect->Animation)
94+
{
95+
pEffect->Animation = nullptr;
96+
break; // one anim must be used by less than one AE
97+
}
98+
}
99+
}
86100
}
87101
}
88102
else if ((abs->AbstractFlags & AbstractFlags::Techno) != AbstractFlags::None)
89103
{
90-
for (auto pEffect : AttachEffectClass::Array)
91-
AnnounceInvalidPointer(pEffect->Invoker, ptr);
104+
auto const pTechno = abstract_cast<TechnoClass*, true>(abs);
105+
106+
if (int count = TechnoExt::ExtMap.Find(pTechno)->AttachedEffectInvokerCount)
107+
{
108+
for (auto const pEffect : AttachEffectClass::Array)
109+
{
110+
if (pTechno == pEffect->Invoker)
111+
{
112+
AnnounceInvalidPointer(pEffect->Invoker, ptr);
113+
count--;
114+
115+
if (count <= 0)
116+
break;
117+
}
118+
}
119+
}
92120
}
93121
}
94122

@@ -314,7 +342,7 @@ void AttachEffectClass::CreateAnim()
314342
if (!this->HasCumulativeAnim)
315343
return;
316344

317-
int count = TechnoExt::ExtMap.Find(this->Techno)->GetAttachedEffectCumulativeCount(this->Type);
345+
const int count = TechnoExt::ExtMap.Find(this->Techno)->GetAttachedEffectCumulativeCount(this->Type);
318346
pAnimType = this->Type->GetCumulativeAnimation(count);
319347
}
320348
else
@@ -327,18 +355,22 @@ void AttachEffectClass::CreateAnim()
327355

328356
if (!this->Animation && pAnimType)
329357
{
330-
auto const pAnim = GameCreate<AnimClass>(pAnimType, this->Techno->Location);
358+
auto const pTechno = this->Techno;
359+
auto const pAnim = GameCreate<AnimClass>(pAnimType, pTechno->Location);
331360

332-
pAnim->SetOwnerObject(this->Techno);
333-
auto const pOwner = this->Type->Animation_UseInvokerAsOwner ? this->InvokerHouse : this->Techno->Owner;
334-
pAnim->Owner = pOwner;
335-
pAnim->RemainingIterations = 0xFFu;
336-
this->Animation = pAnim;
361+
pAnim->SetOwnerObject(pTechno);
362+
pAnim->Owner = this->Type->Animation_UseInvokerAsOwner ? this->InvokerHouse : pTechno->Owner;
363+
364+
auto const pAnimExt = AnimExt::ExtMap.Find(pAnim);
365+
pAnimExt->IsAttachedEffectAnim = true;
337366

338367
if (this->Type->Animation_UseInvokerAsOwner)
339-
AnimExt::ExtMap.Find(pAnim)->SetInvoker(this->Invoker, this->InvokerHouse);
368+
pAnimExt->SetInvoker(this->Invoker, this->InvokerHouse);
340369
else
341-
AnimExt::ExtMap.Find(pAnim)->SetInvoker(this->Techno);
370+
pAnimExt->SetInvoker(pTechno);
371+
372+
pAnim->RemainingIterations = 0xFFu;
373+
this->Animation = pAnim;
342374
}
343375
}
344376

@@ -636,12 +668,14 @@ AttachEffectClass* AttachEffectClass::CreateAndAttach(AttachEffectTypeClass* pTy
636668
currentTypeCount++;
637669
match = attachEffect;
638670

639-
if (pType->Cumulative && (!attachParams.CumulativeRefreshSameSourceOnly || (attachEffect->Source == pSource && attachEffect->Invoker == pInvoker)))
671+
if (!pType->Cumulative)
672+
break;
673+
else if (!attachParams.CumulativeRefreshSameSourceOnly || (attachEffect->Source == pSource && attachEffect->Invoker == pInvoker))
640674
cumulativeMatches.push_back(attachEffect);
641675
}
642676
}
643677

644-
if (pType->Cumulative)
678+
if (cumulativeMatches.size() > 0)
645679
{
646680
if (pType->Cumulative_MaxCount >= 0 && currentTypeCount >= pType->Cumulative_MaxCount)
647681
{
@@ -654,18 +688,15 @@ AttachEffectClass* AttachEffectClass::CreateAndAttach(AttachEffectTypeClass* pTy
654688
}
655689
else
656690
{
657-
if (cumulativeMatches.size() > 0)
658-
{
659-
AttachEffectClass* best = nullptr;
691+
AttachEffectClass* best = nullptr;
660692

661-
for (auto const& ae : cumulativeMatches)
662-
{
663-
if (!best || ae->Duration < best->Duration)
664-
best = ae;
665-
}
666-
667-
best->RefreshDuration(attachParams.DurationOverride);
693+
for (auto const& ae : cumulativeMatches)
694+
{
695+
if (!best || ae->Duration < best->Duration)
696+
best = ae;
668697
}
698+
699+
best->RefreshDuration(attachParams.DurationOverride);
669700
}
670701

671702
return nullptr;
@@ -685,7 +716,7 @@ AttachEffectClass* AttachEffectClass::CreateAndAttach(AttachEffectTypeClass* pTy
685716
}
686717
else
687718
{
688-
targetAEs.push_back(std::make_unique<AttachEffectClass>(pType, pTarget, pInvokerHouse, pInvoker, pSource, attachParams.DurationOverride, attachParams.Delay, attachParams.InitialDelay, attachParams.RecreationDelay));
719+
targetAEs.emplace_back(std::make_unique<AttachEffectClass>(pType, pTarget, pInvokerHouse, pInvoker, pSource, attachParams.DurationOverride, attachParams.Delay, attachParams.InitialDelay, attachParams.RecreationDelay));
689720
auto const pAE = targetAEs.back().get();
690721

691722
if (!currentTypeCount && pType->Cumulative && pType->CumulativeAnimations.size() > 0)
@@ -817,7 +848,8 @@ int AttachEffectClass::RemoveAllOfType(AttachEffectTypeClass* pType, TechnoClass
817848

818849
if (pType->ExpireWeapon && (pType->ExpireWeapon_TriggerOn & ExpireWeaponCondition::Remove) != ExpireWeaponCondition::None)
819850
{
820-
if (!pType->Cumulative || !pType->ExpireWeapon_CumulativeOnlyOnce || pTargetExt->GetAttachedEffectCumulativeCount(pType) < 2)
851+
// can't be GetAttachedEffectCumulativeCount(pType) < 2, or inactive AE might make it stack more than once
852+
if (!pType->Cumulative || !pType->ExpireWeapon_CumulativeOnlyOnce || stackCount == 1)
821853
expireWeapons.push_back(pType->ExpireWeapon);
822854
}
823855

@@ -831,6 +863,11 @@ int AttachEffectClass::RemoveAllOfType(AttachEffectTypeClass* pType, TechnoClass
831863
}
832864

833865
it = targetAEs->erase(it);
866+
867+
if (!pType->Cumulative)
868+
break;
869+
870+
stackCount--;
834871
}
835872
else
836873
{

src/New/Entity/ShieldClass.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,23 @@ void ShieldClass::UpdateType()
5858

5959
void ShieldClass::PointerGotInvalid(void* ptr, bool removed)
6060
{
61-
if (auto const pAnim = abstract_cast<AnimClass*>(static_cast<AbstractClass*>(ptr)))
61+
auto const abs = static_cast<AbstractClass*>(ptr);
62+
63+
if (auto const pAnim = abstract_cast<AnimClass*, true>(abs))
6264
{
63-
for (auto pShield : ShieldClass::Array)
65+
if (auto const pAnimExt = AnimExt::ExtMap.Find(pAnim))
6466
{
65-
if (pAnim == pShield->IdleAnim)
66-
pShield->IdleAnim = nullptr;
67+
if (pAnimExt->IsShieldIdleAnim)
68+
{
69+
for (auto const pShield : ShieldClass::Array)
70+
{
71+
if (pAnim == pShield->IdleAnim)
72+
{
73+
pShield->IdleAnim = nullptr;
74+
break; // one anim must be used by less than one shield
75+
}
76+
}
77+
}
6778
}
6879
}
6980
}
@@ -815,11 +826,16 @@ void ShieldClass::CreateAnim()
815826

816827
if (!this->IdleAnim && idleAnimType)
817828
{
818-
auto const pAnim = GameCreate<AnimClass>(idleAnimType, this->Techno->Location);
829+
auto const pTechno = this->Techno;
830+
auto const pAnim = GameCreate<AnimClass>(idleAnimType, pTechno->Location);
831+
832+
pAnim->SetOwnerObject(pTechno);
833+
pAnim->Owner = pTechno->Owner;
834+
835+
auto const pAnimExt = AnimExt::ExtMap.Find(pAnim);
836+
pAnimExt->SetInvoker(pTechno);
837+
pAnimExt->IsShieldIdleAnim = true;
819838

820-
pAnim->SetOwnerObject(this->Techno);
821-
pAnim->Owner = this->Techno->Owner;
822-
AnimExt::ExtMap.Find(pAnim)->SetInvoker(this->Techno);
823839
pAnim->RemainingIterations = 0xFFu;
824840
this->IdleAnim = pAnim;
825841
}

0 commit comments

Comments
 (0)