root/trunk/src/game/ArenaTeam.cpp @ 6

Revision 2, 18.6 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#include "WorldPacket.h"
20#include "ObjectMgr.h"
21#include "ArenaTeam.h"
22
23ArenaTeam::ArenaTeam()
24{
25    Id              = 0;
26    Type            = 0;
27    Name            = "";
28    CaptainGuid     = 0;
29    BackgroundColor = 0;                                    // background
30    EmblemStyle     = 0;                                    // icon
31    EmblemColor     = 0;                                    // icon color
32    BorderStyle     = 0;                                    // border
33    BorderColor     = 0;                                    // border color
34    stats.games     = 0;
35    stats.played    = 0;
36    stats.rank      = 0;
37    stats.rating    = 1500;
38    stats.wins      = 0;
39    stats.wins2     = 0;
40}
41
42ArenaTeam::~ArenaTeam()
43{
44
45}
46
47bool ArenaTeam::create(uint64 captainGuid, uint32 type, std::string ArenaTeamName)
48{
49    if(!objmgr.GetPlayer(captainGuid))                      // player not exist
50        return false;
51    if(objmgr.GetArenaTeamByName(ArenaTeamName))            // arena team with this name already exist
52        return false;
53
54    sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid));
55
56    CaptainGuid = captainGuid;
57    Name = ArenaTeamName;
58    Type = type;
59
60    QueryResult *result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
61    if( result )
62    {
63        Id = (*result)[0].GetUInt32()+1;
64        delete result;
65    }
66    else Id = 1;
67
68    // ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
69    CharacterDatabase.escape_string(ArenaTeamName);
70
71    CharacterDatabase.BeginTransaction();
72    // CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", Id); - MAX(arenateam)+1 not exist
73    CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", Id);
74    CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
75        "VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')",
76        Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor);
77    CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
78        "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id,stats.rating,stats.games,stats.wins,stats.played,stats.wins2,stats.rank);
79
80    CharacterDatabase.CommitTransaction();
81
82    AddMember(CaptainGuid);
83    return true;
84}
85
86bool ArenaTeam::AddMember(uint64 PlayerGuid)
87{
88    std::string plName;
89    uint8 plClass;
90
91    if(GetMembersSize() >= GetType() * 2)
92    {
93        // arena team is full (can't have more than type * 2 players!)
94        // return false
95        return false;
96    }
97
98    if(!objmgr.GetPlayerNameByGUID(PlayerGuid, plName))     // player doesnt exist
99        return false;
100                                                            // player already in arenateam of that size
101    if(Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0)
102    {
103        sLog.outError("Arena::AddMember() : player already in this sized team");
104        return false;
105    }
106
107    // remove all player signs from another petitions
108    // this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity
109    Player::RemovePetitionsAndSigns(PlayerGuid, GetType());
110
111    Player *pl = objmgr.GetPlayer(PlayerGuid);
112    if(pl)
113    {
114        plClass = (uint8)pl->getClass();
115    }
116    else
117    {
118        QueryResult *result = CharacterDatabase.PQuery("SELECT class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid));
119        if(!result)
120            return false;
121        plClass = (*result)[0].GetUInt8();
122        delete result;
123    }
124
125    ArenaTeamMember newmember;
126    newmember.name          = plName;
127    newmember.guid          = PlayerGuid;
128    newmember.Class         = plClass;
129    newmember.played_season = 0;
130    newmember.played_week   = 0;
131    newmember.wons_season   = 0;
132    newmember.wons_week     = 0;
133    members.push_back(newmember);
134
135    CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid,guid) VALUES ('%u', '%u')", Id, GUID_LOPART(newmember.guid));
136
137    if(pl)
138    {
139        pl->SetInArenaTeam(Id, GetSlot());
140        pl->SetArenaTeamIdInvited(0);
141    }
142    else
143    {
144        Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), Id, PlayerGuid);
145    }
146
147    // hide promote/remove buttons
148    if(CaptainGuid != PlayerGuid)
149    {
150        if(pl)
151            pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
152        else
153            Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, PlayerGuid);
154    }
155    return true;
156}
157
158bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
159{
160    LoadStatsFromDB(ArenaTeamId);
161    LoadMembersFromDB(ArenaTeamId);
162
163    //                                                      0          1    2           3    4               5           6           7           8
164    QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId);
165
166    if(!result)
167        return false;
168
169    Field *fields = result->Fetch();
170
171    Id = fields[0].GetUInt32();
172    Name = fields[1].GetCppString();
173    CaptainGuid  = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
174    Type = fields[3].GetUInt32();
175    BackgroundColor = fields[4].GetUInt32();
176    EmblemStyle = fields[5].GetUInt32();
177    EmblemColor = fields[6].GetUInt32();
178    BorderStyle = fields[7].GetUInt32();
179    BorderColor = fields[8].GetUInt32();
180
181    delete result;
182
183    return true;
184}
185
186void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId)
187{
188    //                                                     0      1     2    3      4     5
189    QueryResult *result = CharacterDatabase.PQuery("SELECT rating,games,wins,played,wins2,rank FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId);
190
191    if(!result)
192        return;
193
194    Field *fields = result->Fetch();
195
196    stats.rating    = fields[0].GetUInt32();
197    stats.games     = fields[1].GetUInt32();
198    stats.wins      = fields[2].GetUInt32();
199    stats.played    = fields[3].GetUInt32();
200    stats.wins2     = fields[4].GetUInt32();
201    stats.rank      = fields[5].GetUInt32();
202
203    delete result;
204}
205
206void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
207{
208    Field *fields;
209
210    QueryResult *result = CharacterDatabase.PQuery("SELECT guid,played_week,wons_week,played_season,wons_season FROM arena_team_member WHERE arenateamid = '%u'", ArenaTeamId);
211    if(!result)
212        return;
213
214    do
215    {
216        fields = result->Fetch();
217        ArenaTeamMember newmember;
218        newmember.guid          = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
219        LoadPlayerStats(&newmember);
220        newmember.played_week   = fields[1].GetUInt32();
221        newmember.wons_week     = fields[2].GetUInt32();
222        newmember.played_season = fields[3].GetUInt32();
223        newmember.wons_season   = fields[4].GetUInt32();
224        members.push_back(newmember);
225    }while( result->NextRow() );
226    delete result;
227}
228
229void ArenaTeam::LoadPlayerStats(ArenaTeamMember *member)
230{
231    Field *fields;
232
233    QueryResult *result = CharacterDatabase.PQuery("SELECT name,class FROM characters WHERE guid = '%u'", GUID_LOPART(member->guid));
234    if(!result)
235        return;
236    fields = result->Fetch();
237    member->name  = fields[0].GetCppString();
238    member->Class = fields[1].GetUInt8();
239
240    delete result;
241}
242
243void ArenaTeam::SetCaptain(uint64 guid)
244{
245    // disable remove/promote buttons
246    Player *oldcaptain = objmgr.GetPlayer(GetCaptain());
247    if(oldcaptain)
248        oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
249    else
250        Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1, GetCaptain());
251
252    // set new captain
253    CaptainGuid = guid;
254
255    // update database
256    CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), Id);
257
258    // enable remove/promote buttons
259    Player *newcaptain = objmgr.GetPlayer(guid);
260    if(newcaptain)
261        newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0);
262    else
263        Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0, guid);
264}
265
266void ArenaTeam::DelMember(uint64 guid)
267{
268    MemberList::iterator itr;
269    for (itr = members.begin(); itr != members.end(); itr++)
270    {
271        if (itr->guid == guid)
272        {
273            members.erase(itr);
274            break;
275        }
276    }
277
278    Player *player = objmgr.GetPlayer(guid);
279    if(player)
280    {
281        player->SetInArenaTeam(0, GetSlot());
282        player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0);
283    }
284    else
285    {
286        Player::SetUInt32ValueInDB(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6), 0, guid);
287    }
288
289    CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE guid = '%u'", GUID_LOPART(guid));
290}
291
292void ArenaTeam::Disband(WorldSession *session)
293{
294    // event
295    WorldPacket data;
296    session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), "");
297    BroadcastPacket(&data);
298
299    uint32 count = members.size();
300    uint64 *memberGuids = new uint64[count];
301
302    MemberList::iterator itr;
303    uint32 i=0;
304    for(itr = members.begin(); itr != members.end(); itr++)
305    {
306        memberGuids[i] = itr->guid;
307        ++i;
308    }
309
310    for(uint32 j = 0; j < count; j++)
311        DelMember(memberGuids[j]);
312    delete[] memberGuids;
313
314    CharacterDatabase.BeginTransaction();
315    CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", Id);
316    CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", Id);
317    CharacterDatabase.CommitTransaction();
318    objmgr.RemoveArenaTeam(this);
319}
320
321void ArenaTeam::Roster(WorldSession *session)
322{
323    Player *pl = NULL;
324
325    WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
326    data << uint32(GetId());                                // arena team id
327    data << uint32(GetMembersSize());                       // members count
328    data << uint32(GetType());                              // arena team type?
329
330    for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
331    {
332        pl = objmgr.GetPlayer(itr->guid);
333        if(pl)
334        {
335            data << uint64(pl->GetGUID());                  // guid
336            data << uint8(1);                               // online flag
337            data << pl->GetName();                          // member name
338            data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
339            data << uint8(pl->getLevel());                  // unknown, probably level
340            data << uint8(pl->getClass());                  // class
341            data << uint32(itr->played_week);               // played this week
342            data << uint32(itr->wons_week);                 // wins this week
343            data << uint32(itr->played_season);             // played this season
344            data << uint32(itr->wons_season);               // wins this season
345            data << uint32(0);                              // personal rating?
346        }
347        else
348        {
349            data << uint64(itr->guid);                      // guid
350            data << uint8(0);                               // online flag
351            data << itr->name;                              // member name
352            data << uint32(itr->guid == GetCaptain() ? 0 : 1);// unknown
353            data << uint8(0);                               // unknown, level?
354            data << uint8(itr->Class);                      // class
355            data << uint32(itr->played_week);               // played this week
356            data << uint32(itr->wons_week);                 // wins this week
357            data << uint32(itr->played_season);             // played this season
358            data << uint32(itr->wons_season);               // wins this season
359            data << uint32(0);                              // personal rating?
360        }
361    }
362    session->SendPacket(&data);
363    sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER");
364}
365
366void ArenaTeam::Query(WorldSession *session)
367{
368    WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1);
369    data << uint32(GetId());                                // team id
370    data << GetName();                                      // team name
371    data << uint32(GetType());                              // arena team type (2=2x2, 3=3x3 or 5=5x5)
372    data << uint32(BackgroundColor);                        // background color
373    data << uint32(EmblemStyle);                            // emblem style
374    data << uint32(EmblemColor);                            // emblem color
375    data << uint32(BorderStyle);                            // border style
376    data << uint32(BorderColor);                            // border color
377    session->SendPacket(&data);
378    sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
379}
380
381void ArenaTeam::Stats(WorldSession *session)
382{
383    WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7);
384    data << uint32(GetId());                                // arena team id
385    data << uint32(stats.rating);                           // rating
386    data << uint32(stats.games);                            // games
387    data << uint32(stats.wins);                             // wins
388    data << uint32(stats.played);                           // played
389    data << uint32(stats.wins2);                            // wins(again o_O)
390    data << uint32(stats.rank);                             // rank
391    session->SendPacket(&data);
392}
393
394void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
395{
396    WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6);
397    data << uint64(guid);                                   // player guid
398    data << uint8(GetSlot());                               // slot (0...2)
399    data << uint32(GetId());                                // arena team id
400    data << uint32(stats.rating);                           // rating
401    data << uint32(stats.games);                            // games
402    data << uint32(stats.wins);                             // wins
403    data << uint32(stats.played);                           // played (count of all games, that played...)
404    data << uint32(0);                                      // 2.3.3 personal rating?
405    session->SendPacket(&data);
406}
407
408void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor)
409{
410    BackgroundColor = backgroundColor;
411    EmblemStyle = emblemStyle;
412    EmblemColor = emblemColor;
413    BorderStyle = borderStyle;
414    BorderColor = borderColor;
415
416    CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", BackgroundColor, EmblemStyle, EmblemColor, BorderStyle, BorderColor, Id);
417}
418
419void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
420{
421    switch(stat_type)
422    {
423        case STAT_TYPE_RATING:
424            stats.rating = value;
425            CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId());
426            break;
427        case STAT_TYPE_GAMES:
428            stats.games = value;
429            CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId());
430            break;
431        case STAT_TYPE_WINS:
432            stats.wins = value;
433            CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId());
434            break;
435        case STAT_TYPE_PLAYED:
436            stats.played = value;
437            CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId());
438            break;
439        case STAT_TYPE_WINS2:
440            stats.wins2 = value;
441            CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId());
442            break;
443        case STAT_TYPE_RANK:
444            stats.rank = value;
445            CharacterDatabase.PExecute("UPDATE arena_team_stats SET rank = '%u' WHERE arenateamid = '%u'", value, GetId());
446            break;
447        default:
448            sLog.outDebug("unknown stat type in ArenaTeam::SetStats() %u", stat_type);
449            break;
450    }
451}
452
453uint8 ArenaTeam::GetSlot() const
454{
455    uint8 slot = GetSlotByType(GetType());
456    if(slot >= MAX_ARENA_SLOT)
457    {
458        sLog.outError("Unknown arena team type %u for arena team %u", uint32(GetType()), GetId());
459        return 0;                                           // better return existed slot to prevent untelated data curruption
460    }
461
462    return slot;
463}
464
465void ArenaTeam::BroadcastPacket(WorldPacket *packet)
466{
467    for (MemberList::iterator itr = members.begin(); itr != members.end(); itr++)
468    {
469        Player *player = objmgr.GetPlayer(itr->guid);
470        if(player)
471            player->GetSession()->SendPacket(packet);
472    }
473}
474
475uint8 ArenaTeam::GetSlotByType( uint32 type )
476{
477    switch(type)
478    {
479        case ARENA_TEAM_2v2: return 0;
480        case ARENA_TEAM_3v3: return 1;
481        case ARENA_TEAM_5v5: return 2;
482        default:
483            break;
484    }
485    return 0xFF;
486}
487
488bool ArenaTeam::HaveMember( uint64 guid ) const
489{
490    for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
491        if(itr->guid==guid)
492            return true;
493
494    return false;
495}
496
497/*
498arenateam fields (id from 2.3.3 client):
4991414 - arena team id 2v2
5001415 - 0=captain, 1=member
5011416 - played this season
5021417 - played this week
5031418 - unk
5041419 - unk
5051420 - arena team id 3v3
5061421 - 0=captain, 1=member
5071422 - played this season
5081423 - played this week
5091424 - unk
5101425 - unk
5111426 - arena team id 5v5
5121427 - 0=captain, 1=member
5131428 - played this season
5141429 - played this week
5151430 - unk
5161431 - unk
517*/
Note: See TracBrowser for help on using the browser.