@@ -56,20 +56,6 @@ enum Spells
56
56
57
57
enum Misc
58
58
{
59
- EVENT_INIT_COMBAT = 1 ,
60
- EVENT_SPELL_FIREBALL = 2 ,
61
- EVENT_SPELL_PHOENIX = 3 ,
62
- EVENT_SPELL_FLAMESTRIKE = 4 ,
63
- EVENT_SPELL_SHOCK_BARRIER = 5 ,
64
- EVENT_CHECK_HEALTH = 6 ,
65
- EVENT_GRAVITY_LAPSE_1_1 = 7 ,
66
- EVENT_GRAVITY_LAPSE_1_2 = 8 ,
67
- EVENT_GRAVITY_LAPSE_2 = 9 ,
68
- EVENT_GRAVITY_LAPSE_3 = 10 ,
69
- EVENT_GRAVITY_LAPSE_4 = 11 ,
70
- EVENT_GRAVITY_LAPSE_5 = 12 ,
71
- EVENT_FINISH_TALK = 13 ,
72
-
73
59
ACTION_TELEPORT_PLAYERS = 1 ,
74
60
ACTION_KNOCKUP = 2 ,
75
61
ACTION_ALLOW_FLY = 3 ,
@@ -78,216 +64,176 @@ enum Misc
78
64
CREATURE_ARCANE_SPHERE = 24708
79
65
};
80
66
81
- struct boss_felblood_kaelthas : public ScriptedAI
67
+ struct boss_felblood_kaelthas : public BossAI
82
68
{
83
- boss_felblood_kaelthas (Creature* creature) : ScriptedAI (creature), summons(me )
69
+ boss_felblood_kaelthas (Creature* creature) : BossAI (creature, DATA_KAELTHAS )
84
70
{
85
- instance = creature->GetInstanceScript ();
86
- introSpeak = false ;
71
+ _hasDoneIntro = false ;
87
72
}
88
73
89
- InstanceScript* instance;
90
- EventMap events;
91
- EventMap events2;
92
- SummonList summons;
93
- bool introSpeak;
94
-
95
74
void Reset () override
96
75
{
97
- events.Reset ();
98
- summons.DespawnAll ();
76
+ BossAI::Reset ();
77
+ _OOCScheduler.CancelAll ();
78
+ _gravityLapseCounter = 0 ;
99
79
me->ApplySpellImmune (0 , IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false );
100
- instance->SetBossState (DATA_KAELTHAS, NOT_STARTED);
101
80
me->SetImmuneToAll (false );
81
+ ScheduleHealthCheckEvent (50 , [&]{
82
+ me->CastStop ();
83
+ me->ApplySpellImmune (0 , IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true );
84
+ DoCastSelf (SPELL_TELEPORT_CENTER, true );
85
+ scheduler.CancelAll ();
86
+
87
+ me->StopMoving ();
88
+ me->GetMotionMaster ()->Clear ();
89
+ me->GetMotionMaster ()->MoveIdle ();
90
+ ScheduleTimedEvent (5s, [&]{
91
+ summons.DoForAllSummons ([&](WorldObject* summon){
92
+ if (Unit* player = SelectTarget (SelectTargetMethod::Random, 0 , 0 .0f , true ))
93
+ if (Creature* summonedCreature = summon->ToCreature ())
94
+ summonedCreature->GetMotionMaster ()->MoveChase (player);
95
+ });
96
+ }, 10s, 15s);
97
+ GravityLapseSequence (true );
98
+ });
102
99
}
103
100
104
101
void JustSummoned (Creature* summon) override
105
102
{
106
- for (SummonList::const_iterator itr = summons.begin (); itr != summons.end (); ++itr)
107
- if (*itr == summon->GetGUID ())
108
- return ;
109
- summons.Summon (summon);
103
+ BossAI::JustSummoned (summon);
104
+ summon->SetReactState (REACT_PASSIVE);
105
+ }
106
+
107
+ void GravityLapseSequence (bool firstTime)
108
+ {
109
+ Talk (firstTime ? SAY_GRAVITY_LAPSE : SAY_RECAST_GRAVITY);
110
+ DoCastSelf (SPELL_GRAVITY_LAPSE_INITIAL);
111
+ scheduler.Schedule (2s, [this ](TaskContext){
112
+ LapseAction (ACTION_TELEPORT_PLAYERS);
113
+ }).Schedule (3s, [this ](TaskContext){
114
+ LapseAction (ACTION_KNOCKUP);
115
+ }).Schedule (4s, [this ](TaskContext){
116
+ LapseAction (ACTION_ALLOW_FLY);
117
+ for (uint8 i = 0 ; i < 3 ; ++i)
118
+ DoCastSelf (SPELL_SUMMON_ARCANE_SPHERE, true );
119
+ DoCastSelf (SPELL_GRAVITY_LAPSE_CHANNEL);
120
+ scheduler.Schedule (30s, [this ](TaskContext){
121
+ LapseAction (ACTION_REMOVE_FLY);
122
+ me->InterruptNonMeleeSpells (false );
123
+ Talk (SAY_TIRED);
124
+ DoCastSelf (SPELL_POWER_FEEDBACK);
125
+ scheduler.Schedule (10s, [this ](TaskContext){
126
+ GravityLapseSequence (false );
127
+ });
128
+ });
129
+ });
110
130
}
111
131
112
132
void InitializeAI () override
113
133
{
114
- ScriptedAI ::InitializeAI ();
134
+ BossAI ::InitializeAI ();
115
135
me->SetImmuneToAll (true );
116
136
}
117
137
118
- void JustDied (Unit*) override
138
+ void JustDied (Unit* killer ) override
119
139
{
120
- instance->SetBossState (DATA_KAELTHAS, DONE);
121
- summons.DespawnAll ();
122
-
140
+ BossAI::JustDied (killer);
123
141
if (GameObject* orb = instance->GetGameObject (DATA_ESCAPE_ORB))
124
142
orb->RemoveGameObjectFlag (GO_FLAG_NOT_SELECTABLE);
125
143
}
126
144
127
- void JustEngagedWith (Unit* /* who*/ ) override
145
+ void JustEngagedWith (Unit* who) override
128
146
{
129
- instance->SetBossState (DATA_KAELTHAS, IN_PROGRESS);
130
- me->SetInCombatWithZone ();
147
+ BossAI::JustEngagedWith (who);
131
148
132
- events.ScheduleEvent (EVENT_SPELL_FIREBALL, 0 );
133
- events.ScheduleEvent (EVENT_SPELL_PHOENIX, 15000 );
134
- events.ScheduleEvent (EVENT_SPELL_FLAMESTRIKE, 22000 );
135
- events.ScheduleEvent (EVENT_CHECK_HEALTH, 1000 );
149
+ ScheduleTimedEvent (0ms, [&]{
150
+ DoCastVictim (SPELL_FIREBALL);
151
+ }, 3000ms, 4500ms);
152
+ ScheduleTimedEvent (15s, [&]{
153
+ Talk (SAY_PHOENIX);
154
+ DoCastSelf (SPELL_PHOENIX);
155
+ }, 60s);
156
+ ScheduleTimedEvent (22s, [&]{
157
+ DoCastRandomTarget (SPELL_FLAMESTRIKE_SUMMON, 0 , 100 .0f );
158
+ Talk (SAY_FLAMESTRIKE);
159
+ }, 25s);
136
160
137
161
if (IsHeroic ())
138
- events.ScheduleEvent (EVENT_SPELL_SHOCK_BARRIER, 50000 );
162
+ ScheduleTimedEvent (50s, [&]{
163
+ DoCastSelf (SPELL_SHOCK_BARRIER, true );
164
+ me->CastCustomSpell (SPELL_PYROBLAST, SPELLVALUE_MAX_TARGETS, 1 , (Unit*)nullptr , false );
165
+ }, 50s);
139
166
}
140
167
141
168
void MoveInLineOfSight (Unit* who) override
142
169
{
143
- if (!introSpeak && me->IsWithinDistInMap (who, 40 .0f ) && who->IsPlayer ())
170
+ if (!_hasDoneIntro && me->IsWithinDistInMap (who, 40 .0f ) && who->IsPlayer ())
144
171
{
145
172
Talk (SAY_AGGRO);
146
- introSpeak = true ;
147
- events2.ScheduleEvent (EVENT_INIT_COMBAT, 35000 );
173
+ _hasDoneIntro = true ;
174
+ _OOCScheduler.Schedule (35s, [this ](TaskContext){
175
+ me->SetReactState (REACT_AGGRESSIVE);
176
+ me->SetImmuneToAll (false );
177
+ me->SetInCombatWithZone ();
178
+ });
148
179
}
149
-
150
- ScriptedAI::MoveInLineOfSight (who);
180
+ BossAI::MoveInLineOfSight (who);
151
181
}
152
182
153
- void DamageTaken (Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
183
+ void DamageTaken (Unit* attacker , uint32& damage, DamageEffectType damagetype , SpellSchoolMask damageSchoolMask ) override
154
184
{
155
185
if (damage >= me->GetHealth ())
156
186
{
157
187
damage = me->GetHealth () - 1 ;
158
188
if (me->isRegeneratingHealth ())
159
189
{
190
+ me->CastStop ();
160
191
me->SetRegeneratingHealth (false );
161
192
me->SetUnitFlag (UNIT_FLAG_DISABLE_MOVE);
162
193
me->SetImmuneToAll (true );
194
+ me->SetStandState (UNIT_STAND_STATE_KNEEL);
163
195
me->CombatStop ();
164
196
me->SetReactState (REACT_PASSIVE);
165
197
LapseAction (ACTION_REMOVE_FLY);
166
- events.Reset ();
167
- events2.ScheduleEvent (EVENT_FINISH_TALK, 6000 );
198
+ scheduler.CancelAll ();
199
+ _OOCScheduler.Schedule (6s, [this ](TaskContext){
200
+ me->KillSelf ();
201
+ });
168
202
Talk (SAY_DEATH);
169
203
}
170
204
}
205
+ BossAI::DamageTaken (attacker, damage, damagetype, damageSchoolMask);
171
206
}
172
207
173
208
void LapseAction (uint8 action)
174
209
{
175
- uint8 counter = 0 ;
176
- Map::PlayerList const & playerList = me->GetMap ()->GetPlayers ();
177
- for (Map::PlayerList::const_iterator itr = playerList.begin (); itr != playerList.end (); ++itr, ++counter)
178
- if (Player* player = itr->GetSource ())
210
+ _gravityLapseCounter = 0 ;
211
+ me->GetMap ()->DoForAllPlayers ([&](Player* player)
212
+ {
213
+ if (action == ACTION_TELEPORT_PLAYERS)
214
+ DoCast (player, SPELL_GRAVITY_LAPSE_PLAYER + _gravityLapseCounter, true );
215
+ else if (action == ACTION_KNOCKUP)
216
+ player->CastSpell (player, SPELL_GRAVITY_LAPSE_DOT, true , nullptr , nullptr , me->GetGUID ());
217
+ else if (action == ACTION_ALLOW_FLY)
218
+ player->CastSpell (player, SPELL_GRAVITY_LAPSE_FLY, true , nullptr , nullptr , me->GetGUID ());
219
+ else if (action == ACTION_REMOVE_FLY)
179
220
{
180
- if (action == ACTION_TELEPORT_PLAYERS)
181
- me->CastSpell (player, SPELL_GRAVITY_LAPSE_PLAYER + counter, true );
182
- else if (action == ACTION_KNOCKUP)
183
- player->CastSpell (player, SPELL_GRAVITY_LAPSE_DOT, true , nullptr , nullptr , me->GetGUID ());
184
- else if (action == ACTION_ALLOW_FLY)
185
- player->CastSpell (player, SPELL_GRAVITY_LAPSE_FLY, true , nullptr , nullptr , me->GetGUID ());
186
- else if (action == ACTION_REMOVE_FLY)
187
- {
188
- player->RemoveAurasDueToSpell (SPELL_GRAVITY_LAPSE_FLY);
189
- player->RemoveAurasDueToSpell (SPELL_GRAVITY_LAPSE_DOT);
190
- }
221
+ player->RemoveAurasDueToSpell (SPELL_GRAVITY_LAPSE_FLY);
222
+ player->RemoveAurasDueToSpell (SPELL_GRAVITY_LAPSE_DOT);
191
223
}
224
+ ++_gravityLapseCounter;
225
+ });
192
226
}
193
227
194
228
void UpdateAI (uint32 diff) override
195
229
{
196
- events2.Update (diff);
197
- switch (events2.ExecuteEvent ())
198
- {
199
- case EVENT_INIT_COMBAT:
200
- me->SetImmuneToAll (false );
201
- if (Unit* target = SelectTargetFromPlayerList (50 .0f ))
202
- AttackStart (target);
203
- return ;
204
- case EVENT_FINISH_TALK:
205
- me->KillSelf ();
206
- return ;
207
- }
208
-
209
- if (!UpdateVictim ())
210
- return ;
211
-
212
- events.Update (diff);
213
- if (me->HasUnitState (UNIT_STATE_CASTING))
214
- return ;
215
-
216
- switch (uint32 eventId = events.ExecuteEvent ())
217
- {
218
- case EVENT_SPELL_FIREBALL:
219
- me->CastSpell (me->GetVictim (), SPELL_FIREBALL, false );
220
- events.ScheduleEvent (EVENT_SPELL_FIREBALL, urand (3000 , 4500 ));
221
- break ;
222
- case EVENT_SPELL_FLAMESTRIKE:
223
- if (Unit* target = SelectTarget (SelectTargetMethod::Random, 0 , 100 , true ))
224
- {
225
- me->CastSpell (target, SPELL_FLAMESTRIKE_SUMMON, true );
226
- Talk (SAY_FLAMESTRIKE);
227
- }
228
- events.ScheduleEvent (EVENT_SPELL_FLAMESTRIKE, 25000 );
229
- break ;
230
- case EVENT_SPELL_SHOCK_BARRIER:
231
- me->CastSpell (me, SPELL_SHOCK_BARRIER, true );
232
- me->CastCustomSpell (SPELL_PYROBLAST, SPELLVALUE_MAX_TARGETS, 1 , (Unit*)nullptr , false );
233
- events.ScheduleEvent (EVENT_SPELL_SHOCK_BARRIER, 50000 );
234
- break ;
235
- case EVENT_SPELL_PHOENIX:
236
- Talk (SAY_PHOENIX);
237
- me->CastSpell (me, SPELL_PHOENIX, false );
238
- events.ScheduleEvent (EVENT_SPELL_PHOENIX, 60000 );
239
- break ;
240
- case EVENT_CHECK_HEALTH:
241
- if (HealthBelowPct (50 ))
242
- {
243
- me->ApplySpellImmune (0 , IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true );
244
- me->CastSpell (me, SPELL_TELEPORT_CENTER, true );
245
- events.Reset ();
246
-
247
- me->StopMoving ();
248
- me->GetMotionMaster ()->Clear ();
249
- me->GetMotionMaster ()->MoveIdle ();
250
-
251
- events.SetPhase (1 );
252
- events.ScheduleEvent (EVENT_GRAVITY_LAPSE_1_1, 0 );
253
- break ;
254
- }
255
- events.ScheduleEvent (EVENT_CHECK_HEALTH, 500 );
256
- break ;
257
- case EVENT_GRAVITY_LAPSE_1_1:
258
- case EVENT_GRAVITY_LAPSE_1_2:
259
- Talk (eventId == EVENT_GRAVITY_LAPSE_1_1 ? SAY_GRAVITY_LAPSE : SAY_RECAST_GRAVITY);
260
- me->CastSpell (me, SPELL_GRAVITY_LAPSE_INITIAL, false );
261
- events.ScheduleEvent (EVENT_GRAVITY_LAPSE_2, 2000 );
262
- break ;
263
- case EVENT_GRAVITY_LAPSE_2:
264
- LapseAction (ACTION_TELEPORT_PLAYERS);
265
- events.ScheduleEvent (EVENT_GRAVITY_LAPSE_3, 1000 );
266
- break ;
267
- case EVENT_GRAVITY_LAPSE_3:
268
- LapseAction (ACTION_KNOCKUP);
269
- events.ScheduleEvent (EVENT_GRAVITY_LAPSE_4, 1000 );
270
- break ;
271
- case EVENT_GRAVITY_LAPSE_4:
272
- LapseAction (ACTION_ALLOW_FLY);
273
- for (uint8 i = 0 ; i < 3 ; ++i)
274
- me->CastSpell (me, SPELL_SUMMON_ARCANE_SPHERE, true );
275
-
276
- me->CastSpell (me, SPELL_GRAVITY_LAPSE_CHANNEL, false );
277
- events.ScheduleEvent (EVENT_GRAVITY_LAPSE_5, 30000 );
278
- break ;
279
- case EVENT_GRAVITY_LAPSE_5:
280
- LapseAction (ACTION_REMOVE_FLY);
281
- me->InterruptNonMeleeSpells (false );
282
- Talk (SAY_TIRED);
283
- me->CastSpell (me, SPELL_POWER_FEEDBACK, false );
284
- events.ScheduleEvent (EVENT_GRAVITY_LAPSE_1_2, 10000 );
285
- break ;
286
- }
287
-
288
- if (events.GetPhaseMask () == 0 )
289
- DoMeleeAttackIfReady ();
230
+ _OOCScheduler.Update (diff);
231
+ BossAI::UpdateAI (diff);
290
232
}
233
+ private:
234
+ TaskScheduler _OOCScheduler;
235
+ bool _hasDoneIntro;
236
+ uint8 _gravityLapseCounter;
291
237
};
292
238
293
239
class spell_mt_phoenix_burn : public SpellScript
0 commit comments