2008-10-11 14:16:25 -05:00
/*
2009-02-04 12:42:26 +01:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
2008-10-14 11:57:03 -05:00
*
2010-01-16 20:19:18 +03:00
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
2008-10-11 14:16:25 -05:00
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
2008-12-08 16:34:03 -06:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2008-10-11 14:16:25 -05:00
* 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
2008-12-08 16:34:03 -06:00
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2008-10-11 14:16:25 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Player.h"
#include "Opcodes.h"
#include "ObjectMgr.h"
#include "Guild.h"
#include "Chat.h"
#include "SocialMgr.h"
#include "Util.h"
2009-03-09 17:48:18 -06:00
#include "Language.h"
2009-08-24 19:23:31 -05:00
#include "World.h"
2009-09-12 22:33:24 -07:00
#include "Config/ConfigEnv.h"
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Guild :: Guild ()
{
2009-08-24 19:23:31 -05:00
m_Id = 0 ;
m_Name = "" ;
m_LeaderGuid = 0 ;
2008-10-11 14:16:25 -05:00
GINFO = MOTD = "" ;
2009-08-24 19:23:31 -05:00
m_EmblemStyle = 0 ;
m_EmblemColor = 0 ;
m_BorderStyle = 0 ;
m_BorderColor = 0 ;
m_BackgroundColor = 0 ;
2009-10-17 15:51:44 -07:00
2010-03-19 18:27:53 +01:00
m_CreatedDate = time ( 0 );
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
m_GuildBankMoney = 0 ;
m_PurchasedTabs = 0 ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
m_GuildEventLogNextGuid = 0 ;
m_GuildBankEventLogNextGuid_Money = 0 ;
2010-03-19 17:24:23 +01:00
2010-02-15 14:30:12 +01:00
for ( uint8 i = 0 ; i < GUILD_BANK_MAX_TABS ; ++ i )
2009-08-24 19:23:31 -05:00
m_GuildBankEventLogNextGuid_Item [ i ] = 0 ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Guild ::~ Guild ()
{
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
bool Guild :: Create ( Player * leader , std :: string gname )
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
if ( objmgr . GetGuildByName ( gname ))
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2009-03-09 17:48:18 -06:00
WorldSession * lSession = leader -> GetSession ();
2009-09-11 14:39:38 -07:00
if ( ! lSession )
2009-03-09 17:48:18 -06:00
return false ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
m_LeaderGuid = leader -> GetGUID ();
m_Name = gname ;
2008-10-11 14:16:25 -05:00
GINFO = "" ;
MOTD = "No message set." ;
2009-08-24 19:23:31 -05:00
m_GuildBankMoney = 0 ;
m_PurchasedTabs = 0 ;
m_Id = objmgr . GenerateGuildId ();
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
sLog . outDebug ( "GUILD: creating guild %s to leader: %u" , gname . c_str (), GUID_LOPART ( m_LeaderGuid ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// gname already assigned to Guild::name, use it to encode string for DB
CharacterDatabase . escape_string ( gname );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
std :: string dbGINFO = GINFO ;
std :: string dbMOTD = MOTD ;
CharacterDatabase . escape_string ( dbGINFO );
CharacterDatabase . escape_string ( dbMOTD );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CharacterDatabase . BeginTransaction ();
// CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid='%u'", Id); - MAX(guildid)+1 not exist
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "DELETE FROM guild_member WHERE guildid='%u'" , m_Id );
2008-10-11 14:16:25 -05:00
CharacterDatabase . PExecute ( "INSERT INTO guild (guildid,name,leaderguid,info,motd,createdate,EmblemStyle,EmblemColor,BorderStyle,BorderColor,BackgroundColor,BankMoney) "
2009-08-24 20:25:32 -05:00
"VALUES('%u','%s','%u', '%s', '%s', UNIX_TIMESTAMP(NOW()),'%u','%u','%u','%u','%u','" UI64FMTD "')" ,
2009-08-24 19:23:31 -05:00
m_Id , gname . c_str (), GUID_LOPART ( m_LeaderGuid ), dbGINFO . c_str (), dbMOTD . c_str (), m_EmblemStyle , m_EmblemColor , m_BorderStyle , m_BorderColor , m_BackgroundColor , m_GuildBankMoney );
2008-10-11 14:16:25 -05:00
CharacterDatabase . CommitTransaction ();
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
CreateDefaultGuildRanks ( lSession -> GetSessionDbLocaleIndex ());
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
return AddMember ( m_LeaderGuid , ( uint32 ) GR_GUILDMASTER );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
void Guild :: CreateDefaultGuildRanks ( int locale_idx )
{
CharacterDatabase . PExecute ( "DELETE FROM guild_rank WHERE guildid='%u'" , m_Id );
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_right WHERE guildid = '%u'" , m_Id );
2009-10-17 15:51:44 -07:00
2009-12-20 15:20:04 +01:00
CreateRank ( objmgr . GetTrinityString ( LANG_GUILD_MASTER , locale_idx ), GR_RIGHT_ALL );
CreateRank ( objmgr . GetTrinityString ( LANG_GUILD_OFFICER , locale_idx ), GR_RIGHT_ALL );
CreateRank ( objmgr . GetTrinityString ( LANG_GUILD_VETERAN , locale_idx ), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK );
CreateRank ( objmgr . GetTrinityString ( LANG_GUILD_MEMBER , locale_idx ), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK );
CreateRank ( objmgr . GetTrinityString ( LANG_GUILD_INITIATE , locale_idx ), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK );
2009-08-24 20:23:54 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool Guild :: AddMember ( uint64 plGuid , uint32 plRank )
{
2008-11-05 20:10:19 -06:00
Player * pl = objmgr . GetPlayer ( plGuid );
2009-09-11 14:39:38 -07:00
if ( pl )
2008-11-05 20:10:19 -06:00
{
2009-09-11 14:39:38 -07:00
if ( pl -> GetGuildId () != 0 )
2008-12-08 16:34:03 -06:00
return false ;
2008-11-05 20:10:19 -06:00
}
else
{
2009-09-11 14:39:38 -07:00
if ( Player :: GetGuildIdFromDB ( plGuid ) != 0 ) // player already in guild
2008-12-08 16:34:03 -06:00
return false ;
2008-11-05 20:10:19 -06:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// remove all player signs from another petitions
// this will be prevent attempt joining player to many guilds and corrupt guild data integrity
Player :: RemovePetitionsAndSigns ( plGuid , 9 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// fill player data
MemberSlot newmember ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( pl )
2009-08-24 20:23:54 -05:00
{
2009-09-11 14:39:38 -07:00
newmember . Name = pl -> GetName ();
newmember . ZoneId = pl -> GetZoneId ();
newmember . Level = pl -> getLevel ();
2009-08-24 20:23:54 -05:00
newmember . Class = pl -> getClass ();
}
else
{
2010-01-23 14:45:58 +01:00
QueryResult_AutoPtr result = CharacterDatabase . PQuery ( "SELECT name,zone,level,class FROM characters WHERE guid = '%u'" , GUID_LOPART ( plGuid ));
2009-09-11 14:39:38 -07:00
if ( ! result )
2009-08-24 20:23:54 -05:00
return false ; // player doesn't exist
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
Field * fields = result -> Fetch ();
2009-09-11 14:39:38 -07:00
newmember . Name = fields [ 0 ]. GetCppString ();
newmember . ZoneId = fields [ 1 ]. GetUInt32 ();
newmember . Level = fields [ 2 ]. GetUInt8 ();
2009-09-02 16:25:16 -05:00
newmember . Class = fields [ 3 ]. GetUInt8 ();
2010-01-23 14:45:58 +01:00
2009-09-11 14:39:38 -07:00
if ( newmember . Level < 1 || newmember . Level > STRONG_MAX_LEVEL ||
2009-09-02 16:25:16 -05:00
newmember . Class < CLASS_WARRIOR || newmember . Class >= MAX_CLASSES )
2009-08-24 20:23:54 -05:00
{
sLog . outError ( "Player (GUID: %u) has a broken data in field `characters` table, cannot add him to guild." , GUID_LOPART ( plGuid ));
return false ;
}
}
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
newmember . RankId = plRank ;
2008-10-11 14:16:25 -05:00
newmember . OFFnote = ( std :: string ) "" ;
2009-09-11 14:39:38 -07:00
newmember . Pnote = ( std :: string ) "" ;
2009-12-24 10:20:15 +01:00
newmember . LogoutTime = time ( NULL );
2008-10-11 14:16:25 -05:00
newmember . BankResetTimeMoney = 0 ; // this will force update at first query
2009-06-18 18:29:28 +02:00
for ( uint8 i = 0 ; i < GUILD_BANK_MAX_TABS ; ++ i )
2008-10-11 14:16:25 -05:00
newmember . BankResetTimeTab [ i ] = 0 ;
members [ GUID_LOPART ( plGuid )] = newmember ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
std :: string dbPnote = newmember . Pnote ;
2008-10-11 14:16:25 -05:00
std :: string dbOFFnote = newmember . OFFnote ;
CharacterDatabase . escape_string ( dbPnote );
CharacterDatabase . escape_string ( dbOFFnote );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CharacterDatabase . PExecute ( "INSERT INTO guild_member (guildid,guid,rank,pnote,offnote) VALUES ('%u', '%u', '%u','%s','%s')" ,
2009-08-24 19:23:31 -05:00
m_Id , GUID_LOPART ( plGuid ), newmember . RankId , dbPnote . c_str (), dbOFFnote . c_str ());
2009-10-17 15:51:44 -07:00
2008-11-30 12:47:26 -06:00
// If player not in game data in data field will be loaded from guild tables, no need to update it!!
2009-09-11 14:39:38 -07:00
if ( pl )
2008-10-11 14:16:25 -05:00
{
2009-08-24 19:23:31 -05:00
pl -> SetInGuild ( m_Id );
2008-10-11 14:16:25 -05:00
pl -> SetRank ( newmember . RankId );
pl -> SetGuildIdInvited ( 0 );
}
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetMOTD ( std :: string motd )
{
MOTD = motd ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// motd now can be used for encoding to DB
CharacterDatabase . escape_string ( motd );
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "UPDATE guild SET motd='%s' WHERE guildid='%u'" , motd . c_str (), m_Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetGINFO ( std :: string ginfo )
{
GINFO = ginfo ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// ginfo now can be used for encoding to DB
CharacterDatabase . escape_string ( ginfo );
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "UPDATE guild SET info='%s' WHERE guildid='%u'" , ginfo . c_str (), m_Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
bool Guild :: LoadGuildFromDB ( QueryResult_AutoPtr guildDataResult )
2008-10-11 14:16:25 -05:00
{
2010-02-18 02:42:59 +01:00
if ( ! guildDataResult )
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
Field * fields = guildDataResult -> Fetch ();
m_Id = fields [ 0 ]. GetUInt32 ();
m_Name = fields [ 1 ]. GetCppString ();
m_LeaderGuid = MAKE_NEW_GUID ( fields [ 2 ]. GetUInt32 (), 0 , HIGHGUID_PLAYER );
m_EmblemStyle = fields [ 3 ]. GetUInt32 ();
m_EmblemColor = fields [ 4 ]. GetUInt32 ();
m_BorderStyle = fields [ 5 ]. GetUInt32 ();
m_BorderColor = fields [ 6 ]. GetUInt32 ();
m_BackgroundColor = fields [ 7 ]. GetUInt32 ();
GINFO = fields [ 8 ]. GetCppString ();
MOTD = fields [ 9 ]. GetCppString ();
2010-03-19 17:24:23 +01:00
m_CreatedDate = fields [ 10 ]. GetUInt64 ();
2010-02-18 02:42:59 +01:00
m_GuildBankMoney = fields [ 11 ]. GetUInt64 ();
m_PurchasedTabs = fields [ 12 ]. GetUInt32 ();
if ( m_PurchasedTabs > GUILD_BANK_MAX_TABS )
m_PurchasedTabs = GUILD_BANK_MAX_TABS ;
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
return true ;
}
bool Guild :: CheckGuildStructure ()
2010-04-07 17:24:07 +02:00
{
2009-08-24 20:23:54 -05:00
// Repair the structure of guild
2009-08-24 20:25:32 -05:00
// If the guildmaster doesn't exist or isn't the member of guild
// attempt to promote another member
2009-08-24 20:23:54 -05:00
int32 GM_rights = GetRank ( GUID_LOPART ( m_LeaderGuid ));
2009-09-11 14:39:38 -07:00
if ( GM_rights == - 1 )
2008-10-11 14:16:25 -05:00
{
2009-08-24 19:23:31 -05:00
DelMember ( m_LeaderGuid );
2008-10-11 14:16:25 -05:00
// check no members case (disbanded)
2009-09-11 14:39:38 -07:00
if ( members . empty ())
2008-10-11 14:16:25 -05:00
return false ;
}
2009-08-24 20:23:54 -05:00
else if ( GM_rights != GR_GUILDMASTER )
SetLeader ( m_LeaderGuid );
2009-10-17 15:51:44 -07:00
2009-09-12 22:33:24 -07:00
// Check config if multiple guildmasters are allowed
if ( sConfig . GetBoolDefault ( "Guild.AllowMultipleGuildMaster" , 0 ) == 0 )
for ( MemberList :: const_iterator itr = members . begin (); itr != members . end (); ++ itr )
if ( itr -> second . RankId == GR_GUILDMASTER && GUID_LOPART ( m_LeaderGuid ) != itr -> first ) // Allow only 1 guildmaster
ChangeRank ( itr -> first , GR_OFFICER ); // set right of member to officer
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
bool Guild :: LoadRanksFromDB ( QueryResult_AutoPtr guildRanksResult )
2008-10-11 14:16:25 -05:00
{
2010-02-18 02:42:59 +01:00
if ( ! guildRanksResult )
2009-09-02 18:40:27 -05:00
{
2010-02-18 02:42:59 +01:00
sLog . outError ( "Guild %u has broken `guild_rank` data, creating new..." , m_Id );
2009-09-02 18:40:27 -05:00
CreateDefaultGuildRanks ( 0 );
return true ;
}
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
Field * fields ;
2008-10-11 14:16:25 -05:00
bool broken_ranks = false ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
//GUILD RANKS are sequence starting from 0 = GUILD_MASTER (ALL PRIVILEGES) to max 9 (lowest privileges)
//the lower rank id is considered higher rank - so promotion does rank-- and demotion does rank++
//between ranks in sequence cannot be gaps - so 0,1,2,4 cannot be
//min ranks count is 5 and max is 10.
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
2010-02-18 02:42:59 +01:00
fields = guildRanksResult -> Fetch ();
//condition that would be true when all ranks in QueryResult will be processed and guild without ranks is being processed
if ( ! fields )
break ;
uint32 guildId = fields [ 0 ]. GetUInt32 ();
if ( guildId < m_Id )
{
//there is in table guild_rank record which doesn't have guildid in guild table, report error
sLog . outErrorDb ( "Guild %u does not exist but it has a record in guild_rank table, deleting it!" , guildId );
CharacterDatabase . PExecute ( "DELETE FROM guild_rank WHERE guildid = '%u'" , guildId );
continue ;
}
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
if ( guildId > m_Id )
//we loaded all ranks for this guild already, break cycle
break ;
uint32 rankID = fields [ 1 ]. GetUInt32 ();
std :: string rankName = fields [ 2 ]. GetCppString ();
uint32 rankRights = fields [ 3 ]. GetUInt32 ();
uint32 rankMoney = fields [ 4 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( rankID != m_Ranks . size ()) // guild_rank.ids are sequence 0,1,2,3..
2008-10-11 14:16:25 -05:00
broken_ranks = true ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
//first rank is guildmaster, prevent loss leader rights
2009-09-11 14:39:38 -07:00
if ( m_Ranks . empty ())
2008-10-11 14:16:25 -05:00
rankRights |= GR_RIGHT_ALL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AddRank ( rankName , rankRights , rankMoney );
2010-02-18 02:42:59 +01:00
} while ( guildRanksResult -> NextRow () );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( m_Ranks . size () < GUILD_RANKS_MIN_COUNT ) // if too few ranks, renew them
2008-10-11 14:16:25 -05:00
{
2009-08-24 20:23:54 -05:00
m_Ranks . clear ();
2010-02-18 02:42:59 +01:00
sLog . outError ( "Guild %u has broken `guild_rank` data, creating new..." , m_Id );
2009-08-24 20:23:54 -05:00
CreateDefaultGuildRanks ( 0 ); // 0 is default locale_idx
broken_ranks = false ;
2008-10-11 14:16:25 -05:00
}
// guild_rank have wrong numbered ranks, repair
2009-09-11 14:39:38 -07:00
if ( broken_ranks )
2008-10-11 14:16:25 -05:00
{
2010-02-18 02:42:59 +01:00
sLog . outError ( "Guild %u has broken `guild_rank` data, repairing..." , m_Id );
2008-10-11 14:16:25 -05:00
CharacterDatabase . BeginTransaction ();
2010-02-18 02:42:59 +01:00
CharacterDatabase . PExecute ( "DELETE FROM guild_rank WHERE guildid='%u'" , m_Id );
2009-10-17 16:20:24 -07:00
for ( size_t i = 0 ; i < m_Ranks . size (); ++ i )
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
std :: string name = m_Ranks [ i ]. Name ;
uint32 rights = m_Ranks [ i ]. Rights ;
2008-10-11 14:16:25 -05:00
CharacterDatabase . escape_string ( name );
2010-02-18 02:42:59 +01:00
CharacterDatabase . PExecute ( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')" , m_Id , uint32 ( i ), name . c_str (), rights );
2008-10-11 14:16:25 -05:00
}
CharacterDatabase . CommitTransaction ();
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
bool Guild :: LoadMembersFromDB ( QueryResult_AutoPtr guildMembersResult )
2008-10-11 14:16:25 -05:00
{
2010-02-18 02:42:59 +01:00
if ( ! guildMembersResult )
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
2010-02-18 02:42:59 +01:00
Field * fields = guildMembersResult -> Fetch ();
//this condition will be true when all rows in QueryResult are processed and new guild without members is going to be loaded - prevent crash
if ( ! fields )
break ;
uint32 guildId = fields [ 0 ]. GetUInt32 ();
if ( guildId < m_Id )
{
//there is in table guild_member record which doesn't have guildid in guild table, report error
sLog . outErrorDb ( "Guild %u does not exist but it has a record in guild_member table, deleting it!" , guildId );
CharacterDatabase . PExecute ( "DELETE FROM guild_member WHERE guildid = '%u'" , guildId );
continue ;
}
if ( guildId > m_Id )
//we loaded all members for this guild already, break cycle
break ;
2010-04-07 17:24:07 +02:00
2008-10-11 14:16:25 -05:00
MemberSlot newmember ;
2010-02-18 02:42:59 +01:00
uint64 guid = MAKE_NEW_GUID ( fields [ 1 ]. GetUInt32 (), 0 , HIGHGUID_PLAYER );
newmember . RankId = fields [ 2 ]. GetUInt32 ();
2009-08-24 20:23:54 -05:00
//don't allow member to have not existing rank!
if ( newmember . RankId >= m_Ranks . size ())
newmember . RankId = GetLowestRank ();
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
newmember . Pnote = fields [ 3 ]. GetCppString ();
newmember . OFFnote = fields [ 4 ]. GetCppString ();
newmember . BankResetTimeMoney = fields [ 5 ]. GetUInt32 ();
newmember . BankRemMoney = fields [ 6 ]. GetUInt32 ();
2010-04-07 17:24:07 +02:00
for ( uint8 i = 0 ; i < GUILD_BANK_MAX_TABS ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-02-18 02:42:59 +01:00
newmember . BankResetTimeTab [ i ] = fields [ 7 + ( 2 * i )]. GetUInt32 ();
newmember . BankRemSlotsTab [ i ] = fields [ 8 + ( 2 * i )]. GetUInt32 ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
newmember . Name = fields [ 19 ]. GetCppString ();
newmember . Level = fields [ 20 ]. GetUInt8 ();
2009-09-02 16:25:16 -05:00
newmember . Class = fields [ 21 ]. GetUInt8 ();
2010-02-18 02:42:59 +01:00
newmember . ZoneId = fields [ 22 ]. GetUInt32 ();
newmember . LogoutTime = fields [ 23 ]. GetUInt64 ();
2009-10-17 15:51:44 -07:00
2009-08-24 20:25:32 -05:00
//this code will remove unexisting character guids from guild
2009-09-11 14:39:38 -07:00
if ( newmember . Level < 1 || newmember . Level > STRONG_MAX_LEVEL ) // can be at broken `data` field
2008-10-21 12:43:24 -05:00
{
2009-08-24 20:23:54 -05:00
sLog . outError ( "Player (GUID: %u) has a broken data in field `characters`.`data`, deleting him from guild!" , GUID_LOPART ( guid ));
CharacterDatabase . PExecute ( "DELETE FROM guild_member WHERE guid = '%u'" , GUID_LOPART ( guid ));
continue ;
2008-10-21 12:43:24 -05:00
}
2009-09-11 14:39:38 -07:00
if ( ! newmember . ZoneId )
2008-10-11 14:16:25 -05:00
{
2009-08-24 20:23:54 -05:00
sLog . outError ( "Player (GUID: %u) has broken zone-data" , GUID_LOPART ( guid ));
// here it will also try the same, to get the zone from characters-table, but additional it tries to find
// the zone through xy coords .. this is a bit redundant, but shouldn't be called often
2009-09-11 14:39:38 -07:00
newmember . ZoneId = Player :: GetZoneIdFromDB ( guid );
2008-10-11 14:16:25 -05:00
}
2009-09-11 14:39:38 -07:00
if ( newmember . Class < CLASS_WARRIOR || newmember . Class >= MAX_CLASSES ) // can be at broken `class` field
2008-12-22 10:59:38 -06:00
{
2009-08-24 20:23:54 -05:00
sLog . outError ( "Player (GUID: %u) has a broken data in field `characters`.`class`, deleting him from guild!" , GUID_LOPART ( guid ));
CharacterDatabase . PExecute ( "DELETE FROM guild_member WHERE guid = '%u'" , GUID_LOPART ( guid ));
continue ;
2008-12-22 10:59:38 -06:00
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
members [ GUID_LOPART ( guid )] = newmember ;
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
} while ( guildMembersResult -> NextRow ());
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( members . empty ())
2009-08-24 20:23:54 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
return true ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
void Guild :: SetMemberStats ( uint64 guid )
2008-10-11 14:16:25 -05:00
{
MemberList :: iterator itr = members . find ( GUID_LOPART ( guid ));
if ( itr == members . end () )
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * pl = ObjectAccessor :: FindPlayer ( guid );
2009-09-11 14:39:38 -07:00
if ( ! pl )
2008-10-11 14:16:25 -05:00
return ;
2009-09-11 14:39:38 -07:00
itr -> second . Name = pl -> GetName ();
itr -> second . Level = pl -> getLevel ();
2009-08-24 20:23:54 -05:00
itr -> second . Class = pl -> getClass ();
2009-09-11 14:39:38 -07:00
itr -> second . ZoneId = pl -> GetZoneId ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetLeader ( uint64 guid )
{
2009-08-24 19:23:31 -05:00
m_LeaderGuid = guid ;
2008-12-08 16:34:03 -06:00
ChangeRank ( guid , GR_GUILDMASTER );
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "UPDATE guild SET leaderguid='%u' WHERE guildid='%u'" , GUID_LOPART ( guid ), m_Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: DelMember ( uint64 guid , bool isDisbanding )
{
2009-08-24 20:23:54 -05:00
//guild master can be deleted when loading guild and guid doesn't exist in characters table
//or when he is removed from guild by gm command
2009-09-11 14:39:38 -07:00
if ( m_LeaderGuid == guid && ! isDisbanding )
2008-10-11 14:16:25 -05:00
{
2008-12-08 16:34:03 -06:00
MemberSlot * oldLeader = NULL ;
MemberSlot * best = NULL ;
uint64 newLeaderGUID = 0 ;
2009-09-11 14:39:38 -07:00
for ( Guild :: MemberList :: iterator i = members . begin (); i != members . end (); ++ i )
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
if ( i -> first == GUID_LOPART ( guid ))
2008-10-11 14:16:25 -05:00
{
2008-12-08 16:34:03 -06:00
oldLeader = & ( i -> second );
continue ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( ! best || best -> RankId > i -> second . RankId )
2008-10-11 14:16:25 -05:00
{
2008-12-08 16:34:03 -06:00
best = & ( i -> second );
newLeaderGUID = i -> first ;
2008-10-11 14:16:25 -05:00
}
}
2009-09-11 14:39:38 -07:00
if ( ! best )
2008-10-11 14:16:25 -05:00
{
2008-12-08 16:34:03 -06:00
Disband ();
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2008-12-08 16:34:03 -06:00
SetLeader ( newLeaderGUID );
2009-10-17 15:51:44 -07:00
2008-12-08 16:34:03 -06:00
// If player not online data in data field will be loaded from guild tabs no need to update it !!
2009-09-11 14:39:38 -07:00
if ( Player * newLeader = objmgr . GetPlayer ( newLeaderGUID ))
2008-12-08 16:34:03 -06:00
newLeader -> SetRank ( GR_GUILDMASTER );
2009-10-17 15:51:44 -07:00
2008-12-08 16:34:03 -06:00
// when leader non-exist (at guild load with deleted leader only) not send broadcasts
2009-09-11 14:39:38 -07:00
if ( oldLeader )
2008-12-08 16:34:03 -06:00
{
2009-09-11 14:39:38 -07:00
WorldPacket data ( SMSG_GUILD_EVENT , ( 1 + 1 + ( oldLeader -> Name ). size () + 1 + ( best -> Name ). size () + 1 ));
2008-12-08 16:34:03 -06:00
data << ( uint8 ) GE_LEADER_CHANGED ;
data << ( uint8 ) 2 ;
2009-09-11 14:39:38 -07:00
data << oldLeader -> Name ;
data << best -> Name ;
2008-12-08 16:34:03 -06:00
BroadcastPacket ( & data );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
data . Initialize ( SMSG_GUILD_EVENT , ( 1 + 1 + ( oldLeader -> Name ). size () + 1 ));
2008-12-08 16:34:03 -06:00
data << ( uint8 ) GE_LEFT ;
data << ( uint8 ) 1 ;
2009-09-11 14:39:38 -07:00
data << oldLeader -> Name ;
2008-12-08 16:34:03 -06:00
BroadcastPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-12-08 16:34:03 -06:00
sLog . outDebug ( "WORLD: Sent (SMSG_GUILD_EVENT)" );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
members . erase ( GUID_LOPART ( guid ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * player = objmgr . GetPlayer ( guid );
2008-11-30 12:47:26 -06:00
// If player not online data in data field will be loaded from guild tabs no need to update it !!
2009-09-11 14:39:38 -07:00
if ( player )
2008-10-11 14:16:25 -05:00
{
player -> SetInGuild ( 0 );
player -> SetRank ( 0 );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CharacterDatabase . PExecute ( "DELETE FROM guild_member WHERE guid = '%u'" , GUID_LOPART ( guid ));
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: ChangeRank ( uint64 guid , uint32 newRank )
{
MemberList :: iterator itr = members . find ( GUID_LOPART ( guid ));
2009-09-11 14:39:38 -07:00
if ( itr != members . end ())
2008-10-11 14:16:25 -05:00
itr -> second . RankId = newRank ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * player = objmgr . GetPlayer ( guid );
2008-11-30 12:47:26 -06:00
// If player not online data in data field will be loaded from guild tabs no need to update it !!
2009-09-11 14:39:38 -07:00
if ( player )
2008-10-11 14:16:25 -05:00
player -> SetRank ( newRank );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CharacterDatabase . PExecute ( "UPDATE guild_member SET rank='%u' WHERE guid='%u'" , newRank , GUID_LOPART ( guid ) );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetPNOTE ( uint64 guid , std :: string pnote )
{
MemberList :: iterator itr = members . find ( GUID_LOPART ( guid ));
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
itr -> second . Pnote = pnote ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// pnote now can be used for encoding to DB
CharacterDatabase . escape_string ( pnote );
CharacterDatabase . PExecute ( "UPDATE guild_member SET pnote = '%s' WHERE guid = '%u'" , pnote . c_str (), itr -> first );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetOFFNOTE ( uint64 guid , std :: string offnote )
{
MemberList :: iterator itr = members . find ( GUID_LOPART ( guid ));
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-10-11 14:16:25 -05:00
return ;
itr -> second . OFFnote = offnote ;
// offnote now can be used for encoding to DB
CharacterDatabase . escape_string ( offnote );
CharacterDatabase . PExecute ( "UPDATE guild_member SET offnote = '%s' WHERE guid = '%u'" , offnote . c_str (), itr -> first );
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
void Guild :: BroadcastToGuild ( WorldSession * session , const std :: string & msg , uint32 language )
2008-10-11 14:16:25 -05:00
{
if ( session && session -> GetPlayer () && HasRankRight ( session -> GetPlayer () -> GetRank (), GR_RIGHT_GCHATSPEAK ))
{
WorldPacket data ;
ChatHandler ( session ). FillMessageData ( & data , CHAT_MSG_GUILD , language , 0 , msg . c_str ());
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
for ( MemberList :: const_iterator itr = members . begin (); itr != members . end (); ++ itr )
{
Player * pl = ObjectAccessor :: FindPlayer ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( pl && pl -> GetSession () && HasRankRight ( pl -> GetRank (), GR_RIGHT_GCHATLISTEN ) && ! pl -> GetSocial () -> HasIgnore ( session -> GetPlayer () -> GetGUIDLow ()) )
pl -> GetSession () -> SendPacket ( & data );
}
}
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
void Guild :: BroadcastToOfficers ( WorldSession * session , const std :: string & msg , uint32 language )
2008-10-11 14:16:25 -05:00
{
2010-02-15 14:30:12 +01:00
if ( session && session -> GetPlayer () && HasRankRight ( session -> GetPlayer () -> GetRank (), GR_RIGHT_OFFCHATSPEAK ))
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
for ( MemberList :: const_iterator itr = members . begin (); itr != members . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
WorldPacket data ;
2010-02-15 14:30:12 +01:00
ChatHandler :: FillMessageData ( & data , session , CHAT_MSG_OFFICER , language , NULL , 0 , msg . c_str (), NULL );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Player * pl = ObjectAccessor :: FindPlayer ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( pl && pl -> GetSession () && HasRankRight ( pl -> GetRank (), GR_RIGHT_OFFCHATLISTEN ) && ! pl -> GetSocial () -> HasIgnore ( session -> GetPlayer () -> GetGUIDLow ()))
pl -> GetSession () -> SendPacket ( & data );
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: BroadcastPacket ( WorldPacket * packet )
{
2009-09-11 14:39:38 -07:00
for ( MemberList :: const_iterator itr = members . begin (); itr != members . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
Player * player = ObjectAccessor :: FindPlayer ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER ));
2009-09-11 14:39:38 -07:00
if ( player )
2008-10-11 14:16:25 -05:00
player -> GetSession () -> SendPacket ( packet );
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: BroadcastPacketToRank ( WorldPacket * packet , uint32 rankId )
{
2009-09-11 14:39:38 -07:00
for ( MemberList :: const_iterator itr = members . begin (); itr != members . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
if ( itr -> second . RankId == rankId )
{
Player * player = ObjectAccessor :: FindPlayer ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER ));
2009-09-11 14:39:38 -07:00
if ( player )
2008-10-11 14:16:25 -05:00
player -> GetSession () -> SendPacket ( packet );
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: CreateRank ( std :: string name_ , uint32 rights )
{
2009-09-11 14:39:38 -07:00
if ( m_Ranks . size () >= GUILD_RANKS_MAX_COUNT )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
// ranks are sequence 0,1,2,... where 0 means guildmaster
uint32 new_rank_id = m_Ranks . size ();
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
AddRank ( name_ , rights , 0 );
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
//existing records in db should be deleted before calling this procedure and m_PurchasedTabs must be loaded already
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
for ( uint32 i = 0 ; i < m_PurchasedTabs ; ++ i )
{
//create bank rights with 0
CharacterDatabase . PExecute ( "INSERT INTO guild_bank_right (guildid,TabId,rid) VALUES ('%u','%u','%u')" , m_Id , i , new_rank_id );
}
2008-10-11 14:16:25 -05:00
// name now can be used for encoding to DB
CharacterDatabase . escape_string ( name_ );
2009-08-24 20:23:54 -05:00
CharacterDatabase . PExecute ( "INSERT INTO guild_rank (guildid,rid,rname,rights) VALUES ('%u', '%u', '%s', '%u')" , m_Id , new_rank_id , name_ . c_str (), rights );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-12-12 11:21:28 -06:00
void Guild :: AddRank ( const std :: string & name_ , uint32 rights , uint32 money )
2008-10-11 14:16:25 -05:00
{
2009-08-24 19:23:31 -05:00
m_Ranks . push_back ( RankInfo ( name_ , rights , money ));
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: DelRank ()
{
2009-09-02 18:40:27 -05:00
// client won't allow to have less than GUILD_RANKS_MIN_COUNT ranks in guild
2009-09-11 14:39:38 -07:00
if ( m_Ranks . size () <= GUILD_RANKS_MIN_COUNT )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
// delete lowest guild_rank
uint32 rank = GetLowestRank ();
CharacterDatabase . PExecute ( "DELETE FROM guild_rank WHERE rid>='%u' AND guildid='%u'" , rank , m_Id );
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
m_Ranks . pop_back ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
std :: string Guild :: GetRankName ( uint32 rankId )
{
2009-09-11 14:39:38 -07:00
if ( rankId >= m_Ranks . size ())
2008-10-11 14:16:25 -05:00
return "<unknown>" ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
return m_Ranks [ rankId ]. Name ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Guild :: GetRankRights ( uint32 rankId )
{
2009-09-11 14:39:38 -07:00
if ( rankId >= m_Ranks . size ())
2008-10-11 14:16:25 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
return m_Ranks [ rankId ]. Rights ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetRankName ( uint32 rankId , std :: string name_ )
{
2009-09-11 14:39:38 -07:00
if ( rankId >= m_Ranks . size ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
m_Ranks [ rankId ]. Name = name_ ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// name now can be used for encoding to DB
CharacterDatabase . escape_string ( name_ );
2009-08-28 01:50:29 +02:00
CharacterDatabase . PExecute ( "UPDATE guild_rank SET rname='%s' WHERE rid='%u' AND guildid='%u'" , name_ . c_str (), rankId , m_Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetRankRights ( uint32 rankId , uint32 rights )
{
2009-09-11 14:39:38 -07:00
if ( rankId >= m_Ranks . size ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
m_Ranks [ rankId ]. Rights = rights ;
2009-10-17 15:51:44 -07:00
2009-08-28 01:50:29 +02:00
CharacterDatabase . PExecute ( "UPDATE guild_rank SET rights='%u' WHERE rid='%u' AND guildid='%u'" , rights , rankId , m_Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-11-05 20:10:19 -06:00
int32 Guild :: GetRank ( uint32 LowGuid )
{
2009-04-29 00:26:07 -05:00
MemberList :: const_iterator itr = members . find ( LowGuid );
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-11-05 20:10:19 -06:00
return - 1 ;
2009-10-17 15:51:44 -07:00
2008-11-05 20:10:19 -06:00
return itr -> second . RankId ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: Disband ()
{
WorldPacket data ( SMSG_GUILD_EVENT , 1 );
data << ( uint8 ) GE_DISBANDED ;
2008-12-08 16:34:03 -06:00
BroadcastPacket ( & data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
while ( ! members . empty ())
{
2009-04-29 00:26:07 -05:00
MemberList :: const_iterator itr = members . begin ();
2008-10-11 14:16:25 -05:00
DelMember ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER ), true );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CharacterDatabase . BeginTransaction ();
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "DELETE FROM guild WHERE guildid = '%u'" , m_Id );
CharacterDatabase . PExecute ( "DELETE FROM guild_rank WHERE guildid = '%u'" , m_Id );
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_tab WHERE guildid = '%u'" , m_Id );
2009-09-11 14:39:38 -07:00
// TODO item_instance should be deleted ?
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_item WHERE guildid = '%u'" , m_Id );
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_right WHERE guildid = '%u'" , m_Id );
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_eventlog WHERE guildid = '%u'" , m_Id );
CharacterDatabase . PExecute ( "DELETE FROM guild_eventlog WHERE guildid = '%u'" , m_Id );
2008-10-11 14:16:25 -05:00
CharacterDatabase . CommitTransaction ();
2009-08-24 19:23:31 -05:00
objmgr . RemoveGuild ( m_Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-09-14 13:34:23 -07:00
void Guild :: Roster ( WorldSession * session /*= NULL*/ )
2008-10-11 14:16:25 -05:00
{
// we can only guess size
2009-08-24 19:23:31 -05:00
WorldPacket data ( SMSG_GUILD_ROSTER , ( 4 + MOTD . length () + 1 + GINFO . length () + 1 + 4 + m_Ranks . size () * ( 4 + 4 + GUILD_BANK_MAX_TABS * ( 4 + 4 )) + members . size () * 50 ));
2008-10-11 14:16:25 -05:00
data << ( uint32 ) members . size ();
data << MOTD ;
data << GINFO ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
data << ( uint32 ) m_Ranks . size ();
for ( RankList :: const_iterator ritr = m_Ranks . begin (); ritr != m_Ranks . end (); ++ ritr )
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
data << uint32 ( ritr -> Rights );
2009-07-24 09:08:35 +08:00
data << uint32 ( ritr -> BankMoneyPerDay ); // count of: withdraw gold(gold/day) Note: in game set gold, in packet set bronze.
for ( int i = 0 ; i < GUILD_BANK_MAX_TABS ; ++ i )
2008-10-11 14:16:25 -05:00
{
2009-07-24 09:08:35 +08:00
data << uint32 ( ritr -> TabRight [ i ]); // for TAB_i rights: view tabs = 0x01, deposit items =0x02
data << uint32 ( ritr -> TabSlotPerDay [ i ]); // for TAB_i count of: withdraw items(stack/day)
2008-10-11 14:16:25 -05:00
}
}
2009-02-15 12:14:14 -06:00
for ( MemberList :: const_iterator itr = members . begin (); itr != members . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
if ( Player * pl = ObjectAccessor :: FindPlayer ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER )))
{
2009-07-24 09:08:35 +08:00
data << uint64 ( pl -> GetGUID ());
data << uint8 ( 1 );
data << pl -> GetName ();
data << uint32 ( itr -> second . RankId );
data << uint8 ( pl -> getLevel ());
data << uint8 ( pl -> getClass ());
data << uint8 ( 0 ); // new 2.4.0
data << uint32 ( pl -> GetZoneId ());
2008-10-11 14:16:25 -05:00
data << itr -> second . Pnote ;
data << itr -> second . OFFnote ;
}
else
{
data << uint64 ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER ));
2009-07-24 09:08:35 +08:00
data << uint8 ( 0 );
2009-09-11 14:39:38 -07:00
data << itr -> second . Name ;
2009-07-24 09:08:35 +08:00
data << uint32 ( itr -> second . RankId );
2009-09-11 14:39:38 -07:00
data << uint8 ( itr -> second . Level );
2009-07-24 09:08:35 +08:00
data << uint8 ( itr -> second . Class );
data << uint8 ( 0 ); // new 2.4.0
2009-09-11 14:39:38 -07:00
data << uint32 ( itr -> second . ZoneId );
2009-12-24 10:20:15 +01:00
data << float ( float ( time ( NULL ) - itr -> second . LogoutTime ) / DAY );
2008-10-11 14:16:25 -05:00
data << itr -> second . Pnote ;
data << itr -> second . OFFnote ;
}
}
2009-09-14 13:34:23 -07:00
if ( session )
session -> SendPacket ( & data );
else
BroadcastPacket ( & data );
2008-10-11 14:16:25 -05:00
sLog . outDebug ( "WORLD: Sent (SMSG_GUILD_ROSTER)" );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: Query ( WorldSession * session )
{
WorldPacket data ( SMSG_GUILD_QUERY_RESPONSE , ( 8 * 32 + 200 )); // we can only guess size
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
data << m_Id ;
data << m_Name ;
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
for ( size_t i = 0 ; i < GUILD_RANKS_MAX_COUNT ; ++ i ) // show always 10 ranks
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
if ( i < m_Ranks . size ())
data << m_Ranks [ i ]. Name ;
2008-10-11 14:16:25 -05:00
else
data << ( uint8 ) 0 ; // null string
}
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
data << uint32 ( m_EmblemStyle );
data << uint32 ( m_EmblemColor );
data << uint32 ( m_BorderStyle );
data << uint32 ( m_BorderColor );
data << uint32 ( m_BackgroundColor );
2008-12-24 09:58:26 -06:00
data << uint32 ( 0 ); // something new in WotLK
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
session -> SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)" );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetEmblem ( uint32 emblemStyle , uint32 emblemColor , uint32 borderStyle , uint32 borderColor , uint32 backgroundColor )
{
2009-08-24 19:23:31 -05:00
m_EmblemStyle = emblemStyle ;
m_EmblemColor = emblemColor ;
m_BorderStyle = borderStyle ;
m_BorderColor = borderColor ;
m_BackgroundColor = backgroundColor ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "UPDATE guild SET EmblemStyle=%u, EmblemColor=%u, BorderStyle=%u, BorderColor=%u, BackgroundColor=%u WHERE guildid = %u" , m_EmblemStyle , m_EmblemColor , m_BorderStyle , m_BorderColor , m_BackgroundColor , m_Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: UpdateLogoutTime ( uint64 guid )
{
MemberList :: iterator itr = members . find ( GUID_LOPART ( guid ));
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-12-24 10:20:15 +01:00
itr -> second . LogoutTime = time ( NULL );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// *************************************************
// Guild Eventlog part
// *************************************************
// Display guild eventlog
2009-08-24 19:23:31 -05:00
void Guild :: DisplayGuildEventLog ( WorldSession * session )
2008-10-11 14:16:25 -05:00
{
// Sending result
WorldPacket data ( MSG_GUILD_EVENT_LOG_QUERY , 0 );
// count, max count == 100
2009-08-24 19:23:31 -05:00
data << uint8 ( m_GuildEventLog . size ());
for ( GuildEventLog :: const_iterator itr = m_GuildEventLog . begin (); itr != m_GuildEventLog . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
// Event type
2009-08-06 17:45:37 -05:00
data << uint8 ( itr -> EventType );
2008-10-11 14:16:25 -05:00
// Player 1
2009-08-06 17:45:37 -05:00
data << uint64 ( itr -> PlayerGuid1 );
2008-10-11 14:16:25 -05:00
// Player 2 not for left/join guild events
2009-08-06 17:45:37 -05:00
if ( itr -> EventType != GUILD_EVENT_LOG_JOIN_GUILD && itr -> EventType != GUILD_EVENT_LOG_LEAVE_GUILD )
data << uint64 ( itr -> PlayerGuid2 );
2008-10-11 14:16:25 -05:00
// New Rank - only for promote/demote guild events
2009-08-06 17:45:37 -05:00
if ( itr -> EventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || itr -> EventType == GUILD_EVENT_LOG_DEMOTE_PLAYER )
data << uint8 ( itr -> NewRank );
2008-10-11 14:16:25 -05:00
// Event timestamp
2009-12-24 10:20:15 +01:00
data << uint32 ( time ( NULL ) - itr -> TimeStamp );
2008-10-11 14:16:25 -05:00
}
session -> SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent (MSG_GUILD_EVENT_LOG_QUERY)" );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Load guild eventlog from DB
void Guild :: LoadGuildEventLogFromDB ()
{
2009-08-24 19:23:31 -05:00
// 0 1 2 3 4 5
2010-01-23 14:45:58 +01:00
QueryResult_AutoPtr result = CharacterDatabase . PQuery ( "SELECT LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp FROM guild_eventlog WHERE guildid=%u ORDER BY TimeStamp DESC,LogGuid DESC LIMIT %u" , m_Id , GUILD_EVENTLOG_MAX_RECORDS );
2009-09-11 14:39:38 -07:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-08-24 19:23:31 -05:00
bool isNextLogGuidSet = false ;
//uint32 configCount = sWorld.getConfig(CONFIG_GUILD_EVENT_LOG_COUNT);
// First event in list will be the oldest and the latest event is last event in list
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-08-24 19:23:31 -05:00
if ( ! isNextLogGuidSet )
{
m_GuildEventLogNextGuid = fields [ 0 ]. GetUInt32 ();
isNextLogGuidSet = true ;
}
2008-10-11 14:16:25 -05:00
// Fill entry
2009-08-24 19:23:31 -05:00
GuildEventLogEntry NewEvent ;
2009-08-06 17:45:37 -05:00
NewEvent . EventType = fields [ 1 ]. GetUInt8 ();
NewEvent . PlayerGuid1 = fields [ 2 ]. GetUInt32 ();
NewEvent . PlayerGuid2 = fields [ 3 ]. GetUInt32 ();
NewEvent . NewRank = fields [ 4 ]. GetUInt8 ();
NewEvent . TimeStamp = fields [ 5 ]. GetUInt64 ();
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
// There can be a problem if more events have same TimeStamp the ORDER can be broken when fields[0].GetUInt32() == configCount, but
// events with same timestamp can appear when there is lag, and we naivly suppose that mangos isn't laggy
// but if problem appears, player will see set of guild events that have same timestamp in bad order
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
// Add entry to list
m_GuildEventLog . push_front ( NewEvent );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
} while ( result -> NextRow ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// Add entry to guild eventlog
void Guild :: LogGuildEvent ( uint8 EventType , uint32 PlayerGuid1 , uint32 PlayerGuid2 , uint8 NewRank )
{
2009-08-24 19:23:31 -05:00
GuildEventLogEntry NewEvent ;
// Create event
2009-08-06 17:45:37 -05:00
NewEvent . EventType = EventType ;
NewEvent . PlayerGuid1 = PlayerGuid1 ;
NewEvent . PlayerGuid2 = PlayerGuid2 ;
NewEvent . NewRank = NewRank ;
2009-12-24 10:20:15 +01:00
NewEvent . TimeStamp = uint32 ( time ( NULL ));
2009-08-24 19:23:31 -05:00
// Count new LogGuid
m_GuildEventLogNextGuid = ( m_GuildEventLogNextGuid + 1 ) % sWorld . getConfig ( CONFIG_GUILD_EVENT_LOG_COUNT );
// Check max records limit
if ( m_GuildEventLog . size () >= GUILD_EVENTLOG_MAX_RECORDS )
m_GuildEventLog . pop_front ();
// Add event to list
m_GuildEventLog . push_back ( NewEvent );
// Save event to DB
CharacterDatabase . PExecute ( "DELETE FROM guild_eventlog WHERE guildid='%u' AND LogGuid='%u'" , m_Id , m_GuildEventLogNextGuid );
2009-05-31 16:15:12 -05:00
CharacterDatabase . PExecute ( "INSERT INTO guild_eventlog (guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','" UI64FMTD "')" ,
2009-08-24 19:23:31 -05:00
m_Id , m_GuildEventLogNextGuid , uint32 ( NewEvent . EventType ), NewEvent . PlayerGuid1 , NewEvent . PlayerGuid2 , uint32 ( NewEvent . NewRank ), NewEvent . TimeStamp );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// *************************************************
// Guild Bank part
// *************************************************
// Bank content related
void Guild :: DisplayGuildBankContent ( WorldSession * session , uint8 TabId )
{
2009-12-17 11:14:55 +01:00
GuildBankTab const * tab = m_TabListMap [ TabId ];
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
if ( ! IsMemberHaveRights ( session -> GetPlayer () -> GetGUIDLow (), TabId , GUILD_BANK_RIGHT_VIEW_TAB ))
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
WorldPacket data ( SMSG_GUILD_BANK_LIST , 1200 );
2009-12-17 11:14:55 +01:00
2008-10-11 14:16:25 -05:00
data << uint64 ( GetGuildBankMoney ());
data << uint8 ( TabId );
2009-08-28 01:50:29 +02:00
data << uint32 ( GetMemberSlotWithdrawRem ( session -> GetPlayer () -> GetGUIDLow (), TabId )); // remaining slots for today
2010-02-15 14:30:12 +01:00
data << uint8 ( 0 ); // Tell client that there's no tab info in this packet
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint8 ( GUILD_BANK_MAX_SLOTS );
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
for ( uint8 i = 0 ; i < GUILD_BANK_MAX_SLOTS ; ++ i )
2008-10-11 14:16:25 -05:00
AppendDisplayGuildBankSlot ( data , tab , i );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
session -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
sLog . outDebug ( "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: DisplayGuildBankContentUpdate ( uint8 TabId , int32 slot1 , int32 slot2 )
{
2009-12-17 11:14:55 +01:00
GuildBankTab const * tab = m_TabListMap [ TabId ];
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
WorldPacket data ( SMSG_GUILD_BANK_LIST , 1200 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint64 ( GetGuildBankMoney ());
data << uint8 ( TabId );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
size_t rempos = data . wpos ();
2010-02-15 14:30:12 +01:00
data << uint32 ( 0 ); // item withdraw amount, will be filled later
data << uint8 ( 0 ); // Tell client that there's no tab info in this packet
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( slot2 == - 1 ) // single item in slot1
2008-10-11 14:16:25 -05:00
{
2010-02-15 14:30:12 +01:00
data << uint8 ( 1 ); // item count
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AppendDisplayGuildBankSlot ( data , tab , slot1 );
}
else // 2 items (in slot1 and slot2)
{
2010-02-15 14:30:12 +01:00
data << uint8 ( 2 ); // item count
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( slot1 > slot2 )
2008-10-11 14:16:25 -05:00
std :: swap ( slot1 , slot2 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
AppendDisplayGuildBankSlot ( data , tab , slot1 );
AppendDisplayGuildBankSlot ( data , tab , slot2 );
}
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
for ( MemberList :: const_iterator itr = members . begin (); itr != members . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
Player * player = ObjectAccessor :: FindPlayer ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER ));
2009-09-11 14:39:38 -07:00
if ( ! player )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( ! IsMemberHaveRights ( itr -> first , TabId , GUILD_BANK_RIGHT_VIEW_TAB ))
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data . put < uint32 > ( rempos , uint32 ( GetMemberSlotWithdrawRem ( player -> GetGUIDLow (), TabId )));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
player -> GetSession () -> SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
sLog . outDebug ( "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: DisplayGuildBankContentUpdate ( uint8 TabId , GuildItemPosCountVec const & slots )
{
2009-12-17 11:14:55 +01:00
GuildBankTab const * tab = m_TabListMap [ TabId ];
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
WorldPacket data ( SMSG_GUILD_BANK_LIST , 1200 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint64 ( GetGuildBankMoney ());
data << uint8 ( TabId );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
size_t rempos = data . wpos ();
2010-02-15 14:30:12 +01:00
data << uint32 ( 0 ); // item withdraw amount, will be filled later
data << uint8 ( 0 ); // Tell client that there's no tab info in this packet
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint8 ( slots . size ()); // updates count
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
for ( GuildItemPosCountVec :: const_iterator itr = slots . begin (); itr != slots . end (); ++ itr )
AppendDisplayGuildBankSlot ( data , tab , itr -> Slot );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
for ( MemberList :: const_iterator itr = members . begin (); itr != members . end (); ++ itr )
2008-10-11 14:16:25 -05:00
{
Player * player = ObjectAccessor :: FindPlayer ( MAKE_NEW_GUID ( itr -> first , 0 , HIGHGUID_PLAYER ));
2009-09-11 14:39:38 -07:00
if ( ! player )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( ! IsMemberHaveRights ( itr -> first , TabId , GUILD_BANK_RIGHT_VIEW_TAB ))
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data . put < uint32 > ( rempos , uint32 ( GetMemberSlotWithdrawRem ( player -> GetGUIDLow (), TabId )));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
player -> GetSession () -> SendPacket ( & data );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
sLog . outDebug ( "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Item * Guild :: GetItem ( uint8 TabId , uint8 SlotId )
{
if ( TabId >= m_TabListMap . size () || SlotId >= GUILD_BANK_MAX_SLOTS )
return NULL ;
return m_TabListMap [ TabId ] -> Slots [ SlotId ];
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// *************************************************
// Tab related
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: DisplayGuildBankTabsInfo ( WorldSession * session )
{
WorldPacket data ( SMSG_GUILD_BANK_LIST , 500 );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint64 ( GetGuildBankMoney ());
data << uint8 ( 0 ); // TabInfo packet must be for TabId 0
2010-02-15 14:30:12 +01:00
data << uint32 ( GetMemberSlotWithdrawRem ( session -> GetPlayer () -> GetGUIDLow (), 0 ));
data << uint8 ( 1 ); // Tell client that this packet includes tab info
2009-09-14 13:34:23 -07:00
data << uint8 ( m_PurchasedTabs ); // here is the number of tabs
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
for ( uint8 i = 0 ; i < m_PurchasedTabs ; ++ i )
2008-10-11 14:16:25 -05:00
{
data << m_TabListMap [ i ] -> Name . c_str ();
data << m_TabListMap [ i ] -> Icon . c_str ();
}
data << uint8 ( 0 ); // Do not send tab content
session -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
sLog . outDebug ( "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
}
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
void Guild :: DisplayGuildBankMoneyUpdate ( WorldSession * session )
2009-12-17 11:14:55 +01:00
{
WorldPacket data ( SMSG_GUILD_BANK_LIST , 8 + 1 + 4 + 1 + 1 );
data << uint64 ( GetGuildBankMoney ());
data << uint8 ( 0 ); // TabId, default 0
2010-02-15 14:30:12 +01:00
data << uint32 ( GetMemberSlotWithdrawRem ( session -> GetPlayer () -> GetGUIDLow (), 0 ));
data << uint8 ( 0 ); // Tell that there's no tab info in this packet
2009-12-17 11:14:55 +01:00
data << uint8 ( 0 ); // not send items
BroadcastPacket ( & data );
sLog . outDebug ( "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
}
2008-10-11 14:16:25 -05:00
void Guild :: CreateNewBankTab ()
{
2009-08-24 19:23:31 -05:00
if ( m_PurchasedTabs >= GUILD_BANK_MAX_TABS )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
++ m_PurchasedTabs ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GuildBankTab * AnotherTab = new GuildBankTab ;
memset ( AnotherTab -> Slots , 0 , GUILD_BANK_MAX_SLOTS * sizeof ( Item * ));
2009-08-24 19:23:31 -05:00
m_TabListMap . resize ( m_PurchasedTabs );
m_TabListMap [ m_PurchasedTabs - 1 ] = AnotherTab ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CharacterDatabase . BeginTransaction ();
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'" , m_Id , uint32 ( m_PurchasedTabs - 1 ));
CharacterDatabase . PExecute ( "INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')" , m_Id , uint32 ( m_PurchasedTabs - 1 ));
2008-10-11 14:16:25 -05:00
CharacterDatabase . CommitTransaction ();
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetGuildBankTabInfo ( uint8 TabId , std :: string Name , std :: string Icon )
{
2009-09-11 14:39:38 -07:00
if ( m_TabListMap [ TabId ] -> Name == Name && m_TabListMap [ TabId ] -> Icon == Icon )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_TabListMap [ TabId ] -> Name = Name ;
m_TabListMap [ TabId ] -> Icon = Icon ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CharacterDatabase . escape_string ( Name );
CharacterDatabase . escape_string ( Icon );
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "UPDATE guild_bank_tab SET TabName='%s',TabIcon='%s' WHERE guildid='%u' AND TabId='%u'" , Name . c_str (), Icon . c_str (), m_Id , uint32 ( TabId ));
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Guild :: GetBankRights ( uint32 rankId , uint8 TabId ) const
{
2009-09-11 14:39:38 -07:00
if ( rankId >= m_Ranks . size () || TabId >= GUILD_BANK_MAX_TABS )
2008-10-11 14:16:25 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
return m_Ranks [ rankId ]. TabRight [ TabId ];
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// *************************************************
2010-02-15 14:30:12 +01:00
// Guild bank loading related
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
// This load should be called on startup only
2008-10-11 14:16:25 -05:00
void Guild :: LoadGuildBankFromDB ()
{
// 0 1 2 3
2010-01-23 14:45:58 +01:00
QueryResult_AutoPtr result = CharacterDatabase . PQuery ( "SELECT TabId, TabName, TabIcon, TabText FROM guild_bank_tab WHERE guildid='%u' ORDER BY TabId" , m_Id );
2009-09-11 14:39:38 -07:00
if ( ! result )
2008-10-11 14:16:25 -05:00
{
2009-08-24 19:23:31 -05:00
m_PurchasedTabs = 0 ;
2008-10-11 14:16:25 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
m_TabListMap . resize ( m_PurchasedTabs );
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
uint8 TabId = fields [ 0 ]. GetUInt8 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GuildBankTab * NewTab = new GuildBankTab ;
memset ( NewTab -> Slots , 0 , GUILD_BANK_MAX_SLOTS * sizeof ( Item * ));
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
NewTab -> Name = fields [ 1 ]. GetCppString ();
NewTab -> Icon = fields [ 2 ]. GetCppString ();
NewTab -> Text = fields [ 3 ]. GetCppString ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_TabListMap [ TabId ] = NewTab ;
2010-02-15 14:30:12 +01:00
} while ( result -> NextRow ());
2009-10-17 15:51:44 -07:00
2008-12-28 12:10:31 -06:00
// data needs to be at first place for Item::LoadFromDB
// 0 1 2 3 4
2009-08-24 19:23:31 -05:00
result = CharacterDatabase . PQuery ( "SELECT data, TabId, SlotId, item_guid, item_entry FROM guild_bank_item JOIN item_instance ON item_guid = guid WHERE guildid='%u' ORDER BY TabId" , m_Id );
2009-09-11 14:39:38 -07:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2008-12-28 12:10:31 -06:00
uint8 TabId = fields [ 1 ]. GetUInt8 ();
uint8 SlotId = fields [ 2 ]. GetUInt8 ();
uint32 ItemGuid = fields [ 3 ]. GetUInt32 ();
uint32 ItemEntry = fields [ 4 ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
if ( TabId >= m_PurchasedTabs || TabId >= GUILD_BANK_MAX_TABS )
2008-10-11 14:16:25 -05:00
{
sLog . outError ( "Guild::LoadGuildBankFromDB: Invalid tab for item (GUID: %u id: #%u) in guild bank, skipped." , ItemGuid , ItemEntry );
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( SlotId >= GUILD_BANK_MAX_SLOTS )
{
sLog . outError ( "Guild::LoadGuildBankFromDB: Invalid slot for item (GUID: %u id: #%u) in guild bank, skipped." , ItemGuid , ItemEntry );
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
ItemPrototype const * proto = objmgr . GetItemPrototype ( ItemEntry );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( ! proto )
2008-10-11 14:16:25 -05:00
{
sLog . outError ( "Guild::LoadGuildBankFromDB: Unknown item (GUID: %u id: #%u) in guild bank, skipped." , ItemGuid , ItemEntry );
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Item * pItem = NewItemOrBag ( proto );
2009-09-11 14:39:38 -07:00
if ( ! pItem -> LoadFromDB ( ItemGuid , 0 , result ))
2008-10-11 14:16:25 -05:00
{
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'" , m_Id , uint32 ( TabId ), uint32 ( SlotId ));
2008-10-11 14:16:25 -05:00
sLog . outError ( "Item GUID %u not found in item_instance, deleting from Guild Bank!" , ItemGuid );
delete pItem ;
continue ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
pItem -> AddToWorld ();
m_TabListMap [ TabId ] -> Slots [ SlotId ] = pItem ;
2009-09-11 14:39:38 -07:00
} while ( result -> NextRow ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// *************************************************
// Money deposit/withdraw related
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SendMoneyInfo ( WorldSession * session , uint32 LowGuid )
{
WorldPacket data ( MSG_GUILD_BANK_MONEY_WITHDRAWN , 4 );
data << uint32 ( GetMemberMoneyWithdrawRem ( LowGuid ));
session -> SendPacket ( & data );
sLog . outDebug ( "WORLD: Sent MSG_GUILD_BANK_MONEY_WITHDRAWN" );
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool Guild :: MemberMoneyWithdraw ( uint32 amount , uint32 LowGuid )
{
uint32 MoneyWithDrawRight = GetMemberMoneyWithdrawRem ( LowGuid );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( MoneyWithDrawRight < amount || GetGuildBankMoney () < amount )
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SetBankMoney ( GetGuildBankMoney () - amount );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( MoneyWithDrawRight < WITHDRAW_MONEY_UNLIMITED )
{
MemberList :: iterator itr = members . find ( LowGuid );
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-10-11 14:16:25 -05:00
return false ;
itr -> second . BankRemMoney -= amount ;
CharacterDatabase . PExecute ( "UPDATE guild_member SET BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'" ,
2009-08-24 19:23:31 -05:00
itr -> second . BankRemMoney , m_Id , LowGuid );
2008-10-11 14:16:25 -05:00
}
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetBankMoney ( int64 money )
{
if ( money < 0 ) // I don't know how this happens, it does!!
money = 0 ;
2009-08-24 19:23:31 -05:00
m_GuildBankMoney = money ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "UPDATE guild SET BankMoney='" UI64FMTD "' WHERE guildid='%u'" , money , m_Id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// *************************************************
// Item per day and money per day related
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool Guild :: MemberItemWithdraw ( uint8 TabId , uint32 LowGuid )
{
uint32 SlotsWithDrawRight = GetMemberSlotWithdrawRem ( LowGuid , TabId );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( SlotsWithDrawRight == 0 )
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( SlotsWithDrawRight < WITHDRAW_SLOT_UNLIMITED )
{
MemberList :: iterator itr = members . find ( LowGuid );
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-10-11 14:16:25 -05:00
return false ;
-- itr -> second . BankRemSlotsTab [ TabId ];
CharacterDatabase . PExecute ( "UPDATE guild_member SET BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'" ,
2009-08-24 19:23:31 -05:00
uint32 ( TabId ), itr -> second . BankRemSlotsTab [ TabId ], m_Id , LowGuid );
2008-10-11 14:16:25 -05:00
}
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool Guild :: IsMemberHaveRights ( uint32 LowGuid , uint8 TabId , uint32 rights ) const
{
MemberList :: const_iterator itr = members . find ( LowGuid );
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-10-11 14:16:25 -05:00
return false ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( itr -> second . RankId == GR_GUILDMASTER )
return true ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
return ( GetBankRights ( itr -> second . RankId , TabId ) & rights ) == rights ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Guild :: GetMemberSlotWithdrawRem ( uint32 LowGuid , uint8 TabId )
{
MemberList :: iterator itr = members . find ( LowGuid );
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-10-11 14:16:25 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( itr -> second . RankId == GR_GUILDMASTER )
return WITHDRAW_SLOT_UNLIMITED ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if (( GetBankRights ( itr -> second . RankId , TabId ) & GUILD_BANK_RIGHT_VIEW_TAB ) != GUILD_BANK_RIGHT_VIEW_TAB )
2008-10-11 14:16:25 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2009-12-24 10:20:15 +01:00
uint32 curTime = uint32 ( time ( NULL ) / MINUTE );
2008-10-11 14:16:25 -05:00
if ( curTime - itr -> second . BankResetTimeTab [ TabId ] >= 24 * HOUR / MINUTE )
{
itr -> second . BankResetTimeTab [ TabId ] = curTime ;
itr -> second . BankRemSlotsTab [ TabId ] = GetBankSlotPerDay ( itr -> second . RankId , TabId );
2010-02-15 14:30:12 +01:00
CharacterDatabase . PExecute ( "UPDATE guild_member SET BankResetTimeTab%u='%u', BankRemSlotsTab%u='%u' WHERE guildid='%u' AND guid='%u'" ,
2009-08-24 19:23:31 -05:00
uint32 ( TabId ), itr -> second . BankResetTimeTab [ TabId ], uint32 ( TabId ), itr -> second . BankRemSlotsTab [ TabId ], m_Id , LowGuid );
2008-10-11 14:16:25 -05:00
}
return itr -> second . BankRemSlotsTab [ TabId ];
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Guild :: GetMemberMoneyWithdrawRem ( uint32 LowGuid )
{
MemberList :: iterator itr = members . find ( LowGuid );
2009-09-11 14:39:38 -07:00
if ( itr == members . end ())
2008-10-11 14:16:25 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( itr -> second . RankId == GR_GUILDMASTER )
return WITHDRAW_MONEY_UNLIMITED ;
2009-10-17 15:51:44 -07:00
2009-12-24 10:20:15 +01:00
uint32 curTime = uint32 ( time ( NULL ) / MINUTE ); // minutes
2008-10-11 14:16:25 -05:00
// 24 hours
if ( curTime > itr -> second . BankResetTimeMoney + 24 * HOUR / MINUTE )
{
itr -> second . BankResetTimeMoney = curTime ;
itr -> second . BankRemMoney = GetBankMoneyPerDay ( itr -> second . RankId );
2010-02-15 14:30:12 +01:00
CharacterDatabase . PExecute ( "UPDATE guild_member SET BankResetTimeMoney='%u', BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'" ,
2009-08-24 19:23:31 -05:00
itr -> second . BankResetTimeMoney , itr -> second . BankRemMoney , m_Id , LowGuid );
2008-10-11 14:16:25 -05:00
}
return itr -> second . BankRemMoney ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetBankMoneyPerDay ( uint32 rankId , uint32 money )
{
2009-08-24 19:23:31 -05:00
if ( rankId >= m_Ranks . size ())
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( rankId == GR_GUILDMASTER )
money = WITHDRAW_MONEY_UNLIMITED ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
m_Ranks [ rankId ]. BankMoneyPerDay = money ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
for ( MemberList :: iterator itr = members . begin (); itr != members . end (); ++ itr )
if ( itr -> second . RankId == rankId )
itr -> second . BankResetTimeMoney = 0 ;
2009-10-17 15:51:44 -07:00
2009-08-28 01:50:29 +02:00
CharacterDatabase . PExecute ( "UPDATE guild_rank SET BankMoneyPerDay='%u' WHERE rid='%u' AND guildid='%u'" , money , rankId , m_Id );
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "UPDATE guild_member SET BankResetTimeMoney='0' WHERE guildid='%u' AND rank='%u'" , m_Id , rankId );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetBankRightsAndSlots ( uint32 rankId , uint8 TabId , uint32 right , uint32 nbSlots , bool db )
{
2009-09-11 14:39:38 -07:00
if ( rankId >= m_Ranks . size () ||
2008-10-11 14:16:25 -05:00
TabId >= GUILD_BANK_MAX_TABS ||
2009-08-24 19:23:31 -05:00
TabId >= m_PurchasedTabs )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( rankId == GR_GUILDMASTER )
{
nbSlots = WITHDRAW_SLOT_UNLIMITED ;
right = GUILD_BANK_RIGHT_FULL ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:23:54 -05:00
m_Ranks [ rankId ]. TabSlotPerDay [ TabId ] = nbSlots ;
m_Ranks [ rankId ]. TabRight [ TabId ] = right ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( db )
{
for ( MemberList :: iterator itr = members . begin (); itr != members . end (); ++ itr )
if ( itr -> second . RankId == rankId )
2009-06-18 18:29:28 +02:00
for ( uint8 i = 0 ; i < GUILD_BANK_MAX_TABS ; ++ i )
2008-10-11 14:16:25 -05:00
itr -> second . BankResetTimeTab [ i ] = 0 ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_right WHERE guildid='%u' AND TabId='%u' AND rid='%u'" , m_Id , uint32 ( TabId ), rankId );
2008-10-11 14:16:25 -05:00
CharacterDatabase . PExecute ( "INSERT INTO guild_bank_right (guildid,TabId,rid,gbright,SlotPerDay) VALUES "
2009-08-24 19:23:31 -05:00
"('%u','%u','%u','%u','%u')" , m_Id , uint32 ( TabId ), rankId , m_Ranks [ rankId ]. TabRight [ TabId ], m_Ranks [ rankId ]. TabSlotPerDay [ TabId ]);
CharacterDatabase . PExecute ( "UPDATE guild_member SET BankResetTimeTab%u='0' WHERE guildid='%u' AND rank='%u'" , uint32 ( TabId ), m_Id , rankId );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Guild :: GetBankMoneyPerDay ( uint32 rankId )
{
2009-09-11 14:39:38 -07:00
if ( rankId >= m_Ranks . size ())
2008-10-11 14:16:25 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( rankId == GR_GUILDMASTER )
return WITHDRAW_MONEY_UNLIMITED ;
2009-08-24 19:23:31 -05:00
return m_Ranks [ rankId ]. BankMoneyPerDay ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 Guild :: GetBankSlotPerDay ( uint32 rankId , uint8 TabId )
{
2009-09-11 14:39:38 -07:00
if ( rankId >= m_Ranks . size () || TabId >= GUILD_BANK_MAX_TABS )
2008-10-11 14:16:25 -05:00
return 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( rankId == GR_GUILDMASTER )
return WITHDRAW_SLOT_UNLIMITED ;
2009-08-24 19:23:31 -05:00
return m_Ranks [ rankId ]. TabSlotPerDay [ TabId ];
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// *************************************************
// Rights per day related
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
bool Guild :: LoadBankRightsFromDB ( QueryResult_AutoPtr guildBankTabRightsResult )
2008-10-11 14:16:25 -05:00
{
2010-02-18 02:42:59 +01:00
if ( ! guildBankTabRightsResult )
return true ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
do
{
2010-02-18 02:42:59 +01:00
Field * fields = guildBankTabRightsResult -> Fetch ();
//prevent crash when all rights in result are already processed
if ( ! fields )
break ;
uint32 guildId = fields [ 0 ]. GetUInt32 ();
if ( guildId < m_Id )
{
//there is in table guild_bank_right record which doesn't have guildid in guild table, report error
sLog . outErrorDb ( "Guild %u does not exist but it has a record in guild_bank_right table, deleting it!" , guildId );
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_right WHERE guildid = '%u'" , guildId );
continue ;
}
if ( guildId > m_Id )
//we loaded all ranks for this guild bank already, break cycle
break ;
uint8 TabId = fields [ 1 ]. GetUInt8 ();
uint32 rankId = fields [ 2 ]. GetUInt32 ();
uint16 right = fields [ 3 ]. GetUInt16 ();
uint16 SlotPerDay = fields [ 4 ]. GetUInt16 ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
SetBankRightsAndSlots ( rankId , TabId , right , SlotPerDay , false );
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
} while ( guildBankTabRightsResult -> NextRow ());
2009-10-17 15:51:44 -07:00
2010-02-18 02:42:59 +01:00
return true ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// *************************************************
// Bank log related
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: LoadGuildBankEventLogFromDB ()
{
2009-08-24 19:23:31 -05:00
// Money log is in TabId = GUILD_BANK_MONEY_LOGS_TAB
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
//uint32 configCount = sWorld.getConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT);
//cycle through all purchased guild bank item tabs
2010-02-15 14:30:12 +01:00
for ( uint32 tabId = 0 ; tabId < m_PurchasedTabs ; ++ tabId )
2009-08-24 19:23:31 -05:00
{
// 0 1 2 3 4 5 6
2010-01-23 14:45:58 +01:00
QueryResult_AutoPtr result = CharacterDatabase . PQuery ( "SELECT LogGuid, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog WHERE guildid='%u' AND TabId='%u' ORDER BY TimeStamp DESC,LogGuid DESC LIMIT %u" , m_Id , tabId , GUILD_BANK_MAX_LOGS );
2009-09-11 14:39:38 -07:00
if ( ! result )
2009-08-24 19:23:31 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
bool isNextLogGuidSet = false ;
do
{
Field * fields = result -> Fetch ();
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
GuildBankEventLogEntry NewEvent ;
NewEvent . EventType = fields [ 1 ]. GetUInt8 ();
NewEvent . PlayerGuid = fields [ 2 ]. GetUInt32 ();
NewEvent . ItemOrMoney = fields [ 3 ]. GetUInt32 ();
NewEvent . ItemStackCount = fields [ 4 ]. GetUInt8 ();
NewEvent . DestTabId = fields [ 5 ]. GetUInt8 ();
NewEvent . TimeStamp = fields [ 6 ]. GetUInt64 ();
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
//if newEvent is moneyEvent, move it to moneyEventTab in DB and report error
if ( NewEvent . isMoneyEvent ())
{
uint32 logGuid = fields [ 0 ]. GetUInt32 ();
CharacterDatabase . PExecute ( "UPDATE guild_bank_eventlog SET TabId='%u' WHERE guildid='%u' AND TabId='%u' AND LogGuid='%u'" , GUILD_BANK_MONEY_LOGS_TAB , m_Id , tabId , logGuid );
sLog . outError ( "GuildBankEventLog ERROR: MoneyEvent LogGuid %u for Guild %u had incorrectly set its TabId to %u, correcting it to %u TabId" , logGuid , m_Id , tabId , GUILD_BANK_MONEY_LOGS_TAB );
continue ;
}
else
//add event to list
//events are ordered from oldest (in beginning) to latest (in the end)
m_GuildBankEventLog_Item [ tabId ]. push_front ( NewEvent );
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
if ( ! isNextLogGuidSet )
{
m_GuildBankEventLogNextGuid_Item [ tabId ] = fields [ 0 ]. GetUInt32 ();
//we don't have to do m_GuildBankEventLogNextGuid_Item[tabId] %= configCount; - it will be done when creating new record
isNextLogGuidSet = true ;
}
2009-09-11 14:39:38 -07:00
} while ( result -> NextRow ());
2009-08-24 19:23:31 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
//special handle for guild bank money log
// 0 1 2 3 4 5 6
2010-01-23 14:45:58 +01:00
QueryResult_AutoPtr result = CharacterDatabase . PQuery ( "SELECT LogGuid, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog WHERE guildid='%u' AND TabId='%u' ORDER BY TimeStamp DESC,LogGuid DESC LIMIT %u" , m_Id , GUILD_BANK_MONEY_LOGS_TAB , GUILD_BANK_MAX_LOGS );
2009-09-11 14:39:38 -07:00
if ( ! result )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
bool isNextMoneyLogGuidSet = false ;
2008-10-11 14:16:25 -05:00
do
{
Field * fields = result -> Fetch ();
2009-08-24 19:23:31 -05:00
if ( ! isNextMoneyLogGuidSet )
2008-10-11 14:16:25 -05:00
{
2009-08-24 19:23:31 -05:00
m_GuildBankEventLogNextGuid_Money = fields [ 0 ]. GetUInt32 ();
//we don't have to do m_GuildBankEventLogNextGuid_Money %= configCount; - it will be done when creating new record
isNextMoneyLogGuidSet = true ;
2008-10-11 14:16:25 -05:00
}
2009-08-24 19:23:31 -05:00
GuildBankEventLogEntry NewEvent ;
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
NewEvent . EventType = fields [ 1 ]. GetUInt8 ();
NewEvent . PlayerGuid = fields [ 2 ]. GetUInt32 ();
NewEvent . ItemOrMoney = fields [ 3 ]. GetUInt32 ();
NewEvent . ItemStackCount = fields [ 4 ]. GetUInt8 ();
NewEvent . DestTabId = fields [ 5 ]. GetUInt8 ();
NewEvent . TimeStamp = fields [ 6 ]. GetUInt64 ();
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
//if newEvent is not moneyEvent, then report error
if ( ! NewEvent . isMoneyEvent ())
sLog . outError ( "GuildBankEventLog ERROR: MoneyEvent LogGuid %u for Guild %u is not MoneyEvent - ignoring..." , fields [ 0 ]. GetUInt32 (), m_Id );
2008-10-11 14:16:25 -05:00
else
2009-08-24 19:23:31 -05:00
//add event to list
//events are ordered from oldest (in beginning) to latest (in the end)
m_GuildBankEventLog_Money . push_front ( NewEvent );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
} while ( result -> NextRow ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: DisplayGuildBankLogs ( WorldSession * session , uint8 TabId )
{
2010-03-15 17:17:19 +01:00
if ( TabId > GUILD_BANK_MAX_TABS ) // tabs starts in 0
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
if ( TabId == GUILD_BANK_MAX_TABS )
{
// Here we display money logs
WorldPacket data ( MSG_GUILD_BANK_LOG_QUERY , m_GuildBankEventLog_Money . size () * ( 4 * 4 + 1 ) + 1 + 1 );
data << uint8 ( TabId ); // Here GUILD_BANK_MAX_TABS
data << uint8 ( m_GuildBankEventLog_Money . size ()); // number of log entries
for ( GuildBankEventLog :: const_iterator itr = m_GuildBankEventLog_Money . begin (); itr != m_GuildBankEventLog_Money . end (); ++ itr )
{
2009-08-24 19:23:31 -05:00
data << uint8 ( itr -> EventType );
2009-08-06 17:45:37 -05:00
data << uint64 ( MAKE_NEW_GUID ( itr -> PlayerGuid , 0 , HIGHGUID_PLAYER ));
2010-03-15 17:17:19 +01:00
data << uint32 ( itr -> ItemOrMoney );
2009-12-24 10:20:15 +01:00
data << uint32 ( time ( NULL ) - itr -> TimeStamp );
2008-10-11 14:16:25 -05:00
}
session -> SendPacket ( & data );
}
else
{
// here we display current tab logs
WorldPacket data ( MSG_GUILD_BANK_LOG_QUERY , m_GuildBankEventLog_Item [ TabId ]. size () * ( 4 * 4 + 1 + 1 ) + 1 + 1 );
data << uint8 ( TabId ); // Here a real Tab Id
2010-03-15 17:17:19 +01:00
data << uint8 ( m_GuildBankEventLog_Item [ TabId ]. size ()); // number of log entries
2008-10-11 14:16:25 -05:00
for ( GuildBankEventLog :: const_iterator itr = m_GuildBankEventLog_Item [ TabId ]. begin (); itr != m_GuildBankEventLog_Item [ TabId ]. end (); ++ itr )
{
2009-08-24 19:23:31 -05:00
data << uint8 ( itr -> EventType );
2009-08-06 17:45:37 -05:00
data << uint64 ( MAKE_NEW_GUID ( itr -> PlayerGuid , 0 , HIGHGUID_PLAYER ));
2010-03-15 17:17:19 +01:00
data << uint32 ( itr -> ItemOrMoney );
data << uint32 ( itr -> ItemStackCount );
if ( itr -> EventType == GUILD_BANK_LOG_MOVE_ITEM || itr -> EventType == GUILD_BANK_LOG_MOVE_ITEM2 )
data << uint8 ( itr -> DestTabId ); // moved tab
2009-12-24 10:20:15 +01:00
data << uint32 ( time ( NULL ) - itr -> TimeStamp );
2008-10-11 14:16:25 -05:00
}
session -> SendPacket ( & data );
}
sLog . outDebug ( "WORLD: Sent (MSG_GUILD_BANK_LOG_QUERY)" );
}
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
void Guild :: LogBankEvent ( uint8 EventType , uint8 TabId , uint32 PlayerGuidLow , uint32 ItemOrMoney , uint8 ItemStackCount , uint8 DestTabId )
2008-10-11 14:16:25 -05:00
{
2009-08-24 19:23:31 -05:00
//create Event
GuildBankEventLogEntry NewEvent ;
NewEvent . EventType = EventType ;
2009-08-06 17:45:37 -05:00
NewEvent . PlayerGuid = PlayerGuidLow ;
NewEvent . ItemOrMoney = ItemOrMoney ;
NewEvent . ItemStackCount = ItemStackCount ;
NewEvent . DestTabId = DestTabId ;
2009-12-24 10:20:15 +01:00
NewEvent . TimeStamp = uint32 ( time ( NULL ));
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
//add new event to the end of event list
uint32 currentTabId = TabId ;
uint32 currentLogGuid = 0 ;
2009-08-06 17:45:37 -05:00
if ( NewEvent . isMoneyEvent ())
2008-10-11 14:16:25 -05:00
{
2009-08-24 19:23:31 -05:00
m_GuildBankEventLogNextGuid_Money = ( m_GuildBankEventLogNextGuid_Money + 1 ) % sWorld . getConfig ( CONFIG_GUILD_BANK_EVENT_LOG_COUNT );
currentLogGuid = m_GuildBankEventLogNextGuid_Money ;
currentTabId = GUILD_BANK_MONEY_LOGS_TAB ;
if ( m_GuildBankEventLog_Money . size () >= GUILD_BANK_MAX_LOGS )
2008-10-11 14:16:25 -05:00
m_GuildBankEventLog_Money . pop_front ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_GuildBankEventLog_Money . push_back ( NewEvent );
}
else
{
2009-08-24 19:23:31 -05:00
m_GuildBankEventLogNextGuid_Item [ TabId ] = (( m_GuildBankEventLogNextGuid_Item [ TabId ]) + 1 ) % sWorld . getConfig ( CONFIG_GUILD_BANK_EVENT_LOG_COUNT );
currentLogGuid = m_GuildBankEventLogNextGuid_Item [ TabId ];
if ( m_GuildBankEventLog_Item [ TabId ]. size () >= GUILD_BANK_MAX_LOGS )
2008-10-11 14:16:25 -05:00
m_GuildBankEventLog_Item [ TabId ]. pop_front ();
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_GuildBankEventLog_Item [ TabId ]. push_back ( NewEvent );
}
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
//save event to database
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u' AND TabId='%u'" , m_Id , currentLogGuid , currentTabId );
2009-10-17 15:51:44 -07:00
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "INSERT INTO guild_bank_eventlog (guildid,LogGuid,TabId,EventType,PlayerGuid,ItemOrMoney,ItemStackCount,DestTabId,TimeStamp) VALUES ('%u','%u','%u','%u','%u','%u','%u','%u','" UI64FMTD "')" ,
m_Id , currentLogGuid , currentTabId , uint32 ( NewEvent . EventType ), NewEvent . PlayerGuid , NewEvent . ItemOrMoney , uint32 ( NewEvent . ItemStackCount ), uint32 ( NewEvent . DestTabId ), NewEvent . TimeStamp );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool Guild :: AddGBankItemToDB ( uint32 GuildId , uint32 BankTab , uint32 BankTabSlot , uint32 GUIDLow , uint32 Entry )
{
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_item WHERE guildid = '%u' AND TabId = '%u'AND SlotId = '%u'" , GuildId , BankTab , BankTabSlot );
CharacterDatabase . PExecute ( "INSERT INTO guild_bank_item (guildid,TabId,SlotId,item_guid,item_entry) "
"VALUES ('%u', '%u', '%u', '%u', '%u')" , GuildId , BankTab , BankTabSlot , GUIDLow , Entry );
return true ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: AppendDisplayGuildBankSlot ( WorldPacket & data , GuildBankTab const * tab , int slot )
{
Item * pItem = tab -> Slots [ slot ];
uint32 entry = pItem ? pItem -> GetEntry () : 0 ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
data << uint8 ( slot );
data << uint32 ( entry );
if ( entry )
{
2010-02-15 14:30:12 +01:00
data << uint32 ( 0 ); // 3.3.0 (0x8000, 0x8020)
data << uint32 ( pItem -> GetItemRandomPropertyId ()); // random item property id + 8
2008-10-11 14:16:25 -05:00
if ( pItem -> GetItemRandomPropertyId ())
2010-02-15 14:30:12 +01:00
data << uint32 ( pItem -> GetItemSuffixFactor ()); // SuffixFactor + 4
2009-10-17 16:20:24 -07:00
2010-02-15 14:30:12 +01:00
data << uint32 ( pItem -> GetCount ()); // +12 ITEM_FIELD_STACK_COUNT
data << uint32 ( 0 ); // +16 Unknown value
2009-08-21 20:07:27 +02:00
data << uint8 ( abs ( pItem -> GetSpellCharges ())); // spell charges
2010-02-15 14:30:12 +01:00
uint8 enchCount = 0 ;
size_t enchCountPos = data . wpos ();
data << uint8 ( enchCount ); // number of enchantments
for ( uint32 i = PERM_ENCHANTMENT_SLOT ; i < MAX_ENCHANTMENT_SLOT ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-02-15 14:30:12 +01:00
if ( uint32 enchId = pItem -> GetEnchantmentId ( EnchantmentSlot ( i )))
{
data << uint8 ( i );
data << uint32 ( enchId );
++ enchCount ;
}
2008-10-11 14:16:25 -05:00
}
2010-02-15 14:30:12 +01:00
data . put < uint8 > ( enchCountPos , enchCount );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Item * Guild :: StoreItem ( uint8 tabId , GuildItemPosCountVec const & dest , Item * pItem )
{
2009-09-11 14:39:38 -07:00
if ( ! pItem )
2008-10-11 14:16:25 -05:00
return NULL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Item * lastItem = pItem ;
2009-10-17 15:51:44 -07:00
2009-11-20 19:11:28 -08:00
for ( GuildItemPosCountVec :: const_iterator itr = dest . begin (); itr != dest . end ();)
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
uint8 slot = itr -> Slot ;
uint32 count = itr -> Count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
++ itr ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( itr == dest . end ())
2008-10-11 14:16:25 -05:00
{
2010-02-15 14:30:12 +01:00
lastItem = _StoreItem ( tabId , slot , pItem , count , false );
2008-10-11 14:16:25 -05:00
break ;
}
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
lastItem = _StoreItem ( tabId , slot , pItem , count , true );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return lastItem ;
}
2009-10-17 15:51:44 -07:00
2009-12-17 11:14:55 +01:00
// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case.
2008-10-11 14:16:25 -05:00
Item * Guild :: _StoreItem ( uint8 tab , uint8 slot , Item * pItem , uint32 count , bool clone )
{
2009-09-11 14:39:38 -07:00
if ( ! pItem )
2008-10-11 14:16:25 -05:00
return NULL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
sLog . outDebug ( "GUILD STORAGE: StoreItem tab = %u, slot = %u, item = %u, count = %u" , tab , slot , pItem -> GetEntry (), count );
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Item * pItem2 = m_TabListMap [ tab ] -> Slots [ slot ];
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( ! pItem2 )
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
if ( clone )
2008-10-11 14:16:25 -05:00
pItem = pItem -> CloneItem ( count );
else
pItem -> SetCount ( count );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( ! pItem )
2008-10-11 14:16:25 -05:00
return NULL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_TabListMap [ tab ] -> Slots [ slot ] = pItem ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
pItem -> SetUInt64Value ( ITEM_FIELD_CONTAINED , 0 );
pItem -> SetUInt64Value ( ITEM_FIELD_OWNER , 0 );
AddGBankItemToDB ( GetId (), tab , slot , pItem -> GetGUIDLow (), pItem -> GetEntry ());
pItem -> FSetState ( ITEM_NEW );
2010-02-15 14:30:12 +01:00
pItem -> SaveToDB (); // not in inventory and can be save standalone
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return pItem ;
}
else
{
2009-12-17 11:14:55 +01:00
pItem2 -> SetCount ( pItem2 -> GetCount () + count );
2008-10-11 14:16:25 -05:00
pItem2 -> FSetState ( ITEM_CHANGED );
2010-02-15 14:30:12 +01:00
pItem2 -> SaveToDB (); // not in inventory and can be save standalone
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( ! clone )
2008-10-11 14:16:25 -05:00
{
pItem -> RemoveFromWorld ();
pItem -> DeleteFromDB ();
delete pItem ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return pItem2 ;
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: RemoveItem ( uint8 tab , uint8 slot )
{
m_TabListMap [ tab ] -> Slots [ slot ] = NULL ;
CharacterDatabase . PExecute ( "DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'" ,
GetId (), uint32 ( tab ), uint32 ( slot ));
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint8 Guild :: _CanStoreItem_InSpecificSlot ( uint8 tab , uint8 slot , GuildItemPosCountVec & dest , uint32 & count , bool swap , Item * pSrcItem ) const
{
Item * pItem2 = m_TabListMap [ tab ] -> Slots [ slot ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// ignore move item (this slot will be empty at move)
2009-09-11 14:39:38 -07:00
if ( pItem2 == pSrcItem )
2008-10-11 14:16:25 -05:00
pItem2 = NULL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint32 need_space ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// empty specific slot - check item fit to slot
2009-09-11 14:39:38 -07:00
if ( ! pItem2 || swap )
2008-10-11 14:16:25 -05:00
{
// non empty stack with space
need_space = pSrcItem -> GetMaxStackCount ();
}
// non empty slot, check item type
else
{
// check item type
2009-09-11 14:39:38 -07:00
if ( pItem2 -> GetEntry () != pSrcItem -> GetEntry ())
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_ITEM_CANT_STACK ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// check free space
2009-09-11 14:39:38 -07:00
if ( pItem2 -> GetCount () >= pSrcItem -> GetMaxStackCount ())
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_ITEM_CANT_STACK ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
need_space = pSrcItem -> GetMaxStackCount () - pItem2 -> GetCount ();
}
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( need_space > count )
2008-10-11 14:16:25 -05:00
need_space = count ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
GuildItemPosCount newPosition = GuildItemPosCount ( slot , need_space );
2009-09-11 14:39:38 -07:00
if ( ! newPosition . isContainedIn ( dest ))
2008-10-11 14:16:25 -05:00
{
dest . push_back ( newPosition );
count -= need_space ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_OK ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint8 Guild :: _CanStoreItem_InTab ( uint8 tab , GuildItemPosCountVec & dest , uint32 & count , bool merge , Item * pSrcItem , uint8 skip_slot ) const
{
2009-11-05 08:42:10 +01:00
assert ( pSrcItem );
2010-02-15 14:30:12 +01:00
for ( uint32 j = 0 ; j < GUILD_BANK_MAX_SLOTS ; ++ j )
2008-10-11 14:16:25 -05:00
{
// skip specific slot already processed in first called _CanStoreItem_InSpecificSlot
2009-09-11 14:39:38 -07:00
if ( j == skip_slot )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
Item * pItem2 = m_TabListMap [ tab ] -> Slots [ j ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// ignore move item (this slot will be empty at move)
2009-09-11 14:39:38 -07:00
if ( pItem2 == pSrcItem )
2008-10-11 14:16:25 -05:00
pItem2 = NULL ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// if merge skip empty, if !merge skip non-empty
2009-09-11 14:39:38 -07:00
if (( pItem2 != NULL ) != merge )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( pItem2 )
2008-10-11 14:16:25 -05:00
{
2009-09-11 14:39:38 -07:00
if ( pItem2 -> GetEntry () == pSrcItem -> GetEntry () && pItem2 -> GetCount () < pSrcItem -> GetMaxStackCount ())
2008-10-11 14:16:25 -05:00
{
uint32 need_space = pSrcItem -> GetMaxStackCount () - pItem2 -> GetCount ();
2009-09-11 14:39:38 -07:00
if ( need_space > count )
2008-10-11 14:16:25 -05:00
need_space = count ;
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
GuildItemPosCount newPosition = GuildItemPosCount ( j , need_space );
2009-09-11 14:39:38 -07:00
if ( ! newPosition . isContainedIn ( dest ))
2008-10-11 14:16:25 -05:00
{
dest . push_back ( newPosition );
count -= need_space ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( count == 0 )
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_OK ;
}
}
}
else
{
uint32 need_space = pSrcItem -> GetMaxStackCount ();
2009-09-11 14:39:38 -07:00
if ( need_space > count )
2008-10-11 14:16:25 -05:00
need_space = count ;
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
GuildItemPosCount newPosition = GuildItemPosCount ( j , need_space );
2009-09-11 14:39:38 -07:00
if ( ! newPosition . isContainedIn ( dest ))
2008-10-11 14:16:25 -05:00
{
dest . push_back ( newPosition );
count -= need_space ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( count == 0 )
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_OK ;
}
}
}
return EQUIP_ERR_OK ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
uint8 Guild :: CanStoreItem ( uint8 tab , uint8 slot , GuildItemPosCountVec & dest , uint32 count , Item * pItem , bool swap ) const
{
sLog . outDebug ( "GUILD STORAGE: CanStoreItem tab = %u, slot = %u, item = %u, count = %u" , tab , slot , pItem -> GetEntry (), count );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( count > pItem -> GetCount ())
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_COULDNT_SPLIT_ITEMS ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( pItem -> IsSoulBound ())
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_CANT_DROP_SOULBOUND ;
2009-10-17 15:51:44 -07:00
2009-12-06 17:46:44 +01:00
// in specific tab
if ( tab >= m_TabListMap . size () || tab >= GUILD_BANK_MAX_TABS )
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG ;
2008-10-11 14:16:25 -05:00
// in specific slot
2009-09-11 14:39:38 -07:00
if ( slot != NULL_SLOT )
2008-10-11 14:16:25 -05:00
{
uint8 res = _CanStoreItem_InSpecificSlot ( tab , slot , dest , count , swap , pItem );
2009-09-11 14:39:38 -07:00
if ( res != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
return res ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( count == 0 )
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_OK ;
}
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
// not specific slot or have space for partly store only in specific slot
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// search stack in tab for merge to
2009-09-11 14:39:38 -07:00
if ( pItem -> GetMaxStackCount () > 1 )
2008-10-11 14:16:25 -05:00
{
2010-02-15 14:30:12 +01:00
uint8 res = _CanStoreItem_InTab ( tab , dest , count , true , pItem , slot );
2009-09-11 14:39:38 -07:00
if ( res != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
return res ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( count == 0 )
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_OK ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
// search free slot in bag for place to
2010-02-15 14:30:12 +01:00
uint8 res = _CanStoreItem_InTab ( tab , dest , count , false , pItem , slot );
2009-09-11 14:39:38 -07:00
if ( res != EQUIP_ERR_OK )
2008-10-11 14:16:25 -05:00
return res ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( count == 0 )
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_OK ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return EQUIP_ERR_BANK_FULL ;
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SetGuildBankTabText ( uint8 TabId , std :: string text )
{
if ( TabId >= GUILD_BANK_MAX_TABS )
return ;
if ( TabId >= m_TabListMap . size ())
return ;
if ( ! m_TabListMap [ TabId ])
return ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( m_TabListMap [ TabId ] -> Text == text )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
utf8truncate ( text , 500 ); // DB and client size limitation
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
m_TabListMap [ TabId ] -> Text = text ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
CharacterDatabase . escape_string ( text );
2009-08-24 19:23:31 -05:00
CharacterDatabase . PExecute ( "UPDATE guild_bank_tab SET TabText='%s' WHERE guildid='%u' AND TabId='%u'" , text . c_str (), m_Id , uint32 ( TabId ));
2009-10-17 15:51:44 -07:00
2009-02-15 11:59:05 -06:00
// announce
SendGuildBankTabText ( NULL , TabId );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
void Guild :: SendGuildBankTabText ( WorldSession * session , uint8 TabId )
{
2009-12-17 11:14:55 +01:00
GuildBankTab const * tab = m_TabListMap [ TabId ];
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
WorldPacket data ( MSG_QUERY_GUILD_BANK_TEXT , 1 + tab -> Text . size () + 1 );
data << uint8 ( TabId );
data << tab -> Text ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( session )
2009-02-15 11:59:05 -06:00
session -> SendPacket ( & data );
else
BroadcastPacket ( & data );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2009-11-20 22:38:01 -08:00
void Guild :: SwapItems ( Player * pl , uint8 BankTab , uint8 BankTabSlot , uint8 BankTabDst , uint8 BankTabSlotDst , uint32 SplitedAmount )
2009-08-24 20:18:16 -05:00
{
// empty operation
2009-09-11 14:39:38 -07:00
if ( BankTab == BankTabDst && BankTabSlot == BankTabSlotDst )
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
Item * pItemSrc = GetItem ( BankTab , BankTabSlot );
if ( ! pItemSrc ) // may prevent crash
return ;
2009-10-17 15:51:44 -07:00
2009-11-20 22:38:01 -08:00
if ( pItemSrc -> GetCount () == 0 )
{
sLog . outCrash ( "Guild::SwapItems: Player %s(GUIDLow: %u) tried to move item %u from tab %u slot %u to tab %u slot %u, but item %u has a stack of zero!" ,
pl -> GetName (), pl -> GetGUIDLow (), pItemSrc -> GetEntry (), BankTab , BankTabSlot , BankTabDst , BankTabSlotDst , pItemSrc -> GetEntry ());
2009-12-17 11:14:55 +01:00
//return; // Commented out for now, uncomment when it's verified that this causes a crash!!
2009-11-20 22:38:01 -08:00
}
if ( SplitedAmount >= pItemSrc -> GetCount ())
2009-08-24 20:18:16 -05:00
SplitedAmount = 0 ; // no split
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
Item * pItemDst = GetItem ( BankTabDst , BankTabSlotDst );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( BankTab != BankTabDst )
2009-08-24 20:18:16 -05:00
{
// check dest pos rights (if different tabs)
2009-09-11 14:39:38 -07:00
if ( ! IsMemberHaveRights ( pl -> GetGUIDLow (), BankTabDst , GUILD_BANK_RIGHT_DEPOSIT_ITEM ))
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
// check source pos rights (if different tabs)
uint32 remRight = GetMemberSlotWithdrawRem ( pl -> GetGUIDLow (), BankTab );
2009-09-11 14:39:38 -07:00
if ( remRight <= 0 )
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
if ( SplitedAmount )
{ // Bank -> Bank item split (in empty or non empty slot
GuildItemPosCountVec dest ;
2010-02-15 14:30:12 +01:00
uint8 msg = CanStoreItem ( BankTabDst , BankTabSlotDst , dest , SplitedAmount , pItemSrc , false );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pItemSrc , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
Item * pNewItem = pItemSrc -> CloneItem ( SplitedAmount );
if ( ! pNewItem )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , pItemSrc , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
CharacterDatabase . BeginTransaction ();
LogBankEvent ( GUILD_BANK_LOG_MOVE_ITEM , BankTab , pl -> GetGUIDLow (), pItemSrc -> GetEntry (), SplitedAmount , BankTabDst );
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
pl -> ItemRemovedQuestCheck ( pItemSrc -> GetEntry (), SplitedAmount );
pItemSrc -> SetCount ( pItemSrc -> GetCount () - SplitedAmount );
2009-08-24 20:18:16 -05:00
pItemSrc -> FSetState ( ITEM_CHANGED );
pItemSrc -> SaveToDB (); // not in inventory and can be save standalone
2010-02-15 14:30:12 +01:00
StoreItem ( BankTabDst , dest , pNewItem );
2009-08-24 20:18:16 -05:00
CharacterDatabase . CommitTransaction ();
}
else // non split
{
GuildItemPosCountVec gDest ;
2010-02-15 14:30:12 +01:00
uint8 msg = CanStoreItem ( BankTabDst , BankTabSlotDst , gDest , pItemSrc -> GetCount (), pItemSrc , false );
2009-09-11 14:39:38 -07:00
if ( msg == EQUIP_ERR_OK ) // merge to
2009-08-24 20:18:16 -05:00
{
CharacterDatabase . BeginTransaction ();
2009-09-11 14:39:38 -07:00
LogBankEvent ( GUILD_BANK_LOG_MOVE_ITEM , BankTab , pl -> GetGUIDLow (), pItemSrc -> GetEntry (), pItemSrc -> GetCount (), BankTabDst );
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
RemoveItem ( BankTab , BankTabSlot );
StoreItem ( BankTabDst , gDest , pItemSrc );
CharacterDatabase . CommitTransaction ();
}
else // swap
{
gDest . clear ();
2010-02-15 14:30:12 +01:00
msg = CanStoreItem ( BankTabDst , BankTabSlotDst , gDest , pItemSrc -> GetCount (), pItemSrc , true );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pItemSrc , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
GuildItemPosCountVec gSrc ;
2010-02-15 14:30:12 +01:00
msg = CanStoreItem ( BankTab , BankTabSlot , gSrc , pItemDst -> GetCount (), pItemDst , true );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pItemDst , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( BankTab != BankTabDst )
2009-08-24 20:18:16 -05:00
{
// check source pos rights (item swapped to src)
2009-09-11 14:39:38 -07:00
if ( ! IsMemberHaveRights ( pl -> GetGUIDLow (), BankTab , GUILD_BANK_RIGHT_DEPOSIT_ITEM ))
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
// check dest pos rights (item swapped to src)
uint32 remRightDst = GetMemberSlotWithdrawRem ( pl -> GetGUIDLow (), BankTabDst );
2009-09-11 14:39:38 -07:00
if ( remRightDst <= 0 )
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
CharacterDatabase . BeginTransaction ();
LogBankEvent ( GUILD_BANK_LOG_MOVE_ITEM , BankTab , pl -> GetGUIDLow (), pItemSrc -> GetEntry (), pItemSrc -> GetCount (), BankTabDst );
LogBankEvent ( GUILD_BANK_LOG_MOVE_ITEM , BankTabDst , pl -> GetGUIDLow (), pItemDst -> GetEntry (), pItemDst -> GetCount (), BankTab );
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
RemoveItem ( BankTab , BankTabSlot );
RemoveItem ( BankTabDst , BankTabSlotDst );
StoreItem ( BankTab , gSrc , pItemDst );
StoreItem ( BankTabDst , gDest , pItemSrc );
CharacterDatabase . CommitTransaction ();
}
}
DisplayGuildBankContentUpdate ( BankTab , BankTabSlot , BankTab == BankTabDst ? BankTabSlotDst : - 1 );
2009-09-11 14:39:38 -07:00
if ( BankTab != BankTabDst )
2009-08-24 20:18:16 -05:00
DisplayGuildBankContentUpdate ( BankTabDst , BankTabSlotDst );
}
void Guild :: MoveFromBankToChar ( Player * pl , uint8 BankTab , uint8 BankTabSlot , uint8 PlayerBag , uint8 PlayerSlot , uint32 SplitedAmount )
{
Item * pItemBank = GetItem ( BankTab , BankTabSlot );
Item * pItemChar = pl -> GetItemByPos ( PlayerBag , PlayerSlot );
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
if ( ! pItemBank ) // Problem to get bank item
return ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( SplitedAmount > pItemBank -> GetCount ())
2009-08-24 20:18:16 -05:00
return ; // cheating?
2009-09-11 14:39:38 -07:00
else if ( SplitedAmount == pItemBank -> GetCount ())
2009-08-24 20:18:16 -05:00
SplitedAmount = 0 ; // no split
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
if ( SplitedAmount )
{ // Bank -> Char split to slot (patly move)
2009-09-11 14:39:38 -07:00
Item * pNewItem = pItemBank -> CloneItem ( SplitedAmount );
if ( ! pNewItem )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , pItemBank , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
ItemPosCountVec dest ;
uint8 msg = pl -> CanStoreItem ( PlayerBag , PlayerSlot , dest , pNewItem , false );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pNewItem , NULL );
2009-08-24 20:18:16 -05:00
delete pNewItem ;
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
// check source pos rights (item moved to inventory)
uint32 remRight = GetMemberSlotWithdrawRem ( pl -> GetGUIDLow (), BankTab );
2009-09-11 14:39:38 -07:00
if ( remRight <= 0 )
2009-08-24 20:18:16 -05:00
{
delete pNewItem ;
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
CharacterDatabase . BeginTransaction ();
LogBankEvent ( GUILD_BANK_LOG_WITHDRAW_ITEM , BankTab , pl -> GetGUIDLow (), pItemBank -> GetEntry (), SplitedAmount );
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
pItemBank -> SetCount ( pItemBank -> GetCount () - SplitedAmount );
pItemBank -> FSetState ( ITEM_CHANGED );
pItemBank -> SaveToDB (); // not in inventory and can be save standalone
2010-02-15 14:30:12 +01:00
pl -> MoveItemToInventory ( dest , pNewItem , true );
2009-08-24 20:18:16 -05:00
pl -> SaveInventoryAndGoldToDB ();
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
MemberItemWithdraw ( BankTab , pl -> GetGUIDLow ());
CharacterDatabase . CommitTransaction ();
}
else // Bank -> Char swap with slot (move)
{
ItemPosCountVec dest ;
uint8 msg = pl -> CanStoreItem ( PlayerBag , PlayerSlot , dest , pItemBank , false );
2009-09-11 14:39:38 -07:00
if ( msg == EQUIP_ERR_OK ) // merge case
2009-08-24 20:18:16 -05:00
{
// check source pos rights (item moved to inventory)
uint32 remRight = GetMemberSlotWithdrawRem ( pl -> GetGUIDLow (), BankTab );
2009-09-11 14:39:38 -07:00
if ( remRight <= 0 )
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
CharacterDatabase . BeginTransaction ();
LogBankEvent ( GUILD_BANK_LOG_WITHDRAW_ITEM , BankTab , pl -> GetGUIDLow (), pItemBank -> GetEntry (), pItemBank -> GetCount ());
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
RemoveItem ( BankTab , BankTabSlot );
2010-02-15 14:30:12 +01:00
pl -> MoveItemToInventory ( dest , pItemBank , true );
2009-08-24 20:18:16 -05:00
pl -> SaveInventoryAndGoldToDB ();
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
MemberItemWithdraw ( BankTab , pl -> GetGUIDLow ());
CharacterDatabase . CommitTransaction ();
}
else // Bank <-> Char swap items
{
// check source pos rights (item swapped to bank)
2009-09-11 14:39:38 -07:00
if ( ! IsMemberHaveRights ( pl -> GetGUIDLow (), BankTab , GUILD_BANK_RIGHT_DEPOSIT_ITEM ))
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( pItemChar )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
if ( ! pItemChar -> CanBeTraded ())
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED , pItemChar , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
ItemPosCountVec iDest ;
msg = pl -> CanStoreItem ( PlayerBag , PlayerSlot , iDest , pItemBank , true );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pItemBank , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
GuildItemPosCountVec gDest ;
2009-09-11 14:39:38 -07:00
if ( pItemChar )
2009-08-24 20:18:16 -05:00
{
2010-02-15 14:30:12 +01:00
msg = CanStoreItem ( BankTab , BankTabSlot , gDest , pItemChar -> GetCount (), pItemChar , true );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pItemChar , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
// check source pos rights (item moved to inventory)
uint32 remRight = GetMemberSlotWithdrawRem ( pl -> GetGUIDLow (), BankTab );
2009-09-11 14:39:38 -07:00
if ( remRight <= 0 )
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( pItemChar )
2009-08-24 20:18:16 -05:00
{
// logging item move to bank
2009-09-11 14:39:38 -07:00
if ( pl -> GetSession () -> GetSecurity () > SEC_PLAYER && sWorld . getConfig ( CONFIG_GM_LOG_TRADE ))
2009-08-24 20:18:16 -05:00
{
2010-02-15 14:30:12 +01:00
sLog . outCommand ( pl -> GetSession () -> GetAccountId (), "GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )" ,
pl -> GetName (), pl -> GetSession () -> GetAccountId (),
pItemChar -> GetProto () -> Name1 , pItemChar -> GetEntry (), pItemChar -> GetCount (),
2009-08-24 20:18:16 -05:00
m_Id );
}
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
CharacterDatabase . BeginTransaction ();
LogBankEvent ( GUILD_BANK_LOG_WITHDRAW_ITEM , BankTab , pl -> GetGUIDLow (), pItemBank -> GetEntry (), pItemBank -> GetCount ());
2009-09-11 14:39:38 -07:00
if ( pItemChar )
2009-08-24 20:18:16 -05:00
LogBankEvent ( GUILD_BANK_LOG_DEPOSIT_ITEM , BankTab , pl -> GetGUIDLow (), pItemChar -> GetEntry (), pItemChar -> GetCount ());
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
RemoveItem ( BankTab , BankTabSlot );
2009-09-11 14:39:38 -07:00
if ( pItemChar )
2009-08-24 20:18:16 -05:00
{
pl -> MoveItemFromInventory ( PlayerBag , PlayerSlot , true );
pItemChar -> DeleteFromInventoryDB ();
}
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( pItemChar )
2009-08-24 20:18:16 -05:00
StoreItem ( BankTab , gDest , pItemChar );
2010-02-15 14:30:12 +01:00
pl -> MoveItemToInventory ( iDest , pItemBank , true );
2009-08-24 20:18:16 -05:00
pl -> SaveInventoryAndGoldToDB ();
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
MemberItemWithdraw ( BankTab , pl -> GetGUIDLow ());
CharacterDatabase . CommitTransaction ();
}
}
DisplayGuildBankContentUpdate ( BankTab , BankTabSlot );
}
void Guild :: MoveFromCharToBank ( Player * pl , uint8 PlayerBag , uint8 PlayerSlot , uint8 BankTab , uint8 BankTabSlot , uint32 SplitedAmount )
{
Item * pItemBank = GetItem ( BankTab , BankTabSlot );
Item * pItemChar = pl -> GetItemByPos ( PlayerBag , PlayerSlot );
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
if ( ! pItemChar ) // Problem to get item from player
return ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( ! pItemChar -> CanBeTraded ())
2009-08-24 20:18:16 -05:00
{
pl -> SendEquipError ( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED , pItemChar , NULL );
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
// check source pos rights (item moved to bank)
2009-09-11 14:39:38 -07:00
if ( ! IsMemberHaveRights ( pl -> GetGUIDLow (), BankTab , GUILD_BANK_RIGHT_DEPOSIT_ITEM ))
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( SplitedAmount > pItemChar -> GetCount ())
2009-08-24 20:18:16 -05:00
return ; // cheating?
2009-09-11 14:39:38 -07:00
else if ( SplitedAmount == pItemChar -> GetCount ())
2009-08-24 20:18:16 -05:00
SplitedAmount = 0 ; // no split
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
if ( SplitedAmount )
{ // Char -> Bank split to empty or non-empty slot (partly move)
GuildItemPosCountVec dest ;
2010-02-15 14:30:12 +01:00
uint8 msg = CanStoreItem ( BankTab , BankTabSlot , dest , SplitedAmount , pItemChar , false );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pItemChar , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
Item * pNewItem = pItemChar -> CloneItem ( SplitedAmount );
2009-09-11 14:39:38 -07:00
if ( ! pNewItem )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , pItemChar , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
// logging item move to bank (before items merge
2009-09-11 14:39:38 -07:00
if ( pl -> GetSession () -> GetSecurity () > SEC_PLAYER && sWorld . getConfig ( CONFIG_GM_LOG_TRADE ))
2009-08-24 20:18:16 -05:00
{
2010-02-15 14:30:12 +01:00
sLog . outCommand ( pl -> GetSession () -> GetAccountId (), "GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )" ,
pl -> GetName (), pl -> GetSession () -> GetAccountId (),
pItemChar -> GetProto () -> Name1 , pItemChar -> GetEntry (), SplitedAmount , m_Id );
2009-08-24 20:18:16 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
CharacterDatabase . BeginTransaction ();
LogBankEvent ( GUILD_BANK_LOG_DEPOSIT_ITEM , BankTab , pl -> GetGUIDLow (), pItemChar -> GetEntry (), SplitedAmount );
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
pl -> ItemRemovedQuestCheck ( pItemChar -> GetEntry (), SplitedAmount );
pItemChar -> SetCount ( pItemChar -> GetCount () - SplitedAmount );
2010-03-16 01:05:56 +01:00
pItemChar -> SetState ( ITEM_CHANGED , pl );
2009-08-24 20:18:16 -05:00
pl -> SaveInventoryAndGoldToDB ();
StoreItem ( BankTab , dest , pNewItem );
CharacterDatabase . CommitTransaction ();
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
DisplayGuildBankContentUpdate ( BankTab , dest );
2009-08-24 20:18:16 -05:00
}
else // Char -> Bank swap with empty or non-empty (move)
{
GuildItemPosCountVec dest ;
2010-02-15 14:30:12 +01:00
uint8 msg = CanStoreItem ( BankTab , BankTabSlot , dest , pItemChar -> GetCount (), pItemChar , false );
2009-09-11 14:39:38 -07:00
if ( msg == EQUIP_ERR_OK ) // merge
2009-08-24 20:18:16 -05:00
{
// logging item move to bank
2009-09-11 14:39:38 -07:00
if ( pl -> GetSession () -> GetSecurity () > SEC_PLAYER && sWorld . getConfig ( CONFIG_GM_LOG_TRADE ))
2009-08-24 20:18:16 -05:00
{
2010-02-15 14:30:12 +01:00
sLog . outCommand ( pl -> GetSession () -> GetAccountId (), "GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )" ,
pl -> GetName (), pl -> GetSession () -> GetAccountId (),
pItemChar -> GetProto () -> Name1 , pItemChar -> GetEntry (), pItemChar -> GetCount (),
2009-08-24 20:18:16 -05:00
m_Id );
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
CharacterDatabase . BeginTransaction ();
LogBankEvent ( GUILD_BANK_LOG_DEPOSIT_ITEM , BankTab , pl -> GetGUIDLow (), pItemChar -> GetEntry (), pItemChar -> GetCount ());
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
pl -> MoveItemFromInventory ( PlayerBag , PlayerSlot , true );
pItemChar -> DeleteFromInventoryDB ();
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
StoreItem ( BankTab , dest , pItemChar );
2009-08-24 20:18:16 -05:00
pl -> SaveInventoryAndGoldToDB ();
CharacterDatabase . CommitTransaction ();
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
DisplayGuildBankContentUpdate ( BankTab , dest );
2009-08-24 20:18:16 -05:00
}
else // Char <-> Bank swap items (posible NULL bank item)
{
ItemPosCountVec iDest ;
2009-09-11 14:39:38 -07:00
if ( pItemBank )
2009-08-24 20:18:16 -05:00
{
msg = pl -> CanStoreItem ( PlayerBag , PlayerSlot , iDest , pItemBank , true );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pItemBank , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
GuildItemPosCountVec gDest ;
2010-02-15 14:30:12 +01:00
msg = CanStoreItem ( BankTab , BankTabSlot , gDest , pItemChar -> GetCount (), pItemChar , true );
2009-09-11 14:39:38 -07:00
if ( msg != EQUIP_ERR_OK )
2009-08-24 20:18:16 -05:00
{
2009-09-11 14:39:38 -07:00
pl -> SendEquipError ( msg , pItemChar , NULL );
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-09-11 14:39:38 -07:00
if ( pItemBank )
2009-08-24 20:18:16 -05:00
{
// check bank pos rights (item swapped with inventory)
uint32 remRight = GetMemberSlotWithdrawRem ( pl -> GetGUIDLow (), BankTab );
2009-09-11 14:39:38 -07:00
if ( remRight <= 0 )
2009-08-24 20:18:16 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
// logging item move to bank
2009-09-11 14:39:38 -07:00
if ( pl -> GetSession () -> GetSecurity () > SEC_PLAYER && sWorld . getConfig ( CONFIG_GM_LOG_TRADE ))
2009-08-24 20:18:16 -05:00
{
2010-02-15 14:30:12 +01:00
sLog . outCommand ( pl -> GetSession () -> GetAccountId (), "GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u )" ,
pl -> GetName (), pl -> GetSession () -> GetAccountId (),
pItemChar -> GetProto () -> Name1 , pItemChar -> GetEntry (), pItemChar -> GetCount (),
2009-08-24 20:18:16 -05:00
m_Id );
}
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
CharacterDatabase . BeginTransaction ();
2009-09-11 14:39:38 -07:00
if ( pItemBank )
2009-08-24 20:18:16 -05:00
LogBankEvent ( GUILD_BANK_LOG_WITHDRAW_ITEM , BankTab , pl -> GetGUIDLow (), pItemBank -> GetEntry (), pItemBank -> GetCount ());
LogBankEvent ( GUILD_BANK_LOG_DEPOSIT_ITEM , BankTab , pl -> GetGUIDLow (), pItemChar -> GetEntry (), pItemChar -> GetCount ());
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
pl -> MoveItemFromInventory ( PlayerBag , PlayerSlot , true );
pItemChar -> DeleteFromInventoryDB ();
2009-09-11 14:39:38 -07:00
if ( pItemBank )
2009-08-24 20:18:16 -05:00
RemoveItem ( BankTab , BankTabSlot );
2009-10-17 15:51:44 -07:00
2009-08-24 20:18:16 -05:00
StoreItem ( BankTab , gDest , pItemChar );
2009-09-11 14:39:38 -07:00
if ( pItemBank )
2010-02-15 14:30:12 +01:00
pl -> MoveItemToInventory ( iDest , pItemBank , true );
2009-08-24 20:18:16 -05:00
pl -> SaveInventoryAndGoldToDB ();
2009-09-11 14:39:38 -07:00
if ( pItemBank )
2009-08-24 20:18:16 -05:00
MemberItemWithdraw ( BankTab , pl -> GetGUIDLow ());
CharacterDatabase . CommitTransaction ();
2009-10-17 15:51:44 -07:00
2010-02-15 14:30:12 +01:00
DisplayGuildBankContentUpdate ( BankTab , gDest );
2009-08-24 20:18:16 -05:00
}
}
}
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
bool GuildItemPosCount :: isContainedIn ( GuildItemPosCountVec const & vec ) const
{
2009-09-11 14:39:38 -07:00
for ( GuildItemPosCountVec :: const_iterator itr = vec . begin (); itr != vec . end (); ++ itr )
if ( itr -> Slot == this -> Slot )
2008-10-11 14:16:25 -05:00
return true ;
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
return false ;
}