diff options
Diffstat (limited to 'src/server')
4 files changed, 481 insertions, 3 deletions
diff --git a/src/server/scripts/Zandalar/AtalDazar/atal_dazar.h b/src/server/scripts/Zandalar/AtalDazar/atal_dazar.h index 2da36868e0b..afd5015ad09 100644 --- a/src/server/scripts/Zandalar/AtalDazar/atal_dazar.h +++ b/src/server/scripts/Zandalar/AtalDazar/atal_dazar.h @@ -38,11 +38,19 @@ enum AtalDazarCreatureIds  {      // Bosses      BOSS_PRIESTESS_ALUNZA = 129614, -    BOSS_VOLKAAL          = 129399, +    BOSS_VOLKAAL          = 122965,      BOSS_REZAN            = 122963,      BOSS_YAZMA            = 129412  }; +enum AtalDazarGameObjectIds +{ +    GO_VOLKAAL_DOOR_1     = 292399, +    GO_VOLKAAL_DOOR_2     = 292400, +    GO_VOLKAAL_DOOR_3     = 292401, +    GO_VOLKAAL_DOOR_4     = 292402 +}; +  template <class AI, class T>  inline AI* GetAtalDazarAI(T* obj)  { diff --git a/src/server/scripts/Zandalar/AtalDazar/boss_volkaal.cpp b/src/server/scripts/Zandalar/AtalDazar/boss_volkaal.cpp new file mode 100644 index 00000000000..358e3ff5171 --- /dev/null +++ b/src/server/scripts/Zandalar/AtalDazar/boss_volkaal.cpp @@ -0,0 +1,457 @@ +/* + * 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 "CellImpl.h" +#include "Creature.h" +#include "GridNotifiersImpl.h" +#include "InstanceScript.h" +#include "MotionMaster.h" +#include "MoveSpline.h" +#include "ObjectAccessor.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" +#include "atal_dazar.h" + +enum VolkaalSpells +{ +    SPELL_SOUL_ANCHOR         = 259537, +    SPELL_BAD_VOODOO          = 250192, +    SPELL_RAPID_DECAY         = 250241, +    SPELL_RAPID_DECAY_TARGET  = 250694, +    SPELL_RAPID_DECAY_RANDOM  = 250697, +    SPELL_TOXIC_POOL          = 250585, +    SPELL_REANIMATE           = 259531, +    SPELL_TOXIC_LEAP_SELECTOR = 250708, +    SPELL_TOXIC_LEAP          = 250258, +    SPELL_TOXIC_LEAP_DAMAGE   = 250259, +    SPELL_NOXIOUS_STENCH      = 259572, +    SPELL_LINGERING_NAUSEA    = 250372 +}; + +enum VolkaalEvents +{ +    EVENT_TOXIC_LEAP = 1, +    EVENT_NOXIOUS_STENCH, +}; + +enum VolkaalActions +{ +    ACTION_TOTEMS_DIED = 1 +}; + +enum VolkaalSummonGroups +{ +    SUMMON_GROUP_VOLKAAL_TOTEMS = 0 +}; + +enum VolkaalTexts +{ +    SAY_AGGRO = 0, +    SAY_DECAY = 1, +    SAY_DIED  = 2, +    SAY_SLAY  = 3, +    SAY_WIPE  = 4 +}; + +// 122965 - Vol'kaal +struct boss_volkaal : public BossAI +{ +    boss_volkaal(Creature* creature) : BossAI(creature, DATA_VOLKAAL), _toxicLeapCount(1), _leaping(false) { } + +    void JustAppeared() override +    { +        me->SummonCreatureGroup(SUMMON_GROUP_VOLKAAL_TOTEMS); +    } + +    void Reset() override +    { +        _Reset(); + +        _toxicLeapCount = 1; +        _leaping = false; +    } + +    void EnterEvadeMode(EvadeReason /*why*/) override +    { +        Talk(SAY_WIPE); + +        instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); +        summons.DespawnAll(); + +        _EnterEvadeMode(); +        _DespawnAtEvade(); +    } + +    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, 1); + +        for (ObjectGuid summonGuid : summons) +        { +            if (Creature * totem = ObjectAccessor::GetCreature(*me, summonGuid)) +                instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, totem, 2); +        } + +        Talk(SAY_AGGRO); + +        events.ScheduleEvent(EVENT_TOXIC_LEAP, 2200ms); +        events.ScheduleEvent(EVENT_NOXIOUS_STENCH, 5800ms); +    } + +    void JustDied(Unit* /*killer*/) override +    { +        _JustDied(); +        instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); +        summons.DespawnAll(); + +        Talk(SAY_DIED); +    } + +    void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override +    { +        if (spellInfo->Id == SPELL_RAPID_DECAY) +        { +            Talk(SAY_DECAY); +            events.CancelEvent(EVENT_TOXIC_LEAP); +        } +    } + +    void MovementInform(uint32 /*type*/, uint32 id) override +    { +        if (id == EVENT_JUMP) +        { +            DoCastSelf(SPELL_TOXIC_LEAP_DAMAGE); +            _leaping = false; +        } +    } + +    void DoAction(int32 action) override +    { +        if (action == ACTION_TOTEMS_DIED) +        { +            for (ObjectGuid summonGuid : summons) +            { +                if (Creature* totem = ObjectAccessor::GetCreature(*me, summonGuid)) +                { +                    totem->SetUnkillable(false); +                    totem->KillSelf(); +                } +            } +        } +    } + +    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_TOXIC_LEAP: +                { +                    _leaping = true; +                    DoCast(SPELL_TOXIC_LEAP_SELECTOR); +                    _toxicLeapCount++; +                    if (_toxicLeapCount % 3 == 2) +                        events.Repeat(8500ms); +                    else +                        events.Repeat(6s); +                    break; +                } +                case EVENT_NOXIOUS_STENCH: +                { +                    if (!_leaping) +                    { +                        DoCast(SPELL_NOXIOUS_STENCH); +                        events.Repeat(19400ms); +                    } +                    else +                        events.Repeat(100ms); +                    break; +                } +                default: +                    break; +            } + +            if (me->HasUnitState(UNIT_STATE_CASTING)) +                return; +        } +    } + +private: +    uint32 _toxicLeapCount; +    bool _leaping; +}; + +// 125977 - Reanimation Totem +struct npc_volkaal_reanimation_totem : public ScriptedAI +{ +    npc_volkaal_reanimation_totem(Creature* creature) : ScriptedAI(creature) { } + +    void JustAppeared() override +    { +        if (IsHeroicOrHigher()) +            me->SetUnkillable(true); +    } + +    void JustEngagedWith(Unit* /*who*/) override +    { +        InstanceScript* instance = me->GetInstanceScript(); +        if (!instance) +            return; + +        if (Creature* volkaal = instance->GetCreature(DATA_VOLKAAL)) +            volkaal->AI()->DoZoneInCombat(); +    } + +    void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override +    { +        if (me->GetHealth() <= damage) +        { +            if (IsHeroicOrHigher()) +            { +                DoCastSelf(SPELL_SOUL_ANCHOR); +                DoCastSelf(SPELL_REANIMATE); +            } +        } +    } + +    void JustDied(Unit* /*killer*/) override +    { +        InstanceScript* instance = me->GetInstanceScript(); +        if (!instance) +            return; + +        instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); +    } +}; + +// 250372 - Lingering Nausea +class spell_volkaal_lingering_nausea : public AuraScript +{ +    void HandlePeriodic(AuraEffect const* aurEff) const +    { +        Unit* target = GetTarget(); + +        if (Unit* caster = GetCaster()) +            caster->CastSpell(target, aurEff->GetAmount(), CastSpellExtraArgsInit{ +                .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, +                .TriggeringAura = aurEff +        }); +    } + +    void Register() override +    { +        OnEffectPeriodic += AuraEffectPeriodicFn(spell_volkaal_lingering_nausea::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); +    } +}; + +// 250368 - Noxious Stench +class spell_volkaal_noxious_stench : public SpellScript +{ +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo ({ SPELL_LINGERING_NAUSEA }); +    } + +    void HandleDummy(SpellEffIndex /*effIndex*/) const +    { +        GetCaster()->CastSpell(GetHitUnit(), SPELL_LINGERING_NAUSEA, CastSpellExtraArgsInit{ +            .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, +            .TriggeringSpell = GetSpell() +        }); +    } + +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_volkaal_noxious_stench::HandleDummy, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); +    } +}; + +// 250708 - Toxic Leap +class spell_volkaal_toxic_leap_selector : public SpellScript +{ +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_TOXIC_LEAP }); +    } + +    void HandleScript(SpellEffIndex /*effIndex*/) const +    { +        GetCaster()->CastSpell(GetHitUnit(), SPELL_TOXIC_LEAP); +    } + +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_volkaal_toxic_leap_selector::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); +    } +}; + +// 250258 - Toxic Leap +class spell_volkaal_toxic_leap : public SpellScript +{ +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo({ SPELL_TOXIC_LEAP }); +    } + +    void HandleHit(SpellEffIndex effIndex) +    { +        PreventHitDefaultEffect(effIndex); + +        float dist = GetCaster()->GetExactDist(GetHitDest()); +        float jumpGravity = 159500.0f / (dist * dist); // constant based on calculating avg of inverse from multiple leaps +        GetCaster()->GetMotionMaster()->MoveJumpWithGravity(*GetHitDest(), 50, jumpGravity, EVENT_JUMP); +    } + +    void Register() override +    { +        OnEffectHit += SpellEffectFn(spell_volkaal_toxic_leap::HandleHit, EFFECT_1, SPELL_EFFECT_JUMP_CHARGE); +    } +}; + +// 250229 - Soul Anchor +class spell_volkaal_soul_anchor : public SpellScript +{ +    void SelectTotem(std::list<WorldObject*>& targets) const +    { +        if (targets.empty()) +        { +            InstanceScript* instance = GetCaster()->GetInstanceScript(); +            if (!instance) +                return; + +            if (Creature* volkaal = instance->GetCreature(DATA_VOLKAAL)) +                volkaal->AI()->DoAction(ACTION_TOTEMS_DIED); + +            Unit* caster = GetCaster(); +            caster->RemoveAurasDueToSpell(SPELL_BAD_VOODOO); +            caster->CastSpell(caster, SPELL_RAPID_DECAY, CastSpellExtraArgsInit{ +                .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR, +                .TriggeringSpell = GetSpell() +            }); +        } +    } + +    void Register() override +    { +        OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_volkaal_soul_anchor::SelectTotem, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); +    } +}; + +// 259531 - Reanimate +class spell_volkaal_reanimate : public SpellScript +{ +    void HandleScript(SpellEffIndex /*effIndex*/) const +    { +        GetCaster()->RemoveAurasDueToSpell(SPELL_SOUL_ANCHOR); +    } + +    void Register() override +    { +        OnEffectHitTarget += SpellEffectFn(spell_volkaal_reanimate::HandleScript, EFFECT_0, SPELL_EFFECT_HEAL_PCT); +    } +}; + +// 250241 - Rapid Decay +class spell_volkaal_rapid_decay : public AuraScript +{ +    bool Validate(SpellInfo const* /*spellInfo*/) override +    { +        return ValidateSpellInfo ({ SPELL_RAPID_DECAY_TARGET, SPELL_RAPID_DECAY_RANDOM }); +    } + +    void HandleToxicPool(AuraEffect const* aurEff) const +    { +        Unit* caster = GetCaster(); +        if (!caster) +            return; + +        float range = 100.0f; +        Player* player = nullptr; +        Trinity::AnyPlayerInObjectRangeCheck check(caster, range); +        Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(caster, player, check); +        Cell::VisitWorldObjects(caster, searcher, range); + +        CastSpellExtraArgs args; +        args.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR; +        args.TriggeringAura = aurEff; +        caster->CastSpell(player->GetPosition(), SPELL_RAPID_DECAY_TARGET, args); +        // not present in 11.0.7 +        //caster->CastSpell(caster, SPELL_RAPID_DECAY_RANDOM, args); +    } + +    void Register() override +    { +        OnEffectPeriodic += AuraEffectPeriodicFn(spell_volkaal_rapid_decay::HandleToxicPool, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE); +    } +}; + +// 250696 - Rapid Decay +// ID - 11243 +struct at_volkaal_rapid_decay : AreaTriggerAI +{ +    at_volkaal_rapid_decay(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + +    void OnUnitEnter(Unit* unit) override +    { +        if (!unit->IsPlayer()) +            return; + +        unit->CastSpell(unit, SPELL_TOXIC_POOL, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR); +    } + +    void OnUnitExit(Unit* unit) override +    { +        unit->RemoveAurasDueToSpell(SPELL_TOXIC_POOL); +    } +}; + +void AddSC_boss_volkaal() +{ +    RegisterAtalDazarCreatureAI(boss_volkaal); +    RegisterAtalDazarCreatureAI(npc_volkaal_reanimation_totem); + +    RegisterSpellScript(spell_volkaal_lingering_nausea); +    RegisterSpellScript(spell_volkaal_noxious_stench); +    RegisterSpellScript(spell_volkaal_toxic_leap_selector); +    RegisterSpellScript(spell_volkaal_toxic_leap); +    RegisterSpellScript(spell_volkaal_soul_anchor); +    RegisterSpellScript(spell_volkaal_reanimate); +    RegisterSpellScript(spell_volkaal_rapid_decay); + +    RegisterAreaTriggerAI(at_volkaal_rapid_decay); +} diff --git a/src/server/scripts/Zandalar/AtalDazar/instance_atal_dazar.cpp b/src/server/scripts/Zandalar/AtalDazar/instance_atal_dazar.cpp index 6bf3af91f54..fd84c32d220 100644 --- a/src/server/scripts/Zandalar/AtalDazar/instance_atal_dazar.cpp +++ b/src/server/scripts/Zandalar/AtalDazar/instance_atal_dazar.cpp @@ -23,9 +23,10 @@  BossBoundaryData const boundaries =  {      { DATA_REZAN, new ZRangeBoundary(639.0f, 650.0f) }, // 647.65f +    { DATA_VOLKAAL, new ZRangeBoundary(709.0f, 730.0f) },  }; -ObjectData const creatureData[] = +constexpr ObjectData creatureData[] =  {      { BOSS_PRIESTESS_ALUNZA, DATA_PRIESTESS_ALUNZA  },      { BOSS_VOLKAAL,          DATA_VOLKAAL           }, @@ -34,7 +35,16 @@ ObjectData const creatureData[] =      { 0,                     0                      }  // END  }; -DungeonEncounterData const encounters[] = +constexpr DoorData doorData[] = +{ +    { GO_VOLKAAL_DOOR_1, DATA_VOLKAAL, EncounterDoorBehavior::OpenWhenNotInProgress }, +    { GO_VOLKAAL_DOOR_2, DATA_VOLKAAL, EncounterDoorBehavior::OpenWhenNotInProgress }, +    { GO_VOLKAAL_DOOR_3, DATA_VOLKAAL, EncounterDoorBehavior::OpenWhenNotInProgress }, +    { GO_VOLKAAL_DOOR_4, DATA_VOLKAAL, EncounterDoorBehavior::OpenWhenNotInProgress }, +    { 0,                 0,            EncounterDoorBehavior::OpenWhenNotInProgress }  // END +}; + +constexpr DungeonEncounterData encounters[] =  {      { DATA_PRIESTESS_ALUNZA, {{ 2084 }} },      { DATA_VOLKAAL,          {{ 2085 }} }, @@ -54,6 +64,7 @@ public:              SetHeaders(DataHeader);              SetBossNumber(EncounterCount);              LoadObjectData(creatureData, nullptr); +            LoadDoorData(doorData);              LoadBossBoundaries(boundaries);              LoadDungeonEncounterData(encounters);          } diff --git a/src/server/scripts/Zandalar/zandalar_script_loader.cpp b/src/server/scripts/Zandalar/zandalar_script_loader.cpp index d907c8036c3..44d821e6c3d 100644 --- a/src/server/scripts/Zandalar/zandalar_script_loader.cpp +++ b/src/server/scripts/Zandalar/zandalar_script_loader.cpp @@ -20,6 +20,7 @@  // Atal'Dazar  void AddSC_instance_atal_dazar();  void AddSC_boss_rezan(); +void AddSC_boss_volkaal();  // Underrot  void AddSC_instance_underrot(); @@ -38,6 +39,7 @@ void AddZandalarScripts()      // Atal'Dazar      AddSC_instance_atal_dazar();      AddSC_boss_rezan(); +    AddSC_boss_volkaal();      // Underrot      AddSC_instance_underrot();  | 
