@@ -671,9 +671,10 @@ int AttachEffectClass::Attach(TechnoClass* pTarget, HouseClass* pInvokerHouse, T
671671// / <param name="pInvoker">Techno that invoked the attachment.</param>
672672// / <param name="pSource">Source object for the attachment e.g a Warhead or Techno.</param>
673673// / <param name="attachParams">Attachment parameters.</param>
674+ // / <param name="checkCumulative">Whether cumulative AE needs to be processed.</param>
674675// / <returns>The created and attached AttachEffect if successful, nullptr if not.</returns>
675676AttachEffectClass* AttachEffectClass::CreateAndAttach (AttachEffectTypeClass* pType, TechnoClass* pTarget, TechnoTypeClass* pTargetType, std::vector<std::unique_ptr<AttachEffectClass>>& targetAEs,
676- HouseClass* pInvokerHouse, TechnoClass* pInvoker, AbstractClass* pSource, AEAttachParams const & attachParams)
677+ HouseClass* pInvokerHouse, TechnoClass* pInvoker, AbstractClass* pSource, AEAttachParams const & attachParams, bool checkCumulative )
677678{
678679 if (!pType)
679680 return nullptr ;
@@ -693,6 +694,7 @@ AttachEffectClass* AttachEffectClass::CreateAndAttach(AttachEffectTypeClass* pTy
693694 return nullptr ;
694695
695696 int currentTypeCount = 0 ;
697+ const bool cumulative = pType->Cumulative && checkCumulative;
696698 AttachEffectClass* match = nullptr ;
697699 std::vector<AttachEffectClass*> cumulativeMatches;
698700 cumulativeMatches.reserve (targetAEs.size ());
@@ -704,12 +706,19 @@ AttachEffectClass* AttachEffectClass::CreateAndAttach(AttachEffectTypeClass* pTy
704706 if (attachEffect->GetType () == pType)
705707 {
706708 currentTypeCount++;
707- match = attachEffect;
708709
709- if (!pType->Cumulative )
710+ if (!cumulative)
711+ {
712+ match = attachEffect;
710713 break ;
714+ }
711715 else if (!attachParams.CumulativeRefreshSameSourceOnly || (attachEffect->Source == pSource && attachEffect->Invoker == pInvoker))
716+ {
712717 cumulativeMatches.push_back (attachEffect);
718+
719+ if (!match || attachEffect->Duration < match->Duration )
720+ match = attachEffect;
721+ }
713722 }
714723 }
715724
@@ -726,15 +735,7 @@ AttachEffectClass* AttachEffectClass::CreateAndAttach(AttachEffectTypeClass* pTy
726735 }
727736 else
728737 {
729- AttachEffectClass* best = nullptr ;
730-
731- for (auto const & ae : cumulativeMatches)
732- {
733- if (!best || ae->Duration < best->Duration )
734- best = ae;
735- }
736-
737- best->RefreshDuration (attachParams.DurationOverride );
738+ match->RefreshDuration (attachParams.DurationOverride );
738739 }
739740
740741 AttachEffectTypeClass::HandleEvent (pTarget);
@@ -749,7 +750,7 @@ AttachEffectClass* AttachEffectClass::CreateAndAttach(AttachEffectTypeClass* pTy
749750 }
750751 }
751752
752- if (!pType-> Cumulative && currentTypeCount > 0 && match)
753+ if (!cumulative && match)
753754 {
754755 match->RefreshDuration (attachParams.DurationOverride );
755756 AttachEffectTypeClass::HandleEvent (pTarget);
@@ -759,7 +760,7 @@ AttachEffectClass* AttachEffectClass::CreateAndAttach(AttachEffectTypeClass* pTy
759760 targetAEs.emplace_back (std::make_unique<AttachEffectClass>(pType, pTarget, pInvokerHouse, pInvoker, pSource, attachParams.DurationOverride , attachParams.Delay , attachParams.InitialDelay , attachParams.RecreationDelay ));
760761 auto const pAE = targetAEs.back ().get ();
761762
762- if (!currentTypeCount && pType-> Cumulative && pType->CumulativeAnimations .size () > 0 )
763+ if (!currentTypeCount && cumulative && pType->CumulativeAnimations .size () > 0 )
763764 pAE->HasCumulativeAnim = true ;
764765
765766 return pAE;
@@ -966,42 +967,46 @@ void AttachEffectClass::TransferAttachedEffects(TechnoClass* pSource, TechnoClas
966967
967968 if (!isValid)
968969 {
969- ++it ;
970+ it = pSourceExt-> AttachedEffects . erase (it) ;
970971 continue ;
971972 }
972973
973974 int currentTypeCount = 0 ;
975+ const bool cumulative = type->Cumulative ;
974976 AttachEffectClass* match = nullptr ;
975- AttachEffectClass* sourceMatch = nullptr ;
976977
977978 for (auto const & aePtr : pTargetExt->AttachedEffects )
978979 {
979980 auto const targetAttachEffect = aePtr.get ();
980981
981982 if (targetAttachEffect->GetType () == type)
982983 {
983- currentTypeCount++;
984- match = targetAttachEffect;
984+ currentTypeCount++;
985985
986- if (targetAttachEffect->Source == attachEffect->Source && targetAttachEffect->Invoker == attachEffect->Invoker )
987- sourceMatch = targetAttachEffect;
986+ if (!cumulative)
987+ {
988+ match = targetAttachEffect;
989+ break ;
990+ }
991+ else if (targetAttachEffect->Source == attachEffect->Source && targetAttachEffect->Invoker == attachEffect->Invoker )
992+ {
993+ if (!match || targetAttachEffect->Duration < match->Duration )
994+ match = targetAttachEffect;
995+ }
988996 }
989997 }
990998
991- if (type->Cumulative && type->Cumulative_MaxCount >= 0 && currentTypeCount >= type->Cumulative_MaxCount && sourceMatch)
992- {
993- sourceMatch->Duration = Math::max (sourceMatch->Duration , attachEffect->Duration );
994- }
995- else if (!type->Cumulative && currentTypeCount > 0 && match)
999+ if (match)
9961000 {
997- match->Duration = Math::max (match->Duration , attachEffect->Duration );
1001+ if (!cumulative || (type->Cumulative_MaxCount >= 0 && currentTypeCount >= type->Cumulative_MaxCount ))
1002+ match->Duration = Math::max (match->Duration , attachEffect->Duration );
9981003 }
9991004 else
10001005 {
10011006 AEAttachParams info {};
10021007 info.DurationOverride = attachEffect->DurationOverride ;
10031008
1004- if (auto const pAE = AttachEffectClass::CreateAndAttach (type, pTarget, pTargetType, pTargetExt->AttachedEffects , attachEffect->InvokerHouse , attachEffect->Invoker , attachEffect->Source , info))
1009+ if (auto const pAE = AttachEffectClass::CreateAndAttach (type, pTarget, pTargetType, pTargetExt->AttachedEffects , attachEffect->InvokerHouse , attachEffect->Invoker , attachEffect->Source , info, false ))
10051010 pAE->Duration = attachEffect->Duration ;
10061011 }
10071012
0 commit comments