diff options
Diffstat (limited to 'src')
48 files changed, 0 insertions, 17693 deletions
diff --git a/src/server/scripts/Argus/AntorusTheBurningThrone/antorus_the_burning_throne.h b/src/server/scripts/Argus/AntorusTheBurningThrone/antorus_the_burning_throne.h deleted file mode 100644 index 7d4fa40ee4c..00000000000 --- a/src/server/scripts/Argus/AntorusTheBurningThrone/antorus_the_burning_throne.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -#ifndef DEF_ANTORUS_THE_BURNING_THRONE_H_ -#define DEF_ANTORUS_THE_BURNING_THRONE_H_ - -#include "CreatureAIImpl.h" - -#define DataHeader "ABT" -#define ABTScriptName "instance_antorus_the_burning_throne" - -uint32 const EncounterCount = 10; - -enum AntorusDataTypes -{ - // Encounters - DATA_GAROTHI_WORLDBREAKER = 0, - DATA_FELHOUNDS_OF_SAGERAS = 1, - DATA_ANTORAN_HIGH_COMMAND = 2, - DATA_PORTAL_KEEPER_HASABEL = 3, - DATA_EONAR_THE_LIFE_BINDER = 4, - DATA_IMONAR_THE_SOULHUNTER = 5, - DATA_KINGAROTH = 6, - DATA_VARIMATHRAS = 7, - DATA_THE_COVEN_OF_SHIVARRA = 8, - DATA_AGGRAMAR = 9, - DATA_ARGUS_THE_UNMAKER = 10, - - // Encounter related data - DATA_DECIMATOR, - DATA_ANNIHILATOR -}; - -enum AntorusCreatureIds -{ - // Bosses - BOSS_GAROTHI_WORLDBREAKER = 122450, - - // Encounter related creatures - /*Garothi Worldbreaker*/ - NPC_DECIMATOR = 122773, - NPC_ANNIHILATOR = 122778, - NPC_ANNIHILATION = 122818, - NPC_GAROTHI_WORLDBREAKER = 124167 -}; - -enum AntorusGameObjectIds -{ - GO_COLLISION = 277365, - GO_ROCK = 278488 -}; - -template <class AI, class T> -inline AI* GetAntorusTheBurningThroneAI(T* obj) -{ - return GetInstanceAI<AI>(obj, ABTScriptName); -} - -#define RegisterAntorusTheBurningThroneCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAntorusTheBurningThroneAI) - -#endif diff --git a/src/server/scripts/Argus/AntorusTheBurningThrone/boss_garothi_worldbreaker.cpp b/src/server/scripts/Argus/AntorusTheBurningThrone/boss_garothi_worldbreaker.cpp deleted file mode 100644 index 94df54aeaf5..00000000000 --- a/src/server/scripts/Argus/AntorusTheBurningThrone/boss_garothi_worldbreaker.cpp +++ /dev/null @@ -1,885 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTriggerAI.h" -#include "Containers.h" -#include "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "GridNotifiers.h" -#include "InstanceScript.h" -#include "Map.h" -#include "ObjectAccessor.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellAuras.h" -#include "SpellScript.h" -#include "SpellAuraEffects.h" -#include "antorus_the_burning_throne.h" - -enum Texts -{ - // Garothi Worldbreaker - SAY_AGGRO = 0, - SAY_DISENGAGE = 1, - SAY_ANNOUNCE_APOCALYPSE_DRIVE = 2, - SAY_APOCALYPSE_DRIVE = 3, - SAY_ANNOUNCE_ERADICATION = 4, - SAY_FINISH_APOCALYPSE_DRIVE = 5, - SAY_DECIMATION = 6, - SAY_ANNIHILATION = 7, - SAY_ANNOUNCE_FEL_BOMBARDMENT = 8, - SAY_SLAY = 9, - SAY_DEATH = 10, - - // Decimator - SAY_ANNOUNCE_DECIMATION = 0 -}; - -enum Spells -{ - // Garothi Worldbreaker - SPELL_MELEE = 248229, - SPELL_APOCALYPSE_DRIVE = 244152, - SPELL_APOCALYPSE_DRIVE_PERIODIC_DAMAGE = 253300, - SPELL_APOCALYPSE_DRIVE_FINAL_DAMAGE = 240277, - SPELL_ERADICATION = 244969, - SPELL_EMPOWERED = 245237, - SPELL_RESTORE_HEALTH = 246012, - SPELL_ANNIHILATOR_CANNON_EJECT = 245527, - SPELL_DECIMATOR_CANNON_EJECT = 245515, - SPELL_FEL_BOMBARDMENT_SELECTOR = 244150, - SPELL_FEL_BOMBARDMENT_WARNING = 246220, - SPELL_FEL_BOMBARDMENT_DUMMY = 245219, - SPELL_FEL_BOMBARDMENT_PERIODIC = 244536, - SPELL_CANNON_CHOOSER = 245124, - SPELL_SEARING_BARRAGE_ANNIHILATOR = 246368, - SPELL_SEARING_BARRAGE_DECIMATOR = 244395, - SPELL_SEARING_BARRAGE_DUMMY_ANNIHILATOR = 244398, - SPELL_SEARING_BARRAGE_DUMMY_DECIMATOR = 246369, - SPELL_SEARING_BARRAGE_SELECTOR = 246360, - SPELL_SEARING_BARRAGE_DAMAGE_ANNIHILATOR = 244400, - SPELL_SEARING_BARRAGE_DAMAGE_DECIMATOR = 246373, - SPELL_CARNAGE = 244106, - - // Decimator - SPELL_DECIMATION_SELECTOR = 244399, - SPELL_DECIMATION_WARNING = 244410, - SPELL_DECIMATION_CAST_VISUAL = 245338, - SPELL_DECIMATION_MISSILE = 244448, - - // Annihilator - SPELL_ANNIHILATION_SUMMON = 244790, - SPELL_ANNIHILATION_SELECTOR = 247572, - SPELL_ANNIHILATION_DUMMY = 244294, - SPELL_ANNIHILATION_DAMAGE_UNSPLITTED = 244762, - - // Annihilation - SPELL_ANNIHILATION_AREA_TRIGGER = 244795, - SPELL_ANNIHILATION_WARNING = 244799, - - // Garothi Worldbreaker (Surging Fel) - SPELL_SURGING_FEL_AREA_TRIGGER = 246655, - SPELL_SURGING_FEL_DAMAGE = 246663 - -}; - -enum Events -{ - // Garothi Worldbreaker - EVENT_REENGAGE_PLAYERS = 1, - EVENT_FEL_BOMBARDMENT, - EVENT_SEARING_BARRAGE, - EVENT_CANNON_CHOOSER, - EVENT_SURGING_FEL -}; - -enum Data -{ - DATA_LAST_FIRED_CANNON = 0 -}; - -enum AnimKits -{ - ANIM_KIT_ID_CANNON_DESTROYED = 13264 -}; - -constexpr uint8 MIN_TARGETS_SIZE = 2; -constexpr uint8 MAX_TARGETS_SIZE = 6; - -enum Misc -{ - SUMMON_GROUP_ID_SURGING_FEL = 0 -}; - -enum EncounterFrameIndexes -{ - ENCOUNTER_FRAME_INDEX_BOSS = 1, - ENCOUNTER_FRAME_INDEX_CANNONS = 2 -}; - -namespace TargetHandler -{ - class VictimCheck - { - public: - VictimCheck(Unit* caster, bool keepTank) : _caster(caster), _keepTank(keepTank) { } - - bool operator()(WorldObject* object) - { - Unit* unit = object->ToUnit(); - if (!unit) - return true; - - if (_caster->GetVictim() && _caster->GetVictim() != unit) - return _keepTank; - - return false; - } - private: - Unit* _caster; - bool _keepTank; // true = remove all nontank targets | false = remove current tank - }; - - void PreferNonTankTargetsAndResizeTargets(std::list<WorldObject*>& targets, Unit* caster) - { - if (targets.empty()) - return; - - std::list<WorldObject*> targetsCopy = targets; - uint8 size = targetsCopy.size(); - // Selecting our prefered target size based on total targets (min 10 player: 2, max 30 player: 6) - uint8 preferedSize = std::min<uint8>(std::max<uint8>(std::ceil(size / 5), MIN_TARGETS_SIZE), MAX_TARGETS_SIZE); - - // Now we get rid of the tank as these abilities prefer non-tanks above tanks as long as there are alternatives - targetsCopy.remove_if(TargetHandler::VictimCheck(caster, false)); - - // We have less available nontank targets than we want, include tanks - if (targetsCopy.size() < preferedSize) - Trinity::Containers::RandomResize(targets, preferedSize); - else - { - // Our target list has enough alternative targets, resize - Trinity::Containers::RandomResize(targetsCopy, preferedSize); - targets = targetsCopy; - } - } -} - -static constexpr uint32 const MaxApocalypseDriveCount = 2; -Position const AnnihilationCenterReferencePos = { -3296.72f, 9767.78f, -60.0f }; - -struct boss_garothi_worldbreaker : public BossAI -{ - boss_garothi_worldbreaker(Creature* creature) : BossAI(creature, DATA_GAROTHI_WORLDBREAKER), - _apocalypseDriveCount(0), _searingBarrageSpellId(0), _lastCanonEntry(NPC_DECIMATOR), _castEradication(false) - { - _apocalypseDriveHealthLimit = { }; - SetCombatMovement(false); - me->SetReactState(REACT_PASSIVE); - } - - void InitializeAI() override - { - switch (GetDifficulty()) - { - case DIFFICULTY_MYTHIC_RAID: - case DIFFICULTY_HEROIC_RAID: - _apocalypseDriveHealthLimit[0] = 65; - _apocalypseDriveHealthLimit[1] = 35; - break; - case DIFFICULTY_NORMAL_RAID: - case DIFFICULTY_LFR_NEW: - _apocalypseDriveHealthLimit[0] = 60; - _apocalypseDriveHealthLimit[1] = 20; - break; - default: - break; - } - } - - void JustAppeared() override - { - me->SummonCreatureGroup(SUMMON_GROUP_ID_SURGING_FEL); - } - - void JustEngagedWith(Unit* who) override - { - me->SetReactState(REACT_AGGRESSIVE); - BossAI::JustEngagedWith(who); - Talk(SAY_AGGRO); - DoCastSelf(SPELL_MELEE); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, ENCOUNTER_FRAME_INDEX_BOSS); - events.ScheduleEvent(EVENT_FEL_BOMBARDMENT, 9s); - events.ScheduleEvent(EVENT_CANNON_CHOOSER, 8s); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - Talk(SAY_DISENGAGE); - _EnterEvadeMode(); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - events.Reset(); - CleanupEncounter(); - _DespawnAtEvade(); - } - - void KilledUnit(Unit* victim) override - { - if (victim->IsPlayer()) - Talk(SAY_SLAY, victim); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - CleanupEncounter(); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - } - - void OnSpellCast(SpellInfo const* spell) override - { - switch (spell->Id) - { - case SPELL_APOCALYPSE_DRIVE_FINAL_DAMAGE: - if (_apocalypseDriveCount < MaxApocalypseDriveCount) - events.Reset(); - events.ScheduleEvent(EVENT_REENGAGE_PLAYERS, 3s + 500ms); - HideCannons(); - me->SetUninteractible(false); - break; - default: - break; - } - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (damage >= me->GetHealth()) - return; - - if (me->HealthBelowPctDamaged(_apocalypseDriveHealthLimit[_apocalypseDriveCount], damage)) - { - me->AttackStop(); - me->SetReactState(REACT_PASSIVE); - me->InterruptNonMeleeSpells(true); - me->SetFacingTo(me->GetHomePosition().GetOrientation()); - events.Reset(); - - if (IsHeroic() || IsMythic()) - events.ScheduleEvent(EVENT_SURGING_FEL, 8s); - - DoCastSelf(SPELL_APOCALYPSE_DRIVE); - DoCastSelf(SPELL_APOCALYPSE_DRIVE_FINAL_DAMAGE); - Talk(SAY_ANNOUNCE_APOCALYPSE_DRIVE); - Talk(SAY_APOCALYPSE_DRIVE); - me->SetUninteractible(true); - - if (Creature* decimator = instance->GetCreature(DATA_DECIMATOR)) - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, decimator, ENCOUNTER_FRAME_INDEX_CANNONS); - decimator->SetUnitFlag(UNIT_FLAG_IN_COMBAT); - decimator->SetUninteractible(false); - } - - if (Creature* annihilator = instance->GetCreature(DATA_ANNIHILATOR)) - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, annihilator, ENCOUNTER_FRAME_INDEX_CANNONS); - annihilator->SetUnitFlag(UNIT_FLAG_IN_COMBAT); - annihilator->SetUninteractible(false); - } - ++_apocalypseDriveCount; - } - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - switch (summon->GetEntry()) - { - case NPC_ANNIHILATION: - summon->CastSpell(summon, SPELL_ANNIHILATION_WARNING); - summon->CastSpell(summon, SPELL_ANNIHILATION_AREA_TRIGGER); - break; - case NPC_ANNIHILATOR: - case NPC_DECIMATOR: - summon->SetReactState(REACT_PASSIVE); - break; - case NPC_GAROTHI_WORLDBREAKER: - _surgingFelDummyGuids.insert(summon->GetGUID()); - break; - default: - break; - } - } - - void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override - { - switch (summon->GetEntry()) - { - case NPC_DECIMATOR: - case NPC_ANNIHILATOR: - me->InterruptNonMeleeSpells(true); - me->RemoveAurasDueToSpell(SPELL_APOCALYPSE_DRIVE); - me->SetUninteractible(false); - - if (summon->GetEntry() == NPC_ANNIHILATOR) - _searingBarrageSpellId = SPELL_SEARING_BARRAGE_ANNIHILATOR; - else - _searingBarrageSpellId = SPELL_SEARING_BARRAGE_DECIMATOR; - - if (_apocalypseDriveCount < MaxApocalypseDriveCount) - events.Reset(); - - events.ScheduleEvent(EVENT_SEARING_BARRAGE, 3s + 500ms); - events.ScheduleEvent(EVENT_REENGAGE_PLAYERS, 3s + 500ms); - _castEradication = true; - - if (summon->GetEntry() == NPC_DECIMATOR) - DoCastSelf(SPELL_DECIMATOR_CANNON_EJECT); - else - DoCastSelf(SPELL_ANNIHILATOR_CANNON_EJECT); - - me->PlayOneShotAnimKitId(ANIM_KIT_ID_CANNON_DESTROYED); - HideCannons(); - break; - default: - break; - } - } - - uint32 GetData(uint32 type) const override - { - if (type == DATA_LAST_FIRED_CANNON) - return _lastCanonEntry; - - return 0; - } - - void SetData(uint32 type, uint32 value) override - { - if (type == DATA_LAST_FIRED_CANNON) - _lastCanonEntry = value; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING) && !me->HasAura(SPELL_APOCALYPSE_DRIVE)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_REENGAGE_PLAYERS: - DoCastSelf(SPELL_EMPOWERED); - DoCastSelf(SPELL_RESTORE_HEALTH); - if (_castEradication) - { - DoCastSelf(SPELL_ERADICATION); - Talk(SAY_ANNOUNCE_ERADICATION); - Talk(SAY_FINISH_APOCALYPSE_DRIVE); - _castEradication = false; - } - me->SetReactState(REACT_AGGRESSIVE); - events.ScheduleEvent(EVENT_FEL_BOMBARDMENT, 20s); - events.ScheduleEvent(EVENT_CANNON_CHOOSER, 18s); - break; - case EVENT_FEL_BOMBARDMENT: - DoCastAOE(SPELL_FEL_BOMBARDMENT_SELECTOR); - events.Repeat(20s); - break; - case EVENT_SEARING_BARRAGE: - DoCastSelf(_searingBarrageSpellId); - break; - case EVENT_CANNON_CHOOSER: - DoCastSelf(SPELL_CANNON_CHOOSER); - events.Repeat(16s); - break; - case EVENT_SURGING_FEL: - { - GuidSet guids = _surgingFelDummyGuids; - guids.erase(_lastSurgingFelDummyGuid); - _lastSurgingFelDummyGuid = Trinity::Containers::SelectRandomContainerElement(guids); - if (Creature* dummy = ObjectAccessor::GetCreature(*me, _lastSurgingFelDummyGuid)) - dummy->CastSpell(dummy, SPELL_SURGING_FEL_AREA_TRIGGER); - - events.Repeat(8s); - break; - } - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - if (me->GetVictim() && me->GetVictim()->IsWithinMeleeRange(me)) - DoMeleeAttackIfReady(); - else - DoSpellAttackIfReady(SPELL_CARNAGE); - } - private: - std::array<uint8, MaxApocalypseDriveCount> _apocalypseDriveHealthLimit; - uint8 _apocalypseDriveCount; - uint32 _searingBarrageSpellId; - uint32 _lastCanonEntry; - bool _castEradication; - ObjectGuid _lastSurgingFelDummyGuid; - GuidSet _surgingFelDummyGuids; - - void CleanupEncounter() - { - if (Creature* decimator = instance->GetCreature(DATA_DECIMATOR)) - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, decimator); - - if (Creature* annihilator = instance->GetCreature(DATA_ANNIHILATOR)) - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, annihilator); - - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DECIMATION_WARNING); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FEL_BOMBARDMENT_WARNING); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FEL_BOMBARDMENT_PERIODIC); - summons.DespawnAll(); - } - - void HideCannons() - { - if (Creature* decimator = instance->GetCreature(DATA_DECIMATOR)) - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, decimator); - decimator->SetUninteractible(true); - decimator->SetUnitFlag(UNIT_FLAG_IMMUNE); - } - - if (Creature* annihilator = instance->GetCreature(DATA_ANNIHILATOR)) - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, annihilator); - annihilator->SetUninteractible(true); - annihilator->SetUnitFlag(UNIT_FLAG_IMMUNE); - } - } -}; - -struct at_garothi_annihilation : AreaTriggerAI -{ - at_garothi_annihilation(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) - { - Initialize(); - } - - void Initialize() - { - _playerCount = 0; - } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - _playerCount++; - - if (Unit* annihilation = at->GetCaster()) - annihilation->RemoveAurasDueToSpell(SPELL_ANNIHILATION_WARNING); - } - - void OnUnitExit(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - _playerCount--; - - if (!_playerCount && !at->IsRemoved()) - if (Unit* annihilation = at->GetCaster()) - annihilation->CastSpell(annihilation, SPELL_ANNIHILATION_WARNING); - } - -private: - uint8 _playerCount; -}; - -class spell_garothi_apocalypse_drive : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_APOCALYPSE_DRIVE_PERIODIC_DAMAGE }); - } - - void HandlePeriodic(AuraEffect const* aurEff) - { - GetTarget()->CastSpell(GetTarget(), SPELL_APOCALYPSE_DRIVE_PERIODIC_DAMAGE, aurEff); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_garothi_apocalypse_drive::HandlePeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -class spell_garothi_fel_bombardment_selector : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_FEL_BOMBARDMENT_WARNING, - SPELL_FEL_BOMBARDMENT_DUMMY - }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - if (targets.empty()) - return; - - if (Unit* caster = GetCaster()) - targets.remove_if(TargetHandler::VictimCheck(caster, true)); - } - - void HandleWarningEffect(SpellEffIndex /*effIndex*/) - { - Creature* caster = GetCaster() ? GetCaster()->ToCreature() : nullptr; - if (!caster || !caster->IsAIEnabled()) - return; - - Unit* target = GetHitUnit(); - caster->AI()->Talk(SAY_ANNOUNCE_FEL_BOMBARDMENT, target); - caster->CastSpell(target, SPELL_FEL_BOMBARDMENT_WARNING, true); - caster->CastSpell(target, SPELL_FEL_BOMBARDMENT_DUMMY, true); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_garothi_fel_bombardment_selector::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_garothi_fel_bombardment_selector::HandleWarningEffect, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -class spell_garothi_fel_bombardment_warning : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_FEL_BOMBARDMENT_PERIODIC }); - } - - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget(), SPELL_FEL_BOMBARDMENT_PERIODIC, true); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_garothi_fel_bombardment_warning::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -class spell_garothi_fel_bombardment_periodic : public AuraScript -{ - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) }); - } - - void HandlePeriodic(AuraEffect const* aurEff) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget(), uint32(aurEff->GetSpellEffectInfo().CalcValue(caster)), true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_garothi_fel_bombardment_periodic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } -}; - -class spell_garothi_searing_barrage_dummy : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SEARING_BARRAGE_SELECTOR }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SEARING_BARRAGE_SELECTOR, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_BASE_POINT0, GetSpellInfo()->Id)); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_garothi_searing_barrage_dummy::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -class spell_garothi_searing_barrage_selector : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SEARING_BARRAGE_DAMAGE_ANNIHILATOR, - SPELL_SEARING_BARRAGE_DAMAGE_DECIMATOR, - SPELL_SEARING_BARRAGE_DUMMY_ANNIHILATOR, - SPELL_SEARING_BARRAGE_DUMMY_DECIMATOR - }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - TargetHandler::PreferNonTankTargetsAndResizeTargets(targets, GetCaster()); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - uint32 spellId = GetEffectValue() == SPELL_SEARING_BARRAGE_DUMMY_ANNIHILATOR ? SPELL_SEARING_BARRAGE_DAMAGE_ANNIHILATOR : SPELL_SEARING_BARRAGE_DAMAGE_DECIMATOR; - if (Unit* caster = GetCaster()) - caster->CastSpell(GetHitUnit(), spellId, true); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_garothi_searing_barrage_selector::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - OnEffectHitTarget += SpellEffectFn(spell_garothi_searing_barrage_selector::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -class spell_garothi_decimation_selector : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DECIMATION_WARNING }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - TargetHandler::PreferNonTankTargetsAndResizeTargets(targets, GetCaster()); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - if (Unit* caster = GetCaster()) - { - caster->CastSpell(GetHitUnit(), SPELL_DECIMATION_WARNING, true); - if (Creature* decimator = caster->ToCreature()) - if (decimator->IsAIEnabled()) - decimator->AI()->Talk(SAY_ANNOUNCE_DECIMATION, GetHitUnit()); - } - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_garothi_decimation_selector::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_garothi_decimation_selector::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -class spell_garothi_decimation_warning : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DECIMATION_MISSILE }); - } - - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - { - if (Unit* caster = GetCaster()) - { - caster->CastSpell(GetTarget(), SPELL_DECIMATION_MISSILE, true); - if (!caster->HasUnitState(UNIT_STATE_CASTING)) - caster->CastSpell(caster, SPELL_DECIMATION_CAST_VISUAL); - } - } - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_garothi_decimation_warning::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -class spell_garothi_carnage : public AuraScript -{ - void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& /*eventInfo`*/) - { - // Usually we could just handle this via spell_proc but since we want - // to silence the console message because it's not a spell trigger proc, we need a script here. - PreventDefaultAction(); - Remove(); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_garothi_carnage::HandleProc, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } -}; - -class spell_garothi_annihilation_selector : public SpellScript -{ - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(GetHitUnit(), uint32(GetEffectInfo().CalcValue(caster)), true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_garothi_annihilation_selector::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -class spell_garothi_annihilation_triggered : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ANNIHILATION_DAMAGE_UNSPLITTED }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - if (target->HasAura(SPELL_ANNIHILATION_WARNING)) - target->CastSpell(target, SPELL_ANNIHILATION_DAMAGE_UNSPLITTED, true); - - target->RemoveAllAuras(); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_garothi_annihilation_triggered::HandleHit, EFFECT_1, SPELL_EFFECT_DUMMY); - } -}; - -class spell_garothi_eradication : public SpellScript -{ - void ChangeDamage() - { - if (Unit* caster = GetCaster()) - { - uint32 damageReduction = CalculatePct(GetHitDamage(), GetHitUnit()->GetDistance(caster)); - SetHitDamage(GetHitDamage() - damageReduction); - } - } - - void Register() override - { - OnHit += SpellHitFn(spell_garothi_eradication::ChangeDamage); - } -}; - -class spell_garothi_surging_fel : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SURGING_FEL_DAMAGE }); - } - - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - GetTarget()->CastSpell(GetTarget(), SPELL_SURGING_FEL_DAMAGE, true); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_garothi_surging_fel::AfterRemove, EFFECT_0, SPELL_AURA_AREA_TRIGGER, AURA_EFFECT_HANDLE_REAL); - } -}; - -class spell_garothi_cannon_chooser : public SpellScript -{ - void HandleDummyEffect(SpellEffIndex /*effIndex*/) - { - Creature* caster = GetHitCreature(); - if (!caster || !caster->IsAIEnabled()) - return; - - InstanceScript* instance = caster->GetInstanceScript(); - if (!instance) - return; - - Creature* decimator = instance->GetCreature(DATA_DECIMATOR); - Creature* annihilator = instance->GetCreature(DATA_ANNIHILATOR); - uint32 lastCannonEntry = caster->AI()->GetData(DATA_LAST_FIRED_CANNON); - - if ((lastCannonEntry == NPC_ANNIHILATOR && decimator) || (decimator && !annihilator)) - { - decimator->CastSpell(decimator, SPELL_DECIMATION_SELECTOR, true); - caster->AI()->Talk(SAY_DECIMATION, decimator); - lastCannonEntry = NPC_DECIMATOR; - } - else if ((lastCannonEntry == NPC_DECIMATOR && annihilator) || (annihilator && !decimator)) - { - uint8 count = caster->GetMap()->IsMythic() ? MAX_TARGETS_SIZE : - std::max<uint8>(MIN_TARGETS_SIZE, std::ceil(float(caster->GetMap()->GetPlayersCountExceptGMs()) / 5)); - - for (uint8 i = 0; i < count; i++) - { - float x = AnnihilationCenterReferencePos.GetPositionX() + cos(frand(0.0f, float(M_PI * 2))) * frand(15.0f, 30.0f); - float y = AnnihilationCenterReferencePos.GetPositionY() + sin(frand(0.0f, float(M_PI * 2))) * frand(15.0f, 30.0f); - float z = caster->GetMap()->GetHeight(caster->GetPhaseShift(), x, y, AnnihilationCenterReferencePos.GetPositionZ()); - annihilator->CastSpell(Position{ x, y, z }, SPELL_ANNIHILATION_SUMMON, true); - } - - annihilator->CastSpell(annihilator, SPELL_ANNIHILATION_DUMMY); - annihilator->CastSpell(annihilator, SPELL_ANNIHILATION_SELECTOR); - caster->AI()->Talk(SAY_ANNIHILATION); - lastCannonEntry = NPC_ANNIHILATOR; - } - - caster->AI()->SetData(DATA_LAST_FIRED_CANNON, lastCannonEntry); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_garothi_cannon_chooser::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -void AddSC_boss_garothi_worldbreaker() -{ - RegisterAntorusTheBurningThroneCreatureAI(boss_garothi_worldbreaker); - RegisterAreaTriggerAI(at_garothi_annihilation); - RegisterSpellScript(spell_garothi_apocalypse_drive); - RegisterSpellScript(spell_garothi_fel_bombardment_selector); - RegisterSpellScript(spell_garothi_fel_bombardment_warning); - RegisterSpellScript(spell_garothi_fel_bombardment_periodic); - RegisterSpellScript(spell_garothi_searing_barrage_dummy); - RegisterSpellScript(spell_garothi_searing_barrage_selector); - RegisterSpellScript(spell_garothi_decimation_selector); - RegisterSpellScript(spell_garothi_decimation_warning); - RegisterSpellScript(spell_garothi_carnage); - RegisterSpellScript(spell_garothi_annihilation_selector); - RegisterSpellScript(spell_garothi_annihilation_triggered); - RegisterSpellScript(spell_garothi_eradication); - RegisterSpellScript(spell_garothi_surging_fel); - RegisterSpellScript(spell_garothi_cannon_chooser); -} diff --git a/src/server/scripts/Argus/AntorusTheBurningThrone/instance_antorus_the_burning_throne.cpp b/src/server/scripts/Argus/AntorusTheBurningThrone/instance_antorus_the_burning_throne.cpp deleted file mode 100644 index d9a3d5aba50..00000000000 --- a/src/server/scripts/Argus/AntorusTheBurningThrone/instance_antorus_the_burning_throne.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "ScriptMgr.h" -#include "antorus_the_burning_throne.h" -#include "Creature.h" -#include "CreatureAI.h" -#include "InstanceScript.h" -#include "Map.h" - -ObjectData const creatureData[] = -{ - { BOSS_GAROTHI_WORLDBREAKER, DATA_GAROTHI_WORLDBREAKER }, - { NPC_DECIMATOR, DATA_DECIMATOR }, - { NPC_ANNIHILATOR, DATA_ANNIHILATOR }, - { 0, 0 } // END -}; - -DoorData const doorData[] = -{ - { GO_COLLISION, DATA_GAROTHI_WORLDBREAKER, EncounterDoorBehavior::OpenWhenDone }, - { GO_ROCK, DATA_GAROTHI_WORLDBREAKER, EncounterDoorBehavior::OpenWhenDone }, - { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } // END -}; - -DungeonEncounterData const encounters[] = -{ - { DATA_GAROTHI_WORLDBREAKER, {{ 2076 }} }, - { DATA_FELHOUNDS_OF_SAGERAS, {{ 2074 }} }, - { DATA_ANTORAN_HIGH_COMMAND, {{ 2070 }} }, - { DATA_PORTAL_KEEPER_HASABEL, {{ 2064 }} }, - { DATA_EONAR_THE_LIFE_BINDER, {{ 2075 }} }, - { DATA_IMONAR_THE_SOULHUNTER, {{ 2082 }} }, - { DATA_KINGAROTH, {{ 2088 }} }, - { DATA_VARIMATHRAS, {{ 2069 }} }, - { DATA_THE_COVEN_OF_SHIVARRA, {{ 2073 }} }, - { DATA_AGGRAMAR, {{ 2063 }} }, - { DATA_ARGUS_THE_UNMAKER, {{ 2092 }} } -}; - -class instance_antorus_the_burning_throne : public InstanceMapScript -{ - public: - instance_antorus_the_burning_throne() : InstanceMapScript(ABTScriptName, 1712) { } - - struct instance_antorus_the_burning_throne_InstanceMapScript: public InstanceScript - { - instance_antorus_the_burning_throne_InstanceMapScript(InstanceMap* map) : InstanceScript(map) - { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - LoadObjectData(creatureData, nullptr); - LoadDoorData(doorData); - LoadDungeonEncounterData(encounters); - } - - void OnCreatureCreate(Creature* creature) override - { - InstanceScript::OnCreatureCreate(creature); - - switch (creature->GetEntry()) - { - case NPC_ANNIHILATION: - if (Creature* garothi = GetCreature(DATA_GAROTHI_WORLDBREAKER)) - garothi->AI()->JustSummoned(creature); - break; - default: - break; - } - } - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_antorus_the_burning_throne_InstanceMapScript(map); - } -}; - -void AddSC_instance_antorus_the_burning_throne() -{ - new instance_antorus_the_burning_throne(); -} diff --git a/src/server/scripts/Argus/argus_script_loader.cpp b/src/server/scripts/Argus/argus_script_loader.cpp deleted file mode 100644 index 54690dd55d0..00000000000 --- a/src/server/scripts/Argus/argus_script_loader.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -// This is where scripts' loading functions should be declared: -void AddSC_boss_garothi_worldbreaker(); -void AddSC_instance_antorus_the_burning_throne(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddArgusScripts() -{ - AddSC_boss_garothi_worldbreaker(); // Antorus the Burning Throne - AddSC_instance_antorus_the_burning_throne(); -} diff --git a/src/server/scripts/BrokenIsles/TrialOfValor/boss_guarm.cpp b/src/server/scripts/BrokenIsles/TrialOfValor/boss_guarm.cpp deleted file mode 100644 index 37129529759..00000000000 --- a/src/server/scripts/BrokenIsles/TrialOfValor/boss_guarm.cpp +++ /dev/null @@ -1,823 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTrigger.h" -#include "AreaTriggerAI.h" -#include "Containers.h" -#include "Conversation.h" -#include "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "InstanceScript.h" -#include "Map.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "Player.h" -#include "ScriptedCreature.h" -#include "ScriptMgr.h" -#include "SharedDefines.h" -#include "SpellAuras.h" -#include "SpellHistory.h" -#include "SpellScript.h" -#include "TemporarySummon.h" -#include "trial_of_valor.h" - -enum GuarmSpells -{ - SPELL_HELYATOSIS_AURA = 231561, - SPELL_HELYATOSIS_INITIAL_ENERGIZE = 235130, - SPELL_MULTI_HEADED_AURA = 227512, - SPELL_MULTI_HEADED_DAMAGE = 227642, - SPELL_FLASHING_FANGS = 227514, - SPELL_OFF_THE_LEASH = 228201, - - SPELL_FLAME_LICK_SELECTOR = 228226, // triggers 228227 missile - SPELL_SHADOW_LICK_SELECTOR = 228250, // triggers 228251 missile - SPELL_FROST_LICK_SELECTOR = 228246, // triggers 228247 missile - - SPELL_BERSERK = 26662, - SPELL_BERSERK_TRAMPLE_AOE = 232224, - SPELL_BERSERK_CHARGE_AT = 232173, // triggers 232197 - - SPELL_GUARDIANS_BREATH_COLOR_SELECTOR = 228187, - SPELL_GUARDIANS_BREATH_SUMMON_ATS_RGB = 232811, // Red Green Blue - SPELL_GUARDIANS_BREATH_SUMMON_ATS_RBG = 232810, // Red Blue Green - SPELL_GUARDIANS_BREATH_SUMMON_ATS_GRB = 232775, // Green Red Blue - SPELL_GUARDIANS_BREATH_SUMMON_ATS_GBR = 232808, // Green Blue Red - SPELL_GUARDIANS_BREATH_SUMMON_ATS_BRG = 232809, // Blue Red Green - SPELL_GUARDIANS_BREATH_SUMMON_ATS_BGR = 232807, // Blue Green Red - SPELL_GUARDIANS_BREATH_UNK = 227573, - SPELL_GUARDIANS_BREATH_CAST_RGB = 227673, // Red Green Blue - SPELL_GUARDIANS_BREATH_CAST_RBG = 227667, // Red Blue Green - SPELL_GUARDIANS_BREATH_CAST_GRB = 227669, // Green Red Blue - SPELL_GUARDIANS_BREATH_CAST_GBR = 227660, // Green Blue Red - SPELL_GUARDIANS_BREATH_CAST_BRG = 227666, // Blue Red Green - SPELL_GUARDIANS_BREATH_CAST_BGR = 227658, // Blue Green Red - SPELL_FIERY_PHLEGM = 232777, // Red - SPELL_FIERY_PHLEGM_AURA = 228758, - SPELL_SALTY_SPITTLE = 232798, // Green - SPELL_SALTY_SPITTLE_AURA = 228768, - SPELL_DARK_DISCHARGE = 232800, // Blue - SPELL_DARK_DISCHARGE_AURA = 228769, - SPELL_FROTHING_RAGE = 228174, // applied x times where x players not getting hit by breath - - SPELL_ROARING_LEAP_SELECTOR = 227894, // @TODO: requires TARGET_DEST_CASTER_CLUMP_CENTROID - SPELL_ROARING_LEAP_INITIAL_KNOCKBACK = 227883, - SPELL_ROARING_LEAP_JUMP = 229350, // triggers 227902 - SPELL_HEADLONG_CHARGE_INITIAL = 227816, - SPELL_HEADLONG_CHARGE_PERIODIC_DAMAGE = 229480, - SPELL_HEADLONG_CHARGE_DAMAGE = 228344, - SPELL_HEADLONG_CHARGE_AT = 227833, // triggers 227843 - - // Mythic - SPELL_VOLATILE_FOAM_INITIAL = 228824, - SPELL_VOLATILE_FOAM_SELECTOR_RED = 228684, - SPELL_VOLATILE_FOAM_SELECTOR_GREEN = 228809, - SPELL_VOLATILE_FOAM_SELECTOR_BLUE = 228817, -}; - -enum GuarmEvents -{ - EVENT_FLASHING_FANGS = 1, - EVENT_CHECK_ENERGY, - EVENT_LICK, - EVENT_ROARING_LEAP, - EVENT_HEADLONG_CHARGE, - EVENT_OFF_THE_LEASH, - EVENT_VOLATILE_FOAM, - EVENT_BERSERK, -}; - -enum GuarmTalks -{ - TALK_GUARDIANS_BREATH_ANNOUNCE = 0, // |TInterface\Icons\SPELL_FIRE_TWILIGHTFLAMEBREATH.BLP:20|t%s begins to cast |cFFFF0000|Hspell:227573|h[Guardian's Breath]|h|r! - TALK_BERSERK = 1, // %s goes into a berserker rage! -}; - -enum GuarmPoints -{ - POINT_BERSERK_JUMP = 0, - - POINT_HEADLONG_CHARGE = 50, - POINT_HEADLONG_CHARGE_MAX = 53, -}; - -enum GuarmPaths -{ - PATH_HEADLONG_CHARGE1 = (114323 * 100) + 0, - PATH_HEADLONG_CHARGE2 = (114323 * 100) + 1, - PATH_HEADLONG_CHARGE3 = (114323 * 100) + 2, - PATH_HEADLONG_CHARGE4 = (114323 * 100) + 3, - PATH_BERSERK = (114323 * 100) + 4, -}; - -enum GuarmSpellCategories -{ - SPELL_CATEGORY_GUARM = 1152, -}; - -enum GuarmConversations -{ - CONVERSATION_DEATH = 3917 -}; - -enum GuarmActions -{ - ACTION_BREATH_HIT_TARGET = 0, - ACTION_HANDLE_FROTHING_RAGE, -}; - -struct JumpMovePathPair -{ - Position JumpPos; - uint32 PathID; -}; - -JumpMovePathPair const HeadlongChargePairs[] = -{ - { { 478.535f, 446.623f, 4.88632f }, PATH_HEADLONG_CHARGE1 }, - { { 460.708f, 445.918f, 4.91909f }, PATH_HEADLONG_CHARGE2 }, - { { 454.967f, 543.651f, 2.99177f }, PATH_HEADLONG_CHARGE3 }, - { { 475.189f, 543.391f, 3.25487f }, PATH_HEADLONG_CHARGE4 }, -}; - -struct GuardiansBreathSpellPair -{ - uint32 SummonATSpellID; - uint32 CastSpellID; -}; - -GuardiansBreathSpellPair const GuardiansBreathSpellPairs[] = -{ - { SPELL_GUARDIANS_BREATH_SUMMON_ATS_RGB, SPELL_GUARDIANS_BREATH_CAST_RGB }, - { SPELL_GUARDIANS_BREATH_SUMMON_ATS_RBG, SPELL_GUARDIANS_BREATH_CAST_RBG }, - { SPELL_GUARDIANS_BREATH_SUMMON_ATS_GRB, SPELL_GUARDIANS_BREATH_CAST_GRB }, - { SPELL_GUARDIANS_BREATH_SUMMON_ATS_GBR, SPELL_GUARDIANS_BREATH_CAST_GBR }, - { SPELL_GUARDIANS_BREATH_SUMMON_ATS_BRG, SPELL_GUARDIANS_BREATH_CAST_BRG }, - { SPELL_GUARDIANS_BREATH_SUMMON_ATS_BGR, SPELL_GUARDIANS_BREATH_CAST_BGR } -}; - -JumpMovePathPair const BerserkerPair = { { 464.035f, 549.979f, 2.95187f }, PATH_BERSERK }; - -// 114323 - Guarm -struct boss_guarm : public BossAI -{ - boss_guarm(Creature* creature) : BossAI(creature, DATA_GUARM), _lickCount(0), _unitsHitByBreathCount(0) { } - - void JustAppeared() override - { - DoCastAOE(SPELL_MULTI_HEADED_AURA); - me->SetMaxPower(POWER_ENERGY, 100); // power is set to 0 in Creature::UpdateMaxPower - } - - void JustDied(Unit* /*killer*/) override - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - - Conversation::CreateConversation(CONVERSATION_DEATH, me, me->GetPosition(), ObjectGuid::Empty); - - _JustDied(); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - - summons.DespawnAll(); - _EnterEvadeMode(); - _DespawnAtEvade(); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); - - DoCastAOE(SPELL_HELYATOSIS_AURA); - DoCastAOE(SPELL_HELYATOSIS_INITIAL_ENERGIZE); - - events.ScheduleEvent(EVENT_FLASHING_FANGS, 6s); - events.ScheduleEvent(EVENT_LICK, 12s); - events.ScheduleEvent(EVENT_CHECK_ENERGY, 500ms); - events.ScheduleEvent(EVENT_OFF_THE_LEASH, 45s); - - if (IsMythic()) - { - events.ScheduleEvent(EVENT_VOLATILE_FOAM, 11s); - events.ScheduleEvent(EVENT_BERSERK, 4min + 4s); - } - else if (IsHeroic()) - events.ScheduleEvent(EVENT_BERSERK, 5min); - else if (GetDifficulty() == DIFFICULTY_NORMAL_RAID) - events.ScheduleEvent(EVENT_BERSERK, 6min); - else // LFR - events.ScheduleEvent(EVENT_BERSERK, 7min); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_FLASHING_FANGS: - DoCastVictim(SPELL_FLASHING_FANGS); - events.ScheduleEvent(EVENT_FLASHING_FANGS, 21s + 500ms); - break; - case EVENT_LICK: - _lickCount++; - DoCastAOE(RAND(SPELL_FLAME_LICK_SELECTOR, SPELL_SHADOW_LICK_SELECTOR, SPELL_FROST_LICK_SELECTOR)); - events.ScheduleEvent(EVENT_LICK, (_lickCount % 2) ? 4s : 10s); - break; - case EVENT_CHECK_ENERGY: - { - events.ScheduleEvent(EVENT_CHECK_ENERGY, 500ms); - if (me->GetPower(POWER_ENERGY) < 100) - break; - - _unitsHitByBreathCount = 0; - if (DoCastVictim(SPELL_GUARDIANS_BREATH_COLOR_SELECTOR) == SPELL_CAST_OK) - Talk(TALK_GUARDIANS_BREATH_ANNOUNCE); - - break; - } - case EVENT_ROARING_LEAP: - DoCastAOE(SPELL_ROARING_LEAP_SELECTOR); - break; - case EVENT_HEADLONG_CHARGE: - DoCastAOE(SPELL_HEADLONG_CHARGE_INITIAL); - break; - case EVENT_OFF_THE_LEASH: - DoCastAOE(SPELL_OFF_THE_LEASH); - events.ScheduleEvent(EVENT_OFF_THE_LEASH, 75s); - events.ScheduleEvent(EVENT_ROARING_LEAP, 3s); - events.ScheduleEvent(EVENT_HEADLONG_CHARGE, 13s); - events.CancelEvent(EVENT_FLASHING_FANGS); - events.CancelEvent(EVENT_LICK); - events.CancelEvent(EVENT_VOLATILE_FOAM); - break; - case EVENT_VOLATILE_FOAM: - DoCastAOE(SPELL_VOLATILE_FOAM_INITIAL); - events.ScheduleEvent(EVENT_VOLATILE_FOAM, 22s); - break; - case EVENT_BERSERK: - DoCastAOE(SPELL_BERSERK); - Talk(TALK_BERSERK, me); - events.CancelEvent(EVENT_FLASHING_FANGS); - events.CancelEvent(EVENT_LICK); - me->GetMotionMaster()->Clear(); // remove ChaseMovementGen - me->SetReactState(REACT_PASSIVE); - me->GetMotionMaster()->MoveJump(BerserkerPair.JumpPos, 42.0f, 21.5f, POINT_BERSERK_JUMP); - break; - default: - break; - } - - DoMeleeAttackIfReady(); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - me->SetReactState(REACT_AGGRESSIVE); - events.ScheduleEvent(EVENT_FLASHING_FANGS, 16s); - events.ScheduleEvent(EVENT_LICK, 18s); - if (IsMythic()) - events.ScheduleEvent(EVENT_VOLATILE_FOAM, 20s); - - // Headlong Charge - if (pathId != BerserkerPair.PathID) - { - me->RemoveAurasDueToSpell(SPELL_HEADLONG_CHARGE_PERIODIC_DAMAGE); - me->RemoveAurasDueToSpell(SPELL_HEADLONG_CHARGE_AT); - events.ScheduleEvent(EVENT_ROARING_LEAP, 5s); - } - else // Berserk - { - me->RemoveAurasDueToSpell(SPELL_BERSERK_CHARGE_AT); - } - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type == EFFECT_MOTION_TYPE) - { - if (pointId >= POINT_HEADLONG_CHARGE && pointId <= POINT_HEADLONG_CHARGE_MAX) - { - uint32 headlongChargeId = pointId - POINT_HEADLONG_CHARGE; - DoCastAOE(SPELL_HEADLONG_CHARGE_DAMAGE, true); // manually trigger first damage tick - DoCastAOE(SPELL_HEADLONG_CHARGE_PERIODIC_DAMAGE, true); - DoCastAOE(SPELL_HEADLONG_CHARGE_AT, true); - - me->GetMotionMaster()->MovePath(HeadlongChargePairs[headlongChargeId].PathID, false, {}, 35.0f); - } - else if (pointId == POINT_BERSERK_JUMP) - { - DoCastAOE(SPELL_BERSERK_TRAMPLE_AOE); - DoCastAOE(SPELL_BERSERK_CHARGE_AT); - DoCastAOE(SPELL_ROARING_LEAP_INITIAL_KNOCKBACK, true); - - me->GetMotionMaster()->MovePath(BerserkerPair.PathID, false, {}, 35.0f); - } - } - } - - void DoAction(int32 param) override - { - switch (param) - { - case ACTION_BREATH_HIT_TARGET: - _unitsHitByBreathCount++; - break; - case ACTION_HANDLE_FROTHING_RAGE: - { - uint32 engagedPlayers = 0; - for (auto const& itr : me->GetThreatManager().GetUnsortedThreatList()) - { - if (itr->GetVictim()->IsPlayer()) - engagedPlayers++; - } - - uint32 frothingRageStacks = engagedPlayers - _unitsHitByBreathCount; - if (frothingRageStacks > 0) - { - if (Aura* aura = me->GetAura(SPELL_FROTHING_RAGE)) - frothingRageStacks += aura->GetStackAmount(); - me->SetAuraStack(SPELL_FROTHING_RAGE, me, frothingRageStacks); - } - break; - } - default: - break; - } - } - -private: - uint8 _lickCount; - uint8 _unitsHitByBreathCount; -}; - -// 227512 - Multi-Headed -class spell_multi_headed_proc_guarm : public AuraScript -{ - void HandleProc(ProcEventInfo& eventInfo) - { - GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_MULTI_HEADED_DAMAGE); - } - - void Register() override - { - OnProc += AuraProcFn(spell_multi_headed_proc_guarm::HandleProc); - } -}; - -// 227642 - Multi-Headed -class spell_multi_headed_damage_guarm : public SpellScript -{ - void FilterTargets(std::list<WorldObject*>& targets) - { - if (targets.size() < 2) - return; - - targets.sort(Trinity::ObjectDistanceOrderPred(GetExplTargetUnit())); - targets.pop_front(); // skip expl target if multiple players are in range - targets.resize(1); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_multi_headed_damage_guarm::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); - } -}; - -// 228226 - Flame Lick -// 228250 - Shadow Lick -// 228246 - Frost Lick -class spell_lick_selector_guarm : public SpellScript -{ - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ (uint32)spellInfo->GetEffect(EFFECT_0).BasePoints }) && ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), GetEffectValue(), true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_lick_selector_guarm::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 228187 - Guardian's Breath -class spell_guardians_breath_color_selector : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_GUARDIANS_BREATH_SUMMON_ATS_RGB, - SPELL_GUARDIANS_BREATH_SUMMON_ATS_RBG, - SPELL_GUARDIANS_BREATH_SUMMON_ATS_GRB, - SPELL_GUARDIANS_BREATH_SUMMON_ATS_GBR, - SPELL_GUARDIANS_BREATH_SUMMON_ATS_BRG, - SPELL_GUARDIANS_BREATH_SUMMON_ATS_BGR, - SPELL_GUARDIANS_BREATH_UNK, - SPELL_GUARDIANS_BREATH_CAST_RGB, - SPELL_GUARDIANS_BREATH_CAST_RBG, - SPELL_GUARDIANS_BREATH_CAST_GRB, - SPELL_GUARDIANS_BREATH_CAST_GBR, - SPELL_GUARDIANS_BREATH_CAST_BRG, - SPELL_GUARDIANS_BREATH_CAST_BGR - }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - GuardiansBreathSpellPair const& pair = GuardiansBreathSpellPairs[urand(0, 6)]; - caster->CastSpell(nullptr, pair.CastSpellID); - caster->CastSpell(nullptr, pair.SummonATSpellID); - caster->CastSpell(nullptr, SPELL_GUARDIANS_BREATH_UNK); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_guardians_breath_color_selector::HandleHit, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } -}; - -// 227673 - Guardian's Breath -// 227667 - Guardian's Breath -// 227669 - Guardian's Breath -// 227660 - Guardian's Breath -// 227666 - Guardian's Breath -// 227658 - Guardian's Breath -class spell_guardians_breath : public SpellScript -{ - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (!caster->IsAIEnabled()) - return; - - caster->GetAI()->DoAction(ACTION_HANDLE_FROTHING_RAGE); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_guardians_breath::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -/* - Guarm - v - Color: R-- Spell: 232803 AreaTrigger: 13352 - Color: -R- Spell: 232773 AreaTrigger: 13352 - Color: --R Spell: 232804 AreaTrigger: 13352 - Color: G-- Spell: 232774 AreaTrigger: 13353 - Color: -G- Spell: 232805 AreaTrigger: 13353 - Color: --G Spell: 232806 AreaTrigger: 13353 - Color: B-- Spell: 232801 AreaTrigger: 13354 - Color: -B- Spell: 232802 AreaTrigger: 13354 - Color: --B Spell: 232776 AreaTrigger: 13354 -*/ - -// 232803 - Guardian's Breath -// 232773 - Guardian's Breath -// 232804 - Guardian's Breath -// 232774 - Guardian's Breath -// 232805 - Guardian's Breath -// 232806 - Guardian's Breath -// 232801 - Guardian's Breath -// 232802 - Guardian's Breath -// 232776 - Guardian's Breath -template<uint32 ColorSpellId> -class at_guardians_breath : public AreaTriggerEntityScript -{ -public: - at_guardians_breath(char const* script) : AreaTriggerEntityScript(script) { } - - template<uint32 ColorSpell> - struct at_guardians_breathAI : AreaTriggerAI - { - at_guardians_breathAI(AreaTrigger* at) : AreaTriggerAI(at) { } - - uint32 GetBreathDebuffByDamageSpell(uint32 breathDamageSpell) const - { - switch (breathDamageSpell) - { - case SPELL_FIERY_PHLEGM: - return SPELL_FIERY_PHLEGM_AURA; - case SPELL_SALTY_SPITTLE: - return SPELL_SALTY_SPITTLE_AURA; - case SPELL_DARK_DISCHARGE: - return SPELL_DARK_DISCHARGE_AURA; - } - return 0; - } - - void OnRemove() override - { - InstanceScript* instance = at->GetInstanceScript(); - if (!instance) - return; - - Creature* guarm = instance->GetCreature(DATA_GUARM); - if (!guarm) - return; - - if (!guarm->IsAIEnabled()) - return; - - for (ObjectGuid const& guid : at->GetInsideUnits()) - { - Player* player = ObjectAccessor::GetPlayer(*at, guid); - if (!player) - continue; - - if (player->isDead()) - continue; - - guarm->GetAI()->DoAction(ACTION_BREATH_HIT_TARGET); - guarm->CastSpell(player, ColorSpell, true); - player->CastSpell(nullptr, GetBreathDebuffByDamageSpell(ColorSpell)); - } - } - }; - - AreaTriggerAI* GetAI(AreaTrigger* at) const override - { - return new at_guardians_breathAI<ColorSpellId>(at); - } -}; - -// 227720 - Mixed Elements -// 227721 - Mixed Elements -// 227735 - Mixed Elements -template<uint32 SpellId1, uint32 SpellId2> -class spell_mixed_elements : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SpellId1, - SpellId2 - }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if([](WorldObject* target) - { - Player* unit = target->ToPlayer(); - if (!unit) - return true; - - if (!unit->HasAura(SpellId1) || !unit->HasAura(SpellId2)) - return true; - - return false; - }); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mixed_elements::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - } -}; - -// 227894 - Roaring Leap -class spell_roaring_leap_selector : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ROARING_LEAP_INITIAL_KNOCKBACK, SPELL_ROARING_LEAP_JUMP }); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - // @TODO: cast 232036 + implement (achievement) - // @TODO: related to achievement aswell: 232393 - caster->CastSpell(nullptr, SPELL_ROARING_LEAP_INITIAL_KNOCKBACK, true); - caster->CastSpell(*GetHitDest(), SPELL_ROARING_LEAP_JUMP); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_roaring_leap_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 227816 - Headlong Charge -class spell_headlong_charge_trigger : public SpellScript -{ - void HandleHit(SpellEffIndex /*effIndex*/) - { - Creature* caster = GetCaster()->ToCreature(); - if (!caster) - return; - - uint8 pairId = urand(0, 3); - caster->GetMotionMaster()->Clear(); // remove ChaseMovementGen - caster->SetReactState(REACT_PASSIVE); - caster->GetMotionMaster()->MoveJump(HeadlongChargePairs[pairId].JumpPos, 42.0f, 21.5f, POINT_HEADLONG_CHARGE + pairId); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_headlong_charge_trigger::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 228201 - Off the Leash -class spell_off_the_leash : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HELYATOSIS_AURA }); - } - - void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/ ) - { - GetTarget()->RemoveAurasDueToSpell(SPELL_HELYATOSIS_AURA); - } - - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->CastSpell(nullptr, SPELL_HELYATOSIS_AURA); - } - - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_off_the_leash::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectApplyFn(spell_off_the_leash::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 228824 - Volatile Foam -class spell_volatile_foam_initial : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_VOLATILE_FOAM_SELECTOR_RED, - SPELL_VOLATILE_FOAM_SELECTOR_GREEN, - SPELL_VOLATILE_FOAM_SELECTOR_BLUE - }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(nullptr, RAND(SPELL_VOLATILE_FOAM_SELECTOR_RED, SPELL_VOLATILE_FOAM_SELECTOR_GREEN, SPELL_VOLATILE_FOAM_SELECTOR_BLUE)); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_volatile_foam_initial::HandleHit, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } -}; - -// 228684 - Volatile Foam // Red -// 228809 - Volatile Foam // Green -// 228817 - Volatile Foam // Blue -template<uint32 ExcludeSpellId> -class spell_volatile_foam_selector : public SpellScript -{ - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ (uint32)spellInfo->GetEffect(EFFECT_0).BasePoints }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if([](WorldObject* target) - { - Unit* unit = target->ToUnit(); - if (!unit) - return true; - - if (unit->HasAura(ExcludeSpellId)) - return true; - - return false; - }); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), GetEffectValue(), true); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_volatile_foam_selector::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_volatile_foam_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 228794 - Flaming Volatile Foam // after dispel -// 228811 - Briney Volatile Foam // after dispel -// 228819 - Shadowy Volatile Foam // after dispel -class spell_volatile_foam : public SpellScript -{ - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.sort(Trinity::ObjectDistanceOrderPred(GetExplTargetUnit())); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_volatile_foam::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_volatile_foam::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_volatile_foam::FilterTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ALLY); - } -}; - -// 228744 - Flaming Volatile Foam // initial -// 228794 - Flaming Volatile Foam // after dispel -// 228810 - Briney Volatile Foam // initial -// 228811 - Briney Volatile Foam // after dispel -// 228818 - Shadowy Volatile Foam // initial -// 228819 - Shadowy Volatile Foam // after dispel -template<uint32 SpellIdOnExpire> -class spell_volatile_foam_aura : public AuraScript -{ - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo( - { - (uint32)spellInfo->GetEffect(EFFECT_0).CalcValue(), // SpellIdOnDispel - SpellIdOnExpire - }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - - AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode(); - if (removeMode == AURA_REMOVE_BY_EXPIRE) - target->CastSpell(target, SpellIdOnExpire); - else if (removeMode == AURA_REMOVE_BY_ENEMY_SPELL) - target->CastSpell(nullptr, GetSpellInfo()->GetEffect(EFFECT_0).CalcValue()); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_volatile_foam_aura::OnRemove, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); - } -}; - -void AddSC_boss_guarm() -{ - RegisterTrialOfValorCreatureAI(boss_guarm); - RegisterSpellScript(spell_multi_headed_proc_guarm); - RegisterSpellScript(spell_multi_headed_damage_guarm); - RegisterSpellScript(spell_lick_selector_guarm); - RegisterSpellScript(spell_guardians_breath_color_selector); - RegisterSpellScript(spell_guardians_breath); - new at_guardians_breath<SPELL_FIERY_PHLEGM>("at_guardians_breath_red"); - new at_guardians_breath<SPELL_SALTY_SPITTLE>("at_guardians_breath_green"); - new at_guardians_breath<SPELL_DARK_DISCHARGE>("at_guardians_breath_blue"); - RegisterSpellScriptWithArgs((spell_mixed_elements<SPELL_FIERY_PHLEGM_AURA, SPELL_SALTY_SPITTLE_AURA>), "spell_mixed_elements_red_green"); - RegisterSpellScriptWithArgs((spell_mixed_elements<SPELL_FIERY_PHLEGM_AURA, SPELL_DARK_DISCHARGE_AURA>), "spell_mixed_elements_red_blue"); - RegisterSpellScriptWithArgs((spell_mixed_elements<SPELL_SALTY_SPITTLE_AURA, SPELL_DARK_DISCHARGE_AURA>), "spell_mixed_elements_green_blue"); - RegisterSpellScript(spell_roaring_leap_selector); - RegisterSpellScript(spell_headlong_charge_trigger); - RegisterSpellScript(spell_off_the_leash); - RegisterSpellScript(spell_volatile_foam_initial); - RegisterSpellScriptWithArgs(spell_volatile_foam_selector<SPELL_FIERY_PHLEGM_AURA>, "spell_volatile_foam_selector_red"); - RegisterSpellScriptWithArgs(spell_volatile_foam_selector<SPELL_SALTY_SPITTLE_AURA>, "spell_volatile_foam_selector_green"); - RegisterSpellScriptWithArgs(spell_volatile_foam_selector<SPELL_DARK_DISCHARGE_AURA>, "spell_volatile_foam_selector_blue"); - RegisterSpellScriptWithArgs(spell_volatile_foam_aura<SPELL_FIERY_PHLEGM_AURA>, "spell_volatile_foam_aura_initial_red"); - RegisterSpellScriptWithArgs(spell_volatile_foam_aura<SPELL_SALTY_SPITTLE_AURA>, "spell_volatile_foam_aura_initial_green"); - RegisterSpellScriptWithArgs(spell_volatile_foam_aura<SPELL_DARK_DISCHARGE_AURA>, "spell_volatile_foam_aura_initial_blue"); - RegisterSpellAndAuraScriptPairWithArgs(spell_volatile_foam, spell_volatile_foam_aura<SPELL_FIERY_PHLEGM_AURA>, "spell_volatile_foam_aura_red"); - RegisterSpellAndAuraScriptPairWithArgs(spell_volatile_foam, spell_volatile_foam_aura<SPELL_SALTY_SPITTLE_AURA>, "spell_volatile_foam_aura_green"); - RegisterSpellAndAuraScriptPairWithArgs(spell_volatile_foam, spell_volatile_foam_aura<SPELL_DARK_DISCHARGE_AURA>, "spell_volatile_foam_aura_blue"); -} diff --git a/src/server/scripts/BrokenIsles/TrialOfValor/instance_trial_of_valor.cpp b/src/server/scripts/BrokenIsles/TrialOfValor/instance_trial_of_valor.cpp deleted file mode 100644 index 9a9552b3dc4..00000000000 --- a/src/server/scripts/BrokenIsles/TrialOfValor/instance_trial_of_valor.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaBoundary.h" -#include "InstanceScript.h" -#include "ScriptMgr.h" -#include "trial_of_valor.h" - -BossBoundaryData const boundaries = -{ - { DATA_GUARM, new RectangleBoundary(443.320f, 492.354f, 430.713f, 561.020f) } -}; - -ObjectData const creatureData[] = -{ - { BOSS_ODYN, DATA_ODYN }, - { BOSS_GUARM, DATA_GUARM }, - { BOSS_HELYA, DATA_HELYA }, - { 0, 0 } // END -}; - -DoorData const doorData[] = -{ - { GO_GUARM_BOSS_DOOR_ENTRANCE, DATA_GUARM, EncounterDoorBehavior::OpenWhenNotInProgress }, - { GO_GUARM_BOSS_DOOR_EXIT, DATA_GUARM, EncounterDoorBehavior::OpenWhenDone }, - { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } // END -}; - -DungeonEncounterData const encounters[] = -{ - { DATA_ODYN, {{ 1958 }} }, - { DATA_GUARM, {{ 1962 }} }, - { DATA_HELYA, {{ 2008 }} }, -}; - -class instance_trial_of_valor : public InstanceMapScript -{ - public: - instance_trial_of_valor() : InstanceMapScript(TOVScriptName, 1648) { } - - struct instance_trial_of_valor_InstanceMapScript: public InstanceScript - { - instance_trial_of_valor_InstanceMapScript(InstanceMap* map) : InstanceScript(map) - { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - LoadObjectData(creatureData, nullptr); - LoadDoorData(doorData); - LoadBossBoundaries(boundaries); - LoadDungeonEncounterData(encounters); - } - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_trial_of_valor_InstanceMapScript(map); - } -}; - -void AddSC_instance_trial_of_valor() -{ - new instance_trial_of_valor(); -} diff --git a/src/server/scripts/BrokenIsles/TrialOfValor/trial_of_valor.h b/src/server/scripts/BrokenIsles/TrialOfValor/trial_of_valor.h deleted file mode 100644 index 13c16395ad7..00000000000 --- a/src/server/scripts/BrokenIsles/TrialOfValor/trial_of_valor.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -#ifndef DEF_AZURE_VAULT_H_ -#define DEF_AZURE_VAULT_H_ - -#include "CreatureAIImpl.h" - -#define DataHeader "TrialOfValor" -#define TOVScriptName "instance_trial_of_valor" - -uint32 const EncounterCount = 3; - -enum TOVDataTypes -{ - // Encounters - DATA_ODYN = 0, - DATA_GUARM, - DATA_HELYA, -}; - -enum TOVCreatureIds -{ - // Bosses - BOSS_ODYN = 114263, - BOSS_GUARM = 114323, - BOSS_HELYA = 114537, -}; - -enum TOVGameObjectIds -{ - GO_GUARM_BOSS_DOOR_ENTRANCE = 266532, - GO_GUARM_BOSS_DOOR_EXIT = 266533, -}; - -template <class AI, class T> -inline AI* GetTrialOfValorAI(T* obj) -{ - return GetInstanceAI<AI>(obj, TOVScriptName); -} - -#define RegisterTrialOfValorCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetTrialOfValorAI) - -#endif diff --git a/src/server/scripts/BrokenIsles/broken_isles_script_loader.cpp b/src/server/scripts/BrokenIsles/broken_isles_script_loader.cpp deleted file mode 100644 index 23c452eb8e5..00000000000 --- a/src/server/scripts/BrokenIsles/broken_isles_script_loader.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -// This is where scripts' loading functions should be declared: - -// Trial of Valor -void AddSC_boss_guarm(); -void AddSC_instance_trial_of_valor(); - -// Orderhalls -void AddSC_orderhall_warrior(); -void AddSC_zone_mardum(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddBrokenIslesScripts() -{ - // Trial of Valor - AddSC_boss_guarm(); - AddSC_instance_trial_of_valor(); - - AddSC_orderhall_warrior(); - AddSC_zone_mardum(); -} diff --git a/src/server/scripts/BrokenIsles/zone_mardum.cpp b/src/server/scripts/BrokenIsles/zone_mardum.cpp deleted file mode 100644 index e01c5f9d638..00000000000 --- a/src/server/scripts/BrokenIsles/zone_mardum.cpp +++ /dev/null @@ -1,1669 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTrigger.h" -#include "AreaTriggerAI.h" -#include "CellImpl.h" -#include "Containers.h" -#include "Conversation.h" -#include "CreatureAIImpl.h" -#include "EventProcessor.h" -#include "GridNotifiersImpl.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "PassiveAI.h" -#include "PhasingHandler.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "SpellAuras.h" -#include "SpellScript.h" -#include "TemporarySummon.h" - -enum MardumSpellData -{ - SPELL_START_DEMON_HUNTER_PLAY_SCENE = 193525 -}; - -enum MardumQuestData -{ - QUEST_DEMON_HUNTER_INTRO_TRACKER = 40076 -}; - -enum MardumConversationData -{ - CONVO_DEMONHUNTER_INTRO_START = 705 -}; - -enum MardumSoundData -{ - SOUND_METAL_WEAPON_UNSHEATH = 700, - SOUND_SPELL_DOUBLE_JUMP = 53780, -}; - -class scene_demonhunter_intro : public SceneScript -{ -public: - scene_demonhunter_intro() : SceneScript("scene_demonhunter_intro") { } - - void OnSceneStart(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - Conversation::CreateConversation(CONVO_DEMONHUNTER_INTRO_START, player, *player, player->GetGUID(), nullptr); - } - - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - PhasingHandler::OnConditionChange(player); - } -}; - -// 196030 - Start: Quest Invis -class spell_demon_hunter_intro_aura : public AuraScript -{ - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->CastSpell(nullptr, SPELL_START_DEMON_HUNTER_PLAY_SCENE, true); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_demon_hunter_intro_aura::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -enum TheInvasionBeginsQuestData -{ - QUEST_THE_INVASION_BEGINS = 40077, - - CONVO_THE_INVASION_BEGINS = 922, - - NPC_KAYN_SUNFURY_INVASION_BEGINS = 93011, - NPC_JAYCE_DARKWEAVER_INVASION_BEGINS = 98228, - NPC_ALLARI_THE_SOULEATER_INVASION_BEGINS = 98227, - NPC_CYANA_NIGHTGLAIVE_INVASION_BEGINS = 98290, - NPC_KORVAS_BLOODTHORN_INVASION_BEGINS = 98292, - NPC_SEVIS_BRIGHTFLAME_INVASION_BEGINS = 99918, - NPC_WRATH_WARRIOR_INVASION_BEGINS = 94580, - - SPELL_THE_INVASION_BEGINS = 187382, - SPELL_TRACK_TARGET_IN_CHANNEL = 175799, - SPELL_DEMON_HUNTER_GLIDE_STATE = 199303 -}; - -enum TheInvasionsBeginsWaypointData -{ - // Kayn - PATH_KAYN_ATTACK_DEMON = 9301100, - PATH_KAYN_AFTER_DEMON = 9301101, - - // Path before Jump - PATH_JAYCE_INVASION_BEGINS = 9822800, - PATH_ALLARI_INVASION_BEGINS = 9822700, - PATH_CYANA_INVASION_BEGINS = 9829000, - PATH_KORVAS_INVASION_BEGINS = 9829200, - PATH_SEVIS_INVASION_BEGINS = 9991800, - - // Path after Jump - PATH_JAYCE_JUMP_INVASION_BEGINS = 9822801, - PATH_ALLARI_JUMP_INVASION_BEGINS = 9822701, - PATH_CYANA_JUMP_INVASION_BEGINS = 9829001, - PATH_KORVAS_JUMP_INVASION_BEGINS = 9829201, - PATH_SEVIS_JUMP_INVASION_BEGINS = 9991801, - - POINT_ILLIDARI_LAND_POS = 1, - POINT_KAYN_TRIGGER_DOUBLE_JUMP = 2, - POINT_KAYN_MOVE_TO_DEMON = 3, -}; - -enum TheInvasionBeginsAnimKitsData -{ - ANIM_DH_WINGS = 58110, - ANIM_DH_RUN = 9767, - ANIM_DH_RUN_ALLARI = 9180, -}; - -enum TheInvasionBeginsVisualData -{ - SPELL_VISUAL_KIT_KAYN_GLIDE = 59738, - SPELL_VISUAL_KIT_KAYN_WINGS = 59406, - SPELL_VISUAL_KIT_KAYN_DOUBLE_JUMP = 58110, - SPELL_VISUAL_KIT_KORVAS_JUMP = 63071, - SPELL_VISUAL_KIT_WRATH_WARRIOR_DIE = 58476, -}; - -Position const WrathWarriorSpawnPosition = { 1081.9166f, 3183.8716f, 26.335993f }; -Position const KaynJumpPos = { 1172.17f, 3202.55f, 54.3479f }; -Position const KaynDoubleJumpPosition = { 1094.2384f, 3186.058f, 28.81562f }; -Position const JayceJumpPos = { 1119.24f, 3203.42f, 38.1061f }; -Position const AllariJumpPos = { 1120.08f, 3197.2f, 36.8502f }; -Position const KorvasJumpPos = { 1117.89f, 3196.24f, 36.2158f }; -Position const SevisJumpPos = { 1120.74f, 3199.47f, 37.5157f }; -Position const CyanaJumpPos = { 1120.34f, 3194.28f, 36.4321f }; - -// 93011 - Kayn Sunfury -struct npc_kayn_sunfury_invasion_begins : public ScriptedAI -{ - npc_kayn_sunfury_invasion_begins(Creature* creature) : ScriptedAI(creature) { } - - void OnQuestAccept(Player* player, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_THE_INVASION_BEGINS) - { - PhasingHandler::OnConditionChange(player); - player->CastSpell(WrathWarriorSpawnPosition, SPELL_THE_INVASION_BEGINS, false); - Conversation::CreateConversation(CONVO_THE_INVASION_BEGINS, player, *player, player->GetGUID(), nullptr, false); - } - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == PATH_KAYN_ATTACK_DEMON) - { - Creature* wrathWarrior = me->FindNearestCreatureWithOptions(100.0f, { .CreatureId = NPC_WRATH_WARRIOR_INVASION_BEGINS, .IgnorePhases = true, .OwnerGuid = me->GetOwnerGUID() }); - if (!wrathWarrior) - return; - - me->SetFacingToObject(wrathWarrior); - - wrathWarrior->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_WRATH_WARRIOR_DIE, 0, 0); - wrathWarrior->KillSelf(); - - _scheduler.Schedule(600ms, [this](TaskContext /*context*/) - { - me->GetMotionMaster()->MovePath(PATH_KAYN_AFTER_DEMON, false); - }); - } - else if (pathId == PATH_KAYN_AFTER_DEMON) - me->DespawnOrUnsummon(); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != EFFECT_MOTION_TYPE) - return; - - if (pointId == POINT_KAYN_TRIGGER_DOUBLE_JUMP) - { - TempSummon* summon = me->ToTempSummon(); - if (!summon) - return; - WorldObject* summoner = summon->GetSummoner(); - if (!summoner) - return; - Player* summonerPlayer = summoner->ToPlayer(); - if (!summonerPlayer) - return; - - me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_KAYN_WINGS, 4, 3000); - me->PlayObjectSound(SOUND_SPELL_DOUBLE_JUMP, me->GetGUID(), summonerPlayer); - me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_KAYN_DOUBLE_JUMP, 0, 0); - me->GetMotionMaster()->MoveJumpWithGravity(KaynDoubleJumpPosition, 24.0, 0.9874f, POINT_KAYN_MOVE_TO_DEMON); - } - else if (pointId == POINT_KAYN_MOVE_TO_DEMON) - { - me->SetAIAnimKitId(ANIM_DH_RUN); - me->GetMotionMaster()->MovePath(PATH_KAYN_ATTACK_DEMON, false, {}, 4.0f); - } - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -// 98228 - Jayce Darkweaver -struct npc_jayce_darkweaver_invasion_begins : public ScriptedAI -{ - npc_jayce_darkweaver_invasion_begins(Creature* creature) : ScriptedAI(creature) { } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == PATH_JAYCE_INVASION_BEGINS) - { - me->CastSpell(nullptr, SPELL_DEMON_HUNTER_GLIDE_STATE, true); - me->GetMotionMaster()->MoveJumpWithGravity(JayceJumpPos, 12.0f, 15.2792f, POINT_ILLIDARI_LAND_POS); - } - else if (pathId == PATH_JAYCE_JUMP_INVASION_BEGINS) - me->DespawnOrUnsummon(); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != EFFECT_MOTION_TYPE) - return; - - if (pointId == POINT_ILLIDARI_LAND_POS) - { - me->RemoveAurasDueToSpell(SPELL_DEMON_HUNTER_GLIDE_STATE); - me->GetMotionMaster()->MovePath(PATH_JAYCE_JUMP_INVASION_BEGINS, false); - } - } -}; - -// 98227 - Allari the Souleater -struct npc_allari_the_souleater_invasion_begins : public ScriptedAI -{ - npc_allari_the_souleater_invasion_begins(Creature* creature) : ScriptedAI(creature) { } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == PATH_ALLARI_INVASION_BEGINS) - { - me->CastSpell(nullptr, SPELL_DEMON_HUNTER_GLIDE_STATE, true); - me->GetMotionMaster()->MoveJumpWithGravity(AllariJumpPos, 12.0f, 9.2722f, POINT_ILLIDARI_LAND_POS); - } - else if (pathId == PATH_ALLARI_JUMP_INVASION_BEGINS) - me->DespawnOrUnsummon(); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != EFFECT_MOTION_TYPE) - return; - - if (pointId == POINT_ILLIDARI_LAND_POS) - { - me->RemoveAurasDueToSpell(SPELL_DEMON_HUNTER_GLIDE_STATE); - me->GetMotionMaster()->MovePath(PATH_ALLARI_JUMP_INVASION_BEGINS, false); - } - } -}; - -// 98292 - Korvas Bloodthorn -struct npc_korvas_bloodthorn_invasion_begins : public ScriptedAI -{ - npc_korvas_bloodthorn_invasion_begins(Creature* creature) : ScriptedAI(creature) { } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == PATH_KORVAS_INVASION_BEGINS) - { - me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_KORVAS_JUMP, 4, 2000); - me->GetMotionMaster()->MoveJumpWithGravity(KorvasJumpPos, 24.0f, 19.2911f, POINT_ILLIDARI_LAND_POS); - } - else if (pathId == PATH_KORVAS_JUMP_INVASION_BEGINS) - me->DespawnOrUnsummon(); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != EFFECT_MOTION_TYPE) - return; - - if (pointId == POINT_ILLIDARI_LAND_POS) - { - me->RemoveAurasDueToSpell(SPELL_DEMON_HUNTER_GLIDE_STATE); - me->GetMotionMaster()->MovePath(PATH_KORVAS_JUMP_INVASION_BEGINS, false); - } - } -}; - -// 99918 - Sevis Brightflame -struct npc_sevis_brightflame_invasion_begins : public ScriptedAI -{ - npc_sevis_brightflame_invasion_begins(Creature* creature) : ScriptedAI(creature) { } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == PATH_SEVIS_INVASION_BEGINS) - { - me->CastSpell(nullptr, SPELL_DEMON_HUNTER_GLIDE_STATE, true); - me->GetMotionMaster()->MoveJumpWithGravity(SevisJumpPos, 12.0f, 13.3033f, POINT_ILLIDARI_LAND_POS); - } - else if (pathId == PATH_SEVIS_JUMP_INVASION_BEGINS) - me->DespawnOrUnsummon(); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != EFFECT_MOTION_TYPE) - return; - - if (pointId == POINT_ILLIDARI_LAND_POS) - { - me->RemoveAurasDueToSpell(SPELL_DEMON_HUNTER_GLIDE_STATE); - me->GetMotionMaster()->MovePath(PATH_SEVIS_JUMP_INVASION_BEGINS, false); - } - } -}; - -// 98290 - Cyana Nightglaive -struct npc_cyana_nightglaive_invasion_begins : public ScriptedAI -{ - npc_cyana_nightglaive_invasion_begins(Creature* creature) : ScriptedAI(creature) { } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == PATH_CYANA_INVASION_BEGINS) - { - me->CastSpell(nullptr, SPELL_DEMON_HUNTER_GLIDE_STATE, true); - me->GetMotionMaster()->MoveJumpWithGravity(CyanaJumpPos, 12.0f, 8.4555f, POINT_ILLIDARI_LAND_POS); - } - else if (pathId == PATH_CYANA_JUMP_INVASION_BEGINS) - me->DespawnOrUnsummon(); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != EFFECT_MOTION_TYPE) - return; - - if (pointId == POINT_ILLIDARI_LAND_POS) - { - me->RemoveAurasDueToSpell(SPELL_DEMON_HUNTER_GLIDE_STATE); - me->GetMotionMaster()->MovePath(PATH_CYANA_JUMP_INVASION_BEGINS, false); - } - } -}; - -// 922 - The Invasion Begins -class conversation_the_invasion_begins : public ConversationScript -{ -public: - conversation_the_invasion_begins() : ConversationScript("conversation_the_invasion_begins") { } - - enum TheInvasionBeginsConversationData - { - CONVO_LINE_TRIGGER_FACING = 2529, - CONVO_LINE_START_PATH = 2288, - - CONVO_ACTOR_IDX_KAYN = 1, - CONVO_ACTOR_IDX_KORVAS = 2, - }; - - enum TheInvasionBeginsEventData - { - EVENT_ILLIDARI_FACE_PLAYERS = 1, - EVENT_ILLIDARI_START_PATH - }; - - void OnConversationCreate(Conversation* conversation, Unit* creator) override - { - Creature* kaynObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = NPC_KAYN_SUNFURY_INVASION_BEGINS, .IgnorePhases = true }); - Creature* jayceObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = NPC_JAYCE_DARKWEAVER_INVASION_BEGINS, .IgnorePhases = true }); - Creature* allariaObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = NPC_ALLARI_THE_SOULEATER_INVASION_BEGINS, .IgnorePhases = true }); - Creature* cyanaObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = NPC_CYANA_NIGHTGLAIVE_INVASION_BEGINS, .IgnorePhases = true }); - Creature* korvasObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = NPC_KORVAS_BLOODTHORN_INVASION_BEGINS, .IgnorePhases = true }); - Creature* sevisObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = NPC_SEVIS_BRIGHTFLAME_INVASION_BEGINS, .IgnorePhases = true }); - if (!kaynObject || !jayceObject || !allariaObject || !cyanaObject || !korvasObject || !sevisObject) - return; - - TempSummon* kaynClone = kaynObject->SummonPersonalClone(kaynObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - TempSummon* jayceClone = jayceObject->SummonPersonalClone(jayceObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - TempSummon* allariaClone = allariaObject->SummonPersonalClone(allariaObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - TempSummon* cyanaClone = cyanaObject->SummonPersonalClone(cyanaObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - TempSummon* korvasClone = korvasObject->SummonPersonalClone(korvasObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - TempSummon* sevisClone = sevisObject->SummonPersonalClone(sevisObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - if (!kaynClone || !jayceClone || !allariaClone || !cyanaClone || !korvasClone || !sevisClone) - return; - - _jayceGUID = jayceClone->GetGUID(); - _allariGUID = allariaClone->GetGUID(); - _cyanaGUID = cyanaClone->GetGUID(); - _sevisGUID = sevisClone->GetGUID(); - allariaClone->SetAIAnimKitId(ANIM_DH_RUN_ALLARI); - kaynClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER)); - - conversation->AddActor(CONVO_THE_INVASION_BEGINS, CONVO_ACTOR_IDX_KAYN, kaynClone->GetGUID()); - conversation->AddActor(CONVO_THE_INVASION_BEGINS, CONVO_ACTOR_IDX_KORVAS, korvasClone->GetGUID()); - conversation->Start(); - } - - void OnConversationStart(Conversation* conversation) override - { - LocaleConstant privateOwnerLocale = conversation->GetPrivateObjectOwnerLocale(); - - if (Milliseconds const* illidariFacingLineStarted = conversation->GetLineStartTime(privateOwnerLocale, CONVO_LINE_TRIGGER_FACING)) - _events.ScheduleEvent(EVENT_ILLIDARI_FACE_PLAYERS, *illidariFacingLineStarted); - - if (Milliseconds const* illidariStartPathLineStarted = conversation->GetLineStartTime(privateOwnerLocale, CONVO_LINE_START_PATH)) - _events.ScheduleEvent(EVENT_ILLIDARI_START_PATH, *illidariStartPathLineStarted); - } - - static void StartCloneChannel(ObjectGuid guid, Conversation* conversation) - { - Unit* privateObjectOwner = ObjectAccessor::GetUnit(*conversation, conversation->GetPrivateObjectOwner()); - if (!privateObjectOwner) - return; - - Creature* clone = ObjectAccessor::GetCreature(*conversation, guid); - if (!clone) - return; - - clone->CastSpell(privateObjectOwner, SPELL_TRACK_TARGET_IN_CHANNEL, false); - } - - static void StartCloneMovement(ObjectGuid cloneGUID, uint32 pathId, uint32 animKit, Conversation* conversation) - { - Creature* clone = ObjectAccessor::GetCreature(*conversation, cloneGUID); - if (!clone) - return; - - clone->InterruptNonMeleeSpells(true); - clone->GetMotionMaster()->MovePath(pathId, false); - if (animKit) - clone->SetAIAnimKitId(animKit); - } - - void OnConversationUpdate(Conversation* conversation, uint32 diff) override - { - _events.Update(diff); - - switch (_events.ExecuteEvent()) - { - case EVENT_ILLIDARI_FACE_PLAYERS: - { - StartCloneChannel(conversation->GetActorUnit(CONVO_ACTOR_IDX_KAYN)->GetGUID(), conversation); - StartCloneChannel(conversation->GetActorUnit(CONVO_ACTOR_IDX_KORVAS)->GetGUID(), conversation); - StartCloneChannel(_jayceGUID, conversation); - StartCloneChannel(_allariGUID, conversation); - StartCloneChannel(_cyanaGUID, conversation); - StartCloneChannel(_sevisGUID, conversation); - break; - } - case EVENT_ILLIDARI_START_PATH: - { - Creature* kaynClone = conversation->GetActorCreature(CONVO_ACTOR_IDX_KAYN); - if (!kaynClone) - break; - - Unit* privateObjectOwner = ObjectAccessor::GetUnit(*conversation, conversation->GetPrivateObjectOwner()); - if (!privateObjectOwner) - return; - - Player* player = privateObjectOwner->ToPlayer(); - if (!player) - return; - - kaynClone->PlayObjectSound(SOUND_METAL_WEAPON_UNSHEATH, kaynClone->GetGUID(), player); - kaynClone->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_KAYN_GLIDE, 4, 3000); - kaynClone->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_KAYN_WINGS, 4, 4000); - kaynClone->GetMotionMaster()->MoveJumpWithGravity(KaynJumpPos, 20.5f, 396.3535f, POINT_KAYN_TRIGGER_DOUBLE_JUMP); - kaynClone->SetSheath(SHEATH_STATE_MELEE); - kaynClone->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - - StartCloneMovement(conversation->GetActorUnit(CONVO_ACTOR_IDX_KORVAS)->GetGUID(), PATH_KORVAS_INVASION_BEGINS, ANIM_DH_RUN, conversation); - StartCloneMovement(_jayceGUID, PATH_JAYCE_INVASION_BEGINS, 0, conversation); - StartCloneMovement(_allariGUID, PATH_ALLARI_INVASION_BEGINS, ANIM_DH_RUN_ALLARI, conversation); - StartCloneMovement(_cyanaGUID, PATH_CYANA_INVASION_BEGINS, 0, conversation); - StartCloneMovement(_sevisGUID, PATH_SEVIS_INVASION_BEGINS, ANIM_DH_RUN, conversation); - break; - } - default: - break; - } - } - -private: - ObjectGuid _jayceGUID; - ObjectGuid _allariGUID; - ObjectGuid _cyanaGUID; - ObjectGuid _sevisGUID; - EventMap _events; -}; - -// 98459 - Kayn Sunfury -// 98458 - Jayce Darkweaver -// 98456 - Allari the Souleater -// 98460 - Korvas Bloodthorn -// 99919 - Sevis Brightflame -// 98457 - Cyana Nightglaive -struct npc_illidari_fighting_invasion_begins : public ScriptedAI -{ - npc_illidari_fighting_invasion_begins(Creature* creature) : ScriptedAI(creature) { } - - enum IllidariFightingSpells - { - SPELL_ILLIDARI_CHAOS_STRIKE = 197639, - SPELL_ILLIDARI_FEL_RUSH = 200879, - }; - - enum IllidariFightingEvents - { - EVENT_CHAOS_STRIKE = 1, - EVENT_FEL_RUSH - }; - - Unit* GetNextTarget() - { - std::list<Unit*> targetList; - Trinity::AnyUnfriendlyUnitInObjectRangeCheck checker(me, me, 100.0f); - Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targetList, checker); - Cell::VisitAllObjects(me, searcher, 100.0f); - targetList.remove_if([](Unit* possibleTarget) - { - return possibleTarget->isAttackingPlayer(); - }); - return Trinity::Containers::SelectRandomContainerElement(targetList); - } - - void ScheduleTargetSelection() - { - _oocScheduler.Schedule(200ms, [this](TaskContext context) - { - Unit* target = GetNextTarget(); - if (!target) - { - context.Repeat(500ms); - return; - } - AttackStart(target); - }); - } - - void JustAppeared() override - { - ScheduleTargetSelection(); - } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_CHAOS_STRIKE, 5s); - _events.ScheduleEvent(EVENT_FEL_RUSH, 7s); - } - - void EnterEvadeMode(EvadeReason why) override - { - // manualling calling it to not move to home position but move to next target instead - _EnterEvadeMode(why); - Reset(); - ScheduleTargetSelection(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - { - _oocScheduler.Update(diff); - return; - } - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (_events.ExecuteEvent()) - { - case EVENT_CHAOS_STRIKE: - DoCastVictim(SPELL_ILLIDARI_CHAOS_STRIKE); - _events.ScheduleEvent(EVENT_CHAOS_STRIKE, 5s); - break; - case EVENT_FEL_RUSH: - DoCastVictim(SPELL_ILLIDARI_FEL_RUSH); - _events.ScheduleEvent(SPELL_ILLIDARI_FEL_RUSH, 7s); - break; - default: - break; - } - - DoMeleeAttackIfReady(); - } - -private: - EventMap _events; - TaskScheduler _oocScheduler; -}; - -enum ETIAshtongueIntroData -{ - QUEST_ENTER_THE_ILLIDARI_ASHTONGUE = 40378, - - NPC_KAYN_SUNFURY_ASHTONGUE = 98229, - NPC_KORVAS_BLOODTHORN_ASHTONGUE = 98354, - NPC_SEVIS_BRIGHTFLAME_ASHTONGUE = 99916, - NPC_ALLARI_SOULEATER_ASHTONGUE = 94410, - - DISPLAY_ID_SEVIS_MOUNT = 64385, - - SAY_KAYN_ACTIVATE_GATEWAY = 0, - SAY_KAYN_CUT_A_HOLE = 1, - SAY_KORVAS_SLAY_MORE_DEMONS = 0, - SAY_SEVIS_SAY_FIND_ALLARI = 1, - - SPELL_VISUAL_KIT_SEVIS_MOUNT = 36264, - - SPELL_CAST_MOUNT_DH_FELSABER = 200175, - SPELL_ASHTONGUE_FELLSABER_KILL_CREDIT = 200254, - - PATH_KAYN_SUNFURY_NEAR_TELEPORT = 9822900, - PATH_KORVAS_BLOODTHORN_NEAR_TELEPORT = 9835400, - PATH_SEVIS_BRIGHTFLAME_GATEWAY = 9991600, -}; - -// 98229 - Kayn Sunfury -struct npc_kayn_sunfury_ashtongue_intro : public ScriptedAI -{ - npc_kayn_sunfury_ashtongue_intro(Creature* creature) : ScriptedAI(creature) { } - - void OnQuestAccept(Player* player, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_ENTER_THE_ILLIDARI_ASHTONGUE) - { - PhasingHandler::OnConditionChange(player); - Creature* kaynObject = GetClosestCreatureWithOptions(player, 10.0f, { .CreatureId = NPC_KAYN_SUNFURY_ASHTONGUE, .IgnorePhases = true }); - Creature* korvasObject = GetClosestCreatureWithOptions(player, 10.0f, { .CreatureId = NPC_KORVAS_BLOODTHORN_ASHTONGUE, .IgnorePhases = true }); - if (!kaynObject || !korvasObject) - return; - - TempSummon* kaynClone = kaynObject->SummonPersonalClone(kaynObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - TempSummon* korvasClone = korvasObject->SummonPersonalClone(korvasObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!kaynClone || !korvasClone) - return; - - korvasClone->SetEmoteState(EMOTE_STATE_READY1H); - kaynClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_QUESTGIVER)); - } - } -}; - -// 98229 - Kayn Sunfury -struct npc_kayn_sunfury_ashtongue_intro_private : public ScriptedAI -{ - npc_kayn_sunfury_ashtongue_intro_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - Creature* korvasObject = GetClosestCreatureWithOptions(me, 10.0f, { .CreatureId = NPC_KORVAS_BLOODTHORN_ASHTONGUE, .IgnorePhases = true, .PrivateObjectOwnerGuid = me->GetPrivateObjectOwner()}); - if (!korvasObject) - return; - - ObjectGuid korvasGuid = korvasObject->GetGUID(); - - _scheduler.Schedule(1s, [this, korvasGuid](TaskContext task) - { - Unit* privateObjectOwner = ObjectAccessor::GetUnit(*me, me->GetPrivateObjectOwner()); - if (!privateObjectOwner) - return; - - Unit* korvas = ObjectAccessor::GetUnit(*me, korvasGuid); - if (!korvas) - return; - - Talk(SAY_KAYN_ACTIVATE_GATEWAY, me); - me->CastSpell(privateObjectOwner, SPELL_TRACK_TARGET_IN_CHANNEL, false); - korvas->CastSpell(privateObjectOwner, SPELL_TRACK_TARGET_IN_CHANNEL, false); - - task.Schedule(6s, [this, korvasGuid](TaskContext task) - { - Talk(SAY_KAYN_CUT_A_HOLE, me); - - task.Schedule(6s, [this, korvasGuid](TaskContext task) - { - Creature* korvas = ObjectAccessor::GetCreature(*me, korvasGuid); - if (!korvas) - return; - - if (!korvas->IsAIEnabled()) - return; - - korvas->AI()->Talk(SAY_KORVAS_SLAY_MORE_DEMONS, me); - me->InterruptNonMeleeSpells(true); - me->GetMotionMaster()->MovePath(PATH_KAYN_SUNFURY_NEAR_TELEPORT, false); - me->SetAIAnimKitId(ANIM_DH_RUN); - me->DespawnOrUnsummon(10s); - - task.Schedule(2s, [this, korvasGuid](TaskContext /*task*/) - { - Creature* korvas = ObjectAccessor::GetCreature(*me, korvasGuid); - if (!korvas) - return; - - korvas->InterruptNonMeleeSpells(true); - korvas->GetMotionMaster()->MovePath(PATH_KORVAS_BLOODTHORN_NEAR_TELEPORT, false); - korvas->SetAIAnimKitId(ANIM_DH_RUN); - korvas->DespawnOrUnsummon(12s); - }); - }); - }); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -CreatureAI* KaynSunfuryNearLegionBannerAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_kayn_sunfury_ashtongue_intro_private(creature); - return new npc_kayn_sunfury_ashtongue_intro(creature); -}; - -// 1053 - Enter the Illidari: Ashtongue -class scene_enter_the_illidari_ashtongue : public SceneScript -{ -public: - scene_enter_the_illidari_ashtongue() : SceneScript("scene_enter_the_illidari_ashtongue") { } - - void OnSceneStart(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - Creature* sevisObject = GetClosestCreatureWithOptions(player, 30.0f, { .CreatureId = NPC_SEVIS_BRIGHTFLAME_ASHTONGUE, .IgnorePhases = true }); - if (!sevisObject) - return; - - TempSummon* sevisClone = sevisObject->SummonPersonalClone(sevisObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!sevisClone) - return; - - sevisClone->CastSpell(player, SPELL_TRACK_TARGET_IN_CHANNEL, false); - sevisClone->DespawnOrUnsummon(15s); - } - - void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override - { - if (triggerName == "SEEFELSABERCREDIT") - player->CastSpell(player, SPELL_ASHTONGUE_FELLSABER_KILL_CREDIT, true); - else if (triggerName == "UPDATEPHASE") - PhasingHandler::OnConditionChange(player); - } -}; - -// 99916 - Sevis Brightflame (Ashtongue Gateway) -struct npc_sevis_brightflame_ashtongue_gateway_private : public ScriptedAI -{ - npc_sevis_brightflame_ashtongue_gateway_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - _scheduler.Schedule(1s, [this](TaskContext task) - { - Talk(SAY_SEVIS_SAY_FIND_ALLARI, me); - - task.Schedule(2s, [this](TaskContext task) - { - me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SEVIS_MOUNT, 0, 0); - me->SetMountDisplayId(DISPLAY_ID_SEVIS_MOUNT); - - task.Schedule(3s, [this](TaskContext /*task*/) - { - me->InterruptNonMeleeSpells(true); - me->GetMotionMaster()->MovePath(PATH_SEVIS_BRIGHTFLAME_GATEWAY, false); - }); - }); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -CreatureAI* SevisBrightflameAshtongueGatewayAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_sevis_brightflame_ashtongue_gateway_private(creature); - return new NullCreatureAI(creature); -}; - -// 200255 - Accepting Felsaber Gift -class spell_accepting_felsaber_gift : public SpellScript -{ - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(nullptr, SPELL_CAST_MOUNT_DH_FELSABER, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_accepting_felsaber_gift::HandleHitTarget, EFFECT_3, SPELL_EFFECT_DUMMY); - } -}; - -// 32 - Mardum - Trigger KillCredit for Quest "Enter the Illidari: Ashtongue" -struct at_enter_the_illidari_ashtongue_allari_killcredit : AreaTriggerAI -{ - at_enter_the_illidari_ashtongue_allari_killcredit(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player || player->GetQuestStatus(QUEST_ENTER_THE_ILLIDARI_ASHTONGUE) != QUEST_STATUS_INCOMPLETE) - return; - - player->KilledMonsterCredit(NPC_ALLARI_SOULEATER_ASHTONGUE); - } -}; - -enum ETICoilskarIntroData -{ - NPC_SEVIS_BRIGHTFLAME_COILSKAR = 99917, - SAY_SEVIS_SAY_MEET_AT_LAST_GATEWAY = 2, - - PATH_SEVIS_BRIGHTFLAME_COILSKAR = 9991700 -}; - -// 1077 - Enter the Illidari: Coilskar -class scene_enter_the_illidari_coilskar : public SceneScript -{ -public: - scene_enter_the_illidari_coilskar() : SceneScript("scene_enter_the_illidari_coilskar") { } - - void OnSceneStart(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - PhasingHandler::OnConditionChange(player); - Creature* sevisObject = GetClosestCreatureWithOptions(player, 30.0f, { .CreatureId = NPC_SEVIS_BRIGHTFLAME_COILSKAR, .IgnorePhases = true }); - if (!sevisObject) - return; - - sevisObject->SummonPersonalClone(sevisObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - } -}; - -// 99917 - Sevis Brightflame (Coilskar Gateway) -struct npc_sevis_brightflame_coilskar_gateway_private : public ScriptedAI -{ - npc_sevis_brightflame_coilskar_gateway_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - TempSummon* summon = me->ToTempSummon(); - if (!summon) - return; - - Unit* summoner = summon->GetSummonerUnit(); - if (!summoner) - return; - - me->SetFacingToObject(summoner); - me->DespawnOrUnsummon(14s); - - _scheduler.Schedule(1s, [this](TaskContext task) - { - Talk(SAY_SEVIS_SAY_MEET_AT_LAST_GATEWAY, me); - - task.Schedule(2s, [this](TaskContext task) - { - me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SEVIS_MOUNT, 0, 0); - me->SetMountDisplayId(DISPLAY_ID_SEVIS_MOUNT); - - task.Schedule(3s, [this](TaskContext /*task*/) - { - me->GetMotionMaster()->MovePath(PATH_SEVIS_BRIGHTFLAME_COILSKAR, false); - }); - }); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -CreatureAI* SevisBrightflameCoilskarGatewayAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_sevis_brightflame_coilskar_gateway_private(creature); - return new NullCreatureAI(creature); -}; - -enum EyeOnThePrizeData -{ - NPC_COLOSSAL_INFERNAL_BALEFUL = 96159, - - QUEST_EYE_ON_THE_PRIZE = 39049, - - DISPLAYID_BALEFUL_EYE = 38795, - - // Inquisitor Baleful text - SAY_BALEFUL_AGGRO = 0, - SAY_BALEFUL_AEGIS = 1, - SAY_BALEFUL_DEATH = 2, - - // Inquisitor Baleful events - EVENT_BALEFUL_MIND_SPIKE = 1, - EVENT_BALEFUL_BEAMING_GAZE, - EVENT_BALEFUL_INCITE_MADNESS, - EVENT_BALEFUL_COLOSS_INFERNAL_SMASH, - - // Inquisitor Baleful points - POINT_BALEFUL_AEGIS_UP = 1, - POINT_BALEFUL_AEGIS_DOWN, - - // Inquisitor Baleful actions - ACTION_BALEFUL_AEGIS_DOWN = 1, - - // Inquisitor Baleful spells - SPELL_BALEFUL_MIND_SPIKE = 194519, - SPELL_BALEFUL_BEAMING_GAZE = 195058, - SPELL_BALEFUL_INCITE_MADNESS = 194529, - SPELL_BALEFUL_LEGION_AEGIS = 192665, - SPELL_BALEFUL_DIE_KNOCKBACK = 190742, - SPELL_BALEFUL_TAKING_POWER = 203925, - SPELL_BALEFUL_KILL_CREDIT = 188559, - - // Baleful Infernal Coloss - SPELL_BALEFUL_COLOSS_INFERNAL_SMASH = 192709, - SPELL_BALEFUL_COLOSS_INFERNAL_SMASH_CAST = 183938, - - // Baleful Beaming Eye - SPELL_BALEFUL_BEAMING_EYE_SUMMON = 195061, - SPELL_BALEFUL_BEAMING_EYE_CREATE_AT = 195051 -}; - -class BalefulColossSmashEvent : public BasicEvent -{ -public: - BalefulColossSmashEvent(Creature* owner) : BasicEvent(), _owner(owner) { } - - bool Execute(uint64, uint32) override - { - Unit* target = _owner->AI()->SelectTarget(SelectTargetMethod::Random, 0, 150.0f, true); - _owner->CastSpell(target, SPELL_BALEFUL_COLOSS_INFERNAL_SMASH, false); - return true; - } - -private: - Creature* _owner; -}; - -Position const BalefulAegisPos = { 592.4335f, 2433.1067f, -62.91178f }; - -// 93105 - Inquisitor Baleful -struct npc_inquisitor_baleful_molten_shore : public ScriptedAI -{ - npc_inquisitor_baleful_molten_shore(Creature* creature) : ScriptedAI(creature), _castedLegionAegis(false) { } - - void JustAppeared() override - { - // Blizz use a personal spawn for every DH on Quest: 39049 which leads to issues - TempSummon* balefulColoss = me->SummonCreature(NPC_COLOSSAL_INFERNAL_BALEFUL, 523.4045f, 2428.4113f, -117.0033f, 0.10887321f, TEMPSUMMON_MANUAL_DESPAWN, 0s); - if (!balefulColoss) - return; - - _balefulColossGUID = balefulColoss->GetGUID(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - Talk(SAY_BALEFUL_AGGRO); - _events.ScheduleEvent(EVENT_BALEFUL_MIND_SPIKE, 3s); - _events.ScheduleEvent(EVENT_BALEFUL_BEAMING_GAZE, 7s); - _events.ScheduleEvent(EVENT_BALEFUL_INCITE_MADNESS, 11s); - } - - void DoAction(int32 action) override - { - if (action == ACTION_BALEFUL_AEGIS_DOWN) - me->GetMotionMaster()->MovePoint(POINT_BALEFUL_AEGIS_DOWN, me->GetHomePosition()); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (pointId == POINT_BALEFUL_AEGIS_UP) - me->SetFacingTo(0.19842f); - else if (pointId == POINT_BALEFUL_AEGIS_DOWN) - me->SetReactState(REACT_AGGRESSIVE); - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (!_castedLegionAegis && me->HealthBelowPctDamaged(60, damage)) - { - if (Creature* balefulColoss = ObjectAccessor::GetCreature(*me, _balefulColossGUID)) - { - balefulColoss->m_Events.AddEventAtOffset(new BalefulColossSmashEvent(balefulColoss), 1s); - balefulColoss->m_Events.AddEventAtOffset(new BalefulColossSmashEvent(balefulColoss), 4s); - balefulColoss->m_Events.AddEventAtOffset(new BalefulColossSmashEvent(balefulColoss), 8s); - balefulColoss->m_Events.AddEventAtOffset(new BalefulColossSmashEvent(balefulColoss), 13s); - } - - DoCast(SPELL_BALEFUL_LEGION_AEGIS); - me->SetReactState(REACT_PASSIVE); - Talk(SAY_BALEFUL_AEGIS); - me->GetMotionMaster()->MovePoint(POINT_BALEFUL_AEGIS_UP, BalefulAegisPos); - _castedLegionAegis = true; - } - } - - void Reset() override - { - _castedLegionAegis = false; - _events.Reset(); - } - - void JustDied(Unit* /*killer*/) override - { - DoCast(SPELL_BALEFUL_DIE_KNOCKBACK); - Talk(SAY_BALEFUL_DEATH); - - if (Creature* balefulColoss = ObjectAccessor::GetCreature(*me, _balefulColossGUID)) - balefulColoss->KillSelf(); - - for (ObjectGuid tapperGUID : me->GetTapList()) - { - if (Player* tapper = ObjectAccessor::GetPlayer(*me, tapperGUID)) - { - tapper->CastSpell(tapper, SPELL_BALEFUL_KILL_CREDIT, false); - tapper->CastSpell(tapper, SPELL_BALEFUL_TAKING_POWER, false); - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BALEFUL_MIND_SPIKE: - DoCastVictim(SPELL_BALEFUL_MIND_SPIKE); - _events.ScheduleEvent(EVENT_BALEFUL_MIND_SPIKE, 7s); - break; - case EVENT_BALEFUL_BEAMING_GAZE: - DoCastVictim(SPELL_BALEFUL_BEAMING_GAZE); - _events.ScheduleEvent(EVENT_BALEFUL_BEAMING_GAZE, 11s); - break; - case EVENT_BALEFUL_INCITE_MADNESS: - DoCastVictim(SPELL_BALEFUL_INCITE_MADNESS); - _events.ScheduleEvent(EVENT_BALEFUL_INCITE_MADNESS, 30s); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - -private: - EventMap _events; - bool _castedLegionAegis; - ObjectGuid _balefulColossGUID; -}; - -// 99160 - Beaming Eye -struct npc_baleful_beaming_eye : public ScriptedAI -{ - npc_baleful_beaming_eye(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetDisplayId(DISPLAYID_BALEFUL_EYE, true); - me->SetPlayHoverAnim(true); - DoCastSelf(SPELL_BALEFUL_BEAMING_EYE_CREATE_AT); - // ToDo: rotation isn't changing orientation, turnspeed should be random - me->GetMotionMaster()->MoveRotate(0, 10000, RAND(ROTATE_DIRECTION_LEFT, ROTATE_DIRECTION_RIGHT)); - } -}; - -// 192665 - Legion Aegis -class spell_mardum_baleful_legion_aegis : public AuraScript -{ - void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - { - if (UnitAI* ai = GetTarget()->GetAI()) - ai->DoAction(ACTION_BALEFUL_AEGIS_DOWN); - } - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_mardum_baleful_legion_aegis::HandleRemove, EFFECT_0, SPELL_AURA_SCHOOL_IMMUNITY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 192709 - Infernal Smash -class spell_mardum_coloss_infernal_smash_selector : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BALEFUL_COLOSS_INFERNAL_SMASH_CAST }); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_BALEFUL_COLOSS_INFERNAL_SMASH_CAST, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_mardum_coloss_infernal_smash_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 195058 - Beaming Gaze (selector) -class spell_mardum_baleful_beaming_gaze_selector : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BALEFUL_BEAMING_EYE_SUMMON }); - } - - void SummonBeamingEye(Unit* origin, float angle) - { - Position dest = origin->GetPosition(); - origin->MovePositionToFirstCollision(dest, 6.5f, angle); - dest.m_positionZ += 0.35f; - origin->CastSpell(dest, SPELL_BALEFUL_BEAMING_EYE_SUMMON, true); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - Unit* hitUnit = GetHitUnit(); - SummonBeamingEye(hitUnit, float(M_PI)); - SummonBeamingEye(hitUnit, float(-M_PI) / 4.0f); - SummonBeamingEye(hitUnit, float(M_PI) / 4.0f); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_mardum_baleful_beaming_gaze_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } -}; - -enum SetThemFreeData -{ - NPC_CYANA_NIGHTGLAIVE_FREED = 94377, - NPC_IZAL_WHITEMOON_FREED = 93117, - NPC_BELATH_DAWNBLADE_FREED = 94400, - NPC_MANNETHREL_DARKSTAR_FREED = 93230, - - SAY_CYANA_NIGHTGLAIVE_FREED = 1, - SAY_IZAL_WHITEMOON_FREED = 1, - SAY_BELATH_DAWNBLADE_FREED = 1, - SAY_MANNETHRE_DARKSTAR_FREED = 1, - - PATH_CYANA_NIGHTGLAIVE_FREED = 9437700, - PATH_IZAL_WHITEMOON_FREED = 9311700, - PATH_BELATH_DAWNBLADE_FREED = 9440000, - PATH_MANNETHREL_DARKSTAR_FREED = 9323000, - - ANIM_DH_WALK_DAZED = 1078 -}; - -// 94377 - Cyana Nightglaive -struct npc_cyana_nightglaive_freed_private : public ScriptedAI -{ - npc_cyana_nightglaive_freed_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->DespawnOrUnsummon(19s); - - _scheduler.Schedule(2s + 500ms, [this](TaskContext task) - { - Talk(SAY_CYANA_NIGHTGLAIVE_FREED, me); - - task.Schedule(3s, [this](TaskContext /*task*/) - { - me->GetMotionMaster()->MovePath(PATH_CYANA_NIGHTGLAIVE_FREED, false); - }); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -CreatureAI* CyanaNightglaiveFreedAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_cyana_nightglaive_freed_private(creature); - return new NullCreatureAI(creature); -}; - -// 93117 - Izal Whitemoon -struct npc_izal_whitemoon_freed_private : public ScriptedAI -{ - npc_izal_whitemoon_freed_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->DespawnOrUnsummon(18s); - - _scheduler.Schedule(2s, [this](TaskContext task) - { - Talk(SAY_IZAL_WHITEMOON_FREED, me); - - task.Schedule(3s, [this](TaskContext /*task*/) - { - me->GetMotionMaster()->MovePath(PATH_CYANA_NIGHTGLAIVE_FREED, false); - }); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -CreatureAI* IzalWhitemoonFreedAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_izal_whitemoon_freed_private(creature); - return new NullCreatureAI(creature); -}; - -// 94400 - Belath Dawnblade -struct npc_belath_dawnblade_freed_private : public ScriptedAI -{ - npc_belath_dawnblade_freed_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->DespawnOrUnsummon(5min); // wtf blizz - - _scheduler.Schedule(3s, [this](TaskContext task) - { - Talk(SAY_BELATH_DAWNBLADE_FREED, me); - - task.Schedule(6s, [this](TaskContext /*task*/) - { - me->GetMotionMaster()->MovePath(PATH_BELATH_DAWNBLADE_FREED, false); - }); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -CreatureAI* BelathDawnbladeFreedAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_belath_dawnblade_freed_private(creature); - return new NullCreatureAI(creature); -}; - -// 93230 - Mannethrel Darkstar -struct npc_mannethrel_darkstar_freed_private : public ScriptedAI -{ - npc_mannethrel_darkstar_freed_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->DespawnOrUnsummon(28s); - - _scheduler.Schedule(2s, [this](TaskContext task) - { - Talk(SAY_BELATH_DAWNBLADE_FREED, me); - - task.Schedule(6s, [this](TaskContext /*task*/) - { - me->SetAIAnimKitId(ANIM_DH_WALK_DAZED); - me->GetMotionMaster()->MovePath(PATH_MANNETHREL_DARKSTAR_FREED, false); - }); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -CreatureAI* MannethrelDarkstarFreedAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_mannethrel_darkstar_freed_private(creature); - return new NullCreatureAI(creature); -}; - -// 204711 - Set Them Free: Cyana Nightglaive Freed Kill Credit -// 204714 - Set Them Free: Izal Whitemoon Freed Kill Credit -// 204712 - Set Them Free: Belath Dawnblade Freed Kill Credit -// 204715 - Set Them Free: Mannethrel Darkstar Freed Kill Credit -template<uint32 CreatureId> -class spell_freed_killcredit_set_them_free : public SpellScript -{ - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - if (Player* player = GetCaster()->ToPlayer()) - { - Creature* staticObject = GetClosestCreatureWithOptions(player, 10.0f, { .CreatureId = CreatureId, .IgnorePhases = true }); - if (!staticObject) - return; - - staticObject->SummonPersonalClone(staticObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_freed_killcredit_set_them_free::HandleHitTarget, EFFECT_1, SPELL_EFFECT_DUMMY); - } -}; - -enum ETIShivarraData -{ - NPC_SEVIS_BRIGHTFLAME_SHIVARRA = 99915, - - GOSSIP_MENU_SACRIFICE_PLAYER = 19132, - GOSSIP_MENU_SACRIFICE_SEVIS = 19133, - - GOSSIP_OPTION_SACRIFICE_PLAYER = 0, - GOSSIP_OPTION_SACRIFICE_SEVIS = 0, - - SAY_SEVIS_PLAYER_SACRIFICE = 1, - SAY_SEVIS_GET_SACRIFICED = 2, - - ANIM_KIT_SWING_WEAPON = 8973, - ANIM_KIT_KNEEL = 2312, - ANIM_KIT_SALUTE = 3342, - ANIM_KIT_ONESHOT_GET_HIT = 881, - - SPELL_VISUAL_SACRIFICE_PLAYER = 55406, - - PATH_SEVIS_GATEWAY_SHIVARRA = 9991500, - - POINT_SEVIS_GATEWAY_SHIVARRA = 1, - - SPELL_SACRIFICE_SEVIS = 196731, - SPELL_SEVIS_SACRIFICE_ME = 196735, - SPELL_SEVIS_CHAOS_STRIKE = 204317, - SPELL_SEVIS_SOUL_MISSILE_02 = 191664, - SPELL_SEVIS_KILLED_ME_AURA = 203292, - SPELL_TRIGGER_SHIVARRA_CONV_WHEN_DEAD = 196866, - - ACTION_SACRIFICE_PLAYER = 1, - ACTION_SACRIFICE_SEVIS, - - QUEST_SEVIS_SACRIFICE_TRACKER = 40087, -}; - -Position const SevisBrightflameShivarraGatewayPosition = { 1587.9618f, 2543.091f, 62.18399f, 3.49967908f }; - -// 99915 - Sevis Brightflame (Shivarra Gateway) -struct npc_sevis_brightflame_shivarra_gateway : public ScriptedAI -{ - npc_sevis_brightflame_shivarra_gateway(Creature* creature) : ScriptedAI(creature), _soulMissileCounter(0) { } - - bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override - { - if (menuId == GOSSIP_MENU_SACRIFICE_PLAYER && gossipListId == GOSSIP_OPTION_SACRIFICE_PLAYER) - { - CloseGossipMenuFor(player); - player->CastSpell(nullptr, SPELL_SEVIS_SACRIFICE_ME, false); - return true; - } - else if (menuId == GOSSIP_MENU_SACRIFICE_SEVIS && gossipListId == GOSSIP_OPTION_SACRIFICE_SEVIS) - { - CloseGossipMenuFor(player); - player->CastSpell(me, SPELL_SACRIFICE_SEVIS, false); - return true; - } - return false; - } - - void DoAction(int32 param) override - { - switch (param) - { - case ACTION_SACRIFICE_PLAYER: - SacrificePlayer(); - break; - case ACTION_SACRIFICE_SEVIS: - SacrificeSelf(); - break; - default: - break; - } - } - - void SacrificeSelf() - { - me->PlayOneShotAnimKitId(ANIM_KIT_ONESHOT_GET_HIT); - Talk(SAY_SEVIS_GET_SACRIFICED, me); - - _scheduler.Schedule(1s, [this](TaskContext task) - { - me->KillSelf(); - - _soulMissileCounter = 0; - task.Schedule(2s, [this](TaskContext task) - { - DoCast(SPELL_SEVIS_SOUL_MISSILE_02); - _soulMissileCounter++; - - if (_soulMissileCounter < 3) - task.Repeat(2s); - }); - }); - } - - void SacrificePlayer() - { - me->DespawnOrUnsummon(22s); - Talk(SAY_SEVIS_PLAYER_SACRIFICE, me); - - _scheduler.Schedule(1s, [this](TaskContext task) - { - TempSummon* summon = me->ToTempSummon(); - if (!summon) - return; - - Unit* summoner = summon->GetSummonerUnit(); - if (!summoner) - return; - - me->GetMotionMaster()->MoveCloserAndStop(POINT_SEVIS_GATEWAY_SHIVARRA, summoner, 2.0f); - - task.Schedule(2s, [this](TaskContext task) - { - me->SendPlaySpellVisualKit(SPELL_VISUAL_SACRIFICE_PLAYER, 4, 1000); - me->SetAIAnimKitId(ANIM_KIT_SWING_WEAPON); - DoCast(SPELL_SEVIS_CHAOS_STRIKE); - - task.Schedule(2s, [this](TaskContext task) - { - me->SetAIAnimKitId(ANIM_KIT_KNEEL); - - task.Schedule(5s, [this](TaskContext task) - { - me->SetAIAnimKitId(ANIM_KIT_SALUTE); - - task.Schedule(3s, [this](TaskContext task) - { - me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SEVIS_MOUNT, 0, 0); - me->SetMountDisplayId(DISPLAY_ID_SEVIS_MOUNT); - - task.Schedule(2s, [this](TaskContext /*task*/) - { - me->GetMotionMaster()->MovePath(PATH_SEVIS_GATEWAY_SHIVARRA, false); - }); - }); - }); - }); - }); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; - uint8 _soulMissileCounter; -}; - -// EventID 47550 -class event_sevis_sacrifice_player : public EventScript -{ -public: - event_sevis_sacrifice_player() : EventScript("event_sevis_sacrifice_player") { } - - void OnTrigger(WorldObject* /*object*/, WorldObject* invoker, uint32 /*eventId*/) override - { - if (Creature* creature = invoker->SummonCreature(NPC_SEVIS_BRIGHTFLAME_SHIVARRA, SevisBrightflameShivarraGatewayPosition, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, invoker->GetGUID())) - { - if (Player* player = invoker->ToPlayer()) - { - player->KilledMonsterCredit(NPC_SEVIS_BRIGHTFLAME_SHIVARRA); - player->CastSpell(nullptr, SPELL_SEVIS_KILLED_ME_AURA, false); - } - creature->AI()->DoAction(ACTION_SACRIFICE_PLAYER); - } - } -}; - -// EventID 47549 -class event_sevis_sacrifice_self : public EventScript -{ -public: - event_sevis_sacrifice_self() : EventScript("event_sevis_sacrifice_self") { } - - void OnTrigger(WorldObject* /*object*/, WorldObject* invoker, uint32 /*eventId*/) override - { - if (Creature* creature = invoker->SummonCreature(NPC_SEVIS_BRIGHTFLAME_SHIVARRA, SevisBrightflameShivarraGatewayPosition, TEMPSUMMON_TIMED_DESPAWN, 60s, 0, 0, invoker->GetGUID())) - { - if (Player* player = invoker->ToPlayer()) - player->KilledMonsterCredit(NPC_SEVIS_BRIGHTFLAME_SHIVARRA); - creature->AI()->DoAction(ACTION_SACRIFICE_SEVIS); - } - } -}; - -// XX - Mardum - Trigger Conversation for Quest "Enter the Illidari: Shivarra" -struct at_enter_the_illidari_shivarra_conversation : AreaTriggerAI -{ - at_enter_the_illidari_shivarra_conversation(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player || !player->HasAura(SPELL_SEVIS_KILLED_ME_AURA)) - return; - - player->CastSpell(nullptr, SPELL_TRIGGER_SHIVARRA_CONV_WHEN_DEAD, true); - } -}; - -// 38765 - Enter the Illidari: Shivarra -class quest_enter_the_illidari_shivarra : public QuestScript -{ -public: - quest_enter_the_illidari_shivarra() : QuestScript("quest_enter_the_illidari_shivarra") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - if (newStatus == QUEST_STATUS_NONE) - { - player->RemoveActiveQuest(QUEST_SEVIS_SACRIFICE_TRACKER, false); - player->RemoveRewardedQuest(QUEST_SEVIS_SACRIFICE_TRACKER); - } - } -}; - -void AddSC_zone_mardum() -{ - // Creature - RegisterCreatureAI(npc_kayn_sunfury_invasion_begins); - RegisterCreatureAI(npc_jayce_darkweaver_invasion_begins); - RegisterCreatureAI(npc_allari_the_souleater_invasion_begins); - RegisterCreatureAI(npc_korvas_bloodthorn_invasion_begins); - RegisterCreatureAI(npc_sevis_brightflame_invasion_begins); - RegisterCreatureAI(npc_cyana_nightglaive_invasion_begins); - RegisterCreatureAI(npc_illidari_fighting_invasion_begins); - RegisterCreatureAI(npc_inquisitor_baleful_molten_shore); - RegisterCreatureAI(npc_baleful_beaming_eye); - RegisterCreatureAI(npc_sevis_brightflame_shivarra_gateway); - - // AISelector - new FactoryCreatureScript<CreatureAI, &KaynSunfuryNearLegionBannerAISelector>("npc_kayn_sunfury_ashtongue_intro"); - new FactoryCreatureScript<CreatureAI, &SevisBrightflameAshtongueGatewayAISelector>("npc_sevis_brightflame_ashtongue_gateway_private"); - new FactoryCreatureScript<CreatureAI, &SevisBrightflameCoilskarGatewayAISelector>("npc_sevis_brightflame_coilskar_gateway_private"); - new FactoryCreatureScript<CreatureAI, &CyanaNightglaiveFreedAISelector>("npc_cyana_nightglaive_freed_private"); - new FactoryCreatureScript<CreatureAI, &IzalWhitemoonFreedAISelector>("npc_izal_whitemoon_freed_private"); - new FactoryCreatureScript<CreatureAI, &BelathDawnbladeFreedAISelector>("npc_belath_dawnblade_freed_private"); - new FactoryCreatureScript<CreatureAI, &MannethrelDarkstarFreedAISelector>("npc_mannethrel_darkstar_freed_private"); - - // AreaTrigger - RegisterAreaTriggerAI(at_enter_the_illidari_ashtongue_allari_killcredit); - RegisterAreaTriggerAI(at_enter_the_illidari_shivarra_conversation); - - // EventScript - new event_sevis_sacrifice_player(); - new event_sevis_sacrifice_self(); - - // Conversation - new conversation_the_invasion_begins(); - - // Scene - new scene_demonhunter_intro(); - new scene_enter_the_illidari_ashtongue(); - new scene_enter_the_illidari_coilskar(); - - // Spells - RegisterSpellScript(spell_demon_hunter_intro_aura); - RegisterSpellScript(spell_accepting_felsaber_gift); - RegisterSpellScript(spell_mardum_baleful_legion_aegis); - RegisterSpellScript(spell_mardum_coloss_infernal_smash_selector); - RegisterSpellScript(spell_mardum_baleful_beaming_gaze_selector); - RegisterSpellScriptWithArgs(spell_freed_killcredit_set_them_free<NPC_CYANA_NIGHTGLAIVE_FREED>, "spell_cyana_nightglaive_killcredit_set_them_free"); - RegisterSpellScriptWithArgs(spell_freed_killcredit_set_them_free<NPC_IZAL_WHITEMOON_FREED>, "spell_izal_whitemoon_killcredit_set_them_free"); - RegisterSpellScriptWithArgs(spell_freed_killcredit_set_them_free<NPC_BELATH_DAWNBLADE_FREED>, "spell_belath_dawnblade_killcredit_set_them_free"); - RegisterSpellScriptWithArgs(spell_freed_killcredit_set_them_free<NPC_MANNETHREL_DARKSTAR_FREED>, "spell_mannethrel_darkstar_killcredit_set_them_free"); - - // Quests - new quest_enter_the_illidari_shivarra(); -}; diff --git a/src/server/scripts/BrokenIsles/zone_orderhall_warrior.cpp b/src/server/scripts/BrokenIsles/zone_orderhall_warrior.cpp deleted file mode 100644 index fd3af9e3974..00000000000 --- a/src/server/scripts/BrokenIsles/zone_orderhall_warrior.cpp +++ /dev/null @@ -1,925 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "Containers.h" -#include "MotionMaster.h" -#include "MovementTypedefs.h" -#include "ObjectAccessor.h" -#include "PhasingHandler.h" -#include "Player.h" -#include "ScriptedCreature.h" -#include "ScriptMgr.h" -#include "TemporarySummon.h" - -enum ValarjarSpells -{ - SPELL_EMOTE_BELCH = 65937, - SPELL_WARRIOR_ORDER_FORMATION_SCENE = 193709, - SPELL_CANCEL_COMPLETE_SCENE_WARRIOR_ORDER_FORMATION = 193711 -}; - -enum Phases -{ - PHASE_ODYN = 5107, - PHASE_DANICA = 5090 -}; - -enum Quests -{ - QUEST_ODYN_AND_THE_VALARJAR = 39654 -}; - -enum Creatures -{ - NPC_KILL_CREDIT_FOLLOWED_DANICA = 103036, - NPC_DANICA_THE_RECLAIMER = 93823, - NPC_KILL_CREDIT_ARRIVED_AT_ODYN = 96532 -}; - -enum Items -{ - ITEM_MONSTER_ITEM_MUTTON_WITH_BITE = 2202, - ITEM_MONSTER_ITEM_TANKARD_WOODEN = 2703, - ITEM_HOV_2H_AXE = 137176, - ITEM_HOV_1H_SWORD = 137263, - ITEM_HOV_SHIELD_2 = 137265 -}; - -struct npc_danica_the_reclaimer : public ScriptedAI -{ - npc_danica_the_reclaimer(Creature* creature) : ScriptedAI(creature) { } - - Position const DanicaPath01[6] = - { - { 1050.219f, 7232.470f, 100.5846f }, - { 1046.207f, 7240.372f, 100.5846f }, - { 1040.963f, 7245.498f, 100.6819f }, - { 1034.726f, 7250.083f, 100.5846f }, - { 1027.422f, 7257.835f, 100.5846f }, - { 1027.542f, 7259.735f, 100.5846f } - }; - - using DanicaPath01Size = std::extent<decltype(DanicaPath01)>; - - Position const DanicaPath02[6] = - { - { 1018.493f, 7247.438f, 100.5846f }, - { 1013.535f, 7243.327f, 100.5846f }, - { 1007.063f, 7235.723f, 100.5846f }, - { 1003.337f, 7229.650f, 100.5846f }, - { 995.4549f, 7227.286f, 100.5846f }, - { 984.4410f, 7224.357f, 100.5846f } - }; - - using DanicaPath02Size = std::extent<decltype(DanicaPath02)>; - - Position const DanicaPath03[5] = - { - { 962.5208f, 7223.089f, 100.5846f }, - { 934.2795f, 7223.116f, 100.5846f }, - { 911.8507f, 7223.776f, 100.5846f }, - { 879.0139f, 7224.100f, 100.9079f }, - { 851.691f, 7224.5490f, 109.5846f } - }; - - using DanicaPath03Size = std::extent<decltype(DanicaPath03)>; - - enum Texts - { - SAY_FIRST_LINE = 1, - SAY_SECOND_LINE = 2, - SAY_THIRD_LINE = 3 - }; - - enum Points - { - POINT_FORGE_OF_ODYN, - POINT_INTRODUCE_MEAD_HALL, - POINT_ODYN - }; - - // Should be the player - // Personal spawn ? Demon Creator is the player who accepts the quest, no phasing involved but the quest giver dissapears and gets replaced with a new one - void IsSummonedBy(WorldObject* summoner) override - { - if (summoner->GetTypeId() != TYPEID_PLAYER) - return; - - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - _summonerGuid = summoner->GetGUID(); - _scheduler.Schedule(2s, [this, summoner](TaskContext /*context*/) - { - me->GetMotionMaster()->MoveSmoothPath(POINT_FORGE_OF_ODYN, DanicaPath01, DanicaPath01Size::value, false, true); - Talk(SAY_FIRST_LINE, summoner); - }); - } - - void MovementInform(uint32 /*type*/, uint32 id) override - { - switch (id) - { - case POINT_FORGE_OF_ODYN: - _scheduler.Schedule(10s, [this](TaskContext /*context*/) - { - Player* player = ObjectAccessor::FindConnectedPlayer(_summonerGuid); - me->GetMotionMaster()->MoveSmoothPath(POINT_INTRODUCE_MEAD_HALL, DanicaPath02, DanicaPath02Size::value, false, true); - Talk(SAY_SECOND_LINE, player); - }); - break; - case POINT_INTRODUCE_MEAD_HALL: - _scheduler.Schedule(10s, [this](TaskContext /*context*/) - { - Player* player = ObjectAccessor::FindConnectedPlayer(_summonerGuid); - me->GetMotionMaster()->MoveSmoothPath(POINT_ODYN, DanicaPath03, DanicaPath03Size::value, false, true); - Talk(SAY_THIRD_LINE, player); - - if (player) - player->KilledMonsterCredit(NPC_KILL_CREDIT_FOLLOWED_DANICA); - }); - break; - case POINT_ODYN: - me->DespawnOrUnsummon(); - break; - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - - // Should be some other way to do this... - void OnQuestAccept(Player* player, Quest const* /*quest*/) override - { - TempSummon* summon = player->SummonCreature(NPC_DANICA_THE_RECLAIMER, 1059.613f, 7224.605f, 100.4608f, 0.03462749f, TEMPSUMMON_MANUAL_DESPAWN, 0s, player->GetGUID()); - if (!summon) - return; - - summon->SetDemonCreatorGUID(player->GetGUID()); - } - -private: - TaskScheduler _scheduler; - ObjectGuid _summonerGuid; -}; - -struct npc_feasting_valarjar : public ScriptedAI -{ - npc_feasting_valarjar(Creature* creature) : ScriptedAI(creature), - _randomEmotes({ EMOTE_ONESHOT_EAT_NO_SHEATHE, EMOTE_ONESHOT_LAUGH_NO_SHEATHE, EMOTE_ONESHOT_ROAR, EMOTE_ONESHOT_LAUGH, EMOTE_ONESHOT_POINT, - EMOTE_ONESHOT_TALK, EMOTE_ONESHOT_CHEER_NO_SHEATHE }) { } - - enum Points - { - POINT_LEAVING - }; - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - - void Reset() override - { - _scheduler.Schedule(5s, 30s, [this](TaskContext context) - { - Emote emoteID = Trinity::Containers::SelectRandomContainerElement(_randomEmotes); - if (emoteID == EMOTE_ONESHOT_EAT_NO_SHEATHE) - { - me->SetVirtualItem(0, urand(0, 1) ? ITEM_MONSTER_ITEM_MUTTON_WITH_BITE : ITEM_MONSTER_ITEM_TANKARD_WOODEN); - _scheduler.Schedule(1s, [this](TaskContext /*context*/) - { - me->SetVirtualItem(0, 0); - if (roll_chance_i(85)) - DoCastSelf(SPELL_EMOTE_BELCH); - }); - } - - me->HandleEmoteCommand(emoteID); - context.Repeat(); - }); - - _scheduler.Schedule(5min, 20min, [this](TaskContext /*context*/) - { - float direction = me->GetOrientation() + M_PI; - me->GetMotionMaster()->MovePoint(POINT_LEAVING, me->GetFirstCollisionPosition(5.0f, direction)); - }); - } - - void MovementInform(uint32 /*type*/, uint32 id) override - { - switch (id) - { - case POINT_LEAVING: - me->DespawnOrUnsummon(); - break; - default: - break; - } - } - -private: - TaskScheduler _scheduler; - std::unordered_set<Emote> _randomEmotes; -}; - -struct npc_valarjar_paying_respect_to_odyn : ScriptedAI -{ - npc_valarjar_paying_respect_to_odyn(Creature* creature) : ScriptedAI(creature), - _randomEmotes({ EMOTE_ONESHOT_POINT, EMOTE_ONESHOT_TALK, EMOTE_ONESHOT_NO }) { } - - enum Points - { - POINT_TABLE, - POINT_ODYN, - POINT_DESPAWN - }; - - virtual size_t GetPathToTableSize() const = 0; - virtual Position const* GetPathToTable() const = 0; - virtual size_t GetPathToOdynSize() const = 0; - virtual Position const* GetPathToOdyn() const = 0; - virtual size_t GetPathToDespawnPointSize() const = 0; - virtual Position const* GetPathToDespawnPoint() const = 0; - - void Reset() override - { - me->GetMotionMaster()->MoveSmoothPath(POINT_TABLE, GetPathToTable(), GetPathToTableSize(), true); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - - void MovementInform(uint32 /*type*/, uint32 id) override - { - switch (id) - { - case POINT_TABLE: - _scheduler.Schedule(3s, 6s, [this](TaskContext /*context*/) - { - me->HandleEmoteCommand(Trinity::Containers::SelectRandomContainerElement(_randomEmotes)); - }); - - _scheduler.Schedule(7s, 15s, [this](TaskContext /*context*/) - { - me->GetMotionMaster()->MoveSmoothPath(POINT_ODYN, GetPathToOdyn(), GetPathToOdynSize(), true); - }); - break; - case POINT_ODYN: - _scheduler.Schedule(1s, 3s, [this](TaskContext /*context*/) - { - me->PlayOneShotAnimKitId(1431); - _scheduler.Schedule(3s, 10s, [this](TaskContext /*context*/) - { - me->GetMotionMaster()->MoveSmoothPath(POINT_DESPAWN, GetPathToDespawnPoint(), GetPathToDespawnPointSize()); - }); - }); - break; - case POINT_DESPAWN: - me->DespawnOrUnsummon(2s); - break; - default: - break; - } - } - -private: - TaskScheduler _scheduler; - std::unordered_set<Emote> _randomEmotes; -}; - -struct npc_incoming_valarjar_aspirant_1 : public npc_valarjar_paying_respect_to_odyn -{ - npc_incoming_valarjar_aspirant_1(Creature* creature) : npc_valarjar_paying_respect_to_odyn(creature) { } - - Position const IncommingValarjarAspirantPath01[11] = - { - { 876.7396f, 7220.805f, 98.91662f }, - { 870.6129f, 7220.945f, 101.8951f }, - { 865.0677f, 7220.975f, 103.7846f }, - { 854.6389f, 7221.030f, 106.7846f }, - { 851.1597f, 7220.292f, 106.7846f }, - { 848.0573f, 7216.386f, 106.7846f }, - { 844.7570f, 7210.920f, 106.7846f }, - { 841.9844f, 7207.228f, 106.7846f }, - { 839.2396f, 7203.619f, 107.5846f }, - { 836.4844f, 7200.202f, 107.5846f }, - { 834.2430f, 7196.000f, 107.5846f } - }; - - using IncommingValarjarAspirantPath01Size = std::extent<decltype(IncommingValarjarAspirantPath01)>; - - Position const IncommingValarjarAspirantPath02[5] = - { - { 828.5851f, 7204.096f, 106.7846f }, - { 819.4636f, 7212.124f, 106.7846f }, - { 814.2853f, 7215.074f, 106.7846f }, - { 809.4948f, 7217.543f, 106.7846f }, - { 806.0313f, 7219.614f, 106.7846f } - }; - - using IncommingValarjarAspirantPath02Size = std::extent<decltype(IncommingValarjarAspirantPath02)>; - - Position const IncommingValarjarAspirantPath03[9] = - { - { 824.1597f, 7221.822f, 106.7846f }, - { 831.7500f, 7221.092f, 106.7846f }, - { 842.4236f, 7222.208f, 106.7846f }, - { 853.5781f, 7222.473f, 106.7846f }, - { 863.9618f, 7223.012f, 103.7846f }, - { 867.9358f, 7223.165f, 103.3735f }, - { 880.6215f, 7222.569f, 97.78457f }, - { 887.8438f, 7221.310f, 97.78457f }, - { 903.7118f, 7215.743f, 97.78458f } - }; - - using IncommingValarjarAspirantPath03Size = std::extent<decltype(IncommingValarjarAspirantPath03)>; - - size_t GetPathToTableSize() const override { return IncommingValarjarAspirantPath01Size::value; } - Position const* GetPathToTable() const override { return IncommingValarjarAspirantPath01; } - size_t GetPathToOdynSize() const override { return IncommingValarjarAspirantPath02Size::value; } - Position const* GetPathToOdyn() const override { return IncommingValarjarAspirantPath02; } - size_t GetPathToDespawnPointSize() const override { return IncommingValarjarAspirantPath03Size::value; } - Position const* GetPathToDespawnPoint() const override { return IncommingValarjarAspirantPath03; } -}; - -struct npc_incoming_valarjar_aspirant_2 : public npc_valarjar_paying_respect_to_odyn -{ - npc_incoming_valarjar_aspirant_2(Creature* creature) : npc_valarjar_paying_respect_to_odyn(creature) { } - - Position const IncommingValarjarAspirantPath01[12] = - { - { 890.5521f, 7235.710f, 97.78457f }, - { 883.8073f, 7233.402f, 97.78457f }, - { 872.1979f, 7234.018f, 101.2886f }, - { 863.5941f, 7234.594f, 103.7846f }, - { 855.2899f, 7235.626f, 106.7593f }, - { 849.8177f, 7236.571f, 106.7846f }, - { 845.7830f, 7241.082f, 106.7846f }, - { 841.8489f, 7246.654f, 106.7846f }, - { 839.7205f, 7250.986f, 106.7846f }, - { 840.8889f, 7254.773f, 107.5846f }, - { 841.9254f, 7259.517f, 107.5846f }, - { 840.6077f, 7266.662f, 107.5846f } - }; - - using IncommingValarjarAspirantPath01Size = std::extent<decltype(IncommingValarjarAspirantPath01)>; - - Position const IncommingValarjarAspirantPath02[6] = - { - { 838.1493f, 7260.027f, 107.5846f }, - { 832.2691f, 7253.756f, 106.7846f }, - { 823.1996f, 7246.677f, 106.7846f }, - { 821.2500f, 7244.573f, 106.7846f }, - { 815.8906f, 7241.437f, 106.7846f }, - { 809.8281f, 7239.580f, 106.7846f } - }; - - using IncommingValarjarAspirantPath02Size = std::extent<decltype(IncommingValarjarAspirantPath02)>; - - Position const IncommingValarjarAspirantPath03[10] = - { - { 827.4757f, 7236.593f, 106.7846f }, - { 837.1840f, 7236.047f, 106.7846f }, - { 847.1684f, 7235.377f, 106.7846f }, - { 854.7185f, 7235.294f, 106.7846f }, - { 862.3524f, 7234.287f, 104.4290f }, - { 882.3489f, 7233.743f, 97.78457f }, - { 894.3768f, 7233.098f, 97.78457f }, - { 906.0660f, 7232.520f, 97.78458f }, - { 915.0070f, 7233.368f, 97.78458f }, - { 924.6910f, 7233.694f, 97.78458f } - }; - - using IncommingValarjarAspirantPath03Size = std::extent<decltype(IncommingValarjarAspirantPath03)>; - - size_t GetPathToTableSize() const override { return IncommingValarjarAspirantPath01Size::value; } - Position const* GetPathToTable() const override { return IncommingValarjarAspirantPath01; } - size_t GetPathToOdynSize() const override { return IncommingValarjarAspirantPath02Size::value; } - Position const* GetPathToOdyn() const override { return IncommingValarjarAspirantPath02; } - size_t GetPathToDespawnPointSize() const override { return IncommingValarjarAspirantPath03Size::value; } - Position const* GetPathToDespawnPoint() const override { return IncommingValarjarAspirantPath03; } -}; - -struct npc_leaving_valarjar_1 : public npc_valarjar_paying_respect_to_odyn -{ - npc_leaving_valarjar_1(Creature* creature) : npc_valarjar_paying_respect_to_odyn(creature) { } - - Position const PathLeavingValarjar01[8] = - { - { 802.5903f, 7304.605f, 106.7846f }, - { 809.3333f, 7296.529f, 106.7846f }, - { 811.8004f, 7293.676f, 106.7846f }, - { 817.4219f, 7287.498f, 106.7846f }, - { 821.0313f, 7283.637f, 106.7846f }, - { 822.1111f, 7275.672f, 106.7846f }, - { 826.4662f, 7270.601f, 107.5846f }, - { 830.8212f, 7268.729f, 107.5846f } - }; - - using PathLeavingValarjar01Size = std::extent<decltype(PathLeavingValarjar01)>; - - Position const PathLeavingValarjar02[6] = - { - { 824.9757f, 7261.047f, 107.5846f }, - { 822.0989f, 7256.705f, 106.7846f }, - { 819.0261f, 7253.674f, 106.7846f }, - { 813.1910f, 7249.034f, 106.7846f }, - { 809.1493f, 7245.616f, 106.7846f }, - { 806.3559f, 7243.057f, 106.7846f } - }; - - using PathLeavingValarjar02Size = std::extent<decltype(PathLeavingValarjar02)>; - - Position const PathLeavingValarjar03[10] = - { - { 825.3177f, 7244.253f, 106.7846f }, - { 837.5816f, 7243.241f, 106.7846f }, - { 845.0243f, 7240.063f, 106.7846f }, - { 853.7274f, 7238.423f, 106.7953f }, - { 862.9948f, 7238.000f, 103.9737f }, - { 872.7899f, 7236.939f, 100.8285f }, - { 882.8333f, 7235.922f, 97.78457f }, - { 897.2813f, 7235.469f, 97.78457f }, - { 908.8090f, 7234.836f, 97.78458f }, - { 919.8750f, 7238.241f, 97.78458f } - }; - - using PathLeavingValarjar03Size = std::extent<decltype(PathLeavingValarjar03)>; - - size_t GetPathToTableSize() const override { return PathLeavingValarjar01Size::value; } - Position const* GetPathToTable() const override { return PathLeavingValarjar01; } - size_t GetPathToOdynSize() const override { return PathLeavingValarjar02Size::value; } - Position const* GetPathToOdyn() const override { return PathLeavingValarjar02; } - size_t GetPathToDespawnPointSize() const override { return PathLeavingValarjar03Size::value; } - Position const* GetPathToDespawnPoint() const override { return PathLeavingValarjar03; } -}; - -struct npc_leaving_valarjar_2 : public npc_valarjar_paying_respect_to_odyn -{ - npc_leaving_valarjar_2(Creature* creature) : npc_valarjar_paying_respect_to_odyn(creature) { } - - Position const PathLeavingValarjar01[7] = - { - { 787.2361f, 7155.902f, 107.5846f }, - { 792.4844f, 7154.038f, 106.7846f }, - { 798.7830f, 7154.968f, 106.7846f }, - { 807.8160f, 7162.251f, 106.7846f }, - { 813.2882f, 7167.856f, 106.7846f }, - { 816.4913f, 7170.818f, 106.7846f }, - { 819.8299f, 7166.373f, 107.6281f } - }; - - using PathLeavingValarjar01Size = std::extent<decltype(PathLeavingValarjar01)>; - - Position const PathLeavingValarjar02[7] = - { - { 818.2708f, 7175.469f, 106.7846f }, - { 819.5643f, 7185.691f, 106.7846f }, - { 818.4184f, 7193.082f, 106.7846f }, - { 818.8750f, 7199.256f, 106.7846f }, - { 815.2361f, 7203.648f, 106.7846f }, - { 809.6198f, 7208.319f, 106.7846f }, - { 804.2743f, 7215.379f, 106.7846f } - }; - - using PathLeavingValarjar02Size = std::extent<decltype(PathLeavingValarjar02)>; - - Position const PathLeavingValarjar03[6] = - { - { 810.8403f, 7231.531f, 106.7846f }, - { 807.5087f, 7248.719f, 106.7846f }, - { 801.2587f, 7254.592f, 106.7846f }, - { 794.6649f, 7265.814f, 107.5846f }, - { 792.0191f, 7274.151f, 107.5846f }, - { 790.1823f, 7282.182f, 107.5846f } - }; - - using PathLeavingValarjar03Size = std::extent<decltype(PathLeavingValarjar03)>; - - size_t GetPathToTableSize() const override { return PathLeavingValarjar01Size::value; } - Position const* GetPathToTable() const override { return PathLeavingValarjar01; } - size_t GetPathToOdynSize() const override { return PathLeavingValarjar02Size::value; } - Position const* GetPathToOdyn() const override { return PathLeavingValarjar02; } - size_t GetPathToDespawnPointSize() const override { return PathLeavingValarjar03Size::value; } - Position const* GetPathToDespawnPoint() const override { return PathLeavingValarjar03; } -}; - -struct npc_odyn : public ScriptedAI -{ - npc_odyn(Creature* creature) : ScriptedAI(creature) { } - - // Should be an better way of doing this... - // What about a QuestScript with a hook "OnPlayerChangeArea" ? But The Great Mead Hall does not have a specific area... - void MoveInLineOfSight(Unit* who) override - { - if (Player* player = who->ToPlayer()) - { - if (player->GetQuestStatus(QUEST_ODYN_AND_THE_VALARJAR) == QUEST_STATUS_INCOMPLETE) - { - if (player->IsInDist(me, 60.0f)) - { - player->KilledMonsterCredit(NPC_KILL_CREDIT_ARRIVED_AT_ODYN); // SPELL_WARRIOR_ORDER_FORMATION_SCENE does not has this credit. - player->CastSpell(player, SPELL_WARRIOR_ORDER_FORMATION_SCENE); - } - } - } - } -}; - -struct npc_spectating_valarjar : public ScriptedAI -{ - npc_spectating_valarjar(Creature* creature) : ScriptedAI(creature), - _randomEmotes({ EMOTE_ONESHOT_CHEER_NO_SHEATHE, EMOTE_ONESHOT_SALUTE, EMOTE_ONESHOT_ROAR, EMOTE_ONESHOT_POINT, EMOTE_ONESHOT_SHOUT }) { } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - - void Reset() override - { - _scheduler.Schedule(5s, 30s, [this](TaskContext context) - { - me->HandleEmoteCommand(Trinity::Containers::SelectRandomContainerElement(_randomEmotes)); - context.Repeat(); - }); - - _scheduler.Schedule(5min, 20min, [this](TaskContext /*context*/) - { - float direction = me->GetOrientation() + M_PI; - me->GetMotionMaster()->MovePoint(0, me->GetFirstCollisionPosition(5.0f, direction)); - }); - } - - void MovementInform(uint32 /*type*/, uint32 id) override - { - switch (id) - { - case 0: - me->DespawnOrUnsummon(); - break; - default: - break; - } - } - -private: - TaskScheduler _scheduler; - std::unordered_set<Emote> _randomEmotes; -}; - -struct npc_valkyr_of_odyn : public ScriptedAI -{ - npc_valkyr_of_odyn(Creature* creature) : ScriptedAI(creature) { } - - virtual Position const* GetPath() const = 0; - virtual size_t GetPathSize() const = 0; - - enum Points - { - POINT_DESPAWN = 1, - POINT_JUMP, - POINT_DESPAWN_JUMP - }; - - void Reset() override - { - if (me->GetPositionZ() >= 100.0f) - { - _scheduler.Schedule(3s, [this](TaskContext /*context*/) - { - me->GetMotionMaster()->MoveSmoothPath(POINT_JUMP, GetPath(), GetPathSize(), false, true); - }); - } - else - me->GetMotionMaster()->MoveSmoothPath(POINT_DESPAWN, GetPath(), GetPathSize(), false, true); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - - void MovementInform(uint32 /*type*/, uint32 id) override - { - switch (id) - { - case POINT_JUMP: - _scheduler.Schedule(250ms, [this](TaskContext /*context*/) - { - /* - * (MovementMonsterSpline) (MovementSpline) MoveTime: 3111 - * (MovementMonsterSpline) (MovementSpline) JumpGravity: 19.2911 -> +-Movement::gravity - * 1.4125f is guessed value. Which makes the JumpGravity way closer to the intended one. Not sure how to do it 100% blizzlike. - * Also the MoveTime is not correct but I don't know how to set it here. - */ - me->GetMotionMaster()->MoveJump({ 1107.84f, 7222.57f, 38.9725f, me->GetOrientation() }, me->GetSpeed(MOVE_RUN), Movement::gravity * 1.4125f, POINT_DESPAWN_JUMP); - }); - break; - case POINT_DESPAWN: - me->DespawnOrUnsummon(500ms); - break; - case POINT_DESPAWN_JUMP: - me->DespawnOrUnsummon(); - break; - default: - break; - } - } - -private: - TaskScheduler _scheduler; -}; - -struct npc_valkyr_of_odyn_1 : public npc_valkyr_of_odyn -{ - npc_valkyr_of_odyn_1(Creature* creature) : npc_valkyr_of_odyn(creature) { } - - Position const Path[7] = - { - { 996.5347f, 7321.393f, 124.0931f }, - { 1009.880f, 7311.655f, 118.0898f }, - { 1024.688f, 7293.689f, 120.4009f }, - { 1038.288f, 7266.321f, 122.2708f }, - { 1049.439f, 7235.418f, 120.1065f }, - { 1067.825f, 7229.589f, 114.6320f }, - { 1082.800f, 7223.660f, 98.63562f } - }; - - using PathSize = std::extent<decltype(Path)>; - - Position const* GetPath() const override { return Path; } - size_t GetPathSize() const override { return PathSize::value; } -}; - -struct npc_valkyr_of_odyn_2 : public npc_valkyr_of_odyn -{ - npc_valkyr_of_odyn_2(Creature* creature) : npc_valkyr_of_odyn(creature) { } - - Position const Path[18] = - { - { 1113.635f, 7214.023f, 7.808200f }, - { 1110.443f, 7213.999f, 17.28479f }, - { 1108.583f, 7213.984f, 22.80371f }, - { 1103.488f, 7221.702f, 70.68047f }, - { 1101.911f, 7222.535f, 82.51234f }, - { 1098.861f, 7222.271f, 90.03111f }, - { 1095.129f, 7223.033f, 94.15130f }, - { 1089.240f, 7223.335f, 97.94925f }, - { 1077.932f, 7222.822f, 110.2143f }, - { 1068.802f, 7223.216f, 110.2143f }, - { 1045.356f, 7224.674f, 114.5371f }, - { 1023.946f, 7224.304f, 120.0150f }, - { 1002.535f, 7224.943f, 121.1011f }, - { 911.7552f, 7227.165f, 121.7384f }, - { 879.1285f, 7227.272f, 121.7384f }, - { 830.8785f, 7233.613f, 121.7384f }, - { 809.5052f, 7267.270f, 121.7384f }, - { 795.2899f, 7311.849f, 121.7384f } - }; - - using PathSize = std::extent<decltype(Path)>; - - Position const* GetPath() const override { return Path; } - size_t GetPathSize() const override { return PathSize::value; } -}; - -struct npc_valkyr_of_odyn_3 : public npc_valkyr_of_odyn -{ - npc_valkyr_of_odyn_3(Creature* creature) : npc_valkyr_of_odyn(creature) { } - - Position const Path[14] = - { - { 1133.929f, 7223.167f, 38.90330f }, - { 1124.510f, 7222.310f, 42.15336f }, - { 1119.903f, 7221.891f, 43.74335f }, - { 1103.934f, 7227.212f, 69.99904f }, - { 1097.554f, 7226.132f, 89.09371f }, - { 1092.602f, 7224.059f, 101.1545f }, - { 1078.701f, 7228.348f, 109.5599f }, - { 1068.967f, 7232.247f, 116.7876f }, - { 1053.540f, 7229.623f, 117.8927f }, - { 1044.104f, 7242.757f, 118.7891f }, - { 1031.111f, 7256.717f, 118.7891f }, - { 1029.684f, 7288.019f, 126.3048f }, - { 1029.889f, 7325.333f, 126.3061f }, - { 1039.043f, 7365.176f, 133.2310f } - }; - - using PathSize = std::extent<decltype(Path)>; - - Position const* GetPath() const override { return Path; } - size_t GetPathSize() const override { return PathSize::value; } -}; - -struct npc_valkyr_of_odyn_4 : public npc_valkyr_of_odyn -{ - npc_valkyr_of_odyn_4(Creature* creature) : npc_valkyr_of_odyn(creature) { } - - Position const Path[7] = - { - { 914.8663f, 7204.922f, 128.1687f }, - { 945.4445f, 7216.170f, 128.1687f }, - { 987.2483f, 7220.554f, 125.4318f }, - { 1015.882f, 7222.849f, 126.0546f }, - { 1053.023f, 7224.076f, 119.6729f }, - { 1071.891f, 7222.934f, 108.9545f }, - { 1081.530f, 7224.331f, 98.63076f } - }; - - using PathSize = std::extent<decltype(Path)>; - - Position const* GetPath() const override { return Path; } - size_t GetPathSize() const override { return PathSize::value; } -}; - -struct npc_valkyr_of_odyn_5 : public npc_valkyr_of_odyn -{ - npc_valkyr_of_odyn_5(Creature* creature) : npc_valkyr_of_odyn(creature) { } - - Position const Path[12] = - { - { 1038.141f, 7134.033f, 105.8965f }, - { 1033.373f, 7134.492f, 105.8965f }, - { 1027.882f, 7136.373f, 105.8965f }, - { 1026.943f, 7144.288f, 105.8965f }, - { 1027.608f, 7167.030f, 108.4167f }, - { 1027.767f, 7180.922f, 108.4167f }, - { 1028.484f, 7197.977f, 108.4167f }, - { 1034.113f, 7207.747f, 108.4167f }, - { 1041.977f, 7216.452f, 108.4167f }, - { 1054.269f, 7223.207f, 108.4167f }, - { 1075.891f, 7224.811f, 101.7954f }, - { 1082.438f, 7224.540f, 99.12900f } - }; - - using PathSize = std::extent<decltype(Path)>; - - Position const* GetPath() const override { return Path; } - size_t GetPathSize() const override { return PathSize::value; } -}; - -struct npc_valkyr_of_odyn_6 : public npc_valkyr_of_odyn -{ - npc_valkyr_of_odyn_6(Creature* creature) : npc_valkyr_of_odyn(creature) { } - - Position const Path[17] = - { - { 1112.011f, 7233.799f, 45.87240f }, - { 1107.887f, 7234.073f, 54.97818f }, - { 1106.264f, 7234.181f, 58.56218f }, - { 1099.969f, 7236.397f, 75.87664f }, - { 1096.552f, 7233.196f, 85.53920f }, - { 1095.531f, 7229.387f, 89.86687f }, - { 1092.981f, 7225.366f, 97.69602f }, - { 1082.800f, 7221.249f, 109.4660f }, - { 1070.983f, 7218.749f, 112.6827f }, - { 1057.455f, 7216.709f, 112.6827f }, - { 1051.859f, 7210.338f, 112.6827f }, - { 1042.427f, 7200.762f, 112.6827f }, - { 1032.616f, 7183.982f, 112.6827f }, - { 1027.792f, 7157.764f, 112.6827f }, - { 1026.870f, 7126.981f, 112.6827f }, - { 1053.083f, 7102.808f, 125.9283f }, - { 1055.122f, 7059.807f, 130.4395f } - }; - - using PathSize = std::extent<decltype(Path)>; - - Position const* GetPath() const override { return Path; } - size_t GetPathSize() const override { return PathSize::value; } -}; - -struct npc_valkyr_of_odyn_7 : public npc_valkyr_of_odyn -{ - npc_valkyr_of_odyn_7(Creature* creature) : npc_valkyr_of_odyn(creature) { } - - Position const Path[10] = - { - { 1064.076f, 7305.979f, 117.5428f }, - { 1058.290f, 7305.543f, 117.5428f }, - { 1046.578f, 7305.583f, 117.5428f }, - { 1034.373f, 7295.979f, 117.5428f }, - { 1026.639f, 7275.582f, 114.1900f }, - { 1030.729f, 7251.381f, 114.1900f }, - { 1040.950f, 7237.213f, 114.1900f }, - { 1057.274f, 7229.228f, 114.1900f }, - { 1070.297f, 7226.421f, 111.7502f }, - { 1082.146f, 7225.846f, 101.0798f } - }; - - using PathSize = std::extent<decltype(Path)>; - - Position const* GetPath() const override { return Path; } - size_t GetPathSize() const override { return PathSize::value; } -}; - -struct npc_weapon_inspector_valarjar : public ScriptedAI -{ - npc_weapon_inspector_valarjar(Creature* creature) : ScriptedAI(creature), - _randomWeapons({ { ITEM_HOV_2H_AXE, 0 }, { ITEM_HOV_1H_SWORD, ITEM_HOV_SHIELD_2 } }) { } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - - void Reset() override - { - _scheduler.Schedule(15s, 20s, [this](TaskContext context) - { - me->SetAIAnimKitId(0); - std::pair<uint32, uint32> weapons = Trinity::Containers::SelectRandomContainerElement(_randomWeapons); - me->SetVirtualItem(0, weapons.first); - me->SetVirtualItem(1, weapons.second); - - context.Schedule(8s, 10s, [this](TaskContext context) - { - me->SetVirtualItem(0, 0); - me->SetVirtualItem(1, 0); - context.Schedule(10s, [this](TaskContext /*context*/) - { - me->SetAIAnimKitId(1583); - }); - }); - - context.Repeat(30s); - }); - } - -private: - TaskScheduler _scheduler; - std::unordered_set<std::pair<uint32, uint32>> _randomWeapons; -}; - -class scene_odyn_intro : public SceneScript -{ -public: - scene_odyn_intro() : SceneScript("scene_odyn_intro") { } - - void OnSceneStart(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - PhasingHandler::RemovePhase(player, PHASE_DANICA, false); - PhasingHandler::RemovePhase(player, PHASE_ODYN, true); - player->SetControlled(true, UNIT_STATE_ROOT); - } - - // Called when a scene is canceled - void OnSceneCancel(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - Finish(player); - } - - // Called when a scene is completed - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - Finish(player); - } - - void Finish(Player* player) - { - PhasingHandler::AddPhase(player, PHASE_ODYN, true); - player->SetControlled(false, UNIT_STATE_ROOT); - player->CastSpell(player, SPELL_CANCEL_COMPLETE_SCENE_WARRIOR_ORDER_FORMATION); - } -}; - -void AddSC_orderhall_warrior() -{ - RegisterCreatureAI(npc_danica_the_reclaimer); - RegisterCreatureAI(npc_feasting_valarjar); - RegisterCreatureAI(npc_incoming_valarjar_aspirant_1); - RegisterCreatureAI(npc_incoming_valarjar_aspirant_2); - RegisterCreatureAI(npc_leaving_valarjar_1); - RegisterCreatureAI(npc_leaving_valarjar_2); - RegisterCreatureAI(npc_odyn); - RegisterCreatureAI(npc_spectating_valarjar); - RegisterCreatureAI(npc_valkyr_of_odyn_1); - RegisterCreatureAI(npc_valkyr_of_odyn_2); - RegisterCreatureAI(npc_valkyr_of_odyn_3); - RegisterCreatureAI(npc_valkyr_of_odyn_4); - RegisterCreatureAI(npc_valkyr_of_odyn_5); - RegisterCreatureAI(npc_valkyr_of_odyn_6); - RegisterCreatureAI(npc_valkyr_of_odyn_7); - RegisterCreatureAI(npc_weapon_inspector_valarjar); - new scene_odyn_intro(); -} diff --git a/src/server/scripts/Draenor/draenor_script_loader.cpp b/src/server/scripts/Draenor/draenor_script_loader.cpp deleted file mode 100644 index 2d8e1f17915..00000000000 --- a/src/server/scripts/Draenor/draenor_script_loader.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - - // This is where scripts' loading functions should be declared: -void AddSC_assault_on_the_dark_portal(); -void AddSC_draenor_shadowmoon_valley(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddDraenorScripts() -{ - AddSC_assault_on_the_dark_portal(); - AddSC_draenor_shadowmoon_valley(); -} diff --git a/src/server/scripts/Draenor/zone_assault_on_the_dark_portal.cpp b/src/server/scripts/Draenor/zone_assault_on_the_dark_portal.cpp deleted file mode 100644 index 4ac8dea6db0..00000000000 --- a/src/server/scripts/Draenor/zone_assault_on_the_dark_portal.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "PhasingHandler.h" -#include "Player.h" -#include "QuestDef.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellScript.h" - -enum AssaultOnTheDarkPortalSpells -{ - SPELL_BLEEDING_HOLLOW_HOLDOUT = 164609, - SPELL_BLEEDING_HOLLOW_TRAIL_OF_FLAME = 164611, - SPELL_CANCEL_TRAIL_OF_FLAME_VISUAL = 165993, - SPELL_DARK_PORTAL_RUN_AWAY = 158985, - SPELL_HUT_CREDIT = 164613, // Serverside Spell - SPELL_PUSH_ARMY = 165072, - SPELL_TRAIL_OF_FLAME_LARGE = 165991 -}; - -enum AssaultOnTheDarkPortalQuests -{ - QUEST_FLAG_ARMY_PUSHED = 35297 -}; - -// 621 - Dark Portal: Run away -class scene_dark_portal_run_away : public SceneScript -{ -public: - scene_dark_portal_run_away() : SceneScript("scene_dark_portal_run_away") { } - - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->RemoveAurasDueToSpell(SPELL_DARK_PORTAL_RUN_AWAY); - PhasingHandler::OnConditionChange(player); - } -}; - -// 34420 - The Cost of War -class quest_the_cost_of_war : public QuestScript -{ -public: - quest_the_cost_of_war() : QuestScript("quest_the_cost_of_war") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - if (newStatus == QUEST_STATUS_NONE) - { - player->RemoveAurasDueToSpell(SPELL_DARK_PORTAL_RUN_AWAY); - PhasingHandler::OnConditionChange(player); - } - else if (newStatus == QUEST_STATUS_INCOMPLETE) - { - player->CastSpell(player, SPELL_DARK_PORTAL_RUN_AWAY, TRIGGERED_FULL_MASK); - PhasingHandler::OnConditionChange(player); - } - } -}; - -// 34422 - Blaze of Glory -class quest_blaze_of_glory : public QuestScript -{ -public: - quest_blaze_of_glory() : QuestScript("quest_blaze_of_glory") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - if (newStatus == QUEST_STATUS_NONE) - { - player->RemoveAurasDueToSpell(SPELL_BLEEDING_HOLLOW_HOLDOUT); - player->RemoveAurasDueToSpell(SPELL_BLEEDING_HOLLOW_TRAIL_OF_FLAME); - player->RemoveAurasDueToSpell(SPELL_PUSH_ARMY); - player->RemoveRewardedQuest(QUEST_FLAG_ARMY_PUSHED); - PhasingHandler::OnConditionChange(player); - } - else if (newStatus == QUEST_STATUS_INCOMPLETE) - PhasingHandler::OnConditionChange(player); - else if (newStatus == QUEST_STATUS_COMPLETE) - player->RemoveAurasDueToSpell(SPELL_BLEEDING_HOLLOW_TRAIL_OF_FLAME); - } -}; - -// 770 - Bleeding Hollow: Holdout -class scene_bleeding_hollow_holdout : public SceneScript -{ -public: - scene_bleeding_hollow_holdout() : SceneScript("scene_bleeding_hollow_holdout") { } - - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->RemoveAurasDueToSpell(SPELL_BLEEDING_HOLLOW_HOLDOUT); - PhasingHandler::OnConditionChange(player); - } - - void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override - { - if (triggerName == "Push") - player->CastSpell(player, SPELL_PUSH_ARMY, false); - } -}; - -// 771 - Bleeding Hollow: Trail of Flame -class scene_bleeding_hollow_trail_of_flame : public SceneScript -{ - public: - scene_bleeding_hollow_trail_of_flame() : SceneScript("scene_bleeding_hollow_trail_of_flame") { } - - void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override - { - if (triggerName == "Visual") - player->CastSpell(player, SPELL_TRAIL_OF_FLAME_LARGE, true); - else if (triggerName == "Clear") - player->CastSpell(player, SPELL_CANCEL_TRAIL_OF_FLAME_VISUAL, true); - else if (triggerName == "Credit") - player->CastSpell(player, SPELL_HUT_CREDIT, true); - } -}; - -void AddSC_assault_on_the_dark_portal() -{ - new scene_dark_portal_run_away(); - new quest_the_cost_of_war(); - new quest_blaze_of_glory(); - new scene_bleeding_hollow_holdout(); - new scene_bleeding_hollow_trail_of_flame(); -}; diff --git a/src/server/scripts/Draenor/zone_draenor_shadowmoon_valley.cpp b/src/server/scripts/Draenor/zone_draenor_shadowmoon_valley.cpp deleted file mode 100644 index 6be13594502..00000000000 --- a/src/server/scripts/Draenor/zone_draenor_shadowmoon_valley.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "PhasingHandler.h" -#include "Player.h" -#include "QuestDef.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "SpellScript.h" - -// 79243 - Baros Alexston -enum BarosAlexstonMisc -{ - // Quest - QUEST_ESTABLISH_YOUR_GARRISON = 34586, - - // Gossip - GOSSIP_OPTION_ESTABLISH_GARRISON = 0, - - // Text - SAY_START_CONSTRUCTION = 0, - - // Spells - SPELL_QUEST_34586_KILLCREDIT = 161033, - SPELL_CREATE_GARRISON_SHADOWMOON_VALLEY_ALLIANCE = 156020, - SPELL_DESPAWN_ALL_SUMMONS_GARRISON_INTRO_ONLY = 160938 -}; - -Position const GarrisonLevelOneCreationPlayerPosition = { 1904.58f, 312.906f, 88.9542f, 4.303615f }; - -struct npc_baros_alexston : public ScriptedAI -{ - npc_baros_alexston(Creature* creature) : ScriptedAI(creature) { } - - bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override - { - if (gossipListId == GOSSIP_OPTION_ESTABLISH_GARRISON) - { - CloseGossipMenuFor(player); - player->CastSpell(player, SPELL_QUEST_34586_KILLCREDIT, true); - player->CastSpell(player, SPELL_CREATE_GARRISON_SHADOWMOON_VALLEY_ALLIANCE, true); - player->CastSpell(player, SPELL_DESPAWN_ALL_SUMMONS_GARRISON_INTRO_ONLY, true); - player->NearTeleportTo(GarrisonLevelOneCreationPlayerPosition); - - PhasingHandler::OnConditionChange(player); - } - - return true; - } - - void OnQuestAccept(Player* player , Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_ESTABLISH_YOUR_GARRISON) - Talk(SAY_START_CONSTRUCTION, player); - } -}; - -void AddSC_draenor_shadowmoon_valley() -{ - RegisterCreatureAI(npc_baros_alexston); -}; diff --git a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.cpp b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.cpp deleted file mode 100644 index 0a7268a10eb..00000000000 --- a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTrigger.h" -#include "AreaTriggerAI.h" -#include "Conversation.h" -#include "InstanceScript.h" -#include "MotionMaster.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Unit.h" -#include "aberrus_the_shadowed_crucible.h" - -enum AberrusEvents -{ - EVENT_SABELLIAN_MOVE = 1, - EVENT_SABELLIAN_MOVE_HOME_POS, - EVENT_KAZZARA_INTRO, - EVENT_KAZZARA_INTRO_DONE -}; - -enum AberrusPaths -{ - PATH_SARKARETH = (202416 * 10) << 3, - PATH_WINGLORD_DEZRAN = (202610 * 10) << 3, - PATH_ZSKARN = (202637 * 10) << 3 -}; - -enum AberrusSpells -{ - SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_1 = 400785, // Sabellian and Wrathion - SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_2 = 403340, // Sabellian and Sarkareth -}; - -enum AberrusMisc -{ - // Sabellian intro - CONVO_ACTOR_IDX_SABELLIAN = 0, - - CONVO_SABELLIAN_INTRO_LINE_01 = 56690, - CONVO_SABELLIAN_INTRO_LINE_02 = 56692, - - // Kazzara intro - CONVO_ACTOR_IDX_WINGLORD_DEZRAN = 0, - CONVO_ACTOR_IDX_ZSKARN = 1, - CONVO_ACTOR_IDX_SARKARETH = 2, - - CONVO_SARKARETH_LAST_LINE = 57821 -}; - -Position const SabellianIntroConvoMovePosition = { 2250.6372f, 2482.3003f, 711.9592f }; - -// Id 26 - Areatrigger -struct at_aberrus_sabellian_conversation_intro : AreaTriggerAI -{ - at_aberrus_sabellian_conversation_intro(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - Creature* sabellian = unit->FindNearestCreature(NPC_SABELLIAN_AT_ABERRUS_ENTRANCE, 50.0f); - - if (!sabellian) - return; - - sabellian->CastSpell(nullptr, SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_1); - at->Remove(); - } -}; - -// Id 27 - Areatrigger -struct at_aberrus_sarkareth_conversation_intro : AreaTriggerAI -{ - at_aberrus_sarkareth_conversation_intro(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - Creature* sabellian = unit->FindNearestCreature(NPC_SABELLIAN_AT_ABERRUS_ENTRANCE, 50.0f); - - if (!sabellian) - return; - - sabellian->CastSpell(nullptr, SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_2); - at->Remove(); - } -}; - -// 20800 - Conversation -class conversation_aberrus_sabellian_intro : public ConversationScript -{ -public: - conversation_aberrus_sabellian_intro() : ConversationScript("conversation_aberrus_sabellian_intro") { } - - void OnConversationStart(Conversation* conversation) override - { - if (Milliseconds const* sabellianMoveStartTime = conversation->GetLineStartTime(DEFAULT_LOCALE, CONVO_SABELLIAN_INTRO_LINE_01)) - _events.ScheduleEvent(EVENT_SABELLIAN_MOVE, *sabellianMoveStartTime); - - if (Milliseconds const* sabellianHomeMoveStartTime = conversation->GetLineStartTime(DEFAULT_LOCALE, CONVO_SABELLIAN_INTRO_LINE_02)) - _events.ScheduleEvent(EVENT_SABELLIAN_MOVE_HOME_POS, *sabellianHomeMoveStartTime + Seconds(2)); - } - - void OnConversationUpdate(Conversation* conversation, uint32 diff) override - { - _events.Update(diff); - - switch (_events.ExecuteEvent()) - { - case EVENT_SABELLIAN_MOVE: - { - Creature* sabellian = conversation->GetActorCreature(CONVO_ACTOR_IDX_SABELLIAN); - if (!sabellian) - break; - - sabellian->SetWalk(true); - sabellian->GetMotionMaster()->MovePoint(0, SabellianIntroConvoMovePosition); - break; - } - case EVENT_SABELLIAN_MOVE_HOME_POS: - { - Creature* sabellian = conversation->GetActorCreature(CONVO_ACTOR_IDX_SABELLIAN); - if (!sabellian) - break; - - sabellian->SetWalk(true); - sabellian->GetMotionMaster()->MovePoint(0, sabellian->ToCreature()->GetHomePosition(), false, sabellian->ToCreature()->GetHomePosition().GetOrientation()); - break; - } - default: - break; - } - } - -private: - EventMap _events; -}; - -// 20985 - Conversation -class conversation_aberrus_kazzara_intro : public ConversationScript -{ -public: - conversation_aberrus_kazzara_intro() : ConversationScript("conversation_aberrus_kazzara_intro") { } - - void OnConversationStart(Conversation* conversation) override - { - _events.ScheduleEvent(EVENT_KAZZARA_INTRO, conversation->GetLineEndTime(DEFAULT_LOCALE, CONVO_SARKARETH_LAST_LINE)); - } - - void OnConversationUpdate(Conversation* conversation, uint32 diff) override - { - _events.Update(diff); - - switch (_events.ExecuteEvent()) - { - case EVENT_KAZZARA_INTRO: - { - Creature* winglordDezran = conversation->GetActorCreature(CONVO_ACTOR_IDX_WINGLORD_DEZRAN); - Creature* zskarn = conversation->GetActorCreature(CONVO_ACTOR_IDX_ZSKARN); - Creature* sarkareth = conversation->GetActorCreature(CONVO_ACTOR_IDX_SARKARETH); - - if (!winglordDezran || !zskarn || !sarkareth) - return; - - sarkareth->GetMotionMaster()->MovePath(PATH_SARKARETH, false); - sarkareth->DespawnOrUnsummon(45s); - - winglordDezran->GetMotionMaster()->MovePath(PATH_WINGLORD_DEZRAN, false); - winglordDezran->DespawnOrUnsummon(45s); - - zskarn->GetMotionMaster()->MovePath(PATH_ZSKARN, false); - zskarn->DespawnOrUnsummon(45s, Seconds::max()); // override respawn time to prevent instant respawn due to CREATURE_FLAG_EXTRA_DUNGEON_BOSS - - if (InstanceScript* instance = conversation->GetInstanceScript()) - { - instance->SetData(DATA_KAZZARA_INTRO_DONE, 1); - if (Creature* kazzara = instance->GetCreature(DATA_KAZZARA_THE_HELLFORGED)) - kazzara->AI()->DoAction(ACTION_START_KAZZARA_INTRO); - } - break; - } - default: - break; - } - } - -private: - EventMap _events; -}; - -void AddSC_aberrus_the_shadowed_crucible() -{ - RegisterAreaTriggerAI(at_aberrus_sabellian_conversation_intro); - RegisterAreaTriggerAI(at_aberrus_sarkareth_conversation_intro); - - new conversation_aberrus_sabellian_intro(); - new conversation_aberrus_kazzara_intro(); -} diff --git a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.h b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.h deleted file mode 100644 index e1797e26faf..00000000000 --- a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -#ifndef DEF_ABERRUS_THE_SHADOWED_CRUCIBLE_H_ -#define DEF_ABERRUS_THE_SHADOWED_CRUCIBLE_H_ - -#include "CreatureAIImpl.h" - -#define ATSCScriptName "instance_aberrus_the_shadowed_crucible" -#define DataHeader "Aberrus" - -uint32 const EncounterCount = 9; - -enum AberrusDataTypes -{ - // Encounters - DATA_KAZZARA_THE_HELLFORGED = 0, - DATA_THE_AMALGAMATION_CHAMBER = 1, - DATA_THE_FORGOTTEN_EXPERIMENTS = 2, - DATA_ASSAULT_OF_THE_ZAQALI = 3, - DATA_RASHOK_THE_ELDER = 4, - DATA_ZSKARN_THE_VIGILANT_STEWARD = 5, - DATA_MAGMORAX = 6, - DATA_ECHO_OF_NELTHARION = 7, - DATA_SCALECOMMANDER_SARKARETH = 8, - - // Additional Data - DATA_KAZZARA_GATE, - - // Misc - DATA_KAZZARA_INTRO_DONE -}; - -enum AberrusCreatureIds -{ - // Bosses - BOSS_KAZZARA_THE_HELLFORGED = 201261, - - BOSS_ETERNAL_BLAZE = 201773, - BOSS_ESSENCE_OF_SHADOW = 201774, - BOSS_SHADOWFLAME_AMALGAMATION = 201934, - - BOSS_NELDRIS = 200912, - BOSS_THADRION = 200913, - BOSS_RIONTHUS = 200918, - - BOSS_WARLORD_KAGNI = 199659, - BOSS_RASHOK_THE_ELDER = 201320, - BOSS_ZSKARN_THE_VIGILANT_STEWARD = 202637, - BOSS_MAGMORAX = 201579, - BOSS_ECHO_OF_NELTHARION = 204223, - BOSS_SCALECOMMANDER_SARKARETH = 205319, - - // Misc - NPC_SABELLIAN_AT_ABERRUS_ENTRANCE = 201575 -}; - -enum AberrusGameObjectIds -{ - GO_KAZZARA_DOOR = 398742, - GO_KAZZARA_GATE = 397996, - GO_INVISIBLE_DOOR = 398588 -}; - -enum AberrusSharedActions -{ - ACTION_START_KAZZARA_INTRO = 0, -}; - -template <class AI, class T> -inline AI* GetAberrusTheShadowedCrucibleAI(T* obj) -{ - return GetInstanceAI<AI>(obj, ATSCScriptName); -} - -#define RegisterAberrusTheShadowedCrucibleCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAberrusTheShadowedCrucibleAI) - -#endif diff --git a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/boss_kazzara_the_hellforged.cpp b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/boss_kazzara_the_hellforged.cpp deleted file mode 100644 index 2cdaaedd6df..00000000000 --- a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/boss_kazzara_the_hellforged.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "CellImpl.h" -#include "GameObject.h" -#include "GridNotifiersImpl.h" -#include "InstanceScript.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "aberrus_the_shadowed_crucible.h" - -enum KazzaraSpells -{ - // Sundered NPCs - SPELL_FEAR = 220540, - - // Kazzara - SPELL_DREAD_LANDING = 411872, - SPELL_KAZZARA_INTRO = 410541 -}; - -// 201261 - Kazzara the Hellforged -struct boss_kazzara_the_hellforged : public BossAI -{ - boss_kazzara_the_hellforged(Creature* creature) : BossAI(creature, DATA_KAZZARA_THE_HELLFORGED) { } - - void JustAppeared() override - { - if (!instance->GetData(DATA_KAZZARA_INTRO_DONE)) - { - me->SetUninteractible(true); - me->SetImmuneToAll(true); - me->SetVisible(false); - } - } - - void DoAction(int32 actionId) override - { - switch (actionId) - { - case ACTION_START_KAZZARA_INTRO: - { - if (GameObject* gate = instance->GetGameObject(DATA_KAZZARA_GATE)) - { - gate->SetFlag(GO_FLAG_IN_USE); - gate->SetGoState(GO_STATE_READY); - } - - me->SetVisible(true); - - DoCast(SPELL_DREAD_LANDING); - DoCast(SPELL_KAZZARA_INTRO); - - scheduler.Schedule(1s + 500ms, [this](TaskContext /*context*/) - { - std::vector<Creature*> sunderedMobs; - GetCreatureListWithOptionsInGrid(sunderedMobs, me, 50.0f, { .StringId = "sundered_mob" }); - for (Creature* sunderedMob : sunderedMobs) - { - if (!sunderedMob->IsAlive() || sunderedMob->IsInCombat()) - continue; - - sunderedMob->CastSpell(nullptr, SPELL_FEAR, false); - } - }); - - scheduler.Schedule(12s, [this](TaskContext /*context*/) - { - me->SetUninteractible(false); - me->SetImmuneToAll(false); - }); - break; - } - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - scheduler.Update(diff); - } -}; - -void AddSC_boss_kazzara_the_hellforged() -{ - RegisterAberrusTheShadowedCrucibleCreatureAI(boss_kazzara_the_hellforged); -} diff --git a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/instance_aberrus_the_shadowed_crucible.cpp b/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/instance_aberrus_the_shadowed_crucible.cpp deleted file mode 100644 index d6e21bd63c8..00000000000 --- a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/instance_aberrus_the_shadowed_crucible.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "Creature.h" -#include "InstanceScript.h" -#include "ScriptMgr.h" -#include "aberrus_the_shadowed_crucible.h" - -ObjectData const creatureData[] = -{ - { BOSS_KAZZARA_THE_HELLFORGED, DATA_KAZZARA_THE_HELLFORGED }, - { BOSS_SHADOWFLAME_AMALGAMATION, DATA_THE_AMALGAMATION_CHAMBER }, - { BOSS_RIONTHUS, DATA_THE_FORGOTTEN_EXPERIMENTS }, - { BOSS_WARLORD_KAGNI, DATA_ASSAULT_OF_THE_ZAQALI }, - { BOSS_RASHOK_THE_ELDER, DATA_RASHOK_THE_ELDER }, - { BOSS_ZSKARN_THE_VIGILANT_STEWARD, DATA_ZSKARN_THE_VIGILANT_STEWARD }, - { BOSS_MAGMORAX, DATA_MAGMORAX }, - { BOSS_ECHO_OF_NELTHARION, DATA_ECHO_OF_NELTHARION }, - { BOSS_SCALECOMMANDER_SARKARETH, DATA_SCALECOMMANDER_SARKARETH }, - { 0, 0 } // END -}; - -DoorData const doorData[] = -{ - { GO_KAZZARA_DOOR, DATA_KAZZARA_THE_HELLFORGED, EncounterDoorBehavior::OpenWhenNotInProgress }, - { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } // END -}; - -ObjectData const objectData[] = -{ - { GO_KAZZARA_GATE, DATA_KAZZARA_GATE }, - { 0, 0 } // END -}; - -DungeonEncounterData const encounters[] = -{ - { DATA_KAZZARA_THE_HELLFORGED, {{ 2688 }} }, - { DATA_THE_AMALGAMATION_CHAMBER, {{ 2687 }} }, - { DATA_THE_FORGOTTEN_EXPERIMENTS, {{ 2693 }} }, - { DATA_ASSAULT_OF_THE_ZAQALI, {{ 2682 }} }, - { DATA_RASHOK_THE_ELDER, {{ 2680 }} }, - { DATA_ZSKARN_THE_VIGILANT_STEWARD, {{ 2689 }} }, - { DATA_MAGMORAX, {{ 2683 }} }, - { DATA_ECHO_OF_NELTHARION, {{ 2684 }} }, - { DATA_SCALECOMMANDER_SARKARETH, {{ 2685 }} } -}; - -enum AberrusInstanceCreatureIds -{ - NPC_SCALECOMMANDER_SARKARETH_AT_KAZZARA = 202416 -}; - -enum AberrusInstanceSpells -{ - SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_3 = 403409 // Winglord Dezran, Sarkareth and Zskarn (Kazzara Summon) -}; - -class instance_aberrus_the_shadowed_crucible : public InstanceMapScript -{ -public: - instance_aberrus_the_shadowed_crucible() : InstanceMapScript(ATSCScriptName, 2569) { } - - struct instance_aberrus_the_shadowed_crucible_InstanceMapScript: public InstanceScript - { - instance_aberrus_the_shadowed_crucible_InstanceMapScript(InstanceMap* map) : InstanceScript(map) - { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - LoadObjectData(creatureData, objectData); - LoadDoorData(doorData); - LoadDungeonEncounterData(encounters); - - _kazzaraIntroDone = false; - _deadSunderedMobs = 0; - } - - uint32 GetData(uint32 dataId) const override - { - switch (dataId) - { - case DATA_KAZZARA_INTRO_DONE: - return _kazzaraIntroDone ? 1 : 0; - default: - break; - } - return 0; - } - - void SetData(uint32 dataId, uint32 /*value*/) override - { - switch (dataId) - { - case DATA_KAZZARA_INTRO_DONE: - _kazzaraIntroDone = true; // no need to pass value, it will never reset to false - break; - default: - break; - } - } - - void OnUnitDeath(Unit* unit) override - { - Creature* creature = unit->ToCreature(); - if (!creature) - return; - - if (creature->HasStringId("sundered_mob")) - { - if (_deadSunderedMobs >= 6) - return; - - _deadSunderedMobs++; - if (_deadSunderedMobs >= 6) - { - Creature* sarkareth = creature->FindNearestCreature(NPC_SCALECOMMANDER_SARKARETH_AT_KAZZARA, 300.0f); - if (!sarkareth) - return; - sarkareth->CastSpell(nullptr, SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_3); - } - } - } - - private: - uint8 _deadSunderedMobs; - bool _kazzaraIntroDone; - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_aberrus_the_shadowed_crucible_InstanceMapScript(map); - } -}; - -void AddSC_instance_aberrus_the_shadowed_crucible() -{ - new instance_aberrus_the_shadowed_crucible(); -} diff --git a/src/server/scripts/DragonIsles/AzureVault/azure_vault.h b/src/server/scripts/DragonIsles/AzureVault/azure_vault.h deleted file mode 100644 index 8f812053155..00000000000 --- a/src/server/scripts/DragonIsles/AzureVault/azure_vault.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -#ifndef DEF_AZURE_VAULT_H_ -#define DEF_AZURE_VAULT_H_ - -#include "CreatureAIImpl.h" - -#define DataHeader "AzureVault" -#define AVScriptName "instance_azure_vault" - -uint32 const EncounterCount = 4; - -enum AVDataTypes -{ - // Encounters - DATA_LEYMOR = 0, - DATA_AZUREBLADE, - DATA_TELASH_GREYWING, - DATA_UMBRELSKUL, - - DATA_LEYMOR_INTRO_DONE -}; - -enum AVCreatureIds -{ - // Bosses - BOSS_LEYMOR = 186644, - BOSS_AZUREBLADE = 186739, - BOSS_TELASH_GREYWING = 199614, - BOSS_UMBRELSKUL = 186738, - - // Leymor - NPC_ARCANE_TENDER = 191164, -}; - -enum AVGameObjectIds -{ - GO_ARCANE_VAULTS_DOOR_LEYMOR_ENTRANCE = 380536, - GO_ARCANE_VAULTS_DOOR_LEYMOR_EXIT = 377951 -}; - -template <class AI, class T> -inline AI* GetAzureVaultAI(T* obj) -{ - return GetInstanceAI<AI>(obj, AVScriptName); -} - -#define RegisterAzureVaultCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAzureVaultAI) - -#endif diff --git a/src/server/scripts/DragonIsles/AzureVault/boss_leymor.cpp b/src/server/scripts/DragonIsles/AzureVault/boss_leymor.cpp deleted file mode 100644 index 903c57b830d..00000000000 --- a/src/server/scripts/DragonIsles/AzureVault/boss_leymor.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTrigger.h" -#include "AreaTriggerAI.h" -#include "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "InstanceScript.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellScript.h" -#include "SpellAuras.h" -#include "SharedDefines.h" -#include "TemporarySummon.h" -#include "azure_vault.h" - -enum LeymorSpells -{ - // Leymor - SPELL_STASIS = 375729, - SPELL_ARCANE_ERUPTION = 375749, - SPELL_LEY_LINE_SPROUTS = 374364, - SPELL_LEY_LINE_SPROUTS_MISSILE = 374362, - SPELL_CONSUMING_STOMP = 374720, - SPELL_CONSUMING_STOMP_DAMAGE = 374731, - SPELL_ERUPTING_FISSURE = 386660, - SPELL_ERUPTING_FISSURE_SPROUT_SELECTOR = 394154, - SPELL_EXPLOSIVE_BRAND = 374567, - SPELL_EXPLOSIVE_BRAND_DAMAGE = 374570, - SPELL_EXPLOSIVE_BRAND_KNOCKBACK = 374582, - SPELL_INFUSED_STRIKE = 374789, - - // Ley-Line Sprout - SPELL_VOLATILE_SAPLING = 388654, - SPELL_LEY_LINE_SPROUT_AT = 374161, - SPELL_ARCANE_POWER = 374736, - - // Volatile Sapling - SPELL_SAPPY_BURST = 375591, - - // Arcane Tender - SPELL_STASIS_RITUAL = 375732, - SPELL_STASIS_RITUAL_MISSILE = 375738, - SPELL_ERRATIC_GROWTH_CHANNEL = 375596, - SPELL_WILD_ERUPTION = 375652, - SPELL_WILD_ERUPTION_MISSILE = 375650 -}; - -enum LeymorEvents -{ - // Leymor - EVENT_LEYMOR_AWAKE = 1, - EVENT_LEY_LINE_SPROUTS, - EVENT_CONSUMING_STOMP, - EVENT_ERUPTING_FISSURE, - EVENT_EXPLOSIVE_BRAND, - EVENT_INFUSED_STRIKE, - - // Arcane Tender - EVENT_ERRATIC_GROWTH = 1, - EVENT_WILD_ERUPTION, - EVENT_INFUSED_GROUND, -}; - -enum LeymorTexts -{ - SAY_ANNOUNCE_AWAKEN = 0 -}; - -enum LeymorVisuals -{ - SPELL_VISUAL_KIT_SPROUT_DEATH = 159239 -}; - -enum LeymorNpcs -{ - NPC_LEYLINE_SPROUTS = 190509 -}; - -enum LeymorActions -{ - ACTION_ARCANE_TENDER_DEATH = 1 -}; - -// 186644 - Leymor -struct boss_leymor : public BossAI -{ - boss_leymor(Creature* creature) : BossAI(creature, DATA_LEYMOR), _killedArcaneTender(0) { } - - void JustAppeared() override - { - if (instance->GetData(DATA_LEYMOR_INTRO_DONE)) - return; - - me->SetUnitFlag(UnitFlags(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC)); - DoCastSelf(SPELL_STASIS); - } - - void DoAction(int32 action) override - { - if (action == ACTION_ARCANE_TENDER_DEATH) - { - _killedArcaneTender++; - if (_killedArcaneTender >= 3) - { - instance->SetData(DATA_LEYMOR_INTRO_DONE, 1); - - scheduler.Schedule(1s, [this](TaskContext /*context*/) - { - me->RemoveAurasDueToSpell(SPELL_STASIS); - me->RemoveUnitFlag(UnitFlags(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC)); - DoCastSelf(SPELL_ARCANE_ERUPTION); - Talk(SAY_ANNOUNCE_AWAKEN); - }); - } - } - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - - summons.DespawnAll(); - _EnterEvadeMode(); - _DespawnAtEvade(); - } - - void OnChannelFinished(SpellInfo const* spell) override - { - if (spell->Id == SPELL_CONSUMING_STOMP) - DoCastAOE(SPELL_CONSUMING_STOMP_DAMAGE, true); - }; - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - events.ScheduleEvent(EVENT_LEY_LINE_SPROUTS, 3s); - events.ScheduleEvent(EVENT_CONSUMING_STOMP, 45s); - events.ScheduleEvent(EVENT_ERUPTING_FISSURE, 20s); - events.ScheduleEvent(EVENT_EXPLOSIVE_BRAND, 31s); - events.ScheduleEvent(EVENT_INFUSED_STRIKE, 10s); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); - } - - void UpdateAI(uint32 diff) override - { - scheduler.Update(diff); - - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_LEY_LINE_SPROUTS: - DoCastSelf(SPELL_LEY_LINE_SPROUTS); - events.ScheduleEvent(EVENT_LEY_LINE_SPROUTS, 48s); - break; - case EVENT_CONSUMING_STOMP: - DoCastSelf(SPELL_CONSUMING_STOMP); - events.ScheduleEvent(EVENT_CONSUMING_STOMP, 48s); - break; - case EVENT_ERUPTING_FISSURE: - DoCastVictim(SPELL_ERUPTING_FISSURE); - events.ScheduleEvent(EVENT_ERUPTING_FISSURE, 48s); - break; - case EVENT_EXPLOSIVE_BRAND: - DoCastSelf(SPELL_EXPLOSIVE_BRAND); - events.ScheduleEvent(EVENT_EXPLOSIVE_BRAND, 48s); - break; - case EVENT_INFUSED_STRIKE: - DoCastVictim(SPELL_INFUSED_STRIKE); - events.ScheduleEvent(EVENT_INFUSED_STRIKE, 48s); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } - -private: - int32 _killedArcaneTender; -}; - -// 191164 - Arcane Tender -struct npc_arcane_tender : public ScriptedAI -{ - npc_arcane_tender(Creature* creature) : ScriptedAI(creature) { } - - void JustDied(Unit* /*killer*/) override - { - Creature* leymor = me->GetInstanceScript()->GetCreature(DATA_LEYMOR); - if (!leymor) - return; - - if (!leymor->IsAIEnabled()) - return; - - leymor->AI()->DoAction(ACTION_ARCANE_TENDER_DEATH); - } - - void JustAppeared() override - { - Creature* leymor = me->GetInstanceScript()->GetCreature(DATA_LEYMOR); - if (!leymor) - return; - - DoCast(leymor, SPELL_STASIS_RITUAL); - } - - void JustReachedHome() override - { - JustAppeared(); - } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_ERRATIC_GROWTH, 22s); - _events.ScheduleEvent(EVENT_WILD_ERUPTION, 12s); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_ERRATIC_GROWTH: - DoCastAOE(SPELL_ERRATIC_GROWTH_CHANNEL); - _events.ScheduleEvent(EVENT_ERRATIC_GROWTH, 22s); - break; - case EVENT_WILD_ERUPTION: - DoCastAOE(SPELL_WILD_ERUPTION); - _events.ScheduleEvent(EVENT_WILD_ERUPTION, 12s); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } -private: - EventMap _events; -}; - -// 190509 - Ley-Line Sprout -struct npc_ley_line_sprouts : public ScriptedAI -{ - npc_ley_line_sprouts(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - DoCastSelf(SPELL_LEY_LINE_SPROUT_AT); - - DoCastAOE(SPELL_ARCANE_POWER, true); - } - - void JustSummoned(Creature* summon) override - { - Creature* leymor = me->GetInstanceScript()->GetCreature(DATA_LEYMOR); - if (!leymor) - return; - - if (!leymor->IsAIEnabled()) - return; - - leymor->AI()->JustSummoned(summon); - } - - void JustDied(Unit* /*killer*/) override - { - if (IsMythic() || IsMythicPlus()) - DoCastAOE(SPELL_VOLATILE_SAPLING, true); - - if (TempSummon* tempSummon = me->ToTempSummon()) - { - if (Unit* summoner = tempSummon->GetSummonerUnit()) - { - if (Aura* aura = summoner->GetAura(SPELL_ARCANE_POWER)) - aura->ModStackAmount(-1); - } - } - } - - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_EXPLOSIVE_BRAND_DAMAGE && spellInfo->Id != SPELL_ERUPTING_FISSURE_SPROUT_SELECTOR) - return; - - me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SPROUT_DEATH, 0, 0); - me->KillSelf(); - } -}; - -// 196559 - Volatile Sapling -struct npc_volatile_sapling : public ScriptedAI -{ - npc_volatile_sapling(Creature* creature) : ScriptedAI(creature), _isSappyBurstCast(false) { } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (me->GetHealth() <= damage) - { - damage = me->GetHealth() - 1; - - if (!_isSappyBurstCast) - { - me->CastSpell(nullptr, SPELL_SAPPY_BURST, false); - _isSappyBurstCast = true; - } - } - } - - void OnSpellFailed(SpellInfo const* spell) override - { - if (spell->Id != SPELL_SAPPY_BURST) - return; - - me->KillSelf(); - } - -private: - bool _isSappyBurstCast; -}; - -static Position const LeyLineSproutGroupOrigin[] = -{ - { -5129.39f, 1253.30f, 555.58f }, - { -5101.68f, 1253.71f, 555.90f }, - { -5114.70f, 1230.28f, 555.89f }, - { -5141.62f, 1230.33f, 555.83f }, - { -5155.62f, 1253.60f, 555.87f }, - { -5141.42f, 1276.70f, 555.89f }, - { -5114.78f, 1277.42f, 555.87f } -}; - -// 374364 - Ley-Line Sprouts -class spell_ley_line_sprouts : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_LEY_LINE_SPROUTS_MISSILE }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - for (Position const& pos : LeyLineSproutGroupOrigin) - { - for (int8 i = 0; i < 2; i++) - GetCaster()->CastSpell(pos, SPELL_LEY_LINE_SPROUTS_MISSILE, true); - } - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_ley_line_sprouts::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 375732 - Stasis Ritual -class spell_stasis_ritual : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_STASIS_RITUAL_MISSILE }); - } - - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(nullptr, SPELL_STASIS_RITUAL_MISSILE, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_stasis_ritual::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -// 375652 - Wild Eruption -class spell_wild_eruption : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WILD_ERUPTION_MISSILE }); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(*GetHitDest(), SPELL_WILD_ERUPTION_MISSILE, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_wild_eruption::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 375749 - Arcane Eruption -struct at_leymor_arcane_eruption : AreaTriggerAI -{ - at_leymor_arcane_eruption(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - unit->ApplyMovementForce(at->GetGUID(), at->GetPosition(), -20.0f, MovementForceType::Gravity); - } - - void OnUnitExit(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - unit->RemoveMovementForce(at->GetGUID()); - } -}; - -// 374567 - Explosive Brand -class spell_explosive_brand : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_EXPLOSIVE_BRAND_KNOCKBACK }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(nullptr, SPELL_EXPLOSIVE_BRAND_KNOCKBACK, true); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_explosive_brand::HandleHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA); - } -}; - -// 374567 - Explosive Brand -class spell_explosive_brand_AuraScript : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_EXPLOSIVE_BRAND_DAMAGE }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - return; - - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget(), SPELL_EXPLOSIVE_BRAND_DAMAGE, true); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_explosive_brand_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 374720 - Consuming Stomp -class spell_consuming_stomp : public AuraScript -{ - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->KillSelf(); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_consuming_stomp::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 386660 - Erupting Fissure -class spell_erupting_fissure : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ERUPTING_FISSURE_SPROUT_SELECTOR }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(*GetHitDest(), SPELL_ERUPTING_FISSURE_SPROUT_SELECTOR, true); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_erupting_fissure::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 375591 - Sappy Burst -class spell_sappy_burst : public SpellScript -{ - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - GetCaster()->KillSelf(); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_sappy_burst::HandleHitTarget, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); - } -}; - -void AddSC_boss_leymor() -{ - // Creature - RegisterAzureVaultCreatureAI(boss_leymor); - RegisterAzureVaultCreatureAI(npc_arcane_tender); - RegisterAzureVaultCreatureAI(npc_ley_line_sprouts); - RegisterAzureVaultCreatureAI(npc_volatile_sapling); - - // Spells - RegisterSpellScript(spell_ley_line_sprouts); - RegisterSpellScript(spell_stasis_ritual); - RegisterSpellScript(spell_wild_eruption); - RegisterSpellScript(spell_consuming_stomp); - RegisterSpellScript(spell_erupting_fissure); - RegisterSpellScript(spell_sappy_burst); - RegisterSpellAndAuraScriptPair(spell_explosive_brand, spell_explosive_brand_AuraScript); - - // AreaTrigger - RegisterAreaTriggerAI(at_leymor_arcane_eruption); -} diff --git a/src/server/scripts/DragonIsles/AzureVault/instance_azure_vault.cpp b/src/server/scripts/DragonIsles/AzureVault/instance_azure_vault.cpp deleted file mode 100644 index 46e6faebb01..00000000000 --- a/src/server/scripts/DragonIsles/AzureVault/instance_azure_vault.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaBoundary.h" -#include "InstanceScript.h" -#include "ScriptMgr.h" -#include "azure_vault.h" - -BossBoundaryData const boundaries = -{ - { DATA_LEYMOR, new CircleBoundary(Position(-5129.39f, 1253.30f), 75.0f) } -}; - -ObjectData const creatureData[] = -{ - { BOSS_LEYMOR, DATA_LEYMOR }, - { BOSS_AZUREBLADE, DATA_AZUREBLADE }, - { BOSS_TELASH_GREYWING, DATA_TELASH_GREYWING }, - { BOSS_UMBRELSKUL, DATA_UMBRELSKUL }, - { 0, 0 } // END -}; - -DoorData const doorData[] = -{ - { GO_ARCANE_VAULTS_DOOR_LEYMOR_ENTRANCE, DATA_LEYMOR, EncounterDoorBehavior::OpenWhenNotInProgress }, - { GO_ARCANE_VAULTS_DOOR_LEYMOR_EXIT, DATA_LEYMOR, EncounterDoorBehavior::OpenWhenDone }, - { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } // END -}; - -DungeonEncounterData const encounters[] = -{ - { DATA_LEYMOR, {{ 2582 }} }, - { DATA_AZUREBLADE, {{ 2585 }} }, - { DATA_TELASH_GREYWING, {{ 2583 }} }, - { DATA_UMBRELSKUL, {{ 2584 }} }, -}; - -class instance_azure_vault : public InstanceMapScript -{ - public: - instance_azure_vault() : InstanceMapScript(AVScriptName, 2515) { } - - struct instance_azure_vault_InstanceMapScript: public InstanceScript - { - instance_azure_vault_InstanceMapScript(InstanceMap* map) : InstanceScript(map) - { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - LoadObjectData(creatureData, nullptr); - LoadDoorData(doorData); - LoadBossBoundaries(boundaries); - LoadDungeonEncounterData(encounters); - - _leymorIntroDone = false; - } - - uint32 GetData(uint32 dataId) const override - { - switch (dataId) - { - case DATA_LEYMOR_INTRO_DONE: - return _leymorIntroDone ? 1 : 0; - default: - break; - } - return 0; - } - - void SetData(uint32 dataId, uint32 /*value*/) override - { - switch (dataId) - { - case DATA_LEYMOR_INTRO_DONE: - _leymorIntroDone = true; // no need to pass value, it will never reset to false - break; - default: - break; - } - } - - private: - bool _leymorIntroDone; - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_azure_vault_InstanceMapScript(map); - } -}; - -void AddSC_instance_azure_vault() -{ - new instance_azure_vault(); -} diff --git a/src/server/scripts/DragonIsles/RubyLifePools/instance_ruby_life_pools.cpp b/src/server/scripts/DragonIsles/RubyLifePools/instance_ruby_life_pools.cpp deleted file mode 100644 index 3db0dd199b6..00000000000 --- a/src/server/scripts/DragonIsles/RubyLifePools/instance_ruby_life_pools.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "InstanceScript.h" -#include "ScriptMgr.h" -#include "ruby_life_pools.h" - -ObjectData const creatureData[] = -{ - { BOSS_MELIDRUSSA_CHILLWORN, DATA_MELIDRUSSA_CHILLWORN }, - { BOSS_KOKIA_BLAZEHOOF, DATA_KOKIA_BLAZEHOOF }, - { BOSS_KYRAKKA, DATA_KYRAKKA_AND_ERKHART_STORMVEIN }, - { 0, 0 } // END -}; - -DoorData const doorData[] = -{ - { GO_FIRE_WALL, DATA_KOKIA_BLAZEHOOF, EncounterDoorBehavior::OpenWhenDone }, - { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } // END -}; - -DungeonEncounterData const encounters[] = -{ - { DATA_MELIDRUSSA_CHILLWORN, {{ 2609 }} }, - { DATA_KOKIA_BLAZEHOOF, {{ 2606 }} }, - { DATA_KYRAKKA_AND_ERKHART_STORMVEIN, {{ 2623 }} } -}; - -class instance_ruby_life_pools : public InstanceMapScript -{ - public: - instance_ruby_life_pools() : InstanceMapScript(RLPScriptName, 2521) { } - - struct instance_ruby_life_pools_InstanceMapScript: public InstanceScript - { - instance_ruby_life_pools_InstanceMapScript(InstanceMap* map) : InstanceScript(map) - { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - LoadObjectData(creatureData, nullptr); - LoadDoorData(doorData); - LoadDungeonEncounterData(encounters); - } - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_ruby_life_pools_InstanceMapScript(map); - } -}; - -void AddSC_instance_ruby_life_pools() -{ - new instance_ruby_life_pools(); -} diff --git a/src/server/scripts/DragonIsles/RubyLifePools/ruby_life_pools.cpp b/src/server/scripts/DragonIsles/RubyLifePools/ruby_life_pools.cpp deleted file mode 100644 index 6071c26ac87..00000000000 --- a/src/server/scripts/DragonIsles/RubyLifePools/ruby_life_pools.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "SpellAuras.h" -#include "SpellScript.h" -#include "ScriptMgr.h" -#include "Unit.h" -#include "ruby_life_pools.h" - -enum RLPSpells -{ - // Flashfrost Chillweaver - SPELL_ICE_SHIELD = 372749, - - // Primal Juggernaut - SPELL_EXCAVATE = 373497 -}; - -// 371652 - Executed -class spell_ruby_life_pools_executed : public AuraScript -{ - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->SetUnitFlag3(UNIT_FLAG3_FAKE_DEAD); - target->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); - target->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_ruby_life_pools_executed::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 384933 - Ice Shield -class spell_ruby_life_pools_ice_shield : public AuraScript -{ - void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - - if (Aura* iceShield = target->GetAura(SPELL_ICE_SHIELD)) - iceShield->RefreshDuration(); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_ruby_life_pools_ice_shield::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -// 372793 - Excavate -class spell_ruby_life_pools_excavate : public AuraScript -{ - void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) - { - if (Unit* caster = GetCaster()) - caster->CastSpell(GetTarget(), SPELL_EXCAVATE, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_ruby_life_pools_excavate::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -// 395029 - Storm Infusion -class spell_ruby_life_pools_storm_infusion : public SpellScript -{ - void SetDest(SpellDestination& dest) - { - dest.RelocateOffset({ 9.0f, 0.0f, 4.0f, 0.0f }); - } - - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_ruby_life_pools_storm_infusion::SetDest, EFFECT_1, TARGET_DEST_DEST); - } -}; - -void AddSC_ruby_life_pools() -{ - RegisterSpellScript(spell_ruby_life_pools_executed); - RegisterSpellScript(spell_ruby_life_pools_ice_shield); - RegisterSpellScript(spell_ruby_life_pools_excavate); - RegisterSpellScript(spell_ruby_life_pools_storm_infusion); -} diff --git a/src/server/scripts/DragonIsles/RubyLifePools/ruby_life_pools.h b/src/server/scripts/DragonIsles/RubyLifePools/ruby_life_pools.h deleted file mode 100644 index 20a688dba85..00000000000 --- a/src/server/scripts/DragonIsles/RubyLifePools/ruby_life_pools.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -#ifndef DEF_RUBY_LIFE_POOLS_H_ -#define DEF_RUBY_LIFE_POOLS_H_ - -#include "CreatureAIImpl.h" - -#define DataHeader "RLP" -#define RLPScriptName "instance_ruby_life_pools" - -uint32 const EncounterCount = 3; - -enum RLPDataTypes -{ - // Encounters - DATA_MELIDRUSSA_CHILLWORN = 0, - DATA_KOKIA_BLAZEHOOF = 1, - DATA_KYRAKKA_AND_ERKHART_STORMVEIN = 2 -}; - -enum RLPCreatureIds -{ - // Bosses - BOSS_MELIDRUSSA_CHILLWORN = 188252, - BOSS_KOKIA_BLAZEHOOF = 189232, - BOSS_KYRAKKA = 190484 -}; - -enum RLPGameObjectIds -{ - GO_FIRE_WALL = 377194 -}; - -template <class AI, class T> -inline AI* GetRubyLifePoolsAI(T* obj) -{ - return GetInstanceAI<AI>(obj, RLPScriptName); -} - -#define RegisterRubyLifePoolsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetRubyLifePoolsAI) - -#endif diff --git a/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp b/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp deleted file mode 100644 index 32150946143..00000000000 --- a/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -// This is where scripts' loading functions should be declared: -void AddSC_zone_the_forbidden_reach(); - -// Ruby Life Pools -void AddSC_instance_ruby_life_pools(); -void AddSC_ruby_life_pools(); - -// Azure Vault -void AddSC_instance_azure_vault(); -void AddSC_boss_leymor(); - -// Aberrus the Shadowed Crucible -void AddSC_instance_aberrus_the_shadowed_crucible(); -void AddSC_aberrus_the_shadowed_crucible(); -void AddSC_boss_kazzara_the_hellforged(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddDragonIslesScripts() -{ - AddSC_zone_the_forbidden_reach(); - - // Ruby Life Pools - AddSC_instance_ruby_life_pools(); - AddSC_ruby_life_pools(); - - // Azure Vault - AddSC_instance_azure_vault(); - AddSC_boss_leymor(); - - // Aberrus the Shadowed Crucible - AddSC_instance_aberrus_the_shadowed_crucible(); - AddSC_aberrus_the_shadowed_crucible(); - AddSC_boss_kazzara_the_hellforged(); -} diff --git a/src/server/scripts/DragonIsles/zone_the_forbidden_reach.cpp b/src/server/scripts/DragonIsles/zone_the_forbidden_reach.cpp deleted file mode 100644 index 4e9057b6c28..00000000000 --- a/src/server/scripts/DragonIsles/zone_the_forbidden_reach.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "ScriptMgr.h" -#include "Containers.h" -#include "Player.h" -#include "Spell.h" -#include "SpellScript.h" -#include "Log.h" - -enum DracthyrLoginSpells -{ - // Spells - SPELL_DRACTHYR_LOGIN = 369728, // teleports to random room, plays scene for the room, binds the home position - SPELL_STASIS_1 = 369735, // triggers 366620 - SPELL_STASIS_2 = 366620, // triggers 366636 - SPELL_STASIS_3 = 366636, // removes 365560, sends first quest (64864) - SPELL_STASIS_4 = 365560, // freeze the target - SPELL_DRACTHYR_MOVIE_ROOM_01 = 394245, // scene for room 1 - SPELL_DRACTHYR_MOVIE_ROOM_02 = 394279, // scene for room 2 - SPELL_DRACTHYR_MOVIE_ROOM_03 = 394281, // scene for room 3 - SPELL_DRACTHYR_MOVIE_ROOM_04 = 394282, // scene for room 4 - //SPELL_DRACTHYR_MOVIE_ROOM_05 = 394283, // scene for room 5 (only plays sound, unused?) -}; - -std::array<std::pair<uint32, Position>, 4> LoginRoomData = -{ - { - { SPELL_DRACTHYR_MOVIE_ROOM_01, { 5725.32f, -3024.26f, 251.047f, 0.01745329238474369f } }, - { SPELL_DRACTHYR_MOVIE_ROOM_02, { 5743.03f, -3067.28f, 251.047f, 0.798488140106201171f } }, - { SPELL_DRACTHYR_MOVIE_ROOM_03, { 5787.1597f, -3083.3906f, 251.04698f, 1.570796370506286621f } }, - { SPELL_DRACTHYR_MOVIE_ROOM_04, { 5829.32f, -3064.49f, 251.047f, 2.364955902099609375f } } - } -}; - -// 369728 - Dracthyr Login -class spell_dracthyr_login : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRACTHYR_MOVIE_ROOM_01, SPELL_DRACTHYR_MOVIE_ROOM_02, SPELL_DRACTHYR_MOVIE_ROOM_03, SPELL_DRACTHYR_MOVIE_ROOM_04 }); - } - - void HandleTeleport(SpellEffIndex /*effIndex*/) - { - std::pair<uint32, Position> const& room = LoginRoomData[urand(0, 3)]; - - WorldLocation dest = GetHitUnit()->GetWorldLocation(); - SetExplTargetDest(dest); - - GetHitDest()->Relocate(room.second); - - GetCaster()->CastSpell(GetHitUnit(), room.first, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_dracthyr_login::HandleTeleport, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); - } -}; - -// 3730 - Dracthyr Evoker Intro (Post Movie) -class scene_dracthyr_evoker_intro : public SceneScript -{ -public: - scene_dracthyr_evoker_intro() : SceneScript("scene_dracthyr_evoker_intro") { } - - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->CastSpell(player, SPELL_STASIS_1, true); - } - - void OnSceneCancel(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->CastSpell(player, SPELL_STASIS_1, true); - } -}; - -void AddSC_zone_the_forbidden_reach() -{ - RegisterSpellScript(spell_dracthyr_login); - new scene_dracthyr_evoker_intro(); -} diff --git a/src/server/scripts/ExilesReach/exiles_reach_script_loader.cpp b/src/server/scripts/ExilesReach/exiles_reach_script_loader.cpp deleted file mode 100644 index 9aba87f489e..00000000000 --- a/src/server/scripts/ExilesReach/exiles_reach_script_loader.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -// This is where scripts' loading functions should be declared: -void AddSC_zone_exiles_reach(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddExilesReachScripts() -{ - AddSC_zone_exiles_reach(); -} diff --git a/src/server/scripts/ExilesReach/zone_exiles_reach.cpp b/src/server/scripts/ExilesReach/zone_exiles_reach.cpp deleted file mode 100644 index 1c56bbe29b5..00000000000 --- a/src/server/scripts/ExilesReach/zone_exiles_reach.cpp +++ /dev/null @@ -1,2251 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTriggerAI.h" -#include "Conversation.h" -#include "CreatureAIImpl.h" -#include "Map.h" -#include "Object.h" -#include "Player.h" -#include "CellImpl.h" -#include "Containers.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "ObjectMgr.h" -#include "PassiveAI.h" -#include "ScriptedCreature.h" -#include "ScriptMgr.h" -#include "ScriptSystem.h" -#include "SpellInfo.h" -#include "SpellScript.h" -#include "TemporarySummon.h" -#include "Transport.h" -#include "Loot.h" - -template<class privateAI, class publicAI> -CreatureAI* GetPrivatePublicPairAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new privateAI(creature); - return new publicAI(creature); -} - -#define RegisterPrivatePublicCreatureAIPair(scriptName, privateAI, publicAI) new FactoryCreatureScript<CreatureAI, &GetPrivatePublicPairAISelector<privateAI, publicAI>>(scriptName); - -static Creature* FindCreatureIgnorePhase(WorldObject const* obj, std::string_view stringId, float range = 100.0f) -{ - return obj->FindNearestCreatureWithOptions(range, { .StringId = stringId, .IgnorePhases = true }); -} - - // ******************************************** - // * Scripting in this section occurs on ship * - // ******************************************** - -enum AttentionExilesReachData -{ - SPELL_DEBUG_LOOK_RIGHT = 290903 -}; - -// 290901 - Attention! -class spell_attention_exiles_reach_tutorial : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEBUG_LOOK_RIGHT }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->CastSpell(GetTarget(), SPELL_DEBUG_LOOK_RIGHT, true); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_attention_exiles_reach_tutorial::OnRemove, EFFECT_0, SPELL_AURA_MOD_ROOT, AURA_EFFECT_HANDLE_REAL); - } -}; - -enum WarmingUpData -{ - CONVERSATION_WARMING_UP_ACCEPT = 12818, - CONVERSATION_WARMING_UP_COMPLETE = 12798, -}; - -class BaseQuestWarmingUp : public QuestScript -{ -public: - BaseQuestWarmingUp(const char* name) : QuestScript(name) { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) - { - if (newStatus == QUEST_STATUS_INCOMPLETE) - Conversation::CreateConversation(CONVERSATION_WARMING_UP_ACCEPT, player, *player, player->GetGUID(), nullptr); - else if (newStatus == QUEST_STATUS_COMPLETE) - Conversation::CreateConversation(CONVERSATION_WARMING_UP_COMPLETE, player, *player, player->GetGUID(), nullptr); - } -}; - -class q56775_warming_up : public BaseQuestWarmingUp -{ -public: - q56775_warming_up() : BaseQuestWarmingUp("q56775_warming_up") { } - - static constexpr float CLONE_ORIENTATION = 5.124503135681152343f; - static constexpr float CLONE_Z_OFFSET = 0.308f; - - void OnQuestStatusChange(Player* player, Quest const* quest, QuestStatus oldStatus, QuestStatus newStatus) override - { - BaseQuestWarmingUp::OnQuestStatusChange(player, quest, oldStatus, newStatus); - - if (newStatus == QUEST_STATUS_REWARDED) - { - Creature* garrickLowerDeck = FindCreatureIgnorePhase(player, "q56775_garrick_lower_deck", 5.0f); - Creature* garrickUpperDeck = FindCreatureIgnorePhase(player, "q56775_garrick_upper_deck", 75.0f); - if (!garrickLowerDeck || !garrickUpperDeck) - return; - - Position pos(garrickLowerDeck->GetPositionX(), garrickLowerDeck->GetPositionY(), garrickLowerDeck->GetPositionZ() - CLONE_Z_OFFSET, CLONE_ORIENTATION); - garrickUpperDeck->SummonPersonalClone(pos, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - } - } -}; - -class q59926_warming_up : public BaseQuestWarmingUp -{ -public: - q59926_warming_up() : BaseQuestWarmingUp("q59926_warming_up") { } - - void OnQuestStatusChange(Player* player, Quest const* quest, QuestStatus oldStatus, QuestStatus newStatus) override - { - BaseQuestWarmingUp::OnQuestStatusChange(player, quest, oldStatus, newStatus); - - if (newStatus == QUEST_STATUS_REWARDED) - { - Creature* grimaxeLowerDeck = FindCreatureIgnorePhase(player, "q59926_grimaxe_lower_deck", 5.0f); - Creature* grimaxeUpperDeck = FindCreatureIgnorePhase(player, "q59926_grimaxe_upper_deck", 75.0f); - if (!grimaxeLowerDeck || !grimaxeUpperDeck) - return; - - grimaxeUpperDeck->SummonPersonalClone(*grimaxeLowerDeck, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - } - } -}; - -enum WarmingUpCaptainData -{ - NPC_WARLORD_BREKA_GRIMAXE2 = 166824, - NPC_WARLORD_BREKA_GRIMAXE3 = 166827, - NPC_CAPTAIN_GARRICK = 156280, - - PATH_GARRICK_TO_COLE = 10501450, - PATH_GARRICK_TO_UPPER_DECK = 10501451, - PATH_GRIMAXE_TO_THROG = 10501900, - PATH_GRIMAXE_TO_UPPER_DECK = 10501901, - - EVENT_SHIP_CAPTAIN1_SCRIPT1 = 1, - EVENT_SHIP_CAPTAIN1_SCRIPT2, - EVENT_SHIP_CAPTAIN1_SCRIPT3, - - SAY_SPAR = 0, -}; - -// 156280 - Captain Garrick -// 166824 - Warlord Breka Grimaxe -struct npc_ship_captain_warming_up_private : public ScriptedAI -{ - npc_ship_captain_warming_up_private(Creature* creature) : ScriptedAI(creature), _pathToSparringPartner(0), _pathToUpperDeck(0) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - } - - void JustAppeared() override - { - if (me->GetEntry() == NPC_CAPTAIN_GARRICK) - { - _pathToSparringPartner = PATH_GARRICK_TO_COLE; - _pathToUpperDeck = PATH_GARRICK_TO_UPPER_DECK; - } - else if (me->GetEntry() == NPC_WARLORD_BREKA_GRIMAXE2) - { - _pathToSparringPartner = PATH_GRIMAXE_TO_THROG; - _pathToUpperDeck = PATH_GRIMAXE_TO_UPPER_DECK; - } - - _events.ScheduleEvent(EVENT_SHIP_CAPTAIN1_SCRIPT1, 1s); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == _pathToSparringPartner) - _events.ScheduleEvent(EVENT_SHIP_CAPTAIN1_SCRIPT2, 0s); - else if (pathId == _pathToUpperDeck) - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SHIP_CAPTAIN1_SCRIPT1: - Talk(SAY_SPAR); - me->GetMotionMaster()->MovePath(_pathToSparringPartner, false); - break; - case EVENT_SHIP_CAPTAIN1_SCRIPT2: - me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - _events.ScheduleEvent(EVENT_SHIP_CAPTAIN1_SCRIPT3, 3s); - break; - case EVENT_SHIP_CAPTAIN1_SCRIPT3: - me->GetMotionMaster()->MovePath(_pathToUpperDeck, false); - break; - default: - break; - } - } - } -private: - EventMap _events; - uint32 _pathToSparringPartner; - uint32 _pathToUpperDeck; -}; - -enum StandYourGroundData -{ - ACTOR_ID_ALLIANCE = 68598, - ACTOR_ID_HORDE = 75920, - - CONVERSATION_PREFIGHT = 14422, - CONVERSATION_AGGRO = 14423, - CONVERSATION_JUMP = 14424, - - EQUIPMENT_SWORD = 108493, - EQUIPMENT_AXE = 175161, - - EVENT_MOVE_TO_A_POSITION = 1, - EVENT_PREFIGHT_CONVERSATION, - EVENT_JUMP_BEHIND, - EVENT_WALK_BACK, - - PATH_ALLIANCE_SPARING_PARTNER = 10501460, - PATH_HORDE_SPARING_PARTNER = 10501870, - - POSITION_SPARPOINT_ADVERTISMENT = 1, - POSITION_SPARPOINT_READY = 2, - - TALK_SPARING_COMPLETE = 0, - - NPC_ALLIANCE_SPARING_PARTNER = 157051, - NPC_HORDE_SPARING_PARTNER = 166814, - NPC_SPAR_POINT_ADVERTISMENT = 174971, - NPC_KILL_CREDIT = 155607, - - SPELL_COMBAT_TRAINING_COMPLETE = 303120, - SPELL_JUMP_LEFT = 312757, - SPELL_JUMP_BEHIND = 312755, - SPELL_COMBAT_TRAINING = 323071, - SPELL_UPDATE_PHASE_SHIFT = 82238, -}; - -// 58209 - Stand Your Ground -// 59927 - Stand Your Ground -class quest_stand_your_ground : public QuestScript -{ -public: - quest_stand_your_ground() : QuestScript("quest_stand_your_ground") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - // Remove aura if player drops quest - if (newStatus == QUEST_STATUS_NONE) - player->CastSpell(player, SPELL_COMBAT_TRAINING_COMPLETE); - } -}; - -// 303065 - Summon Cole - Combat Training (DNT) -// 325108 - Summon Throg - Combat Training (DNT) -class spell_summon_sparring_partner : public SpellScript -{ - void SelectTarget(WorldObject*& target) - { - Player* caster = GetCaster()->ToPlayer(); - if (!caster) - return; - - Creature* partner = FindCreatureIgnorePhase(caster, caster->GetTeam() == ALLIANCE ? "q58209_cole" : "q59927_throg", 10.0f); - if (!partner) - return; - - target = partner; - } - - void Register() override - { - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_summon_sparring_partner::SelectTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY_OR_DB); - } -}; - -// 157051 - Alliance Sparring Partner -// 166814 - Horde Sparring Partner -struct npc_sparring_partner_exiles_reach : public ScriptedAI -{ - npc_sparring_partner_exiles_reach(Creature* creature) : ScriptedAI(creature), _jumped(false), _actorIndex(0), _actorId(0), _path(0) { } - - void JustAppeared() override - { - if (me->GetEntry() == NPC_ALLIANCE_SPARING_PARTNER) - { - SetEquipmentSlots(false, EQUIPMENT_SWORD, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); - _path = PATH_ALLIANCE_SPARING_PARTNER; - _actorId = ACTOR_ID_ALLIANCE; - _actorIndex = 0; - } - else if (me->GetEntry() == NPC_HORDE_SPARING_PARTNER) - { - SetEquipmentSlots(false, EQUIPMENT_AXE, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE); - _path = PATH_HORDE_SPARING_PARTNER; - _actorId = ACTOR_ID_HORDE; - _actorIndex = 1; - } - me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); - _events.ScheduleEvent(EVENT_MOVE_TO_A_POSITION, 1s); - } - - void IsSummonedBy(WorldObject* summonerWO) override - { - Unit* summoner = summonerWO->ToUnit(); - - if (!summoner || !summoner->IsPlayer()) - return; - - _playerGUID = summoner->GetGUID(); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - if (!me->IsAlive()) - return; - - me->CombatStop(true); - EngagementOver(); - me->ResetPlayerDamageReq(); - _events.ScheduleEvent(EVENT_WALK_BACK, 1s); - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE) - return; - - switch (uiId) - { - case POSITION_SPARPOINT_ADVERTISMENT: - me->SetWalk(true); - me->GetMotionMaster()->MovePoint(POSITION_SPARPOINT_READY, me->GetFirstCollisionPosition(2.0f, rand_norm() * static_cast<float>(2 * M_PI))); - break; - case POSITION_SPARPOINT_READY: - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - me->SetFacingToObject(player); - me->SetImmuneToPC(false); - me->SetUninteractible(false); - break; - default: - break; - } - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId != _path) - return; - - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - { - me->DespawnOrUnsummon(); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, SPELL_COMBAT_TRAINING_COMPLETE); - } - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (me->GetHealth() <= damage) - { - damage = 0; - me->SetHealth(1); - DoStopAttack(); - me->SetImmuneToPC(true); - me->SetUninteractible(true); - _events.CancelEvent(EVENT_JUMP_BEHIND); - - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - { - me->SetFacingToObject(player); - Talk(TALK_SPARING_COMPLETE, player); - player->CastSpell(player, SPELL_COMBAT_TRAINING); - player->KilledMonsterCredit(NPC_KILL_CREDIT); - } - } - - if (me->HealthBelowPctDamaged(65, damage) && !_jumped) - { - _jumped = true; - DoCastVictim(SPELL_JUMP_LEFT, true); - StartPrivateConversation(CONVERSATION_JUMP); - _events.ScheduleEvent(EVENT_JUMP_BEHIND, 2s); - } - } - - void JustEngagedWith(Unit* /*who*/) override - { - StartPrivateConversation(CONVERSATION_AGGRO); - } - - void DamageDealt(Unit* target, uint32& damage, DamageEffectType /*damageType*/) override - { - if (target->GetHealthPct() < 95) - damage = 0; - } - - void StartPrivateConversation(uint32 conversationId) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - { - Conversation* conversation = Conversation::CreateConversation(conversationId, player, *player, player->GetGUID(), nullptr, false); - conversation->AddActor(_actorId, _actorIndex, me->GetGUID()); - conversation->Start(); - } - } - - Creature* GetRandomSparPoint() - { - std::list<Creature*> sparPoints; - GetCreatureListWithEntryInGrid(sparPoints, me, NPC_SPAR_POINT_ADVERTISMENT, 25.0f); - Trinity::Containers::RandomResize(sparPoints, 1); - - if (sparPoints.empty()) // should never happen - return nullptr; - - return sparPoints.front(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_MOVE_TO_A_POSITION: - { - if (Creature* sparPoint = GetRandomSparPoint()) - me->GetMotionMaster()->MovePoint(POSITION_SPARPOINT_ADVERTISMENT, sparPoint->GetPosition()); - - _events.ScheduleEvent(EVENT_PREFIGHT_CONVERSATION, 1s); - break; - } - case EVENT_PREFIGHT_CONVERSATION: - StartPrivateConversation(CONVERSATION_PREFIGHT); - break; - case EVENT_JUMP_BEHIND: - DoCastVictim(SPELL_JUMP_BEHIND, true); - break; - case EVENT_WALK_BACK: - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePath(_path, false); - break; - default: - break; - } - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } -private: - EventMap _events; - bool _jumped; - uint8 _actorIndex; - uint32 _actorId; - uint32 _path; - ObjectGuid _playerGUID; -}; - -enum FirstMateStandYourGroundData -{ - QUEST_STAND_YOUR_GROUND_ALLIANCE = 58209, - QUEST_STAND_YOUR_GROUND_HORDE = 59927, - - SPELL_SUMMON_COLE = 303064, - SPELL_SUMMON_THROG = 325107, -}; - -// 160664 - Private Cole -// 166583 - Grunt Throg -struct npc_first_mate_stand_your_ground : public ScriptedAI -{ - npc_first_mate_stand_your_ground(Creature* creature) : ScriptedAI(creature) { } - - void OnQuestAccept(Player* player, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_STAND_YOUR_GROUND_ALLIANCE) - { - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, SPELL_SUMMON_COLE); - } - else if (quest->GetQuestId() == QUEST_STAND_YOUR_GROUND_HORDE) - { - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, SPELL_SUMMON_THROG); - } - } -}; - -struct ActorData -{ - std::string_view StringId; - Position ActorPosition; -}; - -static std::vector<ActorData> const ActorDataMap[2] = -{ - // TEAM_ALLIANCE - { - { "q58208_garrick", { 35.5643f, -1.19837f, 12.1479f, 3.3272014f } }, - { "q58208_richter", { -1.84858f, -8.38776f, 5.10018f, 1.5184366f } }, - { "q58208_keela", { -15.3642f, 6.5793f, 5.5026f, 3.1415925f } }, - { "q58208_bjorn", { 12.8406f, -8.49553f, 4.98031f, 4.8520155f } }, - { "q58208_austin", { -4.48607f, 9.89729f, 5.07851f, 1.5184366f } }, - { "q58208_cole", { -13.3396f, 0.702157f, 5.57996f, 0.087266445f } }, - }, - // TEAM_HORDE - { - { "q59928_grimaxe", { 25.5237f, 0.283005f, 26.5455f, 3.3526998f } }, - { "q59928_throg", { -10.8399f, 11.9039f, 8.88028f, 6.2308254f } }, - { "q59928_mithdran", { -24.4763f, -4.48273f, 9.13471f, 0.62831855f } }, - { "q59928_lana", { -5.1971f, -15.0268f, 8.992f, 4.712389f } }, - { "q59928_bo", { -22.1559f, 5.58041f, 9.09176f, 6.143559f } }, - { "q59928_jinhake", { -31.9464f, 7.5772f, 10.6408f, 6.0737457f } }, - } -}; - -static std::unordered_map<Races, std::string_view> const ActorPetData = -{ - { RACE_HUMAN, "q58208_wolf" }, - { RACE_DWARF, "q58208_bear" }, - { RACE_NIGHTELF, "q58208_tiger" }, - { RACE_GNOME, "q58208_bunny" }, - { RACE_DRAENEI, "q58208_moth" }, - { RACE_WORGEN, "q58208_dog" }, - { RACE_PANDAREN_ALLIANCE, "q58208_turtle" }, - { RACE_ORC, "q59928_wolf" }, - { RACE_UNDEAD_PLAYER, "q59928_bat" }, - { RACE_TAUREN, "q59928_plainstrider" }, - { RACE_TROLL, "q59928_raptor" }, - { RACE_GOBLIN, "q59928_scorpion" }, - { RACE_BLOODELF, "q59928_dragonhawk" }, - { RACE_PANDAREN_HORDE, "q59928_turtle" } -}; - -enum BraceForImpactData -{ - QUEST_BRACE_FOR_IMPACT_ALLIANCE = 58208, - QUEST_BRACE_FOR_IMPACT_HORDE = 59928, -}; - -// 58208 - Brace For Impact -// 59928 - Brace For Impact -class quest_brace_for_impact : public QuestScript -{ -public: - quest_brace_for_impact() : QuestScript("quest_brace_for_impact") { } - - void OnQuestStatusChange(Player* player, Quest const* quest, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - if (newStatus != QUEST_STATUS_COMPLETE) - return; - - TeamId team = TEAM_NEUTRAL; - Position petSpawnPos; - - if (quest->GetQuestId() == QUEST_BRACE_FOR_IMPACT_ALLIANCE) - { - team = TEAM_ALLIANCE; - petSpawnPos = { -1.4492f, 8.06887f, 5.10348f, 2.6005409f }; - } - else if (quest->GetQuestId() == QUEST_BRACE_FOR_IMPACT_HORDE) - { - team = TEAM_HORDE; - petSpawnPos = { -22.8374f, -3.08287f, 9.12613f, 3.857178f }; - } - - if (team == TEAM_NEUTRAL) - return; - - SpawnActors(player, team, petSpawnPos); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - } - - void SpawnActors(Player* player, TeamId team, Position petSpawnPos) - { - for (ActorData const& actor : ActorDataMap[team]) - SpawnActor(player, FindCreatureIgnorePhase(player, actor.StringId, 50.0f), actor.ActorPosition); - - SpawnPet(player, petSpawnPos); - } - - void SpawnPet(Player* player, Position const& position) - { - if (player->GetClass() != CLASS_HUNTER) - return; - - if (std::string_view const* stringId = Trinity::Containers::MapGetValuePtr(ActorPetData, Races(player->GetRace()))) - { - Creature* pet = FindCreatureIgnorePhase(player, *stringId, 25.0f); - if (!pet) - return; - - SpawnActor(player, pet, position); - } - } - - void SpawnActor(Player* player, Creature* creature, Position const& position) - { - TransportBase const* transport = player->GetDirectTransport(); - - if (!transport || !creature) - return; - - float x, y, z, o; - position.GetPosition(x, y, z, o); - transport->CalculatePassengerPosition(x, y, z, &o); - creature->SummonPersonalClone({ x, y, z, o }, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - } -}; - -enum BraceForImpactCaptainData -{ - PATH_GARRICK_FROM_UPPER_DECK = 10505890, - PATH_GARRICK_TO_LOWER_DECK = 10505891, - PATH_GRIMAXE_FROM_UPPER_DECK = 10501910, - PATH_GRIMAXE_TO_LOWER_DECK = 10501911, - - EVENT_SHIP_CAPTAIN2_SCRIPT1 = 1, - EVENT_SHIP_CAPTAIN2_SCRIPT2, - - SAY_GET_TO_POSITIONS = 1, -}; - -// 156280 - Captain Garrick -// 166827 - Warlord Breka Grimaxe -struct npc_ship_captain_brace_for_impact_private : public ScriptedAI -{ - npc_ship_captain_brace_for_impact_private(Creature* creature) : ScriptedAI(creature), _pathPreTalk(0), _pathPostTalk(0), _waitTime(0s){ } - - void JustAppeared() override - { - if (me->GetEntry() == NPC_CAPTAIN_GARRICK) - { - _pathPreTalk = PATH_GARRICK_FROM_UPPER_DECK; - _pathPostTalk = PATH_GARRICK_TO_LOWER_DECK; - _waitTime = 0s; - } - else if (me->GetEntry() == NPC_WARLORD_BREKA_GRIMAXE3) - { - _pathPreTalk = PATH_GRIMAXE_FROM_UPPER_DECK; - _pathPostTalk = PATH_GRIMAXE_TO_LOWER_DECK; - _waitTime = 1s; - } - - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - me->GetMotionMaster()->MovePath(_pathPreTalk, false); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == _pathPreTalk) - _events.ScheduleEvent(EVENT_SHIP_CAPTAIN2_SCRIPT1, _waitTime); - else if (pathId == _pathPostTalk) - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SHIP_CAPTAIN2_SCRIPT1: - Talk(SAY_GET_TO_POSITIONS); - _events.ScheduleEvent(EVENT_SHIP_CAPTAIN2_SCRIPT2, 3s); - break; - case EVENT_SHIP_CAPTAIN2_SCRIPT2: - me->GetMotionMaster()->MovePath(_pathPostTalk, false); - break; - default: - break; - } - } - } -private: - EventMap _events; - uint32 _pathPreTalk; - uint32 _pathPostTalk; - Seconds _waitTime; -}; - -enum BraceForImpactFirstMateData -{ - NPC_PRIVATE_COLE = 160664, - NPC_GRUNT_THROG = 166583, - - PATH_COLE_BRACE_FOR_IMPACT = 10501461, - PATH_THROG_BRACE_FOR_IMPACT = 10501871, - - EVENT_FIRST_MATE_1 = 1, - EVENT_FIRST_MATE_2, - - SAY_STORM = 0, -}; - -// 160664 - Private Cole -// 166583 - Grunt Throg -struct npc_first_mate_brace_for_impact_private : public ScriptedAI -{ - npc_first_mate_brace_for_impact_private(Creature* creature) : ScriptedAI(creature), _path(0) { } - - void JustAppeared() override - { - if (me->GetEntry() == NPC_PRIVATE_COLE) - _path = PATH_COLE_BRACE_FOR_IMPACT; - else if (me->GetEntry() == NPC_GRUNT_THROG) - _path = PATH_THROG_BRACE_FOR_IMPACT; - - _events.ScheduleEvent(EVENT_FIRST_MATE_1, 3s); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (_path && pathId == _path) - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FIRST_MATE_1: - Talk(SAY_STORM); - _events.ScheduleEvent(EVENT_FIRST_MATE_2, 4s); - break; - case EVENT_FIRST_MATE_2: - me->GetMotionMaster()->MovePath(_path, false); - break; - default: - break; - } - } - } -private: - EventMap _events; - uint32 _path; -}; - -enum BraceForImpactCrewData -{ - NPC_QUARTERMASTER_RICHTER = 157042, - NPC_KEE_LA = 157043, - NPC_BJORN_STOUTHANDS = 157044, - NPC_AUSTIN_HUXWORTH = 157046, - - NPC_BO = 166585, - NPC_MITHDRAN_DAWNTRACKER = 166590, - NPC_LANA_JORDAN = 166794, - NPC_PROVISONER_JIN_HAKE = 166799, - - PATH_RICHTER_BRACE_FOR_IMPACT = 10501770, - PATH_KEE_LA_BRACE_FOR_IMPACT = 10501800, - PATH_BJORN_BRACE_FOR_IMPACT = 10501790, - PATH_AUSTIN_BRACE_FOR_IMPACT = 10501780, - - PATH_BO_BRACE_FOR_IMPACT = 10502010, - PATH_MITHDRAN_BRACE_FOR_IMPACT = 10501990, - PATH_LANA_BRACE_FOR_IMPACT = 10501980, - PATH_JIN_HAKE_BRACE_FOR_IMPACT = 10502000, -}; - -// 157042 - Quartermaster Richter -// 157043 - Kee-La -// 157044 - Bjorn Stouthands -// 157046 - Austin Huxworth -// 166585 - Bo -// 166590 - Mithdran Dawntracker -// 166794 - Lana Jordan -// 166799 - Provisoner Jin'hake -struct npc_crew_ship_private : public ScriptedAI -{ - npc_crew_ship_private(Creature* creature) : ScriptedAI(creature), _path(0) { } - - uint32 GetPathID() - { - switch (me->GetEntry()) - { - case NPC_QUARTERMASTER_RICHTER: return PATH_RICHTER_BRACE_FOR_IMPACT; - case NPC_KEE_LA: return PATH_KEE_LA_BRACE_FOR_IMPACT; - case NPC_BJORN_STOUTHANDS: return PATH_BJORN_BRACE_FOR_IMPACT; - case NPC_AUSTIN_HUXWORTH: return PATH_AUSTIN_BRACE_FOR_IMPACT; - case NPC_BO: return PATH_BO_BRACE_FOR_IMPACT; - case NPC_MITHDRAN_DAWNTRACKER: return PATH_MITHDRAN_BRACE_FOR_IMPACT; - case NPC_LANA_JORDAN: return PATH_LANA_BRACE_FOR_IMPACT; - case NPC_PROVISONER_JIN_HAKE: return PATH_JIN_HAKE_BRACE_FOR_IMPACT; - default: return 0; - } - } - - void JustAppeared() override - { - _path = GetPathID(); - _scheduler.Schedule(Seconds(7), [this](TaskContext) - { - me->GetMotionMaster()->MovePath(_path, false); - }); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (_path && pathId == _path) - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; - uint32 _path; -}; - -enum BraceForImpactPetData -{ - EVENT_PET_SHIP_RUN_TO_POSITION = 1, - - MAP_ALLIANCE_SHIP = 2261, - MAP_HORDE_SHIP = 2369, - - PATH_PET_ALLIANCE_SHIP = 10501510, - PATH_PET_HORDE_SHIP = 10502020 -}; - -// 167337 - Mechanical Bunny -// 167342 - Moth -// 167343 - Dragonhawk -// 167344 - Scorpion -// 167345 - Wolf -// 167346 - Wolf -// 167347 - Tiger -// 167348 - Turtle -// 167349 - Plainstrider -// 167350 - Raptor -// 167351 - Bat -// 167352 - Dog -// 167375 - Bear -struct npc_pet_ship_private : public ScriptedAI -{ - npc_pet_ship_private(Creature* creature) : ScriptedAI(creature), _path(0) { } - - void JustAppeared() override - { - if (!me->GetTransport()) - return; - - int32 transportMap = me->GetTransport()->GetMapIdForSpawning(); - if (transportMap == MAP_ALLIANCE_SHIP) - _path = PATH_PET_ALLIANCE_SHIP; - else if (transportMap == MAP_HORDE_SHIP) - _path = PATH_PET_HORDE_SHIP; - - if (_path) - _events.ScheduleEvent(EVENT_PET_SHIP_RUN_TO_POSITION, 8s); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 /*pathId*/) override - { - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - if (eventId == EVENT_PET_SHIP_RUN_TO_POSITION) - me->GetMotionMaster()->MovePath(_path, false); - } - } - -private: - EventMap _events; - uint32 _path; -}; - -enum ExilesReachShipCrashData -{ - MOVIE_ALLIANCE_SHIP_CRASH = 895, - MOVIE_HORDE_SHIP_CRASH = 931, - - SPELL_ALLIANCE_SHIP_CRASH = 305446, - SPELL_HORDE_SHIP_CRASH = 325133, - SPELL_BEGIN_TUTORIAL = 295600, -}; - -class player_exiles_reach_ship_crash : public PlayerScript -{ -public: - player_exiles_reach_ship_crash() : PlayerScript("player_exiles_reach_ship_crash") { } - - void OnMovieComplete(Player* player, uint32 movieId) override - { - switch (movieId) - { - case MOVIE_ALLIANCE_SHIP_CRASH: - player->CastSpell(player, SPELL_ALLIANCE_SHIP_CRASH, true); - break; - case MOVIE_HORDE_SHIP_CRASH: - player->CastSpell(player, SPELL_HORDE_SHIP_CRASH, true); - break; - default: - break; - } - } -}; - -class scene_alliance_and_horde_ship : public SceneScript -{ -public: - scene_alliance_and_horde_ship() : SceneScript("scene_alliance_and_horde_ship") { } - - void StartConvo(Player* player) - { - // This script is used to send conversation to Captian Garrick and Warlord Grimaxe on movement after entering ship - player->CastSpell(player, SPELL_BEGIN_TUTORIAL, true); - } - - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - StartConvo(player); - } - - void OnSceneCancel(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - StartConvo(player); - } -}; - -// *************************************************************** -// * Scripting in this section occurs after teleporting to beach * -// *************************************************************** - -enum KnockedDownExilesReachData -{ - SPELL_KNOCKED_DOWN_STUN2 = 344889 -}; - -// 305445 - Knocked Down! -class spell_knocked_down_exiles_reach_beach : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_KNOCKED_DOWN_STUN2 }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->CastSpell(nullptr, SPELL_KNOCKED_DOWN_STUN2, true); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_knocked_down_exiles_reach_beach::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - } -}; - -enum ExilesReachShipCrashBeachData -{ - SPELL_KNOCKED_DOWN = 305445, - SPELL_CRASHED_LANDED_ALLIANCE = 305464, - SPELL_CRASHED_LANDED_HORDE = 325136 -}; - -// Script scene for washed up on beach to cast spells Alliance and Horde -class scene_alliance_and_horde_crash : public SceneScript -{ -public: - scene_alliance_and_horde_crash() : SceneScript("scene_alliance_and_horde_crash") { } - - void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override - { - if (triggerName == "Begin Knockdown Aura") - player->CastSpell(player, SPELL_KNOCKED_DOWN, true); - } - - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->CastSpell(player, player->GetTeam() == ALLIANCE ? SPELL_CRASHED_LANDED_ALLIANCE : SPELL_CRASHED_LANDED_HORDE, true); - } -}; - -CreatureAI* CaptainGarrickShipAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if ((privateObjectOwner->GetTeam() == ALLIANCE && privateObjectOwner->GetQuestStatus(QUEST_BRACE_FOR_IMPACT_ALLIANCE) == QUEST_STATUS_NONE)) - return new npc_ship_captain_warming_up_private(creature); - else - return new npc_ship_captain_brace_for_impact_private(creature); - } - } - - return new NullCreatureAI(creature); -}; - -enum SpellCrashLandedData -{ - NPC_CAPTAIN_GARRICK_BEACH = 156626, - NPC_WARLORD_BREKA_GRIMAXE_BEACH = 166782 -}; - -// 305464 - Crash Landed -// 325136 - Crash Landed -template<uint32 StaticCaptainNPCId> -class spell_crash_landed_generic : public SpellScript -{ - void HandleEffect(SpellEffIndex /*effIndex*/) - { - Player* player = GetCaster()->ToPlayer(); - if (!player) - return; - - if (Creature* creature = player->FindNearestCreature(StaticCaptainNPCId, 50.0f)) - creature->SummonPersonalClone(creature->GetPosition(), TempSummonType(TEMPSUMMON_MANUAL_DESPAWN), 0s, 0, 0, player); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_crash_landed_generic::HandleEffect, EFFECT_0, SPELL_EFFECT_SEND_EVENT); - } -}; - -enum ExilesReachCaptainsBeachData -{ - CONVERSATION_QUEST_MURLOC_MANIA_ALLIANCE = 12043, - CONVERSATION_QUEST_MURLOC_MANIA_HORDE = 14432, - - EVENT_EMERGENCY_FIRST_AID_SCRIPT_SHEATH = 1, - EVENT_EMERGENCY_FIRST_AID_SCRIPT_BANDAGE, - EVENT_EMERGENCY_FIRST_AID_SCRIPT_MOVE_SECOND_SURVIVOR, - EVENT_EMERGENCY_FIRST_AID_SCRIPT_MOVE_HOME_BEACH, - - POINT_SECOND_SURVIVOR = 0, - POINT_BEACH_HOME = 1, - - QUEST_MURLOC_MANIA_ALLIANCE = 55122, - QUEST_EMERGENCY_FIRST_AID_ALLIANCE = 54951, - QUEST_MURLOC_MANIA_HORDE = 59929, - QUEST_EMERGENCY_FIRST_AID_HORDE = 59930, - - SPELL_BANDAGING = 305584, - - TALK_ARRIVED_AT_BEACH = 0 -}; - -// 156626 - Captain Garrick -// 166782 - Warlord Breka Grimaxe -struct npc_captain_warlord_beach_arrive_private : public ScriptedAI -{ - npc_captain_warlord_beach_arrive_private(Creature* creature) : ScriptedAI(creature) { } - - void IsSummonedBy(WorldObject* summonerWO) override - { - Player* summoner = summonerWO->ToPlayer(); - if (!summoner) - return; - - me->SetFacingToObject(summoner); - Talk(TALK_ARRIVED_AT_BEACH, summoner); - me->DespawnOrUnsummon(5s); - } -}; - -// 156626 - Captain Garrick -// 166782 - Warlord Breka Grimaxe -// for Emergency first aid quest 54951 -struct npc_captain_warlord_first_aid_private : public ScriptedAI -{ - npc_captain_warlord_first_aid_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - } - - void IsSummonedBy(WorldObject* summonerWO) override - { - Player* summoner = summonerWO->ToPlayer(); - if (!summoner) - return; - - _events.ScheduleEvent(EVENT_EMERGENCY_FIRST_AID_SCRIPT_SHEATH, 2s); - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE) - return; - - switch (uiId) - { - case POINT_SECOND_SURVIVOR: - if (Creature* mate = ObjectAccessor::GetCreature(*me, _quartermasterGUID)) - me->CastSpell(mate, SPELL_BANDAGING); - _events.ScheduleEvent(EVENT_EMERGENCY_FIRST_AID_SCRIPT_MOVE_HOME_BEACH, 6s); - break; - case POINT_BEACH_HOME: - me->DespawnOrUnsummon(); - break; - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_EMERGENCY_FIRST_AID_SCRIPT_SHEATH: - me->SetSheath(SHEATH_STATE_UNARMED); - _events.ScheduleEvent(EVENT_EMERGENCY_FIRST_AID_SCRIPT_BANDAGE, 1s); - break; - case EVENT_EMERGENCY_FIRST_AID_SCRIPT_BANDAGE: - if (Creature* mate = ObjectAccessor::GetCreature(*me, _firstMateGUID)) - me->CastSpell(mate, SPELL_BANDAGING); - _events.ScheduleEvent(EVENT_EMERGENCY_FIRST_AID_SCRIPT_MOVE_SECOND_SURVIVOR, 5s); - break; - case EVENT_EMERGENCY_FIRST_AID_SCRIPT_MOVE_SECOND_SURVIVOR: - me->GetMotionMaster()->MovePoint(POINT_SECOND_SURVIVOR, -414.15277f, -2605.2014f, 0.91079247f, false); - break; - case EVENT_EMERGENCY_FIRST_AID_SCRIPT_MOVE_HOME_BEACH: - me->GetMotionMaster()->MovePoint(POINT_BEACH_HOME, -435.15277f, -2610.9915f, 0.649292f, false); - break; - default: - break; - } - } - } - -public: - void SetFirstMateGUID(ObjectGuid coleGUID) - { - _firstMateGUID = coleGUID; - } - - void SetQuartermasterGUID(ObjectGuid richterGUID) - { - _quartermasterGUID = richterGUID; - } - -private: - EventMap _events; - ObjectGuid _firstMateGUID; - ObjectGuid _quartermasterGUID; -}; - -// 156626 - Captain Garrick -struct npc_captain_garrick_beach : public ScriptedAI -{ - npc_captain_garrick_beach(Creature* creature) : ScriptedAI(creature) { } - - void OnQuestAccept(Player* player, Quest const* quest) override - { - switch (quest->GetQuestId()) - { - case QUEST_MURLOC_MANIA_ALLIANCE: - Conversation::CreateConversation(CONVERSATION_QUEST_MURLOC_MANIA_ALLIANCE, player, *player, player->GetGUID(), nullptr); - break; - case QUEST_EMERGENCY_FIRST_AID_ALLIANCE: - { - Creature* cole = FindCreatureIgnorePhase(player, "private_cole_beach", 50.0f); - Creature* richter = FindCreatureIgnorePhase(player, "quartermaster_richter_beach", 50.0f); - if (!cole || !richter) - return; - - Creature* colePersonal = cole->SummonPersonalClone(cole->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - Creature* richterPersonal = richter->SummonPersonalClone(richter->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - Creature* mePersonal = me->SummonPersonalClone(me->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!colePersonal || !richterPersonal || !mePersonal) - return; - - if (npc_captain_warlord_first_aid_private* personalAI = CAST_AI(npc_captain_warlord_first_aid_private, mePersonal->GetAI())) - { - personalAI->SetFirstMateGUID(colePersonal->GetGUID()); - personalAI->SetQuartermasterGUID(richterPersonal->GetGUID()); - } - break; - } - default: - break; - } - } -}; - -// 166782 - Warlord Breka Grimaxe -struct npc_warlord_grimaxe_beach : public ScriptedAI -{ - npc_warlord_grimaxe_beach(Creature* creature) : ScriptedAI(creature) { } - - void OnQuestAccept(Player* player, Quest const* quest) override - { - switch (quest->GetQuestId()) - { - case QUEST_MURLOC_MANIA_HORDE: - Conversation::CreateConversation(CONVERSATION_QUEST_MURLOC_MANIA_HORDE, player, *player, player->GetGUID(), nullptr); - break; - case QUEST_EMERGENCY_FIRST_AID_HORDE: - { - Creature* throg = FindCreatureIgnorePhase(player, "grunt_throg_beach", 50.0f); - Creature* jinhake = FindCreatureIgnorePhase(player, "jin_hake_beach", 50.0f); - if (!throg || !jinhake) - return; - - Creature* throgPersonal = throg->SummonPersonalClone(throg->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - Creature* jinhakePersonal = jinhake->SummonPersonalClone(jinhake->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - Creature* mePersonal = me->SummonPersonalClone(me->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!throgPersonal || !jinhakePersonal || !mePersonal) - return; - - if (npc_captain_warlord_first_aid_private* personalAI = CAST_AI(npc_captain_warlord_first_aid_private, mePersonal->AI())) - { - personalAI->SetFirstMateGUID(throgPersonal->GetGUID()); - personalAI->SetQuartermasterGUID(jinhakePersonal->GetGUID()); - } - break; - } - default: - break; - } - } -}; - -CreatureAI* CaptainGarrickBeachAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if (privateObjectOwner->GetQuestStatus(QUEST_MURLOC_MANIA_ALLIANCE) == QUEST_STATUS_NONE) - return new npc_captain_warlord_beach_arrive_private(creature); - else - return new npc_captain_warlord_first_aid_private(creature); - } - } - return new npc_captain_garrick_beach(creature); -}; - -CreatureAI* WarlordGrimaxeBeachAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if (privateObjectOwner->GetQuestStatus(QUEST_MURLOC_MANIA_HORDE) == QUEST_STATUS_NONE) - return new npc_captain_warlord_beach_arrive_private(creature); - else - return new npc_captain_warlord_first_aid_private(creature); - } - } - return new npc_warlord_grimaxe_beach(creature); -}; - -enum HealedByLeaderBeachData -{ - EVENT_SALUTE = 1, - EVENT_LEAVE_BEACH, - - NPC_COLE_BEACH = 149917, - NPC_RICHTER_BEACH = 156622, - NPC_THROG_BEACH = 166784, - NPC_JINHAKE_BEACH = 166800, - - PATH_LONG_BEACH = 10520070, - PATH_SHORT_BEACH = 10520080 -}; - -// 149917 - Private Cole -// 156622 - Quartermaster Richter -// 166784 - Grunt Throg -// 166800 - Provisioner Jin'hake -// for Emergency first aid quest -template<uint32 PathId, uint32 WaitTime> -struct npc_survivors_healed_by_leader_beach_private : public ScriptedAI -{ - npc_survivors_healed_by_leader_beach_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->SetStandState(UNIT_STAND_STATE_SLEEP); - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_BANDAGING) - return; - - _casterGUID = caster->GetGUID(); - me->SetStandState(UNIT_STAND_STATE_STAND); - _events.ScheduleEvent(EVENT_SALUTE, 2s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SALUTE: - if (Creature* caster = ObjectAccessor::GetCreature(*me, _casterGUID)) - me->SetFacingToObject(caster); - me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - _events.ScheduleEvent(EVENT_LEAVE_BEACH, 2s); - break; - case EVENT_LEAVE_BEACH: - me->GetMotionMaster()->MovePath(PathId, false); - me->DespawnOrUnsummon(Milliseconds(WaitTime)); - break; - default: - break; - } - } - } -private: - EventMap _events; - ObjectGuid _casterGUID; -}; - -CreatureAI* HealedByLeaderAllianceAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_survivors_healed_by_leader_beach_private<PATH_LONG_BEACH, 16 * IN_MILLISECONDS>(creature); - return new NullCreatureAI(creature); -}; - -CreatureAI* HealedByLeaderHordeAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_survivors_healed_by_leader_beach_private<PATH_SHORT_BEACH, 9 * IN_MILLISECONDS>(creature); - return new NullCreatureAI(creature); -}; - -enum ExilesReachAllianceSurvivorsBeachData -{ - CONVERSATION_STOUTHANDS_BEACH = 11685, - CONVERSATION_HUXWORTH_BEACH = 12128, - CONVERSATION_KEE_LA_BEACH = 12127, - - NPC_BJORN_STOUTHANDS_LAYING = 156609, - NPC_AUSTIN_HUXWORTH_LAYING = 156610, - NPC_KEE_LA_LAYING = 156612, - NPC_KEE_LA_STANDING = 151088, - NPC_BJORN_STOUTHANDS_STANDING = 151089, - NPC_AUSTIN_HUXWORTH_STANDING = 154170, - - PATH_KEE_LA_STANDING = ((1052012 * 10) + 1) << 3, - PATH_BJORN_STOUTHANDS_STANDING = ((1052013 * 10) + 1) << 3, - PATH_AUSTIN_HUXWORTH_STANDING = ((1052014 * 10) + 1) << 3, - - SPELL_BANDAGING_QUEST = 297415 -}; - -// 156609 - Bjorn Stouthands -// 156610 - Austin Huxworth -// 156612 - Kee-La -template<uint32 ConversationId> -struct npc_alliance_survivors_beach_laying : public ScriptedAI -{ - npc_alliance_survivors_beach_laying(Creature* creature) : ScriptedAI(creature) { } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_BANDAGING_QUEST) - return; - - if (Player* player = caster->ToPlayer()) - { - player->KilledMonsterCredit(me->GetEntry()); - - Conversation::CreateConversation(ConversationId, player, *player, player->GetGUID(), nullptr); - } - } -}; - -enum ExilesReachHordeSurvivorsBeachData -{ - EVENT_SURVIVORS_HORDE_STAND_AND_TALK = 1, - EVENT_SURVIVORS_HORDE_MOVE_TO_GRIMAXE, - - EVENT_SURVIVORS_SALUTE = 1, - EVENT_SURVIVORS_LEAVE_BEACH, - - NPC_BO_LAYING_LAYING = 166786, - NPC_MITHDRAN_LAYING = 166791, - NPC_LANA_JORDAN_LAYING = 166796, - NPC_BO_STANDING = 166787, - NPC_MITHDRAN_STANDING = 166792, - NPC_LANA_JORDAN_STANDING = 166797, - - QUEST_FINDING_THE_LOST_EXPEDITION_HORDE = 59931, - QUEST_FINDING_THE_LOST_EXPEDITION_ALLIANCE = 54952, - - PATH_BO_TO_GRIMAXE = 10520210, - PATH_MITHDRAN_TO_GRIMAXE = 10520220, - PATH_LANA_JORDAN_TO_GRIMAXE = 10520230, - - PATH_BO_LEAVE_BEACH = ((1052021 * 10) + 1) << 3, - PATH_MITHDRAN_LEAVE_BEACH = ((1052022 * 10) + 1) << 3, - PATH_LANA_JORDAN_LEAVE_BEACH = ((1052023 * 10) + 1) << 3, - - TALK_HORDE_BEACH_THANK_PLAYER = 0 -}; - -// 166786 - Bo -struct npc_bo_beach_laying : public ScriptedAI -{ - npc_bo_beach_laying(Creature* creature) : ScriptedAI(creature) { } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_BANDAGING_QUEST) - return; - - static const Position BoCloneSpawnPosition = { -448.731f, -2606.03f, 0.602435f, 6.17441f }; - - if (Player* player = caster->ToPlayer()) - { - player->KilledMonsterCredit(me->GetEntry()); - - if (Creature* survivor = FindCreatureIgnorePhase(player, "bo_beach", 50.0f)) - survivor->SummonPersonalClone(BoCloneSpawnPosition, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - } - } -}; - -// 166791 - Mithdran Dawntracker -struct npc_mithran_dawntracker_beach_laying : public ScriptedAI -{ - npc_mithran_dawntracker_beach_laying(Creature* creature) : ScriptedAI(creature) { } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_BANDAGING_QUEST) - return; - - static Position const MithranCloneSpawnPosition = { -428.576f, -2593.93f, 0.152832f, 4.849576f }; - - if (Player* player = caster->ToPlayer()) - { - player->KilledMonsterCredit(me->GetEntry()); - - if (Creature* survivor = FindCreatureIgnorePhase(player, "mithran_beach", 50.0f)) - survivor->SummonPersonalClone(MithranCloneSpawnPosition, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - } - } -}; - -// 166796 - Lana Jordan -struct npc_lana_jordan_beach_laying : public ScriptedAI -{ - npc_lana_jordan_beach_laying(Creature* creature) : ScriptedAI(creature) { } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_BANDAGING_QUEST) - return; - - static Position const LanaCloneSpawnPosition = { -420.656f, -2600.28f, 0.556646f, 4.046853f }; - - if (Player* player = caster->ToPlayer()) - { - player->KilledMonsterCredit(me->GetEntry()); - - if (Creature* survivor = FindCreatureIgnorePhase(player, "lana_jordan_beach", 50.0f)) - survivor->SummonPersonalClone(LanaCloneSpawnPosition, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - } - } -}; - -enum ExilesReachMurlocsData -{ - ITEM_STITCHED_CLOTH_SHOES = 174791, - ITEM_STITCHED_LEATHER_BOOTS = 174792, - ITEM_LINKED_MAIL_BOOTS = 174793, - ITEM_DENTED_PLATE_BOOTS = 174794, - - QUEST_MURLOC_HIDEAWAY_BOOTS_DROPPED = 58883 -}; - -// 150228 - Murloc Spearhunter -// 150229 - Murloc Watershaper -struct npc_murloc_spearhunter_watershaper : public ScriptedAI -{ - npc_murloc_spearhunter_watershaper(Creature* creature) : ScriptedAI(creature) { } - - void JustDied(Unit* /*killer*/) override - { - for (auto const& [playerGuid, loot] : me->m_personalLoot) - { - for (LootItem const& lootItem : loot->items) - { - if (lootItem.itemid == ITEM_STITCHED_CLOTH_SHOES || lootItem.itemid == ITEM_STITCHED_LEATHER_BOOTS || lootItem.itemid == ITEM_LINKED_MAIL_BOOTS || lootItem.itemid == ITEM_DENTED_PLATE_BOOTS) - if (Player* player = ObjectAccessor::GetPlayer(*me, playerGuid)) - player->SetRewardedQuest(QUEST_MURLOC_HIDEAWAY_BOOTS_DROPPED); - } - } - } - - void UpdateAI(uint32 /*diff*/) override - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } -}; - -// 150228 - Murloc Spearhunter -// 150229 - Murloc Watershaper -struct npc_murloc_spearhunter_watershaper_higher_ground : public npc_murloc_spearhunter_watershaper -{ - npc_murloc_spearhunter_watershaper_higher_ground(Creature* creature) : npc_murloc_spearhunter_watershaper(creature) { } - - void JustEngagedWith(Unit* who) override - { - me->GetMotionMaster()->MoveJump(who->GetPosition(), 16.0f, 6.2f); - } -}; - -// 166787 - Bo -// 166792 - Mithdran Dawntracker -// 166797 - Lana Jordan -template<uint32 PathId> -struct npc_horde_survivors_beach_q59930_private : public ScriptedAI -{ - npc_horde_survivors_beach_q59930_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->SetStandState(UNIT_STAND_STATE_SLEEP); - } - - void JustAppeared() override - { - _events.ScheduleEvent(EVENT_SURVIVORS_HORDE_STAND_AND_TALK, 1s); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 /*pathId*/) override - { - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SURVIVORS_HORDE_STAND_AND_TALK: - Talk(TALK_HORDE_BEACH_THANK_PLAYER); - me->SetStandState(UNIT_STAND_STATE_STAND); - _events.ScheduleEvent(EVENT_SURVIVORS_HORDE_MOVE_TO_GRIMAXE, 6s); - break; - case EVENT_SURVIVORS_HORDE_MOVE_TO_GRIMAXE: - me->GetMotionMaster()->MovePath(PathId, false); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -// 151088 - Kee La -// 151089 - Bjorn Stouthands -// 154170 - Austin Huxworth -// 166787 - Bo -// 166792 - Mithdran Dawntracker -// 166797 - Lana Jordan -template<uint32 PathId, uint32 WaitTime> -struct npc_survivors_beach_leave_private : public ScriptedAI -{ - npc_survivors_beach_leave_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - _events.ScheduleEvent(EVENT_SURVIVORS_SALUTE, 6s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SURVIVORS_SALUTE: - me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - _events.ScheduleEvent(EVENT_SURVIVORS_LEAVE_BEACH, 2s); - break; - case EVENT_SURVIVORS_LEAVE_BEACH: - me->GetMotionMaster()->MovePath(PathId, false); - me->DespawnOrUnsummon(Milliseconds(WaitTime)); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -CreatureAI* BoBeachStandingAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if ((privateObjectOwner->GetQuestStatus(QUEST_FINDING_THE_LOST_EXPEDITION_HORDE) == QUEST_STATUS_NONE)) - return new npc_horde_survivors_beach_q59930_private<PATH_BO_TO_GRIMAXE>(creature); - else - return new npc_survivors_beach_leave_private<PATH_BO_LEAVE_BEACH, 5 * IN_MILLISECONDS>(creature); - } - } - - return new NullCreatureAI(creature); -}; - -CreatureAI* MithdranBeachStandingAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if ((privateObjectOwner->GetQuestStatus(QUEST_FINDING_THE_LOST_EXPEDITION_HORDE) == QUEST_STATUS_NONE)) - return new npc_horde_survivors_beach_q59930_private<PATH_MITHDRAN_TO_GRIMAXE>(creature); - else - return new npc_survivors_beach_leave_private<PATH_MITHDRAN_LEAVE_BEACH, 4 * IN_MILLISECONDS>(creature); - } - } - - return new NullCreatureAI(creature); -}; - -CreatureAI* LanaJordanBeachStandingAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if ((privateObjectOwner->GetQuestStatus(QUEST_FINDING_THE_LOST_EXPEDITION_HORDE) == QUEST_STATUS_NONE)) - return new npc_horde_survivors_beach_q59930_private<PATH_LANA_JORDAN_TO_GRIMAXE>(creature); - else - return new npc_survivors_beach_leave_private<PATH_LANA_JORDAN_LEAVE_BEACH, 5 * IN_MILLISECONDS>(creature); - } - } - - return new NullCreatureAI(creature); -}; - -CreatureAI* KeeLaBeachStandingAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_survivors_beach_leave_private<PATH_KEE_LA_STANDING, 7 * IN_MILLISECONDS>(creature); - return new NullCreatureAI(creature); -}; - -CreatureAI* BjornBeachStandingAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_survivors_beach_leave_private<PATH_BJORN_STOUTHANDS_STANDING, 4 * IN_MILLISECONDS>(creature); - return new NullCreatureAI(creature); -}; - -CreatureAI* AustinBeachStandingAISelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_survivors_beach_leave_private<PATH_AUSTIN_HUXWORTH_STANDING, 5 * IN_MILLISECONDS>(creature); - return new NullCreatureAI(creature); -}; - -enum LostExpeditionFollowerData -{ - ACTOR_ID_EMPTY = 0, - ACTOR_ID_ALLIANCE_SURVIVOR = 69830, - ACTOR_ID_HORDE_SURVIVOR = 76283, - - ACTOR_INDEX_SURVIVOR_ZERO = 0, - ACTOR_INDEX_SURVIVOR_ONE, - ACTOR_INDEX_SURVIVOR_TWO, - ACTOR_INDEX_SURVIVOR_THREE, - - AREA_ABANDONED_CAMP = 10452, - - CONVERSATION_LINE_ESCORT_ALLIANCE_SURVIVOR = 12044, - CONVERSATION_LINE_ESCORT_HORDE_SURVIVOR = 14437, - CONVERSATION_LINE_ESCORT_SURVIVOR_CAMP = 12058, - - EVENT_INITIAL_SPAWN_CHECK = 1, - EVENT_FOLLOW_PLAYER, - - SPELL_GARRICK_PING = 313664, - SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN = 297295, - SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN = 325075, - - POINT_CAMP_POSITION = 0, -}; - -Position const GarrickAbandonedCampPosition = { -249.059006f, -2492.520020f, 18.0742f }; -Position const GrimaxeAbandonedCampPosition = { -249.20117f, -2492.6191f, 17.964903f }; - -// 165359 - Captain Garrick -// This script is used by Captian Garrick Follower for Finding the Lost Expedition quest -struct npc_garrick_summoned_beach : public ScriptedAI -{ - npc_garrick_summoned_beach(Creature* creature) : ScriptedAI(creature), _reachedCamp(false) {} - - void IsSummonedBy(WorldObject* summoner) override - { - Player* player = summoner->ToPlayer(); - if (!player) - return; - - _playerGUID = player->GetGUID(); - - _events.ScheduleEvent(EVENT_INITIAL_SPAWN_CHECK, 1s); - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_GARRICK_PING) - return; - - if (_reachedCamp) - return; - - _reachedCamp = true; - - if (Player* player = caster->ToPlayer()) - { - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_LINE_ESCORT_SURVIVOR_CAMP, player, *player, _playerGUID, nullptr, false); - conversation->AddActor(ACTOR_ID_ALLIANCE_SURVIVOR, ACTOR_INDEX_SURVIVOR_ONE, me->GetGUID()); - conversation->Start(); - - me->GetMotionMaster()->Remove(FOLLOW_MOTION_TYPE); - me->GetMotionMaster()->MovePoint(POINT_CAMP_POSITION, GarrickAbandonedCampPosition, false); - } - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE || uiId != POINT_CAMP_POSITION) - return; - - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - { - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->RemoveAura(SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN); - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_INITIAL_SPAWN_CHECK: - { - Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID); - if (!player) - break; - - Creature* survivor = FindCreatureIgnorePhase(player, "spawn_check"); - - if (!survivor) - { - if (player->GetAreaId() != AREA_ABANDONED_CAMP) - player->RemoveAura(SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN); - else - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 0s); - } - else - { - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_LINE_ESCORT_ALLIANCE_SURVIVOR, player, *player, _playerGUID, nullptr, false); - conversation->AddActor(ACTOR_ID_ALLIANCE_SURVIVOR, ACTOR_INDEX_SURVIVOR_ONE, me->GetGUID()); - conversation->Start(); - - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 2s); - } - break; - } - case EVENT_FOLLOW_PLAYER: - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - me->GetMotionMaster()->MoveFollow(player, 0.0f, 0.0f); - break; - default: - break; - } - } - } -private: - EventMap _events; - ObjectGuid _playerGUID; - bool _reachedCamp; -}; - -// 166805 - Warlord Breka Grimaxe -// This script is used by Warlord Grimaxe Follower for Finding the Lost Expedition quest -struct npc_grimaxe_summoned_beach : public ScriptedAI -{ - npc_grimaxe_summoned_beach(Creature* creature) : ScriptedAI(creature), _reachedCamp(false) {} - - void IsSummonedBy(WorldObject* summoner) override - { - Player* player = summoner->ToPlayer(); - if (!player) - return; - - _playerGUID = player->GetGUID(); - _reachedCamp = false; - - _events.ScheduleEvent(EVENT_INITIAL_SPAWN_CHECK, 1s); - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_GARRICK_PING) - return; - - if (_reachedCamp) - return; - - if (Player* player = caster->ToPlayer()) - { - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_LINE_ESCORT_SURVIVOR_CAMP, player, *player, _playerGUID, nullptr, false); - conversation->AddActor(ACTOR_ID_HORDE_SURVIVOR, ACTOR_INDEX_SURVIVOR_THREE, me->GetGUID()); - conversation->Start(); - - me->GetMotionMaster()->Remove(FOLLOW_MOTION_TYPE); - me->GetMotionMaster()->MovePoint(POINT_CAMP_POSITION, GrimaxeAbandonedCampPosition, false); - } - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE || uiId != POINT_CAMP_POSITION) - return; - - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - { - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->RemoveAura(SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN); - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_INITIAL_SPAWN_CHECK: - { - Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID); - if (!player) - break; - - Creature* survivor = FindCreatureIgnorePhase(player, "spawn_check"); - - if (!survivor) - { - if (player->GetAreaId() != AREA_ABANDONED_CAMP) - player->RemoveAura(SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN); - else - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 0s); - } - else - { - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_LINE_ESCORT_HORDE_SURVIVOR, player, *player, _playerGUID, nullptr, false); - conversation->AddActor(ACTOR_ID_HORDE_SURVIVOR, ACTOR_INDEX_SURVIVOR_TWO, me->GetGUID()); - conversation->Start(); - - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 2s); - } - break; - } - case EVENT_FOLLOW_PLAYER: - if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) - me->GetMotionMaster()->MoveFollow(player, 0.0f, 0.0f); - break; - default: - break; - } - } - } -private: - EventMap _events; - ObjectGuid _playerGUID; - bool _reachedCamp; -}; - -// 54952 - Finding the Lost Expedition -// 59931 - Finding the Lost Expedition -class quest_finding_the_lost_expedition : public QuestScript -{ -public: - quest_finding_the_lost_expedition(char const* script) : QuestScript(script) { } - - void HandleQuestStatusChange(Player* player, QuestStatus newStatus, uint32 summonSpellId, std::string_view survivor1StringId, std::string_view survivor2StringId, std::string_view survivor3StringId) - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, summonSpellId); - - if (Creature* survivor1 = FindCreatureIgnorePhase(player, survivor1StringId, 25.0f)) - { - Creature* survivor1Personal = survivor1->SummonPersonalClone(survivor1->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - survivor1Personal->SetScriptStringId("spawn_check"); - } - if (Creature* survivor2 = FindCreatureIgnorePhase(player, survivor2StringId, 25.0f)) - survivor2->SummonPersonalClone(survivor2->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (Creature* survivor3 = FindCreatureIgnorePhase(player, survivor3StringId, 25.0f)) - survivor3->SummonPersonalClone(survivor3->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - - break; - case QUEST_STATUS_NONE: - player->RemoveAura(summonSpellId); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - default: - break; - } - } -}; - -// 54952 - Finding the Lost Expedition -class quest_finding_the_lost_expedition_alliance : public quest_finding_the_lost_expedition -{ -public: - quest_finding_the_lost_expedition_alliance() : quest_finding_the_lost_expedition("quest_finding_the_lost_expedition_alliance") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, - SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN, - "kee_la_beach", - "bjorn_stouthands_beach", - "austin_huxworth_beach"); - } -}; - -// 59931 - Finding the Lost Expedition -class quest_finding_the_lost_expedition_horde : public quest_finding_the_lost_expedition -{ -public: - quest_finding_the_lost_expedition_horde() : quest_finding_the_lost_expedition("quest_finding_the_lost_expedition_horde") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, - SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN, - "bo_beach", - "mithran_beach", - "lana_jordan_beach"); - } -}; - -// 305596 - Summon Admiral Garrick Guardian -// 325076 - Summon Warlord Grimaxe -class spell_summon_survivor_beach : public SpellScript -{ - void SelectTarget(WorldObject*& target) - { - Player* caster = GetCaster()->ToPlayer(); - if (!caster) - return; - - Creature* survivor = FindCreatureIgnorePhase(caster, caster->GetTeam() == ALLIANCE ? "q54952_garrick" : "q59931_grimaxe", 5.0f); - if (!survivor) - return; - - target = survivor; - } - - void Register() override - { - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_summon_survivor_beach::SelectTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY_OR_DB); - } -}; - -// ****************************************************************** -// * Scripting in this section occurs after reaching Abandoned Camp * -// ****************************************************************** - -enum CaptainGarrickAbandonedCampData -{ - CONVERSATION_QUEST_COOKING_MEAT_ACCEPT_ALLIANCE = 11696, - CONVERSATION_QUEST_COOKING_MEAT_COMPLETE_ALLIANCE = 12863, - - QUEST_COOKING_MEAT_ALLIANCE = 55174 -}; - -enum WarlordGrimaxeAbandonedCampData -{ - CONVERSATION_QUEST_COOKING_MEAT_ACCEPT_HORDE = 14439, - CONVERSATION_QUEST_COOKING_MEAT_COMPLETE_HORDE = 14611, - - QUEST_COOKING_MEAT_HORDE = 59932 -}; - -template<uint32 QuestId, uint32 ConversationId> -struct npc_captain_abandoned_camp_exiles_reach : public ScriptedAI -{ - npc_captain_abandoned_camp_exiles_reach(Creature* creature) : ScriptedAI(creature) { } - - void OnQuestAccept(Player* player, Quest const* quest) override - { - if (quest->GetQuestId() != QuestId) - return; - - Conversation::CreateConversation(ConversationId, player, *player, player->GetGUID()); - } -}; - -enum CookingMeatQuestData -{ - ANIMATION_KIT_INJURED = 14432 -}; - -Position const InjuredNpcPositionAbandonedCamp = { -245.40973f, -2492.0886f, 18.404648f, 2.4754f }; - -// 55174 - Cooking Meat -// 59932 - Cooking Meat -class quest_cooking_meat : public QuestScript -{ -public: - quest_cooking_meat(char const* script) : QuestScript(script) { } - - void HandleQuestStatusChange(Player* player, QuestStatus newStatus, uint32 completeConversationId, std::string_view injuredStringId) - { - switch (newStatus) - { - case QUEST_STATUS_COMPLETE: - { - Conversation::CreateConversation(completeConversationId, player, *player, player->GetGUID()); - break; - } - case QUEST_STATUS_REWARDED: - { - Creature* injured = FindCreatureIgnorePhase(player, injuredStringId); - if (!injured) - break; - - injured->SummonPersonalClone(InjuredNpcPositionAbandonedCamp, TEMPSUMMON_TIMED_DESPAWN, 2s, 0, 0, player); - break; - } - default: - break; - } - } -}; - -// 55174 - Cooking Meat -class quest_cooking_meat_alliance : public quest_cooking_meat -{ -public: - quest_cooking_meat_alliance() : quest_cooking_meat("quest_cooking_meat_alliance") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, - CONVERSATION_QUEST_COOKING_MEAT_COMPLETE_ALLIANCE, - "alaria_standing_abandoned_camp"); - } -}; - -// 59932 - Cooking Meat -class quest_cooking_meat_horde : public quest_cooking_meat -{ -public: - quest_cooking_meat_horde() : quest_cooking_meat("quest_cooking_meat_horde") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, - CONVERSATION_QUEST_COOKING_MEAT_COMPLETE_HORDE, - "wonza_standing_abandoned_camp"); - } -}; - -struct areatrigger_find_the_lost_expedition : AreaTriggerAI -{ - areatrigger_find_the_lost_expedition(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - if (player->GetQuestStatus(QUEST_FINDING_THE_LOST_EXPEDITION_ALLIANCE) == QUEST_STATUS_COMPLETE || player->GetQuestStatus(QUEST_FINDING_THE_LOST_EXPEDITION_HORDE) == QUEST_STATUS_INCOMPLETE) - player->CastSpell(player, SPELL_GARRICK_PING); - } -}; - -struct areatrigger_find_the_lost_expedition_follower : AreaTriggerAI -{ - areatrigger_find_the_lost_expedition_follower(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - if (player->GetTeam() == ALLIANCE) - { - if (player->GetQuestStatus(QUEST_FINDING_THE_LOST_EXPEDITION_ALLIANCE) != QUEST_STATUS_INCOMPLETE) - return; - - if (player->HasAura(SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN)) - return; - - player->CastSpell(player, SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN); - } - else - { - if (player->GetQuestStatus(QUEST_FINDING_THE_LOST_EXPEDITION_HORDE) != QUEST_STATUS_INCOMPLETE) - return; - - if (player->HasAura(SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN)) - return; - - player->CastSpell(player, SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN); - } - } -}; - -void AddSC_zone_exiles_reach() -{ - // Ship - RegisterSpellScript(spell_attention_exiles_reach_tutorial); - new q59926_warming_up(); - new q56775_warming_up(); - new quest_stand_your_ground(); - RegisterCreatureAI(npc_sparring_partner_exiles_reach); - RegisterSpellScript(spell_summon_sparring_partner); - new FactoryCreatureScript<CreatureAI, &CaptainGarrickShipAISelector>("npc_captain_garrick_ship"); - RegisterPrivatePublicCreatureAIPair("npc_warlord_grimaxe_lower_ship", npc_ship_captain_warming_up_private, NullCreatureAI); - RegisterPrivatePublicCreatureAIPair("npc_warlord_grimaxe_upper_ship", npc_ship_captain_brace_for_impact_private, NullCreatureAI); - RegisterPrivatePublicCreatureAIPair("npc_cole_ship", npc_first_mate_brace_for_impact_private, npc_first_mate_stand_your_ground); - RegisterPrivatePublicCreatureAIPair("npc_throg_ship", npc_first_mate_brace_for_impact_private, npc_first_mate_stand_your_ground); - RegisterPrivatePublicCreatureAIPair("npc_crew_ship", npc_crew_ship_private, NullCreatureAI); - RegisterPrivatePublicCreatureAIPair("npc_pet_ship", npc_pet_ship_private, NullCreatureAI); - new quest_brace_for_impact(); - new player_exiles_reach_ship_crash(); - new scene_alliance_and_horde_ship(); - - // Beach - RegisterSpellScript(spell_knocked_down_exiles_reach_beach); - new scene_alliance_and_horde_crash(); - RegisterSpellScriptWithArgs(spell_crash_landed_generic<NPC_CAPTAIN_GARRICK_BEACH>, "spell_crash_landed_alliance"); - RegisterSpellScriptWithArgs(spell_crash_landed_generic<NPC_WARLORD_BREKA_GRIMAXE_BEACH>, "spell_crash_landed_horde"); - new FactoryCreatureScript<CreatureAI, &CaptainGarrickBeachAISelector>("npc_captain_garrick_beach"); - new FactoryCreatureScript<CreatureAI, &WarlordGrimaxeBeachAISelector>("npc_warlord_grimaxe_beach"); - new FactoryCreatureScript<CreatureAI, &HealedByLeaderAllianceAISelector>("npc_healed_by_leader_alliance_beach"); - new FactoryCreatureScript<CreatureAI, &HealedByLeaderHordeAISelector>("npc_healed_by_leader_horde_beach"); - new GenericCreatureScript<npc_alliance_survivors_beach_laying<CONVERSATION_STOUTHANDS_BEACH>>("npc_bjorn_stouthands_beach_laying"); - new GenericCreatureScript<npc_alliance_survivors_beach_laying<CONVERSATION_HUXWORTH_BEACH>>("npc_austin_huxworth_beach_laying"); - new GenericCreatureScript<npc_alliance_survivors_beach_laying<CONVERSATION_KEE_LA_BEACH>>("npc_kee_la_beach_laying"); - // Note: alliance survivor do not need a script for Emergency First Aid quest - RegisterCreatureAI(npc_bo_beach_laying); - RegisterCreatureAI(npc_mithran_dawntracker_beach_laying); - RegisterCreatureAI(npc_lana_jordan_beach_laying); - RegisterCreatureAI(npc_murloc_spearhunter_watershaper); - RegisterCreatureAI(npc_murloc_spearhunter_watershaper_higher_ground); - new FactoryCreatureScript<CreatureAI, &BoBeachStandingAISelector>("npc_bo_beach_standing"); - new FactoryCreatureScript<CreatureAI, &MithdranBeachStandingAISelector>("npc_mithdran_dawntracker_beach_standing"); - new FactoryCreatureScript<CreatureAI, &LanaJordanBeachStandingAISelector>("npc_lana_jordan_beach_standing"); - new FactoryCreatureScript<CreatureAI, &KeeLaBeachStandingAISelector>("npc_kee_la_beach_standing"); - new FactoryCreatureScript<CreatureAI, &BjornBeachStandingAISelector>("npc_bjorn_stouthands_beach_standing"); - new FactoryCreatureScript<CreatureAI, &AustinBeachStandingAISelector>("npc_austin_huxworth_beach_standing"); - RegisterCreatureAI(npc_garrick_summoned_beach); - RegisterCreatureAI(npc_grimaxe_summoned_beach); - new quest_finding_the_lost_expedition_alliance(); - new quest_finding_the_lost_expedition_horde(); - RegisterSpellScript(spell_summon_survivor_beach); - - // Abandoned Camp - new GenericCreatureScript<npc_captain_abandoned_camp_exiles_reach<QUEST_COOKING_MEAT_ALLIANCE, CONVERSATION_QUEST_COOKING_MEAT_ACCEPT_ALLIANCE>>("npc_captain_garrick_abandoned_camp"); - new GenericCreatureScript<npc_captain_abandoned_camp_exiles_reach<QUEST_COOKING_MEAT_HORDE, CONVERSATION_QUEST_COOKING_MEAT_ACCEPT_HORDE>>("npc_warlord_grimaxe_abandoned_camp"); - new quest_cooking_meat_alliance(); - new quest_cooking_meat_horde(); - RegisterAreaTriggerAI(areatrigger_find_the_lost_expedition); - RegisterAreaTriggerAI(areatrigger_find_the_lost_expedition_follower); -} diff --git a/src/server/scripts/Pandaria/pandaria_scripts_loader.cpp b/src/server/scripts/Pandaria/pandaria_scripts_loader.cpp deleted file mode 100644 index e84ea05039c..00000000000 --- a/src/server/scripts/Pandaria/pandaria_scripts_loader.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -// This is where scripts loading function should be declared: -void AddSC_zone_the_wandering_isle(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddPandariaScripts() -{ - AddSC_zone_the_wandering_isle(); -} diff --git a/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp b/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp deleted file mode 100644 index cc32e5117dc..00000000000 --- a/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "CellImpl.h" -#include "Containers.h" -#include "GridNotifiersImpl.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "Player.h" -#include "ScriptedCreature.h" -#include "ScriptMgr.h" -#include "TaskScheduler.h" - -enum TraineeMisc -{ - SAY_FINISH_FIGHT = 0, - - SPELL_BLACKOUT_KICK = 109080, - - QUEST_29524_KILLCREDIT = 54586, - - POINT_DESPAWN = 0, - - NPC_HUOJIN_TRAINEE_MALE = 54586, - NPC_HUOJIN_TRAINEE_FEMALE = 65470, - NPC_TUSHUI_TRAINEE_MALE = 54587, - NPC_TUSHUI_TRAINEE_FEMALE = 65471, -}; - -Position const TraineeEndpoints[] = { - { 1465.3872f, 3283.8604f, 137.69096f }, - { 1431.401f, 3264.001f, 136.02579f }, - { 1397.2067f, 3276.5618f, 133.84508f }, - { 1441.566f, 3232.8013f, 135.01802f }, - { 1403.632f, 3229.1094f, 132.14877f }, - { 1347.1927f, 3286.5842f, 131.94803f }, - { 1365.1865f, 3338.9502f, 128.57233f }, - { 1349.6024f, 3315.0574f, 130.97443f }, - { 1335.4618f, 3344.019f, 130.42047f }, - { 1360.1198f, 3378.02f, 127.34183f }, - { 1435.8524f, 3355.6423f, 173.77744f }, - { 1432.7031f, 3385.1572f, 184.4187f }, - { 1452.6094f, 3373.3315f, 187.0402f }, - { 1426.7778f, 3364.7517f, 184.39569f }, - { 1450.3646f, 3361.264f, 184.42484f }, -}; - -Emote constexpr TraineeEmotes[5] = -{ - EMOTE_ONESHOT_MONKOFFENSE_ATTACKUNARMED, - EMOTE_ONESHOT_MONKOFFENSE_SPECIALUNARMED, - EMOTE_ONESHOT_MONKOFFENSE_PARRYUNARMED, - EMOTE_ONESHOT_PALMSTRIKE, - EMOTE_ONESHOT_MONKOFFENSE_ATTACKUNARMEDOFF, -}; - -// 54586 - Huojin Trainee -// 65470 - Huojin Trainee -// 54587 - Tushui Trainee -// 65471 - Tushui Trainee -struct npc_tushui_huojin_trainee : public ScriptedAI -{ - npc_tushui_huojin_trainee(Creature* creature) : ScriptedAI(creature), _defeated(false) { } - - Emote PlayRandomEmote() const - { - Emote emote = Trinity::Containers::SelectRandomContainerElement(TraineeEmotes); - me->HandleEmoteCommand(emote); - return emote; - } - - void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (me->HealthBelowPctDamaged(20, damage)) - { - damage = 0; - if (_defeated) - return; - - _defeated = true; - if (attacker) - { - if (Player* player = attacker->ToPlayer()) - player->KilledMonsterCredit(QUEST_29524_KILLCREDIT); - } - - me->SetEmoteState(EMOTE_ONESHOT_NONE); - me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC); - me->CombatStop(); - - _scheduler.Schedule(Seconds(1), [this](TaskContext /*task*/) - { - Talk(SAY_FINISH_FIGHT); - }); - - _scheduler.Schedule(Seconds(3), [this](TaskContext /*task*/) - { - Position currentPosition; - float currentDist = 1000.0f; - for (Position const& pos : TraineeEndpoints) - { - float dist = pos.GetExactDist(me); - if (dist >= currentDist) - continue; - - currentPosition = pos; - currentDist = dist; - } - me->GetMotionMaster()->MovePoint(POINT_DESPAWN, currentPosition); - }); - } - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (id != POINT_DESPAWN) - return; - - me->DespawnOrUnsummon(); - } - - void JustEngagedWith(Unit* /*attacker*/) override - { - _scheduler.Schedule(Seconds(4), [this](TaskContext task) - { - if (me->GetVictim()) - DoCastVictim(SPELL_BLACKOUT_KICK); - - task.Repeat(Seconds(8)); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - - void EnterEvadeMode(EvadeReason why) override - { - if (!_defeated) - ScriptedAI::EnterEvadeMode(why); - } - -protected: - TaskScheduler _scheduler; - bool _defeated; -}; - -enum HuojinTraineeMisc -{ - ACTION_PARTNER_ENTERED_COMBAT = 1, -}; - -class HuojinTraineePartnerSearch -{ -public: - HuojinTraineePartnerSearch(Creature* partner) : _partner(partner), _minDist(10.0f) { } - - bool operator()(Creature const* target) - { - if (target->GetEntry() != NPC_HUOJIN_TRAINEE_MALE && target->GetEntry() != NPC_HUOJIN_TRAINEE_FEMALE) - return false; - if (target == _partner) - return false; - if (target->IsInCombat()) - return false; - if (target->IsInEvadeMode()) - return false; - if (target->isDead()) - return false; - - float dist = target->GetDistance(_partner); - if (dist >= _minDist) - return false; - - _minDist = dist; - return true; - } - -private: - Unit* _partner; - float _minDist; -}; - -// 54586 - Huojin Trainee -// 65470 - Huojin Trainee -struct npc_huojin_trainee : public npc_tushui_huojin_trainee -{ - npc_huojin_trainee(Creature* creature) : npc_tushui_huojin_trainee(creature) { } - - void JustEngagedWith(Unit* attacker) override - { - _scheduler.CancelAll(); - npc_tushui_huojin_trainee::JustEngagedWith(attacker); - - Creature* partner = ObjectAccessor::GetCreature(*me, _partnerGuid); - if (!partner) - return; - - if (partner->AI()) - partner->AI()->DoAction(ACTION_PARTNER_ENTERED_COMBAT); - } - - void DoAction(int32 action) override - { - if (action == ACTION_PARTNER_ENTERED_COMBAT) - { - _scheduler.CancelAll(); - - me->SetEmoteState(EMOTE_ONESHOT_NONE); - _scheduler.Schedule(Seconds(1), [this](TaskContext /*task*/ ) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_BOW); - }); - } - } - - void BeginSparring(ObjectGuid guid) - { - _partnerGuid = guid; - me->SetEmoteState(EMOTE_ONESHOT_NONE); - me->HandleEmoteCommand(EMOTE_ONESHOT_BOW); - - _scheduler.Schedule(Seconds(1), [this](TaskContext /*task*/) - { - me->SetEmoteState(EMOTE_STATE_MONKOFFENSE_READYUNARMED); - }); - - _scheduler.Schedule(Seconds(4), [this](TaskContext task) - { - PlayRandomEmote(); - task.Repeat(Seconds(4)); - }); - } - - Creature* GetNewPartner() const - { - Creature* partner = nullptr; - HuojinTraineePartnerSearch check(me); - Trinity::CreatureLastSearcher<HuojinTraineePartnerSearch> searcher(me, partner, check); - Cell::VisitGridObjects(me, searcher, 10.0f); - return partner; - } - - void BeginSparringDelayed(ObjectGuid partnerGuid) - { - _partnerGuid = partnerGuid; - _scheduler.Schedule(Seconds(1), [this, partnerGuid](TaskContext /*task*/) - { - BeginSparring(partnerGuid); - }); - } - - void InitiateSparring() - { - Creature* partner = GetNewPartner(); - - if (!partner) - return; - - BeginSparring(partner->GetGUID()); - if (Creature* partner = ObjectAccessor::GetCreature(*me, _partnerGuid)) - { - if (npc_huojin_trainee* ai = CAST_AI(npc_huojin_trainee, partner->GetAI())) - ai->BeginSparringDelayed(me->GetGUID()); - } - } - - void JustReachedHome() override - { - InitiateSparring(); - } - - void JustAppeared() override - { - // partner is already assigned, sparring start is delayed - if (!ObjectAccessor::GetCreature(*me, _partnerGuid)) - InitiateSparring(); - } -private: - ObjectGuid _partnerGuid; -}; - -class TushuiTraineeSearch -{ -public: - TushuiTraineeSearch(Creature* leader, float maxDist) : _leader(leader), _maxDist(maxDist) { } - - bool operator()(Creature const* target) const - { - if (target->GetEntry() != NPC_TUSHUI_TRAINEE_MALE && target->GetEntry() != NPC_TUSHUI_TRAINEE_FEMALE) - return false; - if (target->IsInCombat()) - return false; - if (target->IsInEvadeMode()) - return false; - if (target->GetDistance(_leader) >= _maxDist) - return false; - if (target->isDead()) - return false; - - return true; - } - -private: - Creature* _leader; - float _maxDist; -}; - -void HandleEmoteNearbyTushuiTrainees(Creature* leader, Emote emote) -{ - std::list<Creature*> traineeList; - TushuiTraineeSearch check(leader, 10.0f); - Trinity::CreatureListSearcher<TushuiTraineeSearch> searcher(leader, traineeList, check); - Cell::VisitGridObjects(leader, searcher, 10.0f); - - for (Creature* trainee : traineeList) - trainee->HandleEmoteCommand(emote); -} - -// 54587 - Tushui Trainee -// 65471 - Tushui Trainee -struct npc_tushui_leading_trainee : public npc_tushui_huojin_trainee -{ - npc_tushui_leading_trainee(Creature* creature) : npc_tushui_huojin_trainee(creature) { } - - void ScheduleEmoteExecution() - { - _scheduler.Schedule(Seconds(1), [this](TaskContext task) - { - Emote emote = PlayRandomEmote(); - HandleEmoteNearbyTushuiTrainees(me, emote); - task.Repeat(Seconds(6)); - }); - } - - void JustReachedHome() override - { - ScheduleEmoteExecution(); - } - - void JustAppeared() override - { - ScheduleEmoteExecution(); - } - - void JustEngagedWith(Unit* attacker) override - { - _scheduler.CancelAll(); - npc_tushui_huojin_trainee::JustEngagedWith(attacker); - } -}; - -// 61411 - Instructor Zhi -struct npc_instructor_zhi : public ScriptedAI -{ - npc_instructor_zhi(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - _scheduler.Schedule(Seconds(6), [this](TaskContext task) - { - Emote emote = Trinity::Containers::SelectRandomContainerElement(TraineeEmotes); - me->HandleEmoteCommand(emote); - - task.Schedule(Seconds(1), [this, emote](TaskContext /*task*/) - { - HandleEmoteNearbyTushuiTrainees(me, emote); - }); - task.Repeat(Seconds(6)); - }); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -void AddSC_zone_the_wandering_isle() -{ - RegisterCreatureAI(npc_tushui_huojin_trainee); - RegisterCreatureAI(npc_huojin_trainee); - RegisterCreatureAI(npc_tushui_leading_trainee); - RegisterCreatureAI(npc_instructor_zhi); -} diff --git a/src/server/scripts/Shadowlands/SanctumOfDomination/boss_sylvanas_windrunner.cpp b/src/server/scripts/Shadowlands/SanctumOfDomination/boss_sylvanas_windrunner.cpp deleted file mode 100644 index 4ed74a7b144..00000000000 --- a/src/server/scripts/Shadowlands/SanctumOfDomination/boss_sylvanas_windrunner.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTrigger.h" -#include "AreaTriggerAI.h" -#include "Conversation.h" -#include "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "InstanceScript.h" -#include "Map.h" -#include "MotionMaster.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "sanctum_of_domination.h" - -Position const SylvanasIntroPos[4] = -{ - { 231.15799f, -832.816f, 4105.0386f }, - { 242.00348f, -840.51215f, 4105.0386f }, - { 241.23091f, -830.0955f, 4105.0386f }, - { 225.73611f, -844.0746f, 4104.9882f, 1.3613f } -}; - -enum SylvanasSpells -{ - // Stances - SPELL_RANGER_BOW_STANCE = 347560, - SPELL_RANGER_DAGGERS_STANCE = 348010, - - // Miscellanea - SPELL_GENERIC_ANCHOR_HERE = 45313, - SPELL_GENERIC_DUAL_WIELD = 42459, - SPELL_SYLVANAS_DISPLAY_POWER_SUFFERING = 352311, - SPELL_SYLVANAS_ROOT = 347608 -}; - -enum SylvanasPhases -{ - PHASE_ONE = 1, - PHASE_INTERMISSION = 4, - PHASE_TWO = 2, - PHASE_THREE = 3, - PHASE_INTERMISSION_WORLD_STATE = 11 -}; - -enum SylvanasEventGroups -{ - EVENT_GROUP_NORMAL_EVENTS = 1, - EVENT_GROUP_WINDRUNNER_EVENTS = 2 -}; - -enum SylvanasEvents -{ - EVENT_INTRODUCTION = 1, - EVENT_SIZE_MAX = 200 -}; - -enum SylvanasTexts -{ - SAY_ENGAGE = 0, - SAY_SLAY = 1, - SAY_DISENGAGE = 2 -}; - -enum SylvanasConversations -{ - CONVERSATION_SYLVANAS_INTRODUCTION = 17368, - CONVERSATION_SYLVANAS_INTRODUCTION_ACTOR_SYLVANAS_ID = 0, - CONVERSATION_SYLVANAS_INTRODUCTION_ACTOR_BOLVAR_ID = 1 -}; - -enum SylvanasSpawnGroups -{ - SPAWN_GROUP_CHAMPIONS_FIRST_PHASE = 0, - SPAWN_GROUP_CHAMPIONS_THIRD_PHASE, - SPAWN_GROUP_CHAMPIONS_OUTRODUCTION -}; - -enum SylvanasPoints -{ - POINT_INTRODUCTION = 1 -}; - -enum SylvanasSpellVisualKits -{ - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_01 = 150067, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_02 = 150068, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_03 = 150069, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_04 = 150071, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_05 = 150072, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_06 = 150070, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_07 = 150074, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_08 = 150077, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_09 = 150076, - SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_10 = 150075, - SPELL_VISUAL_KIT_BOLVAR_INTRODUCTION_TALK_01 = 150073, - - SPELL_VISUAL_KIT_SYLVANAS_TELEPORT = 150078 -}; - -// 178355 - Sylvanas Shadowcopy (Riding) -struct npc_sylvanas_windrunner_shadowcopy_riding : public ScriptedAI -{ - npc_sylvanas_windrunner_shadowcopy_riding(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetImmuneToAll(true, true); - me->SetUninteractible(true); - me->SetReactState(REACT_PASSIVE); - } -}; - -// 175732 - Sylvanas Windrunner -struct boss_sylvanas_windrunner : public BossAI -{ - boss_sylvanas_windrunner(Creature* creature) : BossAI(creature, DATA_SYLVANAS_WINDRUNNER) { } - - void JustAppeared() override - { - DoCastSelf(SPELL_GENERIC_DUAL_WIELD, true); - DoCastSelf(SPELL_SYLVANAS_DISPLAY_POWER_SUFFERING, true); - - me->SetPower(me->GetPowerType(), 0); - - if (instance->GetData(DATA_SYLVANAS_INTRODUCTION) == DONE) - { - me->RemoveUnitFlag(UNIT_FLAG_NOT_ATTACKABLE_1); - me->SetImmuneToAll(false); - me->SetSpeed(MOVE_RUN, 14.0f); - } - else - { - me->SetUnitFlag(UNIT_FLAG_NOT_ATTACKABLE_1); - me->SetImmuneToAll(true); - me->SetSpeed(MOVE_RUN, 4.0f); - } - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - Talk(SAY_DISENGAGE); - - _EnterEvadeMode(); - - summons.DespawnAll(); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - - _DespawnAtEvade(); - } - - void Reset() override - { - _Reset(); - - // Note: every creature involved in the fight adds UNIT_FLAG_PET_IN_COMBAT or UNIT_FLAG_RENAME when engaging, meaning they're most likely summoned by Sylvanas. - me->SummonCreatureGroup(SPAWN_GROUP_CHAMPIONS_FIRST_PHASE); - - instance->DoUpdateWorldState(WORLD_STATE_SYLVANAS_ENCOUNTER_PHASE, PHASE_ONE); - - events.Reset(); - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (id == POINT_INTRODUCTION) - DoCastSelf(SPELL_GENERIC_ANCHOR_HERE, true); - } - - void KilledUnit(Unit* victim) override - { - if (!victim->IsPlayer()) - return; - - Talk(SAY_SLAY); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); - - Talk(SAY_ENGAGE); - - instance->DoUpdateWorldState(WORLD_STATE_SYLVANAS_ENCOUNTER_PHASE, PHASE_ONE); - - events.SetPhase(PHASE_ONE); - - // Note: Sylvanas uses her root with 2s at the beginning of the encounter, most likely to avoid moving when engaging at stance switch. - DoCastSelf(SPELL_SYLVANAS_ROOT, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_DURATION, 2000)); - - // Note: we won't allow engaging until Phase 1 PR is merged. - me->Say("Only introduction is implemented so far, evading.", LANG_UNIVERSAL); - EnterEvadeMode(EvadeReason::Other); - } -}; - -// 45 - Sylvanas Windrunner's Position Z Check (Serverside) -struct at_sylvanas_windrunner_z_check : AreaTriggerAI -{ - at_sylvanas_windrunner_z_check(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsAlive()) - return; - - if (Player* player = unit->ToPlayer()) - { - if (player->IsGameMaster()) - return; - - if (player->IsAlive()) - player->KillSelf(false); - } - } -}; - -// 46 - Sylvanas Windrunner's Conversation Introduction (Serverside) -struct at_sylvanas_windrunner_introduction : AreaTriggerAI -{ - at_sylvanas_windrunner_introduction(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - InstanceScript* instance = at->GetInstanceScript(); - if (!instance) - return; - - Player* player = unit->ToPlayer(); - if (!player || player->IsGameMaster()) - return; - - if (Creature* sylvanas = instance->GetCreature(DATA_SYLVANAS_WINDRUNNER)) - Conversation::CreateConversation(CONVERSATION_SYLVANAS_INTRODUCTION, sylvanas, sylvanas->GetPosition(), ObjectGuid::Empty); - - at->Remove(); - } -}; - -// 17368 - Sylvanas Windrunner's Introduction (Conversation) -class conversation_sylvanas_windrunner_introduction : public ConversationScript -{ -public: - conversation_sylvanas_windrunner_introduction() : ConversationScript("conversation_sylvanas_windrunner_introduction") { } - - void OnConversationCreate(Conversation* conversation, Unit* creator) override - { - InstanceScript* instance = creator->GetInstanceScript(); - if (!instance) - return; - - Creature* bolvar = instance->GetCreature(DATA_BOLVAR_FORDRAGON_PINNACLE); - if (!bolvar) - return; - - instance->SetData(DATA_SYLVANAS_INTRODUCTION, IN_PROGRESS); - conversation->AddActor(NPC_BOLVAR_FORDRAGON_PINNACLE, CONVERSATION_SYLVANAS_INTRODUCTION_ACTOR_BOLVAR_ID, bolvar->GetGUID()); - - _events.ScheduleEvent(EVENT_INTRODUCTION, 5s + 500ms); - } - - void OnConversationUpdate(Conversation* conversation, uint32 diff) override - { - _events.Update(diff); - - uint32 eventId = _events.ExecuteEvent(); - Creature* sylvanas = nullptr; - Creature* bolvar = nullptr; - - if (eventId) - { - sylvanas = conversation->GetActorCreature(CONVERSATION_SYLVANAS_INTRODUCTION_ACTOR_SYLVANAS_ID); - if (!sylvanas) - return; - - bolvar = conversation->GetActorCreature(CONVERSATION_SYLVANAS_INTRODUCTION_ACTOR_BOLVAR_ID); - if (!bolvar) - return; - } - - switch (eventId) - { - case EVENT_INTRODUCTION: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_01, 0, 0); - sylvanas->SetFacingToObject(bolvar); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 1, 1s + 140ms); - break; - } - - case EVENT_INTRODUCTION + 1: - { - sylvanas->GetMotionMaster()->MovePoint(POINT_INTRODUCTION, SylvanasIntroPos[0], false); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 2, 1s + 500ms); - break; - } - - case EVENT_INTRODUCTION + 2: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_02, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 3, 3s + 360ms); - break; - } - - case EVENT_INTRODUCTION + 3: - { - sylvanas->GetMotionMaster()->MovePoint(POINT_INTRODUCTION, SylvanasIntroPos[1], false); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 4, 469ms); - break; - } - - case EVENT_INTRODUCTION + 4: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_03, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 5, 3s + 500ms); - break; - } - - case EVENT_INTRODUCTION + 5: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_04, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 6, 2s); - break; - } - - case EVENT_INTRODUCTION + 6: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_05, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 7, 5s); - break; - } - - case EVENT_INTRODUCTION + 7: - { - sylvanas->SetFacingToObject(bolvar); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 8, 750ms); - break; - } - - case EVENT_INTRODUCTION + 8: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_06, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 9, 457ms); - break; - } - - case EVENT_INTRODUCTION + 9: - { - sylvanas->GetMotionMaster()->MovePoint(POINT_INTRODUCTION, SylvanasIntroPos[2], false); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 10, 5s + 89ms); - break; - } - - case EVENT_INTRODUCTION + 10: - { - bolvar->SetFacingToObject(sylvanas); - bolvar->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_BOLVAR_INTRODUCTION_TALK_01, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 11, 13s + 567ms); - break; - } - - case EVENT_INTRODUCTION + 11: - { - sylvanas->SetFacingToObject(bolvar); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 12, 484ms); - break; - } - - case EVENT_INTRODUCTION + 12: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_07, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 13, 5s + 516ms); - break; - } - - case EVENT_INTRODUCTION + 13: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_08, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 14, 1s + 516ms); - break; - } - - case EVENT_INTRODUCTION + 14: - { - sylvanas->NearTeleportTo(SylvanasIntroPos[3], false); - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_TELEPORT, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 15, 1s + 265ms); - break; - } - - case EVENT_INTRODUCTION + 15: - { - sylvanas->SetFacingToObject(bolvar); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 16, 969ms); - break; - } - - case EVENT_INTRODUCTION + 16: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_09, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 17, 4s + 766ms); - break; - } - - case EVENT_INTRODUCTION + 17: - { - sylvanas->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SYLVANAS_INTRODUCTION_TALK_10, 0, 0); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 18, 3s + 250ms); - break; - } - - case EVENT_INTRODUCTION + 18: - { - sylvanas->CastSpell(sylvanas, SPELL_RANGER_BOW_STANCE); - - _events.ScheduleEvent(EVENT_INTRODUCTION + 19, 16ms); - break; - } - - case EVENT_INTRODUCTION + 19: - { - sylvanas->CastSpell(sylvanas, SPELL_GENERIC_ANCHOR_HERE); - - if (InstanceScript* instance = sylvanas->GetInstanceScript()) - instance->SetData(DATA_SYLVANAS_INTRODUCTION, DONE); - break; - } - - default: - break; - } - } - -private: - EventMap _events; -}; - -void AddSC_boss_sylvanas_windrunner() -{ - RegisterSanctumOfDominationCreatureAI(boss_sylvanas_windrunner); - RegisterSanctumOfDominationCreatureAI(npc_sylvanas_windrunner_shadowcopy_riding); - - RegisterAreaTriggerAI(at_sylvanas_windrunner_z_check); - RegisterAreaTriggerAI(at_sylvanas_windrunner_introduction); - - new conversation_sylvanas_windrunner_introduction(); -} diff --git a/src/server/scripts/Shadowlands/SanctumOfDomination/instance_sanctum_of_domination.cpp b/src/server/scripts/Shadowlands/SanctumOfDomination/instance_sanctum_of_domination.cpp deleted file mode 100644 index dfba70edc87..00000000000 --- a/src/server/scripts/Shadowlands/SanctumOfDomination/instance_sanctum_of_domination.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "Creature.h" -#include "GameObject.h" -#include "InstanceScript.h" -#include "Map.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "sanctum_of_domination.h" - -ObjectData const creatureData[] = -{ - { BOSS_SYLVANAS_WINDRUNNER, DATA_SYLVANAS_WINDRUNNER }, - { NPC_SYLVANAS_SHADOWCOPY_RIDING, DATA_SYLVANAS_SHADOWCOPY_RIDING }, - { NPC_BOLVAR_FORDRAGON_PINNACLE, DATA_BOLVAR_FORDRAGON_PINNACLE }, - { NPC_JAINA_PROUDMOORE_PINNACLE, DATA_JAINA_PROUDMOORE_PINNACLE }, - { NPC_THRALL_PINNACLE, DATA_THRALL_PINNACLE }, - { NPC_THRONE_OF_THE_DAMNED, DATA_THRONE_OF_THE_DAMNED }, - { 0, 0 } // END -}; - -DungeonEncounterData const encounters[] = -{ - { DATA_THE_TARRAGRUE, {{ 2423 }} }, - { DATA_THE_EYE_OF_THE_JAILER, {{ 2433 }} }, - { DATA_THE_NINE, {{ 2429 }} }, - { DATA_REMNANT_OF_NERZHUL, {{ 2432 }} }, - { DATA_SOULRENDER_DORMAZAIN, {{ 2434 }} }, - { DATA_PAINSMITH_RAZNAL, {{ 2430 }} }, - { DATA_GUARDIAN_OF_THE_FIRST_ONES, {{ 2436 }} }, - { DATA_FATESCRIBE_ROHKALO, {{ 2431 }} }, - { DATA_KELTHUZAD, {{ 2422 }} }, - { DATA_SYLVANAS_WINDRUNNER, {{ 2435 }} } -}; - -class instance_sanctum_of_domination : public InstanceMapScript -{ -public: - instance_sanctum_of_domination() : InstanceMapScript(SODScriptName, 2450) { } - - struct instance_sanctum_of_domination_InstanceMapScript : public InstanceScript - { - instance_sanctum_of_domination_InstanceMapScript(InstanceMap* map) : InstanceScript(map) - { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - LoadDungeonEncounterData(encounters); - LoadObjectData(creatureData, nullptr); - - SylvanasIntroductionState = NOT_STARTED; - } - - void OnCreatureCreate(Creature* creature) override - { - InstanceScript::OnCreatureCreate(creature); - - switch (creature->GetEntry()) - { - case BOSS_SYLVANAS_WINDRUNNER: - SylvanasGUID = creature->GetGUID(); - break; - - case NPC_SYLVANAS_SHADOWCOPY_RIDING: - SylvanasShadowcopyRidingGUID = creature->GetGUID(); - break; - - case NPC_BOLVAR_FORDRAGON_PINNACLE: - BolvarPinnacleGUID = creature->GetGUID(); - break; - - case NPC_JAINA_PROUDMOORE_PINNACLE: - JainaPinnacleGUID = creature->GetGUID(); - break; - - case NPC_THRALL_PINNACLE: - ThrallPinnacleGUID = creature->GetGUID(); - break; - - case NPC_THRONE_OF_THE_DAMNED: - ThroneOfTheDamnedGUID = creature->GetGUID(); - break; - - default: - break; - } - } - - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) - { - case GAMEOBJECT_TORGHAST_SPIKE_01: - case GAMEOBJECT_TORGHAST_SPIKE_02: - case GAMEOBJECT_TORGHAST_SPIKE_03: - case GAMEOBJECT_TORGHAST_SPIKE_04: - case GAMEOBJECT_TORGHAST_SPIKE_05: - case GAMEOBJECT_TORGHAST_SPIKE_06: - case GAMEOBJECT_TORGHAST_SPIKE_07: - case GAMEOBJECT_TORGHAST_SPIKE_08: - case GAMEOBJECT_TORGHAST_SPIKE_09: - case GAMEOBJECT_TORGHAST_SPIKE_10: - case GAMEOBJECT_TORGHAST_SPIKE_11: - case GAMEOBJECT_TORGHAST_SPIKE_12: - TorghastSpikeGUIDs.push_back(go->GetGUID()); - break; - - default: - break; - } - } - - ObjectGuid GetGuidData(uint32 type) const override - { - switch (type) - { - case DATA_SYLVANAS_WINDRUNNER: - return SylvanasGUID; - case DATA_BOLVAR_FORDRAGON_PINNACLE: - return BolvarPinnacleGUID; - case DATA_JAINA_PROUDMOORE_PINNACLE: - return JainaPinnacleGUID; - case DATA_THRALL_PINNACLE: - return ThrallPinnacleGUID; - case DATA_THRONE_OF_THE_DAMNED: - return ThroneOfTheDamnedGUID; - default: - break; - } - - return ObjectGuid::Empty; - } - - bool SetBossState(uint32 id, EncounterState state) override - { - if (!InstanceScript::SetBossState(id, state)) - return false; - - switch (id) - { - case DATA_SYLVANAS_WINDRUNNER: - { - if (state == NOT_STARTED) - { - DoUpdateWorldState(WORLD_STATE_SYLVANAS_ENCOUNTER_STARTED, 0); - - if (Creature* throneTeleporter = GetCreature(DATA_THRONE_OF_THE_DAMNED)) - throneTeleporter->SetVisible(true); - - for (ObjectGuid const& spikeGUID : TorghastSpikeGUIDs) - if (GameObject* torghastSpike = instance->GetGameObject(spikeGUID)) - torghastSpike->SetSpellVisualId(0); - } - else if (state == IN_PROGRESS) - { - DoUpdateWorldState(WORLD_STATE_SYLVANAS_ENCOUNTER_STARTED, 1); - - if (Creature* throneTeleporter = GetCreature(DATA_THRONE_OF_THE_DAMNED)) - throneTeleporter->SetVisible(false); - } - - break; - } - - default: - break; - } - - return true; - } - - void SetData(uint32 type, uint32 data) override - { - switch (type) - { - case DATA_SYLVANAS_INTRODUCTION: - { - switch (data) - { - case IN_PROGRESS: - SylvanasIntroductionState = IN_PROGRESS; - if (Creature* sylvanas = GetCreature(DATA_SYLVANAS_WINDRUNNER)) - sylvanas->SetHomePosition(SylvanasRespawnPos); - break; - - case DONE: - SylvanasIntroductionState = DONE; - if (Creature* sylvanas = GetCreature(DATA_SYLVANAS_WINDRUNNER)) - { - sylvanas->RemoveUnitFlag(UNIT_FLAG_NOT_ATTACKABLE_1); - sylvanas->SetImmuneToAll(false); - sylvanas->SetSpeed(MOVE_RUN, 14.0f); - } - break; - - default: - break; - } - break; - } - - default: - break; - } - } - - uint32 GetData(uint32 type) const override - { - switch (type) - { - case DATA_SYLVANAS_INTRODUCTION: - return SylvanasIntroductionState; - default: - break; - } - - return 0; - } - - protected: - ObjectGuid SylvanasGUID; - ObjectGuid SylvanasShadowcopyRidingGUID; - ObjectGuid BolvarPinnacleGUID; - ObjectGuid JainaPinnacleGUID; - ObjectGuid ThrallPinnacleGUID; - ObjectGuid ThroneOfTheDamnedGUID; - std::vector<ObjectGuid> TorghastSpikeGUIDs; - uint8 SylvanasIntroductionState; - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_sanctum_of_domination_InstanceMapScript(map); - } -}; - -void AddSC_instance_sanctum_of_domination() -{ - new instance_sanctum_of_domination(); -} diff --git a/src/server/scripts/Shadowlands/SanctumOfDomination/sanctum_of_domination.h b/src/server/scripts/Shadowlands/SanctumOfDomination/sanctum_of_domination.h deleted file mode 100644 index 498aecfd715..00000000000 --- a/src/server/scripts/Shadowlands/SanctumOfDomination/sanctum_of_domination.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -#ifndef DEF_SANCTUM_OF_DOMINATION_H_ -#define DEF_SANCTUM_OF_DOMINATION_H_ - -#include "CreatureAIImpl.h" - -#define DataHeader "SanctumOfDomination" -#define SODScriptName "instance_sanctum_of_domination" - -uint32 const EncounterCount = 10; - -Position const SylvanasRespawnPos = { 225.73611f, -844.0746f, 4104.9882f, 1.3613f }; - -enum SanctumOfDominationDataTypes -{ - DATA_THE_TARRAGRUE = 0, - DATA_THE_EYE_OF_THE_JAILER = 1, - DATA_THE_NINE = 2, - DATA_REMNANT_OF_NERZHUL = 3, - DATA_SOULRENDER_DORMAZAIN = 4, - DATA_PAINSMITH_RAZNAL = 5, - DATA_GUARDIAN_OF_THE_FIRST_ONES = 6, - DATA_FATESCRIBE_ROHKALO = 7, - DATA_KELTHUZAD = 8, - DATA_SYLVANAS_WINDRUNNER = 9, - - /* Encounter-related data */ - - /* Sylvanas Windrunner */ - DATA_SYLVANAS_INTRODUCTION, - DATA_SYLVANAS_SHADOWCOPY_RIDING, - DATA_BOLVAR_FORDRAGON_PINNACLE, - DATA_JAINA_PROUDMOORE_PINNACLE, - DATA_THRALL_PINNACLE, - DATA_THRONE_OF_THE_DAMNED -}; - -enum SanctumOfDominationCreatureIds -{ - // Bosses - BOSS_SYLVANAS_WINDRUNNER = 175732, - - /* Encounter-related creatures */ - - /* Sylvanas Windrunner Encounter */ - NPC_SYLVANAS_SHADOWCOPY_RIDING = 178355, - NPC_BOLVAR_FORDRAGON_PINNACLE = 178081, - NPC_JAINA_PROUDMOORE_PINNACLE = 176533, - NPC_THRALL_PINNACLE = 176532, - - NPC_THRONE_OF_THE_DAMNED = 180803 -}; - -enum SanctumOfDominationGameObjectIds -{ - GAMEOBJECT_TORGHAST_SPIKE_01 = 368743, - GAMEOBJECT_TORGHAST_SPIKE_02 = 368744, - GAMEOBJECT_TORGHAST_SPIKE_03 = 368745, - GAMEOBJECT_TORGHAST_SPIKE_04 = 368746, - GAMEOBJECT_TORGHAST_SPIKE_05 = 368747, - GAMEOBJECT_TORGHAST_SPIKE_06 = 368748, - GAMEOBJECT_TORGHAST_SPIKE_07 = 368749, - GAMEOBJECT_TORGHAST_SPIKE_08 = 368750, - GAMEOBJECT_TORGHAST_SPIKE_09 = 368751, - GAMEOBJECT_TORGHAST_SPIKE_10 = 368752, - GAMEOBJECT_TORGHAST_SPIKE_11 = 368753, - GAMEOBJECT_TORGHAST_SPIKE_12 = 368754 -}; - -enum SanctumOfDominationAreas -{ - AREA_PINNACLE_OF_DOMINANCE = 13653, - AREA_EDGE_OF_THE_ABYSS = 13654, - AREA_THE_CRUCIBLE = 13655 -}; - -enum SanctumofDominationWorldStates -{ - WORLD_STATE_SYLVANAS_ENCOUNTER_STARTED = 20346, - WORLD_STATE_SYLVANAS_ENCOUNTER_COMPLETED = 20347, - WORLD_STATE_SYLVANAS_ENCOUNTER_PHASE = 20348, - WORLD_STATE_SYLVANAS_UNK_01 = 21210, // Info: sets to 0 several times on phase 3. - WORLD_STATE_SYLVANAS_UNK_02 = 21166, // Info: sets to 1 when SPELL_FINAL_SCENE is cast on players. - WORLD_STATE_SYLVANAS_UNK_03 = 21120, // Info: sets to 1 when 353687 spell is cast by NPC 179262. - WORLD_STATE_SYLVANAS_ACHIEVEMENT_COMPLETED = 21134, - WORLD_STATE_SYLVANAS_UNK_04 = 20439, // Info: this is always 1 on INIT and the following are 0. - WORLD_STATE_SYLVANAS_UNK_05 = 20440, - WORLD_STATE_SYLVANAS_UNK_06 = 20441, - WORLD_STATE_SYLVANAS_UNK_07 = 20442, - WORLD_STATE_SYLVANAS_UNK_08 = 20443 -}; - -template <class AI, class T> -inline AI* GetSanctumOfDominationAI(T* obj) -{ - return GetInstanceAI<AI>(obj, SODScriptName); -} - -#define RegisterSanctumOfDominationCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetSanctumOfDominationAI) - -#endif diff --git a/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/boss_anduin_wrynn.cpp b/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/boss_anduin_wrynn.cpp deleted file mode 100644 index 258561f3235..00000000000 --- a/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/boss_anduin_wrynn.cpp +++ /dev/null @@ -1,3880 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTrigger.h" -#include "AreaTriggerAI.h" -#include "Containers.h" -#include "Conversation.h" -#include "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "DB2Structure.h" -#include "G3DPosition.hpp" -#include "GameObject.h" -#include "GameObjectAI.h" -#include "GridNotifiers.h" -#include "InstanceScript.h" -#include "Map.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "PathGenerator.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellAuraEffects.h" -#include "SpellAuras.h" -#include "SpellMgr.h" -#include "SpellScript.h" -#include "TemporarySummon.h" -#include "sepulcher_of_the_first_ones.h" - -enum AnduinWrynnSpells -{ - // Pre-Introduction - SPELL_BROKER_SPAWN = 367524, - - // Generic Spells - SPELL_ANDUIN_PLUNGE_KINGSMOURNE = 369125, - SPELL_POWER_DISPLAY_WILLPOWER = 365177, - SPELL_POWER_ENERGIZE_WILLPOWER_SMALL = 365217, - SPELL_POWER_ENERGIZE_WILLPOWER_LARGE = 365228, - SPELL_SOUL_DESPAWN = 362766, - SPELL_SHADESTEP = 363976, - SPELL_ANDUIN_PROGRESSION_AURA = 369317, - SPELL_ANDUIN_WILLPOWER_PERIODIC = 366848, - SPELL_ANDUIN_SOUL_GHOST = 369016, - - // Dark Zeal - SPELL_DARK_ZEAL_AURA = 364247, - SPELL_DARK_ZEAL_BUFF = 364248, - - // Hopebreaker - SPELL_HOPEBREAKER = 361815, - SPELL_HOPEBREAKER_DAMAGE = 361816, - SPELL_HOPEBREAKER_DEBUFF = 361817, - SPELL_HOPEBREAKER_DEBUFF_DAMAGE = 361818, - SPELL_HOPEBREAKER_CLEAR = 364237, - - // Domination Word: Pain - SPELL_DOMINATION_WORD_PAIN = 366849, - - // Befouled Barrier - SPELL_BEFOULED_BARRIER = 365295, - SPELL_BEFOULED_BARRIER_BLACK_RING = 365633, - SPELL_BEFOULED_ERUPTION = 365853, - SPELL_BEFOULED_BARRIER_SPHERE_AREATRIGGER = 365173, - SPELL_BEFOULED_BARRIER_DEBUFF = 365293, - SPELL_BEFOULED_BARRIER_CLEAR = 369871, - SPELL_BEFOULED_BARRIER_EXPLODE = 365300, - - // Blasphemy - SPELL_BLASPHEMY = 361989, - SPELL_BLASPHEMY_PRE_HIT = 364239, - SPELL_BLASPHEMY_OVERCONFIDENCE = 361990, - SPELL_BLASPHEMY_OVERCONFIDENCE_AREATRIGGER = 361992, - SPELL_BLASPHEMY_HOPELESSNESS = 361991, - SPELL_BLASPHEMY_HOPELESSNESS_AREATRIGGER = 361993, - SPELL_BLASPHEMY_SUCCESS = 362014, - SPELL_BLASPHEMY_EXPLODE = 361999, - SPELL_BLASPHEMY_EXPLODE_LFR_NORMAL = 366933, - SPELL_CANCEL_BLASPHEMY = 370161, - SPELL_BLASPHEMY_IMMUNE = 370407, - - // Kingsmourne Hungers - SPELL_KINGSMOURNE_HUNGERS = 362405, - SPELL_KINGSMOURNE_HUNGERS_DAMAGE_IDK = 362406, - SPELL_KINGSMOURNE_HUNGERS_DAMAGE = 362407, - SPELL_LOST_SOUL_DIMENSION = 362055, - SPELL_LOST_SOUL = 362472, - SPELL_LOST_SOUL_GRACE = 370068, - SPELL_LOST_SOUL_CLEAR = 365641, - SPELL_CANCEL_LOST_SOUL = 367774, - SPELL_SEVERED_SOUL = 367769, - SPELL_LOST_SOUL_MYTHIC = 367770, - SPELL_LOST_SOUL_MIRROR_IMAGE = 362402, - SPELL_SCARRED_SOUL = 365445, - SPELL_MIRROR_IMAGE = 362474, - SPELL_FEIGN_DEATH = 114371, - SPELL_BANISH_SOUL = 367771, - SPELL_MIRROR_IMAGE_IGNORE_PHASE_SHIFT = 362473, - SPELL_ANDUIN_LOST_SOUL_TRACKER = 369843, - - // Rain of Despair (Big add) - SPELL_RAIN_OF_DESPAIR = 362391, - SPELL_ANDUIN_SOUL_DESPAIR = 365220, - SPELL_RAIN_OF_DESPAIR_MELEE = 362393, - SPELL_RAIN_OF_DESPAIR_RANGED = 362396, - SPELL_RAIN_OF_DESPAIR_EXPLOSION = 362392, - - // Wicked Star - SPELL_WICKED_STAR = 365030, - SPELL_WICKED_STAR_POINTER = 365021, - SPELL_WICKED_STAR_AREATRIGGER = 365017, - SPELL_WICKED_STAR_DAMAGE_SILENCE = 365024, - SPELL_WICKED_STAR_EMPOWERMENT = 365112, - SPELL_WICKED_STAR_IDK = 365992, - SPELL_WICKED_STAR_TARGETED = 366674, - SPELL_WICKED_STAR_IDK_3 = 369280, - - // Empowered Wicked Star - SPELL_EMPOWERED_WICKED_STAR = 367631, - SPELL_EMPOWERED_WICKED_STAR_POINTER = 367632, - SPELL_EMPOWERED_WICKED_STAR_AREATRIGGER = 367621, - SPELL_EMPOWERED_WICKED_STAR_DAMAGE_SILENCE = 367634, - - // Force of Will - SPELL_FORCE_OF_WILL = 368913, - SPELL_CANCEL_FORCE_OF_WILL = 368978, - - // Fiendish Soul - SPELL_NECROTIC_CLAWS_LEAP = 363019, - SPELL_NECROTIC_CLAWS_DEBUFF = 363020, - SPELL_SOUL_EXPLOSION_TARGET = 363029, - SPELL_SOUL_EXPLOSION_TRIGGER_MISSILE = 363030, - SPELL_SOUL_EXPLOSION_DAMAGE = 363031, - - // Monstrous Soul - SPELL_UNRAVELING_FRENZY_PERIODIC = 363027, - SPELL_UNRAVELING_FRENZY = 363028, - SPELL_NECROTIC_DETONATION = 363024, - - // Grim Reflections - SPELL_GRIM_REFLECTIONS = 365120, - SPELL_GRIM_REFLECTIONS_SUMMON = 365121, - SPELL_GRIM_REFLECTIONS_DEST_SUMMON = 365039, - SPELL_CALAMITY_STATE_VISUAL = 361685, - SPELL_WICKED_STAR_PROTECTION = 370400, - SPELL_PSYCHIC_TERROR = 365008, - SPELL_GRIM_FATE = 367932, - - // Beacon of Hope - SPELL_BEACON_OF_HOPE = 365872, - SPELL_BEACON_OF_HOPE_AREATRIGGER = 362702, - - // Fragment of Hope - SPELL_FRAGMENT_OF_HOPE_AREATRIGGER = 365816, - SPELL_FRAGMENT_OF_HOPE_CLEAR_DEBUFF = 365828, - SPELL_FRAGMENT_OF_HOPE_DAMAGE = 365990, - - // Purging Light - SPELL_PURGING_LIGHT = 368428, - - // Hopelessness - SPELL_HOPELESSNESS = 365958, - SPELL_HOPELESSNESS_MISSILE = 365962, - SPELL_HOPELESSNESS_HOPELESSNESS_AREATRIGGER = 365966, - SPELL_HOPELESSNESS_EXPLODE = 365971, - - // Empowered Hopebreaker - SPELL_EMPOWERED_HOPEBREAKER = 365805, - SPELL_EMPOWERED_HOPEBREAKER_EXPLOSION = 365806, - - // Anduin's Soul - SPELL_LOST_SOUL_PERIODIC = 365650, - SPELL_LOST_SOUL_CONSUME = 365652, - - // Anduin's Hope - SPELL_ANDUIN_SLOW = 365218, - SPELL_GLOOM = 364031, - - // Anduin's Doubt - SPELL_GHOST_VISUAL_COSMETIC = 370833, - - // Remnant of a Fallen King - SPELL_DOMINATION_GRASP = 365216, - SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER = 362505, - SPELL_SHADE_VISUAL = 362490, - SPELL_REMNANT_SPAWN = 362500, - SPELL_DARK_PRESENCE = 368986, - SPELL_WEATHER_COSMETIC = 362493, - SPELL_SPAWN_REMNANT = 362497, - SPELL_REMNANT_TIMER = 365291, - SPELL_RETURN_TO_KINGSMOURNE = 363022, - SPELL_RETURN_TO_KINGSMOURNE_VISUALS = 363021, - SPELL_SHADE_DESPAWN_CEREMONY = 363023, - - // Remorseless Winter - SPELL_REMORSELESS_WINTER = 362542, - SPELL_REMORSELESS_WINTER_PERIODIC = 362543, - SPELL_REMORSELESS_WINTER_DEBUFF_DAMAGE = 362545, - SPELL_REMORSELESS_WINTER_CLEAR = 370619, - - // Army of the Dead - SPELL_ARMY_OF_THE_DEAD = 362862, - SPELL_ECHOES_OF_ANDORHAL = 362863, - SPELL_ECHOES_OF_ANDORHAL_FIENDISH_GHOULS = 362864, - SPELL_ECHOES_OF_ANDORHAL_MONSTROUS_SOUL = 363025, - - // March of the Damned - SPELL_MARCH_OF_THE_DAMNED = 363116, - SPELL_MARCH_OF_THE_DAMNED_PERIODIC = 363233, - SPELL_MARCH_OF_THE_DAMNED_AREATRIGGER = 363133, - SPELL_MARCH_OF_THE_DAMNED_DAMAGE = 364020, - SPELL_DESPAWN_WALLS = 371694, - - // Soul Reaper - SPELL_SOUL_REAPER = 362771, - SPELL_SOUL_REAPER_PHYSICAL_DAMAGE = 362772, - SPELL_SOUL_REAPER_SHADOWFROST_DAMAGE = 362773, - SPELL_SOUL_REAPER_DEBUFF = 362774, - SPELL_SOUL_REAPER_ATTACK_SPEED = 362775, - - // Finish Encounter - SPELL_ANDUIN_KNEEL_POSE = 369367, - SPELL_FINAL_MOVIE = 367306, - SPELL_AWARD_ANDUIN_KILL = 359476, - - // Berserk - SPELL_BERSERK = 26662, - - // Jaina Spells - SPELL_BLINK = 362844, - SPELL_FROSTBOLT = 362843, - SPELL_GENERIC_BLINK = 363984, - - // Sylvanas Spells - SPELL_SHOOT_BOW = 364068, - SPELL_TUMBLE = 364069, - - // Uther Spells - SPELL_BLADE_OF_JUSTICE = 363971, - SPELL_UTHER_CHARGE = 363972, - - // Translocators Teleport - SPELL_TELEPORT_COSMIC_HUB = 364475, - SPELL_TELEPORT_DOMINATIONS_GRASP = 368563, -}; - -enum AnduinWrynnPhases -{ - PHASE_ONE = 1, - PHASE_TWO, - PHASE_THREE, -}; - -enum AnduinWrynnEvents -{ - // Anduin Wrynn - EVENT_HOPEBREAKER = 1, - EVENT_DOMINATION_WORD_PAIN, - EVENT_BEFOULED_BARRIER, - EVENT_UPDATE_BEFOULED_BARRIER, - EVENT_BLASPHEMY, - EVENT_HOPELESSNESS, - EVENT_WICKED_STAR, - EVENT_EMPOWERED_WICKED_STAR, - EVENT_KINGSMOURNE_HUNGERS, - EVENT_INTERMISSION_ONE, - EVENT_INTERMISSION_TWO, - EVENT_GRIM_REFLECTIONS, - EVENT_BEACON_OF_HOPE, - EVENT_EMPOWERED_HOPEBREAKER, - EVENT_BANISH_SOUL, - EVENT_BERSERK, - - // Kingsmourne Room - EVENT_ANDUIN_SOUL, - - // Remnant of a Fallen King - EVENT_ARMY_OF_THE_DEAD, - EVENT_SOUL_REAPER, - EVENT_RETURN_TO_KINGSMOURNE, - - // Fiendish Soul - EVENT_GHOUL_LEAP, - EVENT_NECROTIC_CLAWS, - - // Monstrous Soul - EVENT_UNRAVELING_FRENZY, - EVENT_NECROTIC_DETONATION, - - // Grim Reflections - EVENT_PSYCHIC_TERROR, - EVENT_GRIM_REFLECTION_IMMUNITY, - - // Sylvanas Windrunner - EVENT_CANCEL_SYLVANAS_EVENTS, - EVENT_TUMBLE, - - // Uther the Lightbringer - EVENT_CANCEL_UTHER_EVENTS, - EVENT_BLADE_OF_JUSTICE, - - // Jaina Proudmoore - EVENT_CANCEL_JAINA_EVENTS, - EVENT_BLINK, -}; - -enum AnduinWrynnActions -{ - ACTION_START_PRE_INTRODUCTION = 1, - ACTION_START_MOVEMENT, - ACTION_START_INTRODUCTION, - ACTION_ARTHAS_INTERMISSION_UTHER, - ACTION_ARTHAS_INTERMISSION_SYLVANAS, - ACTION_EXIT_INTERMISSION, - ACTION_ACTIVATE_REMNANT, - ACTION_DESPAWN_REMNANT, - ACTION_SUMMON_KINGSMOURNE_SOULS, - ACTION_END_ENCOUNTER, - ACTION_START_OUTRODUCTION, - ACTION_DESPAIR_GONE, - ACTION_DOUBT_GONE, - ACTION_HOPE_RESTORED, - - // Monstrous Soul - ACTION_NECROTIC_DETONATION, - - // Outroduction - ACTION_MOVE_NPCS_ON_PLATFORM, -}; - -enum AnduinWrynnTexts -{ - SAY_AGGRO = 0, - SAY_HOPEBREAKER = 1, - SAY_BEFOULED_BARRIER = 2, - SAY_BLASPHEMY = 3, - SAY_ANNOUNCE_BLASPHEMY = 4, - SAY_ANNOUNCE_KINGSMOURNE_HUNGERS = 5, - SAY_KINGSMOURNE_HUNGERS = 6, - SAY_WICKED_STAR = 7, - SAY_ANNOUNCE_WICKED_STAR = 8, - SAY_GRIM_REFLECTIONS = 9, - SAY_SLAY = 10, - SAY_EMPOWERED_HOPEBREAKER = 11, - SAY_DISENGAGE = 12, - SAY_NECROTIC_DETONATION = 13, - SAY_ANNOUNCE_EMPOWERED_WICKED_STAR = 14, -}; - -enum AnduinWrynnConversations -{ - CONVERSATION_INTRO = 17835, - CONVERSATION_ARTHAS_UTHER = 17921, - CONVERSATION_ARTHAS_SYLVANAS = 17923, - CONVERSATION_ANDUIN_PHASE_THREE = 17924, - CONVERSATION_ANDUIN_OUTRODUCTION = 17836, -}; - -enum AnduinWrynnSpawnGroups -{ - SPAWN_GROUP_INITIAL = 0 -}; - -enum AnduinWrynnPoints -{ - POINT_START_INTRODUCTION = 1, - POINT_ANDUIN_SOUL = 2, - POINT_ESCAPE_PLATFORM = 3, - POINT_MARCH_OF_THE_DAMNED = 4, -}; - -enum AnduinWrynnPaths -{ - PATH_INTRODUCTION_JAINA = 183664 * 100, - PATH_INTRODUCTION_UTHER = 183665 * 100, - PATH_INTRODUCTION_SYLVANAS = 183666 * 100, - PATH_OUTRODUCTION_FIRIM = 184589 * 100, - PATH_OUTRODUCTION_THRALL = 184599 * 100, - PATH_OUTRODUCTION_BOLVAR = 184601 * 100, -}; - -enum AnduinWrynnSpellVisuals -{ - SPELL_VISUAL_CHEST_LOOT = 114023, -}; - -Position const PreIntroductionAssistersPositions[3] = -{ - { -3826.9548f, -2626.2761f, 78.9296f, 4.644121f }, // Jaina - { -3831.6807f, -2626.2761f, 78.9296f, 5.460620f }, // Uther - { -3818.7300f, -2626.2800f, 78.9296f, 4.558697f }, // Sylvanas -}; - -Position const AssistersSpawnPos[3] = -{ - { -3824.65f, -2692.20f, 91.3485f, 4.64412f}, // Jaina - { -3828.03f, -2688.25f, 91.3485f, 5.46062f}, // Uther - { -3819.48f, -2687.19f, 91.3485f, 4.55870f}, // Sylvanas -}; - -Position const FirimOutroductionPos = { -3830.0156f, -2676.7969f, 91.56402f }; -Position const QuartermasterRahmPos = { -3824.9565f, -2673.0190f, 91.44697f, 4.7163963f }; -Position const LeftKnightPosition = { -3815.4097f, -2677.1824f, 91.44697f, 4.742376f }; -Position const RightKnightPosition = { -3834.6807f, -2677.42360f, 91.44697f, 4.6956997f }; - -Position const DominationGraspCenter = { -3825.0601f, -2715.4600f, 91.3567f, 1.6260f }; - -Position const IntermissionAssistersTeleportPosition[3] = -{ - { -3828.472f, -2688.191f, 91.2652f, 1.9153f }, // Sylvanas - { -3819.519f, -2687.170f, 91.2652f, 2.1812f }, // Uther - { -3824.960f, -2692.550f, 91.2652f, 1.5733f }, // Jaina -}; - -Position const AnduinsDespairSpawnPosition = { -3828.355957f, -2704.1875f, 91.350716f, 4.982021f }; - -Position const AnduinsSoulSpawnPosition = { -3825.060059f, -2715.459961f, 91.356697f, 1.626040f }; - -Position const AnduinsDoubtSpawnPositions[4] = -{ - { -3852.638916f, -2687.373291f, 91.348526f, 5.560700f }, // Right of Uther - { -3852.845459f, -2742.732666f, 91.348534f, 0.961583f }, // Next Right - { -3797.704834f, -2686.685791f, 91.348526f, 3.804689f }, // Left of Sylvanas - { -3799.805664f, -2740.925293f, 91.348541f, 2.247305f }, // Next Left -}; - -Position const AnduinsHopeSpawnPosition[4] = -{ - { -3825.149414f, -2711.508789f, 91.354919f, 1.463445f }, // In front of Anduin - { -3828.751709f, -2715.171875f, 91.354919f, 3.221487f }, // Left of Anduin - { -3821.041748f, -2715.296875f, 91.354889f, 0.046978f }, // Right of Anduin - { -3825.180664f, -2719.208252f, 91.354820f, 4.741285f }, // Behind Anduin -}; - -Position const RemnantOfAFallenKingSpawnPosition = { -3825.2466f, -2700.0486f, 91.3650f, 1.3762f }; - -Position const GrimReflectionsSpawnPositions[4] = -{ - { -3825.389f, -2739.4202f, 91.431305f, 4.8445f}, // back side of Anduin - { -3849.8438f, -2715.0574f, 91.40953f, 2.9961f}, // left side of Anduin - { -3825.4966f, -2692.6199f, 91.487495f, 1.4654f}, // in front of Anduin - { -3800.6980f, -2715.4340f, 91.390780f, 6.2769f}, // right side of Anduin -}; - -Position const MarchOfTheDamnedSpawnPositions[8] = -{ - { -3839.8489f, -2679.7708f, 91.53031f, 5.1081f }, // First right - { -3860.8940f, -2701.0051f, 91.53032f, 5.9010f }, // Second Right - { -3860.5696f, -2729.7344f, 91.53032f, 0.3886f }, // Third Right - { -3839.6390f, -2750.8890f, 91.53032f, 1.1935f }, // Fourth Right - { -3811.0625f, -2679.6528f, 91.53031f, 4.3362f }, // First left - { -3789.8125f, -2700.5088f, 91.53032f, 3.5383f }, // Second Left - { -3789.2812f, -2729.3160f, 91.53032f, 2.7669f }, // Third Left - { -3810.4290f, -2751.0903f, 91.53032f, 1.9584f } // Fourth Left -}; - -Position const BeaconOfHopeSpawnPosition = { -3825.0417f, -2715.3923f, 91.3568f, 0.0f }; - -Position const ChestLootSpawnPosition = { -3840.9915f, -2741.7847f, 91.26521f, 1.334929f }; - -class ActivateGhouls : public BasicEvent -{ -public: - ActivateGhouls(Creature* summoner, Creature* owner) - : _summonerGuid(summoner->GetGUID()), _owner(owner) { } - - bool Execute(uint64 /*time*/, uint32 /*diff*/) override - { - if (Creature* _summoner = ObjectAccessor::GetCreature(*_owner, _summonerGuid)) - { - if (Unit* target = _summoner->AI()->SelectTarget(SelectTargetMethod::Random, 0)) - { - _owner->SetReactState(REACT_AGGRESSIVE); - _owner->AI()->AttackStart(target); - } - } - return true; - } - -private: - ObjectGuid _summonerGuid; - Creature* _owner; -}; - -// 181954 - Anduin Wrynn -struct boss_anduin_wrynn : public BossAI -{ - boss_anduin_wrynn(Creature* creature) : BossAI(creature, DATA_ANDUIN_WRYNN), - _slayTextOnCooldown(false), _intermissionsDone(0), _encounterEnded(false) { } - - void HandleIntroduction() - { - if (instance->GetData(DATA_ANDUIN_WRYNN_INTRODUCTION) == DONE) - { - me->RemoveUnitFlag(UNIT_FLAG_NOT_ATTACKABLE_1); - me->SetImmuneToAll(false); - me->SetSpeed(MOVE_RUN, 11.0f); - me->RemoveAurasDueToSpell(SPELL_ANDUIN_PLUNGE_KINGSMOURNE); - } - else - { - DoCastSelf(SPELL_ANDUIN_PLUNGE_KINGSMOURNE); - me->SetUnitFlag(UNIT_FLAG_NOT_ATTACKABLE_1); - me->SetImmuneToAll(true); - } - } - - void PrepareAssistersForIntermission() const - { - if (Creature* sylvanas = instance->GetCreature(DATA_SYLVANAS_WINDRUNNER_ANDUIN)) - { - sylvanas->CastSpell(IntermissionAssistersTeleportPosition[0], SPELL_GENERIC_BLINK); - sylvanas->AttackStop(); - sylvanas->SetSheath(SHEATH_STATE_RANGED); - sylvanas->SetEmoteState(EMOTE_STATE_READY_BOW); - } - - if (Creature* uther = instance->GetCreature(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN)) - { - uther->CastSpell(IntermissionAssistersTeleportPosition[1], SPELL_GENERIC_BLINK); - uther->AttackStop(); - uther->SetSheath(SHEATH_STATE_MELEE); - uther->SetEmoteState(EMOTE_STATE_READY2H); - } - - if (Creature* jaina = instance->GetCreature(DATA_JAINA_PROUDMOORE_ANDUIN)) - { - jaina->CastSpell(IntermissionAssistersTeleportPosition[2], SPELL_GENERIC_BLINK); - jaina->AttackStop(); - jaina->SetSheath(SHEATH_STATE_RANGED); - jaina->SetEmoteState(EMOTE_STATE_READY2H); - } - } - - void ForceAssistersToAttackRemnant() const - { - Unit* remnant = instance->GetCreature(DATA_REMNANT_OF_A_FALLEN_KING); - if (!remnant) - return; - - auto forceAttack = [this, remnant](uint32 data) - { - Creature* creature = instance->GetCreature(data); - if (!creature) - return; - - creature->AI()->AttackStart(remnant); - creature->SetReactState(REACT_AGGRESSIVE); - }; - - forceAttack(DATA_SYLVANAS_WINDRUNNER_ANDUIN); - forceAttack(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN); - forceAttack(DATA_JAINA_PROUDMOORE_ANDUIN); - } - - void MoveKnightsOnPlatform() const - { - if (Creature* rahm = instance->GetCreature(DATA_QUARTERMASTER_RAHM_ANDUIN)) - rahm->NearTeleportTo(QuartermasterRahmPos); - - std::list<Creature*> knights; - me->GetCreatureListWithOptionsInGrid(knights, 150.0f, { .CreatureId = NPC_KNIGHT_OF_EBON_BLADE_ANDUIN }); - - for (Creature* knight : knights) - { - if (knight->HasStringId("left_knight")) - knight->NearTeleportTo(LeftKnightPosition); - else - knight->NearTeleportTo(RightKnightPosition); - } - } - - void ClearDebuffs() const - { - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_HOPEBREAKER_DEBUFF); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLASPHEMY_OVERCONFIDENCE); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLASPHEMY_HOPELESSNESS); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DOMINATION_WORD_PAIN); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BEFOULED_BARRIER_DEBUFF); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BEFOULED_BARRIER_EXPLODE); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_LOST_SOUL_DIMENSION); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FORCE_OF_WILL); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_SCARRED_SOUL); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_WEATHER_COSMETIC); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_REMORSELESS_WINTER_PERIODIC); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_HOPELESSNESS_HOPELESSNESS_AREATRIGGER); - } - - void JustAppeared() override - { - scheduler.ClearValidator(); - HandleIntroduction(); - me->SetEmoteState(EMOTE_STATE_READY2H); - me->ModifyPower(me->GetPowerType(), 0); - DoCastSelf(SPELL_ANDUIN_PROGRESSION_AURA); - DoCastSelf(SPELL_POWER_DISPLAY_WILLPOWER, true); - DoCastSelf(SPELL_DARK_ZEAL_AURA, true); - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_ENCOUNTER_STARTED, 0); - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_INTERMISSION, 0); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - ClearDebuffs(); - Talk(SAY_DISENGAGE); - if (_encounterEnded == true) - return; - - _DespawnAtEvade(); - summons.DespawnAll(); - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_ENCOUNTER_STARTED, 0); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - } - - void Reset() override - { - _Reset(); - me->SummonCreatureGroup(SPAWN_GROUP_INITIAL); - me->SetPower(POWER_ENERGY, 0); - - _slayTextOnCooldown = false; - _intermissionsDone = 0; - _encounterEnded = false; - } - - void KilledUnit(Unit* victim) override - { - if (_slayTextOnCooldown == false && !victim->IsPlayer()) - { - Talk(SAY_SLAY); - _slayTextOnCooldown = true; - scheduler.Schedule(3s, [this](TaskContext /*task*/) - { - _slayTextOnCooldown = false; - }); - } - } - - void JustSummoned(Creature* summon) override - { - summons.Summon(summon); - - switch (summon->GetEntry()) - { - case NPC_BEFOULED_BARRIER: - { - summon->SetReactState(REACT_PASSIVE); - summon->CastSpell(summon, SPELL_BEFOULED_ERUPTION, true); - summon->CastSpell(summon, SPELL_BEFOULED_BARRIER_SPHERE_AREATRIGGER, true); - summon->CastSpell(summon, SPELL_BEFOULED_BARRIER_BLACK_RING, true); - break; - } - - case BOSS_REMNANT_OF_A_FALLEN_KING: - { - summon->SetReactState(REACT_PASSIVE); - summon->SetUninteractible(true); - summon->CastSpell(summon, SPELL_REMNANT_SPAWN); - break; - } - - case NPC_MARCH_OF_THE_DAMNED: - { - float marchSpeed = 0.0f; - switch (me->GetMap()->GetDifficultyID()) - { - case DIFFICULTY_LFR_NEW: - case DIFFICULTY_NORMAL_RAID: - case DIFFICULTY_HEROIC_RAID: - marchSpeed = 0.40f; - break; - case DIFFICULTY_MYTHIC_RAID: - marchSpeed = 0.60f; - break; - default: - marchSpeed = 0.40f; - break; - } - - summon->SetSpeedRate(MOVE_RUN, marchSpeed); - summon->SetReactState(REACT_PASSIVE); - summon->CastSpell(summon, SPELL_MARCH_OF_THE_DAMNED_AREATRIGGER, true); - scheduler.Schedule(1s, [summon](TaskContext /*task*/) - { - Position exitPlatform = summon->GetFirstCollisionPosition(100.0f, summon->GetAbsoluteAngle(summon)); - summon->GetMotionMaster()->MovePoint(POINT_MARCH_OF_THE_DAMNED, exitPlatform, false, summon->GetOrientation()); - }); - break; - } - - case NPC_BEACON_OF_HOPE: - { - summon->SetReactState(REACT_PASSIVE); - summon->CastSpell(summon, SPELL_BEACON_OF_HOPE_AREATRIGGER); - break; - } - - default: - break; - } - } - - void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override - { - if (summon->GetEntry() == NPC_GRIM_REFLECTION) - summon->DespawnOrUnsummon(3s); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); - PhaseEvents(PHASE_ONE); - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_ENCOUNTER_STARTED, PHASE_ONE); - Talk(SAY_AGGRO); - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_START_PRE_INTRODUCTION: - { - auto teleportNamed = [this](uint32 data, Position const& position) - { - Creature* creature = instance->GetCreature(data); - if (!creature) - return; - - creature->NearTeleportTo(position); - creature->CastSpell(creature, SPELL_BROKER_SPAWN, true); - }; - - teleportNamed(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN, PreIntroductionAssistersPositions[0]); - teleportNamed(DATA_SYLVANAS_WINDRUNNER_ANDUIN, PreIntroductionAssistersPositions[1]); - teleportNamed(DATA_JAINA_PROUDMOORE_ANDUIN, PreIntroductionAssistersPositions[2]); - break; - } - case ACTION_START_MOVEMENT: - { - auto castBrokerSpawn = [this](uint32 data) - { - Creature* creature = instance->GetCreature(data); - if (!creature) - return; - - creature->CastSpell(creature, SPELL_BROKER_SPAWN, true); - }; - - castBrokerSpawn(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN); - castBrokerSpawn(DATA_SYLVANAS_WINDRUNNER_ANDUIN); - castBrokerSpawn(DATA_JAINA_PROUDMOORE_ANDUIN); - break; - } - case ACTION_START_INTRODUCTION: - { - instance->SetData(DATA_ANDUIN_WRYNN_INTRODUCTION, IN_PROGRESS); - scheduler.Schedule(1ms, [this](TaskContext /*task*/) - { - Creature* uther = instance->GetCreature(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN); - if (!uther) - return; - - Creature* sylvanas = instance->GetCreature(DATA_SYLVANAS_WINDRUNNER_ANDUIN); - if (!sylvanas) - return; - - Creature* jaina = instance->GetCreature(DATA_JAINA_PROUDMOORE_ANDUIN); - if (!jaina) - return; - - Conversation* convo = Conversation::CreateConversation(CONVERSATION_INTRO, me, me->GetPosition(), ObjectGuid::Empty, nullptr, false); - if (!convo) - return; - - convo->AddActor(NPC_UTHER_THE_LIGHTBRINGER_ANDUIN, 1, uther->GetGUID()); - convo->AddActor(NPC_SYLVANAS_WINDRUNNER_ANDUIN, 2, sylvanas->GetGUID()); - convo->AddActor(NPC_LADY_JAINA_PROUDMOORE_ANDUIN, 3, jaina->GetGUID()); - convo->Start(); - }); - - scheduler.Schedule(35s, [this](TaskContext /*task*/) - { - instance->SetData(DATA_ANDUIN_WRYNN_INTRODUCTION, DONE); - HandleIntroduction(); - }); - break; - } - case ACTION_MOVE_NPCS_ON_PLATFORM: - { - if (Creature* bolvar = me->GetInstanceScript()->GetCreature(DATA_BOLVAR_FORDRAGON_ANDUIN)) - bolvar->GetMotionMaster()->MovePath(PATH_OUTRODUCTION_BOLVAR, false); - - if (Creature* thrall = me->GetInstanceScript()->GetCreature(DATA_THRALL_ANDUIN)) - thrall->GetMotionMaster()->MovePath(PATH_OUTRODUCTION_THRALL, false); - - scheduler.Schedule(10s, [this](TaskContext /*task*/) - { - MoveKnightsOnPlatform(); - }); - break; - } - case ACTION_START_OUTRODUCTION: - { - Creature* uther = instance->GetCreature(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN); - if (!uther) - break; - - Creature* sylvanas = instance->GetCreature(DATA_SYLVANAS_WINDRUNNER_ANDUIN); - if (!sylvanas) - break; - - Creature* jaina = instance->GetCreature(DATA_JAINA_PROUDMOORE_ANDUIN); - if (!jaina) - break; - - Creature* firim = instance->GetCreature(DATA_FIRIM_ANDUIN); - if (!firim) - break; - - firim->GetMotionMaster()->MovePath(PATH_OUTRODUCTION_FIRIM, false); - - Conversation* convo = Conversation::CreateConversation(CONVERSATION_ANDUIN_OUTRODUCTION, me, me->GetPosition(), ObjectGuid::Empty, nullptr, false); - if (!convo) - break; - - convo->AddActor(NPC_LADY_JAINA_PROUDMOORE_ANDUIN, 1, jaina->GetGUID()); - convo->AddActor(NPC_SYLVANAS_WINDRUNNER_ANDUIN, 2, sylvanas->GetGUID()); - convo->AddActor(NPC_UTHER_THE_LIGHTBRINGER_ANDUIN, 3, uther->GetGUID()); - convo->AddActor(NPC_FIRIM_ANDUIN, 4, firim->GetGUID()); - convo->Start(); - break; - } - case ACTION_ARTHAS_INTERMISSION_UTHER: - { - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_INTERMISSION, 1); - if (Creature* uther = instance->GetCreature(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN)) - { - if (Conversation* convo = Conversation::CreateConversation(CONVERSATION_ARTHAS_UTHER, me, me->GetPosition(), ObjectGuid::Empty, nullptr, false)) - { - convo->AddActor(NPC_UTHER_THE_LIGHTBRINGER_ANDUIN, 1, uther->GetGUID()); - convo->Start(); - } - } - break; - } - case ACTION_ARTHAS_INTERMISSION_SYLVANAS: - { - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_INTERMISSION, 2); - if (Creature* sylvanas = instance->GetCreature(DATA_SYLVANAS_WINDRUNNER_ANDUIN)) - { - if (Conversation* convo = Conversation::CreateConversation(CONVERSATION_ARTHAS_SYLVANAS, me, me->GetPosition(), ObjectGuid::Empty, nullptr, false)) - { - convo->AddActor(NPC_SYLVANAS_WINDRUNNER_ANDUIN, 1, sylvanas->GetGUID()); - convo->Start(); - } - } - break; - } - case ACTION_EXIT_INTERMISSION: - { - if (_intermissionsDone == 0) - { - PhaseEvents(PHASE_TWO); - scheduler.Schedule(3s, [this](TaskContext /*task*/) - { - me->SetReactState(REACT_AGGRESSIVE); - }); - } - else if (_intermissionsDone == 1) - { - PhaseEvents(PHASE_THREE); - scheduler.Schedule(6s, [this](TaskContext /*task*/) - { - me->SetReactState(REACT_AGGRESSIVE); - }); - } - break; - } - case ACTION_END_ENCOUNTER: - { - EndEncounter(); - break; - } - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - scheduler.Update(diff); - - if (!UpdateVictim()) - return; - - Unit* victim = me->GetVictim(); - if (victim && !victim->IsPlayer()) - { - EnterEvadeMode(EvadeReason::NoHostiles); - return; - } - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_HOPEBREAKER: - { - DoCastSelf(SPELL_HOPEBREAKER); - Talk(SAY_HOPEBREAKER); - break; - } - case EVENT_EMPOWERED_HOPEBREAKER: - { - DoCastSelf(SPELL_EMPOWERED_HOPEBREAKER); - Talk(SAY_EMPOWERED_HOPEBREAKER); - if (IsMythic()) - events.Repeat(65500ms); - else - events.Repeat(58400ms); - break; - } - case EVENT_DOMINATION_WORD_PAIN: - { - DoCastSelf(SPELL_DOMINATION_WORD_PAIN); - break; - } - case EVENT_BEFOULED_BARRIER: - { - DoCastSelf(SPELL_BEFOULED_BARRIER); - Talk(SAY_BEFOULED_BARRIER); - break; - } - case EVENT_BLASPHEMY: - { - DoCastSelf(SPELL_BLASPHEMY); - Talk(SAY_ANNOUNCE_BLASPHEMY); - Talk(SAY_BLASPHEMY); - break; - } - case EVENT_HOPELESSNESS: - { - DoCastAOE(SPELL_HOPELESSNESS); - Talk(SAY_BLASPHEMY); - if (IsMythic()) - events.Repeat(65500ms); - else - events.Repeat(58500ms); - break; - } - case EVENT_WICKED_STAR: - { - DoCastSelf(SPELL_WICKED_STAR); - Talk(SAY_WICKED_STAR); - if (events.IsInPhase(PHASE_THREE)) - events.Repeat(58500ms); - break; - } - case EVENT_EMPOWERED_WICKED_STAR: - { - DoCastSelf(SPELL_EMPOWERED_WICKED_STAR, true); - Talk(SAY_WICKED_STAR); - if (IsMythic()) - events.Repeat(65500ms); - else - events.Repeat(58500ms); - break; - } - case EVENT_KINGSMOURNE_HUNGERS: - { - DoCastSelf(SPELL_KINGSMOURNE_HUNGERS); - Talk(SAY_ANNOUNCE_KINGSMOURNE_HUNGERS); - Talk(SAY_KINGSMOURNE_HUNGERS); - break; - } - case EVENT_GRIM_REFLECTIONS: - { - Talk(SAY_GRIM_REFLECTIONS); - DoCastSelf(SPELL_GRIM_REFLECTIONS); - break; - } - case EVENT_BEACON_OF_HOPE: - { - DoCastSelf(SPELL_BEACON_OF_HOPE); - break; - } - case EVENT_INTERMISSION_ONE: - { - StartIntermission(0); - break; - } - case EVENT_INTERMISSION_TWO: - { - StartIntermission(1); - break; - } - case EVENT_BERSERK: - { - DoCastSelf(SPELL_BERSERK); - break; - } - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } - - void StartIntermission(uint8 intermissionNum) - { - auto SpawnRemnant = [this](TaskContext /*task*/) - { - if (Creature* arthas = instance->GetCreature(DATA_REMNANT_OF_A_FALLEN_KING)) - me->CastSpell(arthas, SPELL_SPAWN_REMNANT); - }; - - Seconds timeOffset = intermissionNum * 1s; - - scheduler.Schedule(1ms, [this](TaskContext /*task*/) - { - me->SetReactState(REACT_PASSIVE); - me->CastSpell(DominationGraspCenter, SPELL_SHADESTEP); - PrepareAssistersForIntermission(); - }); - - scheduler.Schedule(1204ms + timeOffset, [this, intermissionNum](TaskContext /*task*/) - { - DoAction(intermissionNum == 0 ? ACTION_ARTHAS_INTERMISSION_UTHER : ACTION_ARTHAS_INTERMISSION_SYLVANAS); - }); - - scheduler.Schedule(2204ms + timeOffset, [this](TaskContext /*task*/) - { - me->SetFacingTo(1.626040f); - }); - - scheduler.Schedule(4s + timeOffset, [this](TaskContext /*task*/) - { - DoCastSelf(SPELL_FORCE_OF_WILL); - DoCastSelf(SPELL_HOPEBREAKER_CLEAR); - DoCastSelf(SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER); - - if (Creature* arthas = me->SummonCreature(BOSS_REMNANT_OF_A_FALLEN_KING, RemnantOfAFallenKingSpawnPosition, TEMPSUMMON_MANUAL_DESPAWN)) - { - me->CastSpell(arthas, SPELL_DOMINATION_GRASP); - me->CastSpell(arthas, SPELL_SPAWN_REMNANT); - } - }); - - scheduler.Schedule(5s + timeOffset, SpawnRemnant); - - scheduler.Schedule(6s + timeOffset, SpawnRemnant); - - scheduler.Schedule(7s + timeOffset, SpawnRemnant); - - scheduler.Schedule(8s + timeOffset, [this, intermissionNum](TaskContext /*task*/) - { - if (intermissionNum == 1 || IsMythic()) - DoCastSelf(SPELL_MARCH_OF_THE_DAMNED_PERIODIC); - - if (Creature* arthas = instance->GetCreature(DATA_REMNANT_OF_A_FALLEN_KING)) - { - me->CastSpell(arthas, SPELL_SPAWN_REMNANT); - arthas->SetImmuneToAll(false); - ForceAssistersToAttackRemnant(); - } - }); - } - - void PhaseEvents(uint8 phase) - { - events.Reset(); - - switch (phase) - { - case PHASE_ONE: - { - events.SetPhase(PHASE_ONE); - events.ScheduleEventSeries(EVENT_HOPEBREAKER, { 5s, 31900ms, 28s, 29900ms, 29900ms }); - events.ScheduleEventSeries(EVENT_BEFOULED_BARRIER, { 17s, 51900ms, 48s }); - events.ScheduleEventSeries(EVENT_BLASPHEMY, { 30s, 49900ms, 54900ms }); - events.ScheduleEventSeries(EVENT_WICKED_STAR, { 55s, 35s, 30s }); - events.ScheduleEventSeries(EVENT_DOMINATION_WORD_PAIN, { 7s, 13s, 13s, 10s, 15s, 13100ms, 12900ms, 13s, 13900ms, 12200ms, 14800ms }); - events.ScheduleEvent(EVENT_INTERMISSION_ONE, 150s); - events.ScheduleEvent(EVENT_BERSERK, 15min); - - if (IsLFR()) - DoCastSelf(SPELL_ANDUIN_WILLPOWER_PERIODIC, true); - else - events.ScheduleEventSeries(EVENT_KINGSMOURNE_HUNGERS, { 45s, 1min }); - break; - } - - case PHASE_TWO: - { - _intermissionsDone = 1; - me->ModifyPower(me->GetPowerType(), 0); - events.SetPhase(PHASE_TWO); - events.ScheduleEventSeries(EVENT_GRIM_REFLECTIONS, { 8700ms, 87s }); - events.ScheduleEventSeries(EVENT_BEFOULED_BARRIER, { 80600ms, 47s }); - events.ScheduleEvent(EVENT_INTERMISSION_TWO, 169s); - - if (!IsMythic()) - { - events.ScheduleEventSeries(EVENT_DOMINATION_WORD_PAIN, { 11500ms, 13s, 13s, 17700ms, 8100ms, 13s, 13s, 14400ms, 11200ms, 12200ms }); - events.ScheduleEventSeries(EVENT_HOPEBREAKER, { 13600ms, 22s, 33300ms, 29s, 29s }); - events.ScheduleEventSeries(EVENT_WICKED_STAR, { 18500ms, 39s, 26s, 30500ms, 19s }); - } - else - { - events.ScheduleEventSeries(EVENT_DOMINATION_WORD_PAIN, { 10700ms, 13s, 13s, 17700ms, 8100ms, 13s, 13s, 14400ms, 11200ms, 12200ms }); - events.ScheduleEventSeries(EVENT_HOPEBREAKER, { 13600ms, 25s, 33s, 29s, 29100ms }); - events.ScheduleEventSeries(EVENT_WICKED_STAR, { 18500ms, 39s, 26s, 30900ms, 19100ms }); - } - - if (IsLFR()) - DoCastSelf(SPELL_ANDUIN_WILLPOWER_PERIODIC, true); - else - events.ScheduleEventSeries(EVENT_KINGSMOURNE_HUNGERS, { 48600ms, 1min }); - break; - } - - case PHASE_THREE: - { - _intermissionsDone = 2; - me->ModifyPower(me->GetPowerType(), 0); - Conversation::CreateConversation(CONVERSATION_ANDUIN_PHASE_THREE, me, me->GetPosition(), ObjectGuid::Empty, nullptr, true); - events.SetPhase(PHASE_THREE); - events.ScheduleEvent(EVENT_BEACON_OF_HOPE, 1ms); - events.ScheduleEvent(EVENT_EMPOWERED_HOPEBREAKER, 11500ms); - events.ScheduleEvent(EVENT_HOPELESSNESS, 21700ms); - - if (!IsMythic()) - events.ScheduleEvent(EVENT_WICKED_STAR, 41s); - else - events.ScheduleEvent(EVENT_EMPOWERED_WICKED_STAR, 41s); - break; - } - default: - break; - } - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (_intermissionsDone < 2 && me->HealthBelowPctDamaged(10, damage)) - { - me->RemoveAurasDueToSpell(SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER); - me->RemoveAurasDueToSpell(SPELL_MARCH_OF_THE_DAMNED_PERIODIC); - scheduler.Schedule(6s, [this](TaskContext /*task*/) - { - me->SetReactState(REACT_AGGRESSIVE); - }); - - scheduler.CancelAll(); - me->SetReactState(REACT_AGGRESSIVE); - PhaseEvents(PHASE_THREE); - - std::list<Creature*> fiendishSouls; - GetCreatureListWithEntryInGrid(fiendishSouls, me, NPC_FIENDISH_SOUL, 50.0f); - - for (Creature* fiends : fiendishSouls) - { - fiends->CastSpell(fiends, SPELL_SOUL_DESPAWN); - fiends->DespawnOrUnsummon(500ms); - } - - std::list<Creature*> marches; - GetCreatureListWithEntryInGrid(marches, me, NPC_MARCH_OF_THE_DAMNED, 50.0f); - - for (Creature* march : marches) - march->DespawnOrUnsummon(); - - if (Creature* remnant = instance->GetCreature(DATA_REMNANT_OF_A_FALLEN_KING)) - remnant->GetAI()->DoAction(ACTION_DESPAWN_REMNANT); - } - } - - void EndEncounter() - { - ClearDebuffs(); - events.Reset(); - scheduler.CancelAll(); - _encounterEnded = true; - instance->SetBossState(DATA_ANDUIN_WRYNN, DONE); - _EnterEvadeMode(); - DoCastSelf(SPELL_ANDUIN_KNEEL_POSE); - - if (Creature* beacon = instance->GetCreature(DATA_BEACON_OF_HOPE)) - beacon->DespawnOrUnsummon(); - - me->SetReactState(REACT_PASSIVE); - me->SetFaction(FACTION_FRIENDLY); - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_ENCOUNTER_COMPLETED, 1); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - DoAction(ACTION_MOVE_NPCS_ON_PLATFORM); - - if (GameObject* chest = me->SummonGameObject(GAMEOBJECT_ANDUIN_CHEST_LOOT, ChestLootSpawnPosition, QuaternionData::fromEulerAnglesZYX(-225.0f, 0.0f, 0.0f), 7_days)) - { - chest->SetGoState(GO_STATE_ACTIVE); - chest->SetSpellVisualId(SPELL_VISUAL_CHEST_LOOT, ObjectGuid::Empty); - } - - scheduler.Schedule(5s, [this](TaskContext /*task*/) - { - instance->DoCastSpellOnPlayers(SPELL_FINAL_MOVIE); - }); - } - -private: - bool _slayTextOnCooldown; - uint8 _intermissionsDone; - bool _encounterEnded; -}; - -// 184830 - Beacon of Hope -struct npc_anduin_wrynn_beacon_of_hope : public ScriptedAI -{ - npc_anduin_wrynn_beacon_of_hope(Creature* creature) : ScriptedAI(creature) { } - - void JustUnregisteredAreaTrigger(AreaTrigger* areaTrigger) override - { - switch (areaTrigger->GetSpellId()) - { - case SPELL_FRAGMENT_OF_HOPE_AREATRIGGER: - { - if (!areaTrigger->GetInsideUnits().empty()) - break; - - InstanceScript* instance = me->GetInstanceScript(); - if (!instance) - break; - - if (Creature* beacon = instance->GetCreature(DATA_BEACON_OF_HOPE)) - beacon->CastSpell(beacon, SPELL_FRAGMENT_OF_HOPE_DAMAGE, true); - break; - } - default: - break; - } - } -}; - -// 183452 - Empty Vessel -struct npc_anduin_wrynn_empty_vessel : public ScriptedAI -{ - npc_anduin_wrynn_empty_vessel(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetReactState(REACT_PASSIVE); - } - - void IsSummonedBy(WorldObject* summoner) override - { - if (!summoner->IsPlayer()) - return; - - summoner->CastSpell(me, SPELL_MIRROR_IMAGE); - DoCast(me, SPELL_FEIGN_DEATH); - } -}; - -// 185607 - Lost Soul -struct npc_anduin_wrynn_lost_soul : public ScriptedAI -{ - npc_anduin_wrynn_lost_soul(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetReactState(REACT_PASSIVE); - _events.ScheduleEvent(EVENT_BANISH_SOUL, 1ms); - } - - void IsSummonedBy(WorldObject* summoner) override - { - if (!summoner->IsPlayer()) - return; - - summoner->CastSpell(me, SPELL_LOST_SOUL_MIRROR_IMAGE); - } - - void JustDied(Unit* /*killer*/) override - { - TempSummon* summon = me->ToTempSummon(); - if (!summon) - return; - - if (Unit* summoner = summon->GetSummonerUnit()) - { - summoner->RemoveAurasDueToSpell(SPELL_SEVERED_SOUL); - summoner->NearTeleportTo(me->GetPosition()); - } - me->DespawnOrUnsummon(2s); - } - - void Reset() override - { - _events.Reset(); - } - - void UpdateAI(uint32 diff) override - { - UpdateVictim(); - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BANISH_SOUL: - { - DoCastSelf(SPELL_BANISH_SOUL); - _events.Repeat(1ms); - break; - } - default: - break; - } - } - } - -private: - EventMap _events; -}; - -// 184519 - Anduin's Soul -struct npc_anduin_wrynn_anduin_soul : public ScriptedAI -{ - npc_anduin_wrynn_anduin_soul(Creature* creature) : ScriptedAI(creature), - _hopeRestored(0), _doubtGone(0), _despairGone(0), _summons(me) { } - - void CheckForReleaseFromKingsmourne() - { - if (_hopeRestored == 4 && _doubtGone == 4 && _despairGone == 1) - { - DoCastAOE(SPELL_LOST_SOUL_CLEAR, true); - _hopeRestored = 0; - _doubtGone = 0; - _despairGone = 0; - } - } - - void JustAppeared() override - { - me->SetDisableGravity(true, true); - me->SetHoverHeight(1.0); - me->SetPlayHoverAnim(true); - DoCastSelf(SPELL_LOST_SOUL_PERIODIC); - } - - void Reset() override - { - _summons.DespawnAll(); - DoCastSelf(SPELL_ANDUIN_SOUL_GHOST, true); - } - - void JustSummoned(Creature* who) override - { - _summons.Summon(who); - } - - void JustDied(Unit* /*killer*/) override - { - _summons.DespawnAll(); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - _summons.DespawnAll(); - DoCastSelf(SPELL_ANDUIN_SOUL_GHOST, true); - } - - void DoAction(int32 action) override - { - InstanceScript* instance = me->GetInstanceScript(); - if (!instance) - return; - - Creature* anduin = instance->GetCreature(DATA_ANDUIN_SOUL); - if (!anduin) - return; - - switch (action) - { - case ACTION_SUMMON_KINGSMOURNE_SOULS: - { - me->SummonCreature(NPC_ANDUIN_DESPAIR, AnduinsDespairSpawnPosition, TEMPSUMMON_TIMED_DESPAWN, 40s); - for (uint8 i = 0; i < 4; i++) - { - me->SummonCreature(NPC_ANDUIN_DOUBT, AnduinsDoubtSpawnPositions[i], TEMPSUMMON_TIMED_DESPAWN, 40s); - me->SummonCreature(NPC_ANDUIN_HOPE, AnduinsHopeSpawnPosition[i], TEMPSUMMON_TIMED_DESPAWN, 40s); - } - break; - } - case ACTION_DESPAIR_GONE: - _despairGone++; - CheckForReleaseFromKingsmourne(); - break; - - case ACTION_DOUBT_GONE: - _doubtGone++; - CheckForReleaseFromKingsmourne(); - break; - - case ACTION_HOPE_RESTORED: - _hopeRestored++; - CheckForReleaseFromKingsmourne(); - break; - - default: - break; - } - } - -public: - uint8 _hopeRestored; - uint8 _doubtGone; - uint8 _despairGone; - SummonList _summons; -}; - -// 184520 - Anduin's Despair -struct npc_anduin_wrynn_anduin_despair : public ScriptedAI -{ - npc_anduin_wrynn_anduin_despair(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) { } - - void JustAppeared() override - { - DoCastSelf(SPELL_RAIN_OF_DESPAIR); - DoCastSelf(SPELL_ANDUIN_SOUL_DESPAIR); - } - - void JustDied(Unit* /*killer*/) override - { - DoCastSelf(SPELL_POWER_ENERGIZE_WILLPOWER_LARGE); - - if (Creature* soul = _instance->GetCreature(DATA_ANDUIN_SOUL)) - soul->GetAI()->DoAction(ACTION_DESPAIR_GONE); - } - -private: - InstanceScript* _instance; -}; - -// 184494 - Anduin's Doubt -struct npc_anduin_wrynn_anduin_doubt : public ScriptedAI -{ - npc_anduin_wrynn_anduin_doubt(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetWalk(true); - DoCastSelf(SPELL_GHOST_VISUAL_COSMETIC, true); - DoZoneInCombat(); - me->GetMotionMaster()->MovePoint(POINT_ANDUIN_SOUL, AnduinsSoulSpawnPosition); - } - - void JustDied(Unit* /*killer*/) override - { - DoCastSelf(SPELL_POWER_ENERGIZE_WILLPOWER_SMALL); - DoCastSelf(SPELL_SOUL_DESPAWN); - - if (Creature* soul = me->GetInstanceScript()->GetCreature(DATA_ANDUIN_SOUL)) - soul->GetAI()->DoAction(ACTION_DOUBT_GONE); - } - - void UpdateAI(uint32 /*diff*/) override - { - UpdateVictim(); - } -}; - -// 184493 - Anduin's Hope -struct npc_anduin_wrynn_anduin_hope : public ScriptedAI -{ - npc_anduin_wrynn_anduin_hope(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) { } - - void Reset() override - { - me->SetRegenerateHealth(false); - me->SetHealth(1); - me->SetReactState(REACT_PASSIVE); - } - - void JustAppeared() override - { - _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 255); - me->SetWalk(true); - DoCastSelf(SPELL_ANDUIN_SLOW); - if (IsHeroic() || IsMythic()) - DoCastSelf(SPELL_GLOOM); - - _scheduler.Schedule(2s, [this](TaskContext /*task*/) - { - Position exitPlatform = me->GetFirstCollisionPosition(100.0f, 0); - me->GetMotionMaster()->MovePoint(POINT_ESCAPE_PLATFORM, exitPlatform, false, me->GetOrientation()); - }); - me->SetHealth(1); - - _scheduler.Schedule(40s, [this](TaskContext /*task*/) - { - me->DespawnOrUnsummon(); - }); - } - - void UpdateAI(uint32 diff) override - { - UpdateVictim(); - - _scheduler.Update(diff); - } - - void HealReceived(Unit* /*healer*/, uint32& heal) override - { - if (me->HealthAbovePctHealed(100, heal)) - { - _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - DoCastSelf(SPELL_POWER_ENERGIZE_WILLPOWER_SMALL); - DoCastSelf(SPELL_SOUL_DESPAWN); - - if (Creature* soul = _instance->GetCreature(DATA_ANDUIN_SOUL)) - soul->GetAI()->DoAction(ACTION_HOPE_RESTORED); - } - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != POINT_MOTION_TYPE) - return; - - switch (pointId) - { - case POINT_ESCAPE_PLATFORM: - { - DoCastSelf(SPELL_SOUL_DESPAWN); - break; - } - default: - break; - } - } - -private: - InstanceScript* _instance; - TaskScheduler _scheduler; -}; - -// 183669 - Fiendish Soul -struct npc_anduin_wrynn_fiendish_soul : public ScriptedAI -{ - npc_anduin_wrynn_fiendish_soul(Creature* creature) : ScriptedAI(creature) { } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_GHOUL_LEAP, 1s); - _events.ScheduleEvent(EVENT_NECROTIC_CLAWS, 10s); - } - - void JustDied(Unit* /*killer*/) override - { - if (IsHeroic() || IsMythic()) - DoCastSelf(SPELL_SOUL_EXPLOSION_TARGET); - - DoCastSelf(SPELL_SOUL_DESPAWN); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_GHOUL_LEAP: - { - std::list<Player*> targetList; - GetPlayerListInGrid(targetList, me, 50.0f); - if (!targetList.empty()) - me->CastSpell(Trinity::Containers::SelectRandomContainerElement(targetList), SPELL_NECROTIC_CLAWS_LEAP); - _events.Repeat(10s); - break; - } - case EVENT_NECROTIC_CLAWS: - { - DoCastVictim(SPELL_NECROTIC_CLAWS_DEBUFF); - _events.Repeat(5s, 10s); - break; - } - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - -private: - EventMap _events; -}; - -// 183671 - Monstrous Soul -struct npc_anduin_wrynn_monstrous_soul : public ScriptedAI -{ - npc_anduin_wrynn_monstrous_soul(Creature* creature) : ScriptedAI(creature) { } - - void JustEngagedWith(Unit* /*who*/) override - { - me->GetInstanceScript()->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 255); - DoCastSelf(SPELL_UNRAVELING_FRENZY_PERIODIC, true); - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (me->HealthBelowPctDamaged(35, damage)) - _events.ScheduleEvent(EVENT_NECROTIC_DETONATION, 1ms); - } - - void Reset() override - { - _events.Reset(); - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_NECROTIC_DETONATION: - { - Talk(SAY_NECROTIC_DETONATION); - DoCastSelf(SPELL_NECROTIC_DETONATION); - break; - } - default: - break; - } - } - - void JustDied(Unit* /*killer*/) override - { - me->GetInstanceScript()->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - me->GetInstanceScript()->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_NECROTIC_DETONATION: - { - Talk(SAY_NECROTIC_DETONATION); - DoCastSelf(SPELL_NECROTIC_DETONATION); - break; - } - default: - break; - } - } - DoMeleeAttackIfReady(); - } - -private: - EventMap _events; -}; - -// 183463 - Remnant of a Fallen King -struct boss_remnant_of_a_fallen_king : public ScriptedAI -{ - boss_remnant_of_a_fallen_king(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summons(creature) { } - - void JustAppeared() override - { - _scheduler.ClearValidator(); - DoCastSelf(SPELL_SHADE_VISUAL); - me->ModifyPower(me->GetPowerType(), 0); - me->SetPower(me->GetPowerType(), 0); - for (MapReference const& players : me->GetMap()->GetPlayers()) - { - if (Player* player = players.GetSource()) - me->CastSpell(player, SPELL_WEATHER_COSMETIC, true); - } - _instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_HOPEBREAKER); - me->SetReactState(REACT_PASSIVE); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - _summons.DespawnAll(); - me->DespawnOrUnsummon(); - - if (Creature* anduin = _instance->GetCreature(DATA_ANDUIN_WRYNN)) - anduin->AI()->EnterEvadeMode(EvadeReason::NoHostiles); - - _instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_WEATHER_COSMETIC); - _instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_REMORSELESS_WINTER_PERIODIC); - _instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_NECROTIC_CLAWS_DEBUFF); - _instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FORCE_OF_WILL); - } - - void ContinueAttacking() const - { - if (Creature* sylvanas = _instance->GetCreature(DATA_SYLVANAS_WINDRUNNER_ANDUIN)) - sylvanas->GetAI()->AttackStartCaster(me, 25.0f); - - if (Creature* uther = _instance->GetCreature(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN)) - uther->GetAI()->AttackStart(me); - - if (Creature* jaina = _instance->GetCreature(DATA_JAINA_PROUDMOORE_ANDUIN)) - jaina->GetAI()->AttackStartCaster(me, 25.0f); - } - - void JustSummoned(Creature* summon) override - { - _summons.Summon(summon); - - switch (summon->GetEntry()) - { - case NPC_FIENDISH_SOUL: - case NPC_MONSTROUS_SOUL: - summon->SetReactState(REACT_PASSIVE); - summon->m_Events.AddEvent(new ActivateGhouls(me, summon), summon->m_Events.CalculateTime(5s)); - break; - default: - break; - } - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_ACTIVATE_REMNANT: - { - DoCastAOE(SPELL_DARK_PRESENCE); - DoZoneInCombat(); - - _scheduler.Schedule(1500ms, [this](TaskContext /*task*/) - { - _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 2); - me->SetUninteractible(false); - }); - - _scheduler.Schedule(2s, [this](TaskContext /*task*/) - { - DoCastSelf(SPELL_REMNANT_TIMER); - _events.ScheduleEvent(EVENT_ARMY_OF_THE_DEAD, 1ms); - _events.ScheduleEvent(EVENT_SOUL_REAPER, 8000ms); - _events.ScheduleEvent(EVENT_RETURN_TO_KINGSMOURNE, 67500ms); - me->SetReactState(REACT_AGGRESSIVE); - ContinueAttacking(); - }); - break; - } - case ACTION_DESPAWN_REMNANT: - { - DoCastSelf(SPELL_SOUL_DESPAWN); - _scheduler.Schedule(500ms, [this](TaskContext /*task*/) - { - EnterEvadeMode(EvadeReason::Other); - }); - break; - } - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_RETURN_TO_KINGSMOURNE: - { - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->InterruptNonMeleeSpells(true); - DoCastSelf(SPELL_RETURN_TO_KINGSMOURNE); - break; - } - case EVENT_ARMY_OF_THE_DEAD: - { - DoCastSelf(SPELL_ARMY_OF_THE_DEAD); - me->SetReactState(REACT_AGGRESSIVE); - if (!IsLFR()) - _events.Repeat(36900ms); - break; - } - case EVENT_SOUL_REAPER: - { - DoCastVictim(SPELL_SOUL_REAPER); - _events.Repeat(12s); - break; - } - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); - } - -private: - EventMap _events; - TaskScheduler _scheduler; - InstanceScript* _instance; - SummonList _summons; -}; - -// 183033 - Grim Reflection -struct npc_anduin_wrynn_grim_reflection : public ScriptedAI -{ - npc_anduin_wrynn_grim_reflection(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - _events.Reset(); - } - - void JustAppeared() override - { - SetCombatMovement(false); - DoCastSelf(SPELL_CALAMITY_STATE_VISUAL); - DoZoneInCombat(); - me->SetReactState(REACT_AGGRESSIVE); - _events.ScheduleEvent(EVENT_PSYCHIC_TERROR, 1ms); - - if (IsLFR() || IsNormal()) - _events.ScheduleEvent(EVENT_GRIM_REFLECTION_IMMUNITY, 1ms); - } - - void JustDied(Unit* /*killer*/) override - { - if (IsMythic()) - DoCastAOE(SPELL_GRIM_FATE); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_PSYCHIC_TERROR: - { - DoCastSelf(SPELL_PSYCHIC_TERROR); - _events.Repeat(2s); - break; - } - case EVENT_GRIM_REFLECTION_IMMUNITY: - { - DoCastSelf(SPELL_WICKED_STAR_PROTECTION); - _events.Repeat(1s); - break; - } - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - } - -private: - EventMap _events; -}; - -// 183666 - Sylvanas Windrunner -struct npc_anduin_wrynn_sylvanas : public ScriptedAI -{ - npc_anduin_wrynn_sylvanas(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetReactState(REACT_AGGRESSIVE); - } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_TUMBLE, 10s); - } - - bool CanAIAttack(Unit const* target) const override - { - return !target->HasAura(SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_TUMBLE: - { - DoCastSelf(SPELL_TUMBLE); - _events.Repeat(10s); - break; - } - default: - break; - } - } - - DoSpellAttackIfReady(SPELL_SHOOT_BOW); - } - -private: - EventMap _events; -}; - -// 183664 - Jaina Proudmoore -struct npc_anduin_wrynn_jaina : public ScriptedAI -{ - npc_anduin_wrynn_jaina(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetReactState(REACT_AGGRESSIVE); - } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_BLINK, 10s); - } - - bool CanAIAttack(Unit const* target) const override - { - return !target->HasAura(SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId != PATH_INTRODUCTION_JAINA) - return; - - if (Creature* anduin = me->GetInstanceScript()->GetCreature(DATA_ANDUIN_WRYNN)) - anduin->GetAI()->DoAction(ACTION_START_INTRODUCTION); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CANCEL_JAINA_EVENTS: - { - _events.CancelEvent(EVENT_BLINK); - break; - } - case EVENT_BLINK: - { - DoCastSelf(SPELL_BLINK); - _events.Repeat(60s); - break; - } - default: - break; - } - } - - DoSpellAttackIfReady(SPELL_FROSTBOLT); - } - -private: - EventMap _events; -}; - -// 183665 - Uther the Lightbringer -struct npc_anduin_wrynn_uther : public ScriptedAI -{ - npc_anduin_wrynn_uther(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetReactState(REACT_AGGRESSIVE); - } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* who) override - { - DoCast(who, SPELL_UTHER_CHARGE); - _events.ScheduleEvent(EVENT_BLADE_OF_JUSTICE, 3s); - } - - bool CanAIAttack(Unit const* target) const override - { - return !target->HasAura(SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CANCEL_UTHER_EVENTS: - { - _events.CancelEvent(EVENT_BLADE_OF_JUSTICE); - break; - } - case EVENT_BLADE_OF_JUSTICE: - { - DoCastVictim(SPELL_BLADE_OF_JUSTICE); - _events.Repeat(10s); - break; - } - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - -private: - EventMap _events; -}; - -// 367524 - Spawn Pre-Introduction -class spell_anduin_wrynn_pre_introduction : public AuraScript -{ - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - switch (caster->GetEntry()) - { - case NPC_LADY_JAINA_PROUDMOORE_ANDUIN: - caster->NearTeleportTo(PreIntroductionAssistersPositions[0]); - break; - case NPC_UTHER_THE_LIGHTBRINGER_ANDUIN: - caster->NearTeleportTo(PreIntroductionAssistersPositions[1]); - break; - case NPC_SYLVANAS_WINDRUNNER_ANDUIN: - caster->NearTeleportTo(PreIntroductionAssistersPositions[2]); - break; - default: - break; - } - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - uint32 pathId = 0; - switch (caster->GetEntry()) - { - case NPC_LADY_JAINA_PROUDMOORE_ANDUIN: - pathId = PATH_INTRODUCTION_JAINA; - break; - case NPC_UTHER_THE_LIGHTBRINGER_ANDUIN: - pathId = PATH_INTRODUCTION_UTHER; - break; - case NPC_SYLVANAS_WINDRUNNER_ANDUIN: - pathId = PATH_INTRODUCTION_SYLVANAS; - break; - default: - break; - } - caster->GetMotionMaster()->MovePath(pathId, false); - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_anduin_wrynn_pre_introduction::OnApply, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_anduin_wrynn_pre_introduction::OnRemove, EFFECT_2, SPELL_AURA_MOD_ROOT, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 369317 - Anduin Progression Aura (Can't be reduced < 1 hp) -class spell_anduin_wrynn_progression_aura : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ANDUIN_PROGRESSION_AURA, SPELL_ANDUIN_KNEEL_POSE }); - } - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) - { - amount = -1; - canBeRecalculated = true; - } - - void Trigger(AuraEffect* /*aurEff*/, DamageInfo const& dmgInfo, uint32& absorbAmount) - { - if (!GetTarget()->GetAura(SPELL_ANDUIN_PROGRESSION_AURA)) - return; - - if (dmgInfo.GetDamage() <= GetTarget()->GetHealth()) - return; - - if (dmgInfo.GetDamage() >= GetTarget()->GetHealth()) - { - absorbAmount = dmgInfo.GetDamage(); - if (_triggered) - return; - - GetTarget()->SetHealth(1); - GetTarget()->CastSpell(GetTarget(), SPELL_ANDUIN_KNEEL_POSE); - GetTarget()->GetAI()->DoAction(ACTION_END_ENCOUNTER); - _triggered = true; - } - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_anduin_wrynn_progression_aura::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_anduin_wrynn_progression_aura::Trigger, EFFECT_0); - } - -private: - bool _triggered = false; -}; - -// 366848 - Anduin Willpower Periodic (Only LFR) -class spell_anduin_wrynn_energize_willpower_lfr : public AuraScript -{ - static constexpr std::array<int32, 22> AnduinRegenCycle = - { 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1 }; // 0.681 willpower per second on Retail - - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - _powerGained = AnduinRegenCycle[_powerRegenCycle++]; - - if (_powerRegenCycle >= 22) - _powerRegenCycle = 0; - - target->ModifyPower(target->GetPowerType(), _powerGained); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_anduin_wrynn_energize_willpower_lfr::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - - uint8 _powerRegenCycle = 0; - uint32 _powerGained = 0; -}; - -// 364247 - Dark Zeal -class spell_anduin_wrynn_dark_zeal : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DARK_ZEAL_BUFF }); - } - - void OnProc(AuraEffect* /*aurEff*/, ProcEventInfo const& eventInfo) - { - Unit* actionTarget = eventInfo.GetActionTarget(); - if (!actionTarget) - return; - - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_DARK_ZEAL_BUFF, true); - - if (actionTarget->GetGUID() == _currentTank) - return; - - target->RemoveAura(SPELL_DARK_ZEAL_BUFF); - _currentTank = actionTarget->GetGUID(); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_anduin_wrynn_dark_zeal::OnProc, EFFECT_0, SPELL_AURA_DUMMY); - } - -private: - ObjectGuid _currentTank; -}; - -// 361815 - Hopebreaker -// 365806 - Empowered Hopebreaker -class spell_anduin_wrynn_hopebreaker : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HOPEBREAKER_DAMAGE, SPELL_HOPEBREAKER_DEBUFF }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) const - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_HOPEBREAKER_DAMAGE, true); - GetCaster()->CastSpell(GetHitUnit(), SPELL_HOPEBREAKER_DEBUFF, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_anduin_wrynn_hopebreaker::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 361817 - Hopebreaker Periodic -class spell_anduin_wrynn_hopebreaker_periodic : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HOPEBREAKER_DEBUFF_DAMAGE }); - } - - void OnPeriodic(AuraEffect const* /*aurEff*/) const - { - if (!GetCaster()) - return; - - GetCaster()->CastSpell(GetTarget(), SPELL_HOPEBREAKER_DEBUFF_DAMAGE, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_anduin_wrynn_hopebreaker_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -// 361818 - Hopebreaker Damage -class spell_anduin_wrynn_hopebreaker_damage : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HOPEBREAKER_DEBUFF }); - } - - void HandleDamage(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - - Aura* hopebreaker = target->GetAura(SPELL_HOPEBREAKER_DEBUFF); - if (!hopebreaker) - return; - - uint8 hopebreakerStacks = hopebreaker->GetStackAmount(); - SetHitDamage(GetHitDamage() * hopebreakerStacks); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_anduin_wrynn_hopebreaker_damage::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } -}; - -// 363133 - March of the Damned, CreatePropertiesId - 24093 -struct at_anduin_wrynn_march_of_the_damned : AreaTriggerAI -{ - at_anduin_wrynn_march_of_the_damned(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - Unit* caster = at->GetCaster(); - if (!caster) - return; - - caster->CastSpell(unit, SPELL_MARCH_OF_THE_DAMNED_DAMAGE, true); - } -}; - -float constexpr BEFOULED_BARRIER_MAX_RADIUS = 12.0f; -float constexpr BEFOULED_BARRIER_MIN_RADIUS = 4.0f; - -// 365173 - Befouled Barrier - CreatePropertiesId: 24332 -struct at_anduin_wrynn_befouled_barrier : AreaTriggerAI -{ - at_anduin_wrynn_befouled_barrier(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnInitialize() override - { - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_BEFOULED_BARRIER_DEBUFF, at->GetMap()->GetDifficultyID())) - _absorbRequired = spellInfo->GetEffect(EFFECT_0).CalcValue(at->GetCaster()); - - at->SetTimeToTargetScale(30000); - - // The aura is handling it automatically - at->SetDuration(-1); - } - - void OnCreate(Spell const* /*creatingSpell*/) override - { - _scheduler.Schedule(500ms, [this](TaskContext task) - { - float startRadius = 1.0f; - - UpdateSize(startRadius, BEFOULED_BARRIER_MAX_RADIUS); - at->SetTimeToTargetScale(500); - - task.Schedule(Milliseconds(at->GetTimeToTargetScale()), [this](TaskContext task) - { - UpdateSizeBasedOnAbsorb(); - task.Repeat(); - }); - }); - } - - void UpdateSize(float radius, float targetRadius) const - { - std::array<DBCPosition2D, 2> points = - { { - { 0.0f, radius }, - { 1.0f, targetRadius } - } }; - - at->SetOverrideScaleCurve(points); - } - - void UpdateSizeBasedOnAbsorb() const - { - Unit* target = at->GetTarget(); - if (!target) - return; - - float radiusMod = 1.0f - (_absorbDone / (float)_absorbRequired); - float targetRadius = BEFOULED_BARRIER_MAX_RADIUS * radiusMod; - float currentRadius = at->GetMaxSearchRadius(); - - if (G3D::fuzzyEq(currentRadius, targetRadius)) - return; - - // Players need to be able to actually enter the AT to heal it no sniff has a value lower than 4.0f - if (targetRadius <= BEFOULED_BARRIER_MIN_RADIUS) - return; - - UpdateSize(currentRadius, targetRadius); - } - - void OnUpdate(uint32 diff) override - { - _scheduler.Update(diff); - } - - void OnUnitEnter(Unit* unit) override - { - Unit* caster = at->GetCaster(); - if (!caster) - return; - - caster->CastSpell(unit, SPELL_BEFOULED_BARRIER_DEBUFF, true); - } - - void OnUnitExit(Unit* unit) override - { - unit->RemoveAura(SPELL_BEFOULED_BARRIER_DEBUFF); - } - - void Absorb(uint32 absorbAmount) - { - _absorbDone += absorbAmount; - - if (_absorbDone < _absorbRequired) - return; - - Unit* target = at->GetTarget(); - if (!target) - return; - - // remove barrier, we're done healing - if (Creature* creature = target->ToCreature()) - { - creature->CastSpell(creature, SPELL_BEFOULED_BARRIER_CLEAR, true); - creature->DespawnOrUnsummon(1s); - } - } - - uint32 GetRemainingAbsorb() const - { - return _absorbRequired - _absorbDone; - } - -private: - uint32 _absorbDone = 0; - uint32 _absorbRequired = 0; - TaskScheduler _scheduler; -}; - -float constexpr BEACON_OF_HOPE_MAX_RADIUS = 12.0f; -float constexpr BEACON_OF_HOPE_MIN_RADIUS = 4.0f; - -// 362702 - Beacon of Hope - CreatePropertiesId: 25025 / 24247 -struct at_anduin_wrynn_beacon_of_hope : AreaTriggerAI -{ - at_anduin_wrynn_beacon_of_hope(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger), - _instance(at->GetInstanceScript()), _entries(0), _chargesRemaining(40) { } - - void OnInitialize() override - { - _entries = 0; - _chargesRemaining = 40; - } - - void OnCreate(Spell const* /*creatingSpell*/) override - { - _scheduler.Schedule(500ms, [this](TaskContext task) - { - float startRadius = 1.0f; - float targetRadius = BEACON_OF_HOPE_MAX_RADIUS; - - UpdateSize(startRadius, targetRadius); - at->SetTimeToTargetScale(500); - - task.Schedule(Milliseconds(at->GetTimeToTargetScale()), [this](TaskContext task) - { - UpdateSizeBasedOnCharges(); - task.Repeat(); - }); - }); - } - - void UpdateSize(float radius, float targetRadius) const - { - std::array<DBCPosition2D, 2> points = - { { - { 0.0f, radius }, - { 1.0f, targetRadius } - } }; - - at->SetOverrideScaleCurve(points); - } - - void UpdateSizeBasedOnCharges() const - { - float radiusMod = 0.205129f * _entries; - float targetRadius = BEACON_OF_HOPE_MAX_RADIUS - radiusMod; - - if (targetRadius <= BEACON_OF_HOPE_MIN_RADIUS || _chargesRemaining <= 0) - at->Remove(); - - float currentRadius = at->GetMaxSearchRadius(); - if (G3D::fuzzyEq(currentRadius, targetRadius)) - return; - - UpdateSize(currentRadius, targetRadius); - } - - void OnUpdate(uint32 diff) override - { - _scheduler.Update(diff); - } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - if (!at->GetCaster()) - return; - - Creature* beacon = _instance->GetCreature(DATA_BEACON_OF_HOPE); - if (!beacon) - return; - - beacon->CastSpell(beacon, SPELL_PURGING_LIGHT, true); - unit->RemoveAurasDueToSpell(SPELL_HOPELESSNESS_HOPELESSNESS_AREATRIGGER); - - if (at->GetMap()->IsMythic()) - { - _entries++; - _chargesRemaining--; - beacon->CastSpell(unit, SPELL_FRAGMENT_OF_HOPE_AREATRIGGER, true); - } - } - -private: - InstanceScript* _instance; - uint8 _entries; - uint8 _chargesRemaining; - TaskScheduler _scheduler; -}; - -// 365816 - Fragment of Hope -class spell_anduin_wrynn_fragment_of_hope : public SpellScript -{ - void SetDest(SpellDestination& destination) const - { - Unit* caster = GetCaster(); - Position dest = caster->GetPosition(); - - if (Creature* beacon = caster->GetInstanceScript()->GetCreature(DATA_BEACON_OF_HOPE)) - beacon->MovePositionToFirstCollision(dest, 30.0f, beacon->GetAbsoluteAngle(GetExplTargetWorldObject()) - beacon->GetOrientation()); - - destination.Relocate(dest); - } - - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_anduin_wrynn_fragment_of_hope::SetDest, EFFECT_0, TARGET_DEST_DEST); - } -}; - -// 365293 - Befouled Barrier -class spell_anduin_wrynn_befouled_barrier_absorb : public AuraScript -{ - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ SPELL_BEFOULED_BARRIER_SPHERE_AREATRIGGER }) - && ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } }); - } - - void OnHealAbsorb(AuraEffect* /*aurEff*/, HealInfo const& healInfo, uint32& absorbAmount) const - { - absorbAmount = CalculatePct(healInfo.GetHeal(), GetEffectInfo(EFFECT_2).CalcValue()); - - Unit* caster = GetCaster(); - if (!caster) - return; - - AreaTrigger* barrier = caster->GetAreaTrigger(SPELL_BEFOULED_BARRIER_SPHERE_AREATRIGGER); - if (!barrier) - return; - - at_anduin_wrynn_befouled_barrier* barrierScript = dynamic_cast<at_anduin_wrynn_befouled_barrier*>(barrier->AI()); - if (!barrierScript) - return; - - barrierScript->Absorb(absorbAmount); - } - - void Register() override - { - OnEffectAbsorbHeal += AuraEffectAbsorbHealFn(spell_anduin_wrynn_befouled_barrier_absorb::OnHealAbsorb, EFFECT_0); - } -}; - -// 365173 - Befouled Barrier Expire -class spell_anduin_wrynn_befouled_barrier_expire : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BEFOULED_BARRIER_SPHERE_AREATRIGGER, SPELL_BEFOULED_BARRIER_EXPLODE }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* target = GetTarget(); - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - { - AreaTrigger* barrier = GetTarget()->GetAreaTrigger(SPELL_BEFOULED_BARRIER_SPHERE_AREATRIGGER); - if (!barrier) - return; - - at_anduin_wrynn_befouled_barrier* barrierScript = dynamic_cast<at_anduin_wrynn_befouled_barrier*>(barrier->AI()); - if (!barrierScript) - return; - - target->CastSpell(target, SPELL_BEFOULED_BARRIER_EXPLODE, CastSpellExtraArgs().AddSpellMod(SPELLVALUE_BASE_POINT1, barrierScript->GetRemainingAbsorb())); - } - - if (Creature* creatureTarget = target->ToCreature()) - creatureTarget->DespawnOrUnsummon(); - } - - void Register() override - { - OnEffectRemove += AuraEffectRemoveFn(spell_anduin_wrynn_befouled_barrier_expire::OnRemove, EFFECT_0, SPELL_AURA_AREA_TRIGGER, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 361989 - Blasphemy -class spell_anduin_wrynn_blasphemy : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BLASPHEMY_PRE_HIT, SPELL_BLASPHEMY_OVERCONFIDENCE, SPELL_BLASPHEMY_HOPELESSNESS }); - } - - void OnPrecast() override - { - GetCaster()->CastSpell(GetCaster(), SPELL_BLASPHEMY_PRE_HIT, true); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - int64 hopelessnessAffected = targets.size() / 2; - int64 maxAffected = hopelessnessAffected * 2; - Trinity::Containers::RandomResize(targets, maxAffected); - - for (WorldObject* target : targets) - { - if (hopelessnessAffected > 0) - { - _spellAssignments[target->GetGUID()] = SPELL_BLASPHEMY_HOPELESSNESS; - hopelessnessAffected--; - } - else - _spellAssignments[target->GetGUID()] = SPELL_BLASPHEMY_OVERCONFIDENCE; - } - } - - void HandleDebuff(SpellEffIndex /*effIndex*/) - { - uint32* spellId = Trinity::Containers::MapGetValuePtr(_spellAssignments, GetHitUnit()->GetGUID()); - if (!spellId) - return; - - GetCaster()->CastSpell(GetHitUnit(), *spellId, true); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anduin_wrynn_blasphemy::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_anduin_wrynn_blasphemy::HandleDebuff, EFFECT_0, SPELL_EFFECT_DUMMY); - } - -private: - std::unordered_map<ObjectGuid /*player*/, uint32 /*spell*/> _spellAssignments; -}; - -// 361992 - Overconfidence CreatePropertiesId: 24616 -// 361993 - Hopelessness CreatePropertiesId: 24616 -struct at_anduin_wrynn_blasphemy : AreaTriggerAI -{ - at_anduin_wrynn_blasphemy(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer() || unit->HasAura(SPELL_BLASPHEMY_PRE_HIT)) - return; - - if (!unit->IsAlive()) - at->Remove(); - - if (unit->HasAura(at->GetSpellId())) - { - uint32 explodeSpellId = SPELL_BLASPHEMY_EXPLODE; - if (at->GetMap()->IsLFR() || at->GetMap()->IsNormal()) - explodeSpellId = SPELL_BLASPHEMY_EXPLODE_LFR_NORMAL; - - unit->CastSpell(unit, explodeSpellId, true); - unit->RemoveAurasDueToSpell(at->GetSpellId()); - if (Unit* target = at->GetTarget()) - { - target->CastSpell(target, explodeSpellId, true); - target->RemoveAurasDueToSpell(at->GetSpellId()); - } - } - else if (at->GetSpellId() == SPELL_BLASPHEMY_HOPELESSNESS_AREATRIGGER && unit->HasAura(SPELL_BLASPHEMY_OVERCONFIDENCE_AREATRIGGER)) - { - unit->RemoveAurasDueToSpell(SPELL_BLASPHEMY_OVERCONFIDENCE); - unit->RemoveAurasDueToSpell(SPELL_BLASPHEMY_OVERCONFIDENCE_AREATRIGGER); - unit->CastSpell(unit, SPELL_BLASPHEMY_SUCCESS, true); - if (Unit* target = at->GetTarget()) - { - target->RemoveAurasDueToSpell(SPELL_BLASPHEMY_HOPELESSNESS); - target->RemoveAurasDueToSpell(SPELL_BLASPHEMY_HOPELESSNESS_AREATRIGGER); - target->CastSpell(target, SPELL_BLASPHEMY_SUCCESS, true); - } - } - else if (at->GetSpellId() == SPELL_BLASPHEMY_OVERCONFIDENCE_AREATRIGGER && unit->HasAura(SPELL_BLASPHEMY_HOPELESSNESS_AREATRIGGER)) - { - unit->RemoveAurasDueToSpell(SPELL_BLASPHEMY_HOPELESSNESS); - unit->RemoveAurasDueToSpell(SPELL_BLASPHEMY_HOPELESSNESS_AREATRIGGER); - unit->CastSpell(unit, SPELL_BLASPHEMY_SUCCESS, true); - if (Unit* target = at->GetTarget()) - { - target->RemoveAurasDueToSpell(SPELL_BLASPHEMY_OVERCONFIDENCE); - target->RemoveAurasDueToSpell(SPELL_BLASPHEMY_OVERCONFIDENCE_AREATRIGGER); - target->CastSpell(target, SPELL_BLASPHEMY_SUCCESS, true); - } - } - else - { - // On Mythic players walking in with no debuff also trigger explosion - if (!at->GetMap()->IsMythic()) - return; - - if (!unit->HasAura(SPELL_BLASPHEMY_HOPELESSNESS_AREATRIGGER) || !unit->HasAura(SPELL_BLASPHEMY_OVERCONFIDENCE_AREATRIGGER)) - { - if (Unit* target = at->GetTarget()) - target->CastSpell(target, SPELL_BLASPHEMY_EXPLODE, true); - } - } - } -}; - -// 361992 - Overconfidence -// 361993 - Hopelessness -class spell_anduin_wrynn_hopelessness_overconfidence : public AuraScript -{ - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo( - { - SPELL_BLASPHEMY_EXPLODE, - SPELL_BLASPHEMY_EXPLODE_LFR_NORMAL - }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - { - Unit* target = GetTarget(); - uint32 explodeSpellId = SPELL_BLASPHEMY_EXPLODE; - if (target->GetMap()->IsLFR() || target->GetMap()->IsNormal()) - explodeSpellId = SPELL_BLASPHEMY_EXPLODE_LFR_NORMAL; - - target->CastSpell(target, explodeSpellId, true); - } - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_anduin_wrynn_hopelessness_overconfidence::OnRemove, EFFECT_0, SPELL_AURA_AREA_TRIGGER, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 365021 - Wicked Star -class spell_anduin_wrynn_wicked_star_selector : public SpellScript -{ - void FilterTargets(std::list<WorldObject*>& targets) - { - uint32 rangedDpsCount = 0; - for (WorldObject* target : targets) - { - Player* targetPlayer = target->ToPlayer(); - if (!targetPlayer) - continue; - - ChrSpecializationEntry const* spec = targetPlayer->GetPrimarySpecializationEntry(); - if (!spec) - continue; - - if (!targetPlayer->IsAlive()) - continue; - - if ((spec->GetRole() == ChrSpecializationRole::Dps && spec->GetFlags().HasFlag(ChrSpecializationFlag::Caster)) || - (spec->GetRole() == ChrSpecializationRole::Dps && spec->GetFlags().HasFlag(ChrSpecializationFlag::Ranged))) - rangedDpsCount++; - } - - targets.remove_if([rangedDpsCount](WorldObject* target) -> bool - { - Player* player = target->ToPlayer(); - if (!player || player->HasAura(SPELL_WICKED_STAR_TARGETED)) - return true; - - if (player->GetPrimarySpecializationEntry()->GetRole() == ChrSpecializationRole::Tank) - return true; - - if (rangedDpsCount >= 3) - { - if (player->GetPrimarySpecializationEntry()->GetRole() == ChrSpecializationRole::Dps && player->GetPrimarySpecializationEntry()->GetFlags().HasFlag(ChrSpecializationFlag::Melee)) - return true; - - if (player->GetPrimarySpecializationEntry()->GetRole() == ChrSpecializationRole::Healer) - return true; - } - return false; - }); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anduin_wrynn_wicked_star_selector::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - } -}; - -// 365021 - Wicked Star -class spell_anduin_wrynn_wicked_star_selector_AuraScript : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WICKED_STAR_TARGETED, GetAreaTriggerSpellID() }); - } - - virtual uint8 GetAnnounceGroupID() const - { - return SAY_ANNOUNCE_WICKED_STAR; - } - - virtual uint32 GetAreaTriggerSpellID() const - { - return SPELL_WICKED_STAR_AREATRIGGER; - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* caster = GetCaster(); - Unit* target = GetTarget(); - if (!caster) - return; - - caster->CastSpell(target, SPELL_WICKED_STAR_TARGETED, true); - - if (Creature* creature = caster->ToCreature()) - if (CreatureAI* anduinAI = creature->AI()) - anduinAI->Talk(GetAnnounceGroupID(), target); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - return; - - Unit* caster = GetCaster(); - if (!caster) - return; - - float angle = caster->GetAbsoluteAngle(GetTarget()); - Position spellDest(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), angle); - - if (InstanceScript* instance = GetTarget()->GetInstanceScript()) - if (Creature* anduin = instance->GetCreature(DATA_ANDUIN_WRYNN)) - anduin->CastSpell(spellDest, GetAreaTriggerSpellID(), true); - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_anduin_wrynn_wicked_star_selector_AuraScript::OnApply, EFFECT_0, SPELL_AURA_MOD_SCALE, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_anduin_wrynn_wicked_star_selector_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_SCALE, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 365017 - Wicked Star CreatePropertiesId: 24741 -struct at_anduin_wrynn_wicked_star : AreaTriggerAI -{ - at_anduin_wrynn_wicked_star(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - static constexpr float GetWickedStarSpeed(Difficulty difficulty) - { - // in yards per second - switch (difficulty) - { - case DIFFICULTY_HEROIC_RAID: - case DIFFICULTY_MYTHIC_RAID: - return 18.0f; - default: // LFR + Normal - return 15.0f; - } - } - - void OnInitialize() override - { - if (Unit* caster = at->GetCaster()) - { - at->SetOrientation(caster->GetOrientation()); - - Position destPos = caster->GetPosition(); - at->MovePositionToFirstCollision(destPos, 100.0f, 0.0f); - - std::vector<G3D::Vector3> splinePoints; - splinePoints.push_back(PositionToVector3(at->GetPosition())); - splinePoints.push_back(PositionToVector3(at->GetPosition())); - splinePoints.push_back(PositionToVector3(destPos)); - splinePoints.push_back(PositionToVector3(at->GetPosition())); - splinePoints.push_back(PositionToVector3(at->GetPosition())); - - float timeToTarget = at->GetDistance(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ()) * 2 / GetWickedStarSpeed(at->GetMap()->GetDifficultyID()) * 1000; - at->InitSplines(std::move(splinePoints), timeToTarget); - } - } - - void OnUnitEnter(Unit* unit) override - { - if (unit->GetEntry() == NPC_SYLVANAS_WINDRUNNER_ANDUIN || unit->GetEntry() == NPC_UTHER_THE_LIGHTBRINGER_ANDUIN || - unit->GetEntry() == NPC_LADY_JAINA_PROUDMOORE_ANDUIN || unit->GetEntry() == BOSS_ANDUIN_WRYNN) - return; - - Unit* caster = at->GetCaster(); - if (!caster) - return; - - if (caster->IsValidAttackTarget(unit)) - caster->CastSpell(unit, SPELL_WICKED_STAR_DAMAGE_SILENCE, CastSpellExtraArgs(TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS))); - else if (caster->IsValidAssistTarget(unit)) - caster->CastSpell(unit, SPELL_WICKED_STAR_EMPOWERMENT, CastSpellExtraArgs(TriggerCastFlags(TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS))); - } - - void OnDestinationReached() override - { - at->Remove(); - } -}; - -// 367632 - Empowered Wicked Star -class spell_anduin_wrynn_empowered_wicked_star_selector_AuraScript : public spell_anduin_wrynn_wicked_star_selector_AuraScript -{ - uint8 GetAnnounceGroupID() const override - { - return SAY_ANNOUNCE_EMPOWERED_WICKED_STAR; - } - - uint32 GetAreaTriggerSpellID() const override - { - return SPELL_EMPOWERED_WICKED_STAR_AREATRIGGER; - } -}; - -// 367621 - Empowered Wicked Star CreatePropertiesId: 24599 -struct at_anduin_wrynn_empowered_wicked_star : public at_anduin_wrynn_wicked_star -{ - at_anduin_wrynn_empowered_wicked_star(AreaTrigger* areatrigger) : at_anduin_wrynn_wicked_star(areatrigger) { } - - static float constexpr EMPOWERED_WICKED_STAR_SPEED = 14.0f; // in yards per second - - void HandleMovement(float angle) const - { - Unit* caster = at->GetCaster(); - if (!caster) - return; - - // hack: when reflection is implemented use at position instead of center; due to mmaps we are causing infinite loop if using at position after dest reach - Position destPos = DominationGraspCenter; - at->MovePositionToFirstCollision(destPos, 100.0f, angle); - - std::vector<G3D::Vector3> splinePoints; - splinePoints.push_back(PositionToVector3(at)); - splinePoints.push_back(PositionToVector3(at)); - splinePoints.push_back(PositionToVector3(destPos)); - splinePoints.push_back(PositionToVector3(destPos)); - - float timeToTarget = at->GetDistance(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ()) / EMPOWERED_WICKED_STAR_SPEED * 1000; - at->InitSplines(std::move(splinePoints), timeToTarget); - } - - void OnInitialize() override - { - HandleMovement(0); - } - - void OnDestinationReached() override - { - // hack: angle should use physical laws for reflection - HandleMovement(frand(0, 2.0f * float(M_PI))); - } -}; - -// 362405 - Kingsmourne Hungers -class spell_anduin_wrynn_kingsmourne_hungers : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_KINGSMOURNE_HUNGERS_DAMAGE, - SPELL_LOST_SOUL_DIMENSION, - SPELL_LOST_SOUL, - SPELL_SEVERED_SOUL - }); - } - - void HandleDummyEffect(SpellEffIndex /*effIndex*/) const - { - Unit* caster = GetCaster(); - Unit* hitUnit = GetHitUnit(); - caster->CastSpell(hitUnit, SPELL_KINGSMOURNE_HUNGERS_DAMAGE, true); - if (caster->GetMap()->IsMythic()) - hitUnit->CastSpell(hitUnit, SPELL_SEVERED_SOUL, true); - caster->CastSpell(hitUnit, SPELL_LOST_SOUL_DIMENSION); - hitUnit->CastSpell(hitUnit, SPELL_LOST_SOUL, true); - } - - void OnCast() const - { - InstanceScript* instance = GetCaster()->GetInstanceScript(); - if (!instance) - return; - - if (Creature* anduinSoul = instance->GetCreature(DATA_ANDUIN_SOUL)) - anduinSoul->GetAI()->DoAction(ACTION_SUMMON_KINGSMOURNE_SOULS); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_anduin_wrynn_kingsmourne_hungers::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); - AfterCast += SpellCastFn(spell_anduin_wrynn_kingsmourne_hungers::OnCast); - } -}; - -// 362055 - Lost Soul -class spell_anduin_wrynn_lost_soul : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_LOST_SOUL_GRACE, - SPELL_SCARRED_SOUL - }); - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - _lostSoulPosition = target->GetPosition(); - target->CastSpell(target, SPELL_LOST_SOUL_GRACE, true); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* target = GetTarget(); - switch (GetTargetApplication()->GetRemoveMode()) - { - case AURA_REMOVE_BY_DEFAULT: - case AURA_REMOVE_BY_ENEMY_SPELL: - target->CastSpell(target, SPELL_SCARRED_SOUL, true); - break; - case AURA_REMOVE_BY_EXPIRE: - { - if (target->GetMap()->IsMythic()) - { - target->KillSelf(); - target->NearTeleportTo(_lostSoulPosition); - } - break; - } - case AURA_REMOVE_BY_DEATH: - { - target->CastSpell(target, SPELL_SCARRED_SOUL, true); - if (target->GetMap()->IsMythic()) - target->NearTeleportTo(_lostSoulPosition); - break; - } - default: - break; - } - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_anduin_wrynn_lost_soul::OnApply, EFFECT_0, SPELL_AURA_PHASE, AURA_EFFECT_HANDLE_REAL); - OnEffectRemove += AuraEffectRemoveFn(spell_anduin_wrynn_lost_soul::OnRemove, EFFECT_1, SPELL_AURA_SCREEN_EFFECT, AURA_EFFECT_HANDLE_REAL); - } - - Position _lostSoulPosition; -}; - -// 362392 - Rain of Despair -class spell_anduin_rain_of_despair_player_selector : public SpellScript -{ - void HandleDespair(SpellEffIndex effIndex) const - { - GetCaster()->CastSpell(GetHitUnit(), GetEffectInfo(effIndex).TriggerSpell, true); - } - - void Register() override - { - OnEffectLaunchTarget += SpellEffectFn(spell_anduin_rain_of_despair_player_selector::HandleDespair, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 362766 - Soul Despawn -class spell_anduin_wrynn_soul_despawn : public SpellScript -{ - void OnCast() const - { - if (Creature* creature = GetCaster()->ToCreature()) - if (creature->GetEntry() == NPC_ANDUIN_HOPE || creature->GetEntry() == NPC_ANDUIN_DOUBT) - creature->DespawnOrUnsummon(3s); - } - - void Register() override - { - AfterCast += SpellCastFn(spell_anduin_wrynn_soul_despawn::OnCast); - } -}; - -// 368913 - Force of Will -class spell_anduin_wrynn_force_of_will : public AuraScript -{ - void RecalculateHook(AuraEffect const* /*aurEffect*/, int32& amount, bool& canBeRecalculated) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - // at 100 will power = 200% Damage Done increase - int32 powerValue = caster->GetPower(caster->GetPowerType()); - amount = 2 * powerValue; - canBeRecalculated = false; - } - - void RecalculateHookDamageTaken(AuraEffect const* /*aurEffect*/, int32& amount, bool& canBeRecalculated) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - // Damage Taken reduction can only be capped to 90% - int32 powerValue = caster->GetPower(caster->GetPowerType()); - amount = -std::min(powerValue, 90); - canBeRecalculated = false; - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - caster->SetPower(caster->GetPowerType(), 0); - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_anduin_wrynn_force_of_will::OnApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_anduin_wrynn_force_of_will::RecalculateHook, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_anduin_wrynn_force_of_will::RecalculateHook, EFFECT_1, SPELL_AURA_MOD_SUMMON_DAMAGE); - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_anduin_wrynn_force_of_will::RecalculateHookDamageTaken, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); - } -}; - -// 363233 - March of the Damned -class spell_anduin_wrynn_march_of_the_damned : public AuraScript -{ - void OnPeriodic(AuraEffect const* aurEff) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - Seconds raidDifficulty = 0s; - - switch (GetCaster()->GetMap()->GetDifficultyID()) - { - case DIFFICULTY_LFR_NEW: - case DIFFICULTY_NORMAL_RAID: - case DIFFICULTY_HEROIC_RAID: - raidDifficulty = 28s; - break; - case DIFFICULTY_MYTHIC_RAID: - raidDifficulty = 21s; - break; - default: - raidDifficulty = 28s; - break; - } - - // Don't summon the wall on aura granted - if (aurEff->GetTickNumber() == 1) - return; - - if (_availableSpawnPositions.empty()) - return; - - Position chosenPosition = Trinity::Containers::SelectRandomContainerElement(_availableSpawnPositions); - auto it = std::find(_availableSpawnPositions.begin(), _availableSpawnPositions.end(), chosenPosition); - _availableSpawnPositions.erase(it); - - GetCaster()->SummonCreature(NPC_MARCH_OF_THE_DAMNED, chosenPosition, TEMPSUMMON_TIMED_DESPAWN, raidDifficulty); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_anduin_wrynn_march_of_the_damned::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - - std::vector<Position> _availableSpawnPositions = { std::begin(MarchOfTheDamnedSpawnPositions), std::end(MarchOfTheDamnedSpawnPositions) }; -}; - -// 362500 - Shade Spawn Ceremony -class spell_remnant_of_a_fallen_king_spawn : public AuraScript -{ - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) - GetTarget()->GetAI()->DoAction(ACTION_ACTIVATE_REMNANT); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_remnant_of_a_fallen_king_spawn::OnRemove, EFFECT_2, SPELL_AURA_TRIGGER_SPELL_ON_EXPIRE, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 365652 - Lost Soul -class spell_anduin_soul_lost_soul : public SpellScript -{ - void FilterTargets(std::list<WorldObject*>& unitList) const - { - unitList.remove_if([this](WorldObject const* target) - { - if (target->GetEntry() == NPC_ANDUIN_DOUBT && target->IsWithinDistInMap(GetCaster(), 0.2f)) - return false; - return true; - }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) const - { - if (Creature* creature = GetHitUnit()->ToCreature()) - creature->DespawnOrUnsummon(); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anduin_soul_lost_soul::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - OnEffectHitTarget += SpellEffectFn(spell_anduin_soul_lost_soul::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 367769 - Severed Soul -class spell_anduin_wrynn_severed_soul : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CANCEL_LOST_SOUL }); - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* caster = GetCaster()) - _soulPosition = caster->GetPosition(); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - caster->CastSpell(caster, SPELL_CANCEL_LOST_SOUL, true); - - if (TempSummon* summon = GetTarget()->ToTempSummon()) - if (summon->GetSummonerUnit() == caster) - caster->NearTeleportTo(_soulPosition); - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_anduin_wrynn_severed_soul::OnApply, EFFECT_0, SPELL_AURA_LINKED_SUMMON, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_anduin_wrynn_severed_soul::OnRemove, EFFECT_1, SPELL_AURA_TRIGGER_SPELL_ON_EXPIRE, AURA_EFFECT_HANDLE_REAL); - } - - Position _soulPosition; -}; - -// 362402 - Lost Soul Mirror Image -class spell_anduin_wrynn_lost_soul_mirror_image : public SpellScript -{ - void FilterTargets(std::list<WorldObject*>& targets) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - ObjectGuid casterGuid = caster->GetGUID(); - - targets.remove_if([casterGuid](WorldObject const* target) -> bool - { - Unit const* unit = target->ToUnit(); - if (!unit) - return true; - - TempSummon const* summon = unit->ToTempSummon(); - if (!summon) - return true; - - if (summon->GetSummonerGUID() != casterGuid) - return true; - - return false; - }); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anduin_wrynn_lost_soul_mirror_image::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anduin_wrynn_lost_soul_mirror_image::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anduin_wrynn_lost_soul_mirror_image::FilterTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENTRY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anduin_wrynn_lost_soul_mirror_image::FilterTargets, EFFECT_3, TARGET_UNIT_SRC_AREA_ENTRY); - } -}; - -// 363029 - Soul Explosion -class spell_friendish_soul_explosion : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SOUL_EXPLOSION_TRIGGER_MISSILE }); - } - - void FilterTargets(std::list<WorldObject*>& targets) const - { - if (targets.empty()) - return; - - targets.remove_if(Trinity::ObjectTypeIdCheck(TYPEID_PLAYER, false)); - - std::vector<WorldObject*> rangedTargets; - for (WorldObject* target : targets) - { - if (target->GetDistance(GetCaster()) >= 5.0f) - { - rangedTargets.push_back(target); - break; - } - } - - if (!rangedTargets.empty()) - { - targets.clear(); - targets.push_back(Trinity::Containers::SelectRandomContainerElement(rangedTargets)); - } - } - - void HandleMissile(SpellEffIndex /*effIndex*/) const - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_SOUL_EXPLOSION_TRIGGER_MISSILE, true); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_friendish_soul_explosion::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_friendish_soul_explosion::HandleMissile, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 363022 - Return to Kingsmourne -class spell_remnant_of_a_fallen_king_return_to_kingsmourne_applied : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_RETURN_TO_KINGSMOURNE_VISUALS }); - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - caster->CastSpell(caster, SPELL_RETURN_TO_KINGSMOURNE_VISUALS); - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_remnant_of_a_fallen_king_return_to_kingsmourne_applied::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 363021 - Return to Kingsmourne -class spell_remnant_of_a_fallen_king_return_to_kingsmourne : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER, - SPELL_CANCEL_FORCE_OF_WILL - }); - } - - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - InstanceScript* instance = caster->GetInstanceScript(); - if (!instance) - return; - - if (Creature* arthas = instance->GetCreature(DATA_REMNANT_OF_A_FALLEN_KING)) - arthas->AI()->EnterEvadeMode(EvadeReason::Other); - - if (Creature* anduin = instance->GetCreature(DATA_ANDUIN_WRYNN)) - { - anduin->RemoveAurasDueToSpell(SPELL_DOMINATION_GRASP_ROOT_AREATRIGGER); - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_INTERMISSION, 0); - instance->DoUpdateWorldState(WORLD_STATE_ANDUIN_ENCOUNTER_STARTED, 1); - if (anduin->IsAIEnabled()) - { - anduin->AI()->DoAction(ACTION_EXIT_INTERMISSION); - anduin->AI()->DoCastSelf(SPELL_CANCEL_FORCE_OF_WILL); - } - } - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_remnant_of_a_fallen_king_return_to_kingsmourne::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 365120 - Grim Reflections -class spell_anduin_wrynn_grim_reflections : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_GRIM_REFLECTIONS_SUMMON }); - } - - void HandleCast() const - { - uint8 reflectionsNumber = GetCaster()->GetMap()->IsMythic() ? 4 : 3; - std::vector<Position> grimReflectionPositions(std::begin(GrimReflectionsSpawnPositions), std::end(GrimReflectionsSpawnPositions)); - Trinity::Containers::RandomResize(grimReflectionPositions, reflectionsNumber); - - for (uint8 i = 0; i < reflectionsNumber; i++) - GetCaster()->CastSpell(grimReflectionPositions[i], SPELL_GRIM_REFLECTIONS_SUMMON, true); - } - - void Register() override - { - OnCast += SpellCastFn(spell_anduin_wrynn_grim_reflections::HandleCast); - } -}; - -// 365872 - Beacon of Hope -class spell_anduin_wrynn_beacon_of_hope : public SpellScript -{ - void OnCast() const - { - GetCaster()->SummonCreature(NPC_BEACON_OF_HOPE, BeaconOfHopeSpawnPosition, TEMPSUMMON_MANUAL_DESPAWN); - } - - void Register() override - { - AfterCast += SpellCastFn(spell_anduin_wrynn_beacon_of_hope::OnCast); - } -}; - -// 365958 - Hopelessness -class spell_anduin_wrynn_hopelessness : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_BLASPHEMY_PRE_HIT, - SPELL_HOPELESSNESS_MISSILE - }); - } - - void OnPrecast() override - { - GetCaster()->CastSpell(GetCaster(), SPELL_BLASPHEMY_PRE_HIT, true); - } - - void HandleDebuff(SpellEffIndex /*effIndex*/) const - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_HOPELESSNESS_MISSILE, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_anduin_wrynn_hopelessness::HandleDebuff, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 365966 - Hopelessness CreatePropertiesId 24443 -struct at_anduin_wrynn_hopelessness : AreaTriggerAI -{ - at_anduin_wrynn_hopelessness(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer() || unit->HasAura(SPELL_BLASPHEMY_PRE_HIT)) - return; - - if (!unit->IsAlive()) - { - at->Remove(); - return; - } - - if (unit->HasAura(at->GetSpellId())) - { - unit->CastSpell(unit, SPELL_BLASPHEMY_EXPLODE, true); - if (Unit* target = at->GetTarget()) - target->CastSpell(target, SPELL_BLASPHEMY_EXPLODE, true); - } - } - - void OnUnitExit(Unit* unit) override - { - if (!unit->IsAlive() && unit->HasAura(at->GetSpellId())) - unit->RemoveAurasDueToSpell(at->GetSpellId()); - } -}; - -// 365966 - Hopelessness -class spell_anduin_wrynn_hopelessness_expire : public AuraScript -{ - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_HOPELESSNESS_EXPLODE }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const - { - switch (GetTargetApplication()->GetRemoveMode()) - { - case AURA_REMOVE_BY_ENEMY_SPELL: - case AURA_REMOVE_BY_EXPIRE: - case AURA_REMOVE_BY_DEATH: - GetTarget()->CastSpell(GetTarget(), SPELL_HOPELESSNESS_EXPLODE, true); - break; - default: - break; - } - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_anduin_wrynn_hopelessness_expire::OnRemove, EFFECT_0, SPELL_AURA_AREA_TRIGGER, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 365291 - Remnant Timer -class spell_remnant_of_a_fallen_king_energize_runic_power : public AuraScript -{ - static constexpr std::array<int32, 3> RemnantRegenCycle = { 1, 1, 2 }; - - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - int32 powerGained = RemnantRegenCycle[_powerRegenCycle++]; - - if (_powerRegenCycle > 2) - _powerRegenCycle = 1; - - target->ModifyPower(target->GetPowerType(), powerGained); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_remnant_of_a_fallen_king_energize_runic_power::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - - uint8 _powerRegenCycle = 0; -}; - -// 362862 - Army of the Dead -class spell_remnant_of_a_fallen_king_army_of_the_dead : public SpellScript -{ - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_ECHOES_OF_ANDORHAL_MONSTROUS_SOUL }); - } - - void HandleAfterCast() const - { - if (GetCaster()->GetMap()->IsLFR()) - return; - - Position monstrousSoulSpawnPosition = GetCaster()->GetNearPosition(frand(30.0f, 50.0f), frand(0.0f, 3.5f)); - GetCaster()->CastSpell(monstrousSoulSpawnPosition, SPELL_ECHOES_OF_ANDORHAL_MONSTROUS_SOUL, true); - } - - void Register() override - { - AfterCast += SpellCastFn(spell_remnant_of_a_fallen_king_army_of_the_dead::HandleAfterCast); - } -}; - -// 362863 - Echoes of Andorhal -class spell_remnant_of_a_fallen_king_echoes_of_andorhal : public SpellScript -{ - void SetDest(SpellDestination& dest) const - { - Position const echoesSummon = GetCaster()->GetRandomPoint(DominationGraspCenter, frand(20.5f, 30.0f)); - dest.Relocate(echoesSummon); - } - - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_remnant_of_a_fallen_king_echoes_of_andorhal::SetDest, EFFECT_0, TARGET_DEST_DEST_RANDOM); - } -}; - -// 362543 - Remorseless Winter -class spell_remnant_of_a_fallen_king_remorseless_winter_periodic : public AuraScript -{ - void OnPeriodic(AuraEffect const* /*aurEff*/) const - { - Unit* caster = GetCaster(); - if (!caster) - return; - - caster->CastSpell(GetTarget(), SPELL_REMORSELESS_WINTER_DEBUFF_DAMAGE, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_remnant_of_a_fallen_king_remorseless_winter_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -// 362545 - Remorseless Winter -class spell_remnant_of_a_fallen_king_remorseless_winter_damage : public SpellScript -{ - void HandleDamage(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - Aura* remorselessWinter = GetHitUnit()->GetAura(SPELL_REMORSELESS_WINTER_PERIODIC); - if (!remorselessWinter) - return; - - SetHitDamage(int32(GetHitDamage() * remorselessWinter->GetStackAmount())); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_remnant_of_a_fallen_king_remorseless_winter_damage::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } -}; - -// 362771 - Soul Reaper -class spell_remnant_of_a_fallen_king_soul_reaper : public SpellScript -{ - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo - ({ - SPELL_SOUL_REAPER_PHYSICAL_DAMAGE, - SPELL_SOUL_REAPER_SHADOWFROST_DAMAGE, - SPELL_SOUL_REAPER_DEBUFF, - SPELL_SOUL_REAPER_ATTACK_SPEED, - }); - } - - void HandleDummyEffect(SpellEffIndex /*effIndex*/) const - { - Unit* caster = GetCaster(); - Unit* hitUnit = GetHitUnit(); - caster->CastSpell(hitUnit, SPELL_SOUL_REAPER_PHYSICAL_DAMAGE, true); - caster->CastSpell(hitUnit, SPELL_SOUL_REAPER_SHADOWFROST_DAMAGE, true); - caster->CastSpell(hitUnit, SPELL_SOUL_REAPER_DEBUFF, true); - caster->CastSpell(caster, SPELL_SOUL_REAPER_ATTACK_SPEED, true); - caster->resetAttackTimer(BASE_ATTACK); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_remnant_of_a_fallen_king_soul_reaper::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// Anduin Wrynn Introduction Custom AT -struct at_anduin_wrynn_pre_introduction : AreaTriggerAI -{ - at_anduin_wrynn_pre_introduction(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player || player->IsGameMaster()) - return; - - InstanceScript* instance = at->GetInstanceScript(); - if (!instance) - return; - - if (Creature* anduin = instance->GetCreature(DATA_ANDUIN_WRYNN)) - anduin->GetAI()->DoAction(ACTION_START_PRE_INTRODUCTION); - - at->Remove(); - } -}; - -// 956 - Anduin End Movie -class movie_anduin_final : public PlayerScript -{ -public: - movie_anduin_final() : PlayerScript("movie_anduin_final") { } - - void MarkPlayerAsSkipped(uint32 playerId) - { - _skippedPlayers.insert(playerId); - } - - void OnMovieComplete(Player* player, uint32 /*movieId*/) override - { - InstanceScript* instance = player->GetInstanceScript(); - if (!instance) - return; - - Creature* anduin = instance->GetCreature(DATA_ANDUIN_WRYNN); - if (!anduin) - return; - - MarkPlayerAsSkipped(static_cast<uint32>(player->GetGUID().GetCounter())); - player->RemoveAurasDueToSpell(SPELL_FINAL_MOVIE); - - // Outroduction must start once every player skips or completes the movie - if (_skippedPlayers.size() == player->GetMap()->GetPlayersCountExceptGMs()) - anduin->GetAI()->DoAction(ACTION_START_OUTRODUCTION); - } - -private: - std::unordered_set<uint32> _skippedPlayers; -}; - -void AddSC_boss_anduin_wrynn() -{ - RegisterSepulcherOfTheFirstOnesCreatureAI(boss_anduin_wrynn); - RegisterSepulcherOfTheFirstOnesCreatureAI(boss_remnant_of_a_fallen_king); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_sylvanas); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_jaina); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_uther); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_empty_vessel); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_lost_soul); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_anduin_soul); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_anduin_despair); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_anduin_doubt); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_anduin_hope); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_monstrous_soul); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_fiendish_soul); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_grim_reflection); - RegisterSepulcherOfTheFirstOnesCreatureAI(npc_anduin_wrynn_beacon_of_hope); - - RegisterAreaTriggerAI(at_anduin_wrynn_pre_introduction); - RegisterSpellScript(spell_anduin_wrynn_pre_introduction); - RegisterSpellScript(spell_anduin_wrynn_progression_aura); - RegisterSpellScript(spell_anduin_wrynn_energize_willpower_lfr); - RegisterSpellScript(spell_anduin_wrynn_dark_zeal); - RegisterSpellScript(spell_anduin_wrynn_hopebreaker); - RegisterSpellScript(spell_anduin_wrynn_hopebreaker_periodic); - RegisterSpellScript(spell_anduin_wrynn_hopebreaker_damage); - RegisterAreaTriggerAI(at_anduin_wrynn_befouled_barrier); - RegisterSpellScript(spell_anduin_wrynn_befouled_barrier_absorb); - RegisterSpellScript(spell_anduin_wrynn_befouled_barrier_expire); - RegisterAreaTriggerAI(at_anduin_wrynn_blasphemy); - RegisterSpellScript(spell_anduin_wrynn_blasphemy); - RegisterSpellScript(spell_anduin_wrynn_hopelessness_overconfidence); - RegisterAreaTriggerAI(at_anduin_wrynn_wicked_star); - RegisterAreaTriggerAI(at_anduin_wrynn_empowered_wicked_star); - RegisterSpellAndAuraScriptPair(spell_anduin_wrynn_wicked_star_selector, spell_anduin_wrynn_wicked_star_selector_AuraScript); - RegisterSpellAndAuraScriptPairWithArgs(spell_anduin_wrynn_wicked_star_selector, spell_anduin_wrynn_empowered_wicked_star_selector_AuraScript, "spell_anduin_wrynn_empowered_wicked_star_selector"); - RegisterSpellScript(spell_anduin_wrynn_kingsmourne_hungers); - RegisterSpellScript(spell_anduin_soul_lost_soul); - RegisterSpellScript(spell_anduin_wrynn_lost_soul); - RegisterSpellScript(spell_anduin_wrynn_lost_soul_mirror_image); - RegisterSpellScript(spell_anduin_wrynn_severed_soul); - RegisterSpellScript(spell_anduin_wrynn_soul_despawn); - RegisterSpellScript(spell_anduin_rain_of_despair_player_selector); - RegisterSpellScript(spell_anduin_wrynn_force_of_will); - RegisterAreaTriggerAI(at_anduin_wrynn_march_of_the_damned); - RegisterSpellScript(spell_anduin_wrynn_march_of_the_damned); - RegisterSpellScript(spell_friendish_soul_explosion); - RegisterSpellScript(spell_anduin_wrynn_grim_reflections); - RegisterAreaTriggerAI(at_anduin_wrynn_beacon_of_hope); - RegisterSpellScript(spell_anduin_wrynn_beacon_of_hope); - RegisterAreaTriggerAI(at_anduin_wrynn_hopelessness); - RegisterSpellScript(spell_anduin_wrynn_hopelessness); - RegisterSpellScript(spell_anduin_wrynn_hopelessness_expire); - RegisterSpellScript(spell_anduin_wrynn_fragment_of_hope); - - RegisterSpellScript(spell_remnant_of_a_fallen_king_spawn); - RegisterSpellScript(spell_remnant_of_a_fallen_king_energize_runic_power); - RegisterSpellScript(spell_remnant_of_a_fallen_king_army_of_the_dead); - RegisterSpellScript(spell_remnant_of_a_fallen_king_echoes_of_andorhal); - RegisterSpellScript(spell_remnant_of_a_fallen_king_soul_reaper); - RegisterSpellScript(spell_remnant_of_a_fallen_king_remorseless_winter_periodic); - RegisterSpellScript(spell_remnant_of_a_fallen_king_remorseless_winter_damage); - RegisterSpellScript(spell_remnant_of_a_fallen_king_return_to_kingsmourne); - RegisterSpellScript(spell_remnant_of_a_fallen_king_return_to_kingsmourne_applied); - - new movie_anduin_final(); -} diff --git a/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/instance_sepulcher_of_the_first_ones.cpp b/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/instance_sepulcher_of_the_first_ones.cpp deleted file mode 100644 index a5d5db534dc..00000000000 --- a/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/instance_sepulcher_of_the_first_ones.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaBoundary.h" -#include "Creature.h" -#include "CreatureAI.h" -#include "InstanceScript.h" -#include "Map.h" -#include "ScriptMgr.h" -#include "sepulcher_of_the_first_ones.h" - -ObjectData const creatureData[] = -{ - // Anduin Wrynn - { BOSS_ANDUIN_WRYNN, DATA_ANDUIN_WRYNN }, - { BOSS_REMNANT_OF_A_FALLEN_KING, DATA_REMNANT_OF_A_FALLEN_KING }, - { NPC_UTHER_THE_LIGHTBRINGER_ANDUIN, DATA_UTHER_THE_LIGHTBRINGER_ANDUIN }, - { NPC_LADY_JAINA_PROUDMOORE_ANDUIN, DATA_JAINA_PROUDMOORE_ANDUIN }, - { NPC_SYLVANAS_WINDRUNNER_ANDUIN, DATA_SYLVANAS_WINDRUNNER_ANDUIN }, - { NPC_THRALL_ANDUIN, DATA_THRALL_ANDUIN }, - { NPC_FIRIM_ANDUIN, DATA_FIRIM_ANDUIN }, - { NPC_ANDUIN_SOUL, DATA_ANDUIN_SOUL }, - { NPC_BEACON_OF_HOPE, DATA_BEACON_OF_HOPE }, - { NPC_QUARTERMASTER_RAHM_ANDUIN, DATA_QUARTERMASTER_RAHM_ANDUIN }, - { NPC_BOLVAR_FORDRAGON_ANDUIN, DATA_BOLVAR_FORDRAGON_ANDUIN }, - { 0, 0 } -}; - -BossBoundaryData const boundaries = -{ - { DATA_ANDUIN_WRYNN, new CircleBoundary({ -3825.0601f, -2715.4600f }, 45.0)}, -}; - -DoorData const doorData[] = -{ - { GAMEOBJECT_BRIDGE_TO_ANDUIN, DATA_ANDUIN_WRYNN, EncounterDoorBehavior::OpenWhenInProgress }, - { GAMEOBJECT_BRIDGE_AFTER_ANDUIN, DATA_ANDUIN_WRYNN, EncounterDoorBehavior::OpenWhenNotDone }, - { 0, 0, EncounterDoorBehavior::OpenWhenInProgress } -}; - -DungeonEncounterData const encounters[] = -{ - { DATA_ANDUIN_WRYNN, {{ 2546 }} }, -}; - -class instance_sepulcher_of_the_first_ones : public InstanceMapScript -{ -public: - instance_sepulcher_of_the_first_ones() : InstanceMapScript(SFOScriptName, 2481) { } - - struct instance_sepulcher_of_the_first_ones_InstanceMapScript : public InstanceScript - { - instance_sepulcher_of_the_first_ones_InstanceMapScript(InstanceMap* map) : InstanceScript(map) - { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - LoadDungeonEncounterData(encounters); - LoadBossBoundaries(boundaries); - LoadObjectData(creatureData, nullptr); - LoadDoorData(doorData); - - AnduinIntroductionState = NOT_STARTED; - } - - bool SetBossState(uint32 id, EncounterState state) override - { - if (!InstanceScript::SetBossState(id, state)) - return false; - - switch (id) - { - case DATA_ANDUIN_WRYNN: - { - if (state == NOT_STARTED) - DoUpdateWorldState(WORLD_STATE_ANDUIN_ENCOUNTER_STARTED, 0); - else if (state == IN_PROGRESS) - { - Creature* anduin = GetCreature(DATA_ANDUIN_WRYNN); - if (!anduin) - return false; - - DoUpdateWorldState(WORLD_STATE_ANDUIN_ENCOUNTER_STARTED, 1); - - // @TODO: uther, sylvanas and jaina should attack anduin but keep faction 35; we lack core support - if (Creature* uther = GetCreature(DATA_UTHER_THE_LIGHTBRINGER_ANDUIN)) - uther->AI()->AttackStart(anduin); - - for (uint32 data : { DATA_SYLVANAS_WINDRUNNER_ANDUIN, DATA_JAINA_PROUDMOORE_ANDUIN }) - { - if (Creature* creature = GetCreature(data)) - creature->AI()->AttackStartCaster(anduin, 25.0f); - } - } - break; - } - default: - break; - } - return true; - } - - void SetData(uint32 type, uint32 data) override - { - switch (type) - { - case DATA_ANDUIN_WRYNN_INTRODUCTION: - { - AnduinIntroductionState = data; - break; - } - default: - break; - } - } - - uint32 GetData(uint32 type) const override - { - switch (type) - { - case DATA_ANDUIN_WRYNN_INTRODUCTION: - return AnduinIntroductionState; - default: - break; - } - - return 0; - } - - protected: - uint8 AnduinIntroductionState; - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_sepulcher_of_the_first_ones_InstanceMapScript(map); - } -}; - -void AddSC_instance_sepulcher_of_the_first_ones() -{ - new instance_sepulcher_of_the_first_ones(); -} diff --git a/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/sepulcher_of_the_first_ones.h b/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/sepulcher_of_the_first_ones.h deleted file mode 100644 index e6efa615e2b..00000000000 --- a/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/sepulcher_of_the_first_ones.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -#ifndef DEF_SEPULCHER_OF_THE_FIRST_ONES_H_ -#define DEF_SEPULCHER_OF_THE_FIRST_ONES_H_ - -#include "CreatureAIImpl.h" - -#define DataHeader "SepulcherOfTheFirstOnes" -#define SFOScriptName "instance_sepulcher_of_the_first_ones" - -uint32 const EncounterCount = 11; - -enum SepulcherOfTheFirstOnesDataTypes -{ - // Bosses - DATA_VIGILANT_CUSTODIAN = 0, - DATA_SKOLEX = 1, - DATA_ARTIFICER_XYMOX = 2, - DATA_HALONDRUS = 3, - DATA_DAUSEGNE = 4, - DATA_PROTOTYPE_PANTHEON = 5, - DATA_LIHUVIM = 6, - DATA_ANDUIN_WRYNN = 7, - DATA_LORDS_OF_DREAD = 8, - DATA_RYGELON = 10, - DATA_JAILER = 11, - - // Anduin Wrynn Encounter - DATA_ANDUIN_WRYNN_INTRODUCTION, - DATA_REMNANT_OF_A_FALLEN_KING, - DATA_SYLVANAS_WINDRUNNER_ANDUIN, - DATA_ANDUIN_SOUL, - DATA_BEACON_OF_HOPE, - DATA_JAINA_PROUDMOORE_ANDUIN, - DATA_UTHER_THE_LIGHTBRINGER_ANDUIN, - DATA_FIRIM_ANDUIN, - DATA_ANDUIN_TREASURE, - DATA_BOLVAR_FORDRAGON_ANDUIN, - DATA_THRALL_ANDUIN, - DATA_QUARTERMASTER_RAHM_ANDUIN, -}; - -enum SepulcherOfTheFirstOnesCreatureIds -{ - // Bosses - BOSS_VIGILANT_CUSTODIAN = 184522, - BOSS_VIGILANT_GUARDIAN = 180773, - BOSS_ANDUIN_WRYNN = 181954, - BOSS_REMNANT_OF_A_FALLEN_KING = 183463, - - // Anduin Wrynn Encounter - NPC_LADY_JAINA_PROUDMOORE_ANDUIN = 183664, - NPC_UTHER_THE_LIGHTBRINGER_ANDUIN = 183665, - NPC_SYLVANAS_WINDRUNNER_ANDUIN = 183666, - NPC_FIRIM_ANDUIN = 184589, - NPC_BEFOULED_BARRIER = 184585, - NPC_ANDUIN_SOUL = 184519, - NPC_ANDUIN_DESPAIR = 184520, - NPC_ANDUIN_HOPE = 184493, - NPC_ANDUIN_DOUBT = 184494, - NPC_EMPTY_VESSEL = 183452, - NPC_LOST_SOUL = 185607, - NPC_MONSTROUS_SOUL = 183671, - NPC_FIENDISH_SOUL = 183669, - NPC_MARCH_OF_THE_DAMNED = 183793, - NPC_GRIM_REFLECTION = 183033, - NPC_BEACON_OF_HOPE = 184830, - NPC_BOLVAR_FORDRAGON_ANDUIN = 184601, - NPC_QUARTERMASTER_RAHM_ANDUIN = 186785, - NPC_THRALL_ANDUIN = 184599, - NPC_KNIGHT_OF_EBON_BLADE_ANDUIN = 184613, -}; - -enum SepulcherOfTheFirstOnesTranslocatorIds -{ - NPC_ANCIENT_TRANSLOCATOR = 182431, -}; - -enum SepulcherOfTheFirstOnesGameObjectIds -{ - GAMEOBJECT_BRIDGE_TO_ANDUIN = 375110, - GAMEOBJECT_BRIDGE_AFTER_ANDUIN = 375035, - GAMEOBJECT_ANDUIN_CHEST_LOOT = 375901, -}; - -enum SepulcherOfTheFirstOnesEvents -{ - EVENT_RESET_PLAYERS_ON_TRANSLOCATOR = 1 -}; - -enum SepulcherOfTheFirstOnesActions -{ - ACTION_START_ANDUIN_OUTRODUCTION = 1, -}; - -enum SepulcherOfTheFirstOnesAreas -{ - AREA_DOMINATION_GRASP = 13965, - AREA_SEPULCHER_OF_THE_FIRST_ONES = 13742, -}; - -enum SepulcherOfTheFirstOnesWorldStates -{ - WORLD_STATE_ANDUIN_ENCOUNTER_STARTED = 21243, - WORLD_STATE_ANDUIN_INTERMISSION = 21433, - WORLD_STATE_ANDUIN_ENCOUNTER_COMPLETED = 21242, -}; - -template <class AI, class T> -inline AI* GetSepulcherOfTheFirstOnesAI(T* obj) -{ - return GetInstanceAI<AI>(obj, SFOScriptName); -} - -#define RegisterSepulcherOfTheFirstOnesCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetSepulcherOfTheFirstOnesAI) - -#endif diff --git a/src/server/scripts/Shadowlands/Torghast/spell_torghast.cpp b/src/server/scripts/Shadowlands/Torghast/spell_torghast.cpp deleted file mode 100644 index adbcbe4b4d9..00000000000 --- a/src/server/scripts/Shadowlands/Torghast/spell_torghast.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "ScriptMgr.h" -#include "Spell.h" -#include "SpellAuraEffects.h" -#include "SpellHistory.h" -#include "SpellMgr.h" -#include "SpellScript.h" -#include "Unit.h" - -// 297721 - Subjugator's Manacles -class spell_torghast_subjugators_manacles : public AuraScript -{ - bool CheckProc(AuraEffect const* /*aurEff*/, ProcEventInfo& procInfo) - { - if (_triggeredTargets.contains(procInfo.GetProcTarget()->GetGUID())) - return false; - - _triggeredTargets.insert(procInfo.GetProcTarget()->GetGUID()); - return true; - } - - void ResetMarkedTargets(bool isNowInCombat) - { - if (!isNowInCombat) - _triggeredTargets.clear(); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_torghast_subjugators_manacles::CheckProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - OnEnterLeaveCombat += AuraEnterLeaveCombatFn(spell_torghast_subjugators_manacles::ResetMarkedTargets); - } - - std::unordered_set<ObjectGuid> _triggeredTargets; -}; - -// 300771 - Blade of the Lifetaker -class spell_torghast_blade_of_the_lifetaker : public AuraScript -{ - void HandleProc(AuraEffect* aurEff, ProcEventInfo& procInfo) - { - PreventDefaultAction(); - - procInfo.GetActor()->CastSpell(procInfo.GetProcTarget(), aurEff->GetSpellEffectInfo().TriggerSpell, CastSpellExtraArgs(aurEff) - .AddSpellMod(SPELLVALUE_BASE_POINT0, GetTarget()->CountPctFromMaxHealth(aurEff->GetAmount())) - .SetTriggeringSpell(procInfo.GetProcSpell())); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_torghast_blade_of_the_lifetaker::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 300796 - Touch of the Unseen -class spell_torghast_touch_of_the_unseen : public AuraScript -{ - static constexpr uint32 SPELL_DOOR_OF_SHADOWS = 300728; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DOOR_OF_SHADOWS }); - } - - bool CheckProc(ProcEventInfo& procInfo) - { - return procInfo.GetSpellInfo() && procInfo.GetSpellInfo()->Id == SPELL_DOOR_OF_SHADOWS; - } - - void HandleProc(AuraEffect* aurEff, ProcEventInfo& procInfo) - { - PreventDefaultAction(); - - procInfo.GetActor()->CastSpell(procInfo.GetProcTarget(), aurEff->GetSpellEffectInfo().TriggerSpell, CastSpellExtraArgs(aurEff) - .AddSpellMod(SPELLVALUE_BASE_POINT0, GetTarget()->CountPctFromMaxHealth(aurEff->GetAmount())) - .SetTriggeringSpell(procInfo.GetProcSpell())); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_torghast_touch_of_the_unseen::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_torghast_touch_of_the_unseen::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 305060 - Yel'Shir's Powerglove -class spell_torghast_yelshirs_powerglove : public SpellScript -{ - void CalculateDamage(Unit const* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod) const - { - if (SpellInfo const* triggeringSpell = GetTriggeringSpell()) - if (Aura const* triggerAura = GetCaster()->GetAura(triggeringSpell->Id)) - pctMod *= triggerAura->GetStackAmount(); - } - - void Register() override - { - CalcDamage += SpellCalcDamageFn(spell_torghast_yelshirs_powerglove::CalculateDamage); - } -}; - -// 321706 - Dimensional Blade -class spell_torghast_dimensional_blade : public SpellScript -{ - static constexpr uint32 SPELL_MAGE_BLINK = 1953; - static constexpr uint32 SPELL_MAGE_SHIMMER = 212653; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_BLINK, SPELL_MAGE_SHIMMER }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - if (!targets.empty()) - { - GetCaster()->GetSpellHistory()->RestoreCharge(sSpellMgr->AssertSpellInfo(SPELL_MAGE_BLINK, DIFFICULTY_NONE)->ChargeCategoryId); - GetCaster()->GetSpellHistory()->RestoreCharge(sSpellMgr->AssertSpellInfo(SPELL_MAGE_SHIMMER, DIFFICULTY_NONE)->ChargeCategoryId); - } - - // filter targets by entry here and not with conditions table because we need to know if any enemy was hit for charge restoration, not just mawrats - targets.remove_if([](WorldObject const* target) - { - switch (target->GetEntry()) - { - case 151353: // Mawrat - case 179458: // Protective Mawrat - case 154030: // Oddly Large Mawrat - case 169871: // Hungry Mawrat - return false; - default: - break; - } - return true; - }); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_torghast_dimensional_blade::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); - } -}; - -// 341324 - Uncontrolled Darkness -class spell_torghast_uncontrolled_darkness : public AuraScript -{ - void Register() override - { - // just a value holder, no hooks - } - -public: - int32 KillCounter = 0; -}; - -// 343174 - Uncontrolled Darkness -class spell_torghast_uncontrolled_darkness_proc : public AuraScript -{ - static constexpr uint32 SPELL_UNCONTROLLED_DARKNESS = 341324; - static constexpr uint32 SPELL_UNCONTROLLED_DARKNESS_BUFF = 341375; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellEffect({ { SPELL_UNCONTROLLED_DARKNESS, EFFECT_1 } }) - && ValidateSpellInfo({ SPELL_UNCONTROLLED_DARKNESS_BUFF }); - } - - void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& /*procInfo*/) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - Aura* uncontrolledDarkness = caster->GetAura(SPELL_UNCONTROLLED_DARKNESS, caster->GetGUID()); - if (!uncontrolledDarkness) - return; - - spell_torghast_uncontrolled_darkness* script = uncontrolledDarkness->GetScript<spell_torghast_uncontrolled_darkness>(); - if (!script) - return; - - if (caster->HasAura(SPELL_UNCONTROLLED_DARKNESS_BUFF)) - { - if (++script->KillCounter >= uncontrolledDarkness->GetSpellInfo()->GetEffect(EFFECT_1).CalcValue()) - { - caster->RemoveAura(SPELL_UNCONTROLLED_DARKNESS_BUFF); - script->KillCounter = 0; - } - } - else - { - if (++script->KillCounter >= uncontrolledDarkness->GetSpellInfo()->GetEffect(EFFECT_0).CalcValue()) - { - caster->CastSpell(caster, SPELL_UNCONTROLLED_DARKNESS_BUFF, true); - script->KillCounter = 0; - } - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_torghast_uncontrolled_darkness_proc::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 342632 - Malevolent Stitching -class spell_torghast_fleshcraft_shield_proc : public AuraScript -{ - static constexpr uint32 SPELL_LABEL_FLESHCRAFT_BUFF = 1103; - - bool CheckProc(ProcEventInfo& procInfo) - { - return procInfo.GetSpellInfo() && procInfo.GetSpellInfo()->HasLabel(SPELL_LABEL_FLESHCRAFT_BUFF); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_torghast_fleshcraft_shield_proc::CheckProc); - } -}; - -// 342779 - Crystallized Dreams -class spell_torghast_soulshape_proc : public AuraScript -{ - static constexpr uint32 SPELL_LABEL_SOULSHAPE = 1100; - - bool CheckProc(ProcEventInfo& procInfo) - { - return procInfo.GetSpellInfo() && procInfo.GetSpellInfo()->HasLabel(SPELL_LABEL_SOULSHAPE); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_torghast_soulshape_proc::CheckProc); - } -}; - -// 342793 - Murmuring Shawl -// 342799 - Gnarled Key -class spell_torghast_door_of_shadows_proc : public AuraScript -{ - static constexpr uint32 SPELL_LABEL_DOOR_OF_SHADOWS = 726; - - bool CheckProc(ProcEventInfo& procInfo) - { - return procInfo.GetSpellInfo() && procInfo.GetSpellInfo()->HasLabel(SPELL_LABEL_DOOR_OF_SHADOWS); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_torghast_door_of_shadows_proc::CheckProc); - } -}; - -// 348908 - Ethereal Wildseed -class spell_torghast_flicker_proc : public AuraScript -{ - static constexpr uint32 SPELL_LABEL_FLICKER = 1105; - - bool CheckProc(ProcEventInfo& procInfo) - { - return procInfo.GetSpellInfo() && procInfo.GetSpellInfo()->HasLabel(SPELL_LABEL_FLICKER); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_torghast_flicker_proc::CheckProc); - } -}; - -// 354569 - Potent Potion -class spell_torghast_potent_potion_proc : public AuraScript -{ - static constexpr uint32 SPELL_LABEL_REJUVENATING_SIPHONED_ESSENCE = 1290; - - bool CheckProc(ProcEventInfo& procInfo) - { - return procInfo.GetSpellInfo() && procInfo.GetSpellInfo()->HasLabel(SPELL_LABEL_REJUVENATING_SIPHONED_ESSENCE); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_torghast_potent_potion_proc::CheckProc); - } -}; - -// 354706 - Spiritual Rejuvenation Potion -class spell_torghast_potent_potion_calc : public SpellScript -{ - static constexpr uint32 SPELL_LABEL_SPIRITUAL_REJUVENATION_POTION = 354568; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellEffect({ { SPELL_LABEL_SPIRITUAL_REJUVENATION_POTION, EFFECT_1 } }); - } - - void SetValue(SpellEffIndex effIndex) - { - SetEffectValue(sSpellMgr->AssertSpellInfo(SPELL_LABEL_SPIRITUAL_REJUVENATION_POTION, GetCastDifficulty())->GetEffect(effIndex) - .CalcValue(GetCaster(), nullptr, GetHitUnit())); - } - - void Register() override - { - OnEffectLaunchTarget += SpellEffectFn(spell_torghast_potent_potion_calc::SetValue, EFFECT_0, SPELL_EFFECT_HEAL); - OnEffectHitTarget += SpellEffectFn(spell_torghast_potent_potion_calc::SetValue, EFFECT_1, SPELL_EFFECT_ENERGIZE); - } -}; - -// 373761 - Poisonous Spores -class spell_torghast_poisonous_spores : public AuraScript -{ - void HandleProc(AuraEffect* aurEff, ProcEventInfo& procInfo) - { - PreventDefaultAction(); - - Spell const* procSpell = procInfo.GetProcSpell(); - procInfo.GetActor()->CastSpell(*procSpell->m_targets.GetDst(), aurEff->GetSpellEffectInfo().TriggerSpell, - CastSpellExtraArgs(aurEff).SetTriggeringSpell(procSpell)); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_torghast_poisonous_spores::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -void AddSC_torghast_spell_scripts() -{ - RegisterSpellScript(spell_torghast_subjugators_manacles); - RegisterSpellScript(spell_torghast_blade_of_the_lifetaker); - RegisterSpellScript(spell_torghast_touch_of_the_unseen); - RegisterSpellScript(spell_torghast_yelshirs_powerglove); - RegisterSpellScript(spell_torghast_dimensional_blade); - RegisterSpellScript(spell_torghast_uncontrolled_darkness); - RegisterSpellScript(spell_torghast_uncontrolled_darkness_proc); - RegisterSpellScript(spell_torghast_fleshcraft_shield_proc); - RegisterSpellScript(spell_torghast_soulshape_proc); - RegisterSpellScript(spell_torghast_door_of_shadows_proc); - RegisterSpellScript(spell_torghast_flicker_proc); - RegisterSpellScript(spell_torghast_potent_potion_proc); - RegisterSpellScript(spell_torghast_potent_potion_calc); - RegisterSpellScript(spell_torghast_poisonous_spores); -} diff --git a/src/server/scripts/Shadowlands/shadowlands_script_loader.cpp b/src/server/scripts/Shadowlands/shadowlands_script_loader.cpp deleted file mode 100644 index 6fd260d7d7c..00000000000 --- a/src/server/scripts/Shadowlands/shadowlands_script_loader.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -// This is where scripts' loading functions should be declared: -void AddSC_covenant_spell_scripts(); -void AddSC_torghast_spell_scripts(); - -void AddSC_boss_sylvanas_windrunner(); -void AddSC_instance_sanctum_of_domination(); - -void AddSC_boss_anduin_wrynn(); -void AddSC_instance_sepulcher_of_the_first_ones(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddShadowlandsScripts() -{ - AddSC_covenant_spell_scripts(); - AddSC_torghast_spell_scripts(); - - // Sanctum of Domination - AddSC_boss_sylvanas_windrunner(); - AddSC_instance_sanctum_of_domination(); - - // Sepulcher of The First Ones - AddSC_boss_anduin_wrynn(); - AddSC_instance_sepulcher_of_the_first_ones(); -} diff --git a/src/server/scripts/Shadowlands/spell_covenant.cpp b/src/server/scripts/Shadowlands/spell_covenant.cpp deleted file mode 100644 index 79cc92cac93..00000000000 --- a/src/server/scripts/Shadowlands/spell_covenant.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "ScriptMgr.h" -#include "SpellAuraEffects.h" -#include "SpellMgr.h" -#include "SpellScript.h" -#include "Unit.h" - -// 323916 - Sulfuric Emission -class spell_soulbind_sulfuric_emission : public AuraScript -{ - static constexpr uint32 SPELL_SULFURIC_EMISSION_COOLDOWN_AURA = 347684; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SULFURIC_EMISSION_COOLDOWN_AURA }); - } - - bool CheckProc(AuraEffect const* aurEff, ProcEventInfo& procInfo) - { - if (!procInfo.GetProcTarget()->HealthBelowPct(aurEff->GetAmount())) - return false; - - if (procInfo.GetProcTarget()->HasAura(SPELL_SULFURIC_EMISSION_COOLDOWN_AURA)) - return false; - - return true; - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_soulbind_sulfuric_emission::CheckProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 332753 - Superior Tactics -class spell_soulbind_superior_tactics : public AuraScript -{ - static constexpr uint32 SPELL_SUPERIOR_TACTICS_COOLDOWN_AURA = 332926; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SUPERIOR_TACTICS_COOLDOWN_AURA }); - } - - bool CheckProc(AuraEffect const* /*aurEff*/, ProcEventInfo& procInfo) - { - if (GetTarget()->HasAura(SPELL_SUPERIOR_TACTICS_COOLDOWN_AURA)) - return false; - - // only dispels from friendly targets count - if (procInfo.GetHitMask() & PROC_HIT_DISPEL && !(procInfo.GetTypeMask() & (PROC_FLAG_DEAL_HELPFUL_ABILITY | PROC_FLAG_DEAL_HELPFUL_SPELL | PROC_FLAG_DEAL_HELPFUL_PERIODIC))) - return false; - - return true; - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_soulbind_superior_tactics::CheckProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -void AddSC_covenant_spell_scripts() -{ - RegisterSpellScript(spell_soulbind_sulfuric_emission); - RegisterSpellScript(spell_soulbind_superior_tactics); -} diff --git a/src/server/scripts/Spells/spell_azerite.cpp b/src/server/scripts/Spells/spell_azerite.cpp deleted file mode 100644 index 5216c468dc7..00000000000 --- a/src/server/scripts/Spells/spell_azerite.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "ScriptMgr.h" -#include "AzeritePackets.h" -#include "Containers.h" -#include "Player.h" -#include "Spell.h" -#include "SpellAuraEffects.h" -#include "SpellInfo.h" -#include "SpellMgr.h" -#include "SpellScript.h" - -class spell_azerite_gen_aura_calc_from_2nd_effect_triggered_spell : public AuraScript -{ - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } }) && ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_1).TriggerSpell }); - } - - void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) - { - if (Unit* caster = GetCaster()) - { - amount = 0; - canBeRecalculated = false; - for (auto const& [_, aurApp] : Trinity::Containers::MapEqualRange(caster->GetAppliedAuras(), GetEffectInfo(EFFECT_1).TriggerSpell)) - if (aurApp->HasEffect(EFFECT_0)) - amount += aurApp->GetBase()->GetEffect(EFFECT_0)->GetAmount(); - } - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_azerite_gen_aura_calc_from_2nd_effect_triggered_spell::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_RATING); - } -}; - -// 270658 - Azerite Fortification -class spell_item_azerite_fortification : public AuraScript -{ - bool CheckProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - Spell const* procSpell = eventInfo.GetProcSpell(); - if (!procSpell) - return false; - - return procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_STUN) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_ROOT) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_ROOT_2) - || procSpell->GetSpellInfo()->HasEffect(SPELL_EFFECT_KNOCK_BACK); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_azerite_fortification::CheckProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -enum StrengthInNumbers -{ - SPELL_STRENGTH_IN_NUMBERS_TRAIT = 271546, - SPELL_STRENGTH_IN_NUMBERS_BUFF = 271550 -}; - -// 271548 - Strength in Numbers -class spell_item_strength_in_numbers : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_STRENGTH_IN_NUMBERS_TRAIT, SPELL_STRENGTH_IN_NUMBERS_BUFF }); - } - - void TriggerHealthBuff() - { - if (AuraEffect const* trait = GetCaster()->GetAuraEffect(SPELL_STRENGTH_IN_NUMBERS_TRAIT, EFFECT_0, GetCaster()->GetGUID())) - if (int64 enemies = GetUnitTargetCountForEffect(EFFECT_0)) - GetCaster()->CastSpell(GetCaster(), SPELL_STRENGTH_IN_NUMBERS_BUFF, CastSpellExtraArgs(TRIGGERED_FULL_MASK) - .AddSpellMod(SPELLVALUE_BASE_POINT0, trait->GetAmount()) - .AddSpellMod(SPELLVALUE_AURA_STACK, enemies)); - } - - void Register() override - { - AfterHit += SpellHitFn(spell_item_strength_in_numbers::TriggerHealthBuff); - } -}; - -enum BlessedPortents -{ - SPELL_BLESSED_PORTENTS_TRAIT = 267889, - SPELL_BLESSED_PORTENTS_HEAL = 280052, -}; - -// 271843 - Blessed Portents -class spell_item_blessed_portents : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BLESSED_PORTENTS_TRAIT, SPELL_BLESSED_PORTENTS_HEAL }); - } - - void CheckProc(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) - { - if (GetTarget()->HealthBelowPctDamaged(50, dmgInfo.GetDamage())) - { - if (Unit* caster = GetCaster()) - if (AuraEffect const* trait = caster->GetAuraEffect(SPELL_BLESSED_PORTENTS_TRAIT, EFFECT_0, caster->GetGUID())) - caster->CastSpell(GetTarget(), SPELL_BLESSED_PORTENTS_HEAL, CastSpellExtraArgs(TRIGGERED_FULL_MASK) - .AddSpellMod(SPELLVALUE_BASE_POINT0, trait->GetAmount())); - } - else - PreventDefaultAction(); - } - - void Register() override - { - OnEffectAbsorb += AuraEffectAbsorbFn(spell_item_blessed_portents::CheckProc, EFFECT_0); - } -}; - -enum ConcentratedMending -{ - SPELL_CONCENTRATED_MENDING_TRAIT = 267882, -}; - -// 272260 - Concentrated Mending -class spell_item_concentrated_mending : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CONCENTRATED_MENDING_TRAIT }); - } - - void RecalculateHealAmount(AuraEffect* aurEff) - { - if (Unit const* caster = GetCaster()) - if (AuraEffect const* trait = caster->GetAuraEffect(SPELL_CONCENTRATED_MENDING_TRAIT, EFFECT_0, caster->GetGUID())) - aurEff->ChangeAmount(trait->GetAmount() * aurEff->GetTickNumber()); - } - - void Register() override - { - OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_item_concentrated_mending::RecalculateHealAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL); - } -}; - -enum BracingChill -{ - SPELL_BRACING_CHILL_TRAIT = 267884, - SPELL_BRACING_CHILL = 272276, - SPELL_BRACING_CHILL_HEAL = 272428, - SPELL_BRACING_CHILL_SEARCH_JUMP_TARGET = 272436, -}; - -// 272276 - Bracing Chill -class spell_item_bracing_chill_proc : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BRACING_CHILL_TRAIT, SPELL_BRACING_CHILL_HEAL, SPELL_BRACING_CHILL_SEARCH_JUMP_TARGET }); - } - - bool CheckHealCaster(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - return GetCasterGUID() == eventInfo.GetActor()->GetGUID(); - } - - void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& procInfo) - { - Unit* caster = procInfo.GetActor(); - if (!caster) - return; - - if (AuraEffect const* trait = caster->GetAuraEffect(SPELL_BRACING_CHILL_TRAIT, EFFECT_0, caster->GetGUID())) - caster->CastSpell(procInfo.GetProcTarget(), SPELL_BRACING_CHILL_HEAL, - CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_BASE_POINT0, trait->GetAmount())); - - if (GetStackAmount() > 1) - caster->CastSpell(nullptr, SPELL_BRACING_CHILL_SEARCH_JUMP_TARGET, - CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount() - 1)); - - Remove(); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_bracing_chill_proc::CheckHealCaster, EFFECT_0, SPELL_AURA_DUMMY); - AfterEffectProc += AuraEffectProcFn(spell_item_bracing_chill_proc::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 272436 - Bracing Chill -class spell_item_bracing_chill_search_jump_target : public SpellScript -{ - void FilterTarget(std::list<WorldObject*>& targets) - { - if (targets.empty()) - return; - - std::list<WorldObject*> copy = targets; - Trinity::Containers::RandomResize(copy, [&](WorldObject* target) - { - return target->IsUnit() && !target->ToUnit()->HasAura(SPELL_BRACING_CHILL, GetCaster()->GetGUID()); - }, 1); - - if (!copy.empty()) - { - // found a preferred target, use that - targets.swap(copy); - return; - } - - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } - - void MoveAura(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_BRACING_CHILL, - CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_AURA_STACK, GetSpellValue()->AuraStackAmount)); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_bracing_chill_search_jump_target::FilterTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY); - OnEffectHitTarget += SpellEffectFn(spell_item_bracing_chill_search_jump_target::MoveAura, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 272837 - Trample the Weak -class spell_item_trample_the_weak : public AuraScript -{ - bool CheckHealthPct(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - return eventInfo.GetActor()->GetHealthPct() > eventInfo.GetActionTarget()->GetHealthPct(); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_trample_the_weak::CheckHealthPct, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 272892 - Wracking Brilliance -class spell_item_wracking_brilliance : public AuraScript -{ - enum - { - SPELL_AGONY_SOUL_SHARD_GAIN = 210067 - }; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_AGONY_SOUL_SHARD_GAIN }); - } - - bool CheckProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - if (spellInfo->Id != SPELL_AGONY_SOUL_SHARD_GAIN) - return false; - - _canTrigger = !_canTrigger; // every other soul shard gain - return _canTrigger; - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_wracking_brilliance::CheckProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } - - bool _canTrigger = true; -}; - -enum OrbitalPrecision -{ - SPELL_MAGE_FROZEN_ORB = 84714 -}; - -// 275514 - Orbital Precision -class spell_item_orbital_precision : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_FROZEN_ORB }); - } - - bool CheckFrozenOrbActive(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - return eventInfo.GetActor()->GetAreaTrigger(SPELL_MAGE_FROZEN_ORB) != nullptr; - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_orbital_precision::CheckFrozenOrbActive, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -enum BlurOfTalons -{ - SPELL_HUNTER_COORDINATED_ASSAULT = 266779 -}; - -// 277966 - Blur of Talons -class spell_item_blur_of_talons : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HUNTER_COORDINATED_ASSAULT }); - } - - bool CheckCoordinatedAssaultActive(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - return eventInfo.GetActor()->HasAura(SPELL_HUNTER_COORDINATED_ASSAULT, eventInfo.GetActor()->GetGUID()); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_blur_of_talons::CheckCoordinatedAssaultActive, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 278519 - Divine Right -class spell_item_divine_right : public AuraScript -{ - bool CheckHealthPct(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - return eventInfo.GetProcTarget()->HasAuraState(AURA_STATE_WOUNDED_20_PERCENT, eventInfo.GetSpellInfo(), eventInfo.GetActor()); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_divine_right::CheckHealthPct, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 280409 - Blood Rite -class spell_item_blood_rite : public AuraScript -{ - void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& /*procInfo*/) - { - RefreshDuration(); - } - - void Register() override - { - AfterEffectProc += AuraEffectProcFn(spell_item_blood_rite::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); - } -}; - -// 281843 - Tradewinds -class spell_item_tradewinds : public AuraScript -{ - enum - { - SPELL_TRADEWINDS_ALLY_BUFF = 281844 - }; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_TRADEWINDS_ALLY_BUFF }); - } - - void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - if (AuraEffect const* trait = GetTarget()->GetAuraEffect(GetEffectInfo(EFFECT_1).TriggerSpell, EFFECT_1)) - GetTarget()->CastSpell(nullptr, SPELL_TRADEWINDS_ALLY_BUFF, - CastSpellExtraArgs(aurEff).AddSpellMod(SPELLVALUE_BASE_POINT0, trait->GetAmount())); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_item_tradewinds::HandleRemove, EFFECT_0, SPELL_AURA_MOD_RATING, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 287379 - Bastion of Might -class spell_item_bastion_of_might : public SpellScript -{ - enum - { - SPELL_WARRIOR_IGNORE_PAIN = 190456 - }; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARRIOR_IGNORE_PAIN }); - } - - void TriggerIgnorePain() - { - GetCaster()->CastSpell(GetCaster(), SPELL_WARRIOR_IGNORE_PAIN, GetSpell()); - } - - void Register() override - { - AfterHit += SpellHitFn(spell_item_bastion_of_might::TriggerIgnorePain); - } -}; - -// 287650 - Echoing Blades -class spell_item_echoing_blades : public AuraScript -{ - void PrepareProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetProcSpell()) - { - if (eventInfo.GetProcSpell()->m_castId != _lastFanOfKnives) - GetEffect(EFFECT_0)->RecalculateAmount(); - - _lastFanOfKnives = eventInfo.GetProcSpell()->m_castId; - } - } - - bool CheckFanOfKnivesCounter(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - return aurEff->GetAmount() > 0; - } - - void ReduceCounter(AuraEffect* aurEff, ProcEventInfo& /*procInfo*/) - { - aurEff->SetAmount(aurEff->GetAmount() - 1); - } - - void Register() override - { - DoPrepareProc += AuraProcFn(spell_item_echoing_blades::PrepareProc); - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_echoing_blades::CheckFanOfKnivesCounter, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - AfterEffectProc += AuraEffectProcFn(spell_item_echoing_blades::ReduceCounter, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } - - ObjectGuid _lastFanOfKnives; -}; - -// 287653 - Echoing Blades -class spell_item_echoing_blades_damage : public SpellScript -{ - enum - { - SPELL_ECHOING_BLADES_TRAIT = 287649 - }; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellEffect({ { SPELL_ECHOING_BLADES_TRAIT, EFFECT_2 } }); - } - - void CalculateDamage(Unit const* /*victim*/, int32& damage, int32& /*flatMod*/, float& /*pctMod*/) const - { - if (AuraEffect const* trait = GetCaster()->GetAuraEffect(SPELL_ECHOING_BLADES_TRAIT, EFFECT_2)) - damage = trait->GetAmount() * 2; - } - - void ForceCritical(Unit const* /*victim*/, float& critChance) - { - critChance = 100.0f; - } - - void Register() override - { - CalcDamage += SpellCalcDamageFn(spell_item_echoing_blades_damage::CalculateDamage); - OnCalcCritChance += SpellOnCalcCritChanceFn(spell_item_echoing_blades_damage::ForceCritical); - } -}; - -// 288882 - Hour of Reaping -class spell_item_hour_of_reaping : public AuraScript -{ - enum - { - SPELL_DH_SOUL_BARRIER = 263648 - }; - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_SOUL_BARRIER }); - } - - bool CheckProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - return GetStackAmount() == GetAura()->CalcMaxStackAmount(); - } - - void TriggerSoulBarrier(AuraEffect* aurEff, ProcEventInfo& /*procInfo*/) - { - GetTarget()->CastSpell(GetTarget(), SPELL_DH_SOUL_BARRIER, aurEff); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_hour_of_reaping::CheckProc, EFFECT_0, SPELL_AURA_DUMMY); - AfterEffectProc += AuraEffectProcFn(spell_item_hour_of_reaping::TriggerSoulBarrier, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 304086 - Azerite Fortification -class spell_item_conflict_wearer_on_stun_proc : public AuraScript -{ - bool CheckProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - Spell const* procSpell = eventInfo.GetProcSpell(); - if (!procSpell) - return false; - - return procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_STUN) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_STUN_DISABLE_GRAVITY); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_item_conflict_wearer_on_stun_proc::CheckProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 305723 - Strife (Azerite Essence) -class spell_item_conflict_rank3 : public AuraScript -{ - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetHitMask() & (PROC_HIT_INTERRUPT | PROC_HIT_DISPEL)) - return true; - - Spell const* procSpell = eventInfo.GetProcSpell(); - if (!procSpell) - return false; - - bool isCrowdControl = procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_CONFUSE) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_FEAR) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_STUN) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_PACIFY) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_ROOT) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_SILENCE) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_PACIFY_SILENCE) - || procSpell->GetSpellInfo()->HasAura(SPELL_AURA_MOD_ROOT_2); - - if (!isCrowdControl) - return false; - - return eventInfo.GetActionTarget()->HasAura([&](Aura const* aura) { return aura->GetCastId() == procSpell->m_castId; }); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_conflict_rank3::CheckProc); - } -}; - -// 277253 - Heart of Azeroth -class spell_item_heart_of_azeroth : public AuraScript -{ - void SetEquippedFlag(AuraEffect const* /*effect*/, AuraEffectHandleModes /*mode*/) - { - SetState(true); - } - - void ClearEquippedFlag(AuraEffect const* /*effect*/, AuraEffectHandleModes /*mode*/) - { - SetState(false); - } - - void SetState(bool equipped) const - { - if (Player* target = GetTarget()->ToPlayer()) - { - WorldPackets::Azerite::PlayerAzeriteItemEquippedStatusChanged statusChanged; - statusChanged.IsHeartEquipped = equipped; - target->SendDirectMessage(statusChanged.Write()); - } - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_item_heart_of_azeroth::SetEquippedFlag, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - OnEffectRemove += AuraEffectRemoveFn(spell_item_heart_of_azeroth::ClearEquippedFlag, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 315176 - Grasping Tendrils -class spell_item_corruption_grasping_tendrils : public AuraScript -{ - bool Load() override - { - return GetUnitOwner()->IsPlayer(); - } - - void CalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) - { - //Player* player = GetUnitOwner()->ToPlayer(); - //amount = std::clamp(10.0f + player->GetRatingBonusValue(CR_CORRUPTION) - player->GetRatingBonusValue(CR_CORRUPTION_RESISTANCE), 0.0f, 99.0f); - //canBeRecalculated = false; - } - - void Register() override - { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_item_corruption_grasping_tendrils::CalcAmount, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED); - } -}; - -void AddSC_azerite_item_spell_scripts() -{ - RegisterSpellScript(spell_azerite_gen_aura_calc_from_2nd_effect_triggered_spell); - RegisterSpellScript(spell_item_azerite_fortification); - RegisterSpellScript(spell_item_strength_in_numbers); - RegisterSpellScript(spell_item_blessed_portents); - RegisterSpellScript(spell_item_concentrated_mending); - RegisterSpellScript(spell_item_bracing_chill_proc); - RegisterSpellScript(spell_item_bracing_chill_search_jump_target); - RegisterSpellScript(spell_item_trample_the_weak); - RegisterSpellScript(spell_item_wracking_brilliance); - RegisterSpellScript(spell_item_orbital_precision); - RegisterSpellScript(spell_item_blur_of_talons); - RegisterSpellScript(spell_item_divine_right); - RegisterSpellScript(spell_item_blood_rite); - RegisterSpellScript(spell_item_tradewinds); - RegisterSpellScript(spell_item_bastion_of_might); - RegisterSpellScript(spell_item_echoing_blades); - RegisterSpellScript(spell_item_echoing_blades_damage); - RegisterSpellScript(spell_item_hour_of_reaping); - RegisterSpellScript(spell_item_conflict_wearer_on_stun_proc); - RegisterSpellScript(spell_item_conflict_rank3); - - RegisterSpellScript(spell_item_heart_of_azeroth); - - RegisterSpellScript(spell_item_corruption_grasping_tendrils); -} diff --git a/src/server/scripts/Spells/spell_dh.cpp b/src/server/scripts/Spells/spell_dh.cpp deleted file mode 100644 index 16c6385e8b7..00000000000 --- a/src/server/scripts/Spells/spell_dh.cpp +++ /dev/null @@ -1,514 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -/* - * Scripts for spells with SPELLFAMILY_DEMONHUNTER and SPELLFAMILY_GENERIC spells used by demon hunter players. - * Ordered alphabetically using scriptname. - * Scriptnames of files in this file should be prefixed with "spell_dh_". - */ - -#include "AreaTrigger.h" -#include "AreaTriggerAI.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "SpellAuraEffects.h" -#include "SpellAuras.h" -#include "SpellHistory.h" -#include "SpellMgr.h" -#include "SpellScript.h" -#include "Unit.h" - -enum DemonHunterSpells -{ - AREATRIGGER_DH_SHATTERED_SOULS_HAVOC = 8352, - AREATRIGGER_DH_SHATTERED_SOULS_HAVOC_DEMON = 11231, - AREATRIGGER_DH_SHATTERED_SOULS_VENGEANCE = 11266, - AREATRIGGER_DH_SHATTERED_SOULS_VENGEANCE_DEMON = 10693, - AREATRIGGER_DH_SOUL_FRAGMENT_HAVOC = 12929, - AREATRIGGER_DH_SOUL_FRAGMENT_VENGEANCE = 10665, - - SPELL_DH_ABYSSAL_STRIKE = 207550, - SPELL_DH_ANNIHILATION = 201427, - SPELL_DH_ANNIHILATION_MH = 227518, - SPELL_DH_ANNIHILATION_OH = 201428, - SPELL_DH_AWAKEN_THE_DEMON_WITHIN_CD = 207128, - SPELL_DH_BLUR = 212800, - SPELL_DH_BLUR_TRIGGER = 198589, - SPELL_DH_BURNING_ALIVE = 207739, - SPELL_DH_BURNING_ALIVE_TARGET_SELECTOR = 207760, - SPELL_DH_CHAOS_NOVA = 179057, - SPELL_DH_CHAOS_STRIKE = 162794, - SPELL_DH_CHAOS_STRIKE_ENERGIZE = 193840, - SPELL_DH_CHAOS_STRIKE_MH = 222031, - SPELL_DH_CHAOS_STRIKE_OH = 199547, - SPELL_DH_CONSUME_SOUL_HAVOC = 228542, - SPELL_DH_CONSUME_SOUL_HAVOC_DEMON = 228556, - SPELL_DH_CONSUME_SOUL_HAVOC_SHATTERED = 228540, - SPELL_DH_CONSUME_SOUL_HEAL = 203794, - SPELL_DH_CONSUME_SOUL_VENGEANCE = 208014, - SPELL_DH_CONSUME_SOUL_VENGEANCE_DEMON = 210050, - SPELL_DH_CONSUME_SOUL_VENGEANCE_SHATTERED = 210047, - SPELL_DH_DARKNESS_ABSORB = 209426, - SPELL_DH_DEMON_BLADES_DMG = 203796, - SPELL_DH_DEMON_SPIKES = 203819, - SPELL_DH_DEMON_SPIKES_TRIGGER = 203720, - SPELL_DH_DEMONIC = 213410, - SPELL_DH_DEMONIC_ORIGINS = 235893, - SPELL_DH_DEMONIC_ORIGINS_BUFF = 235894, - SPELL_DH_DEMONIC_TRAMPLE_DMG = 208645, - SPELL_DH_DEMONIC_TRAMPLE_STUN = 213491, - SPELL_DH_DEMONS_BITE = 162243, - SPELL_DH_EYE_BEAM = 198013, - SPELL_DH_EYE_BEAM_DMG = 198030, - SPELL_DH_EYE_OF_LEOTHERAS_DMG = 206650, - SPELL_DH_FEAST_OF_SOULS = 207697, - SPELL_DH_FEAST_OF_SOULS_PERIODIC_HEAL = 207693, - SPELL_DH_FEED_THE_DEMON = 218612, - SPELL_DH_FEL_BARRAGE = 211053, - SPELL_DH_FEL_BARRAGE_DMG = 211052, - SPELL_DH_FEL_BARRAGE_PROC = 222703, - SPELL_DH_FEL_DEVASTATION = 212084, - SPELL_DH_FEL_DEVASTATION_DMG = 212105, - SPELL_DH_FEL_DEVASTATION_HEAL = 212106, - SPELL_DH_FEL_RUSH = 195072, - SPELL_DH_FEL_RUSH_DMG = 192611, - SPELL_DH_FEL_RUSH_GROUND = 197922, - SPELL_DH_FEL_RUSH_WATER_AIR = 197923, - SPELL_DH_FELBLADE = 232893, - SPELL_DH_FELBLADE_CHARGE = 213241, - SPELL_DH_FELBLADE_DMG = 213243, - SPELL_DH_FELBLADE_PROC = 203557, - SPELL_DH_FELBLADE_PROC_VISUAL = 204497, - SPELL_DH_FELBLADE_PROC1 = 236167, - SPELL_DH_FIERY_BRAND = 204021, - SPELL_DH_FIERY_BRAND_DMG_REDUCTION_DEBUFF = 207744, - SPELL_DH_FIERY_BRAND_DOT = 207771, - SPELL_DH_FIRST_BLOOD = 206416, - SPELL_DH_FLAME_CRASH = 227322, - SPELL_DH_FRAILTY = 224509, - SPELL_DH_GLIDE = 131347, - SPELL_DH_GLIDE_DURATION = 197154, - SPELL_DH_GLIDE_KNOCKBACK = 196353, - SPELL_DH_HAVOC_MASTERY = 185164, - SPELL_DH_ILLIDANS_GRASP = 205630, - SPELL_DH_ILLIDANS_GRASP_DAMAGE = 208618, - SPELL_DH_ILLIDANS_GRASP_JUMP_DEST = 208175, - SPELL_DH_INFERNAL_STRIKE_CAST = 189110, - SPELL_DH_INFERNAL_STRIKE_IMPACT_DAMAGE = 189112, - SPELL_DH_INFERNAL_STRIKE_JUMP = 189111, - SPELL_DH_JAGGED_SPIKES = 205627, - SPELL_DH_JAGGED_SPIKES_DMG = 208790, - SPELL_DH_JAGGED_SPIKES_PROC = 208796, - SPELL_DH_MANA_RIFT_DMG_POWER_BURN = 235904, - SPELL_DH_METAMORPHOSIS = 191428, - SPELL_DH_METAMORPHOSIS_DUMMY = 191427, - SPELL_DH_METAMORPHOSIS_IMPACT_DAMAGE = 200166, - SPELL_DH_METAMORPHOSIS_RESET = 320645, - SPELL_DH_METAMORPHOSIS_TRANSFORM = 162264, - SPELL_DH_METAMORPHOSIS_VENGEANCE_TRANSFORM = 187827, - SPELL_DH_MOMENTUM = 208628, - SPELL_DH_NEMESIS_ABERRATIONS = 208607, - SPELL_DH_NEMESIS_BEASTS = 208608, - SPELL_DH_NEMESIS_CRITTERS = 208609, - SPELL_DH_NEMESIS_DEMONS = 208608, - SPELL_DH_NEMESIS_DRAGONKIN = 208610, - SPELL_DH_NEMESIS_ELEMENTALS = 208611, - SPELL_DH_NEMESIS_GIANTS = 208612, - SPELL_DH_NEMESIS_HUMANOIDS = 208605, - SPELL_DH_NEMESIS_MECHANICALS = 208613, - SPELL_DH_NEMESIS_UNDEAD = 208614, - SPELL_DH_RAIN_FROM_ABOVE = 206803, - SPELL_DH_RAIN_OF_CHAOS = 205628, - SPELL_DH_RAIN_OF_CHAOS_IMPACT = 232538, - SPELL_DH_RAZOR_SPIKES = 210003, - SPELL_DH_SEVER = 235964, - SPELL_DH_SHATTER_SOUL = 209980, - SPELL_DH_SHATTER_SOUL_1 = 209981, - SPELL_DH_SHATTER_SOUL_2 = 210038, - SPELL_DH_SHATTERED_SOUL = 226258, - SPELL_DH_SHATTERED_SOUL_LESSER_SOUL_FRAGMENT_1 = 228533, - SPELL_DH_SHATTERED_SOUL_LESSER_SOUL_FRAGMENT_2 = 237867, - SPELL_DH_SHEAR = 203782, - SPELL_DH_SIGIL_OF_CHAINS_AREA_SELECTOR = 204834, - SPELL_DH_SIGIL_OF_CHAINS_GRIP = 208674, - SPELL_DH_SIGIL_OF_CHAINS_JUMP = 208674, - SPELL_DH_SIGIL_OF_CHAINS_SLOW = 204843, - SPELL_DH_SIGIL_OF_CHAINS_SNARE = 204843, - SPELL_DH_SIGIL_OF_CHAINS_TARGET_SELECT = 204834, - SPELL_DH_SIGIL_OF_CHAINS_VISUAL = 208673, - SPELL_DH_SIGIL_OF_FLAME_AOE = 204598, - SPELL_DH_SIGIL_OF_FLAME_DAMAGE = 204598, - SPELL_DH_SIGIL_OF_FLAME_FLAME_CRASH = 228973, - SPELL_DH_SIGIL_OF_MISERY = 207685, - SPELL_DH_SIGIL_OF_MISERY_AOE = 207685, - SPELL_DH_SIGIL_OF_SILENCE = 204490, - SPELL_DH_SIGIL_OF_SILENCE_AOE = 204490, - SPELL_DH_SOUL_BARRIER = 227225, - SPELL_DH_SOUL_CLEAVE = 228477, - SPELL_DH_SOUL_CLEAVE_DMG = 228478, - SPELL_DH_SOUL_FRAGMENT_COUNTER = 203981, - SPELL_DH_SOUL_FURNACE_DAMAGE_BUFF = 391172, - SPELL_DH_SOUL_RENDING = 204909, - SPELL_DH_SPIRIT_BOMB_DAMAGE = 218677, - SPELL_DH_SPIRIT_BOMB_HEAL = 227255, - SPELL_DH_SPIRIT_BOMB_VISUAL = 218678, - SPELL_DH_THROW_GLAIVE = 185123, - SPELL_DH_UNCONTAINED_FEL = 209261, - SPELL_DH_VENGEFUL_RETREAT = 198813, - SPELL_DH_VENGEFUL_RETREAT_TRIGGER = 198793, -}; - -// 197125 - Chaos Strike -class spell_dh_chaos_strike : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_CHAOS_STRIKE_ENERGIZE }); - } - - void HandleEffectProc(AuraEffect* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - CastSpellExtraArgs args(TRIGGERED_FULL_MASK); - args.AddSpellMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount()); - args.SetTriggeringAura(aurEff); - GetTarget()->CastSpell(GetTarget(), SPELL_DH_CHAOS_STRIKE_ENERGIZE, args); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dh_chaos_strike::HandleEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 206416 - First Blood -class spell_dh_first_blood : public AuraScript -{ -public: - ObjectGuid const& GetFirstTarget() const { return _firstTargetGUID; } - void SetFirstTarget(ObjectGuid const& targetGuid) { _firstTargetGUID = targetGuid; } - -private: - void Register() override - { - } - -private: - ObjectGuid _firstTargetGUID; -}; - -// 188499 - Blade Dance -// 210152 - Death Sweep -class spell_dh_blade_dance : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_FIRST_BLOOD }); - } - - void DecideFirstTarget(std::list<WorldObject*>& targetList) - { - if (targetList.empty()) - return; - - Aura* aura = GetCaster()->GetAura(SPELL_DH_FIRST_BLOOD); - if (!aura) - return; - - ObjectGuid firstTargetGUID = ObjectGuid::Empty; - ObjectGuid selectedTarget = GetCaster()->GetTarget(); - - // Prefer the selected target if he is one of the enemies - if (targetList.size() > 1 && !selectedTarget.IsEmpty()) - { - auto it = std::find_if(targetList.begin(), targetList.end(), [selectedTarget](WorldObject* object) - { - return object->GetGUID() == selectedTarget; - }); - if (it != targetList.end()) - firstTargetGUID = (*it)->GetGUID(); - } - - if (firstTargetGUID.IsEmpty()) - firstTargetGUID = targetList.front()->GetGUID(); - - if (spell_dh_first_blood* script = aura->GetScript<spell_dh_first_blood>()) - script->SetFirstTarget(firstTargetGUID); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dh_blade_dance::DecideFirstTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - } -}; - -// 199552 - Blade Dance -// 200685 - Blade Dance -// 210153 - Death Sweep -// 210155 - Death Sweep -class spell_dh_blade_dance_damage : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_FIRST_BLOOD }); - } - - void HandleHitTarget() - { - int32 damage = GetHitDamage(); - - if (AuraEffect* aurEff = GetCaster()->GetAuraEffect(SPELL_DH_FIRST_BLOOD, EFFECT_0)) - if (spell_dh_first_blood* script = aurEff->GetBase()->GetScript<spell_dh_first_blood>()) - if (GetHitUnit()->GetGUID() == script->GetFirstTarget()) - AddPct(damage, aurEff->GetAmount()); - - SetHitDamage(damage); - } - - void Register() override - { - OnHit += SpellHitFn(spell_dh_blade_dance_damage::HandleHitTarget); - } -}; - -// 204596 - Sigil of Flame -// 207684 - Sigil of Misery -// 202137 - Sigil of Silence -template<uint32 TriggerSpellId> -class areatrigger_dh_generic_sigil : public AreaTriggerEntityScript -{ -public: - areatrigger_dh_generic_sigil(char const* script) : AreaTriggerEntityScript(script) { } - - template<uint32 Trigger> - struct areatrigger_dh_generic_sigilAI : AreaTriggerAI - { - areatrigger_dh_generic_sigilAI(AreaTrigger* at) : AreaTriggerAI(at) { } - - void OnRemove() override - { - if (Unit* caster = at->GetCaster()) - caster->CastSpell(at->GetPosition(), Trigger); - } - }; - - AreaTriggerAI* GetAI(AreaTrigger* at) const override - { - return new areatrigger_dh_generic_sigilAI<TriggerSpellId>(at); - } -}; - -// 208673 - Sigil of Chains -class spell_dh_sigil_of_chains : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_SIGIL_OF_CHAINS_SLOW, SPELL_DH_SIGIL_OF_CHAINS_GRIP }); - } - - void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) - { - if (WorldLocation const* loc = GetExplTargetDest()) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_DH_SIGIL_OF_CHAINS_SLOW, true); - GetHitUnit()->CastSpell(loc->GetPosition(), SPELL_DH_SIGIL_OF_CHAINS_GRIP, true); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_dh_sigil_of_chains::HandleEffectHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 202138 - Sigil of Chains -struct areatrigger_dh_sigil_of_chains : AreaTriggerAI -{ - areatrigger_dh_sigil_of_chains(AreaTrigger* at) : AreaTriggerAI(at) { } - - void OnRemove() override - { - if (Unit* caster = at->GetCaster()) - { - caster->CastSpell(at->GetPosition(), SPELL_DH_SIGIL_OF_CHAINS_VISUAL); - caster->CastSpell(at->GetPosition(), SPELL_DH_SIGIL_OF_CHAINS_TARGET_SELECT); - } - } -}; - -// 131347 - Glide -class spell_dh_glide : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_GLIDE_KNOCKBACK, SPELL_DH_GLIDE_DURATION, SPELL_DH_VENGEFUL_RETREAT_TRIGGER, SPELL_DH_FEL_RUSH }); - } - - SpellCastResult CheckCast() - { - Unit* caster = GetCaster(); - if (caster->IsMounted() || caster->GetVehicleBase()) - return SPELL_FAILED_DONT_REPORT; - - if (!caster->IsFalling()) - return SPELL_FAILED_NOT_ON_GROUND; - - return SPELL_CAST_OK; - } - - void HandleCast() - { - Player* caster = GetCaster()->ToPlayer(); - if (!caster) - return; - - caster->CastSpell(caster, SPELL_DH_GLIDE_KNOCKBACK, true); - caster->CastSpell(caster, SPELL_DH_GLIDE_DURATION, true); - - caster->GetSpellHistory()->StartCooldown(sSpellMgr->AssertSpellInfo(SPELL_DH_VENGEFUL_RETREAT_TRIGGER, GetCastDifficulty()), 0, nullptr, false, 250ms); - caster->GetSpellHistory()->StartCooldown(sSpellMgr->AssertSpellInfo(SPELL_DH_FEL_RUSH, GetCastDifficulty()), 0, nullptr, false, 250ms); - } - - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_dh_glide::CheckCast); - BeforeCast += SpellCastFn(spell_dh_glide::HandleCast); - } -}; - -// 131347 - Glide -class spell_dh_glide_AuraScript : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_GLIDE_DURATION }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveAura(SPELL_DH_GLIDE_DURATION); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_dh_glide_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_FEATHER_FALL, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 197154 - Glide -class spell_dh_glide_timer : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_GLIDE }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveAura(SPELL_DH_GLIDE); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_dh_glide_timer::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 391166 - Soul Furnace -class spell_dh_soul_furnace : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DH_SOUL_FURNACE_DAMAGE_BUFF }); - } - - void CalculateSpellMod(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetStackAmount() == GetAura()->CalcMaxStackAmount()) - { - GetTarget()->CastSpell(GetTarget(), SPELL_DH_SOUL_FURNACE_DAMAGE_BUFF, true); - Remove(); - } - } - - void Register() override - { - AfterEffectApply += AuraEffectApplyFn(spell_dh_soul_furnace::CalculateSpellMod, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - } -}; - -// 339424 - Soul Furnace -class spell_dh_soul_furnace_conduit : public AuraScript -{ - void CalculateSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod) - { - if (aurEff->GetAmount() == 10) - { - if (!spellMod) - { - spellMod = new SpellModifierByClassMask(GetAura()); - spellMod->op = SpellModOp::HealingAndDamage; - spellMod->type = SPELLMOD_PCT; - spellMod->spellId = GetId(); - static_cast<SpellModifierByClassMask*>(spellMod)->mask = flag128(0x80000000); - static_cast<SpellModifierByClassMask*>(spellMod)->value = GetEffect(EFFECT_1)->GetAmount() + 1; - } - } - } - - void Register() override - { - DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_dh_soul_furnace_conduit::CalculateSpellMod, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -void AddSC_demon_hunter_spell_scripts() -{ - RegisterSpellScript(spell_dh_chaos_strike); - - new areatrigger_dh_generic_sigil<SPELL_DH_SIGIL_OF_SILENCE_AOE>("areatrigger_dh_sigil_of_silence"); - new areatrigger_dh_generic_sigil<SPELL_DH_SIGIL_OF_MISERY_AOE>("areatrigger_dh_sigil_of_misery"); - new areatrigger_dh_generic_sigil<SPELL_DH_SIGIL_OF_FLAME_AOE>("areatrigger_dh_sigil_of_flame"); - RegisterAreaTriggerAI(areatrigger_dh_sigil_of_chains); - RegisterSpellScript(spell_dh_sigil_of_chains); - - // Havoc - - /* Spells & Auras */ - - /* Auras */ - - RegisterSpellScript(spell_dh_first_blood); - - /* AreaTrigger */ - - /* Spells */ - - RegisterSpellScript(spell_dh_blade_dance); - RegisterSpellScript(spell_dh_blade_dance_damage); - - // Vengeance - RegisterSpellScript(spell_dh_soul_furnace); - - // Vengeance & Havoc - - RegisterSpellAndAuraScriptPair(spell_dh_glide, spell_dh_glide_AuraScript); - RegisterSpellScript(spell_dh_glide_timer); - - // Soulbind conduits - RegisterSpellScript(spell_dh_soul_furnace_conduit); -} diff --git a/src/server/scripts/Spells/spell_evoker.cpp b/src/server/scripts/Spells/spell_evoker.cpp deleted file mode 100644 index 8004f4115e7..00000000000 --- a/src/server/scripts/Spells/spell_evoker.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -/* - * Scripts for spells with SPELLFAMILY_EVOKER and SPELLFAMILY_GENERIC spells used by evoker players. - * Ordered alphabetically using scriptname. - * Scriptnames of files in this file should be prefixed with "spell_evo_". - */ - -#include "Containers.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "Spell.h" -#include "SpellAuraEffects.h" -#include "SpellHistory.h" -#include "SpellMgr.h" -#include "SpellScript.h" - -enum EvokerSpells -{ - SPELL_EVOKER_ENERGIZING_FLAME = 400006, - SPELL_EVOKER_GLIDE_KNOCKBACK = 358736, - SPELL_EVOKER_HOVER = 358267, - SPELL_EVOKER_LIVING_FLAME = 361469, - SPELL_EVOKER_LIVING_FLAME_DAMAGE = 361500, - SPELL_EVOKER_LIVING_FLAME_HEAL = 361509, - SPELL_EVOKER_PERMEATING_CHILL_TALENT = 370897, - SPELL_EVOKER_PYRE_DAMAGE = 357212, - SPELL_EVOKER_SOAR_RACIAL = 369536 -}; - -enum EvokerSpellLabels -{ - SPELL_LABEL_EVOKER_BLUE = 1465, -}; - -// 362969 - Azure Strike (blue) -class spell_evo_azure_strike : public SpellScript -{ - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove(GetExplTargetUnit()); - Trinity::Containers::RandomResize(targets, GetEffectInfo(EFFECT_0).CalcValue(GetCaster()) - 1); - targets.push_back(GetExplTargetUnit()); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_evo_azure_strike::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); - } -}; - -// 370455 - Charged Blast -class spell_evo_charged_blast : public AuraScript -{ - bool CheckProc(ProcEventInfo& procInfo) - { - return procInfo.GetSpellInfo() && procInfo.GetSpellInfo()->HasLabel(SPELL_LABEL_EVOKER_BLUE); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_evo_charged_blast::CheckProc); - } -}; - -// 358733 - Glide (Racial) -class spell_evo_glide : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_EVOKER_GLIDE_KNOCKBACK, SPELL_EVOKER_HOVER, SPELL_EVOKER_SOAR_RACIAL }); - } - - SpellCastResult CheckCast() - { - Unit* caster = GetCaster(); - - if (!caster->IsFalling()) - return SPELL_FAILED_NOT_ON_GROUND; - - return SPELL_CAST_OK; - } - - void HandleCast() - { - Player* caster = GetCaster()->ToPlayer(); - if (!caster) - return; - - caster->CastSpell(caster, SPELL_EVOKER_GLIDE_KNOCKBACK, true); - - caster->GetSpellHistory()->StartCooldown(sSpellMgr->AssertSpellInfo(SPELL_EVOKER_HOVER, GetCastDifficulty()), 0, nullptr, false, 250ms); - caster->GetSpellHistory()->StartCooldown(sSpellMgr->AssertSpellInfo(SPELL_EVOKER_SOAR_RACIAL, GetCastDifficulty()), 0, nullptr, false, 250ms); - } - - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_evo_glide::CheckCast); - OnCast += SpellCastFn(spell_evo_glide::HandleCast); - } -}; - -// 361469 - Living Flame (Red) -class spell_evo_living_flame : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo ({ SPELL_EVOKER_LIVING_FLAME_DAMAGE, SPELL_EVOKER_LIVING_FLAME_HEAL, SPELL_EVOKER_ENERGIZING_FLAME }); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - Unit* hitUnit = GetHitUnit(); - if (caster->IsFriendlyTo(hitUnit)) - caster->CastSpell(hitUnit, SPELL_EVOKER_LIVING_FLAME_HEAL, true); - else - caster->CastSpell(hitUnit, SPELL_EVOKER_LIVING_FLAME_DAMAGE, true); - } - - void HandleLaunchTarget(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (caster->IsFriendlyTo(GetHitUnit())) - return; - - if (AuraEffect* auraEffect = caster->GetAuraEffect(SPELL_EVOKER_ENERGIZING_FLAME, EFFECT_0)) - { - int32 manaCost = GetSpell()->GetPowerTypeCostAmount(POWER_MANA).value_or(0); - if (manaCost != 0) - GetCaster()->ModifyPower(POWER_MANA, CalculatePct(manaCost, auraEffect->GetAmount())); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_evo_living_flame::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - OnEffectLaunchTarget += SpellEffectFn(spell_evo_living_flame::HandleLaunchTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 381773 - Permeating Chill -class spell_evo_permeating_chill : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_EVOKER_PERMEATING_CHILL_TALENT }); - } - - bool CheckProc(ProcEventInfo& procInfo) - { - SpellInfo const* spellInfo = procInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - if (!spellInfo->HasLabel(SPELL_LABEL_EVOKER_BLUE)) - return false; - - if (!procInfo.GetActor()->HasAura(SPELL_EVOKER_PERMEATING_CHILL_TALENT)) - if (!spellInfo->IsAffected(SPELLFAMILY_EVOKER, { 0x40, 0, 0, 0 })) // disintegrate - return false; - - return true; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_evo_permeating_chill::CheckProc); - } -}; - -// 393568 - Pyre -class spell_evo_pyre : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo ({ SPELL_EVOKER_PYRE_DAMAGE }); - } - - void HandleDamage(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit()->GetPosition(), SPELL_EVOKER_PYRE_DAMAGE, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_evo_pyre::HandleDamage, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -void AddSC_evoker_spell_scripts() -{ - RegisterSpellScript(spell_evo_azure_strike); - RegisterSpellScript(spell_evo_charged_blast); - RegisterSpellScript(spell_evo_glide); - RegisterSpellScript(spell_evo_living_flame); - RegisterSpellScript(spell_evo_permeating_chill); - RegisterSpellScript(spell_evo_pyre); -} diff --git a/src/server/scripts/Spells/spell_monk.cpp b/src/server/scripts/Spells/spell_monk.cpp deleted file mode 100644 index a3c56b8cb2a..00000000000 --- a/src/server/scripts/Spells/spell_monk.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -/* - * Scripts for spells with SPELLFAMILY_MONK and SPELLFAMILY_GENERIC spells used by monk players. - * Scriptnames of files in this file should be prefixed with "spell_monk_". - */ - -#include "ScriptMgr.h" -#include "DB2Stores.h" -#include "Player.h" -#include "Spell.h" -#include "SpellAuraEffects.h" -#include "SpellInfo.h" -#include "SpellMgr.h" -#include "SpellScript.h" - -enum MonkSpells -{ - SPELL_MONK_CALMING_COALESCENCE = 388220, - SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHANNEL = 117952, - SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHI_PROC = 123333, - SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK = 117962, - SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK_CD = 117953, - SPELL_MONK_POWER_STRIKE_PROC = 129914, - SPELL_MONK_POWER_STRIKE_ENERGIZE = 121283, - SPELL_MONK_PROVOKE_SINGLE_TARGET = 116189, - SPELL_MONK_PROVOKE_AOE = 118635, - SPELL_MONK_NO_FEATHER_FALL = 79636, - SPELL_MONK_OPEN_PALM_STRIKES_TALENT = 392970, - SPELL_MONK_ROLL_BACKWARD = 109131, - SPELL_MONK_ROLL_FORWARD = 107427, - SPELL_MONK_SOOTHING_MIST = 115175, - SPELL_MONK_STANCE_OF_THE_SPIRITED_CRANE = 154436, - SPELL_MONK_STAGGER_DAMAGE_AURA = 124255, - SPELL_MONK_STAGGER_HEAVY = 124273, - SPELL_MONK_STAGGER_LIGHT = 124275, - SPELL_MONK_STAGGER_MODERATE = 124274, - SPELL_MONK_SURGING_MIST_HEAL = 116995, -}; - -// 117952 - Crackling Jade Lightning -class spell_monk_crackling_jade_lightning : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_MONK_STANCE_OF_THE_SPIRITED_CRANE, - SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHI_PROC - }); - } - - void OnTick(AuraEffect const* /*aurEff*/) - { - if (Unit* caster = GetCaster()) - if (caster->HasAura(SPELL_MONK_STANCE_OF_THE_SPIRITED_CRANE)) - caster->CastSpell(caster, SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHI_PROC, TRIGGERED_FULL_MASK); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_monk_crackling_jade_lightning::OnTick, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); - } -}; - -// 117959 - Crackling Jade Lightning -class spell_monk_crackling_jade_lightning_knockback_proc_aura : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK, - SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK_CD - }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (GetTarget()->HasAura(SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK_CD)) - return false; - - if (eventInfo.GetActor()->HasAura(SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHANNEL, GetTarget()->GetGUID())) - return false; - - Spell* currentChanneledSpell = GetTarget()->GetCurrentSpell(CURRENT_CHANNELED_SPELL); - if (!currentChanneledSpell || currentChanneledSpell->GetSpellInfo()->Id != SPELL_MONK_CRACKLING_JADE_LIGHTNING_CHANNEL) - return false; - - return true; - } - - void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& eventInfo) - { - GetTarget()->CastSpell(eventInfo.GetActor(), SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK, TRIGGERED_FULL_MASK); - GetTarget()->CastSpell(GetTarget(), SPELL_MONK_CRACKLING_JADE_LIGHTNING_KNOCKBACK_CD, TRIGGERED_FULL_MASK); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_monk_crackling_jade_lightning_knockback_proc_aura::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_monk_crackling_jade_lightning_knockback_proc_aura::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 116849 - Life Cocoon -class spell_monk_life_cocoon : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MONK_CALMING_COALESCENCE }); - } - - void CalculateAbsorb(SpellEffIndex /*effIndex*/) - { - int32 absorb = GetCaster()->CountPctFromMaxHealth(GetEffectValue()); - //if (Player* player = GetCaster()->ToPlayer()) - // AddPct(absorb, player->GetRatingBonusValue(CR_VERSATILITY_HEALING_DONE)); - - if (AuraEffect* calmingCoalescence = GetCaster()->GetAuraEffect(SPELL_MONK_CALMING_COALESCENCE, EFFECT_0, GetCaster()->GetGUID())) - { - AddPct(absorb, calmingCoalescence->GetAmount()); - calmingCoalescence->GetBase()->Remove(); - } - - GetSpell()->SetSpellValue(SPELLVALUE_BASE_POINT0, absorb); - } - - void Register() override - { - OnEffectLaunch += SpellEffectFn(spell_monk_life_cocoon::CalculateAbsorb, EFFECT_2, SPELL_EFFECT_DUMMY); - } -}; - -// 392972 - Open Palm Strikes -class spell_monk_open_palm_strikes : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellEffect({ { SPELL_MONK_OPEN_PALM_STRIKES_TALENT, EFFECT_1} }); - } - - bool CheckProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*procInfo*/) - { - AuraEffect const* talent = GetTarget()->GetAuraEffect(SPELL_MONK_OPEN_PALM_STRIKES_TALENT, EFFECT_1); - return talent && roll_chance_i(talent->GetAmount()); - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_monk_open_palm_strikes::CheckProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 121817 - Power Strike -class spell_monk_power_strike_periodic : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MONK_POWER_STRIKE_PROC }); - } - - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - GetTarget()->CastSpell(GetTarget(), SPELL_MONK_POWER_STRIKE_PROC, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_monk_power_strike_periodic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -// 129914 - Power Strike Proc -class spell_monk_power_strike_proc : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MONK_POWER_STRIKE_ENERGIZE }); - } - - void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - GetTarget()->CastSpell(GetTarget(), SPELL_MONK_POWER_STRIKE_ENERGIZE, true); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_monk_power_strike_proc::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 115546 - Provoke -class spell_monk_provoke : public SpellScript -{ - static uint32 const BlackOxStatusEntry = 61146; - - bool Validate(SpellInfo const* spellInfo) override - { - if (!(spellInfo->GetExplicitTargetMask() & TARGET_FLAG_UNIT_MASK)) // ensure GetExplTargetUnit() will return something meaningful during CheckCast - return false; - return ValidateSpellInfo( - { - SPELL_MONK_PROVOKE_SINGLE_TARGET, - SPELL_MONK_PROVOKE_AOE - }); - } - - SpellCastResult CheckExplicitTarget() - { - if (GetExplTargetUnit()->GetEntry() != BlackOxStatusEntry) - { - SpellInfo const* singleTarget = sSpellMgr->AssertSpellInfo(SPELL_MONK_PROVOKE_SINGLE_TARGET, GetCastDifficulty()); - SpellCastResult singleTargetExplicitResult = singleTarget->CheckExplicitTarget(GetCaster(), GetExplTargetUnit()); - if (singleTargetExplicitResult != SPELL_CAST_OK) - return singleTargetExplicitResult; - } - else if (GetExplTargetUnit()->GetOwnerGUID() != GetCaster()->GetGUID()) - return SPELL_FAILED_BAD_TARGETS; - - return SPELL_CAST_OK; - } - - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (GetHitUnit()->GetEntry() != BlackOxStatusEntry) - GetCaster()->CastSpell(GetHitUnit(), SPELL_MONK_PROVOKE_SINGLE_TARGET, true); - else - GetCaster()->CastSpell(GetHitUnit(), SPELL_MONK_PROVOKE_AOE, true); - } - - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_monk_provoke::CheckExplicitTarget); - OnEffectHitTarget += SpellEffectFn(spell_monk_provoke::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 109132 - Roll -class spell_monk_roll : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MONK_ROLL_BACKWARD, SPELL_MONK_ROLL_FORWARD, SPELL_MONK_NO_FEATHER_FALL }); - } - - SpellCastResult CheckCast() - { - if (GetCaster()->HasUnitState(UNIT_STATE_ROOT)) - return SPELL_FAILED_ROOTED; - return SPELL_CAST_OK; - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetCaster(), GetCaster()->HasUnitMovementFlag(MOVEMENTFLAG_BACKWARD) ? SPELL_MONK_ROLL_BACKWARD : SPELL_MONK_ROLL_FORWARD, - TRIGGERED_IGNORE_CAST_IN_PROGRESS); - GetCaster()->CastSpell(GetCaster(), SPELL_MONK_NO_FEATHER_FALL, true); - } - - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_monk_roll::CheckCast); - OnEffectHitTarget += SpellEffectFn(spell_monk_roll::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 107427 - Roll -// 109131 - Roll (backward) -class spell_monk_roll_aura : public AuraScript -{ - void CalcMovementAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - amount += 100; - } - - void CalcImmunityAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) - { - amount -= 100; - } - - void ChangeRunBackSpeed(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->SetSpeed(MOVE_RUN_BACK, GetTarget()->GetSpeed(MOVE_RUN)); - } - - void RestoreRunBackSpeed(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->UpdateSpeed(MOVE_RUN_BACK); - } - - void Register() override - { - // Values need manual correction - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_monk_roll_aura::CalcMovementAmount, EFFECT_0, SPELL_AURA_MOD_SPEED_NO_CONTROL); - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_monk_roll_aura::CalcMovementAmount, EFFECT_2, SPELL_AURA_MOD_MINIMUM_SPEED); - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_monk_roll_aura::CalcImmunityAmount, EFFECT_5, SPELL_AURA_MECHANIC_IMMUNITY); - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_monk_roll_aura::CalcImmunityAmount, EFFECT_6, SPELL_AURA_MECHANIC_IMMUNITY); - - // This is a special aura that sets backward run speed equal to forward speed - AfterEffectApply += AuraEffectApplyFn(spell_monk_roll_aura::ChangeRunBackSpeed, EFFECT_4, SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectApplyFn(spell_monk_roll_aura::RestoreRunBackSpeed, EFFECT_4, SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED, AURA_EFFECT_HANDLE_REAL); - } -}; - -// Utility for stagger scripts -Aura* FindExistingStaggerEffect(Unit* unit) -{ - if (Aura* auraLight = unit->GetAura(SPELL_MONK_STAGGER_LIGHT)) - return auraLight; - - if (Aura* auraModerate = unit->GetAura(SPELL_MONK_STAGGER_MODERATE)) - return auraModerate; - - if (Aura* auraHeavy = unit->GetAura(SPELL_MONK_STAGGER_HEAVY)) - return auraHeavy; - - return nullptr; -} - -static constexpr SpellEffIndex AuraStaggerEffectTick = EFFECT_0; -static constexpr SpellEffIndex AuraStaggerEffectTotal = EFFECT_1; - -// 115069 - Stagger -class spell_monk_stagger : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MONK_STAGGER_LIGHT, SPELL_MONK_STAGGER_MODERATE, SPELL_MONK_STAGGER_HEAVY }); - } - - void AbsorbNormal(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) - { - Absorb(dmgInfo, 1.0f); - } - - void AbsorbMagic(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/) - { - AuraEffect const* effect = GetEffect(EFFECT_4); - if (!effect) - return; - - Absorb(dmgInfo, float(effect->GetAmount()) / 100.0f); - } - - void Absorb(DamageInfo& dmgInfo, float multiplier) - { - // Prevent default action (which would remove the aura) - PreventDefaultAction(); - - // make sure damage doesn't come from stagger damage spell SPELL_MONK_STAGGER_DAMAGE_AURA - if (SpellInfo const* dmgSpellInfo = dmgInfo.GetSpellInfo()) - if (dmgSpellInfo->Id == SPELL_MONK_STAGGER_DAMAGE_AURA) - return; - - AuraEffect const* effect = GetEffect(AuraStaggerEffectTick); - if (!effect) - return; - - Unit* target = GetTarget(); - float agility = target->GetStat(STAT_AGILITY); - float base = CalculatePct(agility, float(effect->GetAmount())); - float K = sDB2Manager.EvaluateExpectedStat(ExpectedStatType::ArmorConstant, target->GetLevel(), -2, 0, Classes(target->GetClass()), 0); - - float newAmount = (base / (base + K)); - newAmount *= multiplier; - - // Absorb X percentage of the damage - float absorbAmount = float(dmgInfo.GetDamage()) * newAmount; - if (absorbAmount > 0) - { - dmgInfo.AbsorbDamage(absorbAmount); - - // Cast stagger and make it tick on each tick - AddAndRefreshStagger(absorbAmount); - } - } - - void Register() override - { - OnEffectAbsorb += AuraEffectAbsorbFn(spell_monk_stagger::AbsorbNormal, EFFECT_1); - OnEffectAbsorb += AuraEffectAbsorbFn(spell_monk_stagger::AbsorbMagic, EFFECT_2); - } - -private: - void AddAndRefreshStagger(float amount) - { - Unit* target = GetTarget(); - if (Aura* auraStagger = FindExistingStaggerEffect(target)) - { - AuraEffect* effStaggerRemaining = auraStagger->GetEffect(AuraStaggerEffectTotal); - if (!effStaggerRemaining) - return; - - float newAmount = effStaggerRemaining->GetAmount() + amount; - uint32 spellId = GetStaggerSpellId(target, newAmount); - if (spellId == effStaggerRemaining->GetSpellInfo()->Id) - { - auraStagger->RefreshDuration(); - effStaggerRemaining->ChangeAmount(newAmount, false, true /* reapply */); - } - else - { - // amount changed the stagger type so we need to change the stagger amount (e.g. from medium to light) - GetTarget()->RemoveAura(auraStagger); - AddNewStagger(target, spellId, newAmount); - } - } - else - AddNewStagger(target, GetStaggerSpellId(target, amount), amount); - } - - uint32 GetStaggerSpellId(Unit* unit, float amount) - { - const float StaggerHeavy = 0.6f; - const float StaggerModerate = 0.3f; - - float staggerPct = amount / float(unit->GetMaxHealth()); - return (staggerPct >= StaggerHeavy) ? SPELL_MONK_STAGGER_HEAVY : - (staggerPct >= StaggerModerate) ? SPELL_MONK_STAGGER_MODERATE : - SPELL_MONK_STAGGER_LIGHT; - } - - void AddNewStagger(Unit* unit, uint32 staggerSpellId, float staggerAmount) - { - // We only set the total stagger amount. The amount per tick will be set by the stagger spell script - unit->CastSpell(unit, staggerSpellId, CastSpellExtraArgs(SPELLVALUE_BASE_POINT1, staggerAmount).SetTriggerFlags(TRIGGERED_FULL_MASK)); - } -}; - -// 124255 - Stagger - SPELL_MONK_STAGGER_DAMAGE_AURA -class spell_monk_stagger_damage_aura : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MONK_STAGGER_LIGHT, SPELL_MONK_STAGGER_MODERATE, SPELL_MONK_STAGGER_HEAVY }); - } - - void OnPeriodicDamage(AuraEffect const* aurEff) - { - // Update our light/medium/heavy stagger with the correct stagger amount left - if (Aura* auraStagger = FindExistingStaggerEffect(GetTarget())) - { - if (AuraEffect* auraEff = auraStagger->GetEffect(AuraStaggerEffectTotal)) - { - float total = float(auraEff->GetAmount()); - float tickDamage = float(aurEff->GetAmount()); - auraEff->ChangeAmount(total - tickDamage); - } - } - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_monk_stagger_damage_aura::OnPeriodicDamage, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); - } -}; - -// 124273, 124274, 124275 - Light/Moderate/Heavy Stagger - SPELL_MONK_STAGGER_LIGHT / SPELL_MONK_STAGGER_MODERATE / SPELL_MONK_STAGGER_HEAVY -class spell_monk_stagger_debuff_aura : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MONK_STAGGER_DAMAGE_AURA }) - && ValidateSpellEffect({ { SPELL_MONK_STAGGER_DAMAGE_AURA, EFFECT_0 } }); - } - - bool Load() override - { - _period = float(sSpellMgr->AssertSpellInfo(SPELL_MONK_STAGGER_DAMAGE_AURA, GetCastDifficulty())->GetEffect(EFFECT_0).ApplyAuraPeriod); - return true; - } - - void OnReapply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - // Calculate damage per tick - float total = float(aurEff->GetAmount()); - float perTick = total * _period / float(GetDuration()); // should be same as GetMaxDuration() TODO: verify - - // Set amount on effect for tooltip - AuraEffect* effInfo = GetAura()->GetEffect(AuraStaggerEffectTick); - if (effInfo) - effInfo->ChangeAmount(perTick); - - // Set amount on damage aura (or cast it if needed) - CastOrChangeTickDamage(perTick); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes mode) - { - if (mode != AURA_EFFECT_HANDLE_REAL) - return; - - // Remove damage aura - GetTarget()->RemoveAura(SPELL_MONK_STAGGER_DAMAGE_AURA); - } - - void Register() override - { - AfterEffectApply += AuraEffectRemoveFn(spell_monk_stagger_debuff_aura::OnReapply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); - AfterEffectRemove += AuraEffectRemoveFn(spell_monk_stagger_debuff_aura::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - -private: - float _period = 0.0f; - - void CastOrChangeTickDamage(float tickDamage) - { - Unit* unit = GetTarget(); - Aura* auraDamage = unit->GetAura(SPELL_MONK_STAGGER_DAMAGE_AURA); - if (!auraDamage) - { - unit->CastSpell(unit, SPELL_MONK_STAGGER_DAMAGE_AURA, true); - auraDamage = unit->GetAura(SPELL_MONK_STAGGER_DAMAGE_AURA); - } - - if (auraDamage) - if (AuraEffect* eff = auraDamage->GetEffect(AuraStaggerEffectTick)) - eff->ChangeAmount(tickDamage); - } -}; - -void AddSC_monk_spell_scripts() -{ - RegisterSpellScript(spell_monk_crackling_jade_lightning); - RegisterSpellScript(spell_monk_crackling_jade_lightning_knockback_proc_aura); - RegisterSpellScript(spell_monk_life_cocoon); - RegisterSpellScript(spell_monk_open_palm_strikes); - RegisterSpellScript(spell_monk_power_strike_periodic); - RegisterSpellScript(spell_monk_power_strike_proc); - RegisterSpellScript(spell_monk_provoke); - RegisterSpellScript(spell_monk_roll); - RegisterSpellScript(spell_monk_roll_aura); - RegisterSpellScript(spell_monk_stagger); - RegisterSpellScript(spell_monk_stagger_damage_aura); - RegisterSpellScript(spell_monk_stagger_debuff_aura); -} diff --git a/src/server/scripts/Spells/spell_script_loader.cpp b/src/server/scripts/Spells/spell_script_loader.cpp index 7df1d920846..cbe80bafff2 100644 --- a/src/server/scripts/Spells/spell_script_loader.cpp +++ b/src/server/scripts/Spells/spell_script_loader.cpp @@ -17,13 +17,10 @@ // This is where scripts' loading functions should be declared: void AddSC_deathknight_spell_scripts(); -void AddSC_demon_hunter_spell_scripts(); void AddSC_druid_spell_scripts(); -void AddSC_evoker_spell_scripts(); void AddSC_generic_spell_scripts(); void AddSC_hunter_spell_scripts(); void AddSC_mage_spell_scripts(); -void AddSC_monk_spell_scripts(); void AddSC_paladin_spell_scripts(); void AddSC_priest_spell_scripts(); void AddSC_rogue_spell_scripts(); @@ -32,20 +29,16 @@ void AddSC_warlock_spell_scripts(); void AddSC_warrior_spell_scripts(); void AddSC_quest_spell_scripts(); void AddSC_item_spell_scripts(); -void AddSC_azerite_item_spell_scripts(); // The name of this function should match: // void Add${NameOfDirectory}Scripts() void AddSpellsScripts() { AddSC_deathknight_spell_scripts(); - AddSC_demon_hunter_spell_scripts(); AddSC_druid_spell_scripts(); - AddSC_evoker_spell_scripts(); AddSC_generic_spell_scripts(); AddSC_hunter_spell_scripts(); AddSC_mage_spell_scripts(); - AddSC_monk_spell_scripts(); AddSC_paladin_spell_scripts(); AddSC_priest_spell_scripts(); AddSC_rogue_spell_scripts(); @@ -54,5 +47,4 @@ void AddSpellsScripts() AddSC_warrior_spell_scripts(); AddSC_quest_spell_scripts(); AddSC_item_spell_scripts(); - AddSC_azerite_item_spell_scripts(); } diff --git a/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp b/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp deleted file mode 100644 index 496f2139fe4..00000000000 --- a/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaTrigger.h" -#include "AreaTriggerAI.h" -#include "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "InstanceScript.h" -#include "Map.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellAuraEffects.h" -#include "SpellScript.h" -#include "SpellAuras.h" -#include "SharedDefines.h" -#include "TemporarySummon.h" -#include "underrot.h" - -enum CragmawSpells -{ - // Cragmaw - SPELL_CRAWG_EATING = 279156, - SPELL_POWER_DISPLAY_TANTRUM = 271771, - SPELL_POWER_ENERGIZE_TANTRUM = 271775, - SPELL_CHARGE_SELECTOR = 260292, - SPELL_INDIGESTION = 260793, - SPELL_TANTRUM_INITIAL = 260333, - - // Larva - SPELL_DESTROY_LARVA = 260418, - SPELL_METAMORPHOSIS_2 = 260766, - SPELL_SUMMON_BLOOD_TICK = 260353, - SPELL_SUMMON_BLOOD_TICK_VISUAL = 260496, - - // Blood Tick - SPELL_BLOOD_BURST_DAMAGE = 278637, - SPELL_SERRATED_FANGS = 260455, - - // Fetid Maggot - SPELL_FEIGN_DEATH = 159474 -}; - -enum CragmawEvents -{ - // Cragmaw - EVENT_CHARGE_SELECTOR = 1, - EVENT_INDIGESTION, - EVENT_NORMAL_REQUEUE, - EVENT_CHECK_ENERGY_TANTRUM, - - // Blood Tick - EVENT_SERRATED_FANGS = 1 -}; - -enum CragmawPoints -{ - POINT_TANTRUM_START_RND_MOVEMENT = 0 -}; - -enum CragmawNPC -{ - NPC_FETID_MAGGOT = 130909 -}; - -Position const FetidMaggotSpawn = { 857.864f, 984.981f, 39.231f, 4.68147f }; - -// 131817 - Cragmaw the Infested -struct boss_cragmaw_the_infested : public BossAI -{ - boss_cragmaw_the_infested(Creature* creature) : BossAI(creature, DATA_CRAGMAW_THE_INFESTED) { } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - } - - void JustAppeared() override - { - me->SetPowerType(POWER_ENERGY); - DoCast(SPELL_POWER_DISPLAY_TANTRUM); - - if (instance->GetData(DATA_CRAGMAW_CRAWG_EATING)) - return; - - DoCastSelf(SPELL_CRAWG_EATING); - me->SetEmoteState(EMOTE_STATE_EAT); - if (TempSummon* summon = me->SummonCreature(NPC_FETID_MAGGOT, FetidMaggotSpawn)) - { - _fetidMaggotGuid = summon->GetGUID(); - summon->CastSpell(nullptr, SPELL_FEIGN_DEATH, true); - } - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - summons.DespawnAll(); - _EnterEvadeMode(); - _DespawnAtEvade(); - } - - void ScheduleSpells() - { - events.Reset(); - - if (GetDifficulty() == DIFFICULTY_NORMAL) - events.ScheduleEvent(EVENT_NORMAL_REQUEUE, 45s); - - if (urand(0, 1) == 0) - { - events.ScheduleEvent(EVENT_CHARGE_SELECTOR, 9s); - events.ScheduleEvent(EVENT_INDIGESTION, 20s); - events.ScheduleEvent(EVENT_CHARGE_SELECTOR, 33s); - } - else - { - events.ScheduleEvent(EVENT_INDIGESTION, 9s); - events.ScheduleEvent(EVENT_CHARGE_SELECTOR, 21s); - events.ScheduleEvent(EVENT_CHARGE_SELECTOR, 41s); - } - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); - instance->SetData(DATA_CRAGMAW_CRAWG_EATING, 1); - ScheduleSpells(); - events.ScheduleEvent(EVENT_CHECK_ENERGY_TANTRUM, 500ms); - - if (Creature* fetidMaggot = ObjectAccessor::GetCreature(*me, _fetidMaggotGuid)) - fetidMaggot->DespawnOrUnsummon(); - - if (IsHeroicOrHigher()) - DoCast(SPELL_POWER_ENERGIZE_TANTRUM); - } - - void MovementInform(uint32 /*type*/, uint32 id) override - { - if (id == POINT_TANTRUM_START_RND_MOVEMENT) - me->GetMotionMaster()->MoveRandom(20.0f); - } - - void OnChannelFinished(SpellInfo const* spell) override - { - if (spell->Id == SPELL_TANTRUM_INITIAL) - me->SetReactState(REACT_AGGRESSIVE); - }; - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_CHARGE_SELECTOR: - DoCast(SPELL_CHARGE_SELECTOR); - break; - case EVENT_INDIGESTION: - DoCast(SPELL_INDIGESTION); - break; - case EVENT_NORMAL_REQUEUE: - ScheduleSpells(); - break; - case EVENT_CHECK_ENERGY_TANTRUM: - if (me->GetPower(POWER_ENERGY) >= 100) - { - ScheduleSpells(); - DoCast(SPELL_TANTRUM_INITIAL); - me->SetReactState(REACT_PASSIVE); - me->GetMotionMaster()->MovePoint(POINT_TANTRUM_START_RND_MOVEMENT, me->GetHomePosition()); - } - events.Repeat(500ms); - break; - default: - break; - } - - DoMeleeAttackIfReady(); - } -private: - ObjectGuid _fetidMaggotGuid; -}; - -// 132051 - Blood Tick -struct npc_cragmaw_blood_tick : public ScriptedAI -{ - npc_cragmaw_blood_tick(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - Creature* cragmaw = me->GetInstanceScript()->GetCreature(DATA_CRAGMAW_THE_INFESTED); - if (!cragmaw || !cragmaw->IsAIEnabled()) - return; - - cragmaw->AI()->JustSummoned(me); - DoZoneInCombat(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_SERRATED_FANGS, 1s); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasUnitState(UNIT_STATE_STUNNED)) - return; - - switch (_events.ExecuteEvent()) - { - case EVENT_SERRATED_FANGS: - DoCastVictim(SPELL_SERRATED_FANGS); - _events.ScheduleEvent(EVENT_SERRATED_FANGS, 6s); - break; - default: - break; - } - - DoMeleeAttackIfReady(); - } -private: - EventMap _events; -}; - -// 271775 - Tantrum Energy Bar (periodic) -class spell_cragmaw_power_energize_tantrum : public AuraScript -{ - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - target->SetPower(POWER_ENERGY, target->GetPower(POWER_ENERGY) + 2); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_cragmaw_power_energize_tantrum::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -// 260411 - Summon Larva -class spell_cragmaw_summon_larva : public AuraScript -{ - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Creature* creature = GetTarget()->ToCreature()) - creature->DespawnOrUnsummon(300ms); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_cragmaw_summon_larva::OnRemove, EFFECT_0, SPELL_AURA_AREA_TRIGGER, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 260418 - Destroy Larva -struct at_cragmaw_destroy_larva : AreaTriggerAI -{ - at_cragmaw_destroy_larva(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - at->GetCaster()->CastSpell(nullptr, SPELL_DESTROY_LARVA, true); - } -}; - -// 260416 - Metamorphosis -class spell_cragmaw_larva_metamorphosis : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SUMMON_BLOOD_TICK, - SPELL_SUMMON_BLOOD_TICK_VISUAL, - SPELL_METAMORPHOSIS_2 - }); - } - - void HandlePeriodic(AuraEffect const* aurEff) - { - if (aurEff->GetTickNumber() == aurEff->GetTotalTicks() - 2) - GetTarget()->CastSpell(nullptr, SPELL_METAMORPHOSIS_2, true); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - return; - - Unit* target = GetTarget(); - target->CastSpell(nullptr, SPELL_SUMMON_BLOOD_TICK_VISUAL, true); - target->CastSpell(target->GetPosition(), SPELL_SUMMON_BLOOD_TICK, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_cragmaw_larva_metamorphosis::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - AfterEffectRemove += AuraEffectRemoveFn(spell_cragmaw_larva_metamorphosis::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 278641 - Blood Burst -class spell_cragmaw_blood_burst : public AuraScript -{ - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_BLOOD_BURST_DAMAGE, true); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_cragmaw_blood_burst::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -void AddSC_boss_cragmaw_the_infested() -{ - // Creature - RegisterUnderrotCreatureAI(boss_cragmaw_the_infested); - RegisterUnderrotCreatureAI(npc_cragmaw_blood_tick); - - // Spells - RegisterSpellScript(spell_cragmaw_power_energize_tantrum); - RegisterSpellScript(spell_cragmaw_larva_metamorphosis); - RegisterSpellScript(spell_cragmaw_blood_burst); - RegisterSpellScript(spell_cragmaw_summon_larva); - - // AreaTrigger - RegisterAreaTriggerAI(at_cragmaw_destroy_larva); -} diff --git a/src/server/scripts/Zandalar/Underrot/boss_elder_leaxa.cpp b/src/server/scripts/Zandalar/Underrot/boss_elder_leaxa.cpp deleted file mode 100644 index 531d5b78c75..00000000000 --- a/src/server/scripts/Zandalar/Underrot/boss_elder_leaxa.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "Containers.h" -#include "InstanceScript.h" -#include "MotionMaster.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellScript.h" -#include "SpellAuras.h" -#include "underrot.h" - -enum LeaxaSpells -{ - SPELL_TAINT_OF_GHUUN = 260685, - SPELL_BLOOD_BOLT = 260879, - SPELL_SANGUINE_FEAST = 264747, - SPELL_CREEPING_ROT_SELECTOR = 260889, - SPELL_CREEPING_ROT_SUMMON = 260894, - SPELL_CREEPING_ROT_SPAWN_VISUAL = 260891, - SPELL_CREEPING_ROT_AURA = 261496, - SPELL_CREEPING_ROT_PERIODIC_DMG = 261498, - SPELL_BLOOD_MIRROR_SELECTOR = 264603, - SPELL_BLOOD_MIRROR_MISSILE = 264609 -}; - -enum LeaxaEvents -{ - EVENT_BLOOD_BOLT = 1, - EVENT_CREEPING_ROT, - EVENT_SANGUINE_FEAST, - EVENT_BLOOD_MIRROR -}; - -enum LeaxaTexts -{ - SAY_AGGRO = 0, - SAY_SANGUINE_FEAST = 1, - SAY_ROT_AND_WITHER = 2, - SAY_BLOOD_MIRROR = 3, - SAY_ANNOUNCE_BLOOD_MIRROR = 4, - SAY_DEATH = 5 -}; - -enum LeaxaAnimKits -{ - ANIMKIT_BLOOD_EFFIGY_DEATH = 9798 -}; - -// 131318 - Elder Leaxa -struct boss_elder_leaxa : public BossAI -{ - boss_elder_leaxa(Creature* creature) : BossAI(creature, DATA_ELDER_LEAXA) { } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - - Talk(SAY_DEATH); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - summons.DespawnAll(); - _EnterEvadeMode(); - _DespawnAtEvade(); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); - - Talk(SAY_AGGRO); - me->SetAIAnimKitId(0); - events.ScheduleEvent(EVENT_BLOOD_BOLT, 1s); - if (IsHeroicOrHigher()) - events.ScheduleEvent(EVENT_SANGUINE_FEAST, 8s); - events.ScheduleEvent(EVENT_CREEPING_ROT, 12s); - events.ScheduleEvent(EVENT_BLOOD_MIRROR, 17s); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_BLOOD_BOLT: - DoCastVictim(SPELL_BLOOD_BOLT); - events.ScheduleEvent(EVENT_BLOOD_BOLT, 6s); - break; - case EVENT_SANGUINE_FEAST: - Talk(SAY_SANGUINE_FEAST); - DoCastAOE(SPELL_SANGUINE_FEAST); - events.ScheduleEvent(EVENT_SANGUINE_FEAST, 30s); - break; - case EVENT_CREEPING_ROT: - Talk(SAY_ROT_AND_WITHER); - DoCastAOE(SPELL_CREEPING_ROT_SELECTOR); - events.ScheduleEvent(EVENT_CREEPING_ROT, 16s); - break; - case EVENT_BLOOD_MIRROR: - Talk(SAY_BLOOD_MIRROR); - Talk(SAY_ANNOUNCE_BLOOD_MIRROR); - DoCastSelf(SPELL_BLOOD_MIRROR_SELECTOR); - events.ScheduleEvent(EVENT_BLOOD_MIRROR, 47s); - break; - default: - break; - } - - DoMeleeAttackIfReady(); - } -}; - -// 134701 - Blood Effigy -struct npc_blood_effigy : public ScriptedAI -{ - npc_blood_effigy(Creature* creature) : ScriptedAI(creature) { } - - void JustEngagedWith(Unit* /*who*/) override - { - _events.ScheduleEvent(EVENT_BLOOD_BOLT, 1s); - _events.ScheduleEvent(EVENT_SANGUINE_FEAST, 8s); - _events.ScheduleEvent(EVENT_CREEPING_ROT, 12s); - } - - void JustDied(Unit* /*killer*/) override - { - me->SetAIAnimKitId(ANIMKIT_BLOOD_EFFIGY_DEATH); - me->DespawnOrUnsummon(3s); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (_events.ExecuteEvent()) - { - case EVENT_BLOOD_BOLT: - DoCastVictim(SPELL_BLOOD_BOLT); - _events.ScheduleEvent(EVENT_BLOOD_BOLT, 2s); - break; - case EVENT_SANGUINE_FEAST: - DoCastAOE(SPELL_SANGUINE_FEAST); - _events.ScheduleEvent(EVENT_SANGUINE_FEAST, 30s); - break; - case EVENT_CREEPING_ROT: - DoCastAOE(SPELL_CREEPING_ROT_SELECTOR); - _events.ScheduleEvent(EVENT_CREEPING_ROT, 16s); - break; - default: - break; - } - - DoMeleeAttackIfReady(); - } -private: - EventMap _events; -}; - -// 132398 - Blood Wave Stalker -struct npc_blood_wave_stalker : public ScriptedAI -{ - npc_blood_wave_stalker(Creature* creature) : ScriptedAI(creature) { } - - static constexpr float WALK_DISTANCE = 58.0f; - - void JustAppeared() override - { - DoCast(SPELL_CREEPING_ROT_AURA); - - float angle = me->GetOrientation(); - float destX = me->GetPositionX() + WALK_DISTANCE * std::cos(angle); - float destY = me->GetPositionY() + WALK_DISTANCE * std::sin(angle); - float destZ = me->GetPositionZ(); - Position walkDest(destX, destY, destZ); - - me->GetMotionMaster()->MovePoint(0, walkDest); - } -}; - -// 264747 - Sanguine Feast -class spell_sanguine_feast_selector : public SpellScript -{ - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellEffect({ { spellInfo->Id, EFFECT_0 } }) && ValidateSpellInfo({ uint32(spellInfo->GetEffect(EFFECT_0).CalcValue()) }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - caster->CastSpell(GetHitUnit(), uint32(GetEffectInfo().CalcValue(caster))); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_sanguine_feast_selector::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 260889 - Creeping Rot -class spell_creeping_rot_selector : public SpellScript -{ - static constexpr float SPAWN_DISTANCE = 5.0f; - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - Unit* target = GetHitUnit(); - - // make sure spell is cast towards target and caster looks towards target - caster->SetInFront(target); - caster->SetFacingToObject(target); - - caster->CastSpell(target, SPELL_CREEPING_ROT_SUMMON); - - float angle = caster->GetOrientation(); - float destX = caster->GetPositionX() + SPAWN_DISTANCE * std::cos(angle); - float destY = caster->GetPositionY() + SPAWN_DISTANCE * std::sin(angle); - float destZ = caster->GetPositionZ(); - Position spawnVisualDest(destX, destY, destZ); - caster->CastSpell(spawnVisualDest, SPELL_CREEPING_ROT_SPAWN_VISUAL, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_creeping_rot_selector::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 261496 - Creeping Rot (Aura) -class spell_creeping_rot_aura : public AuraScript -{ - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - return; - - Creature* creature = GetTarget()->ToCreature(); - if (!creature) - return; - - creature->DespawnOrUnsummon(); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_creeping_rot_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - } -}; - -static Position const MirrorSpawnPositions[] = -{ - { 879.79865f, 1222.6233f, 56.47815f }, - { 856.184f, 1232.5435f, 56.52007f }, - { 859.34204f, 1238.0243f, 56.520065f }, - { 857.8333f, 1220.6545f, 56.468567f }, - { 876.17365f, 1240.2848f, 56.409615f }, - { 864.25867f, 1240.5903f, 56.520065f }, - { 863.1042f, 1218.0591f, 56.468765f } -}; - -// 264603 - Blood Mirror -class spell_blood_mirror_selector : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BLOOD_MIRROR_MISSILE }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - Position spawnPos = Trinity::Containers::SelectRandomContainerElement(MirrorSpawnPositions); - GetCaster()->CastSpell(spawnPos, SPELL_BLOOD_MIRROR_MISSILE, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_blood_mirror_selector::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 260879 - Blood Bolt -// 264757 - Sanguine Feast -// 261498 - Creeping Rot -class spell_taint_of_ghuun : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_TAINT_OF_GHUUN }); - } - - void HandleHit() - { - InstanceScript* instance = GetHitUnit()->GetInstanceScript(); - if (!instance) - return; - - Creature* leaxa = instance->GetCreature(DATA_ELDER_LEAXA); - if (!leaxa) - return; - - leaxa->CastSpell(GetHitUnit(), SPELL_TAINT_OF_GHUUN, true); - } - - void Register() override - { - AfterHit += SpellHitFn(spell_taint_of_ghuun::HandleHit); - } -}; - -void AddSC_boss_elder_leaxa() -{ - // Creature - RegisterUnderrotCreatureAI(boss_elder_leaxa); - RegisterUnderrotCreatureAI(npc_blood_wave_stalker); - RegisterUnderrotCreatureAI(npc_blood_effigy); - - // Spells - RegisterSpellScript(spell_sanguine_feast_selector); - RegisterSpellScript(spell_creeping_rot_selector); - RegisterSpellScript(spell_creeping_rot_aura); - RegisterSpellScript(spell_blood_mirror_selector); - RegisterSpellScript(spell_taint_of_ghuun); -} diff --git a/src/server/scripts/Zandalar/Underrot/instance_underrot.cpp b/src/server/scripts/Zandalar/Underrot/instance_underrot.cpp deleted file mode 100644 index 12261013e50..00000000000 --- a/src/server/scripts/Zandalar/Underrot/instance_underrot.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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 "AreaBoundary.h" -#include "InstanceScript.h" -#include "ScriptMgr.h" -#include "underrot.h" - -BossBoundaryData const boundaries = -{ - { DATA_ELDER_LEAXA, new CircleBoundary(Position(869.502014f, 1230.199951f), 58.0f) }, - { DATA_CRAGMAW_THE_INFESTED, new CircleBoundary(Position(852.797974f, 982.133545f), 90.0f) } -}; - -ObjectData const creatureData[] = -{ - { BOSS_ELDER_LEAXA, DATA_ELDER_LEAXA }, - { BOSS_SPORECALLER_ZANCHA, DATA_SPORECALLER_ZANCHA }, - { BOSS_CRAGMAW_THE_INFESTED, DATA_CRAGMAW_THE_INFESTED }, - { BOSS_UNBOUND_ABOMINATION, DATA_UNBOUND_ABOMINATION }, - { 0, 0 } // END -}; - -DoorData const doorData[] = -{ - { GO_WALL_DOOR_SHORTCUT_ENTRANCE, DATA_SPORECALLER_ZANCHA, EncounterDoorBehavior::OpenWhenDone }, - { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } // END -}; - -DungeonEncounterData const encounters[] = -{ - { DATA_ELDER_LEAXA, {{ 2111 }} }, - { DATA_CRAGMAW_THE_INFESTED, {{ 2112 }} }, - { DATA_SPORECALLER_ZANCHA, {{ 2118 }} }, - { DATA_UNBOUND_ABOMINATION, {{ 2123 }} }, -}; - -class instance_underrot : public InstanceMapScript -{ -public: - instance_underrot() : InstanceMapScript(UnderrotScriptName, 1841) { } - - struct instance_underrot_InstanceMapScript : public InstanceScript - { - instance_underrot_InstanceMapScript(InstanceMap* map) : InstanceScript(map) - { - SetHeaders(DataHeader); - SetBossNumber(EncounterCount); - LoadObjectData(creatureData, nullptr); - LoadDoorData(doorData); - LoadBossBoundaries(boundaries); - LoadDungeonEncounterData(encounters); - - _cragmawCrawgEating = false; - } - - uint32 GetData(uint32 dataId) const override - { - switch (dataId) - { - case DATA_CRAGMAW_CRAWG_EATING: - return _cragmawCrawgEating ? 1 : 0; - default: - break; - } - return 0; - } - - void SetData(uint32 dataId, uint32 /*value*/) override - { - switch (dataId) - { - case DATA_CRAGMAW_CRAWG_EATING: - _cragmawCrawgEating = true; - break; - default: - break; - } - } - - private: - bool _cragmawCrawgEating; - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_underrot_InstanceMapScript(map); - } -}; - -void AddSC_instance_underrot() -{ - new instance_underrot(); -} diff --git a/src/server/scripts/Zandalar/Underrot/underrot.h b/src/server/scripts/Zandalar/Underrot/underrot.h deleted file mode 100644 index 77849594584..00000000000 --- a/src/server/scripts/Zandalar/Underrot/underrot.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -#ifndef DEF_UNDERROT_H_ -#define DEF_UNDERROT_H_ - -#include "CreatureAIImpl.h" - -#define DataHeader "Underrot" -#define UnderrotScriptName "instance_underrot" - -uint32 const EncounterCount = 4; - -enum UnderrotDataTypes -{ - // Encounters - DATA_ELDER_LEAXA = 0, - DATA_SPORECALLER_ZANCHA, - DATA_CRAGMAW_THE_INFESTED, - DATA_UNBOUND_ABOMINATION, - - DATA_CRAGMAW_CRAWG_EATING -}; - -enum UnderrotCreatureIds -{ - // Bosses - BOSS_ELDER_LEAXA = 131318, - BOSS_SPORECALLER_ZANCHA = 131383, - BOSS_CRAGMAW_THE_INFESTED = 131817, - BOSS_UNBOUND_ABOMINATION = 133007 -}; - -enum UnderrotGameObjectIds -{ - GO_PYRAMID_DOOR_UNBOUND_ABOMINATION_ENTRANCE = 296385, - GO_WALL_DOOR_SHORTCUT_ENTRANCE = 295356 -}; - -template <class AI, class T> -inline AI* GetUnderrotAI(T* obj) -{ - return GetInstanceAI<AI>(obj, UnderrotScriptName); -} - -#define RegisterUnderrotCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetUnderrotAI) - -#endif diff --git a/src/server/scripts/Zandalar/zandalar_script_loader.cpp b/src/server/scripts/Zandalar/zandalar_script_loader.cpp deleted file mode 100644 index 2822c02be62..00000000000 --- a/src/server/scripts/Zandalar/zandalar_script_loader.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the TrinityCore 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 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/>. - */ - -// This is where scripts' loading functions should be declared: - -// Underrot -void AddSC_instance_underrot(); -void AddSC_boss_elder_leaxa(); -void AddSC_boss_cragmaw_the_infested(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddZandalarScripts() -{ - // Underrot - AddSC_instance_underrot(); - AddSC_boss_elder_leaxa(); - AddSC_boss_cragmaw_the_infested(); -} |
