Core/Battleground:

* added a possibility to reload battleground templates
* cleaned up the template structure
* use mapids from BattlemasterList.dbc to calculate random bg
This commit is contained in:
joschiwald
2014-07-09 16:43:56 +02:00
parent 5f69fc9660
commit 7a67d816d9
11 changed files with 227 additions and 246 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
SET @id = 631;
-- Add new permissions
DELETE FROM `rbac_permissions` WHERE `id`=@id;
INSERT INTO `rbac_permissions` (`id`, `name`) VALUES
(@id, 'Command: reload battleground_template');
DELETE FROM `rbac_linked_permissions` WHERE `linkedId`=@id;
INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES
(196, @id);

View File

@@ -0,0 +1,3 @@
DELETE FROM `command` WHERE `name` LIKE 'reload battleground_template';
INSERT INTO `command` (`name`, `permission`, `help`) VALUES
('reload battleground_template', 631, 'Syntax: .reload battleground_template\r\nReload Battleground Templates.');

View File

@@ -534,7 +534,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_RELOAD_COMMAND = 628,
RBAC_PERM_COMMAND_RELOAD_CONDITIONS = 629,
RBAC_PERM_COMMAND_RELOAD_CONFIG = 630,
RBAC_PERM_UNUSED_631 = 631, // unused
RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE = 631,
RBAC_PERM_UNUSED_632 = 632, // unused
RBAC_PERM_COMMAND_RELOAD_CREATURE_LINKED_RESPAWN = 633,
RBAC_PERM_COMMAND_RELOAD_CREATURE_LOOT_TEMPLATE = 634,

View File

@@ -152,18 +152,6 @@ Battleground::Battleground()
m_StartMaxDist = 0.0f;
ScriptId = 0;
m_TeamStartLocX[TEAM_ALLIANCE] = 0;
m_TeamStartLocX[TEAM_HORDE] = 0;
m_TeamStartLocY[TEAM_ALLIANCE] = 0;
m_TeamStartLocY[TEAM_HORDE] = 0;
m_TeamStartLocZ[TEAM_ALLIANCE] = 0;
m_TeamStartLocZ[TEAM_HORDE] = 0;
m_TeamStartLocO[TEAM_ALLIANCE] = 0;
m_TeamStartLocO[TEAM_HORDE] = 0;
m_ArenaTeamIds[TEAM_ALLIANCE] = 0;
m_ArenaTeamIds[TEAM_HORDE] = 0;
@@ -300,16 +288,15 @@ inline void Battleground::_CheckSafePositions(uint32 diff)
{
m_ValidStartPositionTimer = 0;
float x, y, z, o;
for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
Position pos = player->GetPosition();
GetTeamStartLoc(player->GetBGTeam(), x, y, z, o);
if (pos.GetExactDistSq(x, y, z) > maxDist)
Position const* startPos = GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(player->GetBGTeam()));
if (pos.GetExactDistSq(startPos) > maxDist)
{
TC_LOG_DEBUG("bg.battleground", "BATTLEGROUND: Sending %s back to start location (map: %u) (possible exploit)", player->GetName().c_str(), GetMapId());
player->TeleportTo(GetMapId(), x, y, z, o);
player->TeleportTo(GetMapId(), startPos->GetPositionX(), startPos->GetPositionY(), startPos->GetPositionZ(), startPos->GetOrientation());
}
}
}
@@ -550,7 +537,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
}
// Announce BG starting
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE))
sWorld->SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel());
sWorld->SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName().c_str(), GetMinLevel(), GetMaxLevel());
}
}
}
@@ -614,13 +601,16 @@ inline Player* Battleground::_GetPlayerForTeam(uint32 teamId, BattlegroundPlayer
return player;
}
void Battleground::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O)
void Battleground::SetTeamStartPosition(TeamId teamId, Position const& pos)
{
TeamId idx = GetTeamIndexByTeamId(TeamID);
m_TeamStartLocX[idx] = X;
m_TeamStartLocY[idx] = Y;
m_TeamStartLocZ[idx] = Z;
m_TeamStartLocO[idx] = O;
ASSERT(teamId < TEAM_NEUTRAL);
StartPosition[teamId] = pos;
}
Position const* Battleground::GetTeamStartPosition(TeamId teamId) const
{
ASSERT(teamId < TEAM_NEUTRAL);
return &StartPosition[teamId];
}
void Battleground::SendPacketToAll(WorldPacket* packet)

