Skip to content

Commit 640ee45

Browse files
authored
Scripts/The Slave Pens: Modernize Kalithresh script (#30957)
1 parent e045dd0 commit 640ee45

File tree

3 files changed

+177
-157
lines changed

3 files changed

+177
-157
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
--
2+
DELETE FROM `creature_text` WHERE `CreatureID` = 17798 AND `GroupID` = 3 AND `ID` = 1;
3+
DELETE FROM `creature_text` WHERE `CreatureID` = 17798 AND `GroupID` = 5;
4+
INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
5+
(17798,5,0,"%s begins to channel from the nearby distiller...",16,0,100,0,0,0,19166,0,"kalithresh EMOTE_CHANNEL");

src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_warlord_kalithresh.cpp

Lines changed: 170 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -15,194 +15,222 @@
1515
* with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

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 */
2421

2522
#include "ScriptMgr.h"
2623
#include "InstanceScript.h"
24+
#include "MotionMaster.h"
25+
#include "ObjectAccessor.h"
2726
#include "ScriptedCreature.h"
28-
#include "SpellInfo.h"
2927
#include "steam_vault.h"
3028

31-
enum NagaDistiller
29+
enum KalithreshTexts
3230
{
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
4537
};
4638

47-
class npc_naga_distiller : public CreatureScript
39+
enum KalithreshSpells
4840
{
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) { }
5184

52-
CreatureAI* GetAI(Creature* creature) const override
85+
void Reset() override
5386
{
54-
return GetSteamVaultAI<npc_naga_distillerAI>(creature);
87+
_Reset();
88+
_distillerGUID.Clear();
5589
}
5690

57-
struct npc_naga_distillerAI : public ScriptedAI
91+
void JustEngagedWith(Unit* who) override
5892
{
59-
npc_naga_distillerAI(Creature* creature) : ScriptedAI(creature)
60-
{
61-
instance = creature->GetInstanceScript();
62-
}
93+
Talk(SAY_AGGRO);
94+
BossAI::JustEngagedWith(who);
6395

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+
}
65101

66-
void Reset() override
102+
void MoveInLineOfSight(Unit* who) override
103+
{
104+
if (!_introDone && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 50.0f))
67105
{
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);
77108
}
78109

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+
}
87112

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;
90117

91-
void DamageTaken(Unit* /*done_by*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
118+
if (pointId == POINT_DISTILLER)
92119
{
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);
99124

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+
}
104129

105-
CreatureAI* GetAI(Creature* creature) const override
130+
void DoAction(int32 action) override
106131
{
107-
return GetSteamVaultAI<boss_warlord_kalithreshAI>(creature);
132+
if (action == ACTION_DISTILLER_DEAD)
133+
me->RemoveAurasDueToSpell(SPELL_WARLORDS_RAGE);
108134
}
109135

110-
struct boss_warlord_kalithreshAI : public ScriptedAI
136+
void KilledUnit(Unit* /*victim*/) override
111137
{
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+
}
117143

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+
}
125149

126-
InstanceScript* instance;
150+
void UpdateAI(uint32 diff) override
151+
{
152+
if (!UpdateVictim())
153+
return;
127154

128-
uint32 Reflection_Timer;
129-
uint32 Impale_Timer;
130-
uint32 Rage_Timer;
131-
bool CanRage;
155+
events.Update(diff);
132156

133-
void Reset() override
157+
while (uint32 eventId = events.ExecuteEvent())
134158
{
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+
}
138190
}
139191

140-
void JustEngagedWith(Unit* /*who*/) override
141-
{
142-
Talk(SAY_AGGRO);
192+
DoMeleeAttackIfReady();
193+
}
143194

144-
instance->SetBossState(DATA_WARLORD_KALITHRESH, IN_PROGRESS);
145-
}
195+
private:
196+
bool _introDone;
197+
ObjectGuid _distillerGUID;
198+
};
146199

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()) { }
151204

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+
}
159211

160-
void JustDied(Unit* /*killer*/) override
212+
void DoAction(int32 action) override
213+
{
214+
if (action == ACTION_DISTILLER_CHANNEL)
161215
{
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);
165219
}
220+
}
166221

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+
}
198227

199-
DoMeleeAttackIfReady();
200-
}
201-
};
228+
private:
229+
InstanceScript* _instance;
202230
};
203231

204232
void AddSC_boss_warlord_kalithresh()
205233
{
206-
new npc_naga_distiller();
207-
new boss_warlord_kalithresh();
234+
RegisterSteamVaultCreatureAI(boss_warlord_kalithresh);
235+
RegisterSteamVaultCreatureAI(npc_naga_distiller);
208236
}

0 commit comments

Comments
 (0)