TrinityCore
boss_heigan.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#include "ScriptMgr.h"
19#include "GameObject.h"
20#include "InstanceScript.h"
21#include "Map.h"
22#include "naxxramas.h"
23#include "ObjectAccessor.h"
24#include "ScriptedCreature.h"
25#include "SpellScript.h"
26
28{
29 SPELL_DECREPIT_FEVER = 29998, // 25-man: 55011
33};
34
36{
41
44};
45
47{
53};
54
56{
59};
60
61enum Misc
62{
63 DATA_SAFETY_DANCE = 19962139
64};
65
66static const uint32 firstEruptionDBGUID = 84980;
67static const uint8 numSections = 4;
68static const uint8 numEruptions[numSections] = { // count of sequential GO DBGUIDs in the respective section of the room
69 15,
70 25,
71 23,
72 13
73};
74
75struct boss_heigan : public BossAI
76{
77 boss_heigan(Creature* creature) : BossAI(creature, BOSS_HEIGAN), _safeSection(0), _danceDirection(false), _safetyDance(false) { }
78
79 void Reset() override
80 {
82 _Reset();
83 }
84
85 void KilledUnit(Unit* who) override
86 {
87 if (who->GetTypeId() == TYPEID_PLAYER)
88 {
90 _safetyDance = false;
91 }
92 }
93
94 uint32 GetData(uint32 type) const override
95 {
96 return (type == DATA_SAFETY_DANCE && _safetyDance) ? 1u : 0u;
97 }
98
99 void JustDied(Unit* /*killer*/) override
100 {
101 _JustDied();
103 }
104
105 void JustEngagedWith(Unit* who) override
106 {
109
110 _safeSection = 0;
115
116 _safetyDance = true;
117
118 // figure out the current GUIDs of our eruption tiles and which segment they belong in
119 std::unordered_multimap<ObjectGuid::LowType, GameObject*> const& mapGOs = me->GetMap()->GetGameObjectBySpawnIdStore();
120 uint32 spawnId = firstEruptionDBGUID;
121 for (uint8 section = 0; section < numSections; ++section)
122 {
123 _eruptTiles[section].clear();
124 for (uint8 i = 0; i < numEruptions[section]; ++i)
125 {
126 auto tileIt = mapGOs.equal_range(spawnId++);
127 for (auto it = tileIt.first; it != tileIt.second; ++it)
128 _eruptTiles[section].push_back(it->second->GetGUID());
129 }
130 }
131 }
132
133 void UpdateAI(uint32 diff) override
134 {
135 if (!UpdateVictim())
136 return;
137
138 events.Update(diff);
139
140 while (uint32 eventId = events.ExecuteEvent())
141 {
142 switch (eventId)
143 {
144 case EVENT_DISRUPT:
146 events.Repeat(Seconds(11));
147 break;
148 case EVENT_FEVER:
151 break;
152 case EVENT_DANCE:
156 _safeSection = 0;
158 me->AttackStop();
159 me->StopMoving();
164 break;
165 case EVENT_DANCE_END:
168 _safeSection = 0;
173 me->CastStop();
176 break;
177 case EVENT_ERUPT:
179 for (uint8 section = 0; section < numSections; ++section)
180 if (section != _safeSection)
181 for (ObjectGuid tileGUID : _eruptTiles[section])
182 if (GameObject* tile = ObjectAccessor::GetGameObject(*me, tileGUID))
183 {
184 tile->SendCustomAnim(0);
186 args.OriginalCaster = me->GetGUID();
187 tile->CastSpell(tile, tile->GetGOInfo()->trap.spell, args);
188 }
189
190 if (_safeSection == 0)
191 _danceDirection = true;
192 else if (_safeSection == numSections-1)
193 _danceDirection = false;
194
196
198 break;
199 }
200 }
201 }
202
203 private:
204 std::vector<ObjectGuid> _eruptTiles[numSections]; // populated on encounter start
205
206 uint32 _safeSection; // 0 is next to the entrance
207 bool _danceDirection; // true is counter-clockwise, false is clock-wise
208 bool _safetyDance; // is achievement still possible? (= no player deaths yet)
209};
210
211// 29371 - Eruption
213{
215 {
216 Unit* caster = GetCaster();
217 if (!caster || !GetHitUnit())
218 return;
219
220 if (GetHitDamage() >= int32(GetHitUnit()->GetHealth()))
221 if (InstanceScript* instance = caster->GetInstanceScript())
222 if (Creature* Heigan = ObjectAccessor::GetCreature(*caster, instance->GetGuidData(DATA_HEIGAN)))
223 Heigan->AI()->KilledUnit(GetHitUnit());
224 }
225
226 void Register() override
227 {
229 }
230};
231
233{
234 public:
235 achievement_safety_dance() : AchievementCriteriaScript("achievement_safety_dance") { }
236
237 bool OnCheck(Player* /*player*/, Unit* target) override
238 {
239 if (!target)
240 return false;
241
242 if (Creature* Heigan = target->ToCreature())
243 if (Heigan->AI()->GetData(DATA_SAFETY_DANCE))
244 return true;
245
246 return false;
247 }
248};
249
251{
255}
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition: Duration.h:35
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
Spells
Definition: PlayerAI.cpp:32
Milliseconds randtime(Milliseconds min, Milliseconds max)
Definition: Random.cpp:62
#define RegisterSpellScript(spell_script)
Definition: ScriptMgr.h:1369
SpellEffIndex
Definition: SharedDefines.h:29
@ EFFECT_0
Definition: SharedDefines.h:30
@ SPELL_EFFECT_SCHOOL_DAMAGE
#define SpellEffectFn(F, I, N)
Definition: SpellScript.h:842
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
@ DATA_SAFETY_DANCE
Definition: boss_heigan.cpp:63
@ SAY_DEATH
Definition: boss_heigan.cpp:40
@ EMOTE_DANCE
Definition: boss_heigan.cpp:42
@ SAY_AGGRO
Definition: boss_heigan.cpp:37
@ EMOTE_DANCE_END
Definition: boss_heigan.cpp:43
@ SAY_SLAY
Definition: boss_heigan.cpp:38
@ SAY_TAUNT
Definition: boss_heigan.cpp:39
static const uint8 numEruptions[numSections]
Definition: boss_heigan.cpp:68
void AddSC_boss_heigan()
@ SPELL_SPELL_DISRUPTION
Definition: boss_heigan.cpp:30
@ SPELL_TELEPORT_SELF
Definition: boss_heigan.cpp:32
@ SPELL_PLAGUE_CLOUD
Definition: boss_heigan.cpp:31
@ SPELL_DECREPIT_FEVER
Definition: boss_heigan.cpp:29
@ PHASE_FIGHT
Definition: boss_heigan.cpp:57
@ PHASE_DANCE
Definition: boss_heigan.cpp:58
static const uint32 firstEruptionDBGUID
Definition: boss_heigan.cpp:66
static const uint8 numSections
Definition: boss_heigan.cpp:67
@ EVENT_DANCE_END
Definition: boss_heigan.cpp:52
@ EVENT_ERUPT
Definition: boss_heigan.cpp:50
@ EVENT_FEVER
Definition: boss_heigan.cpp:49
@ EVENT_DISRUPT
Definition: boss_heigan.cpp:48
@ EVENT_DANCE
Definition: boss_heigan.cpp:51
Yells
void JustEngagedWith(Unit *who) override
void TeleportCheaters()
EventMap events
void _JustDied()
void DoZoneInCombat()
Definition: CreatureAI.h:161
void Talk(uint8 id, WorldObject const *whisperTarget=nullptr)
Definition: CreatureAI.cpp:56
bool UpdateVictim()
Definition: CreatureAI.cpp:245
Creature *const me
Definition: CreatureAI.h:61
void SetReactState(ReactStates st)
Definition: Creature.h:160
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Repeat(Milliseconds time)
Definition: EventMap.cpp:63
void ScheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:36
bool IsInPhase(uint8 phase) const
Definition: EventMap.h:217
void SetPhase(uint8 phase)
Definition: EventMap.cpp:28
void RescheduleEvent(uint32 eventId, Milliseconds time, uint32 group=0, uint8 phase=0)
Definition: EventMap.cpp:52
GameObjectBySpawnIdContainer & GetGameObjectBySpawnIdStore()
Definition: Map.h:429
static Creature * ToCreature(Object *o)
Definition: Object.h:219
TypeID GetTypeId() const
Definition: Object.h:173
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
int32 GetHitDamage() const
Unit * GetCaster() const
Unit * GetHitUnit() const
HookList< EffectHandler > OnEffectHitTarget
Definition: SpellScript.h:840
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:89
Definition: Unit.h:627
void CastStop(uint32 except_spellid=0)
Definition: Unit.cpp:1135
void StopMoving()
Definition: Unit.cpp:10049
bool AttackStop()
Definition: Unit.cpp:5781
Map * GetMap() const
Definition: Object.h:624
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1042
bool OnCheck(Player *, Unit *target) override
void HandleScript(SpellEffIndex)
void Register() override
TC_GAME_API GameObject * GetGameObject(WorldObject const &u, ObjectGuid const &guid)
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
@ BOSS_HEIGAN
Definition: naxxramas.h:34
@ DATA_HEIGAN
Definition: naxxramas.h:73
#define RegisterNaxxramasCreatureAI(ai_name)
Definition: naxxramas.h:221
ObjectGuid OriginalCaster
Definition: SpellDefines.h:482
void Reset() override
Definition: boss_heigan.cpp:79
void UpdateAI(uint32 diff) override
boss_heigan(Creature *creature)
Definition: boss_heigan.cpp:77
void KilledUnit(Unit *who) override
Definition: boss_heigan.cpp:85
void JustEngagedWith(Unit *who) override
uint32 GetData(uint32 type) const override
Definition: boss_heigan.cpp:94
uint32 _safeSection
std::vector< ObjectGuid > _eruptTiles[numSections]
bool _danceDirection
void JustDied(Unit *) override
Definition: boss_heigan.cpp:99