View File

@@ -256,7 +256,7 @@ class Battleground
/* Battleground */
// Get methods:
char const* GetName() const { return m_Name; }
std::string const& GetName() const { return m_Name; }
BattlegroundTypeId GetTypeID(bool GetRandom = false) const { return GetRandom ? m_RandomTypeID : m_TypeID; }
BattlegroundBracketId GetBracketId() const { return m_BracketId; }
uint32 GetInstanceID() const { return m_InstanceID; }
@@ -282,7 +282,7 @@ class Battleground
bool IsRandom() const { return m_IsRandom; }
// Set methods:
void SetName(char const* Name) { m_Name = Name; }
void SetName(std::string const& name) { m_Name = name; }
void SetTypeID(BattlegroundTypeId TypeID) { m_TypeID = TypeID; }
void SetRandomTypeID(BattlegroundTypeId TypeID) { m_RandomTypeID = TypeID; }
//here we can count minlevel and maxlevel for players
@@ -352,15 +352,8 @@ class Battleground
BattlegroundMap* GetBgMap() const { ASSERT(m_Map); return m_Map; }
BattlegroundMap* FindBgMap() const { return m_Map; }
void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O);
void GetTeamStartLoc(uint32 TeamID, float &X, float &Y, float &Z, float &O) const
{
TeamId idx = GetTeamIndexByTeamId(TeamID);
X = m_TeamStartLocX[idx];
Y = m_TeamStartLocY[idx];
Z = m_TeamStartLocZ[idx];
O = m_TeamStartLocO[idx];
}
void SetTeamStartPosition(TeamId teamId, Position const& pos);
Position const* GetTeamStartPosition(TeamId teamId) const;
void SetStartMaxDist(float startMaxDist) { m_StartMaxDist = startMaxDist; }
float GetStartMaxDist() const { return m_StartMaxDist; }
@@ -559,7 +552,7 @@ class Battleground
bool m_IsRated; // is this battle rated?
bool m_PrematureCountDown;
uint32 m_PrematureCountDownTimer;
char const* m_Name;
std::string m_Name;
/* Pre- and post-update hooks */
@@ -669,10 +662,7 @@ class Battleground
// Start location
uint32 m_MapId;
BattlegroundMap* m_Map;
float m_TeamStartLocX[BG_TEAMS_COUNT];
float m_TeamStartLocY[BG_TEAMS_COUNT];
float m_TeamStartLocZ[BG_TEAMS_COUNT];
float m_TeamStartLocO[BG_TEAMS_COUNT];
Position StartPosition[BG_TEAMS_COUNT];
float m_StartMaxDist;
uint32 ScriptId;
};

View File

