/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#include "AreaDefines.h"
#include "CreatureScript.h"
#include "GameEventMgr.h"
#include "GameObjectScript.h"
#include "GameTime.h"
#include "Player.h"
#include "PlayerScript.h"
#include "ScriptedCreature.h"
#include "Spell.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include
enum eBonfire
{
GO_MIDSUMMER_BONFIRE_SPELL_FOCUS = 181371,
GO_MIDSUMMER_BONFIRE_CAMPFIRE_SPELL_FOCUS = 181377,
GO_AHUNE_BONFIRE = 188073,
SPELL_MIDSUMMER_BONFIRE_BUNNIES_2 = 29114,
SPELL_STAMP_OUT_BONFIRE = 45437,
SPELL_STAMP_OUT_BONFIRE_ART_KIT = 46903,
SPELL_TOSS_FUEL_ON_BONFIRE = 28806,
SPELL_LIGHT_BONFIRE_ART_KIT = 46904,
SPELL_BONFIRES_BLESSING = 45444,
BONFIRE_TYPE_NONE = 0,
BONFIRE_TYPE_ALLIANCE = 1,
BONFIRE_TYPE_HORDE = 2,
BONFIRE_TYPE_CITY = 3,
BONFIRE_TYPE_AHUNE = 4,
COUNT_GO_BONFIRE_ALLIANCE = 40,
COUNT_GO_BONFIRE_HORDE = 38,
COUNT_GO_BONFIRE_CITY = 9,
};
static bool BonfireStampedOutState[COUNT_GO_BONFIRE_ALLIANCE + COUNT_GO_BONFIRE_HORDE];
// ,
const std::map, bool*> BonfireStateStore = {
{ { MAP_EASTERN_KINGDOMS, AREA_DUN_MOROGH, TEAM_ALLIANCE }, &BonfireStampedOutState[0] },
{ { MAP_EASTERN_KINGDOMS, AREA_BADLANDS, TEAM_HORDE }, &BonfireStampedOutState[1] },
{ { MAP_EASTERN_KINGDOMS, AREA_BLASTED_LANDS, TEAM_ALLIANCE }, &BonfireStampedOutState[2] },
{ { MAP_EASTERN_KINGDOMS, AREA_SWAMP_OF_SORROWS, TEAM_HORDE }, &BonfireStampedOutState[3] },
{ { MAP_EASTERN_KINGDOMS, AREA_DUSKWOOD, TEAM_ALLIANCE }, &BonfireStampedOutState[4] },
{ { MAP_EASTERN_KINGDOMS, AREA_WETLANDS, TEAM_ALLIANCE }, &BonfireStampedOutState[5] },
{ { MAP_EASTERN_KINGDOMS, AREA_ELWYNN_FOREST, TEAM_ALLIANCE }, &BonfireStampedOutState[6] },
{ { MAP_EASTERN_KINGDOMS, AREA_WESTERN_PLAGUELANDS, TEAM_ALLIANCE }, &BonfireStampedOutState[7] },
{ { MAP_EASTERN_KINGDOMS, AREA_STRANGLETHORN_VALE, TEAM_ALLIANCE }, &BonfireStampedOutState[8] },
{ { MAP_EASTERN_KINGDOMS, AREA_STRANGLETHORN_VALE, TEAM_HORDE }, &BonfireStampedOutState[9] },
{ { MAP_EASTERN_KINGDOMS, AREA_LOCH_MODAN, TEAM_ALLIANCE }, &BonfireStampedOutState[10] },
{ { MAP_EASTERN_KINGDOMS, AREA_WESTFALL, TEAM_ALLIANCE }, &BonfireStampedOutState[11] },
{ { MAP_EASTERN_KINGDOMS, AREA_REDRIDGE_MOUNTAINS, TEAM_ALLIANCE }, &BonfireStampedOutState[12] },
{ { MAP_EASTERN_KINGDOMS, AREA_ARATHI_HIGHLANDS, TEAM_ALLIANCE }, &BonfireStampedOutState[13] },
{ { MAP_EASTERN_KINGDOMS, AREA_ARATHI_HIGHLANDS, TEAM_HORDE }, &BonfireStampedOutState[14] },
{ { MAP_EASTERN_KINGDOMS, AREA_BURNING_STEPPES, TEAM_ALLIANCE }, &BonfireStampedOutState[15] },
{ { MAP_EASTERN_KINGDOMS, AREA_BURNING_STEPPES, TEAM_HORDE }, &BonfireStampedOutState[16] },
{ { MAP_EASTERN_KINGDOMS, AREA_THE_HINTERLANDS, TEAM_ALLIANCE }, &BonfireStampedOutState[17] },
{ { MAP_EASTERN_KINGDOMS, AREA_THE_HINTERLANDS, TEAM_HORDE }, &BonfireStampedOutState[18] },
{ { MAP_EASTERN_KINGDOMS, AREA_TIRISFAL_GLADES, TEAM_HORDE }, &BonfireStampedOutState[19] },
{ { MAP_EASTERN_KINGDOMS, AREA_SILVERPINE_FOREST, TEAM_HORDE }, &BonfireStampedOutState[20] },
{ { MAP_EASTERN_KINGDOMS, AREA_HILLSBRAD_FOOTHILLS, TEAM_ALLIANCE }, &BonfireStampedOutState[21] },
{ { MAP_EASTERN_KINGDOMS, AREA_HILLSBRAD_FOOTHILLS, TEAM_HORDE }, &BonfireStampedOutState[22] },
{ { MAP_KALIMDOR, AREA_DUROTAR, TEAM_HORDE }, &BonfireStampedOutState[23] },
{ { MAP_KALIMDOR, AREA_DUSTWALLOW_MARSH, TEAM_ALLIANCE }, &BonfireStampedOutState[24] },
{ { MAP_KALIMDOR, AREA_DUSTWALLOW_MARSH, TEAM_HORDE }, &BonfireStampedOutState[25] },
{ { MAP_KALIMDOR, AREA_THE_BARRENS, TEAM_HORDE }, &BonfireStampedOutState[26] },
{ { MAP_KALIMDOR, AREA_TELDRASSIL, TEAM_ALLIANCE }, &BonfireStampedOutState[27] },
{ { MAP_KALIMDOR, AREA_DARKSHORE, TEAM_ALLIANCE }, &BonfireStampedOutState[28] },
{ { MAP_KALIMDOR, AREA_MULGORE, TEAM_HORDE }, &BonfireStampedOutState[29] },
{ { MAP_KALIMDOR, AREA_ASHENVALE, TEAM_ALLIANCE }, &BonfireStampedOutState[30] },
{ { MAP_KALIMDOR, AREA_ASHENVALE, TEAM_HORDE }, &BonfireStampedOutState[31] },
{ { MAP_KALIMDOR, AREA_FERALAS, TEAM_ALLIANCE }, &BonfireStampedOutState[32] },
{ { MAP_KALIMDOR, AREA_FERALAS, TEAM_HORDE }, &BonfireStampedOutState[33] },
{ { MAP_KALIMDOR, AREA_THOUSAND_NEEDLES, TEAM_HORDE }, &BonfireStampedOutState[34] },
{ { MAP_KALIMDOR, AREA_DESOLACE, TEAM_ALLIANCE }, &BonfireStampedOutState[35] },
{ { MAP_KALIMDOR, AREA_DESOLACE, TEAM_HORDE }, &BonfireStampedOutState[36] },
{ { MAP_KALIMDOR, AREA_STONETALON_MOUNTAINS, TEAM_HORDE }, &BonfireStampedOutState[37] },
{ { MAP_KALIMDOR, AREA_TANARIS, TEAM_ALLIANCE }, &BonfireStampedOutState[38] },
{ { MAP_KALIMDOR, AREA_TANARIS, TEAM_HORDE }, &BonfireStampedOutState[39] },
{ { MAP_KALIMDOR, AREA_WINTERSPRING, TEAM_ALLIANCE }, &BonfireStampedOutState[40] },
{ { MAP_KALIMDOR, AREA_WINTERSPRING, TEAM_HORDE }, &BonfireStampedOutState[41] },
{ { MAP_KALIMDOR, AREA_SILITHUS, TEAM_ALLIANCE }, &BonfireStampedOutState[42] },
{ { MAP_KALIMDOR, AREA_SILITHUS, TEAM_HORDE }, &BonfireStampedOutState[43] },
{ { MAP_OUTLAND, AREA_EVERSONG_WOODS, TEAM_HORDE }, &BonfireStampedOutState[44] },
{ { MAP_OUTLAND, AREA_GHOSTLANDS, TEAM_HORDE }, &BonfireStampedOutState[45] },
{ { MAP_OUTLAND, AREA_HELLFIRE_PENINSULA, TEAM_ALLIANCE }, &BonfireStampedOutState[46] },
{ { MAP_OUTLAND, AREA_HELLFIRE_PENINSULA, TEAM_HORDE }, &BonfireStampedOutState[47] },
{ { MAP_OUTLAND, AREA_NAGRAND, TEAM_ALLIANCE }, &BonfireStampedOutState[48] },
{ { MAP_OUTLAND, AREA_NAGRAND, TEAM_HORDE }, &BonfireStampedOutState[49] },
{ { MAP_OUTLAND, AREA_TEROKKAR_FOREST, TEAM_ALLIANCE }, &BonfireStampedOutState[50] },
{ { MAP_OUTLAND, AREA_TEROKKAR_FOREST, TEAM_HORDE }, &BonfireStampedOutState[51] },
{ { MAP_OUTLAND, AREA_SHADOWMOON_VALLEY, TEAM_ALLIANCE }, &BonfireStampedOutState[52] },
{ { MAP_OUTLAND, AREA_SHADOWMOON_VALLEY, TEAM_HORDE }, &BonfireStampedOutState[53] },
{ { MAP_OUTLAND, AREA_ZANGARMARSH, TEAM_ALLIANCE }, &BonfireStampedOutState[54] },
{ { MAP_OUTLAND, AREA_ZANGARMARSH, TEAM_HORDE }, &BonfireStampedOutState[55] },
{ { MAP_OUTLAND, AREA_BLADES_EDGE_MOUNTAINS, TEAM_ALLIANCE }, &BonfireStampedOutState[56] },
{ { MAP_OUTLAND, AREA_BLADES_EDGE_MOUNTAINS, TEAM_HORDE }, &BonfireStampedOutState[57] },
{ { MAP_OUTLAND, AREA_NETHERSTORM, TEAM_ALLIANCE }, &BonfireStampedOutState[58] },
{ { MAP_OUTLAND, AREA_NETHERSTORM, TEAM_HORDE }, &BonfireStampedOutState[59] },
{ { MAP_OUTLAND, AREA_AZUREMYST_ISLE, TEAM_ALLIANCE }, &BonfireStampedOutState[60] },
{ { MAP_OUTLAND, AREA_BLOODMYST_ISLE, TEAM_ALLIANCE }, &BonfireStampedOutState[61] },
{ { MAP_NORTHREND, AREA_DRAGONBLIGHT, TEAM_ALLIANCE }, &BonfireStampedOutState[62] },
{ { MAP_NORTHREND, AREA_DRAGONBLIGHT, TEAM_HORDE }, &BonfireStampedOutState[63] },
{ { MAP_NORTHREND, AREA_ZUL_DRAK, TEAM_ALLIANCE }, &BonfireStampedOutState[64] },
{ { MAP_NORTHREND, AREA_ZUL_DRAK, TEAM_HORDE }, &BonfireStampedOutState[65] },
{ { MAP_NORTHREND, AREA_THE_STORM_PEAKS, TEAM_ALLIANCE }, &BonfireStampedOutState[66] },
{ { MAP_NORTHREND, AREA_THE_STORM_PEAKS, TEAM_HORDE }, &BonfireStampedOutState[67] },
{ { MAP_NORTHREND, AREA_GRIZZLY_HILLS, TEAM_ALLIANCE }, &BonfireStampedOutState[68] },
{ { MAP_NORTHREND, AREA_GRIZZLY_HILLS, TEAM_HORDE }, &BonfireStampedOutState[69] },
{ { MAP_NORTHREND, AREA_HOWLING_FJORD, TEAM_ALLIANCE }, &BonfireStampedOutState[70] },
{ { MAP_NORTHREND, AREA_HOWLING_FJORD, TEAM_HORDE }, &BonfireStampedOutState[71] },
{ { MAP_NORTHREND, AREA_CRYSTALSONG_FOREST, TEAM_ALLIANCE }, &BonfireStampedOutState[72] },
{ { MAP_NORTHREND, AREA_CRYSTALSONG_FOREST, TEAM_HORDE }, &BonfireStampedOutState[73] },
{ { MAP_NORTHREND, AREA_BOREAN_TUNDRA, TEAM_ALLIANCE }, &BonfireStampedOutState[74] },
{ { MAP_NORTHREND, AREA_BOREAN_TUNDRA, TEAM_HORDE }, &BonfireStampedOutState[75] },
{ { MAP_NORTHREND, AREA_SHOLAZAR_BASIN, TEAM_ALLIANCE }, &BonfireStampedOutState[76] },
{ { MAP_NORTHREND, AREA_SHOLAZAR_BASIN, TEAM_HORDE }, &BonfireStampedOutState[77] },
};
uint32 const GoBonfireAlliance[COUNT_GO_BONFIRE_ALLIANCE] = { 187564, 187914, 187916, 187917, 187919, 187920, 187921, 187922, 187923, 187924, 187925, 187926, 187927, 187928, 187929, 187930, 187931, 187932, 187933, 187934, 187935, 187936, 187937, 187938, 187939, 187940, 187941, 187942, 187943, 187944, 187945, 187946, 194032, 194035, 194036, 194038, 194040, 194044, 194045, 194049 };
uint32 const GoBonfireHorde[COUNT_GO_BONFIRE_HORDE] = { 187559, 187947, 187948, 187949, 187950, 187951, 187952, 187953, 187954, 187955, 187956, 187957, 187958, 187959, 187960, 187961, 187962, 187963, 187964, 187965, 187966, 187967, 187968, 187969, 187970, 187971, 187972, 187973, 187974, 187975, 194033, 194034, 194037, 194039, 194042, 194043, 194046, 194048 };
uint32 const GoBonfireCity[COUNT_GO_BONFIRE_CITY] = { 181332, 181333, 181334, 181335, 181336, 181337, 188128, 188129, 188352 };
class MidsummerPlayerScript : public PlayerScript
{
public:
MidsummerPlayerScript() : PlayerScript("MidsummerPlayerScript", {PLAYERHOOK_ON_UPDATE_ZONE})
{
}
void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 /*newArea*/) override
{
if (!IsHolidayActive(HOLIDAY_FIRE_FESTIVAL))
return;
auto itr = BonfireStateStore.find(std::make_tuple(player->GetMapId(), newZone, player->GetTeamId()));
if ((itr != BonfireStateStore.end()) && (itr->second))
{
if (!(*(itr->second)))
{
if (!player->HasAura(SPELL_BONFIRES_BLESSING))
player->CastSpell(player, SPELL_BONFIRES_BLESSING, true);
return;
}
}
player->RemoveAurasDueToSpell(SPELL_BONFIRES_BLESSING);
}
};
struct npc_midsummer_bonfire : public ScriptedAI
{
npc_midsummer_bonfire(Creature* creature) : ScriptedAI(creature)
{
// Midsummer Bonfire Spawn Trap also spawns this NPC (currently unwanted)
if (me->ToTempSummon())
me->DespawnOrUnsummon();
_isStampedOut = nullptr;
_teamId = TEAM_NEUTRAL;
_type = BONFIRE_TYPE_NONE;
_spellFocus = nullptr;
if (!IsHolidayActive(HOLIDAY_FIRE_FESTIVAL))
return;
scheduler.Schedule(420ms, [this](TaskContext context)
{
if (!InitBonfire())
context.Repeat();
});
}
void Ignite()
{
if (_isStampedOut)
*_isStampedOut = false;
if (!_spellFocus)
{
DoCastSelf(SPELL_MIDSUMMER_BONFIRE_BUNNIES_2, true);
if ((_spellFocus = me->FindNearestGameObject(GO_MIDSUMMER_BONFIRE_CAMPFIRE_SPELL_FOCUS, 10.0f)))
me->AddGameObject(_spellFocus);
}
switch (_type)
{
case BONFIRE_TYPE_ALLIANCE:
case BONFIRE_TYPE_HORDE:
DoCastSelf(SPELL_LIGHT_BONFIRE_ART_KIT, true);
UpdateBonfireBlessingBuffs();
break;
case BONFIRE_TYPE_AHUNE:
if (_bonfire)
_bonfire->SetGoState(GO_STATE_ACTIVE);
break;
default:
break;
}
}
void StampOut()
{
switch (_type)
{
case BONFIRE_TYPE_ALLIANCE:
case BONFIRE_TYPE_HORDE:
if (_isStampedOut)
*_isStampedOut = true;
if (_spellFocus)
{
_spellFocus->DespawnOrUnsummon();
_spellFocus->AddObjectToRemoveList();
_spellFocus = nullptr;
}
DoCastSelf(SPELL_STAMP_OUT_BONFIRE_ART_KIT, true);
UpdateBonfireBlessingBuffs();
break;
default:
break;
}
}
void UpdateBonfireBlessingBuffs()
{
if ((_type != BONFIRE_TYPE_ALLIANCE) && (_type != BONFIRE_TYPE_HORDE))
return;
me->GetMap()->DoForAllPlayers([&](Player* p)
{
if ((p->GetZoneId() == me->GetZoneId()) && (p->GetTeamId() == _teamId))
{
if (_isStampedOut)
{
if (*_isStampedOut)
p->RemoveAurasDueToSpell(SPELL_BONFIRES_BLESSING);
else
{
if (!p->HasAura(SPELL_BONFIRES_BLESSING))
p->CastSpell(p, SPELL_BONFIRES_BLESSING, true);
}
}
}
});
}
bool InitBonfire()
{
_type = BONFIRE_TYPE_NONE;
_teamId = TEAM_NEUTRAL;
for (uint32 i = 0; (i < COUNT_GO_BONFIRE_ALLIANCE) && (_type == BONFIRE_TYPE_NONE); i++)
{
if ((_bonfire = me->FindNearestGameObject(GoBonfireAlliance[i], 10.0f)))
{
_type = BONFIRE_TYPE_ALLIANCE;
_teamId = TEAM_ALLIANCE;
}
}
for (uint32 i = 0; (i < COUNT_GO_BONFIRE_HORDE) && (_type == BONFIRE_TYPE_NONE); i++)
{
if ((_bonfire = me->FindNearestGameObject(GoBonfireHorde[i], 10.0f)))
{
_type = BONFIRE_TYPE_HORDE;
_teamId = TEAM_HORDE;
}
}
for (uint32 i = 0; (i < COUNT_GO_BONFIRE_CITY) && (_type == BONFIRE_TYPE_NONE); i++)
{
if ((_bonfire = me->FindNearestGameObject(GoBonfireCity[i], 10.0f)))
{
_type = BONFIRE_TYPE_CITY;
Ignite();
return true;
}
}
if ((_type == BONFIRE_TYPE_NONE) && (_bonfire = me->FindNearestGameObject(GO_AHUNE_BONFIRE, 10.0f)))
{
_type = BONFIRE_TYPE_AHUNE;
return true;
}
if (_type == BONFIRE_TYPE_NONE)
return false;
auto itr = BonfireStateStore.find(std::make_tuple(me->GetMapId(), me->GetZoneId(), _teamId));
if ((itr != BonfireStateStore.end()) && (itr->second))
_isStampedOut = itr->second;
else
LOG_ERROR("scripts.midsummer", "NPC {} (GUID{}) in map {}, zone {} with teamId {} can't locate its entry within BonfireStateStore", me->GetGUID().GetEntry(), me->GetSpawnId(), me->GetMapId(), me->GetZoneId(), _teamId);
Ignite();
return true;
}
void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
{
if (!caster->IsPlayer())
return;
switch (spellInfo->Id)
{
case SPELL_TOSS_FUEL_ON_BONFIRE:
{
Ignite();
break;
}
case SPELL_STAMP_OUT_BONFIRE:
{
StampOut();
// desecrating other faction's bonfire flags player for PVP
caster->SetPvP(true);
break;
}
default:
break;
}
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
}
private:
bool* _isStampedOut;
TeamId _teamId;
uint8 _type;
GameObject* _spellFocus;
GameObject* _bonfire;
};
struct npc_midsummer_bonfire_despawner : public ScriptedAI
{
npc_midsummer_bonfire_despawner(Creature* creature) : ScriptedAI(creature)
{
std::list gobjList;
me->GetGameObjectListWithEntryInGrid(gobjList, GO_MIDSUMMER_BONFIRE_SPELL_FOCUS, 10.0f);
for (std::list::const_iterator itr = gobjList.begin(); itr != gobjList.end(); ++itr)
{
// spawnID is 0 for temp spawns
if (0 == (*itr)->GetSpawnId())
{
(*itr)->DespawnOrUnsummon();
(*itr)->AddObjectToRemoveList();
}
}
me->DespawnOrUnsummon();
}
};
enum torchToss
{
SPELL_TORCH_TOSSING_TRAINING_SUCCESS_A = 45719,
SPELL_TORCH_TOSSING_TRAINING_SUCCESS_H = 46651,
SPELL_TORCH_TOSSING_TRAINING = 45716,
SPELL_TORCH_TOSSING_PRACTICE = 46630,
SPELL_REMOVE_TORCHES = 46074,
};
///////////////////////////////
// SPELLS
///////////////////////////////
class spell_fire_festival_fortitude : public SpellScript
{
PrepareSpellScript(spell_fire_festival_fortitude)
void SelectTargets(std::list& targets)
{
targets.clear();
GetCaster()->GetMap()->DoForAllPlayers([&](Player* p)
{
if (p->GetZoneId() == GetCaster()->GetZoneId())
targets.push_back(p);
});
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_fire_festival_fortitude::SelectTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
class spell_bonfires_blessing : public AuraScript
{
PrepareAuraScript(spell_bonfires_blessing)
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_BONFIRES_BLESSING });
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (!IsHolidayActive(HOLIDAY_FIRE_FESTIVAL))
{
if (Unit* target = GetTarget())
target->RemoveAurasDueToSpell(SPELL_BONFIRES_BLESSING);
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_bonfires_blessing::OnApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
enum CrabDisguise
{
SPELL_CRAB_DISGUISE = 46337,
SPELL_APPLY_DIGUISE = 34804,
SPELL_FADE_DIGUISE = 47693,
};
class spell_gen_crab_disguise : public AuraScript
{
PrepareAuraScript(spell_gen_crab_disguise);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_APPLY_DIGUISE, SPELL_FADE_DIGUISE });
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
{
caster->CastSpell(caster, SPELL_APPLY_DIGUISE, true);
caster->SetFaction(FACTION_BLACKFATHOM);
}
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
{
caster->CastSpell(caster, SPELL_FADE_DIGUISE, true);
caster->RestoreFaction();
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_crab_disguise::OnApply, EFFECT_0, SPELL_AURA_FORCE_REACTION, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_gen_crab_disguise::OnRemove, EFFECT_0, SPELL_AURA_FORCE_REACTION, AURA_EFFECT_HANDLE_REAL);
}
};
enum RibbonPole
{
GO_RIBBON_POLE = 181605,
SPELL_RIBBON_POLE_CHANNEL_VISUAL = 29172,
SPELL_RIBBON_POLE_CHANNEL_VISUAL_2 = 29531,
SPELL_TEST_RIBBON_POLE_CHANNEL_BLUE = 29705,
SPELL_TEST_RIBBON_POLE_CHANNEL_RED = 29726,
SPELL_TEST_RIBBON_POLE_CHANNEL_PINK = 29727,
// player spinning/rorating around himself
SPELL_RIBBON_POLE_PERIODIC_VISUAL = 45406,
// spew lava trails
SPELL_RIBBON_POLE_FIRE_SPIRAL_VISUAL= 45421,
// blue fire ring, duration 5s
SPELL_FLAME_RING = 46842,
// red fire ring, duration 5s
SPELL_FLAME_PATCH = 46836,
// single firework explosion
SPELL_RIBBON_POLE_FIREWORK = 46847,
SPELL_RIBBON_POLE_GROUND_FLOWER = 46969,
SPELL_RIBBON_POLE_XP = 29175,
NPC_RIBBON_POLE_DEBUG_TARGET = 17066,
NPC_GROUND_FLOWER = 25518,
NPC_BIG_DANCING_FLAMES = 26267,
NPC_RIBBON_POLE_FIRE_SPIRAL_BUNNY = 25303,
// dancing players count
THRESHOLD_FLAME_CIRCLE = 1,
THRESHOLD_FIREWORK = 2,
THRESHOLD_FIREWORK_3 = 3,
THRESHOLD_FIREWORK_5 = 5,
THRESHOLD_GROUND_FLOWERS = 3,
THRESHOLD_SPEW_LAVA = 6,
THRESHOLD_DANCING_FLAMES = 7,
MAX_COUNT_GROUND_FLOWERS = 3,
MAX_COUNT_SPEW_LAVA_TARGETS = 2,
MAX_COUNT_DANCING_FLAMES = 4,
};
struct npc_midsummer_ribbon_pole_target : public ScriptedAI
{
npc_midsummer_ribbon_pole_target(Creature* creature) : ScriptedAI(creature)
{
// ribbonPole trap also spawns this NPC (currently unwanted)
if (me->ToTempSummon())
me->DespawnOrUnsummon();
_ribbonPole = nullptr;
_bunny = nullptr;
_dancerList.clear();
LocateRibbonPole();
SpawnFireSpiralBunny();
scheduler.Schedule(1s, [this](TaskContext context)
{
DoCleanupChecks();
context.Repeat();
})
.Schedule(5s, [this](TaskContext context)
{
DoFlameCircleChecks();
context.Repeat();
})
.Schedule(15s, [this](TaskContext context)
{
DoFireworkChecks();
context.Repeat();
})
.Schedule(10s, [this](TaskContext context)
{
DoGroundFlowerChecks();
context.Repeat();
})
.Schedule(10s, [this](TaskContext context)
{
DoSpewLavaChecks();
context.Repeat();
})
.Schedule(15s, [this](TaskContext context)
{
DoDancingFLameChecks();
context.Repeat();
});
}
void SpellHit(Unit* caster, SpellInfo const* spell) override
{
Player* dancer = caster->ToPlayer();
if (!dancer)
return;
switch (spell->Id)
{
case SPELL_TEST_RIBBON_POLE_CHANNEL_BLUE:
case SPELL_TEST_RIBBON_POLE_CHANNEL_RED:
case SPELL_TEST_RIBBON_POLE_CHANNEL_PINK:
break;
default:
return;
}
// prevent duplicates
if (std::find(_dancerList.begin(), _dancerList.end(), dancer->GetGUID()) != _dancerList.end())
return;
_dancerList.push_back(dancer->GetGUID());
}
void LocateRibbonPole()
{
scheduler.Schedule(420ms, [this](TaskContext context)
{
_ribbonPole = me->FindNearestGameObject(GO_RIBBON_POLE, 10.0f);
if (!_ribbonPole)
context.Repeat(420ms);
});
}
void SpawnFireSpiralBunny()
{
_bunny = me->FindNearestCreature(NPC_RIBBON_POLE_FIRE_SPIRAL_BUNNY, 10.0f);
if (!_bunny)
_bunny = DoSpawnCreature(NPC_RIBBON_POLE_FIRE_SPIRAL_BUNNY, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN, 0);
}
void DoCleanupChecks()
{
if (_dancerList.empty())
return;
// remove non-dancing players from list
std::erase_if(_dancerList, [this](ObjectGuid dancerGUID)
{
Player* dancer = ObjectAccessor::GetPlayer(*me, dancerGUID);
return !dancer || !dancer->HasAura(SPELL_RIBBON_POLE_PERIODIC_VISUAL);
});
}
void DoFlameCircleChecks()
{
if (!_ribbonPole)
return;
if (_dancerList.size() >= THRESHOLD_FLAME_CIRCLE)
{
// random blue / red circle
if (urand(0, 1))
_ribbonPole->CastSpell(me, SPELL_FLAME_RING);
else
_ribbonPole->CastSpell(me, SPELL_FLAME_PATCH);
}
}
void DoFireworkChecks()
{
if (!_bunny)
return;
if (_dancerList.size() >= THRESHOLD_FIREWORK)
{
_bunny->CastSpell(nullptr, SPELL_RIBBON_POLE_FIREWORK);
}
if (_dancerList.size() >= THRESHOLD_FIREWORK_3)
{
scheduler.Schedule(500ms, [this](TaskContext /*context*/)
{
_bunny->CastSpell(nullptr, SPELL_RIBBON_POLE_FIREWORK);
})
.Schedule(1s, [this](TaskContext /*context*/)
{
_bunny->CastSpell(nullptr, SPELL_RIBBON_POLE_FIREWORK);
});
}
if (_dancerList.size() >= THRESHOLD_FIREWORK_5)
{
scheduler.Schedule(1500ms, [this](TaskContext /*context*/)
{
_bunny->CastSpell(nullptr, SPELL_RIBBON_POLE_FIREWORK);
})
.Schedule(2s, [this](TaskContext /*context*/)
{
_bunny->CastSpell(nullptr, SPELL_RIBBON_POLE_FIREWORK);
});
}
}
void DoGroundFlowerChecks()
{
if (!_bunny)
return;
if (_dancerList.size() >= THRESHOLD_GROUND_FLOWERS)
{
std::list crList;
me->GetCreaturesWithEntryInRange(crList, 20.0f, NPC_GROUND_FLOWER);
if (crList.size() < MAX_COUNT_GROUND_FLOWERS)
_bunny->CastSpell(nullptr, SPELL_RIBBON_POLE_GROUND_FLOWER);
}
}
void DoSpewLavaChecks()
{
if (!_bunny)
return;
if (_dancerList.size() >= THRESHOLD_SPEW_LAVA)
{
if (!_dancerList.empty())
{
Acore::Containers::RandomShuffle(_dancerList);
for (uint8 i = 0; (i < MAX_COUNT_SPEW_LAVA_TARGETS) && (i < _dancerList.size()); i++)
{
if (Player* dancerTarget = ObjectAccessor::GetPlayer(*me, _dancerList[i]))
{
Creature* fireSpiralBunny = dancerTarget->SummonCreature(NPC_RIBBON_POLE_FIRE_SPIRAL_BUNNY, dancerTarget->GetPositionX(), dancerTarget->GetPositionY(), dancerTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
if (fireSpiralBunny)
fireSpiralBunny->CastSpell(_bunny, SPELL_RIBBON_POLE_FIRE_SPIRAL_VISUAL, true);
}
}
}
}
}
void DoDancingFLameChecks()
{
if (_dancerList.size() >= THRESHOLD_DANCING_FLAMES)
{
std::list crList;
me->GetCreaturesWithEntryInRange(crList, 20.0f, NPC_BIG_DANCING_FLAMES);
if (crList.size() < MAX_COUNT_DANCING_FLAMES)
{
float spawnDist = 12.0f;
float angle = rand_norm() * 2 * M_PI;
DoSpawnCreature(NPC_BIG_DANCING_FLAMES, spawnDist * cos(angle), spawnDist * std::sin(angle), 0, angle + M_PI, TEMPSUMMON_TIMED_DESPAWN, 60000);
}
}
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
}
private:
GuidVector _dancerList;
GameObject* _ribbonPole;
Creature* _bunny;
};
class spell_midsummer_ribbon_pole_firework : public SpellScript
{
PrepareSpellScript(spell_midsummer_ribbon_pole_firework)
void ModDestHeight(SpellDestination& dest)
{
Position const offset = { 0.0f, 0.0f, 20.0f , 0.0f };
dest.RelocateOffset(offset);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_midsummer_ribbon_pole_firework::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_RANDOM);
}
};
class spell_midsummer_ribbon_pole : public AuraScript
{
PrepareAuraScript(spell_midsummer_ribbon_pole)
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo(
{
SPELL_RIBBON_POLE_XP,
SPELL_TEST_RIBBON_POLE_CHANNEL_BLUE,
SPELL_TEST_RIBBON_POLE_CHANNEL_RED,
SPELL_TEST_RIBBON_POLE_CHANNEL_PINK
});
}
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_TEST_RIBBON_POLE_CHANNEL_BLUE);
target->RemoveAura(SPELL_TEST_RIBBON_POLE_CHANNEL_RED);
target->RemoveAura(SPELL_TEST_RIBBON_POLE_CHANNEL_PINK);
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);
// Achievement
if ((GameTime::GetGameTime().count() - GetApplyTime()) > 60 && target->IsPlayer())
target->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 58934, 0, target);
}
// Achievement
if ((time(nullptr) - GetApplyTime()) > 60 && target->IsPlayer())
target->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 58934, 0, target);
}
}
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* ar = GetTarget();
switch (urand(0, 2))
{
case 0:
ar->CastSpell(ar, SPELL_TEST_RIBBON_POLE_CHANNEL_BLUE, true);
break;
case 1:
ar->CastSpell(ar, SPELL_TEST_RIBBON_POLE_CHANNEL_RED, true);
break;
case 2:
default:
ar->CastSpell(ar, SPELL_TEST_RIBBON_POLE_CHANNEL_PINK, true);
break;
}
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_midsummer_ribbon_pole::HandleEffectApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_midsummer_ribbon_pole::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
class spell_midsummer_ribbon_pole_visual : public SpellScript
{
PrepareSpellScript(spell_midsummer_ribbon_pole_visual)
void UpdateTarget(WorldObject*& target)
{
if (!target)
return;
// find NPC at ribbon pole top as target
// trap 181604 also spawns NPCs at pole bottom - ignore those
std::list crList;
target->GetCreaturesWithEntryInRange(crList, 30.0f, NPC_RIBBON_POLE_DEBUG_TARGET);
if (crList.empty())
return;
for (std::list::const_iterator itr = crList.begin(); itr != crList.end(); ++itr)
{
// NPC on ribbon pole top is no tempsummon
if (!(*itr)->ToTempSummon())
{
target = *itr;
return;
}
}
}
void Register() override
{
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_midsummer_ribbon_pole_visual::UpdateTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
}
};
class spell_braziers_hit : public AuraScript
{
PrepareAuraScript(spell_braziers_hit)
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo(
{
SPELL_TORCH_TOSSING_TRAINING_SUCCESS_A,
SPELL_TORCH_TOSSING_TRAINING_SUCCESS_H,
SPELL_TORCH_TOSSING_TRAINING,
SPELL_TORCH_TOSSING_PRACTICE,
});
}
void HandleAfterEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Player* const player = GetTarget()->ToPlayer();
if (!player)
return;
if ((player->HasAura(SPELL_TORCH_TOSSING_TRAINING) && (GetStackAmount() >= 8)) ||
(player->HasAura(SPELL_TORCH_TOSSING_PRACTICE) && (GetStackAmount() >= 20)))
{
player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_A, true);
player->CastSpell(player, SPELL_TORCH_TOSSING_TRAINING_SUCCESS_H, true);
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_braziers_hit::HandleAfterEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
class spell_torch_target_picker : public SpellScript
{
PrepareSpellScript(spell_torch_target_picker)
void SelectTargets(std::list& targets)
{
if (targets.empty())
return;
// keep single random element only
WorldObject* const bunny = Acore::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(bunny);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_torch_target_picker::SelectTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
class spell_torch_tossing_training : public AuraScript
{
PrepareAuraScript(spell_torch_tossing_training)
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_REMOVE_TORCHES });
}
void HandleAfterEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* const target = GetTarget())
target->CastSpell(target, SPELL_REMOVE_TORCHES);
}
void Register() override
{
AfterEffectRemove += AuraEffectApplyFn(spell_torch_tossing_training::HandleAfterEffectRemove, EFFECT_0, SPELL_AURA_DETECT_AMORE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
enum flingTorch
{
NPC_TORCH_TARGET = 26188,
SPELL_FLING_TORCH = 45669,
SPELL_FLING_TORCH_DUMMY = 46747,
SPELL_MISSED_TORCH = 45676,
SPELL_TORCH_COUNTER = 45693,
SPELL_TORCH_SHADOW = 46105,
SPELL_TORCH_CATCH_SUCCESS_A = 46081,
SPELL_TORCH_CATCH_SUCCESS_H = 46654,
SPELL_JUGGLE_TORCH = 45671,
QUEST_MORE_TORCH_TOSS_A = 11924,
QUEST_MORE_TORCH_TOSS_H = 11925,
};
class spell_midsummer_fling_torch : public SpellScript
{
PrepareSpellScript(spell_midsummer_fling_torch);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(
{
SPELL_FLING_TORCH,
SPELL_TORCH_SHADOW,
SPELL_MISSED_TORCH,
SPELL_TORCH_CATCH_SUCCESS_A,
SPELL_TORCH_CATCH_SUCCESS_H,
SPELL_TORCH_COUNTER
});
}
bool handled;
bool Load() override { handled = false; return true; }
void ThrowNextTorch(Unit* caster)
{
Creature* bunny = caster->FindNearestCreature(NPC_TORCH_TARGET, 100.0f);
if (!bunny)
return;
// targets are located on a circle with fixed radius around the target bunny
// first target is chosen randomly anywhere on the circle
// next target is chosen on the opposite half of the circle
// so a minimum flight duration of the torch is guaranteed
float angle = 0.0f;
if (GetSpellInfo()->Id == SPELL_FLING_TORCH_DUMMY)
angle = frand(-1.0f * M_PI, 1.0f * M_PI); // full circle
else
angle = frand(-0.5f * M_PI, 0.5f * M_PI); // half circle
Position pos = bunny->GetPosition();
pos.SetOrientation(caster->GetPosition().GetAbsoluteAngle(pos));
pos.RelocatePolarOffset(angle, 8.0f); // radius is sniffed value
caster->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_FLING_TORCH, true);
caster->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_TORCH_SHADOW, 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() ? QUEST_MORE_TORCH_TOSS_H : QUEST_MORE_TORCH_TOSS_A) == 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() ? SPELL_TORCH_CATCH_SUCCESS_H : SPELL_TORCH_CATCH_SUCCESS_A), true); // Quest completion
aur->SetDuration(1);
return;
}
}
else
target->CastSpell(target, SPELL_TORCH_COUNTER, true);
ThrowNextTorch(GetCaster());
}
}
void Register() override
{
AfterCast += SpellCastFn(spell_midsummer_fling_torch::HandleFinish);
if (m_scriptSpellId == SPELL_JUGGLE_TORCH)
{
OnEffectHitTarget += SpellEffectFn(spell_midsummer_fling_torch::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
}
};
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_TORCH_CATCHING_A = 11657,
QUEST_TORCH_CATCHING_H = 11923,
SPELL_TORCH_SHADOW_SELF = 46121,
SPELL_TORCH_SHADOW_SLOW = 46120,
SPELL_TORCH_SHADOW_MED = 46118,
SPELL_TORCH_SHADOW_FAST = 46117
};
class spell_midsummer_juggling_torch : public SpellScript
{
PrepareSpellScript(spell_midsummer_juggling_torch);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(
{
SPELL_JUGGLE_SELF,
SPELL_JUGGLE_SLOW,
SPELL_JUGGLE_MED,
SPELL_JUGGLE_FAST,
SPELL_TORCH_SHADOW_SELF,
SPELL_TORCH_SHADOW_SLOW,
SPELL_TORCH_SHADOW_MED,
SPELL_TORCH_SHADOW_FAST
});
}
void HandleFinish()
{
Unit* caster = GetCaster();
if (!caster || !caster->IsPlayer())
return;
if (const WorldLocation* loc = GetExplTargetDest())
{
if (loc->GetExactDist(caster) < 3.0f)
{
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_SELF, true);
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_SELF, true);
}
else if (loc->GetExactDist(caster) < 10.0f)
{
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_SLOW, true);
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_SLOW, true);
}
else if (loc->GetExactDist(caster) < 25.0f)
{
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_MED, true);
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_MED, true);
}
else
{
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_FAST, true);
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_FAST, true);
}
}
else
{
caster->CastSpell(caster, SPELL_JUGGLE_SELF, true);
caster->CastSpell(caster, SPELL_TORCH_SHADOW_SELF, true);
}
}
void Register() override
{
AfterCast += SpellCastFn(spell_midsummer_juggling_torch::HandleFinish);
}
};
// 45644 - Juggle Torch (Catch)
class spell_midsummer_torch_catch : public SpellScript
{
PrepareSpellScript(spell_midsummer_torch_catch);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_GIVE_TORCH });
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Player* player = GetHitPlayer();
if (!player)
{
return;
}
if (player->GetQuestStatus(QUEST_TORCH_CATCHING_A) == QUEST_STATUS_REWARDED || player->GetQuestStatus(QUEST_TORCH_CATCHING_H) == QUEST_STATUS_REWARDED)
{
player->CastSpell(player, SPELL_GIVE_TORCH);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_midsummer_torch_catch::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 46592 - Summon Ahune Lieutenant
class spell_midsummer_summon_ahune_lieutenant : public SpellScript
{
PrepareSpellScript(spell_midsummer_summon_ahune_lieutenant);
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
uint32 zoneId = caster->GetZoneId();
uint32 npcEntry = 0;
switch (zoneId)
{
case AREA_ASHENVALE:
npcEntry = 26116; // Frostwave Lieutenant
break;
case AREA_DESOLACE:
npcEntry = 26178; // Hailstone Lieutenant
break;
case AREA_STRANGLETHORN_VALE:
npcEntry = 26204; // Chillwind Lieutenant
break;
case AREA_SEARING_GORGE:
npcEntry = 26214; // Frigid Lieutenant
break;
case AREA_SILITHUS:
npcEntry = 26215; // Glacial Lieutenant
break;
case AREA_HELLFIRE_PENINSULA:
npcEntry = 26216; // Glacial Templar
break;
}
if (npcEntry)
caster->SummonCreature(npcEntry, caster->GetPosition(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, MINUTE * IN_MILLISECONDS);
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_midsummer_summon_ahune_lieutenant::HandleDummy, EFFECT_1, SPELL_EFFECT_APPLY_AURA);
}
};
void AddSC_event_midsummer_scripts()
{
// Player
new MidsummerPlayerScript();
// NPCs
RegisterCreatureAI(npc_midsummer_bonfire);
RegisterCreatureAI(npc_midsummer_bonfire_despawner);
RegisterCreatureAI(npc_midsummer_ribbon_pole_target);
// Spells
RegisterSpellScript(spell_fire_festival_fortitude);
RegisterSpellScript(spell_bonfires_blessing);
RegisterSpellScript(spell_gen_crab_disguise);
RegisterSpellScript(spell_midsummer_ribbon_pole_firework);
RegisterSpellScript(spell_midsummer_ribbon_pole);
RegisterSpellScript(spell_midsummer_ribbon_pole_visual);
RegisterSpellScript(spell_midsummer_fling_torch);
RegisterSpellScript(spell_midsummer_juggling_torch);
RegisterSpellScript(spell_midsummer_torch_catch);
RegisterSpellScript(spell_midsummer_summon_ahune_lieutenant);
RegisterSpellScript(spell_braziers_hit);
RegisterSpellScript(spell_torch_target_picker);
RegisterSpellScript(spell_torch_tossing_training);
}