feat(Core/BG): Allow battlegrounds to be configurable (#20320) (#21124)

This commit is contained in:
valsan-azerty-boi
2025-03-01 16:01:10 +01:00
committed by GitHub
parent de6732da34
commit a3f7e1e76d
11 changed files with 101 additions and 22 deletions

View File

@@ -3698,6 +3698,50 @@ Battleground.SpeedBuffRespawn = 150
Battleground.Override.LowLevels.MinPlayers = 0
#
# Battleground.Warsong.Flags
# Description: Set the number of flags required for a team to win in Warsong battleground
# Default: 3 (Blizzlike)
# 1 (Minimum)
Battleground.Warsong.Flags = 3
#
# Battleground.Arathi.CapturePoints
# Description: Set the number of capture points required for a team to win in Arathi battleground
# Default: 1600 (WotLK)
# 2000 (Vanilla)
Battleground.Arathi.CapturePoints = 1600
#
# Battleground.Alterac.Reinforcements
# Description: Set the number of total reinforcements for each teams in Alterac battleground
# (It is necessary to restart the server after changing the Reinforcements value)
# Default: 600 (Enabled, WotLK)
# 500 (Enabled, MoP)
# 0 (Disabled, early Vanilla, victory only on boss death)
Battleground.Alterac.Reinforcements = 600
#
# Battleground.Alterac.ReputationOnBossDeath
# Description: Set the number of rep point given for a boss killed in Alterac battleground
# (It is necessary to restart the server after changing the ReputationOnBossDeath value)
# Default: 350 (WotLK)
# 389 (Vanilla)
Battleground.Alterac.ReputationOnBossDeath = 350
#
# Battleground.EyeOfTheStorm.CapturePoints
# Description: Set the number of capture points required for a team to win in Eye of the Storm battleground
# (The UI part of the max team score will not be compliant with this parameter without client modification)
# Default: 1600 (WotLK, UI compliant)
# 2000 (TBC, not UI compliant)
Battleground.EyeOfTheStorm.CapturePoints = 1600
#
###################################################################################################

View File

@@ -108,8 +108,8 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff)
auto reputationRewards = uint8(m_TeamScores[teamId] / _reputationTics);
auto information = uint8(m_TeamScores[teamId] / BG_AB_WARNING_NEAR_VICTORY_SCORE);
m_TeamScores[teamId] += BG_AB_TickPoints[controlledPoints];
if (m_TeamScores[teamId] > BG_AB_MAX_TEAM_SCORE)
m_TeamScores[teamId] = BG_AB_MAX_TEAM_SCORE;
if (m_TeamScores[teamId] > static_cast<int32>(_configurableMaxTeamScore))
m_TeamScores[teamId] = _configurableMaxTeamScore;
if (honorRewards < uint8(m_TeamScores[teamId] / _honorTics))
RewardHonorToTeam(GetBonusHonorFromKill(1), teamId);
@@ -132,7 +132,7 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff)
UpdateWorldState(teamId == TEAM_ALLIANCE ? BG_AB_OP_RESOURCES_ALLY : BG_AB_OP_RESOURCES_HORDE, m_TeamScores[teamId]);
if (m_TeamScores[teamId] > m_TeamScores[GetOtherTeamId(teamId)] + 500)
_teamScores500Disadvantage[GetOtherTeamId(teamId)] = true;
if (m_TeamScores[teamId] >= BG_AB_MAX_TEAM_SCORE)
if (m_TeamScores[teamId] >= static_cast<int32>(_configurableMaxTeamScore))
EndBattleground(teamId);
_bgEvents.ScheduleEvent(eventId, BG_AB_TickIntervals[controlledPoints]);
@@ -245,12 +245,11 @@ void BattlegroundAB::FillInitialWorldStates(WorldPackets::WorldState::InitWorldS
for (uint8 i = BG_AB_NODE_STATE_ALLY_OCCUPIED; i <= BG_AB_NODE_STATE_HORDE_CONTESTED; ++i)
packet.Worldstates.emplace_back(node._iconCapture + i - 1, node._state == i ? 1 : 0);
}
packet.Worldstates.emplace_back(BG_AB_OP_OCCUPIED_BASES_ALLY, _controlledPoints[TEAM_ALLIANCE]);
packet.Worldstates.emplace_back(BG_AB_OP_OCCUPIED_BASES_HORDE, _controlledPoints[TEAM_HORDE]);
packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_MAX, BG_AB_MAX_TEAM_SCORE);
packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_MAX, _configurableMaxTeamScore);
packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_WARNING, BG_AB_WARNING_NEAR_VICTORY_SCORE);
packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_ALLY, m_TeamScores[TEAM_ALLIANCE]);
packet.Worldstates.emplace_back(BG_AB_OP_RESOURCES_HORDE, m_TeamScores[TEAM_HORDE]);
@@ -481,6 +480,11 @@ void BattlegroundAB::Init()
_capturePointInfo[BG_AB_NODE_BLACKSMITH]._iconCapture = BG_AB_OP_BLACKSMITH_STATE_ALIENCE;
_capturePointInfo[BG_AB_NODE_LUMBER_MILL]._iconCapture = BG_AB_OP_LUMBERMILL_STATE_ALIENCE;
_capturePointInfo[BG_AB_NODE_GOLD_MINE]._iconCapture = BG_AB_OP_GOLDMINE_STATE_ALIENCE;
uint32 bgArathiCapturePointsConfig = sWorld->getIntConfig(CONFIG_BATTLEGROUND_ARATHI_CAPTUREPOINTS);
_configurableMaxTeamScore = bgArathiCapturePointsConfig > 0
? bgArathiCapturePointsConfig
: static_cast<uint32>(BG_AB_MAX_TEAM_SCORE);
}
void BattlegroundAB::EndBattleground(TeamId winnerTeamId)