@@ -343,20 +343,7 @@ uint32 BattlegroundMgr::CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeI
// create a new battleground that will really be used to play
Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId originalBgTypeId, PvPDifficultyEntry const* bracketEntry, uint8 arenaType, bool isRated)
{
BattlegroundTypeId bgTypeId = originalBgTypeId;
bool isRandom = false;
switch (originalBgTypeId)
{
case BATTLEGROUND_RB:
isRandom = true;
/// Intentional fallback, "All Arenas" is random too
case BATTLEGROUND_AA:
bgTypeId = GetRandomBG(originalBgTypeId);
break;
default:
break;
}
BattlegroundTypeId bgTypeId = GetRandomBG(originalBgTypeId);
// get the template BG
Battleground* bg_template = GetBattlegroundTemplate(bgTypeId);
@@ -406,15 +393,15 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
break;
case BATTLEGROUND_RB:
case BATTLEGROUND_AA:
bg = new Battleground(*bg_template);
break;
default:
return NULL;
}
bool isRandom = bgTypeId != originalBgTypeId && !bg->isArena();
bg->SetBracket(bracketEntry);
bg->SetInstanceID(sMapMgr->GenerateInstanceId());
bg->SetClientInstanceID(CreateClientVisibleInstanceId(isRandom ? BATTLEGROUND_RB : bgTypeId, bracketEntry->GetBracketId()));
bg->SetClientInstanceID(CreateClientVisibleInstanceId(originalBgTypeId, bracketEntry->GetBracketId()));
bg->Reset(); // reset the new bg (set status to status_wait_queue from status_none)
bg->SetStatus(STATUS_WAIT_JOIN); // start the joining of the bg
bg->SetArenaType(arenaType);
@@ -448,82 +435,88 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
}
// used to create the BG templates
bool BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data)
bool BattlegroundMgr::CreateBattleground(BattlegroundTemplate const* bgTemplate)
{
// Create the BG
Battleground* bg = NULL;
switch (data.bgTypeId)
Battleground* bg = GetBattlegroundTemplate(bgTemplate->Id);
if (!bg)
{
case BATTLEGROUND_AV:
bg = new BattlegroundAV;
break;
case BATTLEGROUND_WS:
bg = new BattlegroundWS;
break;
case BATTLEGROUND_AB:
bg = new BattlegroundAB;
break;
case BATTLEGROUND_NA:
bg = new BattlegroundNA;
break;
case BATTLEGROUND_BE:
bg = new BattlegroundBE;
break;
case BATTLEGROUND_EY:
bg = new BattlegroundEY;
break;
case BATTLEGROUND_RL:
bg = new BattlegroundRL;
break;
case BATTLEGROUND_SA:
bg = new BattlegroundSA;
break;
case BATTLEGROUND_DS:
bg = new BattlegroundDS;
break;
case BATTLEGROUND_RV:
bg = new BattlegroundRV;
break;
case BATTLEGROUND_IC:
bg = new BattlegroundIC;
break;
case BATTLEGROUND_AA:
bg = new Battleground;
break;
case BATTLEGROUND_RB:
bg = new Battleground;
bg->SetRandom(true);
break;
default:
return false;
// Create the BG
switch (bgTemplate->Id)
{
case BATTLEGROUND_AV:
bg = new BattlegroundAV();
break;
case BATTLEGROUND_WS:
bg = new BattlegroundWS();
break;
case BATTLEGROUND_AB:
bg = new BattlegroundAB();
break;
case BATTLEGROUND_NA:
bg = new BattlegroundNA();
break;
case BATTLEGROUND_BE:
bg = new BattlegroundBE();
break;
case BATTLEGROUND_EY:
bg = new BattlegroundEY();
break;
case BATTLEGROUND_RL:
bg = new BattlegroundRL();
break;
case BATTLEGROUND_SA:
bg = new BattlegroundSA();
break;
case BATTLEGROUND_DS:
bg = new BattlegroundDS();
break;
case BATTLEGROUND_RV:
bg = new BattlegroundRV();
break;
case BATTLEGROUND_IC:
bg = new BattlegroundIC();
break;
case BATTLEGROUND_AA:
bg = new Battleground();
break;
case BATTLEGROUND_RB:
bg = new Battleground();
bg->SetRandom(true);
break;
default:
return false;
}
bg->SetTypeID(bgTemplate->Id);
bg->SetInstanceID(0);
AddBattleground(bg);
}
bg->SetMapId(data.MapID);
bg->SetTypeID(data.bgTypeId);
bg->SetInstanceID(0);
bg->SetArenaorBGType(data.IsArena);
bg->SetMinPlayersPerTeam(data.MinPlayersPerTeam);
bg->SetMaxPlayersPerTeam(data.MaxPlayersPerTeam);
bg->SetMinPlayers(data.MinPlayersPerTeam * 2);
bg->SetMaxPlayers(data.MaxPlayersPerTeam * 2);
bg->SetName(data.BattlegroundName);
bg->SetTeamStartLoc(ALLIANCE, data.Team1StartLocX, data.Team1StartLocY, data.Team1StartLocZ, data.Team1StartLocO);
bg->SetTeamStartLoc(HORDE, data.Team2StartLocX, data.Team2StartLocY, data.Team2StartLocZ, data.Team2StartLocO);
bg->SetStartMaxDist(data.StartMaxDist);
bg->SetLevelRange(data.LevelMin, data.LevelMax);
bg->SetScriptId(data.scriptId);
AddBattleground(bg);
bg->SetMapId(bgTemplate->BattlemasterEntry->mapid[0]);
bg->SetName(bgTemplate->BattlemasterEntry->name[sWorld->GetDefaultDbcLocale()]);
bg->SetArenaorBGType(bgTemplate->IsArena());
bg->SetMinPlayersPerTeam(bgTemplate->MinPlayersPerTeam);
bg->SetMaxPlayersPerTeam(bgTemplate->MaxPlayersPerTeam);
bg->SetMinPlayers(bgTemplate->MinPlayersPerTeam * 2);
bg->SetMaxPlayers(bgTemplate->MaxPlayersPerTeam * 2);
bg->SetTeamStartPosition(TEAM_ALLIANCE, bgTemplate->StartLocation[TEAM_ALLIANCE]);
bg->SetTeamStartPosition(TEAM_HORDE, bgTemplate->StartLocation[TEAM_HORDE]);
bg->SetStartMaxDist(bgTemplate->MaxStartDistSq);
bg->SetLevelRange(bgTemplate->MinLevel, bgTemplate->MaxLevel);
bg->SetScriptId(bgTemplate->ScriptId);
return true;
}
void BattlegroundMgr::CreateInitialBattlegrounds()
void BattlegroundMgr::LoadBattlegroundTemplates()
{
uint32 oldMSTime = getMSTime();
_battlegroundMapTemplates.clear();
_battlegroundTemplates.clear();
// 0 1 2 3 4 5 6 7 8 9 10 11
QueryResult result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, AllianceStartLoc, AllianceStartO, HordeStartLoc, HordeStartO, StartMaxDist, Weight, ScriptName FROM battleground_template");
if (!result)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 battlegrounds. DB table `battleground_template` is empty.");
@@ -536,7 +529,8 @@ void BattlegroundMgr::CreateInitialBattlegrounds()
{
Field* fields = result->Fetch();
uint32 bgTypeId = fields[0].GetUInt32();
BattlegroundTypeId bgTypeId = BattlegroundTypeId(fields[0].GetUInt32());
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId, NULL))
continue;
@@ -548,86 +542,64 @@ void BattlegroundMgr::CreateInitialBattlegrounds()
continue;
}
CreateBattlegroundData data;
data.bgTypeId = BattlegroundTypeId(bgTypeId);
data.IsArena = (bl->type == TYPE_ARENA);
data.MinPlayersPerTeam = fields[1].GetUInt16();
data.MaxPlayersPerTeam = fields[2].GetUInt16();
data.LevelMin = fields[3].GetUInt8();
data.LevelMax = fields[4].GetUInt8();
float dist = fields[9].GetFloat();
data.StartMaxDist = dist * dist;
BattlegroundTemplate bgTemplate;
bgTemplate.Id = bgTypeId;
bgTemplate.MinPlayersPerTeam = fields[1].GetUInt16();
bgTemplate.MaxPlayersPerTeam = fields[2].GetUInt16();
bgTemplate.MinLevel = fields[3].GetUInt8();
bgTemplate.MaxLevel = fields[4].GetUInt8();
float dist = fields[9].GetFloat();
bgTemplate.MaxStartDistSq = dist * dist;
bgTemplate.Weight = fields[10].GetUInt8();
bgTemplate.ScriptId = sObjectMgr->GetScriptId(fields[11].GetCString());
bgTemplate.BattlemasterEntry = bl;
data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString());
data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()];
data.MapID = bl->mapid[0];
if (data.MaxPlayersPerTeam == 0 || data.MinPlayersPerTeam > data.MaxPlayersPerTeam)
if (bgTemplate.MaxPlayersPerTeam == 0 || bgTemplate.MinPlayersPerTeam > bgTemplate.MaxPlayersPerTeam)
{
TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has bad values for MinPlayersPerTeam (%u) and MaxPlayersPerTeam(%u)",
data.bgTypeId, data.MinPlayersPerTeam, data.MaxPlayersPerTeam);
bgTemplate.Id, bgTemplate.MinPlayersPerTeam, bgTemplate.MaxPlayersPerTeam);
continue;
}
if (data.LevelMin == 0 || data.LevelMax == 0 || data.LevelMin > data.LevelMax)
if (bgTemplate.MinLevel == 0 || bgTemplate.MaxLevel == 0 || bgTemplate.MinLevel > bgTemplate.MaxLevel)
{
TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has bad values for LevelMin (%u) and LevelMax(%u)",
data.bgTypeId, data.LevelMin, data.LevelMax);
TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has bad values for MinLevel (%u) and MaxLevel (%u)",
bgTemplate.Id, bgTemplate.MinLevel, bgTemplate.MaxLevel);
continue;
}
if (data.bgTypeId == BATTLEGROUND_AA || data.bgTypeId == BATTLEGROUND_RB)
{
data.Team1StartLocX = 0;
data.Team1StartLocY = 0;
data.Team1StartLocZ = 0;
data.Team1StartLocO = fields[6].GetFloat();
data.Team2StartLocX = 0;
data.Team2StartLocY = 0;
data.Team2StartLocZ = 0;
data.Team2StartLocO = fields[8].GetFloat();
}
else
if (bgTemplate.Id != BATTLEGROUND_AA && bgTemplate.Id != BATTLEGROUND_RB)
{
uint32 startId = fields[5].GetUInt32();
if (WorldSafeLocsEntry const* start = sWorldSafeLocsStore.LookupEntry(startId))
{
data.Team1StartLocX = start->x;
data.Team1StartLocY = start->y;
data.Team1StartLocZ = start->z;
data.Team1StartLocO = fields[6].GetFloat();
bgTemplate.StartLocation[TEAM_ALLIANCE].Relocate(start->x, start->y, start->z, fields[6].GetFloat());
}
else
{
TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", data.bgTypeId, startId);
TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", bgTemplate.Id, startId);
continue;
}
startId = fields[7].GetUInt32();
if (WorldSafeLocsEntry const* start = sWorldSafeLocsStore.LookupEntry(startId))
{
data.Team2StartLocX = start->x;
data.Team2StartLocY = start->y;
data.Team2StartLocZ = start->z;
data.Team2StartLocO = fields[8].GetFloat();
bgTemplate.StartLocation[TEAM_HORDE].Relocate(start->x, start->y, start->z, fields[8].GetFloat());
}
else
{
TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", data.bgTypeId, startId);
TC_LOG_ERROR("sql.sql", "Table `battleground_template` for id %u has non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", bgTemplate.Id, startId);
continue;
}
}
if (!CreateBattleground(data))
if (!CreateBattleground(&bgTemplate))
continue;
if (data.IsArena)
{
if (data.bgTypeId != BATTLEGROUND_AA)
m_ArenaSelectionWeights[data.bgTypeId] = fields[10].GetUInt8();
}
else if (data.bgTypeId != BATTLEGROUND_RB)
m_BGSelectionWeights[data.bgTypeId] = fields[10].GetUInt8();
_battlegroundTemplates[bgTypeId] = bgTemplate;
if (bgTemplate.BattlemasterEntry->mapid[1] == -1) // in this case we have only one mapId
_battlegroundMapTemplates[bgTemplate.BattlemasterEntry->mapid[0]] = &_battlegroundTemplates[bgTypeId];
++count;
}
@@ -722,15 +694,14 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt
{
if (Battleground* bg = GetBattleground(instanceId, bgTypeId))
{
float x, y, z, O;
uint32 mapid = bg->GetMapId();
uint32 team = player->GetBGTeam();
if (team == 0)
team = player->GetTeam();
bg->GetTeamStartLoc(team, x, y, z, O);
TC_LOG_DEBUG("bg.battleground", "BattlegroundMgr::SendToBattleground: Sending %s to map %u, X %f, Y %f, Z %f, O %f (bgType %u)", player->GetName().c_str(), mapid, x, y, z, O, bgTypeId);
player->TeleportTo(mapid, x, y, z, O);
Position const* pos = bg->GetTeamStartPosition(Battleground::GetTeamIndexByTeamId(team));
TC_LOG_DEBUG("bg.battleground", "BattlegroundMgr::SendToBattleground: Sending %s to map %u, %s (bgType %u)", player->GetName().c_str(), mapid, pos->ToString().c_str(), bgTypeId);
player->TeleportTo(mapid, pos->GetPositionX(), pos->GetPositionY(), pos->GetPositionZ(), pos->GetOrientation());
}
else
TC_LOG_ERROR("bg.battleground", "BattlegroundMgr::SendToBattleground: Instance %u (bgType %u) not found while trying to teleport player %s", instanceId, bgTypeId, player->GetName().c_str());
@@ -987,51 +958,43 @@ bool BattlegroundMgr::IsBGWeekend(BattlegroundTypeId bgTypeId)
BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId)
{
uint32 weight = 0;
BattlegroundTypeId returnBgTypeId = BATTLEGROUND_TYPE_NONE;
BattlegroundSelectionWeightMap selectionWeights;
if (BattlegroundTemplate const* bgTemplate = GetBattlegroundTemplateByTypeId(bgTypeId))
{
uint32 weight = 0;
BattlegroundSelectionWeightMap selectionWeights;
if (bgTypeId == BATTLEGROUND_AA)
{
for (BattlegroundSelectionWeightMap::const_iterator it = m_ArenaSelectionWeights.begin(); it != m_ArenaSelectionWeights.end(); ++it)
for (int32 mapId : bgTemplate->BattlemasterEntry->mapid)
{
if (it->second)
{
weight += it->second;
selectionWeights[it->first] = it->second;
}
}
}
else if (bgTypeId == BATTLEGROUND_RB)
{
for (BattlegroundSelectionWeightMap::const_iterator it = m_BGSelectionWeights.begin(); it != m_BGSelectionWeights.end(); ++it)
{
if (it->second)
{
weight += it->second;
selectionWeights[it->first] = it->second;
}
}
}
if (weight)
{
// Select a random value
uint32 selectedWeight = urand(0, weight - 1);
// Select the correct bg (if we have in DB A(10), B(20), C(10), D(15) --> [0---A---9|10---B---29|30---C---39|40---D---54])
weight = 0;
for (BattlegroundSelectionWeightMap::const_iterator it = selectionWeights.begin(); it != selectionWeights.end(); ++it)
{
weight += it->second;
if (selectedWeight < weight)
{
returnBgTypeId = it->first;
if (mapId == -1)
break;
if (BattlegroundTemplate const* bg = GetBattlegroundTemplateByMapId(mapId))
{
weight += bg->Weight;
selectionWeights[bg->Id] = bg->Weight;
}
}
// there is only one bg to select
if (selectionWeights.size() == 1)
return bgTypeId;
if (weight)
{
// Select a random value
uint32 selectedWeight = urand(0, weight - 1);
// Select the correct bg (if we have in DB A(10), B(20), C(10), D(15) --> [0---A---9|10---B---29|30---C---39|40---D---54])
weight = 0;
for (auto it : selectionWeights)
{
weight += it.second;
if (selectedWeight < weight)
return it.first;
}
}
}
return returnBgTypeId;
return BATTLEGROUND_TYPE_NONE;
}
BGFreeSlotQueueContainer& BattlegroundMgr::GetBGFreeSlotQueueStore(BattlegroundTypeId bgTypeId)

View File

@@ -33,28 +33,6 @@ typedef std::unordered_map<uint32, BattlegroundTypeId> BattleMastersMap;
#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
#define WS_ARENA_DISTRIBUTION_TIME 20001 // Custom worldstate
struct CreateBattlegroundData
{
BattlegroundTypeId bgTypeId;
bool IsArena;
uint32 MinPlayersPerTeam;
uint32 MaxPlayersPerTeam;
uint32 LevelMin;
uint32 LevelMax;
char* BattlegroundName;
uint32 MapID;
float Team1StartLocX;
float Team1StartLocY;
float Team1StartLocZ;
float Team1StartLocO;
float Team2StartLocX;
float Team2StartLocY;
float Team2StartLocZ;
float Team2StartLocO;
float StartMaxDist;
uint32 scriptId;
};
struct BattlegroundData
{
BattlegroundContainer m_Battlegrounds;
@@ -62,6 +40,22 @@ struct BattlegroundData
BGFreeSlotQueueContainer BGFreeSlotQueue;
};
struct BattlegroundTemplate
{
BattlegroundTypeId Id;
uint16 MinPlayersPerTeam;
uint16 MaxPlayersPerTeam;
uint8 MinLevel;
uint8 MaxLevel;
Position StartLocation[BG_TEAMS_COUNT];
float MaxStartDistSq;
uint8 Weight;
uint32 ScriptId;
BattlemasterListEntry const* BattlemasterEntry;
bool IsArena() const { return BattlemasterEntry->type == MAP_ARENA; }
};
class BattlegroundMgr
{
friend class ACE_Singleton<BattlegroundMgr, ACE_Null_Mutex>;
@@ -95,7 +89,7 @@ class BattlegroundMgr
void RemoveFromBGFreeSlotQueue(BattlegroundTypeId bgTypeId, uint32 instanceId);
BGFreeSlotQueueContainer& GetBGFreeSlotQueueStore(BattlegroundTypeId bgTypeId);
void CreateInitialBattlegrounds();
void LoadBattlegroundTemplates();
void DeleteAllBattlegrounds();
void SendToBattleground(Player* player, uint32 InstanceID, BattlegroundTypeId bgTypeId);
@@ -135,7 +129,7 @@ class BattlegroundMgr
}
private:
bool CreateBattleground(CreateBattlegroundData& data);
bool CreateBattleground(BattlegroundTemplate const* bgTemplate);
uint32 CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id);
static bool IsArenaType(BattlegroundTypeId bgTypeId);
BattlegroundTypeId GetRandomBG(BattlegroundTypeId id);
@@ -145,9 +139,6 @@ class BattlegroundMgr
BattlegroundQueue m_BattlegroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES];
typedef std::map<BattlegroundTypeId, uint8> BattlegroundSelectionWeightMap; // TypeId and its selectionWeight
BattlegroundSelectionWeightMap m_ArenaSelectionWeights;
BattlegroundSelectionWeightMap m_BGSelectionWeights;
std::vector<uint64> m_QueueUpdateScheduler;
uint32 m_NextRatedArenaUpdate;
time_t m_NextAutoDistributionTime;
@@ -155,7 +146,31 @@ class BattlegroundMgr
bool m_ArenaTesting;
bool m_Testing;
BattleMastersMap mBattleMastersMap;
BattlegroundTemplate const* GetBattlegroundTemplateByTypeId(BattlegroundTypeId id)
{
BattlegroundTemplateMap::const_iterator itr = _battlegroundTemplates.find(id);
if (itr != _battlegroundTemplates.end())
return &itr->second;
return nullptr;
}
BattlegroundTemplate const* GetBattlegroundTemplateByMapId(uint32 mapId)
{
BattlegroundMapTemplateContainer::const_iterator itr = _battlegroundMapTemplates.find(mapId);
if (itr != _battlegroundMapTemplates.end())
return itr->second;
return nullptr;
}
typedef std::map<BattlegroundTypeId, uint8 /*weight*/> BattlegroundSelectionWeightMap;
typedef std::map<BattlegroundTypeId, BattlegroundTemplate> BattlegroundTemplateMap;
typedef std::map<uint32 /*mapId*/, BattlegroundTemplate*> BattlegroundMapTemplateContainer;
BattlegroundTemplateMap _battlegroundTemplates;
BattlegroundMapTemplateContainer _battlegroundMapTemplates;
};
#define sBattlegroundMgr ACE_Singleton<BattlegroundMgr, ACE_Null_Mutex>::instance()
#endif
#endif // __BATTLEGROUNDMGR_H

