mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 01:37:37 +01:00
Scripts/AQ40: Rewrite Fankriss (#31200)
This commit is contained in:
32
sql/updates/world/3.3.5/2025_08_16_01_world.sql
Normal file
32
sql/updates/world/3.3.5/2025_08_16_01_world.sql
Normal file
@@ -0,0 +1,32 @@
|
||||
--
|
||||
DELETE FROM `spell_target_position` WHERE `ID` IN (518,25831,25832,26630,26631,26632,720,731,1121);
|
||||
INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `VerifiedBuild`) VALUES
|
||||
(518,0,531,-8028.5,1050.9,-54,0,0),
|
||||
(25831,0,531,-8158.03,1139.3,-83.95,0,0),
|
||||
(25832,0,531,-8029.25,1237.78,-85.2285,0,0),
|
||||
(720,0,531,-8043.6,1254.1,-84.3,0,0),
|
||||
(731,0,531,-8003,1222.9,-82.1,0,0),
|
||||
(1121,0,531,-8022.3,1149,-89.1,0,0),
|
||||
(26630,0,531,-8043.6,1254.1,-84.2167,0,0),
|
||||
(26631,0,531,-8003,1222.9,-82.0167,0,0),
|
||||
(26632,0,531,-8022.3,1149,-89.0167,0,0);
|
||||
|
||||
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 15962;
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (15630,15962) AND `source_type` = 0;
|
||||
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
|
||||
(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"),
|
||||
(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"),
|
||||
(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'"),
|
||||
|
||||
(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"),
|
||||
(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");
|
||||
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_fankriss_entangle';
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(720, 'spell_fankriss_entangle'),
|
||||
(731, 'spell_fankriss_entangle'),
|
||||
(1121, 'spell_fankriss_entangle');
|
||||
|
||||
UPDATE `creature_template` SET `speed_run` = 2.14285714286 WHERE `entry` = 15510;
|
||||
UPDATE `creature_template` SET `speed_run` = 1.71428571429 WHERE `entry` = 15630;
|
||||
UPDATE `creature_template` SET `speed_run` = 1.42857142857 WHERE `entry` = 15962;
|
||||
@@ -3173,7 +3173,9 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
ApplySpellFix({
|
||||
42818, // Headless Horseman - Wisp Flight Port
|
||||
42821, // Headless Horseman - Wisp Flight Missile
|
||||
17678 // Despawn Spectral Combatants
|
||||
17678, // Despawn Spectral Combatants
|
||||
720, // Entangle
|
||||
731 // Entangle
|
||||
}, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
|
||||
|
||||
@@ -15,202 +15,175 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Fankriss
|
||||
SD%Complete: 100
|
||||
SDComment: sound not implemented
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
/*
|
||||
* Timers requires to be revisited
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "Containers.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellScript.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
#define SOUND_SENTENCE_YOU 8588
|
||||
#define SOUND_SERVE_TO 8589
|
||||
#define SOUND_LAWS 8590
|
||||
#define SOUND_TRESPASS 8591
|
||||
#define SOUND_WILL_BE 8592
|
||||
|
||||
enum Spells
|
||||
enum FankrissSpells
|
||||
{
|
||||
SPELL_MORTAL_WOUND = 28467,
|
||||
SPELL_ROOT = 28858,
|
||||
SPELL_MORTAL_WOUND = 25646,
|
||||
|
||||
// Enrage for his spawns
|
||||
SPELL_ENRAGE = 28798
|
||||
SPELL_SUMMON_WORM_1 = 518,
|
||||
SPELL_SUMMON_WORM_2 = 25831,
|
||||
SPELL_SUMMON_WORM_3 = 25832,
|
||||
|
||||
SPELL_ENTANGLE_1 = 720,
|
||||
SPELL_ENTANGLE_2 = 731,
|
||||
SPELL_ENTANGLE_3 = 1121,
|
||||
|
||||
SPELL_SPAWN_HATCHLING_1 = 26630,
|
||||
SPELL_SPAWN_HATCHLING_2 = 26631,
|
||||
SPELL_SPAWN_HATCHLING_3 = 26632
|
||||
};
|
||||
|
||||
class boss_fankriss : public CreatureScript
|
||||
enum FankrissEvents
|
||||
{
|
||||
public:
|
||||
boss_fankriss() : CreatureScript("boss_fankriss") { }
|
||||
EVENT_MORTAL_WOUND = 1,
|
||||
EVENT_SUMMON_WORM,
|
||||
EVENT_ENTANGLE
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
// 15510 - Fankriss the Unyielding
|
||||
struct boss_fankriss : public BossAI
|
||||
{
|
||||
boss_fankriss(Creature* creature) : BossAI(creature, DATA_FRANKRIS), _wormsSpawnPerWave(0), _entanglePerWave(0) { }
|
||||
|
||||
std::vector<uint32> SummonWormSpells = { SPELL_SUMMON_WORM_1, SPELL_SUMMON_WORM_2, SPELL_SUMMON_WORM_3 };
|
||||
std::vector<uint32> EntangleSpells = { SPELL_ENTANGLE_1, SPELL_ENTANGLE_2, SPELL_ENTANGLE_3 };
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
return GetAQ40AI<boss_fankrissAI>(creature);
|
||||
_Reset();
|
||||
_wormsSpawnPerWave = urand(1, 3);
|
||||
Trinity::Containers::RandomShuffle(SummonWormSpells);
|
||||
_entanglePerWave = urand(1, 3);
|
||||
Trinity::Containers::RandomShuffle(EntangleSpells);
|
||||
}
|
||||
|
||||
struct boss_fankrissAI : public BossAI
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
boss_fankrissAI(Creature* creature) : BossAI(creature, DATA_FRANKRIS)
|
||||
BossAI::JustEngagedWith(who);
|
||||
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 2s, 6s);
|
||||
events.ScheduleEvent(EVENT_SUMMON_WORM, 30s, 50s);
|
||||
events.ScheduleEvent(EVENT_ENTANGLE, 15s, 20s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
MortalWound_Timer = urand(10000, 15000);
|
||||
SpawnHatchlings_Timer = urand(6000, 12000);
|
||||
SpawnSpawns_Timer = urand(15000, 45000);
|
||||
}
|
||||
|
||||
uint32 MortalWound_Timer;
|
||||
uint32 SpawnHatchlings_Timer;
|
||||
uint32 SpawnSpawns_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void SummonSpawn(Unit* victim)
|
||||
{
|
||||
if (!victim)
|
||||
return;
|
||||
|
||||
int Rand = 10 + (rand32() % 10);
|
||||
float RandX = 0.f;
|
||||
float RandY = 0.f;
|
||||
|
||||
switch (rand32() % 2)
|
||||
switch (eventId)
|
||||
{
|
||||
case 0: RandX = 0.0f - Rand; break;
|
||||
case 1: RandX = 0.0f + Rand; break;
|
||||
}
|
||||
|
||||
Rand = 10 + (rand32() % 10);
|
||||
switch (rand32() % 2)
|
||||
{
|
||||
case 0: RandY = 0.0f - Rand; break;
|
||||
case 1: RandY = 0.0f + Rand; break;
|
||||
}
|
||||
Rand = 0;
|
||||
Creature* Spawn = DoSpawnCreature(15630, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s);
|
||||
if (Spawn)
|
||||
Spawn->AI()->AttackStart(victim);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//MortalWound_Timer
|
||||
if (MortalWound_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_MORTAL_WOUND);
|
||||
MortalWound_Timer = urand(10000, 20000);
|
||||
} else MortalWound_Timer -= diff;
|
||||
|
||||
//Summon 1-3 Spawns of Fankriss at random time.
|
||||
if (SpawnSpawns_Timer <= diff)
|
||||
{
|
||||
switch (urand(0, 2))
|
||||
case EVENT_MORTAL_WOUND:
|
||||
DoCastVictim(SPELL_MORTAL_WOUND);
|
||||
events.Repeat(4s, 12s);
|
||||
break;
|
||||
case EVENT_SUMMON_WORM:
|
||||
{
|
||||
case 0:
|
||||
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
|
||||
break;
|
||||
case 1:
|
||||
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
|
||||
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
|
||||
break;
|
||||
case 2:
|
||||
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
|
||||
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
|
||||
SummonSpawn(SelectTarget(SelectTargetMethod::Random, 0));
|
||||
break;
|
||||
}
|
||||
SpawnSpawns_Timer = urand(30000, 60000);
|
||||
} else SpawnSpawns_Timer -= diff;
|
||||
DoCastSelf(SummonWormSpells[_wormsSpawnPerWave - 1]);
|
||||
|
||||
// Teleporting Random Target to one of the three tunnels and spawn 4 hatchlings near the gamer.
|
||||
//We will only telport if fankriss has more than 3% of hp so teleported gamers can always loot.
|
||||
if (HealthAbovePct(3))
|
||||
{
|
||||
if (SpawnHatchlings_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
|
||||
--_wormsSpawnPerWave;
|
||||
|
||||
if (!_wormsSpawnPerWave)
|
||||
{
|
||||
DoCast(target, SPELL_ROOT);
|
||||
|
||||
if (GetThreat(target))
|
||||
ModifyThreatByPercent(target, -100);
|
||||
|
||||
Creature* Hatchling = nullptr;
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
DoTeleportPlayer(target, -8106.0142f, 1289.2900f, -74.419533f, 5.112f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
case 1:
|
||||
DoTeleportPlayer(target, -7990.135354f, 1155.1907f, -78.849319f, 2.608f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX() - 3, target->GetPositionY() - 3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
case 2:
|
||||
DoTeleportPlayer(target, -8159.7753f, 1127.9064f, -76.868660f, 0.675f);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX() - 3, target->GetPositionY() - 3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s);
|
||||
if (Hatchling)
|
||||
Hatchling->AI()->AttackStart(target);
|
||||
break;
|
||||
}
|
||||
_wormsSpawnPerWave = urand(1, 3);
|
||||
Trinity::Containers::RandomShuffle(SummonWormSpells);
|
||||
events.Repeat(20s, 70s);
|
||||
}
|
||||
SpawnHatchlings_Timer = urand(45000, 60000);
|
||||
} else SpawnHatchlings_Timer -= diff;
|
||||
else
|
||||
events.Repeat(5s, 20s);
|
||||
break;
|
||||
}
|
||||
case EVENT_ENTANGLE:
|
||||
{
|
||||
Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true);
|
||||
|
||||
if (!target)
|
||||
target = me->GetVictim();
|
||||
|
||||
if (target)
|
||||
DoCast(target, EntangleSpells[_entanglePerWave - 1]);
|
||||
|
||||
--_entanglePerWave;
|
||||
|
||||
if (!_entanglePerWave)
|
||||
{
|
||||
_entanglePerWave = urand(1, 3);
|
||||
Trinity::Containers::RandomShuffle(EntangleSpells);
|
||||
events.Repeat(25s, 55s);
|
||||
}
|
||||
else
|
||||
events.Repeat(5s, 10s);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _wormsSpawnPerWave;
|
||||
uint8 _entanglePerWave;
|
||||
};
|
||||
|
||||
// 720, 731, 1121 - Entangle
|
||||
class spell_fankriss_entangle : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_fankriss_entangle);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_SPAWN_HATCHLING_1, SPELL_SPAWN_HATCHLING_2, SPELL_SPAWN_HATCHLING_3 });
|
||||
}
|
||||
|
||||
void HandleAfterCast()
|
||||
{
|
||||
switch (GetSpellInfo()->Id)
|
||||
{
|
||||
case SPELL_ENTANGLE_1:
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_1, true);
|
||||
break;
|
||||
case SPELL_ENTANGLE_2:
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_2, true);
|
||||
break;
|
||||
case SPELL_ENTANGLE_3:
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_SPAWN_HATCHLING_3, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterCast += SpellCastFn(spell_fankriss_entangle::HandleAfterCast);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_fankriss()
|
||||
{
|
||||
new boss_fankriss();
|
||||
RegisterAQ40CreatureAI(boss_fankriss);
|
||||
RegisterSpellScript(spell_fankriss_entangle);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user