Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_midnight.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/* ScriptData
7SDName: Boss_Midnight
8SD%Complete: 100
9SDComment:
10SDCategory: Karazhan
11EndScriptData */
12
13#include "ScriptMgr.h"
14#include "ScriptedCreature.h"
15#include "SpellInfo.h"
16
18{
22
27
30 SPELL_BERSERKER_CHARGE = 26561, //Only when mounted
31
33
34 //Attumen (@todo Use the summoning spell instead of Creature id. It works, but is not convenient for us)
36};
37
39{
40public:
41 boss_attumen() : CreatureScript("boss_attumen") { }
42
44 {
45 return new boss_attumenAI(creature);
46 }
47
48 struct boss_attumenAI : public ScriptedAI
49 {
50 boss_attumenAI(Creature* creature) : ScriptedAI(creature)
51 {
52 Phase = 1;
53
54 CleaveTimer = std::rand() % 15000 + 10000;
55 CurseTimer = 30000;
56 RandomYellTimer = std::rand() % 60000 + 30000; //Occasionally yell
57 ChargeTimer = 20000;
58 ResetTimer = 0;
59 }
60
66 uint32 ChargeTimer; //only when mounted
68
70 {
71 ResetTimer = 0;
72 }
73
79
80 void EnterCombat(Unit* /*who*/) OVERRIDE { }
81
82 void KilledUnit(Unit* /*victim*/) OVERRIDE
83 {
85 }
86
87 void JustDied(Unit* /*killer*/) OVERRIDE
88 {
90 if (Unit* midnight = Unit::GetUnit(*me, Midnight))
91 midnight->Kill(midnight);
92 }
93
94 void UpdateAI(uint32 diff) OVERRIDE;
95
96 void SpellHit(Unit* /*source*/, const SpellInfo* spell) OVERRIDE
97 {
98 if (spell->Mechanic == MECHANIC_DISARM)
100 }
101 };
102};
103
105{
106public:
107 boss_midnight() : CreatureScript("boss_midnight") { }
108
110 {
111 return new boss_midnightAI(creature);
112 }
113
115 {
116 boss_midnightAI(Creature* creature) : ScriptedAI(creature) { }
117
121
123 {
124 Phase = 1;
125 Attumen = 0;
126 Mount_Timer = 0;
127
129 me->SetVisible(true);
130 }
131
132 void EnterCombat(Unit* /*who*/) OVERRIDE { }
133
134 void KilledUnit(Unit* /*victim*/) OVERRIDE
135 {
136 if (Phase == 2)
137 {
138 if (Unit* unit = Unit::GetUnit(*me, Attumen))
139 Talk(SAY_MIDNIGHT_KILL, unit);
140 }
141 }
142
144 {
145 if (!UpdateVictim())
146 return;
147
148 if (Phase == 1 && HealthBelowPct(95))
149 {
150 Phase = 2;
151 if (Creature* attumen = me->SummonCreature(SUMMON_ATTUMEN, 0.0f, 0.0f, 0.0f, 0.0f, TempSummonType::TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000))
152 {
153 Attumen = attumen->GetGUID();
154 attumen->AI()->AttackStart(me->GetVictim());
155 SetMidnight(attumen, me->GetGUID());
156 Talk(SAY_APPEAR, attumen);
157 }
158 }
159 else if (Phase == 2 && HealthBelowPct(25))
160 {
161 if (Unit* pAttumen = Unit::GetUnit(*me, Attumen))
162 Mount(pAttumen);
163 }
164 else if (Phase == 3)
165 {
166 if (Mount_Timer)
167 {
168 if (Mount_Timer <= diff)
169 {
170 Mount_Timer = 0;
171 me->SetVisible(false);
172 me->GetMotionMaster()->MoveIdle();
173 if (Unit* pAttumen = Unit::GetUnit(*me, Attumen))
174 {
175 pAttumen->SetDisplayId(MOUNTED_DISPLAYID);
176 pAttumen->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
177 if (pAttumen->GetVictim())
178 {
179 pAttumen->GetMotionMaster()->MoveChase(pAttumen->GetVictim());
180 pAttumen->SetTarget(pAttumen->GetVictim()->GetGUID());
181 }
182 pAttumen->SetObjectScale(1);
183 }
184 } else Mount_Timer -= diff;
185 }
186 }
187
188 if (Phase != 3)
190 }
191
192 void Mount(Unit* pAttumen)
193 {
194 Talk(SAY_MOUNT, pAttumen);
195 Phase = 3;
198 float angle = me->GetAngle(pAttumen);
199 float distance = me->GetDistance2d(pAttumen);
200 float newX = me->GetPositionX() + std::cos(angle)*(distance/2);
201 float newY = me->GetPositionY() + std::sin(angle)*(distance/2);
202 float newZ = 50;
203 //me->Relocate(newX, newY, newZ, angle);
204 //me->SendMonsterMove(newX, newY, newZ, 0, true, 1000);
205 me->GetMotionMaster()->Clear();
206 me->GetMotionMaster()->MovePoint(0, newX, newY, newZ);
207 distance += 10;
208 newX = me->GetPositionX() + std::cos(angle)*(distance/2);
209 newY = me->GetPositionY() + std::sin(angle)*(distance/2);
210 pAttumen->GetMotionMaster()->Clear();
211 pAttumen->GetMotionMaster()->MovePoint(0, newX, newY, newZ);
212 //pAttumen->Relocate(newX, newY, newZ, -angle);
213 //pAttumen->SendMonsterMove(newX, newY, newZ, 0, true, 1000);
214 Mount_Timer = 1000;
215 }
216
217 void SetMidnight(Creature* pAttumen, uint64 value)
218 {
219 CAST_AI(boss_attumen::boss_attumenAI, pAttumen->AI())->Midnight = value;
220 }
221 };
222};
223
225{
226 if (ResetTimer)
227 {
228 if (ResetTimer <= diff)
229 {
230 ResetTimer = 0;
231 Unit* pMidnight = Unit::GetUnit(*me, Midnight);
232 if (pMidnight)
233 {
235 pMidnight->SetVisible(true);
236 }
237 Midnight = 0;
238 me->SetVisible(false);
239 me->Kill(me);
240 } else ResetTimer -= diff;
241 }
242
243 //Return since we have no target
244 if (!UpdateVictim())
245 return;
246
248 return;
249
250 if (CleaveTimer <= diff)
251 {
253 CleaveTimer = std::rand() % 15000 + 10000;
254 } else CleaveTimer -= diff;
255
256 if (CurseTimer <= diff)
257 {
259 CurseTimer = 30000;
260 } else CurseTimer -= diff;
261
262 if (RandomYellTimer <= diff)
263 {
265 RandomYellTimer = std::rand() % 60000 + 30000;
266 } else RandomYellTimer -= diff;
267
268 if (me->GetUInt32Value(UNIT_FIELD_DISPLAY_ID) == MOUNTED_DISPLAYID)
269 {
270 if (ChargeTimer <= diff)
271 {
272 Unit* target = NULL;
273 ThreatContainer::StorageType const &t_list = me->getThreatManager().getThreatList();
274 std::vector<Unit*> target_list;
275 for (ThreatContainer::StorageType::const_iterator itr = t_list.begin(); itr != t_list.end(); ++itr)
276 {
277 target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
278 if (target && !target->IsWithinDist(me, ATTACK_DISTANCE, false))
279 target_list.push_back(target);
280 target = NULL;
281 }
282 if (!target_list.empty())
283 target = *(target_list.begin()+rand()%target_list.size());
284
286 ChargeTimer = 20000;
287 } else ChargeTimer -= diff;
288 }
289 else
290 {
291 if (HealthBelowPct(25))
292 {
293 Creature* pMidnight = Unit::GetCreature(*me, Midnight);
294 if (pMidnight && pMidnight->GetTypeId() == TypeID::TYPEID_UNIT)
295 {
296 CAST_AI(boss_midnight::boss_midnightAI, (pMidnight->AI()))->Mount(me);
297 me->SetHealth(pMidnight->GetHealth());
299 }
300 }
301 }
302
304}
305
307{
308 new boss_attumen();
309 new boss_midnight();
310}
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
#define ATTACK_DISTANCE
Definition Object.h:22
@ TYPEID_UNIT
Definition Object.h:54
@ TEMPSUMMON_TIMED_OR_DEAD_DESPAWN
Definition Object.h:68
#define CAST_AI(a, b)
@ MECHANIC_DISARM
@ UNIT_FLAG_NON_ATTACKABLE
Definition Unit.h:626
@ UNIT_FLAG_NOT_SELECTABLE
Definition Unit.h:650
@ UNIT_FIELD_DISPLAY_ID
@ UNIT_FIELD_FLAGS
#define SAY_DEATH
#define SAY_KILL
void AddSC_boss_attumen()
Midnight
@ SAY_DEATH
@ SUMMON_ATTUMEN
@ SPELL_SHADOWCLEAVE
@ SAY_DISARMED
@ SAY_MIDNIGHT_KILL
@ SAY_KILL
@ SAY_MOUNT
@ SPELL_INTANGIBLE_PRESENCE
@ MOUNTED_DISPLAYID
@ SAY_APPEAR
@ SAY_RANDOM
@ SPELL_BERSERKER_CHARGE
@ SAY_RANDOM
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureAI * AI() const
Definition Creature.h:483
CreatureScript(const char *name)
void MovePoint(uint32 id, Position const &pos, bool generatePath=true)
void Clear(bool reset=true)
TypeID GetTypeId() const
Definition Object.h:131
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
std::list< HostileReference * > StorageType
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
void DoCastVictim(uint32 spellId, bool triggered=false)
Definition UnitAI.cpp:168
Definition Unit.h:1367
void SetVisible(bool x)
Definition Unit.cpp:4163
MotionMaster * GetMotionMaster()
Definition Unit.h:2605
static Creature * GetCreature(WorldObject &object, uint64 guid)
Definition Unit.cpp:4905
uint32 GetHealth() const
Definition Unit.h:1600
static Unit * GetUnit(WorldObject &object, uint64 guid)
Definition Unit.cpp:4895
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1730
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Creature * me
bool HealthBelowPct(uint32 pct) const
ScriptedAI(Creature *creature)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
boss_attumenAI(Creature *creature)
void KilledUnit(Unit *) OVERRIDE
void JustDied(Unit *) OVERRIDE
void SpellHit(Unit *, const SpellInfo *spell) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
void SetMidnight(Creature *pAttumen, uint64 value)
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void KilledUnit(Unit *) OVERRIDE
boss_midnightAI(Creature *creature)