TrinityCore
Loading...
Searching...
No Matches
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
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
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
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
528};
529
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
@ TEMPSUMMON_TIMED_DESPAWN
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:150
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
uint32 rand32()
Definition Random.cpp:70
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
SpellEffIndex
@ EFFECT_2
@ SPELL_EFFECT_SCRIPT_EFFECT
@ POWER_MANA
@ SPELL_AURA_MOD_DECREASE_SPEED
#define SpellEffectFn(F, I, N)
#define ENSURE_AI(a, b)
Definition UnitAI.h:30
@ UNIT_STAND_STATE_KNEEL
Definition UnitDefines.h:50
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:42
@ UNIT_STATE_ROOT
Definition Unit.h:271
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
TypeID GetTypeId() const
Definition BaseEntity.h:166
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
bool UpdateVictim()
Creature *const me
Definition CreatureAI.h:63
bool UpdateEntry(uint32 entry, CreatureData const *data=nullptr, bool updateLevel=true)
Definition Creature.cpp:593
void LowerPlayerDamageReq(uint64 unDamage)
CreatureAI * AI() const
Definition Creature.h:228
void Clear()
Definition ObjectGuid.h:329
Player * ToPlayer()
Definition Object.h:126
uint32 GetEntry() const
Definition Object.h:89
void AreaExploredOrEventHappens(uint32 questId)
Definition Player.cpp:16552
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition Player.cpp:15962
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
Creature * GetHitCreature() const
Unit * GetCaster() const
HookList< EffectHandler > OnEffectHitTarget
Trinity::IteratorPair< ThreatListIterator, std::nullptr_t > GetUnsortedThreatList() const
SpellCastResult DoCast(uint32 spellId)
Definition UnitAI.cpp:89
Definition Unit.h:635
void SetVisible(bool x)
Definition Unit.cpp:8768
float GetHealthPct() const
Definition Unit.h:796
void SetHealth(uint64 val)
Definition Unit.cpp:9973
uint64 CountPctFromMaxHealth(float pct) const
Definition Unit.h:797
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition Unit.cpp:10731
ThreatManager & GetThreatManager()
Definition Unit.h:1078
void SetInCombatWith(Unit *enemy, bool addSecondUnitSuppressed=false)
Definition Unit.h:1060
void SetFacingToObject(WorldObject const *object, bool force=true)
Definition Unit.cpp:13307
bool IsAlive() const
Definition Unit.h:1185
uint64 GetMaxHealth() const
Definition Unit.h:789
uint64 GetHealth() const
Definition Unit.h:788
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4814
bool HasUnitState(const uint32 f) const
Definition Unit.h:743
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
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:1398
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:1517
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) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition Containers.h:110
bool HealthBelowPct(uint32 pct) const
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()