Scripts/Events: implement Whack-a-Gnoll minigame

This commit is contained in:
Ovahlord
2019-04-09 19:22:32 +02:00
parent 085170b5af
commit ba49cac3aa
4 changed files with 383 additions and 0 deletions

View File

@@ -1747,6 +1747,197 @@ private:
bool _hasHit;
};
enum WhackAGnoll
{
SPELL_WHACK_SUMMON_NORMAL = 102036,
SPELL_WHACK_SUMMON_BABY = 102043,
SPELL_WHACK_SUMMON_BONUS = 102044,
SPELL_GNOLL_AURA_OKAY_TO_HIT = 101996,
SPELL_WHACK_A_GNOLL_ACTION_BAR_REMOVED = 102137,
SPELL_WHACK_A_GNOLL_ACTION_BAR = 110230,
SPELL_WHACK_TRIGGERED = 102022,
SPELL_WHACK_ROOT = 101829
};
class spell_darkmoon_island_whack_summon_aura : public AuraScript
{
PrepareAuraScript(spell_darkmoon_island_whack_summon_aura);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_GNOLL_AURA_OKAY_TO_HIT });
}
void OnPeriodic(AuraEffect const* aurEff)
{
GetTarget()->CastSpell(GetTarget(), SPELL_GNOLL_AURA_OKAY_TO_HIT, true, nullptr, aurEff);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_darkmoon_island_whack_summon_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
class GnollHolderTargetSelector
{
public:
GnollHolderTargetSelector(Unit* caster) : _caster(caster) { }
bool operator() (WorldObject* target)
{
return !_caster->CanSeeOrDetect(target);
}
private:
Unit* _caster;
};
class spell_darkmoon_island_gnoll_aura_okay_to_hit : public SpellScript
{
PrepareSpellScript(spell_darkmoon_island_gnoll_aura_okay_to_hit);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo(
{
SPELL_WHACK_SUMMON_NORMAL,
SPELL_WHACK_SUMMON_BABY,
SPELL_WHACK_SUMMON_BONUS
});
}
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.remove_if(GnollHolderTargetSelector(GetCaster()));
if (targets.size())
Trinity::Containers::RandomResize(targets, 1);
}
void HandleSummon(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
if (!caster)
return;
uint32 summonSpellId = SPELL_WHACK_SUMMON_NORMAL;
if (roll_chance_i(50))
summonSpellId = RAND(SPELL_WHACK_SUMMON_BABY, SPELL_WHACK_SUMMON_BONUS);
caster->CastSpell(GetHitUnit(), summonSpellId, true);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_darkmoon_island_gnoll_aura_okay_to_hit::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_darkmoon_island_gnoll_aura_okay_to_hit::HandleSummon, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
class spell_darkmoon_island_whack_dummy : public SpellScript
{
PrepareSpellScript(spell_darkmoon_island_whack_dummy);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo(
{
SPELL_WHACK_TRIGGERED,
SPELL_WHACK_ROOT,
});
}
void HandleDummy()
{
Unit* caster = GetCaster();
caster->CastSpell(caster, SPELL_WHACK_ROOT, true);
caster->CastSpell(caster, SPELL_WHACK_TRIGGERED);
}
void Register() override
{
AfterCast += SpellCastFn(spell_darkmoon_island_whack_dummy::HandleDummy);
}
};
class spell_darkmoon_island_whack : public SpellScript
{
PrepareSpellScript(spell_darkmoon_island_whack);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.remove_if(GnollHolderTargetSelector(GetCaster()));
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_darkmoon_island_whack::FilterTargets, EFFECT_0, TARGET_UNIT_CONE_ENTRY);
}
};
class spell_darkmoon_island_whack_a_gnoll : public AuraScript
{
PrepareAuraScript(spell_darkmoon_island_whack_a_gnoll);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo(
{
SPELL_WHACK_A_GNOLL_ACTION_BAR,
SPELL_WHACK_A_GNOLL_ACTION_BAR_REMOVED
});
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->RemoveAurasDueToSpell(GetSpellInfo()->Effects[EFFECT_1].TriggerSpell);
target->RemoveAurasDueToSpell(SPELL_WHACK_A_GNOLL_ACTION_BAR);
target->CastSpell(target, SPELL_WHACK_A_GNOLL_ACTION_BAR_REMOVED, true);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_darkmoon_island_whack_a_gnoll::OnRemove, EFFECT_0, SPELL_AURA_OVERRIDE_SPELLS, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_darkmoon_island_whack_a_gnoll_player_action_bar_removed : public SpellScript
{
PrepareSpellScript(spell_darkmoon_island_whack_a_gnoll_player_action_bar_removed);
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.remove_if(GnollHolderTargetSelector(GetCaster()));
}
void DespawnUnits(SpellEffIndex /*effIndex*/)
{
if (Creature* creature = GetHitCreature())
creature->DespawnOrUnsummon();
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_darkmoon_island_whack_a_gnoll_player_action_bar_removed::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_darkmoon_island_whack_a_gnoll_player_action_bar_removed::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_darkmoon_island_whack_a_gnoll_player_action_bar_removed::DespawnUnits, EFFECT_0, SPELL_EFFECT_DUMMY);
OnEffectHitTarget += SpellEffectFn(spell_darkmoon_island_whack_a_gnoll_player_action_bar_removed::DespawnUnits, EFFECT_1, SPELL_EFFECT_DUMMY);
}
};
void AddSC_holiday_spell_scripts()
{
// Love is in the Air
@@ -1800,4 +1991,10 @@ void AddSC_holiday_spell_scripts()
// Darkmoon Island
RegisterSpellScript(spell_darkmoon_island_deathmatch);
RegisterSpellScript(spell_darkmoon_island_ring_toss);
RegisterAuraScript(spell_darkmoon_island_whack_summon_aura);
RegisterSpellScript(spell_darkmoon_island_gnoll_aura_okay_to_hit);
RegisterSpellScript(spell_darkmoon_island_whack_dummy);
RegisterSpellScript(spell_darkmoon_island_whack);
RegisterAuraScript(spell_darkmoon_island_whack_a_gnoll);
RegisterSpellScript(spell_darkmoon_island_whack_a_gnoll_player_action_bar_removed);
}

