2222
2323#include " ScriptMgr.h"
2424#include " InstanceScript.h"
25+ #include " Map.h"
2526#include " naxxramas.h"
2627#include " ScriptedCreature.h"
28+ #include " SpellScript.h"
2729
2830enum PatchwerkTexts
2931{
@@ -38,6 +40,7 @@ enum PatchwerkSpells
3840{
3941 SPELL_HATEFUL_STRIKE_PRIMER = 28307 ,
4042 SPELL_HATEFUL_STRIKE = 28308 ,
43+ SPELL_HATEFUL_STRIKE_HEROIC = 59192 ,
4144 SPELL_FRENZY = 28131 ,
4245 SPELL_BERSERK = 26662 ,
4346 SPELL_SLIME_BOLT = 32309
@@ -106,54 +109,10 @@ struct boss_patchwerk : public BossAI
106109 {
107110 switch (eventId)
108111 {
109- // Move everything to SPELL_HATEFUL_STRIKE_PRIMER spell script
110112 case EVENT_HATEFUL :
111- {
112- // Hateful Strike targets the highest non-MT threat in melee range on 10man
113- // and the higher HP target out of the two highest non-MT threats in melee range on 25man
114- ThreatReference* secondThreat = nullptr ;
115- ThreatReference* thirdThreat = nullptr ;
116-
117- ThreatManager& mgr = me->GetThreatManager ();
118- Unit* currentVictim = mgr.GetCurrentVictim ();
119- auto list = mgr.GetModifiableThreatList ();
120- auto it = list.begin (), end = list.end ();
121- if (it == end)
122- {
123- EnterEvadeMode (EVADE_REASON_NO_HOSTILES );
124- return ;
125- }
126-
127- if ((*it)->GetVictim () != currentVictim)
128- secondThreat = *it;
129- if ((!secondThreat || Is25ManRaid ()) && (++it != end && (*it)->IsAvailable ()))
130- {
131- if ((*it)->GetVictim () != currentVictim)
132- (secondThreat ? thirdThreat : secondThreat) = *it;
133- if (!thirdThreat && Is25ManRaid () && (++it != end && (*it)->IsAvailable ()))
134- thirdThreat = *it;
135- }
136-
137- Unit* pHatefulTarget = nullptr ;
138- if (!secondThreat)
139- pHatefulTarget = currentVictim;
140- else if (!thirdThreat)
141- pHatefulTarget = secondThreat->GetVictim ();
142- else
143- pHatefulTarget = (secondThreat->GetVictim ()->GetHealth () < thirdThreat->GetVictim ()->GetHealth ()) ? thirdThreat->GetVictim () : secondThreat->GetVictim ();
144-
145- // add threat to highest threat targets
146- AddThreat (currentVictim, HATEFUL_THREAT_AMT );
147- if (secondThreat)
148- secondThreat->AddThreat (HATEFUL_THREAT_AMT );
149- if (thirdThreat)
150- thirdThreat->AddThreat (HATEFUL_THREAT_AMT );
151-
152- DoCast (pHatefulTarget, SPELL_HATEFUL_STRIKE , true );
153-
113+ DoCastSelf (SPELL_HATEFUL_STRIKE_PRIMER , true );
154114 events.Repeat (1200ms);
155115 break ;
156- }
157116 case EVENT_BERSERK :
158117 DoCastSelf (SPELL_BERSERK , true );
159118 Talk (EMOTE_BERSERK );
@@ -180,7 +139,65 @@ struct boss_patchwerk : public BossAI
180139 bool _enraged;
181140};
182141
142+ // 28307 - Hateful Strike Primer
143+ class spell_patchwerk_hateful_strike_primer : public SpellScript
144+ {
145+ PrepareSpellScript (spell_patchwerk_hateful_strike_primer);
146+
147+ bool Validate (SpellInfo const * /* spellInfo*/ ) override
148+ {
149+ return ValidateSpellInfo ({ SPELL_HATEFUL_STRIKE , SPELL_HATEFUL_STRIKE_HEROIC });
150+ }
151+
152+ void SelectTargets (std::list<WorldObject*>& targets)
153+ {
154+ Unit* caster = GetCaster ();
155+
156+ uint32 targetLimit = caster->GetMap ()->Is25ManRaid () ? 3 : 2 ;
157+ std::array<Unit*, 3 > newTargets = { };
158+ auto newTargetsItr = newTargets.begin ();
159+ auto newTargetsEnd = newTargetsItr + targetLimit;
160+
161+ for (ThreatReference const * threatRef : caster->GetThreatManager ().GetSortedThreatList ())
162+ {
163+ if (!threatRef->IsOnline () || !threatRef->GetVictim ()->IsPlayer () || !caster->IsWithinMeleeRange (threatRef->GetVictim ()))
164+ continue ;
165+
166+ *newTargetsItr = threatRef->GetVictim ();
167+ if (++newTargetsItr == newTargetsEnd)
168+ break ;
169+ }
170+
171+ // Hateful Strike damages the higher HP target out of the two highest non-MT threats in melee range on 25man
172+ if (newTargets[1 ] && newTargets[2 ] && newTargets[1 ]->GetHealth () < newTargets[2 ]->GetHealth ())
173+ std::swap (newTargets[1 ], newTargets[2 ]);
174+
175+ targets.assign (newTargets.begin (), newTargetsItr);
176+ }
177+
178+ void HandleEffect (SpellEffIndex effIndex)
179+ {
180+ Unit* caster = GetCaster ();
181+
182+ // all targets get threat increase
183+ caster->GetThreatManager ().AddThreat (GetHitUnit (), HATEFUL_THREAT_AMT , GetSpellInfo ());
184+
185+ // Hateful Strike damages the second unit on target list (not the MT)
186+ // or MT if it is the only target
187+ if (GetUnitTargetIndexForEffect (GetHitUnit ()->GetGUID (), effIndex) == 1
188+ || GetUnitTargetCountForEffect (effIndex) == 1 )
189+ caster->CastSpell (GetHitUnit (), caster->GetMap ()->Is25ManRaid () ? SPELL_HATEFUL_STRIKE_HEROIC : SPELL_HATEFUL_STRIKE , true );
190+ }
191+
192+ void Register () override
193+ {
194+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn (spell_patchwerk_hateful_strike_primer::SelectTargets, EFFECT_0 , TARGET_UNIT_SRC_AREA_ENEMY );
195+ OnEffectHitTarget += SpellEffectFn (spell_patchwerk_hateful_strike_primer::HandleEffect, EFFECT_0 , SPELL_EFFECT_DUMMY );
196+ }
197+ };
198+
183199void AddSC_boss_patchwerk ()
184200{
185201 RegisterNaxxramasCreatureAI (boss_patchwerk);
202+ RegisterSpellScript (spell_patchwerk_hateful_strike_primer);
186203}
0 commit comments