2010-10-07 15:35:36 +02:00
/*
2012-12-31 23:15:50 +01:00
* Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by 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 MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2008-10-11 14:16:25 -05:00
*/
2009-10-17 15:51:44 -07:00
2012-11-20 12:30:30 +01:00
#include "AccountMgr.h"
#include "CalendarMgr.h"
#include "Chat.h"
#include "Config.h"
2010-06-08 16:13:55 -06:00
#include "DatabaseEnv.h"
2008-10-11 14:16:25 -05:00
#include "Guild.h"
2012-09-09 11:32:14 +02:00
#include "GuildFinderMgr.h"
2011-05-04 10:08:09 +02:00
#include "GuildMgr.h"
2012-11-20 12:30:30 +01:00
#include "Language.h"
#include "Log.h"
2010-10-17 19:54:13 +06:00
#include "ScriptMgr.h"
#include "SocialMgr.h"
2012-11-20 14:54:33 +01:00
#include "Opcodes.h"
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
#define MAX_GUILD_BANK_TAB_TEXT_LEN 500
#define EMBLEM_PRICE 10 * GOLD
2010-03-19 17:24:23 +01:00
2012-11-08 11:13:46 +01:00
std :: string _GetGuildEventString ( GuildEvents event )
{
switch ( event )
{
case GE_PROMOTION :
return "Member promotion" ;
case GE_DEMOTION :
return "Member demotion" ;
case GE_MOTD :
return "Guild MOTD" ;
case GE_JOINED :
return "Member joined" ;
case GE_LEFT :
return "Member left" ;
case GE_REMOVED :
return "Member removed" ;
case GE_LEADER_IS :
return "Leader is" ;
case GE_LEADER_CHANGED :
return "Leader changed" ;
case GE_DISBANDED :
return "Guild disbanded" ;
case GE_TABARDCHANGE :
return "Tabard change" ;
case GE_RANK_UPDATED :
return "Rank updated" ;
case GE_RANK_DELETED :
return "Rank deleted" ;
case GE_SIGNED_ON :
return "Member signed on" ;
case GE_SIGNED_OFF :
return "Member signed off" ;
case GE_GUILDBANKBAGSLOTS_CHANGED :
return "Bank bag slots changed" ;
case GE_BANK_TAB_PURCHASED :
return "Bank tab purchased" ;
case GE_BANK_TAB_UPDATED :
return "Bank tab updated" ;
case GE_BANK_MONEY_SET :
return "Bank money set" ;
case GE_BANK_MONEY_CHANGED :
return "Bank money changed" ;
case GE_BANK_TEXT_CHANGED :
return "Bank tab text changed" ;
default :
break ;
}
return "<None>" ;
}
2010-10-17 19:54:13 +06:00
inline uint32 _GetGuildBankTabPrice ( uint8 tabId )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
switch ( tabId )
{
case 0 : return 100 ;
case 1 : return 250 ;
case 2 : return 500 ;
case 3 : return 1000 ;
case 4 : return 2500 ;
case 5 : return 5000 ;
default : return 0 ;
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: SendCommandResult ( WorldSession * session , GuildCommandType type , GuildCommandError errCode , std :: string const & param )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
WorldPacket data ( SMSG_GUILD_COMMAND_RESULT , 8 + param . size () + 1 );
data << uint32 ( type );
data << param ;
data << uint32 ( errCode );
session -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_COMMAND_RESULT [%s]: Type: %u, code: %u, param: %s"
, session -> GetPlayerInfo (). c_str (), type , errCode , param . c_str ());
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: SendSaveEmblemResult ( WorldSession * session , GuildEmblemError errCode )
{
WorldPacket data ( MSG_SAVE_GUILD_EMBLEM , 4 );
data << uint32 ( errCode );
session -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "MSG_SAVE_GUILD_EMBLEM [%s] Code: %u" , session -> GetPlayerInfo (). c_str (), errCode );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// LogHolder
Guild :: LogHolder ::~ LogHolder ()
2009-08-24 20:23:54 -05:00
{
2010-10-17 19:54:13 +06:00
// Cleanup
for ( GuildLog :: iterator itr = m_log . begin (); itr != m_log . end (); ++ itr )
delete ( * itr );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Adds event loaded from database to collection
inline void Guild :: LogHolder :: LoadEvent ( LogEntry * entry )
{
2010-12-13 16:58:59 +01:00
if ( m_nextGUID == uint32 ( GUILD_EVENT_LOG_GUID_UNDEFINED ))
2010-10-17 19:54:13 +06:00
m_nextGUID = entry -> GetGUID ();
m_log . push_front ( entry );
2009-08-24 20:23:54 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Adds new event happened in game.
// If maximum number of events is reached, oldest event is removed from collection.
inline void Guild :: LogHolder :: AddEvent ( SQLTransaction & trans , LogEntry * entry )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// Check max records limit
if ( m_log . size () >= m_maxRecords )
2008-11-05 20:10:19 -06:00
{
2010-10-17 19:54:13 +06:00
LogEntry * oldEntry = m_log . front ();
delete oldEntry ;
m_log . pop_front ();
2008-11-05 20:10:19 -06:00
}
2010-10-17 19:54:13 +06:00
// Add event to list
m_log . push_back ( entry );
// Save to DB
entry -> SaveToDB ( trans );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Writes information about all events into packet.
inline void Guild :: LogHolder :: WritePacket ( WorldPacket & data ) const
{
2012-08-27 20:20:17 +02:00
ByteBuffer buffer ;
data . WriteBits ( m_log . size (), 23 );
2010-10-17 19:54:13 +06:00
for ( GuildLog :: const_iterator itr = m_log . begin (); itr != m_log . end (); ++ itr )
2012-08-27 20:20:17 +02:00
( * itr ) -> WritePacket ( data , buffer );
data . FlushBits ();
data . append ( buffer );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
inline uint32 Guild :: LogHolder :: GetNextGUID ()
{
// Next guid was not initialized. It means there are no records for this holder in DB yet.
// Start from the beginning.
2010-12-13 16:58:59 +01:00
if ( m_nextGUID == uint32 ( GUILD_EVENT_LOG_GUID_UNDEFINED ))
2010-10-17 19:54:13 +06:00
m_nextGUID = 0 ;
2009-08-24 20:23:54 -05:00
else
2010-10-17 19:54:13 +06:00
m_nextGUID = ( m_nextGUID + 1 ) % m_maxRecords ;
return m_nextGUID ;
}
// EventLogEntry
void Guild :: EventLogEntry :: SaveToDB ( SQLTransaction & trans ) const
{
2012-09-18 11:33:09 +02:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_EVENTLOG );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt32 ( 1 , m_guid );
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
uint8 index = 0 ;
2012-01-01 01:09:38 +01:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_EVENTLOG );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( index , m_guildId );
stmt -> setUInt32 ( ++ index , m_guid );
stmt -> setUInt8 ( ++ index , uint8 ( m_eventType ));
stmt -> setUInt32 ( ++ index , m_playerGuid1 );
stmt -> setUInt32 ( ++ index , m_playerGuid2 );
stmt -> setUInt8 ( ++ index , m_newRank );
stmt -> setUInt64 ( ++ index , m_timestamp );
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
}
2012-08-27 20:20:17 +02:00
void Guild :: EventLogEntry :: WritePacket ( WorldPacket & data , ByteBuffer & content ) const
2010-10-17 19:54:13 +06:00
{
2012-08-27 20:20:17 +02:00
ObjectGuid guid1 = MAKE_NEW_GUID ( m_playerGuid1 , 0 , HIGHGUID_PLAYER );
ObjectGuid guid2 = MAKE_NEW_GUID ( m_playerGuid2 , 0 , HIGHGUID_PLAYER );
data . WriteBit ( guid1 [ 2 ]);
data . WriteBit ( guid1 [ 4 ]);
data . WriteBit ( guid2 [ 7 ]);
data . WriteBit ( guid2 [ 6 ]);
data . WriteBit ( guid1 [ 3 ]);
data . WriteBit ( guid2 [ 3 ]);
data . WriteBit ( guid2 [ 5 ]);
data . WriteBit ( guid1 [ 7 ]);
data . WriteBit ( guid1 [ 5 ]);
data . WriteBit ( guid1 [ 0 ]);
data . WriteBit ( guid2 [ 4 ]);
data . WriteBit ( guid2 [ 2 ]);
data . WriteBit ( guid2 [ 0 ]);
data . WriteBit ( guid2 [ 1 ]);
data . WriteBit ( guid1 [ 1 ]);
data . WriteBit ( guid1 [ 6 ]);
content . WriteByteSeq ( guid2 [ 3 ]);
content . WriteByteSeq ( guid2 [ 2 ]);
content . WriteByteSeq ( guid2 [ 5 ]);
// New Rank
content << uint8 ( m_newRank );
content . WriteByteSeq ( guid2 [ 4 ]);
content . WriteByteSeq ( guid1 [ 0 ]);
content . WriteByteSeq ( guid1 [ 4 ]);
2010-10-17 19:54:13 +06:00
// Event timestamp
2012-08-27 20:20:17 +02:00
content << uint32 ( :: time ( NULL ) - m_timestamp );
content . WriteByteSeq ( guid1 [ 7 ]);
content . WriteByteSeq ( guid1 [ 3 ]);
content . WriteByteSeq ( guid2 [ 0 ]);
content . WriteByteSeq ( guid2 [ 6 ]);
content . WriteByteSeq ( guid2 [ 7 ]);
content . WriteByteSeq ( guid1 [ 5 ]);
// Event type
content << uint8 ( m_eventType );
content . WriteByteSeq ( guid2 [ 1 ]);
content . WriteByteSeq ( guid1 [ 2 ]);
content . WriteByteSeq ( guid1 [ 6 ]);
content . WriteByteSeq ( guid1 [ 1 ]);
2010-10-17 19:54:13 +06:00
}
// BankEventLogEntry
void Guild :: BankEventLogEntry :: SaveToDB ( SQLTransaction & trans ) const
{
uint8 index = 0 ;
2012-09-18 11:33:09 +02:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_EVENTLOG );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( index , m_guildId );
stmt -> setUInt32 ( ++ index , m_guid );
stmt -> setUInt8 ( ++ index , m_bankTabId );
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
index = 0 ;
2012-01-01 01:09:38 +01:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_BANK_EVENTLOG );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( index , m_guildId );
stmt -> setUInt32 ( ++ index , m_guid );
stmt -> setUInt8 ( ++ index , m_bankTabId );
stmt -> setUInt8 ( ++ index , uint8 ( m_eventType ));
stmt -> setUInt32 ( ++ index , m_playerGuid );
stmt -> setUInt32 ( ++ index , m_itemOrMoney );
stmt -> setUInt16 ( ++ index , m_itemStackCount );
stmt -> setUInt8 ( ++ index , m_destTabId );
stmt -> setUInt64 ( ++ index , m_timestamp );
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
}
2012-08-27 20:20:17 +02:00
void Guild :: BankEventLogEntry :: WritePacket ( WorldPacket & data , ByteBuffer & content ) const
2010-10-17 19:54:13 +06:00
{
2012-08-27 20:20:17 +02:00
ObjectGuid logGuid = MAKE_NEW_GUID ( m_playerGuid , 0 , HIGHGUID_PLAYER );
bool hasItem = m_eventType == GUILD_BANK_LOG_DEPOSIT_ITEM || m_eventType == GUILD_BANK_LOG_WITHDRAW_ITEM ||
m_eventType == GUILD_BANK_LOG_MOVE_ITEM || m_eventType == GUILD_BANK_LOG_MOVE_ITEM2 ;
bool itemMoved = ( m_eventType == GUILD_BANK_LOG_MOVE_ITEM || m_eventType == GUILD_BANK_LOG_MOVE_ITEM2 );
bool hasStack = ( hasItem && m_itemStackCount > 1 ) || itemMoved ;
data . WriteBit ( IsMoneyEvent ());
data . WriteBit ( logGuid [ 4 ]);
data . WriteBit ( logGuid [ 1 ]);
data . WriteBit ( hasItem );
data . WriteBit ( hasStack );
data . WriteBit ( logGuid [ 2 ]);
data . WriteBit ( logGuid [ 5 ]);
data . WriteBit ( logGuid [ 3 ]);
data . WriteBit ( logGuid [ 6 ]);
data . WriteBit ( logGuid [ 0 ]);
data . WriteBit ( itemMoved );
data . WriteBit ( logGuid [ 7 ]);
content . WriteByteSeq ( logGuid [ 6 ]);
content . WriteByteSeq ( logGuid [ 1 ]);
content . WriteByteSeq ( logGuid [ 5 ]);
if ( hasStack )
content << uint32 ( m_itemStackCount );
2011-01-10 20:57:58 +01:00
2012-08-27 20:20:17 +02:00
content << uint8 ( m_eventType );
content . WriteByteSeq ( logGuid [ 2 ]);
content . WriteByteSeq ( logGuid [ 4 ]);
content . WriteByteSeq ( logGuid [ 0 ]);
content . WriteByteSeq ( logGuid [ 7 ]);
content . WriteByteSeq ( logGuid [ 3 ]);
if ( hasItem )
content << uint32 ( m_itemOrMoney );
content << uint32 ( time ( NULL ) - m_timestamp );
if ( IsMoneyEvent ())
content << uint64 ( m_itemOrMoney );
if ( itemMoved )
content << uint8 ( m_destTabId );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
void Guild :: NewsLogEntry :: SaveToDB ( SQLTransaction & trans ) const
{
uint8 index = 0 ;
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_NEWS );
stmt -> setUInt32 ( index , m_guildId );
stmt -> setUInt32 ( ++ index , GetGUID ());
stmt -> setUInt8 ( ++ index , GetType ());
stmt -> setUInt32 ( ++ index , GetPlayerGuid ());
stmt -> setUInt32 ( ++ index , GetFlags ());
stmt -> setUInt32 ( ++ index , GetValue ());
stmt -> setUInt64 ( ++ index , GetTimestamp ());
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
}
void Guild :: NewsLogEntry :: WritePacket ( WorldPacket & data , ByteBuffer & /*content*/ ) const
{
data . WriteBits ( 0 , 26 ); // Not yet implemented used for guild achievements
ObjectGuid guid = GetPlayerGuid ();
data . WriteBit ( guid [ 7 ]);
data . WriteBit ( guid [ 0 ]);
data . WriteBit ( guid [ 6 ]);
data . WriteBit ( guid [ 5 ]);
data . WriteBit ( guid [ 4 ]);
data . WriteBit ( guid [ 3 ]);
data . WriteBit ( guid [ 1 ]);
data . WriteBit ( guid [ 2 ]);
data . FlushBits ();
data . WriteByteSeq ( guid [ 5 ]);
data << uint32 ( GetFlags ()); // 1 sticky
data << uint32 ( GetValue ());
data << uint32 ( 0 ); // always 0
data . WriteByteSeq ( guid [ 7 ]);
data . WriteByteSeq ( guid [ 6 ]);
data . WriteByteSeq ( guid [ 2 ]);
data . WriteByteSeq ( guid [ 3 ]);
data . WriteByteSeq ( guid [ 0 ]);
data . WriteByteSeq ( guid [ 4 ]);
data . WriteByteSeq ( guid [ 1 ]);
data << uint32 ( GetGUID ());
data << uint32 ( GetType ());
data . AppendPackedTime ( GetTimestamp ());
}
2010-10-17 19:54:13 +06:00
// RankInfo
2011-03-10 22:21:50 +01:00
void Guild :: RankInfo :: LoadFromDB ( Field * fields )
2010-10-17 19:54:13 +06:00
{
m_rankId = fields [ 1 ]. GetUInt8 ();
m_name = fields [ 2 ]. GetString ();
m_rights = fields [ 3 ]. GetUInt32 ();
m_bankMoneyPerDay = fields [ 4 ]. GetUInt32 ();
if ( m_rankId == GR_GUILDMASTER ) // Prevent loss of leader rights
m_rights |= GR_RIGHT_ALL ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: RankInfo :: SaveToDB ( SQLTransaction & trans ) const
{
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_RANK );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt8 ( 1 , m_rankId );
stmt -> setString ( 2 , m_name );
stmt -> setUInt32 ( 3 , m_rights );
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-07 09:46:42 +01:00
void Guild :: RankInfo :: CreateMissingTabsIfNeeded ( uint8 tabs , SQLTransaction & trans , bool logOnCreate /* = false */ )
2012-11-02 22:23:14 +01:00
{
2012-11-07 09:46:42 +01:00
for ( uint8 i = 0 ; i < tabs ; ++ i )
2012-11-02 22:23:14 +01:00
{
GuildBankRightsAndSlots & rightsAndSlots = m_bankTabRightsAndSlots [ i ];
if ( rightsAndSlots . GetTabId () == i )
continue ;
rightsAndSlots . SetTabId ( i );
if ( m_rankId == GR_GUILDMASTER )
rightsAndSlots . SetGuildMasterValues ();
2012-11-07 09:46:42 +01:00
if ( logOnCreate )
sLog -> outError ( LOG_FILTER_GUILD , "Guild %u has broken Tab %u for rank %u. Created default tab." , m_guildId , i , m_rankId );
2012-11-02 22:23:14 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_BANK_RIGHT );
stmt -> setUInt32 ( 0 , m_guildId );
2012-11-09 08:22:03 +01:00
stmt -> setUInt8 ( 1 , i );
stmt -> setUInt8 ( 2 , m_rankId );
stmt -> setUInt8 ( 3 , rightsAndSlots . GetRights ());
2012-11-02 22:23:14 +01:00
stmt -> setUInt32 ( 4 , rightsAndSlots . GetSlots ());
trans -> Append ( stmt );
}
}
void Guild :: RankInfo :: SetName ( std :: string const & name )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_name == name )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_name = name ;
2010-08-14 12:17:05 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_RANK_NAME );
2010-10-17 19:54:13 +06:00
stmt -> setString ( 0 , m_name );
stmt -> setUInt8 ( 1 , m_rankId );
stmt -> setUInt32 ( 2 , m_guildId );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: RankInfo :: SetRights ( uint32 rights )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_rankId == GR_GUILDMASTER ) // Prevent loss of leader rights
rights = GR_RIGHT_ALL ;
if ( m_rights == rights )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_rights = rights ;
2010-08-14 12:17:05 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_RANK_RIGHTS );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_rights );
stmt -> setUInt8 ( 1 , m_rankId );
stmt -> setUInt32 ( 2 , m_guildId );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: RankInfo :: SetBankMoneyPerDay ( uint32 money )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_rankId == GR_GUILDMASTER ) // Prevent loss of leader rights
2011-03-08 16:42:00 +01:00
money = uint32 ( GUILD_WITHDRAW_MONEY_UNLIMITED );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( m_bankMoneyPerDay == money )
return ;
2010-08-13 17:39:43 +06:00
2010-10-17 19:54:13 +06:00
m_bankMoneyPerDay = money ;
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_RANK_BANK_MONEY );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , money );
stmt -> setUInt8 ( 1 , m_rankId );
stmt -> setUInt32 ( 2 , m_guildId );
CharacterDatabase . Execute ( stmt );
2010-02-18 02:42:59 +01:00
}
2012-11-02 22:23:14 +01:00
void Guild :: RankInfo :: SetBankTabSlotsAndRights ( GuildBankRightsAndSlots rightsAndSlots , bool saveToDB )
2010-04-07 18:09:10 +02:00
{
2010-10-17 19:54:13 +06:00
if ( m_rankId == GR_GUILDMASTER ) // Prevent loss of leader rights
rightsAndSlots . SetGuildMasterValues ();
2012-11-02 22:23:14 +01:00
GuildBankRightsAndSlots & guildBR = m_bankTabRightsAndSlots [ rightsAndSlots . GetTabId ()];
2012-09-18 11:33:09 +02:00
guildBR = rightsAndSlots ;
2010-10-17 19:54:13 +06:00
if ( saveToDB )
2008-10-11 14:16:25 -05:00
{
2012-11-02 22:23:14 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_BANK_RIGHT );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
2012-11-02 22:23:14 +01:00
stmt -> setUInt8 ( 1 , guildBR . GetTabId ());
2010-10-17 19:54:13 +06:00
stmt -> setUInt8 ( 2 , m_rankId );
2012-11-02 22:23:14 +01:00
stmt -> setUInt8 ( 3 , guildBR . GetRights ());
stmt -> setUInt32 ( 4 , guildBR . GetSlots ());
2010-10-17 19:54:13 +06:00
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// BankTab
2012-11-02 22:23:14 +01:00
void Guild :: BankTab :: LoadFromDB ( Field * fields )
2010-10-17 19:54:13 +06:00
{
m_name = fields [ 2 ]. GetString ();
m_icon = fields [ 3 ]. GetString ();
m_text = fields [ 4 ]. GetString ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
bool Guild :: BankTab :: LoadItemFromDB ( Field * fields )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
uint8 slotId = fields [ 13 ]. GetUInt8 ();
uint32 itemGuid = fields [ 14 ]. GetUInt32 ();
uint32 itemEntry = fields [ 15 ]. GetUInt32 ();
if ( slotId >= GUILD_BANK_MAX_SLOTS )
2009-09-02 18:40:27 -05:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Invalid slot for item (GUID: %u, id: %u) in guild bank, skipped." , itemGuid , itemEntry );
2010-10-17 19:54:13 +06:00
return false ;
2009-09-02 18:40:27 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-28 22:42:33 +02:00
ItemTemplate const * proto = sObjectMgr -> GetItemTemplate ( itemEntry );
2010-10-17 19:54:13 +06:00
if ( ! proto )
2008-10-11 14:16:25 -05:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Unknown item (GUID: %u, id: %u) in guild bank, skipped." , itemGuid , itemEntry );
2010-10-17 19:54:13 +06:00
return false ;
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * pItem = NewItemOrBag ( proto );
2010-10-17 19:54:13 +06:00
if ( ! pItem -> LoadFromDB ( itemGuid , 0 , fields , itemEntry ))
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Item (GUID %u, id: %u) not found in item_instance, deleting from guild bank!" , itemGuid , itemEntry );
2009-10-17 15:51:44 -07:00
2012-09-18 11:33:09 +02:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt8 ( 1 , m_tabId );
stmt -> setUInt8 ( 2 , slotId );
CharacterDatabase . Execute ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
delete pItem ;
return false ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
pItem -> AddToWorld ();
m_items [ slotId ] = pItem ;
2008-10-11 14:16:25 -05:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Deletes contents of the tab from the world (and from DB if necessary)
void Guild :: BankTab :: Delete ( SQLTransaction & trans , bool removeItemsFromDB )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
for ( uint8 slotId = 0 ; slotId < GUILD_BANK_MAX_SLOTS ; ++ slotId )
if ( Item * pItem = m_items [ slotId ])
2010-02-18 02:42:59 +01:00
{
2010-10-17 19:54:13 +06:00
pItem -> RemoveFromWorld ();
if ( removeItemsFromDB )
pItem -> DeleteFromDB ( trans );
delete pItem ;
pItem = NULL ;
2010-02-18 02:42:59 +01:00
}
2010-10-17 19:54:13 +06:00
}
2010-02-18 02:42:59 +01:00
2012-11-02 22:23:14 +01:00
void Guild :: BankTab :: SetInfo ( std :: string const & name , std :: string const & icon )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_name == name && m_icon == icon )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_name = name ;
m_icon = icon ;
2009-10-17 15:51:44 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_BANK_TAB_INFO );
2010-10-17 19:54:13 +06:00
stmt -> setString ( 0 , m_name );
stmt -> setString ( 1 , m_icon );
stmt -> setUInt32 ( 2 , m_guildId );
stmt -> setUInt8 ( 3 , m_tabId );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: BankTab :: SetText ( std :: string const & text )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_text == text )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_text = text ;
utf8truncate ( m_text , MAX_GUILD_BANK_TAB_TEXT_LEN ); // DB and client size limitation
2009-10-17 15:51:44 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_BANK_TAB_TEXT );
2010-10-17 19:54:13 +06:00
stmt -> setString ( 0 , m_text );
stmt -> setUInt32 ( 1 , m_guildId );
stmt -> setUInt8 ( 2 , m_tabId );
CharacterDatabase . Execute ( stmt );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Sets/removes contents of specified slot.
// If pItem == NULL contents are removed.
2012-08-27 20:20:17 +02:00
bool Guild :: BankTab :: SetItem ( SQLTransaction & trans , uint8 slotId , Item * item )
2010-10-17 19:54:13 +06:00
{
if ( slotId >= GUILD_BANK_MAX_SLOTS )
return false ;
2009-10-17 15:51:44 -07:00
2012-08-27 20:20:17 +02:00
m_items [ slotId ] = item ;
2009-10-17 15:51:44 -07:00
2012-09-18 11:33:09 +02:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_ITEM );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt8 ( 1 , m_tabId );
stmt -> setUInt8 ( 2 , slotId );
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2009-10-17 15:51:44 -07:00
2012-08-27 20:20:17 +02:00
if ( item )
2008-10-11 14:16:25 -05:00
{
2012-01-01 01:09:38 +01:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_BANK_ITEM );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt8 ( 1 , m_tabId );
stmt -> setUInt8 ( 2 , slotId );
2012-08-27 20:20:17 +02:00
stmt -> setUInt32 ( 3 , item -> GetGUIDLow ());
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
2012-08-27 20:20:17 +02:00
item -> SetUInt64Value ( ITEM_FIELD_CONTAINED , 0 );
item -> SetUInt64Value ( ITEM_FIELD_OWNER , 0 );
item -> FSetState ( ITEM_NEW );
item -> SaveToDB ( trans ); // Not in inventory and can be saved standalone
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
return true ;
}
2009-10-17 15:51:44 -07:00
2012-08-27 20:20:17 +02:00
void Guild :: BankTab :: SendText ( Guild const * guild , WorldSession * session ) const
2010-10-17 19:54:13 +06:00
{
2012-08-27 20:20:17 +02:00
WorldPacket data ( SMSG_GUILD_BANK_QUERY_TEXT_RESULT , 1 + m_text . size () + 1 );
data . WriteBits ( m_text . length (), 14 );
data << uint32 ( m_tabId );
data . WriteString ( m_text );
2010-07-28 17:19:39 -06:00
2010-10-17 19:54:13 +06:00
if ( session )
2012-11-02 22:23:14 +01:00
{
2012-11-07 23:21:19 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_BANK_QUERY_TEXT_RESULT [%s]: Tabid: %u, Text: %s"
2012-11-02 22:23:14 +01:00
, session -> GetPlayerInfo (). c_str (), m_tabId , m_text . c_str ());
2010-10-17 19:54:13 +06:00
session -> SendPacket ( & data );
2012-11-02 22:23:14 +01:00
}
2010-10-17 19:54:13 +06:00
else
2012-11-02 22:23:14 +01:00
{
2012-11-07 23:21:19 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_BANK_QUERY_TEXT_RESULT [Broadcast]: Tabid: %u, Text: %s" , m_tabId , m_text . c_str ());
2011-10-07 10:54:53 -05:00
guild -> BroadcastPacket ( & data );
2012-11-02 22:23:14 +01:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Member
void Guild :: Member :: SetStats ( Player * player )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
m_name = player -> GetName ();
m_level = player -> getLevel ();
m_class = player -> getClass ();
m_zoneId = player -> GetZoneId ();
m_accountId = player -> GetSession () -> GetAccountId ();
2012-11-07 23:21:19 +01:00
m_achievementPoints = player -> GetAchievementPoints ();
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
void Guild :: Member :: SetStats ( std :: string const & name , uint8 level , uint8 _class , uint32 zoneId , uint32 accountId , uint32 reputation )
2010-10-17 19:54:13 +06:00
{
m_name = name ;
m_level = level ;
m_class = _class ;
m_zoneId = zoneId ;
m_accountId = accountId ;
2012-11-07 23:21:19 +01:00
m_totalReputation = reputation ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: Member :: SetPublicNote ( std :: string const & publicNote )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_publicNote == publicNote )
2008-10-11 14:16:25 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_publicNote = publicNote ;
2009-10-17 15:51:44 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_MEMBER_PNOTE );
2010-10-17 19:54:13 +06:00
stmt -> setString ( 0 , publicNote );
stmt -> setUInt32 ( 1 , GUID_LOPART ( m_guid ));
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: Member :: SetOfficerNote ( std :: string const & officerNote )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_officerNote == officerNote )
2008-10-11 14:16:25 -05:00
return ;
2010-10-17 19:54:13 +06:00
m_officerNote = officerNote ;
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_MEMBER_OFFNOTE );
2010-10-17 19:54:13 +06:00
stmt -> setString ( 0 , officerNote );
stmt -> setUInt32 ( 1 , GUID_LOPART ( m_guid ));
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: Member :: ChangeRank ( uint8 newRank )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
m_rankId = newRank ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Update rank information in player's field, if he is online.
2011-06-12 01:47:45 +02:00
if ( Player * player = FindPlayer ())
2010-10-17 19:54:13 +06:00
player -> SetRank ( newRank );
2009-10-17 15:51:44 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_MEMBER_RANK );
2010-10-17 19:54:13 +06:00
stmt -> setUInt8 ( 0 , newRank );
stmt -> setUInt32 ( 1 , GUID_LOPART ( m_guid ));
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: Member :: SaveToDB ( SQLTransaction & trans ) const
2008-10-11 14:16:25 -05:00
{
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_MEMBER );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt32 ( 1 , GUID_LOPART ( m_guid ));
stmt -> setUInt8 ( 2 , m_rankId );
stmt -> setString ( 3 , m_publicNote );
stmt -> setString ( 4 , m_officerNote );
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
}
// Loads member's data from database.
2010-12-13 22:37:56 +01:00
// If member has broken fields (level, class) returns false.
2010-10-17 19:54:13 +06:00
// In this case member has to be removed from guild.
bool Guild :: Member :: LoadFromDB ( Field * fields )
{
2012-11-02 22:23:14 +01:00
m_publicNote = fields [ 3 ]. GetString ();
m_officerNote = fields [ 4 ]. GetString ();
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
for ( uint8 i = 0 ; i <= GUILD_BANK_MAX_TABS ; ++ i )
m_bankWithdraw [ i ] = fields [ 5 + i ]. GetUInt32 ();
2009-10-17 15:51:44 -07:00
2012-11-04 20:17:37 +01:00
SetStats ( fields [ 14 ]. GetString (),
fields [ 15 ]. GetUInt8 (), // characters.level
fields [ 16 ]. GetUInt8 (), // characters.class
fields [ 17 ]. GetUInt16 (), // characters.zone
2012-11-07 23:21:19 +01:00
fields [ 18 ]. GetUInt32 (), // characters.account
0 );
2012-11-04 20:17:37 +01:00
m_logoutTime = fields [ 19 ]. GetUInt32 (); // characters.logout_time
2012-11-07 23:21:19 +01:00
m_totalActivity = 0 ;
m_weekActivity = 0 ;
m_weekReputation = 0 ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( ! CheckStats ())
return false ;
if ( ! m_zoneId )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Player (GUID: %u) has broken zone-data" , GUID_LOPART ( m_guid ));
2010-10-17 19:54:13 +06:00
m_zoneId = Player :: GetZoneIdFromDB ( m_guid );
2008-10-11 14:16:25 -05:00
}
2012-11-02 22:23:14 +01:00
ResetFlags ();
2010-10-17 19:54:13 +06:00
return true ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Validate player fields. Returns false if corrupted fields are found.
bool Guild :: Member :: CheckStats () const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_level < 1 )
2008-10-11 14:16:25 -05:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Player (GUID: %u) has a broken data in field `characters`.`level`, deleting him from guild!" , GUID_LOPART ( m_guid ));
2010-10-17 19:54:13 +06:00
return false ;
}
2012-09-18 11:33:09 +02:00
2010-10-17 19:54:13 +06:00
if ( m_class < CLASS_WARRIOR || m_class >= MAX_CLASSES )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Player (GUID: %u) has a broken data in field `characters`.`class`, deleting him from guild!" , GUID_LOPART ( m_guid ));
2010-10-17 19:54:13 +06:00
return false ;
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
return true ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Decreases amount of money/slots left for today.
// If (tabId == GUILD_BANK_MAX_TABS) decrease money amount.
// Otherwise decrease remaining items amount for specified tab.
2012-11-02 22:23:14 +01:00
void Guild :: Member :: UpdateBankWithdrawValue ( SQLTransaction & trans , uint8 tabId , uint32 amount )
2008-10-11 14:16:25 -05:00
{
2012-11-02 22:23:14 +01:00
m_bankWithdraw [ tabId ] += amount ;
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_MEMBER_WITHDRAW );
stmt -> setUInt32 ( 0 , GUID_LOPART ( m_guid ));
for ( uint8 i = 0 ; i <= GUILD_BANK_MAX_TABS ;)
{
uint32 withdraw = m_bankWithdraw [ i ++ ];
stmt -> setUInt32 ( i , withdraw );
}
2009-10-17 15:51:44 -07:00
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
void Guild :: Member :: ResetValues ( bool weekly /* = false*/ )
2012-11-02 22:23:14 +01:00
{
for ( uint8 tabId = 0 ; tabId <= GUILD_BANK_MAX_TABS ; ++ tabId )
m_bankWithdraw [ tabId ] = 0 ;
2012-11-07 23:21:19 +01:00
if ( weekly )
{
m_weekActivity = 0 ;
m_weekReputation = 0 ;
}
2012-11-02 22:23:14 +01:00
}
2010-10-17 19:54:13 +06:00
// Get amount of money/slots left for today.
// If (tabId == GUILD_BANK_MAX_TABS) return money amount.
// Otherwise return remaining items amount for specified tab.
2012-11-02 22:23:14 +01:00
int32 Guild :: Member :: GetBankWithdrawValue ( uint8 tabId ) const
2010-10-17 19:54:13 +06:00
{
// Guild master has unlimited amount.
if ( IsRank ( GR_GUILDMASTER ))
return tabId == GUILD_BANK_MAX_TABS ? GUILD_WITHDRAW_MONEY_UNLIMITED : GUILD_WITHDRAW_SLOT_UNLIMITED ;
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
return m_bankWithdraw [ tabId ];
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// EmblemInfo
2012-09-18 11:33:09 +02:00
void EmblemInfo :: ReadPacket ( WorldPacket & recv )
{
recv >> m_style >> m_color >> m_borderStyle >> m_borderColor >> m_backgroundColor ;
}
2010-10-17 19:54:13 +06:00
void EmblemInfo :: LoadFromDB ( Field * fields )
2008-10-11 14:16:25 -05:00
{
2011-01-20 00:08:45 +01:00
m_style = fields [ 3 ]. GetUInt8 ();
m_color = fields [ 4 ]. GetUInt8 ();
m_borderStyle = fields [ 5 ]. GetUInt8 ();
m_borderColor = fields [ 6 ]. GetUInt8 ();
m_backgroundColor = fields [ 7 ]. GetUInt8 ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void EmblemInfo :: WritePacket ( WorldPacket & data ) const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
data << uint32 ( m_style );
data << uint32 ( m_color );
data << uint32 ( m_borderStyle );
data << uint32 ( m_borderColor );
data << uint32 ( m_backgroundColor );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void EmblemInfo :: SaveToDB ( uint32 guildId ) const
2008-10-11 14:16:25 -05:00
{
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_EMBLEM_INFO );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_style );
stmt -> setUInt32 ( 1 , m_color );
stmt -> setUInt32 ( 2 , m_borderStyle );
stmt -> setUInt32 ( 3 , m_borderColor );
stmt -> setUInt32 ( 4 , m_backgroundColor );
stmt -> setUInt32 ( 5 , guildId );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// MoveItemData
bool Guild :: MoveItemData :: CheckItem ( uint32 & splitedAmount )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
ASSERT ( m_pItem );
if ( splitedAmount > m_pItem -> GetCount ())
return false ;
if ( splitedAmount == m_pItem -> GetCount ())
splitedAmount = 0 ;
return true ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-04-29 16:48:15 +06:00
bool Guild :: MoveItemData :: CanStore ( Item * pItem , bool swap , bool sendError )
2008-11-05 20:10:19 -06:00
{
2010-10-17 19:54:13 +06:00
m_vec . clear ();
2011-10-13 17:01:55 -04:00
InventoryResult msg = CanStore ( pItem , swap );
2010-10-17 19:54:13 +06:00
if ( sendError && msg != EQUIP_ERR_OK )
m_pPlayer -> SendEquipError ( msg , pItem );
return ( msg == EQUIP_ERR_OK );
2008-11-05 20:10:19 -06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
bool Guild :: MoveItemData :: CloneItem ( uint32 count )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
ASSERT ( m_pItem );
m_pClonedItem = m_pItem -> CloneItem ( count );
if ( ! m_pClonedItem )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
m_pPlayer -> SendEquipError ( EQUIP_ERR_ITEM_NOT_FOUND , m_pItem );
return false ;
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: MoveItemData :: LogAction ( MoveItemData * pFrom ) const
{
ASSERT ( pFrom -> GetItem ());
2010-08-13 17:39:43 +06:00
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildItemMove ( m_pGuild , m_pPlayer , pFrom -> GetItem (),
2010-10-17 19:54:13 +06:00
pFrom -> IsBank (), pFrom -> GetContainer (), pFrom -> GetSlotId (),
IsBank (), GetContainer (), GetSlotId ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
inline void Guild :: MoveItemData :: CopySlots ( SlotIds & ids ) const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
for ( ItemPosCountVec :: const_iterator itr = m_vec . begin (); itr != m_vec . end (); ++ itr )
ids . insert ( uint8 ( itr -> pos ));
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// PlayerMoveItemData
bool Guild :: PlayerMoveItemData :: InitItem ()
{
m_pItem = m_pPlayer -> GetItemByPos ( m_container , m_slotId );
if ( m_pItem )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// Anti-WPE protection. Do not move non-empty bags to bank.
2011-03-18 15:58:08 +06:00
if ( m_pItem -> IsNotEmptyBag ())
2008-10-11 14:16:25 -05:00
{
2012-08-20 15:54:55 +02:00
m_pPlayer -> SendEquipError ( EQUIP_ERR_DESTROY_NONEMPTY_BAG , m_pItem );
2010-10-17 19:54:13 +06:00
m_pItem = NULL ;
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
// Bound items cannot be put into bank.
else if ( ! m_pItem -> CanBeTraded ())
2008-10-11 14:16:25 -05:00
{
2012-08-20 15:54:55 +02:00
m_pPlayer -> SendEquipError ( EQUIP_ERR_CANT_SWAP , m_pItem );
2010-10-17 19:54:13 +06:00
m_pItem = NULL ;
2008-10-11 14:16:25 -05:00
}
}
2010-10-17 19:54:13 +06:00
return ( m_pItem != NULL );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: PlayerMoveItemData :: RemoveItem ( SQLTransaction & trans , MoveItemData * /*pOther*/ , uint32 splitedAmount )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( splitedAmount )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
m_pItem -> SetCount ( m_pItem -> GetCount () - splitedAmount );
m_pItem -> SetState ( ITEM_CHANGED , m_pPlayer );
m_pPlayer -> SaveInventoryAndGoldToDB ( trans );
}
else
{
m_pPlayer -> MoveItemFromInventory ( m_container , m_slotId , true );
m_pItem -> DeleteFromInventoryDB ( trans );
m_pItem = NULL ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Item * Guild :: PlayerMoveItemData :: StoreItem ( SQLTransaction & trans , Item * pItem )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
ASSERT ( pItem );
m_pPlayer -> MoveItemToInventory ( m_vec , pItem , true );
m_pPlayer -> SaveInventoryAndGoldToDB ( trans );
return pItem ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: PlayerMoveItemData :: LogBankEvent ( SQLTransaction & trans , MoveItemData * pFrom , uint32 count ) const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
ASSERT ( pFrom );
// Bank -> Char
2010-12-13 22:37:56 +01:00
m_pGuild -> _LogBankEvent ( trans , GUILD_BANK_LOG_WITHDRAW_ITEM , pFrom -> GetContainer (), m_pPlayer -> GetGUIDLow (),
2010-10-17 19:54:13 +06:00
pFrom -> GetItem () -> GetEntry (), count );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-10-13 17:01:55 -04:00
inline InventoryResult Guild :: PlayerMoveItemData :: CanStore ( Item * pItem , bool swap )
2010-07-28 17:19:39 -06:00
{
2010-10-17 19:54:13 +06:00
return m_pPlayer -> CanStoreItem ( m_container , m_slotId , m_vec , pItem , swap );
2010-07-28 17:19:39 -06:00
}
2010-10-17 19:54:13 +06:00
// BankMoveItemData
bool Guild :: BankMoveItemData :: InitItem ()
{
m_pItem = m_pGuild -> _GetItem ( m_container , m_slotId );
return ( m_pItem != NULL );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
bool Guild :: BankMoveItemData :: HasStoreRights ( MoveItemData * pOther ) const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
ASSERT ( pOther );
// Do not check rights if item is being swapped within the same bank tab
if ( pOther -> IsBank () && pOther -> GetContainer () == m_container )
return true ;
return m_pGuild -> _MemberHasTabRights ( m_pPlayer -> GetGUID (), m_container , GUILD_BANK_RIGHT_DEPOSIT_ITEM );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
bool Guild :: BankMoveItemData :: HasWithdrawRights ( MoveItemData * pOther ) const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
ASSERT ( pOther );
// Do not check rights if item is being swapped within the same bank tab
if ( pOther -> IsBank () && pOther -> GetContainer () == m_container )
return true ;
2012-11-02 22:23:14 +01:00
int32 slots = 0 ;
if ( Member const * member = m_pGuild -> GetMember ( m_pPlayer -> GetGUID ()))
slots = m_pGuild -> _GetMemberRemainingSlots ( member , m_container );
return slots != 0 ;
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: BankMoveItemData :: RemoveItem ( SQLTransaction & trans , MoveItemData * pOther , uint32 splitedAmount )
{
ASSERT ( m_pItem );
if ( splitedAmount )
{
m_pItem -> SetCount ( m_pItem -> GetCount () - splitedAmount );
m_pItem -> FSetState ( ITEM_CHANGED );
m_pItem -> SaveToDB ( trans );
}
else
{
m_pGuild -> _RemoveItem ( trans , m_container , m_slotId );
m_pItem = NULL ;
}
// Decrease amount of player's remaining items (if item is moved to different tab or to player)
if ( ! pOther -> IsBank () || pOther -> GetContainer () != m_container )
2012-11-02 22:23:14 +01:00
m_pGuild -> _UpdateMemberWithdrawSlots ( trans , m_pPlayer -> GetGUID (), m_container );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Item * Guild :: BankMoveItemData :: StoreItem ( SQLTransaction & trans , Item * pItem )
{
if ( ! pItem )
return NULL ;
2009-12-17 11:14:55 +01:00
2010-10-17 19:54:13 +06:00
BankTab * pTab = m_pGuild -> GetBankTab ( m_container );
if ( ! pTab )
return NULL ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Item * pLastItem = pItem ;
for ( ItemPosCountVec :: const_iterator itr = m_vec . begin (); itr != m_vec . end (); )
{
ItemPosCount pos ( * itr );
++ itr ;
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "GUILD STORAGE: StoreItem tab = %u, slot = %u, item = %u, count = %u" ,
2010-10-17 19:54:13 +06:00
m_container , m_slotId , pItem -> GetEntry (), pItem -> GetCount ());
pLastItem = _StoreItem ( trans , pTab , pItem , pos , itr != m_vec . end ());
}
return pLastItem ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: BankMoveItemData :: LogBankEvent ( SQLTransaction & trans , MoveItemData * pFrom , uint32 count ) const
{
ASSERT ( pFrom -> GetItem ());
if ( pFrom -> IsBank ())
// Bank -> Bank
2010-12-13 22:37:56 +01:00
m_pGuild -> _LogBankEvent ( trans , GUILD_BANK_LOG_MOVE_ITEM , pFrom -> GetContainer (), m_pPlayer -> GetGUIDLow (),
2010-10-17 19:54:13 +06:00
pFrom -> GetItem () -> GetEntry (), count , m_container );
2010-12-13 22:37:56 +01:00
else
2010-10-17 19:54:13 +06:00
// Char -> Bank
2010-12-13 22:37:56 +01:00
m_pGuild -> _LogBankEvent ( trans , GUILD_BANK_LOG_DEPOSIT_ITEM , m_container , m_pPlayer -> GetGUIDLow (),
2010-10-17 19:54:13 +06:00
pFrom -> GetItem () -> GetEntry (), count );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: BankMoveItemData :: LogAction ( MoveItemData * pFrom ) const
{
MoveItemData :: LogAction ( pFrom );
2013-03-08 13:15:25 +01:00
if ( ! pFrom -> IsBank () && m_pPlayer -> GetSession () -> HasPermission ( RBAC_PERM_LOG_GM_TRADE ))
2013-02-25 11:40:51 +01:00
{
2010-12-23 23:25:44 +01:00
sLog -> outCommand ( m_pPlayer -> GetSession () -> GetAccountId (),
2010-10-17 19:54:13 +06:00
"GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u)" ,
2012-10-24 13:29:34 +02:00
m_pPlayer -> GetName (). c_str (), m_pPlayer -> GetSession () -> GetAccountId (),
2011-04-29 19:59:40 +02:00
pFrom -> GetItem () -> GetTemplate () -> Name1 . c_str (), pFrom -> GetItem () -> GetEntry (), pFrom -> GetItem () -> GetCount (),
2010-10-17 19:54:13 +06:00
m_pGuild -> GetId ());
2013-02-25 11:40:51 +01:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Item * Guild :: BankMoveItemData :: _StoreItem ( SQLTransaction & trans , BankTab * pTab , Item * pItem , ItemPosCount & pos , bool clone ) const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
uint8 slotId = uint8 ( pos . pos );
uint32 count = pos . count ;
if ( Item * pItemDest = pTab -> GetItem ( slotId ))
{
pItemDest -> SetCount ( pItemDest -> GetCount () + count );
pItemDest -> FSetState ( ITEM_CHANGED );
pItemDest -> SaveToDB ( trans );
if ( ! clone )
{
pItem -> RemoveFromWorld ();
pItem -> DeleteFromDB ( trans );
delete pItem ;
}
return pItemDest ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( clone )
pItem = pItem -> CloneItem ( count );
else
pItem -> SetCount ( count );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( pItem && pTab -> SetItem ( trans , slotId , pItem ))
return pItem ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
return NULL ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Tries to reserve space for source item.
// If item in destination slot exists it must be the item of the same entry
// and stack must have enough space to take at least one item.
// Returns false if destination item specified and it cannot be used to reserve space.
bool Guild :: BankMoveItemData :: _ReserveSpace ( uint8 slotId , Item * pItem , Item * pItemDest , uint32 & count )
{
uint32 requiredSpace = pItem -> GetMaxStackCount ();
if ( pItemDest )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// Make sure source and destination items match and destination item has space for more stacks.
if ( pItemDest -> GetEntry () != pItem -> GetEntry () || pItemDest -> GetCount () >= pItem -> GetMaxStackCount ())
return false ;
requiredSpace -= pItemDest -> GetCount ();
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
// Let's not be greedy, reserve only required space
requiredSpace = std :: min ( requiredSpace , count );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Reserve space
ItemPosCount pos ( slotId , requiredSpace );
if ( ! pos . isContainedIn ( m_vec ))
{
m_vec . push_back ( pos );
count -= requiredSpace ;
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
return true ;
}
2009-10-17 15:51:44 -07:00
2011-10-13 17:01:55 -04:00
void Guild :: BankMoveItemData :: CanStoreItemInTab ( Item * pItem , uint8 skipSlotId , bool merge , uint32 & count )
2010-10-17 19:54:13 +06:00
{
for ( uint8 slotId = 0 ; ( slotId < GUILD_BANK_MAX_SLOTS ) && ( count > 0 ); ++ slotId )
2008-10-11 14:16:25 -05:00
{
2011-10-13 17:01:55 -04:00
// Skip slot already processed in CanStore (when destination slot was specified)
2010-10-17 19:54:13 +06:00
if ( slotId == skipSlotId )
2008-10-11 14:16:25 -05:00
continue ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Item * pItemDest = m_pGuild -> _GetItem ( m_container , slotId );
if ( pItemDest == pItem )
pItemDest = NULL ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// If merge skip empty, if not merge skip non-empty
if (( pItemDest != NULL ) != merge )
continue ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
_ReserveSpace ( slotId , pItem , pItemDest , count );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-10-13 17:01:55 -04:00
InventoryResult Guild :: BankMoveItemData :: CanStore ( Item * pItem , bool swap )
2008-10-11 14:16:25 -05:00
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "GUILD STORAGE: CanStore() tab = %u, slot = %u, item = %u, count = %u" ,
2010-10-17 19:54:13 +06:00
m_container , m_slotId , pItem -> GetEntry (), pItem -> GetCount ());
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
uint32 count = pItem -> GetCount ();
// Soulbound items cannot be moved
if ( pItem -> IsSoulBound ())
2012-08-20 15:54:55 +02:00
return EQUIP_ERR_DROP_BOUND_ITEM ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Make sure destination bank tab exists
if ( m_container >= m_pGuild -> _GetPurchasedTabsSize ())
2012-08-20 15:54:55 +02:00
return EQUIP_ERR_WRONG_BAG_TYPE ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Slot explicitely specified. Check it.
if ( m_slotId != NULL_SLOT )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
Item * pItemDest = m_pGuild -> _GetItem ( m_container , m_slotId );
// Ignore swapped item (this slot will be empty after move)
if (( pItemDest == pItem ) || swap )
pItemDest = NULL ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( ! _ReserveSpace ( m_slotId , pItem , pItemDest , count ))
2012-08-20 15:54:55 +02:00
return EQUIP_ERR_CANT_STACK ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( count == 0 )
return EQUIP_ERR_OK ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Slot was not specified or it has not enough space for all the items in stack
// Search for stacks to merge with
if ( pItem -> GetMaxStackCount () > 1 )
{
2011-10-13 17:01:55 -04:00
CanStoreItemInTab ( pItem , m_slotId , true , count );
2010-10-17 19:54:13 +06:00
if ( count == 0 )
return EQUIP_ERR_OK ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Search free slot for item
2011-10-13 17:01:55 -04:00
CanStoreItemInTab ( pItem , m_slotId , false , count );
2010-10-17 19:54:13 +06:00
if ( count == 0 )
return EQUIP_ERR_OK ;
return EQUIP_ERR_BANK_FULL ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Guild
2012-11-02 22:23:14 +01:00
Guild :: Guild () :
m_id ( 0 ),
m_leaderGuid ( 0 ),
m_createdDate ( 0 ),
m_accountsNumber ( 0 ),
m_bankMoney ( 0 ),
2012-11-04 20:17:37 +01:00
m_eventLog ( NULL ),
2012-11-07 23:21:19 +01:00
m_newsLog ( NULL ),
2012-11-04 20:17:37 +01:00
m_achievementMgr ( this ),
_level ( 1 ),
_experience ( 0 ),
_todayExperience ( 0 )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
memset ( & m_bankEventLog , 0 , ( GUILD_BANK_MAX_TABS + 1 ) * sizeof ( LogHolder * ));
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Guild ::~ Guild ()
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
SQLTransaction temp ( NULL );
_DeleteBankItems ( temp );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Cleanup
2012-11-02 22:23:14 +01:00
delete m_eventLog ;
m_eventLog = NULL ;
2012-11-07 23:21:19 +01:00
delete m_newsLog ;
m_newsLog = NULL ;
2012-11-02 22:23:14 +01:00
2010-10-17 19:54:13 +06:00
for ( uint8 tabId = 0 ; tabId <= GUILD_BANK_MAX_TABS ; ++ tabId )
2012-11-02 22:23:14 +01:00
{
delete m_bankEventLog [ tabId ];
m_bankEventLog [ tabId ] = NULL ;
}
2010-10-17 19:54:13 +06:00
for ( Members :: iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
2012-11-02 22:23:14 +01:00
{
2010-10-17 19:54:13 +06:00
delete itr -> second ;
2012-11-02 22:23:14 +01:00
itr -> second = NULL ;
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Creates new guild with default data and saves it to database.
2012-11-02 22:23:14 +01:00
bool Guild :: Create ( Player * pLeader , std :: string const & name )
2009-12-17 11:14:55 +01:00
{
2010-10-17 19:54:13 +06:00
// Check if guild with such name already exists
2011-05-04 10:08:09 +02:00
if ( sGuildMgr -> GetGuildByName ( name ))
2010-10-17 19:54:13 +06:00
return false ;
2009-12-17 11:14:55 +01:00
2010-10-17 19:54:13 +06:00
WorldSession * pLeaderSession = pLeader -> GetSession ();
if ( ! pLeaderSession )
return false ;
2009-12-17 11:14:55 +01:00
2011-05-04 10:08:09 +02:00
m_id = sGuildMgr -> GenerateGuildId ();
2010-10-17 19:54:13 +06:00
m_leaderGuid = pLeader -> GetGUID ();
m_name = name ;
m_info = "" ;
m_motd = "No message set." ;
m_bankMoney = 0 ;
m_createdDate = :: time ( NULL );
2012-09-07 14:39:19 +02:00
_level = 1 ;
2012-11-07 23:21:19 +01:00
_experience = 0 ;
_todayExperience = 0 ;
2010-10-17 19:54:13 +06:00
_CreateLogHolders ();
2009-10-17 15:51:44 -07:00
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "GUILD: creating guild [%s] for leader %s (%u)" ,
2012-10-24 13:29:34 +02:00
name . c_str (), pLeader -> GetName (). c_str (), GUID_LOPART ( m_leaderGuid ));
2009-10-17 15:51:44 -07:00
2010-08-21 03:19:25 +02:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2010-10-17 19:54:13 +06:00
2012-11-02 22:23:14 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_MEMBERS );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_id );
trans -> Append ( stmt );
uint8 index = 0 ;
2012-01-01 01:09:38 +01:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( index , m_id );
stmt -> setString ( ++ index , name );
stmt -> setUInt32 ( ++ index , GUID_LOPART ( m_leaderGuid ));
stmt -> setString ( ++ index , m_info );
stmt -> setString ( ++ index , m_motd );
2011-01-20 00:08:45 +01:00
stmt -> setUInt64 ( ++ index , uint32 ( m_createdDate ));
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( ++ index , m_emblemInfo . GetStyle ());
stmt -> setUInt32 ( ++ index , m_emblemInfo . GetColor ());
stmt -> setUInt32 ( ++ index , m_emblemInfo . GetBorderStyle ());
stmt -> setUInt32 ( ++ index , m_emblemInfo . GetBorderColor ());
stmt -> setUInt32 ( ++ index , m_emblemInfo . GetBackgroundColor ());
stmt -> setUInt64 ( ++ index , m_bankMoney );
trans -> Append ( stmt );
2010-08-21 03:19:25 +02:00
CharacterDatabase . CommitTransaction ( trans );
2012-11-02 22:23:14 +01:00
_CreateDefaultGuildRanks ( pLeaderSession -> GetSessionDbLocaleIndex ()); // Create default ranks
bool ret = AddMember ( m_leaderGuid , GR_GUILDMASTER ); // Add guildmaster
2010-10-17 19:54:13 +06:00
if ( ret )
2012-11-04 20:17:37 +01:00
{
2012-11-07 23:21:19 +01:00
_BroadcastEvent ( GE_FOUNDER , 0 );
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildCreate ( this , pLeader , name );
2012-11-04 20:17:37 +01:00
}
2012-08-04 18:40:56 +02:00
2010-10-17 19:54:13 +06:00
return ret ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Disbands guild and deletes all related data from database
void Guild :: Disband ()
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// Call scripts before guild data removed from database
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildDisband ( this );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
_BroadcastEvent ( GE_DISBANDED , 0 );
// Remove all members
while ( ! m_members . empty ())
{
Members :: const_iterator itr = m_members . begin ();
DeleteMember ( itr -> second -> GetGUID (), true );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2012-11-02 22:23:14 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_id );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_RANKS );
stmt -> setUInt32 ( 0 , m_id );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_TABS );
stmt -> setUInt32 ( 0 , m_id );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Free bank tab used memory and delete items stored in them
_DeleteBankItems ( trans , true );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_ITEMS );
stmt -> setUInt32 ( 0 , m_id );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_RIGHTS );
stmt -> setUInt32 ( 0 , m_id );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_EVENTLOGS );
stmt -> setUInt32 ( 0 , m_id );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_EVENTLOGS );
stmt -> setUInt32 ( 0 , m_id );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
CharacterDatabase . CommitTransaction ( trans );
2012-09-09 11:32:14 +02:00
sGuildFinderMgr -> DeleteGuild ( m_id );
2011-05-04 10:08:09 +02:00
sGuildMgr -> RemoveGuild ( m_id );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-25 15:36:45 +02:00
void Guild :: SaveToDB ()
{
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2012-09-07 14:39:19 +02:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_EXPERIENCE );
stmt -> setUInt32 ( 0 , GetLevel ());
stmt -> setUInt64 ( 1 , GetExperience ());
stmt -> setUInt64 ( 2 , GetTodayExperience ());
stmt -> setUInt32 ( 3 , GetId ());
trans -> Append ( stmt );
2012-08-25 15:36:45 +02:00
m_achievementMgr . SaveToDB ( trans );
CharacterDatabase . CommitTransaction ( trans );
}
2012-11-02 22:23:14 +01:00
void Guild :: UpdateMemberData ( Player * player , uint8 dataid , uint32 value )
{
if ( Member * member = GetMember ( player -> GetGUID ()))
{
switch ( dataid )
{
case GUILD_MEMBER_DATA_ZONEID :
2012-11-04 20:17:37 +01:00
member -> SetZoneId ( value );
2012-11-02 22:23:14 +01:00
break ;
2012-11-07 23:21:19 +01:00
case GUILD_MEMBER_DATA_ACHIEVEMENT_POINTS :
member -> SetAchievementPoints ( value );
break ;
2012-11-02 22:23:14 +01:00
case GUILD_MEMBER_DATA_LEVEL :
member -> SetLevel ( value );
break ;
default :
sLog -> outError ( LOG_FILTER_GUILD , "Guild::UpdateMemberData: Called with incorrect DATAID %u (value %u)" , dataid , value );
return ;
}
//HandleRoster();
}
}
void Guild :: OnPlayerStatusChange ( Player * player , uint32 flag , bool state )
{
if ( Member * member = GetMember ( player -> GetGUID ()))
{
if ( state )
member -> AddFlag ( flag );
else member -> RemFlag ( flag );
}
}
2011-09-15 14:08:17 +02:00
void Guild :: HandleRoster ( WorldSession * session /*= NULL*/ )
2008-10-11 14:16:25 -05:00
{
2012-08-04 18:40:56 +02:00
ByteBuffer memberData ( 100 );
2010-10-17 19:54:13 +06:00
// Guess size
2012-08-04 18:40:56 +02:00
WorldPacket data ( SMSG_GUILD_ROSTER , 100 );
data . WriteBits ( m_motd . length (), 11 );
data . WriteBits ( m_members . size (), 18 );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
2012-08-04 18:40:56 +02:00
{
Member * member = itr -> second ;
size_t pubNoteLength = member -> GetPublicNote (). length ();
size_t offNoteLength = member -> GetOfficerNote (). length ();
ObjectGuid guid = member -> GetGUID ();
data . WriteBit ( guid [ 3 ]);
data . WriteBit ( guid [ 4 ]);
2012-08-10 14:25:04 +02:00
data . WriteBit ( 0 ); // Has Authenticator
data . WriteBit ( 0 ); // Can Scroll of Ressurect
2012-08-04 18:40:56 +02:00
data . WriteBits ( pubNoteLength , 8 );
data . WriteBits ( offNoteLength , 8 );
data . WriteBit ( guid [ 0 ]);
data . WriteBits ( member -> GetName (). length (), 7 );
data . WriteBit ( guid [ 1 ]);
data . WriteBit ( guid [ 2 ]);
data . WriteBit ( guid [ 6 ]);
data . WriteBit ( guid [ 5 ]);
data . WriteBit ( guid [ 7 ]);
memberData << uint8 ( member -> GetClass ());
2012-11-07 23:21:19 +01:00
memberData << uint32 ( member -> GetTotalReputation ());
2012-08-04 18:40:56 +02:00
memberData . WriteByteSeq ( guid [ 0 ]);
2012-11-07 23:21:19 +01:00
memberData << uint64 ( member -> GetWeekActivity ());
2012-08-04 18:40:56 +02:00
memberData << uint32 ( member -> GetRankId ());
2012-11-07 23:21:19 +01:00
memberData << uint32 ( member -> GetAchievementPoints ());
2012-08-04 18:40:56 +02:00
// for (2 professions)
memberData << uint32 ( 0 ) << uint32 ( 0 ) << uint32 ( 0 );
memberData << uint32 ( 0 ) << uint32 ( 0 ) << uint32 ( 0 );
memberData . WriteByteSeq ( guid [ 2 ]);
2012-11-04 20:17:37 +01:00
memberData << uint8 ( member -> GetFlags ());
memberData << uint32 ( member -> GetZoneId ());
2012-11-07 23:21:19 +01:00
memberData << uint64 ( member -> GetTotalActivity ());
2012-08-04 18:40:56 +02:00
memberData . WriteByteSeq ( guid [ 7 ]);
2012-11-07 23:21:19 +01:00
memberData << uint32 ( sWorld -> getIntConfig ( CONFIG_GUILD_WEEKLY_REP_CAP ) - member -> GetWeekReputation ());
2012-08-04 18:40:56 +02:00
if ( pubNoteLength )
2012-08-10 16:06:13 +01:00
memberData . WriteString ( member -> GetPublicNote ());
2012-08-04 18:40:56 +02:00
memberData . WriteByteSeq ( guid [ 3 ]);
2012-11-04 20:17:37 +01:00
memberData << uint8 ( member -> GetLevel ());
2012-08-04 18:40:56 +02:00
memberData << int32 ( 0 ); // unk
memberData . WriteByteSeq ( guid [ 5 ]);
memberData . WriteByteSeq ( guid [ 4 ]);
memberData << uint8 ( 0 ); // unk
memberData . WriteByteSeq ( guid [ 1 ]);
2012-11-04 20:17:37 +01:00
memberData << float ( member -> IsOnline () ? 0.0f : float ( :: time ( NULL ) - member -> GetLogoutTime ()) / DAY );
2012-08-04 18:40:56 +02:00
if ( offNoteLength )
2012-08-10 16:06:13 +01:00
memberData . WriteString ( member -> GetOfficerNote ());
2012-08-04 18:40:56 +02:00
memberData . WriteByteSeq ( guid [ 6 ]);
2012-08-10 16:06:13 +01:00
memberData . WriteString ( member -> GetName ());
2012-08-04 18:40:56 +02:00
}
size_t infoLength = m_info . length ();
data . WriteBits ( infoLength , 12 );
data . FlushBits ();
data . append ( memberData );
if ( infoLength )
2012-08-10 16:06:13 +01:00
data . WriteString ( m_info );
2012-08-04 18:40:56 +02:00
2012-08-10 16:06:13 +01:00
data . WriteString ( m_motd );
2012-08-22 19:50:42 +02:00
data << uint32 ( m_accountsNumber );
2012-09-07 14:39:19 +02:00
data << uint32 ( sWorld -> getIntConfig ( CONFIG_GUILD_WEEKLY_REP_CAP ));
2012-09-13 17:24:37 +01:00
data . AppendPackedTime ( m_createdDate );
2012-08-04 18:40:56 +02:00
data << uint32 ( 0 );
2010-10-17 19:54:13 +06:00
if ( session )
2012-11-02 22:23:14 +01:00
{
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_ROSTER [%s]" , session -> GetPlayerInfo (). c_str ());
2010-10-17 19:54:13 +06:00
session -> SendPacket ( & data );
2012-11-02 22:23:14 +01:00
}
2010-10-17 19:54:13 +06:00
else
2012-11-02 22:23:14 +01:00
{
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_ROSTER [Broadcast]" );
2010-10-17 19:54:13 +06:00
BroadcastPacket ( & data );
2012-11-02 22:23:14 +01:00
}
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void Guild :: HandleQuery ( WorldSession * session )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
WorldPacket data ( SMSG_GUILD_QUERY_RESPONSE , 8 * 32 + 200 ); // Guess size
2009-10-17 15:51:44 -07:00
2012-07-09 11:08:33 +02:00
data << uint64 ( GetGUID ());
2010-10-17 19:54:13 +06:00
data << m_name ;
2009-10-17 15:51:44 -07:00
2011-12-22 19:53:47 +00:00
// Rank name
for ( uint8 i = 0 ; i < GUILD_RANKS_MAX_COUNT ; ++ i ) // Always show 10 ranks
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( i < _GetRanksSize ())
data << m_ranks [ i ]. GetName ();
else
data << uint8 ( 0 ); // Empty string
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-12-22 19:53:47 +00:00
// Rank order of creation
for ( uint8 i = 0 ; i < GUILD_RANKS_MAX_COUNT ; ++ i )
{
if ( i < _GetRanksSize ())
data << uint32 ( i );
else
data << uint32 ( 0 );
}
// Rank order of "importance" (sorting by rights)
for ( uint8 i = 0 ; i < GUILD_RANKS_MAX_COUNT ; ++ i )
{
if ( i < _GetRanksSize ())
2012-08-04 18:40:56 +02:00
data << uint32 ( m_ranks [ i ]. GetId ());
2011-12-22 19:53:47 +00:00
else
data << uint32 ( 0 );
}
2010-10-17 19:54:13 +06:00
m_emblemInfo . WritePacket ( data );
2011-12-22 19:53:47 +00:00
data << uint32 ( _GetRanksSize ()); // Number of ranks used
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
session -> SendPacket ( & data );
2012-11-02 22:23:14 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_QUERY_RESPONSE [%s]" , session -> GetPlayerInfo (). c_str ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-04 20:17:37 +01:00
void Guild :: SendGuildRankInfo ( WorldSession * session ) const
2012-08-04 18:40:56 +02:00
{
ByteBuffer rankData ( 100 );
WorldPacket data ( SMSG_GUILD_RANK , 100 );
2012-08-04 19:11:13 +01:00
2012-08-04 18:40:56 +02:00
data . WriteBits ( _GetRanksSize (), 18 );
for ( uint8 i = 0 ; i < _GetRanksSize (); i ++ )
{
2012-08-22 19:50:42 +02:00
RankInfo const * rankInfo = GetRankInfo ( i );
2012-08-04 18:40:56 +02:00
if ( ! rankInfo )
continue ;
data . WriteBits ( rankInfo -> GetName (). length (), 7 );
2012-11-07 23:21:19 +01:00
rankData << uint32 ( rankInfo -> GetId ());
2012-08-04 18:40:56 +02:00
for ( uint8 j = 0 ; j < GUILD_BANK_MAX_TABS ; ++ j )
{
rankData << uint32 ( rankInfo -> GetBankTabSlotsPerDay ( j ));
rankData << uint32 ( rankInfo -> GetBankTabRights ( j ));
}
rankData << uint32 ( rankInfo -> GetBankMoneyPerDay ());
rankData << uint32 ( rankInfo -> GetRights ());
if ( rankInfo -> GetName (). length ())
2012-08-10 16:06:13 +01:00
rankData . WriteString ( rankInfo -> GetName ());
2012-08-04 18:40:56 +02:00
2012-11-07 23:21:19 +01:00
rankData << uint32 ( i );
2012-08-04 18:40:56 +02:00
}
data . FlushBits ();
data . append ( rankData );
session -> SendPacket ( & data );
2012-11-07 23:21:19 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_RANK [%s]" , session -> GetPlayerInfo (). c_str ());
2012-08-04 18:40:56 +02:00
}
2012-11-02 22:23:14 +01:00
void Guild :: HandleSetMOTD ( WorldSession * session , std :: string const & motd )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_motd == motd )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Player must have rights to set MOTD
if ( ! _HasRankRight ( session -> GetPlayer (), GR_RIGHT_SETMOTD ))
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_EDIT_MOTD , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
else
{
m_motd = motd ;
2009-10-17 15:51:44 -07:00
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildMOTDChanged ( this , motd );
2009-10-17 15:51:44 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_MOTD );
2010-10-17 19:54:13 +06:00
stmt -> setString ( 0 , motd );
stmt -> setUInt32 ( 1 , m_id );
CharacterDatabase . Execute ( stmt );
_BroadcastEvent ( GE_MOTD , 0 , motd . c_str ());
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: HandleSetInfo ( WorldSession * session , std :: string const & info )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_info == info )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Player must have rights to set guild's info
2012-11-02 22:23:14 +01:00
if ( _HasRankRight ( session -> GetPlayer (), GR_RIGHT_MODIFY_GUILD_INFO ))
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
m_info = info ;
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildInfoChanged ( this , info );
2010-10-17 19:54:13 +06:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_INFO );
2010-10-17 19:54:13 +06:00
stmt -> setString ( 0 , info );
stmt -> setUInt32 ( 1 , m_id );
CharacterDatabase . Execute ( stmt );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: HandleSetEmblem ( WorldSession * session , const EmblemInfo & emblemInfo )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
if ( ! _IsLeader ( player ))
2012-11-02 22:23:14 +01:00
SendSaveEmblemResult ( session , ERR_GUILDEMBLEM_NOTGUILDMASTER ); // "Only guild leaders can create emblems."
2012-07-24 15:27:42 +01:00
else if ( ! player -> HasEnoughMoney ( uint64 ( EMBLEM_PRICE )))
2012-11-02 22:23:14 +01:00
SendSaveEmblemResult ( session , ERR_GUILDEMBLEM_NOTENOUGHMONEY ); // "You can't afford to do that."
2010-10-17 19:54:13 +06:00
else
{
2012-07-24 15:27:42 +01:00
player -> ModifyMoney ( - int64 ( EMBLEM_PRICE ));
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_emblemInfo = emblemInfo ;
m_emblemInfo . SaveToDB ( m_id );
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
SendSaveEmblemResult ( session , ERR_GUILDEMBLEM_SUCCESS ); // "Guild Emblem saved."
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
HandleQuery ( session );
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-25 14:01:51 +01:00
void Guild :: HandleSetNewGuildMaster ( WorldSession * session , std :: string const & name )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
2012-11-25 14:01:51 +01:00
// Only the guild master can throne a new guild master
2010-10-17 19:54:13 +06:00
if ( ! _IsLeader ( player ))
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_CHANGE_LEADER , ERR_GUILD_PERMISSIONS );
2012-11-25 14:01:51 +01:00
// Old GM must be a guild member
else if ( Member * oldGuildMaster = GetMember ( player -> GetGUID ()))
2008-10-11 14:16:25 -05:00
{
2012-11-25 14:01:51 +01:00
// Same for the new one
if ( Member * newGuildMaster = GetMember ( name ))
2010-10-17 19:54:13 +06:00
{
2012-11-25 14:01:51 +01:00
_SetLeaderGUID ( newGuildMaster );
oldGuildMaster -> ChangeRank ( GR_INITIATE );
2012-10-24 13:29:34 +02:00
_BroadcastEvent ( GE_LEADER_CHANGED , 0 , player -> GetName (). c_str (), name . c_str ());
2010-10-17 19:54:13 +06:00
}
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: HandleSetBankTabInfo ( WorldSession * session , uint8 tabId , std :: string const & name , std :: string const & icon )
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
BankTab * tab = GetBankTab ( tabId );
if ( ! tab )
2008-10-11 14:16:25 -05:00
{
2012-11-02 22:23:14 +01:00
sLog -> outError ( LOG_FILTER_GUILD , "Guild::HandleSetBankTabInfo: Player %s trying to change bank tab info from unexisting tab %d." ,
session -> GetPlayerInfo (). c_str (), tabId );
return ;
2008-10-11 14:16:25 -05:00
}
2012-11-02 22:23:14 +01:00
char aux [ 2 ];
sprintf ( aux , "%u" , tabId );
tab -> SetInfo ( name , icon );
_BroadcastEvent ( GE_BANK_TAB_UPDATED , 0 , aux , name . c_str (), icon . c_str ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-04 18:40:56 +02:00
void Guild :: HandleSetMemberNote ( WorldSession * session , std :: string const & note , uint64 guid , bool isPublic )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// Player must have rights to set public/officer note
2012-08-04 18:40:56 +02:00
if ( ! _HasRankRight ( session -> GetPlayer (), isPublic ? GR_RIGHT_EPNOTE : GR_RIGHT_EOFFNOTE ))
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_PUBLIC_NOTE , ERR_GUILD_PERMISSIONS );
2012-08-04 18:40:56 +02:00
else if ( Member * member = GetMember ( guid ))
2010-10-17 19:54:13 +06:00
{
2012-08-04 18:40:56 +02:00
if ( isPublic )
2012-05-30 08:01:02 +02:00
member -> SetPublicNote ( note );
2012-08-04 18:40:56 +02:00
else
member -> SetOfficerNote ( note );
2012-11-02 22:23:14 +01:00
2012-11-07 23:21:19 +01:00
HandleRoster ( session ); // FIXME - We should send SMSG_GUILD_MEMBER_UPDATE_NOTE
2010-10-17 19:54:13 +06:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: HandleSetRankInfo ( WorldSession * session , uint8 rankId , std :: string const & name , uint32 rights , uint32 moneyPerDay , GuildBankRightsAndSlotsVec rightsAndSlots )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// Only leader can modify ranks
if ( ! _IsLeader ( session -> GetPlayer ()))
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_CHANGE_RANK , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
else if ( RankInfo * rankInfo = GetRankInfo ( rankId ))
{
2012-11-02 22:23:14 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "Changed RankName to '%s', rights to 0x%08X" , name . c_str (), rights );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
rankInfo -> SetName ( name );
rankInfo -> SetRights ( rights );
_SetRankBankMoneyPerDay ( rankId , moneyPerDay );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
for ( GuildBankRightsAndSlotsVec :: const_iterator itr = rightsAndSlots . begin (); itr != rightsAndSlots . end (); ++ itr )
2012-11-02 22:23:14 +01:00
_SetRankBankTabRightsAndSlots ( rankId , * itr );
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
char aux [ 2 ];
sprintf ( aux , "%u" , rankId );
2012-11-07 23:21:19 +01:00
_BroadcastEvent ( GE_RANK_UPDATED , 0 , aux );
2010-10-17 19:54:13 +06:00
}
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: HandleBuyBankTab ( WorldSession * session , uint8 tabId )
{
2012-11-02 22:23:14 +01:00
Player * player = session -> GetPlayer ();
if ( ! player )
2010-10-17 19:54:13 +06:00
return ;
2010-02-18 02:42:59 +01:00
2012-11-02 22:23:14 +01:00
Member const * member = GetMember ( player -> GetGUID ());
if ( ! member )
2010-10-17 19:54:13 +06:00
return ;
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
if ( _GetPurchasedTabsSize () >= GUILD_BANK_MAX_TABS )
2010-10-17 19:54:13 +06:00
return ;
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
if ( tabId != _GetPurchasedTabsSize ())
return ;
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
uint32 tabCost = _GetGuildBankTabPrice ( tabId ) * GOLD ;
if ( ! tabCost )
return ;
2009-10-17 15:51:44 -07:00
2012-11-09 09:03:29 +01:00
if ( ! player -> HasEnoughMoney ( uint64 ( tabCost ))) // Should not happen, this is checked by client
2012-11-07 23:21:19 +01:00
return ;
2012-11-02 22:23:14 +01:00
2012-11-09 09:03:29 +01:00
player -> ModifyMoney ( - int64 ( tabCost ));
2012-11-02 22:23:14 +01:00
_CreateNewBankTab ();
2012-11-07 23:21:19 +01:00
_BroadcastEvent ( GE_BANK_TAB_PURCHASED , 0 );
2012-11-08 11:13:46 +01:00
SendPermissions ( session ); /// Hack to force client to update permissions
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-10-24 13:29:34 +02:00
void Guild :: HandleInviteMember ( WorldSession * session , std :: string const & name )
2008-10-11 14:16:25 -05:00
{
2012-10-24 13:29:34 +02:00
Player * pInvitee = sObjectAccessor -> FindPlayerByName ( name );
2010-10-17 19:54:13 +06:00
if ( ! pInvitee )
{
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_INVITE , ERR_GUILD_PLAYER_NOT_FOUND_S , name );
2008-10-11 14:16:25 -05:00
return ;
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
// Do not show invitations from ignored players
if ( pInvitee -> GetSocial () -> HasIgnore ( player -> GetGUIDLow ()))
return ;
2012-09-18 11:33:09 +02:00
2010-12-23 23:25:44 +01:00
if ( ! sWorld -> getBoolConfig ( CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD ) && pInvitee -> GetTeam () != player -> GetTeam ())
2008-10-11 14:16:25 -05:00
{
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_INVITE , ERR_GUILD_NOT_ALLIED , name );
2010-10-17 19:54:13 +06:00
return ;
2008-10-11 14:16:25 -05:00
}
2012-11-04 20:17:37 +01:00
2010-10-17 19:54:13 +06:00
// Invited player cannot be in another guild
2012-08-04 18:40:56 +02:00
/*if (pInvitee->GetGuildId())
2008-10-11 14:16:25 -05:00
{
2012-11-02 22:23:14 +01:00
SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, name);
2010-10-17 19:54:13 +06:00
return;
2012-08-04 18:40:56 +02:00
}*/
2012-11-04 20:17:37 +01:00
2010-10-17 19:54:13 +06:00
// Invited player cannot be invited
if ( pInvitee -> GetGuildIdInvited ())
{
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_INVITE , ERR_ALREADY_INVITED_TO_GUILD_S , name );
2010-10-17 19:54:13 +06:00
return ;
}
// Inviting player must have rights to invite
if ( ! _HasRankRight ( player , GR_RIGHT_INVITE ))
{
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_INVITE , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
return ;
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_INVITE , ERR_GUILD_COMMAND_SUCCESS , name );
2012-10-24 13:29:34 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "Player %s invited %s to join his Guild" , player -> GetName (). c_str (), name . c_str ());
2010-10-17 19:54:13 +06:00
pInvitee -> SetGuildIdInvited ( m_id );
_LogEvent ( GUILD_EVENT_LOG_INVITE_PLAYER , player -> GetGUIDLow (), pInvitee -> GetGUIDLow ());
2012-08-04 18:40:56 +02:00
WorldPacket data ( SMSG_GUILD_INVITE , 100 );
2012-08-05 21:52:36 -05:00
data << uint32 ( GetLevel ());
2012-08-04 18:40:56 +02:00
data << uint32 ( m_emblemInfo . GetBorderStyle ());
2012-08-10 14:25:04 +02:00
data << uint32 ( m_emblemInfo . GetBorderColor ());
data << uint32 ( m_emblemInfo . GetStyle ());
2012-08-04 18:40:56 +02:00
data << uint32 ( m_emblemInfo . GetBackgroundColor ());
data << uint32 ( m_emblemInfo . GetColor ());
2012-08-17 10:25:29 +02:00
ObjectGuid oldGuildGuid = MAKE_NEW_GUID ( pInvitee -> GetGuildId (), 0 , pInvitee -> GetGuildId () ? uint32 ( HIGHGUID_GUILD ) : 0 );
2012-08-04 18:40:56 +02:00
ObjectGuid newGuildGuid = GetGUID ();
data . WriteBit ( newGuildGuid [ 3 ]);
data . WriteBit ( newGuildGuid [ 2 ]);
data . WriteBits ( pInvitee -> GetGuildName (). length (), 8 );
data . WriteBit ( newGuildGuid [ 1 ]);
data . WriteBit ( oldGuildGuid [ 6 ]);
data . WriteBit ( oldGuildGuid [ 4 ]);
data . WriteBit ( oldGuildGuid [ 1 ]);
data . WriteBit ( oldGuildGuid [ 5 ]);
data . WriteBit ( oldGuildGuid [ 7 ]);
data . WriteBit ( oldGuildGuid [ 2 ]);
data . WriteBit ( newGuildGuid [ 7 ]);
data . WriteBit ( newGuildGuid [ 0 ]);
data . WriteBit ( newGuildGuid [ 6 ]);
data . WriteBits ( m_name . length (), 8 );
data . WriteBit ( oldGuildGuid [ 3 ]);
data . WriteBit ( oldGuildGuid [ 0 ]);
data . WriteBit ( newGuildGuid [ 5 ]);
2012-10-30 10:30:05 +01:00
data . WriteBits ( player -> GetName (). size (), 7 );
2012-08-04 18:40:56 +02:00
data . WriteBit ( newGuildGuid [ 4 ]);
data . FlushBits ();
data . WriteByteSeq ( newGuildGuid [ 1 ]);
data . WriteByteSeq ( oldGuildGuid [ 3 ]);
data . WriteByteSeq ( newGuildGuid [ 6 ]);
data . WriteByteSeq ( oldGuildGuid [ 2 ]);
data . WriteByteSeq ( oldGuildGuid [ 1 ]);
data . WriteByteSeq ( newGuildGuid [ 0 ]);
if ( ! pInvitee -> GetGuildName (). empty ())
2012-08-10 16:06:13 +01:00
data . WriteString ( pInvitee -> GetGuildName ());
2012-08-04 18:40:56 +02:00
data . WriteByteSeq ( newGuildGuid [ 7 ]);
data . WriteByteSeq ( newGuildGuid [ 2 ]);
2012-08-10 16:06:13 +01:00
data . WriteString ( player -> GetName ());
2012-08-04 18:40:56 +02:00
data . WriteByteSeq ( oldGuildGuid [ 7 ]);
data . WriteByteSeq ( oldGuildGuid [ 6 ]);
data . WriteByteSeq ( oldGuildGuid [ 5 ]);
data . WriteByteSeq ( oldGuildGuid [ 0 ]);
data . WriteByteSeq ( newGuildGuid [ 4 ]);
2012-08-10 16:06:13 +01:00
data . WriteString ( m_name );
2012-08-04 19:11:13 +01:00
2012-08-04 18:40:56 +02:00
data . WriteByteSeq ( newGuildGuid [ 5 ]);
data . WriteByteSeq ( newGuildGuid [ 3 ]);
data . WriteByteSeq ( oldGuildGuid [ 4 ]);
2010-10-17 19:54:13 +06:00
pInvitee -> GetSession () -> SendPacket ( & data );
2012-11-02 22:23:14 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_INVITE [%s]" , pInvitee -> GetName (). c_str ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: HandleAcceptMember ( WorldSession * session )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
2010-12-23 23:25:44 +01:00
if ( ! sWorld -> getBoolConfig ( CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD ) &&
2010-12-22 21:25:23 +01:00
player -> GetTeam () != sObjectMgr -> GetPlayerTeamByGUID ( GetLeaderGUID ()))
2010-10-17 19:54:13 +06:00
return ;
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
AddMember ( player -> GetGUID ());
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: HandleLeaveMember ( WorldSession * session )
{
Player * player = session -> GetPlayer ();
// If leader is leaving
if ( _IsLeader ( player ))
{
if ( m_members . size () > 1 )
// Leader cannot leave if he is not the last member
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_QUIT , ERR_GUILD_LEADER_LEAVE );
2012-09-07 14:39:19 +02:00
else if ( GetLevel () >= sWorld -> getIntConfig ( CONFIG_GUILD_UNDELETABLE_LEVEL ))
2012-11-04 20:17:37 +01:00
SendCommandResult ( session , GUILD_COMMAND_QUIT , ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL );
2010-10-17 19:54:13 +06:00
else
2012-11-04 20:17:37 +01:00
Disband (); // Guild is disbanded if leader leaves.
2008-10-11 14:16:25 -05:00
}
else
{
2010-10-17 19:54:13 +06:00
DeleteMember ( player -> GetGUID (), false , false );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
_LogEvent ( GUILD_EVENT_LOG_LEAVE_GUILD , player -> GetGUIDLow ());
2012-10-24 13:29:34 +02:00
_BroadcastEvent ( GE_LEFT , player -> GetGUID (), player -> GetName (). c_str ());
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_QUIT , ERR_GUILD_COMMAND_SUCCESS , m_name );
2010-10-17 19:54:13 +06:00
}
2012-11-18 22:42:28 +00:00
sCalendarMgr -> RemovePlayerGuildEventsAndSignups ( player -> GetGUID (), GetId ());
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-08-04 18:40:56 +02:00
void Guild :: HandleRemoveMember ( WorldSession * session , uint64 guid )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
2012-08-04 18:40:56 +02:00
2010-10-17 19:54:13 +06:00
// Player must have rights to remove members
if ( ! _HasRankRight ( player , GR_RIGHT_REMOVE ))
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_REMOVE , ERR_GUILD_PERMISSIONS );
2012-11-04 20:17:37 +01:00
else if ( Member * member = GetMember ( guid ))
2010-10-17 19:54:13 +06:00
{
2012-11-04 20:17:37 +01:00
std :: string name = member -> GetName ();
2012-08-04 18:40:56 +02:00
// Guild masters cannot be removed
2012-05-30 08:01:02 +02:00
if ( member -> IsRank ( GR_GUILDMASTER ))
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , GUILD_COMMAND_REMOVE , ERR_GUILD_LEADER_LEAVE );
2010-10-17 19:54:13 +06:00
// Do not allow to remove player with the same rank or higher
else
{
2012-11-02 22:23:14 +01:00
Member const * memberMe = GetMember ( player -> GetGUID ());
if ( ! memberMe || member -> IsRankNotLower ( memberMe -> GetRankId ()))
SendCommandResult ( session , GUILD_COMMAND_REMOVE , ERR_GUILD_RANK_TOO_HIGH_S , name );
else
{
// After call to DeleteMember pointer to member becomes invalid
DeleteMember ( guid , false , true );
_LogEvent ( GUILD_EVENT_LOG_UNINVITE_PLAYER , player -> GetGUIDLow (), GUID_LOPART ( guid ));
_BroadcastEvent ( GE_REMOVED , 0 , name . c_str (), player -> GetName (). c_str ());
2012-11-07 23:21:19 +01:00
SendCommandResult ( session , GUILD_COMMAND_REMOVE , ERR_GUILD_COMMAND_SUCCESS , name );
2012-11-02 22:23:14 +01:00
}
2010-10-17 19:54:13 +06:00
}
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-04 20:17:37 +01:00
void Guild :: HandleUpdateMemberRank ( WorldSession * session , uint64 guid , bool demote )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
2012-11-02 22:23:14 +01:00
GuildCommandType type = demote ? GUILD_COMMAND_DEMOTE : GUILD_COMMAND_PROMOTE ;
2010-10-17 19:54:13 +06:00
// Player must have rights to promote
if ( ! _HasRankRight ( player , demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE ))
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , type , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
// Promoted player must be a member of guild
2012-11-04 20:17:37 +01:00
else if ( Member * member = GetMember ( guid ))
2008-10-11 14:16:25 -05:00
{
2012-11-04 20:17:37 +01:00
std :: string name = member -> GetName ();
2010-10-17 19:54:13 +06:00
// Player cannot promote himself
2012-05-30 08:01:02 +02:00
if ( member -> IsSamePlayer ( player -> GetGUID ()))
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , type , ERR_GUILD_NAME_INVALID );
2010-10-17 19:54:13 +06:00
return ;
}
2010-02-15 14:30:12 +01:00
2012-11-02 22:23:14 +01:00
Member const * memberMe = GetMember ( player -> GetGUID ());
uint8 rankId = memberMe -> GetRankId ();
2010-10-17 19:54:13 +06:00
if ( demote )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// Player can demote only lower rank members
2012-11-02 22:23:14 +01:00
if ( member -> IsRankNotLower ( rankId ))
2010-02-15 14:30:12 +01:00
{
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , type , ERR_GUILD_RANK_TOO_HIGH_S , name );
2010-10-17 19:54:13 +06:00
return ;
}
// Lowest rank cannot be demoted
2012-05-30 08:01:02 +02:00
if ( member -> GetRankId () >= _GetLowestRankId ())
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , type , ERR_GUILD_RANK_TOO_LOW_S , name );
2010-10-17 19:54:13 +06:00
return ;
2010-02-15 14:30:12 +01:00
}
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
else
{
// Allow to promote only to lower rank than member's rank
2012-11-02 22:23:14 +01:00
// member->GetRankId() + 1 is the highest rank that current player can promote to
if ( member -> IsRankNotLower ( rankId + 1 ))
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
SendCommandResult ( session , type , ERR_GUILD_RANK_TOO_HIGH_S , name );
2010-10-17 19:54:13 +06:00
return ;
}
}
2012-05-30 08:01:02 +02:00
uint32 newRankId = member -> GetRankId () + ( demote ? 1 : - 1 );
member -> ChangeRank ( newRankId );
_LogEvent ( demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER , player -> GetGUIDLow (), GUID_LOPART ( member -> GetGUID ()), newRankId );
2012-10-24 13:29:34 +02:00
_BroadcastEvent ( demote ? GE_DEMOTION : GE_PROMOTION , 0 , player -> GetName (). c_str (), name . c_str (), _GetRankName ( newRankId ). c_str ());
2012-08-04 18:40:56 +02:00
}
}
void Guild :: HandleSetMemberRank ( WorldSession * session , uint64 targetGuid , uint64 setterGuid , uint32 rank )
{
Player * player = session -> GetPlayer ();
2012-11-04 20:17:37 +01:00
Member * member = GetMember ( targetGuid );
GuildRankRights rights = GR_RIGHT_PROMOTE ;
GuildCommandType type = GUILD_COMMAND_PROMOTE ;
2012-08-04 18:40:56 +02:00
2012-11-04 20:17:37 +01:00
if ( rank > member -> GetRankId ())
2012-08-04 18:40:56 +02:00
{
2012-11-04 20:17:37 +01:00
rights = GR_RIGHT_DEMOTE ;
type = GUILD_COMMAND_DEMOTE ;
}
2012-08-04 19:11:13 +01:00
2012-11-04 20:17:37 +01:00
// Promoted player must be a member of guild
if ( ! _HasRankRight ( player , rights ))
{
SendCommandResult ( session , type , ERR_GUILD_PERMISSIONS );
return ;
}
2012-08-04 18:40:56 +02:00
2012-11-04 20:17:37 +01:00
// Player cannot promote himself
if ( member -> IsSamePlayer ( player -> GetGUID ()))
{
SendCommandResult ( session , type , ERR_GUILD_NAME_INVALID );
return ;
2008-10-11 14:16:25 -05:00
}
2012-11-04 20:17:37 +01:00
SendGuildRanksUpdate ( setterGuid , targetGuid , rank );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: HandleAddNewRank ( WorldSession * session , std :: string const & name )
2008-10-11 14:16:25 -05:00
{
2012-11-02 22:23:14 +01:00
uint8 size = _GetRanksSize ();
if ( size >= GUILD_RANKS_MAX_COUNT )
2010-10-17 19:54:13 +06:00
return ;
// Only leader can add new rank
2012-11-02 22:23:14 +01:00
if ( _IsLeader ( session -> GetPlayer ()))
if ( _CreateRank ( name , GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK ))
2012-11-07 23:21:19 +01:00
_BroadcastEvent ( GE_RANK_CREATED , 0 );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: HandleRemoveRank ( WorldSession * session , uint8 rankId )
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
// Cannot remove rank if total count is minimum allowed by the client or is not leader
if ( _GetRanksSize () <= GUILD_RANKS_MIN_COUNT || rankId >= _GetRanksSize () || ! _IsLeader ( session -> GetPlayer ()))
2010-10-17 19:54:13 +06:00
return ;
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
// Delete bank rights for rank
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK );
stmt -> setUInt32 ( 0 , m_id );
stmt -> setUInt8 ( 1 , rankId );
CharacterDatabase . Execute ( stmt );
// Delete rank
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_RANK );
stmt -> setUInt32 ( 0 , m_id );
stmt -> setUInt8 ( 1 , rankId );
CharacterDatabase . Execute ( stmt );
2010-10-17 19:54:13 +06:00
2012-11-07 23:21:19 +01:00
m_ranks . erase ( m_ranks . begin () + rankId );
2010-10-17 19:54:13 +06:00
2012-11-04 20:17:37 +01:00
_BroadcastEvent ( GE_RANK_DELETED , rankId );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-04 20:17:37 +01:00
void Guild :: HandleMemberDepositMoney ( WorldSession * session , uint64 amount , bool cashFlow /*=false*/ )
2010-10-17 19:54:13 +06:00
{
Player * player = session -> GetPlayer ();
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Call script after validation and before money transfer.
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildMemberDepositMoney ( this , player , amount );
2010-10-17 19:54:13 +06:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
_ModifyBankMoney ( trans , amount , true );
2012-11-04 20:17:37 +01:00
if ( ! cashFlow )
2010-10-17 19:54:13 +06:00
{
2012-11-04 20:17:37 +01:00
player -> ModifyMoney ( - int64 ( amount ));
player -> SaveGoldToDB ( trans );
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
2012-11-04 20:17:37 +01:00
_LogBankEvent ( trans , cashFlow ? GUILD_BANK_LOG_CASH_FLOW_DEPOSIT : GUILD_BANK_LOG_DEPOSIT_MONEY , uint8 ( 0 ), player -> GetGUIDLow (), amount );
2010-10-17 19:54:13 +06:00
CharacterDatabase . CommitTransaction ( trans );
2012-09-11 01:19:11 +01:00
2012-11-02 22:23:14 +01:00
std :: string aux = ByteArrayToHexStr ( reinterpret_cast < uint8 *> ( & amount ), 8 , true );
_BroadcastEvent ( GE_BANK_MONEY_CHANGED , 0 , aux . c_str ());
2013-03-08 13:15:25 +01:00
if ( player -> GetSession () -> HasPermission ( RBAC_PERM_LOG_GM_TRADE ))
2010-10-17 19:54:13 +06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outCommand ( player -> GetSession () -> GetAccountId (),
2012-11-04 20:17:37 +01:00
"GM %s (Account: %u) deposit money (Amount: " UI64FMTD ") to guild bank (Guild ID %u)" ,
2012-10-24 13:29:34 +02:00
player -> GetName (). c_str (), player -> GetSession () -> GetAccountId (), amount , m_id );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2012-11-04 20:17:37 +01:00
bool Guild :: HandleMemberWithdrawMoney ( WorldSession * session , uint64 amount , bool repair )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( m_bankMoney < amount ) // Not enough money in bank
return false ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
Member * member = GetMember ( player -> GetGUID ());
if ( ! member )
2010-10-17 19:54:13 +06:00
return false ;
2009-10-17 15:51:44 -07:00
2012-11-04 20:17:37 +01:00
if ( uint64 ( _GetMemberRemainingMoney ( member )) < amount ) // Check if we have enough slot/money today
2012-11-02 22:23:14 +01:00
return false ;
2010-11-11 22:59:06 +01:00
2010-10-17 19:54:13 +06:00
// Call script after validation and before money transfer.
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildMemberWitdrawMoney ( this , player , amount , repair );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
// Add money to player (if required)
if ( ! repair )
{
2013-02-01 11:38:55 +01:00
if ( ! player -> ModifyMoney ( amount ))
return false ;
2010-10-17 19:54:13 +06:00
player -> SaveGoldToDB ( trans );
}
2013-02-01 11:38:55 +01:00
// Update remaining money amount
member -> UpdateBankWithdrawValue ( trans , GUILD_BANK_MAX_TABS , amount );
// Remove money from bank
_ModifyBankMoney ( trans , amount , false );
2010-10-17 19:54:13 +06:00
// Log guild bank event
_LogBankEvent ( trans , repair ? GUILD_BANK_LOG_REPAIR_MONEY : GUILD_BANK_LOG_WITHDRAW_MONEY , uint8 ( 0 ), player -> GetGUIDLow (), amount );
CharacterDatabase . CommitTransaction ( trans );
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
std :: string aux = ByteArrayToHexStr ( reinterpret_cast < uint8 *> ( & amount ), 8 , true );
_BroadcastEvent ( GE_BANK_MONEY_CHANGED , 0 , aux . c_str ());
2010-10-17 19:54:13 +06:00
return true ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: HandleMemberLogout ( WorldSession * session )
{
Player * player = session -> GetPlayer ();
2012-05-30 08:01:02 +02:00
if ( Member * member = GetMember ( player -> GetGUID ()))
2010-10-17 19:54:13 +06:00
{
2012-05-30 08:01:02 +02:00
member -> SetStats ( player );
member -> UpdateLogoutTime ();
2012-11-02 22:23:14 +01:00
member -> ResetFlags ();
2008-10-11 14:16:25 -05:00
}
2012-10-24 13:29:34 +02:00
_BroadcastEvent ( GE_SIGNED_OFF , player -> GetGUID (), player -> GetName (). c_str ());
2012-08-25 15:36:45 +02:00
SaveToDB ();
2010-10-17 19:54:13 +06:00
}
void Guild :: HandleDisband ( WorldSession * session )
{
// Only leader can disband guild
2012-11-02 22:23:14 +01:00
if ( _IsLeader ( session -> GetPlayer ()))
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
Disband ();
2012-11-02 22:23:14 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "Guild Successfully Disbanded" );
2010-10-17 19:54:13 +06:00
}
}
2009-10-17 15:51:44 -07:00
2012-08-10 14:25:04 +02:00
void Guild :: HandleGuildPartyRequest ( WorldSession * session )
{
Player * player = session -> GetPlayer ();
Group * group = player -> GetGroup ();
// Make sure player is a member of the guild and that he is in a group.
if ( ! IsMember ( player -> GetGUID ()) || ! group )
return ;
WorldPacket data ( SMSG_GUILD_PARTY_STATE_RESPONSE , 13 );
2012-09-07 14:39:19 +02:00
data . WriteBit ( player -> GetMap () -> GetOwnerGuildId ( player -> GetTeam ()) == GetId ()); // Is guild group
2012-08-10 14:25:04 +02:00
data . FlushBits ();
2012-09-07 14:39:19 +02:00
data << float ( 0.f ); // Guild XP multiplier
data << uint32 ( 0 ); // Current guild members
data << uint32 ( 0 ); // Needed guild members
2012-08-10 14:25:04 +02:00
session -> SendPacket ( & data );
2012-11-04 20:17:37 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_PARTY_STATE_RESPONSE [%s]" , session -> GetPlayerInfo (). c_str ());
2012-08-10 14:25:04 +02:00
}
2011-09-15 14:08:17 +02:00
void Guild :: SendEventLog ( WorldSession * session ) const
2010-10-17 19:54:13 +06:00
{
2012-08-27 20:20:17 +02:00
WorldPacket data ( SMSG_GUILD_EVENT_LOG_QUERY_RESULT , 1 + m_eventLog -> GetSize () * ( 1 + 8 + 4 ));
2010-10-17 19:54:13 +06:00
m_eventLog -> WritePacket ( data );
session -> SendPacket ( & data );
2012-11-04 20:17:37 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_EVENT_LOG_QUERY_RESULT [%s]" , session -> GetPlayerInfo (). c_str ());
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
void Guild :: SendNewsUpdate ( WorldSession * session )
{
uint32 size = m_newsLog -> GetSize ();
GuildLog * logs = m_newsLog -> GetGuildLog ();
if ( ! logs )
return ;
WorldPacket data ( SMSG_GUILD_NEWS_UPDATE , ( 21 + size * ( 26 + 8 )) / 8 + ( 8 + 6 * 4 ) * size );
data . WriteBits ( size , 21 );
for ( GuildLog :: const_iterator itr = logs -> begin (); itr != logs -> end (); ++ itr )
{
data . WriteBits ( 0 , 26 ); // Not yet implemented used for guild achievements
ObjectGuid guid = (( NewsLogEntry * )( * itr )) -> GetPlayerGuid ();
data . WriteBit ( guid [ 7 ]);
data . WriteBit ( guid [ 0 ]);
data . WriteBit ( guid [ 6 ]);
data . WriteBit ( guid [ 5 ]);
data . WriteBit ( guid [ 4 ]);
data . WriteBit ( guid [ 3 ]);
data . WriteBit ( guid [ 1 ]);
data . WriteBit ( guid [ 2 ]);
}
data . FlushBits ();
for ( GuildLog :: const_iterator itr = logs -> begin (); itr != logs -> end (); ++ itr )
{
NewsLogEntry * news = ( NewsLogEntry * )( * itr );
ObjectGuid guid = news -> GetPlayerGuid ();
data . WriteByteSeq ( guid [ 5 ]);
data << uint32 ( news -> GetFlags ()); // 1 sticky
data << uint32 ( news -> GetValue ());
data << uint32 ( 0 );
data . WriteByteSeq ( guid [ 7 ]);
data . WriteByteSeq ( guid [ 6 ]);
data . WriteByteSeq ( guid [ 2 ]);
data . WriteByteSeq ( guid [ 3 ]);
data . WriteByteSeq ( guid [ 0 ]);
data . WriteByteSeq ( guid [ 4 ]);
data . WriteByteSeq ( guid [ 1 ]);
data << uint32 ( news -> GetGUID ());
data << uint32 ( news -> GetType ());
data . AppendPackedTime ( news -> GetTimestamp ());
}
session -> SendPacket ( & data );
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_NEWS_UPDATE [%s]" , session -> GetPlayerInfo (). c_str ());
}
2011-09-15 14:08:17 +02:00
void Guild :: SendBankLog ( WorldSession * session , uint8 tabId ) const
2010-10-17 19:54:13 +06:00
{
// GUILD_BANK_MAX_TABS send by client for money log
if ( tabId < _GetPurchasedTabsSize () || tabId == GUILD_BANK_MAX_TABS )
{
2012-08-27 20:20:17 +02:00
LogHolder const * log = m_bankEventLog [ tabId ];
WorldPacket data ( SMSG_GUILD_BANK_LOG_QUERY_RESULT , log -> GetSize () * ( 4 * 4 + 1 ) + 1 + 1 );
data . WriteBit ( GetLevel () >= 5 && tabId == GUILD_BANK_MAX_TABS ); // has Cash Flow perk
log -> WritePacket ( data );
data << uint32 ( tabId );
//if (tabId == GUILD_BANK_MAX_TABS && hasCashFlow)
// data << uint64(cashFlowContribution);
2010-10-17 19:54:13 +06:00
session -> SendPacket ( & data );
2012-11-04 20:17:37 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_BANK_LOG_QUERY_RESULT [%s] TabId: %u" , session -> GetPlayerInfo (). c_str (), tabId );
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void Guild :: SendBankTabText ( WorldSession * session , uint8 tabId ) const
2010-10-17 19:54:13 +06:00
{
2012-08-27 20:20:17 +02:00
if ( BankTab const * tab = GetBankTab ( tabId ))
tab -> SendText ( this , session );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void Guild :: SendPermissions ( WorldSession * session ) const
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
Member const * member = GetMember ( session -> GetPlayer () -> GetGUID ());
if ( ! member )
return ;
uint8 rankId = member -> GetRankId ();
2009-10-17 15:51:44 -07:00
2012-07-19 01:21:41 +02:00
WorldPacket data ( SMSG_GUILD_PERMISSIONS_QUERY_RESULTS , 4 * 15 + 1 );
2010-10-17 19:54:13 +06:00
data << uint32 ( rankId );
2012-07-19 01:21:41 +02:00
data << uint32 ( _GetPurchasedTabsSize ());
2010-10-17 19:54:13 +06:00
data << uint32 ( _GetRankRights ( rankId ));
2012-11-02 22:23:14 +01:00
data << uint32 ( _GetMemberRemainingMoney ( member ));
2012-07-19 01:21:41 +02:00
data . WriteBits ( GUILD_BANK_MAX_TABS , 23 );
2012-01-18 19:01:22 +01:00
for ( uint8 tabId = 0 ; tabId < GUILD_BANK_MAX_TABS ; ++ tabId )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
data << uint32 ( _GetRankBankTabRights ( rankId , tabId ));
2012-11-02 22:23:14 +01:00
data << uint32 ( _GetMemberRemainingSlots ( member , tabId ));
2008-10-11 14:16:25 -05:00
}
2012-07-19 01:21:41 +02:00
2010-10-17 19:54:13 +06:00
session -> SendPacket ( & data );
2012-11-04 20:17:37 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_PERMISSIONS_QUERY_RESULTS [%s] Rank: %u" , session -> GetPlayerInfo (). c_str (), rankId );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void Guild :: SendMoneyInfo ( WorldSession * session ) const
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
Member const * member = GetMember ( session -> GetPlayer () -> GetGUID ());
if ( ! member )
return ;
int32 amount = _GetMemberRemainingMoney ( member );
2012-11-07 23:21:19 +01:00
WorldPacket data ( SMSG_GUILD_BANK_MONEY_WITHDRAWN , 8 );
2012-11-04 20:17:37 +01:00
data << int64 ( amount );
2010-10-17 19:54:13 +06:00
session -> SendPacket ( & data );
2012-11-04 20:17:37 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_BANK_MONEY_WITHDRAWN [%s] Money: %u" , session -> GetPlayerInfo (). c_str (), amount );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: SendLoginInfo ( WorldSession * session )
2008-10-11 14:16:25 -05:00
{
2012-11-07 23:21:19 +01:00
Player * player = session -> GetPlayer ();
Member * member = GetMember ( player -> GetGUID ());
if ( ! member )
return ;
2012-08-22 19:50:42 +02:00
/*
Login sequence:
SMSG_GUILD_EVENT - GE_MOTD
SMSG_GUILD_RANK
SMSG_GUILD_EVENT - GE_SIGNED_ON
-- learn perks
SMSG_GUILD_REPUTATION_WEEKLY_CAP
SMSG_GUILD_ACHIEVEMENT_DATA
SMSG_GUILD_MEMBER_DAILY_RESET // bank withdrawal reset
*/
2010-10-17 19:54:13 +06:00
WorldPacket data ( SMSG_GUILD_EVENT , 1 + 1 + m_motd . size () + 1 );
data << uint8 ( GE_MOTD );
data << uint8 ( 1 );
data << m_motd ;
session -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_EVENT [%s] MOTD" , session -> GetPlayerInfo (). c_str ());
2009-10-17 15:51:44 -07:00
2012-11-04 20:17:37 +01:00
SendGuildRankInfo ( session );
2012-11-02 22:23:14 +01:00
_BroadcastEvent ( GE_SIGNED_ON , player -> GetGUID (), player -> GetName (). c_str ());
2012-08-22 19:50:42 +02:00
// Send to self separately, player is not in world yet and is not found by _BroadcastEvent
2012-11-07 23:21:19 +01:00
data . Initialize ( SMSG_GUILD_EVENT , 1 + 1 + player -> GetName (). size () + 8 );
2012-08-22 19:50:42 +02:00
data << uint8 ( GE_SIGNED_ON );
data << uint8 ( 1 );
2012-11-04 20:17:37 +01:00
data << player -> GetName ();
data << uint64 ( player -> GetGUID ());
2012-08-22 19:50:42 +02:00
session -> SendPacket ( & data );
2012-09-07 14:39:19 +02:00
data . Initialize ( SMSG_GUILD_MEMBER_DAILY_RESET , 0 ); // tells the client to request bank withdrawal limit
session -> SendPacket ( & data );
if ( ! sWorld -> getBoolConfig ( CONFIG_GUILD_LEVELING_ENABLED ))
return ;
2012-08-22 19:50:42 +02:00
for ( uint32 i = 0 ; i < sGuildPerkSpellsStore . GetNumRows (); ++ i )
if ( GuildPerkSpellsEntry const * entry = sGuildPerkSpellsStore . LookupEntry ( i ))
2012-10-18 02:48:36 +03:00
if ( entry -> Level <= GetLevel ())
2012-11-07 23:21:19 +01:00
player -> learnSpell ( entry -> SpellId , true );
2012-08-22 19:50:42 +02:00
2012-11-07 23:21:19 +01:00
SendGuildReputationWeeklyCap ( session , member -> GetWeekReputation ());
2012-08-22 19:50:42 +02:00
2012-11-07 23:21:19 +01:00
m_achievementMgr . SendAllAchievementData ( player );
2012-11-04 20:17:37 +01:00
2012-11-07 23:21:19 +01:00
member -> SetStats ( player );
member -> AddFlag ( GUILDMEMBER_STATUS_ONLINE );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Loading methods
bool Guild :: LoadFromDB ( Field * fields )
{
m_id = fields [ 0 ]. GetUInt32 ();
m_name = fields [ 1 ]. GetString ();
m_leaderGuid = MAKE_NEW_GUID ( fields [ 2 ]. GetUInt32 (), 0 , HIGHGUID_PLAYER );
m_emblemInfo . LoadFromDB ( fields );
m_info = fields [ 8 ]. GetString ();
m_motd = fields [ 9 ]. GetString ();
2011-01-20 00:08:45 +01:00
m_createdDate = time_t ( fields [ 10 ]. GetUInt32 ());
2010-10-17 19:54:13 +06:00
m_bankMoney = fields [ 11 ]. GetUInt64 ();
2012-09-07 14:39:19 +02:00
_level = fields [ 12 ]. GetUInt32 ();
_experience = fields [ 13 ]. GetUInt64 ();
_todayExperience = fields [ 14 ]. GetUInt64 ();
2010-10-17 19:54:13 +06:00
2012-09-07 14:39:19 +02:00
uint8 purchasedTabs = uint8 ( fields [ 15 ]. GetUInt64 ());
2010-10-17 19:54:13 +06:00
if ( purchasedTabs > GUILD_BANK_MAX_TABS )
purchasedTabs = GUILD_BANK_MAX_TABS ;
m_bankTabs . resize ( purchasedTabs );
for ( uint8 i = 0 ; i < purchasedTabs ; ++ i )
m_bankTabs [ i ] = new BankTab ( m_id , i );
_CreateLogHolders ();
return true ;
}
2011-03-10 22:21:50 +01:00
void Guild :: LoadRankFromDB ( Field * fields )
2010-10-17 19:54:13 +06:00
{
RankInfo rankInfo ( m_id );
2011-03-10 22:21:50 +01:00
rankInfo . LoadFromDB ( fields );
2010-10-17 19:54:13 +06:00
m_ranks . push_back ( rankInfo );
}
bool Guild :: LoadMemberFromDB ( Field * fields )
{
uint32 lowguid = fields [ 1 ]. GetUInt32 ();
2012-05-30 08:01:02 +02:00
Member * member = new Member ( m_id , MAKE_NEW_GUID ( lowguid , 0 , HIGHGUID_PLAYER ), fields [ 2 ]. GetUInt8 ());
if ( ! member -> LoadFromDB ( fields ))
2010-10-17 19:54:13 +06:00
{
_DeleteMemberFromDB ( lowguid );
2012-05-30 08:01:02 +02:00
delete member ;
2010-10-17 19:54:13 +06:00
return false ;
}
2012-05-30 08:01:02 +02:00
m_members [ lowguid ] = member ;
2010-10-17 19:54:13 +06:00
return true ;
}
2011-03-10 22:21:50 +01:00
void Guild :: LoadBankRightFromDB ( Field * fields )
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
// tabId rights slots
GuildBankRightsAndSlots rightsAndSlots ( fields [ 1 ]. GetUInt8 (), fields [ 3 ]. GetUInt8 (), fields [ 4 ]. GetUInt32 ());
// rankId
_SetRankBankTabRightsAndSlots ( fields [ 2 ]. GetUInt8 (), rightsAndSlots , false );
2010-10-17 19:54:13 +06:00
}
bool Guild :: LoadEventLogFromDB ( Field * fields )
{
if ( m_eventLog -> CanInsert ())
{
m_eventLog -> LoadEvent ( new EventLogEntry (
m_id , // guild id
fields [ 1 ]. GetUInt32 (), // guid
2011-01-20 01:02:24 +01:00
time_t ( fields [ 6 ]. GetUInt32 ()), // timestamp
2010-10-17 19:54:13 +06:00
GuildEventLogTypes ( fields [ 2 ]. GetUInt8 ()), // event type
fields [ 3 ]. GetUInt32 (), // player guid 1
fields [ 4 ]. GetUInt32 (), // player guid 2
fields [ 5 ]. GetUInt8 ())); // rank
return true ;
}
return false ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
bool Guild :: LoadBankEventLogFromDB ( Field * fields )
{
uint8 dbTabId = fields [ 1 ]. GetUInt8 ();
bool isMoneyTab = ( dbTabId == GUILD_BANK_MONEY_LOGS_TAB );
if ( dbTabId < _GetPurchasedTabsSize () || isMoneyTab )
{
uint8 tabId = isMoneyTab ? uint8 ( GUILD_BANK_MAX_TABS ) : dbTabId ;
LogHolder * pLog = m_bankEventLog [ tabId ];
if ( pLog -> CanInsert ())
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
uint32 guid = fields [ 2 ]. GetUInt32 ();
GuildBankEventLogTypes eventType = GuildBankEventLogTypes ( fields [ 3 ]. GetUInt8 ());
if ( BankEventLogEntry :: IsMoneyEvent ( eventType ))
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( ! isMoneyTab )
2008-10-11 14:16:25 -05:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "GuildBankEventLog ERROR: MoneyEvent(LogGuid: %u, Guild: %u) does not belong to money tab (%u), ignoring..." , guid , m_id , dbTabId );
2010-10-17 19:54:13 +06:00
return false ;
2008-10-11 14:16:25 -05:00
}
}
2010-10-17 19:54:13 +06:00
else if ( isMoneyTab )
2008-10-11 14:16:25 -05:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "GuildBankEventLog ERROR: non-money event (LogGuid: %u, Guild: %u) belongs to money tab, ignoring..." , guid , m_id );
2010-10-17 19:54:13 +06:00
return false ;
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
pLog -> LoadEvent ( new BankEventLogEntry (
m_id , // guild id
guid , // guid
2011-01-20 00:08:45 +01:00
time_t ( fields [ 8 ]. GetUInt32 ()), // timestamp
2010-10-17 19:54:13 +06:00
dbTabId , // tab id
eventType , // event type
fields [ 4 ]. GetUInt32 (), // player guid
fields [ 5 ]. GetUInt32 (), // item or money
fields [ 6 ]. GetUInt16 (), // itam stack count
fields [ 7 ]. GetUInt8 ())); // dest tab id
2008-10-11 14:16:25 -05:00
}
}
2010-10-17 19:54:13 +06:00
return true ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
void Guild :: LoadGuildNewsLogFromDB ( Field * fields )
{
if ( ! m_newsLog -> CanInsert ())
return ;
m_newsLog -> LoadEvent ( new NewsLogEntry (
m_id , // guild id
fields [ 1 ]. GetUInt32 (), // guid
fields [ 6 ]. GetUInt32 (), // timestamp //64 bits?
GuildNews ( fields [ 2 ]. GetUInt8 ()), // type
fields [ 3 ]. GetUInt32 (), // player guid
fields [ 4 ]. GetUInt32 (), // Flags
fields [ 5 ]. GetUInt32 ())); // value
}
2012-11-02 22:23:14 +01:00
void Guild :: LoadBankTabFromDB ( Field * fields )
2008-10-11 14:16:25 -05:00
{
2012-05-30 08:01:02 +02:00
uint8 tabId = fields [ 1 ]. GetUInt8 ();
2010-10-17 19:54:13 +06:00
if ( tabId >= _GetPurchasedTabsSize ())
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Invalid tab (tabId: %u) in guild bank, skipped." , tabId );
2012-11-02 22:23:14 +01:00
else
m_bankTabs [ tabId ] -> LoadFromDB ( fields );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
bool Guild :: LoadBankItemFromDB ( Field * fields )
{
uint8 tabId = fields [ 12 ]. GetUInt8 ();
if ( tabId >= _GetPurchasedTabsSize ())
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Invalid tab for item (GUID: %u, id: #%u) in guild bank, skipped." ,
2010-10-17 19:54:13 +06:00
fields [ 14 ]. GetUInt32 (), fields [ 15 ]. GetUInt32 ());
return false ;
}
return m_bankTabs [ tabId ] -> LoadItemFromDB ( fields );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Validates guild data loaded from database. Returns false if guild should be deleted.
bool Guild :: Validate ()
{
// Validate ranks data
// GUILD RANKS represent a 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++
2011-04-29 20:47:02 +02:00
// Between ranks in sequence cannot be gaps - so 0, 1, 2, 4 is impossible
2012-11-04 20:17:37 +01:00
// Min ranks count is 2 and max is 10.
2010-10-17 19:54:13 +06:00
bool broken_ranks = false ;
2012-11-02 22:23:14 +01:00
uint8 ranks = _GetRanksSize ();
if ( ranks < GUILD_RANKS_MIN_COUNT || ranks > GUILD_RANKS_MAX_COUNT )
2010-10-17 19:54:13 +06:00
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Guild %u has invalid number of ranks, creating new..." , m_id );
2010-10-17 19:54:13 +06:00
broken_ranks = true ;
}
else
{
2012-11-02 22:23:14 +01:00
for ( uint8 rankId = 0 ; rankId < ranks ; ++ rankId )
2010-10-17 19:54:13 +06:00
{
RankInfo * rankInfo = GetRankInfo ( rankId );
if ( rankInfo -> GetId () != rankId )
{
2012-08-03 14:20:18 +02:00
sLog -> outError ( LOG_FILTER_GUILD , "Guild %u has broken rank id %u, creating default set of ranks..." , m_id , rankId );
2010-10-17 19:54:13 +06:00
broken_ranks = true ;
}
2012-11-02 22:23:14 +01:00
else
{
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2012-11-07 09:46:42 +01:00
rankInfo -> CreateMissingTabsIfNeeded ( _GetPurchasedTabsSize (), trans , true );
CharacterDatabase . CommitTransaction ( trans );
2012-11-02 22:23:14 +01:00
}
2010-10-17 19:54:13 +06:00
}
}
2011-12-10 13:48:41 +01:00
2010-10-17 19:54:13 +06:00
if ( broken_ranks )
{
m_ranks . clear ();
_CreateDefaultGuildRanks ( DEFAULT_LOCALE );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Validate members' data
for ( Members :: iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
if ( itr -> second -> GetRankId () > _GetRanksSize ())
itr -> second -> ChangeRank ( _GetLowestRankId ());
2009-12-06 17:46:44 +01:00
2010-10-17 19:54:13 +06:00
// Repair the structure of the guild.
// If the guildmaster doesn't exist or isn't member of the guild
// attempt to promote another member.
Member * pLeader = GetMember ( m_leaderGuid );
if ( ! pLeader )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
DeleteMember ( m_leaderGuid );
// If no more members left, disband guild
if ( m_members . empty ())
{
Disband ();
return false ;
}
}
else if ( ! pLeader -> IsRank ( GR_GUILDMASTER ))
_SetLeaderGUID ( pLeader );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Check config if multiple guildmasters are allowed
2011-09-28 13:00:43 +02:00
if ( ! ConfigMgr :: GetBoolDefault ( "Guild.AllowMultipleGuildMaster" , 0 ))
2010-10-17 19:54:13 +06:00
for ( Members :: iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
if ( itr -> second -> GetRankId () == GR_GUILDMASTER && ! itr -> second -> IsSamePlayer ( m_leaderGuid ))
itr -> second -> ChangeRank ( GR_OFFICER );
_UpdateAccountsNumber ();
return true ;
}
// Broadcasts
2012-11-02 22:23:14 +01:00
void Guild :: BroadcastToGuild ( WorldSession * session , bool officerOnly , std :: string const & msg , uint32 language ) const
2010-10-17 19:54:13 +06:00
{
if ( session && session -> GetPlayer () && _HasRankRight ( session -> GetPlayer (), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK ))
{
WorldPacket data ;
ChatHandler :: FillMessageData ( & data , session , officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD , language , NULL , 0 , msg . c_str (), NULL );
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
2011-06-12 01:47:45 +02:00
if ( Player * player = itr -> second -> FindPlayer ())
2010-12-13 22:37:56 +01:00
if ( player -> GetSession () && _HasRankRight ( player , officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN ) &&
2010-10-17 19:54:13 +06:00
! player -> GetSocial () -> HasIgnore ( session -> GetPlayer () -> GetGUIDLow ()))
player -> GetSession () -> SendPacket ( & data );
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
}
2012-11-04 20:17:37 +01:00
void Guild :: BroadcastAddonToGuild ( WorldSession * session , bool officerOnly , std :: string const & msg , std :: string const & prefix ) const
2012-08-04 15:58:09 +01:00
{
if ( session && session -> GetPlayer () && _HasRankRight ( session -> GetPlayer (), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK ))
{
WorldPacket data ;
2013-01-31 00:35:33 +01:00
ChatHandler :: FillMessageData ( & data , session , officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD , uint32 ( CHAT_MSG_ADDON ), NULL , 0 , msg . c_str (), NULL , prefix . c_str ());
2012-08-04 15:58:09 +01:00
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
if ( Player * player = itr -> second -> FindPlayer ())
if ( player -> GetSession () && _HasRankRight ( player , officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN ) &&
2012-08-10 02:01:25 +01:00
! player -> GetSocial () -> HasIgnore ( session -> GetPlayer () -> GetGUIDLow ()) &&
player -> GetSession () -> IsAddonRegistered ( prefix ))
player -> GetSession () -> SendPacket ( & data );
2012-08-04 15:58:09 +01:00
}
}
2011-06-12 02:06:07 +02:00
void Guild :: BroadcastPacketToRank ( WorldPacket * packet , uint8 rankId ) const
2010-10-17 19:54:13 +06:00
{
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
if ( itr -> second -> IsRank ( rankId ))
2011-06-12 01:47:45 +02:00
if ( Player * player = itr -> second -> FindPlayer ())
2010-10-17 19:54:13 +06:00
player -> GetSession () -> SendPacket ( packet );
}
2009-10-17 15:51:44 -07:00
2011-06-12 02:06:07 +02:00
void Guild :: BroadcastPacket ( WorldPacket * packet ) const
2010-10-17 19:54:13 +06:00
{
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
2011-06-12 01:47:45 +02:00
if ( Player * player = itr -> second -> FindPlayer ())
2010-10-17 19:54:13 +06:00
player -> GetSession () -> SendPacket ( packet );
}
2009-10-17 15:51:44 -07:00
2012-11-18 22:42:28 +00:00
void Guild :: MassInviteToEvent ( WorldSession * session , uint32 minLevel , uint32 maxLevel , uint32 minRank )
{
uint32 count = 0 ;
WorldPacket data ( SMSG_CALENDAR_FILTER_GUILD );
data << uint32 ( count ); // count placeholder
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
{
// not sure if needed, maybe client checks it as well
if ( count >= CALENDAR_MAX_INVITES )
{
if ( Player * player = session -> GetPlayer ())
sCalendarMgr -> SendCalendarCommandResult ( player -> GetGUID (), CALENDAR_ERROR_INVITES_EXCEEDED );
return ;
}
Member * member = itr -> second ;
uint32 level = Player :: GetLevelFromDB ( member -> GetGUID ());
if ( member -> GetGUID () != session -> GetPlayer () -> GetGUID () && level >= minLevel && level <= maxLevel && member -> IsRankNotLower ( minRank ))
{
data . appendPackGUID ( member -> GetGUID ());
data << uint8 ( 0 ); // unk
++ count ;
}
}
data . put < uint32 > ( 0 , count );
session -> SendPacket ( & data );
}
2010-10-17 19:54:13 +06:00
// Members handling
2011-08-30 13:46:36 +02:00
bool Guild :: AddMember ( uint64 guid , uint8 rankId )
2010-10-17 19:54:13 +06:00
{
2011-07-27 12:14:27 +02:00
Player * player = ObjectAccessor :: FindPlayer ( guid );
2010-10-17 19:54:13 +06:00
// Player cannot be in guild
if ( player )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( player -> GetGuildId () != 0 )
return false ;
}
else if ( Player :: GetGuildIdFromDB ( guid ) != 0 )
return false ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Remove all player signs from another petitions
// This will be prevent attempt to join many guilds and corrupt guild data integrity
Player :: RemovePetitionsAndSigns ( guid , GUILD_CHARTER_TYPE );
uint32 lowguid = GUID_LOPART ( guid );
2011-12-22 19:53:47 +00:00
// If rank was not passed, assign lowest possible rank
2010-10-17 19:54:13 +06:00
if ( rankId == GUILD_RANK_NONE )
rankId = _GetLowestRankId ();
2012-05-30 08:01:02 +02:00
Member * member = new Member ( m_id , guid , rankId );
2012-11-02 22:23:14 +01:00
std :: string name ;
2010-10-17 19:54:13 +06:00
if ( player )
2012-11-02 22:23:14 +01:00
{
2012-11-07 23:21:19 +01:00
m_members [ lowguid ] = member ;
2012-11-02 22:23:14 +01:00
player -> SetInGuild ( m_id );
player -> SetGuildIdInvited ( 0 );
player -> SetRank ( rankId );
2012-11-04 20:17:37 +01:00
player -> SetGuildLevel ( GetLevel ());
2012-11-02 22:23:14 +01:00
SendLoginInfo ( player -> GetSession ());
name = player -> GetName ();
}
2010-10-17 19:54:13 +06:00
else
{
2012-11-02 22:23:14 +01:00
member -> ResetFlags ();
2010-10-17 19:54:13 +06:00
bool ok = false ;
// Player must exist
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_SEL_CHAR_DATA_FOR_GUILD );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , lowguid );
if ( PreparedQueryResult result = CharacterDatabase . Query ( stmt ))
{
2011-09-15 14:08:17 +02:00
Field * fields = result -> Fetch ();
2012-11-02 22:23:14 +01:00
name = fields [ 0 ]. GetString ();
2012-05-30 08:01:02 +02:00
member -> SetStats (
2012-11-02 22:23:14 +01:00
name ,
2010-12-13 22:37:56 +01:00
fields [ 1 ]. GetUInt8 (),
2010-10-17 19:54:13 +06:00
fields [ 2 ]. GetUInt8 (),
2011-01-19 22:46:21 +01:00
fields [ 3 ]. GetUInt16 (),
2012-11-07 23:21:19 +01:00
fields [ 4 ]. GetUInt32 (),
0 );
2010-10-17 19:54:13 +06:00
2012-05-30 08:01:02 +02:00
ok = member -> CheckStats ();
2010-10-17 19:54:13 +06:00
}
2012-11-07 23:21:19 +01:00
2010-10-17 19:54:13 +06:00
if ( ! ok )
{
2012-05-30 08:01:02 +02:00
delete member ;
2010-10-17 19:54:13 +06:00
return false ;
}
2012-11-07 23:21:19 +01:00
m_members [ lowguid ] = member ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
SQLTransaction trans ( NULL );
2012-05-30 08:01:02 +02:00
member -> SaveToDB ( trans );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
_UpdateAccountsNumber ();
2012-11-02 22:23:14 +01:00
_LogEvent ( GUILD_EVENT_LOG_JOIN_GUILD , lowguid );
_BroadcastEvent ( GE_JOINED , guid , name . c_str ());
2013-01-02 05:19:18 +01:00
sGuildFinderMgr -> RemoveAllMembershipRequestsFromPlayer ( lowguid );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Call scripts if member was succesfully added (and stored to database)
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildAddMember ( this , player , rankId );
2010-10-17 19:54:13 +06:00
return true ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-08-30 13:46:36 +02:00
void Guild :: DeleteMember ( uint64 guid , bool isDisbanding , bool isKicked )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
uint32 lowguid = GUID_LOPART ( guid );
2011-07-27 12:14:27 +02:00
Player * player = ObjectAccessor :: FindPlayer ( guid );
2010-08-13 17:39:43 +06:00
2010-10-17 19:54:13 +06: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
if ( m_leaderGuid == guid && ! isDisbanding )
{
Member * oldLeader = NULL ;
Member * newLeader = NULL ;
for ( Guild :: Members :: iterator i = m_members . begin (); i != m_members . end (); ++ i )
{
if ( i -> first == lowguid )
oldLeader = i -> second ;
else if ( ! newLeader || newLeader -> GetRankId () > i -> second -> GetRankId ())
newLeader = i -> second ;
}
2012-09-18 11:33:09 +02:00
2010-10-17 19:54:13 +06:00
if ( ! newLeader )
{
Disband ();
return ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
_SetLeaderGUID ( newLeader );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// If player not online data in data field will be loaded from guild tabs no need to update it !!
2011-09-15 14:08:17 +02:00
if ( Player * newLeaderPlayer = newLeader -> FindPlayer ())
2010-10-17 19:54:13 +06:00
newLeaderPlayer -> SetRank ( GR_GUILDMASTER );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// If leader does not exist (at guild loading with deleted leader) do not send broadcasts
if ( oldLeader )
{
_BroadcastEvent ( GE_LEADER_CHANGED , 0 , oldLeader -> GetName (). c_str (), newLeader -> GetName (). c_str ());
_BroadcastEvent ( GE_LEFT , guid , oldLeader -> GetName (). c_str ());
}
}
2012-09-18 11:33:09 +02:00
// Call script on remove before member is actually removed from guild (and database)
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildRemoveMember ( this , player , isDisbanding , isKicked );
2009-10-17 15:51:44 -07:00
2012-05-30 08:01:02 +02:00
if ( Member * member = GetMember ( guid ))
delete member ;
2010-10-17 19:54:13 +06:00
m_members . erase ( lowguid );
// If player not online data in data field will be loaded from guild tabs no need to update it !!
if ( player )
{
player -> SetInGuild ( 0 );
player -> SetRank ( 0 );
2012-09-07 14:39:19 +02:00
player -> SetGuildLevel ( 0 );
2012-11-07 23:21:19 +01:00
2012-09-07 14:39:19 +02:00
for ( uint32 i = 0 ; i < sGuildPerkSpellsStore . GetNumRows (); ++ i )
if ( GuildPerkSpellsEntry const * entry = sGuildPerkSpellsStore . LookupEntry ( i ))
2012-10-18 02:48:36 +03:00
if ( entry -> Level <= GetLevel ())
2012-09-07 14:39:19 +02:00
player -> removeSpell ( entry -> SpellId , false , false );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
_DeleteMemberFromDB ( lowguid );
if ( ! isDisbanding )
_UpdateAccountsNumber ();
}
2011-08-30 13:46:36 +02:00
bool Guild :: ChangeMemberRank ( uint64 guid , uint8 newRank )
2010-10-17 19:54:13 +06:00
{
if ( newRank <= _GetLowestRankId ()) // Validate rank (allow only existing ranks)
2012-05-30 08:01:02 +02:00
if ( Member * member = GetMember ( guid ))
2010-10-17 19:54:13 +06:00
{
2012-05-30 08:01:02 +02:00
member -> ChangeRank ( newRank );
2010-10-17 19:54:13 +06:00
return true ;
}
return false ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2012-11-07 23:21:19 +01:00
bool Guild :: IsMember ( uint64 guid ) const
2011-12-22 03:49:36 +00:00
{
Members :: const_iterator itr = m_members . find ( GUID_LOPART ( guid ));
return itr != m_members . end ();
}
2010-10-17 19:54:13 +06:00
// Bank (items move)
void Guild :: SwapItems ( Player * player , uint8 tabId , uint8 slotId , uint8 destTabId , uint8 destSlotId , uint32 splitedAmount )
2008-10-11 14:16:25 -05:00
{
2010-12-13 22:37:56 +01:00
if ( tabId >= _GetPurchasedTabsSize () || slotId >= GUILD_BANK_MAX_SLOTS ||
2010-10-17 19:54:13 +06:00
destTabId >= _GetPurchasedTabsSize () || destSlotId >= GUILD_BANK_MAX_SLOTS )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( tabId == destTabId && slotId == destSlotId )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
BankMoveItemData from ( this , player , tabId , slotId );
BankMoveItemData to ( this , player , destTabId , destSlotId );
_MoveItems ( & from , & to , splitedAmount );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: SwapItemsWithInventory ( Player * player , bool toChar , uint8 tabId , uint8 slotId , uint8 playerBag , uint8 playerSlotId , uint32 splitedAmount )
2009-08-24 20:18:16 -05:00
{
2010-10-17 19:54:13 +06:00
if (( slotId >= GUILD_BANK_MAX_SLOTS && slotId != NULL_SLOT ) || tabId >= _GetPurchasedTabsSize ())
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
BankMoveItemData bankData ( this , player , tabId , slotId );
PlayerMoveItemData charData ( this , player , playerBag , playerSlotId );
if ( toChar )
_MoveItems ( & bankData , & charData , splitedAmount );
else
_MoveItems ( & charData , & bankData , splitedAmount );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Bank tabs
2012-11-02 22:23:14 +01:00
void Guild :: SetBankTabText ( uint8 tabId , std :: string const & text )
2010-10-17 19:54:13 +06:00
{
if ( BankTab * pTab = GetBankTab ( tabId ))
2009-11-20 22:38:01 -08:00
{
2010-10-17 19:54:13 +06:00
pTab -> SetText ( text );
pTab -> SendText ( this , NULL );
2009-11-20 22:38:01 -08:00
}
2010-10-17 19:54:13 +06:00
}
2009-11-20 22:38:01 -08:00
2010-10-17 19:54:13 +06:00
// Private methods
void Guild :: _CreateLogHolders ()
{
2010-12-23 23:25:44 +01:00
m_eventLog = new LogHolder ( m_id , sWorld -> getIntConfig ( CONFIG_GUILD_EVENT_LOG_COUNT ));
2012-11-07 23:21:19 +01:00
m_newsLog = new LogHolder ( m_id , sWorld -> getIntConfig ( CONFIG_GUILD_NEWS_LOG_COUNT ));
2010-10-17 19:54:13 +06:00
for ( uint8 tabId = 0 ; tabId <= GUILD_BANK_MAX_TABS ; ++ tabId )
2010-12-23 23:25:44 +01:00
m_bankEventLog [ tabId ] = new LogHolder ( m_id , sWorld -> getIntConfig ( CONFIG_GUILD_BANK_EVENT_LOG_COUNT ));
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: _CreateNewBankTab ()
2010-10-17 19:54:13 +06:00
{
uint8 tabId = _GetPurchasedTabsSize (); // Next free id
m_bankTabs . push_back ( new BankTab ( m_id , tabId ));
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_TAB );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_id );
stmt -> setUInt8 ( 1 , tabId );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2012-01-01 01:09:38 +01:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_BANK_TAB );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_id );
stmt -> setUInt8 ( 1 , tabId );
trans -> Append ( stmt );
2009-10-17 15:51:44 -07:00
2012-11-08 11:13:46 +01:00
++ tabId ;
for ( Ranks :: iterator itr = m_ranks . begin (); itr != m_ranks . end (); ++ itr )
( * itr ). CreateMissingTabsIfNeeded ( tabId , trans , false );
2010-10-17 19:54:13 +06:00
CharacterDatabase . CommitTransaction ( trans );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: _CreateDefaultGuildRanks ( LocaleConstant loc )
{
2012-11-02 22:23:14 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_RANKS );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_id );
CharacterDatabase . Execute ( stmt );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_RIGHTS );
stmt -> setUInt32 ( 0 , m_id );
CharacterDatabase . Execute ( stmt );
2009-10-17 15:51:44 -07:00
2010-12-22 21:25:23 +01:00
_CreateRank ( sObjectMgr -> GetTrinityString ( LANG_GUILD_MASTER , loc ), GR_RIGHT_ALL );
_CreateRank ( sObjectMgr -> GetTrinityString ( LANG_GUILD_OFFICER , loc ), GR_RIGHT_ALL );
_CreateRank ( sObjectMgr -> GetTrinityString ( LANG_GUILD_VETERAN , loc ), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK );
_CreateRank ( sObjectMgr -> GetTrinityString ( LANG_GUILD_MEMBER , loc ), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK );
_CreateRank ( sObjectMgr -> GetTrinityString ( LANG_GUILD_INITIATE , loc ), GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
bool Guild :: _CreateRank ( std :: string const & name , uint32 rights )
2010-10-17 19:54:13 +06:00
{
uint8 newRankId = _GetRanksSize ();
2012-09-18 11:33:09 +02:00
if ( newRankId >= GUILD_RANKS_MAX_COUNT )
2012-11-02 22:23:14 +01:00
return false ;
2009-10-17 15:51:44 -07:00
2011-04-29 20:47:02 +02:00
// Ranks represent sequence 0, 1, 2, ... where 0 means guildmaster
2010-10-17 19:54:13 +06:00
RankInfo info ( m_id , newRankId , name , rights , 0 );
m_ranks . push_back ( info );
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2012-11-02 22:23:14 +01:00
info . CreateMissingTabsIfNeeded ( _GetPurchasedTabsSize (), trans );
2010-10-17 19:54:13 +06:00
info . SaveToDB ( trans );
CharacterDatabase . CommitTransaction ( trans );
2012-11-02 22:23:14 +01:00
return true ;
2009-08-24 20:18:16 -05:00
}
2010-10-17 19:54:13 +06:00
// Updates the number of accounts that are in the guild
// Player may have many characters in the guild, but with the same account
void Guild :: _UpdateAccountsNumber ()
2009-08-24 20:18:16 -05:00
{
2010-10-17 19:54:13 +06:00
// We use a set to be sure each element will be unique
std :: set < uint32 > accountsIdSet ;
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
accountsIdSet . insert ( itr -> second -> GetAccountId ());
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_accountsNumber = accountsIdSet . size ();
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Detects if player is the guild master.
2010-12-13 22:37:56 +01:00
// Check both leader guid and player's rank (otherwise multiple feature with
2010-10-17 19:54:13 +06:00
// multiple guild masters won't work)
bool Guild :: _IsLeader ( Player * player ) const
{
if ( player -> GetGUID () == m_leaderGuid )
return true ;
2012-05-30 08:01:02 +02:00
if ( const Member * member = GetMember ( player -> GetGUID ()))
return member -> IsRank ( GR_GUILDMASTER );
2010-10-17 19:54:13 +06:00
return false ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: _DeleteBankItems ( SQLTransaction & trans , bool removeItemsFromDB )
{
for ( uint8 tabId = 0 ; tabId < _GetPurchasedTabsSize (); ++ tabId )
{
m_bankTabs [ tabId ] -> Delete ( trans , removeItemsFromDB );
delete m_bankTabs [ tabId ];
m_bankTabs [ tabId ] = NULL ;
}
m_bankTabs . clear ();
}
2009-10-17 15:51:44 -07:00
2011-08-30 13:46:36 +02:00
bool Guild :: _ModifyBankMoney ( SQLTransaction & trans , uint64 amount , bool add )
2010-10-17 19:54:13 +06:00
{
if ( add )
m_bankMoney += amount ;
else
{
// Check if there is enough money in bank.
if ( m_bankMoney < amount )
return false ;
m_bankMoney -= amount ;
}
2009-10-17 15:51:44 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_BANK_MONEY );
2010-10-17 19:54:13 +06:00
stmt -> setUInt64 ( 0 , m_bankMoney );
stmt -> setUInt32 ( 1 , m_id );
trans -> Append ( stmt );
return true ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: _SetLeaderGUID ( Member * pLeader )
{
if ( ! pLeader )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_leaderGuid = pLeader -> GetGUID ();
pLeader -> ChangeRank ( GR_GUILDMASTER );
2009-10-17 15:51:44 -07:00
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_LEADER );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , GUID_LOPART ( m_leaderGuid ));
stmt -> setUInt32 ( 1 , m_id );
CharacterDatabase . Execute ( stmt );
}
void Guild :: _SetRankBankMoneyPerDay ( uint8 rankId , uint32 moneyPerDay )
{
if ( RankInfo * rankInfo = GetRankInfo ( rankId ))
rankInfo -> SetBankMoneyPerDay ( moneyPerDay );
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
void Guild :: _SetRankBankTabRightsAndSlots ( uint8 rankId , GuildBankRightsAndSlots rightsAndSlots , bool saveToDB )
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
if ( rightsAndSlots . GetTabId () >= _GetPurchasedTabsSize ())
2010-10-17 19:54:13 +06:00
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( RankInfo * rankInfo = GetRankInfo ( rankId ))
2012-11-02 22:23:14 +01:00
rankInfo -> SetBankTabSlotsAndRights ( rightsAndSlots , saveToDB );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
inline std :: string Guild :: _GetRankName ( uint8 rankId ) const
{
if ( const RankInfo * rankInfo = GetRankInfo ( rankId ))
return rankInfo -> GetName ();
return "<unknown>" ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
inline uint32 Guild :: _GetRankRights ( uint8 rankId ) const
{
if ( const RankInfo * rankInfo = GetRankInfo ( rankId ))
return rankInfo -> GetRights ();
return 0 ;
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
inline int32 Guild :: _GetRankBankMoneyPerDay ( uint8 rankId ) const
2010-10-17 19:54:13 +06:00
{
if ( const RankInfo * rankInfo = GetRankInfo ( rankId ))
return rankInfo -> GetBankMoneyPerDay ();
return 0 ;
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
inline int32 Guild :: _GetRankBankTabSlotsPerDay ( uint8 rankId , uint8 tabId ) const
2010-10-17 19:54:13 +06:00
{
if ( tabId < _GetPurchasedTabsSize ())
if ( const RankInfo * rankInfo = GetRankInfo ( rankId ))
return rankInfo -> GetBankTabSlotsPerDay ( tabId );
return 0 ;
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
inline int8 Guild :: _GetRankBankTabRights ( uint8 rankId , uint8 tabId ) const
2010-10-17 19:54:13 +06:00
{
if ( const RankInfo * rankInfo = GetRankInfo ( rankId ))
return rankInfo -> GetBankTabRights ( tabId );
return 0 ;
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
inline int32 Guild :: _GetMemberRemainingSlots ( Member const * member , uint8 tabId ) const
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
if ( member )
{
uint8 rankId = member -> GetRankId ();
if ( rankId == GR_GUILDMASTER )
return GUILD_WITHDRAW_SLOT_UNLIMITED ;
if (( _GetRankBankTabRights ( rankId , tabId ) & GUILD_BANK_RIGHT_VIEW_TAB ) != GR_RIGHT_EMPTY )
{
int32 remaining = _GetRankBankTabSlotsPerDay ( rankId , tabId ) - member -> GetBankWithdrawValue ( tabId );
if ( remaining > 0 )
return remaining ;
}
}
2010-10-17 19:54:13 +06:00
return 0 ;
}
2012-11-02 22:23:14 +01:00
inline int32 Guild :: _GetMemberRemainingMoney ( Member const * member ) const
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
if ( member )
{
uint8 rankId = member -> GetRankId ();
if ( rankId == GR_GUILDMASTER )
return GUILD_WITHDRAW_MONEY_UNLIMITED ;
if (( _GetRankRights ( rankId ) & ( GR_RIGHT_WITHDRAW_REPAIR | GR_RIGHT_WITHDRAW_GOLD )) != GR_RIGHT_EMPTY )
{
int32 remaining = _GetRankBankMoneyPerDay ( rankId ) - member -> GetBankWithdrawValue ( GUILD_BANK_MAX_TABS );
if ( remaining > 0 )
return remaining ;
}
}
2010-10-17 19:54:13 +06:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2012-11-02 22:23:14 +01:00
inline void Guild :: _UpdateMemberWithdrawSlots ( SQLTransaction & trans , uint64 guid , uint8 tabId )
2010-10-17 19:54:13 +06:00
{
2012-11-02 22:23:14 +01:00
if ( Member * member = GetMember ( guid ))
{
uint8 rankId = member -> GetRankId ();
if ( rankId != GR_GUILDMASTER
&& member -> GetBankWithdrawValue ( tabId ) < _GetRankBankTabSlotsPerDay ( rankId , tabId ))
member -> UpdateBankWithdrawValue ( trans , tabId , 1 );
}
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2011-08-30 13:46:36 +02:00
inline bool Guild :: _MemberHasTabRights ( uint64 guid , uint8 tabId , uint32 rights ) const
2010-10-17 19:54:13 +06:00
{
2012-05-30 08:01:02 +02:00
if ( const Member * member = GetMember ( guid ))
2010-10-17 19:54:13 +06:00
{
// Leader always has full rights
2012-05-30 08:01:02 +02:00
if ( member -> IsRank ( GR_GUILDMASTER ) || m_leaderGuid == guid )
2010-10-17 19:54:13 +06:00
return true ;
2012-05-30 08:01:02 +02:00
return ( _GetRankBankTabRights ( member -> GetRankId (), tabId ) & rights ) == rights ;
2009-08-24 20:18:16 -05:00
}
2010-10-17 19:54:13 +06:00
return false ;
2009-08-24 20:18:16 -05:00
}
2010-10-17 19:54:13 +06:00
// Add new event log record
inline void Guild :: _LogEvent ( GuildEventLogTypes eventType , uint32 playerGuid1 , uint32 playerGuid2 , uint8 newRank )
2009-08-24 20:18:16 -05:00
{
2010-10-17 19:54:13 +06:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
m_eventLog -> AddEvent ( trans , new EventLogEntry ( m_id , m_eventLog -> GetNextGUID (), eventType , playerGuid1 , playerGuid2 , newRank ));
CharacterDatabase . CommitTransaction ( trans );
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildEvent ( this , uint8 ( eventType ), playerGuid1 , playerGuid2 , newRank );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Add new bank event log record
void Guild :: _LogBankEvent ( SQLTransaction & trans , GuildBankEventLogTypes eventType , uint8 tabId , uint32 lowguid , uint32 itemOrMoney , uint16 itemStackCount , uint8 destTabId )
{
if ( tabId > GUILD_BANK_MAX_TABS )
2009-08-24 20:18:16 -05:00
return ;
2009-10-17 15:51:44 -07:00
2012-08-27 20:20:17 +02:00
// not logging moves within the same tab
if ( eventType == GUILD_BANK_LOG_MOVE_ITEM && tabId == destTabId )
return ;
2010-10-17 19:54:13 +06:00
uint8 dbTabId = tabId ;
if ( BankEventLogEntry :: IsMoneyEvent ( eventType ))
2010-10-09 17:36:53 +02:00
{
2010-10-17 19:54:13 +06:00
tabId = GUILD_BANK_MAX_TABS ;
dbTabId = GUILD_BANK_MONEY_LOGS_TAB ;
2010-10-09 17:36:53 +02:00
}
2010-10-17 19:54:13 +06:00
LogHolder * pLog = m_bankEventLog [ tabId ];
pLog -> AddEvent ( trans , new BankEventLogEntry ( m_id , pLog -> GetNextGUID (), eventType , dbTabId , lowguid , itemOrMoney , itemStackCount , destTabId ));
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildBankEvent ( this , uint8 ( eventType ), tabId , lowguid , itemOrMoney , itemStackCount , destTabId );
2010-10-17 19:54:13 +06:00
}
2010-10-09 17:36:53 +02:00
2010-10-17 19:54:13 +06:00
inline Item * Guild :: _GetItem ( uint8 tabId , uint8 slotId ) const
{
if ( const BankTab * tab = GetBankTab ( tabId ))
return tab -> GetItem ( slotId );
return NULL ;
}
inline void Guild :: _RemoveItem ( SQLTransaction & trans , uint8 tabId , uint8 slotId )
{
if ( BankTab * pTab = GetBankTab ( tabId ))
pTab -> SetItem ( trans , slotId , NULL );
}
void Guild :: _MoveItems ( MoveItemData * pSrc , MoveItemData * pDest , uint32 splitedAmount )
{
// 1. Initialize source item
if ( ! pSrc -> InitItem ())
return ; // No source item
// 2. Check source item
if ( ! pSrc -> CheckItem ( splitedAmount ))
return ; // Source item or splited amount is invalid
/*
if (pItemSrc->GetCount() == 0)
2009-08-24 20:18:16 -05:00
{
2012-09-18 11:33:09 +02:00
sLog->outFatal(LOG_FILTER_GUILD, "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!",
2010-10-17 19:54:13 +06:00
player->GetName(), player->GetGUIDLow(), pItemSrc->GetEntry(), tabId, slotId, destTabId, destSlotId, pItemSrc->GetEntry());
//return; // Commented out for now, uncomment when it's verified that this causes a crash!!
2009-08-24 20:18:16 -05:00
}
2011-01-16 12:23:17 +01:00
// */
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// 3. Check destination rights
if ( ! pDest -> HasStoreRights ( pSrc ))
return ; // Player has no rights to store item in destination
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// 4. Check source withdraw rights
if ( ! pSrc -> HasWithdrawRights ( pDest ))
return ; // Player has no rights to withdraw items from source
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// 5. Check split
if ( splitedAmount )
{
// 5.1. Clone source item
if ( ! pSrc -> CloneItem ( splitedAmount ))
return ; // Item could not be cloned
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// 5.2. Move splited item to destination
_DoItemsMove ( pSrc , pDest , true , splitedAmount );
}
else // 6. No split
{
// 6.1. Try to merge items in destination (pDest->GetItem() == NULL)
if ( ! _DoItemsMove ( pSrc , pDest , false )) // Item could not be merged
2009-08-24 20:18:16 -05:00
{
2010-10-17 19:54:13 +06:00
// 6.2. Try to swap items
// 6.2.1. Initialize destination item
if ( ! pDest -> InitItem ())
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// 6.2.2. Check rights to store item in source (opposite direction)
if ( ! pSrc -> HasStoreRights ( pDest ))
return ; // Player has no rights to store item in source (opposite direction)
if ( ! pDest -> HasWithdrawRights ( pSrc ))
return ; // Player has no rights to withdraw item from destination (opposite direction)
// 6.2.3. Swap items (pDest->GetItem() != NULL)
_DoItemsMove ( pSrc , pDest , true );
2009-08-24 20:18:16 -05:00
}
2010-10-17 19:54:13 +06:00
}
// 7. Send changes
_SendBankContentUpdate ( pSrc , pDest );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
bool Guild :: _DoItemsMove ( MoveItemData * pSrc , MoveItemData * pDest , bool sendError , uint32 splitedAmount )
{
Item * pDestItem = pDest -> GetItem ();
bool swap = ( pDestItem != NULL );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Item * pSrcItem = pSrc -> GetItem ( splitedAmount );
// 1. Can store source item in destination
if ( ! pDest -> CanStore ( pSrcItem , swap , sendError ))
return false ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// 2. Can store destination item in source
if ( swap )
if ( ! pSrc -> CanStore ( pDestItem , true , true ))
return false ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// GM LOG (TODO: move to scripts)
pDest -> LogAction ( pSrc );
if ( swap )
pSrc -> LogAction ( pDest );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
// 3. Log bank events
pDest -> LogBankEvent ( trans , pSrc , pSrcItem -> GetCount ());
if ( swap )
pSrc -> LogBankEvent ( trans , pDest , pDestItem -> GetCount ());
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// 4. Remove item from source
pSrc -> RemoveItem ( trans , pDest , splitedAmount );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// 5. Remove item from destination
if ( swap )
pDest -> RemoveItem ( trans , pSrc );
// 6. Store item in destination
pDest -> StoreItem ( trans , pSrcItem );
// 7. Store item in source
if ( swap )
pSrc -> StoreItem ( trans , pDestItem );
CharacterDatabase . CommitTransaction ( trans );
return true ;
}
void Guild :: _SendBankContentUpdate ( MoveItemData * pSrc , MoveItemData * pDest ) const
2010-08-13 17:39:43 +06:00
{
2010-10-17 19:54:13 +06:00
ASSERT ( pSrc -> IsBank () || pDest -> IsBank ());
2010-10-25 11:25:42 +02:00
uint8 tabId = 0 ;
2010-10-17 19:54:13 +06:00
SlotIds slots ;
if ( pSrc -> IsBank ()) // B ->
2010-08-13 17:39:43 +06:00
{
2010-10-17 19:54:13 +06:00
tabId = pSrc -> GetContainer ();
slots . insert ( pSrc -> GetSlotId ());
if ( pDest -> IsBank ()) // B -> B
2010-08-13 17:39:43 +06:00
{
2010-10-17 19:54:13 +06:00
// Same tab - add destination slots to collection
if ( pDest -> GetContainer () == pSrc -> GetContainer ())
pDest -> CopySlots ( slots );
else // Different tabs - send second message
2010-08-13 17:39:43 +06:00
{
2010-10-17 19:54:13 +06:00
SlotIds destSlots ;
pDest -> CopySlots ( destSlots );
_SendBankContentUpdate ( pDest -> GetContainer (), destSlots );
2010-08-13 17:39:43 +06:00
}
}
}
2010-10-17 19:54:13 +06:00
else if ( pDest -> IsBank ()) // C -> B
{
tabId = pDest -> GetContainer ();
pDest -> CopySlots ( slots );
}
2012-08-23 15:35:53 +02:00
2010-10-17 19:54:13 +06:00
_SendBankContentUpdate ( tabId , slots );
2010-08-13 17:39:43 +06:00
}
2010-10-17 19:54:13 +06:00
void Guild :: _SendBankContentUpdate ( uint8 tabId , SlotIds slots ) const
2008-10-11 14:16:25 -05:00
{
2012-08-10 14:25:04 +02:00
if ( BankTab const * tab = GetBankTab ( tabId ))
2010-10-17 19:54:13 +06:00
{
2012-08-23 15:35:53 +02:00
ByteBuffer tabData ;
2010-10-17 19:54:13 +06:00
WorldPacket data ( SMSG_GUILD_BANK_LIST , 1200 );
2012-08-23 15:35:53 +02:00
data . WriteBit ( 0 );
data . WriteBits ( slots . size (), 20 ); // Item count
data . WriteBits ( 0 , 22 ); // Tab count
for ( SlotIds :: const_iterator itr = slots . begin (); itr != slots . end (); ++ itr )
{
data . WriteBit ( 0 );
Item const * tabItem = tab -> GetItem ( * itr );
uint32 enchantCount = 0 ;
if ( tabItem )
{
for ( uint32 enchSlot = 0 ; enchSlot < MAX_ENCHANTMENT_SLOT ; ++ enchSlot )
{
if ( uint32 enchantId = tabItem -> GetEnchantmentId ( EnchantmentSlot ( enchSlot )))
{
tabData << uint32 ( enchantId );
tabData << uint32 ( enchSlot );
++ enchantCount ;
}
}
}
data . WriteBits ( enchantCount , 23 ); // enchantment count
tabData << uint32 ( 0 );
tabData << uint32 ( 0 );
tabData << uint32 ( 0 );
tabData << uint32 ( tabItem ? tabItem -> GetCount () : 0 ); // ITEM_FIELD_STACK_COUNT
tabData << uint32 ( * itr );
tabData << uint32 ( 0 );
tabData << uint32 ( tabItem ? tabItem -> GetEntry () : 0 );
tabData << uint32 ( tabItem ? tabItem -> GetItemRandomPropertyId () : 0 );
tabData << uint32 ( tabItem ? abs ( tabItem -> GetSpellCharges ()) : 0 ); // Spell charges
tabData << uint32 ( tabItem ? tabItem -> GetItemSuffixFactor () : 0 ); // SuffixFactor
}
data . FlushBits ();
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint64 ( m_bankMoney );
2012-08-23 15:35:53 +02:00
if ( ! tabData . empty ())
data . append ( tabData );
data << uint32 ( tabId );
2010-10-17 19:54:13 +06:00
size_t rempos = data . wpos ();
data << uint32 ( 0 ); // Item withdraw amount, will be filled later
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
if ( _MemberHasTabRights ( itr -> second -> GetGUID (), tabId , GUILD_BANK_RIGHT_VIEW_TAB ))
2011-06-12 01:47:45 +02:00
if ( Player * player = itr -> second -> FindPlayer ())
2010-10-17 19:54:13 +06:00
{
2012-11-04 20:17:37 +01:00
data . put < uint32 > ( rempos , uint32 ( _GetMemberRemainingSlots ( itr -> second , tabId )));
2010-10-17 19:54:13 +06:00
player -> GetSession () -> SendPacket ( & data );
}
2012-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
2010-10-17 19:54:13 +06:00
}
}
2011-08-30 13:46:36 +02:00
void Guild :: _BroadcastEvent ( GuildEvents guildEvent , uint64 guid , const char * param1 , const char * param2 , const char * param3 ) const
2010-10-17 19:54:13 +06:00
{
uint8 count = ! param3 ? ( ! param2 ? ( ! param1 ? 0 : 1 ) : 2 ) : 3 ;
WorldPacket data ( SMSG_GUILD_EVENT , 1 + 1 + count + ( guid ? 8 : 0 ));
data << uint8 ( guildEvent );
data << uint8 ( count );
if ( param3 )
data << param1 << param2 << param3 ;
else if ( param2 )
data << param1 << param2 ;
else if ( param1 )
data << param1 ;
if ( guid )
data << uint64 ( guid );
BroadcastPacket ( & data );
2012-11-08 11:13:46 +01:00
if ( sLog -> ShouldLog ( LOG_FILTER_GUILD , LOG_LEVEL_DEBUG ))
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_EVENT [Broadcast] Event: %s (%u)" , _GetGuildEventString ( guildEvent ). c_str (), guildEvent );
2008-10-11 14:16:25 -05:00
}
2012-08-04 18:40:56 +02:00
2012-11-04 20:17:37 +01:00
void Guild :: SendBankList ( WorldSession * session , uint8 tabId , bool withContent , bool withTabInfo ) const
2012-11-02 22:23:14 +01:00
{
2012-11-04 20:17:37 +01:00
Member const * member = GetMember ( session -> GetPlayer () -> GetGUID ());
if ( ! member ) // Shouldn't happen, just in case
return ;
ByteBuffer tabData ;
2012-11-02 22:23:14 +01:00
WorldPacket data ( SMSG_GUILD_BANK_LIST , 500 );
2012-11-04 20:17:37 +01:00
data . WriteBit ( 0 );
uint32 itemCount = 0 ;
if ( withContent && _MemberHasTabRights ( session -> GetPlayer () -> GetGUID (), tabId , GUILD_BANK_RIGHT_VIEW_TAB ))
if ( BankTab const * tab = GetBankTab ( tabId ))
for ( uint8 slotId = 0 ; slotId < GUILD_BANK_MAX_SLOTS ; ++ slotId )
if ( tab -> GetItem ( slotId ))
++ itemCount ;
data . WriteBits ( itemCount , 20 );
data . WriteBits ( withTabInfo ? _GetPurchasedTabsSize () : 0 , 22 );
if ( withContent && _MemberHasTabRights ( session -> GetPlayer () -> GetGUID (), tabId , GUILD_BANK_RIGHT_VIEW_TAB ))
{
if ( BankTab const * tab = GetBankTab ( tabId ))
{
for ( uint8 slotId = 0 ; slotId < GUILD_BANK_MAX_SLOTS ; ++ slotId )
{
if ( Item * tabItem = tab -> GetItem ( slotId ))
{
data . WriteBit ( 0 );
uint32 enchants = 0 ;
for ( uint32 ench = 0 ; ench < MAX_ENCHANTMENT_SLOT ; ++ ench )
{
if ( uint32 enchantId = tabItem -> GetEnchantmentId ( EnchantmentSlot ( ench )))
{
tabData << uint32 ( enchantId );
tabData << uint32 ( ench );
++ enchants ;
}
}
data . WriteBits ( enchants , 23 );
tabData << uint32 ( 0 );
tabData << uint32 ( 0 );
tabData << uint32 ( 0 );
tabData << uint32 ( tabItem -> GetCount ()); // ITEM_FIELD_STACK_COUNT
tabData << uint32 ( slotId );
tabData << uint32 ( 0 );
tabData << uint32 ( tabItem -> GetEntry ());
tabData << uint32 ( tabItem -> GetItemRandomPropertyId ());
tabData << uint32 ( abs ( tabItem -> GetSpellCharges ())); // Spell charges
tabData << uint32 ( tabItem -> GetItemSuffixFactor ()); // SuffixFactor
}
}
}
}
2012-11-02 22:23:14 +01:00
2012-11-04 20:17:37 +01:00
if ( withTabInfo )
2012-11-02 22:23:14 +01:00
{
for ( uint8 i = 0 ; i < _GetPurchasedTabsSize (); ++ i )
2012-11-04 20:17:37 +01:00
{
data . WriteBits ( m_bankTabs [ i ] -> GetIcon (). length (), 9 );
data . WriteBits ( m_bankTabs [ i ] -> GetName (). length (), 7 );
}
2012-11-02 22:23:14 +01:00
}
2012-11-04 20:17:37 +01:00
data . FlushBits ();
if ( withTabInfo )
2012-11-02 22:23:14 +01:00
{
2012-11-04 20:17:37 +01:00
for ( uint8 i = 0 ; i < _GetPurchasedTabsSize (); ++ i )
{
data . WriteString ( m_bankTabs [ i ] -> GetIcon ());
data << uint32 ( i );
data . WriteString ( m_bankTabs [ i ] -> GetName ());
}
2012-11-02 22:23:14 +01:00
}
2012-11-04 20:17:37 +01:00
data << uint64 ( m_bankMoney );
if ( ! tabData . empty ())
data . append ( tabData );
data << uint32 ( tabId );
data << uint32 ( _GetMemberRemainingSlots ( member , tabId ));
session -> SendPacket ( & data );
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
}
2012-08-04 18:40:56 +02:00
void Guild :: SendGuildRanksUpdate ( uint64 setterGuid , uint64 targetGuid , uint32 rank )
{
ObjectGuid tarGuid = targetGuid ;
ObjectGuid setGuid = setterGuid ;
Member * member = GetMember ( targetGuid );
ASSERT ( member );
WorldPacket data ( SMSG_GUILD_RANKS_UPDATE , 100 );
data . WriteBit ( setGuid [ 7 ]);
data . WriteBit ( setGuid [ 2 ]);
data . WriteBit ( tarGuid [ 2 ]);
data . WriteBit ( setGuid [ 1 ]);
data . WriteBit ( tarGuid [ 1 ]);
data . WriteBit ( tarGuid [ 7 ]);
data . WriteBit ( tarGuid [ 0 ]);
data . WriteBit ( tarGuid [ 5 ]);
data . WriteBit ( tarGuid [ 4 ]);
data . WriteBit ( rank < member -> GetRankId ()); // 1 == higher, 0 = lower?
data . WriteBit ( setGuid [ 5 ]);
data . WriteBit ( setGuid [ 0 ]);
data . WriteBit ( tarGuid [ 6 ]);
data . WriteBit ( setGuid [ 3 ]);
data . WriteBit ( setGuid [ 6 ]);
data . WriteBit ( tarGuid [ 3 ]);
data . WriteBit ( setGuid [ 4 ]);
data . FlushBits ();
data << uint32 ( rank );
data . WriteByteSeq ( setGuid [ 3 ]);
data . WriteByteSeq ( tarGuid [ 7 ]);
data . WriteByteSeq ( setGuid [ 6 ]);
data . WriteByteSeq ( setGuid [ 2 ]);
data . WriteByteSeq ( tarGuid [ 5 ]);
data . WriteByteSeq ( tarGuid [ 0 ]);
data . WriteByteSeq ( setGuid [ 7 ]);
data . WriteByteSeq ( setGuid [ 5 ]);
data . WriteByteSeq ( tarGuid [ 2 ]);
data . WriteByteSeq ( tarGuid [ 1 ]);
data . WriteByteSeq ( setGuid [ 0 ]);
data . WriteByteSeq ( setGuid [ 4 ]);
data . WriteByteSeq ( setGuid [ 1 ]);
data . WriteByteSeq ( tarGuid [ 3 ]);
data . WriteByteSeq ( tarGuid [ 6 ]);
data . WriteByteSeq ( tarGuid [ 4 ]);
BroadcastPacket ( & data );
member -> ChangeRank ( rank );
2012-11-07 23:21:19 +01:00
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "SMSG_GUILD_RANKS_UPDATE [Broadcast] Target: %u, Issuer: %u, RankId: %u" ,
GUID_LOPART ( targetGuid ), GUID_LOPART ( setterGuid ), rank );
2012-08-04 18:40:56 +02:00
}
2012-09-07 14:39:19 +02:00
void Guild :: GiveXP ( uint32 xp , Player * source )
{
if ( ! sWorld -> getBoolConfig ( CONFIG_GUILD_LEVELING_ENABLED ))
return ;
/// @TODO: Award reputation and count activity for player
if ( GetLevel () >= sWorld -> getIntConfig ( CONFIG_GUILD_MAX_LEVEL ))
xp = 0 ; // SMSG_GUILD_XP_GAIN is always sent, even for no gains
if ( GetLevel () >= GUILD_EXPERIENCE_UNCAPPED_LEVEL )
xp = std :: min ( xp , sWorld -> getIntConfig ( CONFIG_GUILD_DAILY_XP_CAP ) - uint32 ( _todayExperience ));
WorldPacket data ( SMSG_GUILD_XP_GAIN , 8 );
data << uint64 ( xp );
source -> GetSession () -> SendPacket ( & data );
_experience += xp ;
_todayExperience += xp ;
if ( ! xp )
return ;
uint32 oldLevel = GetLevel ();
// Ding, mon!
while ( GetExperience () >= sGuildMgr -> GetXPForGuildLevel ( GetLevel ()) && GetLevel () < sWorld -> getIntConfig ( CONFIG_GUILD_MAX_LEVEL ))
{
_experience -= sGuildMgr -> GetXPForGuildLevel ( GetLevel ());
++ _level ;
2012-12-17 00:41:46 +01:00
// Find all guild perks to learn
std :: vector < uint32 > perksToLearn ;
for ( uint32 i = 0 ; i < sGuildPerkSpellsStore . GetNumRows (); ++ i )
if ( GuildPerkSpellsEntry const * entry = sGuildPerkSpellsStore . LookupEntry ( i ))
if ( entry -> Level > oldLevel && entry -> Level <= GetLevel ())
perksToLearn . push_back ( entry -> SpellId );
2012-09-07 14:39:19 +02:00
2012-12-17 00:41:46 +01:00
// Notify all online players that guild level changed and learn perks
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
2012-09-07 14:39:19 +02:00
{
2012-12-17 00:41:46 +01:00
if ( Player * player = itr -> second -> FindPlayer ())
{
player -> SetGuildLevel ( GetLevel ());
for ( size_t i = 0 ; i < perksToLearn . size (); ++ i )
player -> learnSpell ( perksToLearn [ i ], true );
}
2012-09-07 14:39:19 +02:00
}
2012-12-17 00:41:46 +01:00
AddGuildNews ( GUILD_NEWS_LEVEL_UP , 0 , 0 , _level );
UpdateAchievementCriteria ( ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL , GetLevel (), 0 , 0 , NULL , source );
++ oldLevel ;
}
2012-09-07 14:39:19 +02:00
}
2012-11-07 23:21:19 +01:00
void Guild :: SendGuildXP ( WorldSession * session /* = NULL */ ) const
2012-09-07 14:39:19 +02:00
{
2012-09-18 11:33:09 +02:00
//Member const* member = GetMember(session->GetGuidLow());
2012-09-07 14:39:19 +02:00
WorldPacket data ( SMSG_GUILD_XP , 40 );
data << uint64 ( /*member ? member->GetTotalActivity() :*/ 0 );
data << uint64 ( sGuildMgr -> GetXPForGuildLevel ( GetLevel ()) - GetExperience ()); // XP missing for next level
data << uint64 ( GetTodayExperience ());
data << uint64 ( /*member ? member->GetWeeklyActivity() :*/ 0 );
data << uint64 ( GetExperience ());
session -> SendPacket ( & data );
}
2012-11-07 23:21:19 +01:00
void Guild :: SendGuildReputationWeeklyCap ( WorldSession * session , uint32 reputation ) const
2012-09-09 14:39:34 +02:00
{
2012-11-07 23:21:19 +01:00
uint32 cap = sWorld -> getIntConfig ( CONFIG_GUILD_WEEKLY_REP_CAP ) - reputation ;
WorldPacket data ( SMSG_GUILD_REPUTATION_WEEKLY_CAP , 4 );
data << uint32 ( cap );
session -> SendPacket ( & data );
sLog -> outDebug ( LOG_FILTER_GUILD , "SMSG_GUILD_REPUTATION_WEEKLY_CAP [%s]: Left: %u" ,
session -> GetPlayerInfo (). c_str (), cap );
2012-09-09 14:39:34 +02:00
}
2012-11-07 23:21:19 +01:00
void Guild :: ResetTimes ( bool weekly )
2012-09-09 14:39:34 +02:00
{
2012-11-07 23:21:19 +01:00
_todayExperience = 0 ;
for ( Members :: const_iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
2012-09-09 14:39:34 +02:00
{
2012-11-07 23:21:19 +01:00
itr -> second -> ResetValues ( weekly );
if ( Player * player = itr -> second -> FindPlayer ())
{
//SendGuildXP(player->GetSession());
WorldPacket data ( SMSG_GUILD_MEMBER_DAILY_RESET , 0 ); // tells the client to request bank withdrawal limit
player -> GetSession () -> SendPacket ( & data );
}
2012-09-09 14:39:34 +02:00
}
}
2012-11-07 23:21:19 +01:00
void Guild :: AddGuildNews ( uint8 type , uint64 guid , uint32 flags , uint32 value )
2012-09-09 14:39:34 +02:00
{
2012-11-07 23:21:19 +01:00
uint32 lowGuid = GUID_LOPART ( guid );
NewsLogEntry * news = new NewsLogEntry ( m_id , m_newsLog -> GetNextGUID (), GuildNews ( type ), lowGuid , flags , value );
2012-09-09 14:39:34 +02:00
2012-11-07 23:21:19 +01:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
m_newsLog -> AddEvent ( trans , news );
CharacterDatabase . CommitTransaction ( trans );
2012-09-09 14:39:34 +02:00
2012-11-07 23:21:19 +01:00
WorldPacket data ( SMSG_GUILD_NEWS_UPDATE , 7 + 32 );
data . WriteBits ( 1 , 21 ); // size, we are only sending 1 news here
ByteBuffer buffer ;
news -> WritePacket ( data , buffer );
2012-09-09 14:39:34 +02:00
2012-11-07 23:21:19 +01:00
BroadcastPacket ( & data );
}
2012-09-09 14:39:34 +02:00
2012-11-07 23:21:19 +01:00
bool Guild :: HasAchieved ( uint32 achievementId ) const
{
return m_achievementMgr . HasAchieved ( achievementId );
}
2012-09-09 14:39:34 +02:00
2012-11-12 14:25:51 +01:00
void Guild :: UpdateAchievementCriteria ( AchievementCriteriaTypes type , uint64 miscValue1 , uint64 miscValue2 , uint64 miscValue3 , Unit * unit , Player * player )
2012-11-07 23:21:19 +01:00
{
2012-11-12 14:25:51 +01:00
m_achievementMgr . UpdateAchievementCriteria ( type , miscValue1 , miscValue2 , miscValue3 , unit , player );
2012-09-09 14:39:34 +02:00
}
2012-11-07 23:21:19 +01:00
void Guild :: HandleNewsSetSticky ( WorldSession * session , uint32 newsId , bool sticky )
2012-09-09 14:39:34 +02:00
{
2012-11-07 23:21:19 +01:00
GuildLog * logs = m_newsLog -> GetGuildLog ();
GuildLog :: iterator itr = logs -> begin ();
while ( itr != logs -> end () && ( * itr ) -> GetGUID () != newsId )
++ itr ;
2012-09-09 14:39:34 +02:00
2012-11-07 23:21:19 +01:00
if ( itr == logs -> end ())
2012-09-09 14:39:34 +02:00
{
2012-11-07 23:21:19 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "HandleNewsSetSticky: [%s] requested unknown newsId %u - Sticky: %u" ,
session -> GetPlayerInfo (). c_str (), newsId , sticky );
return ;
2012-09-09 14:39:34 +02:00
}
2012-11-07 23:21:19 +01:00
NewsLogEntry * news = ( NewsLogEntry * )( * itr );
news -> SetSticky ( sticky );
2012-09-09 14:39:34 +02:00
2012-11-07 23:21:19 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "HandleNewsSetSticky: [%s] chenged newsId %u sticky to %u" ,
session -> GetPlayerInfo (). c_str (), newsId , sticky );
2012-09-09 14:39:34 +02:00
2012-11-07 23:21:19 +01:00
WorldPacket data ( SMSG_GUILD_NEWS_UPDATE , 7 + 32 );
data . WriteBits ( 1 , 21 );
ByteBuffer buffer ;
news -> WritePacket ( data , buffer );
session -> SendPacket ( & data );
2008-10-11 14:16:25 -05:00
}