fix(Scripts/HoL): Implement door handling (#23282)

This commit is contained in:
Andrew
2025-10-17 11:53:05 -03:00
committed by GitHub
parent 789c98fccb
commit 5457678f48
6 changed files with 77 additions and 245 deletions

View File

@@ -147,9 +147,9 @@ struct boss_bjarngrim : public npc_escortAI
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
if (m_pInstance)
m_pInstance->SetData(TYPE_BJARNGRIM, NOT_STARTED);
m_pInstance->SetBossState(DATA_BJARNGRIM, NOT_STARTED);
me->CastSpell(me, SPELL_BATTLE_STANCE, true);
DoCastSelf(SPELL_BATTLE_STANCE, true);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
}
@@ -179,7 +179,7 @@ struct boss_bjarngrim : public npc_escortAI
if (m_pInstance)
{
m_pInstance->SetData(TYPE_BJARNGRIM, IN_PROGRESS);
m_pInstance->SetBossState(DATA_BJARNGRIM, IN_PROGRESS);
m_pInstance->SetData(DATA_BJARNGRIM_ACHIEVEMENT, me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE));
}
}
@@ -197,7 +197,7 @@ struct boss_bjarngrim : public npc_escortAI
Talk(SAY_DEATH);
if (m_pInstance)
m_pInstance->SetData(TYPE_BJARNGRIM, DONE);
m_pInstance->SetBossState(DATA_BJARNGRIM, DONE);
}
void RemoveStanceAura(uint8 stance)
@@ -234,8 +234,8 @@ struct boss_bjarngrim : public npc_escortAI
case STANCE_DEFENSIVE:
Talk(SAY_DEFENSIVE_STANCE);
me->CastSpell(me, SPELL_DEFENSIVE_STANCE, true);
me->CastSpell(me, SPELL_DEFENSIVE_AURA, true);
DoCastSelf(SPELL_DEFENSIVE_STANCE, true);
DoCastSelf(SPELL_DEFENSIVE_AURA, true);
events.DelayEvents(20s, STANCE_BERSERKER);
events.DelayEvents(20s, STANCE_BATTLE);
@@ -245,8 +245,8 @@ struct boss_bjarngrim : public npc_escortAI
case STANCE_BERSERKER:
Talk(SAY_BERSERKER_STANCE);
me->CastSpell(me, SPELL_BERSERKER_STANCE, true);
me->CastSpell(me, SPELL_BERSERKER_AURA, true);
DoCastSelf(SPELL_BERSERKER_STANCE, true);
DoCastSelf(SPELL_BERSERKER_AURA, true);
events.DelayEvents(20s, STANCE_DEFENSIVE);
events.DelayEvents(20s, STANCE_BATTLE);
@@ -256,8 +256,8 @@ struct boss_bjarngrim : public npc_escortAI
case STANCE_BATTLE:
Talk(SAY_BATTLE_STANCE);
me->CastSpell(me, SPELL_BATTLE_STANCE, true);
me->CastSpell(me, SPELL_BATTLE_AURA, true);
DoCastSelf(SPELL_BATTLE_STANCE, true);
DoCastSelf(SPELL_BATTLE_AURA, true);
events.DelayEvents(20s, STANCE_BERSERKER);
events.DelayEvents(20s, STANCE_DEFENSIVE);
@@ -272,7 +272,7 @@ struct boss_bjarngrim : public npc_escortAI
void WaypointReached(uint32 Point) override
{
if (Point == 1 || Point == 8)
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
DoCastSelf(SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
else if (Point == 7 || Point == 14)
me->RemoveAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE);
}
@@ -303,53 +303,45 @@ struct boss_bjarngrim : public npc_escortAI
events.Repeat(20s);
break;
///////////////////////////////////////////////////////
///// DEFENSIVE STANCE
///////////////////////////////////////////////////////
// DEFENSIVE STANCE
case EVENT_BJARNGRIM_REFLECTION:
me->CastSpell(me, SPELL_BJARNGRIM_REFLETION, true);
DoCastSelf(SPELL_BJARNGRIM_REFLETION, true);
events.Repeat(8s, 9s);
break;
case EVENT_BJARNGRIM_PUMMEL:
me->CastSpell(me->GetVictim(), SPELL_PUMMEL, false);
DoCastVictim(SPELL_PUMMEL);
events.Repeat(10s, 11s);
break;
case EVENT_BJARNGRIM_KNOCK:
me->CastSpell(me, SPELL_KNOCK_AWAY, false);
DoCastAOE(SPELL_KNOCK_AWAY);
events.Repeat(20s, 21s);
break;
case EVENT_BJARNGRIM_IRONFORM:
me->CastSpell(me, SPELL_IRONFORM, true);
DoCastSelf(SPELL_IRONFORM, true);
events.Repeat(18s, 23s);
break;
///////////////////////////////////////////////////////
///// BERSERKER STANCE
///////////////////////////////////////////////////////
// BERSERKER STANCE
case EVENT_BJARNGRIM_MORTAL_STRIKE:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
DoCastVictim(SPELL_MORTAL_STRIKE);
events.Repeat(10s);
break;
case EVENT_BJARNGRIM_WHIRLWIND:
me->CastSpell(me, SPELL_WHIRLWIND, true);
DoCastSelf(SPELL_WHIRLWIND, true);
events.Repeat(25s);
break;
///////////////////////////////////////////////////////
///// BATTLE STANCE
///////////////////////////////////////////////////////
// BATTLE STANCE
case EVENT_BJARNGRIM_INTERCEPT:
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
me->CastSpell(target, SPELL_INTERCEPT, true);
DoCastRandomTarget(SPELL_INTERCEPT, 0, 40.0f, false, true);
events.Repeat(30s);
break;
case EVENT_BJARNGRIM_CLEAVE:
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
DoCastVictim(SPELL_CLEAVE);
events.Repeat(25s);
break;
case EVENT_BJARNGRIM_SLAM:
me->CastSpell(me->GetVictim(), SPELL_SLAM, false);
DoCastVictim(SPELL_SLAM);
events.Repeat(10s, 12s);
break;
}

