aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts/Battlefield/BattlefieldTB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/scripts/Battlefield/BattlefieldTB.cpp')
-rw-r--r--src/server/scripts/Battlefield/BattlefieldTB.cpp889
1 files changed, 889 insertions, 0 deletions
diff --git a/src/server/scripts/Battlefield/BattlefieldTB.cpp b/src/server/scripts/Battlefield/BattlefieldTB.cpp
new file mode 100644
index 00000000000..e147689d610
--- /dev/null
+++ b/src/server/scripts/Battlefield/BattlefieldTB.cpp
@@ -0,0 +1,889 @@
+/*
+* 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/>.
+*/
+
+// TO-DO:
+// - Implement proper support for vehicles (Player::VehicleSpellInitialize())
+// - Siege Engine Turret (45564) crashing server (Auras: Unknown Shapeshift Type: 24)
+// - Graveyard spirit phasing, ressurection, Spiritual Immunity aura for players nearby
+// - Warn and teleport players out of the Baradin Hold instance (need sniffs; spell 94964?)
+// - Not sure, but players should probably be able to ressurect from guide spirits when there's no battle
+// - Check and script achievements
+
+#include "BattlefieldTB.h"
+#include "AchievementMgr.h"
+#include "Battleground.h"
+#include "CreatureTextMgr.h"
+#include "GameObject.h"
+#include "GameTime.h"
+#include "MapManager.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "Random.h"
+#include "ScriptMgr.h"
+#include "SpellAuras.h"
+#include "TemporarySummon.h"
+#include "World.h"
+#include "WorldStatePackets.h"
+
+BattlefieldTB::~BattlefieldTB() { }
+
+bool BattlefieldTB::SetupBattlefield()
+{
+ m_TypeId = BATTLEFIELD_TB; // See enum BattlefieldTypes
+ m_BattleId = BATTLEFIELD_BATTLEID_TB;
+ m_ZoneId = BATTLEFIELD_TB_ZONEID;
+ m_MapId = BATTLEFIELD_TB_MAPID;
+ m_Map = sMapMgr->CreateBaseMap(m_MapId);
+
+ InitStalker(NPC_DEBUG_ANNOUNCER, TolBaradDebugAnnouncerPos);
+
+ m_MaxPlayer = sWorld->getIntConfig(CONFIG_TOLBARAD_PLR_MAX);
+ m_IsEnabled = sWorld->getBoolConfig(CONFIG_TOLBARAD_ENABLE);
+ m_MinPlayer = sWorld->getIntConfig(CONFIG_TOLBARAD_PLR_MIN);
+ m_MinLevel = sWorld->getIntConfig(CONFIG_TOLBARAD_PLR_MIN_LVL);
+ m_BattleTime = sWorld->getIntConfig(CONFIG_TOLBARAD_BATTLETIME) * MINUTE * IN_MILLISECONDS;
+ m_BonusTime = sWorld->getIntConfig(CONFIG_TOLBARAD_BONUSTIME) * MINUTE * IN_MILLISECONDS;
+ m_NoWarBattleTime = sWorld->getIntConfig(CONFIG_TOLBARAD_NOBATTLETIME) * MINUTE * IN_MILLISECONDS;
+ m_RestartAfterCrash = sWorld->getIntConfig(CONFIG_TOLBARAD_RESTART_AFTER_CRASH) * MINUTE * IN_MILLISECONDS;
+
+ m_TimeForAcceptInvite = 20;
+ m_StartGroupingTimer = 15 * MINUTE * IN_MILLISECONDS;
+ m_StartGrouping = false;
+ m_isActive = false;
+
+ KickPosition.Relocate(-605.5f, 1181.31f, 95.96f, 6.177155f);
+ KickPosition.m_mapId = m_MapId;
+
+ RegisterZone(m_ZoneId);
+
+ m_Data32.resize(BATTLEFIELD_TB_DATA_MAX);
+
+ m_saveTimer = 5 * MINUTE * IN_MILLISECONDS;
+
+ updatedNPCAndObjects = true;
+ m_updateObjectsTimer = 0;
+
+ // Was there a battle going on or time isn't set yet? Then use m_RestartAfterCrash
+ if (sWorld->getWorldState(WS_BATTLEFIELD_TB_STATE_BATTLE) == 1 || sWorld->getWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE) == 0)
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, m_RestartAfterCrash);
+
+ // Set timer
+ m_Timer = sWorld->getWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE);
+
+ // Defending team isn't set yet? Choose randomly.
+ if (sWorld->getWorldState(WS_BATTLEFIELD_TB_FACTION_CONTROLLING) == 0)
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_FACTION_CONTROLLING, uint32(urand(1, 2)));
+
+ // Set defender team
+ SetDefenderTeam(TeamId(sWorld->getWorldState(WS_BATTLEFIELD_TB_FACTION_CONTROLLING) - 1));
+
+ // Just to save world states
+ SendInitWorldStatesToAll();
+
+ // Create capture points
+ for (uint8 i = 0; i < TB_BASE_COUNT; i++)
+ {
+ TolBaradCapturePoint* capturePoint = new TolBaradCapturePoint(this, GetDefenderTeam());
+
+ //Spawn flag pole
+ if (GameObject* go = SpawnGameObject(TBCapturePoints[i].entryFlagPole[GetDefenderTeam()], TBCapturePoints[i].pos, QuaternionData::fromEulerAnglesZYX(TBCapturePoints[i].pos.GetOrientation(), 0.0f, 0.0f)))
+ {
+ go->SetGoArtKit(GetDefenderTeam() == TEAM_ALLIANCE ? TB_GO_ARTKIT_FLAG_ALLIANCE : TB_GO_ARTKIT_FLAG_HORDE);
+ capturePoint->SetCapturePointData(go);
+ }
+ AddCapturePoint(capturePoint);
+ }
+
+ // Spawn towers
+ for (uint8 i = 0; i < TB_TOWERS_COUNT; i++)
+ if (GameObject* go = SpawnGameObject(TBTowers[i].entry, TBTowers[i].pos, QuaternionData::fromEulerAnglesZYX(TBTowers[i].pos.GetOrientation(), 0.0f, 0.0f)))
+ Towers.insert(go->GetGUID());
+
+ // Init Graveyards
+ SetGraveyardNumber(BATTLEFIELD_TB_GRAVEYARD_MAX);
+
+ // Graveyards
+ for (uint8 i = 0; i < BATTLEFIELD_TB_GRAVEYARD_MAX; i++)
+ {
+ BfGraveyard* graveyard = new BfGraveyard(this);
+
+ // When between games, the graveyard is controlled by the defending team
+ graveyard->Initialize(GetDefenderTeam(), TBGraveyards[i].gyid);
+
+ // Spawn spirits
+ for (uint8 team = 0; team < 2; team++)
+ if (Creature* creature = SpawnCreature(TBGraveyards[i].spiritEntry[team], TBGraveyards[i].pos))
+ graveyard->SetSpirit(creature, TeamId(team));
+
+ m_GraveyardList[i] = graveyard;
+ }
+
+ // Time warning vars
+ warnedFiveMinutes = false;
+ warnedTwoMinutes = false;
+ warnedOneMinute = false;
+
+ UpdateNPCsAndGameObjects();
+
+ return true;
+}
+
+bool BattlefieldTB::Update(uint32 diff)
+{
+ bool m_return = Battlefield::Update(diff);
+
+ // Minutes till battle preparation warnings
+ if (GetState() == BATTLEFIELD_INACTIVE)
+ {
+ if (m_Timer <= 5 * MINUTE * IN_MILLISECONDS + m_StartGroupingTimer && !warnedFiveMinutes)
+ {
+ warnedFiveMinutes = true;
+ SendWarning(TB_TEXT_PREPARATIONS_IN_5_MIN);
+ }
+
+ if (m_Timer <= 2 * MINUTE * IN_MILLISECONDS + m_StartGroupingTimer && !warnedTwoMinutes)
+ {
+ warnedTwoMinutes = true;
+ SendWarning(TB_TEXT_PREPARATIONS_IN_2_MIN);
+ }
+
+ if (m_Timer <= 1 * MINUTE * IN_MILLISECONDS + m_StartGroupingTimer && !warnedOneMinute)
+ {
+ warnedOneMinute = true;
+ SendWarning(TB_TEXT_PREPARATIONS_IN_1_MIN);
+ }
+ }
+
+ if (!updatedNPCAndObjects)
+ {
+ if (m_updateObjectsTimer <= diff)
+ {
+ UpdateNPCsAndGameObjects();
+ updatedNPCAndObjects = true;
+ }
+ else
+ m_updateObjectsTimer -= diff;
+ }
+
+ if (m_saveTimer <= diff)
+ {
+ if (!IsWarTime())
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, m_Timer);
+ m_saveTimer = 60 * IN_MILLISECONDS;
+ }
+ else
+ m_saveTimer -= diff;
+
+ return m_return;
+}
+
+void BattlefieldTB::OnPlayerEnterZone(Player* player)
+{
+ if (!m_isActive)
+ RemoveAurasFromPlayer(player);
+
+ SendInitWorldStatesTo(player);
+}
+
+void BattlefieldTB::OnPlayerLeaveZone(Player* player)
+{
+ if (!m_isActive)
+ RemoveAurasFromPlayer(player);
+}
+
+void BattlefieldTB::OnPlayerJoinWar(Player* player)
+{
+ RemoveAurasFromPlayer(player);
+
+ player->SetPvP(true);
+
+ // Bonus damage buff for attackers
+ if (player->GetTeamId() == GetAttackerTeam() && GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED) > 0)
+ player->CastSpell(player, SPELL_TOWER_ATTACK_BONUS, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_AURA_STACK, GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED)));
+}
+
+
+void BattlefieldTB::OnPlayerLeaveWar(Player* player)
+{
+ RemoveAurasFromPlayer(player);
+}
+
+void BattlefieldTB::RemoveAurasFromPlayer(Player* player)
+{
+ player->RemoveAurasDueToSpell(SPELL_TB_SLOW_FALL);
+ player->RemoveAurasDueToSpell(SPELL_TB_VETERAN);
+ player->RemoveAurasDueToSpell(SPELL_TOWER_ATTACK_BONUS);
+ player->RemoveAurasDueToSpell(SPELL_TB_SPIRITUAL_IMMUNITY);
+}
+
+// 62 fields, [7]-[68]
+void BattlefieldTB::FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& packet)
+{
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_ALLIANCE_ATTACKING_SHOW), int32(IsWarTime() && GetAttackerTeam() == TEAM_ALLIANCE ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_HORDE_ATTACKING_SHOW), int32(IsWarTime() && GetAttackerTeam() == TEAM_HORDE ? 1 : 0));
+
+ // Not sure if TB
+ //packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_9_UNKNOWN), int32(1));
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_SOUTH_DAMAGED_NEUTRAL), int32(0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_SOUTH_INTACT_NEUTRAL), int32(0));
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_PROGRESS_SHOW), int32(0));
+
+ // Buildings/bases
+ for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
+ {
+ uint8 i = TB_BASE_COUNT;
+ switch (itr->second->GetCapturePointEntry())
+ {
+ case GO_CAPTURE_POINT_NORTH_A_DEFENDING:
+ case GO_CAPTURE_POINT_NORTH_H_DEFENDING:
+ i = TB_BASE_IRONCLAD_GARRISON;
+ break;
+ case GO_CAPTURE_POINT_EAST_A_DEFENDING:
+ case GO_CAPTURE_POINT_EAST_H_DEFENDING:
+ i = TB_BASE_SLAGWORKS;
+ break;
+ case GO_CAPTURE_POINT_WEST_A_DEFENDING:
+ case GO_CAPTURE_POINT_WEST_H_DEFENDING:
+ i = TB_BASE_WARDENS_VIGIL;
+ break;
+ default:
+ continue;
+ }
+
+ TeamId team = TEAM_NEUTRAL;
+ bool controlled = false;
+ bool capturing = false;
+
+ switch (itr->second->GetObjectiveState())
+ {
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE:
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE:
+ controlled = true;
+ team = itr->second->GetTeamId();
+ break;
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
+ team = TEAM_ALLIANCE;
+ capturing = true;
+ break;
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
+ team = TEAM_HORDE;
+ capturing = true;
+ break;
+ default:
+ team = TEAM_NEUTRAL;
+ break;
+ }
+
+ packet.Worldstates.emplace_back(uint32(TBCapturePoints[i].wsControlled[TEAM_ALLIANCE]), int32(team == TEAM_ALLIANCE && controlled ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(TBCapturePoints[i].wsCapturing[TEAM_ALLIANCE]), int32(team == TEAM_ALLIANCE && capturing ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(TBCapturePoints[i].wsNeutral), int32(team == TEAM_NEUTRAL ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(TBCapturePoints[i].wsCapturing[TEAM_HORDE]), int32(team == TEAM_HORDE && capturing ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(TBCapturePoints[i].wsControlled[TEAM_HORDE]), int32(team == TEAM_HORDE && controlled ? 1 : 0));
+ }
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_TOWERS_DESTROYED_SHOW), int32(GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED)));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_BUILDINGS_CAPTURED_SHOW), int32(IsWarTime() ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_BUILDINGS_CAPTURED), int32(GetData(BATTLEFIELD_TB_DATA_BUILDINGS_CAPTURED)));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_TOWERS_DESTROYED), int32(0));
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_TIME_BATTLE_END_SHOW), int32(IsWarTime() ? 1 : 0));
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_STATE_BATTLE), int32(IsWarTime() ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_STATE_PREPARATIONS), int32(GetState() == BATTLEFIELD_WARMUP ? 1 : 0));
+
+ // Not sure if TB
+ //packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_35_UNKNOWN), int32(0));
+ //packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_36_UNKNOWN), int32(0));
+ //packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_37_UNKNOWN), int32(0));
+
+ // Unused tower icons
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_WEST_DAMAGED_NEUTRAL), int32(0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_WEST_INTACT_NEUTRAL), int32(0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_EAST_DAMAGED_NEUTRAL), int32(0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_EAST_INTACT_NEUTRAL), int32(0));
+
+ // Towers/spires
+ for (uint8 i = 0; i < TB_TOWERS_COUNT; i++)
+ {
+ // Find gameobject
+ for (ObjectGuid guid : Towers)
+ {
+ GameObject* tower = GetGameObject(guid);
+ if (!tower || tower->GetEntry() != TBTowers[i].entry)
+ continue;
+
+ TeamId team = GetDefenderTeam(); // 0-false -> alliance; 1-true -> horde
+ bool intact = tower->GetDestructibleState() == GO_DESTRUCTIBLE_INTACT;
+ bool damaged = tower->GetDestructibleState() == GO_DESTRUCTIBLE_DAMAGED;
+ bool destroyed = tower->GetDestructibleState() == GO_DESTRUCTIBLE_DESTROYED;
+
+ packet.Worldstates.emplace_back(uint32(TBTowers[i].wsIntact[TEAM_ALLIANCE]), int32(!team && intact ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(TBTowers[i].wsDamaged[TEAM_ALLIANCE]), int32(!team && damaged ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(TBTowers[i].wsDestroyed), int32(destroyed ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(TBTowers[i].wsDamaged[TEAM_HORDE]), int32(team && damaged ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(TBTowers[i].wsIntact[TEAM_HORDE]), int32(team && intact ? 1 : 0));
+ }
+ }
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE_SHOW), int32(!IsWarTime() ? 1 : 0));
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_ALLIANCE_CONTROLS_SHOW), int32(!IsWarTime() && GetDefenderTeam() == TEAM_ALLIANCE ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_HORDE_CONTROLS_SHOW), int32(!IsWarTime() && GetDefenderTeam() == TEAM_HORDE ? 1 : 0));
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_TIME_BATTLE_END), int32(IsWarTime() ? GameTime::GetGameTime() + (m_Timer / 1000) : 0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE), int32(!IsWarTime() ? GameTime::GetGameTime() + (m_Timer / 1000) : 0));
+
+ // Not sure if TB
+ //packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_65_UNKNOWN), int32(0));
+ //packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_66_UNKNOWN), int32(0));
+
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_KEEP_ALLIANCE), int32(GetDefenderTeam() == TEAM_ALLIANCE ? 1 : 0));
+ packet.Worldstates.emplace_back(uint32(WS_BATTLEFIELD_TB_KEEP_HORDE), int32(GetDefenderTeam() == TEAM_HORDE ? 1 : 0));
+}
+
+void BattlefieldTB::SendInitWorldStatesTo(Player* player)
+{
+ WorldPackets::WorldState::InitWorldStates packet;
+ packet.AreaID = m_ZoneId;
+ packet.MapID = m_MapId;
+ packet.SubareaID = 0;
+
+ FillInitialWorldStates(packet);
+
+ player->SendDirectMessage(packet.Write());
+}
+
+void BattlefieldTB::SendInitWorldStatesToAll()
+{
+ // Save
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_STATE_BATTLE, uint32(IsWarTime() ? 1 : 0));
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_ALLIANCE_CONTROLS_SHOW, uint32(!IsWarTime() && GetDefenderTeam() == TEAM_ALLIANCE ? 1 : 0));
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_HORDE_CONTROLS_SHOW, uint32(!IsWarTime() && GetDefenderTeam() == TEAM_HORDE ? 1 : 0));
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_ALLIANCE_ATTACKING_SHOW, uint32(IsWarTime() && GetAttackerTeam() == TEAM_ALLIANCE ? 1 : 0));
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_HORDE_ATTACKING_SHOW, uint32(IsWarTime() && GetAttackerTeam() == TEAM_HORDE ? 1 : 0));
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE, uint32(!IsWarTime() ? m_Timer : 0));
+ sWorld->setWorldState(WS_BATTLEFIELD_TB_TIME_NEXT_BATTLE_SHOW, uint32(!IsWarTime() ? 1 : 0));
+
+ // Tol Barad
+ for (uint8 team = 0; team < PVP_TEAMS_COUNT; team++)
+ for (ObjectGuid const& guid : m_players[team])
+ if (Player* player = ObjectAccessor::FindPlayer(guid))
+ SendInitWorldStatesTo(player);
+
+ // Tol Barad Peninsula
+ Map::PlayerList const& players = m_Map->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if (Player* player = itr->GetSource()->ToPlayer())
+ if (player->GetZoneId() == 5389) // ZONE_TOL_BARAD_PENINSULA
+ player->SendInitWorldStates(5389, player->GetAreaId());
+}
+
+void BattlefieldTB::OnStartGrouping()
+{
+ UpdateNPCsAndGameObjects();
+
+ SendUpdateWorldState(WS_BATTLEFIELD_TB_STATE_PREPARATIONS, uint32(1));
+
+ // Teleport players out of questing area
+ for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
+ for (ObjectGuid const& guid : m_players[team])
+ if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (player->GetAreaId() == TBQuestAreas[m_iCellblockRandom].entry)
+ player->CastSpell(player, TBQuestAreas[m_iCellblockRandom].teleportSpell, true);
+
+ // Should we also teleport players out of Baradin Hold underground area?
+};
+
+void BattlefieldTB::OnBattleStart()
+{
+ SetData(BATTLEFIELD_TB_DATA_BUILDINGS_CAPTURED, uint32(0));
+ SetData(BATTLEFIELD_TB_DATA_TOWERS_INTACT, uint32(3));
+ SetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED, uint32(0));
+
+ UpdateNPCsAndGameObjects();
+
+ SendInitWorldStatesToAll();
+};
+
+void BattlefieldTB::OnBattleEnd(bool endByTimer)
+{
+ if (!endByTimer) // Attackers win (but now they are defenders already)
+ SendWarning(GetDefenderTeam() == TEAM_ALLIANCE ? TB_TEXT_FORTRESS_CAPTURE_ALLIANCE : TB_TEXT_FORTRESS_CAPTURE_HORDE);
+ else // Defenders win
+ SendWarning(GetDefenderTeam() == TEAM_ALLIANCE ? TB_TEXT_FORTRESS_DEFEND_ALLIANCE : TB_TEXT_FORTRESS_DEFEND_HORDE);
+
+ // UpdateNPCsAndGameObjects() must be called 1 minute after battle ends
+ m_updateObjectsTimer = 1 * MINUTE * IN_MILLISECONDS;
+ updatedNPCAndObjects = false;
+
+ // Complete quest
+ TeamCastSpell(GetDefenderTeam(), GetDefenderTeam() == TEAM_ALLIANCE ? SPELL_VICTORY_ALLIANCE : SPELL_VICTORY_HORDE);
+
+ // Rewards
+ TeamCastSpell(GetDefenderTeam(), GetDefenderTeam() == TEAM_ALLIANCE ? SPELL_REWARD_VICTORY_ALLIANCE : SPELL_REWARD_VICTORY_HORDE);
+ for (uint32 i = 0; i < GetData(BATTLEFIELD_TB_DATA_TOWERS_INTACT); i++) // Unsure, for each intact tower or only once for having any tower intact?
+ TeamCastSpell(GetDefenderTeam(), SPELL_REWARD_TOWER_INTACT);
+ TeamCastSpell(GetAttackerTeam(), SPELL_REWARD_DEFEAT);
+
+ for (uint8 team = 0; team < 2; ++team)
+ {
+ for (ObjectGuid const& guid : m_PlayersInWar[team])
+ if (Player* player = ObjectAccessor::FindPlayer(guid))
+ RemoveAurasFromPlayer(player);
+
+ m_PlayersInWar[team].clear();
+ }
+
+ // Reset time warning vars
+ warnedFiveMinutes = false;
+ warnedTwoMinutes = false;
+ warnedOneMinute = false;
+};
+
+void BattlefieldTB::UpdateNPCsAndGameObjects()
+{
+ for (ObjectGuid guid : BattleInactiveNPCs)
+ if (Creature* creature = GetCreature(guid))
+ HideNpc(creature);
+
+ for (ObjectGuid guid : BattleInactiveGOs)
+ if (GameObject* gameobject = GetGameObject(guid))
+ gameobject->SetRespawnTime(RESPAWN_ONE_DAY);
+
+ for (ObjectGuid guid : TemporaryNPCs)
+ if (Creature* creature = GetCreature(guid))
+ creature->RemoveFromWorld();
+ TemporaryNPCs.clear();
+
+ for (ObjectGuid guid : TemporaryGOs)
+ if (GameObject* gameobject = GetGameObject(guid))
+ gameobject->Delete();
+ TemporaryGOs.clear();
+
+ // Tol Barad gates - closed during warmup
+ if (GameObject* gates = GetGameObject(TBGatesGUID))
+ gates->SetGoState(GetState() == BATTLEFIELD_WARMUP ? GO_STATE_READY : GO_STATE_ACTIVE);
+
+ // Baradin Hold door - open when inactive
+ if (GameObject* door = GetGameObject(TBDoorGUID))
+ door->SetGoState(GetState() == BATTLEFIELD_INACTIVE ? GO_STATE_ACTIVE : GO_STATE_READY);
+
+ // Decide which cellblock and questgiver will be active.
+ m_iCellblockRandom = GetState() == BATTLEFIELD_INACTIVE ? urand(CELLBLOCK_THE_HOLE, CELLBLOCK_CURSED_DEPTHS) : uint8(CELLBLOCK_NONE);
+
+ // To The Hole gate
+ if (GameObject* door = GetGameObject(m_gateToTheHoleGUID))
+ door->SetGoState(m_iCellblockRandom == CELLBLOCK_THE_HOLE ? GO_STATE_ACTIVE : GO_STATE_READY);
+
+ // D-Block gate
+ if (GameObject* door = GetGameObject(m_gateDBlockGUID))
+ door->SetGoState(m_iCellblockRandom == CELLBLOCK_D_BLOCK ? GO_STATE_ACTIVE : GO_STATE_READY);
+
+ // Cursed Depths gate
+ if (GameObject* door = GetGameObject(m_gateCursedDepthsGUID))
+ door->SetGoState(m_iCellblockRandom == CELLBLOCK_CURSED_DEPTHS ? GO_STATE_ACTIVE : GO_STATE_READY);
+
+ if (GetState() == BATTLEFIELD_INACTIVE)
+ {
+ // Delete capture points
+ for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
+ itr->second->DelCapturePoint();
+ m_capturePoints.clear();
+
+ // Create capture points
+ for (uint8 i = 0; i < TB_BASE_COUNT; i++)
+ {
+ TolBaradCapturePoint* capturePoint = new TolBaradCapturePoint(this, GetDefenderTeam());
+
+ //Spawn flag pole
+ if (GameObject* go = SpawnGameObject(TBCapturePoints[i].entryFlagPole[GetDefenderTeam()], TBCapturePoints[i].pos, QuaternionData::fromEulerAnglesZYX(TBCapturePoints[i].pos.GetOrientation(), 0.0f, 0.0f)))
+ {
+ go->SetGoArtKit(GetDefenderTeam() == TEAM_ALLIANCE ? TB_GO_ARTKIT_FLAG_ALLIANCE : TB_GO_ARTKIT_FLAG_HORDE);
+ capturePoint->SetCapturePointData(go);
+ }
+
+ AddCapturePoint(capturePoint);
+ }
+
+ for (ObjectGuid guid : BattleInactiveNPCs)
+ if (Creature* creature = GetCreature(guid))
+ ShowNpc(creature, true);
+
+ for (ObjectGuid guid : BattleInactiveGOs)
+ if (GameObject* gameobject = GetGameObject(guid))
+ gameobject->SetRespawnTime(RESPAWN_IMMEDIATELY);
+
+ for (uint8 i = 0; i < TB_QUEST_INFANTRY_MAX; i++)
+ {
+ uint32 entry = TB_QUEST_INFANTRY[GetDefenderTeam()][urand(0,3)];
+ if (Creature* creature = SpawnCreature(entry, TBQuestInfantrySpawnData[i]))
+ TemporaryNPCs.insert(creature->GetGUID());
+ }
+
+ for (uint8 i = 0; i < TB_GUARDS_MAX; i++)
+ if (Creature* creature = SpawnCreature(GetDefenderTeam() == TEAM_ALLIANCE ? NPC_BARADIN_GUARD : NPC_HELLSCREAMS_SENTRY, GuardNPCSpawns[i]))
+ TemporaryNPCs.insert(creature->GetGUID());
+
+ for (uint8 i = 0; i < TB_FACTION_NPC_MAX; i++)
+ if (Creature* creature = SpawnCreature(GetDefenderTeam() == TEAM_ALLIANCE ? FactionNPCSpawns[i].entryAlliance : FactionNPCSpawns[i].entryHorde, FactionNPCSpawns[i].pos))
+ TemporaryNPCs.insert(creature->GetGUID());
+
+ if (Creature* creature = SpawnCreature(RandomQuestgivers[GetDefenderTeam()][m_iCellblockRandom], RandomQuestgiverPos))
+ TemporaryNPCs.insert(creature->GetGUID());
+
+ // Spawn portals
+ for (uint8 i = 0; i < TB_PORTAL_MAX; i++)
+ if (GameObject* go = SpawnGameObject(TBPortalEntry[GetDefenderTeam()], TBPortals[i], QuaternionData::fromEulerAnglesZYX(TBPortals[i].GetOrientation(), 0.0f, 0.0f)))
+ TemporaryGOs.insert(go->GetGUID());
+
+ // Update towers
+ for (ObjectGuid guid : Towers)
+ if (GameObject* go = GetGameObject(guid))
+ go->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING);
+ }
+ else if (GetState() == BATTLEFIELD_IN_PROGRESS)
+ {
+ for (uint8 i = 0; i < TB_ABANDONED_SIEGE_ENGINE_COUNT; i++)
+ if (Creature* creature = SpawnCreature(NPC_ABANDONED_SIEGE_ENGINE, TBAbandonedSiegeEngineSpawnData[i]))
+ TemporaryNPCs.insert(creature->GetGUID());
+
+ for (ObjectGuid guid : Towers)
+ {
+ if (GameObject* go = GetGameObject(guid))
+ {
+ go->SetDestructibleState(GO_DESTRUCTIBLE_INTACT);
+ go->ModifyHealth(go->GetGOValue()->Building.MaxHealth);
+ }
+ }
+ }
+
+ // Spawn banners
+ for (uint8 i = 0; i < TB_BANNER_MAX; i++)
+ if (GameObject* go = SpawnGameObject(TBBannerEntry[GetDefenderTeam()], TBBanners[i], QuaternionData::fromEulerAnglesZYX(TBBanners[i].GetOrientation(), 0.0f, 0.0f)))
+ TemporaryGOs.insert(go->GetGUID());
+
+ // Set graveyard controls
+ for (uint8 i = 0; i < BATTLEFIELD_TB_GRAVEYARD_MAX; i++)
+ if (BfGraveyard* graveyard = GetGraveyardById(i))
+ graveyard->GiveControlTo(!IsWarTime() || TBGraveyards[i].defenderControls ? GetDefenderTeam() : GetAttackerTeam());
+};
+
+void BattlefieldTB::OnCreatureCreate(Creature* creature)
+{
+ switch (creature->GetEntry())
+ {
+ // Store NPCs that need visibility toggling
+ case NPC_TOLBARAD_CAPTIVE_SPIRIT:
+ case NPC_TOLBARAD_CELLBLOCK_OOZE:
+ case NPC_TOLBARAD_ARCHMAGE_GALUS:
+ case NPC_TOLBARAD_GHASTLY_CONVICT:
+ case NPC_TOLBARAD_SHIVARRA_DESTROYER:
+ case NPC_TOLBARAD_CELL_WATCHER:
+ case NPC_TOLBARAD_SVARNOS:
+ case NPC_TOLBARAD_JAILED_WRATHGUARD:
+ case NPC_TOLBARAD_IMPRISONED_IMP:
+ case NPC_TOLBARAD_WARDEN_SILVA:
+ case NPC_TOLBARAD_WARDEN_GUARD:
+ case NPC_TOLBARAD_IMPRISONED_WORKER:
+ case NPC_TOLBARAD_EXILED_MAGE:
+ case NPC_CROCOLISK:
+ case NPC_PROBLIM:
+ BattleInactiveNPCs.insert(creature->GetGUID());
+ if (GetState() == BATTLEFIELD_WARMUP) // If battle is about to start, we must hide these.
+ HideNpc(creature);
+ break;
+ case NPC_ABANDONED_SIEGE_ENGINE:
+ creature->SetFaction(TBFactions[GetDefenderTeam()]);
+ creature->CastSpell(creature, SPELL_THICK_LAYER_OF_RUST, true);
+ break;
+ case NPC_SIEGE_ENGINE_TURRET:
+ if (Unit* vehiclebase = creature->GetCharmerOrOwner()->GetVehicleBase())
+ creature->EnterVehicle(vehiclebase);
+ break;
+ case NPC_TOWER_RANGE_FINDER:
+ creature->CastSpell(creature, SPELL_TOWER_RANGE_FINDER_PERIODIC, true);
+ break;
+ case NPC_TB_GY_SPIRIT_BARADIN_HOLD_A:
+ case NPC_TB_GY_SPIRIT_BARADIN_HOLD_H:
+ case NPC_TB_GY_SPIRIT_IRONCLAD_GARRISON_A:
+ case NPC_TB_GY_SPIRIT_WARDENS_VIGIL_A:
+ case NPC_TB_GY_SPIRIT_EAST_SPIRE_A:
+ case NPC_TB_GY_SPIRIT_SOUTH_SPIRE_A:
+ case NPC_TB_GY_SPIRIT_WEST_SPIRE_A:
+ case NPC_TB_GY_SPIRIT_SLAGWORKS_A:
+ case NPC_TB_GY_SPIRIT_IRONCLAD_GARRISON_H:
+ case NPC_TB_GY_SPIRIT_WARDENS_VIGIL_H:
+ case NPC_TB_GY_SPIRIT_SLAGWORKS_H:
+ case NPC_TB_GY_SPIRIT_WEST_SPIRE_H:
+ case NPC_TB_GY_SPIRIT_EAST_SPIRE_H:
+ case NPC_TB_GY_SPIRIT_SOUTH_SPIRE_H:
+ creature->CastSpell(creature, SPELL_TB_SPIRITUAL_IMMUNITY, true);
+ creature->CastSpell(creature, SPELL_TB_SPIRIT_HEAL_CHANNEL, true);
+ break;
+ default:
+ break;
+ }
+};
+
+void BattlefieldTB::OnGameObjectCreate(GameObject* go)
+{
+ switch (go->GetEntry())
+ {
+ case GO_TOLBARAD_GATES:
+ TBGatesGUID = go->GetGUID();
+ go->SetGoState(GetState() == BATTLEFIELD_WARMUP ? GO_STATE_READY : GO_STATE_ACTIVE);
+ break;
+ case GO_TOLBARAD_DOOR:
+ TBDoorGUID = go->GetGUID();
+ go->SetGoState(GetState() == BATTLEFIELD_INACTIVE ? GO_STATE_ACTIVE : GO_STATE_READY);
+ break;
+ case GO_GATE_TO_THE_HOLE:
+ m_gateToTheHoleGUID = go->GetGUID();
+ go->SetGoState(m_iCellblockRandom == CELLBLOCK_THE_HOLE ? GO_STATE_ACTIVE : GO_STATE_READY);
+ break;
+ case GO_GATE_D_BLOCK:
+ m_gateDBlockGUID = go->GetGUID();
+ go->SetGoState(m_iCellblockRandom == CELLBLOCK_D_BLOCK ? GO_STATE_ACTIVE : GO_STATE_READY);
+ break;
+ case GO_CURSED_DEPTHS_GATE:
+ m_gateCursedDepthsGUID = go->GetGUID();
+ go->SetGoState(m_iCellblockRandom == CELLBLOCK_CURSED_DEPTHS ? GO_STATE_ACTIVE : GO_STATE_READY);
+ break;
+ case GO_CRATE_OF_CELLBLOCK_RATIONS:
+ case GO_CURSED_SHACKLES:
+ case GO_DUSTY_PRISON_JOURNAL:
+ case GO_TB_MEETING_STONE:
+ case GO_TB_INSTANCE_VISUAL_1:
+ case GO_TB_INSTANCE_VISUAL_2:
+ case GO_TB_INSTANCE_VISUAL_3:
+ case GO_TB_INSTANCE_VISUAL_4:
+ BattleInactiveGOs.insert(go->GetGUID());
+ if (GetState() == BATTLEFIELD_WARMUP) // If battle is about to start, we must hide these.
+ go->SetRespawnTime(RESPAWN_ONE_DAY);
+ break;
+ default:
+ break;
+ }
+};
+
+void BattlefieldTB::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* /*invoker*/)
+{
+ if (!IsWarTime())
+ return;
+
+ if (eventId == EVENT_COUNT_CAPTURED_BASE)
+ {
+ UpdateCapturedBaseCount();
+ return;
+ }
+
+ if (!obj)
+ return;
+
+ GameObject* go = obj->ToGameObject();
+ if (!go)
+ return;
+
+ TBTowerId towerId;
+ switch (go->GetEntry())
+ {
+ case GO_WEST_SPIRE:
+ towerId = TB_TOWER_WEST_SPIRE;
+ break;
+ case GO_EAST_SPIRE:
+ towerId = TB_TOWER_EAST_SPIRE;
+ break;
+ case GO_SOUTH_SPIRE:
+ towerId = TB_TOWER_SOUTH_SPIRE;
+ break;
+ default:
+ return;
+ }
+
+ if (go->GetDestructibleState() == GO_DESTRUCTIBLE_DAMAGED)
+ TowerDamaged(towerId);
+ else if (go->GetDestructibleState() == GO_DESTRUCTIBLE_DESTROYED)
+ TowerDestroyed(towerId);
+}
+
+void BattlefieldTB::TowerDamaged(TBTowerId tbTowerId)
+{
+ if (!IsWarTime())
+ return;
+
+ SendWarning(TBTowers[tbTowerId].textDamaged);
+
+ SetData(BATTLEFIELD_TB_DATA_TOWERS_INTACT, GetData(BATTLEFIELD_TB_DATA_TOWERS_INTACT) - 1);
+
+ SendUpdateWorldState(uint32(TBTowers[tbTowerId].wsIntact[GetDefenderTeam()]), int32(0));
+ SendUpdateWorldState(uint32(TBTowers[tbTowerId].wsDamaged[GetDefenderTeam()]), int32(1));
+
+ TeamCastSpell(GetAttackerTeam(), SPELL_REWARD_TOWER_DAMAGED);
+}
+
+void BattlefieldTB::TowerDestroyed(TBTowerId tbTowerId)
+{
+ if (!IsWarTime())
+ return;
+
+ // Add 5 minute bonus time
+ m_Timer += m_BonusTime;
+
+ SendUpdateWorldState(WS_BATTLEFIELD_TB_TIME_BATTLE_END, uint32(GameTime::GetGameTime() + (m_Timer / 1000)));
+
+ SendWarning(TBTowers[tbTowerId].textDamaged);
+
+ SetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED, GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED) + 1);
+ SendUpdateWorldState(uint32(WS_BATTLEFIELD_TB_TOWERS_DESTROYED), int32(GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED)));
+
+ SendUpdateWorldState(uint32(TBTowers[tbTowerId].wsDamaged[GetDefenderTeam()]), int32(0));
+ SendUpdateWorldState(uint32(TBTowers[tbTowerId].wsDestroyed), int32(1));
+
+ // Attack bonus buff
+ for (ObjectGuid const& guid : m_PlayersInWar[GetAttackerTeam()])
+ if (Player* player = ObjectAccessor::FindPlayer(guid))
+ player->CastSpell(player, SPELL_TOWER_ATTACK_BONUS, CastSpellExtraArgs(TRIGGERED_FULL_MASK).AddSpellMod(SPELLVALUE_AURA_STACK, GetData(BATTLEFIELD_TB_DATA_TOWERS_DESTROYED)));
+
+ // Honor reward
+ TeamCastSpell(GetAttackerTeam(), SPELL_REWARD_TOWER_DESTROYED);
+}
+
+void BattlefieldTB::UpdateCapturedBaseCount()
+{
+ uint32 numCapturedBases = 0; // How many bases attacker has captured
+
+ for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
+ if (itr->second->GetTeamId() == GetAttackerTeam())
+ numCapturedBases += 1;
+
+ SetData(BATTLEFIELD_TB_DATA_BUILDINGS_CAPTURED, numCapturedBases);
+ SendUpdateWorldState(WS_BATTLEFIELD_TB_BUILDINGS_CAPTURED, uint32(numCapturedBases));
+
+ // Check if attackers won
+ if (numCapturedBases == TB_BASE_COUNT)
+ EndBattle(false);
+}
+
+// Called when player kill a unit in wg zone
+void BattlefieldTB::HandleKill(Player* killer, Unit* victim)
+{
+ if (killer == victim || victim->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ TeamId killerTeam = killer->GetTeamId();
+ for (ObjectGuid const& guid : m_PlayersInWar[killerTeam])
+ if (Player* player = ObjectAccessor::FindPlayer(guid))
+ if (player->GetDistance2d(killer) < 40.0f)
+ PromotePlayer(player);
+}
+
+void BattlefieldTB::PromotePlayer(Player* killer)
+{
+ if (!m_isActive || killer->HasAura(SPELL_TB_VETERAN))
+ return;
+
+ killer->CastSpell(killer, SPELL_TB_VETERAN, true);
+}
+
+TolBaradCapturePoint::TolBaradCapturePoint(BattlefieldTB* battlefield, TeamId teamInControl) : BfCapturePoint(battlefield)
+{
+ m_Bf = battlefield;
+ m_team = teamInControl;
+ m_value = teamInControl == TEAM_ALLIANCE ? m_maxValue : -m_maxValue;
+ m_State = teamInControl == TEAM_ALLIANCE ? BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE : BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE;
+}
+
+void TolBaradCapturePoint::ChangeTeam(TeamId /*oldTeam*/)
+{
+ // Find out index
+ uint8 iBase = TB_BASE_COUNT;
+ for (uint8 i = 0; i < TB_BASE_COUNT; i++)
+ if (GetCapturePointEntry() == TBCapturePoints[i].entryFlagPole[m_Bf->GetDefenderTeam()])
+ iBase = i;
+
+ if (iBase == TB_BASE_COUNT)
+ return;
+
+ // Turn off previous world state icon
+ switch (m_OldState)
+ {
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE:
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE:
+ SendUpdateWorldState(TBCapturePoints[iBase].wsControlled[GetTeamId()], uint32(0));
+ break;
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
+ SendUpdateWorldState(TBCapturePoints[iBase].wsCapturing[TEAM_ALLIANCE], uint32(0));
+ break;
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
+ SendUpdateWorldState(TBCapturePoints[iBase].wsCapturing[TEAM_HORDE], uint32(0));
+ break;
+ default:
+ break;
+ }
+
+ // Turn on new world state icon and send warning
+ switch (m_State)
+ {
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE:
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE:
+ m_Bf->SendWarning(TBCapturePoints[iBase].textGained[GetTeamId()]);
+ SendUpdateWorldState(TBCapturePoints[iBase].wsControlled[GetTeamId()], uint32(1));
+ GetCapturePointGo()->SetGoArtKit(GetTeamId() == TEAM_ALLIANCE ? TB_GO_ARTKIT_FLAG_ALLIANCE : TB_GO_ARTKIT_FLAG_HORDE);
+ break;
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
+ m_Bf->SendWarning(TBCapturePoints[iBase].textLost[TEAM_HORDE]);
+ /* fallthrough */
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
+ SendUpdateWorldState(TBCapturePoints[iBase].wsCapturing[TEAM_ALLIANCE], uint32(1));
+ GetCapturePointGo()->SetGoArtKit(TB_GO_ARTKIT_FLAG_NONE);
+ break;
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
+ m_Bf->SendWarning(TBCapturePoints[iBase].textLost[TEAM_ALLIANCE]);
+ /* fallthrough */
+ case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
+ SendUpdateWorldState(TBCapturePoints[iBase].wsCapturing[TEAM_HORDE], uint32(1));
+ GetCapturePointGo()->SetGoArtKit(TB_GO_ARTKIT_FLAG_NONE);
+ break;
+ default:
+ break;
+ }
+
+ // Update counter
+ m_Bf->ProcessEvent(nullptr, EVENT_COUNT_CAPTURED_BASE, nullptr);
+}
+
+class Battlefield_tol_barad : public BattlefieldScript
+{
+public:
+ Battlefield_tol_barad() : BattlefieldScript("battlefield_tb") { }
+
+ Battlefield* GetBattlefield() const override
+ {
+ return new BattlefieldTB();
+ }
+};
+
+void AddSC_BF_tol_barad()
+{
+ new Battlefield_tol_barad();
+}