aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormegamage <none@none>2008-12-19 16:05:13 -0600
committermegamage <none@none>2008-12-19 16:05:13 -0600
commit400f7b859693eef1043a75a18c369dd871ffb721 (patch)
tree5f480c9380d4125a57cbeb4315ef22ad2ab32a71 /src
parentcebaa3a703f36efeedc5fd786b6eacb7a93585c2 (diff)
*Temp fix for crash caused by AV creature. Need to find a way to allow summoned creatures to use RandomMovement.
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/game/ArenaTeam.cpp310
-rw-r--r--src/game/ArenaTeam.h96
-rw-r--r--src/game/ArenaTeamHandler.cpp71
-rw-r--r--src/game/BattleGround.cpp96
-rw-r--r--src/game/BattleGround.h4
-rw-r--r--src/game/BattleGroundAB.cpp1
-rw-r--r--src/game/BattleGroundAV.cpp2
-rw-r--r--src/game/BattleGroundEY.cpp4
-rw-r--r--src/game/BattleGroundHandler.cpp233
-rw-r--r--src/game/BattleGroundMgr.cpp225
-rw-r--r--src/game/BattleGroundMgr.h6
-rw-r--r--src/game/BattleGroundWS.cpp3
-rw-r--r--src/game/Channel.cpp9
-rw-r--r--src/game/Channel.h2
-rw-r--r--src/game/CharacterHandler.cpp82
-rw-r--r--src/game/Chat.cpp2
-rw-r--r--src/game/Chat.h2
-rw-r--r--src/game/GameEvent.cpp2
-rw-r--r--src/game/Guild.cpp2
-rw-r--r--src/game/Language.h46
-rw-r--r--src/game/Level1.cpp20
-rw-r--r--src/game/Level2.cpp1
-rw-r--r--src/game/Level3.cpp18
-rw-r--r--src/game/MiscHandler.cpp6
-rw-r--r--src/game/MovementHandler.cpp2
-rw-r--r--src/game/ObjectMgr.cpp52
-rw-r--r--src/game/ObjectMgr.h20
-rw-r--r--src/game/PetitionsHandler.cpp211
-rw-r--r--src/game/Player.cpp103
-rw-r--r--src/game/Player.h13
-rw-r--r--src/game/SharedDefines.h24
-rw-r--r--src/game/Spell.cpp32
-rw-r--r--src/game/World.cpp59
-rw-r--r--src/game/World.h16
-rw-r--r--src/game/WorldSession.h6
-rw-r--r--src/game/debugcmds.cpp4
-rw-r--r--src/shared/Database/DBCEnums.h8
-rw-r--r--src/shared/Database/DBCStructure.h9
-rw-r--r--src/trinitycore/Master.cpp2
-rw-r--r--src/trinitycore/trinitycore.conf.dist86
40 files changed, 980 insertions, 910 deletions
diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp
index 5fd72b3545f..5f1dfdb93d7 100644
--- a/src/game/ArenaTeam.cpp
+++ b/src/game/ArenaTeam.cpp
@@ -1,7 +1,5 @@
/*
- * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
- *
- * Copyright (C) 2008 Trinity <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,7 +44,7 @@ ArenaTeam::~ArenaTeam()
}
-bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamName)
+bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName)
{
if(!objmgr.GetPlayer(captainGuid)) // player not exist
return false;
@@ -59,13 +57,7 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
Name = ArenaTeamName;
Type = type;
- QueryResult *result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
- if( result )
- {
- Id = (*result)[0].GetUInt32()+1;
- delete result;
- }
- else Id = 1;
+ Id = objmgr.GenerateArenaTeamId();
// ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
CharacterDatabase.escape_string(ArenaTeamName);
@@ -75,9 +67,9 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", Id);
CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
"VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')",
- Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor);
+ Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor, EmblemStyle, EmblemColor, BorderStyle, BorderColor);
CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
- "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id,stats.rating,stats.games_week,stats.wins_week,stats.games_season,stats.wins_season,stats.rank);
+ "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id, stats.rating, stats.games_week, stats.wins_week, stats.games_season, stats.wins_season, stats.rank);
CharacterDatabase.CommitTransaction();
@@ -85,7 +77,7 @@ bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
return true;
}
-bool ArenaTeam::AddMember(uint64 PlayerGuid)
+bool ArenaTeam::AddMember(const uint64& PlayerGuid)
{
std::string plName;
uint8 plClass;
@@ -137,36 +129,20 @@ bool ArenaTeam::AddMember(uint64 PlayerGuid)
newmember.games_week = 0;
newmember.wins_season = 0;
newmember.wins_week = 0;
- //newmember.personal_rating = 1500;
+ newmember.personal_rating = 1500;
members.push_back(newmember);
- CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid,guid) VALUES ('%u', '%u')", Id, GUID_LOPART(newmember.guid));
+ CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid, personal_rating) VALUES ('%u', '%u', '%u')", Id, GUID_LOPART(newmember.guid), newmember.personal_rating );
if(pl)
{
pl->SetInArenaTeam(Id, GetSlot());
pl->SetArenaTeamIdInvited(0);
+ pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, newmember.personal_rating );
// hide promote/remove buttons
if(CaptainGuid != PlayerGuid)
- pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
- // TODO: personal_rating
- pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5, 1500);
- }
- else
- {
- Tokens tokens;
- if(Player::LoadValuesArrayFromDB(tokens,PlayerGuid))
- {
- Player::SetUInt32ValueInArray(tokens,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), Id);
- // hide promote/remove buttons
- if(CaptainGuid != PlayerGuid)
- Player::SetUInt32ValueInArray(tokens,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
- // TODO: personal_rating
- Player::SetUInt32ValueInArray(tokens,PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 5, 1500);
-
- Player::SaveValuesArrayInDB(tokens,PlayerGuid);
- }
+ pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 1, 1);
}
return true;
}
@@ -196,7 +172,7 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
LoadStatsFromDB(ArenaTeamId);
LoadMembersFromDB(ArenaTeamId);
- if(!GetMembersSize())
+ if(Empty())
{
// arena team is empty, delete from db
CharacterDatabase.BeginTransaction();
@@ -204,7 +180,6 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 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;
}
@@ -233,57 +208,37 @@ void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId)
void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
{
- Field *fields;
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT guid,games_week,wins_week,games_season,wins_season,points_to_add FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
+ // 0 1 2 3 4 5 6 7
+ QueryResult *result = CharacterDatabase.PQuery("SELECT member.guid,played_week,wons_week,played_season,wons_season,personal_rating,name,class "
+ "FROM arena_team_member member "
+ "INNER JOIN characters chars on member.guid = chars.guid "
+ "WHERE member.arenateamid = '%u'", ArenaTeamId);
if(!result)
return;
do
{
- fields = result->Fetch();
+ Field *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.games_week = fields[1].GetUInt32();
newmember.wins_week = fields[2].GetUInt32();
newmember.games_season = fields[3].GetUInt32();
newmember.wins_season = fields[4].GetUInt32();
+ newmember.personal_rating = fields[5].GetUInt32();
+ newmember.name = fields[6].GetCppString();
+ newmember.Class = fields[7].GetUInt8();
members.push_back(newmember);
}while( result->NextRow() );
delete result;
}
-void ArenaTeam::LoadPlayerStats(ArenaTeamMember *member)
-{
- Field *fields;
-
- QueryResult *result = CharacterDatabase.PQuery("SELECT name,class FROM characters WHERE guid = '%u'", GUID_LOPART(member->guid));
- if(!result)
- return;
- fields = result->Fetch();
- member->name = fields[0].GetCppString();
- member->Class = fields[1].GetUInt8();
-
- delete result;
-}
-
-void ArenaTeam::SetCaptain(uint64 guid)
+void ArenaTeam::SetCaptain(const uint64& guid)
{
// disable remove/promote buttons
Player *oldcaptain = objmgr.GetPlayer(GetCaptain());
if(oldcaptain)
oldcaptain->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, GetCaptain());
// set new captain
CaptainGuid = guid;
@@ -295,14 +250,11 @@ void ArenaTeam::SetCaptain(uint64 guid)
Player *newcaptain = objmgr.GetPlayer(guid);
if(newcaptain)
newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0);
- else
- Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0, guid);
}
void ArenaTeam::DelMember(uint64 guid)
{
- MemberList::iterator itr;
- for (itr = members.begin(); itr != members.end(); itr++)
+ for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
{
if (itr->guid == guid)
{
@@ -312,8 +264,7 @@ 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());
@@ -325,22 +276,6 @@ void ArenaTeam::DelMember(uint64 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));
}
@@ -351,24 +286,15 @@ void ArenaTeam::Disband(WorldSession *session)
session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), "");
BroadcastPacket(&data);
- uint32 count = members.size();
- uint64 *memberGuids = new uint64[count];
-
- MemberList::iterator itr;
- uint32 i=0;
- for(itr = members.begin(); itr != members.end(); itr++)
+ while (!members.empty())
{
- memberGuids[i] = itr->guid;
- ++i;
+ // Removing from members is done in DelMember.
+ DelMember(members.front().guid);
}
- for(uint32 j = 0; j < count; j++)
- DelMember(memberGuids[j]);
- delete[] memberGuids;
-
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_member WHERE arenateamid = '%u'", Id); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member
CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", Id);
CharacterDatabase.CommitTransaction();
objmgr.RemoveArenaTeam(this);
@@ -386,38 +312,18 @@ void ArenaTeam::Roster(WorldSession *session)
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
{
pl = objmgr.GetPlayer(itr->guid);
- if(pl)
- {
- data << uint64(pl->GetGUID()); // guid
- data << uint8(1); // online flag
- data << pl->GetName(); // member name
- data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
- data << uint8(pl->getLevel()); // unknown, probably level
- data << uint8(pl->getClass()); // class
- data << uint32(itr->games_week); // played this week
- data << uint32(itr->wins_week); // wins this week
- data << uint32(itr->games_season); // played this season
- data << uint32(itr->wins_season); // wins this season
- //data << uint32(itr->personal_rating); // personal rating
- //TODO
- data << uint32(pl->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5));
- }
- else
- {
- data << uint64(itr->guid); // guid
- data << uint8(0); // online flag
- data << itr->name; // member name
- data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
- data << uint8(0); // unknown, level?
- data << uint8(itr->Class); // class
- data << uint32(itr->games_week); // played this week
- data << uint32(itr->wins_week); // wins this week
- data << uint32(itr->games_season); // played this season
- data << uint32(itr->wins_season); // wins this season
- //data << uint32(itr->personal_rating); // personal rating
- //TODO
- data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, itr->guid));
- }
+
+ data << uint64(itr->guid); // guid
+ data << uint8((pl ? 1 : 0)); // online flag
+ data << itr->name; // member name
+ data << uint32((itr->guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member
+ data << uint8((pl ? pl->getLevel() : 0)); // unknown, level?
+ data << uint8(itr->Class); // class
+ data << uint32(itr->games_week); // played this week
+ data << uint32(itr->wins_week); // wins this week
+ data << uint32(itr->games_season); // played this season
+ data << uint32(itr->wins_season); // wins this season
+ data << uint32(itr->personal_rating); // personal rating
}
session->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
@@ -457,7 +363,7 @@ void ArenaTeam::NotifyStatsChanged()
// 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);
+ Player * plr = objmgr.GetPlayer(itr->guid);
if(plr)
Stats(plr->GetSession());
}
@@ -476,10 +382,8 @@ void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
data << uint32(stats.rating); // rating
data << uint32(stats.games_season); // season played
data << uint32(stats.wins_season); // season wins
- data << member->games_season; // played (count of all games, that the inspected member participated...)
- //data << member->personal_rating; // personal rating
- //TODO
- data << uint32(Player::GetUInt32ValueFromDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + GetSlot() * 6 + 5, guid));
+ data << uint32(member->games_season); // played (count of all games, that the inspected member participated...)
+ data << uint32(member->personal_rating); // personal rating
session->SendPacket(&data);
}
@@ -528,18 +432,6 @@ void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
}
}
-uint8 ArenaTeam::GetSlot() const
-{
- uint8 slot = GetSlotByType(GetType());
- if(slot >= MAX_ARENA_SLOT)
- {
- sLog.outError("Unknown arena team type %u for arena team %u", uint32(GetType()), GetId());
- return 0; // better return existed slot to prevent untelated data curruption
- }
-
- return slot;
-}
-
void ArenaTeam::BroadcastPacket(WorldPacket *packet)
{
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
@@ -560,13 +452,14 @@ uint8 ArenaTeam::GetSlotByType( uint32 type )
default:
break;
}
+ sLog.outError("FATAL: Unknown arena team type %u for some arena team", type);
return 0xFF;
}
-bool ArenaTeam::HaveMember( uint64 guid ) const
+bool ArenaTeam::HaveMember( const uint64& guid ) const
{
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
- if(itr->guid==guid)
+ if(itr->guid == guid)
return true;
return false;
@@ -580,13 +473,9 @@ uint32 ArenaTeam::GetPoints(uint32 MemberRating)
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)
@@ -597,16 +486,18 @@ uint32 ArenaTeam::GetPoints(uint32 MemberRating)
return (uint32) points;
}
-float ArenaTeam::GetChanceAgainst(uint32 rating)
+float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_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));
+ return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f));
}
-int32 ArenaTeam::WonAgainstChance(float chance)
+int32 ArenaTeam::WonAgainst(uint32 againstRating)
{
- // called when the team has won, and had 'chance' calculated chance to beat the opponent
+ // called when the team has won
+ //'chance' calculation - to beat the opponent
+ float chance = GetChanceAgainst(stats.rating,againstRating);
// calculate the rating modification (ELO system with k=32)
int32 mod = (int32)floor(32.0f * (1.0f - chance));
// modify the team stats accordingly
@@ -615,41 +506,45 @@ int32 ArenaTeam::WonAgainstChance(float chance)
stats.wins_week += 1;
stats.games_season += 1;
stats.wins_season += 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)
+ //update team's rank
+ stats.rank = 1;
+ ObjectMgr::ArenaTeamMap::iterator i = objmgr.GetArenaTeamMapBegin();
+ for ( ; i != objmgr.GetArenaTeamMapEnd(); ++i)
{
- higher_rank = result->Fetch()->GetUInt32();
- delete result;
+ if (i->second->GetType() == this->Type && i->second->GetStats().rating > stats.rating)
+ ++stats.rank;
}
- stats.rank = higher_rank + 1;*/
+
// return the rating change, used to display it on the results screen
return mod;
}
-int32 ArenaTeam::LostAgainstChance(float chance)
+int32 ArenaTeam::LostAgainst(uint32 againstRating)
{
- // called when the team has lost, and had 'chance' calculated chance to beat the opponent
+ // called when the team has lost
+ //'chance' calculation - to loose to the opponent
+ float chance = GetChanceAgainst(stats.rating,againstRating);
// 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_week += 1;
stats.games_season += 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)
+ //update team's rank
+
+ stats.rank = 1;
+ ObjectMgr::ArenaTeamMap::iterator i = objmgr.GetArenaTeamMapBegin();
+ for ( ; i != objmgr.GetArenaTeamMapEnd(); ++i)
{
- higher_rank = result->Fetch()->GetUInt32();
- delete result;
+ if (i->second->GetType() == this->Type && i->second->GetStats().rating > stats.rating)
+ ++stats.rank;
}
- stats.rank = higher_rank + 1;*/
- // return the rating adjustment for display
+
+ // return the rating change, used to display it on the results screen
return mod;
}
-void ArenaTeam::MemberLost(Player * plr, uint32 againstrating)
+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)
@@ -657,13 +552,9 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstrating)
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));
+ float chance = GetChanceAgainst(itr->personal_rating, againstRating);
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);
+ itr->ModifyPersonalRating(plr, mod, GetSlot());
// update personal played stats
itr->games_week +=1;
itr->games_season +=1;
@@ -675,7 +566,7 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstrating)
}
}
-void ArenaTeam::MemberWon(Player * plr, uint32 againstrating)
+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)
@@ -683,13 +574,9 @@ void ArenaTeam::MemberWon(Player * plr, uint32 againstrating)
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));
+ float chance = GetChanceAgainst(itr->personal_rating, againstRating);
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);
+ itr->ModifyPersonalRating(plr, mod, GetSlot());
// update personal stats
itr->games_week +=1;
itr->games_season +=1;
@@ -703,48 +590,43 @@ void ArenaTeam::MemberWon(Player * plr, uint32 againstrating)
}
}
-void ArenaTeam::UpdateArenaPointsHelper()
+void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
{
// 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_week < 10)
+ if (stats.games_week < 10)
return;
// to get points, a player has to participate in at least 30% of the matches
- uint32 min_plays = (uint32)ceil(stats.games_week * 0.3);
+ uint32 min_plays = (uint32) ceil(stats.games_week * 0.3);
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
{
// the player participated in enough games, update his points
- if(itr->games_week >= min_plays)
+ uint32 points_to_add = 0;
+ if (itr->games_week >= min_plays)
+ points_to_add = GetPoints(itr->personal_rating);
+ // OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, Id, itr->guid);
+
+ std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.find(GUID_LOPART(itr->guid));
+ if (plr_itr != PlayerPoints.end())
{
- // 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);
+ //check if there is already more points
+ if (plr_itr->second < points_to_add)
+ PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add;
}
- // 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);
- }
+ PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add;
}
}
void ArenaTeam::SaveToDB()
{
// save team and member stats to db
- // called after a match has ended
+ // called after a match has ended, or when calculating arena_points
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_week, stats.games_season, stats.rank, stats.wins_week, stats.wins_season, GetId());
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
{
- CharacterDatabase.PExecute("UPDATE arena_team_member SET games_week = '%u', wins_week = '%u', games_season = '%u', wins_season = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, Id, itr->guid);
+ CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, Id, itr->guid);
}
}
@@ -765,18 +647,18 @@ arenateam fields (id from 2.3.3 client):
1415 - 0=captain, 1=member
1416 - played this week
1417 - played this season
-1418 - unk
+1418 - unk - rank?
1419 - personal arena rating
1420 - arena team id 3v3
1421 - 0=captain, 1=member
1422 - played this week
1423 - played this season
-1424 - unk
+1424 - unk - rank?
1425 - personal arena rating
1426 - arena team id 5v5
1427 - 0=captain, 1=member
1428 - played this week
1429 - played this season
-1430 - unk
+1430 - unk - rank?
1431 - personal arena rating
*/
diff --git a/src/game/ArenaTeam.h b/src/game/ArenaTeam.h
index 2e9f32a97f7..3c6972cdcd0 100644
--- a/src/game/ArenaTeam.h
+++ b/src/game/ArenaTeam.h
@@ -45,7 +45,9 @@ enum ArenaTeamCommandErrors
ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM = 0x09,
ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS = 0x0A,
ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S = 0x0B,
- ERR_ARENA_TEAM_NOT_ALLIED = 0x0C
+ ERR_ARENA_TEAM_NOT_ALLIED = 0x0C,
+ ERR_ARENA_TEAM_PLAYER_TO_LOW = 0x15,
+ ERR_ARENA_TEAM_FULL = 0x16
};
enum ArenaTeamEvents
@@ -87,14 +89,22 @@ struct ArenaTeamMember
{
uint64 guid;
std::string name;
- //uint32 unk2;
- //uint8 unk1;
uint8 Class;
uint32 games_week;
uint32 wins_week;
uint32 games_season;
uint32 wins_season;
- //uint32 personal_rating;
+ uint32 personal_rating;
+
+ void ModifyPersonalRating(Player* plr, int32 mod, uint32 slot)
+ {
+ if (personal_rating + mod < 0)
+ personal_rating = 0;
+ else
+ personal_rating += mod;
+ if(plr)
+ plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot*6) + 5, personal_rating);
+ }
};
struct ArenaTeamStats
@@ -115,58 +125,76 @@ class ArenaTeam
ArenaTeam();
~ArenaTeam();
- bool create(uint64 CaptainGuid, uint32 type, std::string ArenaTeamName);
+ bool Create(uint64 CaptainGuid, uint32 type, std::string ArenaTeamName);
void Disband(WorldSession *session);
typedef std::list<ArenaTeamMember> MemberList;
- uint32 GetId() const { return Id; }
- uint32 GetType() const { return Type; }
- uint8 GetSlot() const;
+ uint32 GetId() const { return Id; }
+ uint32 GetType() const { return Type; }
+ uint8 GetSlot() const { return GetSlotByType(GetType()); }
static uint8 GetSlotByType(uint32 type);
- const uint64& GetCaptain() const { return CaptainGuid; }
- std::string GetName() const { return Name; }
+ const uint64& GetCaptain() const { return CaptainGuid; }
+ std::string GetName() const { return Name; }
const ArenaTeamStats& GetStats() const { return stats; }
void SetStats(uint32 stat_type, uint32 value);
- uint32 GetRating() const { return stats.rating; }
+ uint32 GetRating() const { return stats.rating; }
- uint32 GetEmblemStyle() const { return EmblemStyle; }
- uint32 GetEmblemColor() const { return EmblemColor; }
- uint32 GetBorderStyle() const { return BorderStyle; }
- uint32 GetBorderColor() const { return BorderColor; }
+ uint32 GetEmblemStyle() const { return EmblemStyle; }
+ uint32 GetEmblemColor() const { return EmblemColor; }
+ uint32 GetBorderStyle() const { return BorderStyle; }
+ uint32 GetBorderColor() const { return BorderColor; }
uint32 GetBackgroundColor() const { return BackgroundColor; }
- void SetCaptain(uint64 guid);
- bool AddMember(uint64 PlayerGuid);
+ void SetCaptain(const uint64& guid);
+ bool AddMember(const uint64& PlayerGuid);
+
+ // Shouldn't be const uint64& ed, because than can reference guid from members on Disband
+ // and this method removes given record from list. So invalid reference can happen.
void DelMember(uint64 guid);
void SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor);
- uint32 GetMembersSize() const { return members.size(); }
- MemberList::iterator membersbegin(){ return members.begin(); }
- MemberList::iterator membersEnd(){ return members.end(); }
- bool HaveMember(uint64 guid) const;
- ArenaTeamMember* GetMember(uint64 guid)
+ size_t GetMembersSize() const { return members.size(); }
+ bool Empty() const { return members.empty(); }
+ MemberList::iterator membersBegin() { return members.begin(); }
+ MemberList::iterator membersEnd() { return members.end(); }
+ bool HaveMember(const uint64& guid) const;
+
+ ArenaTeamMember* GetMember(const uint64& guid)
{
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- if(itr->guid==guid)
+ if(itr->guid == guid)
return &(*itr);
return NULL;
}
- ArenaTeamMember* GetMember(std::string& name)
+
+ ArenaTeamMember* GetMember(const std::string& name)
{
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
- if(itr->name==name)
+ if(itr->name == name)
return &(*itr);
return NULL;
}
+ bool IsFighting() const
+ {
+ for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ if (Player *p = objmgr.GetPlayer(itr->guid))
+ {
+ if (p->GetMap()->IsBattleArena())
+ return true;
+ }
+ }
+ return false;
+ }
+
bool LoadArenaTeamFromDB(uint32 ArenaTeamId);
void LoadMembersFromDB(uint32 ArenaTeamId);
void LoadStatsFromDB(uint32 ArenaTeamId);
- void LoadPlayerStats(ArenaTeamMember* member);
void SaveToDB();
@@ -178,18 +206,18 @@ class ArenaTeam
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();
+ float GetChanceAgainst(uint32 own_rating, uint32 enemy_rating);
+ int32 WonAgainst(uint32 againstRating);
+ void MemberWon(Player * plr, uint32 againstRating);
+ int32 LostAgainst(uint32 againstRating);
+ void MemberLost(Player * plr, uint32 againstRating);
- void FinishWeek();
+ void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
void NotifyStatsChanged();
+ void FinishWeek();
+
protected:
uint32 Id;
diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp
index 6a4ff6259d3..d2c9f54d04b 100644
--- a/src/game/ArenaTeamHandler.cpp
+++ b/src/game/ArenaTeamHandler.cpp
@@ -32,7 +32,6 @@
void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
{
sLog.outDebug("MSG_INSPECT_ARENA_TEAMS");
- //recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 8);
@@ -56,7 +55,6 @@ void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data)
{
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_QUERY" );
- //recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
@@ -74,7 +72,6 @@ void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data)
void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
{
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" );
- //recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
@@ -91,7 +88,6 @@ void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER");
- //recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
@@ -112,15 +108,13 @@ void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data)
if(!player)
{
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
return;
}
if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
{
- //SendArenaTeamCommandResult(ARENA_TEAM_INVITE_SS,"",Invitedname,ARENA_TEAM_PLAYER_NOT_FOUND_S);
- // can't find related opcode
- SendNotification(LANG_HIS_ARENA_LEVEL_REQ_ERROR, player->GetName());
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ARENA_TEAM_PLAYER_TO_LOW);
return;
}
@@ -143,21 +137,19 @@ void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data)
if(player->GetArenaTeamId(arenateam->GetSlot()))
{
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S);
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S);
return;
}
if(player->GetArenaTeamIdInvited())
{
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
return;
}
if(arenateam->GetMembersSize() >= arenateam->GetType() * 2)
{
- // should send an "arena team is full" or the likes message, I just don't know the proper values so... ERR_INTERNAL
-// SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_INTERNAL);
- SendNotification(LANG_YOUR_ARENA_TEAM_FULL, player->GetName());
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,arenateam->GetName(),"",ERR_ARENA_TEAM_FULL);
return;
}
@@ -179,23 +171,25 @@ void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/
ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited());
if(!at)
- {
- // arena team not exist
return;
- }
- if(_player->GetArenaTeamId(at->GetSlot()))
+ if(_player->GetArenaTeamIdFromDB(_player->GetGUIDLow(), at->GetType()))
{
- // already in arena team that size
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ALREADY_IN_ARENA_TEAM); // already in arena team that size
return;
}
- // not let enemies sign petition
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain()))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ARENA_TEAM_NOT_ALLIED);// not let enemies sign petition
return;
+ }
if(!at->AddMember(_player->GetGUID()))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ARENA_TEAM_INTERNAL);// arena team not found
return;
+ }
// event
WorldPacket data;
@@ -213,7 +207,6 @@ void WorldSession::HandleArenaTeamInviteDeclineOpcode(WorldPacket & /*recv_data*
void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_LEAVE");
- //recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
@@ -222,10 +215,7 @@ void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
- {
- // send command result
return;
- }
if(_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1)
{
// check for correctness
@@ -247,13 +237,13 @@ void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEAVE_SS, 2, _player->GetName(), at->GetName(), "");
at->BroadcastPacket(&data);
- //SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0);
+ //send you are no longer member of team
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0);
}
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_DISBAND");
- //recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
@@ -262,16 +252,13 @@ void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
- {
- // arena team not found
return;
- }
if(at->GetCaptain() != _player->GetGUID())
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
- }
+
+ if (at->IsFighting())
+ return;
at->Disband(this);
delete at;
@@ -280,7 +267,6 @@ void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_REMOVE_FROM_TEAM");
- //recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
@@ -305,11 +291,14 @@ void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
ArenaTeamMember* member = at->GetMember(name);
if(!member) // member not found
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
return;
+ }
if(at->GetCaptain() == member->guid)
{
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
return;
}
@@ -324,7 +313,6 @@ void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_PROMOTE_TO_CAPTAIN");
- //recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
@@ -349,7 +337,10 @@ void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data
ArenaTeamMember* member = at->GetMember(name);
if(!member) // member not found
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
return;
+ }
if(at->GetCaptain() == member->guid) // target player already captain
return;
@@ -362,13 +353,13 @@ void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data
at->BroadcastPacket(&data);
}
-void WorldSession::SendArenaTeamCommandResult(uint32 unk1, const std::string& str1, const std::string& str2, uint32 unk3)
+void WorldSession::SendArenaTeamCommandResult(uint32 team_action, const std::string& team, const std::string& player, uint32 error_id)
{
- WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+str1.length()+1+str2.length()+1+4);
- data << unk1;
- data << str1;
- data << str2;
- data << unk3;
+ WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+team.length()+1+player.length()+1+4);
+ data << team_action;
+ data << team;
+ data << player;
+ data << error_id;
SendPacket(&data);
}
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp
index 098b5a0d28e..d392f074600 100644
--- a/src/game/BattleGround.cpp
+++ b/src/game/BattleGround.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Object.h"
@@ -86,13 +86,14 @@ BattleGround::BattleGround()
m_PrematureCountDown = false;
m_PrematureCountDown = 0;
+
m_HonorMode = BG_NORMAL;
}
BattleGround::~BattleGround()
{
// remove objects and creatures
- // (this is done automatically in mapmanager update, when the instance is reset after the reset time)
+ // (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)
{
@@ -241,8 +242,8 @@ void BattleGround::Update(time_t diff)
// time's up!
EndBattleGround(0); // noone wins
m_PrematureCountDown = false;
- }
- else
+ }
+ else
{
uint32 newtime = m_PrematureCountDownTimer - diff;
// announce every minute
@@ -306,6 +307,7 @@ void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *
continue;
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ if(!team) team = plr->GetTeam();
if(team == TeamID)
plr->GetSession()->SendPacket(packet);
@@ -334,6 +336,7 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID)
}
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ if(!team) team = plr->GetTeam();
if(team == TeamID)
{
@@ -356,7 +359,8 @@ void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID)
}
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
-
+ if(!team) team = plr->GetTeam();
+
if(team == TeamID)
plr->CastSpell(plr, SpellID, true);
}
@@ -392,6 +396,7 @@ void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
}
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ if(!team) team = plr->GetTeam();
if(team == TeamID)
UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor);
@@ -416,6 +421,7 @@ void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation,
}
uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ if(!team) team = plr->GetTeam();
if(team == TeamID)
plr->ModifyFactionReputation(factionEntry, Reputation);
@@ -438,7 +444,6 @@ 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;
@@ -496,11 +501,9 @@ void BattleGround::EndBattleGround(uint32 winner)
{
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);
+ int32 winner_change = winner_arena_team->WonAgainst(loser_rating);
+ int32 loser_change = loser_arena_team->LostAgainst(winner_rating);
+ sLog.outDebug("--- Winner rating: %u, Loser rating: %u, Winner change: %u, Losser change: %u ---", winner_rating, loser_rating, winner_change, loser_change);
if(winner == ALLIANCE)
{
SetArenaTeamRatingChangeForTeam(ALLIANCE, winner_change);
@@ -538,7 +541,7 @@ void BattleGround::EndBattleGround(uint32 winner)
plr->SpawnCorpseBones();
}
- uint32 team = itr->second.Team;//GetPlayerTeam(plr->GetGUID());
+ uint32 team = itr->second.Team;
if(!team) team = plr->GetTeam();
// per player calculation
@@ -555,6 +558,7 @@ void BattleGround::EndBattleGround(uint32 winner)
if(!Source)
Source = plr;
RewardMark(plr,ITEM_WINNER_COUNT);
+ UpdatePlayerScore(plr, SCORE_BONUS_HONOR, 20);
RewardQuest(plr);
}
else
@@ -577,8 +581,8 @@ void BattleGround::EndBattleGround(uint32 winner)
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();
+ //obsolete: winner_arena_team->UpdateArenaPointsHelper();
+ //obsolete: loser_arena_team->UpdateArenaPointsHelper();
// save the stat changes
winner_arena_team->SaveToDB();
loser_arena_team->SaveToDB();
@@ -693,7 +697,7 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count)
int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex();
if ( loc_idx >= 0 )
if(ItemLocale const *il = objmgr.GetItemLocale(markProto->ItemId))
- if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty())
+ if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
subject = il->Name[loc_idx];
// text
@@ -906,8 +910,8 @@ void BattleGround::Reset()
m_Players.clear();
m_PlayerScores.clear();
- // reset BGSubclass (this cleans up creatures and gos as well)
- this->ResetBGSubclass();
+ // reset BGSubclass
+ ResetBGSubclass();
}
void BattleGround::StartBattleGround()
@@ -932,7 +936,7 @@ void BattleGround::AddPlayer(Player *plr)
// Add to list/maps
m_Players[guid] = bp;
- UpdatePlayersCountByTeam(team, false); // +1 player
+ UpdatePlayersCountByTeam(team, false); // +1 player
WorldPacket data;
sBattleGroundMgr.BuildPlayerJoinedBattleGroundPacket(&data, plr);
@@ -941,10 +945,8 @@ void BattleGround::AddPlayer(Player *plr)
// 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) // gold
{
@@ -973,6 +975,8 @@ void BattleGround::AddPlayer(Player *plr)
}
(plr)->RemovePet(NULL,PET_SAVE_NOT_IN_SLOT);
}
+ else
+ (plr)->SetTemporaryUnsummonedPetNumber(0);
if(GetStatus() == STATUS_WAIT_JOIN) // not started yet
{
@@ -1023,7 +1027,7 @@ void BattleGround::RemoveFromBGFreeSlotQueue()
// 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 BG is starting ... invite anyone
if (GetStatus() == STATUS_WAIT_JOIN)
return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
//if BG is already started .. do not allow to join too much players of one faction
@@ -1045,7 +1049,7 @@ uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const
// 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))
+ if (otherTeam == GetInvitedCount(Team))
diff = 1;
// allow join more ppl if the other side has more players
else if(otherTeam > GetInvitedCount(Team))
@@ -1063,6 +1067,9 @@ uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const
// allow join more ppl if the other side has more players
else if (otherIn > GetPlayersCountByTeam(Team))
diff3 = otherIn - GetPlayersCountByTeam(Team);
+ // or other side has less than minPlayersPerTeam
+ else if (GetInvitedCount(Team) <= GetMinPlayersPerTeam())
+ diff3 = GetMinPlayersPerTeam() - GetInvitedCount(Team) + 1;
// return the minimum of the 3 differences
@@ -1309,16 +1316,6 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f
return NULL;
}
- CreatureData &data = objmgr.NewOrExistCreatureData(pCreature->GetDBTableGUIDLow());
-
- data.id = entry;
-// data.mapid = GetMapId();
- data.posX = x;
- data.posY = y;
- data.posZ = z;
- data.orientation = o;
- data.spawndist = 15;
-
pCreature->AIM_Initialize();
//pCreature->SetDungeonDifficulty(0);
@@ -1328,7 +1325,36 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f
return pCreature;
}
+/*
+void BattleGround::SpawnBGCreature(uint32 type, uint32 respawntime)
+{
+ Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceId());
+ if(!map)
+ return false;
+ if(respawntime == 0)
+ {
+ Creature *obj = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
+ if(obj)
+ {
+ //obj->Respawn(); // bugged
+ obj->SetRespawnTime(0);
+ objmgr.SaveCreatureRespawnTime(obj->GetGUIDLow(), GetInstanceID(), 0);
+ map->Add(obj);
+ }
+ }
+ else
+ {
+ Creature *obj = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
+ if(obj)
+ {
+ obj->setDeathState(DEAD);
+ obj->SetRespawnTime(respawntime);
+ map->Add(obj);
+ }
+ }
+}
+*/
bool BattleGround::DelCreature(uint32 type)
{
Creature *cr = HashMapHolder<Creature>::Find(m_BgCreatures[type]);
@@ -1371,7 +1397,7 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float
if(!pCreature)
{
sLog.outError("Can't create Spirit guide. BattleGround not created!");
- this->EndNow();
+ EndNow();
return false;
}
diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h
index c151a207124..3c98afe6d17 100644
--- a/src/game/BattleGround.h
+++ b/src/game/BattleGround.h
@@ -86,7 +86,7 @@ enum BattleGroundTimeIntervals
{
RESURRECTION_INTERVAL = 30000, // ms
REMIND_INTERVAL = 30000, // ms
- INVITE_ACCEPT_WAIT_TIME = 120000, // ms
+ INVITE_ACCEPT_WAIT_TIME = 80000, // ms
TIME_TO_AUTOREMOVE = 120000, // ms
MAX_OFFLINE_TIME = 300000, // ms
START_DELAY0 = 120000, // ms
@@ -260,6 +260,7 @@ class BattleGround
public:
/* Construction */
BattleGround();
+ /*BattleGround(const BattleGround& bg);*/
virtual ~BattleGround();
virtual void Update(time_t diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version
virtual bool SetupBattleGround() // must be implemented in BG subclass
@@ -438,6 +439,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
diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp
index b8e001fb1f1..00e1090d8d5 100644
--- a/src/game/BattleGroundAB.cpp
+++ b/src/game/BattleGroundAB.cpp
@@ -400,6 +400,7 @@ void BattleGroundAB::_NodeOccupied(uint8 node,Team team)
{
if( !AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], team) )
sLog.outError("Failed to spawn spirit guide! point: %u, team: %u,", node, team);
+// SpawnBGCreature(node,RESPAWN_IMMEDIATELY);
uint8 capturedNodes = 0;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp
index 63511c87111..27cd169ffc3 100644
--- a/src/game/BattleGroundAV.cpp
+++ b/src/game/BattleGroundAV.cpp
@@ -280,7 +280,7 @@ Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type )
data.spawndist = 5;
}
//else spawndist will be 15, so creatures move maximum=10
- creature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
+ //creature->SetDefaultMovementType(RANDOM_MOTION_TYPE);
creature->GetMotionMaster()->Initialize();
creature->setDeathState(JUST_DIED);
creature->Respawn();
diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp
index 3b545e5e65b..1af6aaabf8b 100644
--- a/src/game/BattleGroundEY.cpp
+++ b/src/game/BattleGroundEY.cpp
@@ -73,6 +73,8 @@ void BattleGroundEY::Update(time_t diff)
SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY);
SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY);
+// SpawnBGCreature(EY_SPIRIT_MAIN_ALLIANCE, RESPAWN_IMMEDIATELY);
+// SpawnBGCreature(EY_SPIRIT_MAIN_HORDE, RESPAWN_IMMEDIATELY);
for(uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i)
SpawnBGObject(i, RESPAWN_ONE_DAY);
@@ -772,6 +774,8 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point)
sLog.outError("BatteGroundEY: Failed to spawn spirit guide! point: %u, team: %u, graveyard_id: %u",
Point, Team, m_CapturingPointTypes[Point].GraveYardId);
+// SpawnBGCreature(Point,RESPAWN_IMMEDIATELY);
+
UpdatePointsIcons(Team, Point);
UpdatePointsCount(Team);
}
diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp
index cd3e5f1907d..fc99fe3f1fe 100644
--- a/src/game/BattleGroundHandler.cpp
+++ b/src/game/BattleGroundHandler.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -29,11 +29,11 @@
#include "ObjectAccessor.h"
#include "Object.h"
#include "Chat.h"
-#include "Language.h"
#include "BattleGroundMgr.h"
#include "BattleGroundWS.h"
#include "BattleGround.h"
#include "ArenaTeam.h"
+#include "Language.h"
void WorldSession::HandleBattleGroundHelloOpcode( WorldPacket & recv_data )
{
@@ -98,7 +98,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
// can do this, since it's battleground, not arena
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, 0);
- // ignore if we already in BG or BG queue
+ // ignore if player is already in BG
if(_player->InBattleGround())
return;
@@ -146,80 +146,12 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )
if(!grp)
return;
uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
- switch(err)
+ if (err != BG_JOIN_ERR_OK)
{
- // 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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE), NULL);
- SendPacket(&data);
- }
+ SendBattleGroundOrArenaJoinError(err);
return;
- break;
- case BG_JOIN_ERR_GROUP_DESERTER:
- {
- WorldPacket data;
- ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetTrinityString(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, GetTrinityString(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
@@ -362,7 +294,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
uint8 type; // arenatype if arena
uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
- uint32 instanceId;
+ uint32 instanceId;
uint32 bgTypeId; // type id from dbc
uint16 unk; // 0x1F90 constant?
uint8 action; // enter battle 0x1, leave queue 0x0
@@ -400,7 +332,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
uint8 israted = itrPlayerStatus->second.GroupInfo->IsRated;
uint8 status = 0;
-
+
if(!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID)
{
// not invited to bg, get template
@@ -432,7 +364,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
}
uint32 bgQueueTypeId = 0;
- // get the bg what we were invited to
+ // 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());
@@ -472,6 +404,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
uint32 arenatype = 0;
uint32 israted = 0;
uint32 rating = 0;
+ uint32 opponentsRating = 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()
@@ -481,6 +414,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
arenatype = pitr->second.GroupInfo->ArenaType;
israted = pitr->second.GroupInfo->IsRated;
rating = pitr->second.GroupInfo->ArenaTeamRating;
+ opponentsRating = pitr->second.GroupInfo->OpponentsTeamRating;
}
else
{
@@ -496,7 +430,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
// resurrect the player
if(!_player->isAlive())
{
- _player->ResurrectPlayer(1.0f,false);
+ _player->ResurrectPlayer(1.0f);
_player->SpawnCorpseBones();
}
// stop taxi flight at port
@@ -528,6 +462,19 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data )
break;
case 0: // leave queue
queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId);
+ /*
+ if player leaves rated arena match before match start, it is counted as he played but he lost
+ */
+ if (israted)
+ {
+ ArenaTeam * at = objmgr.GetArenaTeamById(team);
+ if (at)
+ {
+ sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u, because he has left queue!", GUID_LOPART(_player->GetGUID()), opponentsRating);
+ at->MemberLost(_player, opponentsRating);
+ at->SaveToDB();
+ }
+ }
_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[bgQueueTypeId].RemovePlayer(_player->GetGUID(), true);
@@ -745,7 +692,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
BattleGround* bg = NULL;
if( !(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA)) )
{
- sLog.outError("Battleground: template bg (all arenas) not found");
+ sLog.outError("Battleground: template bg (all arenas) not found");
return;
}
@@ -770,94 +717,16 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
if(!grp)
return;
uint32 err = grp->CanJoinBattleGroundQueue(bgTypeId, bgQueueTypeId, arenatype, arenatype, (bool)isRated, type);
- switch(err)
+ if (err != BG_JOIN_ERR_OK)
{
- // 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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(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, GetTrinityString(LANG_BG_GROUP_MEMBER_DESERTER), NULL);
- SendPacket(&data);
- }
+ SendBattleGroundOrArenaJoinError(err);
return;
- break;
- case BG_JOIN_ERR_ALL_QUEUES_USED:
- {
- WorldPacket data;
- ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetTrinityString(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)
+ 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)
@@ -883,7 +752,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )
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 personal rating is more than 150 points below the teams 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;
}
@@ -952,3 +821,41 @@ void WorldSession::HandleBattleGroundReportAFK( WorldPacket & recv_data )
reportedPlayer->ReportedAfkBy(_player);
}
+
+void WorldSession::SendBattleGroundOrArenaJoinError(uint8 err)
+{
+ WorldPacket data;
+ int32 msg;
+ switch (err)
+ {
+ case BG_JOIN_ERR_OFFLINE_MEMBER:
+ msg = LANG_BG_GROUP_OFFLINE_MEMBER;
+ break;
+ case BG_JOIN_ERR_GROUP_TOO_MANY:
+ msg = LANG_BG_GROUP_TOO_LARGE;
+ break;
+ case BG_JOIN_ERR_MIXED_FACTION:
+ msg = LANG_BG_GROUP_MIXED_FACTION;
+ break;
+ case BG_JOIN_ERR_MIXED_LEVELS:
+ msg = LANG_BG_GROUP_MIXED_LEVELS;
+ break;
+ case BG_JOIN_ERR_GROUP_MEMBER_ALREADY_IN_QUEUE:
+ msg = LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE;
+ break;
+ case BG_JOIN_ERR_GROUP_DESERTER:
+ msg = LANG_BG_GROUP_MEMBER_DESERTER;
+ break;
+ case BG_JOIN_ERR_ALL_QUEUES_USED:
+ msg = LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS;
+ break;
+ case BG_JOIN_ERR_GROUP_NOT_ENOUGH:
+ case BG_JOIN_ERR_MIXED_ARENATEAM:
+ default:
+ return;
+ break;
+ }
+ ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_BG_SYSTEM_NEUTRAL, LANG_UNIVERSAL, NULL, 0, GetTrinityString(msg), NULL);
+ SendPacket(&data);
+ return;
+}
diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp
index 87a652f23c2..904a2f65a15 100644
--- a/src/game/BattleGroundMgr.cpp
+++ b/src/game/BattleGroundMgr.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -37,8 +37,8 @@
#include "ObjectMgr.h"
#include "ProgressBar.h"
#include "World.h"
-#include "ArenaTeam.h"
#include "Chat.h"
+#include "ArenaTeam.h"
INSTANTIATE_SINGLETON_1( BattleGroundMgr );
@@ -92,7 +92,7 @@ void BattleGroundQueue::EligibleGroups::Init(BattleGroundQueue::QueuedGroupsList
( (*itr)->JoinTime <= DisregardTime // pass if disregard time is greater than join time
|| (*itr)->ArenaTeamRating == 0 // pass if no rating info
|| ( (*itr)->ArenaTeamRating >= MinRating // pass if matches the rating range
- && (*itr)->ArenaTeamRating <= MaxRating ) ) )
+ && (*itr)->ArenaTeamRating <= MaxRating ) ) )
{
// the group matches the conditions
// insert it in order of groupsize, and join time
@@ -219,11 +219,8 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, uint32 BgTypeId, ui
ginfo->IsInvitedToBGInstanceGUID = 0; // maybe this should be modifiable by function arguments to enable selection of running instances?
ginfo->JoinTime = getMSTime();
ginfo->Team = leader->GetTeam();
-
- if(sBattleGroundMgr.GetMaxRatingDifference()) // if max difference is set, then store rating info for queue
- ginfo->ArenaTeamRating = arenaRating;
- else
- ginfo->ArenaTeamRating = 0; // don't if it doesn't matter
+ ginfo->ArenaTeamRating = arenaRating;
+ ginfo->OpponentsTeamRating = 0; //initialize it to 0
ginfo->Players.clear();
@@ -246,6 +243,38 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)
// add the pinfo to ginfo's list
ginfo->Players[plr->GetGUID()] = &info;
+/*
+ if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) )
+ {
+ BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgTypeId);
+ char const* bgName = bg->GetName();
+
+ uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id);
+ uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id);
+
+ // replace hardcoded max level by player max level for nice output
+ if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL);
+
+ int8 MinPlayers = bg->GetMinPlayersPerTeam();
+
+ uint8 qHorde = m_QueuedPlayers[queue_id].Horde;
+ uint8 qAlliance = m_QueuedPlayers[queue_id].Alliance;
+
+ // Show queue status to player only (when joining queue)
+ if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY))
+ {
+ ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF,
+ bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? (MinPlayers - qAlliance) : 0, qHorde, (MinPlayers > qHorde) ? (MinPlayers - qHorde) : 0);
+ }
+ // System message
+ else
+ {
+ sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD,
+ bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? (MinPlayers - qAlliance) : 0, qHorde, (MinPlayers > qHorde) ? (MinPlayers - qHorde) : 0);
+ }
+
+ }*/
}
void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
@@ -267,7 +296,7 @@ void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
}
if(!IsSet)
- {
+ {
// either player is offline, or he levelled up to another queue category
// sLog.outError("Battleground: removing offline player from BG queue - this might not happen, but it should not cause crash");
for (uint32 i = 0; i < MAX_BATTLEGROUND_QUEUES; i++)
@@ -532,7 +561,7 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
}
//if no players in queue ... do nothing
- if (this->m_QueuedGroups[queue_id].size() == 0)
+ if (m_QueuedGroups[queue_id].empty())
return;
uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, arenatype);
@@ -618,7 +647,7 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
uint32 arenaMaxRating = (arenaRating == 0)? 0 : arenaRating + sBattleGroundMgr.GetMaxRatingDifference();
uint32 discardTime = 0;
// if max rating difference is set and the time past since server startup is greater than the rating discard time
- // (after what time the ratings aren't taken into account when making teams) then
+ // (after what time the ratings aren't taken into account when making teams) then
// the discard time is current_time - time_to_discard, teams that joined after that, will have their ratings taken into account
// else leave the discard time on 0, this way all ratings will be discarded
if(sBattleGroundMgr.GetMaxRatingDifference() && getMSTime() >= sBattleGroundMgr.GetRatingDiscardTimer())
@@ -627,12 +656,12 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
// try to build the selection pools
bool bAllyOK = BuildSelectionPool(bgTypeId, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam, NORMAL_ALLIANCE, arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime);
if(bAllyOK)
- sLog.outDebug("Battleground: ally pool successfully build");
+ sLog.outDebug("Battleground: ally pool succesfully build");
else
sLog.outDebug("Battleground: ally pool wasn't created");
bool bHordeOK = BuildSelectionPool(bgTypeId, queue_id, MinPlayersPerTeam, MaxPlayersPerTeam, NORMAL_HORDE, arenatype, isRated, arenaMinRating, arenaMaxRating, discardTime);
if(bHordeOK)
- sLog.outDebug("Battleground: horde pool successfully built");
+ sLog.outDebug("Battleground: horde pool succesfully built");
else
sLog.outDebug("Battleground: horde pool wasn't created");
@@ -650,7 +679,7 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
!(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+1)%3])) &&
!(bg2 = sBattleGroundMgr.CreateNewBattleGround(arenas[(arena_num+2)%3])) )
{
- sLog.outError("Battleground: couldn't create arena");
+ sLog.outError("Battleground: couldn't create any arena instance!");
return;
}
@@ -716,6 +745,16 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
InviteGroupToBG((*itr),bg2,ALLIANCE);
}
+ if (isRated)
+ {
+ std::list<GroupQueueInfo* >::iterator itr_alliance = m_SelectionPools[NORMAL_ALLIANCE].SelectedGroups.begin();
+ std::list<GroupQueueInfo* >::iterator itr_horde = m_SelectionPools[NORMAL_HORDE].SelectedGroups.begin();
+ (*itr_alliance)->OpponentsTeamRating = (*itr_horde)->ArenaTeamRating;
+ sLog.outDebug("setting oposite teamrating for team %u to %u", (*itr_alliance)->ArenaTeamId, (*itr_alliance)->OpponentsTeamRating);
+ (*itr_horde)->OpponentsTeamRating = (*itr_alliance)->ArenaTeamRating;
+ sLog.outDebug("setting oposite teamrating for team %u to %u", (*itr_horde)->ArenaTeamId, (*itr_horde)->OpponentsTeamRating);
+ }
+
// start the battleground
bg2->StartBattleGround();
}
@@ -857,6 +896,14 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype
InviteGroupToBG((*itr),bg2,ALLIANCE);
}
+ if (isRated)
+ {
+ std::list<GroupQueueInfo* >::iterator itr_alliance = m_SelectionPools[mode1].SelectedGroups.begin();
+ std::list<GroupQueueInfo* >::iterator itr_horde = m_SelectionPools[mode2].SelectedGroups.begin();
+ (*itr_alliance)->OpponentsTeamRating = (*itr_horde)->ArenaTeamRating;
+ (*itr_horde)->OpponentsTeamRating = (*itr_alliance)->ArenaTeamRating;
+ }
+
bg2->StartBattleGround();
}
}
@@ -917,11 +964,6 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
// player logged off (we should do nothing, he is correctly removed from queue in another procedure)
return true;
- // Player can be in another BG queue and must be removed in normal way in any case
- //if (plr->InBattleGround())
- // // player is already in battleground ... do nothing (battleground queue status is deleted when player is teleported to BG)
- // return true;
-
BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID);
if (!bg)
return true;
@@ -936,6 +978,16 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
BattleGroundQueue::QueuedPlayersMap::iterator qMapItr = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()].find(m_PlayerGuid);
if (qMapItr != sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[plr->GetBattleGroundQueueIdFromLevel()].end() && qMapItr->second.GroupInfo && qMapItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID)
{
+ if (qMapItr->second.GroupInfo->IsRated)
+ {
+ ArenaTeam * at = objmgr.GetArenaTeamById(qMapItr->second.GroupInfo->ArenaTeamId);
+ if (at)
+ {
+ sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u", GUID_LOPART(plr->GetGUID()), qMapItr->second.GroupInfo->OpponentsTeamRating);
+ at->MemberLost(plr, qMapItr->second.GroupInfo->OpponentsTeamRating);
+ at->SaveToDB();
+ }
+ }
plr->RemoveBattleGroundQueueId(bgQueueTypeId);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(m_PlayerGuid, true);
sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgQueueTypeId, bg->GetQueueType());
@@ -1016,19 +1068,19 @@ void BattleGroundMgr::Update(time_t diff)
m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA,6,ARENA_TYPE_3v3,true,0);
m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA,6,ARENA_TYPE_5v5,true,0);
m_NextRatingDiscardUpdate = m_RatingDiscardTimer;
- }
- else
+ }
+ else
m_NextRatingDiscardUpdate -= diff;
}
if(m_AutoDistributePoints)
{
if(m_AutoDistributionTimeChecker < diff)
{
- if(time(NULL) > m_NextAutoDistributionTime)
+ if(sWorld.GetGameTime() > m_NextAutoDistributionTime)
{
DistributeArenaPoints();
- m_NextAutoDistributionTime = time(NULL) + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS);
- CharacterDatabase.PExecute("UPDATE saved_variables SET NextArenaPointDistributionTime = FROM_UNIXTIME("I64FMTD")",(uint64)m_NextAutoDistributionTime);
+ m_NextAutoDistributionTime = sWorld.GetGameTime() + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS);
+ CharacterDatabase.PExecute("UPDATE saved_variables SET NextArenaPointDistributionTime = '"I64FMTD"'", m_NextAutoDistributionTime);
}
m_AutoDistributionTimeChecker = 600000; // check 10 minutes
}
@@ -1275,11 +1327,11 @@ void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Pla
void BattleGroundMgr::InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team)
{
// set invited player counters:
- BattleGround* bg = this->GetBattleGround(bgInstanceGUID);
+ BattleGround* bg = GetBattleGround(bgInstanceGUID);
if(!bg)
return;
bg->IncreaseInvitedCount(team);
-
+
plr->SetInviteForBattleGroundQueueType(BGQueueTypeId(bg->GetTypeID(),bg->GetArenaType()), bgInstanceGUID);
// set the arena teams for rated matches
@@ -1327,36 +1379,36 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(uint32 bgTypeId)
sLog.outError("BattleGround: CreateNewBattleGround - bg template not found for %u", bgTypeId);
return 0;
}
-
+
// create a copy of the BG template
switch(bgTypeId)
{
- case BATTLEGROUND_AV:
- bg = new BattleGroundAV(*(BattleGroundAV*)bg_template);
+ case BATTLEGROUND_AV:
+ bg = new BattleGroundAV(*(BattleGroundAV*)bg_template);
break;
- case BATTLEGROUND_WS:
- bg = new BattleGroundWS(*(BattleGroundWS*)bg_template);
+ case BATTLEGROUND_WS:
+ bg = new BattleGroundWS(*(BattleGroundWS*)bg_template);
break;
- case BATTLEGROUND_AB:
- bg = new BattleGroundAB(*(BattleGroundAB*)bg_template);
+ case BATTLEGROUND_AB:
+ bg = new BattleGroundAB(*(BattleGroundAB*)bg_template);
break;
- case BATTLEGROUND_NA:
- bg = new BattleGroundNA(*(BattleGroundNA*)bg_template);
+ case BATTLEGROUND_NA:
+ bg = new BattleGroundNA(*(BattleGroundNA*)bg_template);
break;
- case BATTLEGROUND_BE:
- bg = new BattleGroundBE(*(BattleGroundBE*)bg_template);
+ case BATTLEGROUND_BE:
+ bg = new BattleGroundBE(*(BattleGroundBE*)bg_template);
break;
- case BATTLEGROUND_AA:
- bg = new BattleGroundAA(*(BattleGroundAA*)bg_template);
+ case BATTLEGROUND_AA:
+ bg = new BattleGroundAA(*(BattleGroundAA*)bg_template);
break;
- case BATTLEGROUND_EY:
- bg = new BattleGroundEY(*(BattleGroundEY*)bg_template);
+ case BATTLEGROUND_EY:
+ bg = new BattleGroundEY(*(BattleGroundEY*)bg_template);
break;
- case BATTLEGROUND_RL:
- bg = new BattleGroundRL(*(BattleGroundRL*)bg_template);
+ case BATTLEGROUND_RL:
+ bg = new BattleGroundRL(*(BattleGroundRL*)bg_template);
break;
default:
- //bg = new BattleGround;
+ //bg = new BattleGround;
return 0;
break; // placeholder for non implemented BG
}
@@ -1432,7 +1484,7 @@ uint32 BattleGroundMgr::CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPer
// do NOT add to update list, since this is a template battleground!
// return some not-null value, bgTypeId is good enough for me
- return bgTypeId;
+ return bgTypeId;
}
void BattleGroundMgr::CreateInitialBattleGrounds()
@@ -1557,12 +1609,12 @@ void BattleGroundMgr::InitAutomaticArenaPointDistribution()
if(m_AutoDistributePoints)
{
sLog.outDebug("Initializing Automatic Arena Point Distribution");
- QueryResult * result = CharacterDatabase.Query("SELECT UNIX_TIMESTAMP(NextArenaPointDistributionTime) FROM saved_variables");
+ QueryResult * result = CharacterDatabase.Query("SELECT NextArenaPointDistributionTime FROM saved_variables");
if(!result)
{
- sLog.outDebug("Battleground: Next arena point distribution time not found in SavedVariables, reseting it now.");
- m_NextAutoDistributionTime = time(NULL) + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS);
- CharacterDatabase.PExecute("INSERT INTO saved_variables (NextArenaPointDistributionTime) VALUES ( FROM_UNIXTIME("I64FMTD") )",(uint64)m_NextAutoDistributionTime);
+ sLog.outDebug("Battleground: Next arena point distribution time not found in SavedVariables, reseting it now.");
+ m_NextAutoDistributionTime = sWorld.GetGameTime() + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS);
+ CharacterDatabase.PExecute("INSERT INTO saved_variables (NextArenaPointDistributionTime) VALUES ('"I64FMTD"')", m_NextAutoDistributionTime);
}
else
{
@@ -1576,53 +1628,51 @@ void BattleGroundMgr::InitAutomaticArenaPointDistribution()
void BattleGroundMgr::DistributeArenaPoints()
{
// used to distribute arena points based on last week's stats
+ sWorld.SendGlobalText("Flushing Arena points based on team ratings, this may take a few minutes. Please stand by...", NULL);
- CharacterDatabase.BeginTransaction();
- // direct execute, because of the later GetUInt32ValueFromDB() calls
- // 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10
- CharacterDatabase.DirectPExecute("UPDATE characters b, arena_team_member a SET b.data = CONCAT( SUBSTRING_INDEX(b.data, ' ', '%u'),' ', CAST( IF ( ((CAST( SUBSTRING( b.data FROM (CHAR_LENGTH(SUBSTRING_INDEX(b.data,' ','%u')) + 2) FOR (CHAR_LENGTH(SUBSTRING_INDEX(b.data,' ','%u')) - CHAR_LENGTH(SUBSTRING_INDEX(b.data,' ','%u')) - 1) ) AS UNSIGNED) + (SELECT MAX(c.points_to_add) FROM arena_team_member c WHERE c.guid = b.guid GROUP BY c.guid) ) < '%u'), CAST(SUBSTRING(b.data FROM (CHAR_LENGTH(SUBSTRING_INDEX(b.data,' ','%u')) + 2) FOR (CHAR_LENGTH(SUBSTRING_INDEX(b.data,' ','%u')) - CHAR_LENGTH(SUBSTRING_INDEX(b.data,' ','%u')) - 1) ) AS UNSIGNED) + (SELECT MAX(d.points_to_add) FROM arena_team_member d WHERE d.guid = b.guid GROUP BY d.guid), '%u') AS CHAR),' ',SUBSTRING(b.data FROM (CHAR_LENGTH(SUBSTRING_INDEX(b.data,' ','%u')) + 2))) WHERE b.guid = a.guid",PLAYER_FIELD_ARENA_CURRENCY, PLAYER_FIELD_ARENA_CURRENCY, PLAYER_FIELD_ARENA_CURRENCY+1, PLAYER_FIELD_ARENA_CURRENCY, sWorld.getConfig(CONFIG_MAX_ARENA_POINTS),PLAYER_FIELD_ARENA_CURRENCY, PLAYER_FIELD_ARENA_CURRENCY+1, PLAYER_FIELD_ARENA_CURRENCY, sWorld.getConfig(CONFIG_MAX_ARENA_POINTS), PLAYER_FIELD_ARENA_CURRENCY+1);
- for(int i=0; i<3; ++i)
- {
- // reset weekly played matches
- uint32 position = PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * i + 2;
- CharacterDatabase.DirectPExecute("UPDATE characters SET data = CONCAT( SUBSTRING_INDEX(data,' ','%u'),' ','0',' ',SUBSTRING(data FROM (CHAR_LENGTH(SUBSTRING_INDEX(data,' ','%u')) + 2)))",position, position + 1);
- }
- CharacterDatabase.DirectExecute("UPDATE arena_team_member SET points_to_add = '0', games_week = '0', wins_week = '0'");
- CharacterDatabase.DirectExecute("UPDATE arena_team_stats SET games = '0', wins = '0'");
- CharacterDatabase.CommitTransaction();
+ sWorld.SendGlobalText("Distributing arena points to players...", NULL);
+
+ //temporary structure for storing maximum points to add values for all players
+ std::map<uint32, uint32> PlayerPoints;
- QueryResult *result = CharacterDatabase.PQuery("SELECT guid, data FROM characters WHERE online = '1'");
- if( result )
+ //at first update all points for all team members
+ for(ObjectMgr::ArenaTeamMap::iterator team_itr = objmgr.GetArenaTeamMapBegin(); team_itr != objmgr.GetArenaTeamMapEnd(); ++team_itr)
{
- do
+ if(ArenaTeam * at = team_itr->second)
{
- Field *fields = result->Fetch();
+ at->UpdateArenaPointsHelper(PlayerPoints);
+ }
+ }
- uint32 guid = fields[0].GetUInt32();
- if(Player * pl = objmgr.GetPlayer(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)))
- {
- Tokens data = StrSplit(fields[1].GetCppString(), " ");
- // update arena currency
- pl->SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_ARENA_CURRENCY));
- // reset played this week count for all teams
- for(int i= 0; i < 3; ++i)
- pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 6 * i + 2, 0);
- }
+ //cycle that gives points to all players
+ for (std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.begin(); plr_itr != PlayerPoints.end(); ++plr_itr)
+ {
+ //update to database
+ CharacterDatabase.PExecute("UPDATE characters SET arena_pending_points = '%u' WHERE `guid` = '%u'", plr_itr->second, plr_itr->first);
+ //add points if player is online
+ Player* pl = objmgr.GetPlayer(plr_itr->first);
+ if (pl)
+ pl->ModifyArenaPoints(plr_itr->second);
+ }
- } while (result->NextRow());
+ PlayerPoints.clear();
- delete result;
- }
+ sWorld.SendGlobalText("Finished setting arena points for online players.", NULL);
- for(ObjectMgr::ArenaTeamSet::iterator titr = objmgr.GetArenaTeamSetBegin(); titr != objmgr.GetArenaTeamSetEnd(); ++titr)
+ sWorld.SendGlobalText("Modifying played count, arena points etc. for loaded arena teams, sending updated stats to online players...", NULL);
+ for(ObjectMgr::ArenaTeamMap::iterator titr = objmgr.GetArenaTeamMapBegin(); titr != objmgr.GetArenaTeamMapEnd(); ++titr)
{
- if(ArenaTeam * at = (*titr))
+ if(ArenaTeam * at = titr->second)
{
- at->FinishWeek(); // set played this week etc values to 0 in memory, too
- // at->SaveToDB(); // no need, the modified values are already saved above
- at->NotifyStatsChanged(); // notify the players of the changes
+ at->FinishWeek(); // set played this week etc values to 0 in memory, too
+ at->SaveToDB(); // save changes
+ at->NotifyStatsChanged(); // notify the players of the changes
}
}
+
+ sWorld.SendGlobalText("Modification done.", NULL);
+
+ sWorld.SendGlobalText("Done flushing Arena points.", NULL);
}
void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player* plr, uint32 bgTypeId)
@@ -1782,7 +1832,10 @@ uint8 BattleGroundMgr::BGArenaType(uint32 bgQueueTypeId) const
void BattleGroundMgr::ToggleArenaTesting()
{
m_ArenaTesting = !m_ArenaTesting;
- sWorld.SendWorldText(LANG_ARENA_TESTING, m_ArenaTesting ? "on" : "off");
+ if(m_ArenaTesting)
+ sWorld.SendGlobalText("Arenas are set to 1v1 for debugging. So, don't join as group.", NULL);
+ else
+ sWorld.SendGlobalText("Arenas are set to normal playercount.", NULL);
}
void BattleGroundMgr::SetHolidayWeekends(uint32 mask)
diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h
index 26ca0ae6d13..b217c1d692e 100644
--- a/src/game/BattleGroundMgr.h
+++ b/src/game/BattleGroundMgr.h
@@ -53,13 +53,14 @@ struct GroupQueueInfo // stores informatio
{
std::map<uint64, PlayerQueueInfo*> Players; // player queue info map
uint32 Team; // Player team (ALLIANCE/HORDE)
- bool IsRated; // rated
uint32 BgTypeId; // battleground type id
+ bool IsRated; // rated
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
+ uint32 OpponentsTeamRating; // for rated arena matches
};
class BattleGround;
@@ -72,7 +73,7 @@ class BattleGroundQueue
void Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype = 0, bool isRated = false, uint32 minRating = 0);
GroupQueueInfo * AddGroup(Player * leader, uint32 BgTypeId, uint8 ArenaType, bool isRated, uint32 ArenaRating, uint32 ArenaTeamId = 0);
- void AddPlayer(Player *plr, GroupQueueInfo * ginfo);
+ void AddPlayer(Player *plr, GroupQueueInfo *ginfo);
void RemovePlayer(uint64 guid, bool decreaseInvitedCount);
void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);
void BGEndedRemoveInvites(BattleGround * bg);
@@ -235,7 +236,6 @@ class BattleGroundMgr
const bool isArenaTesting() const { return m_ArenaTesting; }
void SetHolidayWeekends(uint32 mask);
-
private:
/* Battlegrounds */
diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp
index 221fa6b291e..755089473e8 100644
--- a/src/game/BattleGroundWS.cpp
+++ b/src/game/BattleGroundWS.cpp
@@ -78,6 +78,9 @@ void BattleGroundWS::Update(time_t diff)
return;
}
+// for(uint32 i = WS_SPIRIT_MAIN_ALLIANCE; i <= WS_SPIRIT_MAIN_HORDE; i++)
+// SpawnBGCreature(i, RESPAWN_IMMEDIATELY);
+
for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; i++)
{
SpawnBGObject(i, RESPAWN_IMMEDIATELY);
diff --git a/src/game/Channel.cpp b/src/game/Channel.cpp
index 17b761d3933..e05a9793857 100644
--- a/src/game/Channel.cpp
+++ b/src/game/Channel.cpp
@@ -628,7 +628,7 @@ void Channel::Invite(uint64 p, const char *newname)
SendToOne(&data, newp->GetGUID());
data.clear();
}
- MakePlayerInvited(&data, newp->GetGUID());
+ MakePlayerInvited(&data, newp->GetName());
SendToOne(&data, p);
}
@@ -918,13 +918,8 @@ void Channel::MakeNotModerated(WorldPacket *data)
}
// done 0x1D
-void Channel::MakePlayerInvited(WorldPacket *data, uint64 guid)
+void Channel::MakePlayerInvited(WorldPacket *data, const std::string& name)
{
- std::string name;
-
- if(!objmgr.GetPlayerNameByGUID(guid, name) || name.empty())
- return; // player name not found
-
MakeNotifyPacket(data, CHAT_PLAYER_INVITED_NOTICE);
*data << name;
}
diff --git a/src/game/Channel.h b/src/game/Channel.h
index ed7bb316154..b8d322ee9f7 100644
--- a/src/game/Channel.h
+++ b/src/game/Channel.h
@@ -192,7 +192,7 @@ class Channel
void MakeWrongFaction(WorldPacket *data); //? 0x1A
void MakeInvalidName(WorldPacket *data); //? 0x1B
void MakeNotModerated(WorldPacket *data); //? 0x1C
- void MakePlayerInvited(WorldPacket *data, uint64 guid); //+ 0x1D
+ void MakePlayerInvited(WorldPacket *data, const std::string& name); //+ 0x1D
void MakePlayerInviteBanned(WorldPacket *data, uint64 guid); //? 0x1E
void MakeThrottled(WorldPacket *data); //? 0x1F
void MakeNotInArea(WorldPacket *data); //? 0x20
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index a68d46fe6d4..f5d0ff73bbf 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -38,6 +38,7 @@
#include "PlayerDump.h"
#include "SocialMgr.h"
#include "Util.h"
+#include "ArenaTeam.h"
#include "Language.h"
class LoginQueryHolder : public SqlQueryHolder
@@ -61,7 +62,7 @@ bool LoginQueryHolder::Initialize()
// NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure.
// !!! NOTE: including unused `zone`,`online`
- res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
@@ -81,6 +82,7 @@ bool LoginQueryHolder::Initialize()
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'",GUID_LOPART(m_guid));
// in other case still be dummy query
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD, "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO, "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));
return res;
}
@@ -413,7 +415,7 @@ void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data )
}
// is arena team captain
- if(objmgr.GetArenaTeamByCapitan(guid))
+ if(objmgr.GetArenaTeamByCaptain(guid))
{
WorldPacket data(SMSG_CHAR_DELETE, 1);
data << (uint8)CHAR_DELETE_FAILED_ARENA_CAPTAIN;
@@ -455,6 +457,12 @@ void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,8);
+ if(PlayerLoading() || GetPlayer() != NULL)
+ {
+ sLog.outError("Player tryes to login again, AccountId = %d",GetAccountId());
+ return;
+ }
+
m_playerLoading = true;
uint64 playerGuid = 0;
@@ -895,40 +903,14 @@ void WorldSession::HandleToggleCloakOpcode( WorldPacket & /*recv_data*/ )
void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
{
- CHECK_PACKET_SIZE(recv_data,8+1);
-
uint64 guid;
std::string newname;
- std::string oldname;
CHECK_PACKET_SIZE(recv_data, 8+1);
recv_data >> guid;
recv_data >> newname;
- QueryResult *result = CharacterDatabase.PQuery("SELECT at_login, name FROM characters WHERE guid ='%u'", GUID_LOPART(guid));
- if (!result)
- {
- WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_CREATE_ERROR;
- SendPacket( &data );
- return;
- }
-
- uint32 at_loginFlags;
- Field *fields = result->Fetch();
- at_loginFlags = fields[0].GetUInt32();
- oldname = fields[1].GetCppString();
- delete result;
-
- if (!(at_loginFlags & AT_LOGIN_RENAME))
- {
- WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_CREATE_ERROR;
- SendPacket( &data );
- return;
- }
-
// prevent character rename to invalid name
if(!normalizePlayerName(newname))
{
@@ -955,36 +937,58 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)
return;
}
- if(objmgr.GetPlayerGUIDByName(newname)) // character with this name already exist
+ CharacterDatabase.escape_string(newname);
+
+ CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack, GUID_LOPART(guid), newname, "SELECT guid, at_login, name FROM characters WHERE guid = '%u' XOR name = '%s'", GUID_LOPART(guid), newname.c_str());
+}
+
+void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname)
+{
+ WorldSession * session = sWorld.FindSession(accountId);
+ if(!session)
+ return;
+
+ if (!result || result->GetRowCount() != 1)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << (uint8)CHAR_CREATE_ERROR;
- SendPacket( &data );
+ session->SendPacket( &data );
return;
}
- if(newname == oldname) // checked by client
+ Field *fields = result->Fetch();
+ uint32 guidLow = fields[0].GetUInt32();
+ uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);
+ uint32 at_loginFlags = fields[1].GetUInt32();
+ std::string oldname = fields[2].GetCppString();
+ delete result;
+ if(oldname == newname)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
- data << (uint8)CHAR_NAME_FAILURE;
- SendPacket( &data );
+ data << (uint8)CHAR_CREATE_ERROR;
+ session->SendPacket( &data );
return;
}
// we have to check character at_login_flag & AT_LOGIN_RENAME also (fake packets hehe)
+ if (!(at_loginFlags & AT_LOGIN_RENAME))
+ {
+ WorldPacket data(SMSG_CHAR_RENAME, 1);
+ data << (uint8)CHAR_CREATE_ERROR;
+ session->SendPacket( &data );
+ return;
+ }
- CharacterDatabase.escape_string(newname);
- CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME),GUID_LOPART(guid));
- CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid));
+ CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME),guidLow);
+ CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
- std::string IP_str = GetRemoteAddress();
- sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",GetAccountId(),IP_str.c_str(),oldname.c_str(),GUID_LOPART(guid),newname.c_str());
+ sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",session->GetAccountId(),session->GetRemoteAddress().c_str(),oldname.c_str(),guidLow,newname.c_str());
WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1));
data << (uint8)RESPONSE_SUCCESS;
data << guid;
data << newname;
- SendPacket(&data);
+ session->SendPacket(&data);
}
void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data)
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 30bab9ec0d3..4a4a6f8d2be 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -202,6 +202,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMod32Value, "", NULL },
{ "anim", SEC_GAMEMASTER, false, &ChatHandler::HandleAnimCommand, "", NULL },
{ "lootrecipient", SEC_GAMEMASTER, false, &ChatHandler::HandleGetLootRecipient, "", NULL },
+ { "arena", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugArenaCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -592,6 +593,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "cometome", SEC_ADMINISTRATOR, false, &ChatHandler::HandleComeToMeCommand, "", NULL },
{ "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL },
{ "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL },
+ { "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
{ "chardelete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
{ "sendmessage", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMessageCommand, "", NULL },
{ "playall", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlayAllCommand, "", NULL },
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 6c5c07ed70e..2a7b1b62bdd 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -441,9 +441,9 @@ class ChatHandler
bool HandleCombatStopCommand(const char *args);
bool HandleCharDeleteCommand(const char *args);
bool HandleSendMessageCommand(const char * args);
+ bool HandleFlushArenaPointsCommand(const char *args);
bool HandlePlayAllCommand(const char* args);
bool HandleRepairitemsCommand(const char* args);
- bool HandleFlushArenaPointsCommand(const char *args);
//! Development Commands
bool HandleSetValue(const char* args);
diff --git a/src/game/GameEvent.cpp b/src/game/GameEvent.cpp
index 67d895cfc89..17084dd3ebf 100644
--- a/src/game/GameEvent.cpp
+++ b/src/game/GameEvent.cpp
@@ -956,7 +956,7 @@ uint32 GameEvent::Update() // return the next e
uint32 nextEventDelay = max_ge_check_delay; // 1 day
uint32 calcDelay;
std::set<uint16> activate, deactivate;
- for (uint16 itr = 1; itr < mGameEvent.size(); itr++)
+ for (uint16 itr = 1; itr < mGameEvent.size(); ++itr)
{
// must do the activating first, and after that the deactivating
// so first queue it
diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp
index 06eef145af5..df2554db9ea 100644
--- a/src/game/Guild.cpp
+++ b/src/game/Guild.cpp
@@ -380,7 +380,7 @@ bool Guild::FillPlayerData(uint64 guid, MemberSlot* memslot)
return false;
plLevel = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL, guid);
- if(plLevel<1||plLevel>255) // can be at broken `data` field
+ if(plLevel<1||plLevel>STRONG_MAX_LEVEL) // can be at broken `data` field
{
sLog.outError("Player (GUID: %u) has a broken data in field `characters`.`data`.",GUID_LOPART(guid));
return false;
diff --git a/src/game/Language.h b/src/game/Language.h
index 441583c14db..0adaabea88c 100644
--- a/src/game/Language.h
+++ b/src/game/Language.h
@@ -640,12 +640,14 @@ enum TrinityStrings
LANG_PLAYER_DND_DEFAULT = 709,
LANG_PLAYER_AFK_DEFAULT = 710,
- LANG_BG_GROUP_TOO_LARGE = 711,
- LANG_ARENA_GROUP_TOO_LARGE = 712,
+ LANG_BG_QUEUE_ANNOUNCE_SELF = 711,
+ LANG_BG_QUEUE_ANNOUNCE_WORLD = 712,
+
+
LANG_YOUR_ARENA_LEVEL_REQ_ERROR = 713,
- LANG_HIS_ARENA_LEVEL_REQ_ERROR = 714,
+// LANG_HIS_ARENA_LEVEL_REQ_ERROR = 714, an opcode exists for this
LANG_YOUR_BG_LEVEL_REQ_ERROR = 715,
- LANG_YOUR_ARENA_TEAM_FULL = 716,
+// LANG_YOUR_ARENA_TEAM_FULL = 716, an opcode exists for this
LANG_BG_AV_ALLY = 717,
LANG_BG_AV_HORDE = 718,
@@ -686,28 +688,30 @@ enum TrinityStrings
// Room for BG/ARENA 750-769 not used
- LANG_ARENA_YOUR_TEAM_ONLY = 770,
- LANG_ARENA_NOT_ENOUGH_PLAYERS = 771,
- LANG_ARENA_GOLD_WINS = 772,
- LANG_ARENA_GREEN_WINS = 773,
- LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 774,
- LANG_BG_GROUP_OFFLINE_MEMBER = 775,
- LANG_BG_GROUP_MIXED_FACTION = 776,
- LANG_BG_GROUP_MIXED_LEVELS = 777,
- LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 778,
- LANG_BG_GROUP_MEMBER_DESERTER = 779,
- LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 780,
-
- LANG_CANNOT_TELE_TO_BG = 781,
- LANG_CANNOT_SUMMON_TO_BG = 782,
- LANG_CANNOT_GO_TO_BG_GM = 783,
- LANG_CANNOT_GO_TO_BG_FROM_BG = 784,
-
LANG_ARENA_TESTING = 785,
LANG_AUTO_ANN = 786,
LANG_ANNOUNCE_COLOR = 787,
+ LANG_BG_GROUP_TOO_LARGE = 1122, // "Your group is too large for this battleground. Please regroup to join."
+ LANG_ARENA_GROUP_TOO_LARGE = 1123, // "Your group is too large for this arena. Please regroup to join."
+ LANG_ARENA_YOUR_TEAM_ONLY = 1124, // "Your group has members not in your arena team. Please regroup to join."
+ LANG_ARENA_NOT_ENOUGH_PLAYERS = 1125, // "Your group does not have enough players to join this match."
+ LANG_ARENA_GOLD_WINS = 1126, // "The Gold Team wins!"
+ LANG_ARENA_GREEN_WINS = 1127, // "The Green Team wins!"
+ LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 1128, // The battleground will end soon, because there aren't enough players. Get more ppl or win already!
+ LANG_BG_GROUP_OFFLINE_MEMBER = 1129, // "Your group has an offline member. Please remove him before joining."
+ LANG_BG_GROUP_MIXED_FACTION = 1130, // "Your group has players from the opposing faction. You can't join the battleground as a group."
+ LANG_BG_GROUP_MIXED_LEVELS = 1131, // "Your group has players from different battleground brakets. You can't join as group."
+ LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 1132, // "Someone in your party is already in this battleground queue. (S)he must leave it before joining as group."
+ LANG_BG_GROUP_MEMBER_DESERTER = 1133, // "Someone in your party is Deserter. You can't join as group."
+ LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 1134, // "Someone in your party is already in three battleground queues. You cannot join as group."
+
+ LANG_CANNOT_TELE_TO_BG = 1135, // "You cannot teleport to a battleground or arena map."
+ LANG_CANNOT_SUMMON_TO_BG = 1136, // "You cannot summon players to a battleground or arena map."
+ LANG_CANNOT_GO_TO_BG_GM = 1137, // "You must be in GM mode to teleport to a player in a battleground."
+ LANG_CANNOT_GO_TO_BG_FROM_BG = 1138, // "You cannot teleport to a battleground from another battleground. Please leave the current battleground first."
+
// in game strings
LANG_PET_INVALID_NAME = 800,
LANG_NOT_ENOUGH_GOLD = 801,
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index d842cd34361..002b7c9aa3a 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -10,12 +10,12 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Common.h"
@@ -136,7 +136,6 @@ bool ChatHandler::HandleAnnounceCommand(const char* args)
return false;
sWorld.SendWorldText(LANG_SYSTEMMESSAGE,args);
-
return true;
}
@@ -230,7 +229,6 @@ bool ChatHandler::HandleGMChatCommand(const char* args)
return false;
}
-
//Enable\Dissable Invisible mode
bool ChatHandler::HandleVisibleCommand(const char* args)
{
@@ -303,7 +301,7 @@ bool ChatHandler::HandleGPSCommand(const char* args)
Map2ZoneCoordinates(zone_x,zone_y,zone_id);
- Map const *map = MapManager::Instance().GetMap(obj->GetMapId(), obj);
+ Map const *map = obj->GetMap();
float ground_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), MAX_HEIGHT);
float floor_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ());
@@ -363,18 +361,18 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
return false;
}
- Map* pMap = MapManager::Instance().GetMap(m_session->GetPlayer()->GetMapId(),m_session->GetPlayer());
+ Map* pMap = m_session->GetPlayer()->GetMap();
if(pMap->IsBattleGroundOrArena())
{
// cannot summon to bg
- SendSysMessage(LANG_CANNOT_SUMMON_TO_BG);
+ PSendSysMessage(LANG_CANNOT_SUMMON_TO_BG,chr->GetName());
SetSentErrorMessage(true);
return false;
}
else if(pMap->IsDungeon())
{
- Map* cMap = MapManager::Instance().GetMap(chr->GetMapId(),chr);
+ Map* cMap = chr->GetMap();
if( cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId() )
{
// cannot summon from instance to instance
@@ -456,20 +454,20 @@ bool ChatHandler::HandleGonameCommand(const char* args)
Player *chr = objmgr.GetPlayer(name.c_str());
if (chr)
{
- Map* cMap = MapManager::Instance().GetMap(chr->GetMapId(),chr);
+ Map* cMap = chr->GetMap();
if(cMap->IsBattleGroundOrArena())
{
// only allow if gm mode is on
if (!_player->isGameMaster())
{
- SendSysMessage(LANG_CANNOT_GO_TO_BG_GM);
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chr->GetName());
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);
+ PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chr->GetName());
SetSentErrorMessage(true);
return false;
}
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index 6b4848f08d1..2b75b9324c1 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -3137,6 +3137,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
}while(result->NextRow());
// set "wpguid" column to "empty" - no visual waypoint spawned
WorldDatabase.PExecuteLog("UPDATE waypoint_data SET wpguid = '0'");
+ //WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'");
if( hasError )
{
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index f700aeec566..13f6b101a7b 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -3914,8 +3914,8 @@ bool ChatHandler::HandleLevelUpCommand(const char* args)
int32 newlevel = oldlevel + addlevel;
if(newlevel < 1)
newlevel = 1;
- if(newlevel > 255) // hardcoded maximum level
- newlevel = 255;
+ if(newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
+ newlevel = STRONG_MAX_LEVEL;
if(chr)
{
@@ -4673,7 +4673,7 @@ bool ChatHandler::HandleResetAllCommand(const char * args)
return false;
}
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u'",atLogin);
+ CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin);
HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
itr->second->SetAtLoginFlag(atLogin);
@@ -6588,6 +6588,12 @@ bool ChatHandler::HandleSendMessageCommand(const char* args)
return true;
}
+bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
+{
+ sBattleGroundMgr.DistributeArenaPoints();
+ return true;
+}
+
bool ChatHandler::HandleModifyGenderCommand(const char *args)
{
if(!*args)
@@ -6850,12 +6856,6 @@ bool ChatHandler::HandleListFreezeCommand(const char* args)
return true;
}
-bool ChatHandler::HandleFlushArenaPointsCommand(const char * /*args*/)
-{
- sBattleGroundMgr.DistributeArenaPoints();
- return true;
-}
-
bool ChatHandler::HandleGroupLeaderCommand(const char* args)
{
Player* plr = NULL;
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index 0b1bb606b14..f5ee5dbcf4c 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -84,7 +84,7 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
std::string player_name, guild_name;
recv_data >> level_min; // maximal player level, default 0
- recv_data >> level_max; // minimal player level, default 100
+ recv_data >> level_max; // minimal player level, default 100 (MAX_LEVEL)
recv_data >> player_name; // player name, case sensitive...
// recheck
@@ -149,8 +149,8 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data )
// client send in case not set max level value 100 but mangos support 255 max level,
// update it to show GMs with characters after 100 level
- if(level_max >= 100)
- level_max = 255;
+ if(level_max >= MAX_LEVEL)
+ level_max = STRONG_MAX_LEVEL;
uint32 team = _player->GetTeam();
uint32 security = GetSecurity();
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index 95a5ce588b1..0a310cddd96 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -324,7 +324,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
GetPlayer()->m_movementInfo = movementInfo;
- if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z)
+ if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z);
if(GetPlayer()->isMovingOrTurning())
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index a2a7d34fdf5..06bc3b95304 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -141,13 +141,13 @@ ObjectMgr::ObjectMgr()
ObjectMgr::~ObjectMgr()
{
- for( QuestMap::iterator i = mQuestTemplates.begin( ); i != mQuestTemplates.end( ); ++ i )
+ for( QuestMap::iterator i = mQuestTemplates.begin( ); i != mQuestTemplates.end( ); ++i )
{
delete i->second;
}
mQuestTemplates.clear( );
- for( GossipTextMap::iterator i = mGossipText.begin( ); i != mGossipText.end( ); ++ i )
+ for( GossipTextMap::iterator i = mGossipText.begin( ); i != mGossipText.end( ); ++i )
{
delete i->second;
}
@@ -155,7 +155,7 @@ ObjectMgr::~ObjectMgr()
mAreaTriggers.clear();
- for(PetLevelInfoMap::iterator i = petInfo.begin( ); i != petInfo.end( ); ++ i )
+ for(PetLevelInfoMap::iterator i = petInfo.begin( ); i != petInfo.end( ); ++i )
{
delete[] i->second;
}
@@ -288,33 +288,43 @@ Guild* ObjectMgr::GetGuildByLeader(const uint64 &guid) const
return NULL;
}
-ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 ArenaTeamId) const
+ArenaTeam* ObjectMgr::GetArenaTeamById(const uint32 arenateamid) const
{
- for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); ++itr)
- if ((*itr)->GetId() == ArenaTeamId)
- return *itr;
+ ArenaTeamMap::const_iterator itr = mArenaTeamMap.find(arenateamid);
+ if (itr != mArenaTeamMap.end())
+ return itr->second;
return NULL;
}
ArenaTeam* ObjectMgr::GetArenaTeamByName(const std::string& arenateamname) const
{
- for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); ++itr)
- if ((*itr)->GetName() == arenateamname)
- return *itr;
+ for(ArenaTeamMap::const_iterator itr = mArenaTeamMap.begin(); itr != mArenaTeamMap.end(); ++itr)
+ if (itr->second->GetName() == arenateamname)
+ return itr->second;
return NULL;
}
-ArenaTeam* ObjectMgr::GetArenaTeamByCapitan(uint64 const& guid) const
+ArenaTeam* ObjectMgr::GetArenaTeamByCaptain(uint64 const& guid) const
{
- for(ArenaTeamSet::const_iterator itr = mArenaTeamSet.begin(); itr != mArenaTeamSet.end(); ++itr)
- if ((*itr)->GetCaptain() == guid)
- return *itr;
+ for(ArenaTeamMap::const_iterator itr = mArenaTeamMap.begin(); itr != mArenaTeamMap.end(); ++itr)
+ if (itr->second->GetCaptain() == guid)
+ return itr->second;
return NULL;
}
+void ObjectMgr::AddArenaTeam(ArenaTeam* arenaTeam)
+{
+ mArenaTeamMap[arenaTeam->GetId()] = arenaTeam;
+}
+
+void ObjectMgr::RemoveArenaTeam(ArenaTeam* arenaTeam)
+{
+ mArenaTeamMap.erase( arenaTeam->GetId() );
+}
+
AuctionHouseObject * ObjectMgr::GetAuctionsMap( uint32 location )
{
switch ( location )
@@ -2004,8 +2014,8 @@ void ObjectMgr::LoadPetLevelInfo()
uint32 current_level = fields[1].GetUInt32();
if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
{
- if(current_level > 255) // hardcoded level maximum
- sLog.outErrorDb("Wrong (> 255) level %u in `pet_levelstats` table, ignoring.",current_level);
+ if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
+ sLog.outErrorDb("Wrong (> %u) level %u in `pet_levelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level);
else
sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `pet_levelstats` table, ignoring.",current_level);
continue;
@@ -2385,8 +2395,8 @@ void ObjectMgr::LoadPlayerInfo()
uint32 current_level = fields[1].GetUInt32();
if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
{
- if(current_level > 255) // hardcoded level maximum
- sLog.outErrorDb("Wrong (> 255) level %u in `player_classlevelstats` table, ignoring.",current_level);
+ if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
+ sLog.outErrorDb("Wrong (> %u) level %u in `player_classlevelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level);
else
sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_classlevelstats` table, ignoring.",current_level);
continue;
@@ -2480,8 +2490,8 @@ void ObjectMgr::LoadPlayerInfo()
uint32 current_level = fields[2].GetUInt32();
if(current_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
{
- if(current_level > 255) // hardcoded level maximum
- sLog.outErrorDb("Wrong (> 255) level %u in `player_levelstats` table, ignoring.",current_level);
+ if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum
+ sLog.outErrorDb("Wrong (> %u) level %u in `player_levelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level);
else
sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_levelstats` table, ignoring.",current_level);
continue;
@@ -4315,7 +4325,7 @@ void ObjectMgr::AddGossipText(GossipText *pGText)
GossipText *ObjectMgr::GetGossipText(uint32 Text_ID)
{
GossipTextMap::const_iterator itr;
- for (itr = mGossipText.begin(); itr != mGossipText.end(); itr++)
+ for (itr = mGossipText.begin(); itr != mGossipText.end(); ++itr)
{
if(itr->second->Text_ID == Text_ID)
return itr->second;
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index 7750cf7095a..4a35f98b679 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -304,10 +304,10 @@ class ObjectMgr
typedef std::set< Group * > GroupSet;
typedef std::set< Guild * > GuildSet;
- typedef std::set< ArenaTeam * > ArenaTeamSet;
- typedef UNORDERED_MAP<uint32, Quest*> QuestMap;
+ typedef UNORDERED_MAP<uint32, ArenaTeam* > ArenaTeamMap;
+ typedef UNORDERED_MAP<uint32, Quest*> QuestMap;
typedef UNORDERED_MAP<uint32, AreaTrigger> AreaTriggerMap;
@@ -340,13 +340,13 @@ class ObjectMgr
void AddGuild(Guild* guild) { mGuildSet.insert( guild ); }
void RemoveGuild(Guild* guild) { mGuildSet.erase( guild ); }
- ArenaTeam* GetArenaTeamById(const uint32 ArenaTeamId) const;
- ArenaTeam* GetArenaTeamByName(const std::string& ArenaTeamName) const;
- 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(); }
+ ArenaTeam* GetArenaTeamById(const uint32 arenateamid) const;
+ ArenaTeam* GetArenaTeamByName(const std::string& arenateamname) const;
+ ArenaTeam* GetArenaTeamByCaptain(uint64 const& guid) const;
+ void AddArenaTeam(ArenaTeam* arenaTeam);
+ void RemoveArenaTeam(ArenaTeam* arenaTeam);
+ ArenaTeamMap::iterator GetArenaTeamMapBegin() { return mArenaTeamMap.begin(); }
+ ArenaTeamMap::iterator GetArenaTeamMapEnd() { return mArenaTeamMap.end(); }
static CreatureInfo const *GetCreatureTemplate( uint32 id );
CreatureModelInfo const *GetCreatureModelInfo( uint32 modelid );
@@ -835,7 +835,7 @@ class ObjectMgr
GroupSet mGroupSet;
GuildSet mGuildSet;
- ArenaTeamSet mArenaTeamSet;
+ ArenaTeamMap mArenaTeamMap;
ItemMap mItems;
ItemMap mAitems;
diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp
index 9c2107d2ee7..52e6559073b 100644
--- a/src/game/PetitionsHandler.cpp
+++ b/src/game/PetitionsHandler.cpp
@@ -117,14 +117,6 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
return;
}
- for(uint8 i = 0; i < MAX_ARENA_SLOT; i++)
- {
- if(_player->GetArenaTeamId(i) && (i == (unk10-1)))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM);
- return;
- }
- }
switch(unk10)
{
case 1:
@@ -146,6 +138,12 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
sLog.outDebug("unknown selection at buy petition: %u", unk10);
return;
}
+
+ if(_player->GetArenaTeamId(unk10-1))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM);
+ return;
+ }
}
if(type == 9)
@@ -155,12 +153,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_EXISTS);
return;
}
- if(objmgr.IsReservedName(name))
- {
- SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_INVALID);
- return;
- }
- if(!ObjectMgr::IsValidCharterName(name))
+ if(objmgr.IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
{
SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_INVALID);
return;
@@ -173,12 +166,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
return;
}
- if(objmgr.IsReservedName(name))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID);
- return;
- }
- if(!ObjectMgr::IsValidCharterName(name))
+ if(objmgr.IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID);
return;
@@ -218,6 +206,8 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
_player->SendNewItem(charter, 1, true, false);
// a petition is invalid, if both the owner and the type matches
+ // we checked above, if this player is in an arenateam, so this must be
+ // datacorruption
QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE ownerguid = '%u' AND type = '%u'", _player->GetGUIDLow(), type);
std::ostringstream ssInvalidPetitionGUIDs;
@@ -262,15 +252,16 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data)
// solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?)
uint32 petitionguid_low = GUID_LOPART(petitionguid);
- QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid, type FROM petition WHERE petitionguid = '%u'", petitionguid_low);
+ QueryResult *result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", petitionguid_low);
if(!result)
{
sLog.outError("any petition on server...");
return;
}
Field *fields = result->Fetch();
- uint32 type = fields[1].GetUInt32();
+ uint32 type = fields[0].GetUInt32();
delete result;
+
// if guild petition and has guild => error, return;
if(type==9 && _player->GetGuildId())
return;
@@ -328,7 +319,8 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid)
QueryResult *result = CharacterDatabase.PQuery(
"SELECT ownerguid, name, "
- " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs "
+ " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
+ " type "
"FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
if(result)
@@ -337,6 +329,7 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid)
ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
name = fields[1].GetCppString();
signs = fields[2].GetUInt8();
+ type = fields[3].GetUInt32();
delete result;
}
else
@@ -345,20 +338,6 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid)
return;
}
- QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
-
- if(result2)
- {
- Field* fields = result2->Fetch();
- type = fields[0].GetUInt32();
- delete result2;
- }
- else
- {
- sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
- return;
- }
-
WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*13));
data << GUID_LOPART(petitionguid); // guild/team guid (in Trinity always same as GUID_LOPART(petition guid)
data << ownerguid; // charter owner guid
@@ -410,13 +389,13 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data)
if(!item)
return;
- QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ QueryResult *result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
- if(result2)
+ if(result)
{
- Field* fields = result2->Fetch();
+ Field* fields = result->Fetch();
type = fields[0].GetUInt32();
- delete result2;
+ delete result;
}
else
{
@@ -431,12 +410,7 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data)
SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_EXISTS);
return;
}
- if(objmgr.IsReservedName(newname))
- {
- SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_INVALID);
- return;
- }
- if(!ObjectMgr::IsValidCharterName(newname))
+ if(objmgr.IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
{
SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_INVALID);
return;
@@ -449,12 +423,7 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data)
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
return;
}
- if(objmgr.IsReservedName(newname))
- {
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID);
- return;
- }
- if(!ObjectMgr::IsValidCharterName(newname))
+ if(objmgr.IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID);
return;
@@ -482,17 +451,14 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
Field *fields;
uint64 petitionguid;
- uint32 type;
uint8 unk;
- uint64 ownerguid;
recv_data >> petitionguid; // petition guid
recv_data >> unk;
- uint8 signs = 0;
-
QueryResult *result = CharacterDatabase.PQuery(
"SELECT ownerguid, "
- " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs "
+ " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
+ " type "
"FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
if(!result)
@@ -502,8 +468,9 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
}
fields = result->Fetch();
- ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
- signs = fields[1].GetUInt8();
+ uint64 ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ uint8 signs = fields[1].GetUInt8();
+ uint32 type = fields[2].GetUInt32();
delete result;
@@ -513,31 +480,53 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
// not let enemies sign guild charter
if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != objmgr.GetPlayerTeamByGUID(ownerguid))
+ {
+ if(type != 9)
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
+ else
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_NOT_ALLIED);
return;
+ }
- QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
-
- if(result2)
+ if(type != 9)
{
- Field* fields = result2->Fetch();
- type = fields[0].GetUInt32();
- delete result2;
+ if(_player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", _player->GetName(), ERR_ARENA_TEAM_PLAYER_TO_LOW);
+ return;
+ }
+
+ uint8 slot = ArenaTeam::GetSlotByType(type);
+ if(slot >= MAX_ARENA_SLOT)
+ return;
+
+ if(_player->GetArenaTeamId(slot))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S);
+ return;
+ }
+
+ if(_player->GetArenaTeamIdInvited())
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
+ return;
+ }
}
else
{
- sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
- return;
- }
-
- if(type != 9 && _player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- // player is too low level to join an arena team
- SendNotification(LANG_YOUR_ARENA_LEVEL_REQ_ERROR,sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
- return;
+ if(_player->GetGuildId())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ALREADY_IN_GUILD);
+ return;
+ }
+ if(_player->GetGuildIdInvited())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ALREADY_INVITED_TO_GUILD);
+ return;
+ }
}
- signs += 1;
- if(signs > type) // client signs maximum
+ if(++signs > type) // client signs maximum
return;
//client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
@@ -621,29 +610,75 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data)
uint8 signs = 0;
uint64 petitionguid, plguid;
- uint32 petitiontype;
+ uint32 type, junk;
Player *player;
- recv_data >> petitiontype; // 2.0.8 - petition type?
+ recv_data >> junk; // this is not petition type!
recv_data >> petitionguid; // petition guid
recv_data >> plguid; // player guid
- sLog.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", petitiontype, GUID_LOPART(petitionguid), GUID_LOPART(plguid));
player = ObjectAccessor::FindPlayer(plguid);
- if(!player || player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
+ if (!player)
return;
- // not let offer to enemies
- if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam() )
+ QueryResult *result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ if (!result)
return;
- QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
- if(!result)
+ Field *fields = result->Fetch();
+ type = fields[0].GetUInt32();
+ delete result;
+
+ sLog.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", type, GUID_LOPART(petitionguid), GUID_LOPART(plguid));
+
+ if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam() )
{
- sLog.outError("any petition on server...");
+ if(type != 9)
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
+ else
+ SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_NOT_ALLIED);
return;
}
- delete result;
+ if(type != 9)
+ {
+ if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ // player is too low level to join an arena team
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName(), "", ERR_ARENA_TEAM_PLAYER_TO_LOW);
+ return;
+ }
+
+ uint8 slot = ArenaTeam::GetSlotByType(type);
+ if(slot >= MAX_ARENA_SLOT)
+ return;
+
+ if(player->GetArenaTeamId(slot))
+ {
+ // player is already in an arena team
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S);
+ return;
+ }
+
+ if(player->GetArenaTeamIdInvited())
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
+ return;
+ }
+ }
+ else
+ {
+ if(player->GetGuildId())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ALREADY_IN_GUILD);
+ return;
+ }
+
+ if(player->GetGuildIdInvited())
+ {
+ SendGuildCommandResult(GUILD_INVITE_S, _player->GetName(), ALREADY_INVITED_TO_GUILD);
+ return;
+ }
+ }
result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
// result==NULL also correct charter without signs
@@ -813,7 +848,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data)
else // or arena team
{
ArenaTeam* at = new ArenaTeam;
- if(!at->create(_player->GetGUID(), type, name))
+ if(!at->Create(_player->GetGUID(), type, name))
{
sLog.outError("PetitionsHandler: arena team create failed.");
delete at;
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 1be902f72e4..26ba1853176 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -731,12 +731,12 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
}
}
- StoreNewItemInBestSlot(item_id, count);
+ StoreNewItemInBestSlots(item_id, count);
}
}
for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++)
- StoreNewItemInBestSlot(item_id_itr->item_id, item_id_itr->item_amount);
+ StoreNewItemInBestSlots(item_id_itr->item_id, item_id_itr->item_amount);
// bags and main-hand weapon must equipped at this moment
// now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon)
@@ -776,24 +776,30 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8
return true;
}
-bool Player::StoreNewItemInBestSlot(uint32 titem_id, uint32 titem_amount)
+bool Player::StoreNewItemInBestSlots(uint32 titem_id, uint32 titem_amount)
{
sLog.outDebug("STORAGE: Creating initial item, itemId = %u, count = %u",titem_id, titem_amount);
- // attempt equip
- uint16 eDest;
- uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, titem_amount, false );
- if( msg == EQUIP_ERR_OK )
+ // attempt equip by one
+ while(titem_amount > 0)
{
- EquipNewItem( eDest, titem_id, titem_amount, true);
+ uint16 eDest;
+ uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, false );
+ if( msg != EQUIP_ERR_OK )
+ break;
+
+ EquipNewItem( eDest, titem_id, true);
AutoUnequipOffhandIfNeed();
- return true; // equipped
+ --titem_amount;
}
+ if(titem_amount == 0)
+ return true; // equipped
+
// attempt store
ItemPosCountVec sDest;
// store in main bag to simplify second pass (special bags can be not equipped yet at this moment)
- msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount );
+ uint8 msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount );
if( msg == EQUIP_ERR_OK )
{
StoreNewItem( sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id) );
@@ -8098,7 +8104,7 @@ void Player::SendInitWorldStates(bool forceZone, uint32 forceZoneId)
bg->FillInitialWorldStates(data);
else
{
- data << uint32(0xbb8) << uint32(0x0); // 7 gold
+ data << uint32(0xbb8) << uint32(0x0); // 7 gold
data << uint32(0xbb9) << uint32(0x0); // 8 green
data << uint32(0xbba) << uint32(0x0); // 9 show
}
@@ -9666,10 +9672,10 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
}
//////////////////////////////////////////////////////////////////////////
-uint8 Player::CanEquipNewItem( uint8 slot, uint16 &dest, uint32 item, uint32 count, bool swap ) const
+uint8 Player::CanEquipNewItem( uint8 slot, uint16 &dest, uint32 item, bool swap ) const
{
dest = 0;
- Item *pItem = Item::CreateItem( item, count, this );
+ Item *pItem = Item::CreateItem( item, 1, this );
if( pItem )
{
uint8 result = CanEquipItem(slot, dest, pItem, swap );
@@ -10333,12 +10339,12 @@ Item* Player::_StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, boo
}
}
-Item* Player::EquipNewItem( uint16 pos, uint32 item, uint32 count, bool update )
+Item* Player::EquipNewItem( uint16 pos, uint32 item, bool update )
{
- Item *pItem = Item::CreateItem( item, count, this );
+ Item *pItem = Item::CreateItem( item, 1, this );
if( pItem )
{
- ItemAddedQuestCheck( item, count );
+ ItemAddedQuestCheck( item, 1 );
Item * retItem = EquipItem( pos, pItem, update );
return retItem;
@@ -13689,6 +13695,36 @@ void Player::_LoadDeclinedNames(QueryResult* result)
delete result;
}
+void Player::_LoadArenaTeamInfo(QueryResult *result)
+{
+ // arenateamid, played_week, played_season, personal_rating
+ memset((void*)&m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1], 0, sizeof(uint32)*18);
+ if (!result)
+ return;
+
+ do
+ {
+ Field *fields = result->Fetch();
+
+ uint32 arenateamid = fields[0].GetUInt32();
+ uint32 played_week = fields[1].GetUInt32();
+ uint32 played_season = fields[2].GetUInt32();
+ uint32 personal_rating = fields[3].GetUInt32();
+
+ ArenaTeam* aTeam = objmgr.GetArenaTeamById(arenateamid);
+ uint8 arenaSlot = aTeam->GetSlot();
+
+ m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 3] = arenateamid; // TeamID
+ m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 3 + 1] = ((aTeam->GetCaptain() == GetGUID()) ? (uint32)0 : (uint32)1); // Captain 0, member 1
+ m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 3 + 2] = played_week; // Played Week
+ m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 3 + 3] = played_season; // Played Season
+ m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 3 + 4] = 0; // Unk
+ m_uint32Values[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + arenaSlot * 3 + 5] = personal_rating; // Personal Rating
+
+ }while (result->NextRow());
+ delete result;
+}
+
bool Player::LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& o, bool& in_flight, uint64 guid)
{
QueryResult *result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,taxi_path FROM characters WHERE guid = '%u'",GUID_LOPART(guid));
@@ -13791,8 +13827,8 @@ float Player::GetFloatValueFromDB(uint16 index, uint64 guid)
bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
{
- //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32
- //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty FROM characters WHERE guid = '%u'", guid);
+ //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [28] [29] 30 31 32 33
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT guid, account, data, name, race, class, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points FROM characters WHERE guid = '%u'", guid);
QueryResult *result = holder->GetResult(PLAYER_LOGIN_QUERY_LOADFROM);
if(!result)
@@ -13882,6 +13918,14 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
_LoadGroup(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGROUP));
+ _LoadArenaTeamInfo(holder->GetResult(PLAYER_LOGIN_QUERY_LOADARENAINFO));
+
+ uint32 arena_currency = GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY) + fields[33].GetUInt32();
+ if (arena_currency > sWorld.getConfig(CONFIG_MAX_ARENA_POINTS))
+ arena_currency = sWorld.getConfig(CONFIG_MAX_ARENA_POINTS);
+
+ SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, arena_currency);
+
// check arena teams integrity
for(uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
{
@@ -15281,7 +15325,7 @@ void Player::SaveToDB()
"taximask, online, cinematic, "
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, "
"trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, "
- "death_expire_time, taxi_path, latency) VALUES ("
+ "death_expire_time, taxi_path, arena_pending_points, latency) VALUES ("
<< GetGUIDLow() << ", "
<< GetSession()->GetAccountId() << ", '"
<< sql_name << "', "
@@ -15380,7 +15424,8 @@ void Player::SaveToDB()
ss << ", '";
ss << m_taxi.SaveTaxiDestinationsToString();
- ss << "', '";
+
+ ss << "', '0', '";
ss << GetSession()->GetLatency();
ss << "' )";
@@ -17094,8 +17139,14 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
}
else if( IsEquipmentPos( bag, slot ) )
{
+ if(pProto->BuyCount * count != 1)
+ {
+ SendEquipError( EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL );
+ return false;
+ }
+
uint16 dest;
- uint8 msg = CanEquipNewItem( slot, dest, item, pProto->BuyCount * count, false );
+ uint8 msg = CanEquipNewItem( slot, dest, item, false );
if( msg != EQUIP_ERR_OK )
{
SendEquipError( msg, NULL, NULL );
@@ -17117,7 +17168,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
}
}
- if(Item *it = EquipNewItem( dest, item, pProto->BuyCount * count, true ))
+ if(Item *it = EquipNewItem( dest, item, true ))
{
uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count);
@@ -18253,6 +18304,11 @@ uint32 Player::GetBattleGroundQueueIdFromLevel() const
return 6;
else
return level/10 - 1; // 20..29 -> 1, 30-39 -> 2, ...
+ /*
+ assert(bgTypeId < MAX_BATTLEGROUND_TYPES);
+ BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId);
+ assert(bg);
+ return (getLevel() - bg->GetMinLevel()) / 10;*/
}
float Player::GetReputationPriceDiscount( Creature const* pCreature ) const
@@ -18962,7 +19018,8 @@ void Player::HandleFallDamage(MovementInfo& movementInfo)
void Player::HandleFallUnderMap()
{
- if(InBattleGround() && GetBattleGround()
+ if(InBattleGround()
+ && GetBattleGround()
&& GetBattleGround()->HandlePlayerUnderMap(this))
{
// do nothing, the handle already did if returned true
diff --git a/src/game/Player.h b/src/game/Player.h
index 2f3a799805a..55dda581261 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -812,9 +812,10 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOADSPELLCOOLDOWNS = 15,
PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES = 16,
PLAYER_LOGIN_QUERY_LOADGUILD = 17,
-};
+ PLAYER_LOGIN_QUERY_LOADARENAINFO = 18,
-#define MAX_PLAYER_LOGIN_QUERY 18
+ MAX_PLAYER_LOGIN_QUERY
+};
// Player summoning auto-decline time (in secs)
#define MAX_PLAYER_SUMMON_DELAY (2*MINUTE)
@@ -1067,7 +1068,7 @@ class TRINITY_DLL_SPEC Player : public Unit
}
uint8 CanStoreItems( Item **pItem,int count) const;
- uint8 CanEquipNewItem( uint8 slot, uint16 &dest, uint32 item, uint32 count, bool swap ) const;
+ uint8 CanEquipNewItem( uint8 slot, uint16 &dest, uint32 item, bool swap ) const;
uint8 CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading = true ) const;
uint8 CanUnequipItems( uint32 item, uint32 count ) const;
uint8 CanUnequipItem( uint16 src, bool swap ) const;
@@ -1078,10 +1079,10 @@ class TRINITY_DLL_SPEC Player : public Unit
uint8 CanUseAmmo( uint32 item ) const;
Item* StoreNewItem( ItemPosCountVec const& pos, uint32 item, bool update,int32 randomPropertyId = 0 );
Item* StoreItem( ItemPosCountVec const& pos, Item *pItem, bool update );
- Item* EquipNewItem( uint16 pos, uint32 item, uint32 count, bool update );
+ Item* EquipNewItem( uint16 pos, uint32 item, bool update );
Item* EquipItem( uint16 pos, Item *pItem, bool update );
void AutoUnequipOffhandIfNeed();
- bool StoreNewItemInBestSlot(uint32 item_id, uint32 item_count);
+ bool StoreNewItemInBestSlots(uint32 item_id, uint32 item_count);
uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const;
uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const;
@@ -1531,7 +1532,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void SetInArenaTeam(uint32 ArenaTeamId, uint8 slot)
{
SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6), ArenaTeamId);
- SaveDataFieldToDB(); // needed?
}
uint32 GetArenaTeamId(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * 6)); }
static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot);
@@ -2143,6 +2143,7 @@ class TRINITY_DLL_SPEC Player : public Unit
void _LoadFriendList(QueryResult *result);
bool _LoadHomeBind(QueryResult *result);
void _LoadDeclinedNames(QueryResult *result);
+ void _LoadArenaTeamInfo(QueryResult *result);
/*********************************************************/
/*** SAVE SYSTEM ***/
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 94e11f52abd..1045c511bb4 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -42,16 +42,24 @@ enum Races
RACE_TAUREN = 6,
RACE_GNOME = 7,
RACE_TROLL = 8,
- RACE_GOBLIN = 9,
+ //RACE_GOBLIN = 9,
RACE_BLOODELF = 10,
RACE_DRAENEI = 11,
- RACE_FEL_ORC = 12,
- RACE_NAGA = 13,
- RACE_BROKEN = 14,
- RACE_SKELETON = 15,
- MAX_RACES = 16
+ //RACE_FEL_ORC = 12,
+ //RACE_NAGA = 13,
+ //RACE_BROKEN = 14,
+ //RACE_SKELETON = 15,
+ //RACE_VRYKUL = 16,
+ //RACE_TUSKARR = 17,
+ //RACE_FOREST_TROLL = 18,
+ //RACE_TAUNKA = 19,
+ //RACE_NORTHREND_SKELETON = 20,
+ //RACE_ICE_TROLL = 21
};
+// max+1 for player race
+#define MAX_RACES 12
+
#define RACEMASK_ALL_PLAYABLE \
((1<<(RACE_HUMAN-1)) |(1<<(RACE_ORC-1)) |(1<<(RACE_DWARF-1)) | \
(1<<(RACE_NIGHTELF-1))|(1<<(RACE_UNDEAD_PLAYER-1))|(1<<(RACE_TAUREN-1)) | \
@@ -72,9 +80,11 @@ enum Classes
CLASS_WARLOCK = 9,
// CLASS_UNK2 = 10,unused
CLASS_DRUID = 11,
- MAX_CLASSES = 12
};
+// max+1 for player class
+#define MAX_CLASSES 12
+
#define CLASSMASK_ALL_PLAYABLE \
((1<<(CLASS_WARRIOR-1))|(1<<(CLASS_PALADIN-1))|(1<<(CLASS_HUNTER-1))| \
(1<<(CLASS_ROGUE-1)) |(1<<(CLASS_PRIEST-1)) |(1<<(CLASS_SHAMAN-1))| \
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index b576661aede..8bd2887c833 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4840,6 +4840,8 @@ uint8 Spell::CheckItems()
uint32 ItemClass = proto->Class;
if (ItemClass == ITEM_CLASS_CONSUMABLE && m_targets.getUnitTarget())
{
+ // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
+ uint8 failReason = 0;
for (int i = 0; i < 3; i++)
{
// skip check, pet not required like checks, and for TARGET_PET m_targets.getUnitTarget() is not the real target but the caster
@@ -4847,21 +4849,43 @@ uint8 Spell::CheckItems()
continue;
if (m_spellInfo->Effect[i] == SPELL_EFFECT_HEAL)
+ {
if (m_targets.getUnitTarget()->GetHealth() == m_targets.getUnitTarget()->GetMaxHealth())
- return (uint8)SPELL_FAILED_ALREADY_AT_FULL_HEALTH;
+ {
+ failReason = (uint8)SPELL_FAILED_ALREADY_AT_FULL_HEALTH;
+ continue;
+ }
+ else
+ {
+ failReason = 0;
+ break;
+ }
+ }
// Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
if (m_spellInfo->Effect[i] == SPELL_EFFECT_ENERGIZE)
{
if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS)
- return (uint8)SPELL_FAILED_ALREADY_AT_FULL_POWER;
+ {
+ failReason = (uint8)SPELL_FAILED_ALREADY_AT_FULL_POWER;
+ continue;
+ }
Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
-
if (m_targets.getUnitTarget()->GetPower(power) == m_targets.getUnitTarget()->GetMaxPower(power))
- return (uint8)SPELL_FAILED_ALREADY_AT_FULL_POWER;
+ {
+ failReason = (uint8)SPELL_FAILED_ALREADY_AT_FULL_POWER;
+ continue;
+ }
+ else
+ {
+ failReason = 0;
+ break;
+ }
}
}
+ if (failReason)
+ return failReason;
}
}
}
diff --git a/src/game/World.cpp b/src/game/World.cpp
index 7d4be651077..897fe2031d5 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -631,10 +631,11 @@ void World::LoadConfigSettings(bool reload)
}
else
m_configs[CONFIG_MAX_PLAYER_LEVEL] = sConfig.GetIntDefault("MaxPlayerLevel", 60);
- if(m_configs[CONFIG_MAX_PLAYER_LEVEL] > 255)
+
+ if(m_configs[CONFIG_MAX_PLAYER_LEVEL] > MAX_LEVEL)
{
- sLog.outError("MaxPlayerLevel (%i) must be in range 1..255. Set to 255.",m_configs[CONFIG_MAX_PLAYER_LEVEL]);
- m_configs[CONFIG_MAX_PLAYER_LEVEL] = 255;
+ sLog.outError("MaxPlayerLevel (%i) must be in range 1..%u. Set to %u.",m_configs[CONFIG_MAX_PLAYER_LEVEL],MAX_LEVEL,MAX_LEVEL);
+ m_configs[CONFIG_MAX_PLAYER_LEVEL] = MAX_LEVEL;
}
m_configs[CONFIG_START_PLAYER_LEVEL] = sConfig.GetIntDefault("StartPlayerLevel", 1);
@@ -737,14 +738,14 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1);
if(m_configs[CONFIG_START_GM_LEVEL] < m_configs[CONFIG_START_PLAYER_LEVEL])
{
- sLog.outError("GM.StartLevel (%i) must be in range StartPlayerLevel(%u)..255. Set to %u.",
- m_configs[CONFIG_START_GM_LEVEL],m_configs[CONFIG_START_PLAYER_LEVEL],m_configs[CONFIG_START_PLAYER_LEVEL]);
+ sLog.outError("GM.StartLevel (%i) must be in range StartPlayerLevel(%u)..%u. Set to %u.",
+ m_configs[CONFIG_START_GM_LEVEL],m_configs[CONFIG_START_PLAYER_LEVEL], MAX_LEVEL, m_configs[CONFIG_START_PLAYER_LEVEL]);
m_configs[CONFIG_START_GM_LEVEL] = m_configs[CONFIG_START_PLAYER_LEVEL];
}
- else if(m_configs[CONFIG_START_GM_LEVEL] > 255)
+ else if(m_configs[CONFIG_START_GM_LEVEL] > MAX_LEVEL)
{
- sLog.outError("GM.StartLevel (%i) must be in range 1..255. Set to %u.",m_configs[CONFIG_START_GM_LEVEL],255);
- m_configs[CONFIG_START_GM_LEVEL] = 255;
+ sLog.outError("GM.StartLevel (%i) must be in range 1..%u. Set to %u.", m_configs[CONFIG_START_GM_LEVEL], MAX_LEVEL, MAX_LEVEL);
+ m_configs[CONFIG_START_GM_LEVEL] = MAX_LEVEL;
}
m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0);
@@ -835,13 +836,13 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_WORLD_BOSS_LEVEL_DIFF] = sConfig.GetIntDefault("WorldBossLevelDiff",3);
- // note: disable value (-1) will assigned as 0xFFFFFFF, to prevent overflow at calculations limit it to max possible player level (255)
- m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] = sConfig.GetIntDefault("Quests.LowLevelHideDiff",4);
- if(m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] > 255)
- m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] = 255;
- m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] = sConfig.GetIntDefault("Quests.HighLevelHideDiff",7);
- if(m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] > 255)
- m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] = 255;
+ // note: disable value (-1) will assigned as 0xFFFFFFF, to prevent overflow at calculations limit it to max possible player level MAX_LEVEL(100)
+ m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] = sConfig.GetIntDefault("Quests.LowLevelHideDiff", 4);
+ if(m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] > MAX_LEVEL)
+ m_configs[CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF] = MAX_LEVEL;
+ m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] = sConfig.GetIntDefault("Quests.HighLevelHideDiff", 7);
+ if(m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] > MAX_LEVEL)
+ m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] = MAX_LEVEL;
m_configs[CONFIG_DETECT_POS_COLLISION] = sConfig.GetBoolDefault("DetectPosCollision", true);
@@ -871,6 +872,12 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_LISTEN_RANGE_TEXTEMOTE] = sConfig.GetIntDefault("ListenRange.TextEmote", 25);
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_configs[CONFIG_INSTANT_LOGOUT] = sConfig.GetIntDefault("InstantLogout", SEC_MODERATOR);
m_VisibleUnitGreyDistance = sConfig.GetFloatDefault("Visibility.Distance.Grey.Unit", 1);
@@ -2248,7 +2255,7 @@ void World::ScriptsProcess()
void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 team)
{
SessionMap::iterator itr;
- for (itr = m_sessions.begin(); itr != m_sessions.end(); itr++)
+ for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if (itr->second &&
itr->second->GetPlayer() &&
@@ -2315,11 +2322,29 @@ void World::SendWorldText(int32 string_id, ...)
delete data_cache[i][j];
}
+/// Send a System Message to all players (except self if mentioned)
+void World::SendGlobalText(const char* text, WorldSession *self)
+{
+ WorldPacket data;
+
+ // need copy to prevent corruption by strtok call in LineFromMessage original string
+ char* buf = strdup(text);
+ char* pos = buf;
+
+ while(char* line = ChatHandler::LineFromMessage(pos))
+ {
+ ChatHandler::FillMessageData(&data, NULL, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, 0, line, NULL);
+ SendGlobalMessage(&data, self);
+ }
+
+ free(buf);
+}
+
/// Send a packet to all players (or players selected team) in the zone (except self if mentioned)
void World::SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self, uint32 team)
{
SessionMap::iterator itr;
- for (itr = m_sessions.begin(); itr != m_sessions.end(); itr++)
+ for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if (itr->second &&
itr->second->GetPlayer() &&
diff --git a/src/game/World.h b/src/game/World.h
index e93444d8957..903304e25ec 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -178,14 +178,17 @@ 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_MAX_WHO,
-
CONFIG_BG_START_MUSIC,
CONFIG_START_ALL_SPELLS,
CONFIG_HONOR_AFTER_DUEL,
CONFIG_START_ALL_EXPLORED,
-
CONFIG_START_ALL_REP,
CONFIG_ALWAYS_MAXSKILL,
CONFIG_PVP_TOKEN_ENABLE,
@@ -194,13 +197,7 @@ enum WorldConfigs
CONFIG_PVP_TOKEN_COUNT,
CONFIG_NO_RESET_TALENT_COST,
- 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,
+ CONFIG_VALUE_COUNT
};
/// Server rates
@@ -421,6 +418,7 @@ class World
void LoadConfigSettings(bool reload = false);
void SendWorldText(int32 string_id, ...);
+ void SendGlobalText(const char* text, WorldSession *self);
void SendGlobalMessage(WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
void SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
void SendZoneText(uint32 zone, const char *text, WorldSession *self = 0, uint32 team = 0);
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 231fc2a2abf..0ccb8dd9fbb 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -94,7 +94,7 @@ class TRINITY_DLL_SPEC WorldSession
Player* GetPlayer() const { return _player; }
char const* GetPlayerName() const;
void SetSecurity(uint32 security) { _security = security; }
- std::string& GetRemoteAddress() { return m_Address; }
+ std::string const& GetRemoteAddress() { return m_Address; }
void SetPlayer(Player *plr) { _player = plr; }
uint8 Expansion() const { return m_expansion; }
@@ -180,11 +180,12 @@ class TRINITY_DLL_SPEC WorldSession
// Guild/Arena Team
void SendGuildCommandResult(uint32 typecmd, const std::string& str, uint32 cmdresult);
- void SendArenaTeamCommandResult(uint32 unk1, const std::string& str1, const std::string& str2, uint32 unk3);
+ void SendArenaTeamCommandResult(uint32 team_action, const std::string& team, const std::string& player, uint32 error_id);
void BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, const std::string& str1, const std::string& str2, const std::string& str3);
void SendNotInArenaTeamPacket(uint8 type);
void SendPetitionShowList( uint64 guid );
void SendSaveGuildEmblem( uint32 msg );
+ void SendBattleGroundOrArenaJoinError(uint8 err);
// Looking For Group
// TRUE values set by client sending CMSG_LFG_SET_AUTOJOIN and CMSG_LFM_CLEAR_AUTOFILL before player login
@@ -546,6 +547,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandleSetActionBar(WorldPacket& recv_data);
void HandleChangePlayerNameOpcode(WorldPacket& recv_data);
+ static void HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname);
void HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data);
void HandleTotemDestroy(WorldPacket& recv_data);
diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp
index c5ba79d671b..878c4f5a711 100644
--- a/src/game/debugcmds.cpp
+++ b/src/game/debugcmds.cpp
@@ -32,9 +32,9 @@
#include "GossipDef.h"
#include "Language.h"
#include "MapManager.h"
+#include "BattleGroundMgr.h"
#include <fstream>
#include "ObjectMgr.h"
-#include "BattleGroundMgr.h"
bool ChatHandler::HandleDebugInArcCommand(const char* /*args*/)
{
@@ -569,4 +569,4 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/)
}
SendSysMessage("End of hostil reference list.");
return true;
-}
+} \ No newline at end of file
diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h
index 6ad7fdb127a..1d54616a2b5 100644
--- a/src/shared/Database/DBCEnums.h
+++ b/src/shared/Database/DBCEnums.h
@@ -19,6 +19,14 @@
#ifndef DBCENUMS_H
#define DBCENUMS_H
+// client supported max level for player/pets/etc. Avoid overflow or client stability affected.
+// also see GT_MAX_LEVEL define
+#define MAX_LEVEL 100
+
+// Server side limitation. Base at used code requirements.
+// also see MAX_LEVEL and GT_MAX_LEVEL define
+#define STRONG_MAX_LEVEL 255
+
enum AreaTeams
{
AREATEAM_NONE = 0,
diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h
index 94c6589e5e3..99d789f133f 100644
--- a/src/shared/Database/DBCStructure.h
+++ b/src/shared/Database/DBCStructure.h
@@ -131,9 +131,9 @@ struct ChrClassesEntry
//char* name[16]; // 5-20 unused
char* name[16]; // 5-20 unused
// 21 string flag, unused
- //char* string1[16]; // 21-36 unused
+ //char* nameFemale[16]; // 21-36 unused, if different from base (male) case
// 37 string flag, unused
- //char* string2[16]; // 38-53 unused
+ //char* nameNeutralGender[16]; // 38-53 unused, if different from base (male) case
// 54 string flag, unused
// 55, unused
uint32 spellfamily; // 56
@@ -154,9 +154,9 @@ struct ChrRacesEntry
uint32 startmovie; // 13 id from CinematicCamera.dbc
char* name[16]; // 14-29 used for DBC language detection/selection
// 30 string flags, unused
- //char* string1[16]; // 31-46 used for DBC language detection/selection
+ //char* nameFemale[16]; // 31-46, if different from base (male) case
// 47 string flags, unused
- //char* string2[16]; // 48-63 used for DBC language detection/selection
+ //char* nameNeutralGender[16]; // 48-63, if different from base (male) case
// 64 string flags, unused
// 65-67 unused
uint32 addon; // 68 (0 - original race, 1 - tbc addon, ...)
@@ -274,6 +274,7 @@ struct GemPropertiesEntry
uint32 color;
};
+// All Gt* DBC store data for 100 levels, some by 100 per class/race
#define GT_MAX_LEVEL 100
struct GtCombatRatingsEntry
diff --git a/src/trinitycore/Master.cpp b/src/trinitycore/Master.cpp
index 317a3a31a15..eea1606256c 100644
--- a/src/trinitycore/Master.cpp
+++ b/src/trinitycore/Master.cpp
@@ -474,7 +474,7 @@ void Master::clearOnlineAccounts()
"AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID);
- CharacterDatabase.Execute("UPDATE characters SET online = 0");
+ CharacterDatabase.Execute("UPDATE characters SET online = 0 WHERE online<>0");
}
/// Handle termination signals
diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist
index efcaea714ef..214437cd60a 100644
--- a/src/trinitycore/trinitycore.conf.dist
+++ b/src/trinitycore/trinitycore.conf.dist
@@ -1097,6 +1097,48 @@ Death.CorpseReclaimDelay.PvE = 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
+# Default: 300000
+# 0 - disable
+#
+###################################################################################################################
+
+BattleGround.PrematureFinishTimer = 300000
+
+
+###################################################################################################################
+#
# NETWORK CONFIG
#
# Network.Threads
@@ -1158,46 +1200,6 @@ 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
-
-###################################################################################################################
# CUSTOM SERVER OPTIONS
#
# PlayerStart.AllReputation
@@ -1213,9 +1215,6 @@ BattleGround.PrematureFinishTimer = 0
# PlayerStart.MapsExplored
# Players will start with all maps explored if enabled
#
-# PlayerStart.AllFlightPaths
-# Players will start with all flight paths (Note: ALL flight paths, not only player's team)
-#
# PlayerInstantLogout
# Enable or disable instant logout for all players (NOT in combat/while dueling/while falling)
# Default: 0 - off
@@ -1262,7 +1261,6 @@ BattleGround.PrematureFinishTimer = 0
PlayerStart.AllReputation = 0
PlayerStart.AllSpells = 0
PlayerStart.MapsExplored = 0
-PlayerStart.AllFlightPaths = 0
PlayerInstantLogout = 0
MusicInBattleground = 0
HonorPointsAfterDuel = 0