diff options
author | Gustavo <sirikfoll@hotmail.com> | 2017-09-25 17:21:15 -0300 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-09-12 00:17:29 +0200 |
commit | 5e5ca6c84af9b0223c70f18b70f5f645ef559d99 (patch) | |
tree | 216da8bdc07a1e5db2c9fd320e53b8c10a458dd3 | |
parent | e531beeb8312f393896e1975ea537827594bedb7 (diff) |
Core/Scripts: Boss Amanitar rewrite (#20283)
* Core/Scripts: Boss Amanitar rewrite
Fixes mushrooms behavior, correct and script his spell, size, spawn positions, despawn and respawn, and everything else
Fixes Mini spell cast(only re-cast if there is at least one person without the debuff)
Corrects boss initial position
Updates script register model
(cherry picked from commit 0b766db6a41a4db0d631e36fcc753c658b746328)
-rw-r--r-- | sql/updates/world/master/2020_09_12_01_world_2017_09_25_01_world.sql | 6 | ||||
-rw-r--r-- | src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp | 368 |
2 files changed, 214 insertions, 160 deletions
diff --git a/sql/updates/world/master/2020_09_12_01_world_2017_09_25_01_world.sql b/sql/updates/world/master/2020_09_12_01_world_2017_09_25_01_world.sql new file mode 100644 index 00000000000..4fefad6c649 --- /dev/null +++ b/sql/updates/world/master/2020_09_12_01_world_2017_09_25_01_world.sql @@ -0,0 +1,6 @@ +UPDATE `creature` SET `position_x`=340.1726, `position_y`=-878.5924, `position_z`=-74.86385, `orientation`=0.3316126 WHERE `id`=30258; +UPDATE `creature_template` SET `InhabitType`=12, `flags_extra`=0 WHERE `entry` IN(30391,31461,30435,31462); + +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_amanitar_potent_fungus'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(56648,'spell_amanitar_potent_fungus'); diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp index 0a9acfdb37a..7fd6cc46799 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_amanitar.cpp @@ -19,218 +19,266 @@ #include "ahnkahet.h" #include "InstanceScript.h" #include "ScriptedCreature.h" -#include "TemporarySummon.h" +#include "SpellScript.h" -enum Spells +enum AmanitarSpells { - SPELL_BASH = 57094, // Victim - SPELL_ENTANGLING_ROOTS = 57095, // Random Victim 100Y - SPELL_MINI = 57055, // Self - SPELL_VENOM_BOLT_VOLLEY = 57088, // Random Victim 100Y - SPELL_HEALTHY_MUSHROOM_POTENT_FUNGUS = 56648, // Killer 3Y - SPELL_POISONOUS_MUSHROOM_POISON_CLOUD = 57061, // Self - Duration 8 Sec - SPELL_POISONOUS_MUSHROOM_VISUAL_AREA = 61566, // Self - SPELL_POISONOUS_MUSHROOM_VISUAL_AURA = 56741, // Self - SPELL_PUTRID_MUSHROOM = 31690, // To make the mushrooms visible - SPELL_POWER_MUSHROOM_VISUAL_AURA = 56740, + //Amanitar + SPELL_BASH = 57094, + SPELL_ENTANGLING_ROOTS = 57095, + SPELL_MINI = 57055, + SPELL_VENOM_BOLT_VOLLEY = 57088, + SPELL_REMOVE_MUSHROOM_POWER = 57283, + //Mushrooms + SPELL_POTENT_FUNGUS = 56648, + SPELL_POISONOUS_MUSHROOM_POISON_CLOUD = 57061, + SPELL_POISONOUS_MUSHROOM_VISUAL_AURA = 56741, + SPELL_POWER_MUSHROOM_VISUAL_AURA = 56740, + SPELL_PUTRID_MUSHROOM = 31690, + SPELL_GROW = 57059, + SPELL_SHRINK = 31691 }; -enum Creatures -{ - NPC_TRIGGER = 19656 -}; - -enum Events +enum AmanitarEvents { EVENT_SPAWN = 1, EVENT_MINI, EVENT_ROOT, EVENT_BASH, EVENT_BOLT, - EVENT_AURA + EVENT_RESPAWN }; -class boss_amanitar : public CreatureScript +Position const MushroomPositions[32] = { - public: - boss_amanitar() : CreatureScript("boss_amanitar") { } + { 373.4807f, -856.5301f, -74.30518f, 0.2094395f }, + { 358.4792f, -879.3193f, -75.9463f, 5.166174f }, + { 356.5531f, -846.3022f, -72.1796f, 3.193953f }, + { 332.369f, -846.081f, -74.30516f, 4.834562f }, + { 360.2234f, -862.055f, -75.22755f, 1.658063f }, + { 351.7189f, -890.9619f, -76.54617f, 1.064651f }, + { 345.8126f, -869.1772f, -77.17728f, 1.361357f }, + { 367.5179f, -884.0129f, -77.32881f, 4.276057f }, + { 370.6044f, -868.4305f, -74.19881f, 0.8901179f }, + { 381.3156f, -873.2377f, -74.82656f, 1.099557f }, + { 371.5869f, -873.8141f, -74.72424f, 1.082104f }, + { 340.4079f, -891.6375f, -74.99128f, 1.134464f }, + { 368.21f, -851.5953f, -73.99741f, 4.694936f }, + { 328.7047f, -853.9812f, -75.51253f, 0.5759587f }, + { 366.4145f, -876.39f, -75.52739f, 5.253441f }, + { 380.1362f, -861.4344f, -73.45917f, 3.787364f }, + { 373.3007f, -888.8057f, -79.03593f, 5.602507f }, + { 348.3599f, -848.0839f, -73.54117f, 1.745329f }, + { 352.5586f, -882.6624f, -75.68202f, 3.822271f }, + { 357.8967f, -871.179f, -75.77553f, 2.443461f }, + { 360.1034f, -842.3351f, -71.08852f, 4.34587f }, + { 348.1334f, -861.5244f, -74.61307f, 2.565634f }, + { 401.4896f, -866.7059f, -73.22395f, 0.8901179f }, + { 360.1683f, -889.1515f, -76.74798f, 3.612832f }, + { 350.1828f, -907.7313f, -74.94678f, 5.044002f }, + { 340.6278f, -856.5973f, -74.23862f, 4.415683f }, + { 366.4849f, -859.7621f, -74.82679f, 1.500983f }, + { 359.1482f, -853.3346f, -74.47543f, 5.654867f }, + { 374.9992f, -879.0921f, -75.56115f, 1.867502f }, + { 339.5252f, -850.4612f, -74.45442f, 4.764749f }, + { 337.0534f, -864.002f, -75.72749f, 4.642576f }, + { 398.2797f, -851.8694f, -68.84419f, 0.5759587f } +}; - struct boss_amanitarAI : public BossAI - { - boss_amanitarAI(Creature* creature) : BossAI(creature, DATA_AMANITAR) { } +struct boss_amanitar : public BossAI +{ + boss_amanitar(Creature* creature) : BossAI(creature, DATA_AMANITAR) { } - void Reset() override - { - _Reset(); - me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE); - me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); - } + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + events.ScheduleEvent(EVENT_ROOT, Seconds(5), Seconds(9)); + events.ScheduleEvent(EVENT_BASH, Seconds(10), Seconds(14)); + events.ScheduleEvent(EVENT_BOLT, Seconds(15), Seconds(20)); + events.ScheduleEvent(EVENT_MINI, Seconds(12), Seconds(18)); + events.ScheduleEvent(EVENT_SPAWN, Seconds(1)); + events.ScheduleEvent(EVENT_RESPAWN, Seconds(40), Seconds(60)); + } - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + summons.DespawnAll(); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI); + _DespawnAtEvade(); + } - events.ScheduleEvent(EVENT_ROOT, urand(5, 9) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_BASH, urand(10, 14) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_BOLT, urand(15, 20) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_MINI, urand(12, 18) * IN_MILLISECONDS); - events.ScheduleEvent(EVENT_SPAWN, 5 * IN_MILLISECONDS); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + DoCastAOE(SPELL_REMOVE_MUSHROOM_POWER); + instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI); + } - void JustDied(Unit* /*killer*/) override - { - _JustDied(); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI); - } + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + } - void SpawnAdds() - { - uint8 u = 0; + void SummonedCreatureDies(Creature* summon, Unit* killer) override + { + _mushroomsDeque.push_back(summon->GetPosition()); - for (uint8 i = 0; i < 30; ++i) - { - Position pos = me->GetRandomNearPosition(30.0f); - me->UpdateGroundPositionZ(pos.GetPositionX(), pos.GetPositionY(), pos.m_positionZ); + BossAI::SummonedCreatureDies(summon, killer); + } - if (Creature* trigger = me->SummonCreature(NPC_TRIGGER, pos)) - { - Creature* temp1 = trigger->FindNearestCreature(NPC_HEALTHY_MUSHROOM, 4.0f, true); - Creature* temp2 = trigger->FindNearestCreature(NPC_POISONOUS_MUSHROOM, 4.0f, true); - if (!temp1 && !temp2) - { - u = 1 - u; - me->SummonCreature(u > 0 ? NPC_POISONOUS_MUSHROOM : NPC_HEALTHY_MUSHROOM, pos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60 * IN_MILLISECONDS); - } - trigger->DespawnOrUnsummon(); - } - } - } + void SpawnMushroom(Position const pos) + { + me->SummonCreature(roll_chance_i(40) ? NPC_HEALTHY_MUSHROOM : NPC_POISONOUS_MUSHROOM, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 4000); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SPAWN: + for (Position const pos : MushroomPositions) + SpawnMushroom(pos); + break; + case EVENT_MINI: + if (SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, true, -SPELL_MINI)) { - case EVENT_SPAWN: - SpawnAdds(); - events.ScheduleEvent(EVENT_SPAWN, 20 * IN_MILLISECONDS); - break; - case EVENT_MINI: - DoCast(SPELL_MINI); - events.ScheduleEvent(EVENT_MINI, urand(25, 30) * IN_MILLISECONDS); - break; - case EVENT_ROOT: - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_ENTANGLING_ROOTS, true); - events.ScheduleEvent(EVENT_ROOT, urand(10, 15) * IN_MILLISECONDS); - break; - case EVENT_BASH: - DoCastVictim(SPELL_BASH); - events.ScheduleEvent(EVENT_BASH, urand(7, 12) * IN_MILLISECONDS); - break; - case EVENT_BOLT: - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_VENOM_BOLT_VOLLEY, true); - events.ScheduleEvent(EVENT_BOLT, urand(18, 22) * IN_MILLISECONDS); - break; - default: - break; + DoCastAOE(SPELL_MINI); + events.Repeat(Seconds(30)); } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - DoMeleeAttackIfReady(); + else + events.Repeat(Seconds(1)); + break; + case EVENT_ROOT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) + DoCast(target, SPELL_ENTANGLING_ROOTS, true); + events.Repeat(Seconds(10), Seconds(15)); + break; + case EVENT_BASH: + DoCastVictim(SPELL_BASH); + events.Repeat(Seconds(7), Seconds(12)); + break; + case EVENT_BOLT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_VENOM_BOLT_VOLLEY, true); + events.Repeat(Seconds(18), Seconds(22)); + break; + case EVENT_RESPAWN: + while (!_mushroomsDeque.empty()) + { + SpawnMushroom(_mushroomsDeque.front()); + _mushroomsDeque.pop_front(); + } + events.Repeat(Seconds(40), Seconds(60)); + break; + default: + break; } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetAhnKahetAI<boss_amanitarAI>(creature); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } + + DoMeleeAttackIfReady(); + } + + private: + std::deque<Position> _mushroomsDeque; }; -class npc_amanitar_mushrooms : public CreatureScript +struct npc_amanitar_mushrooms : public ScriptedAI { -public: - npc_amanitar_mushrooms() : CreatureScript("npc_amanitar_mushrooms") { } + npc_amanitar_mushrooms(Creature* creature) : ScriptedAI(creature), _active(false) { } - struct npc_amanitar_mushroomsAI : public ScriptedAI + void Reset() override { - npc_amanitar_mushroomsAI(Creature* creature) : ScriptedAI(creature) { } + me->SetReactState(REACT_PASSIVE); + me->SetDisplayFromModel(1); + DoCastSelf(SPELL_PUTRID_MUSHROOM); + DoCastSelf(SPELL_SHRINK, true); + DoCastSelf(SPELL_GROW, true); - EventMap events; + if (me->GetEntry() == NPC_HEALTHY_MUSHROOM) + { + DoCastSelf(SPELL_POWER_MUSHROOM_VISUAL_AURA); + _active = true; + } + else + DoCastSelf(SPELL_POISONOUS_MUSHROOM_VISUAL_AURA); - void Reset() override + _scheduler.Schedule(Milliseconds(800), [this](TaskContext /*context*/) { - events.Reset(); - events.ScheduleEvent(EVENT_AURA, 1 * IN_MILLISECONDS); + DoCastSelf(SPELL_GROW, true); + }); + } + + void MoveInLineOfSight(Unit* target) override + { + if (_active || target->GetTypeId() != TYPEID_PLAYER || me->GetDistance2d(target) > 2.0f) + return; - me->SetDisplayFromModel(1); - DoCast(SPELL_PUTRID_MUSHROOM); + _active = true; - if (me->GetEntry() == NPC_POISONOUS_MUSHROOM) - DoCast(SPELL_POISONOUS_MUSHROOM_VISUAL_AURA); - else - DoCast(SPELL_POWER_MUSHROOM_VISUAL_AURA); - } + target->RemoveAurasDueToSpell(SPELL_POTENT_FUNGUS); + DoCastAOE(SPELL_POISONOUS_MUSHROOM_POISON_CLOUD); - void DamageTaken(Unit* /*attacker*/, uint32 &damage) override + _scheduler.Schedule(Seconds(1), [this](TaskContext /*context*/) { - if (damage >= me->GetHealth() && me->GetEntry() == NPC_HEALTHY_MUSHROOM) - DoCast(me, SPELL_HEALTHY_MUSHROOM_POTENT_FUNGUS, true); - } + me->SetObjectScale(0.1f); + me->DespawnOrUnsummon(Seconds(4)); + }); + } - void EnterCombat(Unit* /*who*/) override { } - void AttackStart(Unit* /*victim*/) override { } + void JustDied(Unit* /*killer*/) override + { + if (me->GetEntry() == NPC_HEALTHY_MUSHROOM) + DoCastAOE(SPELL_POTENT_FUNGUS, true); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } - events.Update(diff); +private: + TaskScheduler _scheduler; + bool _active; +}; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; +// 56648 - Potent Fungus +class spell_amanitar_potent_fungus : public AuraScript +{ + PrepareAuraScript(spell_amanitar_potent_fungus); - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_AURA: - if (me->GetEntry() == NPC_POISONOUS_MUSHROOM) - { - DoCast(me, SPELL_POISONOUS_MUSHROOM_VISUAL_AREA, true); - DoCast(me, SPELL_POISONOUS_MUSHROOM_POISON_CLOUD); - } - events.ScheduleEvent(EVENT_AURA, 7 * IN_MILLISECONDS); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - } - }; + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + if (!target->HasAura(SPELL_MINI)) + return; + + target->RemoveAurasDueToSpell(SPELL_MINI); + Remove(); + } - CreatureAI* GetAI(Creature* creature) const override + void Register() override { - return GetAhnKahetAI<npc_amanitar_mushroomsAI>(creature); + AfterEffectApply += AuraEffectApplyFn(spell_amanitar_potent_fungus::OnApply, EFFECT_0, SPELL_AURA_MOD_SCALE, AURA_EFFECT_HANDLE_REAL); } }; void AddSC_boss_amanitar() { - new boss_amanitar(); - new npc_amanitar_mushrooms(); + RegisterAhnKahetCreatureAI(boss_amanitar); + RegisterAhnKahetCreatureAI(npc_amanitar_mushrooms); + RegisterAuraScript(spell_amanitar_potent_fungus); } |