TrinityCore
zone_netherstorm.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* ScriptData
19SDName: Netherstorm
20SD%Complete: 80
21SDComment: Quest support: 10337, 10652 (special flight paths), 10198, 10191
22SDCategory: Netherstorm
23EndScriptData */
24
25/* ContentData
26npc_commander_dawnforge
27EndContentData */
28
29#include "ScriptMgr.h"
30#include "Containers.h"
31#include "Log.h"
32#include "ObjectAccessor.h"
33#include "Player.h"
34#include "ScriptedCreature.h"
35#include "SpellScript.h"
36
37/*######
38## npc_commander_dawnforge
39######*/
40
41// The Speech of Dawnforge, Ardonis & Pathaleon
43{
49
52
57
60};
61
62// Entries of Arcanist Ardonis, Commander Dawnforge, Pathaleon the Curators Image
64{
65 19830, // Ardonis
66 19831, // Dawnforge
67 21504 // Pathaleon
68};
69
71{
72public:
73 npc_commander_dawnforge() : CreatureScript("npc_commander_dawnforge") { }
74
75 CreatureAI* GetAI(Creature* creature) const override
76 {
77 return new npc_commander_dawnforgeAI(creature);
78 }
79
81 {
83 {
84 Initialize();
85 }
86
88 {
92
93 Phase = 1;
94 PhaseSubphase = 0;
95 Phase_Timer = 4000;
96 isEvent = false;
97 }
98
102
107
108 void Reset() override
109 {
110 Initialize();
111 }
112
113 void JustEngagedWith(Unit* /*who*/) override { }
114
115 void JustSummoned(Creature* summoned) override
116 {
117 pathaleonGUID = summoned->GetGUID();
118 }
119
120 // Emote Ardonis and Pathaleon
122 {
125
126 if (!ardonis || !pathaleon)
127 return;
128
129 // Turn Dawnforge
130 me->SetFacingToObject(pathaleon);
131
132 // Turn Ardonis
133 ardonis->SetFacingToObject(pathaleon);
134
135 //Set them to kneel
138 }
139
140 //Set them back to each other
142 {
143 if (Unit* ardonis = ObjectAccessor::GetUnit(*me, ardonisGUID))
144 {
145 // Turn Dawnforge
146 me->SetFacingToObject(ardonis);
147
148 // Turn Ardonis
149 ardonis->SetFacingToObject(me);
150
151 //Set state
153 ardonis->SetStandState(UNIT_STAND_STATE_STAND);
154 }
155 }
156
157 bool CanStartEvent(Player* player)
158 {
159 if (!isEvent)
160 {
161 Creature* ardonis = me->FindNearestCreature(CreatureEntry[0], 10.0f);
162 if (!ardonis)
163 return false;
164
165 ardonisGUID = ardonis->GetGUID();
166 PlayerGUID = player->GetGUID();
167
168 isEvent = true;
169
171 return true;
172 }
173
174 TC_LOG_DEBUG("scripts", "npc_commander_dawnforge event already in progress, need to wait.");
175 return false;
176 }
177
178 void UpdateAI(uint32 diff) override
179 {
180 //Is event even running?
181 if (!isEvent)
182 return;
183
184 //Phase timing
185 if (Phase_Timer >= diff)
186 {
187 Phase_Timer -= diff;
188 return;
189 }
190
194
195 if (!ardonis || !player)
196 {
197 Reset();
198 return;
199 }
200
201 if (Phase > 4 && !pathaleon)
202 {
203 Reset();
204 return;
205 }
206
207 //Phase 1 Dawnforge say
208 switch (Phase)
209 {
210 case 1:
212 ++Phase;
213 Phase_Timer = 16000;
214 break;
215 //Phase 2 Ardonis say
216 case 2:
217 ardonis->AI()->Talk(SAY_ARCANIST_ARDONIS_1);
218 ++Phase;
219 Phase_Timer = 16000;
220 break;
221 //Phase 3 Dawnforge say
222 case 3:
224 ++Phase;
225 Phase_Timer = 16000;
226 break;
227 //Phase 4 Pathaleon spawns up to phase 9
228 case 4:
229 //spawn pathaleon's image
230 me->SummonCreature(CreatureEntry[2], 2325.851563f, 2799.534668f, 133.084229f, 6.038996f, TEMPSUMMON_TIMED_DESPAWN, 90s);
231 ++Phase;
232 Phase_Timer = 500;
233 break;
234 //Phase 5 Pathaleon say
235 case 5:
237 ++Phase;
238 Phase_Timer = 6000;
239 break;
240 //Phase 6
241 case 6:
242 switch (PhaseSubphase)
243 {
244 //Subphase 1: Turn Dawnforge and Ardonis
245 case 0:
248 Phase_Timer = 8000;
249 break;
250 //Subphase 2 Dawnforge say
251 case 1:
253 PhaseSubphase = 0;
254 ++Phase;
255 Phase_Timer = 8000;
256 break;
257 }
258 break;
259 //Phase 7 Pathaleons say 3 Sentence, every sentence need a subphase
260 case 7:
261 switch (PhaseSubphase)
262 {
263 //Subphase 1
264 case 0:
267 Phase_Timer = 12000;
268 break;
269 //Subphase 2
270 case 1:
273 Phase_Timer = 16000;
274 break;
275 //Subphase 3
276 case 2:
278 PhaseSubphase = 0;
279 ++Phase;
280 Phase_Timer = 10000;
281 break;
282 }
283 break;
284 //Phase 8 Dawnforge & Ardonis say
285 case 8:
287 ardonis->AI()->Talk(SAY_ARCANIST_ARDONIS_2);
288 ++Phase;
289 Phase_Timer = 4000;
290 break;
291 //Phase 9 Pathaleons Despawn, Reset Dawnforge & Ardonis angle
292 case 9:
294 //hide pathaleon, unit will despawn shortly
295 pathaleon->SetVisible(false);
296 PhaseSubphase = 0;
297 ++Phase;
298 Phase_Timer = 3000;
299 break;
300 //Phase 10 Dawnforge say
301 case 10:
304 Reset();
305 break;
306 }
307 }
308 };
309};
310
312{
313public:
314 at_commander_dawnforge() : AreaTriggerScript("at_commander_dawnforge") { }
315
316 bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override
317 {
318 //if player lost aura or not have at all, we should not try start event.
319 if (!player->HasAura(SPELL_SUNFURY_DISGUISE))
320 return false;
321
323 {
324 Creature* Dawnforge = player->FindNearestCreature(CreatureEntry[1], 30.0f);
325 if (!Dawnforge)
326 return false;
327
328 if (ENSURE_AI(npc_commander_dawnforge::npc_commander_dawnforgeAI, Dawnforge->AI())->CanStartEvent(player))
329 return true;
330 }
331 return false;
332 }
333};
334
335/*######
336## npc_phase_hunter
337######*/
338
340{
342
345
347
348 // Spells
354};
355
357{
358public:
359 npc_phase_hunter() : CreatureScript("npc_phase_hunter") { }
360
361 CreatureAI* GetAI(Creature* creature) const override
362 {
363 return new npc_phase_hunterAI(creature);
364 }
365
367 {
369 {
370 Weak = false;
371 Materialize = false;
372 Drained = false;
373 WeakPercent = 25;
374 ManaBurnTimer = 5000;
375 }
376
377 bool Weak;
381
383
385
386 void Reset() override
387 {
388 Weak = false;
389 Materialize = false;
390 Drained = false;
391 WeakPercent = 25 + (rand32() % 16); // 25-40
392
394
395 ManaBurnTimer = 5000 + (rand32() % 3 * 1000); // 5-8 sec cd
396
399 }
400
401 void JustEngagedWith(Unit* who) override
402 {
403 if (who->GetTypeId() == TYPEID_PLAYER)
404 PlayerGUID = who->GetGUID();
405 }
406
407 void UpdateAI(uint32 diff) override
408 {
409 if (!Materialize)
410 {
412 Materialize = true;
413 }
414
415 if (me->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || me->HasUnitState(UNIT_STATE_ROOT)) // if the mob is rooted/slowed by spells eg.: Entangling Roots, Frost Nova, Hamstring, Crippling Poison, etc. => remove it
417
418 if (!UpdateVictim())
419 return;
420
421 // some code to cast spell Mana Burn on random target which has mana
422 if (ManaBurnTimer <= diff)
423 {
424 std::list<Unit*> UnitsWithMana;
425 for (auto* ref : me->GetThreatManager().GetUnsortedThreatList())
426 if (ref->GetVictim()->GetPower(POWER_MANA))
427 UnitsWithMana.push_back(ref->GetVictim());
428 if (!UnitsWithMana.empty())
429 {
431 ManaBurnTimer = urand(8000, 18000); // 8-18 sec cd
432 }
433 else
434 ManaBurnTimer = 3500;
435 } else ManaBurnTimer -= diff;
436
437 if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID)) // start: support for quest 10190
438 {
440 && player->GetQuestStatus(QUEST_RECHARGING_THE_BATTERIES) == QUEST_STATUS_INCOMPLETE)
441 {
443 Weak = true;
444 }
446 {
447 Drained = true;
448 int32 uHpPct = int32(me->GetHealthPct());
449
451
454 me->SetInCombatWith(player);
455 }
456 } // end: support for quest 10190
457 }
458 };
459};
460
461/*######
462## Quest 10857: Teleport This!
463######*/
464
466{
474
475// 38920 - Detonate Teleporter
477{
478 bool Load() override
479 {
480 return GetCaster()->GetTypeId() == TYPEID_UNIT;
481 }
482
483 bool Validate(SpellInfo const* /*spellInfo*/) override
484 {
485 return ValidateSpellInfo(
486 {
490 });
491 }
492
493 void HandleScript(SpellEffIndex /*effIndex*/)
494 {
495 if (Creature* creature = GetHitCreature())
496 {
497 if (Unit* charmer = GetCaster()->GetCharmerOrOwner())
498 {
499 if (Player* player = charmer->ToPlayer())
500 {
501 uint32 spellId = 0;
502
503 switch (creature->GetEntry())
504 {
507 break;
510 break;
513 break;
514 default:
515 return;
516 }
517
518 player->CastSpell(player, spellId);
519 }
520 }
521 }
522 }
523
524 void Register() override
525 {
527 }
528};
529
531{
534 new npc_phase_hunter();
536}
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
@ TEMPSUMMON_TIMED_DESPAWN
Definition: ObjectDefines.h:65
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:145
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
uint32 rand32()
Definition: Random.cpp:70
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_2
Definition: SharedDefines.h:32
@ SPELL_EFFECT_SCRIPT_EFFECT
@ POWER_MANA
@ SPELL_AURA_MOD_DECREASE_SPEED
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
#define ENSURE_AI(a, b)
Definition: UnitAI.h:29
@ UNIT_STAND_STATE_KNEEL
Definition: UnitDefines.h:50
@ UNIT_STAND_STATE_STAND
Definition: UnitDefines.h:42
@ UNIT_STATE_ROOT
Definition: Unit.h:265
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition: Creature.cpp:577
void LowerPlayerDamageReq(uint64 unDamage)
Definition: Creature.cpp:1680
CreatureAI * AI() const
Definition: Creature.h:214
void Clear()
Definition: ObjectGuid.h:286
TypeID GetTypeId() const
Definition: Object.h:173
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
void AreaExploredOrEventHappens(uint32 questId)
Definition: Player.cpp:16577
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: Player.cpp:16050
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Definition: SpellScript.h:162
Creature * GetHitCreature() const
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetUnsortedThreatList() const
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void SetVisible(bool x)
Definition: Unit.cpp:8351
float GetHealthPct() const
Definition: Unit.h:784
void SetHealth(uint64 val)
Definition: Unit.cpp:9346
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition: Unit.cpp:10100
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
void SetInCombatWith(Unit *enemy, bool addSecondUnitSuppressed=false)
Definition: Unit.h:1045
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition: Unit.cpp:12671
bool IsAlive() const
Definition: Unit.h:1164
uint64 GetMaxHealth() const
Definition: Unit.h:777
uint64 GetHealth() const
Definition: Unit.h:776
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4674
uint64 CountPctFromMaxHealth(int32 pct) const
Definition: Unit.h:785
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4664
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition: Object.cpp:2025
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
bool OnTrigger(Player *player, AreaTriggerEntry const *) override
CreatureAI * GetAI(Creature *creature) const override
CreatureAI * GetAI(Creature *creature) const override
bool Validate(SpellInfo const *) override
void HandleScript(SpellEffIndex)
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
TC_GAME_API Player * GetPlayer(Map const *, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:109
bool HealthBelowPct(uint32 pct) const
void JustEngagedWith(Unit *who) override
void UpdateAI(uint32 diff) override
DetonateTeleporter
@ NPC_CENTRAL_TELEPORTER_CREDIT
@ NPC_WESTERN_TELEPORTER_CREDIT
@ SPELL_TELEPORTER_KILL_CREDIT_2
@ NPC_EASTERN_TELEPORTER_CREDIT
@ SPELL_TELEPORTER_KILL_CREDIT_1
@ SPELL_TELEPORTER_KILL_CREDIT_3
CommanderDawnforgeData
@ QUEST_INFO_GATHERING
@ SAY_COMMANDER_DAWNFORGE_1
@ SAY_COMMANDER_DAWNFORGE_5
@ SAY_COMMANDER_DAWNFORGE_2
@ SAY_ARCANIST_ARDONIS_1
@ SAY_PATHALEON_CULATOR_IMAGE_2
@ SAY_PATHALEON_CULATOR_IMAGE_1
@ SAY_COMMANDER_DAWNFORGE_3
@ SAY_ARCANIST_ARDONIS_2
@ SAY_COMMANDER_DAWNFORGE_4
@ SAY_PATHALEON_CULATOR_IMAGE_2_2
@ SPELL_SUNFURY_DISGUISE
@ SAY_PATHALEON_CULATOR_IMAGE_2_1
PhaseHunterData
@ NPC_PHASE_HUNTER_ENTRY
@ SPELL_MATERIALIZE
@ NPC_DRAINED_PHASE_HUNTER_ENTRY
@ SPELL_RECHARGING_BATTERY
@ SPELL_PHASE_SLIP
@ QUEST_RECHARGING_THE_BATTERIES
@ EMOTE_WEAK
@ SPELL_DE_MATERIALIZE
@ SPELL_MANA_BURN
void AddSC_netherstorm()