View File

@@ -341,5 +341,6 @@ private:
uint32 _reputationTics;
uint8 _controlledPoints[PVP_TEAMS_COUNT] {};
bool _teamScores500Disadvantage[PVP_TEAMS_COUNT] {};
uint32 _configurableMaxTeamScore;
};
#endif

View File

@@ -266,6 +266,9 @@ void BattlegroundAV::HandleQuestComplete(uint32 questid, Player* player)
void BattlegroundAV::UpdateScore(TeamId teamId, int16 points)
{
if (BG_AV_SCORE_INITIAL_POINTS == 0)
return; // don't update teamscores if reinforcements are disabled
//note: to remove reinforcementpoints points must be negative, for adding reinforcements points must be positive
m_Team_Scores[teamId] += points;
@@ -475,8 +478,11 @@ void BattlegroundAV::StartingEventOpenDoors()
for (uint8 mine = AV_NORTH_MINE; mine <= AV_SOUTH_MINE; mine++) //mine population
ChangeMineOwner(mine, TEAM_NEUTRAL, true);
UpdateWorldState(AV_SHOW_H_SCORE, 1);
UpdateWorldState(AV_SHOW_A_SCORE, 1);
if (BG_AV_SCORE_INITIAL_POINTS > 0) // display teamscores on top only if reinforcements are enabled
{
UpdateWorldState(AV_SHOW_H_SCORE, 1);
UpdateWorldState(AV_SHOW_A_SCORE, 1);
}
DoorOpen(BG_AV_OBJECT_DOOR_H);
DoorOpen(BG_AV_OBJECT_DOOR_A);
@@ -1114,11 +1120,12 @@ void BattlegroundAV::FillInitialWorldStates(WorldPackets::WorldState::InitWorldS
{
packet.Worldstates.emplace_back(AV_SNOWFALL_N, 1);
}
packet.Worldstates.emplace_back(AV_Alliance_Score, m_Team_Scores[0]);
packet.Worldstates.emplace_back(AV_Horde_Score, m_Team_Scores[1]);
packet.Worldstates.emplace_back(AV_SHOW_A_SCORE, GetStatus() == STATUS_IN_PROGRESS ? 1 : 0);
packet.Worldstates.emplace_back(AV_SHOW_H_SCORE, GetStatus() == STATUS_IN_PROGRESS ? 1 : 0);
packet.Worldstates.emplace_back(AV_SHOW_A_SCORE, GetStatus() == STATUS_IN_PROGRESS && BG_AV_SCORE_INITIAL_POINTS > 0 ? 1 : 0);
packet.Worldstates.emplace_back(AV_SHOW_H_SCORE, GetStatus() == STATUS_IN_PROGRESS && BG_AV_SCORE_INITIAL_POINTS > 0 ? 1 : 0);
SendMineWorldStates(AV_NORTH_MINE);
SendMineWorldStates(AV_SOUTH_MINE);

View File

@@ -21,14 +21,14 @@
#include "Battleground.h"
#include "BattlegroundScore.h"
#define BG_AV_CAPTIME 240000 //4:00
#define BG_AV_SNOWFALL_FIRSTCAP 300000 //5:00 but i also have seen 4:05
#define BG_AV_CAPTIME 240000 //4:00
#define BG_AV_SNOWFALL_FIRSTCAP 300000 //5:00 but i also have seen 4:05
#define BG_AV_SCORE_INITIAL_POINTS 600
#define SEND_MSG_NEAR_LOSE 120
#define BG_AV_SCORE_INITIAL_POINTS (sWorld->getIntConfig(CONFIG_BATTLEGROUND_ALTERAC_REINFORCEMENTS)) // Blizzlike default is 600
#define SEND_MSG_NEAR_LOSE 120
#define BG_AV_KILL_BOSS 4
#define BG_AV_REP_BOSS 350
#define BG_AV_REP_BOSS (sWorld->getIntConfig(CONFIG_BATTLEGROUND_ALTERAC_REP_ONBOSSDEATH)) // Blizzlike default is 350
#define BG_AV_KILL_CAPTAIN 3
#define BG_AV_REP_CAPTAIN 125
@@ -38,7 +38,7 @@
#define BG_AV_REP_TOWER 12
#define BG_AV_RES_TOWER 75
#define BG_AV_GET_COMMANDER 1 //for a safely returned wingcommander
#define BG_AV_GET_COMMANDER 1 //for a safely returned wingcommander
//bonushonor at the end
#define BG_AV_KILL_SURVIVING_TOWER 2
#define BG_AV_REP_SURVIVING_TOWER 12

View File

@@ -114,14 +114,14 @@ void BattlegroundEY::AddPoints(TeamId teamId, uint32 points)
{
uint8 honorRewards = uint8(m_TeamScores[teamId] / _honorTics);
m_TeamScores[teamId] += points;
if (m_TeamScores[teamId] > BG_EY_MAX_TEAM_SCORE)
m_TeamScores[teamId] = BG_EY_MAX_TEAM_SCORE;
if (m_TeamScores[teamId] > static_cast<int32>(_configurableMaxTeamScore))
m_TeamScores[teamId] = _configurableMaxTeamScore;
for (; honorRewards < uint8(m_TeamScores[teamId] / _honorTics); ++honorRewards)
RewardHonorToTeam(GetBonusHonorFromKill(1), teamId);
UpdateWorldState(teamId == TEAM_ALLIANCE ? EY_ALLIANCE_RESOURCES : EY_HORDE_RESOURCES, std::min<uint32>(m_TeamScores[teamId], BG_EY_MAX_TEAM_SCORE));
if (m_TeamScores[teamId] >= BG_EY_MAX_TEAM_SCORE)
UpdateWorldState(teamId == TEAM_ALLIANCE ? EY_ALLIANCE_RESOURCES : EY_HORDE_RESOURCES, std::min<uint32>(m_TeamScores[teamId], _configurableMaxTeamScore));
if (m_TeamScores[teamId] >= static_cast<int32>(_configurableMaxTeamScore))
EndBattleground(teamId);
}
@@ -362,6 +362,11 @@ void BattlegroundEY::Init()
_droppedFlagGUID.Clear();
_flagState = BG_EY_FLAG_STATE_ON_BASE;
_flagCapturedObject = 0;
uint32 bgEyCapturePointsConfig = sWorld->getIntConfig(CONFIG_BATTLEGROUND_EYEOFTHESTORM_CAPTUREPOINTS);
_configurableMaxTeamScore = bgEyCapturePointsConfig > 0
? bgEyCapturePointsConfig
: static_cast<uint32>(BG_EY_MAX_TEAM_SCORE);
}
void BattlegroundEY::RespawnFlag()

View File

@@ -456,5 +456,6 @@ private:
ObjectGuid _droppedFlagGUID;
uint8 _flagState;
uint32 _flagCapturedObject;
uint32 _configurableMaxTeamScore;
};
#endif

