forked from mirror/azerothcore-wotlk
c8f43d8584
Npc positioning Implemented slope check to avoid unwanted climbing for some kind of movements (backwards, repositioning etc.) Implemented backwards movement Re-implemented circle repositioning algorithm (smartest than retail, but with the same feeling) Fixed random position of summoned minions Improved pet following movement. Also, they attack NPC from behind now. Thanks to @Footman Swimming creatures Fixed max_z coordinate for swimming creatures. Now only part of their body is allowed to be out of the water level Fixed pathfinder for swimming creatures creating shortcuts for specific segments, now they swim underwater to reach the seashore instead of flying above the water level. Creatures with water InhabitType but no swimming flag now, when not in combat, will walk on water depth instead of swimming. Thanks @jackpoz for the original code UNIT_FLAG_SWIMMING in UpdateEnvironmentIfNeeded to show the swimming animation correctly when underwater Implemented HasEnoughWater check to avoid swimming creatures to go where the water level is too low but also to properly enable swimming animation only when a creature has enough water to swim. Walking creatures Extended the DetourNavMeshQuery adding area cost based on walkability (slope angle + source height) to find better paths at runtime instead of completely remove them from mmaps improve Z height in certain conditions (see #4205, #4203, #4247 ) Flying creatures Rewriting of the hover system Removed hacks and improved the UpdateEnvironmentIfNeeded. Now creatures can properly switch from flying to walk etc. Spells LOS on spell effect must be calculated on CollisionHeight and HitSpherePoint instead of position coords. Improved position for object/creature spawned via spells Improved checks for Fleeing movements (fear spells) Other improvements Implemented method to calculate the CollisionWidth from dbc (used by repositioning algorithm etc.) Improved raycast and collision checks Co-authored-by: Footman <p.alexej@freenet.de> Co-authored-by: Helias <stefanoborzi32@gmail.com> Co-authored-by: Francesco Borzì <borzifrancesco@gmail.com> Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com>
1781 lines
61 KiB
C++
1781 lines
61 KiB
C++
// Scripted by Xinef
|
|
|
|
#include "ScriptMgr.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "ScriptedGossip.h"
|
|
#include "SpellAuras.h"
|
|
#include "SpellAuraEffects.h"
|
|
#include "GridNotifiers.h"
|
|
#include "SpellScript.h"
|
|
#include "GameEventMgr.h"
|
|
#include "Group.h"
|
|
#include "LFGMgr.h"
|
|
#include "PassiveAI.h"
|
|
#include "CellImpl.h"
|
|
|
|
///////////////////////////////////////
|
|
////// GOS
|
|
///////////////////////////////////////
|
|
|
|
///////////////////////////////////////
|
|
////// NPCS
|
|
///////////////////////////////////////
|
|
|
|
class npc_brewfest_reveler : public CreatureScript
|
|
{
|
|
public:
|
|
npc_brewfest_reveler() : CreatureScript("npc_brewfest_reveler") { }
|
|
|
|
struct npc_brewfest_revelerAI : public ScriptedAI
|
|
{
|
|
npc_brewfest_revelerAI(Creature* c) : ScriptedAI(c) {}
|
|
void ReceiveEmote(Player* player, uint32 emote) override
|
|
{
|
|
if (!IsHolidayActive(HOLIDAY_BREWFEST))
|
|
return;
|
|
|
|
if (emote == TEXT_EMOTE_DANCE)
|
|
me->CastSpell(player, 41586, false);
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_brewfest_revelerAI(creature);
|
|
}
|
|
};
|
|
|
|
enum corenDirebrew
|
|
{
|
|
FACTION_HOSTILE = 754,
|
|
FACTION_FRIEND = 35,
|
|
ITEM_DARK_BREW = 36748,
|
|
ITEM_TREASURE_CHEST = 54535,
|
|
QUEST_COREN_DIREBREW = 25483,
|
|
ACTION_START_FIGHT = 1,
|
|
ACTION_RELEASE_LOOT = 2,
|
|
|
|
NPC_ILSA_DIREBREW = 26764,
|
|
NPC_URSULA_DIREBREW = 26822,
|
|
NPC_ANTAGONIST = 23795,
|
|
|
|
// COREN
|
|
SPELL_DIREBREW_DISARM = 47310,
|
|
SPELL_DISARM_VISUAL = 47407,
|
|
|
|
// SISTERS
|
|
SPELL_BARRELED = 51413,
|
|
SPELL_CHUCK_MUG = 50276,
|
|
SPELL_DARK_STUN = 47340,
|
|
SPELL_PURPLE_VISUAL = 47651,
|
|
|
|
EVENT_DIREBREW_DISARM = 1,
|
|
EVENT_DIREBREW_HEALTH = 2,
|
|
EVENT_SISTERS_BARREL = 3,
|
|
EVENT_SISTERS_CHUCK_MUG = 4,
|
|
EVENT_DIREBREW_RESPAWN1 = 5,
|
|
EVENT_DIREBREW_RESPAWN2 = 6,
|
|
};
|
|
|
|
#define GOSSIP_ITEM_COREN1 "Insult Coren Direbrew's Brew."
|
|
#define GOSSIP_ITEM_COREN2 "Insult."
|
|
|
|
class npc_coren_direbrew : public CreatureScript
|
|
{
|
|
public:
|
|
npc_coren_direbrew() : CreatureScript("npc_coren_direbrew") { }
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_coren_direbrewAI (creature);
|
|
}
|
|
|
|
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction) override
|
|
{
|
|
ClearGossipMenuFor(player);
|
|
switch (uiAction)
|
|
{
|
|
case GOSSIP_ACTION_INFO_DEF+1:
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_COREN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
|
SendGossipMenuFor(player, 15859, creature->GetGUID());
|
|
break;
|
|
case GOSSIP_ACTION_INFO_DEF+2:
|
|
CloseGossipMenuFor(player);
|
|
creature->AI()->DoAction(ACTION_START_FIGHT);
|
|
creature->MonsterSay("You'll pay for this insult, $C.", LANG_UNIVERSAL, player);
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OnGossipHello(Player* player, Creature* creature) override
|
|
{
|
|
if (creature->IsQuestGiver())
|
|
player->PrepareQuestMenu(creature->GetGUID());
|
|
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_COREN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
|
SendGossipMenuFor(player, 15858, creature->GetGUID());
|
|
|
|
return true;
|
|
}
|
|
|
|
struct npc_coren_direbrewAI : public ScriptedAI
|
|
{
|
|
npc_coren_direbrewAI(Creature* c) : ScriptedAI(c), summons(me)
|
|
{
|
|
}
|
|
|
|
EventMap events;
|
|
SummonList summons;
|
|
uint8 phase;
|
|
|
|
void Reset() override
|
|
{
|
|
events.Reset();
|
|
summons.DespawnAll();
|
|
me->setFaction(FACTION_FRIEND);
|
|
phase = 0;
|
|
}
|
|
|
|
void DoAction(int32 param) override
|
|
{
|
|
if (param == ACTION_START_FIGHT)
|
|
{
|
|
Creature* cr = nullptr;
|
|
|
|
for (int i = 0; i < 3; ++i)
|
|
{
|
|
float o = rand_norm() * 2 * M_PI;
|
|
if ((cr = me->SummonCreature(NPC_ANTAGONIST, me->GetPositionX() + 3 * cos(o), me->GetPositionY() + 3 * sin(o), me->GetPositionZ(), me->GetOrientation())))
|
|
{
|
|
if (i == 0)
|
|
cr->MonsterSay("Time to die.", LANG_UNIVERSAL, 0);
|
|
|
|
summons.Summon(cr);
|
|
cr->SetInCombatWithZone();
|
|
}
|
|
}
|
|
|
|
me->CastSpell(me, SPELL_PURPLE_VISUAL, true);
|
|
me->setFaction(FACTION_HOSTILE);
|
|
me->SetInCombatWithZone();
|
|
events.ScheduleEvent(EVENT_DIREBREW_DISARM, 10000);
|
|
events.ScheduleEvent(EVENT_DIREBREW_HEALTH, 1000);
|
|
}
|
|
else if (param == NPC_ILSA_DIREBREW)
|
|
events.ScheduleEvent(EVENT_DIREBREW_RESPAWN1, 10000);
|
|
else if (param == NPC_URSULA_DIREBREW)
|
|
events.ScheduleEvent(EVENT_DIREBREW_RESPAWN2, 10000);
|
|
}
|
|
|
|
void JustDied(Unit* /*killer*/) override
|
|
{
|
|
summons.DespawnAll();
|
|
summons.DoAction(ACTION_RELEASE_LOOT);
|
|
|
|
// HACK FIX FOR TREASURE CHEST
|
|
Quest const* qReward = sObjectMgr->GetQuestTemplate(QUEST_COREN_DIREBREW);
|
|
if (!qReward)
|
|
return;
|
|
|
|
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
|
|
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
|
if (Player* player = itr->GetSource())
|
|
{
|
|
if (player->CanRewardQuest(qReward, false))
|
|
player->RewardQuest(qReward, 0, NULL, false);
|
|
}
|
|
|
|
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
|
if (!players.isEmpty() && players.begin()->GetSource()->GetGroup())
|
|
sLFGMgr->FinishDungeon(players.begin()->GetSource()->GetGroup()->GetGUID(), 287, me->FindMap());
|
|
}
|
|
|
|
void SummonSister(uint32 entry)
|
|
{
|
|
summons.DespawnEntry(entry);
|
|
float o = rand_norm() * 2 * M_PI;
|
|
if (Creature* cr = me->SummonCreature(entry, me->GetPositionX() + 3 * cos(o), me->GetPositionY() + 3 * sin(o), me->GetPositionZ(), me->GetOrientation()))
|
|
{
|
|
cr->CastSpell(cr, SPELL_PURPLE_VISUAL, true);
|
|
cr->SetInCombatWithZone();
|
|
summons.Summon(cr);
|
|
}
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_DIREBREW_RESPAWN1:
|
|
SummonSister(NPC_ILSA_DIREBREW);
|
|
break;
|
|
case EVENT_DIREBREW_RESPAWN2:
|
|
SummonSister(NPC_URSULA_DIREBREW);
|
|
break;
|
|
case EVENT_DIREBREW_DISARM:
|
|
me->CastSpell(me->GetVictim(), SPELL_DIREBREW_DISARM, false);
|
|
me->CastSpell(me, SPELL_DISARM_VISUAL, true);
|
|
events.RepeatEvent(20000);
|
|
break;
|
|
case EVENT_DIREBREW_HEALTH:
|
|
if (me->GetHealthPct() < 66 && phase == 0)
|
|
{
|
|
phase++;
|
|
SummonSister(NPC_ILSA_DIREBREW);
|
|
}
|
|
if (me->GetHealthPct() < 35 && phase == 1)
|
|
{
|
|
SummonSister(NPC_URSULA_DIREBREW);
|
|
return;
|
|
}
|
|
|
|
events.RepeatEvent(1000);
|
|
break;
|
|
}
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
};
|
|
};
|
|
|
|
class npc_coren_direbrew_sisters : public CreatureScript
|
|
{
|
|
public:
|
|
npc_coren_direbrew_sisters() : CreatureScript("npc_coren_direbrew_sisters") { }
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_coren_direbrew_sistersAI (creature);
|
|
}
|
|
|
|
struct npc_coren_direbrew_sistersAI : public ScriptedAI
|
|
{
|
|
npc_coren_direbrew_sistersAI(Creature* c) : ScriptedAI(c)
|
|
{
|
|
}
|
|
|
|
EventMap events;
|
|
|
|
void Reset() override
|
|
{
|
|
events.Reset();
|
|
me->setFaction(FACTION_HOSTILE);
|
|
}
|
|
|
|
void DoAction(int32 param) override
|
|
{
|
|
if (param == ACTION_RELEASE_LOOT && me->GetEntry() == NPC_ILSA_DIREBREW)
|
|
me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
|
}
|
|
|
|
Creature* GetSummoner()
|
|
{
|
|
if (me->IsSummon())
|
|
if (Unit* coren = me->ToTempSummon()->GetSummoner())
|
|
return coren->ToCreature();
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void JustDied(Unit*) override
|
|
{
|
|
if (Creature* coren = GetSummoner())
|
|
{
|
|
if (coren->IsAlive())
|
|
{
|
|
coren->AI()->DoAction(me->GetEntry());
|
|
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnterCombat(Unit* /*who*/) override
|
|
{
|
|
if (me->GetEntry() == NPC_URSULA_DIREBREW)
|
|
events.ScheduleEvent(EVENT_SISTERS_BARREL, 18000);
|
|
|
|
events.ScheduleEvent(EVENT_SISTERS_CHUCK_MUG, 12000);
|
|
}
|
|
|
|
void SpellHitTarget(Unit* target, const SpellInfo* spellInfo) override
|
|
{
|
|
if (spellInfo->Id == SPELL_CHUCK_MUG)
|
|
if (target->ToPlayer())
|
|
target->ToPlayer()->AddItem(ITEM_DARK_BREW, 1);
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_SISTERS_BARREL:
|
|
me->CastSpell(me->GetVictim(), SPELL_BARRELED, false);
|
|
events.RepeatEvent(15000);
|
|
break;
|
|
case EVENT_SISTERS_CHUCK_MUG:
|
|
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
|
|
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
|
|
{
|
|
if (Player* player = itr->GetSource())
|
|
if (player->HasItemCount(ITEM_DARK_BREW))
|
|
{
|
|
me->CastSpell(player, SPELL_DARK_STUN, true);
|
|
player->DestroyItemCount(ITEM_DARK_BREW, 1, true);
|
|
}
|
|
}
|
|
|
|
if (Player* player = SelectTargetFromPlayerList(50.0f, SPELL_DARK_STUN))
|
|
me->CastSpell(player, SPELL_CHUCK_MUG, false);
|
|
|
|
events.RepeatEvent(18000);
|
|
break;
|
|
}
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
};
|
|
};
|
|
|
|
enum kegThrowers
|
|
{
|
|
QUEST_THERE_AND_BACK_AGAIN_A = 11122,
|
|
QUEST_THERE_AND_BACK_AGAIN_H = 11412,
|
|
RAM_DISPLAY_ID = 22630,
|
|
NPC_FLYNN_FIREBREW = 24364,
|
|
NPC_BOK_DROPCERTAIN = 24527,
|
|
ITEM_PORTABLE_BREWFEST_KEG = 33797,
|
|
SPELL_THROW_KEG = 43660,
|
|
SPELL_RAM_AURA = 43883,
|
|
SPELL_ADD_TOKENS = 44501,
|
|
SPELL_COOLDOWN_CHECKER = 43755,
|
|
NPC_RAM_MASTER_RAY = 24497,
|
|
NPC_NEILL_RAMSTEIN = 23558,
|
|
KEG_KILL_CREDIT = 24337,
|
|
};
|
|
|
|
class npc_brewfest_keg_thrower : public CreatureScript
|
|
{
|
|
public:
|
|
npc_brewfest_keg_thrower() : CreatureScript("npc_brewfest_keg_thrower") { }
|
|
|
|
struct npc_brewfest_keg_throwerAI : public ScriptedAI
|
|
{
|
|
npc_brewfest_keg_throwerAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
}
|
|
|
|
void MoveInLineOfSight(Unit* who) override
|
|
{
|
|
if (me->GetDistance(who) < 10.0f && who->GetTypeId() == TYPEID_PLAYER && who->GetMountID() == RAM_DISPLAY_ID)
|
|
{
|
|
if (!who->ToPlayer()->HasItemCount(ITEM_PORTABLE_BREWFEST_KEG)) // portable brewfest keg
|
|
me->CastSpell(who, SPELL_THROW_KEG, true); // throw keg
|
|
}
|
|
}
|
|
|
|
bool CanBeSeen(const Player* player) override
|
|
{
|
|
if (player->GetMountID() == RAM_DISPLAY_ID)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_brewfest_keg_throwerAI(creature);
|
|
}
|
|
};
|
|
|
|
class npc_brewfest_keg_reciver : public CreatureScript
|
|
{
|
|
public:
|
|
npc_brewfest_keg_reciver() : CreatureScript("npc_brewfest_keg_reciver") { }
|
|
|
|
struct npc_brewfest_keg_reciverAI : public ScriptedAI
|
|
{
|
|
npc_brewfest_keg_reciverAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
}
|
|
|
|
void MoveInLineOfSight(Unit* who) override
|
|
{
|
|
if (me->GetDistance(who) < 10.0f && who->GetTypeId() == TYPEID_PLAYER && who->GetMountID() == RAM_DISPLAY_ID)
|
|
{
|
|
Player* player = who->ToPlayer();
|
|
if (player->HasItemCount(ITEM_PORTABLE_BREWFEST_KEG)) // portable brewfest keg
|
|
{
|
|
player->KilledMonsterCredit(KEG_KILL_CREDIT, 0);
|
|
player->CastSpell(me, SPELL_THROW_KEG, true); // throw keg
|
|
player->DestroyItemCount(ITEM_PORTABLE_BREWFEST_KEG, 1, true);
|
|
|
|
// Additional Work
|
|
uint32 spellCooldown = player->GetSpellCooldownDelay(SPELL_COOLDOWN_CHECKER) / IN_MILLISECONDS;
|
|
if (spellCooldown > (HOUR * 18 - 900)) // max aproximated time - 12 minutes
|
|
{
|
|
if (Aura* aur = player->GetAura(SPELL_RAM_AURA))
|
|
{
|
|
int32 diff = aur->GetApplyTime() - (time(nullptr) - (HOUR * 18) + spellCooldown);
|
|
if (diff > 10) // aura applied later
|
|
return;
|
|
|
|
aur->SetDuration(aur->GetDuration() + 30000);
|
|
player->CastSpell(player, SPELL_ADD_TOKENS, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_brewfest_keg_reciverAI(creature);
|
|
}
|
|
|
|
bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*uiSender*/, uint32 uiAction) override
|
|
{
|
|
switch (uiAction)
|
|
{
|
|
case GOSSIP_ACTION_INFO_DEF+1:
|
|
CloseGossipMenuFor(player);
|
|
player->AddSpellCooldown(SPELL_COOLDOWN_CHECKER, 0, 18 * HOUR * IN_MILLISECONDS);
|
|
player->CastSpell(player, 43883, true);
|
|
player->CastSpell(player, 44262, true);
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OnGossipHello(Player* player, Creature* creature) override
|
|
{
|
|
if (creature->IsQuestGiver())
|
|
player->PrepareQuestMenu(creature->GetGUID());
|
|
|
|
if (!player->HasSpellCooldown(SPELL_COOLDOWN_CHECKER) && player->GetQuestRewardStatus(player->GetTeamId() == TEAM_ALLIANCE ? QUEST_THERE_AND_BACK_AGAIN_A : QUEST_THERE_AND_BACK_AGAIN_H))
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Do you have additional work?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
|
|
|
SendGossipMenuFor(player, (creature->GetEntry() == NPC_NEILL_RAMSTEIN ? 8934 : 8976), creature->GetGUID());
|
|
return true;
|
|
}
|
|
};
|
|
|
|
enum barkTrigger
|
|
{
|
|
QUEST_BARK_FOR_DROHN = 11407,
|
|
QUEST_BARK_FOR_VOODOO = 11408,
|
|
QUEST_BARK_FOR_BARLEY = 11293,
|
|
QUEST_BARK_FOR_THUNDERBREW = 11294,
|
|
};
|
|
|
|
class npc_brewfest_bark_trigger : public CreatureScript
|
|
{
|
|
public:
|
|
npc_brewfest_bark_trigger() : CreatureScript("npc_brewfest_bark_trigger") { }
|
|
|
|
struct npc_brewfest_bark_triggerAI : public ScriptedAI
|
|
{
|
|
npc_brewfest_bark_triggerAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
}
|
|
|
|
void MoveInLineOfSight(Unit* who) override
|
|
{
|
|
if (me->GetDistance(who) < 10.0f && who->GetTypeId() == TYPEID_PLAYER && who->GetMountID() == RAM_DISPLAY_ID)
|
|
{
|
|
bool allow = false;
|
|
uint32 quest = 0;
|
|
Player* player = who->ToPlayer();
|
|
// Kalimdor
|
|
if (me->GetMapId() == 1)
|
|
{
|
|
if (player->GetQuestStatus(QUEST_BARK_FOR_DROHN) == QUEST_STATUS_INCOMPLETE)
|
|
{
|
|
allow = true;
|
|
quest = QUEST_BARK_FOR_DROHN;
|
|
}
|
|
else if (player->GetQuestStatus(QUEST_BARK_FOR_VOODOO) == QUEST_STATUS_INCOMPLETE)
|
|
{
|
|
allow = true;
|
|
quest = QUEST_BARK_FOR_VOODOO;
|
|
}
|
|
}
|
|
else if (me->GetMapId() == 0)
|
|
{
|
|
if (player->GetQuestStatus(QUEST_BARK_FOR_BARLEY) == QUEST_STATUS_INCOMPLETE)
|
|
{
|
|
allow = true;
|
|
quest = QUEST_BARK_FOR_BARLEY;
|
|
}
|
|
else if (player->GetQuestStatus(QUEST_BARK_FOR_THUNDERBREW) == QUEST_STATUS_INCOMPLETE)
|
|
{
|
|
allow = true;
|
|
quest = QUEST_BARK_FOR_THUNDERBREW;
|
|
}
|
|
}
|
|
|
|
if (allow)
|
|
{
|
|
QuestStatusMap::iterator itr = player->getQuestStatusMap().find(quest);
|
|
if (itr == player->getQuestStatusMap().end())
|
|
return;
|
|
|
|
QuestStatusData& q_status = itr->second;
|
|
if (q_status.CreatureOrGOCount[me->GetEntry() - 24202] == 0)
|
|
{
|
|
player->KilledMonsterCredit(me->GetEntry(), 0);
|
|
player->MonsterSay(GetTextFor(me->GetEntry(), quest).c_str(), LANG_UNIVERSAL, player);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string GetTextFor(uint32 /*entry*/, uint32 questId)
|
|
{
|
|
std::string str = "";
|
|
switch (questId)
|
|
{
|
|
case QUEST_BARK_FOR_DROHN:
|
|
case QUEST_BARK_FOR_VOODOO:
|
|
{
|
|
switch (urand(0, 3))
|
|
{
|
|
case 0:
|
|
str = "Join with your brothers and sisters at " + std::string(questId == QUEST_BARK_FOR_DROHN ? "Drohn's Distillery" : "T'chali's Voodoo Brewery") + " and drink for the horde!";
|
|
break;
|
|
case 1:
|
|
str = "If you think an orc can hit hard, check out their brew, it hits even harder! See for yourself at " + std::string(questId == QUEST_BARK_FOR_DROHN ? "Drohn's Distillery" : "T'chali's Voodoo Brewery") + ", only at Brewfest!";
|
|
break;
|
|
case 2:
|
|
str = "Celebrate Brewfest with orcs that know what a good drink really is! Check out " + std::string(questId == QUEST_BARK_FOR_DROHN ? "Drohn's Distillery" : "T'chali's Voodoo Brewery") + " at Brewfest!";
|
|
break;
|
|
case 3:
|
|
str = std::string(questId == QUEST_BARK_FOR_DROHN ? "Drohn's Distillery" : "T'chali's Voodoo Brewery") + " knows how to party hard! Check them out at Brewfest!";
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case QUEST_BARK_FOR_BARLEY:
|
|
case QUEST_BARK_FOR_THUNDERBREW:
|
|
{
|
|
switch (urand(0, 3))
|
|
{
|
|
case 0:
|
|
str = "Join with your brothers and sisters at " + std::string(questId == QUEST_BARK_FOR_BARLEY ? "Barleybrews" : "Thunderbrews") + " and drink for the alliance!";
|
|
break;
|
|
case 1:
|
|
str = "If you think an dwarf can hit hard, check out their brew, it hits even harder! See for yourself at " + std::string(questId == QUEST_BARK_FOR_BARLEY ? "Barleybrews" : "Thunderbrews") + ", only at Brewfest!";
|
|
break;
|
|
case 2:
|
|
str = "Celebrate Brewfest with dwarves that know what a good drink really is! Check out " + std::string(questId == QUEST_BARK_FOR_BARLEY ? "Barleybrews" : "Thunderbrews") + " at Brewfest!";
|
|
break;
|
|
case 3:
|
|
str = std::string(questId == QUEST_BARK_FOR_BARLEY ? "Barleybrews" : "Thunderbrews") + " knows how to party hard! Check them out at Brewfest!";
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return str;
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_brewfest_bark_triggerAI(creature);
|
|
}
|
|
};
|
|
|
|
enum darkIronAttack
|
|
{
|
|
// Gos
|
|
GO_MOLE_MACHINE = 195305,
|
|
|
|
// Npcs
|
|
NPC_BARLEYBREW_KEG = 23700,
|
|
NPC_THUNDERBREW_KEG = 23702,
|
|
NPC_GORDOK_KEG = 23706,
|
|
NPC_VOODOO_KEG = 24373,
|
|
NPC_DROHN_KEG = 24372,
|
|
NPC_MOLE_MACHINE_TRIGGER = 23894,
|
|
NPC_DARK_IRON_GUZZLER = 23709,
|
|
NPC_NORMAL_DROHN = 24492,
|
|
NPC_NORMAL_VOODOO = 21349,
|
|
NPC_NORMAL_BARLEYBREW = 23683,
|
|
NPC_NORMAL_THUNDERBREW = 23684,
|
|
NPC_NORMAL_GORDOK = 23685,
|
|
NPC_EVENT_GENERATOR = 23703,
|
|
NPC_SUPER_BREW_TRIGGER = 23808,
|
|
NPC_DARK_IRON_HERALD = 24536,
|
|
|
|
// Events
|
|
EVENT_CHECK_HOUR = 1,
|
|
EVENT_SPAWN_MOLE_MACHINE = 2,
|
|
EVENT_PRE_FINISH_ATTACK = 3,
|
|
EVENT_FINISH_ATTACK = 4,
|
|
EVENT_BARTENDER_SAY = 5,
|
|
|
|
// Spells
|
|
SPELL_THROW_MUG_TO_PLAYER = 42300,
|
|
SPELL_ADD_MUG = 42518,
|
|
SPELL_SPAWN_MOLE_MACHINE = 43563,
|
|
SPELL_KEG_MARKER = 42761,
|
|
SPELL_PLAYER_MUG = 42436,
|
|
SPELL_REPORT_DEATH = 42655,
|
|
SPELL_CREATE_SUPER_BREW = 42715,
|
|
SPELL_DRUNKEN_MASTER = 42696,
|
|
SPELL_SUMMON_PLANS_A = 48145,
|
|
SPELL_SUMMON_PLANS_H = 49318,
|
|
|
|
// Dark Irons
|
|
SPELL_ATTACK_KEG = 42393,
|
|
SPELL_KNOCKBACK_AURA = 42676,
|
|
SPELL_MUG_BOUNCE_BACK = 42522,
|
|
};
|
|
|
|
class npc_dark_iron_attack_generator : public CreatureScript
|
|
{
|
|
public:
|
|
npc_dark_iron_attack_generator() : CreatureScript("npc_dark_iron_attack_generator") { }
|
|
|
|
struct npc_dark_iron_attack_generatorAI : public ScriptedAI
|
|
{
|
|
npc_dark_iron_attack_generatorAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
|
{
|
|
}
|
|
|
|
EventMap events;
|
|
SummonList summons;
|
|
uint32 kegCounter, guzzlerCounter;
|
|
uint8 thrown;
|
|
|
|
void Reset() override
|
|
{
|
|
summons.DespawnAll();
|
|
events.Reset();
|
|
events.ScheduleEvent(EVENT_CHECK_HOUR, 2000);
|
|
kegCounter = 0;
|
|
guzzlerCounter = 0;
|
|
thrown = 0;
|
|
}
|
|
|
|
// DARK IRON ATTACK EVENT
|
|
void MoveInLineOfSight(Unit* /*who*/) override {}
|
|
void EnterCombat(Unit*) override {}
|
|
|
|
void SpellHit(Unit* caster, const SpellInfo* spellInfo) override
|
|
{
|
|
if (spellInfo->Id == SPELL_REPORT_DEATH)
|
|
{
|
|
if (caster->GetEntry() == NPC_DARK_IRON_GUZZLER)
|
|
guzzlerCounter++;
|
|
else
|
|
{
|
|
kegCounter++;
|
|
if (kegCounter == 3)
|
|
FinishEventDueToLoss();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
events.Update(diff);
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_CHECK_HOUR:
|
|
{
|
|
// determine hour
|
|
if (AllowStart())
|
|
{
|
|
PrepareEvent();
|
|
events.RepeatEvent(300000);
|
|
return;
|
|
}
|
|
events.RepeatEvent(2000);
|
|
break;
|
|
}
|
|
case EVENT_SPAWN_MOLE_MACHINE:
|
|
{
|
|
if (me->GetMapId() == 1) // Kalimdor
|
|
{
|
|
float rand = 8 + rand_norm() * 12;
|
|
float angle = rand_norm() * 2 * M_PI;
|
|
float x = 1201.8f + rand * cos(angle);
|
|
float y = -4299.6f + rand * sin(angle);
|
|
if (Creature* cr = me->SummonCreature(NPC_MOLE_MACHINE_TRIGGER, x, y, 21.3f, 0.0f))
|
|
cr->CastSpell(cr, SPELL_SPAWN_MOLE_MACHINE, true);
|
|
}
|
|
else if (me->GetMapId() == 0) // EK
|
|
{
|
|
float rand = rand_norm() * 20;
|
|
float angle = rand_norm() * 2 * M_PI;
|
|
float x = -5157.1f + rand * cos(angle);
|
|
float y = -598.98f + rand * sin(angle);
|
|
if (Creature* cr = me->SummonCreature(NPC_MOLE_MACHINE_TRIGGER, x, y, 398.11f, 0.0f))
|
|
cr->CastSpell(cr, SPELL_SPAWN_MOLE_MACHINE, true);
|
|
}
|
|
events.RepeatEvent(3000);
|
|
break;
|
|
}
|
|
case EVENT_PRE_FINISH_ATTACK:
|
|
{
|
|
events.CancelEvent(EVENT_SPAWN_MOLE_MACHINE);
|
|
events.ScheduleEvent(EVENT_FINISH_ATTACK, 20000);
|
|
break;
|
|
}
|
|
case EVENT_FINISH_ATTACK:
|
|
{
|
|
FinishAttackDueToWin();
|
|
events.RescheduleEvent(EVENT_CHECK_HOUR, 60000);
|
|
break;
|
|
}
|
|
case EVENT_BARTENDER_SAY:
|
|
{
|
|
events.RepeatEvent(12000);
|
|
Creature* sayer = GetRandomBartender();
|
|
if (!sayer)
|
|
return;
|
|
|
|
thrown++;
|
|
if (thrown == 3)
|
|
{
|
|
thrown = 0;
|
|
sayer->MonsterSay("SOMEONE TRY THIS SUPER BREW!", LANG_UNIVERSAL, 0);
|
|
//sayer->CastSpell(sayer, SPELL_CREATE_SUPER_BREW, true);
|
|
sayer->SummonCreature(NPC_SUPER_BREW_TRIGGER, sayer->GetPositionX() + 15 * cos(sayer->GetOrientation()), sayer->GetPositionY() + 15 * sin(sayer->GetOrientation()), sayer->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
|
|
}
|
|
else
|
|
{
|
|
if (urand(0, 1))
|
|
sayer->MonsterSay("Chug and chuck! Chug and chuck!", LANG_UNIVERSAL, 0);
|
|
else
|
|
sayer->MonsterSay("Down the free brew and pelt the Guzzlers with your mug!", LANG_UNIVERSAL, 0);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FinishEventDueToLoss()
|
|
{
|
|
if (Creature* herald = me->FindNearestCreature(NPC_DARK_IRON_HERALD, 100.0f))
|
|
{
|
|
char amount[500];
|
|
sprintf(amount, "We did it boys! Now back to the Grim Guzzler and we'll drink to the %u that were injured!", guzzlerCounter);
|
|
herald->MonsterYell(amount, LANG_UNIVERSAL, 0);
|
|
}
|
|
|
|
Reset();
|
|
events.RescheduleEvent(EVENT_CHECK_HOUR, 60000);
|
|
}
|
|
|
|
void FinishAttackDueToWin()
|
|
{
|
|
if (Creature* herald = me->FindNearestCreature(NPC_DARK_IRON_HERALD, 100.0f))
|
|
{
|
|
char amount[500];
|
|
sprintf(amount, "RETREAT!! We've already lost %u and we can't afford to lose any more!!", guzzlerCounter);
|
|
herald->MonsterYell(amount, LANG_UNIVERSAL, 0);
|
|
}
|
|
|
|
me->CastSpell(me, (me->GetMapId() == 1 ? SPELL_SUMMON_PLANS_H : SPELL_SUMMON_PLANS_A), true);
|
|
Reset();
|
|
}
|
|
|
|
void PrepareEvent()
|
|
{
|
|
Creature* cr;
|
|
if (me->GetMapId() == 1) // Kalimdor
|
|
{
|
|
if ((cr = me->SummonCreature(NPC_DROHN_KEG, 1183.69f, -4315.15f, 21.1875f, 0.750492f)))
|
|
summons.Summon(cr);
|
|
if ((cr = me->SummonCreature(NPC_VOODOO_KEG, 1182.42f, -4272.45f, 21.1182f, -1.02974f)))
|
|
summons.Summon(cr);
|
|
if ((cr = me->SummonCreature(NPC_GORDOK_KEG, 1223.78f, -4296.48f, 21.1707f, -2.86234f)))
|
|
summons.Summon(cr);
|
|
}
|
|
else if (me->GetMapId() == 0) // Eastern Kingdom
|
|
{
|
|
if ((cr = me->SummonCreature(NPC_BARLEYBREW_KEG, -5187.23f, -599.779f, 397.176f, 0.017453f)))
|
|
summons.Summon(cr);
|
|
if ((cr = me->SummonCreature(NPC_THUNDERBREW_KEG, -5160.05f, -632.632f, 397.178f, 1.39626f)))
|
|
summons.Summon(cr);
|
|
if ((cr = me->SummonCreature(NPC_GORDOK_KEG, -5145.75f, -575.667f, 397.176f, -2.28638f)))
|
|
summons.Summon(cr);
|
|
}
|
|
|
|
if ((cr = me->SummonCreature(NPC_DARK_IRON_HERALD, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 300000)))
|
|
summons.Summon(cr);
|
|
|
|
kegCounter = 0;
|
|
guzzlerCounter = 0;
|
|
thrown = 0;
|
|
|
|
events.ScheduleEvent(EVENT_SPAWN_MOLE_MACHINE, 1500);
|
|
events.ScheduleEvent(EVENT_PRE_FINISH_ATTACK, 280000);
|
|
events.ScheduleEvent(EVENT_BARTENDER_SAY, 5000);
|
|
}
|
|
|
|
bool AllowStart()
|
|
{
|
|
time_t curtime = time(nullptr);
|
|
tm strDate;
|
|
localtime_r(&curtime, &strDate);
|
|
|
|
if (strDate.tm_min == 0 || strDate.tm_min == 30)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
Creature* GetRandomBartender()
|
|
{
|
|
uint32 entry = 0;
|
|
switch (urand(0, 2))
|
|
{
|
|
case 0:
|
|
entry = (me->GetMapId() == 1 ? NPC_NORMAL_DROHN : NPC_NORMAL_THUNDERBREW);
|
|
break;
|
|
case 1:
|
|
entry = (me->GetMapId() == 1 ? NPC_NORMAL_VOODOO : NPC_NORMAL_BARLEYBREW);
|
|
break;
|
|
case 2:
|
|
entry = NPC_NORMAL_GORDOK;
|
|
break;
|
|
}
|
|
|
|
return me->FindNearestCreature(entry, 100.0f);
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_dark_iron_attack_generatorAI(creature);
|
|
}
|
|
};
|
|
|
|
class npc_dark_iron_attack_mole_machine : public CreatureScript
|
|
{
|
|
public:
|
|
npc_dark_iron_attack_mole_machine() : CreatureScript("npc_dark_iron_attack_mole_machine") { }
|
|
|
|
struct npc_dark_iron_attack_mole_machineAI : public ScriptedAI
|
|
{
|
|
npc_dark_iron_attack_mole_machineAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
}
|
|
|
|
void EnterCombat(Unit*) override {}
|
|
void MoveInLineOfSight(Unit*) override {}
|
|
void AttackStart(Unit*) override {}
|
|
|
|
uint32 goTimer, summonTimer;
|
|
void Reset() override
|
|
{
|
|
goTimer = 1;
|
|
summonTimer = 0;
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
if (goTimer)
|
|
{
|
|
goTimer += diff;
|
|
if (goTimer >= 3000)
|
|
{
|
|
goTimer = 0;
|
|
summonTimer++;
|
|
if (GameObject* drill = me->SummonGameObject(GO_MOLE_MACHINE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), M_PI / 4, 0.0f, 0.0f, 0.0f, 0.0f, 8))
|
|
{
|
|
//drill->SetGoAnimProgress(0);
|
|
drill->SetLootState(GO_READY);
|
|
drill->UseDoorOrButton(8);
|
|
}
|
|
}
|
|
}
|
|
if (summonTimer)
|
|
{
|
|
summonTimer += diff;
|
|
if (summonTimer >= 2000 && summonTimer < 10000)
|
|
{
|
|
me->SummonCreature(NPC_DARK_IRON_GUZZLER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000);
|
|
summonTimer = 10000;
|
|
}
|
|
if (summonTimer >= 13000 && summonTimer < 20000)
|
|
{
|
|
me->SummonCreature(NPC_DARK_IRON_GUZZLER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000);
|
|
summonTimer = 0;
|
|
me->DespawnOrUnsummon(3000);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_dark_iron_attack_mole_machineAI(creature);
|
|
}
|
|
};
|
|
|
|
class npc_dark_iron_guzzler : public CreatureScript
|
|
{
|
|
public:
|
|
npc_dark_iron_guzzler() : CreatureScript("npc_dark_iron_guzzler") { }
|
|
|
|
struct npc_dark_iron_guzzlerAI : public ScriptedAI
|
|
{
|
|
npc_dark_iron_guzzlerAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
me->SetReactState(REACT_PASSIVE);
|
|
}
|
|
|
|
uint32 timer;
|
|
uint64 targetGUID;
|
|
void EnterCombat(Unit*) override {}
|
|
void MoveInLineOfSight(Unit*) override {}
|
|
void AttackStart(Unit*) override {}
|
|
|
|
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
|
{
|
|
damage = 0;
|
|
}
|
|
|
|
void FindNextKeg()
|
|
{
|
|
uint32 entry[3] = {0, 0, 0};
|
|
uint32 shuffled[3] = {0, 0, 0};
|
|
|
|
if (me->GetMapId() == 1) // Kalimdor
|
|
{
|
|
entry[0] = NPC_DROHN_KEG;
|
|
entry[1] = NPC_VOODOO_KEG;
|
|
entry[2] = NPC_GORDOK_KEG;
|
|
}
|
|
else// if (me->GetMapId() == 0) // EK
|
|
{
|
|
entry[0] = NPC_THUNDERBREW_KEG;
|
|
entry[1] = NPC_BARLEYBREW_KEG;
|
|
entry[2] = NPC_GORDOK_KEG;
|
|
}
|
|
|
|
for (uint8 i = 0; i < 3; ++i)
|
|
{
|
|
uint8 index = 0;
|
|
do
|
|
index = urand(0, 2);
|
|
while (shuffled[index]);
|
|
|
|
shuffled[index] = entry[i];
|
|
}
|
|
|
|
for (uint8 i = 0; i < 3; ++i)
|
|
if (Creature* cr = me->FindNearestCreature(shuffled[i], 100.0f))
|
|
{
|
|
me->GetMotionMaster()->MoveFollow(cr, 1.0f, cr->GetAngle(me));
|
|
targetGUID = cr->GetGUID();
|
|
return;
|
|
}
|
|
|
|
// no kegs found
|
|
me->DisappearAndDie();
|
|
}
|
|
|
|
Unit* GetTarget() { return ObjectAccessor::GetUnit(*me, targetGUID); }
|
|
|
|
void Reset() override
|
|
{
|
|
timer = 0;
|
|
targetGUID = 0;
|
|
me->SetWalk(true);
|
|
FindNextKeg();
|
|
me->ApplySpellImmune(SPELL_ATTACK_KEG, IMMUNITY_ID, SPELL_ATTACK_KEG, true);
|
|
SayText();
|
|
me->CastSpell(me, SPELL_KNOCKBACK_AURA, true);
|
|
}
|
|
|
|
void SayText()
|
|
{
|
|
if (!urand(0, 20))
|
|
{
|
|
switch (urand(0, 4))
|
|
{
|
|
case 0:
|
|
me->MonsterSay("Drink it all boys!", LANG_UNIVERSAL, 0);
|
|
break;
|
|
case 1:
|
|
me->MonsterSay("DRINK! BRAWL! DRINK! BRAWL!", LANG_UNIVERSAL, 0);
|
|
break;
|
|
case 2:
|
|
me->MonsterSay("Did someone say, \"Free Brew\"?", LANG_UNIVERSAL, 0);
|
|
break;
|
|
case 3:
|
|
me->MonsterSay("No one expects the Dark Iron dwarves!", LANG_UNIVERSAL, 0);
|
|
break;
|
|
case 4:
|
|
me->MonsterSay("It's not a party without some crashers!", LANG_UNIVERSAL, 0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void KilledUnit(Unit* who) override
|
|
{
|
|
who->CastSpell(who, SPELL_REPORT_DEATH, true);
|
|
}
|
|
|
|
void SpellHit(Unit* /*caster*/, const SpellInfo* spellInfo) override
|
|
{
|
|
if (me->IsAlive() && spellInfo->Id == SPELL_PLAYER_MUG)
|
|
{
|
|
me->CastSpell(me, SPELL_MUG_BOUNCE_BACK, true);
|
|
Unit::Kill(me, me);
|
|
me->CastSpell(me, SPELL_REPORT_DEATH, true);
|
|
}
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
timer += diff;
|
|
if (timer < 2000)
|
|
return;
|
|
|
|
timer = 0;
|
|
if (targetGUID)
|
|
{
|
|
if (Unit* target = GetTarget())
|
|
me->CastSpell(target, SPELL_ATTACK_KEG, false);
|
|
else
|
|
FindNextKeg();
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_dark_iron_guzzlerAI(creature);
|
|
}
|
|
};
|
|
|
|
class npc_brewfest_super_brew_trigger : public CreatureScript
|
|
{
|
|
public:
|
|
npc_brewfest_super_brew_trigger() : CreatureScript("npc_brewfest_super_brew_trigger") { }
|
|
|
|
struct npc_brewfest_super_brew_triggerAI : public ScriptedAI
|
|
{
|
|
npc_brewfest_super_brew_triggerAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
}
|
|
|
|
uint32 timer;
|
|
void EnterCombat(Unit*) override {}
|
|
void MoveInLineOfSight(Unit* /*who*/) override
|
|
{
|
|
}
|
|
|
|
void AttackStart(Unit*) override {}
|
|
|
|
void Reset() override
|
|
{
|
|
timer = 0;
|
|
me->SummonGameObject(186478, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 30000);
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
timer += diff;
|
|
if (timer >= 500)
|
|
{
|
|
timer = 0;
|
|
Player* player = nullptr;
|
|
acore::AnyPlayerInObjectRangeCheck checker(me, 2.0f);
|
|
acore::PlayerSearcher<acore::AnyPlayerInObjectRangeCheck> searcher(me, player, checker);
|
|
me->VisitNearbyWorldObject(2.0f, searcher);
|
|
if (player)
|
|
{
|
|
player->CastSpell(player, SPELL_DRUNKEN_MASTER, true);
|
|
me->RemoveAllGameObjects();
|
|
Unit::Kill(me, me);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_brewfest_super_brew_triggerAI(creature);
|
|
}
|
|
};
|
|
|
|
///////////////////////////////////////
|
|
////// SPELLS
|
|
///////////////////////////////////////
|
|
|
|
enum ramRacing
|
|
{
|
|
SPELL_TROT = 42992,
|
|
SPELL_CANTER = 42993,
|
|
SPELL_GALLOP = 42994,
|
|
SPELL_RAM_FATIGUE = 43052,
|
|
SPELL_RAM_EXHAUSTED = 43332,
|
|
|
|
CREDIT_TROT = 24263,
|
|
CREDIT_CANTER = 24264,
|
|
CREDIT_GALLOP = 24265,
|
|
|
|
RACING_RAM_MODEL = 22630,
|
|
};
|
|
|
|
class spell_brewfest_main_ram_buff : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_brewfest_main_ram_buff() : SpellScriptLoader("spell_brewfest_main_ram_buff") { }
|
|
|
|
class spell_brewfest_main_ram_buff_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_brewfest_main_ram_buff_AuraScript)
|
|
|
|
uint8 privateLevel;
|
|
uint32 questTick;
|
|
bool Load() override
|
|
{
|
|
questTick = 0;
|
|
privateLevel = 0;
|
|
return true;
|
|
}
|
|
|
|
void HandleEffectPeriodic(AuraEffect const* aurEff)
|
|
{
|
|
Unit* caster = GetCaster();
|
|
if (!caster || !caster->IsMounted() || !caster->ToPlayer())
|
|
return;
|
|
|
|
if (caster->GetMountID() != RACING_RAM_MODEL)
|
|
return;
|
|
|
|
Aura* aur = caster->GetAura(42924);
|
|
if (!aur)
|
|
{
|
|
caster->CastSpell(caster, 42924, true);
|
|
return;
|
|
}
|
|
|
|
// Check if exhausted
|
|
if (caster->GetAura(SPELL_RAM_EXHAUSTED))
|
|
{
|
|
if (privateLevel)
|
|
{
|
|
caster->RemoveAurasDueToSpell(SPELL_CANTER);
|
|
caster->RemoveAurasDueToSpell(SPELL_GALLOP);
|
|
}
|
|
|
|
aur->SetStackAmount(1);
|
|
return;
|
|
}
|
|
|
|
uint32 stack = aur->GetStackAmount();
|
|
uint8 mode = 0;
|
|
switch (privateLevel)
|
|
{
|
|
case 0:
|
|
if (stack > 1)
|
|
{
|
|
questTick = 0;
|
|
caster->CastSpell(caster, SPELL_TROT, true);
|
|
privateLevel++;
|
|
mode = 1; // unapply
|
|
break;
|
|
}
|
|
// just walking, fatiuge handling
|
|
if (Aura* aur = caster->GetAura(SPELL_RAM_FATIGUE))
|
|
aur->ModStackAmount(-4);
|
|
break;
|
|
case 1:
|
|
// One click to maintain speed, more to increase
|
|
if (stack < 2)
|
|
{
|
|
caster->RemoveAurasDueToSpell(SPELL_TROT);
|
|
questTick = 0;
|
|
privateLevel--;
|
|
mode = 2; // apply
|
|
}
|
|
else if (stack > 2)
|
|
{
|
|
questTick = 0;
|
|
caster->CastSpell(caster, SPELL_CANTER, true);
|
|
privateLevel++;
|
|
}
|
|
else if (questTick++ > 3)
|
|
caster->ToPlayer()->KilledMonsterCredit(CREDIT_TROT, 0);
|
|
break;
|
|
case 2:
|
|
// Two - three clicks to maintains speed, less to decrease, more to increase
|
|
if (stack < 3)
|
|
{
|
|
caster->CastSpell(caster, SPELL_TROT, true);
|
|
privateLevel--;
|
|
questTick = 0;
|
|
}
|
|
else if (stack > 4)
|
|
{
|
|
caster->CastSpell(caster, SPELL_GALLOP, true);
|
|
privateLevel++;
|
|
questTick = 0;
|
|
}
|
|
else if (questTick++ > 3)
|
|
caster->ToPlayer()->KilledMonsterCredit(CREDIT_CANTER, 0);
|
|
break;
|
|
case 3:
|
|
// Four or more clicks to maintains speed, less to decrease
|
|
if (stack < 5)
|
|
{
|
|
caster->CastSpell(caster, SPELL_CANTER, true);
|
|
privateLevel--;
|
|
questTick = 0;
|
|
}
|
|
else if (questTick++ > 3)
|
|
caster->ToPlayer()->KilledMonsterCredit(CREDIT_GALLOP, 0);
|
|
break;
|
|
}
|
|
|
|
// Set to base amount
|
|
aur->SetStackAmount(1);
|
|
|
|
// apply/unapply effect 1
|
|
if (mode)
|
|
if (Aura* base = aurEff->GetBase())
|
|
if (AuraEffect* aEff = base->GetEffect(EFFECT_0))
|
|
{
|
|
aEff->SetAmount(mode == 1 ? 0 : -50);
|
|
caster->UpdateSpeed(MOVE_RUN, true);
|
|
}
|
|
}
|
|
|
|
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
if (Unit* target = GetTarget())
|
|
target->RemoveAurasDueToSpell(SPELL_RAM_FATIGUE);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_brewfest_main_ram_buff_AuraScript::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
|
|
OnEffectRemove += AuraEffectRemoveFn(spell_brewfest_main_ram_buff_AuraScript::HandleEffectRemove, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const override
|
|
{
|
|
return new spell_brewfest_main_ram_buff_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_brewfest_ram_fatigue : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_brewfest_ram_fatigue() : SpellScriptLoader("spell_brewfest_ram_fatigue") { }
|
|
|
|
class spell_brewfest_ram_fatigue_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_brewfest_ram_fatigue_AuraScript)
|
|
|
|
void HandleEffectPeriodic(AuraEffect const* aurEff)
|
|
{
|
|
int8 fatigue = 0;
|
|
switch (aurEff->GetId())
|
|
{
|
|
case SPELL_TROT:
|
|
fatigue = -2;
|
|
break;
|
|
case SPELL_CANTER:
|
|
fatigue = 1;
|
|
break;
|
|
case SPELL_GALLOP:
|
|
fatigue = 5;
|
|
break;
|
|
}
|
|
if (Unit* target = GetTarget())
|
|
{
|
|
if (Aura* aur = target->GetAura(SPELL_RAM_FATIGUE))
|
|
{
|
|
aur->ModStackAmount(fatigue);
|
|
if (aur->GetStackAmount() >= 100)
|
|
target->CastSpell(target, SPELL_RAM_EXHAUSTED, true);
|
|
}
|
|
else
|
|
target->CastSpell(target, SPELL_RAM_FATIGUE, true);
|
|
}
|
|
}
|
|
|
|
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
if (Unit* target = GetTarget())
|
|
{
|
|
if (Aura* aur = target->GetAura(SPELL_RAM_FATIGUE))
|
|
aur->ModStackAmount(-15);
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
if (m_scriptSpellId != 43332)
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_brewfest_ram_fatigue_AuraScript::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DUMMY);
|
|
else
|
|
OnEffectRemove += AuraEffectRemoveFn(spell_brewfest_ram_fatigue_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_DECREASE_SPEED, AURA_EFFECT_HANDLE_REAL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const override
|
|
{
|
|
return new spell_brewfest_ram_fatigue_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_brewfest_apple_trap : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_brewfest_apple_trap() : SpellScriptLoader("spell_brewfest_apple_trap") { }
|
|
|
|
class spell_brewfest_apple_trap_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_brewfest_apple_trap_SpellScript);
|
|
|
|
void HandleDummyEffect(SpellEffIndex /*effIndex*/)
|
|
{
|
|
if (Unit* target = GetHitUnit())
|
|
if (Aura* aur = target->GetAura(SPELL_RAM_FATIGUE))
|
|
aur->Remove();
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_brewfest_apple_trap_SpellScript::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_brewfest_apple_trap_SpellScript();
|
|
};
|
|
};
|
|
|
|
class spell_q11117_catch_the_wild_wolpertinger : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_q11117_catch_the_wild_wolpertinger() : SpellScriptLoader("spell_q11117_catch_the_wild_wolpertinger") { }
|
|
|
|
class spell_q11117_catch_the_wild_wolpertinger_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_q11117_catch_the_wild_wolpertinger_SpellScript);
|
|
|
|
SpellCastResult CheckTarget()
|
|
{
|
|
if (Unit* caster = GetCaster())
|
|
if (caster->ToPlayer())
|
|
if (Unit* target = caster->ToPlayer()->GetSelectedUnit())
|
|
if (target->GetEntry() == 23487 && target->IsAlive())
|
|
return SPELL_CAST_OK;
|
|
|
|
return SPELL_FAILED_BAD_TARGETS;
|
|
}
|
|
|
|
void HandleDummyEffect(SpellEffIndex /*effIndex*/)
|
|
{
|
|
if (GetCaster() && GetCaster()->ToPlayer())
|
|
{
|
|
GetCaster()->ToPlayer()->AddItem(32906, 1);
|
|
if (Unit* target = GetCaster()->ToPlayer()->GetSelectedUnit())
|
|
target->ToCreature()->DespawnOrUnsummon(500);
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnCheckCast += SpellCheckCastFn(spell_q11117_catch_the_wild_wolpertinger_SpellScript::CheckTarget);
|
|
OnEffectHitTarget += SpellEffectFn(spell_q11117_catch_the_wild_wolpertinger_SpellScript::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_q11117_catch_the_wild_wolpertinger_SpellScript();
|
|
};
|
|
};
|
|
|
|
enum fillKeg
|
|
{
|
|
GREEN_EMPTY_KEG = 37892,
|
|
BLUE_EMPTY_KEG = 33016,
|
|
YELLOW_EMPTY_KEG = 32912,
|
|
};
|
|
|
|
class spell_brewfest_fill_keg : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_brewfest_fill_keg() : SpellScriptLoader("spell_brewfest_fill_keg") { }
|
|
|
|
class spell_brewfest_fill_keg_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_brewfest_fill_keg_SpellScript);
|
|
|
|
void HandleAfterHit()
|
|
{
|
|
if (GetCaster() && GetCaster()->ToPlayer())
|
|
{
|
|
if (Item* itemCaster = GetCastItem())
|
|
{
|
|
Player* player = GetCaster()->ToPlayer();
|
|
uint32 item = 0;
|
|
switch (itemCaster->GetEntry())
|
|
{
|
|
case GREEN_EMPTY_KEG:
|
|
case BLUE_EMPTY_KEG:
|
|
item = itemCaster->GetEntry() + urand(1, 5); // 5 items, id in range empty+1-5
|
|
break;
|
|
case YELLOW_EMPTY_KEG:
|
|
if (uint8 num = urand(0, 4))
|
|
item = 32916 + num;
|
|
else
|
|
item = 32915;
|
|
break;
|
|
}
|
|
|
|
if (item && player->AddItem(item, 1)) // ensure filled keg is stored
|
|
{
|
|
player->DestroyItemCount(itemCaster->GetEntry(), 1, true);
|
|
GetSpell()->m_CastItem = nullptr;
|
|
GetSpell()->m_castItemGUID = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
AfterHit += SpellHitFn(spell_brewfest_fill_keg_SpellScript::HandleAfterHit);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_brewfest_fill_keg_SpellScript();
|
|
};
|
|
};
|
|
|
|
class spell_brewfest_unfill_keg : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_brewfest_unfill_keg() : SpellScriptLoader("spell_brewfest_unfill_keg") { }
|
|
|
|
class spell_brewfest_unfill_keg_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_brewfest_unfill_keg_SpellScript);
|
|
|
|
uint32 GetEmptyEntry(uint32 baseEntry)
|
|
{
|
|
switch (baseEntry)
|
|
{
|
|
case 37893:
|
|
case 37894:
|
|
case 37895:
|
|
case 37896:
|
|
case 37897:
|
|
return GREEN_EMPTY_KEG;
|
|
case 33017:
|
|
case 33018:
|
|
case 33019:
|
|
case 33020:
|
|
case 33021:
|
|
return BLUE_EMPTY_KEG;
|
|
case 32915:
|
|
case 32917:
|
|
case 32918:
|
|
case 32919:
|
|
case 32920:
|
|
return YELLOW_EMPTY_KEG;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void HandleAfterHit()
|
|
{
|
|
if (GetCaster() && GetCaster()->ToPlayer())
|
|
{
|
|
if (Item* itemCaster = GetCastItem())
|
|
{
|
|
uint32 item = GetEmptyEntry(itemCaster->GetEntry());
|
|
Player* player = GetCaster()->ToPlayer();
|
|
|
|
if (item && player->AddItem(item, 1)) // ensure filled keg is stored
|
|
{
|
|
player->DestroyItemCount(itemCaster->GetEntry(), 1, true);
|
|
GetSpell()->m_CastItem = nullptr;
|
|
GetSpell()->m_castItemGUID = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
AfterHit += SpellHitFn(spell_brewfest_unfill_keg_SpellScript::HandleAfterHit);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_brewfest_unfill_keg_SpellScript();
|
|
};
|
|
};
|
|
|
|
class spell_brewfest_toss_mug : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_brewfest_toss_mug() : SpellScriptLoader("spell_brewfest_toss_mug") { }
|
|
|
|
class spell_brewfest_toss_mug_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_brewfest_toss_mug_SpellScript);
|
|
|
|
SpellCastResult CheckCast()
|
|
{
|
|
if (Unit* caster = GetCaster())
|
|
{
|
|
float z = caster->GetMapHeight(caster->GetPositionX() + 14 * cos(caster->GetOrientation()), caster->GetPositionY() + 14 * sin(caster->GetOrientation()), caster->GetPositionZ());
|
|
WorldLocation pPosition = WorldLocation(caster->GetMapId(), caster->GetPositionX() + 14 * cos(caster->GetOrientation()), caster->GetPositionY() + 14 * sin(caster->GetOrientation()), z, caster->GetOrientation());
|
|
SetExplTargetDest(pPosition);
|
|
}
|
|
|
|
return SPELL_CAST_OK;
|
|
}
|
|
|
|
void FilterTargets(std::list<WorldObject*>& targets)
|
|
{
|
|
Unit* caster = GetCaster();
|
|
if (!caster)
|
|
return;
|
|
|
|
WorldObject* target = nullptr;
|
|
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
|
if (caster->HasInLine((*itr), 2.0f))
|
|
{
|
|
target = (*itr);
|
|
break;
|
|
}
|
|
|
|
targets.clear();
|
|
if (target)
|
|
targets.push_back(target);
|
|
|
|
targets.push_back(caster);
|
|
}
|
|
|
|
void HandleBeforeHit()
|
|
{
|
|
if (Unit* target = GetHitUnit())
|
|
{
|
|
if (!GetCaster() || target->GetGUID() == GetCaster()->GetGUID())
|
|
return;
|
|
|
|
WorldLocation pPosition = WorldLocation(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 4.0f, target->GetOrientation());
|
|
SetExplTargetDest(pPosition);
|
|
}
|
|
}
|
|
|
|
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
|
{
|
|
Creature* cr = nullptr;
|
|
Unit* caster = GetCaster();
|
|
if (!caster)
|
|
return;
|
|
|
|
if (!GetHitUnit() || GetHitUnit()->GetGUID() != caster->GetGUID())
|
|
return;
|
|
|
|
if (caster->GetMapId() == 1) // Kalimdor
|
|
{
|
|
if ((cr = caster->FindNearestCreature(NPC_NORMAL_VOODOO, 40.0f)))
|
|
cr->CastSpell(caster, SPELL_THROW_MUG_TO_PLAYER, true);
|
|
else if ((cr = caster->FindNearestCreature(NPC_NORMAL_DROHN, 40.0f)))
|
|
cr->CastSpell(caster, SPELL_THROW_MUG_TO_PLAYER, true);
|
|
else if ((cr = caster->FindNearestCreature(NPC_NORMAL_GORDOK, 40.0f)))
|
|
cr->CastSpell(caster, SPELL_THROW_MUG_TO_PLAYER, true);
|
|
}
|
|
else // EK
|
|
{
|
|
if ((cr = caster->FindNearestCreature(NPC_NORMAL_THUNDERBREW, 40.0f)))
|
|
cr->CastSpell(caster, SPELL_THROW_MUG_TO_PLAYER, true);
|
|
else if ((cr = caster->FindNearestCreature(NPC_NORMAL_BARLEYBREW, 40.0f)))
|
|
cr->CastSpell(caster, SPELL_THROW_MUG_TO_PLAYER, true);
|
|
else if ((cr = caster->FindNearestCreature(NPC_NORMAL_GORDOK, 40.0f)))
|
|
cr->CastSpell(caster, SPELL_THROW_MUG_TO_PLAYER, true);
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnCheckCast += SpellCheckCastFn(spell_brewfest_toss_mug_SpellScript::CheckCast);
|
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_brewfest_toss_mug_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
|
BeforeHit += SpellHitFn(spell_brewfest_toss_mug_SpellScript::HandleBeforeHit);
|
|
OnEffectHitTarget += SpellEffectFn(spell_brewfest_toss_mug_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_brewfest_toss_mug_SpellScript();
|
|
};
|
|
};
|
|
|
|
class spell_brewfest_add_mug : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_brewfest_add_mug() : SpellScriptLoader("spell_brewfest_add_mug") { }
|
|
|
|
class spell_brewfest_add_mug_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_brewfest_add_mug_SpellScript);
|
|
|
|
void HandleDummyEffect(SpellEffIndex /*effIndex*/)
|
|
{
|
|
if (Unit* target = GetHitUnit())
|
|
target->CastSpell(target, SPELL_ADD_MUG, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_brewfest_add_mug_SpellScript::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_brewfest_add_mug_SpellScript();
|
|
};
|
|
};
|
|
|
|
//
|
|
enum brewBubble
|
|
{
|
|
SPELL_BUBBLE_BUILD_UP = 49828,
|
|
};
|
|
|
|
class npc_brew_bubble : public CreatureScript
|
|
{
|
|
public:
|
|
npc_brew_bubble() : CreatureScript("npc_brew_bubble") { }
|
|
|
|
struct npc_brew_bubbleAI : public NullCreatureAI
|
|
{
|
|
npc_brew_bubbleAI(Creature* creature) : NullCreatureAI(creature)
|
|
{
|
|
}
|
|
|
|
uint32 timer;
|
|
|
|
void Reset() override
|
|
{
|
|
me->SetReactState(REACT_AGGRESSIVE);
|
|
me->GetMotionMaster()->MoveRandom(15.0f);
|
|
timer = 0;
|
|
}
|
|
|
|
void DoAction(int32) override
|
|
{
|
|
timer = 0;
|
|
}
|
|
|
|
void MoveInLineOfSight(Unit* target) override
|
|
{
|
|
if (target->GetEntry() == me->GetEntry())
|
|
if (me->IsWithinDist(target, 1.0f))
|
|
{
|
|
uint8 stacksMe = me->GetAuraCount(SPELL_BUBBLE_BUILD_UP);
|
|
uint8 stacksTarget = target->GetAuraCount(SPELL_BUBBLE_BUILD_UP);
|
|
if (stacksMe >= stacksTarget)
|
|
{
|
|
if (Aura* aura = me->GetAura(SPELL_BUBBLE_BUILD_UP))
|
|
aura->ModStackAmount(stacksTarget + 1);
|
|
else
|
|
me->AddAura(SPELL_BUBBLE_BUILD_UP, me);
|
|
|
|
target->ToCreature()->DespawnOrUnsummon();
|
|
DoAction(0);
|
|
}
|
|
else if (Aura* aura = target->GetAura(SPELL_BUBBLE_BUILD_UP))
|
|
{
|
|
aura->ModStackAmount(stacksMe);
|
|
|
|
target->ToCreature()->AI()->DoAction(0);
|
|
me->DespawnOrUnsummon();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
timer += diff;
|
|
if (timer >= 25000)
|
|
{
|
|
timer = 0;
|
|
me->DespawnOrUnsummon();
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_brew_bubbleAI(creature);
|
|
}
|
|
};
|
|
|
|
void AddSC_event_brewfest_scripts()
|
|
{
|
|
// Npcs
|
|
new npc_brewfest_reveler();
|
|
new npc_coren_direbrew();
|
|
new npc_coren_direbrew_sisters();
|
|
new npc_brewfest_keg_thrower();
|
|
new npc_brewfest_keg_reciver();
|
|
new npc_brewfest_bark_trigger();
|
|
new npc_dark_iron_attack_generator();
|
|
new npc_dark_iron_attack_mole_machine();
|
|
new npc_dark_iron_guzzler();
|
|
new npc_brewfest_super_brew_trigger();
|
|
|
|
// Spells
|
|
// ram
|
|
new spell_brewfest_main_ram_buff();
|
|
new spell_brewfest_ram_fatigue();
|
|
new spell_brewfest_apple_trap();
|
|
// other
|
|
new spell_q11117_catch_the_wild_wolpertinger();
|
|
new spell_brewfest_fill_keg();
|
|
new spell_brewfest_unfill_keg();
|
|
new spell_brewfest_toss_mug();
|
|
new spell_brewfest_add_mug();
|
|
|
|
// beer effect
|
|
new npc_brew_bubble();
|
|
}
|