View File

@@ -3147,6 +3147,119 @@ class npc_druid_treant : public CreatureScript
}
};
enum WhackAGnoll
{
NPC_DARKMOON_FAIRE_GNOLL = 54444,
NPC_DARKMOON_FAIRE_GNOLL_BABY = 54466,
NPC_DARKMOON_FAIRE_GNOLL_BONUS = 54549,
SPELL_WHACK = 102022,
SPELL_WHACK_A_GNOLL_SPAWN = 102136,
SPELL_WHACK_A_GNOLL_KILL_CREDIT = 101835,
SPELL_WRONG_WHACK = 101679,
SPELL_EXPLODE_SMALL = 101640,
SPELL_EXPLODE_BIG = 101655,
SOUND_ID_LAUGHTER = 11816,
SOUND_ID_SUBMERGE = 4791,
AI_ANIM_KIT_SUBMERGE = 529,
EVENT_REGULAR_SUBMERGE = 1,
EVENT_TRIGGERED_SUBMERGE
};
struct npc_darkmoon_island_gnoll : public ScriptedAI
{
npc_darkmoon_island_gnoll(Creature* creature) : ScriptedAI(creature)
{
Initialize();
}
void Initialize()
{
_hit = false;
}
void IsSummonedBy(Unit* /*summoner*/) override
{
DoCastSelf(SPELL_WHACK_A_GNOLL_SPAWN);
_events.ScheduleEvent(EVENT_REGULAR_SUBMERGE, 3s + 500ms);
}
void SpellHit(Unit* caster, SpellInfo const* spell) override
{
if (_hit)
return;
if (spell->Id == SPELL_WHACK)
{
_events.CancelEvent(EVENT_REGULAR_SUBMERGE);
switch (me->GetEntry())
{
case NPC_DARKMOON_FAIRE_GNOLL:
//DoCast(caster, SPELL_WHACK_A_GNOLL_KILL_CREDIT, true);
caster->CastSpell(caster, SPELL_WHACK_A_GNOLL_KILL_CREDIT, true);
DoCastSelf(SPELL_EXPLODE_SMALL);
me->KillSelf();
me->DespawnOrUnsummon(2s);
break;
case NPC_DARKMOON_FAIRE_GNOLL_BONUS:
for (uint8 i = 0; i < 3; i++)
caster->CastSpell(caster, SPELL_WHACK_A_GNOLL_KILL_CREDIT, true);
//DoCast(caster, SPELL_WHACK_A_GNOLL_KILL_CREDIT, true);
DoCastSelf(SPELL_EXPLODE_BIG);
me->KillSelf();
me->DespawnOrUnsummon(2s);
break;
case NPC_DARKMOON_FAIRE_GNOLL_BABY:
caster->CastSpell(caster, SPELL_WRONG_WHACK, true);
//DoCast(caster, SPELL_WRONG_WHACK, true);
if (Player* player = caster->ToPlayer())
me->PlayDirectSound(SOUND_ID_LAUGHTER, player);
_events.ScheduleEvent(EVENT_TRIGGERED_SUBMERGE, 3s + 600ms);
break;
default:
break;
}
_hit = true;
}
}
void UpdateAI(uint32 diff) override
{
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_REGULAR_SUBMERGE:
_hit = true;
me->SetAIAnimKitId(AI_ANIM_KIT_SUBMERGE);
if (TempSummon* summon = me->ToTempSummon())
if (Unit* summoner = summon->GetSummoner())
if (Player* player = summoner->ToPlayer())
me->PlayDirectSound(SOUND_ID_SUBMERGE, player);
me->DespawnOrUnsummon(1s + 500ms);
break;
case EVENT_TRIGGERED_SUBMERGE:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED_NEW);
me->DespawnOrUnsummon(2s + 500ms);
break;
default:
break;
}
}
}
private:
EventMap _events;
bool _hit;
};
void AddSC_npcs_special()
{
new npc_air_force_bots();
@@ -3176,4 +3289,5 @@ void AddSC_npcs_special()
new npc_bountiful_table();
new npc_mage_orb();
new npc_druid_treant();
RegisterCreatureAI(npc_darkmoon_island_gnoll);
}