|
15 | 15 | * with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | */ |
17 | 17 |
|
18 | | -/* ScriptData |
19 | | -SDName: Boss_Warlord_Kalithres |
20 | | -SD%Complete: 65 |
21 | | -SDComment: Contains workarounds regarding warlord's rage spells not acting as expected. Both scripts here require review and fine tuning. |
22 | | -SDCategory: Coilfang Resevoir, The Steamvault |
23 | | -EndScriptData */ |
| 18 | +/* Timers requires update |
| 19 | + * Distillers should respawn at some point, probably in case of wipe |
| 20 | + * All distillers should cast SPELL_QUIET_SUICIDE when encounter is finished */ |
24 | 21 |
|
25 | 22 | #include "ScriptMgr.h" |
26 | 23 | #include "InstanceScript.h" |
| 24 | +#include "MotionMaster.h" |
| 25 | +#include "ObjectAccessor.h" |
27 | 26 | #include "ScriptedCreature.h" |
28 | | -#include "SpellInfo.h" |
29 | 27 | #include "steam_vault.h" |
30 | 28 |
|
31 | | -enum NagaDistiller |
| 29 | +enum KalithreshTexts |
32 | 30 | { |
33 | | - SAY_INTRO = 0, |
34 | | - SAY_REGEN = 1, |
35 | | - SAY_AGGRO = 2, |
36 | | - SAY_SLAY = 3, |
37 | | - SAY_DEATH = 4, |
38 | | - |
39 | | - SPELL_SPELL_REFLECTION = 31534, |
40 | | - SPELL_IMPALE = 39061, |
41 | | - SPELL_WARLORDS_RAGE = 37081, |
42 | | - SPELL_WARLORDS_RAGE_NAGA = 31543, |
43 | | - |
44 | | - SPELL_WARLORDS_RAGE_PROC = 36453 |
| 31 | + SAY_INTRO = 0, |
| 32 | + SAY_REGEN = 1, |
| 33 | + SAY_AGGRO = 2, |
| 34 | + SAY_SLAY = 3, |
| 35 | + SAY_DEATH = 4, |
| 36 | + EMOTE_CHANNEL = 5 |
45 | 37 | }; |
46 | 38 |
|
47 | | -class npc_naga_distiller : public CreatureScript |
| 39 | +enum KalithreshSpells |
48 | 40 | { |
49 | | -public: |
50 | | - npc_naga_distiller() : CreatureScript("npc_naga_distiller") { } |
| 41 | + SPELL_HEAD_CRACK = 16172, |
| 42 | + SPELL_REFLECTION = 31534, |
| 43 | + SPELL_IMPALE = 39061, |
| 44 | + |
| 45 | + SPELL_WARLORDS_RAGE = 37081, |
| 46 | + SPELL_WARLORDS_RAGE_DISTILLER = 31543, |
| 47 | + |
| 48 | + // A bunch of NYI serverside spells, some may be not even used |
| 49 | + SPELL_SUMMON_DISTILLER_1 = 31544, |
| 50 | + SPELL_SUMMON_DISTILLER_2 = 31545, |
| 51 | + SPELL_SUMMON_DISTILLER_3 = 31546, |
| 52 | + |
| 53 | + SPELL_DISTILLER_DUMMY = 31763, |
| 54 | + SPELL_DISTILLER_DUMMY_DESPAWN = 31767, |
| 55 | + SPELL_DISTILLER_DUMMY_TRIGGER_1 = 33761, |
| 56 | + SPELL_DISTILLER_DUMMY_COMBAT = 33769, |
| 57 | + SPELL_DISTILLER_DUMMY_TRIGGER_2 = 34065, |
| 58 | + // Distiller |
| 59 | + SPELL_STUN_SELF = 25900, |
| 60 | + SPELL_QUIET_SUICIDE = 3617 |
| 61 | +}; |
| 62 | + |
| 63 | +enum KalithreshEvents |
| 64 | +{ |
| 65 | + EVENT_HEAD_CRACK = 1, |
| 66 | + EVENT_REFLECTION, |
| 67 | + EVENT_IMPALE, |
| 68 | + EVENT_RAGE |
| 69 | +}; |
| 70 | + |
| 71 | +enum KalithreshMisc |
| 72 | +{ |
| 73 | + SOUND_ID_SLAY = 10396, |
| 74 | + NPC_NAGA_DISTILLER = 17954, |
| 75 | + POINT_DISTILLER = 1, |
| 76 | + ACTION_DISTILLER_DEAD = 1, |
| 77 | + ACTION_DISTILLER_CHANNEL = 1 |
| 78 | +}; |
| 79 | + |
| 80 | +// 17798 - Warlord Kalithresh |
| 81 | +struct boss_warlord_kalithresh : public BossAI |
| 82 | +{ |
| 83 | + boss_warlord_kalithresh(Creature* creature) : BossAI(creature, DATA_WARLORD_KALITHRESH), _introDone(false) { } |
51 | 84 |
|
52 | | - CreatureAI* GetAI(Creature* creature) const override |
| 85 | + void Reset() override |
53 | 86 | { |
54 | | - return GetSteamVaultAI<npc_naga_distillerAI>(creature); |
| 87 | + _Reset(); |
| 88 | + _distillerGUID.Clear(); |
55 | 89 | } |
56 | 90 |
|
57 | | - struct npc_naga_distillerAI : public ScriptedAI |
| 91 | + void JustEngagedWith(Unit* who) override |
58 | 92 | { |
59 | | - npc_naga_distillerAI(Creature* creature) : ScriptedAI(creature) |
60 | | - { |
61 | | - instance = creature->GetInstanceScript(); |
62 | | - } |
| 93 | + Talk(SAY_AGGRO); |
| 94 | + BossAI::JustEngagedWith(who); |
63 | 95 |
|
64 | | - InstanceScript* instance; |
| 96 | + events.ScheduleEvent(EVENT_HEAD_CRACK, 10s, 15s); |
| 97 | + events.ScheduleEvent(EVENT_REFLECTION, 15s, 25s); |
| 98 | + events.ScheduleEvent(EVENT_IMPALE, 7s, 14s); |
| 99 | + events.ScheduleEvent(EVENT_RAGE, 10s, 20s); |
| 100 | + } |
65 | 101 |
|
66 | | - void Reset() override |
| 102 | + void MoveInLineOfSight(Unit* who) override |
| 103 | + { |
| 104 | + if (!_introDone && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 50.0f)) |
67 | 105 | { |
68 | | - me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); |
69 | | - me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); |
70 | | - |
71 | | - //hack, due to really weird spell behaviour :( |
72 | | - if (instance->GetData(DATA_DISTILLER) == IN_PROGRESS) |
73 | | - { |
74 | | - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); |
75 | | - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); |
76 | | - } |
| 106 | + _introDone = true; |
| 107 | + Talk(SAY_INTRO); |
77 | 108 | } |
78 | 109 |
|
79 | | - void JustEngagedWith(Unit* /*who*/) override { } |
80 | | - |
81 | | - void StartRageGen(Unit* /*caster*/) |
82 | | - { |
83 | | - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); |
84 | | - me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); |
85 | | - |
86 | | - DoCast(me, SPELL_WARLORDS_RAGE_NAGA, true); |
| 110 | + BossAI::MoveInLineOfSight(who); |
| 111 | + } |
87 | 112 |
|
88 | | - instance->SetData(DATA_DISTILLER, IN_PROGRESS); |
89 | | - } |
| 113 | + void MovementInform(uint32 type, uint32 pointId) override |
| 114 | + { |
| 115 | + if (type != POINT_MOTION_TYPE) |
| 116 | + return; |
90 | 117 |
|
91 | | - void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override |
| 118 | + if (pointId == POINT_DISTILLER) |
92 | 119 | { |
93 | | - if (me->GetHealth() <= damage) |
94 | | - instance->SetData(DATA_DISTILLER, DONE); |
95 | | - } |
96 | | - }; |
97 | | - |
98 | | -}; |
| 120 | + Talk(EMOTE_CHANNEL); |
| 121 | + Talk(SAY_REGEN); |
| 122 | + me->SetReactState(REACT_AGGRESSIVE); |
| 123 | + DoCastSelf(SPELL_WARLORDS_RAGE); |
99 | 124 |
|
100 | | -class boss_warlord_kalithresh : public CreatureScript |
101 | | -{ |
102 | | -public: |
103 | | - boss_warlord_kalithresh() : CreatureScript("boss_warlord_kalithresh") { } |
| 125 | + if (Creature* distiller = ObjectAccessor::GetCreature(*me, _distillerGUID)) |
| 126 | + distiller->AI()->DoAction(ACTION_DISTILLER_CHANNEL); |
| 127 | + } |
| 128 | + } |
104 | 129 |
|
105 | | - CreatureAI* GetAI(Creature* creature) const override |
| 130 | + void DoAction(int32 action) override |
106 | 131 | { |
107 | | - return GetSteamVaultAI<boss_warlord_kalithreshAI>(creature); |
| 132 | + if (action == ACTION_DISTILLER_DEAD) |
| 133 | + me->RemoveAurasDueToSpell(SPELL_WARLORDS_RAGE); |
108 | 134 | } |
109 | 135 |
|
110 | | - struct boss_warlord_kalithreshAI : public ScriptedAI |
| 136 | + void KilledUnit(Unit* /*victim*/) override |
111 | 137 | { |
112 | | - boss_warlord_kalithreshAI(Creature* creature) : ScriptedAI(creature) |
113 | | - { |
114 | | - Initialize(); |
115 | | - instance = creature->GetInstanceScript(); |
116 | | - } |
| 138 | + if (roll_chance_i(50)) |
| 139 | + Talk(SAY_SLAY); |
| 140 | + else |
| 141 | + DoPlaySoundToSet(me, SOUND_ID_SLAY); |
| 142 | + } |
117 | 143 |
|
118 | | - void Initialize() |
119 | | - { |
120 | | - Reflection_Timer = 10000; |
121 | | - Impale_Timer = 7000 + rand32() % 7000; |
122 | | - Rage_Timer = 45000; |
123 | | - CanRage = false; |
124 | | - } |
| 144 | + void JustDied(Unit* /*killer*/) override |
| 145 | + { |
| 146 | + Talk(SAY_DEATH); |
| 147 | + _JustDied(); |
| 148 | + } |
125 | 149 |
|
126 | | - InstanceScript* instance; |
| 150 | + void UpdateAI(uint32 diff) override |
| 151 | + { |
| 152 | + if (!UpdateVictim()) |
| 153 | + return; |
127 | 154 |
|
128 | | - uint32 Reflection_Timer; |
129 | | - uint32 Impale_Timer; |
130 | | - uint32 Rage_Timer; |
131 | | - bool CanRage; |
| 155 | + events.Update(diff); |
132 | 156 |
|
133 | | - void Reset() override |
| 157 | + while (uint32 eventId = events.ExecuteEvent()) |
134 | 158 | { |
135 | | - Initialize(); |
136 | | - |
137 | | - instance->SetBossState(DATA_WARLORD_KALITHRESH, NOT_STARTED); |
| 159 | + switch (eventId) |
| 160 | + { |
| 161 | + case EVENT_HEAD_CRACK: |
| 162 | + DoCastVictim(SPELL_HEAD_CRACK); |
| 163 | + events.Repeat(20s, 30s); |
| 164 | + break; |
| 165 | + case EVENT_REFLECTION: |
| 166 | + DoCastSelf(SPELL_REFLECTION); |
| 167 | + events.Repeat(15s, 25s); |
| 168 | + break; |
| 169 | + case EVENT_IMPALE: |
| 170 | + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) |
| 171 | + DoCast(target, SPELL_IMPALE); |
| 172 | + events.Repeat(7s, 12s); |
| 173 | + break; |
| 174 | + case EVENT_RAGE: |
| 175 | + if (Creature* distiller = me->FindNearestCreature(NPC_NAGA_DISTILLER, 150.0f)) |
| 176 | + { |
| 177 | + _distillerGUID = distiller->GetGUID(); |
| 178 | + me->SetReactState(REACT_PASSIVE); |
| 179 | + |
| 180 | + float x, y, z; |
| 181 | + distiller->GetContactPoint(me, x, y, z); |
| 182 | + |
| 183 | + me->GetMotionMaster()->MovePoint(POINT_DISTILLER, x, y, z); |
| 184 | + } |
| 185 | + events.Repeat(50s); |
| 186 | + break; |
| 187 | + default: |
| 188 | + break; |
| 189 | + } |
138 | 190 | } |
139 | 191 |
|
140 | | - void JustEngagedWith(Unit* /*who*/) override |
141 | | - { |
142 | | - Talk(SAY_AGGRO); |
| 192 | + DoMeleeAttackIfReady(); |
| 193 | + } |
143 | 194 |
|
144 | | - instance->SetBossState(DATA_WARLORD_KALITHRESH, IN_PROGRESS); |
145 | | - } |
| 195 | +private: |
| 196 | + bool _introDone; |
| 197 | + ObjectGuid _distillerGUID; |
| 198 | +}; |
146 | 199 |
|
147 | | - void KilledUnit(Unit* /*victim*/) override |
148 | | - { |
149 | | - Talk(SAY_SLAY); |
150 | | - } |
| 200 | +// 17954 - Naga Distiller |
| 201 | +struct npc_naga_distiller : public ScriptedAI |
| 202 | +{ |
| 203 | + npc_naga_distiller(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } |
151 | 204 |
|
152 | | - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override |
153 | | - { |
154 | | - //hack :( |
155 | | - if (spellInfo->Id == SPELL_WARLORDS_RAGE_PROC) |
156 | | - if (instance->GetData(DATA_DISTILLER) == DONE) |
157 | | - me->RemoveAurasDueToSpell(SPELL_WARLORDS_RAGE_PROC); |
158 | | - } |
| 205 | + void Reset() override |
| 206 | + { |
| 207 | + me->SetCorpseDelay(2, true); |
| 208 | + DoCastSelf(SPELL_STUN_SELF); |
| 209 | + me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); |
| 210 | + } |
159 | 211 |
|
160 | | - void JustDied(Unit* /*killer*/) override |
| 212 | + void DoAction(int32 action) override |
| 213 | + { |
| 214 | + if (action == ACTION_DISTILLER_CHANNEL) |
161 | 215 | { |
162 | | - Talk(SAY_DEATH); |
163 | | - |
164 | | - instance->SetBossState(DATA_WARLORD_KALITHRESH, DONE); |
| 216 | + // Creature is stunned, cast as triggered |
| 217 | + DoCastSelf(SPELL_WARLORDS_RAGE_DISTILLER, true); |
| 218 | + me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); |
165 | 219 | } |
| 220 | + } |
166 | 221 |
|
167 | | - void UpdateAI(uint32 diff) override |
168 | | - { |
169 | | - if (!UpdateVictim()) |
170 | | - return; |
171 | | - |
172 | | - if (Rage_Timer <= diff) |
173 | | - { |
174 | | - if (Creature* distiller = me->FindNearestCreature(17954, 100.0f)) |
175 | | - { |
176 | | - Talk(SAY_REGEN); |
177 | | - DoCast(me, SPELL_WARLORDS_RAGE); |
178 | | - ENSURE_AI(npc_naga_distiller::npc_naga_distillerAI, distiller->AI())->StartRageGen(me); |
179 | | - } |
180 | | - Rage_Timer = 3000 + rand32() % 15000; |
181 | | - } else Rage_Timer -= diff; |
182 | | - |
183 | | - //Reflection_Timer |
184 | | - if (Reflection_Timer <= diff) |
185 | | - { |
186 | | - DoCast(me, SPELL_SPELL_REFLECTION); |
187 | | - Reflection_Timer = 15000 + rand32() % 10000; |
188 | | - } else Reflection_Timer -= diff; |
189 | | - |
190 | | - //Impale_Timer |
191 | | - if (Impale_Timer <= diff) |
192 | | - { |
193 | | - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) |
194 | | - DoCast(target, SPELL_IMPALE); |
195 | | - |
196 | | - Impale_Timer = 7500 + rand32() % 5000; |
197 | | - } else Impale_Timer -= diff; |
| 222 | + void JustDied(Unit* /*killer*/) override |
| 223 | + { |
| 224 | + if (Creature* kalithresh = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_WARLORD_KALITHRESH))) |
| 225 | + kalithresh->AI()->DoAction(ACTION_DISTILLER_DEAD); |
| 226 | + } |
198 | 227 |
|
199 | | - DoMeleeAttackIfReady(); |
200 | | - } |
201 | | - }; |
| 228 | +private: |
| 229 | + InstanceScript* _instance; |
202 | 230 | }; |
203 | 231 |
|
204 | 232 | void AddSC_boss_warlord_kalithresh() |
205 | 233 | { |
206 | | - new npc_naga_distiller(); |
207 | | - new boss_warlord_kalithresh(); |
| 234 | + RegisterSteamVaultCreatureAI(boss_warlord_kalithresh); |
| 235 | + RegisterSteamVaultCreatureAI(npc_naga_distiller); |
208 | 236 | } |
0 commit comments