View File

@@ -199,7 +199,6 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
{
if (Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(ginfo->BgTypeId))
{
char const* bgName = bg->GetName();
uint32 MinPlayers = bg->GetMinPlayersPerTeam();
uint32 qHorde = 0;
uint32 qAlliance = 0;
@@ -216,13 +215,13 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr
// Show queue status to player only (when joining queue)
if (sWorld->getBoolConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
{
ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bgName, q_min_level, q_max_level,
ChatHandler(leader->GetSession()).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, bg->GetName().c_str(), q_min_level, q_max_level,
qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
}
// System message
else
{
sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level,
sWorld->SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, bg->GetName().c_str(), q_min_level, q_max_level,
qAlliance, (MinPlayers > qAlliance) ? MinPlayers - qAlliance : (uint32)0, qHorde, (MinPlayers > qHorde) ? MinPlayers - qHorde : (uint32)0);
}
}

View File

@@ -1781,7 +1781,7 @@ void World::SetInitialWorldSettings()
///- Initialize Battlegrounds
TC_LOG_INFO("server.loading", "Starting Battleground System");
sBattlegroundMgr->CreateInitialBattlegrounds();
sBattlegroundMgr->LoadBattlegroundTemplates();
sBattlegroundMgr->InitAutomaticArenaPointDistribution();
///- Initialize outdoor pvp

View File

@@ -25,6 +25,7 @@ EndScriptData */
#include "AccountMgr.h"
#include "AchievementMgr.h"
#include "AuctionHouseMgr.h"
#include "BattlegroundMgr.h"
#include "Chat.h"
#include "CreatureTextMgr.h"
#include "DisableMgr.h"
@@ -74,6 +75,7 @@ public:
{ "areatrigger_tavern", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TAVERN, true, &HandleReloadAreaTriggerTavernCommand, "", NULL },
{ "areatrigger_teleport", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TELEPORT, true, &HandleReloadAreaTriggerTeleportCommand, "", NULL },
{ "autobroadcast", rbac::RBAC_PERM_COMMAND_RELOAD_AUTOBROADCAST, true, &HandleReloadAutobroadcastCommand, "", NULL },
{ "battleground_template", rbac::RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE, true, &HandleReloadBattlegroundTemplate, "", NULL },
{ "broadcast_text", rbac::RBAC_PERM_COMMAND_RELOAD_BROADCAST_TEXT, true, &HandleReloadBroadcastTextCommand, "", NULL },
{ "command", rbac::RBAC_PERM_COMMAND_RELOAD_COMMAND, true, &HandleReloadCommandCommand, "", NULL },
{ "conditions", rbac::RBAC_PERM_COMMAND_RELOAD_CONDITIONS, true, &HandleReloadConditions, "", NULL },
@@ -200,6 +202,7 @@ public:
HandleReloadVehicleTemplateAccessoryCommand(handler, "");
HandleReloadAutobroadcastCommand(handler, "");
HandleReloadBattlegroundTemplate(handler, "");
return true;
}
@@ -376,6 +379,14 @@ public:
return true;
}
static bool HandleReloadBattlegroundTemplate(ChatHandler* handler, char const* /*args*/)
{
TC_LOG_INFO("misc", "Re-Loading Battleground Templates...");
sBattlegroundMgr->LoadBattlegroundTemplates();
handler->SendGlobalGMSysMessage("DB table `battleground_template` reloaded.");
return true;
}
static bool HandleReloadBroadcastTextCommand(ChatHandler* handler, const char* /*args*/)
{
TC_LOG_INFO("misc", "Re-Loading Broadcast texts...");