/*
* Ascent MMORPG Server
* Copyright (C) 2005-2007 Ascent Team
*
* 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 3 of the License, or
* 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 _GROUP_H_
#define _GROUP_H_
enum PartyErrors
{
ERR_PARTY_NO_ERROR = 0,
ERR_PARTY_CANNOT_FIND = 1,
ERR_PARTY_IS_NOT_IN_YOUR_PARTY = 2,
ERR_PARTY_UNK = 3,
ERR_PARTY_IS_FULL = 4,
ERR_PARTY_ALREADY_IN_GROUP = 5,
ERR_PARTY_YOU_ARENT_IN_A_PARTY = 6,
ERR_PARTY_YOU_ARE_NOT_LEADER = 7,
ERR_PARTY_WRONG_FACTION = 8,
ERR_PARTY_IS_IGNORING_YOU = 9,
};
enum GroupTypes
{
GROUP_TYPE_PARTY = 0,
GROUP_TYPE_RAID = 1,
};
enum MaxGroupCount
{
MAX_GROUP_SIZE_PARTY = 5,
MAX_GROUP_SIZE_RAID = 40,
};
enum QuickGroupUpdateFlags
{
PARTY_UPDATE_FLAG_POSITION = 1,
PARTY_UPDATE_FLAG_ZONEID = 2,
};
struct PlayerInfo;
typedef struct
{
PlayerInfo * player_info;
Player * player;
}GroupMember;
class Group;
class Player;
typedef std::list GroupMembersSet;
class SubGroup // Most stuff will be done through here, not through the "Group" class.
{
public:
friend class Group;
SubGroup(Group* parent, uint32 id):m_Parent(parent),m_Id(id)
{
}
~SubGroup();
inline GroupMembersSet::iterator GetGroupMembersBegin(void) { return m_GroupMembers.begin(); }
inline GroupMembersSet::iterator GetGroupMembersEnd(void) { return m_GroupMembers.end(); }
bool AddPlayer(PlayerInfo * info, Player *pPlayer);
void RemovePlayer(PlayerInfo * info, Player *pPlayer, bool forced_remove);
bool HasMember(uint64 guid);
inline bool IsFull(void) { return m_GroupMembers.size() >= MAX_GROUP_SIZE_PARTY; }
inline uint32 GetMemberCount(void) { return m_GroupMembers.size(); }
inline uint32 GetID(void) { return m_Id; }
inline void SetID(uint32 newid) { m_Id = newid; }
inline void SetParent(Group* parent) { m_Parent = parent; }
inline Group* GetParent(void) { return m_Parent; }
void Disband(bool bRemoveGroup);
protected:
GroupMembersSet m_GroupMembers;
Group* m_Parent;
uint32 m_Id;
};
class SERVER_DECL Group
{
public:
friend class SubGroup;
static Group* Create();
Group();
~Group();
// Adding/Removal Management
bool AddMember(PlayerInfo * info, Player* pPlayer, int32 subgroupid=-1);
void RemovePlayer(PlayerInfo * info, Player* pPlayer, bool forced_remove);
void UpdateMember(PlayerInfo * info, Player * pPlayer);
// Leaders and Looting
void SetLeader(Player* pPlayer,bool silent);
void SetLooter(Player *pPlayer, uint8 method, uint16 threshold);
Player* GetnextRRlooter();
// Transferring data to clients
void Update(bool delayed = false);
void SendPacketToAll(WorldPacket *packet);
void SendPacketToAllButOne(WorldPacket *packet, Player *pSkipTarget);
void SendNullUpdate(Player *pPlayer);
// Group Combat
void SendPartyKillLog(Object * player, Object * Unit);
// Destroying/Converting
void Disband();
Player* FindFirstPlayer();
// Accessing functions
inline SubGroup* GetSubGroup(uint32 Id)
{
if(Id >= 8)
return 0;
return m_SubGroups[Id];
}
inline uint32 GetSubGroupCount(void) { return m_SubGroupCount; }
inline uint8 GetMethod(void) { return m_LootMethod; }
inline uint8 GetThreshold(void) { return m_LootThreshold; }
inline Player* GetLeader(void) { return m_Leader; }
inline Player* GetLooter(void) { return m_Looter; }
void MovePlayer(PlayerInfo* info, uint8 subgroup);
bool HasMember(Player *pPlayer);
bool HasMember(PlayerInfo * info);
inline uint32 MemberCount(void) { return m_MemberCount; }
inline bool IsFull() { return ((m_GroupType == GROUP_TYPE_PARTY && m_MemberCount >= MAX_GROUP_SIZE_PARTY) || (m_GroupType == GROUP_TYPE_RAID && m_MemberCount >= MAX_GROUP_SIZE_RAID)); }
SubGroup* FindFreeSubGroup();
void ExpandToRaid();
void SaveToDB();
void LoadFromDB(Field *fields);
inline uint8 GetGroupType() { return m_GroupType; }
inline uint32 GetID() { return m_Id; }
void UpdateOutOfRangePlayer(Player * pPlayer, uint32 Flags, bool Distribute, WorldPacket * Packet);
void UpdateAllOutOfRangePlayersFor(Player * pPlayer);
void HandleUpdateFieldChange(uint32 Index, Player * pPlayer);
void HandlePartialChange(uint32 Type, Player * pPlayer);
uint64 m_targetIcons[8];
bool m_disbandOnNoMembers;
inline Mutex& getLock() { return m_groupLock; }
inline void Lock() { m_groupLock.Acquire(); }
inline void Unlock() { return m_groupLock.Release(); }
protected:
Player* m_Leader;
Player* m_Looter;
Player* lastRRlooter; //used to determine next RR looter
uint8 m_LootMethod;
uint16 m_LootThreshold;
uint8 m_GroupType;
uint32 m_Id;
SubGroup* m_SubGroups[8];
uint8 m_SubGroupCount;
uint32 m_MemberCount;
Mutex m_groupLock;
bool m_dirty;
bool m_updateblock;
};
#endif // _GROUP_H_