summaryrefslogtreecommitdiff
path: root/src/scripts/Events/midsummer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripts/Events/midsummer.cpp')
-rw-r--r--src/scripts/Events/midsummer.cpp520
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