fix(Scripts/ShatteredHalls): Implement the Flame Gauntlet event (#16383)
Co-authored-by: Gultask <100873791+Gultask@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
UPDATE `creature_template` SET `ScriptName` = 'npc_shattered_hand_scout' WHERE `entry` = 17693;
|
||||||
|
|
||||||
|
SET @PATH := 17693 * 10;
|
||||||
|
DELETE FROM `waypoint_data` WHERE `id` = @PATH;
|
||||||
|
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
|
||||||
|
(@PATH,1,389.98074,315.4098,1.9338964,NULL,0,1,0,100,0),
|
||||||
|
(@PATH,2,419.4097,315.15308,1.940825,NULL,0,1,0,100,0),
|
||||||
|
(@PATH,3,460.31537,316.02213,1.9368871,NULL,0,1,0,100,0),
|
||||||
|
(@PATH,4,488.62424,315.73007,1.9498857,NULL,0,1,0,100,0);
|
||||||
|
|
||||||
|
DELETE FROM `spell_target_position` WHERE `ID` = 30976;
|
||||||
|
INSERT INTO `spell_target_position` (`ID`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `VerifiedBuild`) VALUES
|
||||||
|
(30976, 540, 520.062, 255.486, 2.0333333, 48999);
|
||||||
|
|
||||||
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 30952);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(13, 1, 30952, 0, 0, 31, 0, 3, 17687, 0, 0, 0, 0, '', 'Shoot Flame Arrow (30952) only hit Flame Arrow (17687)');
|
||||||
|
|
||||||
|
DELETE FROM `creature_formations` WHERE `memberGUID` IN (151094,151095,151096,151097);
|
||||||
|
INSERT INTO `creature_formations` (`memberGUID`, `leaderGUID`, `groupAI`) VALUES
|
||||||
|
(151095,151095,3),
|
||||||
|
(151096,151095,3),
|
||||||
|
(151097,151095,3);
|
||||||
+226
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "CreatureTextMgr.h"
|
#include "CreatureTextMgr.h"
|
||||||
#include "InstanceScript.h"
|
#include "InstanceScript.h"
|
||||||
|
#include "ScriptedCreature.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "shattered_halls.h"
|
#include "shattered_halls.h"
|
||||||
|
|
||||||
@@ -181,6 +182,221 @@ public:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ScoutMisc
|
||||||
|
{
|
||||||
|
SAY_INVADERS_BREACHED = 0,
|
||||||
|
|
||||||
|
SAY_PORUNG_ARCHERS = 0,
|
||||||
|
SAY_PORUNG_READY = 1,
|
||||||
|
SAY_PORUNG_AIM = 2,
|
||||||
|
SAY_PORUNG_FIRE = 3,
|
||||||
|
|
||||||
|
SPELL_CLEAR_ALL = 28471,
|
||||||
|
SPELL_SUMMON_ZEALOTS = 30976,
|
||||||
|
SPELL_SHOOT_FLAME_ARROW = 30952,
|
||||||
|
|
||||||
|
POINT_SCOUT_WP_END = 3,
|
||||||
|
|
||||||
|
SET_DATA_ARBITRARY_VALUE = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct npc_shattered_hand_scout : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_shattered_hand_scout(Creature* creature) : ScriptedAI(creature) { }
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveInLineOfSight(Unit* who) override
|
||||||
|
{
|
||||||
|
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && me->IsWithinDist2d(who, 50.0f) && who->GetPositionZ() > -3.0f
|
||||||
|
&& who->IsPlayer())
|
||||||
|
{
|
||||||
|
me->SetReactState(REACT_PASSIVE);
|
||||||
|
DoCastSelf(SPELL_CLEAR_ALL);
|
||||||
|
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
Talk(SAY_INVADERS_BREACHED);
|
||||||
|
me->GetMotionMaster()->MovePath(me->GetEntry() * 10, false);
|
||||||
|
|
||||||
|
_firstZealots.clear();
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ZEALOT, 15.0f);
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
_firstZealots.insert(creature->GetGUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
|
||||||
|
{
|
||||||
|
if (damage >= me->GetHealth())
|
||||||
|
{
|
||||||
|
// Let creature fall to 1 HP but prevent it from dying.
|
||||||
|
damage = me->GetHealth() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovementInform(uint32 type, uint32 point) override
|
||||||
|
{
|
||||||
|
if (type == WAYPOINT_MOTION_TYPE && point == POINT_SCOUT_WP_END)
|
||||||
|
{
|
||||||
|
me->SetVisible(false);
|
||||||
|
|
||||||
|
if (Creature* porung = GetPorung())
|
||||||
|
{
|
||||||
|
porung->setActive(true);
|
||||||
|
porung->AI()->DoCastAOE(SPELL_SUMMON_ZEALOTS);
|
||||||
|
porung->AI()->Talk(SAY_PORUNG_ARCHERS);
|
||||||
|
|
||||||
|
_scheduler.Schedule(45s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (Creature* porung = GetPorung())
|
||||||
|
{
|
||||||
|
porung->AI()->DoCastAOE(SPELL_SUMMON_ZEALOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Repeat();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.Schedule(1s, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
_zealotGUIDs.clear();
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ZEALOT, 100.0f);
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
creature->AI()->SetData(SET_DATA_ARBITRARY_VALUE, SET_DATA_ARBITRARY_VALUE);
|
||||||
|
_zealotGUIDs.insert(creature->GetGUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& guid : _firstZealots)
|
||||||
|
{
|
||||||
|
if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
|
||||||
|
{
|
||||||
|
zealot->SetInCombatWithZone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Creature* porung = GetPorung())
|
||||||
|
{
|
||||||
|
porung->AI()->Talk(SAY_PORUNG_READY, 3600ms);
|
||||||
|
porung->AI()->Talk(SAY_PORUNG_AIM, 4800ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.Schedule(5800ms, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ARCHER, 100.0f);
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
creature->AI()->DoCastAOE(SPELL_SHOOT_FLAME_ARROW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Creature* porung = GetPorung())
|
||||||
|
{
|
||||||
|
porung->AI()->Talk(SAY_PORUNG_FIRE, 200ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.Schedule(2s, 9750ms, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (FireArrows())
|
||||||
|
{
|
||||||
|
context.Repeat();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!me->SelectNearestPlayer(250.0f))
|
||||||
|
{
|
||||||
|
me->SetVisible(true);
|
||||||
|
me->DespawnOrUnsummon(5s, 5s);
|
||||||
|
|
||||||
|
for (auto const& guid : _zealotGUIDs)
|
||||||
|
{
|
||||||
|
if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
|
||||||
|
{
|
||||||
|
if (zealot->IsAlive())
|
||||||
|
{
|
||||||
|
zealot->DespawnOrUnsummon(5s, 5s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zealot->Respawn(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& guid : _firstZealots)
|
||||||
|
{
|
||||||
|
if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
|
||||||
|
{
|
||||||
|
if (zealot->IsAlive())
|
||||||
|
{
|
||||||
|
zealot->DespawnOrUnsummon(5s, 5s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zealot->Respawn(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.CancelAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
_scheduler.Update(diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FireArrows()
|
||||||
|
{
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ARCHER, 100.0f);
|
||||||
|
|
||||||
|
if (creatureList.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
creature->AI()->DoCastAOE(SPELL_SHOOT_FLAME_ARROW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Creature* GetPorung()
|
||||||
|
{
|
||||||
|
return me->FindNearestCreature(IsHeroic() ? NPC_PORUNG : NPC_BLOOD_GUARD, 100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
GuidSet _zealotGUIDs;
|
||||||
|
GuidSet _firstZealots;
|
||||||
|
};
|
||||||
|
|
||||||
class spell_tsh_shoot_flame_arrow : public SpellScriptLoader
|
class spell_tsh_shoot_flame_arrow : public SpellScriptLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -192,6 +408,15 @@ public:
|
|||||||
|
|
||||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||||
{
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
if (!caster)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unitList.remove_if([&](WorldObject* target) -> bool
|
||||||
|
{
|
||||||
|
return !target->SelectNearestPlayer(15.0f);
|
||||||
|
});
|
||||||
|
|
||||||
Acore::Containers::RandomResize(unitList, 1);
|
Acore::Containers::RandomResize(unitList, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,6 +457,7 @@ public:
|
|||||||
void AddSC_instance_shattered_halls()
|
void AddSC_instance_shattered_halls()
|
||||||
{
|
{
|
||||||
new instance_shattered_halls();
|
new instance_shattered_halls();
|
||||||
|
RegisterShatteredHallsCreatureAI(npc_shattered_hand_scout);
|
||||||
new spell_tsh_shoot_flame_arrow();
|
new spell_tsh_shoot_flame_arrow();
|
||||||
new at_shattered_halls_execution();
|
new at_shattered_halls_execution();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ enum CreatureIds
|
|||||||
{
|
{
|
||||||
NPC_GRAND_WARLOCK_NETHEKURSE = 16807,
|
NPC_GRAND_WARLOCK_NETHEKURSE = 16807,
|
||||||
NPC_FEL_ORC_CONVERT = 17083,
|
NPC_FEL_ORC_CONVERT = 17083,
|
||||||
|
NPC_PORUNG = 20923,
|
||||||
|
NPC_BLOOD_GUARD = 17461,
|
||||||
|
NPC_SH_ZEALOT = 17462,
|
||||||
|
NPC_SH_ARCHER = 17427,
|
||||||
|
|
||||||
// Warchief Kargath
|
// Warchief Kargath
|
||||||
NPC_WARCHIEF_KARGATH = 16808,
|
NPC_WARCHIEF_KARGATH = 16808,
|
||||||
NPC_WARCHIEF_PORTAL = 17611,
|
NPC_WARCHIEF_PORTAL = 17611,
|
||||||
|
|||||||
Reference in New Issue
Block a user