View File

@@ -70,21 +70,13 @@ enum IonarEvents
struct boss_ionar : public BossAI
{
boss_ionar(Creature* creature) : BossAI(creature, DATA_IONAR), summons(creature)
{
m_pInstance = creature->GetInstanceScript();
}
boss_ionar(Creature* creature) : BossAI(creature, DATA_IONAR) { }
void Reset() override
{
_Reset();
HealthCheck = 50;
events.Reset();
summons.DespawnAll();
me->SetVisible(true);
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, NOT_STARTED);
}
void ScheduleEvents(bool spark)
@@ -99,23 +91,15 @@ struct boss_ionar : public BossAI
void JustEngagedWith(Unit*) override
{
me->SetInCombatWithZone();
_JustEngagedWith();
Talk(SAY_AGGRO);
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, IN_PROGRESS);
ScheduleEvents(false);
}
void JustDied(Unit*) override
{
_JustDied();
Talk(SAY_DEATH);
summons.DespawnAll();
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, DONE);
}
void KilledUnit(Unit* victim) override
@@ -210,9 +194,6 @@ struct boss_ionar : public BossAI
}
private:
InstanceScript* m_pInstance;
EventMap events;
SummonList summons;
uint8 HealthCheck;
};

View File

@@ -64,21 +64,15 @@ struct boss_loken : public BossAI
{
boss_loken(Creature* creature) : BossAI(creature, DATA_LOKEN)
{
m_pInstance = creature->GetInstanceScript();
if (m_pInstance)
isActive = m_pInstance->GetData(TYPE_LOKEN_INTRO);
isActive = instance->GetData(DATA_LOKEN_INTRO);
}
void MoveInLineOfSight(Unit*) override { }
void Reset() override
{
events.Reset();
if (m_pInstance)
{
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
m_pInstance->SetData(TYPE_LOKEN, NOT_STARTED);
}
_Reset();
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
HealthCheck = 75;
IntroTimer = 0;
@@ -98,28 +92,21 @@ struct boss_loken : public BossAI
void JustEngagedWith(Unit*) override
{
me->SetInCombatWithZone();
_JustEngagedWith();
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_ARC_LIGHTNING, 10s);
events.ScheduleEvent(EVENT_SHOCKWAVE, 3s);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 15s);
if (m_pInstance)
{
m_pInstance->SetData(TYPE_LOKEN, IN_PROGRESS);
if (me->GetMap()->IsHeroic())
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
}
if (IsHeroic())
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
}
void JustDied(Unit*) override
{
_JustDied();
Talk(SAY_DEATH);
if (m_pInstance)
m_pInstance->SetData(TYPE_LOKEN, DONE);
}
void LokenSpeach(bool hp)
@@ -175,14 +162,13 @@ struct boss_loken : public BossAI
if (IntroTimer >= 60000)
{
isActive = true;
if (m_pInstance)
m_pInstance->SetData(TYPE_LOKEN_INTRO, 1);
instance->SetData(DATA_LOKEN_INTRO, 1);
me->SetControlled(false, UNIT_STATE_STUNNED);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
if (Player* target = SelectTargetFromPlayerList(80))
AttackStart(target);
if (GameObject* globe = instance->GetGameObject(DATA_LOKEN_THRONE))
globe->SetGoState(GO_STATE_ACTIVE);
}
return;
@@ -235,9 +221,6 @@ struct boss_loken : public BossAI
DoMeleeAttackIfReady();
}
private:
InstanceScript* m_pInstance;
EventMap events;
bool isActive;
uint32 IntroTimer;
uint8 HealthCheck;

