Skip to content

Commit 60c8dc1

Browse files
authored
Scripts/AQ40: Rewrite Fankriss (#31200)
1 parent 126fa17 commit 60c8dc1

File tree

3 files changed

+170
-163
lines changed

3 files changed

+170
-163
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--
2+
DELETE FROM `spell_target_position` WHERE `ID` IN (518,25831,25832,26630,26631,26632,720,731,1121);
3+
INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `VerifiedBuild`) VALUES
4+
(518,0,531,-8028.5,1050.9,-54,0,0),
5+
(25831,0,531,-8158.03,1139.3,-83.95,0,0),
6+
(25832,0,531,-8029.25,1237.78,-85.2285,0,0),
7+
(720,0,531,-8043.6,1254.1,-84.3,0,0),
8+
(731,0,531,-8003,1222.9,-82.1,0,0),
9+
(1121,0,531,-8022.3,1149,-89.1,0,0),
10+
(26630,0,531,-8043.6,1254.1,-84.2167,0,0),
11+
(26631,0,531,-8003,1222.9,-82.0167,0,0),
12+
(26632,0,531,-8022.3,1149,-89.0167,0,0);
13+
14+
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 15962;
15+
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (15630,15962) AND `source_type` = 0;
16+
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
17+
(15630,0,0,0,37,0,100,0,0,0,0,0,0,116,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Spawn of Fankriss - On AI Initialize - Set Corpse Delay"),
18+
(15630,0,1,0,11,0,100,0,0,0,0,0,0,38,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Spawn of Fankriss - On Spawn - Set In Combat With Zone"),
19+
(15630,0,2,0,60,0,100,1,20000,20000,0,0,0,11,26662,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Spawn of Fankriss - On Update - Cast 'Berserk'"),
20+
21+
(15962,0,0,0,37,0,100,0,0,0,0,0,0,116,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Vekniss Hatchling - On AI Initialize - Set Corpse Delay"),
22+
(15962,0,1,0,11,0,100,0,0,0,0,0,0,38,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,"Vekniss Hatchling - On Spawn - Set In Combat With Zone");
23+
24+
DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_fankriss_entangle';
25+
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
26+
(720, 'spell_fankriss_entangle'),
27+
(731, 'spell_fankriss_entangle'),
28+
(1121, 'spell_fankriss_entangle');
29+
30+
UPDATE `creature_template` SET `speed_run` = 2.14285714286 WHERE `entry` = 15510;
31+
UPDATE `creature_template` SET `speed_run` = 1.71428571429 WHERE `entry` = 15630;
32+
UPDATE `creature_template` SET `speed_run` = 1.42857142857 WHERE `entry` = 15962;

src/server/game/Spells/SpellMgr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3173,7 +3173,9 @@ void SpellMgr::LoadSpellInfoCorrections()
31733173
ApplySpellFix({
31743174
42818, // Headless Horseman - Wisp Flight Port
31753175
42821, // Headless Horseman - Wisp Flight Missile
3176-
17678 // Despawn Spectral Combatants
3176+
17678, // Despawn Spectral Combatants
3177+
720, // Entangle
3178+
731 // Entangle
31773179
}, [](SpellInfo* spellInfo)
31783180
{
31793181
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards

src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_fankriss.cpp

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

18-
/* ScriptData
19-
SDName: Boss_Fankriss
20-
SD%Complete: 100
21-
SDComment: sound not implemented
22-
SDCategory: Temple of Ahn'Qiraj
23-
EndScriptData */
18+
/*
19+
* Timers requires to be revisited
20+
*/
2421

2522
#include "ScriptMgr.h"
23+
#include "Containers.h"
2624
#include "ScriptedCreature.h"
25+
#include "SpellInfo.h"
26+
#include "SpellScript.h"
2727
#include "temple_of_ahnqiraj.h"
28-
#include "TemporarySummon.h"
2928

30-
#define SOUND_SENTENCE_YOU 8588
31-
#define SOUND_SERVE_TO 8589
32-
#define SOUND_LAWS 8590
33-
#define SOUND_TRESPASS 8591
34-
#define SOUND_WILL_BE 8592
35-
36-
enum Spells
29+
enum FankrissSpells
3730
{
38-
SPELL_MORTAL_WOUND = 28467,
39-
SPELL_ROOT = 28858,
31+
SPELL_MORTAL_WOUND = 25646,
32+
33+
SPELL_SUMMON_WORM_1 = 518,
34+
SPELL_SUMMON_WORM_2 = 25831,
35+
SPELL_SUMMON_WORM_3 = 25832,
4036

41-
// Enrage for his spawns
42-
SPELL_ENRAGE = 28798
37+
SPELL_ENTANGLE_1 = 720,
38+
SPELL_ENTANGLE_2 = 731,
39+
SPELL_ENTANGLE_3 = 1121,
40+
41+
SPELL_SPAWN_HATCHLING_1 = 26630,
42+
SPELL_SPAWN_HATCHLING_2 = 26631,
43+
SPELL_SPAWN_HATCHLING_3 = 26632
44+
};
45+
46+
enum FankrissEvents
47+
{
48+
EVENT_MORTAL_WOUND = 1,
49+
EVENT_SUMMON_WORM,
50+
EVENT_ENTANGLE
4351
};
4452

45-
class boss_fankriss : public CreatureScript
53+
// 15510 - Fankriss the Unyielding
54+
struct boss_fankriss : public BossAI
4655
{
47-
public:
48-
boss_fankriss() : CreatureScript("boss_fankriss") { }
56+
boss_fankriss(Creature* creature) : BossAI(creature, DATA_FRANKRIS), _wormsSpawnPerWave(0), _entanglePerWave(0) { }
4957

50-
CreatureAI* GetAI(Creature* creature) const override
58+
std::vector<uint32> SummonWormSpells = { SPELL_SUMMON_WORM_1, SPELL_SUMMON_WORM_2, SPELL_SUMMON_WORM_3 };
59+
std::vector<uint32> EntangleSpells = { SPELL_ENTANGLE_1, SPELL_ENTANGLE_2, SPELL_ENTANGLE_3 };
60+
61+
void Reset() override
5162
{
52-
return GetAQ40AI<boss_fankrissAI>(creature);
63+
_Reset();
64+
_wormsSpawnPerWave = urand(1, 3);
65+
Trinity::Containers::RandomShuffle(SummonWormSpells);
66+
_entanglePerWave = urand(1, 3);
67+
Trinity::Containers::RandomShuffle(EntangleSpells);
5368
}
5469

55-
struct boss_fankrissAI : public BossAI
70+
void JustEngagedWith(Unit* who) override
5671
{
57-
boss_fankrissAI(Creature* creature) : BossAI(creature, DATA_FRANKRIS)
58-
{
59-
Initialize();
60-
}
72+
BossAI::JustEngagedWith(who);
6173

62-
void Initialize()
63-
{
64-
MortalWound_Timer = urand(10000, 15000);
65-
SpawnHatchlings_Timer = urand(6000, 12000);
66-
SpawnSpawns_Timer = urand(15000, 45000);
67-
}
68-
69-
uint32 MortalWound_Timer;
70-
uint32 SpawnHatchlings_Timer;
71-
uint32 SpawnSpawns_Timer;
74+
events.ScheduleEvent(EVENT_MORTAL_WOUND, 2s, 6s);
75+
events.ScheduleEvent(EVENT_SUMMON_WORM, 30s, 50s);
76+
events.ScheduleEvent(EVENT_ENTANGLE, 15s, 20s);
77+
}
7278

73-
void Reset() override
74-
{
75-
Initialize();
76-
_Reset();
77-
}
79+
void UpdateAI(uint32 diff) override
80+
{
81+
if (!UpdateVictim())
82+
return;
7883

79-
void SummonSpawn(Unit* victim)
80-
{
81-
if (!victim)
82-
return;
84+
events.Update(diff);
8385

84-
int Rand = 10 + (rand32() % 10);
85-
float RandX = 0.f;
86-
float RandY = 0.f;
86+
if (me->HasUnitState(UNIT_STATE_CASTING))
87+
return;
8788

88-
switch (rand32() % 2)
89+
while (uint32 eventId = events.ExecuteEvent())
90+
{
91+
switch (eventId)
8992
{
90-
case 0: RandX = 0.0f - Rand; break;
91-
case 1: RandX = 0.0f + Rand; break;
92-
}
93+
case EVENT_MORTAL_WOUND:
94+
DoCastVictim(SPELL_MORTAL_WOUND);
95+
events.Repeat(4s, 12s);
96+
break;
97+
case EVENT_SUMMON_WORM:
98+
{
99+
DoCastSelf(SummonWormSpells[_wormsSpawnPerWave - 1]);
93100

94-
Rand = 10 + (rand32() % 10);
95-
switch (rand32() % 2)
96-
{
97-
case 0: RandY = 0.0f - Rand; break;
98-
case 1: RandY = 0.0f + Rand; break;
99-
}
100-
Rand = 0;
101-
Creature* Spawn = DoSpawnCreature(15630, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s);
102-
if (Spawn)
103-
Spawn->AI()->AttackStart(victim);
104-
}
101+
--_wormsSpawnPerWave;
105102

106-
void UpdateAI(uint32 diff) override
107-
{
108-
//Return since we have no target
109-
if (!UpdateVictim())
110-
return;
103+
if (!_wormsSpawnPerWave)
104+
{
105+
_wormsSpawnPerWave = urand(1, 3);
106+
Trinity::Containers::RandomShuffle(SummonWormSpells);
107+
events.Repeat(20s, 70s);
108+
}
109+
else
110+
events.Repeat(5s, 20s);
111+
break;
112+
}
113+
case EVENT_ENTANGLE:
114+
{
115+
Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true);
111116

112-
//MortalWound_Timer
113-
if (MortalWound_Timer <= diff)
114-
{
115-
DoCastVictim(SPELL_MORTAL_WOUND);
116-
MortalWound_Timer = urand(10000, 20000);
117-
} else MortalWound_Timer -= diff;
117+
if (!target)
118+
target = me->GetVictim();
118119

119-
//Summon 1-3 Spawns of Fankriss at random time.
120-
if (SpawnSpawns_Timer <= diff)
121-
{
122-
switch (urand(0, 2))
123-
{
124-
case 0:
125-
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
126-
break;
127-
case 1:
128-
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
129-
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
130-
break;
131-
case 2:
132-
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
133-
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
134-
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
135-
break;
136-
}
137-
SpawnSpawns_Timer = urand(30000, 60000);
138-
} else SpawnSpawns_Timer -= diff;
120+
if (target)
121+
DoCast(target, EntangleSpells[_entanglePerWave - 1]);
139122

140-
// Teleporting Random Target to one of the three tunnels and spawn 4 hatchlings near the gamer.
141-
//We will only telport if fankriss has more than 3% of hp so teleported gamers can always loot.
142-
if (HealthAbovePct(3))
143-
{
144-
if (SpawnHatchlings_Timer <= diff)
145-
{
146-
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
123+
--_entanglePerWave;
124+
125+
if (!_entanglePerWave)
147126
{
148-
DoCast(target, SPELL_ROOT);
149-
150-
if (GetThreat(target))
151-
ModifyThreatByPercent(target, -100);
152-
153-
Creature* Hatchling = nullptr;
154-
switch (urand(0, 2))
155-
{
156-
case 0:
157-
DoTeleportPlayer(target, -8106.0142f, 1289.2900f, -74.419533f, 5.112f);
158-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
159-
if (Hatchling)
160-
Hatchling->AI()->AttackStart(target);
161-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
162-
if (Hatchling)
163-
Hatchling->AI()->AttackStart(target);
164-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
165-
if (Hatchling)
166-
Hatchling->AI()->AttackStart(target);
167-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
168-
if (Hatchling)
169-
Hatchling->AI()->AttackStart(target);
170-
break;
171-
case 1:
172-
DoTeleportPlayer(target, -7990.135354f, 1155.1907f, -78.849319f, 2.608f);
173-
Hatchling = me->SummonCreature(15962, target->GetPositionX() - 3, target->GetPositionY() - 3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
174-
if (Hatchling)
175-
Hatchling->AI()->AttackStart(target);
176-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
177-
if (Hatchling)
178-
Hatchling->AI()->AttackStart(target);
179-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
180-
if (Hatchling)
181-
Hatchling->AI()->AttackStart(target);
182-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
183-
if (Hatchling)
184-
Hatchling->AI()->AttackStart(target);
185-
break;
186-
case 2:
187-
DoTeleportPlayer(target, -8159.7753f, 1127.9064f, -76.868660f, 0.675f);
188-
Hatchling = me->SummonCreature(15962, target->GetPositionX() - 3, target->GetPositionY() - 3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
189-
if (Hatchling)
190-
Hatchling->AI()->AttackStart(target);
191-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
192-
if (Hatchling)
193-
Hatchling->AI()->AttackStart(target);
194-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
195-
if (Hatchling)
196-
Hatchling->AI()->AttackStart(target);
197-
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
198-
if (Hatchling)
199-
Hatchling->AI()->AttackStart(target);
200-
break;
201-
}
127+
_entanglePerWave = urand(1, 3);
128+
Trinity::Containers::RandomShuffle(EntangleSpells);
129+
events.Repeat(25s, 55s);
202130
}
203-
SpawnHatchlings_Timer = urand(45000, 60000);
204-
} else SpawnHatchlings_Timer -= diff;
131+
else
132+
events.Repeat(5s, 10s);
133+
break;
134+
}
135+
default:
136+
break;
205137
}
206138

207-
DoMeleeAttackIfReady();
139+
if (me->HasUnitState(UNIT_STATE_CASTING))
140+
return;
141+
}
142+
143+
DoMeleeAttackIfReady();
144+
}
145+
146+
private:
147+
uint8 _wormsSpawnPerWave;
148+
uint8 _entanglePerWave;
149+
};
150+
151+
// 720, 731, 1121 - Entangle
152+
class spell_fankriss_entangle : public SpellScript
153+
{
154+
PrepareSpellScript(spell_fankriss_entangle);
155+
156+
bool Validate(SpellInfo const* /*spellInfo*/) override
157+
{
158+
return ValidateSpellInfo({ SPELL_SPAWN_HATCHLING_1, SPELL_SPAWN_HATCHLING_2, SPELL_SPAWN_HATCHLING_3 });
159+
}
160+
161+
void HandleAfterCast()
162+
{
163+
switch (GetSpellInfo()->Id)
164+
{
165+
case SPELL_ENTANGLE_1:
166+
GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_1, true);
167+
break;
168+
case SPELL_ENTANGLE_2:
169+
GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_2, true);
170+
break;
171+
case SPELL_ENTANGLE_3:
172+
GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_3, true);
173+
break;
174+
default:
175+
break;
208176
}
209-
};
177+
}
210178

179+
void Register() override
180+
{
181+
AfterCast += SpellCastFn(spell_fankriss_entangle::HandleAfterCast);
182+
}
211183
};
212184

213185
void AddSC_boss_fankriss()
214186
{
215-
new boss_fankriss();
187+
RegisterAQ40CreatureAI(boss_fankriss);
188+
RegisterSpellScript(spell_fankriss_entangle);
216189
}

0 commit comments

Comments
 (0)