Scripts/Quest: Rework cocooned creatures (#26554)

This commit is contained in:
offl
2021-05-27 19:05:47 +03:00
committed by GitHub
parent f2f0aeb562
commit 78bd609e8a
5 changed files with 450 additions and 105 deletions

View File

@@ -15,85 +15,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* 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
@@ -824,9 +754,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);
}

View File

@@ -514,7 +514,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,
@@ -527,11 +531,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,
@@ -546,39 +549,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 JustDied(Unit* killer) override
{
if (!killer || killer->GetTypeId() != TYPEID_PLAYER)
return;
Player* player = killer->ToPlayer();
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);
}
};
CreatureAI* GetAI(Creature* creature) const override
void HandleDummy(SpellEffIndex /*effIndex*/)
{
return new npc_riven_widow_cocoonAI(creature);
GetHitUnit()->CastSpell(GetCaster(), Trinity::Containers::SelectRandomContainerElement(CocoonSummonSpells), true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_rivenwood_captives_not_on_quest::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 43287 - Rivenwood Captives: Player On Quest
class spell_rivenwood_captives_on_quest : public SpellScript
{
PrepareSpellScript(spell_rivenwood_captives_on_quest);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(CocoonSummonSpells) && ValidateSpellInfo({ SPELL_SUMMON_FREED_MIST_WHISPER_SCOUT });
}
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
{
OnEffectHitTarget += SpellEffectFn(spell_rivenwood_captives_on_quest::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -588,5 +603,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);
}

View File

@@ -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);
}

View File

@@ -177,8 +177,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);
}