From 09551b663a8190ef2ce9af6ad3e7cb5058e82b2e Mon Sep 17 00:00:00 2001 From: offl <11556157+offl@users.noreply.github.com> Date: Thu, 27 May 2021 19:05:47 +0300 Subject: Scripts/Quest: Rework cocooned creatures (#26554) (cherry picked from commit 78bd609e8a37caa354c42ee6da798ab6c0bb3009) --- .../scripts/Kalimdor/zone_bloodmyst_isle.cpp | 150 +++++++++++---------- .../scripts/Northrend/zone_howling_fjord.cpp | 74 ++++++---- src/server/scripts/Northrend/zone_zuldrak.cpp | 60 +++++++++ .../scripts/Outland/zone_terokkar_forest.cpp | 69 ++++++++++ 4 files changed, 252 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp index 5482bd47c62..0b8f48a26e0 100644 --- a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp @@ -15,85 +15,15 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Bloodmyst_Isle -SD%Complete: 80 -SDComment: Quest support: 9670 -SDCategory: Bloodmyst Isle -EndScriptData */ - -/* ContentData -npc_webbed_creature -EndContentData */ - #include "ScriptMgr.h" #include "CellImpl.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "MotionMaster.h" #include "ObjectAccessor.h" -#include "PassiveAI.h" #include "Player.h" #include "ScriptedEscortAI.h" - -/*###### -## npc_webbed_creature -######*/ - -//possible creatures to be spawned -uint32 const possibleSpawns[31] = {17322, 17661, 17496, 17522, 17340, 17352, 17333, 17524, 17654, 17348, 17339, 17345, 17359, 17353, 17336, 17550, 17330, 17701, 17321, 17325, 17320, 17683, 17342, 17715, 17334, 17341, 17338, 17337, 17346, 17344, 17327}; - -enum WebbedCreature -{ - NPC_EXPEDITION_RESEARCHER = 17681 -}; - -class npc_webbed_creature : public CreatureScript -{ -public: - npc_webbed_creature() : CreatureScript("npc_webbed_creature") { } - - struct npc_webbed_creatureAI : public NullCreatureAI - { - npc_webbed_creatureAI(Creature* creature) : NullCreatureAI(creature) { } - - void Reset() override { } - - void JustEngagedWith(Unit* /*who*/) override { } - - void AttackStart(Unit* /*who*/) override { } - - void MoveInLineOfSight(Unit* /*who*/) override { } - - void JustDied(Unit* killer) override - { - if (!killer) - return; - - uint32 spawnCreatureID = 0; - - switch (urand(0, 2)) - { - case 0: - if (Player* player = killer->ToPlayer()) - player->KilledMonsterCredit(NPC_EXPEDITION_RESEARCHER); - spawnCreatureID = NPC_EXPEDITION_RESEARCHER; - break; - case 1: - case 2: - spawnCreatureID = possibleSpawns[urand(0, 30)]; - break; - } - - me->SummonCreature(spawnCreatureID, 0.0f, 0.0f, 0.0f, me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1min); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_webbed_creatureAI(creature); - } -}; +#include "SpellScript.h" /*###### ## Quest 9759: Ending Their World @@ -815,9 +745,85 @@ public: } }; +/*###### +## Quest 9670: They're Alive! Maybe... +######*/ + +enum FreeWebbedBloodmyst +{ + SPELL_FREE_WEBBED_1 = 30954, + SPELL_FREE_WEBBED_2 = 30955, + SPELL_FREE_WEBBED_3 = 30956, + SPELL_FREE_WEBBED_4 = 30957, + SPELL_FREE_WEBBED_5 = 30958, + SPELL_FREE_WEBBED_6 = 30959, + SPELL_FREE_WEBBED_7 = 30960, + SPELL_FREE_WEBBED_8 = 30961, + SPELL_FREE_WEBBED_9 = 30962, + SPELL_FREE_WEBBED_10 = 30963, + SPELL_FREE_WEBBED_11 = 31010 +}; + +uint32 const CocoonSummonSpells[10] = +{ + SPELL_FREE_WEBBED_1, SPELL_FREE_WEBBED_2, SPELL_FREE_WEBBED_3, SPELL_FREE_WEBBED_4, SPELL_FREE_WEBBED_5, + SPELL_FREE_WEBBED_6, SPELL_FREE_WEBBED_7, SPELL_FREE_WEBBED_8, SPELL_FREE_WEBBED_9, SPELL_FREE_WEBBED_10 +}; + +// 30950 - Free Webbed Creature +class spell_free_webbed : public SpellScript +{ + PrepareSpellScript(spell_free_webbed); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo(CocoonSummonSpells); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), Trinity::Containers::SelectRandomContainerElement(CocoonSummonSpells), true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_free_webbed::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 31009 - Free Webbed Creature +class spell_free_webbed_on_quest : public SpellScript +{ + PrepareSpellScript(spell_free_webbed_on_quest); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo(CocoonSummonSpells) && ValidateSpellInfo({ SPELL_FREE_WEBBED_11 }); + } + + // This one is a bit different from the one used in Terokkar. There is additional spell 31011 which apply periodic aura to trigger + // summon spell 31010 after 1.5 sec. However in retail Expedition Researcher is summoned instantly, we'll use 31010 directly + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + + if (roll_chance_i(66)) + caster->CastSpell(caster, Trinity::Containers::SelectRandomContainerElement(CocoonSummonSpells), true); + else + target->CastSpell(caster, SPELL_FREE_WEBBED_11, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_free_webbed_on_quest::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + void AddSC_bloodmyst_isle() { - new npc_webbed_creature(); new npc_sironas(); new npc_demolitionist_legoso(); + RegisterSpellScript(spell_free_webbed); + RegisterSpellScript(spell_free_webbed_on_quest); } diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp index 2590215091e..a5035094a95 100644 --- a/src/server/scripts/Northrend/zone_howling_fjord.cpp +++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp @@ -512,7 +512,11 @@ class spell_mindless_abomination_explosion_fx_master : public SpellScriptLoader } }; -enum SummonSpells +/*###### +## Quest 11296: Rivenwood Captives +######*/ + +enum RivenwoodCaptives { SPELL_SUMMON_BABY_RIVEN_WIDOWS = 43275, SPELL_SUMMON_DARKCLAW_BAT = 43276, @@ -525,11 +529,10 @@ enum SummonSpells SPELL_SUMMON_WINTERSKORN_WOODSMAN = 43283, SPELL_SUMMON_WINTERSKORN_TRIBESMAN = 43284, SPELL_SUMMON_WINTERSKORN_ORACLE = 43285, - SPELL_SUMMON_FREED_MIST_WHISPER_SCOUT = 43289, - NPC_MIST_WHISPER_SCOUT = 24211 + SPELL_SUMMON_FREED_MIST_WHISPER_SCOUT = 43289 }; -const uint32 rivenWidowCocoonVictims[11] = +uint32 const CocoonSummonSpells[11] = { SPELL_SUMMON_BABY_RIVEN_WIDOWS, SPELL_SUMMON_DARKCLAW_BAT, @@ -544,39 +547,51 @@ const uint32 rivenWidowCocoonVictims[11] = SPELL_SUMMON_WINTERSKORN_ORACLE }; -class npc_riven_widow_cocoon : public CreatureScript +// 43288 - Rivenwood Captives: Player Not On Quest +class spell_rivenwood_captives_not_on_quest : public SpellScript { -public: - npc_riven_widow_cocoon() : CreatureScript("npc_riven_widow_cocoon") { } + PrepareSpellScript(spell_rivenwood_captives_not_on_quest); - struct npc_riven_widow_cocoonAI : public ScriptedAI + bool Validate(SpellInfo const* /*spellInfo*/) override { - npc_riven_widow_cocoonAI(Creature* creature) : ScriptedAI(creature) { } + return ValidateSpellInfo(CocoonSummonSpells); + } - void Reset() override { } - void JustEngagedWith(Unit* /*who*/) override { } - void MoveInLineOfSight(Unit* /*who*/) override { } + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetCaster(), Trinity::Containers::SelectRandomContainerElement(CocoonSummonSpells), true); + } - void JustDied(Unit* killer) override - { - if (!killer || killer->GetTypeId() != TYPEID_PLAYER) - return; + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_rivenwood_captives_not_on_quest::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; - Player* player = killer->ToPlayer(); +// 43287 - Rivenwood Captives: Player On Quest +class spell_rivenwood_captives_on_quest : public SpellScript +{ + PrepareSpellScript(spell_rivenwood_captives_on_quest); - if (roll_chance_i(20)) - { - player->CastSpell(me, SPELL_SUMMON_FREED_MIST_WHISPER_SCOUT, true); - player->KilledMonsterCredit(NPC_MIST_WHISPER_SCOUT); - } - else - player->CastSpell(me, rivenWidowCocoonVictims[urand(0, 10)], true); - } - }; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo(CocoonSummonSpells) && ValidateSpellInfo({ SPELL_SUMMON_FREED_MIST_WHISPER_SCOUT }); + } - CreatureAI* GetAI(Creature* creature) const override + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + + if (roll_chance_i(80)) + target->CastSpell(caster, Trinity::Containers::SelectRandomContainerElement(CocoonSummonSpells), true); + else + target->CastSpell(caster, SPELL_SUMMON_FREED_MIST_WHISPER_SCOUT, true); + } + + void Register() override { - return new npc_riven_widow_cocoonAI(creature); + OnEffectHitTarget += SpellEffectFn(spell_rivenwood_captives_on_quest::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; @@ -586,5 +601,6 @@ void AddSC_howling_fjord() RegisterCreatureAI(npc_daegarn); new npc_mindless_abomination(); new spell_mindless_abomination_explosion_fx_master(); - new npc_riven_widow_cocoon(); + RegisterSpellScript(spell_rivenwood_captives_not_on_quest); + RegisterSpellScript(spell_rivenwood_captives_on_quest); } diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp index 6b1022c631f..e3a1c2ae790 100644 --- a/src/server/scripts/Northrend/zone_zuldrak.cpp +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -1045,6 +1045,64 @@ class spell_drop_disguise : public SpellScript } }; +/*###### +## Quest 12606: Cocooned! +######*/ + +enum Cocooned +{ + SPELL_SUMMON_SCOURGED_CAPTIVE = 51597, + SPELL_SUMMON_CAPTIVE_FOOTMAN = 51599 +}; + +// 51596 - Cocooned: Player Not On Quest +class spell_cocooned_not_on_quest : public SpellScript +{ + PrepareSpellScript(spell_cocooned_not_on_quest); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SUMMON_SCOURGED_CAPTIVE }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetCaster(), SPELL_SUMMON_SCOURGED_CAPTIVE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_cocooned_not_on_quest::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 51598 - Cocooned: Player On Quest +class spell_cocooned_on_quest : public SpellScript +{ + PrepareSpellScript(spell_cocooned_on_quest); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SUMMON_SCOURGED_CAPTIVE, SPELL_SUMMON_CAPTIVE_FOOTMAN }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + + if (roll_chance_i(66)) + target->CastSpell(caster, SPELL_SUMMON_SCOURGED_CAPTIVE, true); + else + target->CastSpell(caster, SPELL_SUMMON_CAPTIVE_FOOTMAN, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_cocooned_on_quest::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + void AddSC_zuldrak() { new npc_drakuru_shackles(); @@ -1063,4 +1121,6 @@ void AddSC_zuldrak() RegisterSpellScript(spell_scourge_disguise_instability); RegisterSpellScript(spell_scourge_disguise_expiring); RegisterSpellScript(spell_drop_disguise); + RegisterSpellScript(spell_cocooned_not_on_quest); + RegisterSpellScript(spell_cocooned_on_quest); } diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp index a77e34f1fe2..b30ef7719a6 100644 --- a/src/server/scripts/Outland/zone_terokkar_forest.cpp +++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp @@ -174,8 +174,77 @@ class spell_skyguard_flare : public SpellScript } }; +/*###### +## Quest 10873: Taken in the Night +######*/ + +enum FreeWebbedTerokkar +{ + SPELL_FREE_WEBBED_1 = 38953, + SPELL_FREE_WEBBED_2 = 38955, + SPELL_FREE_WEBBED_3 = 38956, + SPELL_FREE_WEBBED_4 = 38957, + SPELL_FREE_WEBBED_5 = 38958, + SPELL_FREE_WEBBED_6 = 38978 +}; + +uint32 const CocoonSummonSpells[5] = +{ + SPELL_FREE_WEBBED_1, SPELL_FREE_WEBBED_2, SPELL_FREE_WEBBED_3, SPELL_FREE_WEBBED_4, SPELL_FREE_WEBBED_5 +}; + +// 38949 - Terrokar Free Webbed Creature +class spell_free_webbed_terokkar : public SpellScript +{ + PrepareSpellScript(spell_free_webbed_terokkar); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo(CocoonSummonSpells); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), Trinity::Containers::SelectRandomContainerElement(CocoonSummonSpells), true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_free_webbed_terokkar::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 38950 - Terokkar Free Webbed Creature ON QUEST +class spell_free_webbed_terokkar_on_quest : public SpellScript +{ + PrepareSpellScript(spell_free_webbed_terokkar_on_quest); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo(CocoonSummonSpells) && ValidateSpellInfo({ SPELL_FREE_WEBBED_6 }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + Unit* target = GetHitUnit(); + + if (roll_chance_i(66)) + caster->CastSpell(caster, Trinity::Containers::SelectRandomContainerElement(CocoonSummonSpells), true); + else + target->CastSpell(caster, SPELL_FREE_WEBBED_6, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_free_webbed_terokkar_on_quest::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + void AddSC_terokkar_forest() { new npc_unkor_the_ruthless(); RegisterSpellScript(spell_skyguard_flare); + RegisterSpellScript(spell_free_webbed_terokkar); + RegisterSpellScript(spell_free_webbed_terokkar_on_quest); } -- cgit v1.2.3