fix(Scripts/HoL): fix the Hall of Watchers gauntlet event (#23287)

This commit is contained in:
Andrew
2025-10-18 15:50:39 -03:00
committed by GitHub
parent 21d2e99d7f
commit 9749e177fb
4 changed files with 147 additions and 156 deletions

View File

@@ -372,160 +372,8 @@ private:
InstanceScript* m_pInstance;
};
enum monumentSpells
{
SPELL_FREEZE_ANIM = 16245,
SPELL_AWAKEN = 52875,
SPELL_PIERCING_HOWL = 23600,
SPELL_PENETRATING_STRIKE = 52890,
SPELL_FRIGHTENING_SHOUT = 19134,
SPELL_BLADE_TURNING_N = 52891,
SPELL_BLADE_TURNING_H = 59173,
SPELL_DEADLY_THROW_N = 52885,
SPELL_DEADLY_THROW_H = 59180,
SPELL_DEFLECTION_N = 52879,
SPELL_DEFLECTION_H = 59181,
SPELL_THROW_N = 52904,
SPELL_THROW_H = 59179,
};
enum monumentEvents
{
EVENT_PIERCING_HOWL = 1,
EVENT_PENETRATING_STRIKE = 2,
EVENT_FRIGHTENING_SHOUT = 3,
EVENT_BLADE_TURNING = 4,
EVENT_DEADLY_THROW = 11,
EVENT_DEFLECTION = 12,
EVENT_THROW = 13,
EVENT_UNFREEZE = 20,
};
struct npc_hol_monument : public ScriptedAI
{
npc_hol_monument(Creature* creature) : ScriptedAI(creature)
{
_attackGUID.Clear();
_isActive = urand(0, 1);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->CastSpell(me, SPELL_FREEZE_ANIM, true);
}
void MoveInLineOfSight(Unit* who) override
{
if (_attackGUID)
ScriptedAI::MoveInLineOfSight(who);
else if (_isActive && who->IsPlayer())
{
if ((who->GetPositionX() < me->GetPositionX() || who->GetPositionY() < -220.0f) && me->GetDistance2d(who) < 40)
{
_isActive = false;
_attackGUID = who->GetGUID();
events.Reset();
events.RescheduleEvent(EVENT_UNFREEZE, 5s);
}
}
}
void JustEngagedWith(Unit*) override
{
events.Reset();
if (me->GetEntry() == 28961) // NPC_TITANIUM_SIEGEBREAKER
{
events.ScheduleEvent(EVENT_PIERCING_HOWL, 10s, 25s);
events.ScheduleEvent(EVENT_PENETRATING_STRIKE, 5s, 10s);
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 20s, 28s);
events.ScheduleEvent(EVENT_BLADE_TURNING, 12s);
}
else
{
events.ScheduleEvent(EVENT_THROW, 10s, 25s);
events.ScheduleEvent(EVENT_DEADLY_THROW, 15s, 30s);
events.ScheduleEvent(EVENT_DEFLECTION, 15s);
}
}
void AttackStart(Unit* who) override
{
if (!_attackGUID || !_isActive)
return;
ScriptedAI::AttackStart(who);
}
void UpdateAI(uint32 diff) override
{
if (!_isActive && !_attackGUID)
return;
events.Update(diff);
uint32 eventId = events.ExecuteEvent();
if (eventId == EVENT_UNFREEZE)
{
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->CastSpell(me, SPELL_AWAKEN, true);
me->RemoveAllAuras();
_isActive = true;
if (Unit* target = ObjectAccessor::GetUnit(*me, _attackGUID))
AttackStart(target);
return;
}
//Return since we have no target or if we are disabled from fight
if (!UpdateVictim())
return;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (eventId)
{
case EVENT_PIERCING_HOWL:
me->CastSpell(me->GetVictim(), SPELL_PIERCING_HOWL, false);
events.Repeat(10s, 25s);
break;
case EVENT_PENETRATING_STRIKE:
me->CastSpell(me->GetVictim(), SPELL_PENETRATING_STRIKE, false);
events.Repeat(5s, 10s);
break;
case EVENT_FRIGHTENING_SHOUT:
me->CastSpell(me->GetVictim(), SPELL_FRIGHTENING_SHOUT, false);
events.Repeat(20s, 28s);
break;
case EVENT_BLADE_TURNING:
me->CastSpell(me->GetVictim(), me->GetMap()->IsHeroic() ? SPELL_BLADE_TURNING_H : SPELL_BLADE_TURNING_N, false);
events.Repeat(12s);
break;
case EVENT_THROW:
me->CastSpell(SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0), me->GetMap()->IsHeroic() ? SPELL_THROW_H : SPELL_THROW_N, true);
events.Repeat(10s, 25s);
break;
case EVENT_DEADLY_THROW:
me->CastSpell(SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0), me->GetMap()->IsHeroic() ? SPELL_DEADLY_THROW_H : SPELL_DEADLY_THROW_N, true);
events.Repeat(15s, 30s);
break;
case EVENT_DEFLECTION:
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_DEFLECTION_H : SPELL_DEFLECTION_N, false);
events.Repeat(15s);
break;
}
DoMeleeAttackIfReady();
}
private:
EventMap events;
bool _isActive;
ObjectGuid _attackGUID;
};
void AddSC_boss_volkhan()
{
RegisterHallOfLightningCreatureAI(boss_volkhan);
RegisterHallOfLightningCreatureAI(npc_molten_golem);
RegisterHallOfLightningCreatureAI(npc_hol_monument);
}

