Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_ymiron.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/* Script Data Start
7SDName: Boss ymiron
8SDAuthor: LordVanMartin
9SD%Complete:
10SDComment:
11SDCategory:
12Script Data End */
13
14#include "ScriptMgr.h"
15#include "ScriptedCreature.h"
16#include "utgarde_pinnacle.h"
17#include "SpellInfo.h"
18
42
43//not in db
54
68
75
77{
78 {NPC_BJORN_VISUAL, SAY_SUMMON_BJORN, 404.379f, -335.335f, 104.756f, 413.594f, -335.408f, 107.995f, 3.157f},
79 {NPC_HALDOR_VISUAL, SAY_SUMMON_HALDOR, 380.813f, -335.069f, 104.756f, 369.994f, -334.771f, 107.995f, 6.232f},
80 {NPC_RANULF_VISUAL, SAY_SUMMON_RANULF, 381.546f, -314.362f, 104.756f, 370.841f, -314.426f, 107.995f, 6.232f},
81 {NPC_TORGYN_VISUAL, SAY_SUMMON_TORGYN, 404.310f, -314.761f, 104.756f, 413.992f, -314.703f, 107.995f, 3.157f}
82};
83
84enum Misc
85{
87};
88
90{
91public:
92 boss_ymiron() : CreatureScript("boss_ymiron") { }
93
95 {
96 return new boss_ymironAI(creature);
97 }
98
99 struct boss_ymironAI : public ScriptedAI
100 {
101 boss_ymironAI(Creature* creature) : ScriptedAI(creature)
102 {
103 instance = creature->GetInstanceScript();
104 for (int i = 0; i < 4; ++i)
105 m_uiActiveOrder[i] = i;
106 for (int i = 0; i < 3; ++i)
107 {
108 int r = i + (rand() % (4 - i));
109 int temp = m_uiActiveOrder[i];
111 m_uiActiveOrder[r] = temp;
112 }
113
115 m_uiOrbGUID = 0;
116 }
117
124 bool kingsBane; // Achievement King's Bane
125
128
133
138
142
145
147
149 {
150 m_bIsWalking = false;
151 m_bIsPause = false;
152 m_bIsActiveWithBJORN = false;
153 m_bIsActiveWithHALDOR = false;
154 m_bIsActiveWithRANULF = false;
155 m_bIsActiveWithTORGYN = false;
156 kingsBane = true;
157
158 m_uiFetidRot_Timer = std::rand() % 13000 + 8000;
159 m_uiBane_Timer = std::rand() % 23000 + 18000;
160 m_uiDarkSlash_Timer = std::rand() % 33000 + 28000;
162 m_uiPause_Timer = 0;
163
168
172
175
176 if (instance)
178 }
179
180 void EnterCombat(Unit* /*who*/) OVERRIDE
181 {
183
184 if (instance)
186 }
187
188 void SpellHitTarget(Unit* who, SpellInfo const* spell) OVERRIDE
189 {
190 if (who && who->GetTypeId() == TypeID::TYPEID_PLAYER && spell->Id == 59302)
191 kingsBane = false;
192 }
193
195 {
196 if (type == DATA_KINGS_BANE)
197 return kingsBane ? 1 : 0;
198
199 return 0;
200 }
201
203 {
204 if (m_bIsWalking)
205 {
206 if (m_uiPause_Timer <= diff)
207 {
209 DoCast(me, SPELL_CHANNEL_YMIRON_TO_SPIRIT); // should be on spirit
211 {
212 m_uiActivedCreatureGUID = temp->GetGUID();
213 temp->CastSpell(me, SPELL_CHANNEL_SPIRIT_TO_YMIRON, true);
215 temp->SetDisableGravity(true);
217 {
218 case 0: m_bIsActiveWithBJORN = true; break;
219 case 1: m_bIsActiveWithHALDOR = true; break;
220 case 2: m_bIsActiveWithRANULF = true; break;
221 case 3: m_bIsActiveWithTORGYN = true; break;
222 }
223 }
224
225 m_bIsPause = true;
226 m_bIsWalking = false;
227 m_uiPause_Timer = 3000;
228 } else m_uiPause_Timer -= diff;
229 return;
230 }
231 else if (m_bIsPause)
232 {
233 if (m_uiPause_Timer <= diff)
234 {
239
240 m_bIsPause = false;
241 m_uiPause_Timer = 0;
242 } else m_uiPause_Timer -= diff;
243 return;
244 }
245
246 //Return since we have no target
247 if (!UpdateVictim())
248 return;
249
250 if (!m_bIsPause)
251 {
252 // Normal spells ------------------------------------------------------------------------
253 if (m_uiBane_Timer <= diff)
254 {
256 m_uiBane_Timer = std::rand() % 25000 + 20000;
257 } else m_uiBane_Timer -= diff;
258
259 if (m_uiFetidRot_Timer <= diff)
260 {
262 m_uiFetidRot_Timer = std::rand() % 15000 + 10000;
263 } else m_uiFetidRot_Timer -= diff;
264
265 if (m_uiDarkSlash_Timer <= diff)
266 {
268 m_uiDarkSlash_Timer = std::rand() % 35000 + 30000;
269 } else m_uiDarkSlash_Timer -= diff;
270
272 {
274 m_uiAncestors_Vengeance_Timer = DUNGEON_MODE(std::rand() % 65000 + 60000, std::rand() % 50000 + 45000);
275 } else m_uiAncestors_Vengeance_Timer -= diff;
276
277 // Abilities ------------------------------------------------------------------------------
279 {
280 //DoCast(me, SPELL_SUMMON_SPIRIT_FOUNT); // works fine, but using summon has better control
281 if (Creature* temp = me->SummonCreature(NPC_SPIRIT_FOUNT, 385.0f + rand() % 10, -330.0f + rand() % 10, 104.756f, 0, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 180000))
282 {
283 temp->SetSpeed(MOVE_RUN, 0.4f);
284 temp->CastSpell(temp, DUNGEON_MODE(SPELL_SPIRIT_FOUNT, H_SPELL_SPIRIT_FOUNT), true);
286 temp->SetDisplayId(11686);
287 m_uiOrbGUID = temp->GetGUID();
288 }
289 m_bIsActiveWithBJORN = false; // only one orb
290 } else m_uiAbility_BJORN_Timer -= diff;
291
293 {
295 m_uiAbility_HALDOR_Timer = 5000; // overtime
296 } else m_uiAbility_HALDOR_Timer -= diff;
297
299 {
301 m_uiAbility_RANULF_Timer = 10000; // overtime
302 } else m_uiAbility_RANULF_Timer -= diff;
303
305 {
306 float x, y, z;
307 x = me->GetPositionX()-5;
308 y = me->GetPositionY()-5;
309 z = me->GetPositionZ();
310 for (uint8 i = 0; i < 4; ++i)
311 {
312 //DoCast(me, SPELL_SUMMON_AVENGING_SPIRIT); // works fine, but using summon has better control
313 if (Creature* temp = me->SummonCreature(NPC_AVENGING_SPIRIT, x + rand() % 10, y + rand() % 10, z, 0, TempSummonType::TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
314 {
315 if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
316 {
317 temp->AddThreat(target, 0.0f);
318 temp->AI()->AttackStart(target);
319 }
320 }
321 }
322 m_uiAbility_TORGYN_Timer = 15000; // overtime
323 } else m_uiAbility_TORGYN_Timer -= diff;
324
325 // Health check -----------------------------------------------------------------------------
326 if (me->HealthBelowPct(100 - m_uiHealthAmountMultipler * m_uiHealthAmountModifier))
327 {
328 uint8 m_uiOrder = m_uiHealthAmountModifier - 1;
330
331 me->InterruptNonMeleeSpells(true);
333 me->GetMotionMaster()->Clear();
334 me->StopMoving();
335 me->AttackStop();
336 me->GetMotionMaster()->MovePoint(0, ActiveBoat[m_uiActiveOrder[m_uiOrder]].MoveX, ActiveBoat[m_uiActiveOrder[m_uiOrder]].MoveY, ActiveBoat[m_uiActiveOrder[m_uiOrder]].MoveZ);
337
340
341 m_bIsActiveWithBJORN = false;
342 m_bIsActiveWithHALDOR = false;
343 m_bIsActiveWithRANULF = false;
344 m_bIsActiveWithTORGYN = false;
345
346 m_uiBane_Timer += 8000;
347 m_uiFetidRot_Timer += 8000;
348 m_uiDarkSlash_Timer += 8000;
350
351 m_uiActivedNumber = m_uiOrder;
352 m_bIsWalking = true;
353 m_uiPause_Timer = 2000;
354 return;
355 }
357 }
358 }
359
370
371 void KilledUnit(Unit* /*victim*/) OVERRIDE
372 {
373 Talk(SAY_SLAY);
374 }
375
376 void DespawnBoatGhosts(uint64 m_uiCreatureGUID)
377 {
378 if (m_uiCreatureGUID)
379 if (Creature* temp = Unit::GetCreature(*me, m_uiCreatureGUID))
380 temp->DisappearAndDie();
381
382 m_uiCreatureGUID = 0;
383 }
384 };
385};
386
388{
389 public:
391 {
392 }
393
394 bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
395 {
396 if (!target)
397 return false;
398
399 if (Creature* Ymiron = target->ToCreature())
400 if (Ymiron->AI()->GetData(DATA_KINGS_BANE))
401 return true;
402
403 return false;
404 }
405};
406
408{
409 new boss_ymiron();
411}
std::int32_t int32
Definition Define.h:73
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
@ DONE
@ NOT_STARTED
@ TYPEID_PLAYER
Definition Object.h:55
@ TEMPSUMMON_CORPSE_DESPAWN
Definition Object.h:72
@ TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT
Definition Object.h:71
@ MOVE_RUN
Definition Unit.h:556
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ SELECT_TARGET_RANDOM
Definition UnitAI.h:23
@ UNIT_FIELD_FLAGS
Creatures
@ SAY_SLAY
#define SAY_DEATH
#define SAY_AGGRO
@ NPC_TORGYN_VISUAL
@ NPC_AVENGING_SPIRIT
@ NPC_HALDOR
@ NPC_SPIRIT_FOUNT
@ NPC_RANULF_VISUAL
@ NPC_HALDOR_VISUAL
@ NPC_RANULF
@ NPC_BJORN_VISUAL
@ NPC_BJORN
@ NPC_TORGYN
@ DATA_KINGS_BANE
@ SAY_DEATH
@ SAY_SUMMON_BJORN
@ SAY_SUMMON_RANULF
@ SAY_SUMMON_TORGYN
@ SAY_AGGRO
@ SAY_SLAY
@ SAY_SUMMON_HALDOR
void AddSC_boss_ymiron()
static ActiveBoatStruct ActiveBoat[4]
@ SPELL_SPIRIT_BURST
@ SPELL_SCREAMS_OF_THE_DEAD
@ H_SPELL_SPIRIT_BURST
@ SPELL_SUMMON_AVENGING_SPIRIT
@ SPELL_CHANNEL_SPIRIT_TO_YMIRON
@ SPELL_CHANNEL_YMIRON_TO_SPIRIT
@ H_SPELL_FETID_ROT
@ SPELL_SPIRIT_FOUNT
@ H_SPELL_SPIRIT_FOUNT
@ H_SPELL_SPIRIT_STRIKE
@ SPELL_SUMMON_SPIRIT_FOUNT
@ SPELL_ANCESTORS_VENGEANCE
@ SPELL_SPIRIT_STRIKE
@ SPELL_DARK_SLASH
@ H_SPELL_BANE
@ SPELL_BANE
@ SPELL_FETID_ROT
AchievementCriteriaScript(const char *name)
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
CreatureScript(const char *name)
Creature * ToCreature()
Definition Object.h:207
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
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
bool OnCheck(Player *, Unit *target) OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
@ SPELL_SPIRIT_BURST
Creature * me
ScriptedAI(Creature *creature)
const T & DUNGEON_MODE(const T &normal5, const T &heroic5) const
void EnterCombat(Unit *) OVERRIDE
void DespawnBoatGhosts(uint64 m_uiCreatureGUID)
uint32 GetData(uint32 type) const OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
boss_ymironAI(Creature *creature)
void JustDied(Unit *) OVERRIDE
void SpellHitTarget(Unit *who, SpellInfo const *spell) OVERRIDE
void KilledUnit(Unit *) OVERRIDE
@ DATA_KING_YMIRON_EVENT