Scripts/GB: implement Forgemaster Throngus encounter

This commit is contained in:
Ovalord
2018-01-27 22:09:55 +01:00
parent 8a274f0329
commit 5f6656fcd4
5 changed files with 881 additions and 1 deletions

View File

@@ -0,0 +1,102 @@
-- Template Updates
UPDATE `creature_template` SET `Scriptname`= 'boss_forgemaster_throngus', `flags_extra`= `flags_extra`| 0x40000000, `mechanic_immune_mask`= 617299839 WHERE `entry`= 40177;
UPDATE `creature_template` SET `flags_extra`= `flags_extra`| 0x40000000 | 1, `mechanic_immune_mask`= 617299839, `minlevel`= 87, `maxlevel`= 87 WHERE `entry`= 48702;
-- Cave In Stalker
UPDATE `creature_template` SET `minlevel`= 85, `maxlevel`= 85, `faction`= 7, `unit_flags`= 34078720, `flags_extra`= 131, `ScriptName`= 'npc_throngus_cave_in' WHERE `entry`= 40228;
-- Fixate Stalker
UPDATE `creature_template` SET `minlevel`= 80, `maxlevel`= 80, `faction`= 35, `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 40255;
-- Fire Patch
UPDATE `creature_template` SET `minlevel`= 80, `maxlevel`= 80, `faction`= 7, `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 48711;
-- Template Addons
DELETE FROM `creature_template_addon` WHERE `entry` IN (40228, 48711);
INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES
(40228, '74990'),
(48711, '90752');
-- Spells
DELETE FROM `spell_script_names` WHERE `ScriptName` IN
('spell_throngus_mighty_stomp',
'spell_throngus_pick_weapon',
'spell_throngus_flame_arrow_barrage',
'spell_throngus_flaming_arrow',
'spell_throngus_personal_phalanx',
'spell_throngus_personal_phalanx_aoe',
'spell_throngus_fixate_effect',
'spell_throngus_burning_dual_blades',
'spell_throngus_disorienting_roar',
'spell_throngus_encumbered',
'spell_throngus_impaling_slam');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(74984, 'spell_throngus_mighty_stomp'),
(75000, 'spell_throngus_pick_weapon'),
(74945, 'spell_throngus_flame_arrow_barrage'),
(74944, 'spell_throngus_flaming_arrow'),
(90810, 'spell_throngus_flaming_arrow'),
(74908, 'spell_throngus_personal_phalanx'),
(74914, 'spell_throngus_personal_phalanx_aoe'),
(75071, 'spell_throngus_fixate_effect'),
(74981, 'spell_throngus_burning_dual_blades'),
(90738, 'spell_throngus_burning_dual_blades'),
(74976, 'spell_throngus_disorienting_roar'),
(90737, 'spell_throngus_disorienting_roar'),
(75007, 'spell_throngus_encumbered'),
(90729, 'spell_throngus_encumbered'),
(75056, 'spell_throngus_impaling_slam'),
(90756, 'spell_throngus_impaling_slam');
-- Texts
DELETE FROM `creature_text` WHERE `CreatureID`= 40177;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `Comment`) VALUES
(40177, 0, 0, 'NEIN! Throngus wieder ausgepeitscht, wenn er nicht fertig wird!', 14, 0, 100, 0, 0, 18943, 47777, 'Forgemaster Throngus - Say Aggro'),
(40177, 1, 0, 'You not get through defenses!', 14, 0, 100, 0, 0, 18947, 47781, 'Forgemaster Throngus - Say Personal Phalanx'),
(40177, 2, 0, 'Oh, this gonna HURT!', 14, 0, 100, 53, 0, 18949, 47782, 'Forgemaster Throngus - Say Mace'),
(40177, 3, 0, 'Throngus SLICE you up!', 14, 0, 100, 0, 0, 18948, 47783, 'Forgemaster Throngus - Say Swords'),
(40177, 4, 0, '|TInterface\\Icons\\inv_shield_76.blp:20|t%s equips his |cFFFF0000Shield|r and gains |cFFFF0000|Hspell:74908|h[Personal Phalanx]|h|r!', 41, 0, 100, 0, 0, 0, 40747, 'Forgemaster Throngus - Announce Personal Phalanx'),
(40177, 5, 0, '|TInterface\\Icons\\inv_mace_15.blp:20|t%s equips his |cFFFF0000Mace|r and is |cFFFF0000|Hspell:75007|h[Encumbered]|h|r!', 41, 0, 100, 53, 0, 0, 40239, 'Forgemaster Throngus - Announce Mace'),
(40177, 6, 0, '|TInterface\\Icons\\ability_dualwield.blp:20|t%s equips his |cFFFF0000Swords|r and gains |cFFFF0000|Hspell:74981|h[Dual Blades]|h|r!', 41, 0, 100, 0, 0, 0, 40746, 'Forgemaster Throngus - Announce Swords'),
(40177, 7, 0, '$n is impaled!', 41, 0, 100, 0, 0, 0, 30718, 'Forgemaster Throngus - Announce Impaled'),
(40177, 8, 0, 'Throngus use your corpse on body. Somewhere...', 14, 0, 100, 0, 0, 18944, 47778, 'Forgemaster Throngus - Slay 1'),
(40177, 8, 1, 'You break easy!', 14, 0, 100, 0, 0, 18945, 47779, 'Forgemaster Throngus - Slay 2'),
(40177, 9, 0, 'Death... Good choice. Not best choice maybe, but better than fail and live.', 14, 0, 100, 0, 0, 18946, 47780, 'Forgemaster Throngus to Player');
-- Conditions
DELETE FROM `conditions` WHERE `SourceEntry` IN (74945, 75071) AND `SourceTypeOrReferenceId`= 13;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES
(13, 1, 74945, 0, 0, 31, 0, 3, 40197, 0, 0, 0, '', 'Flame Arrow Barrage - Target Twilight Archer'),
(13, 1, 75071, 0, 0, 31, 0, 3, 40255, 0, 0, 0, '', 'Fixate Effect - Target Fixate Stalker');
-- Proc Entries
DELETE FROM `spell_proc` WHERE `SpellId` IN (74981, 90738, 74976, 90737, 90759);
INSERT INTO `spell_proc` (`SpellId`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `Cooldown`) VALUES
(74981, 0x00000004, 1, 0, 8400),
(90738, 0x00000004, 1, 0, 8400),
(90759, 0x00000004, 1, 0, 2000);
INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`) VALUES
(74976, 1|2|4|8|16|32|64, 0x00015510, 7, 1, 0),
(90737, 1|2|4|8|16|32|64, 0x00015510, 7, 1, 0);
DELETE FROM `creature_onkill_reward` WHERE `creature_id` IN (40177, 48702);
INSERT INTO `creature_onkill_reward` (`creature_id`, `CurrencyId1`, `CurrencyCount1`) VALUES
(40177, 395, 7000),
(48702, 395, 7000);
UPDATE `creature_template` SET `lootid`= 40177 WHERE `entry`= 40177;
UPDATE `creature_template` SET `lootid`= 48702 WHERE `entry`= 48702;
DELETE FROM creature_loot_template WHERE entry IN (40177, 48702);
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Chance`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES
(40177, 56119, 0, 1, 1, 1, 1),
(40177, 56118, 0, 1, 1, 1, 1),
(40177, 56120, 0, 1, 1, 1, 1),
(40177, 56121, 0, 1, 1, 1, 1),
(40177, 56122, 0, 1, 1, 1, 1);
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Chance`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES
(48702, 56448, 0, 1, 1, 1, 1),
(48702, 56447, 0, 1, 1, 1, 1),
(48702, 56445, 0, 1, 1, 1, 1),
(48702, 56449, 0, 1, 1, 1, 1),
(48702, 56446, 0, 1, 1, 1, 1);

View File

@@ -0,0 +1,767 @@
/*
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 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 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 "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "Player.h"
#include "grim_batol.h"
enum Spells
{
// Forgemaster Throngus
SPELL_MIGHTY_STOMP = 74984,
SPELL_PICK_WEAPON = 75000,
SPELL_PERSONAL_PHALANX = 74908,
SPELL_PERSONAL_PHALANX_SUMMON_FIXATE_TRIGGER = 74914,
SPELL_SHIELD_VISUAL = 94588,
SPELL_FIXATE_EFFECT = 75071,
SPELL_FLAMING_SHIELD = 90819,
SPELL_BURNING_DUAL_BLADES = 74981,
SPELL_DISORIENTING_ROAR = 74976,
SPELL_BURNING_FLAMES = 90759,
SPELL_ENCUMBERED = 75007,
SPELL_IMPALING_SLAM = 75056,
// Cave In Stalker
SPELL_CAVE_IN_VISUAL = 74987
};
enum Events
{
EVENT_MIGHTY_STOMP = 1,
EVENT_PICK_WEAPON,
EVENT_FIXATE_PLAYER,
EVENT_FIXATE_EFFECT,
EVENT_FLAMING_SHIELD,
EVENT_DISORIENTING_ROAR,
EVENT_IMPALING_SLAM
};
enum Actions
{
ACTION_PICK_WEAPON = 1,
ACTION_START_PHALLANX,
ACTION_END_PHALLANX,
};
enum Weapons
{
WEAPON_TO_BE_DECIDED = -1,
WEAPON_PERSONAL_PHALANX = 0,
WEAPON_DUAL_BLADES = 1,
WEAPON_MACE = 2
};
enum WeaponModels
{
WEAPON_MODEL_SWORD = 64435,
WEAPON_MODEL_MACE = 49737
};
enum Texts
{
SAY_AGGRO = 0,
SAY_PERSONAL_PHALANX = 1,
SAY_MACE = 2,
SAY_DUAL_BLADES = 3,
SAY_ANNOUNCE_PERSONAL_PHALANX = 4,
SAY_ANNOUNCE_MACE = 5,
SAY_ANNOUNCE_DUAL_BLADES = 6,
SAY_ANNOUNCE_IMPALE = 7,
SAY_SLAY = 8,
SAY_DEATH = 9
};
enum AuraStacks
{
STACK_AMOUNT_DISORIENTING_ROAR_HC = 3
};
enum Seats
{
SEAT_THRONGUS = 0
};
class boss_forgemaster_throngus : public CreatureScript
{
public:
boss_forgemaster_throngus() : CreatureScript("boss_forgemaster_throngus") { }
struct boss_forgemaster_throngusAI : public BossAI
{
boss_forgemaster_throngusAI(Creature* creature) : BossAI(creature, DATA_FORGEMASTER_THRONGUS)
{
Initialize();
}
void Initialize()
{
_lastWeapon = WEAPON_TO_BE_DECIDED;
}
void Reset() override
{
Initialize();
_Reset();
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
Talk(SAY_AGGRO);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
events.ScheduleEvent(EVENT_MIGHTY_STOMP, Seconds(6) + Milliseconds(500));
events.ScheduleEvent(EVENT_PICK_WEAPON, Seconds(10));
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
summons.DespawnAll();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
_EnterEvadeMode();
summons.DespawnAll();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
_DespawnAtEvade();
}
void DoAction(int32 action) override
{
switch (action)
{
case ACTION_PICK_WEAPON:
{
uint8 selectedWeapon = RAND(WEAPON_PERSONAL_PHALANX, WEAPON_MACE);
// Make sure that we will never get the same weapon twice in a row
if (_lastWeapon == selectedWeapon && selectedWeapon < WEAPON_MACE)
selectedWeapon += 1;
else if (_lastWeapon == selectedWeapon && selectedWeapon == WEAPON_MACE)
selectedWeapon = RAND(WEAPON_PERSONAL_PHALANX, WEAPON_DUAL_BLADES);
_lastWeapon = selectedWeapon;
switch (selectedWeapon)
{
case WEAPON_PERSONAL_PHALANX:
DoCastSelf(SPELL_PERSONAL_PHALANX, true);
DoCastSelf(SPELL_SHIELD_VISUAL, true);
Talk(SAY_PERSONAL_PHALANX);
Talk(SAY_ANNOUNCE_PERSONAL_PHALANX);
events.RescheduleEvent(EVENT_FIXATE_PLAYER, Seconds(1));
if (IsHeroic())
events.ScheduleEvent(EVENT_FLAMING_SHIELD, Seconds(3));
break;
case WEAPON_DUAL_BLADES:
DoCastSelf(SPELL_BURNING_DUAL_BLADES, true);
Talk(SAY_DUAL_BLADES);
Talk(SAY_ANNOUNCE_DUAL_BLADES);
events.RescheduleEvent(EVENT_DISORIENTING_ROAR, Seconds(5));
if (IsHeroic())
DoCastSelf(SPELL_BURNING_FLAMES, true);
break;
case WEAPON_MACE:
DoCastSelf(SPELL_ENCUMBERED, true);
Talk(SAY_MACE);
Talk(SAY_ANNOUNCE_MACE);
events.RescheduleEvent(EVENT_IMPALING_SLAM, Seconds(6));
break;
default:
break;
}
break;
}
case ACTION_START_PHALLANX:
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
me->AddUnitState(UNIT_STATE_CANNOT_TURN);
break;
case ACTION_END_PHALLANX:
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveAurasDueToSpell(SPELL_FLAMING_SHIELD);
me->ClearUnitState(UNIT_STATE_CANNOT_TURN);
summons.DespawnEntry(NPC_FIXATE_STALKER);
break;
default:
break;
}
}
void PassengerBoarded(Unit* passenger, int8 seatId, bool apply) override
{
if (!me->GetVehicleKit())
return;
if (apply)
Talk(SAY_ANNOUNCE_IMPALE, passenger);
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
switch (summon->GetEntry())
{
case NPC_FIXATE_STALKER:
events.ScheduleEvent(EVENT_FIXATE_EFFECT, Milliseconds(400));
break;
default:
break;
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) && !me->HasAura(SPELL_PERSONAL_PHALANX))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_MIGHTY_STOMP:
if (!me->HasAura(SPELL_PERSONAL_PHALANX))
DoCastAOE(SPELL_MIGHTY_STOMP);
events.Repeat(Seconds(49));
break;
case EVENT_PICK_WEAPON:
DoCastSelf(SPELL_PICK_WEAPON);
events.Repeat(Seconds(35) + Milliseconds(500));
break;
case EVENT_FIXATE_PLAYER:
if (me->HasAura(SPELL_PERSONAL_PHALANX))
{
summons.DespawnEntry(NPC_FIXATE_STALKER);
DoCastAOE(SPELL_PERSONAL_PHALANX_SUMMON_FIXATE_TRIGGER, true);
events.Repeat(Seconds(8) + Milliseconds(500));
}
break;
case EVENT_FIXATE_EFFECT:
if (Creature* stalker = me->FindNearestCreature(NPC_FIXATE_STALKER, 500.0f, true))
DoCast(stalker, SPELL_FIXATE_EFFECT);
break;
case EVENT_FLAMING_SHIELD:
DoCastSelf(SPELL_FLAMING_SHIELD, true);
break;
case EVENT_DISORIENTING_ROAR:
if (me->CanDualWield())
{
DoCastAOE(SPELL_DISORIENTING_ROAR);
events.Repeat(Seconds(22));
}
break;
case EVENT_IMPALING_SLAM:
if (me->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) == WEAPON_MODEL_MACE)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me, true)))
DoCast(target, SPELL_IMPALING_SLAM);
events.Repeat(Seconds(15) + Milliseconds(500));
}
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
int8 _lastWeapon;
};
CreatureAI* GetAI(Creature *creature) const override
{
return GetGrimBatolAI<boss_forgemaster_throngusAI>(creature);
}
};
// The following script is needed to prevent permanent resets due to a core bug
class npc_throngus_cave_in : public CreatureScript
{
public:
npc_throngus_cave_in() : CreatureScript("npc_throngus_cave_in") { }
struct npc_throngus_cave_inAI : public ScriptedAI
{
npc_throngus_cave_inAI(Creature* creature) : ScriptedAI(creature) { }
void IsSummonedBy(Unit* /*summoner*/) override
{
DoCastAOE(SPELL_CAVE_IN_VISUAL);
}
void UpdateAI(uint32 diff) override
{
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetGrimBatolAI<npc_throngus_cave_inAI>(creature);
}
};
class spell_throngus_mighty_stomp : public SpellScriptLoader
{
public:
spell_throngus_mighty_stomp() : SpellScriptLoader("spell_throngus_mighty_stomp") { }
class spell_throngus_mighty_stomp_SpellScript : public SpellScript
{
PrepareSpellScript(spell_throngus_mighty_stomp_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
Trinity::Containers::RandomResize(targets, 1);
}
void HandleHit(SpellEffIndex effIndex)
{
PreventHitEffect(effIndex);
if (Unit* target = GetHitUnit())
target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true);
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_throngus_mighty_stomp_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_throngus_mighty_stomp_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_throngus_mighty_stomp_SpellScript();
}
};
class spell_throngus_pick_weapon : public SpellScriptLoader
{
public:
spell_throngus_pick_weapon() : SpellScriptLoader("spell_throngus_pick_weapon") { }
class spell_throngus_pick_weapon_SpellScript : public SpellScript
{
PrepareSpellScript(spell_throngus_pick_weapon_SpellScript);
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
if (GetCaster()->GetEntry() == BOSS_FORGEMASTER_THRONGUS)
GetCaster()->ToCreature()->AI()->DoAction(ACTION_PICK_WEAPON);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_throngus_pick_weapon_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_throngus_pick_weapon_SpellScript();
}
};
class spell_throngus_flame_arrow_barrage : public SpellScriptLoader
{
public:
spell_throngus_flame_arrow_barrage() : SpellScriptLoader("spell_throngus_flame_arrow_barrage") { }
class spell_throngus_flame_arrow_barrage_SpellScript : public SpellScript
{
PrepareSpellScript(spell_throngus_flame_arrow_barrage_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
Trinity::Containers::RandomResize(targets, 5);
}
void HandleHit(SpellEffIndex effIndex)
{
PreventHitEffect(effIndex);
if (Unit* target = GetHitUnit())
target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_throngus_flame_arrow_barrage_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_throngus_flame_arrow_barrage_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_throngus_flame_arrow_barrage_SpellScript();
}
};
class spell_throngus_flaming_arrow : public SpellScriptLoader
{
public:
spell_throngus_flaming_arrow() : SpellScriptLoader("spell_throngus_flaming_arrow") { }
class spell_throngus_flaming_arrow_SpellScript : public SpellScript
{
PrepareSpellScript(spell_throngus_flaming_arrow_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
Trinity::Containers::RandomResize(targets, 1);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_throngus_flaming_arrow_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_throngus_flaming_arrow_SpellScript();
}
};
class spell_throngus_personal_phalanx : public SpellScriptLoader
{
public:
spell_throngus_personal_phalanx() : SpellScriptLoader("spell_throngus_personal_phalanx") { }
class spell_throngus_personal_phalanx_AuraScript : public AuraScript
{
PrepareAuraScript(spell_throngus_personal_phalanx_AuraScript);
bool Validate(SpellInfo const* spellInfo) override
{
return ValidateSpellInfo(
{
static_cast<uint32>(spellInfo->Effects[EFFECT_2].BasePoints),
SPELL_FLAMING_SHIELD
});
}
void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetOwner()->ToUnit())
{
caster->CastSpell(caster, aurEff->GetAmount(), true);
if (Creature* throngus = caster->ToCreature())
throngus->AI()->DoAction(ACTION_START_PHALLANX);
}
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetOwner()->ToUnit())
{
if (Creature* throngus = caster->ToCreature())
throngus->AI()->DoAction(ACTION_END_PHALLANX);
}
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_throngus_personal_phalanx_AuraScript::OnApply, EFFECT_2, SPELL_AURA_MOD_PACIFY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_throngus_personal_phalanx_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_throngus_personal_phalanx_AuraScript();
}
};
class spell_throngus_personal_phalanx_aoe : public SpellScriptLoader
{
public:
spell_throngus_personal_phalanx_aoe() : SpellScriptLoader("spell_throngus_personal_phalanx_aoe") { }
class spell_throngus_personal_phalanx_aoe_SpellScript : public SpellScript
{
PrepareSpellScript(spell_throngus_personal_phalanx_aoe_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
Trinity::Containers::RandomResize(targets, 1);
}
void HandleSummon(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
GetHitUnit()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_throngus_personal_phalanx_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_throngus_personal_phalanx_aoe_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_throngus_personal_phalanx_aoe_SpellScript();
}
};
class spell_throngus_fixate_effect : public SpellScriptLoader
{
public:
spell_throngus_fixate_effect() : SpellScriptLoader("spell_throngus_fixate_effect") { }
class spell_throngus_fixate_effect_SpellScript : public SpellScript
{
PrepareSpellScript(spell_throngus_fixate_effect_SpellScript);
void HandleHit(SpellEffIndex /*effIndex*/)
{
if (Unit* caster = GetCaster())
caster->SetOrientation(caster->GetAngle(GetHitUnit()));
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_throngus_fixate_effect_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_throngus_fixate_effect_SpellScript();
}
};
class spell_throngus_burning_dual_blades : public SpellScriptLoader
{
public:
spell_throngus_burning_dual_blades() : SpellScriptLoader("spell_throngus_burning_dual_blades") { }
class spell_throngus_burning_dual_blades_AuraScript : public AuraScript
{
PrepareAuraScript(spell_throngus_burning_dual_blades_AuraScript);
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetOwner()->ToUnit())
{
caster->SetCanDualWield(true);
caster->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, WEAPON_MODEL_SWORD);
caster->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, WEAPON_MODEL_SWORD);
}
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetOwner()->ToUnit())
{
caster->SetCanDualWield(false);
caster->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
caster->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
}
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_throngus_burning_dual_blades_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_throngus_burning_dual_blades_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_throngus_burning_dual_blades_AuraScript();
}
};
class spell_throngus_disorienting_roar : public SpellScriptLoader
{
public:
spell_throngus_disorienting_roar() : SpellScriptLoader("spell_throngus_disorienting_roar") { }
class spell_throngus_disorienting_roar_SpellScript : public SpellScript
{
PrepareSpellScript(spell_throngus_disorienting_roar_SpellScript);
void HandleHeroicDifficulty()
{
if (Unit* target = GetHitUnit())
if (target->GetMap()->IsHeroic())
if (Aura* disorientingRoar = target->GetAura(GetSpellInfo()->Id))
disorientingRoar->SetStackAmount(STACK_AMOUNT_DISORIENTING_ROAR_HC);
}
void Register() override
{
AfterHit += SpellHitFn(spell_throngus_disorienting_roar_SpellScript::HandleHeroicDifficulty);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_throngus_disorienting_roar_SpellScript();
}
class spell_throngus_disorienting_roar_AuraScript : public AuraScript
{
PrepareAuraScript(spell_throngus_disorienting_roar_AuraScript);
bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
if (Aura* aura = GetAura())
{
uint8 stack = aura->GetStackAmount();
if (stack > 1)
{
aura->SetStackAmount(stack - 1);
return false;
}
else
aura->Remove();
}
return false;
}
void Register() override
{
DoCheckProc += AuraCheckProcFn(spell_throngus_disorienting_roar_AuraScript::CheckProc);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_throngus_disorienting_roar_AuraScript();
}
};
class spell_throngus_encumbered : public SpellScriptLoader
{
public:
spell_throngus_encumbered() : SpellScriptLoader("spell_throngus_encumbered") { }
class spell_throngus_encumbered_AuraScript : public AuraScript
{
PrepareAuraScript(spell_throngus_encumbered_AuraScript);
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetOwner()->ToUnit())
caster->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, WEAPON_MODEL_MACE);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetOwner()->ToUnit())
caster->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_throngus_encumbered_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_throngus_encumbered_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_throngus_encumbered_AuraScript();
}
};
class spell_throngus_impaling_slam : public SpellScriptLoader
{
public:
spell_throngus_impaling_slam() : SpellScriptLoader("spell_throngus_impaling_slam") { }
class spell_throngus_impaling_slam_AuraScript : public AuraScript
{
PrepareAuraScript(spell_throngus_impaling_slam_AuraScript);
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
if (Unit* target = GetOwner()->ToUnit())
if (caster->GetVehicleKit())
target->EnterVehicle(caster, SEAT_THRONGUS);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* target = GetOwner()->ToUnit())
if (target->GetVehicleBase())
target->ExitVehicle();
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_throngus_impaling_slam_AuraScript::OnApply, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_throngus_impaling_slam_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_throngus_impaling_slam_AuraScript();
}
};
void AddSC_boss_forgemaster_throngus()
{
new boss_forgemaster_throngus();
new npc_throngus_cave_in();
new spell_throngus_mighty_stomp();
new spell_throngus_pick_weapon();
new spell_throngus_flame_arrow_barrage();
new spell_throngus_flaming_arrow();
new spell_throngus_personal_phalanx();
new spell_throngus_personal_phalanx_aoe();
new spell_throngus_fixate_effect();
new spell_throngus_burning_dual_blades();
new spell_throngus_disorienting_roar();
new spell_throngus_encumbered();
new spell_throngus_impaling_slam();
}

View File

@@ -44,7 +44,11 @@ enum GBCreatureIds
NPC_BLITZ_STALKER = 40040,
NPC_GROUND_SIEGE_STALKER = 40030,
NPC_MALIGNANT_TROGG = 39984,
NPC_TROGG_DWELLER = 45467
NPC_TROGG_DWELLER = 45467,
// Forgemaster Throngus Encounter
NPC_CAVE_IN_STALKER = 40228,
NPC_FIXATE_STALKER = 40255,
};
template<class AI>

View File

@@ -53,6 +53,11 @@ class instance_grim_batol : public InstanceMapScript
if (Creature* umbriss = GetCreature(DATA_GENERAL_UMBRISS))
umbriss->AI()->JustSummoned(creature);
break;
case NPC_CAVE_IN_STALKER:
case NPC_FIXATE_STALKER:
if (Creature* throngus = GetCreature(DATA_FORGEMASTER_THRONGUS))
throngus->AI()->JustSummoned(creature);
break;
default:
break;
}

View File

@@ -75,6 +75,7 @@ void AddSC_gnomeregan(); //Gnomeregan
void AddSC_instance_gnomeregan();
void AddSC_instance_grim_batol(); //Grim Batol
void AddSC_boss_general_umbriss();
void AddSC_boss_forgemaster_throngus();
void AddSC_boss_attumen(); //Karazhan
void AddSC_boss_curator();
void AddSC_boss_maiden_of_virtue();
@@ -274,6 +275,7 @@ void AddEasternKingdomsScripts()
AddSC_instance_gnomeregan();
AddSC_instance_grim_batol(); //Grim Batol
AddSC_boss_general_umbriss();
AddSC_boss_forgemaster_throngus();
AddSC_boss_attumen(); //Karazhan
AddSC_boss_curator();
AddSC_boss_maiden_of_virtue();