View File

@@ -45,10 +45,8 @@ enum HoLDataTypes
enum HoLNPCs
{
NPC_BJARNGRIM = 28586,
NPC_VOLKHAN = 28587,
NPC_IONAR = 28546,
NPC_LOKEN = 28923,
NPC_TITANIUM_THUNDERER = 28965,
NPC_TITANIUM_SIEGEBREAKER = 28961
};
enum HoLGOs
@@ -58,6 +56,11 @@ enum HoLGOs
GO_LOKEN_THRONE = 192654
};
enum HoLActions
{
ACTION_ACTIVATE_TITANIUM_VRYKUL,
};
template <class AI, class T>
inline AI* GetHallsOfLightningAI(T* obj)
{

View File

@@ -15,8 +15,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AreaTriggerScript.h"
#include "CreatureScript.h"
#include "InstanceMapScript.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "halls_of_lightning.h"
@@ -82,7 +84,52 @@ public:
}
};
enum TitaniumHallwaySpells
{
SPELL_FREEZE_ANIM = 16245,
SPELL_AWAKEN = 52875,
};
class at_hol_hall_of_watchers : public OnlyOnceAreaTriggerScript
{
public:
at_hol_hall_of_watchers() : OnlyOnceAreaTriggerScript("at_hol_hall_of_watchers") {}
bool _OnTrigger(Player* player, const AreaTrigger* /*at*/) override
{
std::list<Creature*> creatures;
player->GetCreatureListWithEntryInGrid(creatures, { NPC_TITANIUM_SIEGEBREAKER, NPC_TITANIUM_THUNDERER }, 50.0f);
creatures.remove_if([&](Creature const* creature) -> bool
{
return !player->IsWithinLOSInMap(creature) || !creature->HasAura(SPELL_FREEZE_ANIM);
});
if (creatures.empty())
return false;
Acore::Containers::RandomResize(creatures, urand(2, 4));
ObjectGuid target = player->GetGUID();
for (Creature* creature : creatures)
{
creature->SetHomePosition(player->GetPosition());
creature->AI()->DoCastSelf(SPELL_AWAKEN);
creature->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
creature->m_Events.AddEventAtOffset([creature, target] {
creature->AI()->DoAction(ACTION_ACTIVATE_TITANIUM_VRYKUL);
if (Player* targetPlayer = ObjectAccessor::GetPlayer(*creature, target))
creature->AI()->AttackStart(targetPlayer);
}, 5s);
}
return false;
}
};
void AddSC_instance_halls_of_lightning()
{
new instance_halls_of_lightning();
new at_hol_hall_of_watchers();
}