diff options
Diffstat (limited to 'src/scripts/Events/midsummer.cpp')
-rw-r--r-- | src/scripts/Events/midsummer.cpp | 520 |
1 files changed, 520 insertions, 0 deletions
diff --git a/src/scripts/Events/midsummer.cpp b/src/scripts/Events/midsummer.cpp new file mode 100644 index 0000000000..8fce374e70 --- /dev/null +++ b/src/scripts/Events/midsummer.cpp @@ -0,0 +1,520 @@ +// Scripted by Xinef + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Spell.h" +#include "SpellAuras.h" +#include "SpellScript.h" +#include "Player.h" + +enum eBonfire +{ + GO_MIDSUMMER_BONFIRE = 181288, + + SPELL_STAMP_OUT_BONFIRE = 45437, + SPELL_LIGHT_BONFIRE = 29831, +}; + +class go_midsummer_bonfire : public GameObjectScript +{ +public: + go_midsummer_bonfire() : GameObjectScript("go_midsummer_bonfire") { } + + bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 action) + { + player->CLOSE_GOSSIP_MENU(); + // we know that there is only one gossip. + player->CastSpell(player, SPELL_STAMP_OUT_BONFIRE, true); + return true; + } +}; + +class npc_midsummer_bonfire : public CreatureScript +{ + public: + npc_midsummer_bonfire() : CreatureScript("npc_midsummer_bonfire") { } + + struct npc_midsummer_bonfireAI : public ScriptedAI + { + npc_midsummer_bonfireAI(Creature* c) : ScriptedAI(c) + { + me->IsAIEnabled = true; + goGUID = 0; + if (GameObject* go = me->SummonGameObject(GO_MIDSUMMER_BONFIRE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0)) + { + goGUID = go->GetGUID(); + me->RemoveGameObject(go, false); + } + } + + uint64 goGUID; + + void SpellHit(Unit*, SpellInfo const* spellInfo) + { + if (!goGUID) + return; + + // Extinguish fire + if (spellInfo->Id == SPELL_STAMP_OUT_BONFIRE) + { + if (GameObject* go = ObjectAccessor::GetGameObject(*me, goGUID)) + go->SetPhaseMask(2, true); + } + else if (spellInfo->Id == SPELL_LIGHT_BONFIRE) + { + if (GameObject* go = ObjectAccessor::GetGameObject(*me, goGUID)) + { + go->SetPhaseMask(1, true); + go->SendCustomAnim(1); + } + } + + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_midsummer_bonfireAI(creature); + } +}; + +class npc_midsummer_torch_target : public CreatureScript +{ + public: + npc_midsummer_torch_target() : CreatureScript("npc_midsummer_torch_target") { } + + struct npc_midsummer_torch_targetAI : public ScriptedAI + { + npc_midsummer_torch_targetAI(Creature* c) : ScriptedAI(c) + { + teleTimer = 0; + startTimer = 1; + posVec.clear(); + playerGUID = 0; + me->CastSpell(me, 43313, true); + counter = 0; + maxCount = 0; + } + + uint64 playerGUID; + uint32 startTimer; + uint32 teleTimer; + std::vector<Position> posVec; + uint8 counter; + uint8 maxCount; + + void SetPlayerGUID(uint64 guid, uint8 cnt) + { + playerGUID = guid; + maxCount = cnt; + } + + bool CanBeSeen(Player const* seer) + { + return seer->GetGUID() == playerGUID; + } + + void SpellHit(Unit* caster, SpellInfo const* spellInfo) + { + if (posVec.empty()) + return; + // Triggered spell from torch + if (spellInfo->Id == 46054 && caster->GetTypeId() == TYPEID_PLAYER) + { + me->CastSpell(me, 45724, true); // hit visual anim + if (++counter >= maxCount) + { + caster->CastSpell(caster, (caster->ToPlayer()->GetTeamId() ? 46651 : 45719), true); // quest complete spell + me->DespawnOrUnsummon(1); + return; + } + + teleTimer = 1; + } + } + + void UpdateAI(uint32 diff) + { + if (startTimer) + { + startTimer += diff; + if (startTimer >= 200) + { + startTimer = 0; + FillPositions(); + SelectPosition(); + } + } + if (teleTimer) + { + teleTimer += diff; + if (teleTimer >= 750 && teleTimer < 10000) + { + teleTimer = 10000; + SelectPosition(); + } + else if (teleTimer >= 10500) + { + if (Player* plr = ObjectAccessor::GetPlayer(*me, playerGUID)) + plr->UpdateTriggerVisibility(); + + teleTimer = 0; + } + } + } + + void FillPositions() + { + std::list<GameObject*> gobjList; + me->GetGameObjectListWithEntryInGrid(gobjList, 187708 /*TORCH_GO*/, 30.0f); + for (std::list<GameObject*>::const_iterator itr = gobjList.begin(); itr != gobjList.end(); ++itr) + { + Position pos; + pos.Relocate(*itr); + posVec.push_back(pos); + } + } + + void SelectPosition() + { + if (posVec.empty()) + return; + int8 num = urand(0, posVec.size()-1); + Position pos; + pos.Relocate(posVec.at(num)); + me->m_last_notify_position.Relocate(0.0f, 0.0f, 0.0f); + me->m_last_notify_mstime = World::GetGameTimeMS() + 10000; + + me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_midsummer_torch_targetAI(creature); + } +}; + + +/////////////////////////////// +// SPELLS +/////////////////////////////// + +enum RibbonPole +{ + SPELL_RIBBON_POLE_CHANNEL_VISUAL = 29172, + SPELL_RIBBON_POLE_XP = 29175, + SPELL_RIBBON_POLE_FIREWORKS = 46971, + + NPC_RIBBON_POLE_DEBUG_TARGET = 17066, +}; + +class spell_midsummer_ribbon_pole : public SpellScriptLoader +{ +public: + spell_midsummer_ribbon_pole() : SpellScriptLoader("spell_midsummer_ribbon_pole") { } + + class spell_midsummer_ribbon_pole_AuraScript : public AuraScript + { + PrepareAuraScript(spell_midsummer_ribbon_pole_AuraScript) + + void HandleEffectPeriodic(AuraEffect const * aurEff) + { + PreventDefaultAction(); + if (Unit *target = GetTarget()) + { + Creature* cr = target->FindNearestCreature(NPC_RIBBON_POLE_DEBUG_TARGET, 10.0f); + if (!cr) + { + target->RemoveAura(SPELL_RIBBON_POLE_CHANNEL_VISUAL); + SetDuration(1); + return; + } + + if (Aura* aur = target->GetAura(SPELL_RIBBON_POLE_XP)) + aur->SetDuration(std::min(aur->GetDuration()+3*MINUTE*IN_MILLISECONDS, 60*MINUTE*IN_MILLISECONDS)); + else + target->CastSpell(target, SPELL_RIBBON_POLE_XP, true); + + if (roll_chance_i(5)) + { + cr->Relocate(cr->GetPositionX(), cr->GetPositionY(), cr->GetPositionZ()-6.5f); + cr->CastSpell(cr, SPELL_RIBBON_POLE_FIREWORKS, true); + cr->Relocate(cr->GetPositionX(), cr->GetPositionY(), cr->GetPositionZ()+6.5f); + } + + // Achievement + if ((time(NULL) - GetApplyTime()) > 60 && target->GetTypeId() == TYPEID_PLAYER) + target->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 58934, 0, target); + } + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* ar = GetTarget(); + ar->CastSpell(ar, SPELL_RIBBON_POLE_CHANNEL_VISUAL, true); + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_midsummer_ribbon_pole_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_midsummer_ribbon_pole_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_midsummer_ribbon_pole_AuraScript(); + } +}; + +class spell_midsummer_torch_quest : public SpellScriptLoader +{ +public: + spell_midsummer_torch_quest() : SpellScriptLoader("spell_midsummer_torch_quest") { } + + class spell_midsummer_torch_quest_AuraScript : public AuraScript + { + PrepareAuraScript(spell_midsummer_torch_quest_AuraScript) + + bool Load() + { + torchGUID = 0; + return true; + } + + uint64 torchGUID; + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* ar = GetTarget(); + if (Creature* cr = ar->SummonCreature(25535, ar->GetPositionX(), ar->GetPositionY(), ar->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 90000)) + { + torchGUID = cr->GetGUID(); + CAST_AI(npc_midsummer_torch_target::npc_midsummer_torch_targetAI, cr->AI())->SetPlayerGUID(ar->GetGUID(), (GetId() == 45716 ? 8 : 20)); + } + } + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* cr = ObjectAccessor::GetCreature(*GetTarget(), torchGUID)) + cr->DespawnOrUnsummon(1); + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_midsummer_torch_quest_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DETECT_AMORE, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_midsummer_torch_quest_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DETECT_AMORE, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_midsummer_torch_quest_AuraScript(); + } +}; + +enum flingTorch +{ + NPC_TORCH_TARGET = 26188, + + SPELL_FLING_TORCH = 45669, + SPELL_FLING_TORCH_DUMMY = 46747, + SPELL_MISSED_TORCH = 45676, + SPELL_TORCH_COUNTER = 45693, +}; + +class spell_midsummer_fling_torch : public SpellScriptLoader +{ + public: + spell_midsummer_fling_torch() : SpellScriptLoader("spell_midsummer_fling_torch") {} + + class spell_midsummer_fling_torch_SpellScript : public SpellScript + { + PrepareSpellScript(spell_midsummer_fling_torch_SpellScript); + + bool handled; + bool Load() { handled = false; return true; } + + void ThrowNextTorch(Unit* caster) + { + std::list<Creature*> crList; + caster->GetCreaturesWithEntryInRange(crList, 100.0f, NPC_TORCH_TARGET); + + uint8 rand = urand(0, crList.size()-1); + Position pos; + pos.Relocate(0.0f, 0.0f, 0.0f); + for (std::list<Creature*>::const_iterator itr = crList.begin(); itr != crList.end(); ++itr, --rand) + { + if (caster->GetDistance(*itr) < 5) + { + if (!rand) + rand++; + continue; + } + + if (!rand) + { + pos.Relocate(*itr); + break; + } + } + + // we have any pos + if (pos.GetPositionX()) + caster->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_FLING_TORCH, true); + } + + void HandleFinish() + { + Unit* caster = GetCaster(); + if (!caster || !caster->ToPlayer()) // caster cant be null, but meh :p + return; + + if (GetSpellInfo()->Id != SPELL_FLING_TORCH_DUMMY) + { + if (!handled) + if (const WorldLocation* loc = GetExplTargetDest()) + { + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_MISSED_TORCH, true); + caster->RemoveAurasDueToSpell(SPELL_TORCH_COUNTER); + } + return; + } + + ThrowNextTorch(caster); + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* target = GetHitPlayer()) + { + if (target->GetGUID() != GetCaster()->GetGUID()) + return; + + handled = true; + if (Aura* aur = target->GetAura(SPELL_TORCH_COUNTER)) + { + aur->ModStackAmount(1); + uint8 count = 4; + if (target->GetQuestStatus(target->GetTeamId() ? 11925 : 11924) == QUEST_STATUS_INCOMPLETE) // More Torch Catching quests + count = 10; + + if (aur->GetStackAmount() >= count) + { + //target->CastSpell(target, 46711, true); // Set Flag: all torch returning quests are complete + target->CastSpell(target, (target->GetTeamId() ? 46654 : 46081), true); // Quest completion + aur->SetDuration(1); + return; + } + } + else + target->CastSpell(target, SPELL_TORCH_COUNTER, true); + + ThrowNextTorch(GetCaster()); + } + } + + void Register() + { + AfterCast += SpellCastFn(spell_midsummer_fling_torch_SpellScript::HandleFinish); + if (m_scriptSpellId == 45671) + OnEffectHitTarget += SpellEffectFn(spell_midsummer_fling_torch_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_midsummer_fling_torch_SpellScript(); + } +}; + +enum eJuggle +{ + SPELL_JUGGLE_SELF = 45638, + SPELL_JUGGLE_SLOW = 45792, + SPELL_JUGGLE_MED = 45806, + SPELL_JUGGLE_FAST = 45816, + + SPELL_TORCH_CHECK = 45644, + SPELL_GIVE_TORCH = 45280, + QUEST_CHECK = 11937, +}; + +class spell_midsummer_juggling_torch : public SpellScriptLoader +{ + public: + spell_midsummer_juggling_torch() : SpellScriptLoader("spell_midsummer_juggling_torch") {} + + class spell_midsummer_juggling_torch_SpellScript : public SpellScript + { + PrepareSpellScript(spell_midsummer_juggling_torch_SpellScript); + + bool handled; + bool Load() { handled = false; return true; } + void HandleFinish() + { + Unit* caster = GetCaster(); + if (!caster || caster->GetTypeId() != TYPEID_PLAYER) + return; + + if (const WorldLocation* loc = GetExplTargetDest()) + { + if (loc->GetExactDist(caster) < 3.0f) + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_SELF, true); + else if (loc->GetExactDist(caster) < 10.0f) + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_SLOW, true); + else if (loc->GetExactDist(caster) < 25.0f) + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_MED, true); + else + caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_FAST, true); + } + else + caster->CastSpell(caster, SPELL_JUGGLE_SELF, true); + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + Unit* caster = GetCaster(); + if (!caster || caster->GetTypeId() != TYPEID_PLAYER) + return; + + if (Player* target = GetHitPlayer()) + if (!handled && target->GetQuestRewardStatus(target->GetTeamId() == TEAM_ALLIANCE ? 11657 : 11923)) + { + handled = true; + caster->CastSpell(target, SPELL_GIVE_TORCH, true); + } + } + + void Register() + { + if (m_scriptSpellId == SPELL_TORCH_CHECK) + OnEffectHitTarget += SpellEffectFn(spell_midsummer_juggling_torch_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + else + AfterCast += SpellCastFn(spell_midsummer_juggling_torch_SpellScript::HandleFinish); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_midsummer_juggling_torch_SpellScript(); + } +}; + +void AddSC_event_midsummer_scripts() +{ + // NPCs + new go_midsummer_bonfire(); + new npc_midsummer_bonfire(); + new npc_midsummer_torch_target(); + + // Spells + new spell_midsummer_ribbon_pole(); + new spell_midsummer_torch_quest(); + new spell_midsummer_fling_torch(); + new spell_midsummer_juggling_torch(); +}
\ No newline at end of file |