Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
boss_viscidus.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 "ScriptMgr.h"
7#include "ScriptedCreature.h"
8#include "SpellInfo.h"
10
12{
15 SPELL_TOXIN = 26575,
22 SPELL_VISCIDUS_SHRINKS = 25893, // Removed from client, in world.spell_dbc
23
24 SPELL_MEMBRANE_VISCIDUS = 25994, // damage reduction spell - removed from DBC
25 SPELL_VISCIDUS_WEAKNESS = 25926, // aura which procs at damage - should trigger the slow spells - removed from DBC
26 SPELL_VISCIDUS_GROWS = 25897, // removed from DBC
27 SPELL_SUMMON_GLOBS = 25885, // summons npc 15667 using spells from 25865 to 25884; All spells have target coords - removed from DBC
28 SPELL_VISCIDUS_TELEPORT = 25904, // removed from DBC
29};
30
37
44
55
66
68{
70};
71
72Position const ViscidusCoord = { -7992.36f, 908.19f, -52.62f, 1.68f };
73float const RoomRadius = 40.0f;
74
76{
77 public:
78 boss_viscidus() : CreatureScript("boss_viscidus") { }
79
80 struct boss_viscidusAI : public BossAI
81 {
82 boss_viscidusAI(Creature* creature) : BossAI(creature, DATA_VISCIDUS) { }
83
85 {
86 _Reset();
87 _hitcounter = 0;
89 }
90
91 void DamageTaken(Unit* attacker, uint32& /*damage*/) OVERRIDE
92 {
93 if (_phase != PHASE_MELEE)
94 return;
95
97
98 if (attacker->HasUnitState(UNIT_STATE_MELEE_ATTACKING) && _hitcounter >= HITCOUNTER_EXPLODE)
99 {
101 events.Reset();
104 me->SetVisible(false);
105 me->RemoveAura(SPELL_TOXIN);
106 me->RemoveAura(SPELL_VISCIDUS_FREEZE);
107
108 uint8 NumGlobes = me->GetHealthPct() / 5.0f;
109 for (uint8 i = 0; i < NumGlobes; ++i)
110 {
111 float Angle = i * 2 * M_PI / NumGlobes;
112 float X = ViscidusCoord.GetPositionX() + std::cos(Angle) * RoomRadius;
113 float Y = ViscidusCoord.GetPositionY() + std::sin(Angle) * RoomRadius;
114 float Z = -35.0f;
115
116 if (TempSummon* Glob = me->SummonCreature(NPC_GLOB_OF_VISCIDUS, X, Y, Z))
117 {
118 Glob->UpdateAllowedPositionZ(X, Y, Z);
119 Glob->NearTeleportTo(X, Y, Z, 0.0f);
120 Glob->GetMotionMaster()->MovePoint(ROOM_CENTER, ViscidusCoord);
121 }
122 }
123 }
126 else if (_hitcounter == HITCOUNTER_CRACK)
128 }
129
130 void SpellHit(Unit* /*caster*/, SpellInfo const* spell) OVERRIDE
131 {
132 if ((spell->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) && _phase == PHASE_FROST && me->GetHealthPct() > 5.0f)
133 {
134 ++_hitcounter;
135
137 {
138 _hitcounter = 0;
142 me->RemoveAura(SPELL_VISCIDUS_SLOWED_MORE);
143 events.ScheduleEvent(EVENT_RESET_PHASE, 15000);
144 }
146 {
148 me->RemoveAura(SPELL_VISCIDUS_SLOWED);
150 }
151 else if (_hitcounter >= HITCOUNTER_SLOW)
152 {
155 }
156 }
157 }
158
159 void EnterCombat(Unit* /*who*/) OVERRIDE
160 {
161 _EnterCombat();
162 events.Reset();
163 InitSpells();
164 }
165
167 {
169 events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, std::rand() % 15000 + 10000);
170 events.ScheduleEvent(EVENT_POISON_SHOCK, std::rand() % 12000 + 7000);
171 }
172
174 {
175 summons.DespawnAll();
177 }
178
179 void JustDied(Unit* /*killer*/) OVERRIDE
180 {
182 summons.DespawnAll();
183 }
184
186 {
187 if (!UpdateVictim())
188 return;
189
190 if (_phase == PHASE_GLOB && summons.empty())
191 {
193 me->NearTeleportTo(ViscidusCoord.GetPositionX(),
194 ViscidusCoord.GetPositionY(),
195 ViscidusCoord.GetPositionZ(),
196 ViscidusCoord.GetOrientation());
197
198 _hitcounter = 0;
200 InitSpells();
201 me->SetVisible(true);
202 }
203
204 events.Update(diff);
205
206 while (uint32 eventId = events.ExecuteEvent())
207 {
208 switch (eventId)
209 {
212 events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, std::rand() % 15000 + 10000);
213 break;
216 events.ScheduleEvent(EVENT_POISON_SHOCK, std::rand() % 12000 + 7000);
217 break;
219 _hitcounter = 0;
221 break;
222 default:
223 break;
224 }
225 }
226
227 if (_phase != PHASE_GLOB)
229 }
230
231 private:
234 };
235
237 {
238 return new boss_viscidusAI(creature);
239 }
240};
241
243{
244 public:
245 npc_glob_of_viscidus() : CreatureScript("boss_glob_of_viscidus") { }
246
248 {
249 npc_glob_of_viscidusAI(Creature* creature) : ScriptedAI(creature) { }
250
251 void JustDied(Unit* /*killer*/) OVERRIDE
252 {
253 InstanceScript* Instance = me->GetInstanceScript();
254 if (!Instance)
255 return;
256
257 if (Creature* Viscidus = me->GetMap()->GetCreature(Instance->GetData64(DATA_VISCIDUS)))
258 {
259 if (BossAI* ViscidusAI = dynamic_cast<BossAI*>(Viscidus->GetAI()))
260 ViscidusAI->SummonedCreatureDespawn(me);
261
262 if (Viscidus->IsAlive() && Viscidus->GetHealthPct() < 5.0f)
263 {
264 Viscidus->SetVisible(true);
265 Viscidus->GetVictim()->Kill(Viscidus);
266 }
267 else
268 {
269 Viscidus->SetHealth(Viscidus->GetHealth() - Viscidus->GetMaxHealth() / 20);
270 Viscidus->CastSpell(Viscidus, SPELL_VISCIDUS_SHRINKS);
271 }
272 }
273 }
274
276 {
277 if (id == ROOM_CENTER)
278 {
280 ((TempSummon*)me)->UnSummon();
281 }
282 }
283 };
284
286 {
287 return new npc_glob_of_viscidusAI(creature);
288 }
289};
290
292{
293 new boss_viscidus();
295}
#define M_PI
Definition Common.h:192
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
@ SPELL_SCHOOL_MASK_FROST
@ UNIT_STATE_MELEE_ATTACKING
Definition Unit.h:513
float RoomRadius
void AddSC_boss_viscidus()
@ EMOTE_SLOW
@ EMOTE_CRACK
@ EMOTE_FREEZE
@ EMOTE_FROZEN
@ EMOTE_EXPLODE
@ EMOTE_SHATTER
Position const ViscidusCoord
@ SPELL_POISON_SHOCK
@ SPELL_VISCIDUS_TELEPORT
@ SPELL_VISCIDUS_SLOWED_MORE
@ SPELL_POISONBOLT_VOLLEY
@ SPELL_VISCIDUS_GROWS
@ SPELL_VISCIDUS_SHRINKS
@ SPELL_VISCIDUS_FREEZE
@ SPELL_TOXIN
@ SPELL_VISCIDUS_SUICIDE
@ SPELL_VISCIDUS_WEAKNESS
@ SPELL_VISCIDUS_SLOWED
@ SPELL_MEMBRANE_VISCIDUS
@ SPELL_REJOIN_VISCIDUS
@ SPELL_VISCIDUS_EXPLODE
@ SPELL_SUMMON_GLOBS
@ PHASE_GLOB
@ PHASE_MELEE
@ PHASE_FROST
float const RoomRadius
MovePoints
@ ROOM_CENTER
HitCounter
@ HITCOUNTER_CRACK
@ HITCOUNTER_SLOW
@ HITCOUNTER_EXPLODE
@ HITCOUNTER_SLOW_MORE
@ HITCOUNTER_SHATTER
@ HITCOUNTER_FREEZE
@ EVENT_POISONBOLT_VOLLEY
@ EVENT_POISON_SHOCK
@ EVENT_RESET_PHASE
SummonList summons
EventMap events
BossAI(Creature *creature, uint32 bossId)
void _EnterCombat()
void Talk(uint8 id, WorldObject const *whisperTarget=NULL)
bool UpdateVictim()
virtual void EnterEvadeMode()
CreatureScript(const char *name)
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:28
void DoCast(uint32 spellId)
Definition UnitAI.cpp:110
Definition Unit.h:1367
virtual uint64 GetData64(uint32) const
Definition ZoneScript.h:32
CreatureAI * GetAI(Creature *creature) const OVERRIDE
CreatureAI * GetAI(Creature *creature) const OVERRIDE
Creature * me
ScriptedAI(Creature *creature)
void DamageTaken(Unit *attacker, uint32 &) OVERRIDE
void EnterCombat(Unit *) OVERRIDE
boss_viscidusAI(Creature *creature)
void SpellHit(Unit *, SpellInfo const *spell) OVERRIDE
void UpdateAI(uint32 diff) OVERRIDE
== Triggered Actions Requested ==================
void JustDied(Unit *) OVERRIDE
void MovementInform(uint32, uint32 id) OVERRIDE
@ NPC_GLOB_OF_VISCIDUS
@ DATA_VISCIDUS