mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-23 18:36:31 +01:00
Core/Battlegrounds: Move to scripts (#29799)
* Introduce new BattlegroundScript class for map/bg specific scripts
* Remove all sub, zone specific, battleground classes except Arena
* Move all bg zone scripts to new BattlegroundScripts class in script folder
* Remove ZoneScript from Battleground class
* Remove some unused hooks from Battleground
(cherry picked from commit be11f42a16)
This commit is contained in:
@@ -15,8 +15,9 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "alterac_valley.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "BattlegroundAV.h"
|
||||
#include "Battleground.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "Player.h"
|
||||
@@ -192,10 +193,36 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<AlteracValleySharedActions ActionId>
|
||||
class quest_alterac_valley : public QuestScript
|
||||
{
|
||||
public:
|
||||
quest_alterac_valley(char const* scriptName) : QuestScript(scriptName) { }
|
||||
|
||||
void OnQuestStatusChange(Player* player, Quest const* /*quest*/, QuestStatus /*oldStatus*/, QuestStatus newStatus) override
|
||||
{
|
||||
if (newStatus != QUEST_STATUS_REWARDED)
|
||||
return;
|
||||
|
||||
if (ZoneScript* zoneScript = player->FindZoneScript())
|
||||
zoneScript->DoAction(ActionId, player, player);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_alterac_valley()
|
||||
{
|
||||
RegisterCreatureAI(npc_av_marshal_or_warmaster);
|
||||
RegisterGameObjectAI(go_av_capturable_object);
|
||||
RegisterGameObjectAI(go_av_contested_object);
|
||||
new at_av_exploit();
|
||||
new quest_alterac_valley<ACTION_TURN_IN_SCRAPS>("quest_alterac_valley_armor_scraps");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_COMMANDER_1>("quest_alterac_valley_call_of_air_slidore_guse");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_COMMANDER_2>("quest_alterac_valley_call_of_air_vipore_jeztor");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_COMMANDER_3>("quest_alterac_valley_call_of_air_ichman_mulverick");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_BOSS_1>("quest_alterac_valley_boss_5");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_BOSS_2>("quest_alterac_valley_boss_1");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_NEAR_MINE>("quest_alterac_valley_near_mine");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_OTHER_MINE>("quest_alterac_valley_other_mine");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_RIDER_HIDE>("quest_alterac_valley_ram_harnesses");
|
||||
new quest_alterac_valley<ACTION_TURN_IN_RIDER_TAME>("quest_alterac_valley_empty_stables");
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ALTERAC_VALLEY_H
|
||||
#define __ALTERAC_VALLEY_H
|
||||
|
||||
enum AlteracValleySharedActions
|
||||
{
|
||||
ACTION_BUFF_YELL = -30001,
|
||||
ACTION_AV_INTERACT_CAPTURABLE_OBJECT = 1,
|
||||
ACTION_AV_CAPTURE_CAPTURABLE_OBJECT = 2,
|
||||
|
||||
ACTION_TURN_IN_SCRAPS = 3,
|
||||
ACTION_TURN_IN_COMMANDER_1 = 4,
|
||||
ACTION_TURN_IN_COMMANDER_2 = 5,
|
||||
ACTION_TURN_IN_COMMANDER_3 = 6,
|
||||
ACTION_TURN_IN_BOSS_1,
|
||||
ACTION_TURN_IN_BOSS_2,
|
||||
ACTION_TURN_IN_NEAR_MINE,
|
||||
ACTION_TURN_IN_OTHER_MINE,
|
||||
ACTION_TURN_IN_RIDER_HIDE,
|
||||
ACTION_TURN_IN_RIDER_TAME
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,605 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlegroundScript.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "BattlegroundPackets.h"
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameTime.h"
|
||||
#include "Log.h"
|
||||
#include "Map.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
struct battleground_arathi_basin : BattlegroundScript
|
||||
{
|
||||
// Tick intervals and given points: case 0, 1, 2, 3, 4, 5 captured nodes
|
||||
static constexpr uint32 BG_AB_TickInterval = 2000;
|
||||
static constexpr uint32 BG_AB_TickPoints[6] = { 0, 2, 3, 4, 7, 60 };
|
||||
static constexpr uint32 NORMAL_HONOR_TICKS = 160;
|
||||
static constexpr uint32 WEEKEND_HONOR_TICKS = 260;
|
||||
static constexpr uint32 NORMAL_REPUTATION_TICKS = 120;
|
||||
static constexpr uint32 WEEKEND_REPUTATION_TICKS = 160;
|
||||
|
||||
enum PvpStats
|
||||
{
|
||||
PVP_STAT_BASES_ASSAULTED = 926,
|
||||
PVP_STAT_BASES_DEFENDED = 927,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
AB_EVENT_START_BATTLE = 9158, // Achievement: Let's Get This Done
|
||||
|
||||
AB_EVENT_CONTESTED_STABLES_HORDE = 28523,
|
||||
AB_EVENT_CAPTURE_STABLES_HORDE = 28527,
|
||||
AB_EVENT_DEFENDED_STABLES_HORDE = 28525,
|
||||
AB_EVENT_CONTESTED_STABLES_ALLIANCE = 28522,
|
||||
AB_EVENT_CAPTURE_STABLES_ALLIANCE = 28526,
|
||||
AB_EVENT_DEFENDED_STABLES_ALLIANCE = 28524,
|
||||
|
||||
AB_EVENT_CONTESTED_BLACKSMITH_HORDE = 8876,
|
||||
AB_EVENT_CAPTURE_BLACKSMITH_HORDE = 8773,
|
||||
AB_EVENT_DEFENDED_BLACKSMITH_HORDE = 8770,
|
||||
AB_EVENT_CONTESTED_BLACKSMITH_ALLIANCE = 8874,
|
||||
AB_EVENT_CAPTURE_BLACKSMITH_ALLIANCE = 8769,
|
||||
AB_EVENT_DEFENDED_BLACKSMITH_ALLIANCE = 8774,
|
||||
|
||||
AB_EVENT_CONTESTED_FARM_HORDE = 39398,
|
||||
AB_EVENT_CAPTURE_FARM_HORDE = 39399,
|
||||
AB_EVENT_DEFENDED_FARM_HORDE = 39400,
|
||||
AB_EVENT_CONTESTED_FARM_ALLIANCE = 39401,
|
||||
AB_EVENT_CAPTURE_FARM_ALLIANCE = 39402,
|
||||
AB_EVENT_DEFENDED_FARM_ALLIANCE = 39403,
|
||||
|
||||
AB_EVENT_CONTESTED_GOLD_MINE_HORDE = 39404,
|
||||
AB_EVENT_CAPTURE_GOLD_MINE_HORDE = 39405,
|
||||
AB_EVENT_DEFENDED_GOLD_MINE_HORDE = 39406,
|
||||
AB_EVENT_CONTESTED_GOLD_MINE_ALLIANCE = 39407,
|
||||
AB_EVENT_CAPTURE_GOLD_MINE_ALLIANCE = 39408,
|
||||
AB_EVENT_DEFENDED_GOLD_MINE_ALLIANCE = 39409,
|
||||
|
||||
AB_EVENT_CONTESTED_LUMBER_MILL_HORDE = 39387,
|
||||
AB_EVENT_CAPTURE_LUMBER_MILL_HORDE = 39388,
|
||||
AB_EVENT_DEFENDED_LUMBER_MILL_HORDE = 39389,
|
||||
AB_EVENT_CONTESTED_LUMBER_MILL_ALLIANCE = 39390,
|
||||
AB_EVENT_CAPTURE_LUMBER_MILL_ALLIANCE = 39391,
|
||||
AB_EVENT_DEFENDED_LUMBER_MILL_ALLIANCE = 39392
|
||||
};
|
||||
|
||||
enum Sounds
|
||||
{
|
||||
BG_AB_SOUND_NODE_CLAIMED = 8192,
|
||||
BG_AB_SOUND_NODE_CAPTURED_ALLIANCE = 8173,
|
||||
BG_AB_SOUND_NODE_CAPTURED_HORDE = 8213,
|
||||
BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE = 8212,
|
||||
BG_AB_SOUND_NODE_ASSAULTED_HORDE = 8174,
|
||||
BG_AB_SOUND_NEAR_VICTORY_ALLIANCE = 8456,
|
||||
BG_AB_SOUND_NEAR_VICTORY_HORDE = 8457
|
||||
};
|
||||
|
||||
enum BroadcastTexts
|
||||
{
|
||||
BG_AB_TEXT_ALLIANCE_NEAR_VICTORY = 10598,
|
||||
BG_AB_TEXT_HORDE_NEAR_VICTORY = 10599,
|
||||
};
|
||||
|
||||
enum Score
|
||||
{
|
||||
BG_AB_WARNING_NEAR_VICTORY_SCORE = 1200,
|
||||
BG_AB_MAX_TEAM_SCORE = 1500
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
BG_AB_NPC_THE_BLACK_BRIDE = 150501,
|
||||
BG_AB_NPC_RADULF_LEDER = 150505
|
||||
};
|
||||
|
||||
enum ObjectTypes
|
||||
{
|
||||
BG_AB_OBJECTID_CAPTURE_POINT_STABLES = 227420,
|
||||
BG_AB_OBJECTID_CAPTURE_POINT_BLACKSMITH = 227522,
|
||||
BG_AB_OBJECTID_CAPTURE_POINT_FARM = 227536,
|
||||
BG_AB_OBJECTID_CAPTURE_POINT_GOLD_MINE = 227538,
|
||||
BG_AB_OBJECTID_CAPTURE_POINT_LUMBER_MILL = 227544,
|
||||
|
||||
BG_AB_OBJECTID_GHOST_GATE = 180322,
|
||||
BG_AB_OBJECTID_ALLIANCE_DOOR = 322273,
|
||||
BG_AB_OBJECTID_HORDE_DOOR = 322274
|
||||
};
|
||||
|
||||
enum WorldStates
|
||||
{
|
||||
BG_AB_WS_OCCUPIED_BASES_HORDE = 1778,
|
||||
BG_AB_WS_OCCUPIED_BASES_ALLY = 1779,
|
||||
BG_AB_WS_RESOURCES_ALLY = 1776,
|
||||
BG_AB_WS_RESOURCES_HORDE = 1777,
|
||||
BG_AB_WS_RESOURCES_MAX = 1780,
|
||||
BG_AB_WS_RESOURCES_WARNING = 1955,
|
||||
|
||||
BG_AB_WS_STABLE_ICON = 1842, // Stable map icon (NONE)
|
||||
BG_AB_WS_STABLE_STATE_ALIENCE = 1767, // Stable map state (ALIENCE)
|
||||
BG_AB_WS_STABLE_STATE_HORDE = 1768, // Stable map state (HORDE)
|
||||
BG_AB_WS_STABLE_STATE_CON_ALI = 1769, // Stable map state (CON ALIENCE)
|
||||
BG_AB_WS_STABLE_STATE_CON_HOR = 1770, // Stable map state (CON HORDE)
|
||||
BG_AB_WS_FARM_ICON = 1845, // Farm map icon (NONE)
|
||||
BG_AB_WS_FARM_STATE_ALIENCE = 1772, // Farm state (ALIENCE)
|
||||
BG_AB_WS_FARM_STATE_HORDE = 1773, // Farm state (HORDE)
|
||||
BG_AB_WS_FARM_STATE_CON_ALI = 1774, // Farm state (CON ALIENCE)
|
||||
BG_AB_WS_FARM_STATE_CON_HOR = 1775, // Farm state (CON HORDE)
|
||||
BG_AB_WS_BLACKSMITH_ICON = 1846, // Blacksmith map icon (NONE)
|
||||
BG_AB_WS_BLACKSMITH_STATE_ALIENCE = 1782, // Blacksmith map state (ALIENCE)
|
||||
BG_AB_WS_BLACKSMITH_STATE_HORDE = 1783, // Blacksmith map state (HORDE)
|
||||
BG_AB_WS_BLACKSMITH_STATE_CON_ALI = 1784, // Blacksmith map state (CON ALIENCE)
|
||||
BG_AB_WS_BLACKSMITH_STATE_CON_HOR = 1785, // Blacksmith map state (CON HORDE)
|
||||
BG_AB_WS_LUMBERMILL_ICON = 1844, // Lumber Mill map icon (NONE)
|
||||
BG_AB_WS_LUMBERMILL_STATE_ALIENCE = 1792, // Lumber Mill map state (ALIENCE)
|
||||
BG_AB_WS_LUMBERMILL_STATE_HORDE = 1793, // Lumber Mill map state (HORDE)
|
||||
BG_AB_WS_LUMBERMILL_STATE_CON_ALI = 1794, // Lumber Mill map state (CON ALIENCE)
|
||||
BG_AB_WS_LUMBERMILL_STATE_CON_HOR = 1795, // Lumber Mill map state (CON HORDE)
|
||||
BG_AB_WS_GOLDMINE_ICON = 1843, // Gold Mine map icon (NONE)
|
||||
BG_AB_WS_GOLDMINE_STATE_ALIENCE = 1787, // Gold Mine map state (ALIENCE)
|
||||
BG_AB_WS_GOLDMINE_STATE_HORDE = 1788, // Gold Mine map state (HORDE)
|
||||
BG_AB_WS_GOLDMINE_STATE_CON_ALI = 1789, // Gold Mine map state (CON ALIENCE
|
||||
BG_AB_WS_GOLDMINE_STATE_CON_HOR = 1790, // Gold Mine map state (CON HORDE)
|
||||
|
||||
BG_AB_WS_HAD_500_DISADVANTAGE_ALLIANCE = 3644,
|
||||
BG_AB_WS_HAD_500_DISADVANTAGE_HORDE = 3645,
|
||||
|
||||
BG_AB_WS_FARM_ICON_NEW = 8808, // Farm map icon
|
||||
BG_AB_WS_LUMBER_MILL_ICON_NEW = 8805, // Lumber Mill map icon
|
||||
BG_AB_WS_BLACKSMITH_ICON_NEW = 8799, // Blacksmith map icon
|
||||
BG_AB_WS_GOLD_MINE_ICON_NEW = 8809, // Gold Mine map icon
|
||||
BG_AB_WS_STABLES_ICON_NEW = 5834, // Stable map icon
|
||||
|
||||
BG_AB_WS_FARM_HORDE_CONTROL_STATE = 17328,
|
||||
BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE = 17325,
|
||||
BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE = 17330,
|
||||
BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE = 17326,
|
||||
BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE = 17327,
|
||||
BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE = 17324,
|
||||
BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE = 17329,
|
||||
BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE = 17323,
|
||||
BG_AB_WS_STABLES_HORDE_CONTROL_STATE = 17331,
|
||||
BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE = 17322,
|
||||
};
|
||||
|
||||
explicit battleground_arathi_basin(BattlegroundMap* map) : BattlegroundScript(map), _lastTick(0), _isInformedNearVictory(false)
|
||||
{
|
||||
bool const isBGWeekend = sBattlegroundMgr->IsBGWeekend(battleground->GetTypeID());
|
||||
|
||||
_honorTics = (isBGWeekend) ? WEEKEND_HONOR_TICKS : NORMAL_HONOR_TICKS;
|
||||
_reputationTics = (isBGWeekend) ? WEEKEND_REPUTATION_TICKS : NORMAL_REPUTATION_TICKS;
|
||||
_honorScoreTics = { { 0, 0 } };
|
||||
_reputationScoreTics = { { 0, 0 } };
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
BattlegroundScript::OnInit();
|
||||
|
||||
UpdateWorldState(BG_AB_WS_RESOURCES_MAX, BG_AB_MAX_TEAM_SCORE);
|
||||
UpdateWorldState(BG_AB_WS_RESOURCES_WARNING, BG_AB_WARNING_NEAR_VICTORY_SCORE);
|
||||
}
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
// Accumulate points
|
||||
_lastTick += diff;
|
||||
if (_lastTick > BG_AB_TickInterval)
|
||||
{
|
||||
_lastTick -= BG_AB_TickInterval;
|
||||
|
||||
uint8 ally = 0, horde = 0;
|
||||
_CalculateTeamNodes(ally, horde);
|
||||
uint8 points[PVP_TEAMS_COUNT] = { ally, horde };
|
||||
|
||||
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
||||
{
|
||||
if (!points[team])
|
||||
continue;
|
||||
|
||||
battleground->AddPoint(team == TEAM_HORDE ? HORDE : ALLIANCE, BG_AB_TickPoints[points[team]]);
|
||||
_honorScoreTics[team] += BG_AB_TickPoints[points[team]];
|
||||
_reputationScoreTics[team] += BG_AB_TickPoints[points[team]];
|
||||
|
||||
if (_reputationScoreTics[team] >= _reputationTics)
|
||||
{
|
||||
(team == TEAM_ALLIANCE) ? battleground->RewardReputationToTeam(509, 10, ALLIANCE) : battleground->RewardReputationToTeam(510, 10, HORDE);
|
||||
_reputationScoreTics[team] -= _reputationTics;
|
||||
}
|
||||
|
||||
if (_honorScoreTics[team] >= _honorTics)
|
||||
{
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), (team == TEAM_ALLIANCE) ? ALLIANCE : HORDE);
|
||||
_honorScoreTics[team] -= _honorTics;
|
||||
}
|
||||
|
||||
const uint32 teamScore = battleground->GetTeamScore(static_cast<TeamId>(team));
|
||||
if (!_isInformedNearVictory && teamScore > BG_AB_WARNING_NEAR_VICTORY_SCORE)
|
||||
{
|
||||
if (team == TEAM_ALLIANCE)
|
||||
{
|
||||
battleground->SendBroadcastText(BG_AB_TEXT_ALLIANCE_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
battleground->SendBroadcastText(BG_AB_TEXT_HORDE_NEAR_VICTORY, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY_HORDE);
|
||||
}
|
||||
_isInformedNearVictory = true;
|
||||
}
|
||||
|
||||
if (teamScore > BG_AB_MAX_TEAM_SCORE)
|
||||
battleground->SetTeamPoint(team == TEAM_HORDE ? HORDE : ALLIANCE, BG_AB_MAX_TEAM_SCORE);
|
||||
|
||||
if (team == TEAM_ALLIANCE)
|
||||
UpdateWorldState(BG_AB_WS_RESOURCES_ALLY, teamScore);
|
||||
else
|
||||
UpdateWorldState(BG_AB_WS_RESOURCES_HORDE, teamScore);
|
||||
|
||||
// update achievement flags
|
||||
// we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
|
||||
uint8 otherTeam = (team + 1) % PVP_TEAMS_COUNT;
|
||||
if (teamScore > battleground->GetTeamScore(static_cast<TeamId>(otherTeam)) + 500)
|
||||
{
|
||||
if (team == TEAM_ALLIANCE)
|
||||
UpdateWorldState(BG_AB_WS_HAD_500_DISADVANTAGE_HORDE, 1);
|
||||
else
|
||||
UpdateWorldState(BG_AB_WS_HAD_500_DISADVANTAGE_ALLIANCE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateWorldState(BG_AB_WS_OCCUPIED_BASES_ALLY, ally);
|
||||
UpdateWorldState(BG_AB_WS_OCCUPIED_BASES_HORDE, horde);
|
||||
}
|
||||
|
||||
// Test win condition
|
||||
if (battleground->GetTeamScore(TEAM_ALLIANCE) >= BG_AB_MAX_TEAM_SCORE && battleground->GetTeamScore(TEAM_HORDE) >= BG_AB_MAX_TEAM_SCORE)
|
||||
battleground->EndBattleground(TEAM_OTHER); // draw
|
||||
else if (battleground->GetTeamScore(TEAM_ALLIANCE) >= BG_AB_MAX_TEAM_SCORE)
|
||||
battleground->EndBattleground(ALLIANCE);
|
||||
else if (battleground->GetTeamScore(TEAM_HORDE) >= BG_AB_MAX_TEAM_SCORE)
|
||||
battleground->EndBattleground(HORDE);
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
// Achievement: Let's Get This Done
|
||||
TriggerGameEvent(AB_EVENT_START_BATTLE);
|
||||
}
|
||||
|
||||
void _CalculateTeamNodes(uint8& alliance, uint8& horde) const
|
||||
{
|
||||
alliance = 0;
|
||||
horde = 0;
|
||||
|
||||
for (ObjectGuid const& guid : _capturePoints)
|
||||
{
|
||||
if (GameObject const* capturePoint = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
int32 const wsValue = battlegroundMap->GetWorldStateValue(capturePoint->GetGOInfo()->capturePoint.worldState1);
|
||||
switch (WorldPackets::Battleground::BattlegroundCapturePointState(wsValue))
|
||||
{
|
||||
case WorldPackets::Battleground::BattlegroundCapturePointState::AllianceCaptured:
|
||||
++alliance;
|
||||
break;
|
||||
case WorldPackets::Battleground::BattlegroundCapturePointState::HordeCaptured:
|
||||
++horde;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Team GetPrematureWinner() override
|
||||
{
|
||||
// How many bases each team owns
|
||||
uint8 ally = 0, horde = 0;
|
||||
_CalculateTeamNodes(ally, horde);
|
||||
|
||||
if (ally > horde)
|
||||
return ALLIANCE;
|
||||
if (horde > ally)
|
||||
return HORDE;
|
||||
|
||||
// If the values are equal, fall back to the original result (based on number of players on each team)
|
||||
return BattlegroundScript::GetPrematureWinner();
|
||||
}
|
||||
|
||||
void ProcessEvent(WorldObject* /*source*/, uint32 eventId, WorldObject* invoker) override
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case AB_EVENT_START_BATTLE:
|
||||
{
|
||||
for (ObjectGuid const& guid : _creaturesToRemoveOnMatchStart)
|
||||
if (Creature* creature = battlegroundMap->GetCreature(guid))
|
||||
creature->DespawnOrUnsummon();
|
||||
|
||||
for (ObjectGuid const& guid : _gameobjectsToRemoveOnMatchStart)
|
||||
if (GameObject* gameObject = battlegroundMap->GetGameObject(guid))
|
||||
gameObject->DespawnOrUnsummon();
|
||||
|
||||
for (ObjectGuid const& guid : _doors)
|
||||
{
|
||||
if (GameObject* gameObject = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
gameObject->UseDoorOrButton();
|
||||
gameObject->DespawnOrUnsummon(3s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AB_EVENT_CONTESTED_BLACKSMITH_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 1);
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_BLACKSMITH_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 2);
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_BLACKSMITH_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_BLACKSMITH_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 1);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_BLACKSMITH_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_BLACKSMITH_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_BLACKSMITH_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_FARM_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 1);
|
||||
UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_FARM_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 2);
|
||||
UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_FARM_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_FARM_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 1);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_FARM_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_FARM_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_FARM_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_FARM_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_GOLD_MINE_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 1);
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_GOLD_MINE_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 2);
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_GOLD_MINE_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_GOLD_MINE_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 1);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_GOLD_MINE_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_GOLD_MINE_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_GOLD_MINE_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_LUMBER_MILL_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 1);
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_LUMBER_MILL_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 2);
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_LUMBER_MILL_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_LUMBER_MILL_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 1);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_LUMBER_MILL_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_LUMBER_MILL_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_LUMBER_MILL_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_STABLES_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 1);
|
||||
UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_STABLES_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 2);
|
||||
UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 0);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_STABLES_ALLIANCE:
|
||||
UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE);
|
||||
break;
|
||||
case AB_EVENT_CONTESTED_STABLES_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 1);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_ASSAULTED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
break;
|
||||
case AB_EVENT_DEFENDED_STABLES_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_STABLES_ALLIANCE_CONTROL_STATE, 0);
|
||||
UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
if (Player* player = invoker->ToPlayer())
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
break;
|
||||
case AB_EVENT_CAPTURE_STABLES_HORDE:
|
||||
UpdateWorldState(BG_AB_WS_STABLES_HORDE_CONTROL_STATE, 2);
|
||||
battleground->PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE);
|
||||
break;
|
||||
default:
|
||||
TC_LOG_WARN("bg.events", "BattlegroundAB::ProcessEvent: Unhandled event %u.", eventId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case BG_AB_NPC_THE_BLACK_BRIDE:
|
||||
case BG_AB_NPC_RADULF_LEDER:
|
||||
_creaturesToRemoveOnMatchStart.push_back(creature->GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameObject) override
|
||||
{
|
||||
if (gameObject->GetGOInfo()->type == GAMEOBJECT_TYPE_CAPTURE_POINT)
|
||||
_capturePoints.push_back(gameObject->GetGUID());
|
||||
|
||||
switch (gameObject->GetEntry())
|
||||
{
|
||||
case BG_AB_OBJECTID_GHOST_GATE:
|
||||
_gameobjectsToRemoveOnMatchStart.push_back(gameObject->GetGUID());
|
||||
break;
|
||||
case BG_AB_OBJECTID_ALLIANCE_DOOR:
|
||||
case BG_AB_OBJECTID_HORDE_DOOR:
|
||||
_doors.push_back(gameObject->GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnEnd(Team winner) override
|
||||
{
|
||||
BattlegroundScript::OnEnd(winner);
|
||||
|
||||
// Win reward
|
||||
if (winner == ALLIANCE)
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
|
||||
if (winner == HORDE)
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
|
||||
// Complete map_end rewards (even if no team wins)
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _lastTick;
|
||||
std::array<uint32, PVP_TEAMS_COUNT> _honorScoreTics;
|
||||
std::array<uint32, PVP_TEAMS_COUNT> _reputationScoreTics;
|
||||
bool _isInformedNearVictory;
|
||||
uint32 _honorTics;
|
||||
uint32 _reputationTics;
|
||||
|
||||
GuidVector _gameobjectsToRemoveOnMatchStart;
|
||||
GuidVector _creaturesToRemoveOnMatchStart;
|
||||
GuidVector _doors;
|
||||
GuidVector _capturePoints;
|
||||
};
|
||||
|
||||
void AddSC_battleground_arathi_basin()
|
||||
{
|
||||
RegisterBattlegroundMapScript(battleground_arathi_basin, 2107);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlegroundScript.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
struct battleground_battle_for_gilneas : BattlegroundScript
|
||||
{
|
||||
enum PvpStats : uint32
|
||||
{
|
||||
BFG_OBJECTIVE_BASES_ASSAULTED = 370,
|
||||
BFG_OBJECTIVE_BASES_DEFENDED = 371
|
||||
};
|
||||
|
||||
explicit battleground_battle_for_gilneas(BattlegroundMap* map) : BattlegroundScript(map) { }
|
||||
};
|
||||
|
||||
void AddSC_battleground_battle_for_gilneas()
|
||||
{
|
||||
RegisterBattlegroundMapScript(battleground_battle_for_gilneas, 761);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundScript.h"
|
||||
#include "GameObject.h"
|
||||
#include "Map.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
struct arena_blades_edge : ArenaScript
|
||||
{
|
||||
enum GameObjects
|
||||
{
|
||||
BG_BE_OBJECT_TYPE_DOOR_1 = 183971,
|
||||
BG_BE_OBJECT_TYPE_DOOR_2 = 183973,
|
||||
BG_BE_OBJECT_TYPE_DOOR_3 = 183970,
|
||||
BG_BE_OBJECT_TYPE_DOOR_4 = 183972,
|
||||
BG_BE_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_BE_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
explicit arena_blades_edge(BattlegroundMap* map) : ArenaScript(map) { }
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
AddDoor(BG_BE_OBJECT_TYPE_DOOR_1, 6287.277f, 282.1877f, 3.810925f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f);
|
||||
AddDoor(BG_BE_OBJECT_TYPE_DOOR_2, 6189.546f, 241.7099f, 3.101481f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f);
|
||||
AddDoor(BG_BE_OBJECT_TYPE_DOOR_3, 6299.116f, 296.5494f, 3.308032f, 0.8813917f, 0, 0, 0.4265689f, 0.9044551f);
|
||||
AddDoor(BG_BE_OBJECT_TYPE_DOOR_4, 6177.708f, 227.3481f, 3.604374f, -2.260201f, 0, 0, 0.9044551f, -0.4265689f);
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
for (ObjectGuid const& guid : _doorGUIDs)
|
||||
{
|
||||
if (GameObject* door = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
door->UseDoorOrButton();
|
||||
door->DespawnOrUnsummon(5s);
|
||||
}
|
||||
}
|
||||
|
||||
_scheduler.Schedule(1min, [&](TaskContext)
|
||||
{
|
||||
CreateObject(BG_BE_OBJECT_TYPE_BUFF_1, 6249.042f, 275.3239f, 11.22033f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
|
||||
CreateObject(BG_BE_OBJECT_TYPE_BUFF_2, 6228.26f, 249.566f, 11.21812f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
|
||||
});
|
||||
}
|
||||
|
||||
void AddDoor(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState = GO_STATE_READY)
|
||||
{
|
||||
if (GameObject const* go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState))
|
||||
_doorGUIDs.emplace_back(go->GetGUID());
|
||||
}
|
||||
|
||||
private:
|
||||
GuidVector _doorGUIDs;
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
void AddSC_arena_blades_edge()
|
||||
{
|
||||
RegisterBattlegroundMapScript(arena_blades_edge, 1672);
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundScript.h"
|
||||
#include "Creature.h"
|
||||
#include "Duration.h"
|
||||
#include "EventMap.h"
|
||||
#include "GameObject.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
struct arena_dalaran_sewers : ArenaScript
|
||||
{
|
||||
enum GameObjects
|
||||
{
|
||||
BG_DS_OBJECT_TYPE_DOOR_1 = 192642,
|
||||
BG_DS_OBJECT_TYPE_DOOR_2 = 192643,
|
||||
BG_DS_OBJECT_TYPE_WATER_1 = 194395, // Collision
|
||||
BG_DS_OBJECT_TYPE_WATER_2 = 191877,
|
||||
BG_DS_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_DS_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
BG_DS_EVENT_WATERFALL_WARNING = 1, // Water starting to fall, but no LoS Blocking nor movement blocking
|
||||
BG_DS_EVENT_WATERFALL_ON = 2, // LoS and Movement blocking active
|
||||
BG_DS_EVENT_WATERFALL_OFF = 3,
|
||||
BG_DS_EVENT_WATERFALL_KNOCKBACK = 4,
|
||||
|
||||
BG_DS_EVENT_PIPE_KNOCKBACK = 5
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
BG_DS_NPC_TYPE_WATER_SPOUT = 28567
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
BG_DS_SPELL_FLUSH = 57405, // Visual and target selector for the starting knockback from the pipe
|
||||
BG_DS_SPELL_FLUSH_KNOCKBACK = 61698, // Knockback effect for previous spell (triggered, not needed to be cast)
|
||||
BG_DS_SPELL_WATER_SPOUT = 58873, // Knockback effect of the central waterfall
|
||||
|
||||
SPELL_WARL_DEMONIC_CIRCLE = 48018 // Demonic Circle Summon
|
||||
};
|
||||
|
||||
enum Data
|
||||
{
|
||||
// These values are NOT blizzlike... need the correct data!
|
||||
BG_DS_PIPE_KNOCKBACK_FIRST_DELAY = 5000,
|
||||
BG_DS_PIPE_KNOCKBACK_DELAY = 3000
|
||||
};
|
||||
|
||||
// These values are NOT blizzlike... need the correct data!
|
||||
static constexpr Seconds BG_DS_WATERFALL_TIMER_MIN = 30s;
|
||||
static constexpr Seconds BG_DS_WATERFALL_TIMER_MAX = 60s;
|
||||
static constexpr Seconds BG_DS_WATERFALL_WARNING_DURATION = 5s;
|
||||
static constexpr Seconds BG_DS_WATERFALL_DURATION = 30s;
|
||||
static constexpr Milliseconds BG_DS_WATERFALL_KNOCKBACK_TIMER = 1500ms;
|
||||
static constexpr uint32 BG_DS_DATA_PIPE_KNOCKBACK_COUNT = 1;
|
||||
static constexpr uint32 BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT = 2;
|
||||
|
||||
explicit arena_dalaran_sewers(BattlegroundMap* map) : ArenaScript(map), _pipeKnockBackTimer(BG_DS_PIPE_KNOCKBACK_FIRST_DELAY), _pipeKnockBackCount(0) { }
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
_scheduler.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case BG_DS_EVENT_WATERFALL_WARNING:
|
||||
// Add the water
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(_water2GUID))
|
||||
go->ResetDoorOrButton();
|
||||
_events.ScheduleEvent(BG_DS_EVENT_WATERFALL_ON, BG_DS_WATERFALL_WARNING_DURATION);
|
||||
break;
|
||||
case BG_DS_EVENT_WATERFALL_ON:
|
||||
// Active collision and start knockback timer
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(_water1GUID))
|
||||
go->ResetDoorOrButton();
|
||||
_events.ScheduleEvent(BG_DS_EVENT_WATERFALL_OFF, BG_DS_WATERFALL_DURATION);
|
||||
_events.ScheduleEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK, BG_DS_WATERFALL_KNOCKBACK_TIMER);
|
||||
break;
|
||||
case BG_DS_EVENT_WATERFALL_OFF:
|
||||
// Remove collision and water
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(_water1GUID))
|
||||
go->UseDoorOrButton();
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(_water2GUID))
|
||||
go->UseDoorOrButton();
|
||||
_events.CancelEvent(BG_DS_EVENT_WATERFALL_KNOCKBACK);
|
||||
_events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX);
|
||||
break;
|
||||
case BG_DS_EVENT_WATERFALL_KNOCKBACK:
|
||||
// Repeat knockback while the waterfall still active
|
||||
if (Creature* waterSpout = battlegroundMap->GetCreature(_waterfallCreatureGUID))
|
||||
waterSpout->CastSpell(waterSpout, BG_DS_SPELL_WATER_SPOUT, true);
|
||||
_events.ScheduleEvent(eventId, BG_DS_WATERFALL_KNOCKBACK_TIMER);
|
||||
break;
|
||||
case BG_DS_EVENT_PIPE_KNOCKBACK:
|
||||
for (ObjectGuid const& guid : _pipeCreatureGUIDs)
|
||||
if (Creature* waterSpout = battlegroundMap->GetCreature(guid))
|
||||
waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_pipeKnockBackCount < BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
|
||||
{
|
||||
if (_pipeKnockBackTimer < diff)
|
||||
{
|
||||
for (ObjectGuid const& guid : _pipeCreatureGUIDs)
|
||||
if (Creature* waterSpout = battlegroundMap->GetCreature(guid))
|
||||
waterSpout->CastSpell(waterSpout, BG_DS_SPELL_FLUSH, true);
|
||||
|
||||
++_pipeKnockBackCount;
|
||||
_pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_DELAY;
|
||||
}
|
||||
else
|
||||
_pipeKnockBackTimer -= diff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
AddObject(BG_DS_OBJECT_TYPE_DOOR_1, 1350.95f, 817.2f, 20.8096f, 3.15f, 0, 0, 0.99627f, 0.0862864f, GO_STATE_READY, _doorGUIDs);
|
||||
AddObject(BG_DS_OBJECT_TYPE_DOOR_2, 1232.65f, 764.913f, 20.0729f, 6.3f, 0, 0, 0.0310211f, -0.999519f, GO_STATE_READY, _doorGUIDs);
|
||||
|
||||
if (GameObject const* go = CreateObject(BG_DS_OBJECT_TYPE_WATER_1, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, GO_STATE_READY))
|
||||
_water1GUID = go->GetGUID();
|
||||
|
||||
if (GameObject const* go = CreateObject(BG_DS_OBJECT_TYPE_WATER_2, 1291.56f, 790.837f, 7.1f, 3.14238f, 0, 0, 0.694215f, -0.719768f, GO_STATE_READY))
|
||||
_water2GUID = go->GetGUID();
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
for (ObjectGuid const& guid : _doorGUIDs)
|
||||
{
|
||||
if (GameObject* door = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
door->UseDoorOrButton();
|
||||
door->DespawnOrUnsummon(5s);
|
||||
}
|
||||
}
|
||||
|
||||
_scheduler.Schedule(1min, [&](TaskContext)
|
||||
{
|
||||
CreateObject(BG_DS_OBJECT_TYPE_BUFF_1, 1291.7f, 813.424f, 7.11472f, 4.64562f, 0, 0, 0.730314f, -0.683111f);
|
||||
CreateObject(BG_DS_OBJECT_TYPE_BUFF_2, 1291.7f, 768.911f, 7.11472f, 1.55194f, 0, 0, 0.700409f, 0.713742f);
|
||||
});
|
||||
_events.ScheduleEvent(BG_DS_EVENT_WATERFALL_WARNING, BG_DS_WATERFALL_TIMER_MIN, BG_DS_WATERFALL_TIMER_MAX);
|
||||
_pipeKnockBackTimer = BG_DS_PIPE_KNOCKBACK_FIRST_DELAY;
|
||||
|
||||
// Remove collision and water
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(_water1GUID))
|
||||
go->UseDoorOrButton();
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(_water2GUID))
|
||||
go->UseDoorOrButton();
|
||||
|
||||
for (const auto& [playerGuid, _] : battleground->GetPlayers())
|
||||
if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
|
||||
player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE);
|
||||
}
|
||||
|
||||
void AddObject(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState, GuidVector guidVector) const
|
||||
{
|
||||
if (GameObject const* go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState))
|
||||
guidVector.emplace_back(go->GetGUID());
|
||||
}
|
||||
|
||||
void SetData(uint32 dataId, uint32 value) override
|
||||
{
|
||||
ArenaScript::SetData(dataId, value);
|
||||
if (dataId == BG_DS_DATA_PIPE_KNOCKBACK_COUNT)
|
||||
_pipeKnockBackCount = value;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 dataId) const override
|
||||
{
|
||||
if (dataId == BG_DS_DATA_PIPE_KNOCKBACK_COUNT)
|
||||
return _pipeKnockBackCount;
|
||||
|
||||
return ArenaScript::GetData(dataId);
|
||||
}
|
||||
|
||||
private:
|
||||
GuidVector _doorGUIDs;
|
||||
ObjectGuid _water1GUID;
|
||||
ObjectGuid _water2GUID;
|
||||
ObjectGuid _waterfallCreatureGUID;
|
||||
GuidVector _pipeCreatureGUIDs;
|
||||
TaskScheduler _scheduler;
|
||||
EventMap _events;
|
||||
|
||||
uint32 _pipeKnockBackTimer;
|
||||
uint8 _pipeKnockBackCount;
|
||||
};
|
||||
|
||||
class at_ds_pipe_knockback : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
at_ds_pipe_knockback() : AreaTriggerScript("at_ds_pipe_knockback") { }
|
||||
|
||||
void Trigger(Player* player) const
|
||||
{
|
||||
if (Battleground const* battleground = player->GetBattleground())
|
||||
{
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
// Remove effects of Demonic Circle Summon
|
||||
player->RemoveAurasDueToSpell(arena_dalaran_sewers::SPELL_WARL_DEMONIC_CIRCLE);
|
||||
|
||||
// Someone has get back into the pipes and the knockback has already been performed,
|
||||
// so we reset the knockback count for kicking the player again into the arena.
|
||||
if (battleground->GetBgMap()->GetBattlegroundScript()->GetData(arena_dalaran_sewers::BG_DS_DATA_PIPE_KNOCKBACK_COUNT) >= arena_dalaran_sewers::BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
|
||||
battleground->GetBgMap()->GetBattlegroundScript()->SetData(arena_dalaran_sewers::BG_DS_DATA_PIPE_KNOCKBACK_COUNT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override
|
||||
{
|
||||
Trigger(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnExit(Player* player, AreaTriggerEntry const* /*trigger*/) override
|
||||
{
|
||||
Trigger(player);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_arena_dalaran_sewers()
|
||||
{
|
||||
RegisterBattlegroundMapScript(arena_dalaran_sewers, 617);
|
||||
new at_ds_pipe_knockback();
|
||||
}
|
||||
@@ -0,0 +1,677 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "BattlegroundScript.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameTime.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Timer.h"
|
||||
|
||||
enum EyeOfTheStormWorldStates
|
||||
{
|
||||
EY_ALLIANCE_RESOURCES = 1776,
|
||||
EY_HORDE_RESOURCES = 1777,
|
||||
EY_MAX_RESOURCES = 1780,
|
||||
EY_ALLIANCE_BASE = 2752,
|
||||
EY_HORDE_BASE = 2753,
|
||||
DRAENEI_RUINS_HORDE_CONTROL = 2733,
|
||||
DRAENEI_RUINS_ALLIANCE_CONTROL = 2732,
|
||||
DRAENEI_RUINS_UNCONTROL = 2731,
|
||||
MAGE_TOWER_ALLIANCE_CONTROL = 2730,
|
||||
MAGE_TOWER_HORDE_CONTROL = 2729,
|
||||
MAGE_TOWER_UNCONTROL = 2728,
|
||||
FEL_REAVER_HORDE_CONTROL = 2727,
|
||||
FEL_REAVER_ALLIANCE_CONTROL = 2726,
|
||||
FEL_REAVER_UNCONTROL = 2725,
|
||||
BLOOD_ELF_HORDE_CONTROL = 2724,
|
||||
BLOOD_ELF_ALLIANCE_CONTROL = 2723,
|
||||
BLOOD_ELF_UNCONTROL = 2722,
|
||||
PROGRESS_BAR_PERCENT_GREY = 2720, //100 = empty (only grey), 0 = blue|red (no grey)
|
||||
PROGRESS_BAR_STATUS = 2719, //50 init!, 48 ... hordak bere .. 33 .. 0 = full 100% hordacky, 100 = full alliance
|
||||
PROGRESS_BAR_SHOW = 2718, //1 init, 0 druhy send - bez messagu, 1 = controlled aliance
|
||||
NETHERSTORM_FLAG = 8863,
|
||||
//set to 2 when flag is picked up, and to 1 if it is dropped
|
||||
NETHERSTORM_FLAG_STATE_ALLIANCE = 9808,
|
||||
NETHERSTORM_FLAG_STATE_HORDE = 9809,
|
||||
|
||||
DRAENEI_RUINS_HORDE_CONTROL_STATE = 17362,
|
||||
DRAENEI_RUINS_ALLIANCE_CONTROL_STATE = 17366,
|
||||
MAGE_TOWER_HORDE_CONTROL_STATE = 17361,
|
||||
MAGE_TOWER_ALLIANCE_CONTROL_STATE = 17368,
|
||||
FEL_REAVER_HORDE_CONTROL_STATE = 17364,
|
||||
FEL_REAVER_ALLIANCE_CONTROL_STATE = 17367,
|
||||
BLOOD_ELF_HORDE_CONTROL_STATE = 17363,
|
||||
BLOOD_ELF_ALLIANCE_CONTROL_STATE = 17365,
|
||||
};
|
||||
|
||||
enum EyeOfTheStormSounds
|
||||
{
|
||||
//strange ids, but sure about them
|
||||
BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE = 8212,
|
||||
BG_EY_SOUND_FLAG_CAPTURED_HORDE = 8213,
|
||||
BG_EY_SOUND_FLAG_PICKED_UP_HORDE = 8174,
|
||||
BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
|
||||
BG_EY_SOUND_FLAG_RESET = 8192
|
||||
};
|
||||
|
||||
enum EyeOfTheStormSpells
|
||||
{
|
||||
BG_EY_NETHERSTORM_FLAG_SPELL = 34976,
|
||||
BG_EY_PLAYER_DROPPED_FLAG_SPELL = 34991,
|
||||
|
||||
// Focused/Brutal Assault
|
||||
BG_EY_FOCUSED_ASSAULT_SPELL = 46392,
|
||||
BG_EY_BRUTAL_ASSAULT_SPELL = 46393
|
||||
};
|
||||
|
||||
enum EyeOfTheStormObjectEntry
|
||||
{
|
||||
BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door
|
||||
BG_OBJECT_H_DOOR_EY_ENTRY = 184720, //Horde door
|
||||
BG_OBJECT_FLAG2_EY_ENTRY = 208977, //Netherstorm flag (flagstand)
|
||||
BG_OBJECT_BE_TOWER_CAP_EY_ENTRY = 184080, //BE Tower Cap Pt
|
||||
BG_OBJECT_FR_TOWER_CAP_EY_ENTRY = 184081, //Fel Reaver Cap Pt
|
||||
BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt
|
||||
BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083, //Draenei Tower Cap Pt
|
||||
};
|
||||
|
||||
enum EyeOfTheStormPointsTrigger
|
||||
{
|
||||
AREATRIGGER_CAPTURE_FLAG = 33
|
||||
};
|
||||
|
||||
enum EyeOfTheStormPoints
|
||||
{
|
||||
FEL_REAVER = 0,
|
||||
BLOOD_ELF = 1,
|
||||
DRAENEI_RUINS = 2,
|
||||
MAGE_TOWER = 3,
|
||||
|
||||
EY_PLAYERS_OUT_OF_POINTS = 4,
|
||||
EY_POINTS_MAX = 4
|
||||
};
|
||||
|
||||
constexpr uint32 BG_EY_NotEYWeekendHonorTicks = 260;
|
||||
constexpr uint32 BG_EY_EYWeekendHonorTicks = 160;
|
||||
|
||||
enum BG_EY_Score
|
||||
{
|
||||
BG_EY_WARNING_NEAR_VICTORY_SCORE = 1200,
|
||||
BG_EY_MAX_TEAM_SCORE = 1500
|
||||
};
|
||||
|
||||
enum BG_EY_FlagState
|
||||
{
|
||||
BG_EY_FLAG_STATE_ON_BASE = 0,
|
||||
BG_EY_FLAG_STATE_WAIT_RESPAWN = 1,
|
||||
BG_EY_FLAG_STATE_ON_PLAYER = 2,
|
||||
BG_EY_FLAG_STATE_ON_GROUND = 3
|
||||
};
|
||||
|
||||
enum EYBattlegroundPointState
|
||||
{
|
||||
EY_POINT_NO_OWNER = 0,
|
||||
EY_POINT_STATE_UNCONTROLLED = 0,
|
||||
EY_POINT_UNDER_CONTROL = 3
|
||||
};
|
||||
|
||||
enum BG_EY_ExploitTeleportLocations
|
||||
{
|
||||
EY_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3773,
|
||||
EY_EXPLOIT_TELEPORT_LOCATION_HORDE = 3772
|
||||
};
|
||||
|
||||
enum EyeOFtheStormBroadcastTexts
|
||||
{
|
||||
BG_EY_TEXT_ALLIANCE_TAKEN_FEL_REAVER_RUINS = 17828,
|
||||
BG_EY_TEXT_HORDE_TAKEN_FEL_REAVER_RUINS = 17829,
|
||||
BG_EY_TEXT_ALLIANCE_LOST_FEL_REAVER_RUINS = 91961,
|
||||
BG_EY_TEXT_HORDE_LOST_FEL_REAVER_RUINS = 91962,
|
||||
|
||||
BG_EY_TEXT_ALLIANCE_TAKEN_BLOOD_ELF_TOWER = 17819,
|
||||
BG_EY_TEXT_HORDE_TAKEN_BLOOD_ELF_TOWER = 17823,
|
||||
BG_EY_TEXT_ALLIANCE_LOST_BLOOD_ELF_TOWER = 91957,
|
||||
BG_EY_TEXT_HORDE_LOST_BLOOD_ELF_TOWER = 91958,
|
||||
|
||||
BG_EY_TEXT_ALLIANCE_TAKEN_DRAENEI_RUINS = 17827,
|
||||
BG_EY_TEXT_HORDE_TAKEN_DRAENEI_RUINS = 91917,
|
||||
BG_EY_TEXT_ALLIANCE_LOST_DRAENEI_RUINS = 91959,
|
||||
BG_EY_TEXT_HORDE_LOST_DRAENEI_RUINS = 91960,
|
||||
|
||||
BG_EY_TEXT_ALLIANCE_TAKEN_MAGE_TOWER = 17824,
|
||||
BG_EY_TEXT_HORDE_TAKEN_MAGE_TOWER = 17825,
|
||||
BG_EY_TEXT_ALLIANCE_LOST_MAGE_TOWER = 91963,
|
||||
BG_EY_TEXT_HORDE_LOST_MAGE_TOWER = 91964,
|
||||
|
||||
BG_EY_TEXT_TAKEN_FLAG = 18359,
|
||||
BG_EY_TEXT_FLAG_DROPPED = 18361,
|
||||
BG_EY_TEXT_FLAG_RESET = 18364,
|
||||
BG_EY_TEXT_ALLIANCE_CAPTURED_FLAG = 18375,
|
||||
BG_EY_TEXT_HORDE_CAPTURED_FLAG = 18384,
|
||||
};
|
||||
|
||||
struct BattlegroundEYPointIconsStruct
|
||||
{
|
||||
BattlegroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex,
|
||||
uint32 worldStateAllianceStatusBarIcon, uint32 worldStateHordeStatusBarIcon)
|
||||
: WorldStateControlIndex(_WorldStateControlIndex), WorldStateAllianceControlledIndex(_WorldStateAllianceControlledIndex), WorldStateHordeControlledIndex(_WorldStateHordeControlledIndex),
|
||||
WorldStateAllianceStatusBarIcon(worldStateAllianceStatusBarIcon), WorldStateHordeStatusBarIcon(worldStateHordeStatusBarIcon) { }
|
||||
uint32 WorldStateControlIndex;
|
||||
uint32 WorldStateAllianceControlledIndex;
|
||||
uint32 WorldStateHordeControlledIndex;
|
||||
uint32 WorldStateAllianceStatusBarIcon;
|
||||
uint32 WorldStateHordeStatusBarIcon;
|
||||
};
|
||||
|
||||
struct BattlegroundEYLosingPointStruct
|
||||
{
|
||||
BattlegroundEYLosingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
|
||||
: MessageIdAlliance(_MessageIdAlliance), MessageIdHorde(_MessageIdHorde)
|
||||
{ }
|
||||
|
||||
uint32 MessageIdAlliance;
|
||||
uint32 MessageIdHorde;
|
||||
};
|
||||
|
||||
struct BattlegroundEYCapturingPointStruct
|
||||
{
|
||||
BattlegroundEYCapturingPointStruct(uint32 _MessageIdAlliance, uint32 _MessageIdHorde)
|
||||
: MessageIdAlliance(_MessageIdAlliance), MessageIdHorde(_MessageIdHorde)
|
||||
{ }
|
||||
|
||||
uint32 MessageIdAlliance;
|
||||
uint32 MessageIdHorde;
|
||||
};
|
||||
|
||||
class BattlegroundEYControlZoneHandler : public ControlZoneHandler
|
||||
{
|
||||
public:
|
||||
explicit BattlegroundEYControlZoneHandler(uint32 point) : _point(point) { }
|
||||
|
||||
uint32 GetPoint() const { return _point; }
|
||||
|
||||
private:
|
||||
uint32 _point;
|
||||
};
|
||||
|
||||
const std::array<BattlegroundEYPointIconsStruct, EY_POINTS_MAX> m_PointsIconStruct =
|
||||
{
|
||||
BattlegroundEYPointIconsStruct(FEL_REAVER_UNCONTROL, FEL_REAVER_ALLIANCE_CONTROL, FEL_REAVER_HORDE_CONTROL, FEL_REAVER_ALLIANCE_CONTROL_STATE, FEL_REAVER_HORDE_CONTROL_STATE),
|
||||
BattlegroundEYPointIconsStruct(BLOOD_ELF_UNCONTROL, BLOOD_ELF_ALLIANCE_CONTROL, BLOOD_ELF_HORDE_CONTROL, BLOOD_ELF_ALLIANCE_CONTROL_STATE, BLOOD_ELF_HORDE_CONTROL_STATE),
|
||||
BattlegroundEYPointIconsStruct(DRAENEI_RUINS_UNCONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL, DRAENEI_RUINS_HORDE_CONTROL, DRAENEI_RUINS_ALLIANCE_CONTROL_STATE, DRAENEI_RUINS_HORDE_CONTROL_STATE),
|
||||
BattlegroundEYPointIconsStruct(MAGE_TOWER_UNCONTROL, MAGE_TOWER_ALLIANCE_CONTROL, MAGE_TOWER_HORDE_CONTROL, MAGE_TOWER_ALLIANCE_CONTROL_STATE, MAGE_TOWER_HORDE_CONTROL_STATE)
|
||||
};
|
||||
|
||||
const std::array<BattlegroundEYLosingPointStruct, EY_POINTS_MAX> m_LosingPointTypes =
|
||||
{
|
||||
BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_FEL_REAVER_RUINS, BG_EY_TEXT_HORDE_LOST_FEL_REAVER_RUINS),
|
||||
BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_BLOOD_ELF_TOWER, BG_EY_TEXT_HORDE_LOST_BLOOD_ELF_TOWER),
|
||||
BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_DRAENEI_RUINS, BG_EY_TEXT_HORDE_LOST_DRAENEI_RUINS),
|
||||
BattlegroundEYLosingPointStruct(BG_EY_TEXT_ALLIANCE_LOST_MAGE_TOWER, BG_EY_TEXT_HORDE_LOST_MAGE_TOWER)
|
||||
};
|
||||
|
||||
const std::array<BattlegroundEYCapturingPointStruct, EY_POINTS_MAX> m_CapturingPointTypes =
|
||||
{
|
||||
BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_FEL_REAVER_RUINS, BG_EY_TEXT_HORDE_TAKEN_FEL_REAVER_RUINS),
|
||||
BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_BLOOD_ELF_TOWER, BG_EY_TEXT_HORDE_TAKEN_BLOOD_ELF_TOWER),
|
||||
BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_DRAENEI_RUINS, BG_EY_TEXT_HORDE_TAKEN_DRAENEI_RUINS),
|
||||
BattlegroundEYCapturingPointStruct(BG_EY_TEXT_ALLIANCE_TAKEN_MAGE_TOWER, BG_EY_TEXT_HORDE_TAKEN_MAGE_TOWER)
|
||||
};
|
||||
|
||||
struct battleground_eye_of_the_storm : BattlegroundScript
|
||||
{
|
||||
enum PvpStats
|
||||
{
|
||||
PVP_STAT_FLAG_CAPTURES = 183
|
||||
};
|
||||
|
||||
static constexpr Seconds POINTS_TICK_TIME = 2s;
|
||||
static constexpr Seconds BG_EY_FLAG_ASSAULT_TIMER = 30s;
|
||||
static constexpr uint16 BG_EY_FLAG_BRUTAL_ASSAULT_STACK_COUNT = 5;
|
||||
static constexpr uint32 BG_EY_EVENT_START_BATTLE = 13180;
|
||||
|
||||
static constexpr std::array<uint8, EY_POINTS_MAX> BG_EY_TickPoints = { 1, 2, 5, 10 };
|
||||
static constexpr std::array<uint32, EY_POINTS_MAX> BG_EY_FlagPoints = { 75, 85, 100, 500 };
|
||||
|
||||
explicit battleground_eye_of_the_storm(BattlegroundMap* map) : BattlegroundScript(map)
|
||||
{
|
||||
_honorScoreTics = { 0, 0 };
|
||||
_honorTics = 0;
|
||||
_pointsTimer.Reset(POINTS_TICK_TIME);
|
||||
_assaultEnabled = false;
|
||||
_assaultStackCount = 0;
|
||||
_flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
|
||||
|
||||
_controlZoneHandlers[BG_OBJECT_FR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(FEL_REAVER);
|
||||
_controlZoneHandlers[BG_OBJECT_BE_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(BLOOD_ELF);
|
||||
_controlZoneHandlers[BG_OBJECT_DR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(DRAENEI_RUINS);
|
||||
_controlZoneHandlers[BG_OBJECT_HU_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(MAGE_TOWER);
|
||||
|
||||
bool isBGWeekend = sBattlegroundMgr->IsBGWeekend(battleground->GetTypeID());
|
||||
_honorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks;
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
UpdateWorldState(EY_MAX_RESOURCES, BG_EY_MAX_TEAM_SCORE);
|
||||
}
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
_pointsTimer.Update(diff);
|
||||
if (_pointsTimer.Passed())
|
||||
{
|
||||
_pointsTimer.Reset(POINTS_TICK_TIME);
|
||||
|
||||
uint8 baseCountAlliance = GetControlledBaseCount(TEAM_ALLIANCE);
|
||||
uint8 baseCountHorde = GetControlledBaseCount(TEAM_HORDE);
|
||||
if (baseCountAlliance > 0)
|
||||
AddPoint(ALLIANCE, BG_EY_TickPoints[baseCountAlliance - 1]);
|
||||
if (baseCountHorde > 0)
|
||||
AddPoint(HORDE, BG_EY_TickPoints[baseCountHorde - 1]);
|
||||
}
|
||||
|
||||
if (_assaultEnabled)
|
||||
{
|
||||
_flagAssaultTimer.Update(diff);
|
||||
if (_flagAssaultTimer.Passed())
|
||||
{
|
||||
_flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
|
||||
if (_assaultStackCount < std::numeric_limits<uint8>::max())
|
||||
{
|
||||
_assaultStackCount++;
|
||||
|
||||
// update assault debuff stacks
|
||||
DoForFlagKeepers([&](Player* player) -> void
|
||||
{
|
||||
ApplyAssaultDebuffToPlayer(player);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
for (ObjectGuid const& door : _doorGUIDs)
|
||||
{
|
||||
if (GameObject* gameObject = battlegroundMap->GetGameObject(door))
|
||||
{
|
||||
gameObject->UseDoorOrButton();
|
||||
gameObject->DespawnOrUnsummon(3s);
|
||||
}
|
||||
}
|
||||
|
||||
// Achievement: Flurry
|
||||
TriggerGameEvent(BG_EY_EVENT_START_BATTLE);
|
||||
}
|
||||
|
||||
void AddPoint(Team team, uint32 points)
|
||||
{
|
||||
battleground->AddPoint(team, points);
|
||||
TeamId const team_index = Battleground::GetTeamIndexByTeamId(team);
|
||||
_honorScoreTics[team_index] += points;
|
||||
if (_honorScoreTics[team_index] >= _honorTics)
|
||||
{
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), team);
|
||||
_honorScoreTics[team_index] -= _honorTics;
|
||||
}
|
||||
|
||||
UpdateTeamScore(team_index);
|
||||
}
|
||||
|
||||
uint8 GetControlledBaseCount(TeamId teamId) const
|
||||
{
|
||||
uint8 baseCount = 0;
|
||||
for (auto const& controlZoneHandler : _controlZoneHandlers)
|
||||
{
|
||||
uint32 point = controlZoneHandler.second->GetPoint();
|
||||
switch (teamId)
|
||||
{
|
||||
case TEAM_ALLIANCE:
|
||||
if (battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1)
|
||||
baseCount++;
|
||||
break;
|
||||
case TEAM_HORDE:
|
||||
if (battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1)
|
||||
baseCount++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return baseCount;
|
||||
}
|
||||
|
||||
void DoForFlagKeepers(std::function<void(Player*)> const& action) const
|
||||
{
|
||||
if (GameObject const* flag = battlegroundMap->GetGameObject(_flagGUID))
|
||||
if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
|
||||
action(carrier);
|
||||
}
|
||||
|
||||
void ResetAssaultDebuff()
|
||||
{
|
||||
_assaultEnabled = false;
|
||||
_assaultStackCount = 0;
|
||||
_flagAssaultTimer.Reset(BG_EY_FLAG_ASSAULT_TIMER);
|
||||
DoForFlagKeepers([&](Player* player) -> void
|
||||
{
|
||||
RemoveAssaultDebuffFromPlayer(player);
|
||||
});
|
||||
}
|
||||
|
||||
void ApplyAssaultDebuffToPlayer(Player* player)
|
||||
{
|
||||
if (_assaultStackCount == 0)
|
||||
return;
|
||||
|
||||
uint32 spellId = BG_EY_FOCUSED_ASSAULT_SPELL;
|
||||
if (_assaultStackCount >= BG_EY_FLAG_BRUTAL_ASSAULT_STACK_COUNT)
|
||||
{
|
||||
player->RemoveAurasDueToSpell(BG_EY_FOCUSED_ASSAULT_SPELL);
|
||||
spellId = BG_EY_BRUTAL_ASSAULT_SPELL;
|
||||
}
|
||||
|
||||
Aura* aura = player->GetAura(spellId);
|
||||
if (!aura)
|
||||
{
|
||||
player->CastSpell(player, spellId, true);
|
||||
aura = player->GetAura(spellId);
|
||||
}
|
||||
|
||||
if (aura)
|
||||
aura->SetStackAmount(_assaultStackCount);
|
||||
}
|
||||
|
||||
void RemoveAssaultDebuffFromPlayer(Player* player)
|
||||
{
|
||||
player->RemoveAurasDueToSpell(BG_EY_FOCUSED_ASSAULT_SPELL);
|
||||
player->RemoveAurasDueToSpell(BG_EY_BRUTAL_ASSAULT_SPELL);
|
||||
}
|
||||
|
||||
void UpdateTeamScore(TeamId Team) const
|
||||
{
|
||||
uint32 score = battleground->GetTeamScore(Team);
|
||||
|
||||
if (score >= BG_EY_MAX_TEAM_SCORE)
|
||||
{
|
||||
score = BG_EY_MAX_TEAM_SCORE;
|
||||
if (Team == TEAM_ALLIANCE)
|
||||
battleground->EndBattleground(ALLIANCE);
|
||||
else
|
||||
battleground->EndBattleground(HORDE);
|
||||
}
|
||||
|
||||
if (Team == TEAM_ALLIANCE)
|
||||
UpdateWorldState(EY_ALLIANCE_RESOURCES, score);
|
||||
else
|
||||
UpdateWorldState(EY_HORDE_RESOURCES, score);
|
||||
}
|
||||
|
||||
void OnEnd(Team winner) override
|
||||
{
|
||||
BattlegroundScript::OnEnd(winner);
|
||||
// Win reward
|
||||
if (winner == ALLIANCE)
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
|
||||
if (winner == HORDE)
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
|
||||
|
||||
// Complete map reward
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), ALLIANCE);
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(1), HORDE);
|
||||
}
|
||||
|
||||
void UpdatePointsCount(TeamId teamId) const
|
||||
{
|
||||
if (teamId == TEAM_ALLIANCE)
|
||||
UpdateWorldState(EY_ALLIANCE_BASE, GetControlledBaseCount(TEAM_ALLIANCE));
|
||||
else
|
||||
UpdateWorldState(EY_HORDE_BASE, GetControlledBaseCount(TEAM_HORDE));
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameObject) override
|
||||
{
|
||||
switch (gameObject->GetEntry())
|
||||
{
|
||||
case BG_OBJECT_A_DOOR_EY_ENTRY:
|
||||
case BG_OBJECT_H_DOOR_EY_ENTRY:
|
||||
_doorGUIDs.insert(gameObject->GetGUID());
|
||||
break;
|
||||
case BG_OBJECT_FLAG2_EY_ENTRY:
|
||||
_flagGUID = gameObject->GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CanCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
|
||||
{
|
||||
if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
|
||||
return false;
|
||||
|
||||
if (GameObject const* flag = battlegroundMap->GetGameObject(_flagGUID))
|
||||
{
|
||||
if (flag->GetFlagCarrierGUID() != player->GetGUID())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GameObject const* controlzone = player->FindNearestGameObjectWithOptions(40.0f, { .StringId = "bg_eye_of_the_storm_control_zone" }))
|
||||
{
|
||||
uint32 const point = _controlZoneHandlers[controlzone->GetEntry()]->GetPoint();
|
||||
switch (battleground->GetPlayerTeam(player->GetGUID()))
|
||||
{
|
||||
case ALLIANCE:
|
||||
return battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateAllianceControlledIndex) == 1;
|
||||
case HORDE:
|
||||
return battlegroundMap->GetWorldStateValue(m_PointsIconStruct[point].WorldStateHordeControlledIndex) == 1;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
|
||||
{
|
||||
if (areaTrigger->GetEntry() != AREATRIGGER_CAPTURE_FLAG)
|
||||
return;
|
||||
|
||||
uint32 const baseCount = GetControlledBaseCount(Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID())));
|
||||
|
||||
if (GameObject const* gameObject = battlegroundMap->GetGameObject(_flagGUID))
|
||||
gameObject->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
|
||||
|
||||
Team const team = Team(battleground->GetPlayerTeam(player->GetGUID()));
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
battleground->SendBroadcastText(BG_EY_TEXT_ALLIANCE_CAPTURED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
battleground->PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
battleground->SendBroadcastText(BG_EY_TEXT_HORDE_CAPTURED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
battleground->PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE);
|
||||
}
|
||||
|
||||
if (baseCount > 0)
|
||||
AddPoint(team, BG_EY_FlagPoints[baseCount - 1]);
|
||||
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_BASE);
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_BASE);
|
||||
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_FLAG_CAPTURES, 1);
|
||||
|
||||
ResetAssaultDebuff();
|
||||
player->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
|
||||
}
|
||||
|
||||
void OnFlagStateChange(GameObject* /*flagInBase*/, FlagState /*oldValue*/, FlagState newValue, Player* player) override
|
||||
{
|
||||
switch (newValue)
|
||||
{
|
||||
case FlagState::InBase:
|
||||
ResetAssaultDebuff();
|
||||
break;
|
||||
case FlagState::Dropped:
|
||||
player->CastSpell(player, SPELL_RECENTLY_DROPPED_NEUTRAL_FLAG, true);
|
||||
RemoveAssaultDebuffFromPlayer(player);
|
||||
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN);
|
||||
|
||||
if (battleground->GetPlayerTeam(player->GetGUID()) == ALLIANCE)
|
||||
battleground->SendBroadcastText(BG_EY_TEXT_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE);
|
||||
else
|
||||
battleground->SendBroadcastText(BG_EY_TEXT_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE);
|
||||
break;
|
||||
case FlagState::Taken:
|
||||
if (battleground->GetPlayerTeam(player->GetGUID()) == ALLIANCE)
|
||||
{
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER);
|
||||
battleground->PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_ALLIANCE);
|
||||
battleground->SendBroadcastText(BG_EY_TEXT_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER);
|
||||
battleground->PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE);
|
||||
battleground->SendBroadcastText(BG_EY_TEXT_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
}
|
||||
|
||||
ApplyAssaultDebuffToPlayer(player);
|
||||
_assaultEnabled = true;
|
||||
|
||||
player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
|
||||
break;
|
||||
case FlagState::Respawning:
|
||||
ResetAssaultDebuff();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateWorldState(NETHERSTORM_FLAG, AsUnderlyingType(newValue));
|
||||
}
|
||||
|
||||
void EventTeamLostPoint(TeamId teamId, uint32 point, GameObject* controlZone) const
|
||||
{
|
||||
if (teamId == TEAM_ALLIANCE)
|
||||
{
|
||||
battleground->SendBroadcastText(m_LosingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 0);
|
||||
}
|
||||
else if (teamId == TEAM_HORDE)
|
||||
{
|
||||
battleground->SendBroadcastText(m_LosingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 0);
|
||||
}
|
||||
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 1);
|
||||
UpdatePointsCount(teamId);
|
||||
}
|
||||
|
||||
void EventTeamCapturedPoint(TeamId teamId, uint32 point, GameObject* controlZone) const
|
||||
{
|
||||
if (teamId == TEAM_ALLIANCE)
|
||||
{
|
||||
battleground->SendBroadcastText(m_CapturingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceControlledIndex, 1);
|
||||
}
|
||||
else if (teamId == TEAM_HORDE)
|
||||
{
|
||||
battleground->SendBroadcastText(m_CapturingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeControlledIndex, 1);
|
||||
}
|
||||
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateControlIndex, 0);
|
||||
UpdatePointsCount(teamId);
|
||||
}
|
||||
|
||||
Team GetPrematureWinner() override
|
||||
{
|
||||
if (battleground->GetTeamScore(TEAM_ALLIANCE) > battleground->GetTeamScore(TEAM_HORDE))
|
||||
return ALLIANCE;
|
||||
|
||||
if (battleground->GetTeamScore(TEAM_HORDE) > battleground->GetTeamScore(TEAM_ALLIANCE))
|
||||
return HORDE;
|
||||
|
||||
return BattlegroundScript::GetPrematureWinner();
|
||||
}
|
||||
|
||||
void ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker) override
|
||||
{
|
||||
BattlegroundScript::ProcessEvent(obj, eventId, invoker);
|
||||
|
||||
if (invoker)
|
||||
{
|
||||
if (GameObject* gameobject = invoker->ToGameObject())
|
||||
{
|
||||
if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
{
|
||||
if (!_controlZoneHandlers.contains(gameobject->GetEntry()))
|
||||
return;
|
||||
|
||||
auto controlzone = gameobject->GetGOInfo()->controlZone;
|
||||
BattlegroundEYControlZoneHandler& handler = *_controlZoneHandlers[invoker->GetEntry()];
|
||||
if (eventId == controlzone.NeutralEventAlliance)
|
||||
EventTeamLostPoint(TEAM_ALLIANCE, handler.GetPoint(), gameobject);
|
||||
else if (eventId == controlzone.NeutralEventHorde)
|
||||
EventTeamLostPoint(TEAM_HORDE, handler.GetPoint(), gameobject);
|
||||
else if (eventId == controlzone.ProgressEventAlliance)
|
||||
EventTeamCapturedPoint(TEAM_ALLIANCE, handler.GetPoint(), gameobject);
|
||||
else if (eventId == controlzone.ProgressEventHorde)
|
||||
EventTeamCapturedPoint(TEAM_HORDE, handler.GetPoint(), gameobject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<uint32, PVP_TEAMS_COUNT> _honorScoreTics;
|
||||
|
||||
TimeTracker _pointsTimer;
|
||||
uint32 _honorTics;
|
||||
|
||||
std::unordered_map<uint32, std::unique_ptr<BattlegroundEYControlZoneHandler>> _controlZoneHandlers;
|
||||
GuidUnorderedSet _doorGUIDs;
|
||||
ObjectGuid _flagGUID;
|
||||
|
||||
// Focused/Brutal Assault
|
||||
bool _assaultEnabled;
|
||||
TimeTracker _flagAssaultTimer;
|
||||
uint8 _assaultStackCount;
|
||||
};
|
||||
|
||||
void AddSC_battleground_eye_of_the_storm()
|
||||
{
|
||||
RegisterBattlegroundMapScript(battleground_eye_of_the_storm, 566);
|
||||
}
|
||||
@@ -0,0 +1,902 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlegroundScript.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "GameTime.h"
|
||||
#include "isle_of_conquest.h"
|
||||
#include "Map.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Timer.h"
|
||||
#include "Transport.h"
|
||||
#include "TransportMgr.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
inline constexpr uint16 MAX_REINFORCEMENTS = 400;
|
||||
|
||||
enum BannersTypes
|
||||
{
|
||||
BANNER_A_CONTROLLED,
|
||||
BANNER_A_CONTESTED,
|
||||
BANNER_H_CONTROLLED,
|
||||
BANNER_H_CONTESTED
|
||||
};
|
||||
|
||||
enum BG_IC_ExploitTeleportLocations
|
||||
{
|
||||
IC_EXPLOIT_TELEPORT_LOCATION_ALLIANCE = 3986,
|
||||
IC_EXPLOIT_TELEPORT_LOCATION_HORDE = 3983
|
||||
};
|
||||
|
||||
enum BG_IC_GateState
|
||||
{
|
||||
BG_IC_GATE_OK = 1,
|
||||
BG_IC_GATE_DAMAGED = 2,
|
||||
BG_IC_GATE_DESTROYED = 3
|
||||
};
|
||||
|
||||
enum ICDoorList
|
||||
{
|
||||
BG_IC_H_FRONT,
|
||||
BG_IC_H_WEST,
|
||||
BG_IC_H_EAST,
|
||||
BG_IC_A_FRONT,
|
||||
BG_IC_A_WEST,
|
||||
BG_IC_A_EAST,
|
||||
BG_IC_MAXDOOR
|
||||
};
|
||||
|
||||
enum ICNodePointType
|
||||
{
|
||||
NODE_TYPE_REFINERY,
|
||||
NODE_TYPE_QUARRY,
|
||||
NODE_TYPE_DOCKS,
|
||||
NODE_TYPE_HANGAR,
|
||||
NODE_TYPE_WORKSHOP,
|
||||
|
||||
// Graveyards
|
||||
NODE_TYPE_GRAVEYARD_A,
|
||||
NODE_TYPE_GRAVEYARD_H,
|
||||
|
||||
MAX_NODE_TYPES
|
||||
};
|
||||
|
||||
enum class IsleOfConquestNodeState
|
||||
{
|
||||
Neutral,
|
||||
ConflictA,
|
||||
ConflictH,
|
||||
ControlledA,
|
||||
ControlledH
|
||||
};
|
||||
|
||||
enum ICBroadcastTexts
|
||||
{
|
||||
BG_IC_TEXT_FRONT_GATE_HORDE_DESTROYED = 35409,
|
||||
BG_IC_TEXT_FRONT_GATE_ALLIANCE_DESTROYED = 35410,
|
||||
BG_IC_TEXT_WEST_GATE_HORDE_DESTROYED = 35411,
|
||||
BG_IC_TEXT_WEST_GATE_ALLIANCE_DESTROYED = 35412,
|
||||
BG_IC_TEXT_EAST_GATE_HORDE_DESTROYED = 35413,
|
||||
BG_IC_TEXT_EAST_GATE_ALLIANCE_DESTROYED = 35414
|
||||
};
|
||||
|
||||
// I.E: Hangar, Quarry, Graveyards .. etc
|
||||
struct IoCStaticNodeInfo
|
||||
{
|
||||
ICNodePointType NodeType;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 Assaulted;
|
||||
uint32 Defended;
|
||||
uint32 AllianceTaken;
|
||||
uint32 HordeTaken;
|
||||
} TextIds;
|
||||
|
||||
struct
|
||||
{
|
||||
int32 Uncontrolled;
|
||||
int32 ConflictA;
|
||||
int32 ConflictH;
|
||||
int32 ControlledA;
|
||||
int32 ControlledH;
|
||||
} WorldStateIds;
|
||||
};
|
||||
|
||||
class ICNodePoint
|
||||
{
|
||||
public:
|
||||
explicit ICNodePoint(IsleOfConquestNodeState state, IoCStaticNodeInfo const& nodeInfo) : _state(state), _nodeInfo(nodeInfo)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case IsleOfConquestNodeState::ControlledH:
|
||||
_lastControlled = TEAM_HORDE;
|
||||
break;
|
||||
case IsleOfConquestNodeState::ControlledA:
|
||||
_lastControlled = TEAM_ALLIANCE;
|
||||
break;
|
||||
case IsleOfConquestNodeState::ConflictA:
|
||||
case IsleOfConquestNodeState::ConflictH:
|
||||
case IsleOfConquestNodeState::Neutral:
|
||||
_lastControlled = TEAM_NEUTRAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IsleOfConquestNodeState GetState() const { return _state; }
|
||||
|
||||
bool IsContested() const
|
||||
{
|
||||
return _state == IsleOfConquestNodeState::ConflictA || _state == IsleOfConquestNodeState::ConflictH;
|
||||
}
|
||||
|
||||
TeamId GetLastControlledTeam() const { return _lastControlled; }
|
||||
|
||||
IoCStaticNodeInfo const& GetNodeInfo() const { return _nodeInfo; }
|
||||
|
||||
void UpdateState(IsleOfConquestNodeState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case IsleOfConquestNodeState::ControlledA:
|
||||
_lastControlled = TEAM_ALLIANCE;
|
||||
break;
|
||||
case IsleOfConquestNodeState::ControlledH:
|
||||
_lastControlled = TEAM_HORDE;
|
||||
break;
|
||||
case IsleOfConquestNodeState::Neutral:
|
||||
_lastControlled = TEAM_NEUTRAL;
|
||||
break;
|
||||
case IsleOfConquestNodeState::ConflictA:
|
||||
case IsleOfConquestNodeState::ConflictH:
|
||||
break;
|
||||
}
|
||||
|
||||
_state = state;
|
||||
}
|
||||
private:
|
||||
IsleOfConquestNodeState _state;
|
||||
TeamId _lastControlled;
|
||||
IoCStaticNodeInfo _nodeInfo;
|
||||
};
|
||||
|
||||
const IoCStaticNodeInfo nodePointInitial[MAX_NODE_TYPES] =
|
||||
{
|
||||
{ NODE_TYPE_REFINERY, { 35377, 35378, 35379, 35380 }, { BG_IC_REFINERY_UNCONTROLLED, BG_IC_REFINERY_CONFLICT_A, BG_IC_REFINERY_CONFLICT_H, BG_IC_REFINERY_CONTROLLED_A, BG_IC_REFINERY_CONTROLLED_H } },
|
||||
{ NODE_TYPE_QUARRY, { 35373, 35374, 35375, 35376 }, { BG_IC_QUARRY_UNCONTROLLED, BG_IC_QUARRY_CONFLICT_A, BG_IC_QUARRY_CONFLICT_H, BG_IC_QUARRY_CONTROLLED_A, BG_IC_QUARRY_CONTROLLED_H } },
|
||||
{ NODE_TYPE_DOCKS, { 35365, 35366, 35367, 35368 }, { BG_IC_DOCKS_UNCONTROLLED, BG_IC_DOCKS_CONFLICT_A, BG_IC_DOCKS_CONFLICT_H, BG_IC_DOCKS_CONTROLLED_A, BG_IC_DOCKS_CONTROLLED_H } },
|
||||
{ NODE_TYPE_HANGAR, { 35369, 35370, 35371, 35372 }, { BG_IC_HANGAR_UNCONTROLLED, BG_IC_HANGAR_CONFLICT_A, BG_IC_HANGAR_CONFLICT_H, BG_IC_HANGAR_CONTROLLED_A, BG_IC_HANGAR_CONTROLLED_H } },
|
||||
{ NODE_TYPE_WORKSHOP, { 35278, 35286, 35279, 35280 }, { BG_IC_WORKSHOP_UNCONTROLLED, BG_IC_WORKSHOP_CONFLICT_A, BG_IC_WORKSHOP_CONFLICT_H, BG_IC_WORKSHOP_CONTROLLED_A, BG_IC_WORKSHOP_CONTROLLED_H } },
|
||||
{ NODE_TYPE_GRAVEYARD_A, { 35461, 35459, 35463, 35466 }, { BG_IC_ALLIANCE_KEEP_UNCONTROLLED, BG_IC_ALLIANCE_KEEP_CONFLICT_A, BG_IC_ALLIANCE_KEEP_CONFLICT_H, BG_IC_ALLIANCE_KEEP_CONTROLLED_A, BG_IC_ALLIANCE_KEEP_CONTROLLED_H } },
|
||||
{ NODE_TYPE_GRAVEYARD_H, { 35462, 35460, 35464, 35465 }, { BG_IC_HORDE_KEEP_UNCONTROLLED, BG_IC_HORDE_KEEP_CONFLICT_A, BG_IC_HORDE_KEEP_CONFLICT_H, BG_IC_HORDE_KEEP_CONTROLLED_A, BG_IC_HORDE_KEEP_CONTROLLED_H } }
|
||||
};
|
||||
|
||||
enum HonorRewards
|
||||
{
|
||||
RESOURCE_HONOR_AMOUNT = 12,
|
||||
WINNER_HONOR_AMOUNT = 500
|
||||
};
|
||||
|
||||
enum IsleOfConquestPvpStats
|
||||
{
|
||||
PVP_STAT_BASES_ASSAULTED = 245,
|
||||
PVP_STAT_BASES_DEFENDED = 246
|
||||
};
|
||||
|
||||
enum IsleOfConquestGameObjects
|
||||
{
|
||||
GO_TELEPORTER_1 = 195314, // 195314 H-OUT 66549
|
||||
GO_TELEPORTER_2 = 195313, // 195313 H-IN 66548
|
||||
|
||||
GO_TELEPORTER_3 = 195315, // 195315 A-OUT 66549
|
||||
GO_TELEPORTER_4 = 195316, // 195316 A-IN 66548
|
||||
|
||||
GO_TELEPORTER_EFFECTS_A = 195701,
|
||||
GO_TELEPORTER_EFFECTS_H = 195702,
|
||||
|
||||
GO_DOODAD_HU_PORTCULLIS01 = 195436,
|
||||
GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01 = 195703,
|
||||
GO_DOODAD_PORTCULLISACTIVE02 = 195452,
|
||||
GO_DOODAD_VR_PORTCULLIS01 = 195437,
|
||||
|
||||
GO_HORDE_GATE_1 = 195494,
|
||||
GO_HORDE_GATE_2 = 195495,
|
||||
GO_HORDE_GATE_3 = 195496,
|
||||
|
||||
GO_ALLIANCE_GATE_1 = 195699,
|
||||
GO_ALLIANCE_GATE_2 = 195700,
|
||||
GO_ALLIANCE_GATE_3 = 195698,
|
||||
|
||||
GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01 = 195491,
|
||||
|
||||
// banners
|
||||
GO_BANNER_WORKSHOP_CONTROLLED_H = 195130,
|
||||
GO_BANNER_WORKSHOP_CONTROLLED_A = 195132,
|
||||
GO_BANNER_WORKSHOP_CONTROLLED_N = 195133,
|
||||
GO_BANNER_WORKSHOP_CONTESTED_A = 195144,
|
||||
GO_BANNER_WORKSHOP_CONTESTED_H = 195145,
|
||||
|
||||
GO_BANNER_DOCKS_CONTROLLED_A = 195149,
|
||||
GO_BANNER_DOCKS_CONTESTED_A = 195150,
|
||||
GO_BANNER_DOCKS_CONTROLLED_H = 195151,
|
||||
GO_BANNER_DOCKS_CONTESTED_H = 195152,
|
||||
GO_BANNER_DOCKS_CONTROLLED_N = 195157,
|
||||
|
||||
GO_BANNER_HANGAR_CONTROLLED_A = 195153,
|
||||
GO_BANNER_HANGAR_CONTESTED_A = 195154,
|
||||
GO_BANNER_HANGAR_CONTROLLED_H = 195155,
|
||||
GO_BANNER_HANGAR_CONTESTED_H = 195156,
|
||||
GO_BANNER_HANGAR_CONTROLLED_N = 195158,
|
||||
|
||||
GO_BANNER_QUARRY_CONTROLLED_A = 195334,
|
||||
GO_BANNER_QUARRY_CONTROLLED_H = 195336,
|
||||
GO_BANNER_QUARRY_CONTESTED_A = 195335,
|
||||
GO_BANNER_QUARRY_CONTESTED_H = 195337,
|
||||
GO_BANNER_QUARRY_CONTROLLED_N = 195338,
|
||||
|
||||
GO_BANNER_REFINERY_CONTROLLED_A = 195339,
|
||||
GO_BANNER_REFINERY_CONTROLLED_H = 195341,
|
||||
GO_BANNER_REFINERY_CONTESTED_A = 195340,
|
||||
GO_BANNER_REFINERY_CONTESTED_H = 195342,
|
||||
GO_BANNER_REFINERY_CONTROLLED_N = 195343,
|
||||
|
||||
GO_BANNER_HORDE_KEEP_CONTROLLED_A = 195391,
|
||||
GO_BANNER_HORDE_KEEP_CONTROLLED_H = 195393,
|
||||
GO_BANNER_HORDE_KEEP_CONTESTED_A = 195392,
|
||||
GO_BANNER_HORDE_KEEP_CONTESTED_H = 195394,
|
||||
|
||||
GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A = 195396,
|
||||
GO_BANNER_ALLIANCE_KEEP_CONTROLLED_H = 195398,
|
||||
GO_BANNER_ALLIANCE_KEEP_CONTESTED_A = 195397,
|
||||
GO_BANNER_ALLIANCE_KEEP_CONTESTED_H = 195399,
|
||||
|
||||
GO_KEEP_GATE_H = 195223,
|
||||
GO_KEEP_GATE_A = 195451,
|
||||
GO_KEEP_GATE_2_A = 195452,
|
||||
|
||||
GO_HORDE_GUNSHIP = 195276,
|
||||
GO_ALLIANCE_GUNSHIP = 195121
|
||||
};
|
||||
|
||||
static constexpr Seconds IOC_RESOURCE_TIMER = 45s;
|
||||
|
||||
static constexpr Position GunshipTeleportTriggerPosition[2] =
|
||||
{
|
||||
{ 11.69964981079101562f, 0.034145999699831008f, 20.62075996398925781f, 3.211405754089355468f },
|
||||
{ 7.30560922622680664f, -0.09524600207805633f, 34.51021575927734375f, 3.159045934677124023f }
|
||||
};
|
||||
|
||||
struct battleground_isle_of_conquest : BattlegroundScript
|
||||
{
|
||||
explicit battleground_isle_of_conquest(BattlegroundMap* map) : BattlegroundScript(map)
|
||||
{
|
||||
_factionReinforcements = { MAX_REINFORCEMENTS, MAX_REINFORCEMENTS };
|
||||
|
||||
_gateStatus = { BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK, BG_IC_GATE_OK };
|
||||
|
||||
_gunshipGUIDs = { };
|
||||
_cannonGUIDs = { };
|
||||
_nodePoints = { };
|
||||
_keepGateGUIDs = { };
|
||||
_keepBannerGUIDs = { };
|
||||
|
||||
_nodePoints[NODE_TYPE_REFINERY] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_REFINERY]);
|
||||
_nodePoints[NODE_TYPE_QUARRY] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_QUARRY]);
|
||||
_nodePoints[NODE_TYPE_DOCKS] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_DOCKS]);
|
||||
_nodePoints[NODE_TYPE_HANGAR] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_HANGAR]);
|
||||
_nodePoints[NODE_TYPE_WORKSHOP] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::Neutral, nodePointInitial[NODE_TYPE_WORKSHOP]);
|
||||
_nodePoints[NODE_TYPE_GRAVEYARD_A] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::ControlledA, nodePointInitial[NODE_TYPE_GRAVEYARD_A]);
|
||||
_nodePoints[NODE_TYPE_GRAVEYARD_H] = std::make_unique<ICNodePoint>(IsleOfConquestNodeState::ControlledH, nodePointInitial[NODE_TYPE_GRAVEYARD_H]);
|
||||
|
||||
_resourceTimer.Reset(IOC_RESOURCE_TIMER);
|
||||
}
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
BattlegroundScript::OnUpdate(diff);
|
||||
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
_resourceTimer.Update(diff);
|
||||
if (_resourceTimer.Passed())
|
||||
{
|
||||
for (uint8 i = 0; i < NODE_TYPE_DOCKS; ++i)
|
||||
{
|
||||
if (_nodePoints[i]->GetLastControlledTeam() != TEAM_NEUTRAL && !_nodePoints[i]->IsContested())
|
||||
{
|
||||
_factionReinforcements[_nodePoints[i]->GetLastControlledTeam()] += 1;
|
||||
battleground->RewardHonorToTeam(RESOURCE_HONOR_AMOUNT, _nodePoints[i]->GetLastControlledTeam() == TEAM_ALLIANCE ? ALLIANCE : HORDE);
|
||||
UpdateWorldState((_nodePoints[i]->GetLastControlledTeam() == TEAM_ALLIANCE ? BG_IC_ALLIANCE_REINFORCEMENTS : BG_IC_HORDE_REINFORCEMENTS), _factionReinforcements[_nodePoints[i]->GetLastControlledTeam()]);
|
||||
}
|
||||
}
|
||||
|
||||
_resourceTimer.Reset(IOC_RESOURCE_TIMER);
|
||||
}
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
BattlegroundScript::OnStart();
|
||||
|
||||
auto gameobjectAction = [&](GuidVector const& guids, std::function<void(GameObject*)> const& action) -> void
|
||||
{
|
||||
for (ObjectGuid const& guid : guids)
|
||||
if (GameObject* gameObject = battlegroundMap->GetGameObject(guid))
|
||||
action(gameObject);
|
||||
};
|
||||
|
||||
gameobjectAction(_mainGateDoorGUIDs, [&](GameObject* gameobject) -> void
|
||||
{
|
||||
gameobject->UseDoorOrButton();
|
||||
gameobject->DespawnOrUnsummon(20s);
|
||||
});
|
||||
|
||||
gameobjectAction(_portcullisGUIDs, [&](GameObject* gameobject) -> void
|
||||
{
|
||||
gameobject->UseDoorOrButton();
|
||||
});
|
||||
|
||||
gameobjectAction(_teleporterGUIDs, [&](GameObject* gameobject) -> void
|
||||
{
|
||||
gameobject->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
});
|
||||
|
||||
gameobjectAction(_teleporterEffectGUIDs, [&](GameObject* gameobject) -> void
|
||||
{
|
||||
gameobject->SetGoState(GO_STATE_ACTIVE);
|
||||
});
|
||||
|
||||
_scheduler.Schedule(20s, [&](TaskContext)
|
||||
{
|
||||
for (ObjectGuid const& guid : _wallGUIDs)
|
||||
if (GameObject* gameobject = battlegroundMap->GetGameObject(guid))
|
||||
gameobject->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
|
||||
});
|
||||
}
|
||||
|
||||
void OnUnitKilled(Creature* unit, Unit* killer) override
|
||||
{
|
||||
BattlegroundScript::OnUnitKilled(unit, killer);
|
||||
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
uint32 entry = unit->GetEntry();
|
||||
if (entry == NPC_HIGH_COMMANDER_HALFORD_WYRMBANE)
|
||||
{
|
||||
battleground->RewardHonorToTeam(WINNER_HONOR_AMOUNT, HORDE);
|
||||
battleground->EndBattleground(HORDE);
|
||||
}
|
||||
else if (entry == NPC_OVERLORD_AGMAR)
|
||||
{
|
||||
battleground->RewardHonorToTeam(WINNER_HONOR_AMOUNT, ALLIANCE);
|
||||
battleground->EndBattleground(ALLIANCE);
|
||||
}
|
||||
|
||||
//Achievement Mowed Down
|
||||
// TO-DO: This should be done on the script of each vehicle of the BG.
|
||||
if (unit->IsVehicle())
|
||||
{
|
||||
if (Player* killerPlayer = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
killerPlayer->CastSpell(killerPlayer, SPELL_DESTROYED_VEHICLE_ACHIEVEMENT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPlayerKilled(Player* player, Player* killer) override
|
||||
{
|
||||
BattlegroundScript::OnPlayerKilled(player, killer);
|
||||
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
TeamId const victimTeamId = Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID()));
|
||||
_factionReinforcements[victimTeamId] -= 1;
|
||||
|
||||
UpdateWorldState((battleground->GetPlayerTeam(player->GetGUID()) == ALLIANCE ? BG_IC_ALLIANCE_REINFORCEMENTS : BG_IC_HORDE_REINFORCEMENTS), _factionReinforcements[victimTeamId]);
|
||||
|
||||
// we must end the battleground
|
||||
if (_factionReinforcements[victimTeamId] < 1)
|
||||
battleground->EndBattleground(battleground->GetPlayerTeam(killer->GetGUID()));
|
||||
}
|
||||
|
||||
static uint32 GetGateIDFromEntry(uint32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case GO_HORDE_GATE_1:
|
||||
return BG_IC_H_FRONT;
|
||||
case GO_HORDE_GATE_2:
|
||||
return BG_IC_H_WEST;
|
||||
case GO_HORDE_GATE_3:
|
||||
return BG_IC_H_EAST;
|
||||
case GO_ALLIANCE_GATE_3:
|
||||
return BG_IC_A_FRONT;
|
||||
case GO_ALLIANCE_GATE_1:
|
||||
return BG_IC_A_WEST;
|
||||
case GO_ALLIANCE_GATE_2:
|
||||
return BG_IC_A_EAST;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int32 GetWorldStateFromGateEntry(uint32 id, bool open)
|
||||
{
|
||||
int32 uws = 0;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case GO_HORDE_GATE_1:
|
||||
uws = (open ? BG_IC_GATE_FRONT_H_WS_OPEN : BG_IC_GATE_FRONT_H_WS_CLOSED);
|
||||
break;
|
||||
case GO_HORDE_GATE_2:
|
||||
uws = (open ? BG_IC_GATE_WEST_H_WS_OPEN : BG_IC_GATE_WEST_H_WS_CLOSED);
|
||||
break;
|
||||
case GO_HORDE_GATE_3:
|
||||
uws = (open ? BG_IC_GATE_EAST_H_WS_OPEN : BG_IC_GATE_EAST_H_WS_CLOSED);
|
||||
break;
|
||||
case GO_ALLIANCE_GATE_3:
|
||||
uws = (open ? BG_IC_GATE_FRONT_A_WS_OPEN : BG_IC_GATE_FRONT_A_WS_CLOSED);
|
||||
break;
|
||||
case GO_ALLIANCE_GATE_1:
|
||||
uws = (open ? BG_IC_GATE_WEST_A_WS_OPEN : BG_IC_GATE_WEST_A_WS_CLOSED);
|
||||
break;
|
||||
case GO_ALLIANCE_GATE_2:
|
||||
uws = (open ? BG_IC_GATE_EAST_A_WS_OPEN : BG_IC_GATE_EAST_A_WS_CLOSED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return uws;
|
||||
}
|
||||
|
||||
void UpdateNodeWorldState(ICNodePoint const& node) const
|
||||
{
|
||||
UpdateWorldState(node.GetNodeInfo().WorldStateIds.ConflictA, node.GetState() == IsleOfConquestNodeState::ConflictA);
|
||||
UpdateWorldState(node.GetNodeInfo().WorldStateIds.ConflictH, node.GetState() == IsleOfConquestNodeState::ConflictH);
|
||||
UpdateWorldState(node.GetNodeInfo().WorldStateIds.ControlledA, node.GetState() == IsleOfConquestNodeState::ControlledA);
|
||||
UpdateWorldState(node.GetNodeInfo().WorldStateIds.ControlledH, node.GetState() == IsleOfConquestNodeState::ControlledH);
|
||||
UpdateWorldState(node.GetNodeInfo().WorldStateIds.Uncontrolled, node.GetState() == IsleOfConquestNodeState::Neutral);
|
||||
}
|
||||
|
||||
static ICNodePointType BannerToNodeType(uint32 bannerId)
|
||||
{
|
||||
switch (bannerId)
|
||||
{
|
||||
case GO_BANNER_ALLIANCE_KEEP_CONTESTED_A:
|
||||
case GO_BANNER_ALLIANCE_KEEP_CONTESTED_H:
|
||||
case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A:
|
||||
case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_H:
|
||||
return NODE_TYPE_GRAVEYARD_A;
|
||||
case GO_BANNER_HORDE_KEEP_CONTESTED_A:
|
||||
case GO_BANNER_HORDE_KEEP_CONTESTED_H:
|
||||
case GO_BANNER_HORDE_KEEP_CONTROLLED_A:
|
||||
case GO_BANNER_HORDE_KEEP_CONTROLLED_H:
|
||||
return NODE_TYPE_GRAVEYARD_H;
|
||||
case GO_BANNER_DOCKS_CONTESTED_A:
|
||||
case GO_BANNER_DOCKS_CONTESTED_H:
|
||||
case GO_BANNER_DOCKS_CONTROLLED_A:
|
||||
case GO_BANNER_DOCKS_CONTROLLED_H:
|
||||
case GO_BANNER_DOCKS_CONTROLLED_N:
|
||||
return NODE_TYPE_DOCKS;
|
||||
case GO_BANNER_HANGAR_CONTESTED_A:
|
||||
case GO_BANNER_HANGAR_CONTESTED_H:
|
||||
case GO_BANNER_HANGAR_CONTROLLED_A:
|
||||
case GO_BANNER_HANGAR_CONTROLLED_H:
|
||||
case GO_BANNER_HANGAR_CONTROLLED_N:
|
||||
return NODE_TYPE_HANGAR;
|
||||
case GO_BANNER_WORKSHOP_CONTESTED_A:
|
||||
case GO_BANNER_WORKSHOP_CONTESTED_H:
|
||||
case GO_BANNER_WORKSHOP_CONTROLLED_A:
|
||||
case GO_BANNER_WORKSHOP_CONTROLLED_H:
|
||||
case GO_BANNER_WORKSHOP_CONTROLLED_N:
|
||||
return NODE_TYPE_WORKSHOP;
|
||||
case GO_BANNER_QUARRY_CONTESTED_A:
|
||||
case GO_BANNER_QUARRY_CONTESTED_H:
|
||||
case GO_BANNER_QUARRY_CONTROLLED_A:
|
||||
case GO_BANNER_QUARRY_CONTROLLED_H:
|
||||
case GO_BANNER_QUARRY_CONTROLLED_N:
|
||||
return NODE_TYPE_QUARRY;
|
||||
case GO_BANNER_REFINERY_CONTESTED_A:
|
||||
case GO_BANNER_REFINERY_CONTESTED_H:
|
||||
case GO_BANNER_REFINERY_CONTROLLED_A:
|
||||
case GO_BANNER_REFINERY_CONTROLLED_H:
|
||||
case GO_BANNER_REFINERY_CONTROLLED_N:
|
||||
return NODE_TYPE_REFINERY;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return MAX_NODE_TYPES;
|
||||
}
|
||||
|
||||
void HandleCapturedNodes(ICNodePoint& node)
|
||||
{
|
||||
if (node.GetLastControlledTeam() == TEAM_NEUTRAL)
|
||||
return;
|
||||
|
||||
switch (node.GetNodeInfo().NodeType)
|
||||
{
|
||||
case NODE_TYPE_QUARRY:
|
||||
case NODE_TYPE_REFINERY:
|
||||
battlegroundMap->UpdateAreaDependentAuras();
|
||||
break;
|
||||
case NODE_TYPE_HANGAR:
|
||||
if (Transport* transport = battlegroundMap->GetTransport(_gunshipGUIDs[node.GetLastControlledTeam()]))
|
||||
{
|
||||
// Can't have this in spawngroup, creature is on a transport
|
||||
if (TempSummon* trigger = transport->SummonPassenger(NPC_WORLD_TRIGGER_NOT_FLOATING, GunshipTeleportTriggerPosition[node.GetLastControlledTeam()], TEMPSUMMON_MANUAL_DESPAWN))
|
||||
_gunshipTeleportTarget = trigger->GetGUID();
|
||||
|
||||
transport->EnableMovement(true);
|
||||
}
|
||||
|
||||
for (ObjectGuid const& guid : _cannonGUIDs[node.GetLastControlledTeam()])
|
||||
if (Creature* cannon = battlegroundMap->GetCreature(guid))
|
||||
cannon->SetUninteractible(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
BattlegroundScript::OnCreatureCreate(creature);
|
||||
|
||||
if (creature->HasStringId("bg_ioc_faction_1735"))
|
||||
creature->SetFaction(FACTION_HORDE_GENERIC_WG);
|
||||
else if (creature->HasStringId("bg_ioc_faction_1732"))
|
||||
creature->SetFaction(FACTION_ALLIANCE_GENERIC_WG);
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_ALLIANCE_GUNSHIP_CANNON:
|
||||
_cannonGUIDs[TEAM_ALLIANCE].emplace_back(creature->GetGUID());
|
||||
creature->SetUninteractible(true);
|
||||
creature->SetControlled(true, UNIT_STATE_ROOT);
|
||||
break;
|
||||
case NPC_HORDE_GUNSHIP_CANNON:
|
||||
_cannonGUIDs[TEAM_HORDE].emplace_back(creature->GetGUID());
|
||||
creature->SetUninteractible(true);
|
||||
creature->SetControlled(true, UNIT_STATE_ROOT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject) override
|
||||
{
|
||||
BattlegroundScript::OnGameObjectCreate(gameobject);
|
||||
|
||||
if (gameobject->IsDestructibleBuilding())
|
||||
_wallGUIDs.emplace_back(gameobject->GetGUID());
|
||||
|
||||
if (gameobject->HasStringId("bg_ioc_faction_1735"))
|
||||
gameobject->SetFaction(FACTION_HORDE_GENERIC_WG);
|
||||
else if (gameobject->HasStringId("bg_ioc_faction_1732"))
|
||||
gameobject->SetFaction(FACTION_ALLIANCE_GENERIC_WG);
|
||||
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_TELEPORTER_1:
|
||||
case GO_TELEPORTER_2:
|
||||
case GO_TELEPORTER_3:
|
||||
case GO_TELEPORTER_4:
|
||||
_teleporterGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case GO_TELEPORTER_EFFECTS_A:
|
||||
case GO_TELEPORTER_EFFECTS_H:
|
||||
_teleporterEffectGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case GO_DOODAD_ND_HUMAN_GATE_CLOSEDFX_DOOR01:
|
||||
case GO_DOODAD_ND_WINTERORC_WALL_GATEFX_DOOR01:
|
||||
_mainGateDoorGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case GO_DOODAD_HU_PORTCULLIS01:
|
||||
case GO_DOODAD_VR_PORTCULLIS01:
|
||||
_portcullisGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case GO_KEEP_GATE_H:
|
||||
_keepGateGUIDs[TEAM_HORDE].emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case GO_KEEP_GATE_A:
|
||||
case GO_KEEP_GATE_2_A:
|
||||
_keepGateGUIDs[TEAM_ALLIANCE].emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case GO_BANNER_ALLIANCE_KEEP_CONTROLLED_A:
|
||||
_keepBannerGUIDs[TEAM_ALLIANCE] = gameobject->GetGUID();
|
||||
break;
|
||||
case GO_BANNER_HORDE_KEEP_CONTROLLED_H:
|
||||
_keepBannerGUIDs[TEAM_HORDE] = gameobject->GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
BattlegroundScript::OnInit();
|
||||
|
||||
if (Transport* transport = sTransportMgr->CreateTransport(GO_HORDE_GUNSHIP, battlegroundMap))
|
||||
{
|
||||
_gunshipGUIDs[TEAM_HORDE] = transport->GetGUID();
|
||||
transport->EnableMovement(false);
|
||||
}
|
||||
|
||||
if (Transport* transport = sTransportMgr->CreateTransport(GO_ALLIANCE_GUNSHIP, battlegroundMap))
|
||||
{
|
||||
_gunshipGUIDs[TEAM_ALLIANCE] = transport->GetGUID();
|
||||
transport->EnableMovement(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(uint32 actionId, WorldObject* source, WorldObject* target) override
|
||||
{
|
||||
BattlegroundScript::DoAction(actionId, source, target);
|
||||
|
||||
switch (actionId)
|
||||
{
|
||||
case ACTION_IOC_INTERACT_CAPTURABLE_OBJECT:
|
||||
OnPlayerInteractWithBanner(WorldObject::ToPlayer(source), WorldObject::ToGameObject(target));
|
||||
break;
|
||||
case ACTION_IOC_CAPTURE_CAPTURABLE_OBJECT:
|
||||
HandleCaptureNodeAction(WorldObject::ToGameObject(target));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnPlayerInteractWithBanner(Player* player, GameObject* banner)
|
||||
{
|
||||
if (!player || !banner)
|
||||
return;
|
||||
|
||||
Team const playerTeam = battleground->GetPlayerTeam(player->GetGUID());
|
||||
TeamId const playerTeamId = Battleground::GetTeamIndexByTeamId(playerTeam);
|
||||
ICNodePointType const nodeType = BannerToNodeType(banner->GetEntry());
|
||||
if (nodeType == MAX_NODE_TYPES)
|
||||
return;
|
||||
|
||||
ICNodePoint& node = *_nodePoints[nodeType];
|
||||
|
||||
bool assault = false;
|
||||
bool defend = false;
|
||||
|
||||
switch (node.GetState())
|
||||
{
|
||||
case IsleOfConquestNodeState::Neutral:
|
||||
assault = true;
|
||||
break;
|
||||
case IsleOfConquestNodeState::ControlledH:
|
||||
assault = playerTeamId != TEAM_HORDE;
|
||||
break;
|
||||
case IsleOfConquestNodeState::ControlledA:
|
||||
assault = playerTeamId != TEAM_ALLIANCE;
|
||||
break;
|
||||
case IsleOfConquestNodeState::ConflictA:
|
||||
defend = playerTeamId == node.GetLastControlledTeam();
|
||||
assault = !defend && playerTeamId == TEAM_HORDE;
|
||||
break;
|
||||
case IsleOfConquestNodeState::ConflictH:
|
||||
defend = playerTeamId == node.GetLastControlledTeam();
|
||||
assault = !defend && playerTeamId == TEAM_ALLIANCE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (assault)
|
||||
OnPlayerAssaultNode(player, node);
|
||||
else if (defend)
|
||||
OnPlayerDefendNode(player, node);
|
||||
|
||||
battlegroundMap->UpdateSpawnGroupConditions();
|
||||
}
|
||||
|
||||
void OnPlayerAssaultNode(Player* player, ICNodePoint& node)
|
||||
{
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
Team const playerTeam = battleground->GetPlayerTeam(player->GetGUID());
|
||||
TeamId const playerTeamId = Battleground::GetTeamIndexByTeamId(playerTeam);
|
||||
|
||||
IsleOfConquestNodeState const newState = playerTeamId == TEAM_HORDE ? IsleOfConquestNodeState::ConflictH : IsleOfConquestNodeState::ConflictA;
|
||||
node.UpdateState(newState);
|
||||
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_ASSAULTED, 1);
|
||||
|
||||
ChatMsg const messageType = playerTeamId == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
battleground->SendBroadcastText(node.GetNodeInfo().TextIds.Assaulted, messageType, player);
|
||||
UpdateNodeWorldState(node);
|
||||
|
||||
// apply side effects of each node, only if it wasn't neutral before
|
||||
if (node.GetLastControlledTeam() == TEAM_NEUTRAL)
|
||||
return;
|
||||
|
||||
switch (node.GetNodeInfo().NodeType)
|
||||
{
|
||||
case NODE_TYPE_HANGAR:
|
||||
if (Transport* transport = battlegroundMap->GetTransport(_gunshipGUIDs[node.GetLastControlledTeam()]))
|
||||
transport->EnableMovement(false);
|
||||
|
||||
for (ObjectGuid const& guid : _cannonGUIDs[node.GetLastControlledTeam()])
|
||||
{
|
||||
if (Creature* cannon = battlegroundMap->GetCreature(guid))
|
||||
{
|
||||
cannon->GetVehicleKit()->RemoveAllPassengers();
|
||||
cannon->SetUninteractible(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Despawn teleport trigger target
|
||||
if (Creature* creature = battlegroundMap->GetCreature(_gunshipTeleportTarget))
|
||||
creature->DespawnOrUnsummon();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnPlayerDefendNode(Player* player, ICNodePoint& node)
|
||||
{
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
Team const playerTeam = battleground->GetPlayerTeam(player->GetGUID());
|
||||
TeamId const playerTeamId = Battleground::GetTeamIndexByTeamId(playerTeam);
|
||||
|
||||
node.UpdateState(playerTeamId == TEAM_HORDE ? IsleOfConquestNodeState::ControlledH : IsleOfConquestNodeState::ControlledA);
|
||||
HandleCapturedNodes(node);
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_BASES_DEFENDED, 1);
|
||||
|
||||
ChatMsg const messageType = playerTeamId == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
battleground->SendBroadcastText(node.GetNodeInfo().TextIds.Defended, messageType, player);
|
||||
UpdateNodeWorldState(node);
|
||||
}
|
||||
|
||||
void ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker) override
|
||||
{
|
||||
BattlegroundScript::ProcessEvent(target, eventId, invoker);
|
||||
|
||||
if (GameObject* obj = Object::ToGameObject(target))
|
||||
if (obj->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
|
||||
if (obj->GetGOInfo()->destructibleBuilding.DestroyedEvent == eventId)
|
||||
OnGateDestroyed(obj, invoker);
|
||||
}
|
||||
|
||||
void HandleCaptureNodeAction(GameObject* banner)
|
||||
{
|
||||
if (!banner)
|
||||
return;
|
||||
|
||||
ICNodePointType const nodeType = BannerToNodeType(banner->GetEntry());
|
||||
if (nodeType == MAX_NODE_TYPES)
|
||||
return;
|
||||
|
||||
ICNodePoint& node = *_nodePoints[nodeType];
|
||||
if (node.GetState() == IsleOfConquestNodeState::ConflictH)
|
||||
node.UpdateState(IsleOfConquestNodeState::ControlledH);
|
||||
else if (node.GetState() == IsleOfConquestNodeState::ConflictA)
|
||||
node.UpdateState(IsleOfConquestNodeState::ControlledA);
|
||||
|
||||
HandleCapturedNodes(node);
|
||||
|
||||
ChatMsg const messageType = node.GetLastControlledTeam() == TEAM_ALLIANCE ? CHAT_MSG_BG_SYSTEM_ALLIANCE : CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
uint32 const textId = node.GetLastControlledTeam() == TEAM_ALLIANCE ? node.GetNodeInfo().TextIds.AllianceTaken : node.GetNodeInfo().TextIds.HordeTaken;
|
||||
battleground->SendBroadcastText(textId, messageType);
|
||||
UpdateNodeWorldState(node);
|
||||
}
|
||||
|
||||
void OnGateDestroyed(GameObject* gate, WorldObject* destroyer)
|
||||
{
|
||||
_gateStatus[GetGateIDFromEntry(gate->GetEntry())] = BG_IC_GATE_DESTROYED;
|
||||
int32 const wsGateOpen = GetWorldStateFromGateEntry(gate->GetEntry(), true);
|
||||
int32 const wsGateClosed = GetWorldStateFromGateEntry(gate->GetEntry(), false);
|
||||
if (wsGateOpen)
|
||||
{
|
||||
UpdateWorldState(wsGateClosed, 0);
|
||||
UpdateWorldState(wsGateOpen, 1);
|
||||
}
|
||||
|
||||
TeamId teamId = TEAM_NEUTRAL;
|
||||
uint32 textId;
|
||||
ChatMsg msgType;
|
||||
switch (gate->GetEntry())
|
||||
{
|
||||
case GO_HORDE_GATE_1:
|
||||
textId = BG_IC_TEXT_FRONT_GATE_HORDE_DESTROYED;
|
||||
msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
teamId = TEAM_HORDE;
|
||||
break;
|
||||
case GO_HORDE_GATE_2:
|
||||
textId = BG_IC_TEXT_WEST_GATE_HORDE_DESTROYED;
|
||||
msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
teamId = TEAM_HORDE;
|
||||
break;
|
||||
case GO_HORDE_GATE_3:
|
||||
textId = BG_IC_TEXT_EAST_GATE_HORDE_DESTROYED;
|
||||
msgType = CHAT_MSG_BG_SYSTEM_ALLIANCE;
|
||||
teamId = TEAM_HORDE;
|
||||
break;
|
||||
case GO_ALLIANCE_GATE_1:
|
||||
textId = BG_IC_TEXT_WEST_GATE_ALLIANCE_DESTROYED;
|
||||
msgType = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
teamId = TEAM_ALLIANCE;
|
||||
break;
|
||||
case GO_ALLIANCE_GATE_2:
|
||||
textId = BG_IC_TEXT_EAST_GATE_ALLIANCE_DESTROYED;
|
||||
msgType = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
teamId = TEAM_ALLIANCE;
|
||||
break;
|
||||
case GO_ALLIANCE_GATE_3:
|
||||
textId = BG_IC_TEXT_FRONT_GATE_ALLIANCE_DESTROYED;
|
||||
msgType = CHAT_MSG_BG_SYSTEM_HORDE;
|
||||
teamId = TEAM_ALLIANCE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (teamId != TEAM_NEUTRAL)
|
||||
{
|
||||
GuidVector const keepGates = _keepGateGUIDs[teamId];
|
||||
ObjectGuid const bannerGuid = _keepBannerGUIDs[teamId];
|
||||
|
||||
for (ObjectGuid const& guid : keepGates)
|
||||
if (GameObject* keepGate = battlegroundMap->GetGameObject(guid))
|
||||
keepGate->UseDoorOrButton();
|
||||
|
||||
if (GameObject* banner = battlegroundMap->GetGameObject(bannerGuid))
|
||||
banner->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
battleground->SendBroadcastText(textId, msgType, destroyer);
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<uint16, PVP_TEAMS_COUNT> _factionReinforcements;
|
||||
std::array<BG_IC_GateState, 6> _gateStatus;
|
||||
std::array<std::unique_ptr<ICNodePoint>, 7> _nodePoints;
|
||||
std::array<ObjectGuid, PVP_TEAMS_COUNT> _gunshipGUIDs;
|
||||
GuidVector _teleporterGUIDs;
|
||||
GuidVector _teleporterEffectGUIDs;
|
||||
GuidVector _mainGateDoorGUIDs;
|
||||
GuidVector _portcullisGUIDs;
|
||||
GuidVector _wallGUIDs;
|
||||
std::array<GuidVector, PVP_TEAMS_COUNT> _cannonGUIDs;
|
||||
std::array<GuidVector, PVP_TEAMS_COUNT> _keepGateGUIDs;
|
||||
std::array<ObjectGuid, PVP_TEAMS_COUNT> _keepBannerGUIDs;
|
||||
ObjectGuid _gunshipTeleportTarget;
|
||||
|
||||
TaskScheduler _scheduler;
|
||||
TimeTracker _resourceTimer;
|
||||
};
|
||||
|
||||
void AddSC_battleground_isle_of_conquest()
|
||||
{
|
||||
RegisterBattlegroundMapScript(battleground_isle_of_conquest, 628);
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "BattlegroundIC.h"
|
||||
#include "isle_of_conquest.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
enum BossSpells
|
||||
@@ -15,8 +15,9 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "isle_of_conquest.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "BattlegroundIC.h"
|
||||
#include "Battleground.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "Map.h"
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_ISLE_OF_CONQUEST_H
|
||||
#define TRINITYCORE_ISLE_OF_CONQUEST_H
|
||||
|
||||
enum CreaturesIC
|
||||
{
|
||||
NPC_HIGH_COMMANDER_HALFORD_WYRMBANE = 34924, // Alliance Boss
|
||||
NPC_OVERLORD_AGMAR = 34922, // Horde Boss
|
||||
NPC_KOR_KRON_GUARD = 34918, // horde guard
|
||||
NPC_SEVEN_TH_LEGION_INFANTRY = 34919, // alliance guard
|
||||
NPC_KEEP_CANNON = 34944,
|
||||
NPC_DEMOLISHER = 34775,
|
||||
NPC_SIEGE_ENGINE_H = 35069,
|
||||
NPC_SIEGE_ENGINE_A = 34776,
|
||||
NPC_GLAIVE_THROWER_A = 34802,
|
||||
NPC_GLAIVE_THROWER_H = 35273,
|
||||
NPC_CATAPULT = 34793,
|
||||
NPC_HORDE_GUNSHIP_CANNON = 34935,
|
||||
NPC_ALLIANCE_GUNSHIP_CANNON = 34929,
|
||||
NPC_HORDE_GUNSHIP_CAPTAIN = 35003,
|
||||
NPC_ALLIANCE_GUNSHIP_CAPTAIN = 34960,
|
||||
NPC_WORLD_TRIGGER_NOT_FLOATING = 34984,
|
||||
NPC_WORLD_TRIGGER_ALLIANCE_FRIENDLY = 20213,
|
||||
NPC_WORLD_TRIGGER_HORDE_FRIENDLY = 20212
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_GUNSHIP_READY = 1,
|
||||
ACTION_IOC_INTERACT_CAPTURABLE_OBJECT = 2,
|
||||
ACTION_IOC_CAPTURE_CAPTURABLE_OBJECT = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_OIL_REFINERY = 68719,
|
||||
SPELL_QUARRY = 68720,
|
||||
SPELL_PARACHUTE = 66656,
|
||||
SPELL_SLOW_FALL = 12438,
|
||||
SPELL_DESTROYED_VEHICLE_ACHIEVEMENT = 68357,
|
||||
SPELL_BACK_DOOR_JOB_ACHIEVEMENT = 68502,
|
||||
SPELL_DRIVING_CREDIT_DEMOLISHER = 68365,
|
||||
SPELL_DRIVING_CREDIT_GLAIVE = 68363,
|
||||
SPELL_DRIVING_CREDIT_SIEGE = 68364,
|
||||
SPELL_DRIVING_CREDIT_CATAPULT = 68362,
|
||||
SPELL_SIMPLE_TELEPORT = 12980,
|
||||
SPELL_TELEPORT_VISUAL_ONLY = 51347,
|
||||
SPELL_PARACHUTE_IC = 66657,
|
||||
SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251
|
||||
};
|
||||
|
||||
enum ICWorldStates
|
||||
{
|
||||
BG_IC_ALLIANCE_REINFORCEMENTS_SET = 4221,
|
||||
BG_IC_HORDE_REINFORCEMENTS_SET = 4222,
|
||||
BG_IC_ALLIANCE_REINFORCEMENTS = 4226,
|
||||
BG_IC_HORDE_REINFORCEMENTS = 4227,
|
||||
BG_IC_MAX_REINFORCEMENTS = 17377,
|
||||
|
||||
BG_IC_GATE_FRONT_H_WS_CLOSED = 4317,
|
||||
BG_IC_GATE_WEST_H_WS_CLOSED = 4318,
|
||||
BG_IC_GATE_EAST_H_WS_CLOSED = 4319,
|
||||
BG_IC_GATE_FRONT_A_WS_CLOSED = 4328,
|
||||
BG_IC_GATE_WEST_A_WS_CLOSED = 4327,
|
||||
BG_IC_GATE_EAST_A_WS_CLOSED = 4326,
|
||||
BG_IC_GATE_FRONT_H_WS_OPEN = 4322,
|
||||
BG_IC_GATE_WEST_H_WS_OPEN = 4321,
|
||||
BG_IC_GATE_EAST_H_WS_OPEN = 4320,
|
||||
BG_IC_GATE_FRONT_A_WS_OPEN = 4323,
|
||||
BG_IC_GATE_WEST_A_WS_OPEN = 4324,
|
||||
BG_IC_GATE_EAST_A_WS_OPEN = 4325,
|
||||
|
||||
BG_IC_DOCKS_UNCONTROLLED = 4301,
|
||||
BG_IC_DOCKS_CONFLICT_A = 4305,
|
||||
BG_IC_DOCKS_CONFLICT_H = 4302,
|
||||
BG_IC_DOCKS_CONTROLLED_A = 4304,
|
||||
BG_IC_DOCKS_CONTROLLED_H = 4303,
|
||||
|
||||
BG_IC_HANGAR_UNCONTROLLED = 4296,
|
||||
BG_IC_HANGAR_CONFLICT_A = 4300,
|
||||
BG_IC_HANGAR_CONFLICT_H = 4297,
|
||||
BG_IC_HANGAR_CONTROLLED_A = 4299,
|
||||
BG_IC_HANGAR_CONTROLLED_H = 4298,
|
||||
|
||||
BG_IC_QUARRY_UNCONTROLLED = 4306,
|
||||
BG_IC_QUARRY_CONFLICT_A = 4310,
|
||||
BG_IC_QUARRY_CONFLICT_H = 4307,
|
||||
BG_IC_QUARRY_CONTROLLED_A = 4309,
|
||||
BG_IC_QUARRY_CONTROLLED_H = 4308,
|
||||
|
||||
BG_IC_REFINERY_UNCONTROLLED = 4311,
|
||||
BG_IC_REFINERY_CONFLICT_A = 4315,
|
||||
BG_IC_REFINERY_CONFLICT_H = 4312,
|
||||
BG_IC_REFINERY_CONTROLLED_A = 4314,
|
||||
BG_IC_REFINERY_CONTROLLED_H = 4313,
|
||||
|
||||
BG_IC_WORKSHOP_UNCONTROLLED = 4294,
|
||||
BG_IC_WORKSHOP_CONFLICT_A = 4228,
|
||||
BG_IC_WORKSHOP_CONFLICT_H = 4293,
|
||||
BG_IC_WORKSHOP_CONTROLLED_A = 4229,
|
||||
BG_IC_WORKSHOP_CONTROLLED_H = 4230,
|
||||
|
||||
BG_IC_ALLIANCE_KEEP_UNCONTROLLED = 4341,
|
||||
BG_IC_ALLIANCE_KEEP_CONFLICT_A = 4342,
|
||||
BG_IC_ALLIANCE_KEEP_CONFLICT_H = 4343,
|
||||
BG_IC_ALLIANCE_KEEP_CONTROLLED_A = 4339,
|
||||
BG_IC_ALLIANCE_KEEP_CONTROLLED_H = 4340,
|
||||
|
||||
BG_IC_HORDE_KEEP_UNCONTROLLED = 4346,
|
||||
BG_IC_HORDE_KEEP_CONFLICT_A = 4347,
|
||||
BG_IC_HORDE_KEEP_CONFLICT_H = 4348,
|
||||
BG_IC_HORDE_KEEP_CONTROLLED_A = 4344,
|
||||
BG_IC_HORDE_KEEP_CONTROLLED_H = 4345
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundScript.h"
|
||||
#include "GameObject.h"
|
||||
#include "Map.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
struct arena_nagrand : ArenaScript
|
||||
{
|
||||
enum GameObjects
|
||||
{
|
||||
BG_NA_OBJECT_TYPE_DOOR_1 = 183978,
|
||||
BG_NA_OBJECT_TYPE_DOOR_2 = 183980,
|
||||
BG_NA_OBJECT_TYPE_DOOR_3 = 183977,
|
||||
BG_NA_OBJECT_TYPE_DOOR_4 = 183979,
|
||||
BG_NA_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_NA_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
explicit arena_nagrand(BattlegroundMap* map) : ArenaScript(map) { }
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
AddDoor(BG_NA_OBJECT_TYPE_DOOR_1, 4031.854f, 2966.833f, 12.6462f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f);
|
||||
AddDoor(BG_NA_OBJECT_TYPE_DOOR_2, 4081.179f, 2874.97f, 12.39171f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f);
|
||||
AddDoor(BG_NA_OBJECT_TYPE_DOOR_3, 4023.709f, 2981.777f, 10.70117f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f);
|
||||
AddDoor(BG_NA_OBJECT_TYPE_DOOR_4, 4090.064f, 2858.438f, 10.23631f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f);
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
for (ObjectGuid const& guid : _doorGUIDs)
|
||||
{
|
||||
if (GameObject* door = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
door->UseDoorOrButton();
|
||||
door->DespawnOrUnsummon(5s);
|
||||
}
|
||||
}
|
||||
|
||||
_scheduler.Schedule(1min, [&](TaskContext)
|
||||
{
|
||||
CreateObject(BG_NA_OBJECT_TYPE_BUFF_1, 4009.189941f, 2895.250000f, 13.052700f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
|
||||
CreateObject(BG_NA_OBJECT_TYPE_BUFF_2, 4103.330078f, 2946.350098f, 13.051300f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
|
||||
});
|
||||
}
|
||||
|
||||
void AddDoor(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState = GO_STATE_READY)
|
||||
{
|
||||
if (GameObject const* go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState))
|
||||
_doorGUIDs.emplace_back(go->GetGUID());
|
||||
}
|
||||
|
||||
private:
|
||||
GuidVector _doorGUIDs;
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
void AddSC_arena_nagrand()
|
||||
{
|
||||
RegisterBattlegroundMapScript(arena_nagrand, 1505);
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundScript.h"
|
||||
#include "GameObject.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
struct arena_ring_of_valor : ArenaScript
|
||||
{
|
||||
enum BattlegroundRVGameObjects
|
||||
{
|
||||
BG_RV_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_RV_OBJECT_TYPE_BUFF_2 = 184664,
|
||||
BG_RV_OBJECT_TYPE_FIRE_1 = 192704,
|
||||
BG_RV_OBJECT_TYPE_FIRE_2 = 192705,
|
||||
|
||||
BG_RV_OBJECT_TYPE_FIREDOOR_2 = 192387,
|
||||
BG_RV_OBJECT_TYPE_FIREDOOR_1 = 192388,
|
||||
BG_RV_OBJECT_TYPE_PULLEY_1 = 192389,
|
||||
BG_RV_OBJECT_TYPE_PULLEY_2 = 192390,
|
||||
BG_RV_OBJECT_TYPE_GEAR_1 = 192393,
|
||||
BG_RV_OBJECT_TYPE_GEAR_2 = 192394,
|
||||
BG_RV_OBJECT_TYPE_ELEVATOR_1 = 194582,
|
||||
BG_RV_OBJECT_TYPE_ELEVATOR_2 = 194586,
|
||||
|
||||
BG_RV_OBJECT_TYPE_PILAR_COLLISION_1 = 194580, // axe
|
||||
BG_RV_OBJECT_TYPE_PILAR_COLLISION_2 = 194579, // arena // big
|
||||
BG_RV_OBJECT_TYPE_PILAR_COLLISION_3 = 194581, // lightning
|
||||
BG_RV_OBJECT_TYPE_PILAR_COLLISION_4 = 194578, // ivory // big
|
||||
|
||||
BG_RV_OBJECT_TYPE_PILAR_1 = 194583, // axe
|
||||
BG_RV_OBJECT_TYPE_PILAR_2 = 194584, // arena
|
||||
BG_RV_OBJECT_TYPE_PILAR_3 = 194585, // lightning
|
||||
BG_RV_OBJECT_TYPE_PILAR_4 = 194587 // ivory
|
||||
};
|
||||
|
||||
enum BattlegroundRVData
|
||||
{
|
||||
BG_RV_STATE_OPEN_FENCES,
|
||||
BG_RV_STATE_SWITCH_PILLARS,
|
||||
BG_RV_STATE_CLOSE_FIRE,
|
||||
|
||||
BG_RV_PILLAR_SWITCH_TIMER = 25000,
|
||||
BG_RV_FIRE_TO_PILLAR_TIMER = 20000,
|
||||
BG_RV_CLOSE_FIRE_TIMER = 5000,
|
||||
BG_RV_FIRST_TIMER = 20133,
|
||||
};
|
||||
|
||||
explicit arena_ring_of_valor(BattlegroundMap* map) : ArenaScript(map), _timer(0), _state(0), _pillarCollision(false) { }
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
if (_timer < diff)
|
||||
{
|
||||
switch (_state)
|
||||
{
|
||||
case BG_RV_STATE_OPEN_FENCES:
|
||||
// Open fire (only at game start)
|
||||
for (ObjectGuid const& guid : _fireGUIDs)
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(guid))
|
||||
go->UseDoorOrButton();
|
||||
for (ObjectGuid const& guid : _firedoorGUIDs)
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(guid))
|
||||
go->UseDoorOrButton();
|
||||
_timer = BG_RV_CLOSE_FIRE_TIMER;
|
||||
_state = BG_RV_STATE_CLOSE_FIRE;
|
||||
break;
|
||||
case BG_RV_STATE_CLOSE_FIRE:
|
||||
for (ObjectGuid const& guid : _fireGUIDs)
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(guid))
|
||||
go->ResetDoorOrButton();
|
||||
for (ObjectGuid const& guid : _firedoorGUIDs)
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(guid))
|
||||
go->ResetDoorOrButton();
|
||||
// Fire got closed after five seconds, leaves twenty seconds before toggling pillars
|
||||
_timer = BG_RV_FIRE_TO_PILLAR_TIMER;
|
||||
_state = BG_RV_STATE_SWITCH_PILLARS;
|
||||
break;
|
||||
case BG_RV_STATE_SWITCH_PILLARS:
|
||||
TogglePillarCollision();
|
||||
_timer = BG_RV_PILLAR_SWITCH_TIMER;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
_timer -= diff;
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
CreateObject(BG_RV_OBJECT_TYPE_ELEVATOR_1, 763.536377f, -294.535767f, 0.505383f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_ELEVATOR_2, 763.506348f, -273.873352f, 0.505383f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
CreateObject(BG_RV_OBJECT_TYPE_FIRE_1, 743.543457f, -283.799469f, 28.286655f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_FIRE_2, 782.971802f, -283.799469f, 28.286655f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_FIREDOOR_1, 743.711060f, -284.099609f, 27.542587f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_FIREDOOR_2, 783.221252f, -284.133362f, 27.535686f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
CreateObject(BG_RV_OBJECT_TYPE_GEAR_1, 763.664551f, -261.872986f, 26.686588f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_GEAR_2, 763.578979f, -306.146149f, 26.665222f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PULLEY_1, 700.722290f, -283.990662f, 39.517582f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PULLEY_2, 826.303833f, -283.996429f, 39.517582f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PILAR_1, 763.632385f, -306.162384f, 25.909504f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PILAR_2, 723.644287f, -284.493256f, 24.648525f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PILAR_3, 763.611145f, -261.856750f, 25.909504f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PILAR_4, 802.211609f, -284.493256f, 24.648525f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PILAR_COLLISION_1, 763.632385f, -306.162384f, 30.639660f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PILAR_COLLISION_2, 723.644287f, -284.493256f, 32.382710f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PILAR_COLLISION_3, 763.611145f, -261.856750f, 30.639660f, 0.000000f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_PILAR_COLLISION_4, 802.211609f, -284.493256f, 32.382710f, 3.141593f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
for (ObjectGuid const& guid : _elevatorGUIDs)
|
||||
{
|
||||
if (GameObject* door = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
door->UseDoorOrButton();
|
||||
door->DespawnOrUnsummon(5s);
|
||||
}
|
||||
}
|
||||
|
||||
_state = BG_RV_STATE_OPEN_FENCES;
|
||||
_timer = BG_RV_FIRST_TIMER;
|
||||
|
||||
// Should be false at first, TogglePillarCollision will do it.
|
||||
_pillarCollision = true;
|
||||
TogglePillarCollision();
|
||||
|
||||
_scheduler.Schedule(1min, [&](TaskContext)
|
||||
{
|
||||
CreateObject(BG_RV_OBJECT_TYPE_BUFF_1, 735.551819f, -284.794678f, 28.276682f, 0.034906f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
CreateObject(BG_RV_OBJECT_TYPE_BUFF_2, 791.224487f, -284.794464f, 28.276682f, 2.600535f, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
});
|
||||
}
|
||||
|
||||
void TogglePillarCollision()
|
||||
{
|
||||
// Toggle visual pillars, pulley, gear, and collision based on previous state
|
||||
|
||||
GuidVector smallPillarGuids;
|
||||
smallPillarGuids.insert(std::end(smallPillarGuids), std::begin(_pillarSmallGUIDs), std::end(_pillarSmallGUIDs));
|
||||
smallPillarGuids.insert(std::end(smallPillarGuids), std::begin(_gearGUIDs), std::end(_gearGUIDs));
|
||||
|
||||
for (ObjectGuid const& guid : smallPillarGuids)
|
||||
{
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
if (_pillarCollision)
|
||||
go->UseDoorOrButton();
|
||||
else
|
||||
go->ResetDoorOrButton();
|
||||
}
|
||||
}
|
||||
|
||||
GuidVector bigPillarGuids;
|
||||
bigPillarGuids.insert(std::end(bigPillarGuids), std::begin(_pillarBigGUIDs), std::end(_pillarBigGUIDs));
|
||||
bigPillarGuids.insert(std::end(bigPillarGuids), std::begin(_pulleyGUIDs), std::end(_pulleyGUIDs));
|
||||
|
||||
for (ObjectGuid const& guid : bigPillarGuids)
|
||||
{
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
if (_pillarCollision)
|
||||
go->ResetDoorOrButton();
|
||||
else
|
||||
go->UseDoorOrButton();
|
||||
}
|
||||
}
|
||||
|
||||
GuidVector allObjects;
|
||||
allObjects.insert(std::end(allObjects), std::begin(smallPillarGuids), std::end(smallPillarGuids));
|
||||
allObjects.insert(std::end(allObjects), std::begin(bigPillarGuids), std::end(bigPillarGuids));
|
||||
allObjects.insert(std::end(allObjects), std::begin(_pillarSmallCollisionGUIDs), std::end(_pillarSmallCollisionGUIDs));
|
||||
allObjects.insert(std::end(allObjects), std::begin(_pillarBigCollisionGUIDs), std::end(_pillarBigCollisionGUIDs));
|
||||
|
||||
for (ObjectGuid const& guid : allObjects)
|
||||
{
|
||||
if (GameObject* go = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
bool isCollision = false;
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case BG_RV_OBJECT_TYPE_PILAR_COLLISION_1:
|
||||
case BG_RV_OBJECT_TYPE_PILAR_COLLISION_2:
|
||||
case BG_RV_OBJECT_TYPE_PILAR_COLLISION_3:
|
||||
case BG_RV_OBJECT_TYPE_PILAR_COLLISION_4:
|
||||
isCollision = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (isCollision)
|
||||
{
|
||||
GOState state = ((go->GetGOInfo()->door.startOpen != 0) == _pillarCollision) ? GO_STATE_ACTIVE : GO_STATE_READY;
|
||||
go->SetGoState(state);
|
||||
}
|
||||
|
||||
for (auto const& [playerGuid, _]: battleground->GetPlayers())
|
||||
if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
|
||||
go->SendUpdateToPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
_pillarCollision = !_pillarCollision;
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject) override
|
||||
{
|
||||
ArenaScript::OnGameObjectCreate(gameobject);
|
||||
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case BG_RV_OBJECT_TYPE_ELEVATOR_1:
|
||||
case BG_RV_OBJECT_TYPE_ELEVATOR_2:
|
||||
_elevatorGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case BG_RV_OBJECT_TYPE_FIRE_1:
|
||||
case BG_RV_OBJECT_TYPE_FIRE_2:
|
||||
_fireGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case BG_RV_OBJECT_TYPE_FIREDOOR_1:
|
||||
case BG_RV_OBJECT_TYPE_FIREDOOR_2:
|
||||
_firedoorGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case BG_RV_OBJECT_TYPE_GEAR_1:
|
||||
case BG_RV_OBJECT_TYPE_GEAR_2:
|
||||
_gearGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case BG_RV_OBJECT_TYPE_PILAR_1:
|
||||
case BG_RV_OBJECT_TYPE_PILAR_3:
|
||||
_pillarSmallGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case BG_RV_OBJECT_TYPE_PILAR_2:
|
||||
case BG_RV_OBJECT_TYPE_PILAR_4:
|
||||
_pillarBigGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case BG_RV_OBJECT_TYPE_PILAR_COLLISION_1:
|
||||
case BG_RV_OBJECT_TYPE_PILAR_COLLISION_3:
|
||||
_pillarSmallCollisionGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case BG_RV_OBJECT_TYPE_PILAR_COLLISION_2:
|
||||
case BG_RV_OBJECT_TYPE_PILAR_COLLISION_4:
|
||||
_pillarBigCollisionGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
case BG_RV_OBJECT_TYPE_PULLEY_1:
|
||||
case BG_RV_OBJECT_TYPE_PULLEY_2:
|
||||
_pulleyGUIDs.emplace_back(gameobject->GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GuidVector _elevatorGUIDs;
|
||||
GuidVector _gearGUIDs;
|
||||
GuidVector _fireGUIDs;
|
||||
GuidVector _firedoorGUIDs;
|
||||
GuidVector _pillarSmallCollisionGUIDs;
|
||||
GuidVector _pillarBigCollisionGUIDs;
|
||||
GuidVector _pillarSmallGUIDs;
|
||||
GuidVector _pillarBigGUIDs;
|
||||
GuidVector _pulleyGUIDs;
|
||||
TaskScheduler _scheduler;
|
||||
|
||||
uint32 _timer;
|
||||
uint32 _state;
|
||||
bool _pillarCollision;
|
||||
};
|
||||
|
||||
void AddSC_arena_ring_of_valor()
|
||||
{
|
||||
RegisterBattlegroundMapScript(arena_ring_of_valor, 618);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundScript.h"
|
||||
#include "GameObject.h"
|
||||
#include "Map.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
struct arena_ruins_of_lordaeron : ArenaScript
|
||||
{
|
||||
enum BattlegroundRLGameObjects
|
||||
{
|
||||
BG_RL_OBJECT_TYPE_DOOR_1 = 185918,
|
||||
BG_RL_OBJECT_TYPE_DOOR_2 = 185917,
|
||||
BG_RL_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_RL_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
explicit arena_ruins_of_lordaeron(BattlegroundMap* map) : ArenaScript(map) { }
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
AddDoor(BG_RL_OBJECT_TYPE_DOOR_1, 1293.561f, 1601.938f, 31.60557f, -1.457349f, 0, 0, -0.6658813f, 0.7460576f);
|
||||
AddDoor(BG_RL_OBJECT_TYPE_DOOR_2, 1278.648f, 1730.557f, 31.60557f, 1.684245f, 0, 0, 0.7460582f, 0.6658807f);
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
for (ObjectGuid const& guid : _doorGUIDs)
|
||||
{
|
||||
if (GameObject* door = battlegroundMap->GetGameObject(guid))
|
||||
{
|
||||
door->UseDoorOrButton();
|
||||
door->DespawnOrUnsummon(5s);
|
||||
}
|
||||
}
|
||||
|
||||
_scheduler.Schedule(1min, [&](TaskContext)
|
||||
{
|
||||
CreateObject(BG_RL_OBJECT_TYPE_BUFF_1, 1328.719971f, 1632.719971f, 36.730400f, -1.448624f, 0, 0, 0.6626201f, -0.7489557f);
|
||||
CreateObject(BG_RL_OBJECT_TYPE_BUFF_2, 1243.300049f, 1699.170044f, 34.872601f, -0.06981307f, 0, 0, 0.03489945f, -0.9993908f);
|
||||
});
|
||||
}
|
||||
|
||||
void AddDoor(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState = GO_STATE_READY)
|
||||
{
|
||||
if (GameObject const* go = CreateObject(entry, x, y, z, o, rotation0, rotation1, rotation2, rotation3, goState))
|
||||
_doorGUIDs.emplace_back(go->GetGUID());
|
||||
}
|
||||
|
||||
private:
|
||||
GuidVector _doorGUIDs;
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
void AddSC_arena_ruins_of_lordaeron()
|
||||
{
|
||||
RegisterBattlegroundMapScript(arena_ruins_of_lordaeron, 572);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "strand_of_the_ancients.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "BattlegroundSA.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "Player.h"
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITYCORE_STRAND_OF_THE_ANCIENTS_H
|
||||
#define TRINITYCORE_STRAND_OF_THE_ANCIENTS_H
|
||||
|
||||
enum StrandOfTheAncientSharedActions
|
||||
{
|
||||
ACTION_SOTA_CAPTURE_GRAVEYARD
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlegroundScript.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
struct battleground_twin_peaks : BattlegroundScript
|
||||
{
|
||||
enum PvpStats : uint32
|
||||
{
|
||||
BG_TP_FLAG_CAPTURES = 290,
|
||||
BG_TP_FLAG_RETURNS = 291
|
||||
};
|
||||
|
||||
explicit battleground_twin_peaks(BattlegroundMap* map) : BattlegroundScript(map) { }
|
||||
};
|
||||
|
||||
void AddSC_battleground_twin_peaks()
|
||||
{
|
||||
RegisterBattlegroundMapScript(battleground_twin_peaks, 726);
|
||||
}
|
||||
@@ -0,0 +1,608 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AreaTrigger.h"
|
||||
#include "BattlegroundScript.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "GameObject.h"
|
||||
#include "GameTime.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "Timer.h"
|
||||
|
||||
struct battleground_warsong_gulch : BattlegroundScript
|
||||
{
|
||||
static constexpr Seconds FLAG_ASSAULT_TIMER = 30s;
|
||||
|
||||
enum Misc
|
||||
{
|
||||
MAX_TEAM_SCORE = 3,
|
||||
FLAG_BRUTAL_ASSAULT_STACK_COUNT = 5
|
||||
};
|
||||
|
||||
enum Spells : uint32
|
||||
{
|
||||
SPELL_FOCUSED_ASSAULT = 46392,
|
||||
SPELL_BRUTAL_ASSAULT = 46393,
|
||||
SPELL_CAPTURED_ALLIANCE_COSMETIC_FX = 262508,
|
||||
SPELL_CAPTURED_HORDE_COSMETIC_FX = 262512,
|
||||
SPELL_WARSONG_FLAG = 23333,
|
||||
SPELL_WARSONG_FLAG_DROPPED = 23334,
|
||||
SPELL_SILVERWING_FLAG = 23335,
|
||||
SPELL_SILVERWING_FLAG_DROPPED = 23336,
|
||||
SPELL_QUICK_CAP_TIMER = 183317,
|
||||
};
|
||||
|
||||
enum AreaTriggers : uint32
|
||||
{
|
||||
AT_CAPTURE_POINT_ALLIANCE = 30,
|
||||
AT_CAPTURE_POINT_HORDE = 31
|
||||
};
|
||||
|
||||
enum Events : uint32
|
||||
{
|
||||
EVENT_START_BATTLE = 35912
|
||||
};
|
||||
|
||||
enum PvpStats : uint32
|
||||
{
|
||||
PVP_STAT_FLAG_CAPTURES = 928,
|
||||
PVP_STAT_FLAG_RETURNS = 929
|
||||
};
|
||||
|
||||
enum WorldStates : int32
|
||||
{
|
||||
WORLD_STATE_FLAG_STATE_ALLIANCE = 1545,
|
||||
WORLD_STATE_FLAG_STATE_HORDE = 1546,
|
||||
WORLD_STATE_FLAG_STATE_NEUTRAL = 1547,
|
||||
WORLD_STATE_HORDE_FLAG_COUNT_PICKED_UP = 17712,
|
||||
WORLD_STATE_ALLIANCE_FLAG_COUNT_PICKED_UP = 17713,
|
||||
WORLD_STATE_FLAG_CAPTURES_ALLIANCE = 1581,
|
||||
WORLD_STATE_FLAG_CAPTURES_HORDE = 1582,
|
||||
WORLD_STATE_FLAG_CAPTURES_MAX = 1601,
|
||||
WORLD_STATE_FLAG_CAPTURES_MAX_NEW = 17303,
|
||||
WORLD_STATE_FLAG_CONTROL_HORDE = 2338,
|
||||
WORLD_STATE_FLAG_CONTROL_ALLIANCE = 2339,
|
||||
WORLD_STATE_STATE_TIMER = 4248,
|
||||
WORLD_STATE_STATE_TIMER_ACTIVE = 4247
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
TEXT_START_ONE_MINUTE = 10015,
|
||||
TEXT_START_HALF_MINUTE = 10016,
|
||||
TEXT_BATTLE_HAS_BEGUN = 10014,
|
||||
TEXT_CAPTURED_HORDE_FLAG = 9801,
|
||||
TEXT_CAPTURED_ALLIANCE_FLAG = 9802,
|
||||
TEXT_FLAGS_PLACED = 9803,
|
||||
TEXT_ALLIANCE_FLAG_PICKED_UP = 9804,
|
||||
TEXT_ALLIANCE_FLAG_DROPPED = 9805,
|
||||
TEXT_HORDE_FLAG_PICKED_UP = 9807,
|
||||
TEXT_HORDE_FLAG_DROPPED = 9806,
|
||||
TEXT_ALLIANCE_FLAG_RETURNED = 9808,
|
||||
TEXT_HORDE_FLAG_RETURNED = 9809
|
||||
};
|
||||
|
||||
enum Sounds
|
||||
{
|
||||
SOUND_FLAG_CAPTURED_ALLIANCE = 8173,
|
||||
SOUND_FLAG_CAPTURED_HORDE = 8213,
|
||||
SOUND_FLAG_PLACED = 8232,
|
||||
SOUND_FLAG_RETURNED = 8192,
|
||||
SOUND_HORDE_FLAG_PICKED_UP = 8212,
|
||||
SOUND_ALLIANCE_FLAG_PICKED_UP = 8174,
|
||||
SOUND_FLAGS_RESPAWNED = 8232
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
OBJECT_ALLIANCE_DOOR = 309704,
|
||||
OBJECT_PORTCULLIS_009 = 309705,
|
||||
OBJECT_PORTCULLIS_002 = 309883,
|
||||
OBJECT_COLLISION_PC_SIZE = 242273,
|
||||
OBJECT_HORDE_GATE_1 = 352709,
|
||||
OBJECT_HORDE_GATE_2 = 352710,
|
||||
OBJECT_ALLIANCE_FLAG_IN_BASE = 227741,
|
||||
OBJECT_HORDE_FLAG_IN_BASE = 227740
|
||||
};
|
||||
|
||||
static constexpr std::array<std::array<uint32, 3>, 2> HONOR_REWARDS =
|
||||
{{
|
||||
{ 20, 40, 40 },
|
||||
{ 60, 40, 80 }
|
||||
}};
|
||||
|
||||
explicit battleground_warsong_gulch(BattlegroundMap* map) : BattlegroundScript(map), _lastFlagCaptureTeam(TEAM_OTHER), _bothFlagsKept(false), _flags({ }), _assaultStackCount(0), _capturePointAreaTriggers({ })
|
||||
{
|
||||
_flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
|
||||
|
||||
if (sBattlegroundMgr->IsBGWeekend(battleground->GetTypeID()))
|
||||
{
|
||||
_reputationCapture = 45;
|
||||
_honorWinKills = 3;
|
||||
_honorEndKills = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
_reputationCapture = 35;
|
||||
_honorWinKills = 1;
|
||||
_honorEndKills = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void OnUpdate(uint32 diff) override
|
||||
{
|
||||
BattlegroundScript::OnUpdate(diff);
|
||||
|
||||
if (battleground->GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
if (battleground->GetElapsedTime() >= 17 * MINUTE * IN_MILLISECONDS)
|
||||
{
|
||||
if (battleground->GetTeamScore(TEAM_ALLIANCE) == 0)
|
||||
{
|
||||
if (battleground->GetTeamScore(TEAM_HORDE) == 0) // No one scored - result is tie
|
||||
battleground->EndBattleground(TEAM_OTHER);
|
||||
else // Horde has more points and thus wins
|
||||
battleground->EndBattleground(HORDE);
|
||||
}
|
||||
else if (battleground->GetTeamScore(TEAM_HORDE) == 0) // Alliance has > 0, Horde has 0, alliance wins
|
||||
battleground->EndBattleground(ALLIANCE);
|
||||
else if (battleground->GetTeamScore(TEAM_HORDE) == battleground->GetTeamScore(TEAM_ALLIANCE)) // Team score equal, winner is team that scored the last flag
|
||||
battleground->EndBattleground(_lastFlagCaptureTeam);
|
||||
else if (battleground->GetTeamScore(TEAM_HORDE) > battleground->GetTeamScore(TEAM_ALLIANCE)) // Last but not least, check who has the higher score
|
||||
battleground->EndBattleground(HORDE);
|
||||
else
|
||||
battleground->EndBattleground(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
if (_bothFlagsKept)
|
||||
{
|
||||
_flagAssaultTimer.Update(diff);
|
||||
if (_flagAssaultTimer.Passed())
|
||||
{
|
||||
_flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
|
||||
if (_assaultStackCount < std::numeric_limits<uint8>::max())
|
||||
{
|
||||
_assaultStackCount++;
|
||||
|
||||
// update assault debuff stacks
|
||||
DoForFlagKeepers([&](Player* player) -> void
|
||||
{
|
||||
ApplyAssaultDebuffToPlayer(player);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnStart() override
|
||||
{
|
||||
BattlegroundScript::OnStart();
|
||||
for (ObjectGuid door : _doors)
|
||||
{
|
||||
if (GameObject* gameObject = battlegroundMap->GetGameObject(door))
|
||||
{
|
||||
gameObject->UseDoorOrButton();
|
||||
gameObject->DespawnOrUnsummon(3s);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateWorldState(WORLD_STATE_STATE_TIMER_ACTIVE, 1);
|
||||
UpdateWorldState(WORLD_STATE_STATE_TIMER, std::chrono::system_clock::to_time_t(GameTime::GetSystemTime() + 15min));
|
||||
|
||||
// players joining later are not eligibles
|
||||
TriggerGameEvent(EVENT_START_BATTLE);
|
||||
}
|
||||
|
||||
void OnEnd(Team winner) override
|
||||
{
|
||||
BattlegroundScript::OnEnd(winner);
|
||||
// Win reward
|
||||
if (winner == ALLIANCE)
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(_honorWinKills), ALLIANCE);
|
||||
if (winner == HORDE)
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(_honorWinKills), HORDE);
|
||||
|
||||
// Complete map_end rewards (even if no team wins)
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(_honorEndKills), ALLIANCE);
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(_honorEndKills), HORDE);
|
||||
}
|
||||
|
||||
void DoForFlagKeepers(std::function<void(Player*)> const& action) const
|
||||
{
|
||||
for (ObjectGuid flagGUID : _flags)
|
||||
if (GameObject const* flag = battlegroundMap->GetGameObject(flagGUID))
|
||||
if (Player* carrier = ObjectAccessor::FindPlayer(flag->GetFlagCarrierGUID()))
|
||||
action(carrier);
|
||||
}
|
||||
|
||||
void ResetAssaultDebuff()
|
||||
{
|
||||
_bothFlagsKept = false;
|
||||
_assaultStackCount = 0;
|
||||
_flagAssaultTimer.Reset(FLAG_ASSAULT_TIMER);
|
||||
DoForFlagKeepers([&](Player* player) -> void
|
||||
{
|
||||
RemoveAssaultDebuffFromPlayer(player);
|
||||
});
|
||||
}
|
||||
|
||||
void ApplyAssaultDebuffToPlayer(Player* player) const
|
||||
{
|
||||
if (_assaultStackCount == 0)
|
||||
return;
|
||||
|
||||
uint32 spellId = SPELL_FOCUSED_ASSAULT;
|
||||
if (_assaultStackCount >= FLAG_BRUTAL_ASSAULT_STACK_COUNT)
|
||||
{
|
||||
player->RemoveAurasDueToSpell(SPELL_FOCUSED_ASSAULT);
|
||||
spellId = SPELL_BRUTAL_ASSAULT;
|
||||
}
|
||||
|
||||
Aura* aura = player->GetAura(spellId);
|
||||
if (!aura)
|
||||
{
|
||||
player->CastSpell(player, spellId, true);
|
||||
aura = player->GetAura(spellId);
|
||||
}
|
||||
|
||||
if (aura)
|
||||
aura->SetStackAmount(_assaultStackCount);
|
||||
}
|
||||
|
||||
void RemoveAssaultDebuffFromPlayer(Player* player) const
|
||||
{
|
||||
player->RemoveAurasDueToSpell(SPELL_FOCUSED_ASSAULT);
|
||||
player->RemoveAurasDueToSpell(SPELL_BRUTAL_ASSAULT);
|
||||
}
|
||||
|
||||
FlagState GetFlagState(TeamId team) const
|
||||
{
|
||||
if (GameObject const* flag = battlegroundMap->GetGameObject(_flags[team]))
|
||||
return flag->GetFlagState();
|
||||
|
||||
return FlagState(0);
|
||||
}
|
||||
|
||||
ObjectGuid const& GetFlagCarrierGUID(TeamId team) const
|
||||
{
|
||||
if (GameObject const* flag = battlegroundMap->GetGameObject(_flags[team]))
|
||||
return flag->GetFlagCarrierGUID();
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
void HandleFlagRoomCapturePoint()
|
||||
{
|
||||
DoForFlagKeepers([&](Player* player) -> void
|
||||
{
|
||||
TeamId const team = Battleground::GetTeamIndexByTeamId(battleground->GetPlayerTeam(player->GetGUID()));
|
||||
if (AreaTrigger* trigger = battlegroundMap->GetAreaTrigger(_capturePointAreaTriggers[team]))
|
||||
if (trigger->GetInsideUnits().contains(player->GetGUID()))
|
||||
if (CanCaptureFlag(trigger, player))
|
||||
OnCaptureFlag(trigger, player);
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateFlagState(uint32 team, FlagState value) const
|
||||
{
|
||||
auto transformValueToOtherTeamControlWorldState = [](FlagState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case FlagState::InBase:
|
||||
case FlagState::Dropped:
|
||||
case FlagState::Respawning:
|
||||
return 1;
|
||||
case FlagState::Taken:
|
||||
return 2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
UpdateWorldState(WORLD_STATE_FLAG_STATE_ALLIANCE, AsUnderlyingType(value));
|
||||
UpdateWorldState(WORLD_STATE_FLAG_CONTROL_HORDE, transformValueToOtherTeamControlWorldState(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWorldState(WORLD_STATE_FLAG_STATE_HORDE, AsUnderlyingType(value));
|
||||
UpdateWorldState(WORLD_STATE_FLAG_CONTROL_ALLIANCE, transformValueToOtherTeamControlWorldState(value));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateTeamScore(TeamId team) const
|
||||
{
|
||||
if (team == TEAM_ALLIANCE)
|
||||
UpdateWorldState(WORLD_STATE_FLAG_CAPTURES_ALLIANCE, battleground->GetTeamScore(team));
|
||||
else
|
||||
UpdateWorldState(WORLD_STATE_FLAG_CAPTURES_HORDE, battleground->GetTeamScore(team));
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameObject) override
|
||||
{
|
||||
BattlegroundScript::OnGameObjectCreate(gameObject);
|
||||
switch (gameObject->GetEntry())
|
||||
{
|
||||
case OBJECT_ALLIANCE_DOOR:
|
||||
case OBJECT_PORTCULLIS_009:
|
||||
case OBJECT_PORTCULLIS_002:
|
||||
case OBJECT_COLLISION_PC_SIZE:
|
||||
case OBJECT_HORDE_GATE_1:
|
||||
case OBJECT_HORDE_GATE_2:
|
||||
_doors.insert(gameObject->GetGUID());
|
||||
break;
|
||||
case OBJECT_ALLIANCE_FLAG_IN_BASE:
|
||||
_flags[TEAM_ALLIANCE] = gameObject->GetGUID();
|
||||
break;
|
||||
case OBJECT_HORDE_FLAG_IN_BASE:
|
||||
_flags[TEAM_HORDE] = gameObject->GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnAreaTriggerCreate(AreaTrigger* areaTrigger) override
|
||||
{
|
||||
BattlegroundScript::OnAreaTriggerCreate(areaTrigger);
|
||||
if (!areaTrigger->IsStaticSpawn())
|
||||
return;
|
||||
|
||||
switch (areaTrigger->GetEntry())
|
||||
{
|
||||
case AT_CAPTURE_POINT_ALLIANCE:
|
||||
_capturePointAreaTriggers[TEAM_ALLIANCE] = areaTrigger->GetGUID();
|
||||
break;
|
||||
case AT_CAPTURE_POINT_HORDE:
|
||||
_capturePointAreaTriggers[TEAM_HORDE] = areaTrigger->GetGUID();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnFlagStateChange(GameObject* flagInBase, FlagState oldValue, FlagState newValue, Player* player) override
|
||||
{
|
||||
BattlegroundScript::OnFlagStateChange(flagInBase, oldValue, newValue, player);
|
||||
|
||||
Team const team = flagInBase->GetEntry() == OBJECT_HORDE_FLAG_IN_BASE ? HORDE : ALLIANCE;
|
||||
TeamId const otherTeamId = Battleground::GetTeamIndexByTeamId(GetOtherTeam(team));
|
||||
|
||||
UpdateFlagState(team, newValue);
|
||||
|
||||
switch (newValue)
|
||||
{
|
||||
case FlagState::InBase:
|
||||
{
|
||||
if (battleground->GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
ResetAssaultDebuff();
|
||||
if (player)
|
||||
{
|
||||
// flag got returned to base by player interaction
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_FLAG_RETURNS, 1); // +1 flag returns
|
||||
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
battleground->SendBroadcastText(TEXT_ALLIANCE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
battleground->PlaySoundToAll(SOUND_FLAG_RETURNED);
|
||||
}
|
||||
else
|
||||
{
|
||||
battleground->SendBroadcastText(TEXT_HORDE_FLAG_RETURNED, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
battleground->PlaySoundToAll(SOUND_FLAG_RETURNED);
|
||||
}
|
||||
}
|
||||
// Flag respawned due to timeout/capture
|
||||
else if (GetFlagState(otherTeamId) != FlagState::Respawning)
|
||||
{
|
||||
// if other flag is respawning, we will let that one handle the message and sound to prevent double message/sound.
|
||||
battleground->SendBroadcastText(TEXT_FLAGS_PLACED, CHAT_MSG_BG_SYSTEM_NEUTRAL);
|
||||
battleground->PlaySoundToAll(SOUND_FLAGS_RESPAWNED);
|
||||
}
|
||||
|
||||
HandleFlagRoomCapturePoint();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FlagState::Dropped:
|
||||
{
|
||||
player->RemoveAurasDueToSpell(SPELL_QUICK_CAP_TIMER);
|
||||
RemoveAssaultDebuffFromPlayer(player);
|
||||
|
||||
uint32 recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_HORDE_FLAG;
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
recentlyDroppedSpellId = SPELL_RECENTLY_DROPPED_ALLIANCE_FLAG;
|
||||
battleground->SendBroadcastText(TEXT_ALLIANCE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
}
|
||||
else
|
||||
battleground->SendBroadcastText(TEXT_HORDE_FLAG_DROPPED, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
|
||||
player->CastSpell(player, recentlyDroppedSpellId, true);
|
||||
break;
|
||||
}
|
||||
case FlagState::Taken:
|
||||
{
|
||||
if (team == HORDE)
|
||||
{
|
||||
battleground->SendBroadcastText(TEXT_HORDE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
battleground->PlaySoundToAll(SOUND_HORDE_FLAG_PICKED_UP);
|
||||
}
|
||||
else
|
||||
{
|
||||
battleground->SendBroadcastText(TEXT_ALLIANCE_FLAG_PICKED_UP, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
battleground->PlaySoundToAll(SOUND_ALLIANCE_FLAG_PICKED_UP);
|
||||
}
|
||||
|
||||
if (GetFlagState(otherTeamId) == FlagState::Taken)
|
||||
_bothFlagsKept = true;
|
||||
|
||||
ApplyAssaultDebuffToPlayer(player);
|
||||
|
||||
flagInBase->CastSpell(player, SPELL_QUICK_CAP_TIMER, true);
|
||||
player->StartCriteria(CriteriaStartEvent::BeSpellTarget, SPELL_QUICK_CAP_TIMER, Seconds(GameTime::GetGameTime() - flagInBase->GetFlagTakenFromBaseTime()));
|
||||
break;
|
||||
}
|
||||
case FlagState::Respawning:
|
||||
ResetAssaultDebuff();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool CanCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
|
||||
{
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return false;
|
||||
|
||||
Team const team = battleground->GetPlayerTeam(player->GetGUID());
|
||||
TeamId const teamId = Battleground::GetTeamIndexByTeamId(team);
|
||||
TeamId const otherTeamId = Battleground::GetTeamIndexByTeamId(GetOtherTeam(team));
|
||||
|
||||
if (areaTrigger->GetGUID() != _capturePointAreaTriggers[teamId])
|
||||
return false;
|
||||
|
||||
// check if enemy flag's carrier is this player
|
||||
if (GetFlagCarrierGUID(otherTeamId) != player->GetGUID())
|
||||
return false;
|
||||
|
||||
// check that team's flag is in base
|
||||
return GetFlagState(teamId) == FlagState::InBase;
|
||||
}
|
||||
|
||||
void OnCaptureFlag(AreaTrigger* areaTrigger, Player* player) override
|
||||
{
|
||||
BattlegroundScript::OnCaptureFlag(areaTrigger, player);
|
||||
|
||||
Team winner = TEAM_OTHER;
|
||||
|
||||
Team const team = battleground->GetPlayerTeam(player->GetGUID());
|
||||
TeamId const teamId = Battleground::GetTeamIndexByTeamId(team);
|
||||
TeamId const otherTeamId = Battleground::GetTeamIndexByTeamId(GetOtherTeam(team));
|
||||
|
||||
/*
|
||||
1. Update flag states & score world states
|
||||
2. update points
|
||||
3. chat message & sound
|
||||
4. update criterias & achievements
|
||||
5. remove all related auras
|
||||
?. Reward honor & reputation
|
||||
*/
|
||||
|
||||
// 1. update the flag states
|
||||
for (ObjectGuid const& flagGuid: _flags)
|
||||
if (GameObject const* flag = battlegroundMap->GetGameObject(flagGuid))
|
||||
flag->HandleCustomTypeCommand(GameObjectType::SetNewFlagState(FlagState::Respawning, player));
|
||||
|
||||
// 2. update points
|
||||
if (battleground->GetTeamScore(teamId) < MAX_TEAM_SCORE)
|
||||
battleground->AddPoint(team, 1);
|
||||
|
||||
UpdateTeamScore(teamId);
|
||||
|
||||
// 3. chat message & sound
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
battleground->SendBroadcastText(TEXT_CAPTURED_HORDE_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
battleground->PlaySoundToAll(SOUND_FLAG_CAPTURED_ALLIANCE);
|
||||
battleground->RewardReputationToTeam(890, _reputationCapture, ALLIANCE);
|
||||
player->CastSpell(player, SPELL_CAPTURED_ALLIANCE_COSMETIC_FX);
|
||||
}
|
||||
else
|
||||
{
|
||||
battleground->SendBroadcastText(TEXT_CAPTURED_ALLIANCE_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
battleground->PlaySoundToAll(SOUND_FLAG_CAPTURED_HORDE);
|
||||
battleground->RewardReputationToTeam(889, _reputationCapture, HORDE);
|
||||
player->CastSpell(player, SPELL_CAPTURED_HORDE_COSMETIC_FX);
|
||||
}
|
||||
|
||||
// 4. update criteria's for achievement, player score etc.
|
||||
battleground->UpdatePvpStat(player, PVP_STAT_FLAG_CAPTURES, 1); // +1 flag captures
|
||||
|
||||
// 5. Remove all related auras
|
||||
RemoveAssaultDebuffFromPlayer(player);
|
||||
|
||||
if (GameObject const* flag = battlegroundMap->GetGameObject(_flags[otherTeamId]))
|
||||
player->RemoveAurasDueToSpell(flag->GetGOInfo()->newflag.pickupSpell, flag->GetGUID());
|
||||
|
||||
player->RemoveAurasDueToSpell(SPELL_QUICK_CAP_TIMER);
|
||||
|
||||
player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::PvPActive);
|
||||
|
||||
battleground->RewardHonorToTeam(battleground->GetBonusHonorFromKill(2), team);
|
||||
|
||||
// update last flag capture to be used if teamscore is equal
|
||||
SetLastFlagCapture(team);
|
||||
|
||||
if (battleground->GetTeamScore(teamId) == MAX_TEAM_SCORE)
|
||||
winner = team;
|
||||
|
||||
if (winner)
|
||||
{
|
||||
UpdateWorldState(WORLD_STATE_FLAG_STATE_ALLIANCE, 1);
|
||||
UpdateWorldState(WORLD_STATE_FLAG_STATE_HORDE, 1);
|
||||
UpdateWorldState(WORLD_STATE_STATE_TIMER_ACTIVE, 0);
|
||||
|
||||
battleground->RewardHonorToTeam(HONOR_REWARDS[BattlegroundMgr::IsBGWeekend(battleground->GetTypeID()) ? 1 : 0][0], winner);
|
||||
battleground->EndBattleground(winner);
|
||||
}
|
||||
}
|
||||
|
||||
Team GetPrematureWinner() override
|
||||
{
|
||||
if (battleground->GetTeamScore(TEAM_ALLIANCE) > battleground->GetTeamScore(TEAM_HORDE))
|
||||
return ALLIANCE;
|
||||
if (battleground->GetTeamScore(TEAM_HORDE) > battleground->GetTeamScore(TEAM_ALLIANCE))
|
||||
return HORDE;
|
||||
|
||||
return BattlegroundScript::GetPrematureWinner();
|
||||
}
|
||||
|
||||
void SetLastFlagCapture(Team team)
|
||||
{
|
||||
_lastFlagCaptureTeam = team;
|
||||
}
|
||||
|
||||
private:
|
||||
Team _lastFlagCaptureTeam;
|
||||
bool _bothFlagsKept;
|
||||
GuidSet _doors;
|
||||
std::array<ObjectGuid, PVP_TEAMS_COUNT> _flags;
|
||||
|
||||
TimeTracker _flagAssaultTimer;
|
||||
uint8 _assaultStackCount;
|
||||
std::array<ObjectGuid, PVP_TEAMS_COUNT> _capturePointAreaTriggers;
|
||||
|
||||
uint32 _honorWinKills;
|
||||
uint32 _honorEndKills;
|
||||
uint32 _reputationCapture;
|
||||
};
|
||||
|
||||
void AddSC_battleground_warsong_gulch()
|
||||
{
|
||||
RegisterBattlegroundMapScript(battleground_warsong_gulch, 2106);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// This is where scripts' loading functions should be declared:
|
||||
// Alterac Valley
|
||||
void AddSC_alterac_valley();
|
||||
void AddSC_boss_balinda();
|
||||
void AddSC_boss_drekthar();
|
||||
void AddSC_boss_galvangar();
|
||||
void AddSC_boss_vanndar();
|
||||
void AddSC_battleground_alterac_valley();
|
||||
|
||||
// Arathi Basin
|
||||
void AddSC_arathi_basin();
|
||||
void AddSC_battleground_arathi_basin();
|
||||
|
||||
// Eye of the storm
|
||||
void AddSC_battleground_eye_of_the_storm();
|
||||
|
||||
// Warsong Gulch
|
||||
void AddSC_battleground_warsong_gulch();
|
||||
|
||||
// Isle of Conquest
|
||||
void AddSC_battleground_isle_of_conquest();
|
||||
void AddSC_isle_of_conquest();
|
||||
void AddSC_boss_ioc_horde_alliance();
|
||||
|
||||
// Strand of the Ancients
|
||||
void AddSC_battleground_strand_of_the_ancients();
|
||||
void AddSC_strand_of_the_ancients();
|
||||
|
||||
// Blade's Edge Arena
|
||||
void AddSC_arena_blades_edge();
|
||||
void AddSC_arena_dalaran_sewers();
|
||||
void AddSC_arena_nagrand();
|
||||
void AddSC_arena_ruins_of_lordaeron();
|
||||
void AddSC_arena_ring_of_valor();
|
||||
|
||||
void AddSC_battleground_twin_peaks();
|
||||
void AddSC_battleground_battle_for_gilneas();
|
||||
|
||||
// The name of this function should match:
|
||||
// void Add${NameOfDirectory}Scripts()
|
||||
void AddBattlegroundsScripts()
|
||||
{
|
||||
// Alterac Valley
|
||||
AddSC_alterac_valley();
|
||||
AddSC_boss_balinda();
|
||||
AddSC_boss_drekthar();
|
||||
AddSC_boss_galvangar();
|
||||
AddSC_boss_vanndar();
|
||||
AddSC_battleground_alterac_valley();
|
||||
|
||||
// Arathi Basin
|
||||
AddSC_arathi_basin();
|
||||
AddSC_battleground_arathi_basin();
|
||||
|
||||
// Eye of the Storm
|
||||
AddSC_battleground_eye_of_the_storm();
|
||||
|
||||
// Warsong Gulch
|
||||
AddSC_battleground_warsong_gulch();
|
||||
|
||||
// Isle of Conquest
|
||||
AddSC_battleground_isle_of_conquest();
|
||||
AddSC_isle_of_conquest();
|
||||
AddSC_boss_ioc_horde_alliance();
|
||||
|
||||
// Strand of the Ancients
|
||||
AddSC_battleground_strand_of_the_ancients();
|
||||
AddSC_strand_of_the_ancients();
|
||||
|
||||
AddSC_arena_blades_edge();
|
||||
AddSC_arena_dalaran_sewers();
|
||||
AddSC_arena_nagrand();
|
||||
AddSC_arena_ruins_of_lordaeron();
|
||||
AddSC_arena_ring_of_valor();
|
||||
|
||||
AddSC_battleground_twin_peaks();
|
||||
AddSC_battleground_battle_for_gilneas();
|
||||
}
|
||||
@@ -1418,15 +1418,11 @@ public:
|
||||
|
||||
if (linked)
|
||||
{
|
||||
if (Battleground* bg = player->GetBattleground())
|
||||
nearestLoc = bg->GetClosestGraveyard(player);
|
||||
|
||||
if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId()))
|
||||
nearestLoc = bf->GetClosestGraveyard(player);
|
||||
else
|
||||
{
|
||||
if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetMap(), player->GetZoneId()))
|
||||
nearestLoc = bf->GetClosestGraveyard(player);
|
||||
else
|
||||
nearestLoc = sObjectMgr->GetClosestGraveyard(*player, player->GetTeam(), player);
|
||||
}
|
||||
nearestLoc = sObjectMgr->GetClosestGraveyard(*player, player->GetTeam(), player);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -16,12 +16,6 @@
|
||||
*/
|
||||
|
||||
// This is where scripts' loading functions should be declared:
|
||||
void AddSC_alterac_valley(); //Alterac Valley
|
||||
void AddSC_boss_balinda();
|
||||
void AddSC_boss_drekthar();
|
||||
void AddSC_boss_galvangar();
|
||||
void AddSC_boss_vanndar();
|
||||
void AddSC_arathi_basin(); //Arathi Basin
|
||||
void AddSC_boss_alizabal(); //Baradin Hold
|
||||
void AddSC_boss_occuthar();
|
||||
void AddSC_boss_argaloth();
|
||||
@@ -211,12 +205,6 @@ void AddSC_undercity();
|
||||
// void Add${NameOfDirectory}Scripts()
|
||||
void AddEasternKingdomsScripts()
|
||||
{
|
||||
AddSC_alterac_valley(); //Alterac Valley
|
||||
AddSC_boss_balinda();
|
||||
AddSC_boss_drekthar();
|
||||
AddSC_boss_galvangar();
|
||||
AddSC_boss_vanndar();
|
||||
AddSC_arathi_basin(); //Arathi Basin
|
||||
AddSC_boss_alizabal(); //Baradin Hold
|
||||
AddSC_boss_occuthar();
|
||||
AddSC_boss_argaloth();
|
||||
|
||||
@@ -194,9 +194,6 @@ void AddSC_boss_baltharus_the_warborn();
|
||||
void AddSC_boss_saviana_ragefire();
|
||||
void AddSC_boss_general_zarithrian();
|
||||
void AddSC_boss_halion();
|
||||
// Isle of Conquest
|
||||
void AddSC_isle_of_conquest();
|
||||
void AddSC_boss_ioc_horde_alliance();
|
||||
|
||||
void AddSC_dalaran();
|
||||
void AddSC_borean_tundra();
|
||||
@@ -210,8 +207,6 @@ void AddSC_wintergrasp();
|
||||
void AddSC_zuldrak();
|
||||
void AddSC_crystalsong_forest();
|
||||
|
||||
void AddSC_strand_of_the_ancients();
|
||||
|
||||
// The name of this function should match:
|
||||
// void Add${NameOfDirectory}Scripts()
|
||||
void AddNorthrendScripts()
|
||||
@@ -394,9 +389,6 @@ void AddNorthrendScripts()
|
||||
AddSC_boss_saviana_ragefire();
|
||||
AddSC_boss_general_zarithrian();
|
||||
AddSC_boss_halion();
|
||||
// Isle of Conquest
|
||||
AddSC_isle_of_conquest();
|
||||
AddSC_boss_ioc_horde_alliance();
|
||||
|
||||
AddSC_dalaran();
|
||||
AddSC_borean_tundra();
|
||||
@@ -408,6 +400,4 @@ void AddNorthrendScripts()
|
||||
AddSC_storm_peaks();
|
||||
AddSC_wintergrasp();
|
||||
AddSC_zuldrak();
|
||||
|
||||
AddSC_strand_of_the_ancients();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ SDCategory: Dalaran
|
||||
Script Data End */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "BattlegroundDS.h"
|
||||
#include "Containers.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Mail.h"
|
||||
@@ -254,44 +253,8 @@ private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
class at_ds_pipe_knockback : public AreaTriggerScript
|
||||
{
|
||||
public:
|
||||
at_ds_pipe_knockback() : AreaTriggerScript("at_ds_pipe_knockback") { }
|
||||
|
||||
void Trigger(Player* player) const
|
||||
{
|
||||
if (Battleground* battleground = player->GetBattleground())
|
||||
{
|
||||
if (battleground->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
// Remove effects of Demonic Circle Summon
|
||||
player->RemoveAurasDueToSpell(SPELL_WARL_DEMONIC_CIRCLE);
|
||||
|
||||
// Someone has get back into the pipes and the knockback has already been performed,
|
||||
// so we reset the knockback count for kicking the player again into the arena.
|
||||
if (battleground->GetData(BG_DS_DATA_PIPE_KNOCKBACK_COUNT) >= BG_DS_PIPE_KNOCKBACK_TOTAL_COUNT)
|
||||
battleground->SetData(BG_DS_DATA_PIPE_KNOCKBACK_COUNT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override
|
||||
{
|
||||
Trigger(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnExit(Player* player, AreaTriggerEntry const* /*trigger*/) override
|
||||
{
|
||||
Trigger(player);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_dalaran()
|
||||
{
|
||||
RegisterCreatureAI(npc_mageguard_dalaran);
|
||||
RegisterCreatureAI(npc_minigob_manabonk);
|
||||
new at_ds_pipe_knockback();
|
||||
}
|
||||
|
||||
@@ -3081,9 +3081,6 @@ class spell_item_rocket_boots : public SpellScript
|
||||
void HandleDummy(SpellEffIndex /* effIndex */)
|
||||
{
|
||||
Player* caster = GetCaster()->ToPlayer();
|
||||
if (Battleground* bg = caster->GetBattleground())
|
||||
bg->EventPlayerDroppedFlag(caster);
|
||||
|
||||
caster->GetSpellHistory()->ResetCooldown(SPELL_ROCKET_BOOTS_PROC);
|
||||
caster->CastSpell(caster, SPELL_ROCKET_BOOTS_PROC, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user