View File

@@ -80,46 +80,30 @@ enum Yells
struct boss_volkhan : public BossAI
{
boss_volkhan(Creature* creature) : BossAI(creature, DATA_VOLKHAN), summons(creature)
{
m_pInstance = creature->GetInstanceScript();
}
boss_volkhan(Creature* creature) : BossAI(creature, DATA_VOLKHAN), summons(creature) { }
void Reset() override
{
_Reset();
x = y = z = PointID = ShatteredCount = 0;
HealthCheck = 100;
events.Reset();
summons.DespawnAll();
me->SetSpeed(MOVE_RUN, 1.2f, true);
me->SetReactState(REACT_AGGRESSIVE);
if (m_pInstance)
{
m_pInstance->SetData(TYPE_VOLKHAN, NOT_STARTED);
m_pInstance->SetData(DATA_VOLKHAN_ACHIEVEMENT, true);
}
instance->SetData(DATA_VOLKHAN_ACHIEVEMENT, true);
}
void JustEngagedWith(Unit*) override
{
_JustEngagedWith();
me->SetInCombatWithZone();
Talk(SAY_AGGRO);
if (m_pInstance)
m_pInstance->SetData(TYPE_VOLKHAN, IN_PROGRESS);
ScheduleEvents(false);
}
void JustDied(Unit*) override
{
_JustDied();
Talk(SAY_DEATH);
summons.DespawnAll();
if (m_pInstance)
m_pInstance->SetData(TYPE_VOLKHAN, DONE);
}
void GetNextPos()
@@ -198,7 +182,7 @@ struct boss_volkhan : public BossAI
{
ShatteredCount++;
if (ShatteredCount > 4)
m_pInstance->SetData(DATA_VOLKHAN_ACHIEVEMENT, false);
instance->SetData(DATA_VOLKHAN_ACHIEVEMENT, false);
}
}
@@ -300,7 +284,6 @@ struct boss_volkhan : public BossAI
}
private:
InstanceScript* m_pInstance;
EventMap events;
SummonList summons;
uint8 HealthCheck;

View File

@@ -24,7 +24,7 @@
#define HallsOfLightningScriptName "instance_halls_of_lightning"
enum BossIds
enum HoLBossIds
{
DATA_BJARNGRIM = 0,
DATA_IONAR = 1,
@@ -33,15 +33,14 @@ enum BossIds
MAX_ENCOUNTERS
};
enum HoLEvents
enum HoLDataTypes
{
TYPE_BJARNGRIM = 0,
TYPE_IONAR = 1,
TYPE_LOKEN = 2,
TYPE_VOLKHAN = 3,
TYPE_LOKEN_INTRO = 4,
MAX_ENCOUNTER = 5,
DATA_LOKEN_INTRO = 0,
// GameObject data
DATA_LOKEN_THRONE = 0,
// Achievement data
DATA_BJARNGRIM_ACHIEVEMENT = 10,
DATA_VOLKHAN_ACHIEVEMENT = 11,
};
@@ -56,10 +55,10 @@ enum HoLNPCs
enum HoLGOs
{
GO_BJARNGRIM_DOOR = 191416, //_doors10
GO_VOLKHAN_DOOR = 191325, //_doors07
GO_IONAR_DOOR = 191326, //_doors05
GO_LOKEN_DOOR = 191324, //_doors02
GO_BJARNGRIM_DOOR = 191416,
GO_VOLKHAN_DOOR = 191325,
GO_IONAR_DOOR = 191326,
GO_LOKEN_DOOR = 191324,
GO_LOKEN_THRONE = 192654,
};

View File

