mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 00:48:56 +01:00
Scripts/HallsOfStone: Sjonnir, some improvements
- rewritten to BossAI - added spawn ordered by percent, according to official data Closes #10702 Signed-off-by: joschiwald <joschiwald@online.de>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (51849, 50840, 50834, 50830, 50831);
|
||||
INSERT INTO `spelldifficulty_dbc`(`id`,`spellid0`,`spellid1`) VALUES
|
||||
(51849, 51849, 59861),
|
||||
(50840, 50840, 59848),
|
||||
(50834, 50834, 59846),
|
||||
(50830, 50830, 59844),
|
||||
(50831, 50831, 59845);
|
||||
@@ -15,280 +15,238 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Script Data Start
|
||||
SDName: Boss sjonnir
|
||||
SDAuthor: LordVanMartin
|
||||
SD%Complete:
|
||||
SDComment:
|
||||
SDCategory:
|
||||
Script Data End */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "halls_of_stone.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_LIGHTING_RING = 51849, //Periodic Trigger (interval 2s) spell = 50841
|
||||
H_SPELL_LIGHTING_RING = 59861, //Periodic Trigger (interval 2s) spell = 59849
|
||||
SPELL_LIGHTING_RING_1 = 50840, //Periodic Trigger (interval 2s) spell = 50841
|
||||
H_SPELL_LIGHTING_RING_1 = 59848, //Periodic Trigger (interval 2s) spell = 59849
|
||||
SPELL_STATIC_CHARGE = 50834, //Periodic Trigger 2s interval, spell =50835
|
||||
H_SPELL_STATIC_CHARGE = 59846, //Periodic Trigger 2s interval, spell =50847
|
||||
SPELL_CHAIN_LIGHTING = 50830,
|
||||
H_SPELL_CHAIN_LIGHTING = 59844,
|
||||
SPELL_LIGHTING_SHIELD = 50831,
|
||||
H_SPELL_LIGHTING_SHIELD = 59845,
|
||||
SPELL_FRENZY = 28747
|
||||
SPELL_LIGHTING_RING = 51849, // Periodic Trigger (interval 2s) spell = 50841
|
||||
SPELL_LIGHTING_RING_1 = 50840, // Periodic Trigger (interval 2s) spell = 50841
|
||||
SPELL_STATIC_CHARGE = 50834, // Periodic Trigger 2s interval, spell =50835
|
||||
SPELL_CHAIN_LIGHTING = 50830,
|
||||
SPELL_LIGHTING_SHIELD = 50831,
|
||||
SPELL_FRENZY = 28747
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_DEATH = 2
|
||||
};
|
||||
|
||||
#define EMOTE_GENERIC_FRENZY -1000002
|
||||
|
||||
enum SjonnirCreatures
|
||||
{
|
||||
CREATURE_FORGED_IRON_TROGG = 27979,
|
||||
CREATURE_MALFORMED_OOZE = 27981,
|
||||
CREATURE_FORGED_IRON_DWARF = 27982,
|
||||
CREATURE_IRON_SLUDGE = 28165
|
||||
NPC_FORGED_IRON_TROGG = 27979,
|
||||
NPC_MALFORMED_OOZE = 27981,
|
||||
NPC_FORGED_IRON_DWARF = 27982,
|
||||
NPC_IRON_SLUDGE = 28165,
|
||||
NPC_EARTHEN_DWARF = 27980
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
DATA_TIME_BEFORE_OOZE = 150000, // 2min 30 secs
|
||||
ACTION_OOZE_DEAD = 1,
|
||||
DATA_ABUSE_THE_OOZE = 2
|
||||
ACTION_OOZE_DEAD = 1,
|
||||
DATA_ABUSE_THE_OOZE = 2
|
||||
};
|
||||
|
||||
struct Locations
|
||||
enum Events
|
||||
{
|
||||
float x, y, z;
|
||||
EVENT_CHAIN_LIGHTNING = 1,
|
||||
EVENT_LIGHTNING_SHIELD,
|
||||
EVENT_STATIC_CHARGE,
|
||||
EVENT_LIGHTNING_RING,
|
||||
EVENT_SUMMON,
|
||||
EVENT_FRENZY,
|
||||
};
|
||||
|
||||
static Locations PipeLocations[] =
|
||||
Position const PipeLocations[] =
|
||||
{
|
||||
{1295.44f, 734.07f, 200.3f}, //left
|
||||
{1297.7f, 595.6f, 199.9f} //right
|
||||
{ 1295.44f, 734.07f, 200.3f, 0.0f }, // left
|
||||
{ 1297.7f, 595.6f, 199.9f, 0.0f } // right
|
||||
};
|
||||
|
||||
static Locations CenterPoint = {1295.21f, 667.157f, 189.691f};
|
||||
Position const CenterPoint = { 1295.21f, 667.157f, 189.691f, 0.0f };
|
||||
|
||||
class boss_sjonnir : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_sjonnir() : CreatureScript("boss_sjonnir") { }
|
||||
public:
|
||||
boss_sjonnir() : CreatureScript("boss_sjonnir") { }
|
||||
|
||||
struct boss_sjonnirAI : public ScriptedAI
|
||||
{
|
||||
boss_sjonnirAI(Creature* creature) : ScriptedAI(creature), lSummons(me)
|
||||
struct boss_sjonnirAI : public BossAI
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
boss_sjonnirAI(Creature* creature) : BossAI(creature, DATA_SJONNIR) { }
|
||||
|
||||
bool bIsFrenzy;
|
||||
|
||||
uint32 uiChainLightningTimer;
|
||||
uint32 uiLightningShieldTimer;
|
||||
uint32 uiStaticChargeTimer;
|
||||
uint32 uiLightningRingTimer;
|
||||
uint32 uiSummonTimer;
|
||||
uint32 uiFrenzyTimer;
|
||||
uint32 uiEncounterTimer;
|
||||
uint8 abuseTheOoze;
|
||||
|
||||
SummonList lSummons;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() OVERRIDE
|
||||
{
|
||||
bIsFrenzy = false;
|
||||
|
||||
uiEncounterTimer = 0;
|
||||
uiChainLightningTimer = urand(3000, 8000);
|
||||
uiLightningShieldTimer = urand(20000, 25000);
|
||||
uiStaticChargeTimer = urand(20000, 25000);
|
||||
uiLightningRingTimer = urand(30000, 35000);
|
||||
uiSummonTimer = 5000;
|
||||
uiFrenzyTimer = 300000; //5 minutes
|
||||
abuseTheOoze = 0;
|
||||
|
||||
lSummons.DespawnAll();
|
||||
|
||||
if (instance)
|
||||
instance->SetBossState(DATA_SJONNIR, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) OVERRIDE
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
uiEncounterTimer = 0;
|
||||
|
||||
if (instance)
|
||||
void Reset() OVERRIDE
|
||||
{
|
||||
/*
|
||||
if (GameObject* pDoor = instance->instance->GetGameObject(instance->GetData64(DATA_SJONNIR_DOOR)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
_Reset();
|
||||
abuseTheOoze = 0;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who) OVERRIDE
|
||||
{
|
||||
if (!instance->CheckRequiredBosses(DATA_SJONNIR, who->ToPlayer()))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
_EnterCombat();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, urand(3000, 8000));
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_SHIELD, urand(20000, 25000));
|
||||
events.ScheduleEvent(EVENT_STATIC_CHARGE, urand(20000, 25000));
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_RING, urand(30000, 35000));
|
||||
events.ScheduleEvent(EVENT_SUMMON, 5000);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 300000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) OVERRIDE
|
||||
{
|
||||
summon->GetMotionMaster()->MovePoint(0, CenterPoint);
|
||||
/*if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
summon->AI()->AttackStart(target);*/
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) OVERRIDE
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) OVERRIDE
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) OVERRIDE
|
||||
{
|
||||
if (action == ACTION_OOZE_DEAD)
|
||||
++abuseTheOoze;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const OVERRIDE
|
||||
{
|
||||
if (type == DATA_ABUSE_THE_OOZE)
|
||||
return abuseTheOoze;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) OVERRIDE
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
case EVENT_CHAIN_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_CHAIN_LIGHTING);
|
||||
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, urand(10000, 15000));
|
||||
break;
|
||||
case EVENT_LIGHTNING_SHIELD:
|
||||
DoCast(me, SPELL_LIGHTING_SHIELD);
|
||||
break;
|
||||
case EVENT_STATIC_CHARGE:
|
||||
DoCastVictim(SPELL_STATIC_CHARGE);
|
||||
events.ScheduleEvent(EVENT_STATIC_CHARGE, urand(20000, 25000));
|
||||
break;
|
||||
case EVENT_LIGHTNING_RING:
|
||||
DoCast(me, SPELL_LIGHTING_RING);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_RING, urand(30000, 35000));
|
||||
break;
|
||||
case EVENT_SUMMON:
|
||||
{
|
||||
uint8 summonPipe = urand(0, 1);
|
||||
if (HealthAbovePct(75))
|
||||
me->SummonCreature(NPC_FORGED_IRON_DWARF, PipeLocations[summonPipe], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
else if (HealthAbovePct(50))
|
||||
me->SummonCreature(NPC_FORGED_IRON_TROGG, PipeLocations[summonPipe], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
else if (HealthAbovePct(25))
|
||||
me->SummonCreature(NPC_MALFORMED_OOZE, PipeLocations[summonPipe], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
else
|
||||
me->SummonCreature(NPC_EARTHEN_DWARF, PipeLocations[summonPipe], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON, 20000);
|
||||
break;
|
||||
}
|
||||
case EVENT_FRENZY:
|
||||
/// @todo: add emote
|
||||
DoCast(me, SPELL_FRENZY, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
instance->SetBossState(DATA_SJONNIR, IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) OVERRIDE
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiChainLightningTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_CHAIN_LIGHTING);
|
||||
uiChainLightningTimer = urand(10000, 15000);
|
||||
} else uiChainLightningTimer -= diff;
|
||||
|
||||
if (uiLightningShieldTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_LIGHTING_SHIELD);
|
||||
uiLightningShieldTimer -= diff;
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
if (uiStaticChargeTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_STATIC_CHARGE);
|
||||
uiStaticChargeTimer = urand(20000, 25000);
|
||||
} uiStaticChargeTimer -= diff;
|
||||
private:
|
||||
uint8 abuseTheOoze;
|
||||
};
|
||||
|
||||
if (uiLightningRingTimer <= diff)
|
||||
{
|
||||
if (me->IsNonMeleeSpellCasted(false))
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SPELL_LIGHTING_RING);
|
||||
uiLightningRingTimer = urand(30000, 35000);
|
||||
} else uiLightningRingTimer -= diff;
|
||||
|
||||
if (uiSummonTimer <= diff)
|
||||
{
|
||||
uint32 uiSummonPipe = rand()%2;
|
||||
me->SummonCreature(uiEncounterTimer > DATA_TIME_BEFORE_OOZE ? CREATURE_MALFORMED_OOZE :
|
||||
RAND(CREATURE_FORGED_IRON_DWARF, CREATURE_FORGED_IRON_TROGG),
|
||||
PipeLocations[uiSummonPipe].x, PipeLocations[uiSummonPipe].y, PipeLocations[uiSummonPipe].z, 0.0f,
|
||||
TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
uiSummonTimer = 20000;
|
||||
} else uiSummonTimer -= diff;
|
||||
|
||||
if (!bIsFrenzy)
|
||||
{
|
||||
if (uiFrenzyTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
bIsFrenzy = true;
|
||||
}
|
||||
else uiFrenzyTimer -= diff;
|
||||
}
|
||||
|
||||
uiEncounterTimer +=diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) OVERRIDE
|
||||
CreatureAI* GetAI(Creature* creature) const OVERRIDE
|
||||
{
|
||||
summon->GetMotionMaster()->MovePoint(0, CenterPoint.x, CenterPoint.y, CenterPoint.z);
|
||||
/*if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
summon->AI()->AttackStart(target);*/
|
||||
lSummons.Summon(summon);
|
||||
return GetHallsOfStoneAI<boss_sjonnirAI>(creature);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) OVERRIDE
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
lSummons.DespawnAll();
|
||||
|
||||
if (instance)
|
||||
instance->SetBossState(DATA_SJONNIR, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) OVERRIDE
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) OVERRIDE
|
||||
{
|
||||
if (action == ACTION_OOZE_DEAD)
|
||||
++abuseTheOoze;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const OVERRIDE
|
||||
{
|
||||
if (type == DATA_ABUSE_THE_OOZE)
|
||||
return abuseTheOoze;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const OVERRIDE
|
||||
{
|
||||
return GetHallsOfStoneAI<boss_sjonnirAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_malformed_ooze : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_malformed_ooze() : CreatureScript("npc_malformed_ooze") { }
|
||||
public:
|
||||
npc_malformed_ooze() : CreatureScript("npc_malformed_ooze") { }
|
||||
|
||||
struct npc_malformed_oozeAI : public ScriptedAI
|
||||
{
|
||||
npc_malformed_oozeAI(Creature* creature) : ScriptedAI(creature) {}
|
||||
|
||||
uint32 uiMergeTimer;
|
||||
|
||||
void Reset() OVERRIDE
|
||||
struct npc_malformed_oozeAI : public ScriptedAI
|
||||
{
|
||||
uiMergeTimer = 10000;
|
||||
}
|
||||
npc_malformed_oozeAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void UpdateAI(uint32 diff) OVERRIDE
|
||||
{
|
||||
if (uiMergeTimer <= diff)
|
||||
void Reset() OVERRIDE
|
||||
{
|
||||
if (Creature* temp = me->FindNearestCreature(CREATURE_MALFORMED_OOZE, 3.0f, true))
|
||||
_mergeTimer = 10000;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) OVERRIDE
|
||||
{
|
||||
if (_mergeTimer <= diff)
|
||||
{
|
||||
DoSpawnCreature(CREATURE_IRON_SLUDGE, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
|
||||
temp->DisappearAndDie();
|
||||
me->DisappearAndDie();
|
||||
if (Creature* temp = me->FindNearestCreature(NPC_MALFORMED_OOZE, 3.0f, true))
|
||||
{
|
||||
DoSpawnCreature(NPC_IRON_SLUDGE, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
|
||||
temp->DisappearAndDie();
|
||||
me->DisappearAndDie();
|
||||
}
|
||||
_mergeTimer = 3000;
|
||||
}
|
||||
uiMergeTimer = 3000;
|
||||
} else uiMergeTimer -= diff;
|
||||
else
|
||||
_mergeTimer -= diff;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _mergeTimer;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const OVERRIDE
|
||||
{
|
||||
return GetHallsOfStoneAI<npc_malformed_oozeAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const OVERRIDE
|
||||
{
|
||||
return GetHallsOfStoneAI<npc_malformed_oozeAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_iron_sludge : public CreatureScript
|
||||
@@ -307,8 +265,8 @@ class npc_iron_sludge : public CreatureScript
|
||||
|
||||
void JustDied(Unit* /*killer*/) OVERRIDE
|
||||
{
|
||||
if (Creature* Sjonnir = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SJONNIR)))
|
||||
Sjonnir->AI()->DoAction(ACTION_OOZE_DEAD);
|
||||
if (Creature* sjonnir = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SJONNIR)))
|
||||
sjonnir->AI()->DoAction(ACTION_OOZE_DEAD);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user