15
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
*/
17
17
18
+ /*
19
+ * Whirlwind gets interrupted in lots of cases
20
+ * Conversation between creatures requires rechecks and improvements
21
+ */
22
+
18
23
#include " ScriptMgr.h"
19
24
#include " arcatraz.h"
20
25
#include " InstanceScript.h"
21
26
#include " ObjectAccessor.h"
22
27
#include " ScriptedCreature.h"
28
+ #include " SpellInfo.h"
29
+ #include " SpellMgr.h"
30
+ #include " SpellScript.h"
23
31
24
- enum Say
32
+ enum DalliahTexts
25
33
{
26
34
// Dalliah the Doomsayer
27
35
SAY_AGGRO = 1 ,
@@ -36,83 +44,112 @@ enum Say
36
44
SAY_DALLIAH_25_PERCENT = 5
37
45
};
38
46
39
- enum Spells
47
+ enum DalliahSpells
40
48
{
41
49
SPELL_GIFT_OF_THE_DOOMSAYER = 36173 ,
42
50
SPELL_WHIRLWIND = 36142 ,
43
51
SPELL_HEAL = 36144 ,
44
- SPELL_SHADOW_WAVE = 39016 // Heroic only
52
+ SPELL_SHADOW_WAVE = 39016 , // Heroic only
53
+
54
+ SPELL_DUMMY = 36177
45
55
};
46
56
47
- enum Events
57
+ enum DalliahEvents
48
58
{
49
59
EVENT_GIFT_OF_THE_DOOMSAYER = 1 ,
50
- EVENT_WHIRLWIND = 2 ,
51
- EVENT_HEAL = 3 ,
52
- EVENT_SHADOW_WAVE = 4 , // Heroic only
53
- EVENT_ME_FIRST = 5 ,
54
- EVENT_SOCCOTHRATES_DEATH = 6
60
+ EVENT_WHIRLWIND,
61
+ EVENT_HEAL,
62
+ EVENT_SHADOW_WAVE,
63
+
64
+ EVENT_ME_FIRST,
65
+ EVENT_SOCCOTHRATES_DEATH
55
66
};
56
67
68
+ // 20885 - Dalliah the Doomsayer
57
69
struct boss_dalliah_the_doomsayer : public BossAI
58
70
{
59
- boss_dalliah_the_doomsayer (Creature* creature) : BossAI(creature, DATA_DALLIAH)
60
- {
61
- soccothratesTaunt = false ;
62
- soccothratesDeath = false ;
63
- }
71
+ boss_dalliah_the_doomsayer (Creature* creature) : BossAI(creature, DATA_DALLIAH),
72
+ _soccothratesTaunt (false ), _soccothratesDeath(false ) { }
64
73
65
74
void Reset () override
66
75
{
67
76
_Reset ();
68
- soccothratesTaunt = false ;
69
- soccothratesDeath = false ;
70
- }
71
-
72
- void JustDied (Unit* /* killer*/ ) override
73
- {
74
- _JustDied ();
75
- Talk (SAY_DEATH);
76
-
77
- if (Creature* soccothrates = ObjectAccessor::GetCreature (*me, instance->GetGuidData (DATA_SOCCOTHRATES)))
78
- if (soccothrates->IsAlive () && !soccothrates->IsInCombat ())
79
- soccothrates->AI ()->SetData (1 , 1 );
77
+ _soccothratesTaunt = false ;
78
+ _soccothratesDeath = false ;
80
79
}
81
80
82
81
void JustEngagedWith (Unit* who) override
83
82
{
84
83
BossAI::JustEngagedWith (who);
85
- events.ScheduleEvent (EVENT_GIFT_OF_THE_DOOMSAYER, 1s, 4s );
86
- events.ScheduleEvent (EVENT_WHIRLWIND, 7s, 9s );
84
+ events.ScheduleEvent (EVENT_GIFT_OF_THE_DOOMSAYER, 0s, 10s );
85
+ events.ScheduleEvent (EVENT_WHIRLWIND, 5s, 10s );
87
86
if (IsHeroic ())
88
- events.ScheduleEvent (EVENT_SHADOW_WAVE, 11s, 16s );
87
+ events.ScheduleEvent (EVENT_SHADOW_WAVE, 10s, 15s );
89
88
events.ScheduleEvent (EVENT_ME_FIRST, 6s);
90
89
Talk (SAY_AGGRO);
91
90
}
92
91
93
- void KilledUnit (Unit* /* victim*/ ) override
94
- {
95
- Talk (SAY_SLAY);
96
- }
97
-
98
92
void SetData (uint32 /* type*/ , uint32 data) override
99
93
{
100
94
switch (data)
101
95
{
102
96
case 1 :
103
97
events.ScheduleEvent (EVENT_SOCCOTHRATES_DEATH, 6s);
104
- soccothratesDeath = true ;
98
+ _soccothratesDeath = true ;
105
99
break ;
106
100
default :
107
101
break ;
108
102
}
109
103
}
110
104
105
+ void DamageTaken (Unit* /* attacker*/ , uint32& damage, DamageEffectType /* damageType*/ , SpellInfo const * /* spellInfo = nullptr*/ ) override
106
+ {
107
+ if (!_soccothratesTaunt && me->HealthBelowPctDamaged (25 , damage))
108
+ {
109
+ _soccothratesTaunt = true ;
110
+
111
+ if (Creature* soccothrates = ObjectAccessor::GetCreature (*me, instance->GetGuidData (DATA_SOCCOTHRATES)))
112
+ soccothrates->AI ()->Talk (SAY_DALLIAH_25_PERCENT);
113
+ }
114
+ }
115
+
116
+ void SpellHit (WorldObject* /* caster*/ , SpellInfo const * spellInfo) override
117
+ {
118
+ if (spellInfo->Id == SPELL_DUMMY)
119
+ events.ScheduleEvent (EVENT_HEAL, 0s);
120
+ }
121
+
122
+ void OnSpellCast (SpellInfo const * spell) override
123
+ {
124
+ if (spell->Id == SPELL_WHIRLWIND)
125
+ if (roll_chance_i (30 ))
126
+ Talk (SAY_WHIRLWIND);
127
+
128
+ if (spell->Id == sSpellMgr ->GetSpellIdForDifficulty (SPELL_HEAL, me))
129
+ if (roll_chance_i (50 ))
130
+ Talk (SAY_HEAL);
131
+ }
132
+
133
+ void KilledUnit (Unit* /* victim*/ ) override
134
+ {
135
+ Talk (SAY_SLAY);
136
+ }
137
+
138
+ void JustDied (Unit* /* killer*/ ) override
139
+ {
140
+ _JustDied ();
141
+ Talk (SAY_DEATH);
142
+
143
+ if (Creature* soccothrates = ObjectAccessor::GetCreature (*me, instance->GetGuidData (DATA_SOCCOTHRATES)))
144
+ if (soccothrates->IsAlive () && !soccothrates->IsInCombat ())
145
+ soccothrates->AI ()->SetData (1 , 1 );
146
+ }
147
+
111
148
void UpdateAI (uint32 diff) override
112
149
{
113
150
if (!UpdateVictim ())
114
151
{
115
- if (soccothratesDeath )
152
+ if (_soccothratesDeath )
116
153
{
117
154
events.Update (diff);
118
155
@@ -142,23 +179,21 @@ struct boss_dalliah_the_doomsayer : public BossAI
142
179
switch (eventId)
143
180
{
144
181
case EVENT_GIFT_OF_THE_DOOMSAYER:
145
- DoCastVictim (SPELL_GIFT_OF_THE_DOOMSAYER, true );
146
- events.ScheduleEvent (EVENT_GIFT_OF_THE_DOOMSAYER, 16s, 21s );
182
+ DoCastVictim (SPELL_GIFT_OF_THE_DOOMSAYER);
183
+ events.Repeat (10s, 20s );
147
184
break ;
148
185
case EVENT_WHIRLWIND:
149
- DoCast (me, SPELL_WHIRLWIND);
150
- Talk (SAY_WHIRLWIND);
151
- events.ScheduleEvent (EVENT_WHIRLWIND, 19s, 21s);
152
- events.ScheduleEvent (EVENT_HEAL, 6s);
186
+ DoCastSelf (SPELL_WHIRLWIND);
187
+ events.Repeat (15s, 25s);
153
188
break ;
154
189
case EVENT_HEAL:
155
- DoCast (me, SPELL_HEAL);
156
- Talk (SAY_HEAL);
190
+ DoCastSelf (SPELL_HEAL);
157
191
break ;
158
192
case EVENT_SHADOW_WAVE:
159
- DoCastVictim (SPELL_SHADOW_WAVE, true );
160
- events.ScheduleEvent (EVENT_SHADOW_WAVE, 11s, 16s );
193
+ DoCastVictim (SPELL_SHADOW_WAVE);
194
+ events.Repeat (10s, 15s );
161
195
break ;
196
+
162
197
case EVENT_ME_FIRST:
163
198
if (Creature* soccothrates = ObjectAccessor::GetCreature (*me, instance->GetGuidData (DATA_SOCCOTHRATES)))
164
199
if (soccothrates->IsAlive () && !soccothrates->IsInCombat ())
@@ -172,22 +207,39 @@ struct boss_dalliah_the_doomsayer : public BossAI
172
207
return ;
173
208
}
174
209
175
- if (HealthBelowPct (25 ) && !soccothratesTaunt)
176
- {
177
- if (Creature* soccothrates = ObjectAccessor::GetCreature (*me, instance->GetGuidData (DATA_SOCCOTHRATES)))
178
- soccothrates->AI ()->Talk (SAY_DALLIAH_25_PERCENT);
179
- soccothratesTaunt = true ;
180
- }
181
-
182
210
DoMeleeAttackIfReady ();
183
211
}
184
212
185
213
private:
186
- bool soccothratesTaunt;
187
- bool soccothratesDeath;
214
+ bool _soccothratesTaunt;
215
+ bool _soccothratesDeath;
216
+ };
217
+
218
+ // 36142 - Whirlwind
219
+ class spell_dalliah_the_doomsayer_whirlwind : public AuraScript
220
+ {
221
+ PrepareAuraScript (spell_dalliah_the_doomsayer_whirlwind);
222
+
223
+ bool Validate (SpellInfo const * /* spellInfo*/ ) override
224
+ {
225
+ return ValidateSpellInfo ({ SPELL_DUMMY });
226
+ }
227
+
228
+ void AfterRemove (AuraEffect const * /* aurEff*/ , AuraEffectHandleModes /* mode*/ )
229
+ {
230
+ // When Whirlwind ends, creature casts Dummy spell. When Dummy spell hits,
231
+ // creature casts Heal spell and this is how Heal after Whirlwind is handled
232
+ GetTarget ()->CastSpell (GetTarget (), SPELL_DUMMY, true );
233
+ }
234
+
235
+ void Register () override
236
+ {
237
+ AfterEffectRemove += AuraEffectRemoveFn (spell_dalliah_the_doomsayer_whirlwind::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
238
+ }
188
239
};
189
240
190
241
void AddSC_boss_dalliah_the_doomsayer ()
191
242
{
192
243
RegisterArcatrazCreatureAI (boss_dalliah_the_doomsayer);
244
+ RegisterSpellScript (spell_dalliah_the_doomsayer_whirlwind);
193
245
}
0 commit comments