View File

@@ -222,10 +222,10 @@ void BattlegroundWS::EventPlayerCapturedFlag(Player* player)
RewardHonorToTeam(GetBonusHonorFromKill(2), player->GetTeamId());
if (GetTeamScore(TEAM_ALLIANCE) == BG_WS_MAX_TEAM_SCORE || GetTeamScore(TEAM_HORDE) == BG_WS_MAX_TEAM_SCORE)
if (GetTeamScore(TEAM_ALLIANCE) == _configurableMaxTeamScore || GetTeamScore(TEAM_HORDE) == _configurableMaxTeamScore)
{
UpdateWorldState(BG_WS_STATE_TIMER_ACTIVE, 0);
EndBattleground(GetTeamScore(TEAM_HORDE) == BG_WS_MAX_TEAM_SCORE ? TEAM_HORDE : TEAM_ALLIANCE);
EndBattleground(GetTeamScore(TEAM_HORDE) == _configurableMaxTeamScore ? TEAM_HORDE : TEAM_ALLIANCE);
}
else
_bgEvents.ScheduleEvent(BG_WS_EVENT_RESPAWN_BOTH_FLAGS, BG_WS_FLAG_RESPAWN_TIME);
@@ -497,6 +497,11 @@ void BattlegroundWS::Init()
_honorWinKills = 1;
_honorEndKills = 2;
}
uint32 bgWarsongFlagsConfig = sWorld->getIntConfig(CONFIG_BATTLEGROUND_WARSONG_FLAGS);
_configurableMaxTeamScore = bgWarsongFlagsConfig > 0
? bgWarsongFlagsConfig
: static_cast<uint32>(BG_WS_MAX_TEAM_SCORE);
}
void BattlegroundWS::EndBattleground(TeamId winnerTeamId)
@@ -551,7 +556,7 @@ void BattlegroundWS::FillInitialWorldStates(WorldPackets::WorldState::InitWorldS
packet.Worldstates.reserve(7);
packet.Worldstates.emplace_back(BG_WS_FLAG_CAPTURES_ALLIANCE, GetTeamScore(TEAM_ALLIANCE));
packet.Worldstates.emplace_back(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(TEAM_HORDE));
packet.Worldstates.emplace_back(BG_WS_FLAG_CAPTURES_MAX, BG_WS_MAX_TEAM_SCORE);
packet.Worldstates.emplace_back(BG_WS_FLAG_CAPTURES_MAX, _configurableMaxTeamScore);
packet.Worldstates.emplace_back(BG_WS_STATE_TIMER_ACTIVE, GetStatus() == STATUS_IN_PROGRESS ? 1 : 0);
packet.Worldstates.emplace_back(BG_WS_STATE_TIMER, GetMatchTime());

View File

@@ -272,6 +272,7 @@ private:
uint32 _reputationCapture;
uint32 _honorWinKills;
uint32 _honorEndKills;
uint32 _configurableMaxTeamScore;
void PostUpdateImpl(uint32 diff) override;
};

