/*
* Copyright (C) 2008-2012 TrinityCore
* Copyright (C) 2005-2009 MaNGOS
*
* 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 .
*/
#ifndef TRINITYCORE_GUILD_H
#define TRINITYCORE_GUILD_H
#include "World.h"
#include "Item.h"
#include "WorldPacket.h"
#include "ObjectMgr.h"
#include "Player.h"
class Item;
enum GuildMisc
{
GUILD_BANK_MAX_TABS = 8, // send by client for money log also
GUILD_BANK_MAX_SLOTS = 98,
GUILD_BANK_MONEY_LOGS_TAB = 100, // used for money log in DB
GUILD_RANKS_MIN_COUNT = 5,
GUILD_RANKS_MAX_COUNT = 10,
GUILD_RANK_NONE = 0xFF,
GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF,
GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF,
GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF,
};
enum GuildDefaultRanks
{
// These ranks can be modified, but they cannot be deleted
GR_GUILDMASTER = 0,
GR_OFFICER = 1,
GR_VETERAN = 2,
GR_MEMBER = 3,
GR_INITIATE = 4,
// When promoting member server does: rank--
// When demoting member server does: rank++
};
enum GuildRankRights
{
GR_RIGHT_EMPTY = 0x00000040,
GR_RIGHT_GCHATLISTEN = GR_RIGHT_EMPTY | 0x00000001,
GR_RIGHT_GCHATSPEAK = GR_RIGHT_EMPTY | 0x00000002,
GR_RIGHT_OFFCHATLISTEN = GR_RIGHT_EMPTY | 0x00000004,
GR_RIGHT_OFFCHATSPEAK = GR_RIGHT_EMPTY | 0x00000008,
GR_RIGHT_INVITE = GR_RIGHT_EMPTY | 0x00000010,
GR_RIGHT_REMOVE = GR_RIGHT_EMPTY | 0x00000020,
GR_RIGHT_PROMOTE = GR_RIGHT_EMPTY | 0x00000080,
GR_RIGHT_DEMOTE = GR_RIGHT_EMPTY | 0x00000100,
GR_RIGHT_SETMOTD = GR_RIGHT_EMPTY | 0x00001000,
GR_RIGHT_EPNOTE = GR_RIGHT_EMPTY | 0x00002000,
GR_RIGHT_VIEWOFFNOTE = GR_RIGHT_EMPTY | 0x00004000,
GR_RIGHT_EOFFNOTE = GR_RIGHT_EMPTY | 0x00008000,
GR_RIGHT_MODIFY_GUILD_INFO = GR_RIGHT_EMPTY | 0x00010000,
GR_RIGHT_WITHDRAW_GOLD_LOCK = 0x00020000, // remove money withdraw capacity
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk
GR_RIGHT_ALL = 0x001DF1FF
};
enum GuildCommandType
{
GUILD_CREATE_S = 0x00,
GUILD_INVITE_S = 0x01,
GUILD_QUIT_S = 0x03,
GUILD_FOUNDER_S = 0x0E,
GUILD_UNK1 = 0x13,
GUILD_UNK2 = 0x14
};
enum GuildCommandError
{
ERR_PLAYER_NO_MORE_IN_GUILD = 0x00,
ERR_GUILD_INTERNAL = 0x01,
ERR_ALREADY_IN_GUILD = 0x02,
ERR_ALREADY_IN_GUILD_S = 0x03,
ERR_INVITED_TO_GUILD = 0x04,
ERR_ALREADY_INVITED_TO_GUILD_S = 0x05,
ERR_GUILD_NAME_INVALID = 0x06,
ERR_GUILD_NAME_EXISTS_S = 0x07,
ERR_GUILD_LEADER_LEAVE = 0x08,
ERR_GUILD_PERMISSIONS = 0x08,
ERR_GUILD_PLAYER_NOT_IN_GUILD = 0x09,
ERR_GUILD_PLAYER_NOT_IN_GUILD_S = 0x0A,
ERR_GUILD_PLAYER_NOT_FOUND_S = 0x0B,
ERR_GUILD_NOT_ALLIED = 0x0C,
ERR_GUILD_RANK_TOO_HIGH_S = 0x0D,
ERR_GUILD_RANK_TOO_LOW_S = 0x0E,
ERR_GUILD_RANKS_LOCKED = 0x11,
ERR_GUILD_RANK_IN_USE = 0x12,
ERR_GUILD_IGNORING_YOU_S = 0x13,
ERR_GUILD_UNK1 = 0x14,
ERR_GUILD_WITHDRAW_LIMIT = 0x19,
ERR_GUILD_NOT_ENOUGH_MONEY = 0x1A,
ERR_GUILD_BANK_FULL = 0x1C,
ERR_GUILD_ITEM_NOT_FOUND = 0x1D,
ERR_GUILD_TOO_MUCH_MONEY = 0x1F,
ERR_GUILD_BANK_WRONG_TAB = 0x20,
ERR_RANK_REQUIRES_AUTHENTICATOR = 0x22,
ERR_GUILD_BANK_VOUCHER_FAILED = 0x23,
ERR_GUILD_TRIAL_ACCOUNT = 0x24,
ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL = 0x25,
ERR_GUILD_MOVE_STARTING = 0x26,
ERR_GUILD_REP_TOO_LOW = 0x27,
};
enum GuildEvents
{
GE_PROMOTION = 1,
GE_DEMOTION = 2,
GE_MOTD = 3,
GE_JOINED = 4,
GE_LEFT = 5,
GE_REMOVED = 6,
GE_LEADER_IS = 7,
GE_LEADER_CHANGED = 8,
GE_DISBANDED = 9,
GE_TABARDCHANGE = 10,
GE_RANK_UPDATED = 11,
GE_RANK_CREATED = 12,
GE_RANK_DELETED = 13,
GE_RANK_ORDER_CHANGED = 14,
GE_FOUNDER = 15, // At guild creation - Set founder
GE_SIGNED_ON = 16,
GE_SIGNED_OFF = 17,
GE_GUILDBANKBAGSLOTS_CHANGED = 18,
GE_BANK_TAB_PURCHASED = 19,
GE_BANK_TAB_UPDATED = 20,
GE_BANK_MONEY_UPDATED = 21,
GE_BANK_MONEY_WITHDRAWN = 22,
GE_BANK_TEXT_CHANGED = 23,
// 24 - error 795
GE_SIGNED_ON_MOBILE = 25,
GE_SIGNED_Off_MOBILE = 26,
};
enum PetitionTurns
{
PETITION_TURN_OK = 0,
PETITION_TURN_ALREADY_IN_GUILD = 2,
PETITION_TURN_NEED_MORE_SIGNATURES = 4,
PETITION_TURN_GUILD_PERMISSIONS = 11,
PETITION_TURN_GUILD_NAME_INVALID = 12,
};
enum PetitionSigns
{
PETITION_SIGN_OK = 0,
PETITION_SIGN_ALREADY_SIGNED = 1,
PETITION_SIGN_ALREADY_IN_GUILD = 2,
PETITION_SIGN_CANT_SIGN_OWN = 3,
PETITION_SIGN_NOT_SERVER = 4,
PETITION_SIGN_FULL = 5,
PETITION_SIGN_ALREADY_SIGNED_OTHER = 6,
PETITION_SIGN_RESTRICTED_ACCOUNT = 7,
};
enum GuildBankRights
{
GUILD_BANK_RIGHT_VIEW_TAB = 0x01,
GUILD_BANK_RIGHT_PUT_ITEM = 0x02,
GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04,
GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM,
GUILD_BANK_RIGHT_FULL = 0xFF,
};
enum GuildBankEventLogTypes
{
GUILD_BANK_LOG_DEPOSIT_ITEM = 1,
GUILD_BANK_LOG_WITHDRAW_ITEM = 2,
GUILD_BANK_LOG_MOVE_ITEM = 3,
GUILD_BANK_LOG_DEPOSIT_MONEY = 4,
GUILD_BANK_LOG_WITHDRAW_MONEY = 5,
GUILD_BANK_LOG_REPAIR_MONEY = 6,
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
GUILD_BANK_LOG_UNK1 = 8,
GUILD_BANK_LOG_BUY_SLOT = 9,
};
enum GuildEventLogTypes
{
GUILD_EVENT_LOG_INVITE_PLAYER = 1,
GUILD_EVENT_LOG_JOIN_GUILD = 2,
GUILD_EVENT_LOG_PROMOTE_PLAYER = 3,
GUILD_EVENT_LOG_DEMOTE_PLAYER = 4,
GUILD_EVENT_LOG_UNINVITE_PLAYER = 5,
GUILD_EVENT_LOG_LEAVE_GUILD = 6,
};
enum GuildEmblemError
{
ERR_GUILDEMBLEM_SUCCESS = 0,
ERR_GUILDEMBLEM_INVALID_TABARD_COLORS = 1,
ERR_GUILDEMBLEM_NOGUILD = 2,
ERR_GUILDEMBLEM_NOTGUILDMASTER = 3,
ERR_GUILDEMBLEM_NOTENOUGHMONEY = 4,
ERR_GUILDEMBLEM_INVALIDVENDOR = 5
};
enum GuildMemberFlags
{
GUILDMEMBER_STATUS_NONE = 0x0000,
GUILDMEMBER_STATUS_ONLINE = 0x0001,
GUILDMEMBER_STATUS_AFK = 0x0002,
GUILDMEMBER_STATUS_DND = 0x0004,
GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app
};
////////////////////////////////////////////////////////////////////////////////////////////
// Emblem info
class EmblemInfo
{
public:
EmblemInfo() : m_style(0), m_color(0), m_borderStyle(0), m_borderColor(0), m_backgroundColor(0) { }
void LoadFromDB(Field* fields);
void SaveToDB(uint32 guildId) const;
void ReadPacket(WorldPacket& recv) { recv >> m_style >> m_color >> m_borderStyle >> m_borderColor >> m_backgroundColor; }
void WritePacket(WorldPacket& data) const;
uint32 GetStyle() const { return m_style; }
uint32 GetColor() const { return m_color; }
uint32 GetBorderStyle() const { return m_borderStyle; }
uint32 GetBorderColor() const { return m_borderColor; }
uint32 GetBackgroundColor() const { return m_backgroundColor; }
private:
uint32 m_style;
uint32 m_color;
uint32 m_borderStyle;
uint32 m_borderColor;
uint32 m_backgroundColor;
};
// Structure for storing guild bank rights and remaining slots together.
struct GuildBankRightsAndSlots
{
GuildBankRightsAndSlots() : rights(0), slots(0) { }
GuildBankRightsAndSlots(uint32 _rights, uint32 _slots) : rights(_rights), slots(_slots) { }
inline bool IsEqual(GuildBankRightsAndSlots const& rhs) const { return rights == rhs.rights && slots == rhs.slots; }
void SetGuildMasterValues()
{
rights = GUILD_BANK_RIGHT_FULL;
slots = uint32(GUILD_WITHDRAW_SLOT_UNLIMITED);
}
uint32 rights;
uint32 slots;
};
typedef std::vector GuildBankRightsAndSlotsVec;
typedef std::set SlotIds;
class Guild
{
private:
// Class representing guild member
class Member
{
struct RemainingValue
{
RemainingValue() : value(0), resetTime(0) { }
uint32 value;
uint32 resetTime;
};
public:
Member(uint32 guildId, uint64 guid, uint32 rankId) : m_guildId(guildId), m_guid(guid), m_logoutTime(::time(NULL)), m_rankId(rankId) { }
void SetStats(Player* player);
void SetStats(const std::string& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId);
bool CheckStats() const;
void SetPublicNote(const std::string& publicNote);
void SetOfficerNote(const std::string& officerNote);
std::string GetPublicNote() { return m_publicNote; };
std::string GetOfficerNote() { return m_officerNote; };
bool LoadFromDB(Field* fields);
void SaveToDB(SQLTransaction& trans) const;
uint64 GetGUID() const { return m_guid; }
std::string GetName() const { return m_name; }
uint32 GetAccountId() const { return m_accountId; }
uint32 GetRankId() const { return m_rankId; }
uint8 GetClass() const { return m_class; }
uint8 GetLevel() const { return m_level; }
uint8 GetZone() const { return m_zoneId; }
uint64 GetLogoutTime() const { return m_logoutTime; }
void ChangeRank(uint8 newRank);
inline void UpdateLogoutTime() { m_logoutTime = ::time(NULL); }
inline bool IsRank(uint8 rankId) const { return m_rankId == rankId; }
inline bool IsRankNotLower(uint8 rankId) const { return m_rankId <= rankId; }
inline bool IsSamePlayer(uint64 guid) const { return m_guid == guid; }
void DecreaseBankRemainingValue(SQLTransaction& trans, uint8 tabId, uint32 amount);
uint32 GetBankRemainingValue(uint8 tabId, const Guild* guild) const;
void ResetTabTimes();
void ResetMoneyTime();
inline Player* FindPlayer() const { return ObjectAccessor::FindPlayer(m_guid); }
private:
uint32 m_guildId;
// Fields from characters table
uint64 m_guid;
std::string m_name;
uint32 m_zoneId;
uint8 m_level;
uint8 m_class;
uint64 m_logoutTime;
uint32 m_accountId;
// Fields from guild_member table
uint32 m_rankId;
std::string m_publicNote;
std::string m_officerNote;
RemainingValue m_bankRemaining[GUILD_BANK_MAX_TABS + 1];
};
// Base class for event entries
class LogEntry
{
public:
LogEntry(uint32 guildId, uint32 guid) : m_guildId(guildId), m_guid(guid), m_timestamp(::time(NULL)) { }
LogEntry(uint32 guildId, uint32 guid, time_t timestamp) : m_guildId(guildId), m_guid(guid), m_timestamp(timestamp) { }
virtual ~LogEntry() { }
uint32 GetGUID() const { return m_guid; }
virtual void SaveToDB(SQLTransaction& trans) const = 0;
virtual void WritePacket(WorldPacket& data) const = 0;
protected:
uint32 m_guildId;
uint32 m_guid;
uint64 m_timestamp;
};
// Event log entry
class EventLogEntry : public LogEntry
{
public:
EventLogEntry(uint32 guildId, uint32 guid, GuildEventLogTypes eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) :
LogEntry(guildId, guid), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) { }
EventLogEntry(uint32 guildId, uint32 guid, time_t timestamp, GuildEventLogTypes eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) :
LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_playerGuid1(playerGuid1), m_playerGuid2(playerGuid2), m_newRank(newRank) { }
~EventLogEntry() { }
void SaveToDB(SQLTransaction& trans) const;
void WritePacket(WorldPacket& data) const;
private:
GuildEventLogTypes m_eventType;
uint32 m_playerGuid1;
uint32 m_playerGuid2;
uint8 m_newRank;
};
// Bank event log entry
class BankEventLogEntry : public LogEntry
{
public:
static bool IsMoneyEvent(GuildBankEventLogTypes eventType)
{
return
eventType == GUILD_BANK_LOG_DEPOSIT_MONEY ||
eventType == GUILD_BANK_LOG_WITHDRAW_MONEY ||
eventType == GUILD_BANK_LOG_REPAIR_MONEY;
}
BankEventLogEntry(uint32 guildId, uint32 guid, GuildBankEventLogTypes eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) :
LogEntry(guildId, guid), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid),
m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { }
BankEventLogEntry(uint32 guildId, uint32 guid, time_t timestamp, uint8 tabId, GuildBankEventLogTypes eventType, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) :
LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid),
m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { }
~BankEventLogEntry() { }
void SaveToDB(SQLTransaction& trans) const;
void WritePacket(WorldPacket& data) const;
private:
GuildBankEventLogTypes m_eventType;
uint8 m_bankTabId;
uint32 m_playerGuid;
uint32 m_itemOrMoney;
uint16 m_itemStackCount;
uint8 m_destTabId;
};
// Class encapsulating work with events collection
class LogHolder
{
public:
LogHolder(uint32 guildId, uint32 maxRecords) : m_guildId(guildId), m_maxRecords(maxRecords), m_nextGUID(uint32(GUILD_EVENT_LOG_GUID_UNDEFINED)) { }
~LogHolder();
uint8 GetSize() const { return uint8(m_log.size()); }
// Checks if new log entry can be added to holder when loading from DB
inline bool CanInsert() const { return m_log.size() < m_maxRecords; }
// Adds event from DB to collection
void LoadEvent(LogEntry* entry);
// Adds new event to collection and saves it to DB
void AddEvent(SQLTransaction& trans, LogEntry* entry);
// Writes information about all events to packet
void WritePacket(WorldPacket& data) const;
uint32 GetNextGUID();
private:
typedef std::list GuildLog;
GuildLog m_log;
uint32 m_guildId;
uint32 m_maxRecords;
uint32 m_nextGUID;
};
// Class encapsulating guild rank data
class RankInfo
{
public:
RankInfo(uint32 guildId) : m_guildId(guildId), m_rankId(GUILD_RANK_NONE), m_rights(GR_RIGHT_EMPTY), m_bankMoneyPerDay(0) { }
RankInfo(uint32 guildId, uint32 rankId, const std::string& name, uint32 rights, uint32 money) :
m_guildId(guildId), m_rankId(rankId), m_name(name), m_rights(rights), m_bankMoneyPerDay(money) { }
void LoadFromDB(Field* fields);
void SaveToDB(SQLTransaction& trans) const;
uint32 GetId() const { return m_rankId; }
std::string GetName() const { return m_name; }
void SetName(const std::string& name);
uint32 GetRights() const { return m_rights; }
void SetRights(uint32 rights);
bool operator < (const RankInfo& rank) const { return m_rights > rank.GetRights(); }
bool operator == (const RankInfo& rank) const { return m_rights == rank.GetRights(); }
uint32 GetBankMoneyPerDay() const { return m_rankId == GR_GUILDMASTER ? GUILD_WITHDRAW_MONEY_UNLIMITED : m_bankMoneyPerDay; }
void SetBankMoneyPerDay(uint32 money);
inline uint32 GetBankTabRights(uint8 tabId) const { return tabId < GUILD_BANK_MAX_TABS ? m_bankTabRightsAndSlots[tabId].rights : 0; }
inline uint32 GetBankTabSlotsPerDay(uint8 tabId) const
{
if (tabId < GUILD_BANK_MAX_TABS)
return m_rankId == GR_GUILDMASTER ? GUILD_WITHDRAW_SLOT_UNLIMITED : m_bankTabRightsAndSlots[tabId].slots;
return 0;
}
void SetBankTabSlotsAndRights(uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB);
private:
uint32 m_guildId;
uint32 m_rankId;
std::string m_name;
uint32 m_rights;
uint32 m_bankMoneyPerDay;
GuildBankRightsAndSlots m_bankTabRightsAndSlots[GUILD_BANK_MAX_TABS];
};
class BankTab
{
public:
BankTab(uint32 guildId, uint8 tabId) : m_guildId(guildId), m_tabId(tabId)
{
memset(m_items, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*));
}
bool LoadFromDB(Field* fields);
bool LoadItemFromDB(Field* fields);
void Delete(SQLTransaction& trans, bool removeItemsFromDB = false);
void WritePacket(WorldPacket& data) const;
void WriteSlotPacket(WorldPacket& data, uint8 slotId) const;
void WriteInfoPacket(WorldPacket& data) const
{
data << m_name;
data << m_icon;
}
void SetInfo(const std::string& name, const std::string& icon);
void SetText(const std::string& text);
void SendText(const Guild* guild, WorldSession* session) const;
inline Item* GetItem(uint8 slotId) const { return slotId < GUILD_BANK_MAX_SLOTS ? m_items[slotId] : NULL; }
bool SetItem(SQLTransaction& trans, uint8 slotId, Item* pItem);
private:
uint32 m_guildId;
uint8 m_tabId;
Item* m_items[GUILD_BANK_MAX_SLOTS];
std::string m_name;
std::string m_icon;
std::string m_text;
};
// Movement data
class MoveItemData
{
public:
MoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : m_pGuild(guild), m_pPlayer(player),
m_container(container), m_slotId(slotId), m_pItem(NULL), m_pClonedItem(NULL) { }
virtual ~MoveItemData() { }
virtual bool IsBank() const = 0;
// Initializes item pointer. Returns true, if item exists, false otherwise.
virtual bool InitItem() = 0;
// Checks splited amount against item. Splited amount cannot be more that number of items in stack.
virtual bool CheckItem(uint32& splitedAmount);
// Defines if player has rights to save item in container
virtual bool HasStoreRights(MoveItemData* /*pOther*/) const { return true; }
// Defines if player has rights to withdraw item from container
virtual bool HasWithdrawRights(MoveItemData* /*pOther*/) const { return true; }
// Checks if container can store specified item
bool CanStore(Item* pItem, bool swap, bool sendError);
// Clones stored item
bool CloneItem(uint32 count);
// Remove item from container (if splited update items fields)
virtual void RemoveItem(SQLTransaction& trans, MoveItemData* pOther, uint32 splitedAmount = 0) = 0;
// Saves item to container
virtual Item* StoreItem(SQLTransaction& trans, Item* pItem) = 0;
// Log bank event
virtual void LogBankEvent(SQLTransaction& trans, MoveItemData* pFrom, uint32 count) const = 0;
// Log GM action
virtual void LogAction(MoveItemData* pFrom) const;
// Copy slots id from position vector
void CopySlots(SlotIds& ids) const;
Item* GetItem(bool isCloned = false) const { return isCloned ? m_pClonedItem : m_pItem; }
uint8 GetContainer() const { return m_container; }
uint8 GetSlotId() const { return m_slotId; }
protected:
virtual InventoryResult CanStore(Item* pItem, bool swap) = 0;
Guild* m_pGuild;
Player* m_pPlayer;
uint8 m_container;
uint8 m_slotId;
Item* m_pItem;
Item* m_pClonedItem;
ItemPosCountVec m_vec;
};
class PlayerMoveItemData : public MoveItemData
{
public:
PlayerMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) :
MoveItemData(guild, player, container, slotId) { }
bool IsBank() const { return false; }
bool InitItem();
void RemoveItem(SQLTransaction& trans, MoveItemData* pOther, uint32 splitedAmount = 0);
Item* StoreItem(SQLTransaction& trans, Item* pItem);
void LogBankEvent(SQLTransaction& trans, MoveItemData* pFrom, uint32 count) const;
protected:
InventoryResult CanStore(Item* pItem, bool swap);
};
class BankMoveItemData : public MoveItemData
{
public:
BankMoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) :
MoveItemData(guild, player, container, slotId) { }
bool IsBank() const { return true; }
bool InitItem();
bool HasStoreRights(MoveItemData* pOther) const;
bool HasWithdrawRights(MoveItemData* pOther) const;
void RemoveItem(SQLTransaction& trans, MoveItemData* pOther, uint32 splitedAmount);
Item* StoreItem(SQLTransaction& trans, Item* pItem);
void LogBankEvent(SQLTransaction& trans, MoveItemData* pFrom, uint32 count) const;
void LogAction(MoveItemData* pFrom) const;
protected:
InventoryResult CanStore(Item* pItem, bool swap);
private:
Item* _StoreItem(SQLTransaction& trans, BankTab* pTab, Item* pItem, ItemPosCount& pos, bool clone) const;
bool _ReserveSpace(uint8 slotId, Item* pItem, Item* pItemDest, uint32& count);
void CanStoreItemInTab(Item* pItem, uint8 skipSlotId, bool merge, uint32& count);
};
typedef UNORDERED_MAP Members;
typedef std::vector Ranks;
typedef std::vector BankTabs;
public:
static void SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, const std::string& param = "");
static void SendSaveEmblemResult(WorldSession* session, GuildEmblemError errCode);
Guild();
~Guild();
bool Create(Player* pLeader, const std::string& name);
void Disband();
// Getters
uint32 GetId() const { return m_id; }
uint64 GetGUID() const { return MAKE_NEW_GUID(m_id, 0, HIGHGUID_GUILD); }
uint64 GetLeaderGUID() const { return m_leaderGuid; }
const std::string& GetName() const { return m_name; }
const std::string& GetMOTD() const { return m_motd; }
const std::string& GetInfo() const { return m_info; }
// Handle client commands
void HandleRoster(WorldSession* session = NULL); // NULL = broadcast
void HandleQuery(WorldSession* session);
void HandleGuildRanks(WorldSession* session);
void HandleSetMOTD(WorldSession* session, const std::string& motd);
void HandleSetInfo(WorldSession* session, const std::string& info);
void HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo);
void HandleSetLeader(WorldSession* session, const std::string& name);
void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, const std::string& name, const std::string& icon);
void HandleSetMemberNote(WorldSession* session, std::string const& note, uint64 guid, bool isPublic);
void HandleSetRankInfo(WorldSession* session, uint32 rankId, const std::string& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec rightsAndSlots);
void HandleBuyBankTab(WorldSession* session, uint8 tabId);
void HandleInviteMember(WorldSession* session, const std::string& name);
void HandleAcceptMember(WorldSession* session);
void HandleLeaveMember(WorldSession* session);
void HandleRemoveMember(WorldSession* session, uint64 guid);
void HandleUpdateMemberRank(WorldSession* session, uint64 targetGuid, bool demote);
void HandleSetMemberRank(WorldSession* session, uint64 targetGuid, uint64 setterGuid, uint32 rank);
void HandleAddNewRank(WorldSession* session, const std::string& name);
void HandleRemoveRank(WorldSession* session, uint32 rankId);
void HandleMemberDepositMoney(WorldSession* session, uint32 amount);
bool HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool repair = false);
void HandleMemberLogout(WorldSession* session);
void HandleDisband(WorldSession* session);
void HandleGuildPartyRequest(WorldSession* session);
// Send info to client
void SendInfo(WorldSession* session) const;
void SendEventLog(WorldSession* session) const;
void SendBankLog(WorldSession* session, uint8 tabId) const;
void SendBankTabsInfo(WorldSession* session) const;
void SendBankTabData(WorldSession* session, uint8 tabId) const;
void SendBankTabText(WorldSession* session, uint8 tabId) const;
void SendPermissions(WorldSession* session) const;
void SendMoneyInfo(WorldSession* session) const;
void SendLoginInfo(WorldSession* session) const;
// Load from DB
bool LoadFromDB(Field* fields);
void LoadRankFromDB(Field* fields);
bool LoadMemberFromDB(Field* fields);
bool LoadEventLogFromDB(Field* fields);
void LoadBankRightFromDB(Field* fields);
bool LoadBankTabFromDB(Field* fields);
bool LoadBankEventLogFromDB(Field* fields);
bool LoadBankItemFromDB(Field* fields);
bool Validate();
// Broadcasts
void BroadcastToGuild(WorldSession* session, bool officerOnly, const std::string& msg, uint32 language = LANG_UNIVERSAL) const;
void BroadcastAddonToGuild(WorldSession* session, bool officerOnly, const std::string& msg, const std::string& prefix) const;
void BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const;
void BroadcastPacket(WorldPacket* packet) const;
template
void BroadcastWorker(Do& _do, Player* except = NULL)
{
for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if (Player* player = itr->second->FindPlayer())
if (player != except)
_do(player);
}
// Members
// Adds member to guild. If rankId == GUILD_RANK_NONE, lowest rank is assigned.
bool AddMember(uint64 guid, uint8 rankId = GUILD_RANK_NONE);
void DeleteMember(uint64 guid, bool isDisbanding = false, bool isKicked = false);
bool ChangeMemberRank(uint64 guid, uint8 newRank);
bool IsMember(uint64 guid);
// Bank
void SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount);
void SwapItemsWithInventory(Player* player, bool toChar, uint8 tabId, uint8 slotId, uint8 playerBag, uint8 playerSlotId, uint32 splitedAmount);
// Bank tabs
void SetBankTabText(uint8 tabId, const std::string& text);
AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }
AchievementMgr const& GetAchievementMgr() const { return m_achievementMgr; }
uint32 GetLevel() const { return m_level; }
protected:
uint32 m_id;
std::string m_name;
uint64 m_leaderGuid;
std::string m_motd;
std::string m_info;
time_t m_createdDate;
EmblemInfo m_emblemInfo;
uint32 m_accountsNumber;
uint64 m_bankMoney;
Ranks m_ranks;
Members m_members;
BankTabs m_bankTabs;
// These are actually ordered lists. The first element is the oldest entry.
LogHolder* m_eventLog;
LogHolder* m_bankEventLog[GUILD_BANK_MAX_TABS + 1];
AchievementMgr m_achievementMgr;
uint32 m_level;
private:
inline uint32 _GetRanksSize() const { return uint32(m_ranks.size()); }
inline const RankInfo* GetRankInfo(uint32 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; }
inline RankInfo* GetRankInfo(uint32 rankId) { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; }
inline bool _HasRankRight(Player* player, uint32 right) const { return (_GetRankRights(player->GetRank()) & right) != GR_RIGHT_EMPTY; }
inline uint32 _GetLowestRankId() const { return uint32(m_ranks.size() - 1); }
inline uint8 _GetPurchasedTabsSize() const { return uint8(m_bankTabs.size()); }
inline BankTab* GetBankTab(uint8 tabId) { return tabId < m_bankTabs.size() ? m_bankTabs[tabId] : NULL; }
inline const BankTab* GetBankTab(uint8 tabId) const { return tabId < m_bankTabs.size() ? m_bankTabs[tabId] : NULL; }
inline const Member* GetMember(uint64 guid) const
{
Members::const_iterator itr = m_members.find(GUID_LOPART(guid));
return itr != m_members.end() ? itr->second : NULL;
}
inline Member* GetMember(uint64 guid)
{
Members::iterator itr = m_members.find(GUID_LOPART(guid));
return itr != m_members.end() ? itr->second : NULL;
}
inline Member* GetMember(WorldSession* session, const std::string& name)
{
for (Members::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if (itr->second->GetName() == name)
return itr->second;
SendCommandResult(session, GUILD_INVITE_S, ERR_GUILD_PLAYER_NOT_IN_GUILD_S, name);
return NULL;
}
inline void _DeleteMemberFromDB(uint32 lowguid) const
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER);
stmt->setUInt32(0, lowguid);
CharacterDatabase.Execute(stmt);
}
// Creates log holders (either when loading or when creating guild)
void _CreateLogHolders();
// Tries to create new bank tab
bool _CreateNewBankTab();
// Creates default guild ranks with names in given locale
void _CreateDefaultGuildRanks(LocaleConstant loc);
// Creates new rank
void _CreateRank(const std::string& name, uint32 rights);
// Update account number when member added/removed from guild
void _UpdateAccountsNumber();
bool _IsLeader(Player* player) const;
void _DeleteBankItems(SQLTransaction& trans, bool removeItemsFromDB = false);
bool _ModifyBankMoney(SQLTransaction& trans, uint64 amount, bool add);
void _SetLeaderGUID(Member* pLeader);
void _SetRankBankMoneyPerDay(uint32 rankId, uint32 moneyPerDay);
void _SetRankBankTabRightsAndSlots(uint32 rankId, uint8 tabId, GuildBankRightsAndSlots rightsAndSlots, bool saveToDB = true);
uint32 _GetRankBankTabRights(uint32 rankId, uint8 tabId) const;
uint32 _GetRankRights(uint32 rankId) const;
uint32 _GetRankBankMoneyPerDay(uint32 rankId) const;
uint32 _GetRankBankTabSlotsPerDay(uint32 rankId, uint8 tabId) const;
std::string _GetRankName(uint32 rankId) const;
uint32 _GetMemberRemainingSlots(uint64 guid, uint8 tabId) const;
uint32 _GetMemberRemainingMoney(uint64 guid) const;
void _DecreaseMemberRemainingSlots(SQLTransaction& trans, uint64 guid, uint8 tabId);
bool _MemberHasTabRights(uint64 guid, uint8 tabId, uint32 rights) const;
void _LogEvent(GuildEventLogTypes eventType, uint32 playerGuid1, uint32 playerGuid2 = 0, uint8 newRank = 0);
void _LogBankEvent(SQLTransaction& trans, GuildBankEventLogTypes eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount = 0, uint8 destTabId = 0);
Item* _GetItem(uint8 tabId, uint8 slotId) const;
void _RemoveItem(SQLTransaction& trans, uint8 tabId, uint8 slotId);
void _MoveItems(MoveItemData* pSrc, MoveItemData* pDest, uint32 splitedAmount);
bool _DoItemsMove(MoveItemData* pSrc, MoveItemData* pDest, bool sendError, uint32 splitedAmount = 0);
void _SendBankContent(WorldSession* session, uint8 tabId) const;
void _SendBankMoneyUpdate(WorldSession* session) const;
void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const;
void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const;
void SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank);
void _BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* param1 = NULL, const char* param2 = NULL, const char* param3 = NULL) const;
};
#endif