1008 lines
49 KiB
C#
1008 lines
49 KiB
C#
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
|
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
|
|
|
using Framework.Constants;
|
|
using Game.Entities;
|
|
using Game.Networking.Packets;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Game.BattleGrounds.Zones
|
|
{
|
|
class BgArathiBasin : Battleground
|
|
{
|
|
public BgArathiBasin(BattlegroundTemplate battlegroundTemplate) : base(battlegroundTemplate)
|
|
{
|
|
m_IsInformedNearVictory = false;
|
|
BgObjects = new ObjectGuid[ABObjectTypes.Max];
|
|
BgCreatures = new ObjectGuid[ABBattlegroundNodes.AllCount + 5];//+5 for aura triggers
|
|
|
|
for (byte i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
{
|
|
m_Nodes[i] = 0;
|
|
m_prevNodes[i] = 0;
|
|
m_NodeTimers[i] = 0;
|
|
m_BannerTimers[i].timer = 0;
|
|
m_BannerTimers[i].type = 0;
|
|
m_BannerTimers[i].teamIndex = 0;
|
|
}
|
|
|
|
for (byte i = 0; i < SharedConst.PvpTeamsCount; ++i)
|
|
{
|
|
m_lastTick[i] = 0;
|
|
m_HonorScoreTics[i] = 0;
|
|
m_ReputationScoreTics[i] = 0;
|
|
}
|
|
|
|
m_HonorTics = 0;
|
|
m_ReputationTics = 0;
|
|
}
|
|
|
|
public override void PostUpdateImpl(uint diff)
|
|
{
|
|
if (GetStatus() == BattlegroundStatus.InProgress)
|
|
{
|
|
int[] team_points = { 0, 0 };
|
|
|
|
for (byte node = 0; node < ABBattlegroundNodes.DynamicNodesCount; ++node)
|
|
{
|
|
// 3 sec delay to spawn new banner instead previous despawned one
|
|
if (m_BannerTimers[node].timer != 0)
|
|
{
|
|
if (m_BannerTimers[node].timer > diff)
|
|
m_BannerTimers[node].timer -= diff;
|
|
else
|
|
{
|
|
m_BannerTimers[node].timer = 0;
|
|
_CreateBanner(node, (ABNodeStatus)m_BannerTimers[node].type, m_BannerTimers[node].teamIndex, false);
|
|
}
|
|
}
|
|
|
|
// 1-minute to occupy a node from contested state
|
|
if (m_NodeTimers[node] != 0)
|
|
{
|
|
if (m_NodeTimers[node] > diff)
|
|
m_NodeTimers[node] -= diff;
|
|
else
|
|
{
|
|
m_NodeTimers[node] = 0;
|
|
// Change from contested to occupied !
|
|
int teamIndex = (int)m_Nodes[node] - 1;
|
|
m_prevNodes[node] = m_Nodes[node];
|
|
m_Nodes[node] += 2;
|
|
// burn current contested banner
|
|
_DelBanner(node, ABNodeStatus.Contested, (byte)teamIndex);
|
|
// create new occupied banner
|
|
_CreateBanner(node, ABNodeStatus.Occupied, teamIndex, true);
|
|
_SendNodeUpdate(node);
|
|
_NodeOccupied(node, (teamIndex == TeamId.Alliance) ? Team.Alliance : Team.Horde);
|
|
// Message to chatlog
|
|
|
|
if (teamIndex == 0)
|
|
{
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextAllianceTaken, ChatMsg.BgSystemAlliance);
|
|
PlaySoundToAll(SoundCapturedAlliance);
|
|
}
|
|
else
|
|
{
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextHordeTaken, ChatMsg.BgSystemHorde);
|
|
PlaySoundToAll(SoundCapturedHorde);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int team = 0; team < SharedConst.PvpTeamsCount; ++team)
|
|
if (m_Nodes[node] == team + ABNodeStatus.Occupied)
|
|
++team_points[team];
|
|
}
|
|
|
|
// Accumulate points
|
|
for (int team = 0; team < SharedConst.PvpTeamsCount; ++team)
|
|
{
|
|
int points = team_points[team];
|
|
if (points == 0)
|
|
continue;
|
|
|
|
m_lastTick[team] += diff;
|
|
|
|
if (m_lastTick[team] > TickIntervals[points])
|
|
{
|
|
m_lastTick[team] -= TickIntervals[points];
|
|
m_TeamScores[team] += TickPoints[points];
|
|
m_HonorScoreTics[team] += TickPoints[points];
|
|
m_ReputationScoreTics[team] += TickPoints[points];
|
|
|
|
if (m_ReputationScoreTics[team] >= m_ReputationTics)
|
|
{
|
|
if (team == TeamId.Alliance)
|
|
RewardReputationToTeam(509, 10, Team.Alliance);
|
|
else
|
|
RewardReputationToTeam(510, 10, Team.Horde);
|
|
|
|
m_ReputationScoreTics[team] -= m_ReputationTics;
|
|
}
|
|
|
|
if (m_HonorScoreTics[team] >= m_HonorTics)
|
|
{
|
|
RewardHonorToTeam(GetBonusHonorFromKill(1), (team == TeamId.Alliance) ? Team.Alliance : Team.Horde);
|
|
m_HonorScoreTics[team] -= m_HonorTics;
|
|
}
|
|
|
|
if (!m_IsInformedNearVictory && m_TeamScores[team] > WarningNearVictoryScore)
|
|
{
|
|
if (team == TeamId.Alliance)
|
|
{
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.AllianceNearVictory, ChatMsg.BgSystemNeutral);
|
|
PlaySoundToAll(SoundNearVictoryAlliance);
|
|
}
|
|
else
|
|
{
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.HordeNearVictory, ChatMsg.BgSystemNeutral);
|
|
PlaySoundToAll(SoundNearVictoryHorde);
|
|
}
|
|
m_IsInformedNearVictory = true;
|
|
}
|
|
|
|
if (m_TeamScores[team] > MaxTeamScore)
|
|
m_TeamScores[team] = MaxTeamScore;
|
|
|
|
if (team == TeamId.Alliance)
|
|
UpdateWorldState(ABWorldStates.ResourcesAlly, (int)m_TeamScores[team]);
|
|
else
|
|
UpdateWorldState(ABWorldStates.ResourcesHorde, (int)m_TeamScores[team]);
|
|
// update achievement flags
|
|
// we increased m_TeamScores[team] so we just need to check if it is 500 more than other teams resources
|
|
int otherTeam = (team + 1) % SharedConst.PvpTeamsCount;
|
|
if (m_TeamScores[team] > m_TeamScores[otherTeam] + 500)
|
|
{
|
|
if (team == TeamId.Alliance)
|
|
UpdateWorldState(ABWorldStates.Had500DisadvantageHorde, 1);
|
|
else
|
|
UpdateWorldState(ABWorldStates.Had500DisadvantageAlliance, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test win condition
|
|
if (m_TeamScores[TeamId.Alliance] >= MaxTeamScore)
|
|
EndBattleground(Team.Alliance);
|
|
else if (m_TeamScores[TeamId.Horde] >= MaxTeamScore)
|
|
EndBattleground(Team.Horde);
|
|
}
|
|
}
|
|
|
|
public override void StartingEventCloseDoors()
|
|
{
|
|
// despawn banners, auras and buffs
|
|
for (int obj = ABObjectTypes.BannerNeutral; obj < ABBattlegroundNodes.DynamicNodesCount * 8; ++obj)
|
|
SpawnBGObject(obj, BattlegroundConst.RespawnOneDay);
|
|
for (int i = 0; i < ABBattlegroundNodes.DynamicNodesCount * 3; ++i)
|
|
SpawnBGObject(ABObjectTypes.SpeedbuffStables + i, BattlegroundConst.RespawnOneDay);
|
|
|
|
// Starting doors
|
|
DoorClose(ABObjectTypes.GateA);
|
|
DoorClose(ABObjectTypes.GateH);
|
|
SpawnBGObject(ABObjectTypes.GateA, BattlegroundConst.RespawnImmediately);
|
|
SpawnBGObject(ABObjectTypes.GateH, BattlegroundConst.RespawnImmediately);
|
|
|
|
// Starting base spirit guides
|
|
_NodeOccupied(ABBattlegroundNodes.SpiritAliance, Team.Alliance);
|
|
_NodeOccupied(ABBattlegroundNodes.SpiritHorde, Team.Horde);
|
|
}
|
|
|
|
public override void StartingEventOpenDoors()
|
|
{
|
|
// spawn neutral banners
|
|
for (int banner = ABObjectTypes.BannerNeutral, i = 0; i < 5; banner += 8, ++i)
|
|
SpawnBGObject(banner, BattlegroundConst.RespawnImmediately);
|
|
for (int i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
{
|
|
//randomly select buff to spawn
|
|
int buff = RandomHelper.IRand(0, 2);
|
|
SpawnBGObject(ABObjectTypes.SpeedbuffStables + buff + i * 3, BattlegroundConst.RespawnImmediately);
|
|
}
|
|
DoorOpen(ABObjectTypes.GateA);
|
|
DoorOpen(ABObjectTypes.GateH);
|
|
|
|
// Achievement: Let's Get This Done
|
|
TriggerGameEvent(EventStartBattle);
|
|
}
|
|
|
|
public override void AddPlayer(Player player, BattlegroundQueueTypeId queueId)
|
|
{
|
|
bool isInBattleground = IsPlayerInBattleground(player.GetGUID());
|
|
base.AddPlayer(player, queueId);
|
|
if (!isInBattleground)
|
|
PlayerScores[player.GetGUID()] = new BattlegroundABScore(player.GetGUID(), player.GetBGTeam());
|
|
}
|
|
|
|
public override void RemovePlayer(Player Player, ObjectGuid guid, Team team)
|
|
{
|
|
}
|
|
|
|
public override void HandleAreaTrigger(Player player, uint trigger, bool entered)
|
|
{
|
|
switch (trigger)
|
|
{
|
|
case 6635: // Horde Start
|
|
case 6634: // Alliance Start
|
|
if (GetStatus() == BattlegroundStatus.WaitJoin && !entered)
|
|
TeleportPlayerToExploitLocation(player);
|
|
break;
|
|
case 3948: // Arathi Basin Alliance Exit.
|
|
case 3949: // Arathi Basin Horde Exit.
|
|
case 3866: // Stables
|
|
case 3869: // Gold Mine
|
|
case 3867: // Farm
|
|
case 3868: // Lumber Mill
|
|
case 3870: // Black Smith
|
|
case 4020: // Unk1
|
|
case 4021: // Unk2
|
|
case 4674: // Unk3
|
|
default:
|
|
base.HandleAreaTrigger(player, trigger, entered);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void _CreateBanner(byte node, ABNodeStatus type, int teamIndex, bool delay)
|
|
{
|
|
// Just put it into the queue
|
|
if (delay)
|
|
{
|
|
m_BannerTimers[node].timer = 2000;
|
|
m_BannerTimers[node].type = (byte)type;
|
|
m_BannerTimers[node].teamIndex = (byte)teamIndex;
|
|
return;
|
|
}
|
|
|
|
int obj = node * 8 + (byte)type + teamIndex;
|
|
|
|
SpawnBGObject(obj, BattlegroundConst.RespawnImmediately);
|
|
|
|
// handle aura with banner
|
|
if (type == 0)
|
|
return;
|
|
obj = node * 8 + ((type == ABNodeStatus.Occupied) ? (5 + teamIndex) : 7);
|
|
SpawnBGObject(obj, BattlegroundConst.RespawnImmediately);
|
|
}
|
|
|
|
void _DelBanner(byte node, ABNodeStatus type, byte teamIndex)
|
|
{
|
|
int obj = node * 8 + (byte)type + teamIndex;
|
|
SpawnBGObject(obj, BattlegroundConst.RespawnOneDay);
|
|
|
|
// handle aura with banner
|
|
if (type == 0)
|
|
return;
|
|
obj = node * 8 + ((type == ABNodeStatus.Occupied) ? (5 + teamIndex) : 7);
|
|
SpawnBGObject(obj, BattlegroundConst.RespawnOneDay);
|
|
}
|
|
|
|
void _SendNodeUpdate(byte node)
|
|
{
|
|
// Send node owner state update to refresh map icons on client
|
|
int[] idPlusArray = { 0, 2, 3, 0, 1 };
|
|
int[] statePlusArray = { 0, 2, 0, 2, 0 };
|
|
|
|
if (m_prevNodes[node] != 0)
|
|
UpdateWorldState(NodeStates[node] + idPlusArray[(int)m_prevNodes[node]], 0);
|
|
else
|
|
UpdateWorldState(NodeIcons[node], 0);
|
|
|
|
UpdateWorldState(NodeStates[node] + idPlusArray[(byte)m_Nodes[node]], 1);
|
|
|
|
switch (node)
|
|
{
|
|
case ABBattlegroundNodes.NodeStables:
|
|
UpdateWorldState(ABWorldStates.StablesIconNew, (int)m_Nodes[node] + statePlusArray[(int)m_Nodes[node]]);
|
|
UpdateWorldState(ABWorldStates.StablesHordeControlState, m_Nodes[node] == ABNodeStatus.HordeOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.HordeContested ? 1 : 0));
|
|
UpdateWorldState(ABWorldStates.StablesAllianceControlState, m_Nodes[node] == ABNodeStatus.AllyOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.AllyContested ? 1 : 0));
|
|
break;
|
|
case ABBattlegroundNodes.NodeBlacksmith:
|
|
UpdateWorldState(ABWorldStates.BlacksmithIconNew, (int)m_Nodes[node] + statePlusArray[(int)m_Nodes[node]]);
|
|
UpdateWorldState(ABWorldStates.BlacksmithHordeControlState, m_Nodes[node] == ABNodeStatus.HordeOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.HordeContested ? 1 : 0));
|
|
UpdateWorldState(ABWorldStates.BlacksmithAllianceControlState, m_Nodes[node] == ABNodeStatus.AllyOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.AllyContested ? 1 : 0));
|
|
break;
|
|
case ABBattlegroundNodes.NodeFarm:
|
|
UpdateWorldState(ABWorldStates.FarmIconNew, (int)m_Nodes[node] + statePlusArray[(int)m_Nodes[node]]);
|
|
UpdateWorldState(ABWorldStates.FarmHordeControlState, m_Nodes[node] == ABNodeStatus.HordeOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.HordeContested ? 1 : 0));
|
|
UpdateWorldState(ABWorldStates.FarmAllianceControlState, m_Nodes[node] == ABNodeStatus.AllyOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.AllyContested ? 1 : 0));
|
|
break;
|
|
case ABBattlegroundNodes.NodeLumberMill:
|
|
UpdateWorldState(ABWorldStates.LumberMillIconNew, (int)m_Nodes[node] + statePlusArray[(int)m_Nodes[node]]);
|
|
UpdateWorldState(ABWorldStates.LumberMillHordeControlState, m_Nodes[node] == ABNodeStatus.HordeOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.HordeContested ? 1 : 0));
|
|
UpdateWorldState(ABWorldStates.LumberMillAllianceControlState, m_Nodes[node] == ABNodeStatus.AllyOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.AllyContested ? 1 : 0));
|
|
break;
|
|
case ABBattlegroundNodes.NodeGoldMine:
|
|
UpdateWorldState(ABWorldStates.GoldMineIconNew, (int)m_Nodes[node] + statePlusArray[(int)m_Nodes[node]]);
|
|
UpdateWorldState(ABWorldStates.GoldMineHordeControlState, m_Nodes[node] == ABNodeStatus.HordeOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.HordeContested ? 1 : 0));
|
|
UpdateWorldState(ABWorldStates.GoldMineAllianceControlState, m_Nodes[node] == ABNodeStatus.AllyOccupied ? 2 : (m_Nodes[node] == ABNodeStatus.AllyContested ? 1 : 0));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// How many bases each team owns
|
|
byte ally = 0, horde = 0;
|
|
for (byte i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
if (m_Nodes[i] == ABNodeStatus.AllyOccupied)
|
|
++ally;
|
|
else if (m_Nodes[i] == ABNodeStatus.HordeOccupied)
|
|
++horde;
|
|
|
|
UpdateWorldState(ABWorldStates.OccupiedBasesAlly, ally);
|
|
UpdateWorldState(ABWorldStates.OccupiedBasesHorde, horde);
|
|
}
|
|
|
|
void _NodeOccupied(byte node, Team team)
|
|
{
|
|
if (!AddSpiritGuide(node, SpiritGuidePos[node], GetTeamIndexByTeamId(team)))
|
|
Log.outError(LogFilter.Battleground, "Failed to spawn spirit guide! point: {0}, team: {1}, ", node, team);
|
|
|
|
if (node >= ABBattlegroundNodes.DynamicNodesCount)//only dynamic nodes, no start points
|
|
return;
|
|
|
|
byte capturedNodes = 0;
|
|
for (byte i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
if (m_Nodes[i] == ABNodeStatus.Occupied + GetTeamIndexByTeamId(team) && m_NodeTimers[i] == 0)
|
|
++capturedNodes;
|
|
|
|
if (capturedNodes >= 5)
|
|
CastSpellOnTeam(BattlegroundConst.AbQuestReward5Bases, team);
|
|
if (capturedNodes >= 4)
|
|
CastSpellOnTeam(BattlegroundConst.AbQuestReward4Bases, team);
|
|
|
|
Creature trigger = !BgCreatures[node + 7].IsEmpty() ? GetBGCreature(node + 7) : null; // 0-6 spirit guides
|
|
if (trigger == null)
|
|
trigger = AddCreature(SharedConst.WorldTrigger, node + 7, NodePositions[node], GetTeamIndexByTeamId(team));
|
|
|
|
//add bonus honor aura trigger creature when node is accupied
|
|
//cast bonus aura (+50% honor in 25yards)
|
|
//aura should only apply to players who have accupied the node, set correct faction for trigger
|
|
if (trigger != null)
|
|
{
|
|
trigger.SetFaction(team == Team.Alliance ? 84u : 83u);
|
|
trigger.CastSpell(trigger, BattlegroundConst.SpellHonorableDefender25y, false);
|
|
}
|
|
}
|
|
|
|
void _NodeDeOccupied(byte node)
|
|
{
|
|
//only dynamic nodes, no start points
|
|
if (node >= ABBattlegroundNodes.DynamicNodesCount)
|
|
return;
|
|
|
|
//remove bonus honor aura trigger creature when node is lost
|
|
DelCreature(node + 7);//null checks are in DelCreature! 0-6 spirit guides
|
|
|
|
DelCreature(node);
|
|
|
|
// buff object isn't despawned
|
|
}
|
|
|
|
//Invoked if a player used a banner as a gameobject
|
|
public override void EventPlayerClickedOnFlag(Player source, GameObject target_obj)
|
|
{
|
|
if (GetStatus() != BattlegroundStatus.InProgress)
|
|
return;
|
|
|
|
byte node = ABBattlegroundNodes.NodeStables;
|
|
GameObject obj = GetBgMap().GetGameObject(BgObjects[node * 8 + 7]);
|
|
while ((node < ABBattlegroundNodes.DynamicNodesCount) && ((obj == null) || (!source.IsWithinDistInMap(obj, 10))))
|
|
{
|
|
++node;
|
|
obj = GetBgMap().GetGameObject(BgObjects[node * 8 + ABObjectTypes.AuraContested]);
|
|
}
|
|
|
|
if (node == ABBattlegroundNodes.DynamicNodesCount)
|
|
{
|
|
// this means our player isn't close to any of banners - maybe cheater ??
|
|
return;
|
|
}
|
|
|
|
int teamIndex = GetTeamIndexByTeamId(GetPlayerTeam(source.GetGUID()));
|
|
|
|
// Check if player really could use this banner, not cheated
|
|
if (!(m_Nodes[node] == 0 || teamIndex == (int)m_Nodes[node] % 2))
|
|
return;
|
|
|
|
source.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
|
uint sound;
|
|
// If node is neutral, change to contested
|
|
if (m_Nodes[node] == ABNodeStatus.Neutral)
|
|
{
|
|
UpdatePlayerScore(source, ScoreType.BasesAssaulted, 1);
|
|
m_prevNodes[node] = m_Nodes[node];
|
|
m_Nodes[node] = (ABNodeStatus)(teamIndex + 1);
|
|
// burn current neutral banner
|
|
_DelBanner(node, ABNodeStatus.Neutral, 0);
|
|
// create new contested banner
|
|
_CreateBanner(node, ABNodeStatus.Contested, (byte)teamIndex, true);
|
|
_SendNodeUpdate(node);
|
|
m_NodeTimers[node] = FlagCapturingTime;
|
|
|
|
// FIXME: team and node names not localized
|
|
if (teamIndex == TeamId.Alliance)
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextAllianceClaims, ChatMsg.BgSystemAlliance, source);
|
|
else
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextHordeClaims, ChatMsg.BgSystemHorde, source);
|
|
|
|
sound = SoundClaimed;
|
|
}
|
|
// If node is contested
|
|
else if ((m_Nodes[node] == ABNodeStatus.AllyContested) || (m_Nodes[node] == ABNodeStatus.HordeContested))
|
|
{
|
|
// If last state is NOT occupied, change node to enemy-contested
|
|
if (m_prevNodes[node] < ABNodeStatus.Occupied)
|
|
{
|
|
UpdatePlayerScore(source, ScoreType.BasesAssaulted, 1);
|
|
m_prevNodes[node] = m_Nodes[node];
|
|
m_Nodes[node] = (ABNodeStatus.Contested + teamIndex);
|
|
// burn current contested banner
|
|
_DelBanner(node, ABNodeStatus.Contested, (byte)teamIndex);
|
|
// create new contested banner
|
|
_CreateBanner(node, ABNodeStatus.Contested, (byte)teamIndex, true);
|
|
_SendNodeUpdate(node);
|
|
m_NodeTimers[node] = FlagCapturingTime;
|
|
|
|
if (teamIndex == TeamId.Alliance)
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextAllianceAssaulted, ChatMsg.BgSystemAlliance, source);
|
|
else
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextHordeAssaulted, ChatMsg.BgSystemHorde, source);
|
|
}
|
|
// If contested, change back to occupied
|
|
else
|
|
{
|
|
UpdatePlayerScore(source, ScoreType.BasesDefended, 1);
|
|
m_prevNodes[node] = m_Nodes[node];
|
|
m_Nodes[node] = (ABNodeStatus.Occupied + teamIndex);
|
|
// burn current contested banner
|
|
_DelBanner(node, ABNodeStatus.Contested, (byte)teamIndex);
|
|
// create new occupied banner
|
|
_CreateBanner(node, ABNodeStatus.Occupied, (byte)teamIndex, true);
|
|
_SendNodeUpdate(node);
|
|
m_NodeTimers[node] = 0;
|
|
_NodeOccupied(node, (teamIndex == TeamId.Alliance) ? Team.Alliance : Team.Horde);
|
|
|
|
if (teamIndex == TeamId.Alliance)
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextAllianceDefended, ChatMsg.BgSystemAlliance, source);
|
|
else
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextHordeDefended, ChatMsg.BgSystemHorde, source);
|
|
}
|
|
sound = (teamIndex == TeamId.Alliance) ? SoundAssaultedAlliance : SoundAssaultedHorde;
|
|
}
|
|
// If node is occupied, change to enemy-contested
|
|
else
|
|
{
|
|
UpdatePlayerScore(source, ScoreType.BasesAssaulted, 1);
|
|
m_prevNodes[node] = m_Nodes[node];
|
|
m_Nodes[node] = (ABNodeStatus.Contested + teamIndex);
|
|
// burn current occupied banner
|
|
_DelBanner(node, ABNodeStatus.Occupied, (byte)teamIndex);
|
|
// create new contested banner
|
|
_CreateBanner(node, ABNodeStatus.Contested, (byte)teamIndex, true);
|
|
_SendNodeUpdate(node);
|
|
_NodeDeOccupied(node);
|
|
m_NodeTimers[node] = FlagCapturingTime;
|
|
|
|
if (teamIndex == TeamId.Alliance)
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextAllianceAssaulted, ChatMsg.BgSystemAlliance, source);
|
|
else
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextHordeAssaulted, ChatMsg.BgSystemHorde, source);
|
|
|
|
sound = (teamIndex == TeamId.Alliance) ? SoundAssaultedAlliance : SoundAssaultedHorde;
|
|
}
|
|
|
|
// If node is occupied again, send "X has taken the Y" msg.
|
|
if (m_Nodes[node] >= ABNodeStatus.Occupied)
|
|
{
|
|
// FIXME: team and node names not localized
|
|
if (teamIndex == TeamId.Alliance)
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextAllianceTaken, ChatMsg.BgSystemAlliance);
|
|
else
|
|
SendBroadcastText(ABBattlegroundBroadcastTexts.ABNodes[node].TextHordeTaken, ChatMsg.BgSystemHorde);
|
|
}
|
|
PlaySoundToAll(sound);
|
|
}
|
|
|
|
public override Team GetPrematureWinner()
|
|
{
|
|
// How many bases each team owns
|
|
byte ally = 0, horde = 0;
|
|
for (byte i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
if (m_Nodes[i] == ABNodeStatus.AllyOccupied)
|
|
++ally;
|
|
else if (m_Nodes[i] == ABNodeStatus.HordeOccupied)
|
|
++horde;
|
|
|
|
if (ally > horde)
|
|
return Team.Alliance;
|
|
else if (horde > ally)
|
|
return Team.Horde;
|
|
|
|
// If the values are equal, fall back to the original result (based on number of players on each team)
|
|
return base.GetPrematureWinner();
|
|
}
|
|
|
|
public override bool SetupBattleground()
|
|
{
|
|
bool result = true;
|
|
for (int i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
{
|
|
result &= AddObject(ABObjectTypes.BannerNeutral + 8 * i, (uint)(NodeObjectId.Banner0 + i), NodePositions[i], 0, 0, (float)Math.Sin(NodePositions[i].GetOrientation() / 2), (float)Math.Cos(NodePositions[i].GetOrientation() / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.BannerContA + 8 * i, ABObjectIds.BannerContA, NodePositions[i], 0, 0, (float)Math.Sin(NodePositions[i].GetOrientation() / 2), (float)Math.Cos(NodePositions[i].GetOrientation() / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.BannerContH + 8 * i, ABObjectIds.BannerContH, NodePositions[i], 0, 0, (float)Math.Sin(NodePositions[i].GetOrientation() / 2), (float)Math.Cos(NodePositions[i].GetOrientation() / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.BannerAlly + 8 * i, ABObjectIds.BannerA, NodePositions[i], 0, 0, (float)Math.Sin(NodePositions[i].GetOrientation() / 2), (float)Math.Cos(NodePositions[i].GetOrientation() / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.BannerHorde + 8 * i, ABObjectIds.BannerH, NodePositions[i], 0, 0, (float)Math.Sin(NodePositions[i].GetOrientation() / 2), (float)Math.Cos(NodePositions[i].GetOrientation() / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.AuraAlly + 8 * i, ABObjectIds.AuraA, NodePositions[i], 0, 0, (float)Math.Sin(NodePositions[i].GetOrientation() / 2), (float)Math.Cos(NodePositions[i].GetOrientation() / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.AuraHorde + 8 * i, ABObjectIds.AuraH, NodePositions[i], 0, 0, (float)Math.Sin(NodePositions[i].GetOrientation() / 2), (float)Math.Cos(NodePositions[i].GetOrientation() / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.AuraContested + 8 * i, ABObjectIds.AuraC, NodePositions[i], 0, 0, (float)Math.Sin(NodePositions[i].GetOrientation() / 2), (float)Math.Cos(NodePositions[i].GetOrientation() / 2), BattlegroundConst.RespawnOneDay);
|
|
if (!result)
|
|
{
|
|
Log.outError(LogFilter.Sql, "BatteGroundAB: Failed to spawn some object Battleground not created!");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
result &= AddObject(ABObjectTypes.GateA, ABObjectIds.GateA, DoorPositions[0][0], DoorPositions[0][1], DoorPositions[0][2], DoorPositions[0][3], DoorPositions[0][4], DoorPositions[0][5], DoorPositions[0][6], DoorPositions[0][7], BattlegroundConst.RespawnImmediately);
|
|
result &= AddObject(ABObjectTypes.GateH, ABObjectIds.GateH, DoorPositions[1][0], DoorPositions[1][1], DoorPositions[1][2], DoorPositions[1][3], DoorPositions[1][4], DoorPositions[1][5], DoorPositions[1][6], DoorPositions[1][7], BattlegroundConst.RespawnImmediately);
|
|
if (!result)
|
|
{
|
|
Log.outError(LogFilter.Sql, "BatteGroundAB: Failed to spawn door object Battleground not created!");
|
|
return false;
|
|
}
|
|
|
|
//buffs
|
|
for (int i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
{
|
|
result &= AddObject(ABObjectTypes.SpeedbuffStables + 3 * i, Buff_Entries[0], BuffPositions[i][0], BuffPositions[i][1], BuffPositions[i][2], BuffPositions[i][3], 0, 0, (float)Math.Sin(BuffPositions[i][3] / 2), (float)Math.Cos(BuffPositions[i][3] / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.SpeedbuffStables + 3 * i + 1, Buff_Entries[1], BuffPositions[i][0], BuffPositions[i][1], BuffPositions[i][2], BuffPositions[i][3], 0, 0, (float)Math.Sin(BuffPositions[i][3] / 2), (float)Math.Cos(BuffPositions[i][3] / 2), BattlegroundConst.RespawnOneDay);
|
|
result &= AddObject(ABObjectTypes.SpeedbuffStables + 3 * i + 2, Buff_Entries[2], BuffPositions[i][0], BuffPositions[i][1], BuffPositions[i][2], BuffPositions[i][3], 0, 0, (float)Math.Sin(BuffPositions[i][3] / 2), (float)Math.Cos(BuffPositions[i][3] / 2), BattlegroundConst.RespawnOneDay);
|
|
if (!result)
|
|
{
|
|
Log.outError(LogFilter.Sql, "BatteGroundAB: Failed to spawn buff object!");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
UpdateWorldState(ABWorldStates.ResourcesMax, MaxTeamScore);
|
|
UpdateWorldState(ABWorldStates.ResourcesWarning, WarningNearVictoryScore);
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void Reset()
|
|
{
|
|
//call parent's class reset
|
|
base.Reset();
|
|
|
|
for (var i = 0; i < SharedConst.PvpTeamsCount; ++i)
|
|
{
|
|
m_TeamScores[i] = 0;
|
|
m_lastTick[i] = 0;
|
|
m_HonorScoreTics[i] = 0;
|
|
m_ReputationScoreTics[i] = 0;
|
|
}
|
|
|
|
m_IsInformedNearVictory = false;
|
|
bool isBGWeekend = Global.BattlegroundMgr.IsBGWeekend(GetTypeID());
|
|
m_HonorTics = (isBGWeekend) ? ABBGWeekendHonorTicks : NotABBGWeekendHonorTicks;
|
|
m_ReputationTics = (isBGWeekend) ? ABBGWeekendReputationTicks : NotABBGWeekendReputationTicks;
|
|
|
|
for (byte i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
{
|
|
m_Nodes[i] = 0;
|
|
m_prevNodes[i] = 0;
|
|
m_NodeTimers[i] = 0;
|
|
m_BannerTimers[i].timer = 0;
|
|
}
|
|
}
|
|
|
|
public override void EndBattleground(Team winner)
|
|
{
|
|
// Win reward
|
|
if (winner == Team.Alliance)
|
|
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Alliance);
|
|
if (winner == Team.Horde)
|
|
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Horde);
|
|
// Complete map_end rewards (even if no team wins)
|
|
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Horde);
|
|
RewardHonorToTeam(GetBonusHonorFromKill(1), Team.Alliance);
|
|
|
|
base.EndBattleground(winner);
|
|
}
|
|
|
|
public override WorldSafeLocsEntry GetClosestGraveyard(Player player)
|
|
{
|
|
int teamIndex = GetTeamIndexByTeamId(GetPlayerTeam(player.GetGUID()));
|
|
|
|
// Is there any occupied node for this team?
|
|
List<byte> nodes = new();
|
|
for (byte i = 0; i < ABBattlegroundNodes.DynamicNodesCount; ++i)
|
|
if (m_Nodes[i] == ABNodeStatus.Occupied + teamIndex)
|
|
nodes.Add(i);
|
|
|
|
WorldSafeLocsEntry good_entry = null;
|
|
// If so, select the closest node to place ghost on
|
|
if (!nodes.Empty())
|
|
{
|
|
float plr_x = player.GetPositionX();
|
|
float plr_y = player.GetPositionY();
|
|
|
|
float mindist = 999999.0f;
|
|
for (byte i = 0; i < nodes.Count; ++i)
|
|
{
|
|
WorldSafeLocsEntry entry = Global.ObjectMgr.GetWorldSafeLoc(GraveyardIds[nodes[i]]);
|
|
if (entry == null)
|
|
continue;
|
|
float dist = (entry.Loc.GetPositionX() - plr_x) * (entry.Loc.GetPositionX() - plr_x) + (entry.Loc.GetPositionY() - plr_y) * (entry.Loc.GetPositionY() - plr_y);
|
|
if (mindist > dist)
|
|
{
|
|
mindist = dist;
|
|
good_entry = entry;
|
|
}
|
|
}
|
|
nodes.Clear();
|
|
}
|
|
// If not, place ghost on starting location
|
|
if (good_entry == null)
|
|
good_entry = Global.ObjectMgr.GetWorldSafeLoc(GraveyardIds[teamIndex + 5]);
|
|
|
|
return good_entry;
|
|
}
|
|
|
|
public override WorldSafeLocsEntry GetExploitTeleportLocation(Team team)
|
|
{
|
|
return Global.ObjectMgr.GetWorldSafeLoc(team == Team.Alliance ? ExploitTeleportLocationAlliance : ExploitTeleportLocationHorde);
|
|
}
|
|
|
|
public override bool UpdatePlayerScore(Player player, ScoreType type, uint value, bool doAddHonor = true)
|
|
{
|
|
if (!base.UpdatePlayerScore(player, type, value, doAddHonor))
|
|
return false;
|
|
|
|
switch (type)
|
|
{
|
|
case ScoreType.BasesAssaulted:
|
|
player.UpdateCriteria(CriteriaType.TrackedWorldStateUIModified, (uint)ABObjectives.AssaultBase);
|
|
break;
|
|
case ScoreType.BasesDefended:
|
|
player.UpdateCriteria(CriteriaType.TrackedWorldStateUIModified, (uint)ABObjectives.DefendBase);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Nodes info:
|
|
/// 0: neutral
|
|
/// 1: ally contested
|
|
/// 2: horde contested
|
|
/// 3: ally occupied
|
|
/// 4: horde occupied
|
|
/// </summary>
|
|
ABNodeStatus[] m_Nodes = new ABNodeStatus[ABBattlegroundNodes.DynamicNodesCount];
|
|
ABNodeStatus[] m_prevNodes = new ABNodeStatus[ABBattlegroundNodes.DynamicNodesCount];
|
|
BannerTimer[] m_BannerTimers = new BannerTimer[ABBattlegroundNodes.DynamicNodesCount];
|
|
uint[] m_NodeTimers = new uint[ABBattlegroundNodes.DynamicNodesCount];
|
|
uint[] m_lastTick = new uint[SharedConst.PvpTeamsCount];
|
|
uint[] m_HonorScoreTics = new uint[SharedConst.PvpTeamsCount];
|
|
uint[] m_ReputationScoreTics = new uint[SharedConst.PvpTeamsCount];
|
|
bool m_IsInformedNearVictory;
|
|
uint m_HonorTics;
|
|
uint m_ReputationTics;
|
|
|
|
//Const
|
|
public const uint NotABBGWeekendHonorTicks = 260;
|
|
public const uint ABBGWeekendHonorTicks = 160;
|
|
public const uint NotABBGWeekendReputationTicks = 160;
|
|
public const uint ABBGWeekendReputationTicks = 120;
|
|
|
|
public const int EventStartBattle = 9158;// Achievement: Let's Get This Done
|
|
|
|
public const int SoundClaimed = 8192;
|
|
public const int SoundCapturedAlliance = 8173;
|
|
public const int SoundCapturedHorde = 8213;
|
|
public const uint SoundAssaultedAlliance = 8212;
|
|
public const uint SoundAssaultedHorde = 8174;
|
|
public const int SoundNearVictoryAlliance = 8456;
|
|
public const int SoundNearVictoryHorde = 8457;
|
|
|
|
public const int FlagCapturingTime = 60000;
|
|
|
|
public const int WarningNearVictoryScore = 1400;
|
|
public const int MaxTeamScore = 1500;
|
|
|
|
public const uint ExploitTeleportLocationAlliance = 3705;
|
|
public const uint ExploitTeleportLocationHorde = 3706;
|
|
|
|
public static Position[] NodePositions =
|
|
{
|
|
new Position(1166.785f, 1200.132f, -56.70859f, 0.9075713f), // stables
|
|
new Position(977.0156f, 1046.616f, -44.80923f, -2.600541f), // blacksmith
|
|
new Position(806.1821f, 874.2723f, -55.99371f, -2.303835f), // farm
|
|
new Position(856.1419f, 1148.902f, 11.18469f, -2.303835f), // lumber mill
|
|
new Position(1146.923f, 848.1782f, -110.917f, -0.7330382f) // gold mine
|
|
};
|
|
|
|
// x, y, z, o, rot0, rot1, rot2, rot3
|
|
public static float[][] DoorPositions =
|
|
{
|
|
new float[] {1284.597f, 1281.167f, -15.97792f, 0.7068594f, 0.012957f, -0.060288f, 0.344959f, 0.93659f },
|
|
new float[] {708.0903f, 708.4479f, -17.8342f, -2.391099f, 0.050291f, 0.015127f, 0.929217f, -0.365784f}
|
|
};
|
|
|
|
// Tick intervals and given points: case 0, 1, 2, 3, 4, 5 captured nodes
|
|
public static uint[] TickIntervals = { 0, 12000, 9000, 6000, 3000, 1000 };
|
|
public static uint[] TickPoints = { 0, 10, 10, 10, 10, 30 };
|
|
|
|
// WorldSafeLocs ids for 5 nodes, and for ally, and horde starting location
|
|
public static uint[] GraveyardIds = { 895, 894, 893, 897, 896, 898, 899 };
|
|
|
|
// x, y, z, o
|
|
public static float[][] BuffPositions =
|
|
{
|
|
new float[] {1185.566f, 1184.629f, -56.36329f, 2.303831f }, // stables
|
|
new float[] {990.1131f, 1008.73f, -42.60328f, 0.8203033f }, // blacksmith
|
|
new float[] {818.0089f, 842.3543f, -56.54062f, 3.176533f }, // farm
|
|
new float[] {808.8463f, 1185.417f, 11.92161f, 5.619962f }, // lumber mill
|
|
new float[] {1147.091f, 816.8362f, -98.39896f, 6.056293f } // gold mine
|
|
};
|
|
|
|
public static Position[] SpiritGuidePos =
|
|
{
|
|
new Position(1200.03f, 1171.09f, -56.47f, 5.15f), // stables
|
|
new Position(1017.43f, 960.61f, -42.95f, 4.88f), // blacksmith
|
|
new Position(833.00f, 793.00f, -57.25f, 5.27f), // farm
|
|
new Position(775.17f, 1206.40f, 15.79f, 1.90f), // lumber mill
|
|
new Position(1207.48f, 787.00f, -83.36f, 5.51f), // gold mine
|
|
new Position(1354.05f, 1275.48f, -11.30f, 4.77f), // alliance starting base
|
|
new Position(714.61f, 646.15f, -10.87f, 4.34f) // horde starting base
|
|
};
|
|
|
|
public static int[] NodeStates = { 1767, 1782, 1772, 1792, 1787 };
|
|
|
|
public static int[] NodeIcons = { 1842, 1846, 1845, 1844, 1843 };
|
|
}
|
|
|
|
class BattlegroundABScore : BattlegroundScore
|
|
{
|
|
public BattlegroundABScore(ObjectGuid playerGuid, Team team) : base(playerGuid, team)
|
|
{
|
|
BasesAssaulted = 0;
|
|
BasesDefended = 0;
|
|
}
|
|
|
|
public override void UpdateScore(ScoreType type, uint value)
|
|
{
|
|
switch (type)
|
|
{
|
|
case ScoreType.BasesAssaulted:
|
|
BasesAssaulted += value;
|
|
break;
|
|
case ScoreType.BasesDefended:
|
|
BasesDefended += value;
|
|
break;
|
|
default:
|
|
base.UpdateScore(type, value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public override void BuildPvPLogPlayerDataPacket(out PVPMatchStatistics.PVPMatchPlayerStatistics playerData)
|
|
{
|
|
base.BuildPvPLogPlayerDataPacket(out playerData);
|
|
|
|
playerData.Stats.Add(new PVPMatchStatistics.PVPMatchPlayerPVPStat((int)ABObjectives.AssaultBase, BasesAssaulted));
|
|
playerData.Stats.Add(new PVPMatchStatistics.PVPMatchPlayerPVPStat((int)ABObjectives.DefendBase, BasesDefended));
|
|
}
|
|
|
|
public override uint GetAttr1() { return BasesAssaulted; }
|
|
public override uint GetAttr2() { return BasesDefended; }
|
|
|
|
uint BasesAssaulted;
|
|
uint BasesDefended;
|
|
}
|
|
|
|
struct BannerTimer
|
|
{
|
|
public uint timer;
|
|
public byte type;
|
|
public byte teamIndex;
|
|
}
|
|
|
|
#region Consts
|
|
struct ABWorldStates
|
|
{
|
|
public const int OccupiedBasesHorde = 1778;
|
|
public const int OccupiedBasesAlly = 1779;
|
|
public const int ResourcesAlly = 1776;
|
|
public const int ResourcesHorde = 1777;
|
|
public const int ResourcesMax = 1780;
|
|
public const int ResourcesWarning = 1955;
|
|
|
|
public const int StableIcon = 1842; // Stable Map Icon (None)
|
|
public const int StableStateAlience = 1767; // Stable Map State (Alience)
|
|
public const int StableStateHorde = 1768; // Stable Map State (Horde)
|
|
public const int StableStateConAli = 1769; // Stable Map State (Con Alience)
|
|
public const int StableStateConHor = 1770; // Stable Map State (Con Horde)
|
|
public const int FarmIcon = 1845; // Farm Map Icon (None)
|
|
public const int FarmStateAlience = 1772; // Farm State (Alience)
|
|
public const int FarmStateHorde = 1773; // Farm State (Horde)
|
|
public const int FarmStateConAli = 1774; // Farm State (Con Alience)
|
|
public const int FarmStateConHor = 1775; // Farm State (Con Horde)
|
|
public const int BlacksmithIcon = 1846; // Blacksmith Map Icon (None)
|
|
public const int BlacksmithStateAlience = 1782; // Blacksmith Map State (Alience)
|
|
public const int BlacksmithStateHorde = 1783; // Blacksmith Map State (Horde)
|
|
public const int BlacksmithStateConAli = 1784; // Blacksmith Map State (Con Alience)
|
|
public const int BlacksmithStateConHor = 1785; // Blacksmith Map State (Con Horde)
|
|
public const int LumbermillIcon = 1844; // Lumber Mill Map Icon (None)
|
|
public const int LumbermillStateAlience = 1792; // Lumber Mill Map State (Alience)
|
|
public const int LumbermillStateHorde = 1793; // Lumber Mill Map State (Horde)
|
|
public const int LumbermillStateConAli = 1794; // Lumber Mill Map State (Con Alience)
|
|
public const int LumbermillStateConHor = 1795; // Lumber Mill Map State (Con Horde)
|
|
public const int GoldmineIcon = 1843; // Gold Mine Map Icon (None)
|
|
public const int GoldmineStateAlience = 1787; // Gold Mine Map State (Alience)
|
|
public const int GoldmineStateHorde = 1788; // Gold Mine Map State (Horde)
|
|
public const int GoldmineStateConAli = 1789; // Gold Mine Map State (Con Alience
|
|
public const int GoldmineStateConHor = 1790; // Gold Mine Map State (Con Horde)
|
|
|
|
public const int Had500DisadvantageAlliance = 3644;
|
|
public const int Had500DisadvantageHorde = 3645;
|
|
|
|
public const int FarmIconNew = 8808; // Farm Map Icon
|
|
public const int LumberMillIconNew = 8805; // Lumber Mill Map Icon
|
|
public const int BlacksmithIconNew = 8799; // Blacksmith Map Icon
|
|
public const int GoldMineIconNew = 8809; // Gold Mine Map Icon
|
|
public const int StablesIconNew = 5834; // Stable Map Icon
|
|
|
|
public const int FarmHordeControlState = 17328;
|
|
public const int FarmAllianceControlState = 17325;
|
|
public const int LumberMillHordeControlState = 17330;
|
|
public const int LumberMillAllianceControlState = 17326;
|
|
public const int BlacksmithHordeControlState = 17327;
|
|
public const int BlacksmithAllianceControlState = 17324;
|
|
public const int GoldMineHordeControlState = 17329;
|
|
public const int GoldMineAllianceControlState = 17323;
|
|
public const int StablesHordeControlState = 17331;
|
|
public const int StablesAllianceControlState = 17322;
|
|
}
|
|
|
|
// Note: code uses that these IDs follow each other
|
|
struct NodeObjectId
|
|
{
|
|
public const uint Banner0 = 180087; // Stables Banner
|
|
public const uint Banner1 = 180088; // Blacksmith Banner
|
|
public const uint Banner2 = 180089; // Farm Banner
|
|
public const uint Banner3 = 180090; // Lumber Mill Banner
|
|
public const uint Banner4 = 180091; // Gold Mine Banner
|
|
}
|
|
|
|
struct ABObjectTypes
|
|
{
|
|
// for all 5 node points 8*5=40 objects
|
|
public const int BannerNeutral = 0;
|
|
public const int BannerContA = 1;
|
|
public const int BannerContH = 2;
|
|
public const int BannerAlly = 3;
|
|
public const int BannerHorde = 4;
|
|
public const int AuraAlly = 5;
|
|
public const int AuraHorde = 6;
|
|
public const int AuraContested = 7;
|
|
//Gates
|
|
public const int GateA = 40;
|
|
public const int GateH = 41;
|
|
//Buffs
|
|
public const int SpeedbuffStables = 42;
|
|
public const int RegenbuffStables = 43;
|
|
public const int BerserkbuffStables = 44;
|
|
public const int SpeedbuffBlacksmith = 45;
|
|
public const int RegenbuffBlacksmith = 46;
|
|
public const int BerserkbuffBlacksmith = 47;
|
|
public const int SpeedbuffFarm = 48;
|
|
public const int RegenbuffFarm = 49;
|
|
public const int BerserkbuffFarm = 50;
|
|
public const int SpeedbuffLumberMill = 51;
|
|
public const int RegenbuffLumberMill = 52;
|
|
public const int BerserkbuffLumberMill = 53;
|
|
public const int SpeedbuffGoldMine = 54;
|
|
public const int RegenbuffGoldMine = 55;
|
|
public const int BerserkbuffGoldMine = 56;
|
|
public const int Max = 57;
|
|
}
|
|
|
|
// Object id templates from DB
|
|
struct ABObjectIds
|
|
{
|
|
public const uint BannerA = 180058;
|
|
public const uint BannerContA = 180059;
|
|
public const uint BannerH = 180060;
|
|
public const uint BannerContH = 180061;
|
|
|
|
public const uint AuraA = 180100;
|
|
public const uint AuraH = 180101;
|
|
public const uint AuraC = 180102;
|
|
|
|
public const uint GateA = 180255;
|
|
public const uint GateH = 180256;
|
|
}
|
|
|
|
struct ABBattlegroundNodes
|
|
{
|
|
public const int NodeStables = 0;
|
|
public const int NodeBlacksmith = 1;
|
|
public const int NodeFarm = 2;
|
|
public const int NodeLumberMill = 3;
|
|
public const int NodeGoldMine = 4;
|
|
|
|
public const int DynamicNodesCount = 5; // Dynamic Nodes That Can Be Captured
|
|
|
|
public const int SpiritAliance = 5;
|
|
public const int SpiritHorde = 6;
|
|
|
|
public const int AllCount = 7; // All Nodes (Dynamic And Static)
|
|
}
|
|
|
|
struct ABBattlegroundBroadcastTexts
|
|
{
|
|
public const uint AllianceNearVictory = 10598;
|
|
public const uint HordeNearVictory = 10599;
|
|
|
|
public static ABNodeInfo[] ABNodes =
|
|
{
|
|
new ABNodeInfo(ABBattlegroundNodes.NodeStables, 10199, 10200, 10203, 10204, 10201, 10202, 10286, 10287),
|
|
new ABNodeInfo(ABBattlegroundNodes.NodeBlacksmith, 10211, 10212, 10213, 10214, 10215, 10216, 10290, 10291),
|
|
new ABNodeInfo(ABBattlegroundNodes.NodeFarm, 10217, 10218, 10219, 10220, 10221, 10222, 10288, 10289),
|
|
new ABNodeInfo(ABBattlegroundNodes.NodeLumberMill, 10224, 10225, 10226, 10227, 10228, 10229, 10284, 10285),
|
|
new ABNodeInfo(ABBattlegroundNodes.NodeGoldMine, 10230, 10231, 10232, 10233, 10234, 10235, 10282, 10283)
|
|
};
|
|
}
|
|
|
|
struct ABNodeInfo
|
|
{
|
|
public ABNodeInfo(uint nodeId, uint textAllianceAssaulted, uint textHordeAssaulted, uint textAllianceTaken, uint textHordeTaken, uint textAllianceDefended, uint textHordeDefended, uint textAllianceClaims, uint textHordeClaims)
|
|
{
|
|
NodeId = nodeId;
|
|
TextAllianceAssaulted = textAllianceAssaulted;
|
|
TextHordeAssaulted = textHordeAssaulted;
|
|
TextAllianceTaken = textAllianceTaken;
|
|
TextHordeTaken = textHordeTaken;
|
|
TextAllianceDefended = textAllianceDefended;
|
|
TextHordeDefended = textHordeDefended;
|
|
TextAllianceClaims = textAllianceClaims;
|
|
TextHordeClaims = textHordeClaims;
|
|
}
|
|
|
|
public uint NodeId;
|
|
public uint TextAllianceAssaulted;
|
|
public uint TextHordeAssaulted;
|
|
public uint TextAllianceTaken;
|
|
public uint TextHordeTaken;
|
|
public uint TextAllianceDefended;
|
|
public uint TextHordeDefended;
|
|
public uint TextAllianceClaims;
|
|
public uint TextHordeClaims;
|
|
}
|
|
|
|
enum ABNodeStatus
|
|
{
|
|
Neutral = 0,
|
|
Contested = 1,
|
|
AllyContested = 1,
|
|
HordeContested = 2,
|
|
Occupied = 3,
|
|
AllyOccupied = 3,
|
|
HordeOccupied = 4
|
|
}
|
|
|
|
enum ABObjectives
|
|
{
|
|
AssaultBase = 122,
|
|
DefendBase = 123
|
|
}
|
|
#endregion
|
|
}
|