Skip to content

Commit 126fa17

Browse files
authored
Scripts/AQ20: Refactor Kurinnaxx and implement Sand Trap (#31203)
1 parent 7de212a commit 126fa17

File tree

3 files changed

+163
-99
lines changed

3 files changed

+163
-99
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--
2+
DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_kurinnaxx_sand_trap';
3+
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
4+
(26524, 'spell_kurinnaxx_sand_trap');
5+
6+
-- Should be disturbed instead (activate object action)
7+
UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = 180647;
8+
DELETE FROM `smart_scripts` WHERE `entryorguid` = 180647 AND `source_type` = 1;
9+
INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_param4`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
10+
(180647,1,0,0,60,0,100,1,4500,4500,0,0,0,11,25656,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Sand Trap - On Update - Cast 'Sand Trap' (No Repeat)"),
11+
(180647,1,1,0,60,0,100,1,4500,4500,0,0,0,41,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Sand Trap - On Update - Despawn (No Repeat)");
12+
13+
DELETE FROM `creature_text` WHERE `CreatureID` = 15348;
14+
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
15+
(15348,0,0,"%s goes into a frenzy!",16,0,100,0,0,0,2384,0,"Kurinnaxx EMOTE_FRENZY");
16+
17+
UPDATE `creature_text` SET `TextRange` = 3 WHERE `CreatureID` = 15339 AND `GroupID` = 5;

src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_kurinnaxx.cpp

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

18+
/*
19+
* Timers requires to be revisited
20+
*/
21+
1822
#include "ScriptMgr.h"
19-
#include "CreatureTextMgr.h"
23+
#include "Containers.h"
2024
#include "InstanceScript.h"
2125
#include "ObjectAccessor.h"
2226
#include "ruins_of_ahnqiraj.h"
2327
#include "ScriptedCreature.h"
28+
#include "SpellInfo.h"
29+
#include "SpellScript.h"
2430

25-
enum Spells
31+
enum KurinnaxxTexts
2632
{
27-
SPELL_MORTALWOUND = 25646,
28-
SPELL_SANDTRAP = 25648,
29-
SPELL_ENRAGE = 26527,
30-
SPELL_SUMMON_PLAYER = 26446,
31-
SPELL_TRASH = 3391, // Should perhaps be triggered by an aura? Couldn't find any though
32-
SPELL_WIDE_SLASH = 25814
33+
SAY_KURINAXX_DEATH = 5,
34+
EMOTE_FRENZY = 0
3335
};
3436

35-
enum Events
37+
enum KurinnaxxSpells
3638
{
37-
EVENT_MORTAL_WOUND = 1,
38-
EVENT_SANDTRAP = 2,
39-
EVENT_TRASH = 3,
40-
EVENT_WIDE_SLASH = 4
39+
SPELL_MORTAL_WOUND = 25646,
40+
SPELL_SAND_TRAP_TRIGGER = 26524,
41+
SPELL_THRASH = 3391,
42+
SPELL_WIDE_SLASH = 25814,
43+
SPELL_FRENZY = 26527,
44+
SPELL_SUMMON_PLAYER = 26446,
45+
46+
SPELL_SAND_TRAP_EFFECT = 25648
4147
};
4248

43-
enum Texts
49+
enum KurinnaxxEvents
4450
{
45-
SAY_KURINAXX_DEATH = 5, // Yelled by Ossirian the Unscarred
51+
EVENT_MORTAL_WOUND = 1,
52+
EVENT_SAND_TRAP,
53+
EVENT_THRASH,
54+
EVENT_WIDE_SLASH,
55+
EVENT_FRENZY,
56+
EVENT_SUMMON_PLAYER
4657
};
4758

48-
class boss_kurinnaxx : public CreatureScript
59+
// 15348 - Kurinnaxx
60+
struct boss_kurinnaxx : public BossAI
4961
{
50-
public:
51-
boss_kurinnaxx() : CreatureScript("boss_kurinnaxx") { }
52-
53-
struct boss_kurinnaxxAI : public BossAI
62+
boss_kurinnaxx(Creature* creature) : BossAI(creature, DATA_KURINNAXX), _frenzied(false) { }
63+
64+
void Reset() override
65+
{
66+
_Reset();
67+
_frenzied = false;
68+
}
69+
70+
void JustEngagedWith(Unit* who) override
71+
{
72+
BossAI::JustEngagedWith(who);
73+
74+
events.ScheduleEvent(EVENT_MORTAL_WOUND, 2s, 8s);
75+
events.ScheduleEvent(EVENT_SAND_TRAP, 5s, 10s);
76+
events.ScheduleEvent(EVENT_THRASH, 0s, 15s);
77+
events.ScheduleEvent(EVENT_WIDE_SLASH, 10s, 15s);
78+
events.ScheduleEvent(EVENT_SUMMON_PLAYER, 5s);
79+
}
80+
81+
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
82+
{
83+
if (!_frenzied && me->HealthBelowPctDamaged(30, damage))
5484
{
55-
boss_kurinnaxxAI(Creature* creature) : BossAI(creature, DATA_KURINNAXX)
56-
{
57-
Initialize();
58-
}
85+
_frenzied = true;
86+
events.ScheduleEvent(EVENT_FRENZY, 0s);
87+
}
88+
}
5989

60-
void Initialize()
61-
{
62-
_enraged = false;
63-
}
90+
void OnSpellCast(SpellInfo const* spell) override
91+
{
92+
if (spell->Id == SPELL_FRENZY)
93+
Talk(EMOTE_FRENZY);
94+
}
6495

65-
void Reset() override
66-
{
67-
_Reset();
68-
Initialize();
69-
events.ScheduleEvent(EVENT_MORTAL_WOUND, 8s);
70-
events.ScheduleEvent(EVENT_SANDTRAP, 5s, 15s);
71-
events.ScheduleEvent(EVENT_TRASH, 1s);
72-
events.ScheduleEvent(EVENT_WIDE_SLASH, 11s);
73-
}
96+
void JustDied(Unit* /*killer*/) override
97+
{
98+
_JustDied();
99+
if (Creature* ossirian = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_OSSIRIAN)))
100+
ossirian->AI()->Talk(SAY_KURINAXX_DEATH);
101+
}
74102

75-
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
76-
{
77-
if (!_enraged && HealthBelowPct(30))
78-
{
79-
DoCast(me, SPELL_ENRAGE);
80-
_enraged = true;
81-
}
82-
}
103+
void UpdateAI(uint32 diff) override
104+
{
105+
if (!UpdateVictim())
106+
return;
83107

84-
void JustDied(Unit* /*killer*/) override
85-
{
86-
_JustDied();
87-
if (Creature* Ossirian = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_OSSIRIAN)))
88-
sCreatureTextMgr->SendChat(Ossirian, SAY_KURINAXX_DEATH, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE);
89-
}
108+
events.Update(diff);
90109

91-
void UpdateAI(uint32 diff) override
110+
if (me->HasUnitState(UNIT_STATE_CASTING))
111+
return;
112+
113+
while (uint32 eventId = events.ExecuteEvent())
114+
{
115+
switch (eventId)
92116
{
93-
if (!UpdateVictim())
94-
return;
95-
96-
events.Update(diff);
97-
98-
if (me->HasUnitState(UNIT_STATE_CASTING))
99-
return;
100-
101-
while (uint32 eventId = events.ExecuteEvent())
102-
{
103-
switch (eventId)
104-
{
105-
case EVENT_MORTAL_WOUND:
106-
DoCastVictim(SPELL_MORTALWOUND);
107-
events.ScheduleEvent(EVENT_MORTAL_WOUND, 8s);
108-
break;
109-
case EVENT_SANDTRAP:
110-
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
111-
target->CastSpell(target, SPELL_SANDTRAP, true);
112-
else if (Unit* victim = me->GetVictim())
113-
victim->CastSpell(victim, SPELL_SANDTRAP, true);
114-
events.ScheduleEvent(EVENT_SANDTRAP, 5s, 15s);
115-
break;
116-
case EVENT_WIDE_SLASH:
117-
DoCast(me, SPELL_WIDE_SLASH);
118-
events.ScheduleEvent(EVENT_WIDE_SLASH, 11s);
119-
break;
120-
case EVENT_TRASH:
121-
DoCast(me, SPELL_TRASH);
122-
events.ScheduleEvent(EVENT_WIDE_SLASH, 15s);
123-
break;
124-
default:
125-
break;
126-
}
127-
128-
if (me->HasUnitState(UNIT_STATE_CASTING))
129-
return;
130-
}
131-
132-
DoMeleeAttackIfReady();
117+
case EVENT_MORTAL_WOUND:
118+
DoCastVictim(SPELL_MORTAL_WOUND);
119+
events.Repeat(4s, 12s);
120+
break;
121+
case EVENT_SAND_TRAP:
122+
DoCastSelf(SPELL_SAND_TRAP_TRIGGER);
123+
events.Repeat(5s, 15s);
124+
break;
125+
case EVENT_THRASH:
126+
DoCastSelf(SPELL_THRASH);
127+
events.Repeat(10s, 20s);
128+
break;
129+
case EVENT_WIDE_SLASH:
130+
DoCastSelf(SPELL_WIDE_SLASH);
131+
events.Repeat(10s, 15s);
132+
break;
133+
case EVENT_FRENZY:
134+
DoCastSelf(SPELL_FRENZY);
135+
break;
136+
case EVENT_SUMMON_PLAYER:
137+
if (me->GetDistance(me->GetVictim()) > 10.0f)
138+
DoCastVictim(SPELL_SUMMON_PLAYER);
139+
events.Repeat(5s);
140+
break;
141+
default:
142+
break;
133143
}
134-
private:
135-
bool _enraged;
136-
};
137144

138-
CreatureAI* GetAI(Creature* creature) const override
139-
{
140-
return GetAQ20AI<boss_kurinnaxxAI>(creature);
145+
if (me->HasUnitState(UNIT_STATE_CASTING))
146+
return;
141147
}
148+
149+
DoMeleeAttackIfReady();
150+
}
151+
152+
private:
153+
bool _frenzied;
154+
};
155+
156+
// 26524 - Sand Trap
157+
class spell_kurinnaxx_sand_trap : public SpellScript
158+
{
159+
PrepareSpellScript(spell_kurinnaxx_sand_trap);
160+
161+
bool Validate(SpellInfo const* /*spellInfo*/) override
162+
{
163+
return ValidateSpellInfo({ SPELL_SAND_TRAP_EFFECT });
164+
}
165+
166+
void FilterTargets(std::list<WorldObject*>& targets)
167+
{
168+
if (targets.empty())
169+
return;
170+
171+
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
172+
targets.clear();
173+
targets.push_back(target);
174+
}
175+
176+
void HandleScript(SpellEffIndex /*effIndex*/)
177+
{
178+
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SAND_TRAP_EFFECT, true);
179+
}
180+
181+
void Register() override
182+
{
183+
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kurinnaxx_sand_trap::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
184+
OnEffectHitTarget += SpellEffectFn(spell_kurinnaxx_sand_trap::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
185+
}
142186
};
143187

144188
void AddSC_boss_kurinnaxx()
145189
{
146-
new boss_kurinnaxx();
190+
RegisterAQ20CreatureAI(boss_kurinnaxx);
191+
RegisterSpellScript(spell_kurinnaxx_sand_trap);
147192
}

src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@ inline AI* GetAQ20AI(T* obj)
6666
return GetInstanceAI<AI>(obj, AQ20ScriptName);
6767
}
6868

69+
#define RegisterAQ20CreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAQ20AI)
70+
6971
#endif

0 commit comments

Comments
 (0)