diff --git a/sql/updates/world/4.3.4/2020_05_04_00_world.sql b/sql/updates/world/4.3.4/2020_05_04_00_world.sql new file mode 100644 index 00000000000..c9a91ba481d --- /dev/null +++ b/sql/updates/world/4.3.4/2020_05_04_00_world.sql @@ -0,0 +1,85 @@ +-- Template Updates +-- Ammunae +UPDATE `creature_template` SET `ScriptName`= 'boss_ammunae' WHERE `entry`= 39731; +UPDATE `creature_template` SET `DamageModifier`= 90, `flags_extra`= 1 WHERE `entry`= 48715; +-- Seedling Pod +UPDATE `creature_template` SET `unit_flags`= 64, `unit_flags2`= 33556480, `RegenHealth`= 0, `mechanic_immune_mask`= 650854271, `flags_extra`= 256 | 1073741824, `ScriptName`= 'npc_ammunae_seedling_pod' WHERE `entry` IN (40550, 51329); +-- Seedling Pod (Visual) +UPDATE `creature_template` SET `unit_flags2`= 2048, `unit_flags`= 33554496, `AIName`= 'NullCreatureAI' WHERE `entry`= 40592; +-- Bloodpetal Blossom +UPDATE `creature_template` SET `ScriptName`= 'npc_ammunae_bloodpetal_blossom' WHERE `entry`= 40620; +UPDATE `creature_template` SET `unit_flags2`= 2048, `unit_flags`= 33816576 WHERE `entry` IN (40620, 48716); +-- Bloodpetal Sprout +UPDATE `creature_template` SET `ScriptName`= 'npc_ammunae_bloodpetal_sprout' WHERE `entry`= 40630; +UPDATE `creature_template` SET `unit_flags2`= 2048, `unit_flags`= 33816576 WHERE `entry` IN (40630, 48717); +-- Bloodpetal Blossom (Visual) +UPDATE `creature_template` SET `unit_flags2`= 2048, `unit_flags`= 33554432, `AIName`= 'NullCreatureAI' WHERE `entry`= 40622; +-- Spore +UPDATE `creature_template` SET `speed_run`= 0.71428, `ScriptName` = 'npc_ammunae_spore' WHERE `entry`= 40585; + +-- Addons +UPDATE `creature_template_addon` SET `auras`= '' WHERE `entry`= 39731; + +-- Spell Scripts +DELETE FROM `spell_script_names` WHERE `ScriptName` IN +('spell_gen_zero_energy_zero_regen', +'spell_ammunae_consume_life_energy', +'spell_ammunae_summon_bloodpetal_blossom', +'spell_ammunae_rampant_growth', +'spell_ammunae_fixate'); + +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(72242, 'spell_gen_zero_energy_zero_regen'), +(75725, 'spell_ammunae_consume_life_energy'), +(75774, 'spell_ammunae_summon_bloodpetal_blossom'), +(75790, 'spell_ammunae_rampant_growth'), +(89888, 'spell_ammunae_rampant_growth'), +(73686, 'spell_ammunae_fixate'); + +-- Conditions +DELETE FROM `conditions` WHERE `SourceEntry` IN (75657, 94970, 89124, 75774, 75790, 89888, 75702, 89889) AND `SourceTypeOrReferenceId`= 13; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES +(13, 3, 75657, 0, 0, 31, 0, 3, 39731, 0, 0, 0, '', 'Energize - Target Ammunae'), +(13, 3, 94970, 0, 0, 31, 0, 3, 39731, 0, 0, 0, '', 'Energize - Target Ammunae'), +(13, 1, 89124 , 0, 0, 31, 0, 3, 39731, 0, 0, 0, '', 'Energizing Growth - Target Ammunae'), +(13, 1, 75774 , 0, 0, 31, 0, 3, 40550, 0, 0, 0, '', 'Bloodpetal Blossom - Target Seedling Pod'), +(13, 1, 75774 , 0, 1, 31, 0, 3, 51329, 0, 0, 0, '', 'Bloodpetal Blossom - Target Seedling Pod'), +(13, 1, 75790 , 0, 0, 31, 0, 3, 40550, 0, 0, 0, '', 'Rampant Growth - Target Seedling Pod'), +(13, 1, 75790 , 0, 1, 31, 0, 3, 51329, 0, 0, 0, '', 'Rampant Growth - Target Seedling Pod'), +(13, 1, 89888 , 0, 0, 31, 0, 3, 40550, 0, 0, 0, '', 'Rampant Growth - Target Seedling Pod'), +(13, 1, 89888 , 0, 1, 31, 0, 3, 51329, 0, 0, 0, '', 'Rampant Growth - Target Seedling Pod'), +(13, 6, 75702 , 0, 0, 31, 0, 3, 40620, 0, 0, 0, '', 'Noxious Spores - Target Bloodpetal Blossom'), +(13, 6, 75702 , 0, 1, 31, 0, 3, 40630, 0, 0, 0, '', 'Noxious Spores - Target Bloodpetal Sprout'), +(13, 6, 89889 , 0, 0, 31, 0, 3, 40620, 0, 0, 0, '', 'Noxious Spores - Target Bloodpetal Blossom'), +(13, 6, 89889 , 0, 1, 31, 0, 3, 40630, 0, 0, 0, '', 'Noxious Spores - Target Bloodpetal Sprout'); + + +-- Serverside Spells +DELETE FROM `spell_dbc` WHERE `Id` IN (75621, 94991, 75688, 75771, 75791, 75769, 75695); +INSERT INTO `spell_dbc` (`Id`, `CastingTimeIndex`, `DurationIndex`, `RangeIndex`, `AttributesEx`, `Comment`) VALUES +(75621, 1, 21, 1, 0x100, '(Serverside/Non-DB2) Summon Seedling Pod'), +(94991, 1, 21, 1, 0x100, '(Serverside/Non-DB2) Summon Seedling Pod'), +(75688, 1, 21, 1, 0x100, '(Serverside/Non-DB2) Summon Seedling Pod'), +(75771, 1, 21, 1, 0x100, '(Serverside/Non-DB2) Bloodpetal Blossom'), +(75791, 1, 21, 1, 0x100, '(Serverside/Non-DB2) Summon Bloodpetal Sprout'), +(75769, 1, 21, 1, 0x100, '(Serverside/Non-DB2) Summon Bloodpetal Blossom Visual'), +(75695, 1, 21, 1, 0x100, '(Serverside/Non-DB2) Summon Spore'); + +DELETE FROM `spelleffect_dbc` WHERE `Id` IN (160099, 160100, 160101, 160102, 160103, 160104, 160105); +INSERT INTO `spelleffect_dbc` (`Id`, `Effect`, `EffectMiscValue`, `EffectMiscValueB`, `EffectRadiusIndex`, `EffectRadiusMaxIndex`, `EffectImplicitTargetA`, `EffectImplicitTargetB`, `SpellID`, `EffectIndex`, `Comment`) VALUES +(160099, 28, 40592, 64, 0, 0, 18, 0, 75688, 0, ''), +(160100, 28, 40550, 64, 23, 23, 18, 86, 75621, 0, ''), +(160101, 28, 51329, 64, 23, 23, 18, 86, 94991, 0, ''), +(160102, 28, 40620, 64, 0, 0, 18, 0, 75771, 0, ''), +(160103, 28, 40630, 64, 0, 0, 18, 0, 75791, 0, ''), +(160104, 28, 40622, 64, 0, 0, 18, 0, 75769, 0, ''), +(160105, 28, 40585, 64, 0, 0, 18, 0, 75695, 0, ''); + +-- Texts +DELETE FROM `creature_text` WHERE `CreatureID`= 39731; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `comment`) VALUES +(39731, 0, 0, 'This chamber will flourish with your life energy!', 14, 0, 100, 0, 0, 18571, 44767, 'Ammunae - Aggro'), +(39731, 1, 0, 'Your life, UNLEASHED!', 14, 0, 100, 0, 0, 18572, 44771, 'Ammunae - Rampant Growth'), +(39731, 2, 0, 'The cycle continues...', 14, 0, 100, 0, 0, 18569, 44770, 'Ammunae - Death'), +(39731, 3, 0, 'Wither away!', 14, 0, 100, 0, 0, 18573, 44768, 'Ammunae - Slay 1'), +(39731, 3, 1, 'Waste of energy.', 14, 0, 100, 0, 0, 18574, 44769, 'Ammunae - Slay 2'); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 03708f821ce..2b4505bd882 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4714,6 +4714,22 @@ void SpellMgr::LoadSpellInfoCorrections() { spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_4_YARDS); }); + + // Spore Cloud + ApplySpellFix({ 75701 }, [](SpellInfo* spellInfo) + { + spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_1; + }); + + // Noxious Spores + ApplySpellFix({ + 75702, + 89889 + }, [](SpellInfo* spellInfo) + { + spellInfo->Effects[EFFECT_0].RadiusEntry = nullptr; + }); + // END OF HALLS OF ORIGINATION SPELLS // diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_ammunae.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_ammunae.cpp index a8616bdc0f1..5d4c5261b95 100644 --- a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_ammunae.cpp +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_ammunae.cpp @@ -16,7 +16,11 @@ */ #include "halls_of_origination.h" +#include "CreatureAIImpl.h" +#include "PassiveAI.h" +#include "Player.h" #include "ScriptMgr.h" +#include "SpellAuraEffects.h" #include "SpellMgr.h" #include "ScriptedCreature.h" #include "SpellScript.h" @@ -25,212 +29,550 @@ enum Spells { // Ammunae - SPELL_ZERO_ENERGY = 72242, - SPELL_WITHER = 76043, - SPELL_CONSUME_LIFE_ENERGY = 75725, - SPELL_RAMPANT_GROWTH = 75790, - SPELL_SUMMON_SEEDLING_POD = 75621, // summons 40550 (normal) or 51329 (heroic) - SPELL_SUMMON_SPORE = 75695, // summons 40585 - - // Consume Life Energy spell - SPELL_CONSUME_LIFE_ENERGY_LEECH = 79768, - SPELL_CONSUME_LIFE_ENERGY_ENERGIZE = 75665, + SPELL_ZERO_ENERGY_ZERO_REGEN = 72242, + SPELL_WITHER = 76043, + SPELL_CONSUME_LIFE_ENERGY = 75725, + SPELL_CONSUME_LIFE_ENERGY_ENERGIZE = 75665, + SPELL_CONSUME_LIFE_ENERGY_BURN_MANA = 75718, + SPELL_CONSUME_LIFE_ENERGY_BURN_RUNIC_POWER = 79768, + SPELL_CONSUME_LIFE_ENERGY_BURN_ENERGY = 79766, + SPELL_CONSUME_LIFE_ENERGY_BURN_RAGE = 79767, + SPELL_CONSUME_LIFE_ENERGY_BURN_FOCUS = 80968, + SPELL_RAMPANT_GROWTH = 75790, + SPELL_SUMMON_BLOODPETAL_BLOSSOM = 75774, + SPELL_SUMMON_SEEDLING_POD = 75621, + SPELL_SUMMON_SPORE = 75695, - // Seedling Pod npc - SPELL_SEEDLING_POD_ENERGIZE = 75708, - SPELL_FORCECAST_SUMMON_BLOSSOM = 75774, // forces Seedling Pods to cast 75771 - SPELL_SUMMON_BLOODPETAL_BLOSSOM = 75771 // summons 40620 + // Seedling Pod + SPELL_ENERGIZE = 75657, + SPELL_ENERGIZING_GROWTH = 75624, + SPELL_SEEDLING_POD_VISUAL = 75687, + SPELL_SUMMON_SEEDLING_POD_2 = 75688, + + // Bloodpetal Blossom + SPELL_SHRINK = 59632, + SPELL_SUBMERGE = 76486, + SPELL_BLOODPETAL_BLOSSOM = 75768, + SPELL_EMERGE = 76485, + SPELL_THORN_SLASH = 76044, + + // Blootpetal Sprout + SPELL_SUMMON_BLOODPETAL_SPROUT = 75795, + SPELL_SUMMON_BLOODPETAL_BLOSOM_VISUAL = 75769, + SPELL_SUMMON_BLOODPETAL_BLOOM_STATE = 75770, + SPELL_FIXATE = 73686, + + // Spore + SPELL_SPORE_CLOUD = 75701 }; enum Texts { - SAY_DEATH = 0, - SAY_AGGRO = 1, - SAY_SPECIAL = 2, - SAY_PLAYER_KILL = 3 + // Ammunae + SAY_AGGRO = 0, + SAY_RAMPANT_GROWTH = 1, + SAY_DEATH = 2, + SAY_SLAY = 3 }; - enum Events { // Ammunae EVENT_WITHER = 1, - EVENT_APPLY_IMMUNITY, EVENT_CONSUME_LIFE_ENERGY, - EVENT_SEEDLING_POD, + EVENT_RAMPANT_GROWTH, + EVENT_SUMMON_SEEDLING_POD, EVENT_SUMMON_BLOODPETAL_BLOSSOM, EVENT_SUMMON_SPORE, - // Blossom + // Bloodpetal Blossom + EVENT_ENGAGE_PLAYERS, EVENT_TRANSFORM, + EVENT_REMOVE_SHRINK_AURA, EVENT_EMERGE, - EVENT_THORN_SLASH + EVENT_THORN_SLASH, + + // Bloodpetal Sprout + EVENT_FIXATE }; -// 39731 Ammunae -class boss_ammunae : public CreatureScript +struct boss_ammunae : public BossAI { - public: - boss_ammunae() : CreatureScript("boss_ammunae") { } + boss_ammunae(Creature* creature) : BossAI(creature, DATA_AMMUNAE), _firstDrainLifeEnergyCycle(true) { } - struct boss_ammunaeAI : public BossAI + void JustAppeared() override + { + me->MakeInterruptable(false); + me->AddAura(SPELL_ZERO_ENERGY_ZERO_REGEN, me); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _JustEngagedWith(); + Talk(SAY_AGGRO); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + events.ScheduleEvent(EVENT_SUMMON_SEEDLING_POD, 7s); + events.ScheduleEvent(EVENT_SUMMON_SEEDLING_POD, 14s, 15s); + events.ScheduleEvent(EVENT_WITHER, 7s, 9s); + events.ScheduleEvent(EVENT_CONSUME_LIFE_ENERGY, 21s); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + summons.DespawnAll(); + _DespawnAtEvade(); + } + + void JustDied(Unit* /*who*/) override + { + Talk(SAY_DEATH); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _JustDied(); + } + + void KilledUnit(Unit* victim) override + { + if (victim->IsPlayer()) + Talk(SAY_SLAY, victim); + } + + void OnSpellCastFinished(SpellInfo const* spell, SpellFinishReason /*reason*/) override + { + if (spell->Id == SPELL_WITHER) + me->MakeInterruptable(false); + } + + void JustSummoned(Creature* summon) override + { + summons.RemoveNotExisting(); + summons.Summon(summon); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() || !CheckInRoom()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - boss_ammunaeAI(Creature* creature) : BossAI(creature, DATA_AMMUNAE) { } - - void Reset() override + switch (eventId) { - _Reset(); - me->MakeInterruptable(false); - me->AddAura(SPELL_ZERO_ENERGY, me); - } - - void JustEngagedWith(Unit* /*who*/) override - { - _JustEngagedWith(); - Talk(SAY_AGGRO); - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); - - events.ScheduleEvent(EVENT_WITHER, !IsHeroic() ? Seconds(7) : Seconds(5)); - events.ScheduleEvent(EVENT_SEEDLING_POD, Seconds(7)); - events.ScheduleEvent(EVENT_CONSUME_LIFE_ENERGY, Seconds(20)); - events.ScheduleEvent(EVENT_SUMMON_SPORE, Seconds(47)); - } - - void JustReachedHome() override - { - me->AddAura(SPELL_ZERO_ENERGY, me); - me->SetPower(POWER_ENERGY, 0); - instance->SetBossState(DATA_AMMUNAE, NOT_STARTED); - _JustReachedHome(); - } - - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_PLAYER_KILL); - } - - void EnterEvadeMode(EvadeReason /*why*/) override - { - instance->SetBossState(DATA_AMMUNAE, FAIL); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - me->MakeInterruptable(false); - events.Reset(); - _EnterEvadeMode(); - } - - void JustDied(Unit* /*who*/) override - { - Talk(SAY_DEATH); - instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); - _JustDied(); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() || !CheckInRoom()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while(uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + case EVENT_WITHER: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.f, true)) { - case EVENT_WITHER: - me->MakeInterruptable(true); - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - DoCast(target, SPELL_WITHER); - events.ScheduleEvent(EVENT_APPLY_IMMUNITY, 1500); - events.Repeat(Seconds(20)); - break; - case EVENT_APPLY_IMMUNITY: - me->MakeInterruptable(false); - break; - case EVENT_SEEDLING_POD: - // If 100 energy, cast Rampant Growth - if (me->GetPower(POWER_ENERGY) >= 100) - { - Talk(SAY_SPECIAL); - me->SetPower(POWER_ENERGY, 0); - DoCast(SPELL_RAMPANT_GROWTH); - } - DoCast(SPELL_SUMMON_SEEDLING_POD); - events.Repeat(Seconds(7)); - break; - case EVENT_CONSUME_LIFE_ENERGY: - DoCast(SPELL_CONSUME_LIFE_ENERGY); - events.Repeat(Seconds(15)); - break; - case EVENT_SUMMON_SPORE: - DoCast(SPELL_SUMMON_SPORE); - events.Repeat(Seconds(47)); - break; - default: - break; + me->MakeInterruptable(true); + DoCast(target, SPELL_WITHER); + } + break; + case EVENT_CONSUME_LIFE_ENERGY: + DoCastAOE(SPELL_CONSUME_LIFE_ENERGY); + events.Repeat(20s); + events.ScheduleEvent(EVENT_SUMMON_SEEDLING_POD, 6s); + events.ScheduleEvent(EVENT_RAMPANT_GROWTH, 6s); + + if (_firstDrainLifeEnergyCycle) + { + events.ScheduleEvent(EVENT_SUMMON_BLOODPETAL_BLOSSOM, 6s); + _firstDrainLifeEnergyCycle = false; + } + else + { + events.ScheduleEvent(EVENT_SUMMON_SPORE, 7s); + _firstDrainLifeEnergyCycle = true; } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } + events.ScheduleEvent(EVENT_SUMMON_SEEDLING_POD, 14s, 15s); + events.ScheduleEvent(EVENT_WITHER, 7s, 8s); - DoMeleeAttackIfReady(); + break; + case EVENT_RAMPANT_GROWTH: + if (me->GetPower(POWER_ENERGY) == me->GetMaxPower(POWER_ENERGY)) + { + Talk(SAY_RAMPANT_GROWTH); + DoCastAOE(SPELL_RAMPANT_GROWTH); + events.RescheduleEvent(EVENT_SUMMON_SEEDLING_POD, 11s); + events.RescheduleEvent(EVENT_WITHER, 3s); + } + break; + case EVENT_SUMMON_SEEDLING_POD: + DoCastSelf(SPELL_SUMMON_SEEDLING_POD); + break; + case EVENT_SUMMON_BLOODPETAL_BLOSSOM: + DoCastAOE(SPELL_SUMMON_BLOODPETAL_BLOSSOM); + break; + case EVENT_SUMMON_SPORE: + DoCastSelf(SPELL_SUMMON_SPORE); + break; + default: + break; } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_ammunaeAI(creature); } + DoMeleeAttackIfReady(); + } + private: + bool _firstDrainLifeEnergyCycle; }; -// 75725 Consume Life Energy -class spell_ammunae_consume_life_energy : public SpellScriptLoader +struct npc_ammunae_seedling_pod : public NullCreatureAI { -public: - spell_ammunae_consume_life_energy() : SpellScriptLoader("spell_ammunae_consume_life_energy") { } + npc_ammunae_seedling_pod(Creature* creature) : NullCreatureAI(creature) { } - class spell_ammunae_consume_life_energy_SpellScript : public SpellScript + void JustAppeared() override { - PrepareSpellScript(spell_ammunae_consume_life_energy_SpellScript); + DoCastSelf(SPELL_SUMMON_SEEDLING_POD_2); + DoCastSelf(SPELL_ENERGIZING_GROWTH); + DoCastSelf(SPELL_ENERGIZE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_6); + } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CONSUME_LIFE_ENERGY_LEECH, SPELL_CONSUME_LIFE_ENERGY_ENERGIZE }); - } - - void FilterTargets(std::list& targets) - { - if (targets.empty()) - return; - - Trinity::Containers::RandomResize(targets, 1); - } - - void HandleScript(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_CONSUME_LIFE_ENERGY_LEECH); - GetCaster()->CastSpell(GetCaster(), SPELL_CONSUME_LIFE_ENERGY_ENERGIZE); - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ammunae_consume_life_energy_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - OnEffectHitTarget += SpellEffectFn(spell_ammunae_consume_life_energy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const override + void JustSummoned(Creature* summon) override { - return new spell_ammunae_consume_life_energy_SpellScript(); + switch (summon->GetEntry()) + { + case NPC_SEEDLING_POD_VISUAL: + summon->CastSpell(summon, SPELL_SEEDLING_POD_VISUAL); + summon->DespawnOrUnsummon(2s + 600ms); + break; + case NPC_BLOODPETAL_BLOSSOM: + case NPC_BLOODPETAL_SPROUT: + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* ammunae = instance->GetCreature(DATA_AMMUNAE)) + if (ammunae->IsAIEnabled) + ammunae->AI()->JustSummoned(summon); + break; + default: + break; + } + } + + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(1s + 200ms); + } +}; + +struct npc_ammunae_bloodpetal_blossom : public ScriptedAI +{ + npc_ammunae_bloodpetal_blossom(Creature* creature) : ScriptedAI(creature) { } + + void JustAppeared() override + { + DoCastSelf(SPELL_SHRINK); + DoCastSelf(SPELL_SUBMERGE); + _events.ScheduleEvent(EVENT_ENGAGE_PLAYERS, 1s); + } + + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(2s); + } + + void JustSummoned(Creature* summon) override + { + summon->CastSpell(summon, SPELL_SUMMON_BLOODPETAL_BLOOM_STATE); + summon->DespawnOrUnsummon(2s + 600ms); + } + + void UpdateAI(uint32 diff) override + { + UpdateVictim(); + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ENGAGE_PLAYERS: + DoZoneInCombat(); + _events.ScheduleEvent(EVENT_TRANSFORM, 1s); + break; + case EVENT_TRANSFORM: + DoCastSelf(SPELL_BLOODPETAL_BLOSSOM); + DoCastSelf(SPELL_SUMMON_BLOODPETAL_BLOSOM_VISUAL, true); + _events.ScheduleEvent(EVENT_REMOVE_SHRINK_AURA, 1s + 500ms); + break; + case EVENT_REMOVE_SHRINK_AURA: + me->RemoveAurasDueToSpell(SPELL_SHRINK); + _events.ScheduleEvent(EVENT_EMERGE, 3s + 400ms); + break; + case EVENT_EMERGE: + me->RemoveAurasDueToSpell(SPELL_SUBMERGE); + DoCastSelf(SPELL_EMERGE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + _events.ScheduleEvent(SPELL_THORN_SLASH, 3s); + break; + case SPELL_THORN_SLASH: + DoCastVictim(SPELL_THORN_SLASH); + _events.Repeat(8s); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + +private: + EventMap _events; +}; + +struct npc_ammunae_bloodpetal_sprout : public ScriptedAI +{ + npc_ammunae_bloodpetal_sprout(Creature* creature) : ScriptedAI(creature) { } + + void JustAppeared() override + { + DoCastSelf(SPELL_SUBMERGE); + _events.ScheduleEvent(EVENT_ENGAGE_PLAYERS, 400ms); + } + + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(2s); + } + + void JustSummoned(Creature* summon) override + { + summon->CastSpell(summon, SPELL_SUMMON_BLOODPETAL_BLOOM_STATE); + summon->DespawnOrUnsummon(2s + 600ms); + } + + void UpdateAI(uint32 diff) override + { + UpdateVictim(); + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ENGAGE_PLAYERS: + DoZoneInCombat(); + _events.ScheduleEvent(EVENT_TRANSFORM, 1s + 200ms); + break; + case EVENT_TRANSFORM: + DoCastSelf(SPELL_SUMMON_BLOODPETAL_SPROUT); + DoCastSelf(SPELL_SUMMON_BLOODPETAL_BLOSOM_VISUAL, true); + _events.ScheduleEvent(EVENT_EMERGE, 5s); + break; + case EVENT_EMERGE: + me->RemoveAurasDueToSpell(SPELL_SUBMERGE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 35.f, true)) + DoCast(target, SPELL_FIXATE); + DoCastSelf(SPELL_EMERGE); + _events.ScheduleEvent(EVENT_FIXATE, 5s); + break; + case EVENT_FIXATE: + DoCastVictim(SPELL_FIXATE); + _events.Repeat(5s); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + +private: + EventMap _events; +}; + +struct npc_ammunae_spore : public ScriptedAI +{ + npc_ammunae_spore(Creature* creature) : ScriptedAI(creature) + { + me->SetReactState(REACT_PASSIVE); + } + + void JustAppeared() override + { + _events.ScheduleEvent(EVENT_ENGAGE_PLAYERS, 1s); + } + + void JustDied(Unit* /*killer*/) override + { + me->CastSpell(me, SPELL_SPORE_CLOUD); + + me->m_Events.AddEventAtOffset([this]() + { + me->RemoveAllAuras(); + me->DespawnOrUnsummon(1s + 500ms); + }, 29s); + } + + void UpdateAI(uint32 diff) override + { + UpdateVictim(); + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ENGAGE_PLAYERS: + me->SetReactState(REACT_AGGRESSIVE); + DoZoneInCombat(); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } +private: + EventMap _events; +}; + +class spell_ammunae_consume_life_energy : public SpellScript +{ + PrepareSpellScript(spell_ammunae_consume_life_energy); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_CONSUME_LIFE_ENERGY_BURN_MANA, + SPELL_CONSUME_LIFE_ENERGY_BURN_RAGE, + SPELL_CONSUME_LIFE_ENERGY_BURN_RUNIC_POWER, + SPELL_CONSUME_LIFE_ENERGY_BURN_FOCUS, + SPELL_CONSUME_LIFE_ENERGY_BURN_ENERGY, + SPELL_CONSUME_LIFE_ENERGY_ENERGIZE + }); + } + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + Trinity::Containers::RandomResize(targets, 1); + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_CONSUME_LIFE_ENERGY_ENERGIZE); + + Player* player = GetHitPlayer(); + if (!player) + return; + + uint32 spellId = SPELL_CONSUME_LIFE_ENERGY_BURN_MANA; + switch (player->getClass()) + { + case CLASS_WARRIOR: + spellId = SPELL_CONSUME_LIFE_ENERGY_BURN_RAGE; + break; + case CLASS_HUNTER: + spellId = SPELL_CONSUME_LIFE_ENERGY_BURN_FOCUS; + break; + case CLASS_DEATH_KNIGHT: + spellId = SPELL_CONSUME_LIFE_ENERGY_BURN_RUNIC_POWER; + break; + case CLASS_ROGUE: + spellId = SPELL_CONSUME_LIFE_ENERGY_BURN_ENERGY; + break; + case CLASS_DRUID: + if (player->GetShapeshiftForm() == FORM_CAT) + spellId = SPELL_CONSUME_LIFE_ENERGY_BURN_ENERGY; + else if (player->GetShapeshiftForm() == FORM_BEAR) + spellId = SPELL_CONSUME_LIFE_ENERGY_BURN_RAGE; + break; + default: + break; + } + + caster->CastSpell(GetHitUnit(), spellId); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ammunae_consume_life_energy::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_ammunae_consume_life_energy::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class spell_ammunae_summon_bloodpetal_blossom : public SpellScript +{ + PrepareSpellScript(spell_ammunae_summon_bloodpetal_blossom); + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + Trinity::Containers::RandomResize(targets, 1); + } + + void HandleDespawn(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + target->DespawnOrUnsummon(1s + 200ms); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ammunae_summon_bloodpetal_blossom::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + OnEffectHitTarget += SpellEffectFn(spell_ammunae_summon_bloodpetal_blossom::HandleDespawn, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + } +}; + +class spell_ammunae_rampant_growth : public SpellScript +{ + PrepareSpellScript(spell_ammunae_rampant_growth); + + void HandleDespawn(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + target->DespawnOrUnsummon(1s + 600ms); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ammunae_rampant_growth::HandleDespawn, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + } +}; + +class spell_ammunae_fixate : public SpellScript +{ + PrepareSpellScript(spell_ammunae_fixate); + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()) + GetHitUnit()->CastSpell(caster, GetEffectValue(), true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ammunae_fixate::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); } }; void AddSC_boss_ammunae() { - new boss_ammunae(); - new spell_ammunae_consume_life_energy(); + RegisterHallsOfOriginationCreatureAI(boss_ammunae); + RegisterHallsOfOriginationCreatureAI(npc_ammunae_seedling_pod); + RegisterHallsOfOriginationCreatureAI(npc_ammunae_bloodpetal_blossom); + RegisterHallsOfOriginationCreatureAI(npc_ammunae_bloodpetal_sprout); + RegisterHallsOfOriginationCreatureAI(npc_ammunae_spore); + RegisterSpellScript(spell_ammunae_consume_life_energy); + RegisterSpellScript(spell_ammunae_summon_bloodpetal_blossom); + RegisterSpellScript(spell_ammunae_rampant_growth); + RegisterSpellScript(spell_ammunae_fixate); } diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h b/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h index a8b90cdb002..b7a63e48a0f 100644 --- a/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h @@ -123,6 +123,12 @@ enum HOOCreatures NPC_FLUX_ANIMATOR = 40033, NPC_STAR_SHARD = 40106, + /*Ammunae*/ + NPC_SEEDLING_POD_VISUAL = 40592, + NPC_BLOODPETAL_BLOSSOM = 40620, + NPC_BLOODPETAL_BLOSSOM_VISUAL = 40622, + NPC_BLOODPETAL_SPROUT = 40630, + /*Setesh*/ NPC_SETESH_CHAOS_SEED = 41126, NPC_SETESH_CHAOS_BLAST = 41041, diff --git a/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp index e20e9c71e68..25d8c1639e0 100644 --- a/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp +++ b/src/server/scripts/Kalimdor/kalimdor_script_loader.cpp @@ -110,7 +110,7 @@ void AddSC_halls_of_origination(); void AddSC_boss_temple_guardian_anhuur(); void AddSC_boss_earthrager_ptah(); void AddSC_boss_anraphet(); -//void AddSC_boss_ammunae(); +void AddSC_boss_ammunae(); //void AddSC_boss_isiset(); //void AddSC_boss_setesh(); void AddSC_boss_rajh(); @@ -242,7 +242,7 @@ void AddKalimdorScripts() AddSC_boss_temple_guardian_anhuur(); AddSC_boss_earthrager_ptah(); AddSC_boss_anraphet(); - //AddSC_boss_ammunae(); + AddSC_boss_ammunae(); //AddSC_boss_isiset(); //AddSC_boss_setesh(); AddSC_boss_rajh(); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index ac10d0903fa..a79d4824cd6 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -5506,6 +5506,21 @@ class spell_gen_ghost : public AuraScript } }; +class spell_gen_zero_energy_zero_regen : public AuraScript +{ + PrepareAuraScript(spell_gen_zero_energy_zero_regen); + + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->SetPower(POWER_ENERGY, 0); + } + + void Register() override + { + AfterEffectApply += AuraEffectRemoveFn(spell_gen_zero_energy_zero_regen::AfterApply, EFFECT_0, SPELL_AURA_MOD_POWER_REGEN_PERCENT, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -5635,4 +5650,5 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_cauldron_of_battle); RegisterSpellScript(spell_gen_flask_of_battle); RegisterAuraScript(spell_gen_ghost); + RegisterAuraScript(spell_gen_zero_energy_zero_regen); }