@@ -20,94 +20,38 @@
#include "ScriptedCreature.h"
#include "halls_of_lightning.h"
DoorData const doorData[] =
{
{ GO_BJARNGRIM_DOOR, DATA_BJARNGRIM, DOOR_TYPE_PASSAGE },
{ GO_VOLKHAN_DOOR, DATA_VOLKHAN, DOOR_TYPE_PASSAGE },
{ GO_IONAR_DOOR, DATA_IONAR, DOOR_TYPE_PASSAGE },
{ GO_LOKEN_DOOR, DATA_LOKEN, DOOR_TYPE_PASSAGE },
{ 0, 0, DOOR_TYPE_ROOM }
};
ObjectData const gameObjectData[] =
{
{ GO_LOKEN_THRONE, DATA_LOKEN_THRONE },
{ 0, 0 }
};
class instance_halls_of_lightning : public InstanceMapScript
{
public:
instance_halls_of_lightning() : InstanceMapScript("instance_halls_of_lightning", MAP_HALLS_OF_LIGHTNING) { }
InstanceScript* GetInstanceScript(InstanceMap* pMap) const override
{
return new instance_halls_of_lightning_InstanceMapScript(pMap);
}
struct instance_halls_of_lightning_InstanceMapScript : public InstanceScript
{
instance_halls_of_lightning_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
{
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTERS);
LoadDoorData(doorData);
LoadObjectData(nullptr, gameObjectData);
volkhanAchievement = false;
bjarngrimAchievement = false;
};
bool IsEncounterInProgress() const override
{
if (InstanceScript::IsEncounterInProgress())
return true;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
{
if (m_auiEncounter[i] == IN_PROGRESS && i != TYPE_LOKEN_INTRO)
{
return true;
}
}
return false;
}
void OnCreatureCreate(Creature* pCreature) override
{
switch (pCreature->GetEntry())
{
case NPC_BJARNGRIM:
m_uiGeneralBjarngrimGUID = pCreature->GetGUID();
break;
case NPC_VOLKHAN:
m_uiVolkhanGUID = pCreature->GetGUID();
break;
case NPC_IONAR:
m_uiIonarGUID = pCreature->GetGUID();
break;
case NPC_LOKEN:
m_uiLokenGUID = pCreature->GetGUID();
break;
}
}
void OnGameObjectCreate(GameObject* pGo) override
{
switch (pGo->GetEntry())
{
case GO_BJARNGRIM_DOOR:
m_uiBjarngrimDoorGUID = pGo->GetGUID();
if (m_auiEncounter[TYPE_BJARNGRIM] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_VOLKHAN_DOOR:
m_uiVolkhanDoorGUID = pGo->GetGUID();
if (m_auiEncounter[TYPE_VOLKHAN] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_IONAR_DOOR:
m_uiIonarDoorGUID = pGo->GetGUID();
if (m_auiEncounter[TYPE_IONAR] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_LOKEN_DOOR:
m_uiLokenDoorGUID = pGo->GetGUID();
if (m_auiEncounter[TYPE_LOKEN] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_LOKEN_THRONE:
m_uiLokenGlobeGUID = pGo->GetGUID();
break;
}
}
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override
{
switch (criteria_id)
@@ -122,8 +66,7 @@ public:
void SetData(uint32 uiType, uint32 uiData) override
{
m_auiEncounter[uiType] = uiData;
if (uiType == TYPE_LOKEN_INTRO)
if (uiType == DATA_LOKEN_INTRO)
SaveToDB();
// Achievements
@@ -135,67 +78,18 @@ public:
if (uiData != DONE)
return;
switch (uiType)
{
case TYPE_BJARNGRIM:
HandleGameObject(m_uiBjarngrimDoorGUID, true);
break;
case TYPE_VOLKHAN:
HandleGameObject(m_uiVolkhanDoorGUID, true);
break;
case TYPE_IONAR:
HandleGameObject(m_uiIonarDoorGUID, true);
break;
case TYPE_LOKEN:
HandleGameObject(m_uiLokenDoorGUID, true);
//Appears to be type 5 GO with animation. Need to figure out how this work, code below only placeholder
if (GameObject* pGlobe = instance->GetGameObject(m_uiLokenGlobeGUID))
pGlobe->SetGoState(GO_STATE_ACTIVE);
break;
}
SaveToDB();
}
void ReadSaveDataMore(std::istringstream& data) override
{
data >> m_auiEncounter[0];
data >> m_auiEncounter[1];
data >> m_auiEncounter[2];
data >> m_auiEncounter[3];
}
void WriteSaveDataMore(std::ostringstream& data) override
{
data << m_auiEncounter[0] << ' '
<< m_auiEncounter[1] << ' '
<< m_auiEncounter[2] << ' '
<< m_auiEncounter[3] << ' ';
}
uint32 GetData(uint32 uiType) const override
{
return m_auiEncounter[uiType];
}
private:
uint32 m_auiEncounter[MAX_ENCOUNTER];
ObjectGuid m_uiGeneralBjarngrimGUID;
ObjectGuid m_uiIonarGUID;
ObjectGuid m_uiLokenGUID;
ObjectGuid m_uiVolkhanGUID;
ObjectGuid m_uiBjarngrimDoorGUID;
ObjectGuid m_uiVolkhanDoorGUID;
ObjectGuid m_uiIonarDoorGUID;
ObjectGuid m_uiLokenDoorGUID;
ObjectGuid m_uiLokenGlobeGUID;
bool volkhanAchievement;
bool bjarngrimAchievement;
};
InstanceScript* GetInstanceScript(InstanceMap* pMap) const override
{
return new instance_halls_of_lightning_InstanceMapScript(pMap);
}
};
void AddSC_instance_halls_of_lightning()