[svn] -enabled instantiated battlegrounds
-enabled arena matches -rewritten battleground queuing to support joining as group -removed queue announcements --HG-- branch : trunk
This commit is contained in:
+28
-3
@@ -198,6 +198,7 @@ INSERT INTO `command` VALUES
|
||||
('debug setvalue',3,'Syntax: .debug setvalue #field #value #isInt\r\n\r\nSet the field #field of the selected creature with value #value. If no creature is selected, set the content of your field.\r\n\r\nUse a #isInt of value 1 if #value is an integer.'),
|
||||
('debug standstate',2,'Syntax: .debug standstate #emoteid\r\n\r\nChange the emote of your character while standing to #emoteid.'),
|
||||
('debug update',3,'Syntax: .debug update #field #value\r\n\r\nUpdate the field #field of the selected character or creature with value #value.\r\n\r\nIf no #value is provided, display the content of field #field.'),
|
||||
('debug arena',3,'Syntax: .debug arena\r\n\r\n Toggles arena 1v1 or normal mode.'),
|
||||
('delticket',2,'Syntax: .delticket all\r\n .delticket #num\r\n .delticket $character_name\r\n\rall to dalete all tickets at server, $character_name to delete ticket of this character, #num to delete ticket #num.'),
|
||||
('demorph',2,'Syntax: .demorph\r\n\r\nDemorph the selected player.'),
|
||||
('die',3,'Syntax: .die\r\n\r\nKill the selected player. If no player is selected, it will kill you.'),
|
||||
@@ -208,6 +209,7 @@ INSERT INTO `command` VALUES
|
||||
('event start',2,'Syntax: .event start #event_id\r\nStart event #event_id. Set start time for event to current moment (change not saved in DB).'),
|
||||
('event stop',2,'Syntax: .event stop #event_id\r\nStop event #event_id. Set start time for event to time in past that make current moment is event stop time (change not saved in DB).'),
|
||||
('explorecheat',3,'Syntax: .explorecheat #flag\r\n\r\nReveal or hide all maps for the selected player. If no player is selected, hide or reveal maps to you.\r\n\r\nUse a #flag of value 1 to reveal, use a #flag value of 0 to hide all maps.'),
|
||||
('flusharenapoints',3,'Syntax: .flusharenapoints\r\n\r\nUse it to distribute arena points based on arena team ratings, and start a new week.'),
|
||||
('gm',1,'Syntax: .gm on/off\r\n\r\nEnable or Disable GM MODE'),
|
||||
('gm fly',3,'Syntax: .gm fly on/off\r\nEnable/disable gm fly mode.'),
|
||||
('gm list',0,'Syntax: .gm list\r\n\r\nDisplay a list of available Game Masters.'),
|
||||
@@ -1363,6 +1365,7 @@ CREATE TABLE `instance_template` (
|
||||
LOCK TABLES `instance_template` WRITE;
|
||||
/*!40000 ALTER TABLE `instance_template` DISABLE KEYS */;
|
||||
INSERT INTO `instance_template` VALUES
|
||||
(30,0,10,0,50,0,NULL,NULL,NULL,NULL,''),
|
||||
(33,0,22,30,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(34,0,24,32,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
(36,0,15,20,10,7200,NULL,NULL,NULL,NULL,''),
|
||||
@@ -1386,9 +1389,15 @@ INSERT INTO `instance_template` VALUES
|
||||
(409,0,60,0,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(429,0,55,60,5,7200,NULL,NULL,NULL,NULL,''),
|
||||
(469,0,60,0,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(489,0,10,0,50,0,NULL,NULL,NULL,NULL,''),
|
||||
(509,0,60,0,20,259200,NULL,NULL,NULL,NULL,''),
|
||||
(529,0,10,0,50,0,NULL,NULL,NULL,NULL,''),
|
||||
(531,0,60,0,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(533,0,60,0,40,604800,NULL,NULL,NULL,NULL,'');
|
||||
(533,0,60,0,40,604800,NULL,NULL,NULL,NULL,''),
|
||||
(559,0,10,0,50,0,NULL,NULL,NULL,NULL,''),
|
||||
(562,0,10,0,50,0,NULL,NULL,NULL,NULL,''),
|
||||
(566,0,10,0,50,0,NULL,NULL,NULL,NULL,''),
|
||||
(572,0,10,0,50,0,NULL,NULL,NULL,NULL,'');
|
||||
/*!40000 ALTER TABLE `instance_template` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
@@ -2566,8 +2575,24 @@ INSERT INTO `mangos_string` VALUES
|
||||
(708,'%s is Away from Keyboard: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(709,'Do not Disturb',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(710,'Away from Keyboard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(711,'Queue status for %s (Lvl: %u to %u)\nQueued alliances: %u (Need at least %u more)\nQueued hordes: %u (Need at least %u more)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(712,'|cffff0000[BG Queue Announcer]:|r %s -- [%u-%u] A: %u (Need: %u), H: %u (Needs %u)|r',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
(711,'Your group is too large for this battleground. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(712,'Your group is too large for this arena. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(713,'Your group has members not in your arena team. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(714,'Your group does not have enough players to join this match.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(715,'The Gold Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(716,'The Green Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(717, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(718, 'Your group has an offline member. Please remove him before joining.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(719, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(720, 'Your group has players from different battleground brakets. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(721, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(722, 'Someone in your party is Deserter. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(723, 'Someone in your party is already in three battleground queues. You cannot join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(724, 'You cannot teleport to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(725, 'You cannot summon players to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(726, 'You must be in GM mode to teleport to a player in a battleground.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(727, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(728, 'Arena testing turned %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
/*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
DELETE FROM `instance_template` WHERE `map` IN ('489', '30', '529', '566', '559', '562', '572');
|
||||
INSERT INTO `instance_template` (`map`, `parent`, `levelMin`, `levelMax`, `maxPlayers`, `reset_delay`) VALUES
|
||||
('489', '0', '10', '0', '50', '0'),
|
||||
('30', '0', '10', '0', '50', '0'),
|
||||
('529', '0', '10', '0', '50', '0'),
|
||||
('566', '0', '10', '0', '50', '0'),
|
||||
('559', '0', '10', '0', '50', '0'),
|
||||
('562', '0', '10', '0', '50', '0'),
|
||||
('572', '0', '10', '0', '50', '0');
|
||||
|
||||
DELETE FROM `command` WHERE `name` = "flusharenapoints";
|
||||
DELETE FROM `command` WHERE `name` = "debug arena";
|
||||
INSERT INTO `command` (`name`, `security`, `help`) VALUES
|
||||
('flusharenapoints',3,'Syntax: .flusharenapoints\r\n\r\nUse it to distribute arena points based on arena team ratings, and start a new week.'),
|
||||
('debug arena',3,'Syntax: .debug arena\r\n\r\n Toggles arena 1v1 or normal mode.');
|
||||
|
||||
|
||||
DELETE FROM mangos_string WHERE entry BETWEEN 711 AND 728;
|
||||
INSERT INTO mangos_string (entry, content_default) VALUES
|
||||
(711,'Your group is too large for this battleground. Please regroup to join.'),
|
||||
(712,'Your group is too large for this arena. Please regroup to join.'),
|
||||
(713,'Your group has members not in your arena team. Please regroup to join.'),
|
||||
(714,'Your group does not have enough players to join this match.'),
|
||||
(715,'The Gold Team wins!'),
|
||||
(716,'The Green Team wins!'),
|
||||
(717, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.'),
|
||||
(718, 'Your group has an offline member. Please remove him before joining.'),
|
||||
(719, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.'),
|
||||
(720, 'Your group has players from different battleground brakets. You can\'t join as group.'),
|
||||
(721, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.'),
|
||||
(722, 'Someone in your party is Deserter. You can\'t join as group.'),
|
||||
(723, 'Someone in your party is already in three battleground queues. You cannot join as group.'),
|
||||
(724, 'You cannot teleport to a battleground or arena map.'),
|
||||
(725, 'You cannot summon players to a battleground or arena map.'),
|
||||
(726, 'You must be in GM mode to teleport to a player in a battleground.'),
|
||||
(727, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.'),
|
||||
(728, 'Arena testing turned %s');
|
||||
|
||||
+303
-31
@@ -51,7 +51,7 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
|
||||
if(objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist
|
||||
return false;
|
||||
|
||||
sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid));
|
||||
sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(captainGuid));
|
||||
|
||||
CaptainGuid = captainGuid;
|
||||
Name = ArenaTeamName;
|
||||
@@ -138,10 +138,8 @@ bool ArenaTeam::AddMember(uint64 PlayerGuid)
|
||||
{
|
||||
pl->SetInArenaTeam(Id, GetSlot());
|
||||
pl->SetArenaTeamIdInvited(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), Id, PlayerGuid);
|
||||
// personal rating
|
||||
pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5, 1500);
|
||||
}
|
||||
|
||||
// hide promote/remove buttons
|
||||
@@ -149,18 +147,39 @@ bool ArenaTeam::AddMember(uint64 PlayerGuid)
|
||||
{
|
||||
if(pl)
|
||||
pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
|
||||
else
|
||||
Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, PlayerGuid);
|
||||
}
|
||||
|
||||
// setuint32valueindb is asynch, can't be used here
|
||||
Tokens tokens;
|
||||
if(!Player::LoadValuesArrayFromDB(tokens,PlayerGuid))
|
||||
return false;
|
||||
|
||||
// arena team id
|
||||
uint16 index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6);
|
||||
char buf[11];
|
||||
snprintf(buf,11,"%u",Id);
|
||||
tokens[index] = buf;
|
||||
// pers rating
|
||||
index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5;
|
||||
buf[11];
|
||||
snprintf(buf,11,"%u",1500);
|
||||
tokens[index] = buf;
|
||||
// hide promote/remove buttons
|
||||
if(CaptainGuid != PlayerGuid)
|
||||
{
|
||||
index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6);
|
||||
buf[11];
|
||||
snprintf(buf,11,"%u",1);
|
||||
tokens[index] = buf;
|
||||
}
|
||||
|
||||
Player::SaveValuesArrayInDB(tokens,PlayerGuid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
|
||||
{
|
||||
LoadStatsFromDB(ArenaTeamId);
|
||||
LoadMembersFromDB(ArenaTeamId);
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId);
|
||||
|
||||
if(!result)
|
||||
@@ -180,6 +199,22 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
|
||||
|
||||
delete result;
|
||||
|
||||
// only load here, so additional checks can be made
|
||||
LoadStatsFromDB(ArenaTeamId);
|
||||
LoadMembersFromDB(ArenaTeamId);
|
||||
|
||||
if(!GetMembersSize())
|
||||
{
|
||||
// arena team is empty, delete from db
|
||||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId);
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId);
|
||||
CharacterDatabase.CommitTransaction();
|
||||
// return false
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -207,7 +242,7 @@ void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
|
||||
{
|
||||
Field *fields;
|
||||
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT guid,played_week,wons_week,played_season,wons_season FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT guid,played_week,wons_week,played_season,wons_season,points_to_add FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
|
||||
if(!result)
|
||||
return;
|
||||
|
||||
@@ -216,6 +251,14 @@ void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
|
||||
fields = result->Fetch();
|
||||
ArenaTeamMember newmember;
|
||||
newmember.guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
|
||||
// check if this member is in this arenateam
|
||||
// based on character data field
|
||||
if(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6),newmember.guid) != ArenaTeamId)
|
||||
{
|
||||
// the player's registered arena team for this slot isn't this team, so delete member info from here
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE guid = '%u' AND arenateamid = '%u'",fields[0].GetUInt32(), ArenaTeamId);
|
||||
continue;
|
||||
}
|
||||
LoadPlayerStats(&newmember);
|
||||
newmember.played_week = fields[1].GetUInt32();
|
||||
newmember.wons_week = fields[2].GetUInt32();
|
||||
@@ -276,17 +319,36 @@ void ArenaTeam::DelMember(uint64 guid)
|
||||
}
|
||||
|
||||
Player *player = objmgr.GetPlayer(guid);
|
||||
// this will be ugly. because of the asynchronous sql handling, we have to set all the fields of the player at once, and save them at once, or else the save will only modify the last field.
|
||||
// rip off of setuint32valueindb
|
||||
if(player)
|
||||
{
|
||||
player->SetInArenaTeam(0, GetSlot());
|
||||
player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0);
|
||||
}
|
||||
else
|
||||
// delete all info regarding this team
|
||||
for(int i = 0; i < 6; ++i)
|
||||
{
|
||||
Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), 0, guid);
|
||||
player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE guid = '%u'", GUID_LOPART(guid));
|
||||
// we have to do it this way, setuint32valueindb is asynch, unsafe to use multiple times in a row on the same player
|
||||
Tokens tokens;
|
||||
if(!Player::LoadValuesArrayFromDB(tokens,guid))
|
||||
return;
|
||||
|
||||
for(int i = 0; i < 6; ++i)
|
||||
{
|
||||
uint16 index = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i;
|
||||
char buf[11];
|
||||
snprintf(buf,11,"%u",0);
|
||||
tokens[index] = buf;
|
||||
}
|
||||
|
||||
Player::SaveValuesArrayInDB(tokens,guid);
|
||||
|
||||
// only delete from this arena team!
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid));
|
||||
}
|
||||
|
||||
void ArenaTeam::Disband(WorldSession *session)
|
||||
@@ -313,6 +375,7 @@ void ArenaTeam::Disband(WorldSession *session)
|
||||
|
||||
CharacterDatabase.BeginTransaction();
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", Id);
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", Id);
|
||||
CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", Id);
|
||||
CharacterDatabase.CommitTransaction();
|
||||
objmgr.RemoveArenaTeam(this);
|
||||
@@ -342,7 +405,7 @@ void ArenaTeam::Roster(WorldSession *session)
|
||||
data << uint32(itr->wons_week); // wins this week
|
||||
data << uint32(itr->played_season); // played this season
|
||||
data << uint32(itr->wons_season); // wins this season
|
||||
data << uint32(0); // personal rating?
|
||||
data << uint32(pl->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5)); // personal rating?
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -356,7 +419,7 @@ void ArenaTeam::Roster(WorldSession *session)
|
||||
data << uint32(itr->wons_week); // wins this week
|
||||
data << uint32(itr->played_season); // played this season
|
||||
data << uint32(itr->wons_season); // wins this season
|
||||
data << uint32(0); // personal rating?
|
||||
data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, itr->guid)); // personal rating?
|
||||
}
|
||||
}
|
||||
session->SendPacket(&data);
|
||||
@@ -391,6 +454,18 @@ void ArenaTeam::Stats(WorldSession *session)
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
void ArenaTeam::NotifyStatsChanged()
|
||||
{
|
||||
// this is called after a rated match ended
|
||||
// updates arena team stats for every member of the team (not only the ones who participated!)
|
||||
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
Player * plr=objmgr.GetPlayer(itr->guid);
|
||||
if(plr)
|
||||
Stats(plr->GetSession());
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
|
||||
{
|
||||
WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6);
|
||||
@@ -398,10 +473,20 @@ void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
|
||||
data << uint8(GetSlot()); // slot (0...2)
|
||||
data << uint32(GetId()); // arena team id
|
||||
data << uint32(stats.rating); // rating
|
||||
data << uint32(stats.games); // games
|
||||
data << uint32(stats.wins); // wins
|
||||
data << uint32(stats.played); // played (count of all games, that played...)
|
||||
data << uint32(0); // 2.3.3 personal rating?
|
||||
data << uint32(stats.played); // season played
|
||||
data << uint32(stats.wins2); // season wins
|
||||
uint32 participated = 0;
|
||||
for(MemberList::iterator itr = members.begin(); itr!= members.end(); ++itr)
|
||||
{
|
||||
if(itr->guid == guid)
|
||||
{
|
||||
participated = itr->played_season;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data << uint32(participated); // played (count of all games, that the inspected member participated...)
|
||||
data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, guid)); // unk, 2.3.3 (personal rating?)
|
||||
|
||||
session->SendPacket(&data);
|
||||
}
|
||||
|
||||
@@ -494,24 +579,211 @@ bool ArenaTeam::HaveMember( uint64 guid ) const
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 ArenaTeam::GetPoints(uint32 MemberRating)
|
||||
{
|
||||
// returns how many points would be awarded with this team type with this rating
|
||||
float points;
|
||||
|
||||
uint32 rating = MemberRating + 150 < stats.rating ? MemberRating : stats.rating;
|
||||
|
||||
if(rating<=1500)
|
||||
{
|
||||
points = (float)rating * 0.22f + 14.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
|
||||
}
|
||||
|
||||
// type penalties for <5v5 teams
|
||||
if(Type == ARENA_TEAM_2v2)
|
||||
points *= 0.76f;
|
||||
else if(Type == ARENA_TEAM_3v3)
|
||||
points *= 0.88f;
|
||||
|
||||
return (uint32) points;
|
||||
}
|
||||
|
||||
float ArenaTeam::GetChanceAgainst(uint32 rating)
|
||||
{
|
||||
// returns the chance to win against a team with the given rating, used in the rating adjustment calculation
|
||||
// ELO system
|
||||
return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)rating - (float)stats.rating)/400.0f));
|
||||
}
|
||||
|
||||
int32 ArenaTeam::WonAgainstChance(float chance)
|
||||
{
|
||||
// called when the team has won, and had 'chance' calculated chance to beat the opponent
|
||||
// calculate the rating modification (ELO system with k=32)
|
||||
int32 mod = (int32)floor(32.0f * (1.0f - chance));
|
||||
// modify the team stats accordingly
|
||||
stats.rating += mod;
|
||||
stats.games += 1;
|
||||
stats.wins += 1;
|
||||
stats.played += 1;
|
||||
stats.wins2 += 1;
|
||||
/* this should be done in .flusharenapoints; not a breaker though.
|
||||
uint32 higher_rank = 0;
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT DISTINCT COUNT(arenateamid) FROM arena_team_stats WHERE rating > '%u' AND arenateamid <> '%u'",stats.rating, Id);
|
||||
if(result)
|
||||
{
|
||||
higher_rank = result->Fetch()->GetUInt32();
|
||||
delete result;
|
||||
}
|
||||
stats.rank = higher_rank + 1;*/
|
||||
// return the rating change, used to display it on the results screen
|
||||
return mod;
|
||||
}
|
||||
|
||||
int32 ArenaTeam::LostAgainstChance(float chance)
|
||||
{
|
||||
// called when the team has lost, and had 'chance' calculated chance to beat the opponent
|
||||
// calculate the rating modification (ELO system with k=32)
|
||||
int32 mod = (int32)ceil(32.0f * (0.0f - chance));
|
||||
// modify the team stats accordingly
|
||||
stats.rating += mod;
|
||||
stats.games += 1;
|
||||
stats.played += 1;
|
||||
/* uint32 higher_rank = 0;
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT DISTINCT COUNT (arenateamid) FROM arena_team_stats WHERE rating > '%u' AND arenateamid <> '%u'",stats.rating, Id);
|
||||
if(result)
|
||||
{
|
||||
higher_rank = result->Fetch()->GetUInt32();
|
||||
delete result;
|
||||
}
|
||||
stats.rank = higher_rank + 1;*/
|
||||
// return the rating adjustment for display
|
||||
return mod;
|
||||
}
|
||||
|
||||
void ArenaTeam::MemberLost(Player * plr, uint32 againstrating)
|
||||
{
|
||||
// called for each participant of a match after losing
|
||||
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
if(itr->guid == plr->GetGUID())
|
||||
{
|
||||
// update personal rating
|
||||
int32 personalrating = plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5);
|
||||
float chance = 1.0f/(1.0f+exp(log(10.0f)*(float)((float)againstrating - (float)personalrating)/400.0f));
|
||||
int32 mod = (int32)ceil(32.0f * (0.0f - chance));
|
||||
personalrating += mod;
|
||||
if(personalrating < 0)
|
||||
personalrating = 0;
|
||||
plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, personalrating);
|
||||
// update personal played stats
|
||||
itr->played_week +=1;
|
||||
itr->played_season +=1;
|
||||
// update the unit fields
|
||||
plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 2, itr->played_week);
|
||||
plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 3, itr->played_season);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::MemberWon(Player * plr, uint32 againstrating)
|
||||
{
|
||||
// called for each participant after winning a match
|
||||
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
if(itr->guid == plr->GetGUID())
|
||||
{
|
||||
// update personal rating
|
||||
int32 personalrating = plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5);
|
||||
float chance = 1.0f/(1.0f+exp(log(10.0f)*(float)((float)againstrating - (float)personalrating)/400.0f));
|
||||
int32 mod = (int32)floor(32.0f * (1.0f - chance));
|
||||
personalrating += mod;
|
||||
if(personalrating < 0)
|
||||
personalrating = 0;
|
||||
plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, personalrating);
|
||||
// update personal stats
|
||||
itr->played_week +=1;
|
||||
itr->played_season +=1;
|
||||
itr->wons_season += 1;
|
||||
itr->wons_week += 1;
|
||||
// update unit fields
|
||||
plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 2, itr->played_week);
|
||||
plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * GetSlot() + 3, itr->played_season);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::UpdateArenaPointsHelper()
|
||||
{
|
||||
// called after a match has ended and the stats are already modified
|
||||
// helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
|
||||
// 10 played games per week is a minimum
|
||||
if(stats.games < 10)
|
||||
return;
|
||||
// to get points, a player has to participate in at least 30% of the matches
|
||||
uint32 min_plays = ceil(stats.games * 0.3);
|
||||
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
// the player participated in enough games, update his points
|
||||
if(itr->played_week >= min_plays)
|
||||
{
|
||||
// do it separately for online and offline players
|
||||
// online players might have modified personal rating in MemberLost/MemberWon, that's not already saved to DB because of asynch queries
|
||||
// offline player cant have a personal rating not matching the db
|
||||
Player * plr = objmgr.GetPlayer(itr->guid);
|
||||
uint32 points_to_add = 0;
|
||||
if(plr)
|
||||
points_to_add = GetPoints(plr->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5));
|
||||
else
|
||||
points_to_add = GetPoints(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5,itr->guid));
|
||||
// it's enough to set the points in memory, the saving is done in separate function
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, Id, itr->guid);
|
||||
}
|
||||
// the player failed to participate in enough games, so no points for him
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", 0, Id, itr->guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::SaveToDB()
|
||||
{
|
||||
// save team and member stats to db
|
||||
// called after a match has ended
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", stats.rating, stats.games, stats.played, stats.rank, stats.wins, stats.wins2, GetId());
|
||||
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->played_week, itr->wons_week, itr->played_season, itr->wons_season, Id, itr->guid);
|
||||
}
|
||||
}
|
||||
|
||||
void ArenaTeam::FinishWeek()
|
||||
{
|
||||
stats.games = 0; // played this week
|
||||
stats.wins = 0; // wins this week
|
||||
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
|
||||
{
|
||||
itr->played_week = 0;
|
||||
itr->wons_week = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
arenateam fields (id from 2.3.3 client):
|
||||
1414 - arena team id 2v2
|
||||
1415 - 0=captain, 1=member
|
||||
1416 - played this season
|
||||
1417 - played this week
|
||||
1416 - played this week
|
||||
1417 - played this season
|
||||
1418 - unk
|
||||
1419 - unk
|
||||
1419 - personal arena rating
|
||||
1420 - arena team id 3v3
|
||||
1421 - 0=captain, 1=member
|
||||
1422 - played this season
|
||||
1423 - played this week
|
||||
1422 - played this week
|
||||
1423 - played this season
|
||||
1424 - unk
|
||||
1425 - unk
|
||||
1425 - personal arena rating
|
||||
1426 - arena team id 5v5
|
||||
1427 - 0=captain, 1=member
|
||||
1428 - played this season
|
||||
1429 - played this week
|
||||
1428 - played this week
|
||||
1429 - played this season
|
||||
1430 - unk
|
||||
1431 - unk
|
||||
1431 - personal arena rating
|
||||
*/
|
||||
|
||||
@@ -149,6 +149,8 @@ class ArenaTeam
|
||||
void LoadStatsFromDB(uint32 ArenaTeamId);
|
||||
void LoadPlayerStats(ArenaTeamMember* member);
|
||||
|
||||
void SaveToDB();
|
||||
|
||||
void BroadcastPacket(WorldPacket *packet);
|
||||
|
||||
void Roster(WorldSession *session);
|
||||
@@ -156,6 +158,19 @@ class ArenaTeam
|
||||
void Stats(WorldSession *session);
|
||||
void InspectStats(WorldSession *session, uint64 guid);
|
||||
|
||||
uint32 GetPoints(uint32 MemberRating);
|
||||
float GetChanceAgainst(uint32 rating);
|
||||
int32 WonAgainstChance(float chance);
|
||||
void MemberWon(Player * plr, uint32 againstrating);
|
||||
int32 LostAgainstChance(float chance);
|
||||
void MemberLost(Player * plr, uint32 againstrating);
|
||||
|
||||
void UpdateArenaPointsHelper();
|
||||
|
||||
void FinishWeek();
|
||||
|
||||
void NotifyStatsChanged();
|
||||
|
||||
protected:
|
||||
|
||||
uint32 Id;
|
||||
|
||||
+379
-66
@@ -24,6 +24,7 @@
|
||||
#include "Language.h"
|
||||
#include "Chat.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "ArenaTeam.h"
|
||||
#include "World.h"
|
||||
#include "Util.h"
|
||||
|
||||
@@ -47,6 +48,8 @@ BattleGround::BattleGround()
|
||||
m_Name = "";
|
||||
m_LevelMin = 0;
|
||||
m_LevelMax = 0;
|
||||
m_InBGFreeSlotQueue = false;
|
||||
m_SetDeleteThis = false;
|
||||
|
||||
m_MaxPlayersPerTeam = 0;
|
||||
m_MaxPlayers = 0;
|
||||
@@ -67,21 +70,54 @@ BattleGround::BattleGround()
|
||||
m_TeamStartLocO[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamStartLocO[BG_TEAM_HORDE] = 0;
|
||||
|
||||
m_ArenaTeamIds[BG_TEAM_ALLIANCE] = 0;
|
||||
m_ArenaTeamIds[BG_TEAM_HORDE] = 0;
|
||||
|
||||
m_ArenaTeamRatingChanges[BG_TEAM_ALLIANCE] = 0;
|
||||
m_ArenaTeamRatingChanges[BG_TEAM_HORDE] = 0;
|
||||
|
||||
m_BgRaids[BG_TEAM_ALLIANCE] = NULL;
|
||||
m_BgRaids[BG_TEAM_HORDE] = NULL;
|
||||
|
||||
m_PlayersCount[BG_TEAM_ALLIANCE] = 0;
|
||||
m_PlayersCount[BG_TEAM_HORDE] = 0;
|
||||
|
||||
m_PrematureCountDown = false;
|
||||
m_PrematureCountDown = 0;
|
||||
}
|
||||
|
||||
BattleGround::~BattleGround()
|
||||
{
|
||||
// remove objects and creatures
|
||||
// (this is done automatically in mapmanager update, when the instance is reset after the reset time)
|
||||
int size = m_BgCreatures.size();
|
||||
for(int i = 0; i < size; ++i)
|
||||
{
|
||||
DelCreature(i);
|
||||
}
|
||||
size = m_BgObjects.size();
|
||||
for(int i = 0; i < size; ++i)
|
||||
{
|
||||
DelObject(i);
|
||||
}
|
||||
|
||||
// delete creature and go respawn times
|
||||
WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'",GetInstanceID());
|
||||
WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'",GetInstanceID());
|
||||
// delete instance from db
|
||||
CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'",GetInstanceID());
|
||||
// remove from battlegrounds
|
||||
sBattleGroundMgr.RemoveBattleGround(GetInstanceID());
|
||||
// unload map
|
||||
if(Map * map = MapManager::Instance().FindMap(GetMapId(), GetInstanceID()))
|
||||
if(map->IsBattleGroundOrArena())
|
||||
((BattleGroundMap*)map)->SetUnload();
|
||||
// remove from bg free slot queue
|
||||
this->RemoveFromBGFreeSlotQueue();
|
||||
}
|
||||
|
||||
void BattleGround::Update(time_t diff)
|
||||
{
|
||||
|
||||
if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize())
|
||||
//BG is empty
|
||||
return;
|
||||
@@ -188,6 +224,33 @@ void BattleGround::Update(time_t diff)
|
||||
m_ResurrectQueue.clear();
|
||||
}
|
||||
|
||||
// if less then minimum players are in on one side, then start premature finish timer
|
||||
if(GetStatus() == STATUS_IN_PROGRESS && !isArena() && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam()))
|
||||
{
|
||||
if(!m_PrematureCountDown)
|
||||
{
|
||||
m_PrematureCountDown = true;
|
||||
m_PrematureCountDownTimer = sBattleGroundMgr.GetPrematureFinishTime();
|
||||
SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING);
|
||||
}
|
||||
else if(m_PrematureCountDownTimer < diff)
|
||||
{
|
||||
// time's up!
|
||||
EndBattleGround(0); // noone wins
|
||||
m_PrematureCountDown = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 newtime = m_PrematureCountDownTimer - diff;
|
||||
// announce every minute
|
||||
if(m_PrematureCountDownTimer != sBattleGroundMgr.GetPrematureFinishTime() && newtime / 60000 != m_PrematureCountDownTimer / 60000)
|
||||
SendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING);
|
||||
m_PrematureCountDownTimer = newtime;
|
||||
}
|
||||
}
|
||||
else if (m_PrematureCountDown)
|
||||
m_PrematureCountDown = false;
|
||||
|
||||
if(GetStatus() == STATUS_WAIT_LEAVE)
|
||||
{
|
||||
// remove all players from battleground after 2 minutes
|
||||
@@ -239,7 +302,9 @@ void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *
|
||||
if(!self && sender == plr)
|
||||
continue;
|
||||
|
||||
if(plr->GetTeam() == TeamID)
|
||||
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
|
||||
|
||||
if(team == TeamID)
|
||||
plr->GetSession()->SendPacket(packet);
|
||||
}
|
||||
}
|
||||
@@ -265,7 +330,9 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(plr->GetTeam() == TeamID)
|
||||
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
|
||||
|
||||
if(team == TeamID)
|
||||
{
|
||||
sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
@@ -285,7 +352,9 @@ void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(plr->GetTeam() == TeamID)
|
||||
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
|
||||
|
||||
if(team == TeamID)
|
||||
plr->CastSpell(plr, SpellID, true);
|
||||
}
|
||||
}
|
||||
@@ -302,7 +371,9 @@ void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(plr->GetTeam() == TeamID)
|
||||
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
|
||||
|
||||
if(team == TeamID)
|
||||
UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor);
|
||||
}
|
||||
}
|
||||
@@ -324,7 +395,9 @@ void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation,
|
||||
continue;
|
||||
}
|
||||
|
||||
if(plr->GetTeam() == TeamID)
|
||||
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
|
||||
|
||||
if(team == TeamID)
|
||||
plr->ModifyFactionReputation(factionEntry, Reputation);
|
||||
}
|
||||
}
|
||||
@@ -345,30 +418,87 @@ void BattleGround::UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player
|
||||
|
||||
void BattleGround::EndBattleGround(uint32 winner)
|
||||
{
|
||||
// battleground finished, remove from the running bg's list
|
||||
this->RemoveFromBGFreeSlotQueue();
|
||||
|
||||
ArenaTeam * winner_arena_team = NULL;
|
||||
ArenaTeam * loser_arena_team = NULL;
|
||||
uint32 loser_rating = 0;
|
||||
uint32 winner_rating = 0;
|
||||
WorldPacket data;
|
||||
Player *Source = NULL;
|
||||
const char *winmsg = "";
|
||||
|
||||
if(winner == ALLIANCE)
|
||||
{
|
||||
if(isBattleGround())
|
||||
winmsg = GetMangosString(LANG_BG_A_WINS);
|
||||
else
|
||||
winmsg = GetMangosString(LANG_ARENA_GOLD_WINS);
|
||||
|
||||
PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound
|
||||
|
||||
SetWinner(WINNER_ALLIANCE);
|
||||
}
|
||||
else
|
||||
else if(winner == HORDE)
|
||||
{
|
||||
if(isBattleGround())
|
||||
winmsg = GetMangosString(LANG_BG_H_WINS);
|
||||
else
|
||||
winmsg = GetMangosString(LANG_ARENA_GREEN_WINS);
|
||||
|
||||
PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound
|
||||
|
||||
SetWinner(WINNER_HORDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWinner(3);
|
||||
}
|
||||
|
||||
SetStatus(STATUS_WAIT_LEAVE);
|
||||
m_EndTime = 0;
|
||||
|
||||
// arena rating calculation
|
||||
if(isArena() && isRated())
|
||||
{
|
||||
if(winner == ALLIANCE)
|
||||
{
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
|
||||
}
|
||||
else if(winner == HORDE)
|
||||
{
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
|
||||
}
|
||||
if(winner_arena_team && loser_arena_team)
|
||||
{
|
||||
loser_rating = loser_arena_team->GetStats().rating;
|
||||
winner_rating = winner_arena_team->GetStats().rating;
|
||||
float winner_chance = winner_arena_team->GetChanceAgainst(loser_rating);
|
||||
float loser_chance = loser_arena_team->GetChanceAgainst(winner_rating);
|
||||
int32 winner_change = winner_arena_team->WonAgainstChance(winner_chance);
|
||||
int32 loser_change = loser_arena_team->LostAgainstChance(loser_chance);
|
||||
sLog.outDebug("--- %u ; %u ; %d ; %d ; %u ; %u ---",winner_rating,loser_rating,winner_chance,loser_chance,winner_change,loser_change);
|
||||
if(winner == ALLIANCE)
|
||||
{
|
||||
SetArenaTeamRatingChangeForTeam(ALLIANCE, winner_change);
|
||||
SetArenaTeamRatingChangeForTeam(HORDE, loser_change);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetArenaTeamRatingChangeForTeam(HORDE, winner_change);
|
||||
SetArenaTeamRatingChangeForTeam(ALLIANCE, loser_change);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetArenaTeamRatingChangeForTeam(ALLIANCE, 0);
|
||||
SetArenaTeamRatingChangeForTeam(HORDE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for(std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(itr->first);
|
||||
@@ -378,13 +508,29 @@ void BattleGround::EndBattleGround(uint32 winner)
|
||||
continue;
|
||||
}
|
||||
|
||||
// should remove spirit of redemption
|
||||
if(plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
|
||||
plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
|
||||
|
||||
if(!plr->isAlive())
|
||||
{
|
||||
plr->ResurrectPlayer(1.0f);
|
||||
plr->SpawnCorpseBones();
|
||||
}
|
||||
|
||||
if(plr->GetTeam() == winner)
|
||||
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
|
||||
if(!team) team = plr->GetTeam();
|
||||
|
||||
// per player calculation
|
||||
if(isArena() && isRated() && winner_arena_team && loser_arena_team)
|
||||
{
|
||||
if(team == winner)
|
||||
winner_arena_team->MemberWon(plr,loser_rating);
|
||||
else
|
||||
loser_arena_team->MemberLost(plr,winner_rating);
|
||||
}
|
||||
|
||||
if(team == winner)
|
||||
{
|
||||
if(!Source)
|
||||
Source = plr;
|
||||
@@ -404,10 +550,28 @@ void BattleGround::EndBattleGround(uint32 winner)
|
||||
sBattleGroundMgr.BuildPvpLogDataPacket(&data, this);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
|
||||
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
if(isArena() && isRated() && winner_arena_team && loser_arena_team)
|
||||
{
|
||||
// update arena points only after increasing the player's match count!
|
||||
winner_arena_team->UpdateArenaPointsHelper();
|
||||
loser_arena_team->UpdateArenaPointsHelper();
|
||||
// save the stat changes
|
||||
winner_arena_team->SaveToDB();
|
||||
loser_arena_team->SaveToDB();
|
||||
// send updated arena team stats to players
|
||||
// this way all arena team members will get notified, not only the ones who participated in this match
|
||||
winner_arena_team->NotifyStatsChanged();
|
||||
loser_arena_team->NotifyStatsChanged();
|
||||
}
|
||||
|
||||
// inform invited players about the removal
|
||||
sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
|
||||
|
||||
if(Source)
|
||||
{
|
||||
ChatHandler(Source).FillMessageData(&data, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, Source->GetGUID(), winmsg);
|
||||
@@ -558,12 +722,16 @@ void BattleGround::BlockMovement(Player *plr)
|
||||
|
||||
void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket)
|
||||
{
|
||||
uint32 team = GetPlayerTeam(guid);
|
||||
bool participant = false;
|
||||
// Remove from lists/maps
|
||||
std::map<uint64, BattleGroundPlayer>::iterator itr = m_Players.find(guid);
|
||||
if(itr != m_Players.end())
|
||||
{
|
||||
UpdatePlayersCountByTeam(itr->second.Team, true); // -1 player
|
||||
UpdatePlayersCountByTeam(team, true); // -1 player
|
||||
m_Players.erase(itr);
|
||||
// check if the player was a participant of the match, or only entered through gm command (goname)
|
||||
participant = true;
|
||||
}
|
||||
|
||||
std::map<uint64, BattleGroundScore*>::iterator itr2 = m_PlayerScores.find(guid);
|
||||
@@ -577,6 +745,10 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
|
||||
|
||||
Player *plr = objmgr.GetPlayer(guid);
|
||||
|
||||
// should remove spirit of redemption
|
||||
if(plr && plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
|
||||
plr->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT);
|
||||
|
||||
if(plr && !plr->isAlive()) // resurrect on exit
|
||||
{
|
||||
plr->ResurrectPlayer(1.0f);
|
||||
@@ -589,66 +761,106 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
|
||||
{
|
||||
plr->ClearAfkReports();
|
||||
|
||||
if(participant) // if the player was a match participant, remove auras, calc rating, update queue
|
||||
{
|
||||
if(!team) team = plr->GetTeam();
|
||||
|
||||
uint32 bgTypeId = GetTypeID();
|
||||
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());
|
||||
// if arena, remove the specific arena auras
|
||||
if(isArena())
|
||||
{
|
||||
if(!sWorld.IsFFAPvPRealm())
|
||||
plr->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
|
||||
plr->RemoveArenaAuras(true); // removes debuffs / dots etc., we don't want the player to die after porting out
|
||||
bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing)
|
||||
|
||||
// summon old pet if there was one and there isn't a current pet
|
||||
if(!plr->GetPet() && plr->GetTemporaryUnsummonedPetNumber())
|
||||
{
|
||||
Pet* NewPet = new Pet;
|
||||
if(!NewPet->LoadPetFromDB(plr, 0, (plr)->GetTemporaryUnsummonedPetNumber(), true))
|
||||
delete NewPet;
|
||||
|
||||
(plr)->SetTemporaryUnsummonedPetNumber(0);
|
||||
}
|
||||
|
||||
if(isRated() && GetStatus() == STATUS_IN_PROGRESS)
|
||||
{
|
||||
//left a rated match while the encounter was in progress, consider as loser
|
||||
ArenaTeam * winner_arena_team = 0;
|
||||
ArenaTeam * loser_arena_team = 0;
|
||||
if(team == HORDE)
|
||||
{
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
|
||||
}
|
||||
else
|
||||
{
|
||||
winner_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(HORDE));
|
||||
loser_arena_team = objmgr.GetArenaTeamById(GetArenaTeamIdForTeam(ALLIANCE));
|
||||
}
|
||||
if(winner_arena_team && loser_arena_team)
|
||||
{
|
||||
loser_arena_team->MemberLost(plr,winner_arena_team->GetRating());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
if(SendPacket)
|
||||
{
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(m_TypeID), STATUS_NONE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, team, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0);
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
// this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg
|
||||
plr->RemoveBattleGroundQueueId(m_TypeID);
|
||||
plr->RemoveBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
DecreaseInvitedCount(plr->GetTeam());
|
||||
DecreaseInvitedCount(team);
|
||||
//we should update battleground queue, but only if bg isn't ending
|
||||
if (GetQueueType() < MAX_BATTLEGROUND_QUEUES)
|
||||
sBattleGroundMgr.m_BattleGroundQueues[GetTypeID()].Update(GetTypeID(), GetQueueType());
|
||||
|
||||
if(!plr->GetBattleGroundId())
|
||||
return;
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueType());
|
||||
|
||||
Group * group = plr->GetGroup();
|
||||
|
||||
// remove from raid group if exist
|
||||
if(group && group == GetBgRaid(plr->GetTeam()))
|
||||
if(group && group == GetBgRaid(team))
|
||||
{
|
||||
if(!group->RemoveMember(guid, 0)) // group was disbanded
|
||||
{
|
||||
SetBgRaid(plr->GetTeam(), NULL);
|
||||
SetBgRaid(team, NULL);
|
||||
delete group;
|
||||
}
|
||||
}
|
||||
|
||||
// Do next only if found in battleground
|
||||
plr->SetBattleGroundId(0); // We're not in BG.
|
||||
|
||||
// Let others know
|
||||
sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, plr);
|
||||
SendPacketToTeam(plr->GetTeam(), &data, plr, false);
|
||||
SendPacketToTeam(team, &data, plr, false);
|
||||
}
|
||||
|
||||
// Do next only if found in battleground
|
||||
plr->SetBattleGroundId(0); // We're not in BG.
|
||||
// reset destination bg team
|
||||
plr->SetBGTeam(0);
|
||||
|
||||
if(Transport)
|
||||
{
|
||||
plr->TeleportTo(plr->GetBattleGroundEntryPointMap(), plr->GetBattleGroundEntryPointX(), plr->GetBattleGroundEntryPointY(), plr->GetBattleGroundEntryPointZ(), plr->GetBattleGroundEntryPointO());
|
||||
//sLog.outDetail("BATTLEGROUND: Sending %s to %f,%f,%f,%f", pl->GetName(), x,y,z,O);
|
||||
}
|
||||
|
||||
// Log
|
||||
sLog.outDetail("BATTLEGROUND: Removed player %s from BattleGround.", plr->GetName());
|
||||
}
|
||||
|
||||
/// there will be code which will add battleground to BGFreeSlotQueue , when battleground instance will exist
|
||||
// we always should check if BG is in that queue before adding..
|
||||
|
||||
if(!GetPlayersSize())
|
||||
if(!GetPlayersSize() && !GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE))
|
||||
{
|
||||
Reset();
|
||||
// if no players left AND no invitees left, set this bg to delete in next update
|
||||
// direct deletion could cause crashes
|
||||
m_SetDeleteThis = true;
|
||||
// return to prevent addition to freeslotqueue
|
||||
return;
|
||||
}
|
||||
|
||||
// a player exited the battleground, so there are free slots. add to queue
|
||||
this->AddToBGFreeSlotQueue();
|
||||
}
|
||||
|
||||
// this method is called when no players remains in battleground
|
||||
@@ -660,6 +872,8 @@ void BattleGround::Reset()
|
||||
SetStartTime(0);
|
||||
SetEndTime(0);
|
||||
SetLastResurrectTime(0);
|
||||
SetArenaType(0);
|
||||
SetRated(false);
|
||||
|
||||
m_Events = 0;
|
||||
|
||||
@@ -668,11 +882,12 @@ void BattleGround::Reset()
|
||||
|
||||
m_InvitedAlliance = 0;
|
||||
m_InvitedHorde = 0;
|
||||
m_InBGFreeSlotQueue = false;
|
||||
|
||||
m_Players.clear();
|
||||
m_PlayerScores.clear();
|
||||
|
||||
// reset BGSubclass
|
||||
// reset BGSubclass (this cleans up creatures and gos as well)
|
||||
this->ResetBGSubclass();
|
||||
}
|
||||
|
||||
@@ -704,10 +919,13 @@ void BattleGround::AddPlayer(Player *plr)
|
||||
sBattleGroundMgr.BuildPlayerJoinedBattleGroundPacket(&data, plr);
|
||||
SendPacketToTeam(team, &data, plr, false);
|
||||
|
||||
// add arena specific auras
|
||||
if(isArena())
|
||||
{
|
||||
// remove auras first, only then reset spell cooldowns
|
||||
// this is to prevent bugging amp. curse, combustion, etc. like spells
|
||||
plr->RemoveArenaAuras();
|
||||
plr->RemoveArenaSpellCooldowns();
|
||||
//plr->RemoveArenaAuras();
|
||||
plr->RemoveAllEnchantments(TEMP_ENCHANTMENT_SLOT);
|
||||
if(team == ALLIANCE && plr->GetTeam() == ALLIANCE)
|
||||
plr->CastSpell(plr,SPELL_ALLIANCE_GOLD_FLAG,true);
|
||||
@@ -719,6 +937,17 @@ void BattleGround::AddPlayer(Player *plr)
|
||||
plr->CastSpell(plr,SPELL_HORDE_GREEN_FLAG,true);
|
||||
plr->DestroyConjuredItems(true);
|
||||
|
||||
Pet* pet = plr->GetPet();
|
||||
if(pet)
|
||||
{
|
||||
if(pet->getPetType() == SUMMON_PET || pet->getPetType() == HUNTER_PET)
|
||||
{
|
||||
(plr)->SetTemporaryUnsummonedPetNumber(pet->GetCharmInfo()->GetPetNumber());
|
||||
(plr)->SetOldPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL));
|
||||
}
|
||||
(plr)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT);
|
||||
}
|
||||
|
||||
if(GetStatus() == STATUS_WAIT_JOIN) // not started yet
|
||||
{
|
||||
plr->CastSpell(plr, SPELL_ARENA_PREPARATION, true);
|
||||
@@ -733,23 +962,27 @@ void BattleGround::AddPlayer(Player *plr)
|
||||
plr->CastSpell(plr, SPELL_PREPARATION, true); // reduces all mana cost of spells.
|
||||
}
|
||||
|
||||
if(isArena())
|
||||
plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_FFA_PVP);
|
||||
|
||||
// Log
|
||||
sLog.outDetail("BATTLEGROUND: Player %s joined the battle.", plr->GetName());
|
||||
}
|
||||
|
||||
/* This method should be called only once ... it adds pointer to queue */
|
||||
void BattleGround::AddToBGFreeSlotQueue()
|
||||
{
|
||||
// make sure to add only once
|
||||
if(!m_InBGFreeSlotQueue)
|
||||
{
|
||||
sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].push_front(this);
|
||||
m_InBGFreeSlotQueue = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* This method removes this battleground from free queue - it must be called when deleting battleground - not used now*/
|
||||
void BattleGround::RemoveFromBGFreeSlotQueue()
|
||||
{
|
||||
/* uncomment this code when battlegrounds will work like instances
|
||||
// set to be able to re-add if needed
|
||||
m_InBGFreeSlotQueue = false;
|
||||
// uncomment this code when battlegrounds will work like instances
|
||||
for (std::deque<BattleGround*>::iterator itr = sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].begin(); itr != sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetInstanceID() == m_InstanceID)
|
||||
@@ -757,30 +990,66 @@ void BattleGround::RemoveFromBGFreeSlotQueue()
|
||||
sBattleGroundMgr.BGFreeSlotQueue[m_TypeID].erase(itr);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
this method should decide, if we can invite new player of certain team to BG, it is based on BATTLEGROUND_STATUS
|
||||
*/
|
||||
bool BattleGround::HasFreeSlotsForTeam(uint32 Team) const
|
||||
// get the number of free slots for team
|
||||
// works in similar way that HasFreeSlotsForTeam did, but this is needed for join as group
|
||||
uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const
|
||||
{
|
||||
//if BG is starting ... invite anyone:
|
||||
if (GetStatus() == STATUS_WAIT_JOIN)
|
||||
return GetInvitedCount(Team) < GetMaxPlayersPerTeam();
|
||||
return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
|
||||
//if BG is already started .. do not allow to join too much players of one faction
|
||||
uint32 otherTeam;
|
||||
uint32 otherIn;
|
||||
if (Team == ALLIANCE)
|
||||
{
|
||||
otherTeam = GetInvitedCount(HORDE);
|
||||
otherIn = GetPlayersCountByTeam(HORDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
otherTeam = GetInvitedCount(ALLIANCE);
|
||||
otherIn = GetPlayersCountByTeam(ALLIANCE);
|
||||
}
|
||||
if (GetStatus() == STATUS_IN_PROGRESS)
|
||||
return (GetInvitedCount(Team) <= otherTeam && GetInvitedCount(Team) < GetMaxPlayersPerTeam());
|
||||
{
|
||||
// difference based on ppl invited (not necessarily entered battle)
|
||||
// default: allow 0
|
||||
uint32 diff = 0;
|
||||
// allow join one person if the sides are equal (to fill up bg to minplayersperteam)
|
||||
if (otherTeam == GetInvitedCount(Team))
|
||||
diff = 1;
|
||||
// allow join more ppl if the other side has more players
|
||||
else if(otherTeam > GetInvitedCount(Team))
|
||||
diff = otherTeam - GetInvitedCount(Team);
|
||||
|
||||
return false;
|
||||
// difference based on max players per team (don't allow inviting more)
|
||||
uint32 diff2 = (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
|
||||
|
||||
// difference based on players who already entered
|
||||
// default: allow 0
|
||||
uint32 diff3 = 0;
|
||||
// allow join one person if the sides are equal (to fill up bg minplayersperteam)
|
||||
if (otherIn == GetPlayersCountByTeam(Team))
|
||||
diff3 = 1;
|
||||
// allow join more ppl if the other side has more players
|
||||
else if (otherIn > GetPlayersCountByTeam(Team))
|
||||
diff3 = otherIn - GetPlayersCountByTeam(Team);
|
||||
|
||||
// return the minimum of the 3 differences
|
||||
|
||||
// min of diff and diff 2
|
||||
diff = diff < diff2 ? diff : diff2;
|
||||
|
||||
// min of diff, diff2 and diff3
|
||||
return diff < diff3 ? diff : diff3 ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this method isn't called already, it will be useful when more battlegrounds of one type will be available */
|
||||
bool BattleGround::HasFreeSlots() const
|
||||
{
|
||||
return GetPlayersSize() < GetMaxPlayers();
|
||||
@@ -806,9 +1075,13 @@ void BattleGround::UpdatePlayerScore(Player *Source, uint32 type, uint32 value)
|
||||
itr->second->HonorableKills += value;
|
||||
break;
|
||||
case SCORE_BONUS_HONOR: // Honor bonus
|
||||
// do not add honor in arenas
|
||||
if(isBattleGround())
|
||||
{
|
||||
// reward honor instantly
|
||||
if(Source->RewardHonor(NULL, 1, value))
|
||||
itr->second->BonusHonor += value;
|
||||
}
|
||||
break;
|
||||
//used only in EY, but in MSG_PVP_LOG_DATA opcode
|
||||
case SCORE_DAMAGE_DONE: // Damage Done
|
||||
@@ -864,15 +1137,26 @@ void BattleGround::RemovePlayerFromResurrectQueue(uint64 player_guid)
|
||||
|
||||
bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
|
||||
{
|
||||
GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);
|
||||
if(!goinfo)
|
||||
Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID());
|
||||
if(!map)
|
||||
return false;
|
||||
|
||||
// must be created this way, adding to godatamap would add it to the base map of the instance
|
||||
// and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
|
||||
// so we must create it specific for this instance
|
||||
GameObject * go = new GameObject;
|
||||
if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
|
||||
{
|
||||
sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry);
|
||||
sLog.outError("Cannot create gameobject template %u! BattleGround not created!", entry);
|
||||
delete go;
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
uint32 guid = go->GetGUIDLow();
|
||||
|
||||
uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
|
||||
|
||||
// without this, UseButtonOrDoor caused the crash, since it tried to get go info from godata
|
||||
// iirc that was changed, so adding to go data map is no longer required if that was the only function using godata from GameObject without checking if it existed
|
||||
GameObjectData& data = objmgr.NewGOData(guid);
|
||||
|
||||
data.id = entry;
|
||||
@@ -886,13 +1170,13 @@ bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float
|
||||
data.rotation2 = rotation2;
|
||||
data.rotation3 = rotation3;
|
||||
data.spawntimesecs = respawnTime;
|
||||
data.spawnMask = 1;
|
||||
data.animprogress = 100;
|
||||
data.go_state = 1;
|
||||
data.spawnMask = 1;
|
||||
objmgr.AddGameobjectToGrid(guid, &data);
|
||||
|
||||
m_BgObjects[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT);
|
||||
|
||||
*/
|
||||
// add to world, so it can be later looked up from HashMapHolder
|
||||
go->AddToWorld();
|
||||
m_BgObjects[type] = go->GetGUID();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -934,6 +1218,9 @@ void BattleGround::DoorOpen(uint32 type)
|
||||
|
||||
void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime)
|
||||
{
|
||||
Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID());
|
||||
if(!map)
|
||||
return;
|
||||
if( respawntime == 0 )
|
||||
{
|
||||
GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);
|
||||
@@ -942,30 +1229,27 @@ void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime)
|
||||
//we need to change state from GO_JUST_DEACTIVATED to GO_READY in case battleground is starting again
|
||||
if( obj->getLootState() == GO_JUST_DEACTIVATED )
|
||||
obj->SetLootState(GO_READY);
|
||||
obj->Respawn();
|
||||
obj->SetRespawnTime(0);
|
||||
map->Add(obj);
|
||||
}
|
||||
else
|
||||
objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObject *obj = HashMapHolder<GameObject>::Find(m_BgObjects[type]);
|
||||
if(obj)
|
||||
{
|
||||
map->Add(obj);
|
||||
obj->SetRespawnTime(respawntime);
|
||||
obj->SetLootState(GO_JUST_DEACTIVATED);
|
||||
}
|
||||
else
|
||||
objmgr.SaveGORespawnTime(GUID_LOPART(m_BgObjects[type]), 0, time(NULL) + respawntime);
|
||||
}
|
||||
}
|
||||
|
||||
Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o)
|
||||
Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime)
|
||||
{
|
||||
// note: this should normally be FindMap
|
||||
// but it's a hack to allow the battlegrounds to initialize at server startup
|
||||
Map * map = MapManager::Instance().GetMap(GetMapId(), 0);
|
||||
if(!map) return NULL;
|
||||
Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID());
|
||||
if(!map)
|
||||
return NULL;
|
||||
|
||||
Creature* pCreature = new Creature;
|
||||
if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, entry, teamval))
|
||||
@@ -989,6 +1273,7 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f
|
||||
|
||||
map->Add(pCreature);
|
||||
m_BgCreatures[type] = pCreature->GetGUID();
|
||||
|
||||
return pCreature;
|
||||
}
|
||||
|
||||
@@ -1072,8 +1357,11 @@ void BattleGround::SendMessageToAll(int32 entry)
|
||||
|
||||
void BattleGround::EndNow()
|
||||
{
|
||||
RemoveFromBGFreeSlotQueue();
|
||||
SetStatus(STATUS_WAIT_LEAVE);
|
||||
SetEndTime(TIME_TO_AUTOREMOVE);
|
||||
// inform invited players about the removal
|
||||
sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this);
|
||||
}
|
||||
|
||||
// Battleground messages are localized using the dbc lang, they are not client language dependent
|
||||
@@ -1151,3 +1439,28 @@ void BattleGround::HandleKillPlayer( Player *player, Player *killer )
|
||||
// to be able to remove insignia
|
||||
player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE );
|
||||
}
|
||||
|
||||
// return the player's team based on battlegroundplayer info
|
||||
// used in same faction arena matches mainly
|
||||
uint32 BattleGround::GetPlayerTeam(uint64 guid)
|
||||
{
|
||||
std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.find(guid);
|
||||
if(itr!=m_Players.end())
|
||||
return itr->second.Team;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const
|
||||
{
|
||||
int count = 0;
|
||||
for(std::map<uint64, BattleGroundPlayer>::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
if(itr->second.Team == Team)
|
||||
{
|
||||
Player * pl = objmgr.GetPlayer(itr->first);
|
||||
if(pl && pl->isAlive())
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
+53
-1
@@ -143,6 +143,18 @@ enum BattleGroundTypeId
|
||||
BATTLEGROUND_RL = 8
|
||||
};
|
||||
|
||||
// handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time
|
||||
enum BattleGroundQueueTypeId
|
||||
{
|
||||
BATTLEGROUND_QUEUE_AV = 1,
|
||||
BATTLEGROUND_QUEUE_WS = 2,
|
||||
BATTLEGROUND_QUEUE_AB = 3,
|
||||
BATTLEGROUND_QUEUE_EY = 4,
|
||||
BATTLEGROUND_QUEUE_2v2 = 5,
|
||||
BATTLEGROUND_QUEUE_3v3 = 6,
|
||||
BATTLEGROUND_QUEUE_5v5 = 7,
|
||||
};
|
||||
|
||||
enum ScoreType
|
||||
{
|
||||
SCORE_KILLING_BLOWS = 1,
|
||||
@@ -195,6 +207,20 @@ enum BattleGroundTeamId
|
||||
BG_TEAM_HORDE = 1
|
||||
};
|
||||
|
||||
enum BattleGroundJoinError
|
||||
{
|
||||
BG_JOIN_ERR_OK = 0,
|
||||
BG_JOIN_ERR_OFFLINE_MEMBER = 1,
|
||||
BG_JOIN_ERR_GROUP_TOO_MANY = 2,
|
||||
BG_JOIN_ERR_MIXED_FACTION = 3,
|
||||
BG_JOIN_ERR_MIXED_LEVELS = 4,
|
||||
BG_JOIN_ERR_MIXED_ARENATEAM = 5,
|
||||
BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE = 6,
|
||||
BG_JOIN_ERR_GROUP_DESERTER = 7,
|
||||
BG_JOIN_ERR_ALL_QUEUES_USED = 8,
|
||||
BG_JOIN_ERR_GROUP_NOT_ENOUGH = 9
|
||||
};
|
||||
|
||||
class BattleGroundScore
|
||||
{
|
||||
public:
|
||||
@@ -296,6 +322,7 @@ class BattleGround
|
||||
}
|
||||
bool HasFreeSlotsForTeam(uint32 Team) const;
|
||||
bool HasFreeSlots() const;
|
||||
uint32 GetFreeSlotsForTeam(uint32 Team) const;
|
||||
|
||||
bool isArena() const { return m_IsArena; }
|
||||
bool isBattleGround() const { return !m_IsArena; }
|
||||
@@ -366,6 +393,7 @@ class BattleGround
|
||||
|
||||
uint8 GetTeamIndexByTeamId(uint32 Team) const { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; }
|
||||
uint32 GetPlayersCountByTeam(uint32 Team) const { return m_PlayersCount[GetTeamIndexByTeamId(Team)]; }
|
||||
uint32 GetAlivePlayersCountByTeam(uint32 Team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
|
||||
void UpdatePlayersCountByTeam(uint32 Team, bool remove)
|
||||
{
|
||||
if(remove)
|
||||
@@ -374,6 +402,12 @@ class BattleGround
|
||||
++m_PlayersCount[GetTeamIndexByTeamId(Team)];
|
||||
}
|
||||
|
||||
// used for rated arena battles
|
||||
void SetArenaTeamIdForTeam(uint32 Team, uint32 ArenaTeamId) { m_ArenaTeamIds[GetTeamIndexByTeamId(Team)] = ArenaTeamId; }
|
||||
uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; }
|
||||
void SetArenaTeamRatingChangeForTeam(uint32 Team, int32 RatingChange) { m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)] = RatingChange; }
|
||||
int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; }
|
||||
|
||||
/* Triggers handle */
|
||||
// must be implemented in BG subclass
|
||||
virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) {}
|
||||
@@ -390,6 +424,7 @@ class BattleGround
|
||||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(float /*x*/, float /*y*/, float /*z*/, uint32 /*team*/) { return NULL; }
|
||||
|
||||
virtual void AddPlayer(Player *plr); // must be implemented in BG subclass
|
||||
|
||||
virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket);
|
||||
// can be extended in in BG subclass
|
||||
|
||||
@@ -402,7 +437,8 @@ class BattleGround
|
||||
BGCreatures m_BgCreatures;
|
||||
void SpawnBGObject(uint32 type, uint32 respawntime);
|
||||
bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0);
|
||||
Creature* AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o);
|
||||
// void SpawnBGCreature(uint32 type, uint32 respawntime);
|
||||
Creature* AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime = 0);
|
||||
bool DelCreature(uint32 type);
|
||||
bool DelObject(uint32 type);
|
||||
bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team);
|
||||
@@ -411,6 +447,13 @@ class BattleGround
|
||||
void DoorClose(uint32 type);
|
||||
const char *GetMangosString(int32 entry);
|
||||
|
||||
virtual bool HandlePlayerUnderMap(Player * plr) {return false;}
|
||||
|
||||
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
|
||||
uint32 GetPlayerTeam(uint64 guid);
|
||||
|
||||
void SetDeleteThis() {m_SetDeleteThis = true;}
|
||||
|
||||
protected:
|
||||
//this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround
|
||||
void EndNow();
|
||||
@@ -443,6 +486,8 @@ class BattleGround
|
||||
uint32 m_LastResurrectTime;
|
||||
uint32 m_Queue_type;
|
||||
uint8 m_ArenaType; // 2=2v2, 3=3v3, 5=5v5
|
||||
bool m_InBGFreeSlotQueue; // used to make sure that BG is only once inserted into the BattleGroundMgr.BGFreeSlotQueue[bgTypeId] deque
|
||||
bool m_SetDeleteThis; // used for safe deletion of the bg after end / all players leave
|
||||
// this variable is not used .... it can be found in many other ways... but to store it in BG object instance is useless
|
||||
//uint8 m_BattleGroundType; // 3=BG, 4=arena
|
||||
//instead of uint8 (in previous line) is bool used
|
||||
@@ -450,6 +495,8 @@ class BattleGround
|
||||
uint8 m_Winner; // 0=alliance, 1=horde, 2=none
|
||||
int32 m_StartDelayTime;
|
||||
bool m_IsRated; // is this battle rated?
|
||||
bool m_PrematureCountDown;
|
||||
uint32 m_PrematureCountDownTimer;
|
||||
char const *m_Name;
|
||||
|
||||
/* Player lists */
|
||||
@@ -468,6 +515,11 @@ class BattleGround
|
||||
/* Players count by team */
|
||||
uint32 m_PlayersCount[2];
|
||||
|
||||
/* Arena team ids by team */
|
||||
uint32 m_ArenaTeamIds[2];
|
||||
|
||||
int32 m_ArenaTeamRatingChanges[2];
|
||||
|
||||
/* Limits */
|
||||
uint32 m_LevelMin;
|
||||
uint32 m_LevelMax;
|
||||
|
||||
@@ -50,6 +50,13 @@ void BattleGroundAB::Update(time_t diff)
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDebug("Arathi Basin: entering state STATUS_WAIT_JOIN ...");
|
||||
|
||||
// despawn banners, auras and buffs
|
||||
|
||||
@@ -47,6 +47,12 @@ void BattleGroundBE::Update(time_t diff)
|
||||
if (!(m_Events & 0x01))
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
@@ -86,6 +92,11 @@ void BattleGroundBE::Update(time_t diff)
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player *plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
|
||||
|
||||
if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,11 +113,23 @@ void BattleGroundBE::AddPlayer(Player *plr)
|
||||
BattleGroundBEScore* sc = new BattleGroundBEScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
|
||||
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
|
||||
}
|
||||
|
||||
void BattleGroundBE::RemovePlayer(Player *plr, uint64 guid)
|
||||
{
|
||||
if(GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
|
||||
void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
|
||||
@@ -122,15 +145,25 @@ void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer)
|
||||
|
||||
BattleGround::HandleKillPlayer(player,killer);
|
||||
|
||||
uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam());
|
||||
UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
++m_TeamKills[killer_team_index]; // add kills to killer's team
|
||||
|
||||
if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam()))
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(killer->GetTeam());
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
else if(!GetAlivePlayersCountByTeam(HORDE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
bool BattleGroundBE::HandlePlayerUnderMap(Player *player)
|
||||
{
|
||||
player->TeleportTo(GetMapId(),6238.930176,262.963470,0.889519,player->GetOrientation(),false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
@@ -159,10 +192,16 @@ void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
// HandleTriggerBuff(buff_guid,Source);
|
||||
}
|
||||
|
||||
void BattleGroundBE::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0x9f1) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7
|
||||
data << uint32(0x9f0) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8
|
||||
data << uint32(0x9f3) << uint32(1); // 9
|
||||
}
|
||||
|
||||
void BattleGroundBE::ResetBGSubclass()
|
||||
{
|
||||
m_TeamKills[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamKills[BG_TEAM_HORDE] = 0;
|
||||
|
||||
}
|
||||
|
||||
bool BattleGroundBE::SetupBattleGround()
|
||||
|
||||
@@ -64,12 +64,11 @@ class BattleGroundBE : public BattleGround
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
void ResetBGSubclass();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
bool HandlePlayerUnderMap(Player * plr);
|
||||
|
||||
/* Scorekeeping */
|
||||
void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
|
||||
|
||||
private:
|
||||
uint32 m_TeamKills[2]; // count of kills for each team
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -54,6 +54,13 @@ void BattleGroundEY::Update(time_t diff)
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
|
||||
|
||||
@@ -572,7 +579,17 @@ void BattleGroundEY::HandleKillPlayer(Player *player, Player *killer)
|
||||
|
||||
void BattleGroundEY::EventPlayerDroppedFlag(Player *Source)
|
||||
{
|
||||
// Drop allowed in any BG state
|
||||
if(GetStatus() != STATUS_IN_PROGRESS)
|
||||
{
|
||||
// if not running, do not cast things at the dropper player, neither send unnecessary messages
|
||||
// just take off the aura
|
||||
if(IsFlagPickedup() && GetFlagPickerGUID() == Source->GetGUID())
|
||||
{
|
||||
SetFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!IsFlagPickedup())
|
||||
return;
|
||||
|
||||
+485
-154
@@ -26,9 +26,12 @@
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Object.h"
|
||||
#include "Chat.h"
|
||||
#include "Language.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "BattleGroundWS.h"
|
||||
#include "BattleGround.h"
|
||||
#include "ArenaTeam.h"
|
||||
|
||||
void WorldSession::HandleBattleGroundHelloOpcode( WorldPacket & recv_data )
|
||||
{
|
||||
@@ -75,16 +78,23 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
||||
uint32 bgTypeId;
|
||||
uint32 instanceId;
|
||||
uint8 joinAsGroup;
|
||||
Group * grp;
|
||||
|
||||
recv_data >> guid; // battlemaster guid
|
||||
recv_data >> bgTypeId; // battleground type id (DBC id)
|
||||
recv_data >> instanceId; // instance id, 0 if First Available selected
|
||||
recv_data >> joinAsGroup; // join as group
|
||||
|
||||
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from: " I64FMT " for BG (Type: %u)", guid, bgTypeId);
|
||||
|
||||
if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating?
|
||||
if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
|
||||
{
|
||||
sLog.outError("Battleground: invalid bgtype received. possible cheater? player guid %u",_player->GetGUIDLow());
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from: " I64FMT, guid);
|
||||
|
||||
// can do this, since it's battleground, not arena
|
||||
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, 0);
|
||||
|
||||
// ignore if we already in BG or BG queue
|
||||
if(_player->InBattleGround())
|
||||
@@ -97,6 +107,20 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
||||
if(!unit->isBattleMaster()) // it's not battlemaster
|
||||
return;
|
||||
|
||||
// get bg instance or bg template if instance not found
|
||||
BattleGround * bg = 0;
|
||||
if(instanceId)
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId);
|
||||
|
||||
if(!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId)))
|
||||
{
|
||||
sLog.outError("Battleground: no available bg / template found");
|
||||
return;
|
||||
}
|
||||
|
||||
// check queueing conditions
|
||||
if(!joinAsGroup)
|
||||
{
|
||||
// check Deserter debuff
|
||||
if( !_player->CanJoinToBattleground() )
|
||||
{
|
||||
@@ -105,66 +129,128 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
return;
|
||||
}
|
||||
|
||||
// check existence
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId);
|
||||
if(!bg)
|
||||
// check if already in queue
|
||||
if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
//player is already in this queue
|
||||
return;
|
||||
|
||||
if(joinAsGroup && _player->GetGroup())
|
||||
// check if has free queue slots
|
||||
if(!_player->HasFreeBattleGroundQueueId())
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Group *grp = _player->GetGroup();
|
||||
grp = _player->GetGroup();
|
||||
// no group found, error
|
||||
if(!grp)
|
||||
return;
|
||||
uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
|
||||
switch(err)
|
||||
{
|
||||
// TODO: add error-based feedback to players in all cases
|
||||
case BG_JOIN_ERR_GROUP_TOO_MANY:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_TOO_LARGE), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_OFFLINE_MEMBER:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_OFFLINE_MEMBER), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_MIXED_FACTION:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MIXED_FACTION), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_MIXED_LEVELS:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MIXED_LEVELS), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_GROUP_DESERTER:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MEMBER_DESERTER), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_ALL_QUEUES_USED:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
// all ok, can join
|
||||
case BG_JOIN_ERR_OK:
|
||||
break;
|
||||
// these aren't possible outcomes in bgs
|
||||
case BG_JOIN_ERR_GROUP_NOT_ENOUGH:
|
||||
case BG_JOIN_ERR_MIXED_ARENATEAM:
|
||||
return;
|
||||
break;
|
||||
// not the above? shouldn't happen, don't let join
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// if we're here, then the conditions to join a bg are met. We can proceed in joining.
|
||||
|
||||
// _player->GetGroup() was already checked, grp is already initialized
|
||||
if(joinAsGroup /* && _player->GetGroup()*/)
|
||||
{
|
||||
sLog.outDebug("Battleground: the following players are joining as group:");
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0);
|
||||
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player *member = itr->getSource();
|
||||
if(!member) continue;
|
||||
if(!member) continue; // this should never happen
|
||||
|
||||
if( !member->CanJoinToBattleground() )
|
||||
{
|
||||
WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
|
||||
data << (uint32) 0xFFFFFFFE;
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
continue;
|
||||
}
|
||||
if (member->InBattleGroundQueueForBattleGroundType(bgTypeId))
|
||||
//player is already in this queue
|
||||
continue;
|
||||
|
||||
WorldPacket data;
|
||||
// add to queue
|
||||
uint32 queueSlot = member->AddBattleGroundQueueId(bgTypeId);
|
||||
if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
{
|
||||
// fill data packet
|
||||
//member->GetSession()->SendPacket(data);
|
||||
continue;
|
||||
}
|
||||
uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // add to queue
|
||||
|
||||
// store entry point coords (same as leader entry point)
|
||||
member->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
|
||||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].AddPlayer(member, bgTypeId);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(member, ginfo);
|
||||
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
|
||||
}
|
||||
sLog.outDebug("Battleground: group end");
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_player->InBattleGroundQueueForBattleGroundType(bgTypeId))
|
||||
//player is already in this queue
|
||||
return;
|
||||
uint32 queueSlot = _player->AddBattleGroundQueueId(bgTypeId);
|
||||
if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
{
|
||||
WorldPacket data;
|
||||
// fill data packet
|
||||
//SendPacket(data);
|
||||
return;
|
||||
}
|
||||
|
||||
// already checked if queueSlot is valid, now just get it
|
||||
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
|
||||
// store entry point coords
|
||||
_player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
|
||||
|
||||
@@ -172,7 +258,11 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
|
||||
SendPacket(&data);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].AddPlayer(_player, bgTypeId);
|
||||
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel());
|
||||
sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,12 +336,11 @@ void WorldSession::HandleBattleGroundListOpcode( WorldPacket &recv_data )
|
||||
uint32 bgTypeId;
|
||||
recv_data >> bgTypeId; // id from DBC
|
||||
|
||||
if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating?
|
||||
return;
|
||||
|
||||
// can't be received if player not in BG queue
|
||||
if(!_player->InBattleGroundQueueForBattleGroundType(bgTypeId))
|
||||
if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
|
||||
{
|
||||
sLog.outError("Battleground: invalid bgtype received.");
|
||||
return;
|
||||
}
|
||||
|
||||
BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
|
||||
|
||||
@@ -269,82 +358,188 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
|
||||
|
||||
sLog.outDebug( "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message");
|
||||
|
||||
uint8 unk1;
|
||||
uint8 type; // arenatype if arena
|
||||
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
|
||||
uint32 instanceId;
|
||||
uint32 bgTypeId; // type id from dbc
|
||||
uint16 unk; // 0x1F90 constant?
|
||||
uint8 action; // enter battle 0x1, leave queue 0x0
|
||||
|
||||
recv_data >> unk1 >> unk2 >> bgTypeId >> unk >> action;
|
||||
recv_data >> type >> unk2 >> bgTypeId >> unk >> action;
|
||||
|
||||
if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating?
|
||||
return;
|
||||
if(bgTypeId >= MAX_BATTLEGROUND_TYPES)
|
||||
{
|
||||
sLog.outError("Battleground: invalid bgtype received.");
|
||||
// update battleground slots for the player to fix his UI and sent data.
|
||||
// this is a HACK, I don't know why the client starts sending invalid packets in the first place.
|
||||
// it usually happens with extremely high latency (if debugging / stepping in the code for example)
|
||||
if(_player->InBattleGroundQueue())
|
||||
{
|
||||
// update all queues, send invitation info if player is invited, queue info if queued
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
uint32 queue_id = _player->GetBattleGroundQueueId(i);
|
||||
if(!queue_id)
|
||||
continue;
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
|
||||
// if the player is not in queue, contine
|
||||
if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
|
||||
continue;
|
||||
|
||||
if(!_player->InBattleGroundQueueForBattleGroundType(bgTypeId))
|
||||
return;
|
||||
// no group information, this should never happen
|
||||
if(!itrPlayerStatus->second.GroupInfo)
|
||||
continue;
|
||||
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId);
|
||||
BattleGround * bg = NULL;
|
||||
|
||||
// get possibly needed data from groupinfo
|
||||
bgTypeId = itrPlayerStatus->second.GroupInfo->BgTypeId;
|
||||
uint8 arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
|
||||
uint8 israted = itrPlayerStatus->second.GroupInfo->IsRated;
|
||||
uint8 status = 0;
|
||||
|
||||
|
||||
if(!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID)
|
||||
{
|
||||
// not invited to bg, get template
|
||||
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
status = STATUS_WAIT_QUEUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the bg we're invited to
|
||||
BattleGround * bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID);
|
||||
status = STATUS_WAIT_JOIN;
|
||||
}
|
||||
|
||||
// if bg not found, then continue
|
||||
if(!bg)
|
||||
return;
|
||||
continue;
|
||||
|
||||
// don't invite if already in the instance
|
||||
if(_player->InBattleGround() && _player->GetBattleGround() && _player->GetBattleGround()->GetInstanceID() == bg->GetInstanceID())
|
||||
continue;
|
||||
|
||||
// re - invite player with proper data
|
||||
WorldPacket data;
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, itrPlayerStatus->second.GroupInfo->Team?itrPlayerStatus->second.GroupInfo->Team:_player->GetTeam(), i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype, israted);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 bgQueueTypeId = 0;
|
||||
// get the bg what we were invited to
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus;
|
||||
bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId,type);
|
||||
itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
|
||||
|
||||
if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
|
||||
{
|
||||
sLog.outError("Battleground: itrplayerstatus not found.");
|
||||
return;
|
||||
}
|
||||
instanceId = itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID;
|
||||
|
||||
// if action == 1, then instanceId is _required_
|
||||
if(!instanceId && action == 1)
|
||||
{
|
||||
sLog.outError("Battleground: instance not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId);
|
||||
|
||||
// bg template might and must be used in case of leaving queue, when instance is not created yet
|
||||
if(!bg && action == 0)
|
||||
bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
|
||||
if(!bg)
|
||||
{
|
||||
sLog.outError("Battleground: bg not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
bgTypeId = bg->GetTypeID();
|
||||
|
||||
if(_player->InBattleGroundQueue())
|
||||
{
|
||||
uint32 queueSlot = 0;
|
||||
uint32 team = 0;
|
||||
uint32 arenatype = 0;
|
||||
uint32 israted = 0;
|
||||
uint32 rating = 0;
|
||||
// get the team info from the queue
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator pitr = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
|
||||
if(pitr !=sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end()
|
||||
&& pitr->second.GroupInfo )
|
||||
{
|
||||
team = pitr->second.GroupInfo->Team;
|
||||
arenatype = pitr->second.GroupInfo->ArenaType;
|
||||
israted = pitr->second.GroupInfo->IsRated;
|
||||
rating = pitr->second.GroupInfo->ArenaTeamRating;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Battleground: Invalid player queue info!");
|
||||
return;
|
||||
}
|
||||
WorldPacket data;
|
||||
switch(action)
|
||||
{
|
||||
case 1: // port to battleground
|
||||
// cheating?
|
||||
if(!_player->IsInvitedForBattleGroundType(bgTypeId))
|
||||
return;
|
||||
|
||||
// check if player is not deserter
|
||||
if( !_player->CanJoinToBattleground() )
|
||||
{
|
||||
WorldPacket data2;
|
||||
data2.Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
|
||||
data2 << (uint32) 0xFFFFFFFE;
|
||||
SendPacket(&data2);
|
||||
return;
|
||||
}
|
||||
|
||||
// if the player is dead, resurrect him before teleport
|
||||
if(!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId))
|
||||
return; // cheating?
|
||||
// resurrect the player
|
||||
if(!_player->isAlive())
|
||||
{
|
||||
_player->ResurrectPlayer(1.0f,false);
|
||||
_player->SpawnCorpseBones();
|
||||
}
|
||||
|
||||
// leave current group
|
||||
// stop taxi flight at port
|
||||
if(_player->isInFlight())
|
||||
{
|
||||
_player->GetMotionMaster()->MovementExpired();
|
||||
_player->m_taxi.ClearTaxiDestinations();
|
||||
}
|
||||
_player->RemoveFromGroup();
|
||||
|
||||
// packet to player about BG status
|
||||
queueSlot = _player->GetBattleGroundQueueIndex(bgTypeId);
|
||||
queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());
|
||||
_player->GetSession()->SendPacket(&data);
|
||||
|
||||
// remove battleground queue status from BGmgr
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].RemovePlayer(_player->GetGUID(), false);
|
||||
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), false);
|
||||
// this is still needed here if battleground "jumping" shouldn't add deserter debuff
|
||||
// also this required to prevent stuck at old battleground after SetBattleGroundId set to new
|
||||
if( BattleGround *currentBg = _player->GetBattleGround() )
|
||||
currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true);
|
||||
|
||||
_player->SetBattleGroundId(bg->GetTypeID());
|
||||
sBattleGroundMgr.SendToBattleGround(_player, bgTypeId);
|
||||
bg->AddPlayer(_player);
|
||||
// set the destination instance id
|
||||
_player->SetBattleGroundId(bg->GetInstanceID());
|
||||
// set the destination team
|
||||
_player->SetBGTeam(team);
|
||||
// bg->HandleBeforeTeleportToBattleGround(_player);
|
||||
sBattleGroundMgr.SendToBattleGround(_player, instanceId);
|
||||
// add only in HandleMoveWorldPortAck()
|
||||
// bg->AddPlayer(_player,team);
|
||||
sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.",_player->GetName(),_player->GetGUIDLow(),bg->GetInstanceID(),bg->GetTypeID(),bgQueueTypeId);
|
||||
break;
|
||||
case 0: // leave queue
|
||||
queueSlot = _player->GetBattleGroundQueueIndex(bgTypeId);
|
||||
_player->RemoveBattleGroundQueueId(bgTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
|
||||
queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
_player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_NONE, 0, 0);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgTypeId].RemovePlayer(_player->GetGUID(), true);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), true);
|
||||
// player left queue, we should update it, maybe now his group fits in
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId,_player->GetBattleGroundQueueIdFromLevel(),arenatype,israted,rating);
|
||||
SendPacket(&data);
|
||||
sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.",_player->GetName(),_player->GetGUIDLow(),bg->GetTypeID(),bgQueueTypeId);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Battleground port: unknown action %u", action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattleGroundLeaveOpcode( WorldPacket & /*recv_data*/ )
|
||||
{
|
||||
@@ -383,7 +578,8 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
|
||||
BattleGround *bg = _player->GetBattleGround();
|
||||
if(bg)
|
||||
{
|
||||
uint32 queueSlot = _player->GetBattleGroundQueueIndex(bg->GetTypeID());
|
||||
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType());
|
||||
uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
|
||||
if((bg->GetStatus() <= STATUS_IN_PROGRESS))
|
||||
{
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime());
|
||||
@@ -391,15 +587,25 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
|
||||
}
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
uint32 queue_id = _player->GetBattleGroundQueueId(i);
|
||||
if (i == queueSlot || !queue_id)
|
||||
uint32 queue_id = _player->GetBattleGroundQueueId(i); // battlegroundqueueid stores the type id, not the instance id, so this is definitely wrong
|
||||
uint8 arenatype = sBattleGroundMgr.BGArenaType(queue_id);
|
||||
uint8 isRated = 0;
|
||||
if (i == queueSlot || !queue_id) // we need to get the instance ids
|
||||
continue;
|
||||
BattleGround *bg2 = sBattleGroundMgr.GetBattleGround(queue_id);
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
|
||||
if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
|
||||
continue;
|
||||
if(itrPlayerStatus->second.GroupInfo)
|
||||
{
|
||||
arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
|
||||
isRated = itrPlayerStatus->second.GroupInfo->IsRated;
|
||||
}
|
||||
BattleGround *bg2 = sBattleGroundMgr.GetBattleGroundTemplate(sBattleGroundMgr.BGTemplateId(queue_id)); // try this
|
||||
if(bg2)
|
||||
{
|
||||
//in this call is small bug, this call should be filled by player's waiting time in queue
|
||||
//this call nulls all timers for client :
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg2, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0,arenatype,isRated);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
@@ -410,16 +616,36 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ )
|
||||
// we should update all queues? .. i'm not sure if this code is correct
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
if(uint32 queue_id = _player->GetBattleGroundQueueId(i))
|
||||
uint32 queue_id = _player->GetBattleGroundQueueId(i);
|
||||
if(!queue_id)
|
||||
continue;
|
||||
uint32 bgTypeId = sBattleGroundMgr.BGTemplateId(queue_id);
|
||||
uint8 arenatype = sBattleGroundMgr.BGArenaType(queue_id);
|
||||
uint8 isRated = 0;
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID());
|
||||
if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end())
|
||||
continue;
|
||||
if(itrPlayerStatus->second.GroupInfo)
|
||||
{
|
||||
if(BattleGround *bg = sBattleGroundMgr.GetBattleGround(queue_id))
|
||||
arenatype = itrPlayerStatus->second.GroupInfo->ArenaType;
|
||||
isRated = itrPlayerStatus->second.GroupInfo->IsRated;
|
||||
}
|
||||
if(bg && queue_id)
|
||||
{
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), i, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* else // not sure if it needed...
|
||||
{
|
||||
for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, NULL, _player->GetTeam(),i , STATUS_NONE, 0, 0);
|
||||
SendPacket(&data);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void WorldSession::HandleAreaSpiritHealerQueryOpcode( WorldPacket & recv_data )
|
||||
@@ -479,16 +705,12 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
|
||||
if(_player->InBattleGround())
|
||||
return;
|
||||
|
||||
for(int qId = 0; qId < PLAYER_MAX_BATTLEGROUND_QUEUES; ++qId)
|
||||
{
|
||||
if(_player->GetBattleGroundQueueId(qId) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 guid; // arena Battlemaster guid
|
||||
uint8 type; // 2v2, 3v3 or 5v5
|
||||
uint8 asGroup; // asGroup
|
||||
uint8 isRated; // isRated
|
||||
Group * grp;
|
||||
|
||||
recv_data >> guid >> type >> asGroup >> isRated;
|
||||
|
||||
Creature *unit = ObjectAccessor::GetCreature(*_player, guid);
|
||||
@@ -499,6 +721,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
|
||||
return;
|
||||
|
||||
uint8 arenatype = 0;
|
||||
uint32 arenaRating = 0;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
@@ -516,88 +739,196 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
|
||||
return;
|
||||
}
|
||||
|
||||
if(isRated && !_player->GetArenaTeamId(type)) // player not in arena team of that size
|
||||
//check existance
|
||||
BattleGround* bg = NULL;
|
||||
if( !(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA)) )
|
||||
{
|
||||
sLog.outError("Battleground: template bg (all arenas) not found");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 bgTypeId = bg->GetTypeID();
|
||||
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, arenatype);
|
||||
|
||||
// check queueing conditions
|
||||
if(!asGroup)
|
||||
{
|
||||
// check if already in queue
|
||||
if (_player->GetBattleGroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
//player is already in this queue
|
||||
return;
|
||||
// check if has free queue slots
|
||||
if(!_player->HasFreeBattleGroundQueueId())
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
grp = _player->GetGroup();
|
||||
// no group found, error
|
||||
if(!grp)
|
||||
return;
|
||||
uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, arenatype, arenatype, (bool)isRated, type);
|
||||
switch(err)
|
||||
{
|
||||
// TODO: add error-based feedback to players in all cases
|
||||
case BG_JOIN_ERR_GROUP_TOO_MANY:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_ARENA_GROUP_TOO_LARGE), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_GROUP_NOT_ENOUGH:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_ARENA_NOT_ENOUGH_PLAYERS), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_MIXED_ARENATEAM:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_ARENA_YOUR_TEAM_ONLY), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_OFFLINE_MEMBER:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_OFFLINE_MEMBER), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_MIXED_FACTION:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MIXED_FACTION), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_MIXED_LEVELS:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MIXED_LEVELS), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_GROUP_DESERTER:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MEMBER_DESERTER), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
case BG_JOIN_ERR_ALL_QUEUES_USED:
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetMangosString(LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS), NULL);
|
||||
SendPacket(&data);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
// all ok, can join
|
||||
case BG_JOIN_ERR_OK:
|
||||
break;
|
||||
// not the above? shouldn't happen, don't let join
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
uint32 ateamId = 0;
|
||||
|
||||
if(isRated)
|
||||
{
|
||||
ateamId = _player->GetArenaTeamId(type);
|
||||
// check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice)
|
||||
ArenaTeam * at = objmgr.GetArenaTeamById(ateamId);
|
||||
if(!at)
|
||||
{
|
||||
_player->GetSession()->SendNotInArenaTeamPacket(arenatype);
|
||||
return;
|
||||
}
|
||||
|
||||
if(asGroup && !_player->GetGroup()) // player not in group
|
||||
return;
|
||||
|
||||
// check existence
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGround(BATTLEGROUND_AA);
|
||||
if(!bg)
|
||||
return;
|
||||
|
||||
bg->SetArenaType(arenatype);
|
||||
bg->SetRated(isRated);
|
||||
|
||||
if(asGroup && _player->GetGroup())
|
||||
// get the team rating for queueing
|
||||
arenaRating = at->GetRating();
|
||||
// the arenateam id must match for everyone in the group
|
||||
// get the personal ratings for queueing
|
||||
uint32 avg_pers_rating = 0;
|
||||
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Group *grp = _player->GetGroup();
|
||||
Player *member = itr->getSource();
|
||||
|
||||
// calc avg personal rating
|
||||
avg_pers_rating += member->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (type*6) + 5);
|
||||
}
|
||||
|
||||
if( arenatype )
|
||||
avg_pers_rating /= arenatype;
|
||||
|
||||
// if avg personal rating is more than 150 points below the team’s rating, the team will be queued against an opponent matching or similar to the average personal rating
|
||||
if(avg_pers_rating + 150 < arenaRating)
|
||||
arenaRating = avg_pers_rating;
|
||||
}
|
||||
|
||||
if(asGroup)
|
||||
{
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, arenaRating, ateamId);
|
||||
sLog.outDebug("Battleground: arena join as group start");
|
||||
if(isRated)
|
||||
sLog.outDebug("Battleground: arena team id %u, leader %s queued with rating %u for type %u",_player->GetArenaTeamId(type),_player->GetName(),arenaRating,arenatype);
|
||||
for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player *member = itr->getSource();
|
||||
if(!member) continue;
|
||||
|
||||
/*if (!member->CanJoinToBattleground())
|
||||
//player has deserter aura .. do nothing
|
||||
*/
|
||||
|
||||
if (member->InBattleGroundQueueForBattleGroundType(BATTLEGROUND_AA))
|
||||
//player is already in this queue
|
||||
continue;
|
||||
|
||||
// add to queue
|
||||
uint32 queueSlot = member->AddBattleGroundQueueId(BATTLEGROUND_AA);
|
||||
if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
{
|
||||
WorldPacket data;
|
||||
//fill data
|
||||
//member->GetSession()->SendPacket(data);
|
||||
continue;
|
||||
}
|
||||
uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);// add to queue
|
||||
|
||||
// store entry point coords (same as leader entry point)
|
||||
member->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
|
||||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, member->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, BATTLEGROUND_AA);
|
||||
sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId);
|
||||
member->GetSession()->SendPacket(&data);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[BATTLEGROUND_AA].AddPlayer(member, BATTLEGROUND_AA);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(member, ginfo);
|
||||
sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName());
|
||||
}
|
||||
sLog.outDebug("Battleground: arena join as group end");
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(), arenatype, isRated, arenaRating);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*if (!member->CanJoinToBattleground())
|
||||
//player has deserter aura .. do nothing
|
||||
*/
|
||||
|
||||
if (_player->InBattleGroundQueueForBattleGroundType(BATTLEGROUND_AA))
|
||||
//player is already in this queue
|
||||
return;
|
||||
|
||||
uint32 queueSlot = _player->AddBattleGroundQueueId(BATTLEGROUND_AA);
|
||||
if (queueSlot == PLAYER_MAX_BATTLEGROUND_QUEUES)
|
||||
{
|
||||
WorldPacket data;
|
||||
//fill data (player is in 3 queues already)
|
||||
//SendPacket(data);
|
||||
return;
|
||||
}
|
||||
uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId);
|
||||
|
||||
// store entry point coords
|
||||
_player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
|
||||
|
||||
WorldPacket data;
|
||||
// send status packet (in queue)
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0);
|
||||
sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, _player->GetTeam(), queueSlot, STATUS_WAIT_QUEUE, 0, 0, arenatype, isRated);
|
||||
SendPacket(&data);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[BATTLEGROUND_AA].AddPlayer(_player, BATTLEGROUND_AA);
|
||||
GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, arenaRating);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);
|
||||
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(), arenatype, isRated, arenaRating);
|
||||
sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1164
-247
File diff suppressed because it is too large
Load Diff
+106
-34
@@ -34,51 +34,98 @@ typedef std::deque<BattleGround*> BGFreeSlotQueueType;
|
||||
|
||||
#define MAX_BATTLEGROUND_TYPES 9 // each BG type will be in array
|
||||
|
||||
struct PlayerQueueInfo
|
||||
#define MAX_BATTLEGROUND_QUEUE_TYPES 8
|
||||
|
||||
#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
|
||||
|
||||
struct GroupQueueInfo; // type predefinition
|
||||
struct PlayerQueueInfo // stores information for players in queue
|
||||
{
|
||||
uint32 InviteTime; // first invite time
|
||||
uint32 LastInviteTime; // last invite time
|
||||
uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG
|
||||
uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes
|
||||
GroupQueueInfo * GroupInfo; // pointer to the associated groupqueueinfo
|
||||
};
|
||||
|
||||
struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!)
|
||||
{
|
||||
std::map<uint64, PlayerQueueInfo*> Players; // player queue info map
|
||||
uint32 Team; // Player team (ALLIANCE/HORDE)
|
||||
bool IsRated;
|
||||
bool AsGroup; // uint32 GroupId;
|
||||
uint8 ArenaType;
|
||||
};
|
||||
|
||||
struct PlayersCount
|
||||
{
|
||||
uint32 Alliance;
|
||||
uint32 Horde;
|
||||
};
|
||||
|
||||
template<class _Kty, class _Ty> class bgqueue: public std::map<_Kty, _Ty>
|
||||
{
|
||||
public:
|
||||
uint32 Alliance;
|
||||
uint32 Horde;
|
||||
//bool Ready; // not used now
|
||||
//uint32 AverageTime; //not already implemented (it should be average time in queue for last 10 players)
|
||||
bool IsRated; // rated
|
||||
uint32 BgTypeId; // battleground type id
|
||||
uint8 ArenaType; // 2v2, 3v3, 5v5 or 0 when BG
|
||||
uint32 ArenaTeamId; // team id if rated match
|
||||
uint32 JoinTime; // time when group was added
|
||||
uint32 IsInvitedToBGInstanceGUID; // was invited to certain BG
|
||||
uint32 ArenaTeamRating; // if rated match, inited to the rating of the team
|
||||
};
|
||||
|
||||
class BattleGround;
|
||||
class BattleGroundQueue
|
||||
{
|
||||
public:
|
||||
BattleGroundQueue();
|
||||
~BattleGroundQueue();
|
||||
/*
|
||||
uint32 GetType();
|
||||
void SetType(uint32 type);*/
|
||||
|
||||
void Update(uint32 bgTypeId, uint32 queue_id);
|
||||
void Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype = 0, bool isRated = false, uint32 minRating = 0);
|
||||
|
||||
void AddPlayer(Player *plr, uint32 bgTypeId);
|
||||
GroupQueueInfo * AddGroup(Player * leader, uint32 BgTypeId, uint8 ArenaType, bool isRated, uint32 ArenaRating, uint32 ArenaTeamId = 0);
|
||||
void AddPlayer(Player *plr, GroupQueueInfo * ginfo);
|
||||
void RemovePlayer(uint64 guid, bool decreaseInvitedCount);
|
||||
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
|
||||
void BGEndedRemoveInvites(BattleGround * bg);
|
||||
|
||||
typedef bgqueue<uint64, PlayerQueueInfo> QueuedPlayersMap;
|
||||
typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;
|
||||
QueuedPlayersMap m_QueuedPlayers[MAX_BATTLEGROUND_QUEUES];
|
||||
typedef std::list<uint64> PlayerGuidsSortedByTimeQueue;
|
||||
PlayerGuidsSortedByTimeQueue m_PlayersSortedByWaitTime[MAX_BATTLEGROUND_QUEUES];
|
||||
|
||||
typedef std::list<GroupQueueInfo*> QueuedGroupsList;
|
||||
QueuedGroupsList m_QueuedGroups[MAX_BATTLEGROUND_QUEUES];
|
||||
|
||||
// class to hold pointers to the groups eligible for a specific selection pool building mode
|
||||
class EligibleGroups : public std::list<GroupQueueInfo *>
|
||||
{
|
||||
public:
|
||||
void Init(QueuedGroupsList * source, uint32 BgTypeId, uint32 side, uint32 MaxPlayers, uint8 ArenaType = 0, bool IsRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
|
||||
void RemoveGroup(GroupQueueInfo * ginfo);
|
||||
};
|
||||
|
||||
EligibleGroups m_EligibleGroups;
|
||||
|
||||
// class to select and invite groups to bg
|
||||
class SelectionPool
|
||||
{
|
||||
public:
|
||||
void Init();
|
||||
void AddGroup(GroupQueueInfo * group);
|
||||
GroupQueueInfo * GetMaximalGroup();
|
||||
void RemoveGroup(GroupQueueInfo * group);
|
||||
uint32 GetPlayerCount() const {return PlayerCount;}
|
||||
public:
|
||||
std::list<GroupQueueInfo *> SelectedGroups;
|
||||
private:
|
||||
uint32 PlayerCount;
|
||||
GroupQueueInfo * MaxGroup;
|
||||
};
|
||||
|
||||
enum SelectionPoolBuildMode
|
||||
{
|
||||
NORMAL_ALLIANCE,
|
||||
NORMAL_HORDE,
|
||||
ONESIDE_ALLIANCE_TEAM1,
|
||||
ONESIDE_ALLIANCE_TEAM2,
|
||||
ONESIDE_HORDE_TEAM1,
|
||||
ONESIDE_HORDE_TEAM2,
|
||||
|
||||
NUM_SELECTION_POOL_TYPES
|
||||
};
|
||||
|
||||
SelectionPool m_SelectionPools[NUM_SELECTION_POOL_TYPES];
|
||||
|
||||
bool BuildSelectionPool(uint32 bgTypeId, uint32 queue_id, uint32 MinPlayers, uint32 MaxPlayers, SelectionPoolBuildMode mode, uint8 ArenaType = 0, bool isRated = false, uint32 MinRating = 0, uint32 MaxRating = 0, uint32 DisregardTime = 0, uint32 excludeTeam = 0);
|
||||
|
||||
private:
|
||||
|
||||
bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -96,7 +143,6 @@ class BGQueueInviteEvent : public BasicEvent
|
||||
private:
|
||||
uint64 m_PlayerGuid;
|
||||
uint32 m_BgInstanceGUID;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -116,7 +162,6 @@ class BGQueueRemoveEvent : public BasicEvent
|
||||
uint32 m_PlayersTeam;
|
||||
};
|
||||
|
||||
|
||||
class BattleGroundMgr
|
||||
{
|
||||
public:
|
||||
@@ -132,18 +177,18 @@ class BattleGroundMgr
|
||||
void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId);
|
||||
void BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value);
|
||||
void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg);
|
||||
void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2);
|
||||
void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype = 0, uint8 israted = 0);
|
||||
void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid);
|
||||
|
||||
/* Player invitation */
|
||||
// called from Queue update, or from Addplayer to queue
|
||||
void InvitePlayer(Player* plr, uint32 bgInstanceGUID);
|
||||
void InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team);
|
||||
|
||||
/* Battlegrounds */
|
||||
BattleGroundSet::iterator GetBattleGroundsBegin() { return m_BattleGrounds.begin(); };
|
||||
BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); };
|
||||
|
||||
BattleGround* GetBattleGround(uint8 ID)
|
||||
BattleGround* GetBattleGround(uint32 ID)
|
||||
{
|
||||
BattleGroundSet::iterator i = m_BattleGrounds.find(ID);
|
||||
if(i != m_BattleGrounds.end())
|
||||
@@ -152,9 +197,13 @@ class BattleGroundMgr
|
||||
return NULL;
|
||||
};
|
||||
|
||||
BattleGround * GetBattleGroundTemplate(uint32 bgTypeId);
|
||||
BattleGround * CreateNewBattleGround(uint32 bgTypeId);
|
||||
|
||||
uint32 CreateBattleGround(uint32 bgTypeId, 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);
|
||||
|
||||
inline void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; };
|
||||
void RemoveBattleGround(uint32 instanceID);
|
||||
|
||||
void CreateInitialBattleGrounds();
|
||||
|
||||
@@ -162,16 +211,39 @@ class BattleGroundMgr
|
||||
|
||||
/* Battleground queues */
|
||||
//these queues are instantiated when creating BattlegroundMrg
|
||||
BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_TYPES]; // public, because we need to access them in BG handler code
|
||||
BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; // public, because we need to access them in BG handler code
|
||||
|
||||
BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPES];
|
||||
|
||||
void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid);
|
||||
|
||||
bool IsArenaType(uint32 bgTypeId) const;
|
||||
bool IsBattleGroundType(uint32 bgTypeId) const;
|
||||
uint32 BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) const;
|
||||
uint32 BGTemplateId(uint32 bgQueueTypeId) const;
|
||||
uint8 BGArenaType(uint32 bgQueueTypeId) const;
|
||||
|
||||
uint32 GetMaxRatingDifference() const {return m_MaxRatingDifference;}
|
||||
uint32 GetRatingDiscardTimer() const {return m_RatingDiscardTimer;}
|
||||
|
||||
void InitAutomaticArenaPointDistribution();
|
||||
void DistributeArenaPoints();
|
||||
uint32 GetPrematureFinishTime() const {return m_PrematureFinishTimer;}
|
||||
void ToggleArenaTesting();
|
||||
const bool isArenaTesting() const { return m_ArenaTesting; }
|
||||
|
||||
private:
|
||||
|
||||
/* Battlegrounds */
|
||||
BattleGroundSet m_BattleGrounds;
|
||||
uint32 m_MaxRatingDifference;
|
||||
uint32 m_RatingDiscardTimer;
|
||||
uint32 m_NextRatingDiscardUpdate;
|
||||
bool m_AutoDistributePoints;
|
||||
uint64 m_NextAutoDistributionTime;
|
||||
uint32 m_AutoDistributionTimeChecker;
|
||||
uint32 m_PrematureFinishTimer;
|
||||
bool m_ArenaTesting;
|
||||
};
|
||||
|
||||
#define sBattleGroundMgr MaNGOS::Singleton<BattleGroundMgr>::Instance()
|
||||
|
||||
+56
-11
@@ -47,6 +47,12 @@ void BattleGroundNA::Update(time_t diff)
|
||||
if (!(m_Events & 0x01))
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
@@ -73,6 +79,9 @@ void BattleGroundNA::Update(time_t diff)
|
||||
for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
for(uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, 60);
|
||||
|
||||
SendMessageToAll(LANG_ARENA_BEGUN);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
SetStartDelayTime(0);
|
||||
@@ -80,6 +89,11 @@ void BattleGroundNA::Update(time_t diff)
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player *plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
|
||||
|
||||
if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,11 +110,23 @@ void BattleGroundNA::AddPlayer(Player *plr)
|
||||
BattleGroundNAScore* sc = new BattleGroundNAScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
|
||||
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
|
||||
}
|
||||
|
||||
void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/)
|
||||
{
|
||||
if(GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
|
||||
void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
|
||||
@@ -116,15 +142,25 @@ void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer)
|
||||
|
||||
BattleGround::HandleKillPlayer(player,killer);
|
||||
|
||||
uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam());
|
||||
UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
++m_TeamKills[killer_team_index]; // add kills to killer's team
|
||||
|
||||
if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam()))
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(killer->GetTeam());
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
else if(!GetAlivePlayersCountByTeam(HORDE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
bool BattleGroundNA::HandlePlayerUnderMap(Player *player)
|
||||
{
|
||||
player->TeleportTo(GetMapId(),4055.504395,2919.660645,13.611241,player->GetOrientation(),false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
@@ -149,19 +185,28 @@ void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
// HandleTriggerBuff(buff_guid,Source);
|
||||
}
|
||||
|
||||
void BattleGroundNA::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0xa0f) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7
|
||||
data << uint32(0xa10) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8
|
||||
data << uint32(0xa11) << uint32(1); // 9
|
||||
}
|
||||
|
||||
void BattleGroundNA::ResetBGSubclass()
|
||||
{
|
||||
m_TeamKills[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamKills[BG_TEAM_HORDE] = 0;
|
||||
|
||||
}
|
||||
|
||||
bool BattleGroundNA::SetupBattleGround()
|
||||
{
|
||||
// gates
|
||||
if( !AddObject(BG_NA_OBJECT_DOOR_1, BG_NA_OBJECT_TYPE_DOOR_1, 4031.854f, 2966.833f, 12.6462f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_2, BG_NA_OBJECT_TYPE_DOOR_2, 4081.179f, 2874.97f, 12.39171f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_3, BG_NA_OBJECT_TYPE_DOOR_3, 4023.709f, 2981.777f, 10.70117f, -2.648788f, 0, 0, 0.9697962f, -0.2439165f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_4, BG_NA_OBJECT_TYPE_DOOR_4, 4090.064f, 2858.438f, 10.23631f, 0.4928045f, 0, 0, 0.2439165f, 0.9697962f, RESPAWN_IMMEDIATELY))
|
||||
if( !AddObject(BG_NA_OBJECT_DOOR_1, BG_NA_OBJECT_TYPE_DOOR_1, 4031.854, 2966.833, 12.6462, -2.648788, 0, 0, 0.9697962, -0.2439165, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_2, BG_NA_OBJECT_TYPE_DOOR_2, 4081.179, 2874.97, 12.39171, 0.4928045, 0, 0, 0.2439165, 0.9697962, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_3, BG_NA_OBJECT_TYPE_DOOR_3, 4023.709, 2981.777, 10.70117, -2.648788, 0, 0, 0.9697962, -0.2439165, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_NA_OBJECT_DOOR_4, BG_NA_OBJECT_TYPE_DOOR_4, 4090.064, 2858.438, 10.23631, 0.4928045, 0, 0, 0.2439165, 0.9697962, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_NA_OBJECT_BUFF_1, BG_NA_OBJECT_TYPE_BUFF_1, 4009.189941, 2895.250000, 13.052700, -1.448624, 0, 0, 0.6626201, -0.7489557, 120)
|
||||
|| !AddObject(BG_NA_OBJECT_BUFF_2, BG_NA_OBJECT_TYPE_BUFF_2, 4103.330078, 2946.350098, 13.051300, -0.06981307, 0, 0, 0.03489945, -0.9993908, 120))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundNA: Failed to spawn some object!");
|
||||
return false;
|
||||
|
||||
@@ -26,7 +26,9 @@ enum BattleGroundNAObjectTypes
|
||||
BG_NA_OBJECT_DOOR_2 = 1,
|
||||
BG_NA_OBJECT_DOOR_3 = 2,
|
||||
BG_NA_OBJECT_DOOR_4 = 3,
|
||||
BG_NA_OBJECT_MAX = 4
|
||||
BG_NA_OBJECT_BUFF_1 = 4,
|
||||
BG_NA_OBJECT_BUFF_2 = 5,
|
||||
BG_NA_OBJECT_MAX = 6
|
||||
};
|
||||
|
||||
enum BattleGroundNAObjects
|
||||
@@ -34,7 +36,9 @@ enum BattleGroundNAObjects
|
||||
BG_NA_OBJECT_TYPE_DOOR_1 = 183978,
|
||||
BG_NA_OBJECT_TYPE_DOOR_2 = 183980,
|
||||
BG_NA_OBJECT_TYPE_DOOR_3 = 183977,
|
||||
BG_NA_OBJECT_TYPE_DOOR_4 = 183979
|
||||
BG_NA_OBJECT_TYPE_DOOR_4 = 183979,
|
||||
BG_NA_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_NA_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
class BattleGroundNAScore : public BattleGroundScore
|
||||
@@ -61,9 +65,8 @@ class BattleGroundNA : public BattleGround
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
virtual void ResetBGSubclass();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
|
||||
private:
|
||||
uint32 m_TeamKills[2]; // count of kills for each team
|
||||
bool HandlePlayerUnderMap(Player * plr);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -47,6 +47,13 @@ void BattleGroundRL::Update(time_t diff)
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++)
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
|
||||
@@ -73,6 +80,9 @@ void BattleGroundRL::Update(time_t diff)
|
||||
for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; i++)
|
||||
DoorOpen(i);
|
||||
|
||||
for(uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; i++)
|
||||
SpawnBGObject(i, 60);
|
||||
|
||||
SendMessageToAll(LANG_ARENA_BEGUN);
|
||||
SetStatus(STATUS_IN_PROGRESS);
|
||||
SetStartDelayTime(0);
|
||||
@@ -80,6 +90,11 @@ void BattleGroundRL::Update(time_t diff)
|
||||
for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if(Player *plr = objmgr.GetPlayer(itr->first))
|
||||
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
|
||||
|
||||
if(!GetPlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,11 +111,23 @@ void BattleGroundRL::AddPlayer(Player *plr)
|
||||
BattleGroundRLScore* sc = new BattleGroundRLScore;
|
||||
|
||||
m_PlayerScores[plr->GetGUID()] = sc;
|
||||
|
||||
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
|
||||
}
|
||||
|
||||
void BattleGroundRL::RemovePlayer(Player *plr, uint64 guid)
|
||||
{
|
||||
if(GetStatus() == STATUS_WAIT_LEAVE)
|
||||
return;
|
||||
|
||||
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE))
|
||||
EndBattleGround(HORDE);
|
||||
else if(GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE))
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
|
||||
void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
|
||||
@@ -116,15 +143,25 @@ void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer)
|
||||
|
||||
BattleGround::HandleKillPlayer(player,killer);
|
||||
|
||||
uint32 killer_team_index = GetTeamIndexByTeamId(killer->GetTeam());
|
||||
UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE));
|
||||
UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE));
|
||||
|
||||
++m_TeamKills[killer_team_index]; // add kills to killer's team
|
||||
|
||||
if(m_TeamKills[killer_team_index] >= GetPlayersCountByTeam(player->GetTeam()))
|
||||
if(!GetAlivePlayersCountByTeam(ALLIANCE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(killer->GetTeam());
|
||||
EndBattleGround(HORDE);
|
||||
}
|
||||
else if(!GetAlivePlayersCountByTeam(HORDE))
|
||||
{
|
||||
// all opponents killed
|
||||
EndBattleGround(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
bool BattleGroundRL::HandlePlayerUnderMap(Player *player)
|
||||
{
|
||||
player->TeleportTo(GetMapId(),1285.810547,1667.896851,39.957642,player->GetOrientation(),false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
@@ -150,17 +187,26 @@ void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger)
|
||||
// HandleTriggerBuff(buff_guid,Source);
|
||||
}
|
||||
|
||||
void BattleGroundRL::FillInitialWorldStates(WorldPacket &data)
|
||||
{
|
||||
data << uint32(0xbb8) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7
|
||||
data << uint32(0xbb9) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8
|
||||
data << uint32(0xbba) << uint32(1); // 9
|
||||
}
|
||||
|
||||
void BattleGroundRL::ResetBGSubclass()
|
||||
{
|
||||
m_TeamKills[BG_TEAM_ALLIANCE] = 0;
|
||||
m_TeamKills[BG_TEAM_HORDE] = 0;
|
||||
|
||||
}
|
||||
|
||||
bool BattleGroundRL::SetupBattleGround()
|
||||
{
|
||||
// gates
|
||||
if( !AddObject(BG_RL_OBJECT_DOOR_1, BG_RL_OBJECT_TYPE_DOOR_1, 1293.561f, 1601.938f, 31.60557f, -1.457349f, 0, 0, -0.6658813f, 0.7460576f, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RL_OBJECT_DOOR_2, BG_RL_OBJECT_TYPE_DOOR_2, 1278.648f, 1730.557f, 31.60557f, 1.684245f, 0, 0, 0.7460582f, 0.6658807f, RESPAWN_IMMEDIATELY))
|
||||
if( !AddObject(BG_RL_OBJECT_DOOR_1, BG_RL_OBJECT_TYPE_DOOR_1, 1293.561, 1601.938, 31.60557, -1.457349, 0, 0, -0.6658813, 0.7460576, RESPAWN_IMMEDIATELY)
|
||||
|| !AddObject(BG_RL_OBJECT_DOOR_2, BG_RL_OBJECT_TYPE_DOOR_2, 1278.648, 1730.557, 31.60557, 1.684245, 0, 0, 0.7460582, 0.6658807, RESPAWN_IMMEDIATELY)
|
||||
// buffs
|
||||
|| !AddObject(BG_RL_OBJECT_BUFF_1, BG_RL_OBJECT_TYPE_BUFF_1, 1328.719971, 1632.719971, 36.730400, -1.448624, 0, 0, 0.6626201, -0.7489557, 120)
|
||||
|| !AddObject(BG_RL_OBJECT_BUFF_2, BG_RL_OBJECT_TYPE_BUFF_2, 1243.300049, 1699.170044, 34.872601, -0.06981307, 0, 0, 0.03489945, -0.9993908, 120))
|
||||
{
|
||||
sLog.outErrorDb("BatteGroundRL: Failed to spawn some object!");
|
||||
return false;
|
||||
|
||||
@@ -24,13 +24,17 @@ enum BattleGroundRLObjectTypes
|
||||
{
|
||||
BG_RL_OBJECT_DOOR_1 = 0,
|
||||
BG_RL_OBJECT_DOOR_2 = 1,
|
||||
BG_RL_OBJECT_MAX = 2
|
||||
BG_RL_OBJECT_BUFF_1 = 2,
|
||||
BG_RL_OBJECT_BUFF_2 = 3,
|
||||
BG_RL_OBJECT_MAX = 4
|
||||
};
|
||||
|
||||
enum BattleGroundRLObjects
|
||||
{
|
||||
BG_RL_OBJECT_TYPE_DOOR_1 = 185918,
|
||||
BG_RL_OBJECT_TYPE_DOOR_2 = 185917
|
||||
BG_RL_OBJECT_TYPE_DOOR_2 = 185917,
|
||||
BG_RL_OBJECT_TYPE_BUFF_1 = 184663,
|
||||
BG_RL_OBJECT_TYPE_BUFF_2 = 184664
|
||||
};
|
||||
|
||||
class BattleGroundRLScore : public BattleGroundScore
|
||||
@@ -57,9 +61,8 @@ class BattleGroundRL : public BattleGround
|
||||
void HandleAreaTrigger(Player *Source, uint32 Trigger);
|
||||
bool SetupBattleGround();
|
||||
virtual void ResetBGSubclass();
|
||||
virtual void FillInitialWorldStates(WorldPacket &d);
|
||||
void HandleKillPlayer(Player* player, Player *killer);
|
||||
|
||||
private:
|
||||
uint32 m_TeamKills[2]; // count of kills for each team
|
||||
bool HandlePlayerUnderMap(Player * plr);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -49,6 +49,13 @@ void BattleGroundWS::Update(time_t diff)
|
||||
{
|
||||
m_Events |= 0x01;
|
||||
|
||||
// setup here, only when at least one player has ported to the map
|
||||
if(!SetupBattleGround())
|
||||
{
|
||||
EndNow();
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; i++)
|
||||
{
|
||||
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
|
||||
@@ -285,7 +292,32 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source)
|
||||
|
||||
void BattleGroundWS::EventPlayerDroppedFlag(Player *Source)
|
||||
{
|
||||
// Drop allowed in any BG state
|
||||
if(GetStatus() != STATUS_IN_PROGRESS)
|
||||
{
|
||||
// if not running, do not cast things at the dropper player (prevent spawning the "dropped" flag), neither send unnecessary messages
|
||||
// just take off the aura
|
||||
if(Source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
if(!this->IsHordeFlagPickedup())
|
||||
return;
|
||||
if(GetHordeFlagPickerGUID() == Source->GetGUID())
|
||||
{
|
||||
SetHordeFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_WARSONG_FLAG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!this->IsAllianceFlagPickedup())
|
||||
return;
|
||||
if(GetAllianceFlagPickerGUID() == Source->GetGUID())
|
||||
{
|
||||
SetAllianceFlagPicker(0);
|
||||
Source->RemoveAurasDueToSpell(BG_WS_SPELL_SILVERWING_FLAG);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const char *message = "";
|
||||
uint8 type = 0;
|
||||
|
||||
@@ -163,6 +163,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "Mod32Value", SEC_ADMINISTRATOR, &ChatHandler::HandleMod32Value, "", NULL },
|
||||
{ "anim", SEC_GAMEMASTER, &ChatHandler::HandleAnimCommand, "", NULL },
|
||||
{ "lootrecipient", SEC_GAMEMASTER, &ChatHandler::HandleGetLootRecipient, "", NULL },
|
||||
{ "arena", SEC_ADMINISTRATOR, &ChatHandler::HandleDebugArenaCommand, "", NULL },
|
||||
{ NULL, 0, NULL, "", NULL }
|
||||
};
|
||||
|
||||
@@ -511,6 +512,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "cometome", SEC_ADMINISTRATOR, &ChatHandler::HandleComeToMeCommand, "", NULL },
|
||||
{ "damage", SEC_ADMINISTRATOR, &ChatHandler::HandleDamageCommand, "", NULL },
|
||||
{ "combatstop", SEC_GAMEMASTER, &ChatHandler::HandleCombatStopCommand, "", NULL },
|
||||
{ "flusharenapoints", SEC_ADMINISTRATOR, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
|
||||
|
||||
{ NULL, 0, NULL, "", NULL }
|
||||
};
|
||||
|
||||
@@ -380,6 +380,7 @@ class ChatHandler
|
||||
bool HandleCastTargetCommand(const char *args);
|
||||
bool HandleComeToMeCommand(const char *args);
|
||||
bool HandleCombatStopCommand(const char *args);
|
||||
bool HandleFlushArenaPointsCommand(const char *args);
|
||||
|
||||
//! Development Commands
|
||||
bool HandleSetValue(const char* args);
|
||||
@@ -392,6 +393,7 @@ class ChatHandler
|
||||
bool HandleSaveAllCommand(const char* args);
|
||||
bool HandleGetItemState(const char * args);
|
||||
bool HandleGetLootRecipient(const char * args);
|
||||
bool HandleDebugArenaCommand(const char * args);
|
||||
|
||||
Player* getSelectedPlayer();
|
||||
Creature* getSelectedCreature();
|
||||
|
||||
@@ -1244,6 +1244,54 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed )
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
uint32 Group::CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
|
||||
{
|
||||
// check for min / max count
|
||||
uint32 memberscount = GetMembersCount();
|
||||
if(memberscount < MinPlayerCount)
|
||||
return BG_JOIN_ERR_GROUP_NOT_ENOUGH;
|
||||
if(memberscount > MaxPlayerCount)
|
||||
return BG_JOIN_ERR_GROUP_TOO_MANY;
|
||||
|
||||
// get a player as reference, to compare other players' stats to (arena team id, queue id based on level, etc.)
|
||||
Player * reference = GetFirstMember()->getSource();
|
||||
// no reference found, can't join this way
|
||||
if(!reference)
|
||||
return BG_JOIN_ERR_OFFLINE_MEMBER;
|
||||
|
||||
uint32 bgQueueId = reference->GetBattleGroundQueueIdFromLevel();
|
||||
uint32 arenaTeamId = reference->GetArenaTeamId(arenaSlot);
|
||||
uint32 team = reference->GetTeam();
|
||||
|
||||
// check every member of the group to be able to join
|
||||
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player *member = itr->getSource();
|
||||
// offline member? don't let join
|
||||
if(!member)
|
||||
return BG_JOIN_ERR_OFFLINE_MEMBER;
|
||||
// don't allow cross-faction join as group
|
||||
if(member->GetTeam() != team)
|
||||
return BG_JOIN_ERR_MIXED_FACTION;
|
||||
// not in the same battleground level braket, don't let join
|
||||
if(member->GetBattleGroundQueueIdFromLevel() != bgQueueId)
|
||||
return BG_JOIN_ERR_MIXED_LEVELS;
|
||||
// don't let join rated matches if the arena team id doesn't match
|
||||
if(isRated && member->GetArenaTeamId(arenaSlot) != arenaTeamId)
|
||||
return BG_JOIN_ERR_MIXED_ARENATEAM;
|
||||
// don't let join if someone from the group is already in that bg queue
|
||||
if(member->InBattleGroundQueueForBattleGroundQueueType(bgQueueType))
|
||||
return BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE;
|
||||
// check for deserter debuff in case not arena queue
|
||||
if(bgTypeId != BATTLEGROUND_AA && !member->CanJoinToBattleground())
|
||||
return BG_JOIN_ERR_GROUP_DESERTER;
|
||||
// check if member can join any more battleground queues
|
||||
if(!member->HasFreeBattleGroundQueueId())
|
||||
return BG_JOIN_ERR_ALL_QUEUES_USED;
|
||||
}
|
||||
return BG_JOIN_ERR_OK;
|
||||
}
|
||||
|
||||
//===================================================
|
||||
//============== Roll ===============================
|
||||
//===================================================
|
||||
|
||||
@@ -232,6 +232,7 @@ class MANGOS_DLL_SPEC Group
|
||||
SendUpdate();
|
||||
}
|
||||
void SetBattlegroundGroup(BattleGround *bg) { m_bgGroup = bg; }
|
||||
uint32 CanJoinBattleGroundQueue(uint32 bgTypeId, uint32 bgQueueType, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot);
|
||||
|
||||
void ChangeMembersGroup(const uint64 &guid, const uint8 &group);
|
||||
void ChangeMembersGroup(Player *player, const uint8 &group);
|
||||
|
||||
+21
-2
@@ -607,8 +607,27 @@ enum MangosStrings
|
||||
LANG_PLAYER_DND_DEFAULT = 709,
|
||||
LANG_PLAYER_AFK_DEFAULT = 710,
|
||||
|
||||
LANG_BG_QUEUE_ANNOUNCE_SELF = 711,
|
||||
LANG_BG_QUEUE_ANNOUNCE_WORLD = 712,
|
||||
LANG_BG_GROUP_TOO_LARGE = 711,
|
||||
LANG_ARENA_GROUP_TOO_LARGE = 712,
|
||||
LANG_ARENA_YOUR_TEAM_ONLY = 713,
|
||||
LANG_ARENA_NOT_ENOUGH_PLAYERS = 714,
|
||||
LANG_ARENA_GOLD_WINS = 715,
|
||||
LANG_ARENA_GREEN_WINS = 716,
|
||||
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 717,
|
||||
LANG_BG_GROUP_OFFLINE_MEMBER = 718,
|
||||
LANG_BG_GROUP_MIXED_FACTION = 719,
|
||||
LANG_BG_GROUP_MIXED_LEVELS = 720,
|
||||
LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 721,
|
||||
LANG_BG_GROUP_MEMBER_DESERTER = 722,
|
||||
LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 723,
|
||||
|
||||
LANG_CANNOT_TELE_TO_BG = 724,
|
||||
LANG_CANNOT_SUMMON_TO_BG = 725,
|
||||
LANG_CANNOT_GO_TO_BG_GM = 726,
|
||||
LANG_CANNOT_GO_TO_BG_FROM_BG = 727,
|
||||
|
||||
LANG_ARENA_TESTING = 728
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
+52
-3
@@ -315,7 +315,14 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
|
||||
|
||||
Map* pMap = MapManager::Instance().GetMap(m_session->GetPlayer()->GetMapId(),m_session->GetPlayer());
|
||||
|
||||
if(pMap->Instanceable())
|
||||
if(pMap->IsBattleGroundOrArena())
|
||||
{
|
||||
// cannot summon to bg
|
||||
SendSysMessage(LANG_CANNOT_SUMMON_TO_BG);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
else if(pMap->IsDungeon())
|
||||
{
|
||||
Map* cMap = MapManager::Instance().GetMap(chr->GetMapId(),chr);
|
||||
if( cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId() )
|
||||
@@ -401,7 +408,27 @@ bool ChatHandler::HandleGonameCommand(const char* args)
|
||||
if (chr)
|
||||
{
|
||||
Map* cMap = MapManager::Instance().GetMap(chr->GetMapId(),chr);
|
||||
if(cMap->Instanceable())
|
||||
if(cMap->IsBattleGroundOrArena())
|
||||
{
|
||||
// only allow if gm mode is on
|
||||
if (!_player->isGameMaster())
|
||||
{
|
||||
SendSysMessage(LANG_CANNOT_GO_TO_BG_GM);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
// if already in a bg, don't let port to other
|
||||
else if (_player->GetBattleGroundId())
|
||||
{
|
||||
SendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
// all's well, set bg id
|
||||
// when porting out from the bg, it will be reset to 0
|
||||
_player->SetBattleGroundId(chr->GetBattleGroundId());
|
||||
}
|
||||
else if(cMap->IsDungeon())
|
||||
{
|
||||
Map* pMap = MapManager::Instance().GetMap(_player->GetMapId(),_player);
|
||||
|
||||
@@ -1585,7 +1612,6 @@ bool ChatHandler::HandleTeleCommand(const char * args)
|
||||
|
||||
// id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
|
||||
GameTele const* tele = extractGameTeleFromLink((char*)args);
|
||||
|
||||
if (!tele)
|
||||
{
|
||||
SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
|
||||
@@ -1593,6 +1619,14 @@ bool ChatHandler::HandleTeleCommand(const char * args)
|
||||
return false;
|
||||
}
|
||||
|
||||
MapEntry const * me = sMapStore.LookupEntry(tele->mapId);
|
||||
if(!me || me->IsBattleGroundOrArena())
|
||||
{
|
||||
SendSysMessage(LANG_CANNOT_TELE_TO_BG);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// stop flight if need
|
||||
if(_player->isInFlight())
|
||||
{
|
||||
@@ -1865,6 +1899,14 @@ bool ChatHandler::HandleNameTeleCommand(const char * args)
|
||||
return false;
|
||||
}
|
||||
|
||||
MapEntry const * me = sMapStore.LookupEntry(tele->mapId);
|
||||
if(!me || me->IsBattleGroundOrArena())
|
||||
{
|
||||
SendSysMessage(LANG_CANNOT_TELE_TO_BG);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
Player *chr = objmgr.GetPlayer(name.c_str());
|
||||
if (chr)
|
||||
{
|
||||
@@ -1927,6 +1969,13 @@ bool ChatHandler::HandleGroupTeleCommand(const char * args)
|
||||
return false;
|
||||
}
|
||||
|
||||
MapEntry const * me = sMapStore.LookupEntry(tele->mapId);
|
||||
if(!me || me->IsBattleGroundOrArena())
|
||||
{
|
||||
SendSysMessage(LANG_CANNOT_TELE_TO_BG);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
Group *grp = player->GetGroup();
|
||||
if(!grp)
|
||||
{
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "Config/ConfigEnv.h"
|
||||
#include "Util.h"
|
||||
#include "ItemEnchantmentMgr.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "InstanceSaveMgr.h"
|
||||
#include "InstanceData.h"
|
||||
|
||||
@@ -5457,3 +5458,9 @@ bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
|
||||
((InstanceMap*)map)->GetInstanceData()->SaveToDB();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
|
||||
{
|
||||
sBattleGroundMgr.DistributeArenaPoints();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,17 @@ Map* MapInstanced::GetInstance(const WorldObject* obj)
|
||||
uint32 NewInstanceId = 0; // instanceId of the resulting map
|
||||
Player* player = (Player*)obj;
|
||||
|
||||
// TODO: battlegrounds and arenas
|
||||
if(IsBattleGroundOrArena())
|
||||
{
|
||||
// instantiate or find existing bg map for player
|
||||
// the instance id is set in battlegroundid
|
||||
NewInstanceId = player->GetBattleGroundId();
|
||||
assert(NewInstanceId);
|
||||
map = _FindMap(NewInstanceId);
|
||||
if(!map)
|
||||
map = CreateBattleGround(NewInstanceId);
|
||||
return map;
|
||||
}
|
||||
|
||||
InstancePlayerBind *pBind = player->GetBoundInstance(GetId(), player->GetDifficulty());
|
||||
InstanceSave *pSave = pBind ? pBind->save : NULL;
|
||||
|
||||
@@ -107,7 +107,7 @@ MapManager::_GetBaseMap(uint32 id)
|
||||
Guard guard(*this);
|
||||
|
||||
const MapEntry* entry = sMapStore.LookupEntry(id);
|
||||
if (entry && entry->IsDungeon())
|
||||
if (entry && entry->Instanceable())
|
||||
{
|
||||
m = new MapInstanced(id, i_gridCleanUpDelay, 0);
|
||||
}
|
||||
|
||||
@@ -846,6 +846,10 @@ void WorldSession::HandleCorpseReclaimOpcode(WorldPacket &recv_data)
|
||||
if (GetPlayer()->isAlive())
|
||||
return;
|
||||
|
||||
if (BattleGround * bg = _player->GetBattleGround())
|
||||
if(bg->isArena())
|
||||
return;
|
||||
|
||||
// body not released yet
|
||||
if(!GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
|
||||
return;
|
||||
|
||||
@@ -130,22 +130,28 @@ void WorldSession::HandleMoveWorldportAckOpcode()
|
||||
_player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
|
||||
|
||||
// battleground state preper
|
||||
if(_player->InBattleGround())
|
||||
// only add to bg group and object, if the player was invited (else he entered through command)
|
||||
if(_player->InBattleGround() && _player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId()))
|
||||
{
|
||||
BattleGround *bg = _player->GetBattleGround();
|
||||
if(bg)
|
||||
{
|
||||
bg->AddPlayer(_player);
|
||||
if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg
|
||||
{
|
||||
if(!bg->GetBgRaid(_player->GetTeam())) // first player joined
|
||||
// get the team this way, because arenas might 'override' the teams.
|
||||
uint32 team = bg->GetPlayerTeam(_player->GetGUID());
|
||||
if(!team)
|
||||
team = _player->GetTeam();
|
||||
if(!bg->GetBgRaid(team)) // first player joined
|
||||
{
|
||||
Group *group = new Group;
|
||||
bg->SetBgRaid(_player->GetTeam(), group);
|
||||
bg->SetBgRaid(team, group);
|
||||
group->Create(_player->GetGUIDLow(), _player->GetName());
|
||||
}
|
||||
else // raid already exist
|
||||
{
|
||||
bg->GetBgRaid(_player->GetTeam())->AddMember(_player->GetGUID(), _player->GetName());
|
||||
bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -364,6 +370,14 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
if(movementInfo.z < -500.0f)
|
||||
{
|
||||
if(GetPlayer()->InBattleGround()
|
||||
&& GetPlayer()->GetBattleGround()
|
||||
&& GetPlayer()->GetBattleGround()->HandlePlayerUnderMap(_player))
|
||||
{
|
||||
// do nothing, the handle already did if returned true
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this is actually called many times while falling
|
||||
// even after the player has been teleported away
|
||||
@@ -381,6 +395,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
|
||||
GetPlayer()->RepopAtGraveyard();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
|
||||
{
|
||||
|
||||
@@ -310,6 +310,8 @@ class ObjectMgr
|
||||
ArenaTeam* GetArenaTeamByCapitan(uint64 const& guid) const;
|
||||
void AddArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.insert( arenateam ); }
|
||||
void RemoveArenaTeam(ArenaTeam* arenateam) { mArenaTeamSet.erase( arenateam ); }
|
||||
ArenaTeamSet::iterator GetArenaTeamSetBegin() { return mArenaTeamSet.begin(); }
|
||||
ArenaTeamSet::iterator GetArenaTeamSetEnd() { return mArenaTeamSet.end(); }
|
||||
|
||||
static CreatureInfo const *GetCreatureTemplate( uint32 id );
|
||||
CreatureModelInfo const *GetCreatureModelInfo( uint32 modelid );
|
||||
|
||||
+64
-18
@@ -346,8 +346,8 @@ Player::Player (WorldSession *session): Unit()
|
||||
m_bgBattleGroundID = 0;
|
||||
for (int j=0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; j++)
|
||||
{
|
||||
m_bgBattleGroundQueueID[j].bgType = 0;
|
||||
m_bgBattleGroundQueueID[j].invited = false;
|
||||
m_bgBattleGroundQueueID[j].bgQueueType = 0;
|
||||
m_bgBattleGroundQueueID[j].invitedToInstance = 0;
|
||||
}
|
||||
m_bgTeam = 0;
|
||||
|
||||
@@ -1439,7 +1439,8 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
MapEntry const* mEntry = sMapStore.LookupEntry(mapid);
|
||||
|
||||
// don't let enter battlegrounds without assigned battleground id (for example through areatrigger)...
|
||||
if(!InBattleGround() && mEntry->IsBattleGround() && !GetSession()->GetSecurity())
|
||||
// don't let gm level > 1 either
|
||||
if(!InBattleGround() && mEntry->IsBattleGroundOrArena())
|
||||
return false;
|
||||
|
||||
bool tbc = GetSession()->IsTBC() && sWorld.getConfig(CONFIG_EXPANSION) > 0;
|
||||
@@ -3454,6 +3455,29 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
||||
guild->DelMember(guid);
|
||||
}
|
||||
|
||||
// remove from arena teams
|
||||
uint32 at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_2v2);
|
||||
if(at_id != 0)
|
||||
{
|
||||
ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
|
||||
if(at)
|
||||
at->DelMember(playerguid);
|
||||
}
|
||||
at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_3v3);
|
||||
if(at_id != 0)
|
||||
{
|
||||
ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
|
||||
if(at)
|
||||
at->DelMember(playerguid);
|
||||
}
|
||||
at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_5v5);
|
||||
if(at_id != 0)
|
||||
{
|
||||
ArenaTeam * at = objmgr.GetArenaTeamById(at_id);
|
||||
if(at)
|
||||
at->DelMember(playerguid);
|
||||
}
|
||||
|
||||
// the player was uninvited already on logout so just remove from group
|
||||
QueryResult *resultGroup = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", guid);
|
||||
if(resultGroup)
|
||||
@@ -5883,6 +5907,10 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor)
|
||||
// need call before fields update to have chance move yesterday data to appropriate fields before today data change.
|
||||
UpdateHonorFields();
|
||||
|
||||
// do not reward honor in arenas, but return true to enable onkill spellproc
|
||||
if(InBattleGround() && GetBattleGround() && GetBattleGround()->isArena())
|
||||
return true;
|
||||
|
||||
if(honor <= 0)
|
||||
{
|
||||
if(!uVictim || uVictim == this || uVictim->HasAuraType(SPELL_AURA_NO_PVP_CREDIT))
|
||||
@@ -6046,12 +6074,12 @@ uint32 Player::GetRankFromDB(uint64 guid)
|
||||
|
||||
uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
|
||||
{
|
||||
// need fix it!
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid FROM arena_team_member WHERE guid='%u'", GUID_LOPART(guid));
|
||||
if(result)
|
||||
{
|
||||
// init id to 0, check the arena type before assigning a value to id
|
||||
uint32 id = 0;
|
||||
bool found = false;
|
||||
// init id to find the type of the arenateam
|
||||
uint32 id = (*result)[0].GetUInt32();
|
||||
do
|
||||
{
|
||||
QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM arena_team WHERE arenateamid='%u'", id);
|
||||
@@ -6062,13 +6090,13 @@ uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
|
||||
if(dbtype == type)
|
||||
{
|
||||
// if the type matches, we've found the id
|
||||
id = (*result)[0].GetUInt32();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(result->NextRow());
|
||||
delete result;
|
||||
return id;
|
||||
if(found) return id;
|
||||
}
|
||||
// no arenateam for the specified guid, return 0
|
||||
return 0;
|
||||
@@ -7709,19 +7737,34 @@ void Player::SendInitWorldStates()
|
||||
data << uint32(0xa5f) << uint32(0x0); // 35
|
||||
break;
|
||||
case 3698: // Nagrand Arena
|
||||
if (bg && bg->GetTypeID() == BATTLEGROUND_NA)
|
||||
bg->FillInitialWorldStates(data);
|
||||
else
|
||||
{
|
||||
data << uint32(0xa0f) << uint32(0x0); // 7
|
||||
data << uint32(0xa10) << uint32(0x0); // 8
|
||||
data << uint32(0xa11) << uint32(0x0); // 9
|
||||
data << uint32(0xa11) << uint32(0x0); // 9 show
|
||||
}
|
||||
break;
|
||||
case 3702: // Blade's Edge Arena
|
||||
data << uint32(0x9f0) << uint32(0x0); // 7
|
||||
data << uint32(0x9f1) << uint32(0x0); // 8
|
||||
data << uint32(0x9f3) << uint32(0x0); // 9
|
||||
if (bg && bg->GetTypeID() == BATTLEGROUND_BE)
|
||||
bg->FillInitialWorldStates(data);
|
||||
else
|
||||
{
|
||||
data << uint32(0x9f0) << uint32(0x0); // 7 gold
|
||||
data << uint32(0x9f1) << uint32(0x0); // 8 green
|
||||
data << uint32(0x9f3) << uint32(0x0); // 9 show
|
||||
}
|
||||
break;
|
||||
case 3968: // Ruins of Lordaeron
|
||||
data << uint32(0xbb8) << uint32(0x0); // 7
|
||||
data << uint32(0xbb9) << uint32(0x0); // 8
|
||||
data << uint32(0xbba) << uint32(0x0); // 9
|
||||
if (bg && bg->GetTypeID() == BATTLEGROUND_RL)
|
||||
bg->FillInitialWorldStates(data);
|
||||
else
|
||||
{
|
||||
data << uint32(0xbb8) << uint32(0x0); // 7 gold
|
||||
data << uint32(0xbb9) << uint32(0x0); // 8 green
|
||||
data << uint32(0xbba) << uint32(0x0); // 9 show
|
||||
}
|
||||
break;
|
||||
case 3703: // Shattrath City
|
||||
break;
|
||||
@@ -14710,8 +14753,10 @@ void Player::SaveToDB()
|
||||
// first save/honor gain after midnight will also update the player's honor fields
|
||||
UpdateHonorFields();
|
||||
|
||||
// Must saved before enter into BattleGround
|
||||
if(InBattleGround())
|
||||
// players aren't saved on battleground maps
|
||||
uint32 mapid = IsBeingTeleported() ? GetTeleportDest().mapid : GetMapId();
|
||||
const MapEntry * me = sMapStore.LookupEntry(mapid);
|
||||
if(!me || me->IsBattleGroundOrArena())
|
||||
return;
|
||||
|
||||
int is_save_resting = HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0;
|
||||
@@ -17460,7 +17505,8 @@ bool Player::InArena() const
|
||||
|
||||
bool Player::GetBGAccessByLevel(uint32 bgTypeId) const
|
||||
{
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGround(bgTypeId);
|
||||
// get a template bg instead of running one
|
||||
BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
|
||||
if(!bg)
|
||||
return false;
|
||||
|
||||
|
||||
+41
-20
@@ -1802,24 +1802,32 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||
static uint32 GetMaxLevelForBattleGroundQueueId(uint32 queue_id);
|
||||
uint32 GetBattleGroundQueueIdFromLevel() const;
|
||||
|
||||
uint32 GetBattleGroundQueueId(uint32 index) const { return m_bgBattleGroundQueueID[index].bgType; }
|
||||
uint32 GetBattleGroundQueueIndex(uint32 bgType) const
|
||||
bool InBattleGroundQueue() const
|
||||
{
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
if (m_bgBattleGroundQueueID[i].bgType == bgType)
|
||||
if (m_bgBattleGroundQueueID[i].bgQueueType != 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetBattleGroundQueueId(uint32 index) const { return m_bgBattleGroundQueueID[index].bgQueueType; }
|
||||
uint32 GetBattleGroundQueueIndex(uint32 bgQueueType) const
|
||||
{
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
if (m_bgBattleGroundQueueID[i].bgQueueType == bgQueueType)
|
||||
return i;
|
||||
return PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
bool IsInvitedForBattleGroundType(uint32 bgType) const
|
||||
bool IsInvitedForBattleGroundQueueType(uint32 bgQueueType) const
|
||||
{
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
if (m_bgBattleGroundQueueID[i].bgType == bgType)
|
||||
return m_bgBattleGroundQueueID[i].invited;
|
||||
if (m_bgBattleGroundQueueID[i].bgQueueType == bgQueueType)
|
||||
return m_bgBattleGroundQueueID[i].invitedToInstance != 0;
|
||||
return PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
bool InBattleGroundQueueForBattleGroundType(uint32 bgType) const
|
||||
bool InBattleGroundQueueForBattleGroundQueueType(uint32 bgQueueType) const
|
||||
{
|
||||
return GetBattleGroundQueueIndex(bgType) < PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
return GetBattleGroundQueueIndex(bgQueueType) < PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
|
||||
void SetBattleGroundId(uint32 val) { m_bgBattleGroundID = val; }
|
||||
@@ -1827,34 +1835,47 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||
{
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
if (m_bgBattleGroundQueueID[i].bgType == 0 || m_bgBattleGroundQueueID[i].bgType == val)
|
||||
if (m_bgBattleGroundQueueID[i].bgQueueType == 0 || m_bgBattleGroundQueueID[i].bgQueueType == val)
|
||||
{
|
||||
m_bgBattleGroundQueueID[i].bgType = val;
|
||||
m_bgBattleGroundQueueID[i].invited = false;
|
||||
m_bgBattleGroundQueueID[i].bgQueueType = val;
|
||||
m_bgBattleGroundQueueID[i].invitedToInstance = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return PLAYER_MAX_BATTLEGROUND_QUEUES;
|
||||
}
|
||||
bool HasFreeBattleGroundQueueId()
|
||||
{
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
if (m_bgBattleGroundQueueID[i].bgQueueType == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
void RemoveBattleGroundQueueId(uint32 val)
|
||||
{
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
{
|
||||
if (m_bgBattleGroundQueueID[i].bgType == val)
|
||||
if (m_bgBattleGroundQueueID[i].bgQueueType == val)
|
||||
{
|
||||
m_bgBattleGroundQueueID[i].bgType = 0;
|
||||
m_bgBattleGroundQueueID[i].invited = false;
|
||||
m_bgBattleGroundQueueID[i].bgQueueType = 0;
|
||||
m_bgBattleGroundQueueID[i].invitedToInstance = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
void SetInviteForBattleGroundType(uint32 bgType)
|
||||
void SetInviteForBattleGroundQueueType(uint32 bgQueueType, uint32 instanceId)
|
||||
{
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
if (m_bgBattleGroundQueueID[i].bgType == bgType)
|
||||
m_bgBattleGroundQueueID[i].invited = true;
|
||||
if (m_bgBattleGroundQueueID[i].bgQueueType == bgQueueType)
|
||||
m_bgBattleGroundQueueID[i].invitedToInstance = instanceId;
|
||||
}
|
||||
bool IsInvitedForBattleGroundInstance(uint32 instanceId) const
|
||||
{
|
||||
for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++)
|
||||
if (m_bgBattleGroundQueueID[i].invitedToInstance == instanceId)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetBattleGroundEntryPointMap() const { return m_bgEntryPointMap; }
|
||||
float GetBattleGroundEntryPointX() const { return m_bgEntryPointX; }
|
||||
float GetBattleGroundEntryPointY() const { return m_bgEntryPointY; }
|
||||
@@ -2034,8 +2055,8 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||
*/
|
||||
struct BgBattleGroundQueueID_Rec
|
||||
{
|
||||
uint32 bgType;
|
||||
bool invited;
|
||||
uint32 bgQueueType;
|
||||
uint32 invitedToInstance;
|
||||
};
|
||||
BgBattleGroundQueueID_Rec m_bgBattleGroundQueueID[PLAYER_MAX_BATTLEGROUND_QUEUES];
|
||||
uint32 m_bgEntryPointMap;
|
||||
|
||||
@@ -2518,7 +2518,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)
|
||||
return;
|
||||
}
|
||||
|
||||
if(BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgType))
|
||||
if(BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(bgType))
|
||||
bg->SendRewardMarkByMail(player,newitemid,no_space);
|
||||
}
|
||||
}
|
||||
|
||||
+35
-19
@@ -593,25 +593,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
||||
((Creature*)pVictim)->SetLootRecipient(this);
|
||||
if (health <= damage)
|
||||
{
|
||||
// battleground things
|
||||
if(pVictim->GetTypeId() == TYPEID_PLAYER && (((Player*)pVictim)->InBattleGround()))
|
||||
{
|
||||
Player *killed = ((Player*)pVictim);
|
||||
Player *killer = NULL;
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
killer = ((Player*)this);
|
||||
else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
|
||||
{
|
||||
Unit *owner = GetOwner();
|
||||
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
|
||||
killer = ((Player*)owner);
|
||||
}
|
||||
|
||||
if(killer)
|
||||
if(BattleGround *bg = killed->GetBattleGround())
|
||||
bg->HandleKillPlayer(killed, killer); // drop flags and etc
|
||||
}
|
||||
|
||||
DEBUG_LOG("DealDamage: victim just died");
|
||||
|
||||
// find player: owner of controlled `this` or `this` itself maybe
|
||||
@@ -750,6 +731,25 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
||||
|
||||
he->DuelComplete(DUEL_INTERUPTED);
|
||||
}
|
||||
|
||||
// battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill)
|
||||
if(pVictim->GetTypeId() == TYPEID_PLAYER && (((Player*)pVictim)->InBattleGround()))
|
||||
{
|
||||
Player *killed = ((Player*)pVictim);
|
||||
Player *killer = NULL;
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
killer = ((Player*)this);
|
||||
else if(GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
|
||||
{
|
||||
Unit *owner = GetOwner();
|
||||
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
|
||||
killer = ((Player*)owner);
|
||||
}
|
||||
|
||||
if(killer)
|
||||
if(BattleGround *bg = killed->GetBattleGround())
|
||||
bg->HandleKillPlayer(killed, killer); // drop flags and etc
|
||||
}
|
||||
}
|
||||
else // if (health <= damage)
|
||||
{
|
||||
@@ -4143,6 +4143,22 @@ void Unit::RemoveAllAuras()
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::RemoveArenaAuras(bool onleave)
|
||||
{
|
||||
// in join, remove positive buffs, on end, remove negative
|
||||
// used to remove positive visible auras in arenas
|
||||
for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
|
||||
{
|
||||
if ( !(iter->second->GetSpellProto()->AttributesEx4 & (1<<21)) // don't remove stances, shadowform, pally/hunter auras
|
||||
&& !iter->second->IsPassive() // don't remove passive auras
|
||||
&& (!(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) || !(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNK8)) // not unaffected by invulnerability auras or not having that unknown flag (that seemed the most probable)
|
||||
&& (iter->second->IsPositive() ^ onleave)) // remove positive buffs on enter, negative buffs on leave
|
||||
RemoveAura(iter);
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::RemoveAllAurasOnDeath()
|
||||
{
|
||||
// used just after dieing to remove all visible auras
|
||||
|
||||
@@ -1003,6 +1003,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||
void RemoveAurasWithDispelType( DispelType type );
|
||||
|
||||
void RemoveAllAuras();
|
||||
void RemoveArenaAuras(bool onleave = false);
|
||||
void RemoveAllAurasOnDeath();
|
||||
void DelayAura(uint32 spellId, uint32 effindex, int32 delaytime);
|
||||
|
||||
|
||||
+8
-2
@@ -629,8 +629,6 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfig.GetBoolDefault("Instance.IgnoreRaid", false);
|
||||
|
||||
m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER] = sConfig.GetBoolDefault("Battleground.CastDeserter", true);
|
||||
m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", true);
|
||||
m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false);
|
||||
|
||||
m_configs[CONFIG_CAST_UNSTUCK] = sConfig.GetBoolDefault("CastUnstuck", true);
|
||||
m_configs[CONFIG_INSTANCE_RESET_TIME_HOUR] = sConfig.GetIntDefault("Instance.ResetTimeHour", 4);
|
||||
@@ -770,6 +768,13 @@ void World::LoadConfigSettings(bool reload)
|
||||
m_configs[CONFIG_LISTEN_RANGE_YELL] = sConfig.GetIntDefault("ListenRange.Yell", 300);
|
||||
|
||||
|
||||
m_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfig.GetIntDefault("Arena.MaxRatingDifference", 0);
|
||||
m_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfig.GetIntDefault("Arena.RatingDiscardTimer",300000);
|
||||
m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfig.GetBoolDefault("Arena.AutoDistributePoints", false);
|
||||
m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfig.GetIntDefault("Arena.AutoDistributeInterval", 7);
|
||||
|
||||
m_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfig.GetIntDefault("BattleGround.PrematureFinishTimer", 0);
|
||||
|
||||
m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1);
|
||||
if(m_VisibleUnitGreyDistance > MAX_VISIBILITY_DISTANCE)
|
||||
{
|
||||
@@ -1156,6 +1161,7 @@ void World::SetInitialWorldSettings()
|
||||
///- Initialize Battlegrounds
|
||||
sLog.outString( "Starting BattleGround System" );
|
||||
sBattleGroundMgr.CreateInitialBattleGrounds();
|
||||
sBattleGroundMgr.InitAutomaticArenaPointDistribution();
|
||||
|
||||
//Not sure if this can be moved up in the sequence (with static data loading) as it uses MapManager
|
||||
sLog.outString( "Loading Transports..." );
|
||||
|
||||
+5
-2
@@ -101,8 +101,6 @@ enum WorldConfigs
|
||||
CONFIG_INSTANCE_IGNORE_LEVEL,
|
||||
CONFIG_INSTANCE_IGNORE_RAID,
|
||||
CONFIG_BATTLEGROUND_CAST_DESERTER,
|
||||
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
|
||||
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY,
|
||||
CONFIG_INSTANCE_RESET_TIME_HOUR,
|
||||
CONFIG_INSTANCE_UNLOAD_DELAY,
|
||||
CONFIG_CAST_UNSTUCK,
|
||||
@@ -159,6 +157,11 @@ enum WorldConfigs
|
||||
CONFIG_LISTEN_RANGE_SAY,
|
||||
CONFIG_LISTEN_RANGE_TEXTEMOTE,
|
||||
CONFIG_LISTEN_RANGE_YELL,
|
||||
CONFIG_ARENA_MAX_RATING_DIFFERENCE,
|
||||
CONFIG_ARENA_RATING_DISCARD_TIMER,
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
|
||||
CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
|
||||
CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER,
|
||||
CONFIG_VALUE_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "GossipDef.h"
|
||||
#include "Language.h"
|
||||
#include "MapManager.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
|
||||
bool ChatHandler::HandleDebugInArcCommand(const char* /*args*/)
|
||||
{
|
||||
@@ -512,3 +513,9 @@ bool ChatHandler::HandleGetItemState(const char* args)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleDebugArenaCommand(const char * /*args*/)
|
||||
{
|
||||
sBattleGroundMgr.ToggleArenaTesting();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -471,9 +471,10 @@ struct MapEntry
|
||||
|
||||
// Helpers
|
||||
bool IsExpansionMap() const { return addon != 0; }
|
||||
bool Instanceable() const { return map_type == MAP_INSTANCE || map_type == MAP_RAID; }
|
||||
// NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable
|
||||
|
||||
|
||||
bool IsDungeon() const { return map_type == MAP_INSTANCE || map_type == MAP_RAID; }
|
||||
bool Instanceable() const { return map_type == MAP_INSTANCE || map_type == MAP_RAID || map_type == MAP_BATTLEGROUND || map_type == MAP_ARENA; }
|
||||
bool IsRaid() const { return map_type == MAP_RAID; }
|
||||
bool IsBattleGround() const { return map_type == MAP_BATTLEGROUND; }
|
||||
bool IsBattleArena() const { return map_type == MAP_ARENA; }
|
||||
|
||||
@@ -437,16 +437,6 @@ LogColors = ""
|
||||
# Default: 1 (true)
|
||||
# 0 (false)
|
||||
#
|
||||
# Battleground.QueueAnnouncer.Enable
|
||||
# Enable queue announcer posting to chat
|
||||
# Default: 1 (true)
|
||||
# 0 (false)
|
||||
#
|
||||
# Battleground.QueueAnnouncer.PlayerOnly
|
||||
# Enable queue announcer posting to chat
|
||||
# Default: 0 (false)
|
||||
# 1 (true)
|
||||
#
|
||||
# CastUnstuck
|
||||
# Allow cast or not Unstuck spell at .start or client Help option use
|
||||
# Default: 1 (true)
|
||||
@@ -537,8 +527,6 @@ MaxArenaPoints = 5000
|
||||
StartPlayerLevel = 1
|
||||
ActivateWeather = 1
|
||||
Battleground.CastDeserter = 1
|
||||
Battleground.QueueAnnouncer.Enable = 1
|
||||
Battleground.QueueAnnouncer.PlayerOnly = 0
|
||||
CastUnstuck = 1
|
||||
Instance.IgnoreLevel = 0
|
||||
Instance.IgnoreRaid = 0
|
||||
@@ -1025,3 +1013,43 @@ Ra.IP = 0.0.0.0
|
||||
Ra.Port = 3443
|
||||
Ra.MinLevel = 3
|
||||
Ra.Secure = 1
|
||||
|
||||
###################################################################################################################
|
||||
#
|
||||
# Rated arena matches config
|
||||
#
|
||||
# MaxRatingDifference: the maximum rating difference between two groups in rated matches
|
||||
# Default: 0 (disable, rating difference is discarded)
|
||||
#
|
||||
# RatingDiscardTimer: after the specified milliseconds has passed,
|
||||
# rating information will be discarded when selecting teams for matches
|
||||
# also initiates an update by this timer
|
||||
# Default: 60000
|
||||
#
|
||||
# AutoDistributePoints: set if arena points should be distributed automatically, or by GM command
|
||||
# Default: 0 (disable) (recommended): use gm command or sql query to distribute the points
|
||||
# 1 (enable): arena points are distributed automatically
|
||||
#
|
||||
# AutoDistributeInterval: how often should the distribution take place
|
||||
# if automatic distribution is enabled
|
||||
# in days
|
||||
# Default: 7 (weekly)
|
||||
#
|
||||
###################################################################################################################
|
||||
|
||||
Arena.MaxRatingDifference = 0
|
||||
Arena.RatingDiscardTimer = 60000
|
||||
Arena.AutoDistributePoints = 0
|
||||
Arena.AutoDistributeInterval = 7
|
||||
|
||||
###################################################################################################################
|
||||
#
|
||||
# Battleground config
|
||||
#
|
||||
# PrematureFinishTimer: the time to end the bg if there are less than minplayersperteam on one side
|
||||
# in milliseconds, 0 - disabled
|
||||
# Default: 0
|
||||
#
|
||||
###################################################################################################################
|
||||
|
||||
BattleGround.PrematureFinishTimer = 0
|
||||
|
||||
Reference in New Issue
Block a user