mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 09:17:18 +00:00
Merge branch 'master' into Playerbot
This commit is contained in:
7
data/sql/updates/db_world/2023_06_07_00.sql
Normal file
7
data/sql/updates/db_world/2023_06_07_00.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
-- DB update 2023_06_05_01 -> 2023_06_07_00
|
||||
--
|
||||
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'boss_porung' WHERE `entry` = 20923;
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (20923, 17461) AND `source_type` = 0;
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (2092300, 1746100) AND `source_type` = 9;
|
||||
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
|
||||
(17461, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 45, 2, 0, 0, 0, 0, 0, 19, 17693, 100, 0, 0, 0, 0, 0, 0, 'Shattered Hand Blood Guard - On Just Died - Set Data 2 0');
|
||||
3
data/sql/updates/db_world/2023_06_07_01.sql
Normal file
3
data/sql/updates/db_world/2023_06_07_01.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
-- DB update 2023_06_07_00 -> 2023_06_07_01
|
||||
--
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|256|4194304 WHERE `entry` IN (17839, 20744, 21140, 22172, 21104, 21148, 22170, 22171);
|
||||
3
data/sql/updates/db_world/2023_06_07_02.sql
Normal file
3
data/sql/updates/db_world/2023_06_07_02.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
-- DB update 2023_06_07_01 -> 2023_06_07_02
|
||||
--
|
||||
UPDATE `gameobject` SET `spawnMask`=2 WHERE `guid` = 30237 AND `id` = 184174;
|
||||
7
data/sql/updates/db_world/2023_06_07_03.sql
Normal file
7
data/sql/updates/db_world/2023_06_07_03.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
-- DB update 2023_06_07_02 -> 2023_06_07_03
|
||||
DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-151090,-151091,-151092,-151093)) AND (`source_type` = 0) AND (`id` IN (1000));
|
||||
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
|
||||
(-151090, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Immune To All'),
|
||||
(-151091, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Immune To All'),
|
||||
(-151092, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Immune To All'),
|
||||
(-151093, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Immune To All');
|
||||
9
data/sql/updates/db_world/2023_06_07_04.sql
Normal file
9
data/sql/updates/db_world/2023_06_07_04.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- DB update 2023_06_07_03 -> 2023_06_07_04
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask` = 0 WHERE `entry` IN (16507, 16700, 17465, 17670, 17671, 20593, 20589, 20583, 20588, 20584, 20582, 20590, 20587, 20586); -- setting to 0
|
||||
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|1|2|8|16|64|128|1024|2048|4096|8192|65536|8388608|536870912 WHERE `entry` IN (17671, 20584); -- full cc
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|1|1024|65536 WHERE `entry` IN (17465, 20583); -- MC/charm, snare and poly
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|65536 WHERE `entry` IN (16700, 20589); -- poly
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|536870912 WHERE `entry` IN (16507, 20593); -- sap
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|65536 WHERE `entry` = 20588; -- houndmaster HC only immune to poly
|
||||
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|1 WHERE `entry` IN (20588, 20584, 20582, 20586, 20587, 20589, 20590, 20593); -- HC only houndmaster, champion, brawler, gladiator, heathen, legionnaire, reaver and sentry MC immune
|
||||
@@ -4541,6 +4541,12 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->MaxAffectedTargets = 1;
|
||||
});
|
||||
|
||||
// Acid Spit
|
||||
ApplySpellFix({ 34290 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->MaxAffectedTargets = 1;
|
||||
});
|
||||
|
||||
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
|
||||
{
|
||||
SpellInfo* spellInfo = mSpellInfoMap[i];
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "shattered_halls.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CLEAR_ALL = 28471,
|
||||
SPELL_SUMMON_ZEALOTS = 30976,
|
||||
SPELL_SHOOT_FLAME_ARROW = 30952,
|
||||
SPELL_CLEAVE = 15496
|
||||
};
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_INVADERS_BREACHED = 0,
|
||||
|
||||
SAY_PORUNG_ARCHERS = 0,
|
||||
SAY_PORUNG_READY = 1,
|
||||
SAY_PORUNG_AIM = 2,
|
||||
SAY_PORUNG_FIRE = 3,
|
||||
SAY_PORUNG_AGGRO = 4
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
POINT_SCOUT_WP_END = 3,
|
||||
|
||||
SET_DATA_ARBITRARY_VALUE = 1,
|
||||
SET_DATA_ENCOUNTER_DONE = 2
|
||||
};
|
||||
|
||||
struct boss_porung : public BossAI
|
||||
{
|
||||
boss_porung(Creature* creature) : BossAI(creature, DATA_PORUNG) { }
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
|
||||
Talk(SAY_PORUNG_AGGRO);
|
||||
scheduler.Schedule(2s, 4s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
context.Repeat(8s, 10s);
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
|
||||
if (Creature* scout = me->FindNearestCreature(NPC_SH_SCOUT, 250.f))
|
||||
scout->AI()->SetData(SET_DATA_ENCOUNTER_DONE, 0);
|
||||
}
|
||||
};
|
||||
|
||||
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 SetData(uint32 type, uint32 /*data*/) override
|
||||
{
|
||||
if (type != SET_DATA_ENCOUNTER_DONE)
|
||||
return;
|
||||
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
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 SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tsh_shoot_flame_arrow);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->CastSpell(target, 30953, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_tsh_shoot_flame_arrow::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_tsh_shoot_flame_arrow::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_porung()
|
||||
{
|
||||
RegisterShatteredHallsCreatureAI(boss_porung);
|
||||
RegisterShatteredHallsCreatureAI(npc_shattered_hand_scout);
|
||||
RegisterSpellScript(spell_tsh_shoot_flame_arrow);
|
||||
}
|
||||
@@ -182,264 +182,6 @@ 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
|
||||
{
|
||||
public:
|
||||
spell_tsh_shoot_flame_arrow() : SpellScriptLoader("spell_tsh_shoot_flame_arrow") { }
|
||||
|
||||
class spell_tsh_shoot_flame_arrow_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_tsh_shoot_flame_arrow_SpellScript);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Unit* target = GetHitUnit())
|
||||
target->CastSpell(target, 30953, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_tsh_shoot_flame_arrow_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_tsh_shoot_flame_arrow_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_tsh_shoot_flame_arrow_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class at_shattered_halls_execution : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
@@ -462,7 +204,5 @@ public:
|
||||
void AddSC_instance_shattered_halls()
|
||||
{
|
||||
new instance_shattered_halls();
|
||||
RegisterShatteredHallsCreatureAI(npc_shattered_hand_scout);
|
||||
new spell_tsh_shoot_flame_arrow();
|
||||
new at_shattered_halls_execution();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ enum DataTypes
|
||||
DATA_NETHEKURSE = 0,
|
||||
DATA_OMROGG = 1,
|
||||
DATA_KARGATH = 2,
|
||||
ENCOUNTER_COUNT = 3,
|
||||
DATA_PORUNG = 3,
|
||||
ENCOUNTER_COUNT = 4,
|
||||
|
||||
DATA_ENTERED_ROOM = 10,
|
||||
DATA_PRISONER_1 = 11,
|
||||
@@ -49,6 +50,7 @@ enum CreatureIds
|
||||
NPC_BLOOD_GUARD = 17461,
|
||||
NPC_SH_ZEALOT = 17462,
|
||||
NPC_SH_ARCHER = 17427,
|
||||
NPC_SH_SCOUT = 17693,
|
||||
|
||||
// Warchief Kargath
|
||||
NPC_WARCHIEF_KARGATH = 16808,
|
||||
|
||||
@@ -75,6 +75,7 @@ void AddSC_instance_blood_furnace();
|
||||
void AddSC_boss_magtheridon(); //HC Magtheridon's Lair
|
||||
void AddSC_instance_magtheridons_lair();
|
||||
void AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls
|
||||
void AddSC_boss_porung();
|
||||
void AddSC_boss_warbringer_omrogg();
|
||||
void AddSC_boss_warchief_kargath_bladefist();
|
||||
void AddSC_instance_shattered_halls();
|
||||
@@ -179,6 +180,7 @@ void AddOutlandScripts()
|
||||
AddSC_boss_magtheridon(); //HC Magtheridon's Lair
|
||||
AddSC_instance_magtheridons_lair();
|
||||
AddSC_boss_grand_warlock_nethekurse(); //HC Shattered Halls
|
||||
AddSC_boss_porung();
|
||||
AddSC_boss_warbringer_omrogg();
|
||||
AddSC_boss_warchief_kargath_bladefist();
|
||||
AddSC_instance_shattered_halls();
|
||||
@@ -219,4 +221,4 @@ void AddOutlandScripts()
|
||||
AddSC_shattrath_city();
|
||||
AddSC_terokkar_forest();
|
||||
//AddSC_zangarmarsh();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user