diff options
51 files changed, 0 insertions, 24341 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 9e574dbdeeb..00000000000 --- a/src/server/scripts/Argus/AntorusTheBurningThrone/boss_garothi_worldbreaker.cpp +++ /dev/null @@ -1,883 +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)) - 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 2d84a644f07..00000000000 --- a/src/server/scripts/BrokenIsles/TrialOfValor/boss_guarm.cpp +++ /dev/null @@ -1,821 +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; - } - } - - 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 66a862bf8ee..00000000000 --- a/src/server/scripts/BrokenIsles/zone_mardum.cpp +++ /dev/null @@ -1,1664 +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; - } - } - -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; - } - } - } - -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); - DoCastSelf(SPELL_BALEFUL_BEAMING_EYE_CREATE_AT); - // ToDo: rotation isn't changing orientation, turnspeed should be random - me->GetMotionMaster()->MoveRotate(0, RAND(ROTATE_DIRECTION_LEFT, ROTATE_DIRECTION_RIGHT), 10s); - } -}; - -// 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 c9a7bb16b78..00000000000 --- a/src/server/scripts/Draenor/zone_assault_on_the_dark_portal.cpp +++ /dev/null @@ -1,456 +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 "PhasingHandler.h" -#include "Player.h" -#include "QuestDef.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedFollowerAI.h" -#include "SpellScript.h" -#include "TemporarySummon.h" - -enum AssaultOnTheDarkPortalSpells -{ - SPELL_ALTAR_ALTERCATION_CANCEL_AURAS = 167547, // Serverside Spell - SPELL_BLEEDING_HOLLOW_HOLDOUT = 164609, - SPELL_BLEEDING_HOLLOW_KILROGG_REVEAL = 161771, - SPELL_BLEEDING_HOLLOW_TRAIL_OF_FLAME = 164611, - SPELL_BLEEDING_HOLLOW_SNEAKY_ARMY = 165061, - SPELL_BLOOD_RITUAL_ORB_BEAM = 170044, - SPELL_CANCEL_PHASE_AURA = 165053, - SPELL_CANCEL_TRAIL_OF_FLAME_VISUAL = 165993, - SPELL_DARK_PORTAL_RUN_AWAY = 158985, - SPELL_HUT_CREDIT = 164613, // Serverside Spell - SPELL_ON_ALTAR = 161637, - SPELL_PUSH_ARMY = 165072, - SPELL_TRAIL_OF_FLAME_LARGE = 165991, - SPELL_UPDATE_PHASE_SHIFT_PLAYER = 82238 -}; - -enum AssaultOnTheDarkPortalQuests -{ - QUEST_FLAG_ARMY_PUSHED = 35297, - QUEST_ALTAR_ALTERCATION = 34423, -}; - -enum AssaultOnTheDarkPortalQuestObjectives -{ - OBJECTIVE_ALTAR_ALTERCATION_SPEAK_WITH_ARIOK = 273075, - OBJECTIVE_ALTAR_ALTERCATION_ESCORT_ARIOK = 273677, -}; - -enum AssaultOnTheDarkPortalNPCs -{ - NPC_ALTAR_ALTERCATION_ARIOK = 80087, - NPC_ALTAR_ALTERCATION_KILROGG = 81926, - NPC_BLEEDING_HOLLOW_BLOODCHOSEN = 81895 -}; - -enum AssaultOnTheDarkPortalTexts -{ - // Ariok - SAY_ARIOK_INTRO_1 = 0, - SAY_ARIOK_INTRO_2 = 1, - SAY_ARIOK_INTRO_3 = 2, - SAY_ARIOK_ON_ALTAR_1 = 3, - SAY_ARIOK_ON_ALTAR_2 = 4, - SAY_ARIOK_MIDDLE_ORB_INTERACT = 5, - SAY_ARIOK_ALTAR_KILROGG_REVEAL = 6, - - // Kilrogg - SAY_KILROGG_WEST_ORB_INTERACT = 0, - SAY_KILROGG_ENTER_ALTAR_AT = 1 -}; - -enum AssaultOnTheDarkPortalActions -{ - ACTION_INTRO = 1, - ACTION_ON_ALTAR = 2 -}; - -enum AssaultOnTheDarkPortalEvents -{ - EVENT_TALK_1 = 1, - EVENT_TALK_2, - EVENT_TALK_3, - EVENT_ALTAR -}; - -// 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); - } -}; - -// 34423 - Altar Altercation -class quest_altar_altercation : public QuestScript -{ -public: - quest_altar_altercation() : QuestScript("quest_altar_altercation") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - if (newStatus == QUEST_STATUS_NONE) - player->CastSpell(player, SPELL_ALTAR_ALTERCATION_CANCEL_AURAS, TRIGGERED_FULL_MASK); - } -}; - -// 161618 - Summon Ariok -class spell_altar_altercation_summon_ariok : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_UPDATE_PHASE_SHIFT_PLAYER }); - } - - void HandleOnCast() - { - GetCaster()->CastSpell(GetCaster(), SPELL_UPDATE_PHASE_SHIFT_PLAYER, TRIGGERED_FULL_MASK); - } - - void Register() override - { - BeforeCast += SpellCastFn(spell_altar_altercation_summon_ariok::HandleOnCast); - } -}; - -// 694 - Bleeding Hollow: Kilrogg Reveal -class scene_bleeding_hollow_kilrogg_reveal : public SceneScript -{ -public: - scene_bleeding_hollow_kilrogg_reveal() : SceneScript("scene_bleeding_hollow_kilrogg_reveal") { } - - void OnSceneCancel(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->CastSpell(player, SPELL_CANCEL_PHASE_AURA, false); - } - - void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override - { - if (triggerName == "FreeCamera") - player->CastSpell(player, SPELL_CANCEL_PHASE_AURA, false); - } -}; - -// 167955 - Destroying -class spell_altar_altercation_destroying : public SpellScript -{ - void HandleOnHit(SpellEffIndex /*effIndex*/) - { - Creature* creature = GetHitUnit()->ToCreature(); - if (!creature) - return; - - creature->DespawnOrUnsummon(); // @TODO: Spawntracking should cause despawn for casting player only and respawn on abandon quest - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_altar_altercation_destroying::HandleOnHit, EFFECT_1, SPELL_EFFECT_DUMMY); - } -}; - -// 80087 - Ariok -struct npc_altar_altercation_ariok : public FollowerAI -{ - npc_altar_altercation_ariok(Creature* creature) : FollowerAI(creature) { } - - void JustAppeared() override - { - DoAction(ACTION_INTRO); - - if (TempSummon const* tempSummon = me->ToTempSummon()) - { - if (Player* summoner = tempSummon->GetSummoner()->ToPlayer()) - { - if (!summoner) - return; - - StartFollow(summoner); - } - } - } - - void DoAction(int32 action) override - { - switch (action) - { - case ACTION_INTRO: - { - events.ScheduleEvent(EVENT_TALK_1, 1s); - break; - } - case ACTION_ON_ALTAR: - { - Talk(SAY_ARIOK_ON_ALTAR_1); - me->AddUnitState(UNIT_STATE_ROOT); - events.ScheduleEvent(EVENT_ALTAR, 5s + 400ms); - break; - } - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - events.Update(diff); - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_TALK_1: - Talk(SAY_ARIOK_INTRO_1); - events.ScheduleEvent(EVENT_TALK_2, 5s + 700ms); - break; - case EVENT_TALK_2: - Talk(SAY_ARIOK_INTRO_2); - events.ScheduleEvent(EVENT_TALK_3, 7s + 400ms); - break; - case EVENT_TALK_3: - Talk(SAY_ARIOK_INTRO_3); - break; - case EVENT_ALTAR: - me->ClearUnitState(UNIT_STATE_ROOT); - Talk(SAY_ARIOK_ON_ALTAR_2); - break; - default: - break; - } - } - } -private: - EventMap events; -}; - -// 164979 - (Serverside/Non-DB2) Trigger Ariok -class spell_trigger_ariok_altar_altercation : public SpellScript -{ - void HandleOnHit(SpellEffIndex /*effIndex*/) - { - Creature* creature = GetHitUnit()->ToCreature(); - - if (!creature) - return; - - if (GetCaster()->HasAura(SPELL_BLEEDING_HOLLOW_KILROGG_REVEAL)) - { - creature->AI()->Talk(SAY_ARIOK_ALTAR_KILROGG_REVEAL); - creature->DespawnOrUnsummon(); - } - else if (GetCaster()->HasAura(SPELL_ON_ALTAR)) - creature->AI()->DoAction(ACTION_ON_ALTAR); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_trigger_ariok_altar_altercation::HandleOnHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 83670 - Blood Ritual Orb -struct npc_altar_altercation_blood_ritual_orb : public ScriptedAI -{ - npc_altar_altercation_blood_ritual_orb(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - if (Creature* bloodChosen = me->FindNearestCreature(NPC_BLEEDING_HOLLOW_BLOODCHOSEN, 50.0f)) - me->CastSpell(bloodChosen, SPELL_BLOOD_RITUAL_ORB_BEAM, true); - } - - void OnSpellClick(Unit* clicker, bool /*spellClickHandled*/) override - { - if (me->HasStringId("west_orb")) - { - Creature* kilrogg = clicker->FindNearestCreatureWithOptions(50.0f, { .CreatureId = NPC_ALTAR_ALTERCATION_KILROGG, .IgnorePhases = true }); - if (!kilrogg) - return; - - kilrogg->AI()->Talk(SAY_KILROGG_WEST_ORB_INTERACT, clicker); - } - else if (me->HasStringId("middle_orb")) - { - Creature* ariok = clicker->FindNearestCreatureWithOptions(50.0f, { .CreatureId = NPC_ALTAR_ALTERCATION_ARIOK, .IsSummon = true, .IgnorePhases = true, .OwnerGuid = clicker->GetGUID() }); - if (!ariok) - return; - - clicker->CastSpell(clicker, SPELL_BLEEDING_HOLLOW_SNEAKY_ARMY, true); - ariok->AI()->Talk(SAY_ARIOK_MIDDLE_ORB_INTERACT); - } - } - - void UpdateAI(uint32 /*diff*/) override - { - UpdateVictim(); - } -}; - -// Id - 52 -struct at_altar_altercation_kilrogg_talk : AreaTriggerAI -{ - at_altar_altercation_kilrogg_talk(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - Creature* kilrogg = unit->FindNearestCreature(NPC_ALTAR_ALTERCATION_KILROGG, 100.0f); - if (!kilrogg) - return; - - kilrogg->AI()->Talk(SAY_KILROGG_ENTER_ALTAR_AT, player); - } -}; - -// Id - 50 -struct at_altar_altercation_reach_altar : AreaTriggerAI -{ - at_altar_altercation_reach_altar(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - if (!player->IsQuestObjectiveComplete(QUEST_ALTAR_ALTERCATION, OBJECTIVE_ALTAR_ALTERCATION_SPEAK_WITH_ARIOK)) - return; - - if (player->IsQuestObjectiveComplete(QUEST_ALTAR_ALTERCATION, OBJECTIVE_ALTAR_ALTERCATION_ESCORT_ARIOK)) - return; - - player->CastSpell(nullptr, SPELL_ON_ALTAR); - } - - void OnUnitExit(Unit* unit) override - { - unit->RemoveAurasDueToSpell(SPELL_ON_ALTAR); - } -}; - -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(); - - new quest_altar_altercation(); - RegisterSpellScript(spell_altar_altercation_summon_ariok); - new scene_bleeding_hollow_kilrogg_reveal(); - RegisterSpellScript(spell_altar_altercation_destroying); - RegisterCreatureAI(npc_altar_altercation_ariok); - RegisterSpellScript(spell_trigger_ariok_altar_altercation); - RegisterCreatureAI(npc_altar_altercation_blood_ritual_orb); - RegisterAreaTriggerAI(at_altar_altercation_kilrogg_talk); - RegisterAreaTriggerAI(at_altar_altercation_reach_altar); -}; 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 7527b516936..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_STATE, DONE); - 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 33556dd97cb..00000000000 --- a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/aberrus_the_shadowed_crucible.h +++ /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/>. - */ - -#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, - - // Creatures - DATA_SARKARETH_AT_KAZZARA, - - // Gameobjects - DATA_KAZZARA_GATE, - - // Misc - DATA_KAZZARA_INTRO_STATE -}; - -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, - - // Kazzara Trash - NPC_SCALECOMMANDER_SARKARETH_AT_KAZZARA = 202416, - NPC_SUNDERED_DEVASTATOR = 198869, - NPC_SUNDERED_SCALEGUARD = 198871, - NPC_SUNDERED_MANAWEAVER = 198872, - NPC_SUNDERED_EDGELORD = 198873, - - // 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 203b871f863..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_STATE) != 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 7f8b83bce13..00000000000 --- a/src/server/scripts/DragonIsles/AberrusTheShadowedCrucible/instance_aberrus_the_shadowed_crucible.cpp +++ /dev/null @@ -1,158 +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 }, - { NPC_SCALECOMMANDER_SARKARETH_AT_KAZZARA, DATA_SARKARETH_AT_KAZZARA }, - { 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 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); - - _kazzaraIntroState = NOT_STARTED; - _kazzaraAliveIntroNPCs = 0; - } - - uint32 GetData(uint32 dataId) const override - { - switch (dataId) - { - case DATA_KAZZARA_INTRO_STATE: - return _kazzaraIntroState; - default: - break; - } - return 0; - } - - void SetData(uint32 dataId, uint32 value) override - { - switch (dataId) - { - case DATA_KAZZARA_INTRO_STATE: - _kazzaraIntroState = value; - break; - default: - break; - } - } - - void OnCreatureCreate(Creature* creature) override - { - InstanceScript::OnCreatureCreate(creature); - - if (creature->HasStringId("kazzara_intro_trash")) - _kazzaraAliveIntroNPCs++; - } - - void OnUnitDeath(Unit* unit) override - { - Creature* creature = unit->ToCreature(); - if (!creature) - return; - - if (creature->HasStringId("kazzara_intro_trash")) - { - if (_kazzaraIntroState != NOT_STARTED) - return; - - _kazzaraAliveIntroNPCs--; - if (_kazzaraAliveIntroNPCs > 0) - return; - - _kazzaraIntroState = IN_PROGRESS; - - Creature* sarkareth = GetCreature(DATA_SARKARETH_AT_KAZZARA); - if (!sarkareth) - return; - - sarkareth->CastSpell(nullptr, SPELL_ABERRUS_ENTRANCE_RP_CONVERSATION_3); - } - } - - private: - uint8 _kazzaraAliveIntroNPCs; - uint8 _kazzaraIntroState; - }; - - 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 b23f9795825..00000000000 --- a/src/server/scripts/DragonIsles/AzureVault/boss_leymor.cpp +++ /dev/null @@ -1,573 +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; - } - } - -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; - } - } -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/boss_telash_greywing.cpp b/src/server/scripts/DragonIsles/AzureVault/boss_telash_greywing.cpp deleted file mode 100644 index 1e9c8a72e0a..00000000000 --- a/src/server/scripts/DragonIsles/AzureVault/boss_telash_greywing.cpp +++ /dev/null @@ -1,501 +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 "Map.h" -#include "MotionMaster.h" -#include "InstanceScript.h" -#include "ObjectAccessor.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "SpellAuraEffects.h" -#include "SpellScript.h" -#include "SpellAuras.h" -#include "SharedDefines.h" -#include "azure_vault.h" - -enum TelashSpells -{ - // Telash - SPELL_POWER_ENERGIZE_ICE_POWER_PERIODIC = 389453, - SPELL_FROST_BOMB_CAST = 386781, - SPELL_FROST_BOMB_AURA = 386881, - SPELL_FROST_BOMB_DAMAGE = 386910, - SPELL_FROZEN_GROUND_AT = 387149, - SPELL_ICY_DEVASTATOR = 387151, - SPELL_ABSOLUTE_ZERO_CAST = 387928, - SPELL_ABSOLUTE_ZERO_JUMP = 387981, - SPELL_ABSOLUTE_ZERO_JUMP_BACK = 388082, - SPELL_ABSOLUTE_ZERO_SHIELD = 388084, - SPELL_ABSOLUTE_ZERO_DAMAGE = 388008, - SPELL_ACTIVATE_VAULT_RUNE = 390209, - SPELL_VAULT_RUNE_AT_AURA = 388065, - SPELL_VAULT_RUNE_SHIELD = 390201, - SPELL_INACTIVE_VAULT_RUNE = 390238, - - // Conversation - SPELL_TELASH_APPROACH_CONV = 389379 -}; - -enum TelashEvents -{ - EVENT_FROST_BOMB = 1, - EVENT_ICY_DEVASTATOR = 2, - EVENT_ABSOLUTE_ZERO = 3 -}; - -enum TelashSummonGroups -{ - SUMMON_GROUP_TELASH_VAULT_RUNES = 0 -}; - -enum TelashActions -{ - ACTION_RESCHEDULE_SPELLS = 1, -}; - -enum TelashText -{ - SAY_AGGRO = 0, - SAY_FROST_BOMB = 1, - SAY_ICY_DEVASTATOR = 2, - SAY_FLY_TO_MIDDLE = 3, - SAY_ANNOUNCE_ABSOLUTE_ZERO = 4, - SAY_DEATH = 5 -}; - -Position const TelashJumpPosition = { -5336.8003f, 1066.6493f, 344.32678f }; - -Position const TelashJumpBackPositions[] = -{ - { -5350.0835f, 1089.8976f, 340.5709f, 5.0882f }, - { -5310.4464f, 1066.8134f, 340.5967f, 3.9184f }, - { -5350.3934f, 1043.9323f, 340.5894f, 2.0924f } -}; - -// 186737 - Telash Greywing -struct boss_telash_greywing : public BossAI -{ - boss_telash_greywing(Creature* creature) : BossAI(creature, DATA_TELASH_GREYWING), _isInCenter(false), _frostBombRemaining(0), _icyDevastatorRemaining(0) { } - - void JustAppeared() override - { - me->SummonCreatureGroup(SUMMON_GROUP_TELASH_VAULT_RUNES); - me->SetPower(me->GetPowerType(), 60); - } - - void JustEngagedWith(Unit* who) override - { - BossAI::JustEngagedWith(who); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); - - _frostBombRemaining = 1; - _icyDevastatorRemaining = 1; - - Talk(SAY_AGGRO); - DoCast(SPELL_POWER_ENERGIZE_ICE_POWER_PERIODIC); - events.ScheduleEvent(EVENT_FROST_BOMB, 3500ms); - events.ScheduleEvent(EVENT_ICY_DEVASTATOR, 14500ms); - events.ScheduleEvent(EVENT_ABSOLUTE_ZERO, 500ms); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - summons.DespawnAll(); - _EnterEvadeMode(); - _DespawnAtEvade(); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - summons.DespawnAll(); - } - - void MovementInform(uint32 /*type*/, uint32 id) override - { - if (id == EVENT_JUMP) - { - if (!_isInCenter) - { - DoCastSelf(SPELL_ABSOLUTE_ZERO_DAMAGE); - _isInCenter = true; - } - else - { - DoCastSelf(SPELL_POWER_ENERGIZE_ICE_POWER_PERIODIC); - me->RemoveAurasDueToSpell(SPELL_ABSOLUTE_ZERO_SHIELD); - me->SetReactState(REACT_AGGRESSIVE); - _isInCenter = false; - } - } - } - - 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_FROST_BOMB: - { - Talk(SAY_FROST_BOMB); - DoCastSelf(SPELL_FROST_BOMB_CAST); - - _frostBombRemaining--; - if (!_frostBombRemaining) - { - if (_icyDevastatorRemaining == 1) - { - events.CancelEvent(EVENT_ICY_DEVASTATOR); - events.ScheduleEvent(EVENT_ICY_DEVASTATOR, 10800ms); - } - break; - } - - events.ScheduleEvent(EVENT_FROST_BOMB, _frostBombRemaining == 2 ? 18200ms : 15800ms); - break; - } - case EVENT_ICY_DEVASTATOR: - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 75.0f, true)) - { - Talk(SAY_ICY_DEVASTATOR); - DoCast(target, SPELL_ICY_DEVASTATOR); - - _icyDevastatorRemaining--; - if (!_icyDevastatorRemaining) - { - if (_frostBombRemaining == 1) - { - events.CancelEvent(EVENT_FROST_BOMB); - events.ScheduleEvent(EVENT_FROST_BOMB, 7300ms); - } - break; - } - events.ScheduleEvent(EVENT_ICY_DEVASTATOR, 23100ms); - } - break; - } - case EVENT_ABSOLUTE_ZERO: - if (me->GetPower(me->GetPowerType()) >= 100) - { - Talk(SAY_FLY_TO_MIDDLE); - Talk(SAY_ANNOUNCE_ABSOLUTE_ZERO); - me->SetReactState(REACT_PASSIVE); - me->SetDisableGravity(true, true); - me->RemoveAurasDueToSpell(SPELL_POWER_ENERGIZE_ICE_POWER_PERIODIC); - DoCastSelf(SPELL_ABSOLUTE_ZERO_CAST); - DoCastSelf(SPELL_ABSOLUTE_ZERO_SHIELD); - DoCastSelf(SPELL_ACTIVATE_VAULT_RUNE); - events.CancelEvent(EVENT_FROST_BOMB); - events.CancelEvent(EVENT_ICY_DEVASTATOR); - } - events.Repeat(500ms); - break; - default: - break; - } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - } - - void DoAction(int32 param) override - { - if (param == ACTION_RESCHEDULE_SPELLS) - { - _frostBombRemaining = 3; - _icyDevastatorRemaining = 2; - - events.ScheduleEvent(EVENT_FROST_BOMB, 4300ms); - events.ScheduleEvent(EVENT_ICY_DEVASTATOR, 15200ms); - } - } - -private: - bool _isInCenter; - uint8 _frostBombRemaining; - uint8 _icyDevastatorRemaining; -}; - -// 30743 - Vault Rune -struct at_telash_greywing_vault_rune : AreaTriggerAI -{ - at_telash_greywing_vault_rune(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - Unit* caster = at->GetCaster(); - if (!caster) - return; - - if (caster->HasAura(SPELL_VAULT_RUNE_SHIELD)) - return; - - caster->CastSpell(nullptr, SPELL_VAULT_RUNE_SHIELD, true); - } - - void OnUnitExit(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - for (ObjectGuid const& guid : at->GetInsideUnits()) - { - Player* player = ObjectAccessor::GetPlayer(*at, guid); - if (!player) - continue; - - if (player->isDead()) - continue; - - return; - } - - Unit* caster = at->GetCaster(); - if (!caster) - return; - - caster->RemoveAurasDueToSpell(SPELL_VAULT_RUNE_SHIELD); - } - - void OnRemove() override - { - if (!at->GetMap()->IsMythic() && !at->GetMap()->IsMythicPlus()) - return; - - for (ObjectGuid const& guid : at->GetInsideUnits()) - { - Player* player = ObjectAccessor::GetPlayer(*at, guid); - if (!player) - continue; - - if (player->isDead()) - continue; - - Unit* caster = at->GetCaster(); - if (!caster) - return; - - caster->CastSpell(caster, SPELL_INACTIVE_VAULT_RUNE, true); - break; - } - } -}; - -// 389453 - Ice Power (periodic) -class spell_telash_ice_power_periodic : public AuraScript -{ - void HandlePeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - target->SetPower(target->GetPowerType(), target->GetPower(POWER_ENERGY) + 2); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_telash_ice_power_periodic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -// 386781 - Frost Bomb -class spell_telash_frost_bomb_cast : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_FROST_BOMB_AURA }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_FROST_BOMB_AURA, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_telash_frost_bomb_cast::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 386881 - Frost Bomb -class spell_telash_frost_bomb_aura : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_FROST_BOMB_DAMAGE, - SPELL_FROZEN_GROUND_AT - }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) - return; - - if (Unit* caster = GetCaster()) - { - caster->CastSpell(GetTarget(), SPELL_FROZEN_GROUND_AT, true); - caster->CastSpell(GetTarget(), SPELL_FROST_BOMB_DAMAGE, true); - } - } - - void Register() override - { - OnEffectRemove += AuraEffectRemoveFn(spell_telash_frost_bomb_aura::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 387928 - Absolute Zero -class spell_telash_absolute_zero_cast : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ABSOLUTE_ZERO_JUMP }); - } - - void HandleHit(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(TelashJumpPosition, SPELL_ABSOLUTE_ZERO_JUMP, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_telash_absolute_zero_cast::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 390209 - Activate Vault Rune -class spell_telash_activate_vault_rune : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_VAULT_RUNE_AT_AURA, - SPELL_INACTIVE_VAULT_RUNE - }); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - if (GetHitUnit()->HasAura(SPELL_INACTIVE_VAULT_RUNE)) - return; - - GetHitUnit()->CastSpell(nullptr, SPELL_VAULT_RUNE_AT_AURA, true); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_telash_activate_vault_rune::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 388008 - Absolute Zero -class spell_telash_absolute_zero_damage : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_ABSOLUTE_ZERO_JUMP_BACK, - SPELL_VAULT_RUNE_AT_AURA, - SPELL_VAULT_RUNE_SHIELD - }); - } - - Position const& GetClosestPositionToMaxThreatTarget(Unit* victim) - { - float nearestDist = std::numeric_limits<float>::max(); - Position const* nearestPos = &TelashJumpBackPositions[0]; - - for (Position const& pos : TelashJumpBackPositions) - { - float dist = victim->GetDistance(pos); - if (dist < nearestDist) - { - nearestDist = dist; - nearestPos = &pos; - } - } - - return *nearestPos; - } - - void HandleAfterCast() - { - Unit* caster = GetCaster(); - UnitAI* casterAI = caster->GetAI(); - if (!casterAI) - return; - - Unit* victim = casterAI->SelectTarget(SelectTargetMethod::MaxThreat); - if (!victim) - return; - - casterAI->DoAction(ACTION_RESCHEDULE_SPELLS); - caster->CastSpell(GetClosestPositionToMaxThreatTarget(victim), SPELL_ABSOLUTE_ZERO_JUMP_BACK, true); - } - - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - GetHitUnit()->RemoveAurasDueToSpell(SPELL_VAULT_RUNE_AT_AURA); - GetHitUnit()->RemoveAurasDueToSpell(SPELL_VAULT_RUNE_SHIELD); - } - - void Register() override - { - AfterCast += SpellCastFn(spell_telash_absolute_zero_damage::HandleAfterCast); - OnEffectHitTarget += SpellEffectFn(spell_telash_absolute_zero_damage::HandleHitTarget, EFFECT_1, SPELL_EFFECT_DUMMY); - } -}; - -void AddSC_boss_telash_greywing() -{ - // Creature - RegisterAzureVaultCreatureAI(boss_telash_greywing); - - // AreaTrigger - RegisterAreaTriggerAI(at_telash_greywing_vault_rune); - - // Spells - RegisterSpellScript(spell_telash_ice_power_periodic); - RegisterSpellScript(spell_telash_frost_bomb_cast); - RegisterSpellScript(spell_telash_frost_bomb_aura); - RegisterSpellScript(spell_telash_absolute_zero_cast); - RegisterSpellScript(spell_telash_activate_vault_rune); - RegisterSpellScript(spell_telash_absolute_zero_damage); -} 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 6034566a993..00000000000 --- a/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp +++ /dev/null @@ -1,54 +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(); -void AddSC_boss_telash_greywing(); - -// 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(); - AddSC_boss_telash_greywing(); - - // 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 4c756e8afa9..00000000000 --- a/src/server/scripts/DragonIsles/zone_the_forbidden_reach.cpp +++ /dev/null @@ -1,190 +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 "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?) - SPELL_MAINTAIN_DERVISHIAN = 369731, // Alliance Personal Summon - SPELL_MAINTAIN_KODETHI = 370112, // Horde Personal Summon - SPELL_AWAKEN_DRACTYHR_QUEST_ABANDON = 369744, - SPELL_STASIS_FEEDBACK_KNOCKBACK = 364074, - SPELL_STASIS_FEEDBACK_VISUAL = 374633 -}; - -struct DracthyrLoginRoom -{ - uint32 MovieSpellId; - Position PlayerPosition; - Position SummonPosition; -}; - -std::array<DracthyrLoginRoom, 4> LoginRoomData = -{ - { - { - SPELL_DRACTHYR_MOVIE_ROOM_01, - { 5725.32f, -3024.26f, 251.047f, 0.01745329238474369f }, - { 5739.97216796875f, -3023.970458984375f, 251.172332763671875f, 3.193952560424804687f } - }, - { - SPELL_DRACTHYR_MOVIE_ROOM_02, - { 5743.03f, -3067.28f, 251.047f, 0.798488140106201171f }, - { 5754.3046875f, -3056.34716796875f, 251.1725006103515625f, 3.926990747451782226f } - }, - { - SPELL_DRACTHYR_MOVIE_ROOM_03, - { 5787.1597f, -3083.3906f, 251.04698f, 1.570796370506286621f }, - { 5787.44970703125f, -3069.335205078125f, 251.168121337890625f, 4.729842185974121093f } - }, - { - SPELL_DRACTHYR_MOVIE_ROOM_04, - { 5829.32f, -3064.49f, 251.047f, 2.364955902099609375f }, - { 5818.533203125f, -3054.5625f, 251.3630828857421875f, 5.480333805084228515f } - } - } -}; - -// 369728 - Dracthyr Login -// 369744 - Awaken, Dracthyr OnquestAbandon -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*/) - { - DracthyrLoginRoom const& room = LoginRoomData[urand(0, 3)]; - - WorldLocation dest = GetHitUnit()->GetWorldLocation(); - SetExplTargetDest(dest); - - GetHitDest()->Relocate(room.PlayerPosition); - - GetCaster()->CastSpell(GetHitUnit(), room.MovieSpellId, 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); - } -}; - -// 369730 - Summon Dervishian -// 370111 - Summon Kodethi -class spell_dracthyr_summon_dervishian : public SpellScript -{ - void SetDest(SpellDestination& dest) - { - float currentDist = 1000.0f; - DracthyrLoginRoom const* currentRoom = nullptr; - - for (DracthyrLoginRoom const& room : LoginRoomData) - { - float dist = GetCaster()->GetDistance(room.PlayerPosition); - if (dist < currentDist) - { - currentDist = dist; - currentRoom = &room; - } - } - if (!currentRoom) - return; - - dest.Relocate(currentRoom->SummonPosition); - } - - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_dracthyr_summon_dervishian::SetDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); - } -}; - -// 64864 - Awaken, Dracthyr -class quest_awaken_dracthyr : public QuestScript -{ -public: - quest_awaken_dracthyr() : QuestScript("quest_awaken_dracthyr") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - if (newStatus == QUEST_STATUS_NONE) - player->CastSpell(player, SPELL_AWAKEN_DRACTYHR_QUEST_ABANDON, false); - } -}; - -// 30308 - Stasis Feedback -struct at_dracthyr_stasis_feedback : AreaTriggerAI -{ - at_dracthyr_stasis_feedback(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - if (!unit->IsPlayer()) - return; - - unit->CastSpell(nullptr, SPELL_STASIS_FEEDBACK_KNOCKBACK, false); - if (Unit* caster = at->GetCaster()) - caster->CastSpell(caster->GetPosition(), SPELL_STASIS_FEEDBACK_VISUAL, true); - } -}; - -void AddSC_zone_the_forbidden_reach() -{ - RegisterSpellScript(spell_dracthyr_login); - new scene_dracthyr_evoker_intro(); - RegisterSpellScript(spell_dracthyr_summon_dervishian); - new quest_awaken_dracthyr(); - RegisterAreaTriggerAI(at_dracthyr_stasis_feedback); -} 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 e5f0e36616d..00000000000 --- a/src/server/scripts/ExilesReach/zone_exiles_reach.cpp +++ /dev/null @@ -1,7189 +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 "CreatureAIImpl.h" -#include "Map.h" -#include "Object.h" -#include "Player.h" -#include "CellImpl.h" -#include "Containers.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "ObjectMgr.h" -#include "PassiveAI.h" -#include "ScriptedCreature.h" -#include "ScriptMgr.h" -#include "ScriptSystem.h" -#include "SpellAuras.h" -#include "SpellInfo.h" -#include "SpellScript.h" -#include "TemporarySummon.h" -#include "Transport.h" -#include "Loot.h" -#include "SpellHistory.h" -#include "WorldStateMgr.h" -#include "Unit.h" -#include "Vehicle.h" -#include "WorldSession.h" -#include "CombatAI.h" -#include "PhasingHandler.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_UPDATE_PHASE_SHIFT); - 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 -{ - // @TODO: drop after TARGET_UNK_142 impl - - 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->SetImmuneToPC(true); - _events.ScheduleEvent(EVENT_MOVE_TO_A_POSITION, 1s); - } - - 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 (Unit* owner = me->GetDemonCreator()) - me->SetFacingToObject(owner); - me->SetImmuneToPC(false); - me->SetUninteractible(false); - break; - default: - break; - } - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId != _path) - return; - - if (Unit* owner = me->GetDemonCreator()) - { - me->DespawnOrUnsummon(); - owner->CastSpell(owner, SPELL_UPDATE_PHASE_SHIFT); - owner->CastSpell(owner, 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 = me->GetDemonCreatorPlayer()) - { - 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 (Unit* owner = me->GetDemonCreator()) - { - Conversation* conversation = Conversation::CreateConversation(conversationId, owner, *owner, owner->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; - } -private: - EventMap _events; - bool _jumped; - uint8 _actorIndex; - uint32 _actorId; - uint32 _path; -}; - -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* CaptainGarrickAISelector(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); - player->UpdateVisibilityForPlayer(); // Needed to make survivor stand instantly - } - } -}; - -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 constexpr Position 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 constexpr Position 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) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, playerGuid)) - { - if (player->IsQuestRewarded(QUEST_MURLOC_HIDEAWAY_BOOTS_DROPPED)) - break; - - 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) - player->SetRewardedQuest(QUEST_MURLOC_HIDEAWAY_BOOTS_DROPPED); - } - } - } - } -}; - -// 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_ALLIANCE_SURVIVOR = 69830, - ACTOR_ID_HORDE_SURVIVOR = 76283, - - 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, -}; - -static constexpr Position GarrickAbandonedCampPosition = { -249.059006f, -2492.520020f, 18.0742f }; -static constexpr Position 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 - { - _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 (Unit* owner = me->GetOwner()) - { - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_LINE_ESCORT_SURVIVOR_CAMP, owner, *owner, owner->GetGUID(), nullptr, false); - conversation->AddActor(ACTOR_ID_ALLIANCE_SURVIVOR, 1, 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 (Unit* owner = me->GetOwner()) - { - owner->CastSpell(owner, SPELL_UPDATE_PHASE_SHIFT); - owner->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: - { - Unit* owner = me->GetOwner(); - if (!owner) - break; - - Creature* survivor = FindCreatureIgnorePhase(owner, "spawn_check"); - - if (!survivor) - { - if (owner->GetAreaId() != AREA_ABANDONED_CAMP) - owner->RemoveAura(SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN); - else - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 0s); - } - else - { - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_LINE_ESCORT_ALLIANCE_SURVIVOR, owner, *owner, owner->GetGUID(), nullptr, false); - conversation->AddActor(ACTOR_ID_ALLIANCE_SURVIVOR, 1, me->GetGUID()); - conversation->Start(); - - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 2s); - } - break; - } - case EVENT_FOLLOW_PLAYER: - if (Unit* owner = me->GetOwner()) - me->GetMotionMaster()->MoveFollow(owner, 0.0f, float(M_PI / 4.0f)); - break; - default: - break; - } - } - } -private: - EventMap _events; - 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 - { - _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 (Unit* owner = me->GetOwner()) - { - if (Conversation* conversation = Conversation::CreateConversation(CONVERSATION_LINE_ESCORT_SURVIVOR_CAMP, owner, *owner, owner->GetGUID(), nullptr, false)) - { - conversation->AddActor(ACTOR_ID_HORDE_SURVIVOR, 3, 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 (Unit* owner = me->GetOwner()) - { - owner->CastSpell(owner, SPELL_UPDATE_PHASE_SHIFT); - owner->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: - { - Unit* owner = me->GetOwner(); - if (!owner) - break; - - Creature* survivor = FindCreatureIgnorePhase(owner, "spawn_check"); - - if (!survivor) - { - if (owner->GetAreaId() != AREA_ABANDONED_CAMP) - owner->RemoveAura(SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN); - else - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 0s); - } - else - { - if (Conversation* conversation = Conversation::CreateConversation(CONVERSATION_LINE_ESCORT_HORDE_SURVIVOR, owner, *owner, owner->GetGUID(), nullptr, false)) - { - conversation->AddActor(ACTOR_ID_HORDE_SURVIVOR, 2, me->GetGUID()); - conversation->Start(); - } - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 2s); - } - break; - } - case EVENT_FOLLOW_PLAYER: - if (Unit* owner = me->GetOwner()) - me->GetMotionMaster()->MoveFollow(owner, 0.0f, float(M_PI / 4.0f)); - break; - default: - break; - } - } - } -private: - EventMap _events; - 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 -{ - // @TODO: drop after TARGET_UNK_142 impl - - 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 -}; - -static constexpr Position 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; - - Creature* injuredTemp = injured->SummonPersonalClone(InjuredNpcPositionAbandonedCamp, TEMPSUMMON_TIMED_DESPAWN, 2s, 0, 0, player); - injuredTemp->SetAIAnimKitId(ANIMATION_KIT_INJURED); - 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); - } - } -}; - -enum EnhancedCombatTacticsData -{ - SPELL_SUMMON_CAPTAIN_GARRICK_COMBAT = 320211, - SPELL_SUMMON_WARLORD_GRIMAXE_COMBAT = 325180 -}; - -// 59254 - Enhanced Combat Tactics (Alliance) -// 59339 - Enhanced Combat Tactics (Alliance Monk) -// 59933 - Enhanced Combat Tactics (Horde) -// 59934 - Enhanced Combat Tactics (Horde Monk) -class quest_enhanced_combat_tactics : public QuestScript -{ -public: - quest_enhanced_combat_tactics() : QuestScript("quest_enhanced_combat_tactics") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, player->GetTeam() == ALLIANCE ? SPELL_SUMMON_CAPTAIN_GARRICK_COMBAT : SPELL_SUMMON_WARLORD_GRIMAXE_COMBAT); - break; - case QUEST_STATUS_NONE: - player->RemoveAura(player->GetTeam() == ALLIANCE ? SPELL_SUMMON_CAPTAIN_GARRICK_COMBAT : SPELL_SUMMON_WARLORD_GRIMAXE_COMBAT); - player->UpdateObjectVisibility(); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - default: - break; - } - } -}; - -// 320175 - Summon Garrick - Combat Training (DNT) -// 325181 - Summon Grimaxe - Combat Training (DNT) -class spell_summon_combat_trainer : public SpellScript -{ - // @TODO: drop after TARGET_UNK_142 impl - - void SelectTarget(WorldObject*& target) - { - Player* caster = GetCaster()->ToPlayer(); - if (!caster) - return; - - Creature* partner = FindCreatureIgnorePhase(caster, caster->GetTeam() == ALLIANCE ? "garrick_camp" : "grimaxe_camp", 10.0f); - if (!partner) - return; - - target = partner; - } - - void Register() override - { - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_summon_combat_trainer::SelectTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY_OR_DB); - } -}; - -enum EnhancedCombatTrainerData -{ - ACTOR_ID_ALLIANCE_ENHANCED_TRAINING = 74771, - ACTOR_ID_HORDE_ENHANCED_TRAINING = 76285, - - CHARGE_CATEGORY_CHARGE_SPELL = 1386, - - CONVERSATION_PREFIGHT_WALK_ENHANCED = 13710, - CONVERSATION_USE_SPELLS_AT_RANGE = 13630, - CONVERSATION_READY_COMBAT = 14440, - // Warrior - CONVERSATION_READY_COMBAT_WARRIOR = 14441, - CONVERSATION_CHARGE_ZERO_RES_ENHANCED = 14444, - CONVERSATION_SLAM_ENHANCED = 14447, - CONVERSATION_CHARGE_ONE_RES_ENHANCED = 14448, - CONVERSATION_CHARGE_FINAL_ENHANCED = 14449, - CONVERSATION_CHARGE_KICKBACK = 13611, - // Paladin - CONVERSATION_HOLY_POWER_ONE_PALADIN = 14452, - CONVERSATION_CRUSADER_STRIKE_ONE_PALADIN = 14453, - CONVERSATION_CRUSADER_STRIKE_TWO_PALADIN = 14454, - CONVERSATION_SHIELD_SLAM_ONE_PALADIN = 14455, - CONVERSATION_HOLY_POWER_TWO_PALADIN = 14456, - CONVERSATION_SHIELD_SLAM_TWO_PALADIN = 14457, - CONVERSATION_CRUSADER_STRIKE_THREE_PALADIN = 14458, - CONVERSATION_HOLY_POWER_THREE_PALADIN = 14459, - // Rogue - CONVERSATION_SINISTER_STRIKE_ONE_ROGUE = 14486, - CONVERSATION_REGULAR_ATTACKS_ROGUE = 14487, - CONVERSATION_THREE_COMBO_POINTS_ROGUE = 14488, - CONVERSATION_THREE_COMBO_EVISCERATE_ROGUE = 14489, - CONVERSATION_SINISTER_STRIKE_TWO_ROGUE = 14490, - CONVERSATION_FOUR_COMBO_POINTS_ROGUE = 14491, - CONVERSATION_FOUR_COMBO_EVISCERATE_ROGUE = 14492, - CONVERSATION_SINISTER_STRIKE_THREE_ROGUE = 14493, - CONVERSATION_FIVE_COMBO_POINTS_ROGUE = 14494, - CONVERSATION_FAILED_EVISCERATE_ROGUE = 14495, - // Priest - CONVERSATION_SHADOW_WORD_PAIN_QUEST_CREDIT_PRIEST = 13892, - CONVERSATION_SMITE_PRE_COMBAT_PRIEST = 14460, - CONVERSATION_SHADOW_WORD_PAIN_PRE_COMBAT_PRIEST = 14461, - CONVERSATION_SHADOW_WORD_PAIN_TOO_SOON_PRIEST = 14462, - CONVERSATION_SHADOW_WORD_PAIN_FADING_PRIEST = 14463, - // Shaman - CONVERSATION_LIGHTNINGBOLT_FIRST_SHAMAN = 13631, - CONVERSATION_PRIMAL_STRIKE_FIRST_SHAMAN = 13632, - CONVERSATION_PRIMAL_STRIKE_QUEST_CREDIT_SHAMAN = 13633, - CONVERSATION_LIGHTNINGBOLT_RANGE_SHAMAN = 14475, - // Mage - CONVERSATION_FROSTBOLT_MAGE = 13634, - CONVERSATION_FIRE_BLAST_QUEST_CREDIT_MAGE = 13635, - CONVERSATION_FROSTBOLT_CLOSE_MAGE = 14476, - CONVERSATION_FIRE_BLAST_MAGE_NO_CREDIT = 14477, - // Warlock - CONVERSATION_CORRUPTION_QUEST_CREDIT_WARLOCK = 13895, - CONVERSATION_SHADOW_BOLT_PRE_COMBAT_WARLOCK = 14465, - CONVERSATION_CORRUPTION_CAST_PRE_COMBAT_WARLOCK = 14466, - CONVERSATION_CORRUPTION_CAST_TOO_SOON_WARLOCK = 14467, - CONVERSATION_CORRUPTION_IS_FADING_WARLOCK = 14468, - // Druid - CONVERSATION_MOONFIRE_QUEST_CREDIT_DRUID = 13893, - CONVERSATION_WRATH_PRE_COMBAT_DRUID = 14471, - CONVERSATION_MOONFIRE_CAST_PRE_COMBAT_DRUID = 14472, - CONVERSATION_MOONFIRE_CAST_TOO_SOON_DRUID = 14473, - CONVERSATION_MOONFIRE_WEARING_OFF_DRUID = 14474, - - // All classes - EVENT_COMBAT_TRAINING_WALK_AND_TALK = 1, - EVENT_COMBAT_TRAINING_FACE_PLAYER, - EVENT_COMBAT_RUN_BACK, - EVENT_COMBAT_TRAINING_END, - EVENT_COMBAT_CHECK_PLAYER, - // Rogue - EVENT_COMBAT_TRAINING_SINISTER_CHECK_ROGUE, - // Priest, Warlock, Druid - EVENT_COMBAT_TRAINING_SPELL_FADING, - // Shaman - EVENT_COMBAT_TRAINING_RESET_SHAMAN, - EVENT_COMBAT_TRAINING_AGGRO_CHECK_SHAMAN, - // Mage - EVENT_COMBAT_TRAINING_RESET_MAGE, - EVENT_COMBAT_TRAINING_AGGRO_CHECK_MAGE, - - NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED = 164577, - NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED2 = 164775, - //NPC_HORDE_SPARING_PARTNER_ENHANCED = 166916, - NPC_INVISBUNNY_CAMP = 167761, - - PATH_COMBAT_TRAINER_HOME = 10512100, - - POINT_WALK_POINT_ENHANCED_TRAINING = 1, - POINT_RUN_POINT_ENHANCED_TRAINING = 2, - POINT_TRAINING_POINT_ENHANCED_TRAINING = 3, - - QUEST_ENHANCED_COMBAT_TACTICS_ALLIANCE = 59254, - QUEST_ENHANCED_COMBAT_TACTICS_ALLIANCE_MONK = 59339, - QUEST_ENHANCED_COMBAT_TACTICS_HORDE = 59933, - QUEST_ENHANCED_COMBAT_TACTICS_HORDE_MONK = 59934, - - QUEST_OBJECTIVE_HORDE_ABILITIES_PROVEN = 397255, - QUEST_OBJECTIVE_HORDE_TIGER_PALM = 397258, - QUEST_OBJECTIVE_HORDE_BLACKOUT_KICK = 397259, - QUEST_OBJECTIVE_ALLIANCE_ABILITIES_PROVEN = 396220, - QUEST_OBJECTIVE_ALLIANCE_TIGER_PALM = 396353, - QUEST_OBJECTIVE_ALLIANCE_BLACKOUT_KICK = 396354, - - SPELL_DRINK_HEALING_POTION = 320229, - SPELL_KNOCKBACK = 320735, - SPELL_CHARGE_KNOCKBACK_DRUID = 320767, - SPELL_CHARGE = 100, - SPELL_SLAM = 1464, - SPELL_CHARGE_KNOCKBACK_WARRIOR = 320583, - SPELL_SHIELD_OF_THE_RIGHTEOUS = 53600, - SPELL_CRUSADER_STRIKE = 35395, - SPELL_SINISTER_STRIKE = 1752, - SPELL_EVISCERATE = 196819, - SPELL_SMITE = 585, - SPELL_SHADOW_WORD_PAIN = 589, - SPELL_CHARGE_KNOCKBACK = 320605, - SPELL_PRIMAL_STRIKE = 73899, - SPELL_LIGHTNING_BOLT = 188196, - SPELL_FIRE_BLAST = 319836, - SPELL_FROSTBOLT = 116, - SPELL_CORRUPTION = 172, - SPELL_SHADOWBOLT = 686, - SPELL_MOONFIRE = 164812, - SPELL_WRATH = 5176, - SPELL_TIGER_PALM = 100780, - SPELL_BLACKOUT_KICK = 100784, - SPELL_RANGED_ROOT_DNT = 320608, - SPELL_AGGRO_RADIUS_CHECK_DNT_WARRIOR = 320741, - SPELL_AGGRO_RADIUS_CHECK_DNT_PRIEST = 320649, - SPELL_AGGRO_RADIUS_CHECK_DNT_SHAMAN = 320705, - SPELL_AGGRO_RADIUS_CHECK_DNT_WARRIOR_MAGE = 320741, - SPELL_AGGRO_RADIUS_CHECK_DNT_WARLOCK = 320606, - SPELL_AGGRO_RADIUS_CHECK_DNT_DRUID = 320766 -}; - -static constexpr Position EnhancedTrainingWalkPosition = { -250.60243f, -2485.2517f, 17.787413f }; -static constexpr Position EnhancedTrainingRunPosition = { -231.5225f, -2480.5276f, 19.019197f }; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_combat_training : public ScriptedAI -{ - npc_sparring_partner_combat_training(Creature* creature) : ScriptedAI(creature), _questID(0), _summonSpellAuraID(0) { } - - virtual void OnReadyPointReached() { } - - virtual void HandleClassEvent(uint32 /*eventId*/) { } - - void JustAppeared() override - { - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_WALK_AND_TALK, 2s); - } - - void IsSummonedBy(WorldObject* summonerWO) override - { - Player* player = summonerWO->GetAffectingPlayer(); - if (!player) - return; - - if (player->GetTeam() == ALLIANCE) - { - _summonSpellAuraID = SPELL_SUMMON_CAPTAIN_GARRICK_COMBAT; - - if (player->GetClass() == CLASS_MONK) - _questID = QUEST_ENHANCED_COMBAT_TACTICS_ALLIANCE_MONK; - else - _questID = QUEST_ENHANCED_COMBAT_TACTICS_ALLIANCE; - } - else - { - _summonSpellAuraID = SPELL_SUMMON_WARLORD_GRIMAXE_COMBAT; - - if (player->GetClass() == CLASS_MONK) - _questID = QUEST_ENHANCED_COMBAT_TACTICS_HORDE_MONK; - else - _questID = QUEST_ENHANCED_COMBAT_TACTICS_HORDE; - } - } - - uint8 GetQuestCredits() - { - Player* player = me->GetDemonCreatorPlayer(); - if (!player) - return 0; - - uint32 objectiveId = 0; - switch (_questID) - { - case QUEST_ENHANCED_COMBAT_TACTICS_ALLIANCE: - objectiveId = QUEST_OBJECTIVE_ALLIANCE_ABILITIES_PROVEN; - break; - case QUEST_ENHANCED_COMBAT_TACTICS_HORDE: - objectiveId = QUEST_OBJECTIVE_HORDE_ABILITIES_PROVEN; - break; - default: - break; - } - - return player->GetQuestObjectiveData(_questID, objectiveId); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - if (!me->IsAlive()) - return; - - me->CombatStop(true); - EngagementOver(); - me->ResetPlayerDamageReq(); - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE) - return; - - switch (uiId) - { - case POINT_WALK_POINT_ENHANCED_TRAINING: - me->SetWalk(false); - me->GetMotionMaster()->MovePoint(POINT_RUN_POINT_ENHANCED_TRAINING, EnhancedTrainingRunPosition); - break; - case POINT_RUN_POINT_ENHANCED_TRAINING: - { - std::list<Creature*> sparpoints; - GetCreatureListWithEntryInGrid(sparpoints, me, NPC_INVISBUNNY_CAMP, 100.0f); - Trinity::Containers::RandomResize(sparpoints, 1); - - for (Creature* creature : sparpoints) - me->GetMotionMaster()->MovePoint(POINT_TRAINING_POINT_ENHANCED_TRAINING, creature->GetPosition()); - break; - } - case POINT_TRAINING_POINT_ENHANCED_TRAINING: - { - Unit* owner = me->GetDemonCreator(); - if (!owner) - break; - - me->SetFacingToObject(owner); - me->SetImmuneToPC(false); - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - _events.ScheduleEvent(EVENT_COMBAT_CHECK_PLAYER, 1s); - - OnReadyPointReached(); - break; - } - default: - break; - } - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - damage = me->GetHealth() - 1; - - if (me->HealthBelowPctDamaged(20, damage)) - me->CastSpell(me, SPELL_DRINK_HEALING_POTION); - } - - void DamageDealt(Unit* target, uint32& damage, DamageEffectType /*damageType*/) override - { - if (target->GetHealthPct() < 91) - damage = 0; - } - - void StartConversationWithPlayer(uint32 conversationId) - { - if (Player* player = me->GetDemonCreatorPlayer()) - { - Conversation* conversation = Conversation::CreateConversation(conversationId, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(ACTOR_ID_ALLIANCE_ENHANCED_TRAINING, 0, player->GetTeam() == ALLIANCE ? me->GetGUID() : ObjectGuid::Empty); - conversation->AddActor(ACTOR_ID_HORDE_ENHANCED_TRAINING, 1, player->GetTeam() == HORDE ? me->GetGUID() : ObjectGuid::Empty); - conversation->Start(); - } - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - // Used to check if reached home - if (pathId == PATH_COMBAT_TRAINER_HOME) - { - if (Unit* owner = me->GetDemonCreator()) - { - owner->CastSpell(owner, SPELL_UPDATE_PHASE_SHIFT); - owner->RemoveAura(_summonSpellAuraID); - } - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_COMBAT_TRAINING_WALK_AND_TALK: - // Used by all classes - me->SetWalk(true); - me->GetMotionMaster()->MovePoint(POINT_WALK_POINT_ENHANCED_TRAINING, EnhancedTrainingWalkPosition); - StartConversationWithPlayer(CONVERSATION_PREFIGHT_WALK_ENHANCED); - break; - case EVENT_COMBAT_TRAINING_FACE_PLAYER: - { - // Used by all classes - if (Unit* owner = me->GetDemonCreator()) - me->SetFacingToObject(owner); - - me->SetImmuneToPC(false); - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - break; - } - case EVENT_COMBAT_TRAINING_END: - // Used by all classes - me->SetImmuneToPC(true); - me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - me->RemoveAllAuras(); - if (Unit* owner = me->GetDemonCreator()) - { - me->SetFacingToObject(owner); - StartConversationWithPlayer(CONVERSATION_CHARGE_FINAL_ENHANCED); - _events.ScheduleEvent(EVENT_COMBAT_RUN_BACK, 4s); - } - break; - case EVENT_COMBAT_RUN_BACK: - // Used by all classes - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePath(PATH_COMBAT_TRAINER_HOME, false); - break; - default: - HandleClassEvent(eventId); - break; - } - } - - if (!UpdateVictim()) - return; - } - -protected: - uint32 _questID; - uint32 _summonSpellAuraID; - EventMap _events; -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_warrior : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_warrior(Creature* creature) : npc_sparring_partner_combat_training(creature), _slamCounter(0), _secondaryCheck(false) { } - - void ResetWarrior(Player* player) - { - _slamCounter = 0; - me->SetImmuneToPC(true); - me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - player->GetSpellHistory()->ResetCharges(CHARGE_CATEGORY_CHARGE_SPELL); - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_WARRIOR_MAGE); - me->CastSpell(me, SPELL_RANGED_ROOT_DNT); - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_FACE_PLAYER, 1s); - StartConversationWithPlayer(CONVERSATION_CHARGE_KICKBACK); - } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT_WARRIOR); - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_WARRIOR_MAGE); - me->CastSpell(me, SPELL_RANGED_ROOT_DNT); - _secondaryCheck = true; - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_CHARGE) - { - me->RemoveAura(SPELL_RANGED_ROOT_DNT); - me->RemoveAura(SPELL_AGGRO_RADIUS_CHECK_DNT_WARRIOR_MAGE); - - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - - switch (GetQuestCredits()) - { - case 1: - StartConversationWithPlayer(CONVERSATION_CHARGE_ZERO_RES_ENHANCED); - break; - case 2: - StartConversationWithPlayer(CONVERSATION_CHARGE_ONE_RES_ENHANCED); - break; - case 3: - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - break; - default: - break; - } - } - else if (spellInfo->Id == SPELL_SLAM) - { - ++_slamCounter; - - if (_slamCounter == 3 && GetQuestCredits()) - ResetWarrior(player); - - if (!_secondaryCheck) - return; - - _secondaryCheck = false; - StartConversationWithPlayer(CONVERSATION_SLAM_ENHANCED); - } - } - -private: - uint8 _slamCounter; - bool _secondaryCheck; -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_paladin : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_paladin(Creature* creature) : npc_sparring_partner_combat_training(creature), _secondaryCheck(false), _holyPowerCheck(false) { } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT); - _holyPowerCheck = true; - _secondaryCheck = true; - } - - void HandleClassEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_COMBAT_CHECK_PLAYER: - { - if (_holyPowerCheck) // Used by paladin - { - if (Unit* owner = me->GetDemonCreator()) - { - if (owner->GetPower(POWER_HOLY_POWER) >= 3) - { - switch (GetQuestCredits()) - { - case 0: - StartConversationWithPlayer(CONVERSATION_HOLY_POWER_ONE_PALADIN); - break; - case 1: - StartConversationWithPlayer(CONVERSATION_HOLY_POWER_TWO_PALADIN); - break; - case 2: - StartConversationWithPlayer(CONVERSATION_HOLY_POWER_THREE_PALADIN); - break; - default: - break; - } - _holyPowerCheck = false; - } - } - } - _events.ScheduleEvent(EVENT_COMBAT_CHECK_PLAYER, 500ms); - break; - } - default: - break; - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_SHIELD_OF_THE_RIGHTEOUS) - { - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - - switch (GetQuestCredits()) - { - case 1: - StartConversationWithPlayer(CONVERSATION_SHIELD_SLAM_ONE_PALADIN); - _secondaryCheck = true; - break; - case 2: - StartConversationWithPlayer(CONVERSATION_SHIELD_SLAM_TWO_PALADIN); - _secondaryCheck = true; - break; - case 3: - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - _events.CancelEvent(EVENT_COMBAT_CHECK_PLAYER); - break; - default: - break; - } - } - else if (spellInfo->Id == SPELL_CRUSADER_STRIKE) - { - if (_secondaryCheck) - { - switch (GetQuestCredits()) - { - case 0: - StartConversationWithPlayer(CONVERSATION_CRUSADER_STRIKE_ONE_PALADIN); - break; - case 1: - StartConversationWithPlayer(CONVERSATION_CRUSADER_STRIKE_TWO_PALADIN); - break; - case 2: - StartConversationWithPlayer(CONVERSATION_CRUSADER_STRIKE_THREE_PALADIN); - break; - default: - break; - } - _secondaryCheck = false; - _holyPowerCheck = true; - } - } - } - -private: - bool _secondaryCheck; - bool _holyPowerCheck; -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_rogue : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_rogue(Creature* creature) : npc_sparring_partner_combat_training(creature), _comboPointsCounter(0), _secondaryCheck(false), _comboPointCheck(false) { } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT); - _comboPointCheck = true; - _secondaryCheck = true; - } - - void JustEngagedWith(Unit* /*who*/) override - { - if (!GetQuestCredits()) - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_SINISTER_CHECK_ROGUE, 8s, 20s); - } - - void HandleClassEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_COMBAT_TRAINING_SINISTER_CHECK_ROGUE: - StartConversationWithPlayer(CONVERSATION_REGULAR_ATTACKS_ROGUE); - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_SINISTER_CHECK_ROGUE, 8s, 20s); - break; - case EVENT_COMBAT_CHECK_PLAYER: - { - if (_comboPointCheck) // Used by rogue - { - if (Unit* owner = me->GetDemonCreator()) - _comboPointsCounter = owner->GetPower(POWER_COMBO_POINTS); - - if (_comboPointsCounter >= (GetQuestCredits() + 3)) - { - switch (GetQuestCredits()) - { - case 0: - StartConversationWithPlayer(CONVERSATION_THREE_COMBO_POINTS_ROGUE); - break; - case 1: - StartConversationWithPlayer(CONVERSATION_FOUR_COMBO_POINTS_ROGUE); - break; - case 2: - StartConversationWithPlayer(CONVERSATION_FIVE_COMBO_POINTS_ROGUE); - break; - default: - break; - } - _comboPointCheck = false; - } - } - _events.ScheduleEvent(EVENT_COMBAT_CHECK_PLAYER, 500ms); - break; - } - default: - break; - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_EVISCERATE) - { - _comboPointCheck = true; - if (_comboPointsCounter >= (GetQuestCredits() + 3)) - { - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - - switch (GetQuestCredits()) - { - case 1: - StartConversationWithPlayer(CONVERSATION_THREE_COMBO_EVISCERATE_ROGUE); - _secondaryCheck = true; - break; - case 2: - StartConversationWithPlayer(CONVERSATION_FOUR_COMBO_EVISCERATE_ROGUE); - _secondaryCheck = true; - break; - case 3: - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - _events.CancelEvent(EVENT_COMBAT_CHECK_PLAYER); - break; - default: - break; - } - } - else - { - StartConversationWithPlayer(CONVERSATION_FAILED_EVISCERATE_ROGUE); - } - } - else if (spellInfo->Id == SPELL_SINISTER_STRIKE) - { - if (!GetQuestCredits()) - _events.RescheduleEvent(EVENT_COMBAT_TRAINING_SINISTER_CHECK_ROGUE, 8s, 20s); - - if (_secondaryCheck) - { - switch (GetQuestCredits()) - { - case 0: - StartConversationWithPlayer(CONVERSATION_SINISTER_STRIKE_ONE_ROGUE); - break; - case 1: - StartConversationWithPlayer(CONVERSATION_SINISTER_STRIKE_TWO_ROGUE); - break; - case 2: - StartConversationWithPlayer(CONVERSATION_SINISTER_STRIKE_THREE_ROGUE); - break; - default: - break; - } - _secondaryCheck = false; - } - } - } - -private: - uint8 _comboPointsCounter; - bool _secondaryCheck; - bool _comboPointCheck; -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_priest : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_priest(Creature* creature) : npc_sparring_partner_combat_training(creature), _shadowWordPainInPandemicWindow(false), _secondaryCheck(false) { } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT); - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_PRIEST); - me->CastSpell(me, SPELL_RANGED_ROOT_DNT); - _secondaryCheck = true; - } - - void HandleClassEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_COMBAT_TRAINING_SPELL_FADING: - { - Aura* aura = me->GetAura(SPELL_SHADOW_WORD_PAIN); - if (!aura) - break; - - if (!_shadowWordPainInPandemicWindow) - { - int32 pandemicDuration = CalculatePct(aura->GetMaxDuration(), 30.0f); - if (aura->GetDuration() <= pandemicDuration) - { - _shadowWordPainInPandemicWindow = true; - StartConversationWithPlayer(CONVERSATION_SHADOW_WORD_PAIN_FADING_PRIEST); - } - } - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_SPELL_FADING, 1s); - break; - } - default: - break; - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_SHADOW_WORD_PAIN) - { - if (_events.GetTimeUntilEvent(EVENT_COMBAT_TRAINING_SPELL_FADING) == Milliseconds::max()) - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_SPELL_FADING, 1s); - - if (!_shadowWordPainInPandemicWindow) - { - if (_secondaryCheck) - { - StartConversationWithPlayer(CONVERSATION_SHADOW_WORD_PAIN_PRE_COMBAT_PRIEST); - me->SetImmuneToPC(false); - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - me->RemoveAura(SPELL_RANGED_ROOT_DNT); - _secondaryCheck = false; - } - else - StartConversationWithPlayer(CONVERSATION_SHADOW_WORD_PAIN_TOO_SOON_PRIEST); - } - else - { - _shadowWordPainInPandemicWindow = false; - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - - if (player->GetQuestStatus(_questID) == QUEST_STATUS_COMPLETE) - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - else - StartConversationWithPlayer(CONVERSATION_SHADOW_WORD_PAIN_QUEST_CREDIT_PRIEST); - } - } - else if (spellInfo->Id == SPELL_SMITE) - { - if (_secondaryCheck) - StartConversationWithPlayer(CONVERSATION_SMITE_PRE_COMBAT_PRIEST); - } - } - -private: - bool _shadowWordPainInPandemicWindow; - bool _secondaryCheck; -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_shaman : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_shaman(Creature* creature) : npc_sparring_partner_combat_training(creature), _primalStrikeCounter(0), _secondaryCheck(false) { } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT); - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_SHAMAN); - me->CastSpell(me, SPELL_RANGED_ROOT_DNT); - _secondaryCheck = true; - } - - void HandleClassEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_COMBAT_TRAINING_RESET_SHAMAN: - if (Unit* owner = me->GetDemonCreator()) - { - me->CastSpell(owner, SPELL_KNOCKBACK); - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_AGGRO_CHECK_SHAMAN, 2s); - } - break; - case EVENT_COMBAT_TRAINING_AGGRO_CHECK_SHAMAN: - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_SHAMAN); - me->SetImmuneToPC(false); - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - _secondaryCheck = true; - break; - default: - break; - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_PRIMAL_STRIKE) - { - if (!player->IsWithinDist(me, 2.0f)) - return; - - ++_primalStrikeCounter; - - if (_primalStrikeCounter < 3) - { - if (_primalStrikeCounter == 1) - StartConversationWithPlayer(CONVERSATION_PRIMAL_STRIKE_FIRST_SHAMAN); - return; - } - - _primalStrikeCounter = 0; - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - - if (player->GetQuestStatus(_questID) == QUEST_STATUS_COMPLETE) - { - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - } - else - { - StartConversationWithPlayer(CONVERSATION_PRIMAL_STRIKE_QUEST_CREDIT_SHAMAN); - me->SetImmuneToPC(true); - me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_RESET_SHAMAN, 3s); - } - } - else if (spellInfo->Id == SPELL_LIGHTNING_BOLT) - { - me->RemoveAura(SPELL_RANGED_ROOT_DNT); - me->RemoveAura(SPELL_AGGRO_RADIUS_CHECK_DNT_SHAMAN); - if (_secondaryCheck) - { - StartConversationWithPlayer(CONVERSATION_LIGHTNINGBOLT_FIRST_SHAMAN); - _secondaryCheck = false; - } - else - { - if (player->IsWithinDist(me, 2.0f)) - StartConversationWithPlayer(CONVERSATION_LIGHTNINGBOLT_RANGE_SHAMAN); - } - } - } - -private: - uint8 _primalStrikeCounter; - bool _secondaryCheck; -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_mage : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_mage(Creature* creature) : npc_sparring_partner_combat_training(creature), _secondaryCheck(true) { } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT); - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_WARRIOR_MAGE); - me->CastSpell(me, SPELL_RANGED_ROOT_DNT); - _secondaryCheck = true; - } - - void HandleClassEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_COMBAT_TRAINING_RESET_MAGE: - if (Unit* owner = me->GetDemonCreator()) - { - me->CastSpell(owner, SPELL_KNOCKBACK); - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_AGGRO_CHECK_MAGE, 2s); - } - break; - case EVENT_COMBAT_TRAINING_AGGRO_CHECK_MAGE: - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_WARRIOR_MAGE); - me->SetImmuneToPC(false); - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - _secondaryCheck = true; - break; - default: - break; - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_FIRE_BLAST) - { - if (player->IsWithinDist(me, 2.0f)) - { - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - - if (player->GetQuestStatus(_questID) == QUEST_STATUS_COMPLETE) - { - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - } - else - { - StartConversationWithPlayer(CONVERSATION_FIRE_BLAST_QUEST_CREDIT_MAGE); - me->SetImmuneToPC(true); - me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_RESET_MAGE, 4s); - } - } - else - { - StartConversationWithPlayer(CONVERSATION_FIRE_BLAST_MAGE_NO_CREDIT); - } - } - else if (spellInfo->Id == SPELL_FROSTBOLT) - { - me->RemoveAura(SPELL_RANGED_ROOT_DNT); - me->RemoveAura(SPELL_AGGRO_RADIUS_CHECK_DNT_WARRIOR_MAGE); - if (_secondaryCheck) - { - StartConversationWithPlayer(CONVERSATION_FROSTBOLT_MAGE); - _secondaryCheck = false; - } - else - { - if (player->IsWithinDist(me, 2.0f)) - StartConversationWithPlayer(CONVERSATION_FROSTBOLT_CLOSE_MAGE); - } - } - } - -private: - bool _secondaryCheck; -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_warlock : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_warlock(Creature* creature) : npc_sparring_partner_combat_training(creature), _corruptionInPandemicWindow(false), _secondaryCheck(false) { } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT); - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_WARLOCK); - me->CastSpell(me, SPELL_RANGED_ROOT_DNT); - _secondaryCheck = true; - } - - void HandleClassEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_COMBAT_TRAINING_SPELL_FADING: - { - Aura* aura = me->GetAura(SPELL_CORRUPTION); - if (!aura) - break; - - if (!_corruptionInPandemicWindow) - { - int32 pandemicDuration = CalculatePct(aura->GetMaxDuration(), 30.0f); - if (aura->GetDuration() <= pandemicDuration) - { - _corruptionInPandemicWindow = true; - StartConversationWithPlayer(CONVERSATION_CORRUPTION_IS_FADING_WARLOCK); - } - } - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_SPELL_FADING, 1s); - break; - } - default: - break; - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_CORRUPTION) - { - if (_events.GetTimeUntilEvent(EVENT_COMBAT_TRAINING_SPELL_FADING) == Milliseconds::max()) - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_SPELL_FADING, 1s); - - if (!_corruptionInPandemicWindow) - { - if (_secondaryCheck) - { - StartConversationWithPlayer(CONVERSATION_CORRUPTION_CAST_PRE_COMBAT_WARLOCK); - me->SetImmuneToPC(false); - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - me->RemoveAura(SPELL_RANGED_ROOT_DNT); - _secondaryCheck = false; - } - else - StartConversationWithPlayer(CONVERSATION_CORRUPTION_CAST_TOO_SOON_WARLOCK); - } - else - { - _corruptionInPandemicWindow = false; - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - - if (player->GetQuestStatus(_questID) == QUEST_STATUS_COMPLETE) - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - else - StartConversationWithPlayer(CONVERSATION_CORRUPTION_QUEST_CREDIT_WARLOCK); - } - } - else if (spellInfo->Id == SPELL_SHADOWBOLT) - { - if (_secondaryCheck) - StartConversationWithPlayer(CONVERSATION_SHADOW_BOLT_PRE_COMBAT_WARLOCK); - } - } - -private: - bool _corruptionInPandemicWindow; - bool _secondaryCheck; -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_monk : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_monk(Creature* creature) : npc_sparring_partner_combat_training(creature) { } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT); - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_TIGER_PALM) - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - else if (spellInfo->Id == SPELL_BLACKOUT_KICK) - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED2); - - if (player->GetQuestStatus(_questID) == QUEST_STATUS_COMPLETE) - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - } -}; - -// 164577 - Alliance Sparring Partner -// 166916 - Horde Sparring Partner -struct npc_sparring_partner_enhanced_combat_training_druid : public npc_sparring_partner_combat_training -{ - npc_sparring_partner_enhanced_combat_training_druid(Creature* creature) : npc_sparring_partner_combat_training(creature), _hitByMoonfire(false), _moonfireInPandemicWindow(false) { } - - void OnReadyPointReached() override - { - StartConversationWithPlayer(CONVERSATION_READY_COMBAT); - me->CastSpell(me, SPELL_AGGRO_RADIUS_CHECK_DNT_DRUID); - me->CastSpell(me, SPELL_RANGED_ROOT_DNT); - _moonfireInPandemicWindow = false; - _hitByMoonfire = false; - } - - void HandleClassEvent(uint32 eventId) override - { - switch (eventId) - { - case EVENT_COMBAT_TRAINING_SPELL_FADING: - { - Aura* aura = me->GetAura(SPELL_MOONFIRE); - if (!aura) - break; - - if (!_moonfireInPandemicWindow) - { - int32 pandemicDuration = CalculatePct(aura->GetMaxDuration(), 30.0f); - if (aura->GetDuration() <= pandemicDuration) - { - _moonfireInPandemicWindow = true; - StartConversationWithPlayer(CONVERSATION_MOONFIRE_WEARING_OFF_DRUID); - } - } - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_SPELL_FADING, 1s); - break; - } - default: - break; - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - Player* player = caster->ToPlayer(); - if (!player) - return; - - if (spellInfo->Id == SPELL_MOONFIRE) - { - if (_events.GetTimeUntilEvent(EVENT_COMBAT_TRAINING_SPELL_FADING) == Milliseconds::max()) - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_SPELL_FADING, 1s); - - if (!_moonfireInPandemicWindow) - { - if (!_hitByMoonfire) - { - StartConversationWithPlayer(CONVERSATION_MOONFIRE_CAST_PRE_COMBAT_DRUID); - me->SetImmuneToPC(false); - me->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - me->RemoveAura(SPELL_RANGED_ROOT_DNT); - _hitByMoonfire = true; - } - else - StartConversationWithPlayer(CONVERSATION_MOONFIRE_CAST_TOO_SOON_DRUID); - } - else - { - _moonfireInPandemicWindow = false; - player->KilledMonsterCredit(NPC_ALLIANCE_SPARRING_PARTNER_ENHANCED); - - if (player->GetQuestStatus(_questID) == QUEST_STATUS_COMPLETE) - _events.ScheduleEvent(EVENT_COMBAT_TRAINING_END, 1s); - else - StartConversationWithPlayer(CONVERSATION_MOONFIRE_QUEST_CREDIT_DRUID); - } - } - else if (spellInfo->Id == SPELL_WRATH) - { - if (!_hitByMoonfire) - StartConversationWithPlayer(CONVERSATION_WRATH_PRE_COMBAT_DRUID); - } - } - -private: - bool _hitByMoonfire; - bool _moonfireInPandemicWindow; -}; - -CreatureAI* SparringPartnerEnhancedCombatTrainingSelector(Creature* creature) -{ - TempSummon* summon = creature->ToTempSummon(); - if (!summon) - return new NullCreatureAI(creature); - - Unit* summoner = summon->GetSummonerUnit(); - if (!summoner) - return new NullCreatureAI(creature); - - Player* player = summoner->ToPlayer(); - if (!player) - return new NullCreatureAI(creature); - - switch (player->GetClass()) - { - case CLASS_WARRIOR: - return new npc_sparring_partner_enhanced_combat_training_warrior(creature); - case CLASS_PALADIN: - return new npc_sparring_partner_enhanced_combat_training_paladin(creature); - case CLASS_ROGUE: - return new npc_sparring_partner_enhanced_combat_training_rogue(creature); - case CLASS_PRIEST: - return new npc_sparring_partner_enhanced_combat_training_priest(creature); - case CLASS_SHAMAN: - return new npc_sparring_partner_enhanced_combat_training_shaman(creature); - case CLASS_MAGE: - return new npc_sparring_partner_enhanced_combat_training_mage(creature); - case CLASS_WARLOCK: - return new npc_sparring_partner_enhanced_combat_training_warlock(creature); - case CLASS_MONK: - return new npc_sparring_partner_enhanced_combat_training_monk(creature); - case CLASS_DRUID: - return new npc_sparring_partner_enhanced_combat_training_druid(creature); - default: - return new NullCreatureAI(creature); - } - if (creature->IsPrivateObject()) - return new npc_survivors_beach_leave_private<PATH_KEE_LA_STANDING, 7 * IN_MILLISECONDS>(creature); - return new NullCreatureAI(creature); -}; - -struct at_aggro_radius_check_enhanced_combat_tactics : AreaTriggerAI -{ - at_aggro_radius_check_enhanced_combat_tactics(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - Unit* caster = at->GetCaster(); - if (!caster) - { - at->RemoveFromWorld(); - return; - } - - caster->SetFacingToObject(player); - - switch (player->GetClass()) - { - case CLASS_WARRIOR: - caster->CastSpell(player, SPELL_CHARGE_KNOCKBACK_WARRIOR); - break; - case CLASS_PRIEST: - case CLASS_SHAMAN: - case CLASS_MAGE: - case CLASS_WARLOCK: - caster->CastSpell(player, SPELL_CHARGE_KNOCKBACK); - break; - case CLASS_DRUID: - caster->CastSpell(player, SPELL_CHARGE_KNOCKBACK_DRUID); - break; - default: - break; - } - } -}; - -// 320605 - Charge Knockback (DNT) -class spell_knockback_charge_enhanced_training : public SpellScript -{ - void HandleLaunch(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - } - - void HandleEffect(SpellEffIndex effIndex) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - Player* player = GetHitUnit()->ToPlayer(); - if (!player) - return; - - Conversation* conversation = Conversation::CreateConversation(GetSpellInfo()->GetEffect(effIndex).MiscValue, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(ACTOR_ID_ALLIANCE_ENHANCED_TRAINING, 0, player->GetTeam() == ALLIANCE ? caster->GetGUID() : ObjectGuid::Empty); - conversation->AddActor(ACTOR_ID_HORDE_ENHANCED_TRAINING, 1, player->GetTeam() == ALLIANCE ? ObjectGuid::Empty : caster->GetGUID()); - conversation->Start(); - } - - void Register() override - { - OnEffectLaunchTarget += SpellEffectFn(spell_knockback_charge_enhanced_training::HandleLaunch, EFFECT_1, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - OnEffectHitTarget += SpellEffectFn(spell_knockback_charge_enhanced_training::HandleEffect, EFFECT_1, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - } -}; - -enum NorthboundData -{ - CONVERSATION_QUEST_NORTHBOUND_ACCEPT_ALLIANCE = 12066, - CONVERSATION_QUEST_NORTHBOUND_ACCEPT_HORDE = 14499, - - POINT_LEADER_RUN = 0, - - ACTOR_ID_0_NORTHBOUND_ACCEPT_ALLIANCE = 71310, - ACTOR_ID_1_NORTHBOUND_ACCEPT_ALLIANCE = 71297, - ACTOR_ID_0_NORTHBOUND_ACCEPT_HORDE = 79890, - ACTOR_ID_1_NORTHBOUND_ACCEPT_HORDE = 79888, - ACTOR_ID_0_NORTHBOUND_AREATRIGGER_ALLIANCE = 71317, - ACTOR_ID_1_NORTHBOUND_AREATRIGGER_HORDE = 76319, - - QUEST_NORTHBOND_ALLIANCE = 55173, - QUEST_NORTHBOND_HORDE = 59935, - - SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN_NORTHBOUND = 305660, - SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN_NORTHBOUND = 344382, - SPELL_LINGER_NORTHBOUND_ALLIANCE = 305665, - SPELL_LINGER_NORTHBOUND_HORDE = 344385, -}; - -static constexpr Position GarrickQuillboarBriarpatchPosition = { -142.62154f, -2641.0364f, 48.775497f }; -static constexpr Position GrimaxeQuillboarBriarpatchPosition = { -142.56076f, -2640.9915f, 48.755478f }; - -// 165360 - Alliance Survivor -// This script is used by Captian Garrick Follower for Northbound quest -struct npc_leader_northbound : public ScriptedAI -{ - npc_leader_northbound(Creature* creature) : ScriptedAI(creature), _conversationId(0), _actorIdOne(0), _actorIdTwo(0), _lingerSpellId(0), _guardianSpellId(0) {} - - void JustAppeared() override - { - Player* player = me->GetAffectingPlayer(); - if (!player) - return; - - player->UpdateVisibilityForPlayer(); - - Creature* survivor = FindCreatureIgnorePhase(player, player->GetTeam() == ALLIANCE ? "alaria_standing_abandoned_camp" : "wonza_standing_abandoned_camp", 5.0f); - if (!survivor) - return; - - if (player->GetTeam() == ALLIANCE) - { - _conversationId = CONVERSATION_QUEST_NORTHBOUND_ACCEPT_ALLIANCE; - _actorIdOne = ACTOR_ID_0_NORTHBOUND_ACCEPT_ALLIANCE; - _actorIdTwo = ACTOR_ID_1_NORTHBOUND_ACCEPT_ALLIANCE; - _runToPosition = GarrickQuillboarBriarpatchPosition; - _lingerSpellId = SPELL_LINGER_NORTHBOUND_ALLIANCE; - _guardianSpellId = SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN_NORTHBOUND; - } - else - { - _conversationId = CONVERSATION_QUEST_NORTHBOUND_ACCEPT_HORDE; - _actorIdOne = ACTOR_ID_0_NORTHBOUND_ACCEPT_HORDE; - _actorIdTwo = ACTOR_ID_1_NORTHBOUND_ACCEPT_HORDE; - _runToPosition = GrimaxeQuillboarBriarpatchPosition; - _lingerSpellId = SPELL_LINGER_NORTHBOUND_HORDE; - _guardianSpellId = SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN_NORTHBOUND; - } - - Conversation* conversation = Conversation::CreateConversation(_conversationId, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(0, 0, player->GetGUID()); - conversation->AddActor(_actorIdOne, 1, me->GetGUID()); - conversation->AddActor(_actorIdTwo, 2, survivor->GetGUID()); - conversation->Start(); - } - - void IsSummonedBy(WorldObject* /*summoner*/) override - { - _events.ScheduleEvent(EVENT_FOLLOW_PLAYER, 3s); - } - - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == _lingerSpellId) - { - me->GetMotionMaster()->Remove(FOLLOW_MOTION_TYPE); - me->GetMotionMaster()->MovePoint(POINT_LEADER_RUN, _runToPosition, false); - } - return; - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE) - return; - - if (uiId != POINT_LEADER_RUN) - return; - - me->SetFacingTo(6.0737457275390625); - - if (Player* player = me->GetAffectingPlayer()) - { - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->RemoveAura(_guardianSpellId); - player->UpdateVisibilityForPlayer(); - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_FOLLOW_PLAYER: - if (Player* player = me->GetAffectingPlayer()) - me->GetMotionMaster()->MoveFollow(player, 0.0f, float(M_PI / 4.0f)); - break; - default: - break; - } - } - } - -private: - EventMap _events; - uint32 _conversationId; - uint32 _actorIdOne; - uint32 _actorIdTwo; - Position _runToPosition; - uint32 _lingerSpellId; - uint32 _guardianSpellId; -}; - -// 55173 - Northbound -// 59935 - Northbound -class quest_northbound : public QuestScript -{ -public: - quest_northbound(char const* script) : QuestScript(script) { } - - void HandleQuestStatusChange(Player* player, QuestStatus newStatus, uint32 summonSpellId) - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, summonSpellId); - break; - case QUEST_STATUS_NONE: - player->RemoveAura(summonSpellId); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->UpdateVisibilityForPlayer(); - break; - default: - break; - } - } -}; - -// 55173 - Northbound -class quest_northbound_alliance : public quest_northbound -{ -public: - quest_northbound_alliance() : quest_northbound("quest_northbound_alliance") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN_NORTHBOUND); - } -}; - -// 59935 - Northbound -class quest_northbound_horde : public quest_northbound -{ -public: - quest_northbound_horde() : quest_northbound("quest_northbound_horde") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN_NORTHBOUND); - } -}; - -// 305661 - Summon Admiral Garrick Guardian Summons Alliance Entry: 165360 -// 344383 - Summon Admiral Garrick Guardian Summons Horde Entry: 175034 -class spell_summon_leader_northbound : public SpellScript -{ - // @TODO: drop after TARGET_UNK_142 impl - - void SelectTarget(WorldObject*& target) - { - Player* caster = GetCaster()->ToPlayer(); - if (!caster) - return; - - Creature* survivor = FindCreatureIgnorePhase(caster, caster->GetTeam() == ALLIANCE ? "garrick_camp" : "grimaxe_camp", 5.0f); - if (!survivor) - return; - - target = survivor; - } - - void Register() override - { - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_summon_leader_northbound::SelectTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY_OR_DB); - } -}; - -struct at_northbound_linger : AreaTriggerAI -{ - at_northbound_linger(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - if (player->GetTeam() == ALLIANCE) - { - if (player->GetQuestStatus(QUEST_NORTHBOND_ALLIANCE) != QUEST_STATUS_COMPLETE) - return; - - if (!player->HasAura(SPELL_SUMMON_ADMIRAL_GARRICK_GUARDIAN_NORTHBOUND)) - return; - - if (player->HasAura(SPELL_LINGER_NORTHBOUND_ALLIANCE)) - return; - - player->CastSpell(player, SPELL_LINGER_NORTHBOUND_ALLIANCE); - } - else - { - if (player->GetQuestStatus(QUEST_NORTHBOND_HORDE) != QUEST_STATUS_COMPLETE) - return; - - if (!player->HasAura(SPELL_SUMMON_WARLORD_GRIMAXE_GUARDIAN_NORTHBOUND)) - return; - - if (player->HasAura(SPELL_LINGER_NORTHBOUND_HORDE)) - return; - - player->CastSpell(player, SPELL_LINGER_NORTHBOUND_HORDE); - } - } -}; - -// @TODO: drop -// 305665 - Scene Linger (DNT) -// 344385 - Scene Linger (DNT) -class spell_scene_linger_northbound: public SpellScript -{ - void HandleLaunch(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - } - - void HandleEffect(SpellEffIndex effIndex) - { - Player* player = GetHitUnit()->ToPlayer(); - if (!player) - return; - - Creature* scout = FindCreatureIgnorePhase(player, player->GetTeam() == ALLIANCE ? "huxworth_briarpatch" : "dawntracker_briarpatch", 100.0f); - if (!scout) - return; - - Conversation* conversation = Conversation::CreateConversation(GetSpellInfo()->GetEffect(effIndex).MiscValue, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(ACTOR_ID_0_NORTHBOUND_AREATRIGGER_ALLIANCE, 0, player->GetTeam() == ALLIANCE ? scout->GetGUID() : ObjectGuid::Empty); - conversation->AddActor(ACTOR_ID_1_NORTHBOUND_AREATRIGGER_HORDE, 1, player->GetTeam() == ALLIANCE ? ObjectGuid::Empty : scout->GetGUID()); - conversation->Start(); - } - - void Register() override - { - OnEffectLaunchTarget += SpellEffectFn(spell_scene_linger_northbound::HandleLaunch, EFFECT_2, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - OnEffectHitTarget += SpellEffectFn(spell_scene_linger_northbound::HandleEffect, EFFECT_2, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - } -}; - -// *********************************************************************** -// * Scripting in this section occurs after reaching Quilboar Briarpatch * -// *********************************************************************** - -// Taming the Wild Quest -enum TamingTheWilds -{ - QUEST_TAMING_THE_WILDS_ALLIANCE = 59342, - QUEST_TAMING_THE_WILDS_HORDE = 59937, - QUEST_TRACKER_TAMING_THE_WILDS_COMPLETE = 55607, - - QUEST_OBJECTIVE_TRAINED_ALLIANCE = 84761, - QUEST_OBJECTIVE_TRAINED_HORDE = 85021, - QUEST_OBJECTIVE_BEAST_TAMED_ALLIANCE = 84759, - QUEST_OBJECTIVE_BEAST_TAMED_HORDE = 85023, - - SPELL_TAME_BEAST = 1515 -}; - -// 59342 - Taming the Wilds -// 59937 - Taming the Wilds -class quest_taming_the_wilds : public QuestScript -{ -public: - quest_taming_the_wilds(char const* script) : QuestScript(script) { } - - void HandleQuestStatusChange(Player* player, QuestStatus newStatus, std::string_view creatureString, uint32 questObjective1, uint32 questObjective2) - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - if (Creature* survivor = FindCreatureIgnorePhase(player, creatureString, 5.0f)) - survivor->SummonPersonalClone(survivor->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - - // Hacks QUEST_OBJECTIVE_CRITERIA_TREE needs research - if (player->HasSpell(SPELL_TAME_BEAST)) - player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_CRITERIA_TREE, questObjective1, 1); - - if (player->GetQuestStatus(QUEST_TRACKER_TAMING_THE_WILDS_COMPLETE) == QUEST_STATUS_REWARDED) - player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_CRITERIA_TREE, questObjective2, 1); - break; - default: - break; - } - } -}; - -// 59342 - Taming The Wild -class quest_taming_the_wilds_alliance : public quest_taming_the_wilds -{ -public: - quest_taming_the_wilds_alliance() : quest_taming_the_wilds("quest_taming_the_wilds_alliance") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, "huxworth_briarpatch", QUEST_OBJECTIVE_TRAINED_ALLIANCE, QUEST_OBJECTIVE_BEAST_TAMED_ALLIANCE); - } -}; - -// 59937 - Taming The Wild -class quest_taming_the_wilds_horde : public quest_taming_the_wilds -{ -public: - quest_taming_the_wilds_horde() : quest_taming_the_wilds("quest_taming_the_wilds_horde") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, "dawntracker_briarpatch", QUEST_OBJECTIVE_TRAINED_HORDE, QUEST_OBJECTIVE_BEAST_TAMED_HORDE); - } -}; - -enum TamingTheWildsData -{ - CONVERSATION_HORDE_TRAINER = 14613, - CONVERSATION_HORDE_ACTOR = 76440, - - EVENT_ME_TURN_TO_PLAYER = 1, - EVENT_ME_END_OF_CAST = 2, - - SPELL_TUTORIAL_HEALTH_DNT = 316840, - SPELL_LEARNING_TAME_BEAST = 320852, - SPELL_LEARN_TAME_BEAST = 320840, - SPELL_LEARN_CALL_PET = 320842, - SPELL_TAME_BEAST_EFFECT = 13481, - - SAY_PET_TRAINING_ALLIANCE = 0, - SAY_FIND_A_BEAST_ALLIANCE = 1, - SAY_FIND_A_BEAST_HORDE = 0 -}; - -// 154327 - Austin Huxsworth -struct npc_huxsworth_hunter_quest_private : public ScriptedAI -{ - npc_huxsworth_hunter_quest_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP); - } - - void JustAppeared() override - { - me->SetStandState(UNIT_STAND_STATE_STAND); - _events.ScheduleEvent(EVENT_ME_TURN_TO_PLAYER, 1s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_ME_TURN_TO_PLAYER: - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetPrivateObjectOwner())) - { - me->SetFacingToObject(player); - me->SetEmoteState(EMOTE_STATE_TALK); - Talk(SAY_PET_TRAINING_ALLIANCE); - player->CastSpell(player, SPELL_LEARNING_TAME_BEAST); - _events.ScheduleEvent(EVENT_ME_END_OF_CAST, 8s); - } - break; - case EVENT_ME_END_OF_CAST: - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetPrivateObjectOwner())) - { - if (player->GetQuestStatus(QUEST_TRACKER_TAMING_THE_WILDS_COMPLETE) != QUEST_STATUS_REWARDED) - player->CastSpell(player, SPELL_TUTORIAL_HEALTH_DNT); - - if (!player->HasSpell(SPELL_TAME_BEAST)) - { - player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_CRITERIA_TREE, QUEST_OBJECTIVE_TRAINED_ALLIANCE, 1); - player->CastSpell(player, SPELL_LEARN_TAME_BEAST); - player->CastSpell(player, SPELL_LEARN_CALL_PET); - } - - me->SetEmoteState(EMOTE_STATE_NONE); - Talk(SAY_FIND_A_BEAST_ALLIANCE); - } - me->DespawnOrUnsummon(4s); - break; - default: - break; - } - } - } - -private: - EventMap _events; -}; - -enum HuxsworthBriarpatchData -{ - CONVERSATION_BRIARPATCH_ALLIANCE = 12073, - - CONVERSATION_ACTOR_GARRICK_BRIARPATCH = 71326, - CONVERSATION_ACTOR_HUXSWORTH_BRIARPATCH = 71327, - - EVENT_HUXSWORTH_GARRICK_CONVERSATION = 1, - EVENT_HUXSWORTH_GARRICK_RUN_BRIARPATCH = 2, -}; - -static constexpr Position GarrickBriarpatchDespawnPosition = { -112.92383f, -2640.541f, 52.35042f }; -static constexpr Position HuxworthBriarpatchDespawnPosition = { -112.61979f, -2645.9775f, 52.22835f }; - -// 154327 - Austin Huxsworth -struct npc_huxsworth_briarpatch_quest_private : public ScriptedAI -{ - npc_huxsworth_briarpatch_quest_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP); - } - - void JustAppeared() override - { - me->SetStandState(UNIT_STAND_STATE_STAND); - if (Creature* garrick = ObjectAccessor::GetCreature(*me, _garrickGUID)) - garrick->SetStandState(UNIT_STAND_STATE_STAND); - - _events.ScheduleEvent(EVENT_HUXSWORTH_GARRICK_CONVERSATION, 2s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_HUXSWORTH_GARRICK_CONVERSATION: - { - if (Unit* player = ObjectAccessor::GetPlayer(*me, me->GetPrivateObjectOwner())) - { - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_BRIARPATCH_ALLIANCE, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - break; - - conversation->AddActor(CONVERSATION_ACTOR_GARRICK_BRIARPATCH, 0, _garrickGUID); - conversation->AddActor(CONVERSATION_ACTOR_HUXSWORTH_BRIARPATCH, 1, me->GetGUID()); - conversation->Start(); - _events.ScheduleEvent(EVENT_HUXSWORTH_GARRICK_RUN_BRIARPATCH, 13s); - } - break; - } - case EVENT_HUXSWORTH_GARRICK_RUN_BRIARPATCH: - if (Creature* garrick = ObjectAccessor::GetCreature(*me, _garrickGUID)) - { - garrick->GetMotionMaster()->MovePoint(0, GarrickBriarpatchDespawnPosition); - garrick->DespawnOrUnsummon(3s); - } - me->GetMotionMaster()->MovePoint(0, HuxworthBriarpatchDespawnPosition); - me->DespawnOrUnsummon(3s); - break; - default: - break; - } - } - } - -public: - void SetGarrickGUID(ObjectGuid garrickGUID) - { - _garrickGUID = garrickGUID; - } - -private: - EventMap _events; - ObjectGuid _garrickGUID; -}; - -// 166996 - Mithdran Dawntracker -struct npc_dawntracker_hunter_quest_private : public ScriptedAI -{ - npc_dawntracker_hunter_quest_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP); - } - - void JustAppeared() override - { - me->SetStandState(UNIT_STAND_STATE_STAND); - _events.ScheduleEvent(EVENT_ME_TURN_TO_PLAYER, 1s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_ME_TURN_TO_PLAYER: - if (Unit* player = ObjectAccessor::GetPlayer(*me, me->GetPrivateObjectOwner())) - { - me->SetFacingToObject(player); - me->SetEmoteState(EMOTE_STATE_TALK); - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_HORDE_TRAINER, player, *player, player->GetGUID(), nullptr, false); - if (conversation) - { - conversation->AddActor(CONVERSATION_HORDE_ACTOR, 0, me->GetGUID()); - conversation->Start(); - } - player->CastSpell(player, SPELL_LEARNING_TAME_BEAST); - _events.ScheduleEvent(EVENT_ME_END_OF_CAST, 8s); - } - break; - case EVENT_ME_END_OF_CAST: - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetPrivateObjectOwner())) - { - if (player->GetQuestStatus(QUEST_TRACKER_TAMING_THE_WILDS_COMPLETE) != QUEST_STATUS_REWARDED) - player->CastSpell(player, SPELL_TUTORIAL_HEALTH_DNT); - - if (!player->HasSpell(SPELL_TAME_BEAST)) - { - player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_CRITERIA_TREE, QUEST_OBJECTIVE_TRAINED_HORDE, 1); - player->CastSpell(player, SPELL_LEARN_TAME_BEAST); - player->CastSpell(player, SPELL_LEARN_CALL_PET); - } - } - me->SetEmoteState(EMOTE_STATE_NONE); - Talk(SAY_FIND_A_BEAST_HORDE); - me->DespawnOrUnsummon(4s); - break; - default: - break; - } - } - } - -private: - EventMap _events; -}; - -enum DawntrackerBriarpatch -{ - CONVERSATION_BRIARPATCH_HORDE = 14513, - - CONVERSATION_ACTOR_GRIMAXE_BRIARPATCH = 76330, - CONVERSATION_ACTOR_DAWNTRACKER_BRIARPATCH = 76331, - - EVENT_DAWNTRACKER_GRIMAXE_CONVERSATION = 1, - EVENT_DAWNTRACKER_GRIMAXE_RUN_BRIARPATCH = 2, -}; - -static constexpr Position GrimaxeBriarpatchDespawnPosition = { -112.92383f, -2640.541f, 52.35042f }; -static constexpr Position DawntrackerBriarpatchDespawnPosition = { -112.61979f, -2645.9775f, 52.22835f }; - -// 166996 - Mithdran Dawntracker -struct npc_dawntracker_briarpatch_quest_private : public ScriptedAI -{ - npc_dawntracker_briarpatch_quest_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP); - } - - void JustAppeared() override - { - me->SetStandState(UNIT_STAND_STATE_STAND); - if (Creature* grimaxe = ObjectAccessor::GetCreature(*me, _grimaxeGUID)) - grimaxe->SetStandState(UNIT_STAND_STATE_STAND); - - _events.ScheduleEvent(EVENT_DAWNTRACKER_GRIMAXE_CONVERSATION, 2s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_DAWNTRACKER_GRIMAXE_CONVERSATION: - { - if (Unit* player = ObjectAccessor::GetPlayer(*me, me->GetPrivateObjectOwner())) - { - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_BRIARPATCH_HORDE, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - break; - - conversation->AddActor(CONVERSATION_ACTOR_GRIMAXE_BRIARPATCH, 0, _grimaxeGUID); - conversation->AddActor(CONVERSATION_ACTOR_DAWNTRACKER_BRIARPATCH, 1, me->GetGUID()); - conversation->Start(); - _events.ScheduleEvent(EVENT_HUXSWORTH_GARRICK_RUN_BRIARPATCH, 13s); - } - break; - } - case EVENT_DAWNTRACKER_GRIMAXE_RUN_BRIARPATCH: - if (Creature* grimaxe = ObjectAccessor::GetCreature(*me, _grimaxeGUID)) - { - grimaxe->GetMotionMaster()->MovePoint(0, GrimaxeBriarpatchDespawnPosition ); - grimaxe->DespawnOrUnsummon(2s); - } - me->GetMotionMaster()->MovePoint(0, DawntrackerBriarpatchDespawnPosition); - me->DespawnOrUnsummon(2s); - break; - default: - break; - } - } - } - -public: - void SetGrimaxeGUID(ObjectGuid grimaxeGUID) - { - _grimaxeGUID = grimaxeGUID; - } - -private: - EventMap _events; - ObjectGuid _grimaxeGUID; -}; - -CreatureAI* HuxsworthBriarpatchSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if (privateObjectOwner->GetQuestStatus(QUEST_TAMING_THE_WILDS_ALLIANCE) == QUEST_STATUS_INCOMPLETE) - return new npc_huxsworth_hunter_quest_private(creature); - else - return new npc_huxsworth_briarpatch_quest_private(creature); - } - } - return new NullCreatureAI(creature); -}; - -CreatureAI* DawntrackerBriarpatchSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if (privateObjectOwner->GetQuestStatus(QUEST_TAMING_THE_WILDS_HORDE) == QUEST_STATUS_INCOMPLETE) - return new npc_dawntracker_hunter_quest_private(creature); - else - return new npc_dawntracker_briarpatch_quest_private(creature); - } - } - return new NullCreatureAI(creature); -}; - -// 316840 - Tutorial - Health (DNT) -class spell_tutorial_health_dnt_proc_aura : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_TAME_BEAST_EFFECT }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetSpellInfo() && eventInfo.GetSpellInfo()->Id == SPELL_TAME_BEAST_EFFECT) - return true; - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_tutorial_health_dnt_proc_aura::CheckProc); - } -}; - -// 316841 - Tutorial - Health (DNT) -class spell_tutorial_health_dnt : public SpellScript -{ - void HandleScript(SpellEffIndex /*effIndex*/) - { - // This shouldn't happen until tame beast spell completes - if (Player* player = GetCaster()->ToPlayer()) - { - if (player->GetTeam() == ALLIANCE) - player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_CRITERIA_TREE, QUEST_OBJECTIVE_BEAST_TAMED_ALLIANCE, 1); - else - player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_CRITERIA_TREE, QUEST_OBJECTIVE_BEAST_TAMED_HORDE, 1); - } - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_tutorial_health_dnt::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } -}; - -enum QuilboarQuest -{ - QUEST_DOWN_WITH_THE_QUILBOAR_ALLIANCE = 55186, - QUEST_FORBIDDEN_QUILBOAR_NECROMANY_ALLIANCE = 55184, - QUEST_DOWN_WITH_THE_QUILBOAR_HORDE = 59938, - QUEST_FORBIDDEN_QUILBOAR_NECROMANY_HORDE = 59939, - - SPELL_VALIDATED_QUEST_ACCEPT_BRIARPATCH_ALLIANCE = 298984, - SPELL_VALIDATED_QUEST_ACCEPT_BRIARPATCH_HORDE = 325309 -}; - -// 55186 - Quest Down with the Quilboar "Alliance" -// 55184 - Forbidden Quilboar Necromancy "Alliance" -// 59938 - Quest Down with the Quilboar "Horde" -// 59939 - Forbidden Quilboar Necromancy "Horde" -class quest_briarpatch : public QuestScript -{ -public: - quest_briarpatch(char const* script) : QuestScript(script) { } - - void HandleQuestStatusChange(Player* player, QuestStatus newStatus, uint32 questDown, uint32 questForbidden, uint32 spellValidated) - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - if (player->GetQuestStatus(questDown) != QUEST_STATUS_NONE && player->GetQuestStatus(questForbidden) != QUEST_STATUS_NONE) - { - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, spellValidated); - } - break; - case QUEST_STATUS_NONE: - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - default: - break; - } - } -}; - -// 55186 - Quest Down with the Quilboar "Alliance" -// 55184 - Forbidden Quilboar Necromancy "Alliance" -class quest_briarpatch_alliance : public quest_briarpatch -{ -public: - quest_briarpatch_alliance() : quest_briarpatch("quest_briarpatch_alliance") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, QUEST_DOWN_WITH_THE_QUILBOAR_ALLIANCE, QUEST_FORBIDDEN_QUILBOAR_NECROMANY_ALLIANCE, SPELL_VALIDATED_QUEST_ACCEPT_BRIARPATCH_ALLIANCE); - } -}; - -// 59938 - Quest Down with the Quilboar "Horde" -// 59939 - Forbidden Quilboar Necromancy "Horde" -class quest_briarpatch_horde : public quest_briarpatch -{ -public: - quest_briarpatch_horde() : quest_briarpatch("quest_briarpatch_horde") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, QUEST_DOWN_WITH_THE_QUILBOAR_HORDE, QUEST_FORBIDDEN_QUILBOAR_NECROMANY_HORDE, SPELL_VALIDATED_QUEST_ACCEPT_BRIARPATCH_HORDE); - } -}; - -// 298984 - Validated Quest Accept -class spell_validated_quest_accept_briarpatch_alliance : public SpellScript -{ - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (Player* player = GetCaster()->ToPlayer()) - { - Creature* huxsworth = FindCreatureIgnorePhase(player, "huxworth_briarpatch", 10.0f); - Creature* garrick = FindCreatureIgnorePhase(player, "garrick_briarpatch", 10.0f); - if (!huxsworth || !garrick) - return; - - Creature* huxsworthPersonal = huxsworth->SummonPersonalClone(huxsworth->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - Creature* garrickPersonal = garrick->SummonPersonalClone(garrick->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!huxsworthPersonal || !garrickPersonal) - return; - - if (npc_huxsworth_briarpatch_quest_private* huxworthAI = CAST_AI(npc_huxsworth_briarpatch_quest_private, huxsworthPersonal->AI())) - huxworthAI->SetGarrickGUID(garrickPersonal->GetGUID()); - } - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_validated_quest_accept_briarpatch_alliance::HandleScript, EFFECT_0, SPELL_EFFECT_SEND_EVENT); - } -}; - -// 325309 - Validated Quest Accept -class spell_validated_quest_accept_briarpatch_horde : public SpellScript -{ - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (Player* player = GetCaster()->ToPlayer()) - { - Creature* dawntracker = FindCreatureIgnorePhase(player, "dawntracker_briarpatch", 10.0f); - Creature* grimaxe = FindCreatureIgnorePhase(player, "grimaxe_briarpatch", 10.0f); - if (!dawntracker || !grimaxe) - return; - - Creature* dawntrackerPersonal = dawntracker->SummonPersonalClone(dawntracker->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - Creature* grimaxePersonal = grimaxe->SummonPersonalClone(grimaxe->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!dawntrackerPersonal || !grimaxePersonal) - return; - - if (npc_dawntracker_briarpatch_quest_private* dawntrackerAI = CAST_AI(npc_dawntracker_briarpatch_quest_private, dawntrackerPersonal->AI())) - dawntrackerAI->SetGrimaxeGUID(grimaxePersonal->GetGUID()); - } - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_validated_quest_accept_briarpatch_horde::HandleScript, EFFECT_0, SPELL_EFFECT_SEND_EVENT); - } -}; - -enum GeolordData -{ - CONVERSATION_GEOLORD_AGGRO = 13712, - - CONVERSATION_ACTOR_GEOLORD = 70670, - CONVERSATION_ACTOR_LINDIE = 71238, - CONVERSATION_ACTOR_CORK = 75976, - - EVENT_CAST_EARTH_BOLT = 1, - EVENT_CAST_UPHEAVAL = 2, - - NPC_CORK_FIZZLEPOP = 167008, - NPC_LINDIE_SPRINGSTOCK = 154301, - NPC_INVIS_BUNNY_GEOLORD = 155371, - - ACTION_FREE_PRISONER = 1, - - SPELL_NECROTIC_RITUAL_DNT = 305513, - SPELL_EARTH_BOLT = 270453, - SPELL_UPHEAVAL = 319273, - - WORLDSTATE_HORDE = 4486 -}; - -static constexpr Position PrisonerPosition = { 16.4271f, -2511.82f, 78.8215f, 5.66398f }; - -// 151091 - Geolord Grek'og -struct npc_geolord_grekog : public ScriptedAI -{ - npc_geolord_grekog(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - uint32 prisonerEntry = NPC_LINDIE_SPRINGSTOCK; - - if (sWorldStateMgr->GetValue(WORLDSTATE_HORDE, me->GetMap()) == 1) - prisonerEntry = NPC_CORK_FIZZLEPOP; - - Creature* bunny = me->FindNearestCreatureWithOptions(25.0f, { .CreatureId = NPC_INVIS_BUNNY_GEOLORD, .IgnorePhases = true }); - if (!bunny) - return; - - if (Creature* prisoner = bunny->SummonCreature(prisonerEntry, PrisonerPosition, TEMPSUMMON_MANUAL_DESPAWN)) - _prisonerGUID = prisoner->GetGUID(); - } - - void JustDied(Unit* /*killer*/) override - { - if (Creature* prisoner = ObjectAccessor::GetCreature(*me, _prisonerGUID)) - prisoner->AI()->DoAction(ACTION_FREE_PRISONER); - } - - void JustEngagedWith(Unit* who) override - { - if (Player* player = who->ToPlayer()) - { - Conversation::CreateConversation(CONVERSATION_GEOLORD_AGGRO, player, *player, player->GetGUID(), nullptr, true); - - _events.ScheduleEvent(EVENT_CAST_EARTH_BOLT, 3s, 5s); - _events.ScheduleEvent(EVENT_CAST_UPHEAVAL, 10s, 15s); - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CAST_EARTH_BOLT: - { - DoCastVictim(SPELL_EARTH_BOLT); - _events.ScheduleEvent(EVENT_CAST_EARTH_BOLT, 10s, 12s); - break; - } - case EVENT_CAST_UPHEAVAL: - { - DoCastSelf(SPELL_UPHEAVAL); - _events.ScheduleEvent(EVENT_CAST_UPHEAVAL, 10s, 15s); - break; - } - default: - break; - } - } - } -private: - EventMap _events; - ObjectGuid _prisonerGUID; -}; - -enum BriarpatchPrisonerData -{ - EVENT_RUN_TO_PLAINS = 1, - - SAY_GET_OUT_OF_HERE = 0 -}; - -static constexpr Position BriarpatchPrisonerJumpToPosition = { 19.5174f, -2513.75f, 74.0545f }; -static constexpr Position PrisonerBriarpatchDespawnPosition = { 51.005207f, -2485.644f, 78.15223f }; - -// 167008 - Cork Fizzlepop -// 154301 - Lindie Springstock -struct npc_briarpatch_prisoner : public ScriptedAI -{ - npc_briarpatch_prisoner(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - me->SetDisableGravity(true); - me->SetControlled(true, UNIT_STATE_ROOT); - me->CastSpell(me, SPELL_NECROTIC_RITUAL_DNT); - } - - void DoAction(int32 param) override - { - if (param == ACTION_FREE_PRISONER) - { - me->RemoveAllAuras(); - me->SetDisableGravity(false); - me->SetControlled(false, UNIT_STATE_ROOT); - me->GetMotionMaster()->MoveJump(BriarpatchPrisonerJumpToPosition, 7.9894905f, 19.29110336303710937f); - Talk(SAY_GET_OUT_OF_HERE); - _events.ScheduleEvent(EVENT_RUN_TO_PLAINS, 4s); - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_RUN_TO_PLAINS: - me->GetMotionMaster()->MovePoint(0, PrisonerBriarpatchDespawnPosition); - me->DespawnOrUnsummon(5s); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -enum OgreOverseerQuilboarText -{ - SAY_AGGRO = 0, - SAY_DEATH = 1, -}; - -enum ExilesReachQuilboarData -{ - ITEM_STITCHED_CLOTH_TUNIC = 174811, - ITEM_STITCHED_LEATHER_TUNIC = 174812, - ITEM_LINKED_MAIL_HAUBERK = 174813, - ITEM_DENTED_CHESTPLATE = 174814, - - QUEST_BRIARPATCH_CHEST_DROPPED = 58904 -}; - -enum QuilboarWarriorGeomancerData -{ - EVENT_BRUTAL_STRIKE = 1, - EVENT_GEOMANCER_EARTH_BOLT = 1, - - SPELL_NECROTIC_BURST = 313261, - SPELL_QUILBOAR_SLEEP_DNT = 313265, - SPELL_BRUTAL_STRIKE = 317383, - SPELL_GEOMANCER_EARTH_BOLT = 321188 -}; - -// 150237 - Quilboar Warrior -struct npc_quilboar_warrior : public ScriptedAI -{ - npc_quilboar_warrior(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* who) override - { - me->RemoveAura(SPELL_QUILBOAR_SLEEP_DNT); - - if (roll_chance_f(33.33f)) - Talk(SAY_AGGRO, who); - - _events.ScheduleEvent(EVENT_BRUTAL_STRIKE, 3s, 5s); - } - - void JustDied(Unit* killer) override - { - if (roll_chance_f(33.33f)) - Talk(SAY_DEATH, killer); - - for (auto const& [playerGuid, loot] : me->m_personalLoot) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, playerGuid)) - { - if (player->IsQuestRewarded(QUEST_BRIARPATCH_CHEST_DROPPED)) - break; - - for (LootItem const& lootItem : loot->items) - { - if (lootItem.itemid == ITEM_STITCHED_CLOTH_TUNIC || lootItem.itemid == ITEM_STITCHED_LEATHER_TUNIC || lootItem.itemid == ITEM_LINKED_MAIL_HAUBERK || lootItem.itemid == ITEM_DENTED_CHESTPLATE) - { - player->SetRewardedQuest(QUEST_BRIARPATCH_CHEST_DROPPED); - break; - } - } - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BRUTAL_STRIKE: - DoCastVictim(SPELL_BRUTAL_STRIKE); - _events.ScheduleEvent(EVENT_BRUTAL_STRIKE, 8s, 12s); - break; - default: - break; - } - } - } - -private: - EventMap _events; -}; - -// 150238 - Quilboar Geomancer -struct npc_quilboar_geomancer : public ScriptedAI -{ - npc_quilboar_geomancer(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* who) override - { - me->RemoveAura(SPELL_QUILBOAR_SLEEP_DNT); - - if (roll_chance_f(33.33f)) - Talk(SAY_AGGRO, who); - - _events.ScheduleEvent(EVENT_GEOMANCER_EARTH_BOLT, 3s, 5s); - } - - void JustDied(Unit* killer) override - { - if (roll_chance_f(33.33f)) - Talk(SAY_DEATH, killer); - - for (auto const& [playerGuid, loot] : me->m_personalLoot) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, playerGuid)) - { - if (player->IsQuestRewarded(QUEST_BRIARPATCH_CHEST_DROPPED)) - break; - - for (LootItem const& lootItem : loot->items) - { - if (lootItem.itemid == ITEM_STITCHED_CLOTH_TUNIC || lootItem.itemid == ITEM_STITCHED_LEATHER_TUNIC || lootItem.itemid == ITEM_LINKED_MAIL_HAUBERK || lootItem.itemid == ITEM_DENTED_CHESTPLATE) - { - player->SetRewardedQuest(QUEST_BRIARPATCH_CHEST_DROPPED); - break; - } - } - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_GEOMANCER_EARTH_BOLT: - DoCastVictim(SPELL_GEOMANCER_EARTH_BOLT); - _events.ScheduleEvent(EVENT_GEOMANCER_EARTH_BOLT, 3s, 10s); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -enum ExilesReachOgreOverseerData -{ - EVENT_OVERSEER_BACKHAND = 1, - EVENT_OVERSEER_EARTHSHATTER = 2, - - ITEM_BATTERED_CLOAK = 11847, - ITEM_OVERSEERS_MANDATE = 174790, - - QUEST_BRIARPATCH_OVERSEER_CLOAK_DROPPED = 56051, - - SPELL_BACKHAND = 276991, - SPELL_EARTHSHATTER = 319292 -}; - -// 156676 - Ogre Overseer -struct npc_ogre_overseer : public ScriptedAI -{ - npc_ogre_overseer(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* who) override - { - Talk(SAY_AGGRO, who); - - _events.ScheduleEvent(EVENT_OVERSEER_BACKHAND, 5s); - _events.ScheduleEvent(EVENT_OVERSEER_EARTHSHATTER, 10s, 15s); - } - - void JustDied(Unit* killer) override - { - Talk(SAY_DEATH, killer); - - for (auto const& [playerGuid, loot] : me->m_personalLoot) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, playerGuid)) - { - if (player->IsQuestRewarded(QUEST_BRIARPATCH_OVERSEER_CLOAK_DROPPED)) - break; - - for (LootItem const& lootItem : loot->items) - { - if (lootItem.itemid == ITEM_BATTERED_CLOAK) - { - player->SetRewardedQuest(QUEST_BRIARPATCH_OVERSEER_CLOAK_DROPPED); - break; - } - } - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_OVERSEER_BACKHAND: - DoCastVictim(SPELL_BACKHAND); - _events.ScheduleEvent(EVENT_OVERSEER_BACKHAND, 15s, 20s); - break; - case EVENT_OVERSEER_EARTHSHATTER: - DoCastAOE(SPELL_EARTHSHATTER); - _events.ScheduleEvent(EVENT_OVERSEER_EARTHSHATTER, 15s, 20s); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -enum BriarpathPlainsConversations -{ - CONVERSATION_DOWN_WITH_THE_QUILLBOAR_COMPLETE_ALLIANCE = 12076, - CONVERSATION_DOWN_WITH_THE_QUILLBOAR_COMPLETE_HORDE = 14514 -}; - -struct at_briarpatch_to_plains : AreaTriggerAI -{ - at_briarpatch_to_plains(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - // @TODO: remove when conversation cooldown is implemented - void StartConversation(Player* player, uint32 conversationId) - { - std::vector<WorldObject*> objs; - - Trinity::ObjectEntryAndPrivateOwnerIfExistsCheck check(player->GetGUID(), conversationId); - Trinity::WorldObjectListSearcher<Trinity::ObjectEntryAndPrivateOwnerIfExistsCheck> checker(nullptr, objs, check, GRID_MAP_TYPE_MASK_CONVERSATION); - Cell::VisitGridObjects(player, checker, 100.0f); - - if (objs.empty()) - Conversation::CreateConversation(conversationId, player, *player, player->GetGUID(), nullptr); - } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player) - return; - - if (player->GetTeam() == ALLIANCE) - { - if (player->GetQuestStatus(QUEST_DOWN_WITH_THE_QUILBOAR_ALLIANCE) != QUEST_STATUS_COMPLETE) - return; - - StartConversation(player, CONVERSATION_DOWN_WITH_THE_QUILLBOAR_COMPLETE_ALLIANCE); - } - else - { - if (player->GetQuestStatus(QUEST_DOWN_WITH_THE_QUILBOAR_HORDE) != QUEST_STATUS_COMPLETE) - return; - - StartConversation(player, CONVERSATION_DOWN_WITH_THE_QUILLBOAR_COMPLETE_HORDE); - } - } -}; - -class spell_quilboar_sleep_dnt : public AuraScript -{ - void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) - { - if (Creature* target = GetTarget()->ToCreature()) - target->SetReactState(REACT_PASSIVE); - } - - void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/) - { - if (Creature* target = GetTarget()->ToCreature()) - { - target->SetReactState(REACT_AGGRESSIVE); - target->SetStandState(UNIT_STAND_STATE_STAND); - } - } - - void Register() override - { - OnEffectRemove += AuraEffectRemoveFn(spell_quilboar_sleep_dnt::RemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - AfterEffectApply += AuraEffectApplyFn(spell_quilboar_sleep_dnt::ApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// ************************************************************** -// * Scripting in this section occurs after reaching The Plains * -// ************************************************************** - -enum LindieSpringStockData -{ - CONVERSATION_RESIZE_COPTER_ALLIANCE = 12078, - CONVERSATION_RESIZE_COPTER_HORDE = 14516, - - CONVERSATION_ACTOR_GOBLIN_ALLIANCE = 71345, - CONVERSATION_ACTOR_GOBLIN_HORDE = 76337, - CONVERSATION_ACTOR_COPTER = 71344, - - EVENT_CONVERSATION = 1, - EVENT_RESIZE_COPTER_1 = 2, - EVENT_RESIZE_COPTER_2 = 3, - EVENT_RESIZE_COPTER_3 = 4, - EVENT_RESIZE_COPTER_4 = 5, - EVENT_RESIZE_COPTER_5 = 6, - EVENT_RESIZE_COPTER_6 = 7, - - NPC_LINDIE_SPRINGSTOCK_PLAINS = 149899, - - QUEST_THE_SCOUT_O_MATIC_5000 = 55193, - QUEST_THE_CHOPPY_BOOSTER_MK5 = 59940, - - SPELL_RE_SIZING = 313269, - SPELL_GROW_ONE = 129310, - SPELL_GROW_TWO = 94214, - SPELL_GROW_THREE = 111701 -}; - -static constexpr Position MiniChopperJumpPosition = { 107.979f, -2414.13f, 95.6243f }; - -// 149899 - Lindie Springstock -// 167019 - Cork Fizzlepop -struct npc_gnome_goblin_plains_make_copter_private : public ScriptedAI -{ - npc_gnome_goblin_plains_make_copter_private(Creature* creature) : ScriptedAI(creature), _conversationId(0), _conversationActorId(0), _timer(0ms) { } - - void JustAppeared() override - { - if (me->GetEntry() == NPC_LINDIE_SPRINGSTOCK_PLAINS) - { - _conversationId = CONVERSATION_RESIZE_COPTER_ALLIANCE; - _conversationActorId = CONVERSATION_ACTOR_GOBLIN_ALLIANCE; - _timer = 1350ms; - } - else - { - _conversationId = CONVERSATION_RESIZE_COPTER_HORDE; - _conversationActorId = CONVERSATION_ACTOR_GOBLIN_HORDE; - _timer = 750ms; - } - - _events.ScheduleEvent(EVENT_CONVERSATION, 1s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CONVERSATION: - { - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetPrivateObjectOwner())) - { - Conversation* conversation = Conversation::CreateConversation(_conversationId, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - break; - - conversation->AddActor(_conversationActorId, 0, me->GetGUID()); - conversation->AddActor(CONVERSATION_ACTOR_COPTER, 1, _copterGUID); - conversation->Start(); - } - - if (Creature* copter = ObjectAccessor::GetCreature(*me, _copterGUID)) - copter->GetMotionMaster()->MoveJump(MiniChopperJumpPosition, 19.29f, 6.99f); - - _events.ScheduleEvent(EVENT_RESIZE_COPTER_1, 6s); - break; - } - case EVENT_RESIZE_COPTER_1: - { - if (Creature* copter = ObjectAccessor::GetCreature(*me, _copterGUID)) - { - me->SetFacingTo(0.488383f); - me->CastSpell(copter, SPELL_RE_SIZING); - copter->CastSpell(copter, SPELL_GROW_ONE); - } - _events.ScheduleEvent(EVENT_RESIZE_COPTER_2, 2s); - break; - } - case EVENT_RESIZE_COPTER_2: - { - if (Creature* copter = ObjectAccessor::GetCreature(*me, _copterGUID)) - copter->RemoveAura(SPELL_GROW_ONE); - - _events.ScheduleEvent(EVENT_RESIZE_COPTER_3, _timer); - break; - } - case EVENT_RESIZE_COPTER_3: - { - if (Creature* copter = ObjectAccessor::GetCreature(*me, _copterGUID)) - copter->CastSpell(copter, SPELL_GROW_TWO); - - _events.ScheduleEvent(EVENT_RESIZE_COPTER_4, _timer); - break; - } - case EVENT_RESIZE_COPTER_4: - { - if (Creature* copter = ObjectAccessor::GetCreature(*me, _copterGUID)) - copter->RemoveAura(SPELL_GROW_TWO); - - _events.ScheduleEvent(EVENT_RESIZE_COPTER_5, _timer); - break; - } - case EVENT_RESIZE_COPTER_5: - { - if (Creature* copter = ObjectAccessor::GetCreature(*me, _copterGUID)) - copter->CastSpell(copter, SPELL_GROW_THREE); - - me->CastStop(SPELL_RE_SIZING); - me->SetFacingTo(4.50382f); - me->DespawnOrUnsummon(27s); - _events.ScheduleEvent(EVENT_RESIZE_COPTER_6, _timer); - break; - } - case EVENT_RESIZE_COPTER_6: - { - if (Creature* copter = ObjectAccessor::GetCreature(*me, _copterGUID)) - { - copter->RemoveAura(SPELL_GROW_THREE); - copter->DespawnOrUnsummon(2s); - } - break; - } - default: - break; - } - } - } - -public: - void SetCopterGUID(ObjectGuid copterGUID) - { - _copterGUID = copterGUID; - } - -private: - EventMap _events; - ObjectGuid _copterGUID; - uint32 _conversationId; - uint32 _conversationActorId; - Milliseconds _timer; -}; - -CreatureAI* LindieSpringstockSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if (privateObjectOwner->GetQuestStatus(QUEST_THE_SCOUT_O_MATIC_5000) == QUEST_STATUS_INCOMPLETE) - return new npc_gnome_goblin_plains_make_copter_private(creature); - } - } - return new NullCreatureAI(creature); -}; - -CreatureAI* CorkFizzlepopSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - { - if (Player* privateObjectOwner = ObjectAccessor::GetPlayer(*creature, creature->GetPrivateObjectOwner())) - { - if (privateObjectOwner->GetQuestStatus(QUEST_THE_CHOPPY_BOOSTER_MK5) == QUEST_STATUS_INCOMPLETE) - return new npc_gnome_goblin_plains_make_copter_private(creature); - } - } - return new NullCreatureAI(creature); -}; - -enum CopterRideData -{ - CONVERSATION_RIDE_TO_OGRE_RUINS_ALLIANCE = 12083, - CONVERSATION_RIDE_FROM_OGRE_RUINS_ALLIANCE = 12084, - CONVERSATION_RIDE_TO_OGRE_RUINS_HORDE = 14517, - CONVERSATION_RIDE_FROM_OGRE_RUINS_HORDE = 14520, - - EVENT_START_SCOUT_OGRE_RUINS = 1, - EVENT_RETURN_FROM_OGRE_RUINS = 2, - EVENT_TRIGGER_CREW_MOVE = 3, - - NPC_SCOUT_O_MATIC_5000 = 156518, - NPC_CHOPPY_BOOSTER_MK5 = 167027, - - PATH_COPTER_TO_RUINS = 15652600, - PATH_COPTER_FROM_RUINS = 15652601, - PATH_WONSA_PLAINS = 16790900, - PATH_BO_PLAINS = 16791000, - PATH_LANA_PLAINS = 16791100, - PATH_JINHAKE_PLAINS = 16791200, - PATH_THROG_PLAINS = 16791300, - - SPELL_SCENE_OGRE_RUINS_ALLIANCE = 321342, - SPELL_SCENE_OGRE_RUINS_HORDE = 326626, - SPELL_ROPED_DNT = 303067, - SPELL_SCOUT_O_MATIC_PING_DNT = 321340, - SCOUT_O_MATIC_DESUMMON = 305548 -}; - -// 156526 - Scout-o-Matic 5000 -struct npc_scoutomatic_5000 : public ScriptedAI -{ - npc_scoutomatic_5000(Creature* creature) : ScriptedAI(creature) { } - - void IsSummonedBy(WorldObject* summoner) override - { - if (Player* player = summoner->ToPlayer()) - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - } - - void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override - { - if (apply && passenger->IsPlayer()) - { - me->CastSpell(passenger, SPELL_ROPED_DNT); - _events.ScheduleEvent(EVENT_START_SCOUT_OGRE_RUINS, 2s); - } - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - Player* player = ObjectAccessor::GetPlayer(*me, me->GetOwnerGUID()); - if (!player) - return; - - if (pathId == PATH_COPTER_TO_RUINS) - { - player->CastSpell(player, SPELL_SCENE_OGRE_RUINS_ALLIANCE); - } - else - { - player->CastSpell(player, SCOUT_O_MATIC_DESUMMON, CastSpellExtraArgs(TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE)); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_SCOUT_O_MATIC_PING_DNT) - { - if (Player* player = caster->ToPlayer()) - player->KilledMonsterCredit(NPC_SCOUT_O_MATIC_5000); - - _events.ScheduleEvent(EVENT_RETURN_FROM_OGRE_RUINS, 1s); - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_START_SCOUT_OGRE_RUINS: - { - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetOwnerGUID())) - { - me->SetSpeed(MOVE_WALK, 5.5f); - me->GetMotionMaster()->MovePath(PATH_COPTER_TO_RUINS, false); - Conversation::CreateConversation(CONVERSATION_RIDE_TO_OGRE_RUINS_ALLIANCE, player, *player, player->GetGUID(), nullptr); - } - break; - } - case EVENT_RETURN_FROM_OGRE_RUINS: - { - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetOwnerGUID())) - { - me->SetSpeed(MOVE_WALK, 5.0f); - me->GetMotionMaster()->MovePath(PATH_COPTER_FROM_RUINS, false); - Conversation::CreateConversation(CONVERSATION_RIDE_FROM_OGRE_RUINS_ALLIANCE, player, *player, player->GetGUID(), nullptr); - } - break; - } - default: - break; - } - } - } - -private: - EventMap _events; -}; - -static constexpr Position HordeCrewPersonalSpawnLocation[] = -{ - { 50.920593f, -2477.466f, 79.444374f, 0.8753076f }, - { 60.51328f, -2476.4822f, 81.034775f, 0.9128374f }, - { 53.08128f, -2476.5154f, 79.822624f, 0.9394135f }, - { 53.281864f, -2480.052f, 79.18003f, 0.78539818f }, - { 53.936935f, -2475.588f, 80.24179f, 0.91009599f } -}; - -// 167905 - Choppy Booster Mk. 5 -struct npc_choppy_booster_scout : public ScriptedAI -{ - npc_choppy_booster_scout(Creature* creature) : ScriptedAI(creature) { } - - void IsSummonedBy(WorldObject* summoner) override - { - if (Player* player = summoner->ToPlayer()) - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - } - - void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override - { - if (apply && passenger->IsPlayer()) - { - me->CastSpell(passenger, SPELL_ROPED_DNT); - _events.ScheduleEvent(EVENT_START_SCOUT_OGRE_RUINS, 2s); - } - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - Player* player = ObjectAccessor::GetPlayer(*me, me->GetOwnerGUID()); - if (!player) - return; - - if (pathId == PATH_COPTER_TO_RUINS) - { - player->CastSpell(player, SPELL_SCENE_OGRE_RUINS_HORDE); - } - else - { - player->CastSpell(player, SCOUT_O_MATIC_DESUMMON, CastSpellExtraArgs(TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE)); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - } - } - - void SpellHit(WorldObject* caster, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_SCOUT_O_MATIC_PING_DNT) - { - if (Player* player = caster->ToPlayer()) - player->KilledMonsterCredit(NPC_CHOPPY_BOOSTER_MK5); - - _events.ScheduleEvent(EVENT_RETURN_FROM_OGRE_RUINS, 1s); - } - return; - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_START_SCOUT_OGRE_RUINS: - { - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetOwnerGUID())) - { - me->SetSpeed(MOVE_WALK, 6.0f); - me->GetMotionMaster()->MovePath(PATH_COPTER_TO_RUINS, false); - Conversation::CreateConversation(CONVERSATION_RIDE_TO_OGRE_RUINS_HORDE, player, *player, player->GetGUID(), nullptr); - } - break; - } - case EVENT_RETURN_FROM_OGRE_RUINS: - { - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetOwnerGUID())) - { - me->SetSpeed(MOVE_WALK, 4.5f); - me->GetMotionMaster()->MovePath(PATH_COPTER_FROM_RUINS, false); - Conversation::CreateConversation(CONVERSATION_RIDE_FROM_OGRE_RUINS_HORDE, player, *player, player->GetGUID(), nullptr); - _events.ScheduleEvent(EVENT_TRIGGER_CREW_MOVE, 11s); - } - break; - } - case EVENT_TRIGGER_CREW_MOVE: - if (Player* player = ObjectAccessor::GetPlayer(*me, me->GetOwnerGUID())) - { - if (Creature* wonsa = FindCreatureIgnorePhase(player, "wonsa_darkmaul_plains")) - if (Creature* wonsaClone = wonsa->SummonPersonalClone(HordeCrewPersonalSpawnLocation[0], TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player)) - wonsaClone->GetMotionMaster()->MovePath(PATH_WONSA_PLAINS, false); - - if (Creature* bo = FindCreatureIgnorePhase(player, "bo_darkmaul_plains")) - if (Creature* boClone = bo->SummonPersonalClone(HordeCrewPersonalSpawnLocation[1], TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player)) - boClone->GetMotionMaster()->MovePath(PATH_BO_PLAINS, false); - - if (Creature* lana = FindCreatureIgnorePhase(player, "lana_darkmaul_plains")) - if (Creature* lanaClone = lana->SummonPersonalClone(HordeCrewPersonalSpawnLocation[2], TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player)) - lanaClone->GetMotionMaster()->MovePath(PATH_LANA_PLAINS, false); - - if (Creature* jinhake = FindCreatureIgnorePhase(player, "jinhake_darkmaul_plains")) - if (Creature* jinhakeClone = jinhake->SummonPersonalClone(HordeCrewPersonalSpawnLocation[3], TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player)) - jinhakeClone->GetMotionMaster()->MovePath(PATH_JINHAKE_PLAINS, false); - - if (Creature* throg = FindCreatureIgnorePhase(player, "throg_darkmaul_plains")) - if (Creature* throgClone = throg->SummonPersonalClone(HordeCrewPersonalSpawnLocation[4], TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player)) - throgClone->GetMotionMaster()->MovePath(PATH_THROG_PLAINS, false); - } - break; - default: - break; - } - } - } - -private: - EventMap _events; -}; - -CreatureAI* ChoppyBoosterSelector(Creature* creature) -{ - if (Player* player = ObjectAccessor::GetPlayer(*creature, creature->GetOwnerGUID())) - { - if (player->GetQuestStatus(QUEST_THE_CHOPPY_BOOSTER_MK5) == QUEST_STATUS_INCOMPLETE) - return new npc_choppy_booster_scout(creature); - } - return new NullCreatureAI(creature); -}; - -// 167909 - Won'sa -// 167910 - Bo -// 167911 - Lana Jordan -// 167912 - Provisoner Jin'hake -// 167913 - Grunt Throg -struct npc_horde_crew_plains_private : public ScriptedAI -{ - npc_horde_crew_plains_private(Creature* creature) : ScriptedAI(creature) { } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 /*pathId*/) override - { - me->DespawnOrUnsummon(); - } -}; - -CreatureAI* HordeCrewPlainsSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_horde_crew_plains_private(creature); - - return new NullCreatureAI(creature); -}; - -static constexpr Position CopterCloneSpawnPosition = { 100.583f, -2417.87f, 90.268f, 0.0f }; - -// Quest 55193 - The Scout-o-Matic 5000 "Alliance" -// Quest 59940 - The Choppy Booster Mk. 5 "Horde" -class quest_scout_chopper : public QuestScript -{ -public: - quest_scout_chopper(char const* script) : QuestScript(script) { } - - void HandleQuestStatusChange(Player* player, QuestStatus newStatus, std::string_view goblinString, std::string_view copterString) - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - { - Creature* goblin = FindCreatureIgnorePhase(player, goblinString, 10.0f); - Creature* copter = FindCreatureIgnorePhase(player, copterString, 10.0f); - if (!goblin || !copter) - return; - - Creature* goblinPersonal = goblin->SummonPersonalClone(goblin->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - Creature* copterPersonal = copter->SummonPersonalClone(CopterCloneSpawnPosition, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!goblinPersonal || !copterPersonal) - return; - - copterPersonal->SetObjectScale(0.2f); - copterPersonal->RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK); - - if (npc_gnome_goblin_plains_make_copter_private* personalAI = CAST_AI(npc_gnome_goblin_plains_make_copter_private, goblinPersonal->AI())) - personalAI->SetCopterGUID(copterPersonal->GetGUID()); - - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - } - case QUEST_STATUS_NONE: - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - default: - break; - } - } -}; - -// 55193 - The Scout-o-Matic 5000 "Alliance" -class quest_scout_o_matic_5000 : public quest_scout_chopper -{ -public: - quest_scout_o_matic_5000() : quest_scout_chopper("quest_scout_o_matic_5000") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, "lindie_springstock_plains", "scout_o_matic"); - } -}; - -// 59940 - The Choppy Booster Mk. 5 "Horde" -class quest_choppy_booster_mk5 : public quest_scout_chopper -{ -public: - quest_choppy_booster_mk5() : quest_scout_chopper("quest_choppy_booster_mk5") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, "cork_fizzlepop_plains", "choppy_booster"); - } -}; - -// Quest 56034 - Re-sizing the Situation "Alliance" -// Quest 59941 - Re-sizing the Situation "Horde" -enum ResizingQuestData -{ - ACTOR_LINDIE_RESIZING_QUEST = 71366, - ACTOR_CORK_RESIZING_QUEST = 76343, - - CONVERSATION_RESIZING_QUEST_ACCEPT = 12086, - CONVERSATION_RESIZING_REPORT_BACK = 12089, - - EVENT_RESIZING_FOLLOW_PLAYER = 1, - EVENT_RESIZING_RUN_HOME = 2, - - POINT_HOME_POSITION = 0, - - SPELL_SUMMON_LINDIE_SPRINGSTOCK_GUARDIAN_Q56034 = 305750, - SPELL_SUMMON_CORK_FIZZLEPOP_GUARDIAN_Q59941 = 326634, - SPELL_LINDIE_DESUMMON_Q56034 = 305756, - SPELL_PING_LINDIE_Q56034_Q59941 = 305754, -}; - -Position ResizingGuardianPosition = { 100.56077f, -2418.0713f, 90.34765f }; - -// 156749 - Lindie Springstock -struct npc_lindie_springstock_q56034 : public ScriptedAI -{ - npc_lindie_springstock_q56034(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - Unit* owner = me->GetOwner(); - - Player* player = owner->ToPlayer(); - if (!player) - return; - - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_RESIZING_QUEST_ACCEPT, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(0, 0, player->GetGUID()); - conversation->AddActor(ACTOR_LINDIE_RESIZING_QUEST, 1, me->GetGUID()); - conversation->AddActor(ACTOR_CORK_RESIZING_QUEST, 2, ObjectGuid::Empty); - conversation->Start(); - - _events.ScheduleEvent(EVENT_RESIZING_FOLLOW_PLAYER, 2s); - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE) - return; - - if (uiId != 0) - return; - - if (Unit* owner = me->GetOwner()) - owner->CastSpell(owner, SPELL_LINDIE_DESUMMON_Q56034); - } - - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_PING_LINDIE_Q56034_Q59941) - return; - - _events.ScheduleEvent(EVENT_RESIZING_RUN_HOME, 2s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_RESIZING_FOLLOW_PLAYER: - { - if (Unit* owner = me->GetOwner()) - me->GetMotionMaster()->MoveFollow(owner, 0.0f, float(M_PI / 4.0f)); - break; - } - case EVENT_RESIZING_RUN_HOME: - { - me->GetMotionMaster()->MovePoint(POINT_HOME_POSITION, ResizingGuardianPosition); - break; - } - default: - break; - } - } - } - -private: - EventMap _events; -}; - -// 167915 - Cork Fizzlepop -struct npc_cork_fizzlepop_q59941 : public ScriptedAI -{ - npc_cork_fizzlepop_q59941(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - Unit* owner = me->GetOwner(); - if (!owner) - return; - - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_RESIZING_QUEST_ACCEPT, owner, *owner, owner->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(0, 0, owner->GetGUID()); - conversation->AddActor(ACTOR_LINDIE_RESIZING_QUEST, 1, ObjectGuid::Empty); - conversation->AddActor(ACTOR_CORK_RESIZING_QUEST, 2, me->GetGUID()); - conversation->Start(); - - _events.ScheduleEvent(EVENT_RESIZING_FOLLOW_PLAYER, 2s); - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE) - return; - - if (uiId != 0) - return; - - if (Unit* owner = me->GetOwner()) - { - owner->CastSpell(owner, SPELL_UPDATE_PHASE_SHIFT); - owner->RemoveAura(SPELL_SUMMON_CORK_FIZZLEPOP_GUARDIAN_Q59941); - } - } - - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_PING_LINDIE_Q56034_Q59941) - return; - - Unit* owner = me->GetOwner(); - if (!owner) - return; - - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_RESIZING_REPORT_BACK, owner, *owner, owner->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(0, 0, owner->GetGUID()); - conversation->AddActor(ACTOR_LINDIE_RESIZING_QUEST, 1, ObjectGuid::Empty); - conversation->AddActor(ACTOR_CORK_RESIZING_QUEST, 2, me->GetGUID()); - conversation->Start(); - - _events.ScheduleEvent(EVENT_RESIZING_RUN_HOME, 2s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_RESIZING_FOLLOW_PLAYER: - { - if (Unit* owner = me->GetOwner()) - me->GetMotionMaster()->MoveFollow(owner, 0.0f, float(M_PI / 4.0f)); - break; - } - case EVENT_RESIZING_RUN_HOME: - { - me->GetMotionMaster()->MovePoint(POINT_HOME_POSITION, ResizingGuardianPosition); - break; - } - default: - break; - } - } - } - -private: - EventMap _events; -}; - -enum ReSizedBoarData -{ - EVENT_BOAR_GROW = 1, - EVENT_BOAR_MOVE = 2, - - SPELL_GROW_Q56034 = 129310, - - SOUND_GROW_Q56034 = 157469 -}; - -Position GiantBoarPosition = { 116.146f, -2430.48f, 90.508415f }; - -// 156736 - Wandering Boar -struct npc_re_sized_boar_q56034 : public ScriptedAI -{ - npc_re_sized_boar_q56034(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - _events.ScheduleEvent(EVENT_BOAR_GROW, 1s); - } - - void MovementInform(uint32 uiType, uint32 uiId) override - { - if (uiType != POINT_MOTION_TYPE) - return; - - if (uiId != POINT_HOME_POSITION) - return; - - me->SetFacingTo(0.785398f); - - if (Unit* summoner = me->GetDemonCreator()) - summoner->CastSpell(summoner, SPELL_UPDATE_PHASE_SHIFT); - - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BOAR_GROW: - me->CastSpell(me, SPELL_GROW_Q56034); - me->PlayDirectSound(SOUND_GROW_Q56034); - _events.ScheduleEvent(EVENT_BOAR_MOVE, 1s); - break; - case EVENT_BOAR_MOVE: - me->SetWalk(false); - me->GetMotionMaster()->MovePoint(POINT_HOME_POSITION, GiantBoarPosition); - break; - default: - break; - } - } - } - -private: - EventMap _events; -}; - -// Spell 305749 - Summon Admiral Garrick Guardian -// Spell 326635 - Summon Cork (DNT) -class spell_summon_guardian_q56034_q59941 : public SpellScript -{ - // @TODO: drop after TARGET_UNK_142 impl - - void SelectTarget(WorldObject*& target) - { - Unit* caster = GetCaster(); - if (!caster) - return; - - Player* player = caster->ToPlayer(); - if (!player) - return; - - Creature* survivor = FindCreatureIgnorePhase(player, player->GetTeam() == ALLIANCE ? "lindie_springstock_plains" : "cork_fizzlepop_plains", 5.0f); - if (!survivor) - return; - - target = survivor; - } - - void Register() override - { - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_summon_guardian_q56034_q59941::SelectTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY_OR_DB); - } -}; - -enum ReSizingData -{ - NPC_WANDERING_BOAR = 156716, - NPC_LINDIE_SPRINGSTOCK_GUARDIAN = 156749, - NPC_CORK_FIZZLEPOP_GUARDIAN = 167915, - - QUEST_RE_SIZING_THE_SITUATION_ALLIANCE = 56034, - QUEST_RE_SIZING_THE_SITUATION_HORDE = 59941, - - QUEST_OBJECTIVE_RE_SIZING_THE_SITUATION_ALLIANCE = 390101, - QUEST_OBJECTIVE_RE_SIZING_THE_SITUATION_HORDE = 397274, - - SPELL_RESIZER_HIT_ONE_Q56034_Q59941 = 305724, - SPELL_RESIZER_HIT_TWO_Q56034_Q59941 = 305721, - SPELL_RESIZER_HIT_THREE_Q56034 = 305742, - SPELL_RESIZING_Q59941 = 325345, - SPELL_RE_SIZER_OVERCHARGED_Q56034 = 325347 -}; - -// 305716 - Re-Sizing -class spell_re_sizing_q56034 : public SpellScript -{ - SpellCastResult CheckCast() - { - if (!GetExplTargetUnit()) - return SPELL_FAILED_BAD_TARGETS; - - Creature* target = GetExplTargetUnit()->ToCreature(); - if (!target) - return SPELL_FAILED_BAD_TARGETS; - - if (target->GetEntry() != NPC_WANDERING_BOAR) - return SPELL_FAILED_BAD_TARGETS; - - return SPELL_CAST_OK; - } - - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_re_sizing_q56034::CheckCast); - } -}; - -// 305716 - Re-Sizing -class spell_re_sizing_aura_q56034 : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_RESIZER_HIT_ONE_Q56034_Q59941, - SPELL_RESIZER_HIT_TWO_Q56034_Q59941, - SPELL_PING_LINDIE_Q56034_Q59941, - }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Player* player = Object::ToPlayer(GetCaster()); - Creature* creature = Object::ToCreature(GetTarget()); - if (!player || !creature) - return; - - switch (player->GetQuestObjectiveData(QUEST_RE_SIZING_THE_SITUATION_ALLIANCE, QUEST_OBJECTIVE_RE_SIZING_THE_SITUATION_ALLIANCE)) - { - case 0: - player->CastSpell(creature, SPELL_RESIZER_HIT_ONE_Q56034_Q59941, true); - creature->DespawnOrUnsummon(2s); - break; - case 1: - player->CastSpell(creature, SPELL_RESIZER_HIT_TWO_Q56034_Q59941, true); - creature->DespawnOrUnsummon(); - break; - case 2: - player->CastSpell(creature, SPELL_RESIZER_HIT_THREE_Q56034, true); - player->CastSpell(player, SPELL_PING_LINDIE_Q56034_Q59941, true); - creature->DespawnOrUnsummon(); - break; - default: - break; - } - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_re_sizing_aura_q56034::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 305724 - Resizer Hit -// 305721 - Resizer Hit -class spell_resizer_hit_one_two_q56034_q59941 : public SpellScript -{ - void HandleLaunch(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - } - - void HandleEffect(SpellEffIndex effIndex) - { - Player* player = Object::ToPlayer(GetCaster()); - if (!player) - return; - - uint32 guardianID = player->GetTeam() == ALLIANCE ? NPC_LINDIE_SPRINGSTOCK_GUARDIAN : NPC_CORK_FIZZLEPOP_GUARDIAN; - - Creature* guardian = player->FindNearestCreatureWithOptions(10.0f, { .CreatureId = guardianID, .OwnerGuid = player->GetGUID() }); - if (!guardian) - return; - - Conversation* conversation = Conversation::CreateConversation(GetSpellInfo()->GetEffect(effIndex).MiscValue, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(0, 0, player->GetGUID()); - conversation->AddActor(ACTOR_LINDIE_RESIZING_QUEST, 1, player->GetTeam() == ALLIANCE ? guardian->GetGUID() : ObjectGuid::Empty); - conversation->AddActor(ACTOR_CORK_RESIZING_QUEST, 2, player->GetTeam() == ALLIANCE ? ObjectGuid::Empty : guardian->GetGUID()); - conversation->Start(); - } - - void Register() override - { - OnEffectLaunchTarget += SpellEffectFn(spell_resizer_hit_one_two_q56034_q59941::HandleLaunch, EFFECT_3, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - OnEffectHitTarget += SpellEffectFn(spell_resizer_hit_one_two_q56034_q59941::HandleEffect, EFFECT_3, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - } -}; - -// 305742 - Resizer Hit -class spell_resizer_hit_three_q56034 : public SpellScript -{ - void HandleLaunch(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - } - - void HandleEffect(SpellEffIndex effIndex) - { - Player* player = Object::ToPlayer(GetCaster()); - if (!player) - return; - - uint32 guardianID = player->GetTeam() == ALLIANCE ? NPC_LINDIE_SPRINGSTOCK_GUARDIAN : NPC_CORK_FIZZLEPOP_GUARDIAN; - - Creature* guardian = player->FindNearestCreatureWithOptions(10.0f, { .CreatureId = guardianID, .OwnerGuid = player->GetGUID() }); - if (!guardian) - return; - - Conversation* conversation = Conversation::CreateConversation(GetSpellInfo()->GetEffect(effIndex).MiscValue, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(0, 0, player->GetGUID()); - conversation->AddActor(ACTOR_LINDIE_RESIZING_QUEST, 1, player->GetTeam() == ALLIANCE ? guardian->GetGUID() : ObjectGuid::Empty); - conversation->AddActor(ACTOR_CORK_RESIZING_QUEST, 2, player->GetTeam() == ALLIANCE ? ObjectGuid::Empty : guardian->GetGUID()); - conversation->Start(); - } - - void Register() override - { - OnEffectLaunchTarget += SpellEffectFn(spell_resizer_hit_three_q56034::HandleLaunch, EFFECT_4, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - OnEffectHitTarget += SpellEffectFn(spell_resizer_hit_three_q56034::HandleEffect, EFFECT_4, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - } -}; - -// 325346 - Re-Sizing -class spell_re_sizing_q59941 : public SpellScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_RESIZING_Q59941, - SPELL_RE_SIZER_OVERCHARGED_Q56034, - SPELL_PING_LINDIE_Q56034_Q59941, - }); - } - - SpellCastResult CheckCast() - { - if (!GetExplTargetUnit()) - return SPELL_FAILED_BAD_TARGETS; - - Creature* target = GetExplTargetUnit()->ToCreature(); - if (!target) - return SPELL_FAILED_BAD_TARGETS; - - if (target->GetEntry() != NPC_WANDERING_BOAR) - return SPELL_FAILED_BAD_TARGETS; - - return SPELL_CAST_OK; - } - - void HandleScript(SpellEffIndex /*effIndex*/) - { - Player* player = Object::ToPlayer(GetCaster()); - Creature* creature = Object::ToCreature(GetHitUnit()); - if (!player || !creature) - return; - - switch (player->GetQuestObjectiveData(QUEST_RE_SIZING_THE_SITUATION_HORDE, QUEST_OBJECTIVE_RE_SIZING_THE_SITUATION_HORDE)) - { - case 0: - case 1: - player->CastSpell(creature, SPELL_RESIZING_Q59941, true); - break; - case 2: - player->CastSpell(creature, SPELL_RE_SIZER_OVERCHARGED_Q56034, true); - player->CastSpell(player, SPELL_PING_LINDIE_Q56034_Q59941, true); - creature->DespawnOrUnsummon(3s); - break; - default: - break; - } - } - - void Register() override - { - OnCheckCast += SpellCheckCastFn(spell_re_sizing_q59941::CheckCast); - OnEffectHitTarget += SpellEffectFn(spell_re_sizing_q59941::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } -}; - -// 325345 - Re-Sizing -class spell_re_sizing_aura_q59941 : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_RESIZER_HIT_ONE_Q56034_Q59941, - SPELL_RESIZER_HIT_TWO_Q56034_Q59941 - }); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Player* player = Object::ToPlayer(GetCaster()); - Creature* creature = Object::ToCreature(GetTarget()); - if (!player || !creature) - return; - - switch (player->GetQuestObjectiveData(QUEST_RE_SIZING_THE_SITUATION_HORDE, QUEST_OBJECTIVE_RE_SIZING_THE_SITUATION_HORDE)) - { - case 0: - player->CastSpell(creature, SPELL_RESIZER_HIT_ONE_Q56034_Q59941, true); - creature->DespawnOrUnsummon(2s); - break; - case 1: - player->CastSpell(creature, SPELL_RESIZER_HIT_TWO_Q56034_Q59941, true); - creature->DespawnOrUnsummon(); - break; - default: - break; - } - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_re_sizing_aura_q59941::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 325368 - Re-sizer Slaughter (DNT) -class spell_re_sizer_slaughter : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_UPDATE_PHASE_SHIFT - }); - } - - void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->CastSpell(nullptr, SPELL_UPDATE_PHASE_SHIFT); - } - - void Register() override - { - AfterEffectApply += AuraEffectRemoveFn(spell_re_sizer_slaughter::OnApply, EFFECT_0, SPELL_AURA_PLAY_SCENE, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_re_sizer_slaughter::OnApply, EFFECT_0, SPELL_AURA_PLAY_SCENE, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 56034 - Re-sizing the Situation "Alliance" -// 59941 - Re-sizing the Situation "Horde" -class quest_resizing_the_situation : public QuestScript -{ -public: - quest_resizing_the_situation(char const* script) : QuestScript(script) { } - - void HandleQuestStatusChange(Player* player, QuestStatus newStatus, uint32 SummonSpell) - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, SummonSpell); - break; - case QUEST_STATUS_NONE: - player->RemoveAura(SummonSpell); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - default: - break; - } - } -}; - -// 56034 - Re-sizing the Situation "Alliance" -class quest_resizing_the_situation_alliance : public quest_resizing_the_situation -{ -public: - quest_resizing_the_situation_alliance() : quest_resizing_the_situation("quest_resizing_the_situation_alliance") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, SPELL_SUMMON_LINDIE_SPRINGSTOCK_GUARDIAN_Q56034); - } -}; - -// 59941 - Re-sizing the Situation "Horde" -class quest_resizing_the_situation_horde : public quest_resizing_the_situation -{ -public: - quest_resizing_the_situation_horde() : quest_resizing_the_situation("quest_resizing_the_situation_horde") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, SPELL_SUMMON_CORK_FIZZLEPOP_GUARDIAN_Q59941); - } -}; - -enum QuestRideBoar -{ - NPC_ALLIANCE_CAPTAIN = 174955, - NPC_HENRY_GARRICK_PRISONER = 156799, - - SPELL_SUMMON_DARKMAUL_PLAINS_QUESTGIVERS_SUMMON = 305779, - SPELL_SUMMON_DARKMAUL_PLAINS_QUESTGIVERS_AURA = 305776, - SPELL_PING_GARRICK_TORGOK = 316982, - SPELL_REUNION_DNT_ALLIANCE = 305893, - SPELL_RITUAL_SCENE_OGRE_CITADEL_DNT = 321693, - SPELL_RITUAL_SCENE_HRUN_BEAM_DNT = 321692, - SPELL_RITUAL_SCENE_HARPY_BEAM_DNT = 321691, - SPELL_RITUAL_SCENE_MAIN_BEAM_DNT = 321690 -}; - -static constexpr Position ReDeatherAbandonTeleportPos = { 102.3f, -2422.5f, 90.1f, 0.764454185962677001f }; - -// 55879 - Ride of the Scientifically Enhanced Boar -class quest_ride_of_the_scientifically_enhanced_boar : public QuestScript -{ -public: - quest_ride_of_the_scientifically_enhanced_boar() : QuestScript("quest_ride_of_the_scientifically_enhanced_boar") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->CastSpell(player, SPELL_SUMMON_DARKMAUL_PLAINS_QUESTGIVERS_SUMMON); - break; - case QUEST_STATUS_COMPLETE: - player->CombatStop(); - player->CastSpell(player, SPELL_PING_GARRICK_TORGOK); - break; - case QUEST_STATUS_REWARDED: - player->CastSpell(player, SPELL_REUNION_DNT_ALLIANCE); - player->CastSpell(player, SPELL_RITUAL_SCENE_OGRE_CITADEL_DNT); - player->CastSpell(player, SPELL_RITUAL_SCENE_HRUN_BEAM_DNT); - player->CastSpell(player, SPELL_RITUAL_SCENE_HARPY_BEAM_DNT); - player->CastSpell(player, SPELL_RITUAL_SCENE_MAIN_BEAM_DNT); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - case QUEST_STATUS_NONE: - player->RemoveAura(SPELL_RITUAL_SCENE_OGRE_CITADEL_DNT); - player->RemoveAura(SPELL_RITUAL_SCENE_HRUN_BEAM_DNT); - player->RemoveAura(SPELL_RITUAL_SCENE_HARPY_BEAM_DNT); - player->RemoveAura(SPELL_RITUAL_SCENE_MAIN_BEAM_DNT); - player->RemoveAura(SPELL_SUMMON_DARKMAUL_PLAINS_QUESTGIVERS_AURA); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->NearTeleportTo(ReDeatherAbandonTeleportPos); - break; - default: - break; - } - } -}; - -enum SceneOgreRuinsRideBoar -{ - QUEST_RIDE_ENHANCED_BOAR = 55879, - QUEST_RIDE_BOAR_OBJECTIVE_TWO = 396499, - QUEST_RIDE_BOAR_OBJECTIVE_TWO_MAX = 8, - - SPELL_ENHANCED_BOAR_TRAMPLE = 305557, - SPELL_ENHANCED_BOAR_CHARGE = 321627, - SPELL_ENHANCED_BOAR_KILL_CREDIT = 321668, - SPELL_ENHANCED_BOAR_PING_VEHICLE = 305559, - SPELL_ENHANCED_BOAR_CHARGE_CONVO = 305815, - SPELL_ENHANCED_BOAR_KNOCKBACK = 306356, - SPELL_ENHANCED_BOAR_KNOCKBACK_HINT = 306357 -}; - -// Script scene for Ride of the Scientifically Enhanced Boar quest -class scene_darkmaul_plains_skeleton_army_alliance : public SceneScript -{ -public: - scene_darkmaul_plains_skeleton_army_alliance() : SceneScript("scene_darkmaul_plains_skeleton_army_alliance") { } - - void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override - { - if (triggerName == "Trampling Time") - { - player->CastSpell(player, SPELL_ENHANCED_BOAR_TRAMPLE, true); - if (Unit* boar = player->GetVehicleBase()) - boar->CastSpell(boar, SPELL_ENHANCED_BOAR_CHARGE, true); - } - else if (triggerName == "Big Kill Credit") - { - player->CastSpell(player, SPELL_ENHANCED_BOAR_KILL_CREDIT, true); - - if (player->GetQuestObjectiveData(QUEST_RIDE_ENHANCED_BOAR, QUEST_RIDE_BOAR_OBJECTIVE_TWO) == QUEST_RIDE_BOAR_OBJECTIVE_TWO_MAX) - player->CastSpell(player, SPELL_ENHANCED_BOAR_PING_VEHICLE); - } - else if (triggerName == "Conversation") - { - player->CastSpell(player, SPELL_ENHANCED_BOAR_CHARGE_CONVO, true); - } - else if (triggerName == "Knockback") - { - player->CastSpell(player, SPELL_ENHANCED_BOAR_KNOCKBACK, true); - } - else if (triggerName == "Hint") - { - player->CastSpell(player, SPELL_ENHANCED_BOAR_KNOCKBACK_HINT, true); - } - } -}; - -// Spell 305779 - Summon Darkmaul Plains Questgivers (DNT) -class spell_summon_darkmaul_plains_questgivers_q55879 : public SpellScript -{ - // @TODO: drop after TARGET_UNK_142 impl - - void SelectTarget(WorldObject*& target) - { - Player* player = Object::ToPlayer(GetCaster()); - if (!player) - return; - - Creature* survivor = FindCreatureIgnorePhase(player, "captain_garrick_plains", 5.0f); - if (!survivor) - return; - - target = survivor; - } - - void Register() override - { - OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_summon_darkmaul_plains_questgivers_q55879::SelectTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY_OR_DB); - } -}; - -enum SpellRidingGiantBoar -{ - SPELL_RIDING_GIANT_BOAR_305068 = 305068, - SPELL_RIDING_GIANT_BOAR_321670 = 321670 -}; - -// 173426 - Riding Giant Boar -class spell_riding_giant_boar_q55879 : public AuraScript -{ - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_RIDING_GIANT_BOAR_305068, - SPELL_RIDING_GIANT_BOAR_321670, - SPELL_UPDATE_PHASE_SHIFT - }); - } - - void OnAuraRemoveHandler(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Player* player = Object::ToPlayer(GetCaster()); - if (!player) - return; - - player->RemoveAura(SPELL_RIDING_GIANT_BOAR_305068); - player->RemoveAura(SPELL_RIDING_GIANT_BOAR_321670); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_riding_giant_boar_q55879::OnAuraRemoveHandler, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL); - } -}; - -enum SpellKnockbackHint -{ - ACTOR_ALLIANCE_CAPTAIN = 71372 -}; - -// 305742 - Resizer Hit -class spell_knockback_hint_q56034 : public SpellScript -{ - void HandleLaunch(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - } - - void HandleEffect(SpellEffIndex effIndex) - { - Player* player = Object::ToPlayer(GetCaster()); - if (!player) - return; - - Creature* garrick = player->FindNearestCreatureWithOptions(10.0f, { .CreatureId = NPC_ALLIANCE_CAPTAIN, .OwnerGuid = player->GetGUID() }); - if (!garrick) - return; - - Conversation* conversation = Conversation::CreateConversation(GetSpellInfo()->GetEffect(effIndex).MiscValue, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(ACTOR_ALLIANCE_CAPTAIN, 0, garrick->GetGUID()); - conversation->Start(); - } - - void Register() override - { - OnEffectLaunchTarget += SpellEffectFn(spell_knockback_hint_q56034::HandleLaunch, EFFECT_0, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - OnEffectHitTarget += SpellEffectFn(spell_knockback_hint_q56034::HandleEffect, EFFECT_0, SPELL_EFFECT_CREATE_PRIVATE_CONVERSATION); - } -}; - -enum CaptainGarrickGiantBoar -{ - ACTION_EXIT_BOAR = 1, - - ACTOR_HENRY_GARRICK_PRISONER = 78493, - - CONVERSATION_CAPTAIN_GARRICK_RIDE_BOAR_QUEST_ACCEPT = 12090, - - CONVERSATION_CAPTAIN_GARRICK_RIDE_BOAR_QUEST_HENRY = 15615, - CONVERSATION_CAPTAIN_GARRICK_RIDE_BOAR_QUEST_EXIT = 12092, - - EVENT_CAPTAIN_GARRICK_RIDE_BOAR = 1, - EVENT_CAPTAIN_GARRICK_RIDE_BOAR_CHECK_OWNER = 2, - EVENT_CAPTAIN_GARRICK_RIDE_BOAR_TALK_TO_HENRY = 3, - EVENT_CAPTAIN_GARRICK_RIDE_BOAR_HENRY_DESPAWN = 4, - EVENT_CAPTAIN_GARRICK_RIDE_BOAR_EXIT_BOAR_CONVERSATION = 5, - - NPC_GIANT_BOAR = 156267, - - PHASE_SEE_TORGOK = 14663, - - POINT_HENRY_POSITION = 0, - - SPELL_PING_GARRICK_TO_RIDE_BOAR = 316984, - SPELL_RIDE_VEHICLE_CAPTIAN_BOAR = 63315 -}; - -Position MoveToPrisonerPosition = { 232.16145f, -2292.5347f, 80.91198f }; - -// 174955 - Captain Garrick -struct npc_captain_garrick_q55879 : public ScriptedAI -{ - npc_captain_garrick_q55879(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - return; - - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_CAPTAIN_GARRICK_RIDE_BOAR_QUEST_ACCEPT, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(0, 0, player->GetGUID()); - conversation->AddActor(ACTOR_ALLIANCE_CAPTAIN, 1, me->GetGUID()); - conversation->Start(); - - me->SetReactState(REACT_PASSIVE); - me->GetMotionMaster()->MoveFollow(player, 0.0f, float(M_PI / 4.0f)); - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (me->GetHealth() <= damage) - damage = me->GetHealth() - 1; - } - - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override - { - switch (spellInfo->Id) - { - case SPELL_PING_GARRICK_TO_RIDE_BOAR: - { - Unit* owner = me->GetOwner(); - if (!owner) - break; - - PhasingHandler::InheritPhaseShift(me, owner); - PhasingHandler::ResetPhaseShift(me); - - _events.ScheduleEvent(EVENT_CAPTAIN_GARRICK_RIDE_BOAR, 2s); - break; - } - case SPELL_ENHANCED_BOAR_PING_VEHICLE: - { - PhasingHandler::AddPhase(me, PHASE_SEE_TORGOK, true); - _events.ScheduleEvent(EVENT_CAPTAIN_GARRICK_RIDE_BOAR_EXIT_BOAR_CONVERSATION, 500ms); - break; - } - case SPELL_PING_GARRICK_TORGOK: - { - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - break; - - Creature* henry = FindCreatureIgnorePhase(me, "henry_garrick_ogre_ruins_prisoner"); - if (!henry) - break; - - Creature* henryPersonal = henry->SummonPersonalClone(henry->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!henryPersonal) - break; - - me->SetReactState(REACT_AGGRESSIVE); - _henryGUID = henryPersonal->GetGUID(); - _events.ScheduleEvent(EVENT_CAPTAIN_GARRICK_RIDE_BOAR_TALK_TO_HENRY, 1s); - break; - } - default: - break; - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CAPTAIN_GARRICK_RIDE_BOAR: - { - if (Unit* owner = me->GetOwner()) - { - Creature* boar = owner->FindNearestCreatureWithOptions(10.0f, { .CreatureId = NPC_GIANT_BOAR, .OwnerGuid = owner->GetGUID() }); - if (!boar) - return; - - boar->SetControlled(false, UNIT_STATE_ROOT); - me->CastSpell(boar, SPELL_RIDE_VEHICLE_CAPTIAN_BOAR); - } - break; - } - case EVENT_CAPTAIN_GARRICK_RIDE_BOAR_TALK_TO_HENRY: - { - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - break; - - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_CAPTAIN_GARRICK_RIDE_BOAR_QUEST_HENRY, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - break; - - conversation->AddActor(ACTOR_ALLIANCE_CAPTAIN, 0, me->GetGUID()); - conversation->AddActor(ACTOR_HENRY_GARRICK_PRISONER, 1, _henryGUID); - conversation->Start(); - - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(POINT_HENRY_POSITION, MoveToPrisonerPosition); - _events.ScheduleEvent(EVENT_CAPTAIN_GARRICK_RIDE_BOAR_HENRY_DESPAWN, 18s); - break; - } - case EVENT_CAPTAIN_GARRICK_RIDE_BOAR_HENRY_DESPAWN: - { - me->DespawnOrUnsummon(); - if (Creature* henry = ObjectAccessor::GetCreature(*me, _henryGUID)) - henry->DespawnOrUnsummon(); - - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - break; - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - } - case EVENT_CAPTAIN_GARRICK_RIDE_BOAR_EXIT_BOAR_CONVERSATION: - { - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - break; - - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_CAPTAIN_GARRICK_RIDE_BOAR_QUEST_EXIT, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - break; - - conversation->AddActor(0, 0, player->GetGUID()); - conversation->AddActor(ACTOR_ALLIANCE_CAPTAIN, 1, me->GetGUID()); - conversation->Start(); - break; - } - default: - break; - } - } - - UpdateVictim(); - } -private: - EventMap _events; - ObjectGuid _henryGUID; -}; - -enum GiantBoar -{ - EVENT_GIANT_BOAR_SIZE_ONE = 1, - EVENT_GIANT_BOAR_SIZE_TWO = 2, - EVENT_GIANT_BOAR_SIZE_THREE = 3, - EVENT_GIANT_BOAR_SIZE_FOUR = 4, - EVENT_GIANT_BOAR_EJECT_PASSENGERS = 5, - EVENT_GIANT_BOAR_UNROOT = 6, - - SOUND_ENLARGE_BOAR = 157516, - SOUND_SHRINK_BOAR = 157517, - - VEHICLE_BOAR_SEAT_ONE = 1 -}; - -// 156267 - Giant Boar -struct npc_giant_boar_vehicle_q55879 : public VehicleAI -{ - npc_giant_boar_vehicle_q55879(Creature* creature) : VehicleAI(creature), _endOfScene(false) - { - me->SetOrientation(0.844224f); - } - - void JustAppeared() override - { - me->SetSpeed(MOVE_RUN, 14.0f); - } - - void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override - { - if (apply && passenger->IsPlayer()) - { - me->SetControlled(true, UNIT_STATE_ROOT); - passenger->SetMovedUnit(me); - passenger->CastSpell(passenger, SPELL_PING_GARRICK_TO_RIDE_BOAR); // Ping Garrick to ride Boar (DNT) - passenger->CastSpell(passenger, SPELL_UPDATE_PHASE_SHIFT); - } - else if (apply && passenger->IsCreature()) - { - passenger->ChangeSeat(VEHICLE_BOAR_SEAT_ONE); - } - } - - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id == SPELL_ENHANCED_BOAR_PING_VEHICLE) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_01); - me->SetControlled(true, UNIT_STATE_ROOT); - me->CastSpell(me, SPELL_ENHANCED_BOAR_CHARGE); - _endOfScene = true; - _events.ScheduleEvent(EVENT_GIANT_BOAR_SIZE_ONE, 4s); - - if (Unit* owner = me->GetOwner()) - owner->CastSpell(owner, SPELL_UPDATE_PHASE_SHIFT); - } - } - - void UpdateAI(uint32 diff) override - { - if (!_endOfScene) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_GIANT_BOAR_SIZE_ONE: - me->PlayDirectSound(SOUND_ENLARGE_BOAR); - me->SetObjectScale(1.2f); - _events.ScheduleEvent(EVENT_GIANT_BOAR_SIZE_TWO, 1000ms); - break; - case EVENT_GIANT_BOAR_SIZE_TWO: - me->PlayDirectSound(SOUND_SHRINK_BOAR); - me->SetObjectScale(0.7f); - _events.ScheduleEvent(EVENT_GIANT_BOAR_SIZE_THREE, 1000ms); - break; - case EVENT_GIANT_BOAR_SIZE_THREE: - me->PlayDirectSound(SOUND_ENLARGE_BOAR); - me->SetObjectScale(1.2f); - _events.ScheduleEvent(EVENT_GIANT_BOAR_SIZE_FOUR, 500ms); - break; - case EVENT_GIANT_BOAR_SIZE_FOUR: - me->PlayDirectSound(SOUND_SHRINK_BOAR); - me->SetObjectScale(0.1f); - _events.ScheduleEvent(EVENT_GIANT_BOAR_EJECT_PASSENGERS, 500ms); - break; - case EVENT_GIANT_BOAR_EJECT_PASSENGERS: - me->RemoveAllAuras(); - _events.ScheduleEvent(EVENT_GIANT_BOAR_UNROOT, 500ms); - break; - case EVENT_GIANT_BOAR_UNROOT: - me->SetControlled(false, UNIT_STATE_ROOT); - break; - default: - break; - } - } - } -private: - EventMap _events; - bool _endOfScene; -}; - -enum TorgokData -{ - EVENT_CAST_SPIRIT_BOLT = 1, - EVENT_CAST_SOUL_GRASP = 2, - - ITEM_TORGOKS_REAGENT_POUCH = 176398, - - QUEST_TORGOKS_REAGENT_POUCH_DROPPED = 59610, - - SPELL_SPIRIT_BOLT = 319294, - SPELL_SOUL_GRASP = 319298 -}; - -// 162817 - Torgok -struct npc_torgok_q55879 : public ScriptedAI -{ - npc_torgok_q55879(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - _events.Reset(); - } - - void JustEngagedWith(Unit* who) override - { - Talk(SAY_AGGRO, who); - - _events.ScheduleEvent(EVENT_CAST_SPIRIT_BOLT, 4s); - _events.ScheduleEvent(EVENT_CAST_SOUL_GRASP, 14s); - } - - void JustDied(Unit* killer) override - { - Talk(SAY_DEATH, killer); - - for (auto const& [playerGuid, loot] : me->m_personalLoot) - { - if (Player* player = ObjectAccessor::GetPlayer(*me, playerGuid)) - { - for (LootItem const& lootItem : loot->items) - { - if (lootItem.itemid == ITEM_TORGOKS_REAGENT_POUCH) - { - player->SetRewardedQuest(QUEST_TORGOKS_REAGENT_POUCH_DROPPED); - break; - } - } - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CAST_SPIRIT_BOLT: - DoCastVictim(SPELL_SPIRIT_BOLT); - _events.ScheduleEvent(EVENT_CAST_SPIRIT_BOLT, 6s); - break; - case EVENT_CAST_SOUL_GRASP: - DoCastAOE(SPELL_SOUL_GRASP); - _events.ScheduleEvent(EVENT_CAST_SOUL_GRASP, 14s); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -enum PrisonerQuest55879 -{ - PATH_PRISONER_TO_GROUND = 80000230 -}; - -// 156799 - Henry Garrick -// 167126 - Shuja Grimaxe -struct npc_prisoner_q55879_private : public ScriptedAI -{ - npc_prisoner_q55879_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - } - - void JustAppeared() override - { - me->RemoveAllAuras(); - me->GetMotionMaster()->MovePath(PATH_PRISONER_TO_GROUND, false); - } -}; - -CreatureAI* PrisonerQ55879Selector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_prisoner_q55879_private(creature); - else - return new NullCreatureAI(creature); -}; - -enum TheReDeather -{ - CONVERSATION_ACCEPT_RE_DEATHER_QUEST = 14525, - CONVERSATION_RE_DEATHER_EXPLODE = 14526, - - NPC_HORDE_WARRIOR = 167146, - NPC_SHUJA_GRIMAXE_PRISONER = 167126, - - QUEST_RE_DEATHER = 59942, - - OBJECTIVE_RE_DEATHER_CADAVERS_KILLED = 397279, - - RE_DEATHER_CADAVERS_KILLED_MAX = 8, - - SPELL_REUNION_DNT_HORDE = 326678, - SPELL_RE_DEATHER_TEMP_OBJECTIVE_CHECK = 325394, - SPELL_RE_DEATHER_ROUGH_LANDING_DNT = 325401, - SPELL_RE_DEATHER_SUMMON_GRIMAXE = 325429 -}; - -// 59942 - The Re-Deather -class quest_the_re_deather : public QuestScript -{ -public: - quest_the_re_deather() : QuestScript("quest_the_re_deather") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - Conversation::CreateConversation(CONVERSATION_ACCEPT_RE_DEATHER_QUEST, player, *player, player->GetGUID(), nullptr); - break; - case QUEST_STATUS_COMPLETE: - player->CombatStop(); - player->CastSpell(player, SPELL_PING_GARRICK_TORGOK); - break; - case QUEST_STATUS_REWARDED: - player->CastSpell(player, SPELL_REUNION_DNT_HORDE); - player->CastSpell(player, SPELL_RITUAL_SCENE_OGRE_CITADEL_DNT); - player->CastSpell(player, SPELL_RITUAL_SCENE_HRUN_BEAM_DNT); - player->CastSpell(player, SPELL_RITUAL_SCENE_HARPY_BEAM_DNT); - player->CastSpell(player, SPELL_RITUAL_SCENE_MAIN_BEAM_DNT); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - case QUEST_STATUS_NONE: - { - player->CastSpell(player, SPELL_RITUAL_SCENE_OGRE_CITADEL_DNT); - player->RemoveAura(SPELL_RE_DEATHER_SUMMON_GRIMAXE); - player->RemoveAura(SPELL_RITUAL_SCENE_HRUN_BEAM_DNT); - player->RemoveAura(SPELL_RITUAL_SCENE_HARPY_BEAM_DNT); - player->RemoveAura(SPELL_RITUAL_SCENE_MAIN_BEAM_DNT); - player->RemoveAura(SPELL_RE_DEATHER_TEMP_OBJECTIVE_CHECK); - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - player->NearTeleportTo(ReDeatherAbandonTeleportPos); - break; - } - default: - break; - } - } -}; - -// 2489 -class scene_darkmaul_plains_skeleton_army_horde : public SceneScript -{ -public: - scene_darkmaul_plains_skeleton_army_horde() : SceneScript("scene_darkmaul_plains_skeleton_army_horde") { } - - void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override - { - if (triggerName == "Big Kill Credit") - { - player->CastSpell(player, SPELL_ENHANCED_BOAR_KILL_CREDIT, true); - - if (player->GetQuestObjectiveData(QUEST_RE_DEATHER, OBJECTIVE_RE_DEATHER_CADAVERS_KILLED) == RE_DEATHER_CADAVERS_KILLED_MAX) - { - player->CastSpell(player, SPELL_ENHANCED_BOAR_PING_VEHICLE); // Ping Vehicle - player->CastSpell(player, SPELL_RE_DEATHER_TEMP_OBJECTIVE_CHECK); // Temp Objective Check - Conversation::CreateConversation(CONVERSATION_RE_DEATHER_EXPLODE, player, *player, player->GetGUID(), nullptr); - } - } - else if (triggerName == "Conversation") - { - player->CastSpell(player, SPELL_ENHANCED_BOAR_CHARGE_CONVO, true); // Does nothing but it's blizzlike - } - else if (triggerName == "Teleport") - { - player->CastSpell(player, SPELL_RE_DEATHER_ROUGH_LANDING_DNT); - } - } - - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - } -}; - -enum GrimaxeReDeather -{ - ACTOR_SHUJA_GRIMAXE_PRISONER = 76004, - ACTOR_WARLORD_GRIMAXE_Q59942 = 76357, - ACTOR_SHUJA_GRIMAXE_FREED = 78501, - - CONVERSATION_WARLORD_GRIMAXE_SPAWN_Q59942 = 14527, - CONVERSATION_WARLORD_GRIMAXE_QUEST_COMPLETE_Q59942 = 15618 -}; - -// 167146 - Warlord Grimaxe -struct npc_warlord_grimaxe_q59942 : public ScriptedAI -{ - npc_warlord_grimaxe_q59942(Creature* creature) : ScriptedAI(creature) - { - me->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); - } - - void JustAppeared() override - { - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - return; - - Creature* shuja = FindCreatureIgnorePhase(me, "shuja_grimaxe_ogre_ruins_prisoner"); - if (!shuja) - return; - - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_WARLORD_GRIMAXE_SPAWN_Q59942, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - return; - - conversation->AddActor(ACTOR_SHUJA_GRIMAXE_PRISONER, 0, shuja->GetGUID()); - conversation->AddActor(ACTOR_WARLORD_GRIMAXE_Q59942, 1, me->GetGUID()); - conversation->Start(); - - me->GetMotionMaster()->MoveFollow(player, 0.0f, float(M_PI / 4.0f)); - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (me->GetHealth() <= damage) - damage = me->GetHealth() - 1; - } - - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override - { - switch (spellInfo->Id) - { - case SPELL_PING_GARRICK_TORGOK: - { - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - break; - - Creature* shuja = FindCreatureIgnorePhase(me, "shuja_grimaxe_ogre_ruins_prisoner"); - if (!shuja) - break; - - Creature* shujaPersonal = shuja->SummonPersonalClone(shuja->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!shujaPersonal) - break; - - me->SetReactState(REACT_AGGRESSIVE); - _shujaGUID = shujaPersonal->GetGUID(); - _events.ScheduleEvent(EVENT_CAPTAIN_GARRICK_RIDE_BOAR_TALK_TO_HENRY, 1s); - break; - } - default: - break; - } - } - - void OnDespawn() override - { - if (Creature* shuja = ObjectAccessor::GetCreature(*me, _shujaGUID)) - shuja->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CAPTAIN_GARRICK_RIDE_BOAR_TALK_TO_HENRY: - { - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - break; - - Conversation* conversation = Conversation::CreateConversation(CONVERSATION_WARLORD_GRIMAXE_QUEST_COMPLETE_Q59942, player, *player, player->GetGUID(), nullptr, false); - if (!conversation) - break; - - conversation->AddActor(ACTOR_WARLORD_GRIMAXE_Q59942, 0, me->GetGUID()); - conversation->AddActor(ACTOR_SHUJA_GRIMAXE_FREED, 1, _shujaGUID); - conversation->Start(); - - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(POINT_HENRY_POSITION, MoveToPrisonerPosition); - _events.ScheduleEvent(EVENT_CAPTAIN_GARRICK_RIDE_BOAR_HENRY_DESPAWN, 22s); - break; - } - case EVENT_CAPTAIN_GARRICK_RIDE_BOAR_HENRY_DESPAWN: - { - me->DespawnOrUnsummon(); - if (Creature* shuja = ObjectAccessor::GetCreature(*me, _shujaGUID)) - shuja->DespawnOrUnsummon(); - - Player* player = Object::ToPlayer(me->GetOwner()); - if (!player) - break; - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - } - default: - break; - } - } - - UpdateVictim(); - } -private: - EventMap _events; - ObjectGuid _shujaGUID; -}; - -// *************************************************************** -// * Scripting in this section occurs between Ogre Ruins and Pit * -// *************************************************************** - -enum WestwardBound -{ - NPC_BJORN_STOUTHANDS_PIT_ONE = 156891, - NPC_ALARIA_PIT_ONE = 156803, - NPC_LANAJORDAN_PIT_ONE = 167225, - NPC_WONSA_PIT_ONE = 167226 -}; - -static constexpr Position BjornWestwardBoundRuinsPos = { 192.181f, -2311.44f, 80.6975f, 3.368485450744628906f }; -static constexpr Position AlariaWestwardBoundRuinsPos = { 190.953f, -2308.32f, 80.6586f, 2.984513044357299804f }; -static constexpr Position LanaWestwardBoundRuinsPos = { 160.486f, -2307.31f, 84.053f, 2.932153224945068359f }; -static constexpr Position WonsaWestwardBoundRuinsPos = { 160.431f, -2310.11f, 84.4598f, 3.03687286376953125f }; - -// 55965 - Quest Westward Bound "Alliance" -// 59948 - Quest Westward Bound "Horde" -class quest_westward_bound : public QuestScript -{ -public: - quest_westward_bound(char const* script) : QuestScript(script) { } - - void HandleQuestStatusChange(Player* player, QuestStatus newStatus, std::string_view creatureStringOne, std::string_view creatureStringTwo, uint32 questEnderEntry, uint32 questEnderCompanionEntry, Position questGiverPos, Position companionPos) - { - switch (newStatus) - { - case QUEST_STATUS_INCOMPLETE: - { - Creature* questEnder = FindCreatureIgnorePhase(player, creatureStringOne, 125.0f); - if (!questEnder) - return; - - Creature* questEnderCompanion = FindCreatureIgnorePhase(player, creatureStringTwo, 125.0f); - if (!questEnderCompanion) - return; - - questEnder->SummonPersonalClone(questGiverPos, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - questEnderCompanion->SummonPersonalClone(companionPos, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - break; - } - case QUEST_STATUS_NONE: - { - player->CastSpell(player, SPELL_UPDATE_PHASE_SHIFT); - - if (Creature* questGiver = player->FindNearestCreatureWithOptions(100.0f, { .CreatureId = questEnderEntry, .IgnorePhases = true, .PrivateObjectOwnerGuid = player->GetGUID() })) - questGiver->DespawnOrUnsummon(); - - if (Creature* companion = player->FindNearestCreatureWithOptions(100.0f, { .CreatureId = questEnderCompanionEntry, .IgnorePhases = true, .PrivateObjectOwnerGuid = player->GetGUID() })) - companion->DespawnOrUnsummon(); - - break; - } - default: - break; - } - } -}; - -// 55965 - Quest Westward Bound "Alliance" -class quest_westward_bound_alliance : public quest_westward_bound -{ -public: - quest_westward_bound_alliance() : quest_westward_bound("quest_westward_bound_alliance") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, "bjorn_stouthands_pit_pre_quest", "alaria_pit_pre_quest", NPC_BJORN_STOUTHANDS_PIT_ONE, NPC_ALARIA_PIT_ONE, BjornWestwardBoundRuinsPos, AlariaWestwardBoundRuinsPos); - } -}; - -// 59948 - Quest Westward Bound "Horde" -class quest_westward_bound_horde : public quest_westward_bound -{ -public: - quest_westward_bound_horde() : quest_westward_bound("quest_westward_bound_horde") { } - - void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override - { - HandleQuestStatusChange(player, newStatus, "lana_joran_pit_pre_quest", "wonsa_pit_pre_quest", NPC_LANAJORDAN_PIT_ONE, NPC_WONSA_PIT_ONE, LanaWestwardBoundRuinsPos, WonsaWestwardBoundRuinsPos); - } -}; - -enum BjornRunToPit -{ - EVENT_BJORN_RUN_TO_PIT = 1, - - PATH_BJORN_RUN_TO_PIT = 10518900, - - SAY_BJORN_RUN_TO_PIT = 0, - SAY_BJORN_REACHED_PIT = 1 -}; - -// 156891 - Bjorn Stouthands -struct npc_bjorn_stouthands_q55965_private : public ScriptedAI -{ - npc_bjorn_stouthands_q55965_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - } - - void JustAppeared() override - { - _events.ScheduleEvent(EVENT_BJORN_RUN_TO_PIT, 1s); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 /*pathId*/) override - { - Talk(SAY_BJORN_REACHED_PIT); - me->DespawnOrUnsummon(4s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_BJORN_RUN_TO_PIT: - Talk(SAY_BJORN_RUN_TO_PIT); - me->GetMotionMaster()->MovePath(PATH_BJORN_RUN_TO_PIT, false); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -CreatureAI* BjornRuinsSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_bjorn_stouthands_q55965_private(creature); - else - return new NullCreatureAI(creature); -}; - -enum LanaRunToPit -{ - EVENT_LANA_SAY_AT_RUINS = 1, - EVENT_LANA_RUN_TO_PIT = 2, - - PATH_LANA_RUN_TO_PIT = 80000570, - - SAY_LANA_RUN_TO_PIT = 0, - SAY_LANA_REACHED_PIT = 1 -}; - -// 167225 - Lana Jordan -struct npc_lana_jordan_q59948_private : public ScriptedAI -{ - npc_lana_jordan_q59948_private(Creature* creature) : ScriptedAI(creature) { } - - void InitializeAI() override - { - me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); - } - - void JustAppeared() override - { - _events.ScheduleEvent(EVENT_LANA_SAY_AT_RUINS, 1s); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 /*pathId*/) override - { - Talk(SAY_LANA_REACHED_PIT); - me->DespawnOrUnsummon(7s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_LANA_SAY_AT_RUINS: - Talk(SAY_BJORN_RUN_TO_PIT); - _events.ScheduleEvent(EVENT_LANA_RUN_TO_PIT, 5s); - break; - case EVENT_LANA_RUN_TO_PIT: - me->GetMotionMaster()->MovePath(PATH_LANA_RUN_TO_PIT, false); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -CreatureAI* LanaRuinsSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_lana_jordan_q59948_private(creature); - else - return new NullCreatureAI(creature); -}; - -enum CompanionRunToPit -{ - EVENT_COMPANION_RUN_TO_PIT = 1, - - PATH_ALARIA_RUN_TO_PIT = 10518890, - PATH_WONSA_RUN_TO_PIT = 80000580 -}; - -// 156891 - Alaria -// 167226 - Won'sa -template<uint32 PitPathId> -struct npc_companion_q55965_q59948_private : public ScriptedAI -{ - npc_companion_q55965_q59948_private(Creature* creature) : ScriptedAI(creature) { } - - void JustAppeared() override - { - _events.ScheduleEvent(EVENT_COMPANION_RUN_TO_PIT, 1s); - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 /*pathId*/) override - { - me->DespawnOrUnsummon(1s); - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_COMPANION_RUN_TO_PIT: - me->GetMotionMaster()->MovePath(PitPathId, false); - break; - default: - break; - } - } - } -private: - EventMap _events; -}; - -CreatureAI* AlariaRuinsSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_companion_q55965_q59948_private<PATH_ALARIA_RUN_TO_PIT>(creature); - else - return new NullCreatureAI(creature); -}; - -CreatureAI* WansaRuinsSelector(Creature* creature) -{ - if (creature->IsPrivateObject()) - return new npc_companion_q55965_q59948_private<PATH_WONSA_RUN_TO_PIT>(creature); - else - return new NullCreatureAI(creature); -}; - -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, &CaptainGarrickAISelector>("npc_captain_garrick"); - 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); - // Quest Enhanced Combat Tactics - new quest_enhanced_combat_tactics(); - RegisterSpellScript(spell_summon_combat_trainer); - new FactoryCreatureScript<CreatureAI, &SparringPartnerEnhancedCombatTrainingSelector>("npc_sparring_partner_combat_training"); - RegisterAreaTriggerAI(at_aggro_radius_check_enhanced_combat_tactics); - RegisterSpellScript(spell_knockback_charge_enhanced_training); - // Quest Northbound - RegisterCreatureAI(npc_leader_northbound); - new quest_northbound_alliance(); - new quest_northbound_horde(); - RegisterSpellScript(spell_summon_leader_northbound); - RegisterAreaTriggerAI(at_northbound_linger); - RegisterSpellScript(spell_scene_linger_northbound); - // Quest Taming The Wilds - new quest_taming_the_wilds_alliance(); - new quest_taming_the_wilds_horde(); - new FactoryCreatureScript<CreatureAI, &HuxsworthBriarpatchSelector>("npc_huxsworth_briarpatch"); - new FactoryCreatureScript<CreatureAI, &DawntrackerBriarpatchSelector>("npc_dawntracker_briarpatch"); - RegisterSpellScript(spell_tutorial_health_dnt_proc_aura); - RegisterSpellScript(spell_tutorial_health_dnt); - // Briarpatch - new quest_briarpatch_alliance(); - new quest_briarpatch_horde(); - RegisterSpellScript(spell_validated_quest_accept_briarpatch_alliance); - RegisterSpellScript(spell_validated_quest_accept_briarpatch_horde); - RegisterCreatureAI(npc_geolord_grekog); - new GenericCreatureScript<npc_briarpatch_prisoner>("npc_cork_fizzlepop_briarpatch"); - new GenericCreatureScript<npc_briarpatch_prisoner>("npc_lindie_springstock_briarpatch"); - RegisterCreatureAI(npc_quilboar_warrior); - RegisterCreatureAI(npc_quilboar_geomancer); - RegisterCreatureAI(npc_ogre_overseer); - RegisterAreaTriggerAI(at_briarpatch_to_plains); - RegisterSpellScript(spell_quilboar_sleep_dnt); - // Plains scouting quest - new quest_scout_o_matic_5000(); - new quest_choppy_booster_mk5(); - new FactoryCreatureScript<CreatureAI, &LindieSpringstockSelector>("npc_lindie_springstock_plains"); - new FactoryCreatureScript<CreatureAI, &CorkFizzlepopSelector>("npc_cork_fizzlepop_plains"); - RegisterCreatureAI(npc_scoutomatic_5000); - new FactoryCreatureScript<CreatureAI, &ChoppyBoosterSelector>("npc_choppy_booster"); - new FactoryCreatureScript<CreatureAI, &HordeCrewPlainsSelector>("npc_horde_crew_plains"); - // Plains Resizing the situation - new quest_resizing_the_situation_alliance(); - new quest_resizing_the_situation_horde(); - RegisterCreatureAI(npc_lindie_springstock_q56034); - RegisterCreatureAI(npc_cork_fizzlepop_q59941); - RegisterCreatureAI(npc_re_sized_boar_q56034); - RegisterSpellScript(spell_summon_guardian_q56034_q59941); - RegisterSpellAndAuraScriptPair(spell_re_sizing_q56034, spell_re_sizing_aura_q56034); - RegisterSpellScript(spell_resizer_hit_one_two_q56034_q59941); - RegisterSpellScript(spell_resizer_hit_three_q56034); - RegisterSpellScript(spell_re_sizing_q59941); - RegisterSpellScript(spell_re_sizing_aura_q59941); - RegisterSpellScript(spell_re_sizer_slaughter); - // Ride Boar - new quest_ride_of_the_scientifically_enhanced_boar(); - new scene_darkmaul_plains_skeleton_army_alliance(); - RegisterSpellScript(spell_summon_darkmaul_plains_questgivers_q55879); - RegisterSpellScript(spell_riding_giant_boar_q55879); - RegisterSpellScript(spell_knockback_hint_q56034); - RegisterCreatureAI(npc_captain_garrick_q55879); - RegisterCreatureAI(npc_giant_boar_vehicle_q55879); - RegisterCreatureAI(npc_torgok_q55879); - new FactoryCreatureScript<CreatureAI, &PrisonerQ55879Selector>("npc_prisoner_q55879"); - // The Re-Deather - new quest_the_re_deather(); - new scene_darkmaul_plains_skeleton_army_horde(); - RegisterCreatureAI(npc_warlord_grimaxe_q59942); - // Westward Bound - new quest_westward_bound_alliance(); - new quest_westward_bound_horde(); - new FactoryCreatureScript<CreatureAI, &BjornRuinsSelector>("npc_bjorn_stouthands_q55965"); - new FactoryCreatureScript<CreatureAI, &LanaRuinsSelector>("npc_lana_jordan_q59948"); - new FactoryCreatureScript<CreatureAI, &AlariaRuinsSelector>("npc_alaria_q55965"); - new FactoryCreatureScript<CreatureAI, &WansaRuinsSelector>("npc_wonsa_q59948"); -}; diff --git a/src/server/scripts/KulTiras/kultiras_script_loader.cpp b/src/server/scripts/KulTiras/kultiras_script_loader.cpp deleted file mode 100644 index e4ed7ba007f..00000000000 --- a/src/server/scripts/KulTiras/kultiras_script_loader.cpp +++ /dev/null @@ -1,27 +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_boralus(); - -// The name of this function should match: -// void Add${NameOfDirectory}Scripts() -void AddKulTirasScripts() -{ - AddSC_zone_boralus(); -} diff --git a/src/server/scripts/KulTiras/zone_boralus.cpp b/src/server/scripts/KulTiras/zone_boralus.cpp deleted file mode 100644 index 32dc6942110..00000000000 --- a/src/server/scripts/KulTiras/zone_boralus.cpp +++ /dev/null @@ -1,807 +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 "CreatureAIImpl.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "PhasingHandler.h" -#include "Player.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "SpellInfo.h" -#include "SpellScript.h" -#include "TemporarySummon.h" - -enum GetYourBearingsData -{ - QUEST_GET_YOUR_BEARINGS = 47099, - - KILL_CREDIT_FERRY_DOCK_VISITED = 124588, - KILL_CREDIT_COUNTING_HOUSE_VISITED = 124586, - KILL_CREDIT_SNUG_HARBOR_INN_VISITED = 124768, - KILL_CREDIT_FLIGHT_MASTER_VISITED = 124587, - - OBJECTIVE_FERRY_DOCK_VISITED = 291081, - OBJECTIVE_COUNTING_HOUSE_VISITED = 291079, - OBJECTIVE_SNUG_HARBOR_INN_VISITED = 291080, - OBJECTIVE_FLIGHT_MASTER_VISITED = 291171, - - NPC_SUMMONED_KULTIRAN_GUARD = 124630, - - CONVO_ACTOR_KULTIRAN_GUARD = 59582, - - POINT_KULTIRAN_GUARD = 1, - POINT_KULTIRAN_GUARD_FLIGHT_MASTER = 2, - - SPELL_HUB_TOUR_CONVO_FERRY = 247669, - SPELL_HUB_TOUR_CONVO_BANK = 247749, - SPELL_HUB_TOUR_CONVO_INN = 247894, - SPELL_HUB_TOUR_CONVO_FLIGHT_MASTER = 247753 -}; - -enum TheOldKnightData -{ - QUEST_THE_OLD_KNIGHT = 46729, - - NPC_CYRUS_CRESTFALL = 122370, - NPC_GENN_GREYMANE = 120788, - NPC_GREYGUARD = 120599, - - GOSSIP_MENU_CYRUS_SHAKING_HANDS = 22543, - GOSSIP_OPTION_CYRUS_SHAKING_HANDS = 0, - - CONVO_ACCEPT_OLD_KNIGHT_QUEST = 9556, - CONVO_CYRUS_MEETS_GENN_IN_OFFICE = 8062, - CONVO_CYRUS_SHAKING_HAND = 7653, - - CONVO_ACTOR_CYRUS_CRESTFAL = 59635, - - OBJECTIVE_ENTER_HARBORMASTERS_OFFICE = 335127, - - KILLCREDIT_SPEAK_WITH_CYRUS_OLD_KNIGHT = 137009, - KILLCREDIT_HEAR_CYRUS_TALE_OLD_KNIGHT = 137877, - - PATH_KULTIRAN_GUARD_ENTER_OFFICE = 12463000, - PATH_KULTIRAN_GUARD_AFTER_SCENE_OFFICE = 12463001, - PATH_CYRUS_CRESTFAL_AFTER_SCENE_OFFICE = 12237000, - PATH_GENN_GREYMANE_AFTER_SCENE_OFFICE = 12078800, - PATH_GREYGUARD_TWO_AFTER_SCENE_OFFICE = 12059900, - PATH_GREYGUARD_ONE_AFTER_SCENE_OFFICE = 12059901, - - SPELL_ENTER_HARBOR_MASTERS_OFFICE = 268759, - SPELL_FIND_CYRUS_OBJECTIVE_COMPLETE = 269054, - SPELL_CLIENT_SCENE_CYRUS_AND_GENN = 271234 -}; - -// 124630 - Taelia -struct npc_taelia_get_your_bearings : public ScriptedAI -{ - npc_taelia_get_your_bearings(Creature* creature) : ScriptedAI(creature) { } - - void IsSummonedBy(WorldObject* summoner) override - { - // might be handled by SummonProperties - if (Player* player = summoner->ToPlayer()) - me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - } - - void OnQuestAccept(Player* player, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_THE_OLD_KNIGHT) - Conversation::CreateConversation(CONVO_ACCEPT_OLD_KNIGHT_QUEST, player, *player, player->GetGUID(), nullptr, false); - } - - void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override - { - if (spellInfo->Id != SPELL_FIND_CYRUS_OBJECTIVE_COMPLETE) - return; - - me->GetMotionMaster()->MovePath(PATH_KULTIRAN_GUARD_AFTER_SCENE_OFFICE, false); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (pointId == POINT_KULTIRAN_GUARD) - { - if (Unit* summoner = me->GetOwner()) - me->SetFacingToObject(summoner); - } - } - - void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override - { - if (pathId == PATH_KULTIRAN_GUARD_AFTER_SCENE_OFFICE) - me->DespawnOrUnsummon(); - } -}; - -// 5360 - Conversation -class conversation_boralus_hub_tour_00 : public ConversationScript -{ -public: - conversation_boralus_hub_tour_00() : ConversationScript("conversation_boralus_hub_tour_00") { } - - void OnConversationCreate(Conversation* conversation, Unit* creator) override - { - Creature* kultiranGuard = creator->FindNearestCreatureWithOptions(20.0f, { .CreatureId = NPC_SUMMONED_KULTIRAN_GUARD, .IgnorePhases = true, .OwnerGuid = creator->GetGUID() }); - if (!kultiranGuard) - return; - - conversation->AddActor(CONVO_ACTOR_KULTIRAN_GUARD, 0, kultiranGuard->GetGUID()); - conversation->Start(); - } -}; - -// XX - Boralus - Get your Bearings (Ferry) -// XX - Boralus - Get your Bearings (Bank) -// XX - Boralus - Get your Bearings (Inn) -// XX - Boralus - Get your Bearings (Flightmaster) -template<uint32 QuestId, uint32 ObjectiveId, uint32 SpellId> -struct at_boralus_get_your_bearings : AreaTriggerAI -{ - at_boralus_get_your_bearings(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player || player->GetQuestStatus(QuestId) != QUEST_STATUS_INCOMPLETE || player->GetQuestObjectiveData(QuestId, ObjectiveId)) - return; - - player->CastSpell(nullptr, SpellId, false); - } -}; - -// 5362 - Conversation - Get your Bearings (Ferry) -class conversation_boralus_hub_tour : public ConversationScript -{ -public: - conversation_boralus_hub_tour(char const* scriptName) : ConversationScript(scriptName) { } - - enum ConversationFerryData - { - EVENT_TAELIA_CREDIT = 1 - }; - - virtual Position const& GetGuardMovePosition() = 0; - virtual uint32 GetKillCreditId() = 0; - - void OnConversationCreate(Conversation* conversation, Unit* creator) override - { - Creature* kultiranGuard = creator->FindNearestCreatureWithOptions(20.0f, { .CreatureId = NPC_SUMMONED_KULTIRAN_GUARD, .IgnorePhases = true, .OwnerGuid = creator->GetGUID() }); - if (!kultiranGuard) - return; - - kultiranGuard->GetMotionMaster()->Clear(); - kultiranGuard->GetMotionMaster()->MovePoint(POINT_KULTIRAN_GUARD, GetGuardMovePosition()); - - conversation->AddActor(CONVO_ACTOR_KULTIRAN_GUARD, 0, kultiranGuard->GetGUID()); - conversation->Start(); - } - - void OnConversationStart(Conversation* conversation) override - { - LocaleConstant privateOwnerLocale = conversation->GetPrivateObjectOwnerLocale(); - - _events.ScheduleEvent(EVENT_TAELIA_CREDIT, conversation->GetLastLineEndTime(privateOwnerLocale)); - } - - void OnConversationUpdate(Conversation* conversation, uint32 diff) override - { - _events.Update(diff); - - switch (_events.ExecuteEvent()) - { - case EVENT_TAELIA_CREDIT: - { - Player* player = ObjectAccessor::GetPlayer(*conversation, conversation->GetPrivateObjectOwner()); - if (!player) - break; - - Creature* kultiranGuard = player->FindNearestCreatureWithOptions(50.0f, { .CreatureId = NPC_SUMMONED_KULTIRAN_GUARD, .IgnorePhases = true, .OwnerGuid = player->GetGUID() }); - if (!kultiranGuard) - break; - - player->KilledMonsterCredit(GetKillCreditId()); - kultiranGuard->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - break; - } - default: - break; - } - } -private: - EventMap _events; -}; - -Position const TaeliaFerryPos = { 1039.5955f, -598.00653f, 1.458778f }; - -// 5362 - Conversation - Get your Bearings (Ferry) -class conversation_boralus_hub_tour_ferry : public conversation_boralus_hub_tour -{ -public: - conversation_boralus_hub_tour_ferry() : conversation_boralus_hub_tour("conversation_boralus_hub_tour_ferry") { } - - Position const& GetGuardMovePosition() - { - return TaeliaFerryPos; - } - - uint32 GetKillCreditId() - { - return KILL_CREDIT_FERRY_DOCK_VISITED; - } -}; - -Position const TaeliaBankPos = { 1118.7385f, -622.4115f, 17.76035f }; - -// 5365 - Conversation Get your Bearings (Counting House) -class conversation_boralus_hub_tour_counting_house : public conversation_boralus_hub_tour -{ -public: - conversation_boralus_hub_tour_counting_house() : conversation_boralus_hub_tour("conversation_boralus_hub_tour_counting_house") { } - - Position const& GetGuardMovePosition() - { - return TaeliaBankPos; - } - - uint32 GetKillCreditId() - { - return KILL_CREDIT_COUNTING_HOUSE_VISITED; - } -}; - -Position const TaeliaInnPos = { 1177.39f, -587.682f, 31.557224f }; - -// 5375 - Conversation Get your Bearings (Harbor Inn) -class conversation_boralus_hub_tour_harbor_inn : public conversation_boralus_hub_tour -{ -public: - conversation_boralus_hub_tour_harbor_inn() : conversation_boralus_hub_tour("conversation_boralus_hub_tour_harbor_inn") { } - - Position const& GetGuardMovePosition() - { - return TaeliaInnPos; - } - - uint32 GetKillCreditId() - { - return KILL_CREDIT_SNUG_HARBOR_INN_VISITED; - } -}; - -Position const TaeliaFlightMasterPos = { 1149.82f, -471.071f, 30.503826f }; - -// 5366 - Conversation Get your Bearings (Flight Master) -class conversation_boralus_hub_tour_flight_master : public conversation_boralus_hub_tour -{ -public: - conversation_boralus_hub_tour_flight_master() : conversation_boralus_hub_tour("conversation_boralus_hub_tour_flight_master") { } - - Position const& GetGuardMovePosition() - { - return TaeliaFlightMasterPos; - } - - uint32 GetKillCreditId() - { - return KILL_CREDIT_FLIGHT_MASTER_VISITED; - } -}; - -// 9556 - Conversation The Old Knight (accept Quest) -class conversation_boralus_accept_old_knight : public ConversationScript -{ -public: - conversation_boralus_accept_old_knight() : ConversationScript("conversation_boralus_accept_old_knight") { } - - void OnConversationCreate(Conversation* conversation, Unit* creator) override - { - Creature* kultiranGuard = creator->FindNearestCreatureWithOptions(20.0f, { .CreatureId = NPC_SUMMONED_KULTIRAN_GUARD, .IgnorePhases = true, .OwnerGuid = creator->GetGUID() }); - if (!kultiranGuard) - return; - - conversation->AddActor(CONVO_ACTOR_KULTIRAN_GUARD, 0, kultiranGuard->GetGUID()); - conversation->Start(); - } -}; - -// XX - Boralus The Old Knight (Enter the Harbormasters Office) -struct at_boralus_old_knight_enter_harbormasters_office : AreaTriggerAI -{ - at_boralus_old_knight_enter_harbormasters_office(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player || player->GetQuestStatus(QUEST_THE_OLD_KNIGHT) != QUEST_STATUS_INCOMPLETE || player->GetQuestObjectiveData(QUEST_THE_OLD_KNIGHT, OBJECTIVE_ENTER_HARBORMASTERS_OFFICE)) - return; - - player->CastSpell(nullptr, SPELL_ENTER_HARBOR_MASTERS_OFFICE, false); - } -}; - -// 7605 - Conversation The Old Knight (Enter the Harbormasters Office) -class conversation_boralus_enter_harbormaster_office : public ConversationScript -{ -public: - conversation_boralus_enter_harbormaster_office() : ConversationScript("conversation_boralus_enter_harbormaster_office") { } - - void OnConversationCreate(Conversation* conversation, Unit* creator) override - { - Creature* kultiranGuard = creator->FindNearestCreatureWithOptions(20.0f, { .CreatureId = NPC_SUMMONED_KULTIRAN_GUARD, .IgnorePhases = true, .OwnerGuid = creator->GetGUID() }); - if (!kultiranGuard) - return; - - kultiranGuard->GetMotionMaster()->Clear(); - kultiranGuard->GetMotionMaster()->MovePath(PATH_KULTIRAN_GUARD_ENTER_OFFICE, false); - - conversation->AddActor(CONVO_ACTOR_KULTIRAN_GUARD, 0, kultiranGuard->GetGUID()); - conversation->Start(); - } -}; - -// XX - Boralus The Old Knight (Genn Greymane arrives Boralus) -struct at_boralus_old_knight_genn_arrives_boralus : AreaTriggerAI -{ - at_boralus_old_knight_genn_arrives_boralus(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player || player->GetQuestStatus(QUEST_THE_OLD_KNIGHT) != QUEST_STATUS_INCOMPLETE || player->GetQuestObjectiveData(QUEST_THE_OLD_KNIGHT, OBJECTIVE_ENTER_HARBORMASTERS_OFFICE)) - return; - - player->CastSpell(nullptr, SPELL_CLIENT_SCENE_CYRUS_AND_GENN, false); - } -}; - -// 1960 - Client Scene: Cyrus and Genn -class scene_boralus_client_scene_cyrus_and_genn : public SceneScript -{ -public: - scene_boralus_client_scene_cyrus_and_genn() : SceneScript("scene_boralus_client_scene_cyrus_and_genn") { } - - void OnSceneComplete(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->CastSpell(player, SPELL_FIND_CYRUS_OBJECTIVE_COMPLETE, true); - } - - void OnSceneCancel(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/) override - { - player->CastSpell(player, SPELL_FIND_CYRUS_OBJECTIVE_COMPLETE, true); - } -}; - -Position const TaeliaTeleportOfficePos = { 1054.29f, -469.776f, 11.7166f, 3.065999f }; - -// 269054 - Find Cyrus Objective Complete -class spell_boralus_find_cyrus_objective_complete : public SpellScript -{ - void HandleHitTarget(SpellEffIndex /*effIndex*/) - { - if (Player* player = GetHitUnit()->ToPlayer()) - { - player->KilledMonsterCredit(NPC_CYRUS_CRESTFALL); - Conversation::CreateConversation(CONVO_CYRUS_MEETS_GENN_IN_OFFICE, player, *player, player->GetGUID(), nullptr, false); - } - else - { - if (GetHitUnit()->GetEntry() != NPC_SUMMONED_KULTIRAN_GUARD) - return; - - GetHitUnit()->NearTeleportTo(TaeliaTeleportOfficePos); - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_boralus_find_cyrus_objective_complete::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -Position const CyrusOfficePos = { 1056.310f, -470.567f, 11.656f, 5.80610f }; -Position const GennOfficePos = { 1052.689f, -470.200f, 11.692f, 0.24838f }; -Position const GreyguardOneOfficePos = { 1044.979f, -468.523f, 8.386f, 6.03047f }; -Position const GreyguardTwoOfficePos = { 1042.359f, -467.738f, 8.386f, 6.04665f }; - -// 8062 - Conversation -class conversation_boralus_cyrus_meets_genn : public ConversationScript -{ -public: - conversation_boralus_cyrus_meets_genn() : ConversationScript("conversation_boralus_cyrus_meets_genn") { } - - enum OldKnightsConversationData - { - CONVO_LINE_CYRUS_AND_GENN_DESPAWN = 18298, - - EVENT_OLD_KNIGHTS_CLONE_DESPAWN = 1 - }; - - void OnConversationCreate(Conversation* conversation, Unit* creator) override - { - Creature* cyrusObject = GetClosestCreatureWithOptions(creator, 30.0f, { .CreatureId = NPC_CYRUS_CRESTFALL, .IgnorePhases = true }); - Creature* gennObject = GetClosestCreatureWithOptions(creator, 30.0f, { .CreatureId = NPC_GENN_GREYMANE, .IgnorePhases = true }); - Creature* greyguardOneObject = GetClosestCreatureWithOptions(creator, 30.0f, { .CreatureId = NPC_GREYGUARD, .StringId = "GreyguardOne", .IgnorePhases = true }); - Creature* greyguardTwoObject = GetClosestCreatureWithOptions(creator, 30.0f, { .CreatureId = NPC_GREYGUARD, .StringId = "GreyguardTwo", .IgnorePhases = true }); - if (!cyrusObject || !gennObject || !greyguardOneObject || !greyguardTwoObject) - return; - - TempSummon* cyrusClone = cyrusObject->SummonPersonalClone(CyrusOfficePos, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - TempSummon* gennClone = gennObject->SummonPersonalClone(GennOfficePos, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - TempSummon* greyguardOneClone = greyguardOneObject->SummonPersonalClone(GreyguardOneOfficePos, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - TempSummon* greyguardTwoClone = greyguardTwoObject->SummonPersonalClone(GreyguardTwoOfficePos, TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - if (!cyrusClone || !gennClone || !greyguardOneClone || !greyguardTwoClone) - return; - - _gennCloneGUID = gennClone->GetGUID(); - - cyrusClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER)); - gennClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER)); - - cyrusClone->GetMotionMaster()->MovePath(PATH_CYRUS_CRESTFAL_AFTER_SCENE_OFFICE, false); - gennClone->GetMotionMaster()->MovePath(PATH_GENN_GREYMANE_AFTER_SCENE_OFFICE, false); - greyguardOneClone->GetMotionMaster()->MovePath(PATH_GREYGUARD_ONE_AFTER_SCENE_OFFICE, false); - greyguardTwoClone->GetMotionMaster()->MovePath(PATH_GREYGUARD_TWO_AFTER_SCENE_OFFICE, false); - - conversation->AddActor(CONVO_ACTOR_CYRUS_CRESTFAL, 0, cyrusClone->GetGUID()); - conversation->Start(); - } - - void OnConversationStart(Conversation* conversation) override - { - LocaleConstant privateOwnerLocale = conversation->GetPrivateObjectOwnerLocale(); - - _events.ScheduleEvent(EVENT_OLD_KNIGHTS_CLONE_DESPAWN, conversation->GetLineEndTime(privateOwnerLocale, CONVO_LINE_CYRUS_AND_GENN_DESPAWN)); - } - - void OnConversationUpdate(Conversation* conversation, uint32 diff) override - { - _events.Update(diff); - - switch (_events.ExecuteEvent()) - { - case EVENT_OLD_KNIGHTS_CLONE_DESPAWN: - { - Creature* cyrusClone = conversation->GetActorCreature(0); - if (!cyrusClone) - break; - - Unit* privateObjectOwner = ObjectAccessor::GetUnit(*conversation, conversation->GetPrivateObjectOwner()); - if (!privateObjectOwner) - return; - - if (Creature* gennClone = ObjectAccessor::GetCreature(*conversation, _gennCloneGUID)) - gennClone->DespawnOrUnsummon(); - - cyrusClone->DespawnOrUnsummon(); - PhasingHandler::OnConditionChange(privateObjectOwner); - break; - } - default: - break; - } - } - -private: - ObjectGuid _gennCloneGUID; - EventMap _events; -}; - -// 122370 - Cyrus Crestfall -struct npc_cyrus_crestfall_old_knight : public ScriptedAI -{ - npc_cyrus_crestfall_old_knight(Creature* creature) : ScriptedAI(creature) { } - - bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override - { - // Quest 46729 - The Old Knight - if (menuId == GOSSIP_MENU_CYRUS_SHAKING_HANDS && gossipListId == GOSSIP_OPTION_CYRUS_SHAKING_HANDS) - { - CloseGossipMenuFor(player); - player->KilledMonsterCredit(KILLCREDIT_SPEAK_WITH_CYRUS_OLD_KNIGHT); - Conversation::CreateConversation(CONVO_CYRUS_SHAKING_HAND, player, *player, player->GetGUID(), nullptr, false); - } - return true; - } -}; - -Position const CyrusMoveToOfficeFirePos = { 1075.257f, -487.25696f, 9.812291f }; -Position const CyrusStaticOfficePos = { 1071.428f, -486.312f, 9.783f, 3.4995f }; - -// 7653 - Conversation -class conversation_cyrus_crestfall_shaking_hands : public ConversationScript -{ -public: - conversation_cyrus_crestfall_shaking_hands() : ConversationScript("conversation_cyrus_crestfall_shaking_hands") { } - - enum ShakingHandsConversationData - { - CONVO_LINE_CYRUS_START_WALK_TO_FIRE = 17416, - CONVO_LINE_CYRUS_CHANGE_FACING_GENN = 17419, - CONVO_LINE_CYRUS_MOVE_BACK_TO_GENN = 17421, - CONVO_LINE_CYRUS_DESPAWN_CLONE_OFFICE = 17423, - - EVENT_CYRUS_START_WALK_TO_FIRE = 1, - EVENT_CYRUS_CHANGE_FACING_GENN = 2, - EVENT_CYRUS_MOVE_BACK_TO_GENN = 3, - EVENT_CYRUS_DESPAWN_CLONE_OFFICE = 4, - - POINT_CYRUS_MOVE_TO_OFFICE_FIRE = 1, - POINT_CYRUS_MOVE_BACK_TO_GENN = 2 - }; - - void OnConversationCreate(Conversation* conversation, Unit* creator) override - { - Creature* cyrusObject = GetClosestCreatureWithOptions(creator, 10.0f, { .CreatureId = NPC_CYRUS_CRESTFALL, .IgnorePhases = true }); - if (!cyrusObject) - return; - - TempSummon* cyrusClone = cyrusObject->SummonPersonalClone(cyrusObject->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, creator->ToPlayer()); - if (!cyrusClone) - return; - - cyrusClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER)); - - conversation->AddActor(CONVO_ACTOR_CYRUS_CRESTFAL, 1, cyrusClone->GetGUID()); - conversation->Start(); - } - - void OnConversationStart(Conversation* conversation) override - { - LocaleConstant privateOwnerLocale = conversation->GetPrivateObjectOwnerLocale(); - - _events.ScheduleEvent(EVENT_CYRUS_START_WALK_TO_FIRE, conversation->GetLineEndTime(privateOwnerLocale, CONVO_LINE_CYRUS_START_WALK_TO_FIRE)); - _events.ScheduleEvent(EVENT_CYRUS_CHANGE_FACING_GENN, conversation->GetLineEndTime(privateOwnerLocale, CONVO_LINE_CYRUS_CHANGE_FACING_GENN)); - _events.ScheduleEvent(EVENT_CYRUS_MOVE_BACK_TO_GENN, conversation->GetLineEndTime(privateOwnerLocale, CONVO_LINE_CYRUS_MOVE_BACK_TO_GENN)); - _events.ScheduleEvent(EVENT_CYRUS_DESPAWN_CLONE_OFFICE, conversation->GetLineEndTime(privateOwnerLocale, CONVO_LINE_CYRUS_DESPAWN_CLONE_OFFICE)); - } - - void OnConversationUpdate(Conversation* conversation, uint32 diff) override - { - _events.Update(diff); - - switch (_events.ExecuteEvent()) - { - case EVENT_CYRUS_START_WALK_TO_FIRE: - { - Creature* cyrusClone = conversation->GetActorCreature(1); - if (!cyrusClone) - break; - - cyrusClone->SetWalk(true); - cyrusClone->GetMotionMaster()->MovePoint(POINT_CYRUS_MOVE_TO_OFFICE_FIRE, CyrusMoveToOfficeFirePos); - break; - } - case EVENT_CYRUS_CHANGE_FACING_GENN: - { - Creature* cyrusClone = conversation->GetActorCreature(1); - if (!cyrusClone) - break; - - cyrusClone->SetFacingTo(3.49956f); - break; - } - case EVENT_CYRUS_MOVE_BACK_TO_GENN: - { - Creature* cyrusClone = conversation->GetActorCreature(1); - if (!cyrusClone) - break; - - Player* privateObjectOwner = ObjectAccessor::GetPlayer(*conversation, conversation->GetPrivateObjectOwner()); - if (!privateObjectOwner) - return; - - cyrusClone->SetWalk(true); - cyrusClone->GetMotionMaster()->MovePoint(POINT_CYRUS_MOVE_BACK_TO_GENN, CyrusStaticOfficePos); - privateObjectOwner->KilledMonsterCredit(KILLCREDIT_HEAR_CYRUS_TALE_OLD_KNIGHT); - break; - } - case EVENT_CYRUS_DESPAWN_CLONE_OFFICE: - { - Creature* cyrusClone = conversation->GetActorCreature(1); - if (!cyrusClone) - break; - - cyrusClone->DespawnOrUnsummon(); - break; - } - default: - break; - } - } - -private: - EventMap _events; -}; - -enum SanctumOfTheSagesData -{ - QUEST_SANCTUM_OF_THE_SAGES = 47186, - - NPC_7TH_LEGION_MAGUS_WITH_GOSSIP = 137066, - NPC_7TH_LEGION_MAGUS = 143613, - - GOSSIP_MENU_OPEN_CITY_PORTALS = 22548, - GOSSIP_OPTION_OPEN_CITY_PORTALS = 0, - - CONVO_SANCTUM_OF_THE_SAGES = 8356, - - KILLCREDIT_OPEN_CAPITAL_PORTALS = 137066, - - SPELL_LEGION_MAGUS_ARCANE_CHANNEL = 54219, - - PATH_MAGUS_OPEN_PORTAL_STORMWIND = 13706600, - PATH_MAGUS_FINISH_PORTAL_STORMWIND = 13706601, - PATH_MAGUS_OPEN_PORTAL_EXODAR = 14361300, - PATH_MAGUS_FINISH_PORTAL_EXODAR = 14361301, - PATH_MAGUS_OPEN_PORTAL_IRONFORGE = 14361302, - PATH_MAGUS_FINISH_PORTAL_IRONFORGE = 14361303 -}; - -// 137066 - 7th Legion Magus -// 143613 - 7th Legion Magus -struct npc_7th_legion_magus_sanctum_of_the_sages : public ScriptedAI -{ - npc_7th_legion_magus_sanctum_of_the_sages(Creature* creature) : ScriptedAI(creature) { } - - bool OnGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override - { - // Quest 47186 - Sanctum of the Sages - if (menuId == GOSSIP_MENU_OPEN_CITY_PORTALS && gossipListId == GOSSIP_OPTION_OPEN_CITY_PORTALS) - { - CloseGossipMenuFor(player); - player->KilledMonsterCredit(KILLCREDIT_OPEN_CAPITAL_PORTALS); - - Creature* magusStormwind = GetClosestCreatureWithOptions(player, 10.0f, { .CreatureId = NPC_7TH_LEGION_MAGUS_WITH_GOSSIP, .StringId = "MagusStormwind", .IgnorePhases = true}); - Creature* magusExodar = GetClosestCreatureWithOptions(player, 10.0f, { .CreatureId = NPC_7TH_LEGION_MAGUS, .StringId = "MagusExodar", .IgnorePhases = true}); - Creature* magusIronforge = GetClosestCreatureWithOptions(player, 10.0f, { .CreatureId = NPC_7TH_LEGION_MAGUS, .StringId = "MagusIronforge", .IgnorePhases = true}); - if (!magusStormwind || !magusExodar || !magusIronforge) - return true; - - TempSummon* magusStormwindClone = magusStormwind->SummonPersonalClone(magusStormwind->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - TempSummon* magusExodarClone = magusExodar->SummonPersonalClone(magusExodar->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - TempSummon* magusIronforgeClone = magusIronforge->SummonPersonalClone(magusIronforge->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0, 0, player); - if (!magusStormwindClone || !magusExodarClone || !magusIronforgeClone) - return true; - - magusStormwindClone->RemoveNpcFlag(NPCFlags(UNIT_NPC_FLAG_GOSSIP)); - magusStormwindClone->GetMotionMaster()->MovePath(PATH_MAGUS_OPEN_PORTAL_STORMWIND, false); - magusExodarClone->GetMotionMaster()->MovePath(PATH_MAGUS_OPEN_PORTAL_EXODAR, false); - magusIronforgeClone->GetMotionMaster()->MovePath(PATH_MAGUS_OPEN_PORTAL_IRONFORGE, false); - } - return true; - } - - void WaypointReached(uint32 /*waypointId*/, uint32 pathId) override - { - if (pathId == PATH_MAGUS_OPEN_PORTAL_EXODAR) - { - DoCastAOE(SPELL_LEGION_MAGUS_ARCANE_CHANNEL); - _scheduler.Schedule(3s + 500ms, [this](TaskContext task) - { - me->InterruptSpell(CURRENT_CHANNELED_SPELL); - task.Schedule(1s + 500ms, [this](TaskContext /*task*/) - { - me->GetMotionMaster()->MovePath(PATH_MAGUS_FINISH_PORTAL_EXODAR, false); - }); - }); - } - else if (pathId == PATH_MAGUS_OPEN_PORTAL_IRONFORGE) - { - DoCastAOE(SPELL_LEGION_MAGUS_ARCANE_CHANNEL); - _scheduler.Schedule(3s + 500ms, [this](TaskContext task) - { - me->InterruptSpell(CURRENT_CHANNELED_SPELL); - task.Schedule(1s + 500ms, [this](TaskContext /*task*/) - { - me->GetMotionMaster()->MovePath(PATH_MAGUS_FINISH_PORTAL_IRONFORGE, false); - }); - }); - } - else if (pathId == PATH_MAGUS_OPEN_PORTAL_STORMWIND) - { - DoCastAOE(SPELL_LEGION_MAGUS_ARCANE_CHANNEL); - _scheduler.Schedule(3s + 500ms, [this](TaskContext task) - { - me->InterruptSpell(CURRENT_CHANNELED_SPELL); - task.Schedule(1s + 500ms, [this](TaskContext /*task*/) - { - TempSummon* summon = me->ToTempSummon(); - if (!summon) - return; - - Unit* summoner = summon->GetSummonerUnit(); - if (!summoner) - return; - - PhasingHandler::OnConditionChange(summoner); - me->GetMotionMaster()->MovePath(PATH_MAGUS_FINISH_PORTAL_STORMWIND, false); - }); - }); - } - else if (pathId == PATH_MAGUS_FINISH_PORTAL_STORMWIND || pathId == PATH_MAGUS_FINISH_PORTAL_EXODAR || pathId == PATH_MAGUS_FINISH_PORTAL_IRONFORGE) - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } - -private: - TaskScheduler _scheduler; -}; - -// 64 - Boralus - Sanctum of the Sages -struct at_boralus_sanctum_of_the_sages_conversation : AreaTriggerAI -{ - at_boralus_sanctum_of_the_sages_conversation(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } - - void OnUnitEnter(Unit* unit) override - { - Player* player = unit->ToPlayer(); - if (!player || player->GetQuestStatus(QUEST_SANCTUM_OF_THE_SAGES) != QUEST_STATUS_COMPLETE) - return; - - Conversation::CreateConversation(CONVO_SANCTUM_OF_THE_SAGES, player, *player, player->GetGUID(), nullptr, true); - } -}; - -void AddSC_zone_boralus() -{ - // Creature - RegisterCreatureAI(npc_taelia_get_your_bearings); - RegisterCreatureAI(npc_cyrus_crestfall_old_knight); - RegisterCreatureAI(npc_7th_legion_magus_sanctum_of_the_sages); - - // Conversation - new conversation_boralus_hub_tour_00(); - new conversation_boralus_hub_tour_ferry(); - new conversation_boralus_hub_tour_counting_house(); - new conversation_boralus_hub_tour_harbor_inn(); - new conversation_boralus_hub_tour_flight_master(); - new conversation_boralus_accept_old_knight(); - new conversation_boralus_enter_harbormaster_office(); - new conversation_boralus_cyrus_meets_genn(); - new conversation_cyrus_crestfall_shaking_hands(); - - // Scene - new scene_boralus_client_scene_cyrus_and_genn(); - - // AreaTrigger - RegisterAreaTriggerAI(at_boralus_old_knight_enter_harbormasters_office); - RegisterAreaTriggerAI(at_boralus_old_knight_genn_arrives_boralus); - RegisterAreaTriggerAI(at_boralus_sanctum_of_the_sages_conversation); - - // AreaTrigger Template - new GenericAreaTriggerEntityScript<at_boralus_get_your_bearings<QUEST_GET_YOUR_BEARINGS, OBJECTIVE_FERRY_DOCK_VISITED, SPELL_HUB_TOUR_CONVO_FERRY>>("at_boralus_get_your_bearings_ferry"); - new GenericAreaTriggerEntityScript<at_boralus_get_your_bearings<QUEST_GET_YOUR_BEARINGS, OBJECTIVE_COUNTING_HOUSE_VISITED, SPELL_HUB_TOUR_CONVO_BANK>>("at_boralus_get_your_bearings_counting_house"); - new GenericAreaTriggerEntityScript<at_boralus_get_your_bearings<QUEST_GET_YOUR_BEARINGS, OBJECTIVE_SNUG_HARBOR_INN_VISITED, SPELL_HUB_TOUR_CONVO_INN>>("at_boralus_get_your_bearings_inn"); - new GenericAreaTriggerEntityScript<at_boralus_get_your_bearings<QUEST_GET_YOUR_BEARINGS, OBJECTIVE_FLIGHT_MASTER_VISITED, SPELL_HUB_TOUR_CONVO_FLIGHT_MASTER>>("at_boralus_get_your_bearings_flight_master"); - - // Spells - RegisterSpellScript(spell_boralus_find_cyrus_objective_complete); -} 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 a9bd29a40bf..00000000000 --- a/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp +++ /dev/null @@ -1,409 +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; - } - - 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 62f6ca3f78b..00000000000 --- a/src/server/scripts/Shadowlands/SepulcherOfTheFirstOnes/boss_anduin_wrynn.cpp +++ /dev/null @@ -1,3849 +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, -}; - -constexpr Position 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 -}; - -//constexpr Position FirimOutroductionPos = { -3830.0156f, -2676.7969f, 91.56402f }; -constexpr Position QuartermasterRahmPos = { -3824.9565f, -2673.0190f, 91.44697f, 4.7163963f }; -constexpr Position LeftKnightPosition = { -3815.4097f, -2677.1824f, 91.44697f, 4.742376f }; -constexpr Position RightKnightPosition = { -3834.6807f, -2677.42360f, 91.44697f, 4.6956997f }; - -constexpr Position DominationGraspCenter = { -3825.0601f, -2715.4600f, 91.3567f, 1.6260f }; - -constexpr Position 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 -}; - -constexpr Position AnduinsDespairSpawnPosition = { -3828.355957f, -2704.1875f, 91.350716f, 4.982021f }; - -constexpr Position AnduinsSoulSpawnPosition = { -3825.060059f, -2715.459961f, 91.356697f, 1.626040f }; - -constexpr Position 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 -}; - -constexpr Position 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 -}; - -constexpr Position RemnantOfAFallenKingSpawnPosition = { -3825.2466f, -2700.0486f, 91.3650f, 1.3762f }; - -constexpr Position 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 -}; - -constexpr Position BeaconOfHopeSpawnPosition = { -3825.0417f, -2715.3923f, 91.3568f, 0.0f }; - -constexpr Position 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; - } - } - - 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); - 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; - } - } - } - -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; - } - } - } - -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; - } - } - -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); - me->SetCanMelee(false); // DoSpellAttackIfReady - } - - 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); - me->SetCanMelee(false); // DoSpellAttackIfReady - } - - 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; - } - } - } - -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); - } -}; - -// 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_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 760bcaa515a..00000000000 --- a/src/server/scripts/Spells/spell_azerite.cpp +++ /dev/null @@ -1,646 +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()) - { - target->ApplyAllAzeriteEmpoweredItemMods(equipped); - - 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 6e66c820454..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 4c174e055a3..00000000000 --- a/src/server/scripts/Zandalar/Underrot/boss_cragmaw_the_infested.cpp +++ /dev/null @@ -1,359 +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; - } - } -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; - } - } -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 a22a79be16d..00000000000 --- a/src/server/scripts/Zandalar/Underrot/boss_elder_leaxa.cpp +++ /dev/null @@ -1,354 +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; - } - } -}; - -// 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; - } - } -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(); -} |