diff --git a/sql/updates/world/custom/custom_2018_09_23_00_world.sql b/sql/updates/world/custom/custom_2018_09_23_00_world.sql new file mode 100644 index 00000000000..595496fbb87 --- /dev/null +++ b/sql/updates/world/custom/custom_2018_09_23_00_world.sql @@ -0,0 +1,79 @@ +-- Template Updates +-- High Priestes Kilnara +UPDATE `creature_template` SET `DamageModifier`= 120, `BaseVariance`= 0.5, `mingold`= 20000, `maxgold`= 21000, `mechanic_immune_mask`= 80297855,`ScriptName`= 'boss_high_priestess_kilnara' WHERE `entry`= 52059; +-- Avatar of Bethekk +UPDATE `creature_template` SET `DamageModifier`= 60, `BaseVariance`= 0.5, `exp`= 3, `minlevel`= 87, `maxlevel`= 87, `mechanic_immune_mask`= 617299839 WHERE `entry`= 52602; +-- Pride of Bethekk +UPDATE `creature_template` SET `DamageModifier`= 10, `BaseVariance`= 0.5, `unit_flags`= 0x8000, `ScriptName`= 'npc_kilnara_pride_of_bethekk' WHERE `entry`= 52061; +-- Pride of Bethekk (Transform) +UPDATE `creature_template` SET `unit_flags`= 0x8000 WHERE `entry`= 52061; +-- Wave of Agony +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128 WHERE `entry`= 52160; +-- Wave of Agony (Visual wave) +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 2 WHERE `entry`= 52147; + +-- Spells +DELETE FROM `spell_script_names` WHERE `ScriptName` IN +('spell_kilnara_tears_of_blood', +'spell_kilnara_wave_of_agony', +'spell_kilnara_wave_of_agony_dummy', +'spell_kilnara_primal_awakening', +'spell_kilnara_gaping_wound'); + +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(96435, 'spell_kilnara_tears_of_blood'), +(98270, 'spell_kilnara_wave_of_agony'), +(96457, 'spell_kilnara_wave_of_agony_dummy'), +(96530, 'spell_kilnara_primal_awakening'), +(97355, 'spell_kilnara_gaping_wound'); + +DELETE FROM `creature_template_addon` WHERE `entry`= 52147; +INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES +(52147, '96532'); + +-- Conditions +DELETE FROM `conditions` WHERE `SourceEntry` IN (96465, 96530) AND `SourceTypeOrReferenceId`= 13; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES +(13, 1, 96465, 0, 0, 31, 0, 3, 52160, 0, 0, 0, '', 'Wave of Agony - Target Wave of Agony'), +(13, 1, 96530, 0, 0, 31, 0, 3, 52061, 0, 0, 0, '', 'Primale Awakening - Target Pride of Bethekk'); + +-- Summon Groups +DELETE FROM `creature_summon_groups` WHERE `summonerId`= 52059; +INSERT INTO `creature_summon_groups` (`groupId`, `summonerId`, `summonerType`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`) VALUES +(0, 52059, 0, 52061, -11517.2, -1646.82, 44.4849, 3.87463, 6, 4000), +(0, 52059, 0, 52061, -11518.1, -1651.48, 44.4849, 2.26893, 6, 4000), +(0, 52059, 0, 52061, -11520.6, -1646, 44.4849, 4.95674, 6, 4000), +(0, 52059, 0, 52061, -11521.8, -1651.58, 44.4849, 0.977384, 6, 4000), +(0, 52059, 0, 52061, -11504.1, -1650.26, 44.4849, 2.26893, 6, 4000), +(0, 52059, 0, 52061, -11508.7, -1603.38, 44.4849, 5.41052, 6, 4000), +(0, 52059, 0, 52061, -11508.3, -1607.37, 44.4849, 0.977384, 6, 4000), +(0, 52059, 0, 52061, -11523.2, -1609.31, 44.4849, 0.977384, 6, 4000), +(0, 52059, 0, 52061, -11523.2, -1605.96, 44.4849, 5.41052, 6, 4000), +(0, 52059, 0, 52061, -11519.7, -1609, 44.4849, 2.26893, 6, 4000), +(0, 52059, 0, 52061, -11519.2, -1605.37, 44.4849, 3.56047, 6, 4000), +(0, 52059, 0, 52061, -11504.6, -1603.33, 44.4849, 3.87463, 6, 4000), +(0, 52059, 0, 52061, -11504.3, -1645.56, 44.4849, 4.66003, 6, 4000), +(0, 52059, 0, 52061, -11507, -1644.55, 44.4849, 4.7822, 6, 4000), +(0, 52059, 0, 52061, -11506.6, -1651.04, 44.4849, 1.6057, 6, 4000), +(0, 52059, 0, 52061, -11505.6, -1607.56, 44.4849, 2.26893, 6, 4000); + +DELETE FROM `creature` WHERE `guid` IN (262602, 271426, 271427, 276829, 289056, 295339, 295353, 318887, 318907, 319126, 319682, 334853, 334863, 334932, 334957, 335469); +DELETE FROM `creature_addon` WHERE `guid` IN (262602, 271426, 271427, 276829, 289056, 295339, 295353, 318887, 318907, 319126, 319682, 334853, 334863, 334932, 334957, 335469); + +-- Loot +-- Loot +DELETE FROM `creature_onkill_reward` WHERE `creature_id`= 52059; +INSERT INTO `creature_onkill_reward` (`creature_id`, `CurrencyId1`, `CurrencyCount1`) VALUES +(52059, 395, 7000); + +DELETE FROM `creature_loot_template` WHERE `Entry`= 52059; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Chance`, `LootMode`, `Reference`, `MaxCount`) VALUES +(52059, 520590, 100, 1, 520590, 1); + +DELETE FROM `reference_loot_template` WHERE `Entry`= 520590; +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Chance`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES +(520590, 69614, 0, 1, 1, 1, 1), +(520590, 69612, 0, 1, 1, 1, 1), +(520590, 69611, 0, 1, 1, 1, 1), +(520590, 69613, 0, 1, 1, 1, 1), +(520590, 69610, 0, 1, 1, 1, 1); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 03f4cb85ba9..ee8a0254e00 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4745,6 +4745,47 @@ void SpellMgr::LoadSpellInfoCorrections() // ENDOF GILNEAS SPELLS + // + // ZUL'GURUB SPELLS + // + + // Tears of Blood + ApplySpellFix({ + 96422, + 96957, + }, [](SpellInfo* spellInfo) + { + spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS); + }); + + // Wave of Agony + ApplySpellFix({ 96461 }, [](SpellInfo* spellInfo) + { + spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_2_YARDS); + }); + + // Wave of Agony (Damage) + ApplySpellFix({ 96460 }, [](SpellInfo* spellInfo) + { + spellInfo->AttributesCu |= SPELL_ATTR0_CU_CONE_LINE; + }); + + // Gaping Wound + ApplySpellFix({ 97355 }, [](SpellInfo* spellInfo) + { + spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(5); // 40yd + spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_40_YARDS); + spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DEST); + }); + + // Cave In + ApplySpellFix({ 97380 }, [](SpellInfo* spellInfo) + { + spellInfo->AttributesCu |= SPELL_ATTR0_CU_NEGATIVE_EFF0; + }); + + // ENDOF ZUL'GURUB SPELLS + // Disenchant ApplySpellFix({ 13262 }, [](SpellInfo* spellInfo) { diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_high_priestess_kilnara.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_high_priestess_kilnara.cpp new file mode 100644 index 00000000000..d86ed22ea76 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_high_priestess_kilnara.cpp @@ -0,0 +1,486 @@ +/* + * Copyright (C) 2008-2018 TrinityCore + * + * 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 . + */ + +#include "GridNotifiers.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Spell.h" +#include "zulgurub.h" + +enum Yells +{ + // High Priestess Kilnara + SAY_AGGRO = 0, + SAY_WAVE_OF_AGONY = 1, + SAY_TRANSFROM_1 = 2, + SAY_TRANSFROM_2 = 3, + SAY_SLAY = 4, + SAY_DEATH = 5 +}; + +enum Spells +{ + // High Priestess Kilnara + SPELL_CLEAR_ACHIEVEMENT_CREDITS = 98840, + SPELL_KILNARA_HOVER_VISUAL_1 = 97459, + SPELL_KILNARA_HOVER_VISUAL_2 = 97428, + SPELL_SHADOW_BOLT = 96516, + SPELL_TEARS_OF_BLOOD = 96438, + SPELL_WAIL_OF_SORROW = 96909, + SPELL_LASH_OF_ANGUISH = 96423, + SPELL_WAVE_OF_AGONY = 96457, + SPELL_WAVE_OF_AGONY_TARGETING = 98270, + SPELL_WAVE_OF_AGONY_DUMMY_PING = 96465, + SPELL_WAVE_OF_AGONY_DAMAGE = 96542, + SPELL_CAVE_IN = 97380, + SPELL_PRIMAL_BLESSING = 96559, + SPELL_PRIMAL_AWAKENING = 96530, + SPELL_RAGE_OF_THE_ANCIENTS = 96896, + SPELL_VENGEFUL_SMASH = 96593, + SPELL_CAMOUFLAGE = 96594, + SPELL_RAVAGE = 96592, + SPELL_RAVAGE_CAMOUFLAGE = 96700, + + // Pride of Bethekk + SPELL_DARK_SLUMBER = 96446, + SPELL_GAPING_WOUND = 97355 +}; + +enum Events +{ + // High Priestess Kilnara + EVENT_SHADOW_BOLT = 1, + EVENT_TEARS_OF_BLOOD, + EVENT_WAIL_OF_SORROW, + EVENT_LASH_OF_ANGUISH, + EVENT_WAVE_OF_AGONY, + EVENT_MAKE_PANTHERS_ATTACKABLE, + EVENT_TRANSFORM, + EVENT_PRIMAL_BLESSING, + EVENT_PRIMAL_AWAKENING, + EVENT_REENGAGE_PLAYER, + EVENT_VENGEFUL_SMASH, + EVENT_RAVAGE, + EVENT_CAMOUFLAGE, + EVENT_PREPARE_RAVAGE, + EVENT_RAVAGE_CAMOUFLAGE, + + // Pride of Bethekk + EVENT_GAPING_WOUND +}; + +enum SummonGroups +{ + SUMMON_GROUP_PRIDE_OF_BETHEK = 0 +}; + +struct boss_high_priestess_kilnara : public BossAI +{ + boss_high_priestess_kilnara(Creature* creature) : BossAI(creature, DATA_HIGH_PRIESTESS_KILNARA) + { + Initialize(); + } + + void Initialize() + { + _transformed = false; + } + + void Reset() override + { + _Reset(); + Initialize(); + me->MakeInterruptable(false); + me->SummonCreatureGroup(SUMMON_GROUP_PRIDE_OF_BETHEK); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _JustEngagedWith(); + Talk(SAY_AGGRO); + DoCastAOE(SPELL_CLEAR_ACHIEVEMENT_CREDITS); + + me->SetHover(false); + me->SendSetPlayHoverAnim(false); + me->RemoveAurasDueToSpell(SPELL_KILNARA_HOVER_VISUAL_1); + me->RemoveAurasDueToSpell(SPELL_KILNARA_HOVER_VISUAL_2); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + + events.ScheduleEvent(EVENT_SHADOW_BOLT, 1s + 500ms); + events.ScheduleEvent(EVENT_MAKE_PANTHERS_ATTACKABLE, 1s + 700ms); + events.ScheduleEvent(EVENT_TEARS_OF_BLOOD, 8s + 800ms); + events.ScheduleEvent(EVENT_LASH_OF_ANGUISH, 17s); + events.ScheduleEvent(EVENT_WAVE_OF_AGONY, 29s + 500ms); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + Talk(SAY_DEATH); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + summons.DespawnAll(); + me->RemoveAllAuras(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _DespawnAtEvade(); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (!_transformed && me->HealthBelowPctDamaged(50, damage)) + { + events.Reset(); + events.ScheduleEvent(EVENT_TRANSFORM, 1ms); + _transformed = true; + } + } + + void OnSuccessfulSpellCast(SpellInfo const* spell) override + { + if (spell->Id == SPELL_CAMOUFLAGE) + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + switch (summon->GetEntry()) + { + case NPC_WAVE_OF_AGONY_1: + { + Talk(SAY_WAVE_OF_AGONY); + float angle = me->GetAngle(summon); + me->SetFacingToObject(summon); + me->SetOrientation(angle); // Updating orientation before casting the following summon spell + DoCast(summon, SPELL_WAVE_OF_AGONY); + break; + } + case NPC_WAVE_OF_AGONY_2: + summon->DespawnOrUnsummon(3s); + break; + case NPC_PRIDE_OF_BETHEKK: + summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + summon->SetReactState(REACT_PASSIVE); + break; + default: + break; + } + } + + 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_SHADOW_BOLT: + DoCastVictim(SPELL_SHADOW_BOLT); + events.Repeat(2s, 2s + 500ms); + break; + case EVENT_TEARS_OF_BLOOD: + DoCastSelf(SPELL_TEARS_OF_BLOOD); + events.Repeat(21s, 24s); + break; + case EVENT_LASH_OF_ANGUISH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + me->CastSpell(target, SPELL_LASH_OF_ANGUISH, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_CAST_DIRECTLY)); + events.Repeat(22s, 23s); + break; + case EVENT_WAVE_OF_AGONY: + DoCastAOE(SPELL_WAVE_OF_AGONY_TARGETING); + events.DelayEvents(5s); + events.Repeat(42s + 500ms); + break; + case EVENT_MAKE_PANTHERS_ATTACKABLE: + for (ObjectGuid guid : summons) + if (Creature* creature = ObjectAccessor::GetCreature(*me, guid)) + if (creature->GetEntry() == NPC_PRIDE_OF_BETHEKK) + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + break; + case EVENT_TRANSFORM: + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + DoCastAOE(SPELL_CAVE_IN); + Talk(SAY_TRANSFROM_1); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SPELL_CHANNEL_OMNI); + instance->SetData(DATA_CAST_CAVE_IN_VISUAL, DONE); + events.ScheduleEvent(EVENT_PRIMAL_BLESSING, 6s); + break; + case EVENT_PRIMAL_BLESSING: + DoCastSelf(SPELL_PRIMAL_BLESSING); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY_UNARMED); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED); + events.ScheduleEvent(EVENT_PRIMAL_AWAKENING, 1s); + break; + case EVENT_PRIMAL_AWAKENING: + DoCastAOE(SPELL_PRIMAL_AWAKENING); + DoCastSelf(SPELL_RAGE_OF_THE_ANCIENTS); + events.ScheduleEvent(EVENT_REENGAGE_PLAYER, 1s + 200ms); + break; + case EVENT_REENGAGE_PLAYER: + Talk(SAY_TRANSFROM_2); + me->SetReactState(REACT_AGGRESSIVE); + if (Unit* victim = me->GetVictim()) + AttackStart(victim); + events.ScheduleEvent(EVENT_VENGEFUL_SMASH, 7s + 200ms); + events.ScheduleEvent(EVENT_RAVAGE, 4s); + events.ScheduleEvent(EVENT_CAMOUFLAGE, 22s); + break; + case EVENT_VENGEFUL_SMASH: + DoCastAOE(SPELL_VENGEFUL_SMASH); + events.Repeat(35s, 37s); + break; + case EVENT_RAVAGE: + DoCastVictim(SPELL_RAVAGE); + events.Repeat(11s); + break; + case EVENT_CAMOUFLAGE: + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + DoCastSelf(SPELL_CAMOUFLAGE); + events.DelayEvents(10s); + events.Repeat(36s + 500ms); + events.ScheduleEvent(EVENT_PREPARE_RAVAGE, 2s); + break; + case EVENT_PREPARE_RAVAGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true, 0)) + AttackStart(target); + events.ScheduleEvent(EVENT_RAVAGE_CAMOUFLAGE, 4s); + break; + case EVENT_RAVAGE_CAMOUFLAGE: + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); + me->RemoveAurasDueToSpell(SPELL_CAMOUFLAGE); + if (Player* player = me->SelectNearestPlayer(10.0f)) + DoCast(player, SPELL_RAVAGE_CAMOUFLAGE); + break; + default: + break; + } + } + + if (_transformed) + DoMeleeAttackIfReady(); + } +private: + bool _transformed; +}; + +struct npc_kilnara_pride_of_bethekk : public ScriptedAI +{ + npc_kilnara_pride_of_bethekk(Creature* creature) : ScriptedAI(creature) { } + + void JustEngagedWith(Unit* /*who*/) override + { + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveAurasDueToSpell(SPELL_DARK_SLUMBER); + _events.ScheduleEvent(EVENT_GAPING_WOUND, 8s); + } + + 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_GAPING_WOUND: + DoCastAOE(SPELL_GAPING_WOUND); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); + } +private: + EventMap _events; +}; + +class spell_kilnara_tears_of_blood : public AuraScript +{ + PrepareAuraScript(spell_kilnara_tears_of_blood); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WAIL_OF_SORROW }); + } + + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* creature = GetTarget()->ToCreature()) + creature->MakeInterruptable(true); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* creature = GetTarget()->ToCreature()) + { + creature->MakeInterruptable(true); + creature->CastSpell(creature, SPELL_WAIL_OF_SORROW); + } + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_kilnara_tears_of_blood::AfterApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_kilnara_tears_of_blood::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } +}; + +class AttackerVictimCheck +{ + public: + AttackerVictimCheck(Unit* _attacker) : attacker(_attacker) { } + + bool operator()(WorldObject* object) + { + return (attacker->GetVictim() && attacker->GetVictim() == object->ToUnit()); + } + private: + Unit* attacker; +}; + +class spell_kilnara_wave_of_agony : public SpellScript +{ + PrepareSpellScript(spell_kilnara_wave_of_agony); + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + targets.remove_if(AttackerVictimCheck(GetCaster())); + + if (targets.empty()) + return; + + Trinity::Containers::RandomResize(targets, 1); + } + + void HandleHit(SpellEffIndex effIndex) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].BasePoints, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_kilnara_wave_of_agony::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kilnara_wave_of_agony::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } +}; + +class spell_kilnara_wave_of_agony_dummy : public AuraScript +{ + PrepareAuraScript(spell_kilnara_wave_of_agony_dummy); + + void HandlePeriodic(AuraEffect const* aurEff) + { + if (Unit* caster = GetCaster()) + { + if (Unit* target = GetTarget()) + { + caster->CastSpell(target, SPELL_WAVE_OF_AGONY_DAMAGE, true); + caster->CastSpell(target, SPELL_WAVE_OF_AGONY_DUMMY_PING, true); + } + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_kilnara_wave_of_agony_dummy::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +class spell_kilnara_primal_awakening : public AuraScript +{ + PrepareAuraScript(spell_kilnara_primal_awakening); + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* creature = GetTarget()->ToCreature()) + if (creature->IsAIEnabled) + creature->AI()->DoZoneInCombat(); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_kilnara_primal_awakening::AfterRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + } +}; + +class spell_kilnara_gaping_wound : public SpellScript +{ + PrepareSpellScript(spell_kilnara_gaping_wound); + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Effects[EFFECT_2].BasePoints)); + + if (targets.empty()) + return; + + Trinity::Containers::RandomResize(targets, 1); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kilnara_gaping_wound::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } +}; + +void AddSC_boss_high_priestess_kilnara() +{ + RegisterZulGurubCreatureAI(boss_high_priestess_kilnara); + RegisterZulGurubCreatureAI(npc_kilnara_pride_of_bethekk); + + RegisterAuraScript(spell_kilnara_tears_of_blood); + RegisterSpellScript(spell_kilnara_wave_of_agony); + RegisterAuraScript(spell_kilnara_wave_of_agony_dummy); + RegisterAuraScript(spell_kilnara_primal_awakening); + RegisterSpellScript(spell_kilnara_gaping_wound); +} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp deleted file mode 100644 index 5b9a8052201..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2008-2018 TrinityCore - * - * 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 . - */ - -#include "ObjectMgr.h" -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Spell.h" -#include "zulgurub.h" - -enum Yells -{ - SAY_AGGRO = 0, - SAY_WAVE_OF_AGONY = 1, // ID - 96457 Wave of Agony - SAY_TRANSFROM_1 = 2, - SAY_TRANSFROM_2 = 3, - SAY_PLAYER_KILL = 4, - SAY_DEATH = 5 -}; - -enum Spells -{ -}; - -enum Events -{ -}; - -class boss_kilnara : public CreatureScript -{ - public: - boss_kilnara() : CreatureScript("boss_kilnara") { } - - struct boss_kilnaraAI : public BossAI - { - boss_kilnaraAI(Creature* creature) : BossAI(creature, DATA_KILNARA) { } - - void Reset() override - { - _Reset(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _JustEngagedWith(); - Talk(SAY_AGGRO); - } - - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - Talk(SAY_DEATH); - } - - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_PLAYER_KILL); - } - - 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) - { - default: - break; - } - } - */ - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulGurubAI(creature); - } -}; - -void AddSC_boss_kilnara() -{ - new boss_kilnara(); -} diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index f8e18b27ec9..decff6522e1 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -26,7 +26,7 @@ ObjectData const creatureData[] = { { BOSS_HIGH_PRIEST_VENOXIS, DATA_HIGH_PRIEST_VENOXIS }, { BOSS_BLOODLORD_MANDOKIR, DATA_BLOODLORD_MANDOKIR }, - { BOSS_KILNARA, DATA_KILNARA }, + { BOSS_HIGH_PRIESTESS_KILNARA, DATA_HIGH_PRIESTESS_KILNARA }, { BOSS_ZANZIL, DATA_ZANZIL }, { BOSS_JINDO_THE_GODBREAKER, DATA_JINDO_THE_GODBREAKER }, { NPC_OHGAN, DATA_OHGAN } @@ -34,12 +34,12 @@ ObjectData const creatureData[] = DoorData const doorData[] = { - { GO_VENOXIS_COIL, DATA_HIGH_PRIEST_VENOXIS, DOOR_TYPE_ROOM }, - { GO_ARENA_DOOR_1, DATA_BLOODLORD_MANDOKIR, DOOR_TYPE_ROOM }, - { GO_FORCEFIELD, DATA_KILNARA, DOOR_TYPE_ROOM }, - { GO_ZANZIL_DOOR, DATA_ZANZIL, DOOR_TYPE_ROOM }, - //{ GO_THE_CACHE_OF_MADNESS_DOOR, DATA_xxxxxxx, DOOR_TYPE_ROOM }, - { 0, 0, DOOR_TYPE_ROOM } // END + { GO_VENOXIS_COIL, DATA_HIGH_PRIEST_VENOXIS, DOOR_TYPE_ROOM }, + { GO_ARENA_DOOR_1, DATA_BLOODLORD_MANDOKIR, DOOR_TYPE_ROOM }, + { GO_FORCEFIELD, DATA_HIGH_PRIESTESS_KILNARA, DOOR_TYPE_ROOM }, + { GO_ZANZIL_DOOR, DATA_ZANZIL, DOOR_TYPE_ROOM }, + //{ GO_THE_CACHE_OF_MADNESS_DOOR, DATA_xxxxxxx, DOOR_TYPE_ROOM }, + { 0, 0, DOOR_TYPE_ROOM } // END }; class instance_zulgurub : public InstanceMapScript @@ -72,6 +72,9 @@ class instance_zulgurub : public InstanceMapScript if (Creature* mandokir = GetCreature(DATA_BLOODLORD_MANDOKIR)) mandokir->AI()->JustSummoned(creature); break; + case NPC_CAVE_IN_STALKER: + _caveInStalkerGUIDs.push_back(creature->GetGUID()); + break; default: break; } @@ -90,14 +93,21 @@ class instance_zulgurub : public InstanceMapScript return true; } - /* void SetData(uint32 type, uint32 data) override { switch (type) { + case DATA_CAST_CAVE_IN_VISUAL: + for (ObjectGuid guid : _caveInStalkerGUIDs) + if (Creature* stalker = instance->GetCreature(guid)) + stalker->CastSpell(stalker, SPELL_CAVE_IN_VISUAL, false); + break; + default: + break; } } + /* uint32 GetData(uint32 type) const override { switch (type) @@ -107,6 +117,8 @@ class instance_zulgurub : public InstanceMapScript return 0; } */ + private: + GuidVector _caveInStalkerGUIDs; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index 3e43db3bcf2..ad987fcf5d1 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -31,7 +31,7 @@ enum ZGDataTypes // Bosses DATA_HIGH_PRIEST_VENOXIS = 0, DATA_BLOODLORD_MANDOKIR = 1, - DATA_KILNARA = 2, + DATA_HIGH_PRIESTESS_KILNARA = 2, DATA_ZANZIL = 3, DATA_JINDO_THE_GODBREAKER = 4, @@ -44,6 +44,9 @@ enum ZGDataTypes // Bloodlord Mandokir DATA_OHGAN = 9, + // High Priestess Kilnara + DATA_CAST_CAVE_IN_VISUAL = 10, + // Jin'do the Godbreaker DATA_JINDOR_TRIGGER }; @@ -53,7 +56,7 @@ enum ZGCreatureIds // Bosses BOSS_HIGH_PRIEST_VENOXIS = 52155, BOSS_BLOODLORD_MANDOKIR = 52151, - BOSS_KILNARA = 52059, + BOSS_HIGH_PRIESTESS_KILNARA = 52059, BOSS_ZANZIL = 52053, BOSS_JINDO_THE_GODBREAKER = 52148, @@ -75,6 +78,12 @@ enum ZGCreatureIds NPC_OHGAN = 52157, NPC_DEVASTATING_SLAM = 52324, + // High Priestess Kilnara + NPC_WAVE_OF_AGONY_1 = 52160, + NPC_WAVE_OF_AGONY_2 = 52147, + NPC_PRIDE_OF_BETHEKK = 52061, + NPC_CAVE_IN_STALKER = 52387, + // Jin'do the Godbreaker NPC_JINDO_TRIGGER = 52150, NPC_SPIRIT_OF_HAKKAR = 52222, @@ -103,6 +112,11 @@ enum ZGGameObjectIds GO_THE_CACHE_OF_MADNESS_DOOR = 208843 }; +enum ZGSpells +{ + SPELL_CAVE_IN_VISUAL = 96935 +}; + template inline AI* GetZulGurubAI(T* obj) { diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index 730172c72ad..6266b6bb51a 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -204,7 +204,7 @@ void AddSC_zulaman(); void AddSC_boss_grilek(); // Zul'Gurub void AddSC_boss_hazzarah(); void AddSC_boss_jindo_the_godbreaker(); -void AddSC_boss_kilnara(); +void AddSC_boss_high_priestess_kilnara(); void AddSC_boss_mandokir(); void AddSC_boss_renataki(); void AddSC_boss_high_priest_venoxis(); @@ -425,7 +425,7 @@ void AddEasternKingdomsScripts() AddSC_boss_grilek(); // Zul'Gurub AddSC_boss_hazzarah(); AddSC_boss_jindo_the_godbreaker(); - AddSC_boss_kilnara(); + AddSC_boss_high_priestess_kilnara(); AddSC_boss_mandokir(); AddSC_boss_renataki(); AddSC_boss_high_priest_venoxis();