1127 lines
43 KiB
C++
1127 lines
43 KiB
C++
/* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "Battlefield.h"
|
|
#include "BattlefieldMgr.h"
|
|
#include "BattlefieldWG.h"
|
|
#include "CombatAI.h"
|
|
#include "GameGraveyard.h"
|
|
#include "GameObjectAI.h"
|
|
#include "ObjectMgr.h"
|
|
#include "Player.h"
|
|
#include "PoolMgr.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "ScriptedGossip.h"
|
|
#include "ScriptMgr.h"
|
|
#include "ScriptSystem.h"
|
|
#include "SpellScript.h"
|
|
#include "Vehicle.h"
|
|
#include "World.h"
|
|
#include "WorldSession.h"
|
|
|
|
#define GOSSIP_HELLO_DEMO1 "Build catapult."
|
|
#define GOSSIP_HELLO_DEMO2 "Build demolisher."
|
|
#define GOSSIP_HELLO_DEMO3 "Build siege engine."
|
|
#define GOSSIP_HELLO_DEMO4 "I cannot build more!"
|
|
|
|
enum eWGqueuenpctext
|
|
{
|
|
WG_NPCQUEUE_TEXT_H_NOWAR = 14775,
|
|
WG_NPCQUEUE_TEXT_H_QUEUE = 14790,
|
|
WG_NPCQUEUE_TEXT_H_WAR = 14777,
|
|
WG_NPCQUEUE_TEXT_A_NOWAR = 14782,
|
|
WG_NPCQUEUE_TEXT_A_QUEUE = 14791,
|
|
WG_NPCQUEUE_TEXT_A_WAR = 14781,
|
|
WG_NPCQUEUE_TEXTOPTION_JOIN = -1850507,
|
|
};
|
|
|
|
enum Spells
|
|
{
|
|
// Demolisher engineers spells
|
|
SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE = 61409, //
|
|
SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE = 56662, // Which faction uses which ?
|
|
SPELL_BUILD_CATAPULT_FORCE = 56664,
|
|
SPELL_BUILD_DEMOLISHER_FORCE = 56659,
|
|
SPELL_ACTIVATE_CONTROL_ARMS = 49899,
|
|
|
|
SPELL_VEHICLE_TELEPORT = 49759,
|
|
|
|
// Spirit guide
|
|
SPELL_CHANNEL_SPIRIT_HEAL = 22011,
|
|
|
|
// RP-GG
|
|
SPELL_RP_GG_TRIGGER_MISSILE = 49769,
|
|
|
|
// Teleport to fortress
|
|
SPELL_TELEPORT_TO_FORTRESS = 59096,
|
|
};
|
|
|
|
enum CreatureIds
|
|
{
|
|
NPC_GOBLIN_MECHANIC = 30400,
|
|
NPC_GNOMISH_ENGINEER = 30499,
|
|
|
|
NPC_WINTERGRASP_CONTROL_ARMS = 27852,
|
|
|
|
NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC = 23742,
|
|
};
|
|
|
|
enum QuestIds
|
|
{
|
|
QUEST_BONES_AND_ARROWS_HORDE_ATT = 13199,
|
|
QUEST_JINXING_THE_WALLS_HORDE_ATT = 13202,
|
|
QUEST_SLAY_THEM_ALL_HORDE_ATT = 13180,
|
|
QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT = 13200,
|
|
QUEST_HEALING_WITH_ROSES_HORDE_ATT = 13201,
|
|
QUEST_DEFEND_THE_SIEGE_HORDE_ATT = 13223,
|
|
|
|
QUEST_BONES_AND_ARROWS_HORDE_DEF = 13193,
|
|
QUEST_WARDING_THE_WALLS_HORDE_DEF = 13192,
|
|
QUEST_SLAY_THEM_ALL_HORDE_DEF = 13178,
|
|
QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF = 13191,
|
|
QUEST_HEALING_WITH_ROSES_HORDE_DEF = 13194,
|
|
QUEST_TOPPLING_THE_TOWERS_HORDE_DEF = 13539,
|
|
QUEST_STOP_THE_SIEGE_HORDE_DEF = 13185,
|
|
|
|
QUEST_BONES_AND_ARROWS_ALLIANCE_ATT = 13196,
|
|
QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT = 13198,
|
|
QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT = 13179,
|
|
QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT = 13222,
|
|
QUEST_A_RARE_HERB_ALLIANCE_ATT = 13195,
|
|
QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_ATT = 13197,
|
|
|
|
QUEST_BONES_AND_ARROWS_ALLIANCE_DEF = 13154,
|
|
QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF = 13153,
|
|
QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF = 13177,
|
|
QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF = 13538,
|
|
QUEST_STOP_THE_SIEGE_ALLIANCE_DEF = 13186,
|
|
QUEST_A_RARE_HERB_ALLIANCE_DEF = 13156,
|
|
QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_DEF = 236,
|
|
};
|
|
|
|
uint8 const MAX_WINTERGRASP_VEHICLES = 4;
|
|
|
|
uint32 const vehiclesList[MAX_WINTERGRASP_VEHICLES] =
|
|
{
|
|
NPC_WINTERGRASP_CATAPULT,
|
|
NPC_WINTERGRASP_DEMOLISHER,
|
|
NPC_WINTERGRASP_SIEGE_ENGINE_ALLIANCE,
|
|
NPC_WINTERGRASP_SIEGE_ENGINE_HORDE
|
|
};
|
|
|
|
////////////////////////////////////////////////
|
|
/////// NPCs
|
|
////////////////////////////////////////////////
|
|
|
|
class npc_wg_demolisher_engineer : public CreatureScript
|
|
{
|
|
public:
|
|
npc_wg_demolisher_engineer() : CreatureScript("npc_wg_demolisher_engineer") { }
|
|
|
|
bool OnGossipHello(Player* player, Creature* creature) override
|
|
{
|
|
if (creature->IsQuestGiver())
|
|
player->PrepareQuestMenu(creature->GetGUID());
|
|
|
|
if (canBuild(creature))
|
|
{
|
|
if (player->HasAura(SPELL_CORPORAL))
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
|
else if (player->HasAura(SPELL_LIEUTENANT))
|
|
{
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
|
}
|
|
}
|
|
else
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9);
|
|
|
|
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
|
|
return true;
|
|
}
|
|
|
|
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender */, uint32 action) override
|
|
{
|
|
CloseGossipMenuFor(player);
|
|
|
|
if (canBuild(creature))
|
|
{
|
|
switch (action - GOSSIP_ACTION_INFO_DEF)
|
|
{
|
|
case 0:
|
|
creature->CastSpell(player, SPELL_BUILD_CATAPULT_FORCE, true);
|
|
break;
|
|
case 1:
|
|
creature->CastSpell(player, SPELL_BUILD_DEMOLISHER_FORCE, true);
|
|
break;
|
|
case 2:
|
|
creature->CastSpell(player, player->GetTeamId() == TEAM_ALLIANCE ? SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE : SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE, true);
|
|
break;
|
|
}
|
|
creature->CastSpell(creature, SPELL_ACTIVATE_CONTROL_ARMS, true);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
bool canBuild(Creature* creature)
|
|
{
|
|
Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
|
|
if (!wintergrasp)
|
|
return false;
|
|
|
|
switch (creature->GetEntry())
|
|
{
|
|
case NPC_GOBLIN_MECHANIC:
|
|
return (wintergrasp->GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H) > wintergrasp->GetData(BATTLEFIELD_WG_DATA_VEHICLE_H));
|
|
case NPC_GNOMISH_ENGINEER:
|
|
return (wintergrasp->GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A) > wintergrasp->GetData(BATTLEFIELD_WG_DATA_VEHICLE_A));
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
class npc_wg_spirit_guide : public CreatureScript
|
|
{
|
|
public:
|
|
npc_wg_spirit_guide() : CreatureScript("npc_wg_spirit_guide") { }
|
|
|
|
bool OnGossipHello(Player* player, Creature* creature) override
|
|
{
|
|
if (creature->IsQuestGiver())
|
|
player->PrepareQuestMenu(creature->GetGUID());
|
|
|
|
Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
|
|
if (!wintergrasp)
|
|
return true;
|
|
|
|
GraveyardVect graveyard = wintergrasp->GetGraveyardVector();
|
|
for (uint8 i = 0; i < graveyard.size(); i++)
|
|
if (graveyard[i]->GetControlTeamId() == player->GetTeamId())
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, sObjectMgr->GetAcoreStringForDBCLocale(((BfGraveyardWG*)graveyard[i])->GetTextId()), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + i);
|
|
|
|
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
|
|
return true;
|
|
}
|
|
|
|
bool OnGossipSelect(Player* player, Creature* /*creature */, uint32 /*sender */, uint32 action) override
|
|
{
|
|
CloseGossipMenuFor(player);
|
|
|
|
Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
|
|
if (wintergrasp)
|
|
{
|
|
GraveyardVect gy = wintergrasp->GetGraveyardVector();
|
|
for (uint8 i = 0; i < gy.size(); i++)
|
|
if (action - GOSSIP_ACTION_INFO_DEF == i && gy[i]->GetControlTeamId() == player->GetTeamId())
|
|
if (GraveyardStruct const* safeLoc = sGraveyard->GetGraveyard(gy[i]->GetGraveyardId()))
|
|
player->TeleportTo(safeLoc->Map, safeLoc->x, safeLoc->y, safeLoc->z, 0);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
struct npc_wg_spirit_guideAI : public ScriptedAI
|
|
{
|
|
npc_wg_spirit_guideAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
me->setActive(true);
|
|
}
|
|
|
|
void UpdateAI(uint32 /*diff*/) override
|
|
{
|
|
if (!me->HasUnitState(UNIT_STATE_CASTING))
|
|
DoCast(me, SPELL_CHANNEL_SPIRIT_HEAL);
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_wg_spirit_guideAI(creature);
|
|
}
|
|
};
|
|
|
|
enum eWgQueue
|
|
{
|
|
EVENT_ARCANIST_BRAEDIN_YELL = 1,
|
|
EVENT_MAGISTER_SURDIEL_YELL = 2,
|
|
EVENT_SPELL_FROST_ARMOR = 3,
|
|
|
|
SAY_ARCANIST_BRAEDIN = 0,
|
|
SAY_MAGISTER_SURDIEL = 0,
|
|
|
|
NPC_ARCANIST_BRAEDIN = 32169,
|
|
NPC_MAGISTER_SURDIEL = 32170,
|
|
|
|
SPELL_FROST_ARMOR = 31256
|
|
};
|
|
|
|
class npc_wg_queue : public CreatureScript
|
|
{
|
|
public:
|
|
npc_wg_queue() : CreatureScript("npc_wg_queue") { }
|
|
|
|
bool OnGossipHello(Player* player, Creature* creature) override
|
|
{
|
|
if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK))
|
|
return false;
|
|
|
|
if (creature->IsQuestGiver())
|
|
player->PrepareQuestMenu(creature->GetGUID());
|
|
|
|
Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
|
|
if (!wintergrasp)
|
|
return true;
|
|
|
|
if (wintergrasp->IsWarTime())
|
|
{
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT_19, "Queue for Wintergrasp.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
|
SendGossipMenuFor(player, wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_WAR : WG_NPCQUEUE_TEXT_A_WAR, creature->GetGUID());
|
|
}
|
|
else
|
|
{
|
|
uint32 timer = wintergrasp->GetTimer() / 1000;
|
|
player->SendUpdateWorldState(4354, time(nullptr) + timer);
|
|
if (timer < 15 * MINUTE)
|
|
{
|
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Queue for Wintergrasp.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
|
SendGossipMenuFor(player, wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_QUEUE : WG_NPCQUEUE_TEXT_A_QUEUE, creature->GetGUID());
|
|
}
|
|
else
|
|
SendGossipMenuFor(player, wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_NOWAR : WG_NPCQUEUE_TEXT_A_NOWAR, creature->GetGUID());
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool OnGossipSelect(Player* player, Creature* /*creature */, uint32 /*sender */, uint32 /*action*/) override
|
|
{
|
|
CloseGossipMenuFor(player);
|
|
|
|
Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
|
|
if (!wintergrasp)
|
|
return true;
|
|
|
|
if (wintergrasp->IsWarTime())
|
|
wintergrasp->InvitePlayerToWar(player);
|
|
else
|
|
{
|
|
uint32 timer = wintergrasp->GetTimer() / 1000;
|
|
if (timer < 15 * MINUTE)
|
|
wintergrasp->InvitePlayerToQueue(player);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
struct npc_wg_queueAI : public ScriptedAI
|
|
{
|
|
npc_wg_queueAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
if (creature->GetEntry() == NPC_ARCANIST_BRAEDIN)
|
|
events.ScheduleEvent(EVENT_ARCANIST_BRAEDIN_YELL, 0);
|
|
else if (creature->GetEntry() == NPC_MAGISTER_SURDIEL)
|
|
events.ScheduleEvent(EVENT_MAGISTER_SURDIEL_YELL, 0);
|
|
|
|
events.ScheduleEvent(EVENT_SPELL_FROST_ARMOR, 0);
|
|
}
|
|
|
|
EventMap events;
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
if (!sWorld->getBoolConfig(CONFIG_WINTERGRASP_ENABLE))
|
|
return;
|
|
|
|
ScriptedAI::UpdateAI(diff);
|
|
|
|
events.Update(diff);
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_ARCANIST_BRAEDIN_YELL:
|
|
if (Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
|
|
{
|
|
if (wintergrasp->IsWarTime())
|
|
{
|
|
Talk(SAY_ARCANIST_BRAEDIN);
|
|
events.ScheduleEvent(EVENT_ARCANIST_BRAEDIN_YELL, 240000);
|
|
break;
|
|
}
|
|
}
|
|
events.ScheduleEvent(EVENT_ARCANIST_BRAEDIN_YELL, 5000);
|
|
break;
|
|
case EVENT_MAGISTER_SURDIEL_YELL:
|
|
if (Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
|
|
{
|
|
uint32 timer = wintergrasp->GetTimer() / 1000;
|
|
if (!wintergrasp->IsWarTime() && timer < 5 * MINUTE && timer > 4 * MINUTE)
|
|
{
|
|
Talk(SAY_MAGISTER_SURDIEL);
|
|
events.ScheduleEvent(EVENT_MAGISTER_SURDIEL_YELL, 300000);
|
|
break;
|
|
}
|
|
}
|
|
events.ScheduleEvent(EVENT_MAGISTER_SURDIEL_YELL, 5000);
|
|
break;
|
|
case EVENT_SPELL_FROST_ARMOR:
|
|
me->CastSpell(me, SPELL_FROST_ARMOR, true);
|
|
events.ScheduleEvent(EVENT_SPELL_FROST_ARMOR, 900000);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_wg_queueAI(creature);
|
|
}
|
|
};
|
|
|
|
class npc_wg_quest_giver : public CreatureScript
|
|
{
|
|
public:
|
|
npc_wg_quest_giver() : CreatureScript("npc_wg_quest_giver") { }
|
|
|
|
bool OnGossipHello(Player* player, Creature* creature) override
|
|
{
|
|
if (creature->IsQuestGiver())
|
|
player->PrepareQuestMenu(creature->GetGUID());
|
|
|
|
Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
|
|
if (!wintergrasp)
|
|
return true;
|
|
|
|
if (creature->IsQuestGiver())
|
|
{
|
|
QuestRelationBounds objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry());
|
|
QuestRelationBounds objectQIR = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(creature->GetEntry());
|
|
|
|
QuestMenu& qm = player->PlayerTalkClass->GetQuestMenu();
|
|
qm.ClearMenu();
|
|
|
|
for (QuestRelations::const_iterator i = objectQIR.first; i != objectQIR.second; ++i)
|
|
{
|
|
uint32 quest_id = i->second;
|
|
QuestStatus status = player->GetQuestStatus(quest_id);
|
|
if (status == QUEST_STATUS_COMPLETE)
|
|
qm.AddMenuItem(quest_id, 4);
|
|
else if (status == QUEST_STATUS_INCOMPLETE)
|
|
qm.AddMenuItem(quest_id, 4);
|
|
//else if (status == QUEST_STATUS_AVAILABLE)
|
|
// qm.AddMenuItem(quest_id, 2);
|
|
}
|
|
|
|
// xinef: add att/def doubles if this quest is spawned
|
|
std::vector<uint32> questRelationVector;
|
|
for (QuestRelations::const_iterator i = objectQR.first; i != objectQR.second; ++i)
|
|
{
|
|
uint32 questId = i->second;
|
|
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
|
if (!quest)
|
|
continue;
|
|
|
|
switch (questId)
|
|
{
|
|
case QUEST_BONES_AND_ARROWS_ALLIANCE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_BONES_AND_ARROWS_ALLIANCE_DEF))
|
|
continue;
|
|
questRelationVector.push_back(QUEST_BONES_AND_ARROWS_ALLIANCE_ATT);
|
|
break;
|
|
case QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF))
|
|
continue;
|
|
questRelationVector.push_back(QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT);
|
|
break;
|
|
case QUEST_A_RARE_HERB_ALLIANCE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_A_RARE_HERB_ALLIANCE_DEF))
|
|
continue;
|
|
questRelationVector.push_back(QUEST_A_RARE_HERB_ALLIANCE_ATT);
|
|
break;
|
|
case QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_DEF))
|
|
continue;
|
|
questRelationVector.push_back(QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_ATT);
|
|
break;
|
|
case QUEST_BONES_AND_ARROWS_HORDE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_BONES_AND_ARROWS_HORDE_DEF))
|
|
continue;
|
|
questRelationVector.push_back(QUEST_BONES_AND_ARROWS_HORDE_ATT);
|
|
break;
|
|
case QUEST_JINXING_THE_WALLS_HORDE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_WARDING_THE_WALLS_HORDE_DEF))
|
|
continue;
|
|
questRelationVector.push_back(QUEST_JINXING_THE_WALLS_HORDE_ATT);
|
|
break;
|
|
case QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF))
|
|
continue;
|
|
questRelationVector.push_back(QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT);
|
|
break;
|
|
case QUEST_HEALING_WITH_ROSES_HORDE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_HEALING_WITH_ROSES_HORDE_DEF))
|
|
continue;
|
|
questRelationVector.push_back(QUEST_HEALING_WITH_ROSES_HORDE_ATT);
|
|
break;
|
|
default:
|
|
questRelationVector.push_back(questId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (std::vector<uint32>::const_iterator i = questRelationVector.begin(); i != questRelationVector.end(); ++i)
|
|
{
|
|
uint32 questId = *i;
|
|
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
|
switch (questId)
|
|
{
|
|
// Horde attacker
|
|
case QUEST_BONES_AND_ARROWS_HORDE_ATT:
|
|
case QUEST_JINXING_THE_WALLS_HORDE_ATT:
|
|
case QUEST_SLAY_THEM_ALL_HORDE_ATT:
|
|
case QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT:
|
|
case QUEST_HEALING_WITH_ROSES_HORDE_ATT:
|
|
case QUEST_DEFEND_THE_SIEGE_HORDE_ATT:
|
|
if (wintergrasp->GetAttackerTeam() == TEAM_HORDE)
|
|
{
|
|
QuestStatus status = player->GetQuestStatus(questId);
|
|
|
|
if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 4);
|
|
else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 2);
|
|
}
|
|
break;
|
|
// Horde defender
|
|
case QUEST_BONES_AND_ARROWS_HORDE_DEF:
|
|
case QUEST_WARDING_THE_WALLS_HORDE_DEF:
|
|
case QUEST_SLAY_THEM_ALL_HORDE_DEF:
|
|
case QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF:
|
|
case QUEST_HEALING_WITH_ROSES_HORDE_DEF:
|
|
case QUEST_TOPPLING_THE_TOWERS_HORDE_DEF:
|
|
case QUEST_STOP_THE_SIEGE_HORDE_DEF:
|
|
if (wintergrasp->GetDefenderTeam() == TEAM_HORDE)
|
|
{
|
|
QuestStatus status = player->GetQuestStatus(questId);
|
|
|
|
if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 4);
|
|
else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 2);
|
|
}
|
|
break;
|
|
// Alliance attacker
|
|
case QUEST_BONES_AND_ARROWS_ALLIANCE_ATT:
|
|
case QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT:
|
|
case QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT:
|
|
case QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT:
|
|
case QUEST_A_RARE_HERB_ALLIANCE_ATT:
|
|
case QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_ATT:
|
|
if (wintergrasp->GetAttackerTeam() == TEAM_ALLIANCE)
|
|
{
|
|
QuestStatus status = player->GetQuestStatus(questId);
|
|
|
|
if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 4);
|
|
else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 2);
|
|
}
|
|
break;
|
|
// Alliance defender
|
|
case QUEST_BONES_AND_ARROWS_ALLIANCE_DEF:
|
|
case QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF:
|
|
case QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF:
|
|
case QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF:
|
|
case QUEST_STOP_THE_SIEGE_ALLIANCE_DEF:
|
|
case QUEST_A_RARE_HERB_ALLIANCE_DEF:
|
|
case QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_DEF:
|
|
if (wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE)
|
|
{
|
|
QuestStatus status = player->GetQuestStatus(questId);
|
|
|
|
if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 4);
|
|
else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 2);
|
|
}
|
|
break;
|
|
default:
|
|
QuestStatus status = player->GetQuestStatus(questId);
|
|
|
|
if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 4);
|
|
else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false))
|
|
qm.AddMenuItem(questId, 2);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
|
|
return true;
|
|
}
|
|
|
|
uint32 GetDialogStatus(Player* player, Creature* creature) override
|
|
{
|
|
QuestRelationBounds qr = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry());
|
|
QuestRelationBounds qir = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(creature->GetEntry());
|
|
QuestGiverStatus result = DIALOG_STATUS_NONE;
|
|
|
|
for (QuestRelations::const_iterator i = qir.first; i != qir.second; ++i)
|
|
{
|
|
QuestGiverStatus result2 = DIALOG_STATUS_NONE;
|
|
uint32 questId = i->second;
|
|
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
|
if (!quest)
|
|
continue;
|
|
|
|
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_AVAILABLE, quest->GetQuestId());
|
|
if (!sConditionMgr->IsObjectMeetToConditions(player, conditions))
|
|
continue;
|
|
|
|
QuestStatus status = player->GetQuestStatus(questId);
|
|
if ((status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(questId)) ||
|
|
(quest->IsAutoComplete() && player->CanTakeQuest(quest, false)))
|
|
{
|
|
if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly())
|
|
result2 = DIALOG_STATUS_REWARD_REP;
|
|
else
|
|
result2 = DIALOG_STATUS_REWARD;
|
|
}
|
|
else if (status == QUEST_STATUS_INCOMPLETE)
|
|
result2 = DIALOG_STATUS_INCOMPLETE;
|
|
|
|
if (result2 > result)
|
|
result = result2;
|
|
}
|
|
|
|
for (QuestRelations::const_iterator i = qr.first; i != qr.second; ++i)
|
|
{
|
|
QuestGiverStatus result2 = DIALOG_STATUS_NONE;
|
|
uint32 questId = i->second;
|
|
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
|
|
if (!quest)
|
|
continue;
|
|
|
|
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_AVAILABLE, quest->GetQuestId());
|
|
if (!sConditionMgr->IsObjectMeetToConditions(player, conditions))
|
|
continue;
|
|
|
|
switch (questId)
|
|
{
|
|
case QUEST_BONES_AND_ARROWS_ALLIANCE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_BONES_AND_ARROWS_ALLIANCE_DEF))
|
|
continue;
|
|
break;
|
|
case QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF))
|
|
continue;
|
|
break;
|
|
case QUEST_A_RARE_HERB_ALLIANCE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_A_RARE_HERB_ALLIANCE_DEF))
|
|
continue;
|
|
break;
|
|
case QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_FUELING_THE_DEMOLISHERS_ALLIANCE_DEF))
|
|
continue;
|
|
break;
|
|
case QUEST_BONES_AND_ARROWS_HORDE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_BONES_AND_ARROWS_HORDE_DEF))
|
|
continue;
|
|
break;
|
|
case QUEST_JINXING_THE_WALLS_HORDE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_WARDING_THE_WALLS_HORDE_DEF))
|
|
continue;
|
|
break;
|
|
case QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF))
|
|
continue;
|
|
break;
|
|
case QUEST_HEALING_WITH_ROSES_HORDE_ATT:
|
|
if (!sPoolMgr->IsSpawnedObject<Quest>(QUEST_HEALING_WITH_ROSES_HORDE_DEF))
|
|
continue;
|
|
break;
|
|
}
|
|
|
|
QuestStatus status = player->GetQuestStatus(questId);
|
|
if (status == QUEST_STATUS_NONE)
|
|
{
|
|
if (player->CanSeeStartQuest(quest))
|
|
{
|
|
if (player->SatisfyQuestLevel(quest, false))
|
|
{
|
|
if (quest->IsAutoComplete())
|
|
result2 = DIALOG_STATUS_REWARD_REP;
|
|
else if (player->getLevel() <= (player->GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
|
|
{
|
|
if (quest->IsDaily())
|
|
result2 = DIALOG_STATUS_AVAILABLE_REP;
|
|
else
|
|
result2 = DIALOG_STATUS_AVAILABLE;
|
|
}
|
|
else
|
|
result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
|
|
}
|
|
else
|
|
result2 = DIALOG_STATUS_UNAVAILABLE;
|
|
}
|
|
}
|
|
|
|
if (result2 > result)
|
|
result = result2;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
};
|
|
|
|
class npc_wg_siege_machine : public CreatureScript
|
|
{
|
|
public:
|
|
npc_wg_siege_machine() : CreatureScript("npc_wg_siege_machine") { }
|
|
|
|
struct npc_wg_siege_machineAI : public VehicleAI
|
|
{
|
|
npc_wg_siege_machineAI(Creature* creature) : VehicleAI(creature)
|
|
{
|
|
checkTimer = 0;
|
|
}
|
|
|
|
uint32 checkTimer;
|
|
|
|
bool CanControlVehicle(Unit* passenger)
|
|
{
|
|
if (passenger->HasAura(SPELL_LIEUTENANT))
|
|
return true;
|
|
|
|
if (me->GetEntry() == NPC_WINTERGRASP_CATAPULT && passenger->HasAura(SPELL_CORPORAL))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
VehicleAI::UpdateAI(diff);
|
|
|
|
checkTimer += diff;
|
|
if (checkTimer >= 1000)
|
|
{
|
|
checkTimer = 0;
|
|
if (me->GetVehicleKit())
|
|
for (SeatMap::iterator itr = me->GetVehicleKit()->Seats.begin(); itr != me->GetVehicleKit()->Seats.end(); ++itr)
|
|
if (const VehicleSeatEntry* seatInfo = itr->second.SeatInfo)
|
|
if (seatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
|
|
if (Unit* passenger = ObjectAccessor::GetUnit(*me, itr->second.Passenger.Guid))
|
|
if (!CanControlVehicle(passenger))
|
|
{
|
|
passenger->ExitVehicle();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return new npc_wg_siege_machineAI(creature);
|
|
}
|
|
};
|
|
|
|
////////////////////////////////////////////////
|
|
/////// GOs
|
|
////////////////////////////////////////////////
|
|
|
|
class go_wg_vehicle_teleporter : public GameObjectScript
|
|
{
|
|
public:
|
|
go_wg_vehicle_teleporter() : GameObjectScript("go_wg_vehicle_teleporter") { }
|
|
|
|
struct go_wg_vehicle_teleporterAI : public GameObjectAI
|
|
{
|
|
go_wg_vehicle_teleporterAI(GameObject* gameObject) : GameObjectAI(gameObject),
|
|
_checkTimer(0)
|
|
{
|
|
}
|
|
|
|
bool IsFriendly(Unit* passenger)
|
|
{
|
|
return ((go->GetUInt32Value(GAMEOBJECT_FACTION) == WintergraspFaction[TEAM_HORDE] && passenger->getRaceMask() & RACEMASK_HORDE) ||
|
|
(go->GetUInt32Value(GAMEOBJECT_FACTION) == WintergraspFaction[TEAM_ALLIANCE] && passenger->getRaceMask() & RACEMASK_ALLIANCE));
|
|
}
|
|
|
|
Creature* IsValidVehicle(Creature* cVeh)
|
|
{
|
|
if (!cVeh->HasAura(SPELL_VEHICLE_TELEPORT))
|
|
if (Vehicle* vehicle = cVeh->GetVehicleKit())
|
|
if (Unit* passenger = vehicle->GetPassenger(0))
|
|
if (IsFriendly(passenger))
|
|
if (Creature* teleportTrigger = passenger->SummonTrigger(go->GetPositionX() - 60.0f, go->GetPositionY(), go->GetPositionZ() + 1.0f, cVeh->GetOrientation(), 1000))
|
|
return teleportTrigger;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
_checkTimer += diff;
|
|
if (_checkTimer >= 1000)
|
|
{
|
|
for (uint8 i = 0; i < MAX_WINTERGRASP_VEHICLES; i++)
|
|
if (Creature* vehicleCreature = go->FindNearestCreature(vehiclesList[i], 3.0f, true))
|
|
if (Creature* teleportTrigger = IsValidVehicle(vehicleCreature))
|
|
teleportTrigger->CastSpell(vehicleCreature, SPELL_VEHICLE_TELEPORT, true);
|
|
|
|
_checkTimer = 0;
|
|
}
|
|
}
|
|
private:
|
|
uint32 _checkTimer;
|
|
};
|
|
|
|
GameObjectAI* GetAI(GameObject* go) const override
|
|
{
|
|
return new go_wg_vehicle_teleporterAI(go);
|
|
}
|
|
};
|
|
|
|
////////////////////////////////////////////////
|
|
/////// SPELLs
|
|
////////////////////////////////////////////////
|
|
|
|
class spell_wintergrasp_force_building : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_wintergrasp_force_building() : SpellScriptLoader("spell_wintergrasp_force_building") { }
|
|
|
|
class spell_wintergrasp_force_building_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_wintergrasp_force_building_SpellScript);
|
|
|
|
bool Validate(SpellInfo const* /*spell*/) override
|
|
{
|
|
return ValidateSpellInfo(
|
|
{
|
|
SPELL_BUILD_CATAPULT_FORCE,
|
|
SPELL_BUILD_DEMOLISHER_FORCE,
|
|
SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE,
|
|
SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE
|
|
});
|
|
}
|
|
|
|
void HandleScript(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitDefaultEffect(effIndex);
|
|
if (Unit* target = GetHitUnit())
|
|
target->CastSpell(target, GetEffectValue(), false, nullptr, nullptr, target->GetGUID());
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_force_building_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_wintergrasp_force_building_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_wintergrasp_create_vehicle : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_wintergrasp_create_vehicle() : SpellScriptLoader("spell_wintergrasp_create_vehicle") { }
|
|
|
|
class spell_wintergrasp_create_vehicle_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_wintergrasp_create_vehicle_SpellScript);
|
|
|
|
void HandleSummon(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitEffect(effIndex);
|
|
|
|
uint32 entry = GetSpellInfo()->Effects[effIndex].MiscValue;
|
|
SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(GetSpellInfo()->Effects[effIndex].MiscValueB);
|
|
int32 duration = GetSpellInfo()->GetDuration();
|
|
if (!GetOriginalCaster() || !properties)
|
|
return;
|
|
|
|
if (TempSummon* summon = GetCaster()->GetMap()->SummonCreature(entry, *GetHitDest(), properties, duration, GetOriginalCaster(), GetSpellInfo()->Id))
|
|
{
|
|
summon->SetCreatorGUID(GetOriginalCaster()->GetGUID());
|
|
summon->HandleSpellClick(GetCaster());
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHit += SpellEffectFn(spell_wintergrasp_create_vehicle_SpellScript::HandleSummon, EFFECT_1, SPELL_EFFECT_SUMMON);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_wintergrasp_create_vehicle_SpellScript;
|
|
}
|
|
};
|
|
|
|
class spell_wintergrasp_rp_gg : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_wintergrasp_rp_gg() : SpellScriptLoader("spell_wintergrasp_rp_gg") { }
|
|
|
|
class spell_wintergrasp_rp_gg_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_wintergrasp_rp_gg_SpellScript);
|
|
|
|
bool handled;
|
|
bool Load() override
|
|
{
|
|
handled = false;
|
|
return true;
|
|
}
|
|
|
|
void HandleFinish()
|
|
{
|
|
if (!GetExplTargetDest())
|
|
return;
|
|
|
|
GetCaster()->CastSpell(GetExplTargetDest()->GetPositionX(), GetExplTargetDest()->GetPositionY(), GetExplTargetDest()->GetPositionZ(), SPELL_RP_GG_TRIGGER_MISSILE, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
AfterCast += SpellCastFn(spell_wintergrasp_rp_gg_SpellScript::HandleFinish);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_wintergrasp_rp_gg_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_wintergrasp_portal : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_wintergrasp_portal() : SpellScriptLoader("spell_wintergrasp_portal") { }
|
|
|
|
class spell_wintergrasp_portal_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_wintergrasp_portal_SpellScript);
|
|
|
|
void HandleScript(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitDefaultEffect(effIndex);
|
|
Player* target = GetHitPlayer();
|
|
Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
|
|
if (!wintergrasp || !target || target->getLevel() < 75 || (wintergrasp->GetDefenderTeam() != target->GetTeamId()))
|
|
return;
|
|
|
|
target->CastSpell(target, SPELL_TELEPORT_TO_FORTRESS, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_wintergrasp_portal_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_wintergrasp_water : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_wintergrasp_water() : SpellScriptLoader("spell_wintergrasp_water") { }
|
|
|
|
class spell_wintergrasp_water_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_wintergrasp_water_SpellScript);
|
|
|
|
SpellCastResult CheckCast()
|
|
{
|
|
Unit* target = GetCaster();
|
|
if (!target || !target->IsVehicle())
|
|
return SPELL_FAILED_DONT_REPORT;
|
|
|
|
return SPELL_CAST_OK;
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnCheckCast += SpellCheckCastFn(spell_wintergrasp_water_SpellScript::CheckCast);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_wintergrasp_water_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_wintergrasp_hide_small_elementals : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_wintergrasp_hide_small_elementals() : SpellScriptLoader("spell_wintergrasp_hide_small_elementals") { }
|
|
|
|
class spell_wintergrasp_hide_small_elementals_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_wintergrasp_hide_small_elementals_AuraScript);
|
|
|
|
void HandlePeriodicDummy(AuraEffect const* /*aurEff*/)
|
|
{
|
|
Unit* target = GetTarget();
|
|
Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(target->GetZoneId());
|
|
bool enable = !Bf || !Bf->IsWarTime();
|
|
target->SetPhaseMask(enable ? 1 : 512, true);
|
|
PreventDefaultAction();
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_wintergrasp_hide_small_elementals_AuraScript::HandlePeriodicDummy, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const override
|
|
{
|
|
return new spell_wintergrasp_hide_small_elementals_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_wg_reduce_damage_by_distance : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_wg_reduce_damage_by_distance() : SpellScriptLoader("spell_wg_reduce_damage_by_distance") { }
|
|
|
|
class spell_wg_reduce_damage_by_distance_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_wg_reduce_damage_by_distance_SpellScript);
|
|
|
|
void RecalculateDamage()
|
|
{
|
|
if (!GetExplTargetDest() || !GetHitUnit())
|
|
return;
|
|
|
|
float maxDistance = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster()); // Xinef: always stored in EFFECT_0
|
|
float distance = std::min<float>(GetHitUnit()->GetDistance(*GetExplTargetDest()), maxDistance);
|
|
|
|
int32 damage = std::max<int32>(0, int32(GetHitDamage() - floor(GetHitDamage() * (distance / maxDistance))));
|
|
SetHitDamage(damage);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnHit += SpellHitFn(spell_wg_reduce_damage_by_distance_SpellScript::RecalculateDamage);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_wg_reduce_damage_by_distance_SpellScript();
|
|
}
|
|
};
|
|
|
|
////////////////////////////////////////////////
|
|
/////// ACHIEVEMENTs
|
|
////////////////////////////////////////////////
|
|
|
|
class achievement_wg_didnt_stand_a_chance : public AchievementCriteriaScript
|
|
{
|
|
public:
|
|
achievement_wg_didnt_stand_a_chance() : AchievementCriteriaScript("achievement_wg_didnt_stand_a_chance") { }
|
|
|
|
bool OnCheck(Player* source, Unit* target) override
|
|
{
|
|
if (!target)
|
|
return false;
|
|
|
|
if (Player* victim = target->ToPlayer())
|
|
{
|
|
if (!victim->IsMounted())
|
|
return false;
|
|
|
|
if (Vehicle* vehicle = source->GetVehicle())
|
|
if (vehicle->GetVehicleInfo()->m_ID == 244) // Wintergrasp Tower Cannon
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
};
|
|
|
|
class achievement_wg_vehicular_gnomeslaughter : public AchievementCriteriaScript
|
|
{
|
|
public:
|
|
achievement_wg_vehicular_gnomeslaughter() : AchievementCriteriaScript("achievement_wg_vehicular_gnomeslaughter") { }
|
|
|
|
bool OnCheck(Player* source, Unit* target) override
|
|
{
|
|
if (!target)
|
|
return false;
|
|
|
|
if (Unit* vehicle = source->GetVehicleBase())
|
|
if (vehicle->GetEntry() == NPC_WINTERGRASP_SIEGE_ENGINE_ALLIANCE || vehicle->GetEntry() == NPC_WINTERGRASP_SIEGE_ENGINE_HORDE ||
|
|
vehicle->GetEntry() == NPC_WINTERGRASP_CATAPULT || vehicle->GetEntry() == NPC_WINTERGRASP_DEMOLISHER ||
|
|
vehicle->GetEntry() == NPC_WINTERGRASP_TOWER_CANNON)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
};
|
|
|
|
class achievement_wg_within_our_grasp : public AchievementCriteriaScript
|
|
{
|
|
public:
|
|
achievement_wg_within_our_grasp() : AchievementCriteriaScript("achievement_wg_within_our_grasp") { }
|
|
|
|
bool OnCheck(Player* /*source*/, Unit* /*target*/) override
|
|
{
|
|
Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG);
|
|
if (!wintergrasp)
|
|
return false;
|
|
|
|
return wintergrasp->GetTimer() >= (20 * MINUTE * IN_MILLISECONDS);
|
|
}
|
|
};
|
|
|
|
void AddSC_wintergrasp()
|
|
{
|
|
// NPCs
|
|
new npc_wg_queue();
|
|
new npc_wg_spirit_guide();
|
|
new npc_wg_demolisher_engineer();
|
|
new npc_wg_quest_giver();
|
|
new npc_wg_siege_machine();
|
|
|
|
// GOs
|
|
new go_wg_vehicle_teleporter();
|
|
|
|
// SPELLs
|
|
new spell_wintergrasp_force_building();
|
|
new spell_wintergrasp_create_vehicle();
|
|
new spell_wintergrasp_rp_gg();
|
|
new spell_wintergrasp_portal();
|
|
new spell_wintergrasp_water();
|
|
new spell_wintergrasp_hide_small_elementals();
|
|
new spell_wg_reduce_damage_by_distance();
|
|
|
|
// ACHIEVEMENTs
|
|
new achievement_wg_didnt_stand_a_chance();
|
|
new achievement_wg_vehicular_gnomeslaughter();
|
|
new achievement_wg_within_our_grasp();
|
|
}
|