View File

@@ -318,6 +318,11 @@ enum WorldIntConfigs
CONFIG_BATTLEGROUND_SPEED_BUFF_RESPAWN,
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_LIMIT_MIN_LEVEL,
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_LIMIT_MIN_PLAYERS,
CONFIG_BATTLEGROUND_WARSONG_FLAGS,
CONFIG_BATTLEGROUND_ARATHI_CAPTUREPOINTS,
CONFIG_BATTLEGROUND_ALTERAC_REINFORCEMENTS,
CONFIG_BATTLEGROUND_ALTERAC_REP_ONBOSSDEATH,
CONFIG_BATTLEGROUND_EYEOFTHESTORM_CAPTUREPOINTS,
CONFIG_WINTERGRASP_ENABLE,
CONFIG_ARENA_MAX_RATING_DIFFERENCE,
CONFIG_ARENA_RATING_DISCARD_TIMER,

View File

@@ -927,6 +927,12 @@ void World::LoadConfigSettings(bool reload)
_int_configs[CONFIG_BATTLEGROUND_SPEED_BUFF_RESPAWN] = 150;
}
_int_configs[CONFIG_BATTLEGROUND_WARSONG_FLAGS] = sConfigMgr->GetOption<uint32>("Battleground.Warsong.Flags", 3);
_int_configs[CONFIG_BATTLEGROUND_ARATHI_CAPTUREPOINTS] = sConfigMgr->GetOption<uint32>("Battleground.Arathi.CapturePoints", 1600);
_int_configs[CONFIG_BATTLEGROUND_ALTERAC_REINFORCEMENTS] = sConfigMgr->GetOption<uint32>("Battleground.Alterac.Reinforcements", 600);
_int_configs[CONFIG_BATTLEGROUND_ALTERAC_REP_ONBOSSDEATH] = sConfigMgr->GetOption<uint32>("Battleground.Alterac.ReputationOnBossDeath", 350);
_int_configs[CONFIG_BATTLEGROUND_EYEOFTHESTORM_CAPTUREPOINTS] = sConfigMgr->GetOption<uint32>("Battleground.EyeOfTheStorm.CapturePoints", 1600);
_int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfigMgr->GetOption<uint32>("Arena.MaxRatingDifference", 150);
_int_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfigMgr->GetOption<uint32>("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS);
_int_configs[CONFIG_ARENA_PREV_OPPONENTS_DISCARD_TIMER] = sConfigMgr->GetOption<uint32>("Arena.PreviousOpponentsDiscardTimer", 2 * MINUTE * IN_MILLISECONDS);