Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_earthrager_ptah.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "ObjectMgr.h"
7#include "ScriptMgr.h"
8#include "ScriptedCreature.h"
9#include "SpellScript.h"
10#include "SpellAuraEffects.h"
11#include "Player.h"
12#include "Weather.h"
13#include "WorldSession.h"
15
17{
20};
21
30
32{
36
39
40 SPELL_SUMMON_QUICKSAND = 75550, // Spell not in DBC, no SMSG_SPELL_START/GO for it
41
43
46};
47
56
61
63{
64public:
65 SummonScarab(Unit* owner, InstanceScript* instance) : _owner(owner), _instance(instance) { }
66
67 bool Execute(uint64 /*execTime*/, uint32 /*diff*/)
68 {
69 if (!_instance || _instance->GetBossState(DATA_EARTHRAGER_PTAH) != IN_PROGRESS)
70 return true; // delete event
71
73 _owner->RemoveAurasDueToSpell(SPELL_BEETLE_BURROW);
74 return true;
75 }
76protected:
79};
80
82{
83public:
84 boss_earthrager_ptah() : CreatureScript("boss_earthrager_ptah") { }
85
87 {
89
90 void Cleanup()
91 {
92 std::list<Creature*> units;
93
95 for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr)
96 (*itr)->DespawnOrUnsummon();
97
99 for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr)
100 (*itr)->DespawnOrUnsummon();
101 }
102
103 void SendWeather(WeatherState weather, float grade) const
104 {
105 WorldPacket data(SMSG_WEATHER, 4 + 4 + 1);
106 data << uint32(weather); // WeatherID
107 data << float(grade); // Intensity
108 data.WriteBit(false); // Abrupt
109 data.FlushBits();
110 SendPacketToPlayers(&data);
111 }
112
113 // Send packet to all players in Tomb of the Earthrager
114 void SendPacketToPlayers(WorldPacket const* data) const
115 {
116 Map::PlayerList const& players = me->GetMap()->GetPlayers();
117 if (!players.isEmpty())
118 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
119 if (Player* player = itr->GetSource())
120 if (player->GetAreaId() == AREA_TOMB_OF_THE_EARTHRAGER)
121 player->GetSession()->SendPacket(data);
122 }
123
125 {
126 _summonDeaths = 0;
127 _hasDispersed = false;
128 Cleanup();
129 _Reset();
130 events.SetPhase(PHASE_NORMAL);
131 events.ScheduleEvent(EVENT_RAGING_SMASH, std::rand() % 12000 + 7000, 0, PHASE_NORMAL);
132 events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL);
133 events.ScheduleEvent(EVENT_EARTH_SPIKE, std::rand() % 21000 + 16000, 0, PHASE_NORMAL);
134 }
135
136 void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
137 {
138 if (me->HealthBelowPctDamaged(50, damage) && (events.GetPhaseMask() & PHASE_MASK_NORMAL) && !_hasDispersed)
139 {
140 events.SetPhase(PHASE_DISPERSE);
141 _hasDispersed = true;
142
143 me->AttackStop();
146 events.ScheduleEvent(EVENT_PTAH_EXPLODE, 6000, 0, PHASE_DISPERSE);
147 events.ScheduleEvent(EVENT_QUICKSAND, 10000, 0, PHASE_DISPERSE);
148
149 std::list<Creature*> stalkers;
151 std::list<Creature*> beetlers = stalkers;
152
153 Skyfire::Containers::RandomResizeList(beetlers, 9); // Holds the summoners of Jeweled Scarab
154
155 for (std::list<Creature*>::iterator itr = beetlers.begin(); itr != beetlers.end(); ++itr)
156 {
157 stalkers.remove((*itr)); // Remove it to prevent a single trigger from spawning multiple npcs.
158 (*itr)->CastSpell((*itr), SPELL_BEETLE_BURROW); // Cast visual
159 // Summon after 5 seconds.
160 (*itr)->m_Events.AddEvent(new SummonScarab((*itr), instance), (*itr)->m_Events.CalculateTime(5000));
161 }
162
163 Skyfire::Containers::RandomResizeList(stalkers, 2); // Holds the summoners of Dustbone Horror
164
165 for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
166 (*itr)->CastSpell((*itr), SPELL_SUMMON_DUSTBONE_HORROR);
167 }
168 }
169
170 void SetData(uint32 index, uint32 /*value*/) OVERRIDE
171 {
172 if (index == DATA_SUMMON_DEATHS)
173 {
175 if (_summonDeaths == 11) // All summons died
176 {
178 me->RemoveAurasDueToSpell(SPELL_PTAH_EXPLOSION);
179 events.SetPhase(PHASE_NORMAL);
180 events.ScheduleEvent(EVENT_RAGING_SMASH, std::rand() % 12000 + 7000, 0, PHASE_NORMAL);
181 events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL);
182 events.ScheduleEvent(EVENT_EARTH_SPIKE, std::rand() % 21000 + 16000, 0, PHASE_NORMAL);
183 }
184 }
185 }
186
187 void EnterCombat(Unit* /*who*/) OVERRIDE
188 {
189 instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
191 _EnterCombat();
192 }
193
194 void JustDied(Unit* /*killer*/) OVERRIDE
195 {
196 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
198 _JustDied();
199 Cleanup();
200 }
201
203 {
204 instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
206 instance->SetBossState(DATA_EARTHRAGER_PTAH, FAIL);
207 }
208
210 {
211 if (!UpdateVictim() || !CheckInRoom())
212 return;
213
214 events.Update(diff);
215
216 if (me->HasUnitState(UNIT_STATE_CASTING))
217 return;
218
219 while (uint32 eventId = events.ExecuteEvent())
220 {
221 switch (eventId)
222 {
225 events.ScheduleEvent(EVENT_RAGING_SMASH, std::rand() % 12000 + 7000, 0, PHASE_NORMAL);
226 break;
227 case EVENT_FLAME_BOLT:
229 events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL);
230 break;
232 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
234 events.ScheduleEvent(EVENT_EARTH_SPIKE, std::rand() % 21000 + 16000, 0, PHASE_NORMAL);
235 break;
238 break;
239 case EVENT_QUICKSAND:
240 // Spell not in DBC, it is not cast either, according to sniffs
241 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
242 if (Creature* quicksand = me->SummonCreature(NPC_QUICKSAND, *target))
243 quicksand->SetUInt32Value(UNIT_FIELD_CREATED_BY_SPELL, SPELL_SUMMON_QUICKSAND);
244 events.ScheduleEvent(EVENT_QUICKSAND, 10000, 0, PHASE_DISPERSE);
245 break;
246 }
247 }
248
249 if (events.GetPhaseMask() & PHASE_MASK_NORMAL) // Do not melee in the disperse phase
251 }
252
253 protected:
256 };
257
259 {
261 }
262};
263
289
329
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
@ IN_PROGRESS
@ FAIL
@ ENCOUNTER_FRAME_DISENGAGE
@ ENCOUNTER_FRAME_ENGAGE
void GetCreatureListWithEntryInGrid(std::list< Creature * > &list, WorldObject *source, uint32 entry, float maxSearchRange)
@ EFFECT_0
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_AURA_DUMMY
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectRemoveFn(F, I, N, M)
@ UNIT_STATE_CASTING
Definition Unit.h:527
@ UNIT_FLAG_DISABLE_POWERS
Definition Unit.h:654
@ UNIT_FLAG_UNK_31
Definition Unit.h:656
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FLAG2_FEIGN_DEATH
Definition Unit.h:663
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS2
@ UNIT_FIELD_FLAGS
@ UNIT_FIELD_CREATED_BY_SPELL
#define SAY_DEATH
#define SAY_AGGRO
@ DATA_SUMMON_DEATHS
@ SPELL_EARTH_SPIKE_WARN
@ SPELL_SANDSTORM
@ SPELL_SUMMON_QUICKSAND
@ SPELL_SUMMON_JEWELED_SCARAB
@ SPELL_PTAH_EXPLOSION
@ SPELL_RAGING_SMASH
@ SPELL_SUMMON_DUSTBONE_HORROR
@ SPELL_BEETLE_BURROW
@ SPELL_FLAME_BOLT
@ PHASE_MASK_DISPERSE
@ PHASE_MASK_NORMAL
void AddSC_boss_earthrager_ptah()
@ EVENT_EARTH_SPIKE
@ EVENT_FLAME_BOLT
@ EVENT_QUICKSAND
@ EVENT_PTAH_EXPLODE
@ EVENT_RAGING_SMASH
@ PHASE_NORMAL
Unit * GetCaster() const
HookList< EffectApplyHandler > OnEffectRemove
HookList< EffectApplyHandler > OnEffectApply
InstanceScript *const instance
void _JustReachedHome()
bool CheckInRoom()
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void FlushBits()
Definition ByteBuffer.h:154
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureScript(const char *name)
bool isEmpty() const
Definition LinkedList.h:86
MapRefManager PlayerList
Definition Map.h:406
iterator end()
iterator begin()
LinkedListHead::Iterator< MapReference const > const_iterator
Unit * GetCaster()
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
SpellScriptLoader(const char *name)
SummonScarab(Unit *owner, InstanceScript *instance)
bool Execute(uint64, uint32)
InstanceScript * _instance
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
Definition UnitAI.cpp:66
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
CreatureAI * GetAI(Creature *creature) const OVERRIDE
SpellScript * GetSpellScript() const OVERRIDE
@ SMSG_WEATHER
Definition Opcodes.h:1065
WeatherState
Definition Weather.h:34
@ WEATHER_STATE_LIGHT_SANDSTORM
Definition Weather.h:43
@ WEATHER_STATE_FOG
Definition Weather.h:36
@ NPC_BEETLE_STALKER
@ NPC_JEWELED_SCARAB
@ NPC_DUSTBONE_HORROR
@ NPC_QUICKSAND
@ AREA_TOMB_OF_THE_EARTHRAGER
CreatureAI * GetHallsOfOriginationAI(Creature *creature)
@ DATA_EARTHRAGER_PTAH
void RandomResizeList(std::list< T > &list, uint32 size)
Definition Containers.h:19
Creature * me
void SendPacketToPlayers(WorldPacket const *data) const
void DamageTaken(Unit *, uint32 &damage) OVERRIDE
void SendWeather(WeatherState weather, float grade) const
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void SetData(uint32 index, uint32) OVERRIDE