server/game/src/party.h

365 lines
8.5 KiB
C++

#ifndef __INC_METIN_II_GAME_PARTY_H__
#define __INC_METIN_II_GAME_PARTY_H__
#include "char.h"
enum // unit : minute
{
PARTY_ENOUGH_MINUTE_FOR_EXP_BONUS = 60, // 파티 결성 후 60분 후 부터 추가 경험치 보너스
PARTY_HEAL_COOLTIME_LONG = 60,
PARTY_HEAL_COOLTIME_SHORT = 30,
PARTY_MAX_MEMBER = 8,
PARTY_DEFAULT_RANGE = 5000,
};
enum EPartyRole
{
PARTY_ROLE_NORMAL,
PARTY_ROLE_LEADER,
PARTY_ROLE_ATTACKER,
PARTY_ROLE_TANKER,
PARTY_ROLE_BUFFER,
PARTY_ROLE_SKILL_MASTER,
PARTY_ROLE_HASTE,
PARTY_ROLE_DEFENDER,
PARTY_ROLE_MAX_NUM,
};
enum EPartyExpDistributionModes
{
PARTY_EXP_DISTRIBUTION_NON_PARITY,
PARTY_EXP_DISTRIBUTION_PARITY,
PARTY_EXP_DISTRIBUTION_MAX_NUM
};
class CParty;
class CDungeon;
class CPartyManager : public singleton<CPartyManager>
{
public:
typedef std::map<DWORD, LPPARTY> TPartyMap;
typedef std::set<LPPARTY> TPCPartySet;
public:
CPartyManager();
virtual ~CPartyManager();
void Initialize();
//void SendPartyToDB();
void EnablePCParty() { m_bEnablePCParty = true; sys_log(0,"PARTY Enable"); }
void DisablePCParty() { m_bEnablePCParty = false; sys_log(0,"PARTY Disable"); }
bool IsEnablePCParty() { return m_bEnablePCParty; }
LPPARTY CreateParty(LPCHARACTER pkLeader);
void DeleteParty(LPPARTY pParty);
void DeleteAllParty();
bool SetParty(LPCHARACTER pkChr);
void SetPartyMember(DWORD dwPID, LPPARTY pParty);
void P2PLogin(DWORD pid, const char* name);
void P2PLogout(DWORD pid);
LPPARTY P2PCreateParty(DWORD pid);
void P2PDeleteParty(DWORD pid);
void P2PJoinParty(DWORD leader, DWORD pid, BYTE role = 0);
void P2PQuitParty(DWORD pid);
private:
TPartyMap m_map_pkParty; // PID로 어느 파티에 있나 검색하기 위한 컨테이너
TPartyMap m_map_pkMobParty; // Mob 파티는 PID 대신 VID 로 따로 관리한다.
TPCPartySet m_set_pkPCParty; // 사람들의 파티 전체 집합
bool m_bEnablePCParty; // 디비가 켜져있지 않으면 사람들의 파티 상태가 변경불가
};
enum EPartyMessages
{
PM_ATTACK, // Attack him
PM_RETURN, // Return back to position
PM_ATTACKED_BY, // I was attacked by someone
PM_AGGRO_INCREASE, // My aggro is increased
};
class CParty
{
public:
typedef struct SMember
{
LPCHARACTER pCharacter;
bool bNear;
BYTE bRole;
BYTE bLevel;
std::string strName;
} TMember;
typedef std::map<DWORD, TMember> TMemberMap;
typedef std::map<std::string, int> TFlagMap;
public:
CParty();
virtual ~CParty();
void P2PJoin(DWORD dwPID);
void P2PQuit(DWORD dwPID);
virtual void Join(DWORD dwPID);
void Quit(DWORD dwPID);
void Link(LPCHARACTER pkChr);
void Unlink(LPCHARACTER pkChr);
void ChatPacketToAllMember(BYTE type, const char* format, ...);
void UpdateOnlineState(DWORD dwPID, const char* name);
void UpdateOfflineState(DWORD dwPID);
DWORD GetLeaderPID();
LPCHARACTER GetLeaderCharacter();
LPCHARACTER GetLeader() { return m_pkChrLeader; }
DWORD GetMemberCount();
DWORD GetNearMemberCount() { return m_iCountNearPartyMember; }
bool IsMember(DWORD pid) { return m_memberMap.find(pid) != m_memberMap.end(); }
bool IsNearLeader(DWORD pid);
bool IsPositionNearLeader(LPCHARACTER ch);
void SendMessage(LPCHARACTER ch, BYTE bMsg, DWORD dwArg1, DWORD dwArg2);
void SendPartyJoinOneToAll(DWORD dwPID);
void SendPartyJoinAllToOne(LPCHARACTER ch);
void SendPartyRemoveOneToAll(DWORD dwPID);
void SendPartyInfoOneToAll(DWORD pid);
void SendPartyInfoOneToAll(LPCHARACTER ch);
void SendPartyInfoAllToOne(LPCHARACTER ch);
void SendPartyLinkOneToAll(LPCHARACTER ch);
void SendPartyLinkAllToOne(LPCHARACTER ch);
void SendPartyUnlinkOneToAll(LPCHARACTER ch);
int GetPartyBonusExpPercent() { return m_iExpBonus; }
int GetPartyBonusAttackGrade() { return m_iAttBonus; }
int GetPartyBonusDefenseGrade() { return m_iDefBonus; }
int ComputePartyBonusExpPercent();
inline int ComputePartyBonusAttackGrade();
inline int ComputePartyBonusDefenseGrade();
template <class Func> void ForEachMember(Func & f);
template <class Func> void ForEachMemberPtr(Func & f);
template <class Func> void ForEachOnlineMember(Func & f);
template <class Func> void ForEachNearMember(Func & f);
template <class Func> void ForEachOnMapMember (Func & f, int lMapIndex);
template <class Func> bool ForEachOnMapMemberBool (Func & f, int lMapIndex);
void Update();
int GetExpBonusPercent();
bool SetRole(DWORD pid, BYTE bRole, bool on);
BYTE GetRole(DWORD pid);
bool IsRole(DWORD pid, BYTE bRole);
BYTE GetMemberMaxLevel();
BYTE GetMemberMinLevel();
void ComputeRolePoint(LPCHARACTER ch, BYTE bRole, bool bAdd);
void HealParty();
void SummonToLeader(DWORD pid);
void SetPCParty(bool b) { m_bPCParty = b; }
LPCHARACTER GetNextOwnership(LPCHARACTER ch, int x, int y);
void SetFlag(const std::string& name, int value);
int GetFlag(const std::string& name);
void SetDungeon(LPDUNGEON pDungeon);
LPDUNGEON GetDungeon();
BYTE CountMemberByVnum(DWORD dwVnum);
void SetParameter(int iMode);
int GetExpDistributionMode();
void SetExpCentralizeCharacter(DWORD pid);
LPCHARACTER GetExpCentralizeCharacter();
void RequestSetMemberLevel(DWORD pid, BYTE level);
void P2PSetMemberLevel(DWORD pid, BYTE level);
protected:
void IncreaseOwnership();
virtual void Initialize();
void Destroy();
void RemovePartyBonus();
void RemoveBonus();
void RemoveBonusForOne(DWORD pid);
void SendParameter(LPCHARACTER ch);
void SendParameterToAll();
TMemberMap m_memberMap;
DWORD m_dwLeaderPID;
LPCHARACTER m_pkChrLeader;
LPEVENT m_eventUpdate;
TMemberMap::iterator m_itNextOwner;
private:
int m_iExpDistributionMode;
LPCHARACTER m_pkChrExpCentralize;
DWORD m_dwPartyStartTime;
DWORD m_dwPartyHealTime;
bool m_bPartyHealReady;
bool m_bCanUsePartyHeal;
int m_anRoleCount[PARTY_ROLE_MAX_NUM];
int m_anMaxRole[PARTY_ROLE_MAX_NUM];
int m_iLongTimeExpBonus;
// used in Update
int m_iLeadership;
int m_iExpBonus;
int m_iAttBonus;
int m_iDefBonus;
// changed only in Update
int m_iCountNearPartyMember;
bool m_bPCParty;
TFlagMap m_map_iFlag;
LPDUNGEON m_pkDungeon;
// 아귀 동굴용 dungeon 멤버 변수.
// 정말 이렇게까지 하고 싶진 않았는데, 던전에서 party 관리가 정말로 개판이라
// 그거 고치기 전까지는 이렇게 임시로 해놓는다.
LPDUNGEON m_pkDungeon_for_Only_party;
public:
void SetDungeon_for_Only_party(LPDUNGEON pDungeon);
LPDUNGEON GetDungeon_for_Only_party();
};
template <class Func> void CParty::ForEachMember(Func & f)
{
TMemberMap::iterator it;
for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it)
f(it->first);
}
template <class Func> void CParty::ForEachMemberPtr(Func & f)
{
TMemberMap::iterator it;
for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it)
f(it->second.pCharacter);
}
template <class Func> void CParty::ForEachOnlineMember(Func & f)
{
TMemberMap::iterator it;
for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it)
if (it->second.pCharacter)
f(it->second.pCharacter);
}
template <class Func> void CParty::ForEachNearMember(Func & f)
{
TMemberMap::iterator it;
for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it)
if (it->second.pCharacter && it->second.bNear)
f(it->second.pCharacter);
}
template <class Func> void CParty::ForEachOnMapMember (Func & f, int lMapIndex)
{
TMemberMap::iterator it;
for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it)
{
LPCHARACTER ch = it->second.pCharacter;
if (ch)
{
if (ch->GetMapIndex () == lMapIndex)
f(ch);
}
}
}
template <class Func> bool CParty::ForEachOnMapMemberBool(Func & f, int lMapIndex)
{
TMemberMap::iterator it;
for (it = m_memberMap.begin(); it != m_memberMap.end(); ++it)
{
LPCHARACTER ch = it->second.pCharacter;
if (ch)
{
if (ch->GetMapIndex () == lMapIndex)
{
if(f(ch) == false)
{
return false;
}
}
}
}
return true;
}
inline int CParty::ComputePartyBonusAttackGrade()
{
/*
if (GetNearMemberCount() <= 1)
return 0;
int leadership = GetLeaderCharacter()->GetLeadershipSkillLevel();
int n = GetNearMemberCount();
if (n >= 3 && leadership >= 10)
return 2;
if (n >= 2 && leadership >= 4)
return 1;
*/
return 0;
}
inline int CParty::ComputePartyBonusDefenseGrade()
{
/*
if (GetNearMemberCount() <= 1)
return 0;
int leadership = GetLeaderCharacter()->GetLeadershipSkillLevel();
int n = GetNearMemberCount();
if (n >= 5 && leadership >= 24)
return 2;
if (n >= 4 && leadership >= 16)
return 1;
*/
return 0;
}
#endif