2010-10-07 15:35:36 +02:00
/*
2012-01-01 00:32:13 +01:00
* Copyright (C) 2008-2012 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
2010-06-08 16:13:55 -06:00
#include "DatabaseEnv.h"
2008-10-11 14:16:25 -05:00
#include "Guild.h"
2011-05-04 10:08:09 +02:00
#include "GuildMgr.h"
2010-10-17 19:54:13 +06:00
#include "ScriptMgr.h"
2008-10-11 14:16:25 -05:00
#include "Chat.h"
2010-07-29 01:22:45 +02:00
#include "Config.h"
2010-10-17 19:54:13 +06:00
#include "SocialMgr.h"
#include "Log.h"
2011-09-08 15:11:55 +02:00
#include "AccountMgr.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
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
2010-10-17 19:54:13 +06:00
void Guild :: SendCommandResult ( WorldSession * session , GuildCommandType type , GuildCommandError errCode , const std :: string & 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-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_COMMAND_RESULT)" );
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-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (MSG_SAVE_GUILD_EMBLEM)" );
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
{
data << uint8 ( m_log . size ());
for ( GuildLog :: const_iterator itr = m_log . begin (); itr != m_log . end (); ++ itr )
( * itr ) -> WritePacket ( data );
}
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
{
PreparedStatement * stmt = NULL ;
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_EVENTLOG );
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
}
void Guild :: EventLogEntry :: WritePacket ( WorldPacket & data ) const
{
// Event type
data << uint8 ( m_eventType );
// Player 1
data << uint64 ( MAKE_NEW_GUID ( m_playerGuid1 , 0 , HIGHGUID_PLAYER ));
// Player 2 not for left/join guild events
if ( m_eventType != GUILD_EVENT_LOG_JOIN_GUILD && m_eventType != GUILD_EVENT_LOG_LEAVE_GUILD )
data << uint64 ( MAKE_NEW_GUID ( m_playerGuid2 , 0 , HIGHGUID_PLAYER ));
// New Rank - only for promote/demote guild events
if ( m_eventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || m_eventType == GUILD_EVENT_LOG_DEMOTE_PLAYER )
data << uint8 ( m_newRank );
// Event timestamp
data << uint32 ( :: time ( NULL ) - m_timestamp );
}
///////////////////////////////////////////////////////////////////////////////
// BankEventLogEntry
void Guild :: BankEventLogEntry :: SaveToDB ( SQLTransaction & trans ) const
{
PreparedStatement * stmt = NULL ;
uint8 index = 0 ;
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_EVENTLOG );
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
}
void Guild :: BankEventLogEntry :: WritePacket ( WorldPacket & data ) const
{
data << uint8 ( m_eventType );
data << uint64 ( MAKE_NEW_GUID ( m_playerGuid , 0 , HIGHGUID_PLAYER ));
data << uint32 ( m_itemOrMoney );
2011-01-10 20:57:58 +01:00
// if ( m_eventType != 4 || m_eventType != 5 || m_eventType != 6 || m_eventType != 8 || m_eventType != 9 )
if ( m_eventType < GUILD_BANK_LOG_DEPOSIT_MONEY )
2009-08-24 20:23:54 -05:00
{
2010-10-17 19:54:13 +06:00
data << uint32 ( m_itemStackCount );
if ( m_eventType == GUILD_BANK_LOG_MOVE_ITEM || m_eventType == GUILD_BANK_LOG_MOVE_ITEM2 )
data << uint8 ( m_destTabId );
2009-08-24 20:23:54 -05:00
}
2011-01-10 20:57:58 +01:00
data << uint32 ( time ( NULL ) - m_timestamp );
2010-10-17 19:54:13 +06:00
}
2009-10-17 15:51:44 -07:00
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
2010-10-17 19:54:13 +06:00
void Guild :: RankInfo :: SetName ( const std :: string & 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
2010-10-17 19:54:13 +06:00
PreparedStatement * stmt = NULL ;
2012-01-01 01:09:38 +01:00
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 );
2012-01-01 01:09:38 +01:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_RANK_BANK_RESET_TIME );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt8 ( 1 , m_rankId );
CharacterDatabase . Execute ( stmt );
2010-02-18 02:42:59 +01:00
}
2010-10-17 19:54:13 +06:00
void Guild :: RankInfo :: SetBankTabSlotsAndRights ( uint8 tabId , 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 ();
if ( m_bankTabRightsAndSlots [ tabId ]. IsEqual ( rightsAndSlots ))
return ;
m_bankTabRightsAndSlots [ tabId ] = rightsAndSlots ;
if ( saveToDB )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
PreparedStatement * stmt = NULL ;
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_RIGHT );
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt8 ( 1 , tabId );
stmt -> setUInt8 ( 2 , m_rankId );
CharacterDatabase . Execute ( stmt );
2012-01-01 01:09:38 +01:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_BANK_RIGHT );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt8 ( 1 , tabId );
stmt -> setUInt8 ( 2 , m_rankId );
stmt -> setUInt8 ( 3 , m_bankTabRightsAndSlots [ tabId ]. rights );
stmt -> setUInt32 ( 4 , m_bankTabRightsAndSlots [ tabId ]. slots );
CharacterDatabase . Execute ( stmt );
2012-01-01 01:09:38 +01:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_UPD_GUILD_RANK_BANK_TIME0 + tabId );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_guildId );
stmt -> setUInt8 ( 1 , m_rankId );
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
bool Guild :: BankTab :: LoadFromDB ( Field * fields )
{
m_name = fields [ 2 ]. GetString ();
m_icon = fields [ 3 ]. GetString ();
m_text = fields [ 4 ]. GetString ();
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
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
2010-10-17 19:54:13 +06:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM );
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
2010-10-17 19:54:13 +06:00
inline void Guild :: BankTab :: WritePacket ( WorldPacket & data ) const
{
data << uint8 ( GUILD_BANK_MAX_SLOTS );
for ( uint8 slotId = 0 ; slotId < GUILD_BANK_MAX_SLOTS ; ++ slotId )
WriteSlotPacket ( data , slotId );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Writes information about contents of specified slot into packet.
void Guild :: BankTab :: WriteSlotPacket ( WorldPacket & data , uint8 slotId ) const
{
2011-09-15 14:08:17 +02:00
Item * pItem = GetItem ( slotId );
2010-10-17 19:54:13 +06:00
uint32 itemEntry = pItem ? pItem -> GetEntry () : 0 ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint8 ( slotId );
data << uint32 ( itemEntry );
if ( itemEntry )
{
data << uint32 ( 0 ); // 3.3.0 (0x00018020, 0x00018000)
data << uint32 ( pItem -> GetItemRandomPropertyId ()); // Random item property id
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( pItem -> GetItemRandomPropertyId ())
data << uint32 ( pItem -> GetItemSuffixFactor ()); // SuffixFactor
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint32 ( pItem -> GetCount ()); // ITEM_FIELD_STACK_COUNT
data << uint32 ( 0 );
data << uint8 ( abs ( pItem -> GetSpellCharges ())); // Spell charges
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
uint8 enchCount = 0 ;
size_t enchCountPos = data . wpos ();
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint8 ( enchCount ); // Number of enchantments
for ( uint32 i = PERM_ENCHANTMENT_SLOT ; i < MAX_ENCHANTMENT_SLOT ; ++ i )
if ( uint32 enchId = pItem -> GetEnchantmentId ( EnchantmentSlot ( i )))
{
data << uint8 ( i );
data << uint32 ( enchId );
++ enchCount ;
}
data . put < uint8 > ( enchCountPos , enchCount );
}
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 :: BankTab :: SetInfo ( const std :: string & name , const std :: string & 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
2010-10-17 19:54:13 +06:00
void Guild :: BankTab :: SetText ( const std :: string & 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.
bool Guild :: BankTab :: SetItem ( SQLTransaction & trans , uint8 slotId , Item * pItem )
{
if ( slotId >= GUILD_BANK_MAX_SLOTS )
return false ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
m_items [ slotId ] = pItem ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
PreparedStatement * stmt = NULL ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_ITEM );
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
2010-10-17 19:54:13 +06:00
if ( pItem )
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 );
stmt -> setUInt32 ( 3 , pItem -> GetGUIDLow ());
2010-12-13 16:27:14 +01:00
CharacterDatabase . ExecuteOrAppend ( trans , stmt );
2010-10-17 19:54:13 +06:00
pItem -> SetUInt64Value ( ITEM_FIELD_CONTAINED , 0 );
pItem -> SetUInt64Value ( ITEM_FIELD_OWNER , 0 );
pItem -> FSetState ( ITEM_NEW );
pItem -> 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
2011-10-07 10:54:53 -05:00
void Guild :: BankTab :: SendText ( const Guild * guild , WorldSession * session ) const
2010-10-17 19:54:13 +06:00
{
WorldPacket data ( MSG_QUERY_GUILD_BANK_TEXT , 1 + m_text . size () + 1 );
data << uint8 ( m_tabId );
data << m_text ;
2010-07-28 17:19:39 -06:00
2010-10-17 19:54:13 +06:00
if ( session )
session -> SendPacket ( & data );
else
2011-10-07 10:54:53 -05:00
guild -> BroadcastPacket ( & data );
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 ();
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: Member :: SetStats ( const std :: string & name , uint8 level , uint8 _class , uint32 zoneId , uint32 accountId )
{
m_name = name ;
m_level = level ;
m_class = _class ;
m_zoneId = zoneId ;
m_accountId = accountId ;
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 :: SetPublicNote ( const std :: string & 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
2010-10-17 19:54:13 +06:00
void Guild :: Member :: SetOfficerNote ( const std :: string & 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 )
{
m_publicNote = fields [ 3 ]. GetString ();
m_officerNote = fields [ 4 ]. GetString ();
m_bankRemaining [ GUILD_BANK_MAX_TABS ]. resetTime = fields [ 5 ]. GetUInt32 ();
m_bankRemaining [ GUILD_BANK_MAX_TABS ]. value = fields [ 6 ]. GetUInt32 ();
for ( uint8 i = 0 ; i < GUILD_BANK_MAX_TABS ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
m_bankRemaining [ i ]. resetTime = fields [ 7 + i * 2 ]. GetUInt32 ();
m_bankRemaining [ i ]. value = fields [ 8 + i * 2 ]. GetUInt32 ();
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
SetStats ( fields [ 19 ]. GetString (),
2012-05-30 08:01:02 +02:00
fields [ 20 ]. GetUInt8 (), // characters.level
fields [ 21 ]. GetUInt8 (), // characters.class
fields [ 22 ]. GetUInt16 (), // characters.zone
fields [ 23 ]. GetUInt32 ()); // characters.account
m_logoutTime = fields [ 24 ]. GetUInt32 (); // characters.logout_time
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
}
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 ;
}
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.
void Guild :: Member :: DecreaseBankRemainingValue ( SQLTransaction & trans , uint8 tabId , uint32 amount )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
m_bankRemaining [ tabId ]. value -= amount ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement (
2010-12-13 22:37:56 +01:00
tabId == GUILD_BANK_MAX_TABS ?
2012-01-01 01:09:38 +01:00
CHAR_UPD_GUILD_MEMBER_BANK_REM_MONEY :
CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS0 + tabId );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_bankRemaining [ tabId ]. value );
stmt -> setUInt32 ( 1 , m_guildId );
stmt -> setUInt32 ( 2 , GUID_LOPART ( m_guid ));
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
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.
// If reset time was more than 24 hours ago, renew reset time and reset amount to maximum value.
2011-10-07 10:54:53 -05:00
uint32 Guild :: Member :: GetBankRemainingValue ( uint8 tabId , const Guild * guild ) 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
2010-10-17 19:54:13 +06:00
// Check rights for non-money tab.
if ( tabId != GUILD_BANK_MAX_TABS )
2011-10-07 10:54:53 -05:00
if (( guild -> _GetRankBankTabRights ( m_rankId , tabId ) & GUILD_BANK_RIGHT_VIEW_TAB ) != GUILD_BANK_RIGHT_VIEW_TAB )
2010-10-17 19:54:13 +06:00
return 0 ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
uint32 curTime = uint32 ( :: time ( NULL ) / MINUTE ); // minutes
if ( curTime > m_bankRemaining [ tabId ]. resetTime + 24 * HOUR / MINUTE )
2009-08-24 20:23:54 -05:00
{
2010-10-17 19:54:13 +06:00
RemainingValue & rv = const_cast < RemainingValue &> ( m_bankRemaining [ tabId ]);
rv . resetTime = curTime ;
rv . value = tabId == GUILD_BANK_MAX_TABS ?
2011-10-07 10:54:53 -05:00
guild -> _GetRankBankMoneyPerDay ( m_rankId ) :
guild -> _GetRankBankTabSlotsPerDay ( m_rankId , tabId );
2010-10-17 19:54:13 +06:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement (
tabId == GUILD_BANK_MAX_TABS ?
2012-01-01 01:09:38 +01:00
CHAR_UPD_GUILD_MEMBER_BANK_TIME_MONEY :
CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS0 + tabId );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_bankRemaining [ tabId ]. resetTime );
stmt -> setUInt32 ( 1 , m_bankRemaining [ tabId ]. value );
stmt -> setUInt32 ( 2 , m_guildId );
stmt -> setUInt32 ( 3 , GUID_LOPART ( m_guid ));
CharacterDatabase . Execute ( stmt );
2009-08-24 20:23:54 -05:00
}
2010-10-17 19:54:13 +06:00
return m_bankRemaining [ tabId ]. value ;
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 :: Member :: ResetTabTimes ()
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
for ( uint8 tabId = 0 ; tabId < GUILD_BANK_MAX_TABS ; ++ tabId )
m_bankRemaining [ tabId ]. resetTime = 0 ;
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 :: Member :: ResetMoneyTime ()
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
m_bankRemaining [ GUILD_BANK_MAX_TABS ]. resetTime = 0 ;
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
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
{
2010-10-17 19:54:13 +06:00
m_pPlayer -> SendEquipError ( EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS , m_pItem );
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
{
2010-10-17 19:54:13 +06:00
m_pPlayer -> SendEquipError ( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED , m_pItem );
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 ;
return ( m_pGuild -> _GetMemberRemainingSlots ( m_pPlayer -> GetGUID (), m_container ) != 0 );
}
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 )
m_pGuild -> _DecreaseMemberRemainingSlots ( trans , m_pPlayer -> GetGUID (), m_container );
}
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 );
2011-09-08 15:11:55 +02:00
if ( ! pFrom -> IsBank () && sWorld -> getBoolConfig ( CONFIG_GM_LOG_TRADE ) && ! AccountMgr :: IsPlayerAccount ( m_pPlayer -> GetSession () -> GetSecurity ())) // TODO: move to scripts
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)" ,
m_pPlayer -> GetName (), 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 ());
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 ())
return EQUIP_ERR_CANT_DROP_SOULBOUND ;
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 ())
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG ;
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 ))
return EQUIP_ERR_ITEM_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-07-19 16:07:37 +02:00
Guild :: Guild () : m_id ( 0 ), m_leaderGuid ( 0 ), m_createdDate ( 0 ), m_accountsNumber ( 0 ), m_bankMoney ( 0 ), m_eventLog ( NULL ), m_achievementMgr ( this ), m_level ( 1 )
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
if ( m_eventLog )
delete m_eventLog ;
for ( uint8 tabId = 0 ; tabId <= GUILD_BANK_MAX_TABS ; ++ tabId )
if ( m_bankEventLog [ tabId ])
delete m_bankEventLog [ tabId ];
for ( Members :: iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
delete itr -> second ;
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.
bool Guild :: Create ( Player * pLeader , const std :: string & 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-08-10 14:25:04 +02:00
m_level = 1 ;
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)" ,
2010-10-17 19:54:13 +06:00
name . c_str (), pLeader -> GetName (), GUID_LOPART ( m_leaderGuid ));
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
PreparedStatement * stmt = NULL ;
2010-08-21 03:19:25 +02:00
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_MEMBERS );
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 );
2010-10-17 19:54:13 +06:00
// Create default ranks
_CreateDefaultGuildRanks ( pLeaderSession -> GetSessionDbLocaleIndex ());
// Add guildmaster
bool ret = AddMember ( m_leaderGuid , GR_GUILDMASTER );
if ( ret )
// Call scripts on successful create
2010-12-22 21:25:23 +01:00
sScriptMgr -> OnGuildCreate ( this , pLeader , name );
2010-10-17 19:54:13 +06:00
2012-08-04 18:40:56 +02:00
_BroadcastEvent ( GE_FOUNDER , m_leaderGuid );
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
PreparedStatement * stmt = NULL ;
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD );
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 );
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
2010-10-17 19:54:13 +06:00
///////////////////////////////////////////////////////////////////////////////
// HANDLE CLIENT COMMANDS
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 ;
Player * player = member -> FindPlayer ();
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 ]);
uint8 flags = GUILDMEMBER_STATUS_NONE ;
if ( player )
{
flags |= GUILDMEMBER_STATUS_ONLINE ;
if ( player -> isAFK ())
flags |= GUILDMEMBER_STATUS_AFK ;
if ( player -> isDND ())
flags |= GUILDMEMBER_STATUS_DND ;
}
memberData << uint8 ( member -> GetClass ());
memberData << int32 ( 0 ); // unk
memberData . WriteByteSeq ( guid [ 0 ]);
memberData << uint64 ( 0 ); // weekly activity
memberData << uint32 ( member -> GetRankId ());
memberData << uint32 ( 0 ); // player->GetAchievementMgr().GetCompletedAchievementsAmount()
// for (2 professions)
memberData << uint32 ( 0 ) << uint32 ( 0 ) << uint32 ( 0 );
memberData << uint32 ( 0 ) << uint32 ( 0 ) << uint32 ( 0 );
memberData . WriteByteSeq ( guid [ 2 ]);
memberData << uint8 ( flags );
memberData << uint32 ( player ? player -> GetZoneId () : member -> GetZone ());
memberData << uint64 ( 0 ); // Total activity
memberData . WriteByteSeq ( guid [ 7 ]);
memberData << uint32 ( 0 ); // Remaining guild week Rep
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 ]);
memberData << uint8 ( player ? player -> getLevel () : member -> GetLevel ());
memberData << int32 ( 0 ); // unk
memberData . WriteByteSeq ( guid [ 5 ]);
memberData . WriteByteSeq ( guid [ 4 ]);
memberData << uint8 ( 0 ); // unk
memberData . WriteByteSeq ( guid [ 1 ]);
memberData << float ( player ? 0.0f : float ( :: time ( NULL ) - member -> GetLogoutTime ()) / DAY );
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-04 18:40:56 +02:00
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
data << uint32 ( 0 );
2010-10-17 19:54:13 +06:00
if ( session )
session -> SendPacket ( & data );
else
BroadcastPacket ( & data );
2012-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_ROSTER)" );
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-08-02 08:04:12 +02:00
2012-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)" );
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 :: HandleGuildRanks ( WorldSession * session )
{
// perhaps move to guild.cpp.....
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 ++ )
{
RankInfo * rankInfo = GetRankInfo ( i );
if ( ! rankInfo )
continue ;
data . WriteBits ( rankInfo -> GetName (). length (), 7 );
rankData << uint32 ( i );
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
rankData << uint32 ( rankInfo -> GetId ());
}
data . FlushBits ();
data . append ( rankData );
session -> SendPacket ( & data );
}
2010-10-17 19:54:13 +06:00
void Guild :: HandleSetMOTD ( WorldSession * session , const std :: string & 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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , 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
2010-10-17 19:54:13 +06:00
void Guild :: HandleSetInfo ( WorldSession * session , const std :: string & 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
if ( ! _HasRankRight ( session -> GetPlayer (), GR_RIGHT_MODIFY_GUILD_INFO ))
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_CREATE_S , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
else
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 ))
2011-10-07 10:54:53 -05:00
// "Only guild leaders can create emblems."
2010-10-17 19:54:13 +06:00
SendSaveEmblemResult ( session , ERR_GUILDEMBLEM_NOTGUILDMASTER );
2012-07-24 15:27:42 +01:00
else if ( ! player -> HasEnoughMoney ( uint64 ( EMBLEM_PRICE )))
2010-10-17 19:54:13 +06:00
// "You can't afford to do that."
SendSaveEmblemResult ( session , ERR_GUILDEMBLEM_NOTENOUGHMONEY );
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
2010-10-17 19:54:13 +06:00
// "Guild Emblem saved."
SendSaveEmblemResult ( session , ERR_GUILDEMBLEM_SUCCESS );
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
2010-10-17 19:54:13 +06:00
void Guild :: HandleSetLeader ( WorldSession * session , const std :: string & name )
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
// Only leader can assign new leader
if ( ! _IsLeader ( player ))
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
// Old leader must be a member of guild
else if ( Member * pOldLeader = GetMember ( player -> GetGUID ()))
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// New leader must be a member of guild
if ( Member * pNewLeader = GetMember ( session , name ))
{
_SetLeaderGUID ( pNewLeader );
pOldLeader -> ChangeRank ( GR_OFFICER );
_BroadcastEvent ( GE_LEADER_CHANGED , 0 , player -> GetName (), name . c_str ());
}
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
else
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
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 :: HandleSetBankTabInfo ( WorldSession * session , uint8 tabId , const std :: string & name , const std :: string & icon )
{
if ( BankTab * pTab = GetBankTab ( tabId ))
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
pTab -> SetInfo ( name , icon );
SendBankTabsInfo ( session );
_SendBankContent ( session , tabId );
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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , 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 );
2010-10-17 19:54:13 +06:00
HandleRoster ( session );
}
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 :: HandleSetRankInfo ( WorldSession * session , uint32 rankId , const std :: string & 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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
else if ( RankInfo * rankInfo = GetRankInfo ( rankId ))
{
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: 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
uint8 tabId = 0 ;
for ( GuildBankRightsAndSlotsVec :: const_iterator itr = rightsAndSlots . begin (); itr != rightsAndSlots . end (); ++ itr )
_SetRankBankTabRightsAndSlots ( rankId , tabId ++ , * itr );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
HandleQuery ( session );
HandleRoster (); // Broadcast for tab rights update
}
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: HandleBuyBankTab ( WorldSession * session , uint8 tabId )
{
if ( tabId != _GetPurchasedTabsSize ())
return ;
2010-02-18 02:42:59 +01:00
2010-10-17 19:54:13 +06:00
uint32 tabCost = _GetGuildBankTabPrice ( tabId ) * GOLD ;
if ( ! tabCost )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
Player * player = session -> GetPlayer ();
2012-07-24 15:27:42 +01:00
if ( ! player -> HasEnoughMoney ( uint64 ( tabCost ))) // Should not happen, this is checked by client
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 ( ! _CreateNewBankTab ())
return ;
2009-10-17 15:51:44 -07:00
2012-07-24 15:27:42 +01:00
player -> ModifyMoney ( - int64 ( tabCost ));
2011-03-08 16:42:00 +01:00
_SetRankBankMoneyPerDay ( player -> GetRank (), uint32 ( GUILD_WITHDRAW_MONEY_UNLIMITED ));
_SetRankBankTabRightsAndSlots ( player -> GetRank (), tabId , GuildBankRightsAndSlots ( GUILD_BANK_RIGHT_FULL , uint32 ( GUILD_WITHDRAW_SLOT_UNLIMITED )));
2010-10-17 19:54:13 +06:00
HandleRoster (); // Broadcast for tab rights update
SendBankTabsInfo ( session );
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 :: HandleInviteMember ( WorldSession * session , const std :: string & name )
2008-10-11 14:16:25 -05:00
{
2010-12-23 23:25:44 +01:00
Player * pInvitee = sObjectAccessor -> FindPlayerByName ( name . c_str ());
2010-10-17 19:54:13 +06:00
if ( ! pInvitee )
{
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , 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 ;
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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_NOT_ALLIED , name );
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
// 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-08-04 18:40:56 +02:00
SendCommandResult(session, GUILD_INVITE, ERR_ALREADY_IN_GUILD_S, name);
2010-10-17 19:54:13 +06:00
return;
2012-08-04 18:40:56 +02:00
}*/
2010-10-17 19:54:13 +06:00
// Invited player cannot be invited
if ( pInvitee -> GetGuildIdInvited ())
{
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , 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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , 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
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "Player %s invited %s to join his Guild" , player -> GetName (), 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 ]);
data . WriteBits ( strlen ( player -> GetName ()), 7 );
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-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_INVITE)" );
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
2010-10-17 19:54:13 +06:00
if ( AddMember ( player -> GetGUID ()))
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
_LogEvent ( GUILD_EVENT_LOG_JOIN_GUILD , player -> GetGUIDLow ());
_BroadcastEvent ( GE_JOINED , player -> GetGUID (), player -> GetName ());
}
}
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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_QUIT_S , ERR_GUILD_LEADER_LEAVE );
2010-10-17 19:54:13 +06:00
else
// Guild is disbanded if leader leaves.
Disband ();
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 ());
_BroadcastEvent ( GE_LEFT , player -> GetGUID (), player -> GetName ());
2009-10-17 15:51:44 -07:00
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_QUIT_S , ERR_PLAYER_NO_MORE_IN_GUILD , m_name );
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-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
Player * removedPlayer = ObjectAccessor :: FindPlayer ( guid );
Member * member = GetMember ( guid );
2010-10-17 19:54:13 +06:00
// Player must have rights to remove members
if ( ! _HasRankRight ( player , GR_RIGHT_REMOVE ))
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
2012-08-04 18:40:56 +02:00
// Removed player must be a member of the guild
else if ( member && removedPlayer )
2010-10-17 19:54:13 +06:00
{
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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_QUIT_S , ERR_GUILD_LEADER_LEAVE );
2010-10-17 19:54:13 +06:00
// Do not allow to remove player with the same rank or higher
2012-05-30 08:01:02 +02:00
else if ( member -> IsRankNotLower ( player -> GetRank ()))
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_QUIT_S , ERR_GUILD_RANK_TOO_HIGH_S , removedPlayer -> GetName ());
2010-10-17 19:54:13 +06:00
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 ));
2012-08-04 18:40:56 +02:00
_BroadcastEvent ( GE_REMOVED , 0 , removedPlayer -> GetName (), player -> GetName ());
2010-10-17 19:54:13 +06:00
}
}
2012-08-04 18:40:56 +02:00
else if ( removedPlayer )
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_QUIT_S , ERR_PLAYER_NO_MORE_IN_GUILD , removedPlayer -> GetName ());
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 :: HandleUpdateMemberRank ( WorldSession * session , uint64 targetGuid , bool demote )
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
// Promoted player must be a member of guild
2012-08-04 18:40:56 +02:00
if ( Member * member = GetMember ( targetGuid ))
2008-10-11 14:16:25 -05:00
{
2012-08-04 18:40:56 +02:00
if ( ! _HasRankRight ( player , demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE ))
{
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
2012-08-04 18:40:56 +02:00
return ;
}
2012-08-04 19:11:13 +01:00
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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_NAME_INVALID );
2010-10-17 19:54:13 +06:00
return ;
}
2010-02-15 14:30:12 +01:00
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-05-30 08:01:02 +02:00
if ( member -> IsRankNotLower ( player -> GetRank ()))
2010-02-15 14:30:12 +01:00
{
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_RANK_TOO_HIGH_S , member -> GetName ());
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-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_RANK_TOO_LOW_S , member -> GetName ());
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-05-30 08:01:02 +02:00
// member->GetRank() + 1 is the highest rank that current player can promote to
if ( member -> IsRankNotLower ( player -> GetRank () + 1 ))
2010-10-17 19:54:13 +06:00
{
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_RANK_TOO_HIGH_S , member -> GetName ());
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-08-04 18:40:56 +02:00
_BroadcastEvent ( demote ? GE_DEMOTION : GE_PROMOTION , 0 , player -> GetName (), member -> GetName (). c_str (), _GetRankName ( newRankId ). c_str ());
}
}
void Guild :: HandleSetMemberRank ( WorldSession * session , uint64 targetGuid , uint64 setterGuid , uint32 rank )
{
Player * player = session -> GetPlayer ();
// Promoted player must be a member of guild
if ( Member * member = GetMember ( targetGuid ))
{
if ( ! _HasRankRight ( player , rank > member -> GetRankId () ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE ))
{
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
2012-08-04 18:40:56 +02:00
return ;
}
2012-08-04 19:11:13 +01:00
2012-08-04 18:40:56 +02:00
// Player cannot promote himself
if ( member -> IsSamePlayer ( player -> GetGUID ()))
{
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_NAME_INVALID );
2012-08-04 18:40:56 +02:00
return ;
}
SendGuildRanksUpdate ( setterGuid , targetGuid , rank );
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 :: HandleAddNewRank ( WorldSession * session , std :: string const & name ) //, uint32 rankId)
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( _GetRanksSize () >= GUILD_RANKS_MAX_COUNT )
return ;
// Only leader can add new rank
if ( ! _IsLeader ( session -> GetPlayer ()))
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
else
{
_CreateRank ( name , GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK );
HandleQuery ( session );
HandleRoster (); // Broadcast for tab rights update
}
}
2009-10-17 15:51:44 -07:00
2012-08-04 18:40:56 +02:00
void Guild :: HandleRemoveRank ( WorldSession * session , uint32 rankId )
2010-10-17 19:54:13 +06:00
{
// Cannot remove rank if total count is minimum allowed by the client
if ( _GetRanksSize () <= GUILD_RANKS_MIN_COUNT )
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
// Only leader can delete ranks
if ( ! _IsLeader ( session -> GetPlayer ()))
2012-08-10 14:25:04 +02:00
SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
2010-10-17 19:54:13 +06:00
else
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
// Delete bank rights for rank
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK );
stmt -> setUInt32 ( 0 , m_id );
2012-08-04 18:40:56 +02:00
stmt -> setUInt8 ( 1 , rankId );
2010-10-17 19:54:13 +06:00
CharacterDatabase . Execute ( stmt );
// Delete rank
2012-08-04 18:40:56 +02:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_RANK );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_id );
2012-08-04 18:40:56 +02:00
stmt -> setUInt8 ( 1 , rankId );
2010-10-17 19:54:13 +06:00
CharacterDatabase . Execute ( stmt );
2012-08-04 18:40:56 +02:00
m_ranks . erase ( m_ranks . begin () + rankId - 1 );
2010-10-17 19:54:13 +06:00
HandleQuery ( session );
HandleRoster (); // Broadcast for tab rights update
}
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: HandleMemberDepositMoney ( WorldSession * session , uint32 amount )
{
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 ();
// Add money to bank
_ModifyBankMoney ( trans , amount , true );
// Remove money from player
2012-07-24 15:27:42 +01:00
player -> ModifyMoney ( - int64 ( amount ));
2010-10-17 19:54:13 +06:00
player -> SaveGoldToDB ( trans );
// Log GM action (TODO: move to scripts)
2011-09-08 15:11:55 +02:00
if ( ! AccountMgr :: IsPlayerAccount ( player -> GetSession () -> GetSecurity ()) && sWorld -> getBoolConfig ( CONFIG_GM_LOG_TRADE ))
2010-10-17 19:54:13 +06:00
{
2010-12-23 23:25:44 +01:00
sLog -> outCommand ( player -> GetSession () -> GetAccountId (),
2012-08-17 10:25:29 +02:00
"GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)" ,
2010-10-17 19:54:13 +06:00
player -> GetName (), player -> GetSession () -> GetAccountId (), amount , m_id );
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
// Log guild bank event
_LogBankEvent ( trans , GUILD_BANK_LOG_DEPOSIT_MONEY , uint8 ( 0 ), player -> GetGUIDLow (), amount );
CharacterDatabase . CommitTransaction ( trans );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
SendBankTabsInfo ( session );
_SendBankContent ( session , 0 );
_SendBankMoneyUpdate ( session );
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 :: HandleMemberWithdrawMoney ( WorldSession * session , uint32 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 ();
if ( ! _HasRankRight ( player , repair ? GR_RIGHT_WITHDRAW_REPAIR : GR_RIGHT_WITHDRAW_GOLD ))
return false ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
uint32 remainingMoney = _GetMemberRemainingMoney ( player -> GetGUID ());
if ( ! remainingMoney )
return false ;
2009-10-17 15:51:44 -07:00
2010-11-11 22:59:06 +01:00
if ( remainingMoney < amount )
return false ;
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 ();
// Update remaining money amount
2010-12-13 16:58:59 +01:00
if ( remainingMoney < uint32 ( GUILD_WITHDRAW_MONEY_UNLIMITED ))
2012-05-30 08:01:02 +02:00
if ( Member * member = GetMember ( player -> GetGUID ()))
member -> DecreaseBankRemainingValue ( trans , GUILD_BANK_MAX_TABS , amount );
2010-10-17 19:54:13 +06:00
// Remove money from bank
_ModifyBankMoney ( trans , amount , false );
// Add money to player (if required)
if ( ! repair )
{
player -> ModifyMoney ( amount );
player -> SaveGoldToDB ( trans );
}
// 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
2010-10-17 19:54:13 +06:00
SendMoneyInfo ( session );
if ( ! repair )
{
SendBankTabsInfo ( session );
_SendBankContent ( session , 0 );
_SendBankMoneyUpdate ( session );
}
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 ();
2008-10-11 14:16:25 -05:00
}
2010-10-17 19:54:13 +06:00
_BroadcastEvent ( GE_SIGNED_OFF , player -> GetGUID (), player -> GetName ());
}
void Guild :: HandleDisband ( WorldSession * session )
{
// Only leader can disband guild
if ( ! _IsLeader ( session -> GetPlayer ()))
2012-08-10 14:25:04 +02:00
Guild :: SendCommandResult ( session , GUILD_INVITE_S , ERR_GUILD_PERMISSIONS );
2008-10-11 14:16:25 -05:00
else
{
2010-10-17 19:54:13 +06:00
Disband ();
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: 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 );
data . WriteBit ( 0 ); // Is guild group
data . FlushBits ();
data << float ( 0.f ); // Guild XP multiplier
data << uint32 ( 0 ); // Current guild members
data << uint32 ( 0 ); // Needed guild members
session -> SendPacket ( & data );
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Sent (SMSG_GUILD_PARTY_STATE_RESPONSE)" );
}
2010-10-17 19:54:13 +06:00
///////////////////////////////////////////////////////////////////////////////
// Send data to client
void Guild :: SendInfo ( WorldSession * session ) const
{
WorldPacket data ( SMSG_GUILD_INFO , m_name . size () + 4 + 4 + 4 );
data << m_name ;
data << secsToTimeBitFields ( m_createdDate ); // 3.x (prev. year + month + day)
data << uint32 ( m_members . size ()); // Number of members
data << m_accountsNumber ; // Number of accounts
session -> SendPacket ( & data );
2012-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_INFO)" );
2010-10-17 19:54:13 +06:00
}
2011-09-15 14:08:17 +02:00
void Guild :: SendEventLog ( WorldSession * session ) const
2010-10-17 19:54:13 +06:00
{
WorldPacket data ( MSG_GUILD_EVENT_LOG_QUERY , 1 + m_eventLog -> GetSize () * ( 1 + 8 + 4 ));
m_eventLog -> WritePacket ( data );
session -> SendPacket ( & data );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (MSG_GUILD_EVENT_LOG_QUERY)" );
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 :: 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 )
{
const LogHolder * pLog = m_bankEventLog [ tabId ];
WorldPacket data ( MSG_GUILD_BANK_LOG_QUERY , pLog -> GetSize () * ( 4 * 4 + 1 ) + 1 + 1 );
data << uint8 ( tabId );
pLog -> WritePacket ( data );
session -> SendPacket ( & data );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (MSG_GUILD_BANK_LOG_QUERY)" );
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 :: SendBankTabData ( WorldSession * session , uint8 tabId ) const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
if ( tabId < _GetPurchasedTabsSize ())
{
SendMoneyInfo ( session );
_SendBankContent ( session , 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 :: SendBankTabsInfo ( WorldSession * session ) const
2008-10-11 14:16:25 -05:00
{
2010-10-17 19:54:13 +06:00
WorldPacket data ( SMSG_GUILD_BANK_LIST , 500 );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint64 ( m_bankMoney );
data << uint8 ( 0 ); // TabInfo packet must be for tabId 0
data << uint32 ( _GetMemberRemainingSlots ( session -> GetPlayer () -> GetGUID (), 0 ));
data << uint8 ( 1 ); // Tell client that this packet includes tab info
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint8 ( _GetPurchasedTabsSize ()); // Number of tabs
for ( uint8 i = 0 ; i < _GetPurchasedTabsSize (); ++ i )
m_bankTabs [ i ] -> WriteInfoPacket ( data );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint8 ( 0 ); // Do not send tab content
session -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
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
}
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
{
if ( const BankTab * pTab = GetBankTab ( tabId ))
pTab -> SendText ( this , session );
}
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
{
2011-08-30 13:46:36 +02:00
uint64 guid = session -> GetPlayer () -> GetGUID ();
2012-08-04 18:40:56 +02:00
uint32 rankId = session -> GetPlayer () -> GetRank ();
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 ));
data << uint32 ( _GetMemberRemainingMoney ( guid ));
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 ));
data << uint32 ( _GetMemberRemainingSlots ( guid , 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-08-04 18:40:56 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_PERMISSIONS_QUERY_RESULTS)" );
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-07-19 01:21:41 +02:00
WorldPacket data ( SMSG_GUILD_BANK_MONEY_WITHDRAWN , 4 );
data << uint64 ( _GetMemberRemainingMoney ( session -> GetPlayer () -> GetGUID ()));
2010-10-17 19:54:13 +06:00
session -> SendPacket ( & data );
2012-08-04 18:40:56 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent SMSG_GUILD_BANK_MONEY_WITHDRAWN" );
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 :: SendLoginInfo ( WorldSession * session ) const
2008-10-11 14:16:25 -05:00
{
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 );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent guild MOTD (SMSG_GUILD_EVENT)" );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
SendBankTabsInfo ( session );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
_BroadcastEvent ( GE_SIGNED_ON , session -> GetPlayer () -> GetGUID (), session -> GetPlayer () -> GetName ());
}
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-05-30 08:01:02 +02:00
uint8 purchasedTabs = uint8 ( fields [ 12 ]. 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
{
// rights slots
GuildBankRightsAndSlots rightsAndSlots ( fields [ 3 ]. GetUInt8 (), fields [ 4 ]. GetUInt32 ());
// rankId tabId
_SetRankBankTabRightsAndSlots ( fields [ 2 ]. GetUInt8 (), fields [ 1 ]. GetUInt8 (), rightsAndSlots , false );
}
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
2010-10-17 19:54:13 +06:00
bool 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 );
2010-10-17 19:54:13 +06:00
return false ;
}
return m_bankTabs [ tabId ] -> LoadFromDB ( fields );
}
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
2010-10-17 19:54:13 +06:00
// Min ranks count is 5 and max is 10.
bool broken_ranks = false ;
if ( _GetRanksSize () < GUILD_RANKS_MIN_COUNT || _GetRanksSize () > GUILD_RANKS_MAX_COUNT )
{
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
{
for ( uint8 rankId = 0 ; rankId < _GetRanksSize (); ++ rankId )
{
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 ;
}
}
}
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
2011-09-15 14:08:17 +02:00
void Guild :: BroadcastToGuild ( WorldSession * session , bool officerOnly , const std :: string & 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-08-04 15:58:09 +01:00
void Guild :: BroadcastAddonToGuild ( WorldSession * session , bool officerOnly , const std :: string & msg , const std :: string & prefix ) const
{
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 , CHAT_MSG_ADDON , NULL , 0 , msg . c_str (), NULL , prefix . c_str ());
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
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 );
2010-10-17 19:54:13 +06:00
if ( player )
2012-05-30 08:01:02 +02:00
member -> SetStats ( player );
2010-10-17 19:54:13 +06:00
else
{
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-05-30 08:01:02 +02:00
member -> SetStats (
2010-12-13 22:37:56 +01:00
fields [ 0 ]. GetString (),
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 (),
2010-10-17 19:54:13 +06:00
fields [ 4 ]. GetUInt32 ());
2012-05-30 08:01:02 +02:00
ok = member -> CheckStats ();
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 ;
}
2008-10-11 14:16:25 -05:00
}
2012-05-30 08:01:02 +02:00
m_members [ lowguid ] = member ;
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 );
2010-10-17 19:54:13 +06:00
// If player not in game data in will be loaded from guild tables, so no need to update it!
if ( player )
{
player -> SetInGuild ( m_id );
player -> SetRank ( rankId );
2012-08-10 14:25:04 +02:00
player -> SetGuildLevel ( m_level );
2010-10-17 19:54:13 +06:00
player -> SetGuildIdInvited ( 0 );
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
_UpdateAccountsNumber ();
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 ;
}
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 ());
}
}
// Call script on remove before member is acutally 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 );
}
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
2011-12-22 03:49:36 +00:00
bool Guild :: IsMember ( uint64 guid )
{
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
void Guild :: SetBankTabText ( uint8 tabId , const std :: string & text )
{
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 ));
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
2010-10-17 19:54:13 +06:00
bool Guild :: _CreateNewBankTab ()
{
if ( _GetPurchasedTabsSize () >= GUILD_BANK_MAX_TABS )
return false ;
2009-10-17 15:51:44 -07:00
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
PreparedStatement * stmt = NULL ;
SQLTransaction trans = CharacterDatabase . BeginTransaction ();
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
stmt = CharacterDatabase . GetPreparedStatement ( CHAR_DEL_GUILD_BANK_TAB );
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
2010-10-17 19:54:13 +06:00
CharacterDatabase . CommitTransaction ( trans );
return true ;
}
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
void Guild :: _CreateDefaultGuildRanks ( LocaleConstant loc )
{
PreparedStatement * stmt = NULL ;
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 );
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
2010-10-17 19:54:13 +06:00
void Guild :: _CreateRank ( const std :: string & name , uint32 rights )
{
if ( _GetRanksSize () >= GUILD_RANKS_MAX_COUNT )
return ;
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
2012-08-04 18:40:56 +02:00
uint32 newRankId = _GetRanksSize ();
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 ();
for ( uint8 i = 0 ; i < _GetPurchasedTabsSize (); ++ i )
{
// Create bank rights with default values
2012-01-01 01:09:38 +01:00
PreparedStatement * stmt = CharacterDatabase . GetPreparedStatement ( CHAR_INS_GUILD_BANK_RIGHT_DEFAULT );
2010-10-17 19:54:13 +06:00
stmt -> setUInt32 ( 0 , m_id );
stmt -> setUInt8 ( 1 , i );
stmt -> setUInt8 ( 2 , newRankId );
trans -> Append ( stmt );
2009-08-24 20:18:16 -05:00
}
2010-10-17 19:54:13 +06:00
info . SaveToDB ( trans );
CharacterDatabase . CommitTransaction ( trans );
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 );
}
2012-08-04 18:40:56 +02:00
void Guild :: _SetRankBankMoneyPerDay ( uint32 rankId , uint32 moneyPerDay )
2010-10-17 19:54:13 +06:00
{
if ( RankInfo * rankInfo = GetRankInfo ( rankId ))
2009-08-24 20:18:16 -05:00
{
2010-10-17 19:54:13 +06:00
for ( Members :: iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
if ( itr -> second -> IsRank ( rankId ))
itr -> second -> ResetMoneyTime ();
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
rankInfo -> SetBankMoneyPerDay ( moneyPerDay );
}
}
2009-10-17 15:51:44 -07:00
2012-08-04 18:40:56 +02:00
void Guild :: _SetRankBankTabRightsAndSlots ( uint32 rankId , uint8 tabId , GuildBankRightsAndSlots rightsAndSlots , bool saveToDB )
2010-10-17 19:54:13 +06:00
{
if ( tabId >= _GetPurchasedTabsSize ())
return ;
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
if ( RankInfo * rankInfo = GetRankInfo ( rankId ))
{
for ( Members :: iterator itr = m_members . begin (); itr != m_members . end (); ++ itr )
if ( itr -> second -> IsRank ( rankId ))
itr -> second -> ResetTabTimes ();
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
rankInfo -> SetBankTabSlotsAndRights ( tabId , rightsAndSlots , saveToDB );
}
}
2009-10-17 15:51:44 -07:00
2012-08-04 18:40:56 +02:00
inline std :: string Guild :: _GetRankName ( uint32 rankId ) const
2010-10-17 19:54:13 +06:00
{
if ( const RankInfo * rankInfo = GetRankInfo ( rankId ))
return rankInfo -> GetName ();
return "<unknown>" ;
}
2009-10-17 15:51:44 -07:00
2012-08-04 18:40:56 +02:00
inline uint32 Guild :: _GetRankRights ( uint32 rankId ) const
2010-10-17 19:54:13 +06:00
{
if ( const RankInfo * rankInfo = GetRankInfo ( rankId ))
return rankInfo -> GetRights ();
return 0 ;
}
2009-10-17 15:51:44 -07:00
2012-08-04 18:40:56 +02:00
inline uint32 Guild :: _GetRankBankMoneyPerDay ( uint32 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-08-04 18:40:56 +02:00
inline uint32 Guild :: _GetRankBankTabSlotsPerDay ( uint32 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-08-04 18:40:56 +02:00
inline uint32 Guild :: _GetRankBankTabRights ( uint32 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
2011-08-30 13:46:36 +02:00
inline uint32 Guild :: _GetMemberRemainingSlots ( uint64 guid , uint8 tabId ) const
2010-10-17 19:54:13 +06:00
{
2012-05-30 08:01:02 +02:00
if ( const Member * member = GetMember ( guid ))
return member -> GetBankRemainingValue ( tabId , this );
2010-10-17 19:54:13 +06:00
return 0 ;
}
2011-08-30 13:46:36 +02:00
inline uint32 Guild :: _GetMemberRemainingMoney ( uint64 guid ) const
2010-10-17 19:54:13 +06:00
{
2012-05-30 08:01:02 +02:00
if ( const Member * member = GetMember ( guid ))
return member -> GetBankRemainingValue ( GUILD_BANK_MAX_TABS , this );
2010-10-17 19:54:13 +06:00
return 0 ;
}
2009-10-17 15:51:44 -07:00
2011-08-30 13:46:36 +02:00
inline void Guild :: _DecreaseMemberRemainingSlots ( SQLTransaction & trans , uint64 guid , uint8 tabId )
2010-10-17 19:54:13 +06:00
{
// Remaining slots must be more then 0
if ( uint32 remainingSlots = _GetMemberRemainingSlots ( guid , tabId ))
// Ignore guild master
2010-12-13 16:42:09 +01:00
if ( remainingSlots < uint32 ( GUILD_WITHDRAW_SLOT_UNLIMITED ))
2012-05-30 08:01:02 +02:00
if ( Member * member = GetMember ( guid ))
member -> DecreaseBankRemainingValue ( 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
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-08-03 14:20:18 +02:00
sLog->outFatal(LOG_FILTER_GENERAL, "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 ;
}
2011-09-15 14:08:17 +02:00
void Guild :: _SendBankContent ( WorldSession * session , uint8 tabId ) const
2010-10-17 19:54:13 +06:00
{
2011-08-30 13:46:36 +02:00
uint64 guid = session -> GetPlayer () -> GetGUID ();
2010-10-17 19:54:13 +06:00
if ( _MemberHasTabRights ( guid , tabId , GUILD_BANK_RIGHT_VIEW_TAB ))
if ( const BankTab * pTab = GetBankTab ( tabId ))
2009-08-24 20:18:16 -05:00
{
2010-10-17 19:54:13 +06:00
WorldPacket data ( SMSG_GUILD_BANK_LIST , 1200 );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint64 ( m_bankMoney );
data << uint8 ( tabId );
data << uint32 ( _GetMemberRemainingSlots ( guid , tabId ));
data << uint8 ( 0 ); // Tell client that there's no tab info in this packet
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
pTab -> WritePacket ( data );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
session -> SendPacket ( & data );
2009-10-17 15:51:44 -07:00
2012-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
2009-08-24 20:18:16 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
void Guild :: _SendBankMoneyUpdate ( WorldSession * session ) const
2010-04-11 11:06:51 +04:00
{
2010-10-17 19:54:13 +06:00
WorldPacket data ( SMSG_GUILD_BANK_LIST , 8 + 1 + 4 + 1 + 1 );
2010-04-11 11:06:51 +04:00
2010-10-17 19:54:13 +06:00
data << uint64 ( m_bankMoney );
data << uint8 ( 0 ); // tabId, default 0
data << uint32 ( _GetMemberRemainingSlots ( session -> GetPlayer () -> GetGUID (), 0 ));
data << uint8 ( 0 ); // Tell that there's no tab info in this packet
data << uint8 ( 0 ); // No items
2010-04-11 11:06:51 +04:00
BroadcastPacket ( & data );
2012-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent (SMSG_GUILD_BANK_LIST)" );
2010-04-11 11:06:51 +04:00
}
2010-10-17 19:54:13 +06:00
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 );
}
_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
{
WorldPacket data ( SMSG_GUILD_BANK_LIST , 1200 );
2009-10-17 15:51:44 -07:00
2010-10-17 19:54:13 +06:00
data << uint64 ( m_bankMoney );
data << uint8 ( tabId );
size_t rempos = data . wpos ();
data << uint32 ( 0 ); // Item withdraw amount, will be filled later
data << uint8 ( 0 ); // Tell client that there's no tab info in this packet
data << uint8 ( slots . size ());
for ( uint8 slotId = 0 ; slotId < GUILD_BANK_MAX_SLOTS ; ++ slotId )
if ( slots . find ( slotId ) != slots . end ())
2012-08-10 14:25:04 +02:00
tab -> WriteSlotPacket ( data , slotId );
2010-10-17 19:54:13 +06:00
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
{
data . put < uint32 > ( rempos , uint32 ( _GetMemberRemainingSlots ( player -> GetGUID (), tabId )));
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-08-03 14:20:18 +02:00
sLog -> outDebug ( LOG_FILTER_GUILD , "WORLD: Sent SMSG_GUILD_EVENT" );
2008-10-11 14:16:25 -05:00
}
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 );
sLog -> outDebug ( LOG_FILTER_NETWORKIO , "WORLD: Sent SMSG_GUILD_RANKS_UPDATE" );
}