forked from metin2/server
176 lines
5.9 KiB
C++
176 lines
5.9 KiB
C++
#ifndef __INC_METIN_II_GAME_CHARACTER_MANAGER_H__
|
|
#define __INC_METIN_II_GAME_CHARACTER_MANAGER_H__
|
|
|
|
#ifdef M2_USE_POOL
|
|
#include "pool.h"
|
|
#endif
|
|
|
|
#include <common/stl.h>
|
|
#include <common/length.h>
|
|
|
|
#include "vid.h"
|
|
|
|
class CDungeon;
|
|
class CHARACTER;
|
|
class CharacterVectorInteractor;
|
|
|
|
class CHARACTER_MANAGER : public singleton<CHARACTER_MANAGER>
|
|
{
|
|
public:
|
|
typedef std::unordered_map<std::string, LPCHARACTER> NAME_MAP;
|
|
|
|
CHARACTER_MANAGER();
|
|
virtual ~CHARACTER_MANAGER();
|
|
|
|
void Destroy();
|
|
|
|
void GracefulShutdown(); // 정상적 셧다운할 때 사용. PC를 모두 저장시키고 Destroy 한다.
|
|
|
|
DWORD AllocVID();
|
|
|
|
LPCHARACTER CreateCharacter(const char * name, DWORD dwPID = 0);
|
|
#ifndef DEBUG_ALLOC
|
|
void DestroyCharacter(LPCHARACTER ch);
|
|
#else
|
|
void DestroyCharacter(LPCHARACTER ch, const char* file, size_t line);
|
|
#endif
|
|
|
|
void Update(int iPulse);
|
|
|
|
LPCHARACTER SpawnMob(DWORD dwVnum, int lMapIndex, int x, int y, int z, bool bSpawnMotion = false, int iRot = -1, bool bShow = true);
|
|
LPCHARACTER SpawnMobRange(DWORD dwVnum, int lMapIndex, int sx, int sy, int ex, int ey, bool bIsException=false, bool bSpawnMotion = false , bool bAggressive = false);
|
|
LPCHARACTER SpawnGroup(DWORD dwVnum, int lMapIndex, int sx, int sy, int ex, int ey, LPREGEN pkRegen = NULL, bool bAggressive_ = false, LPDUNGEON pDungeon = NULL);
|
|
bool SpawnGroupGroup(DWORD dwVnum, int lMapIndex, int sx, int sy, int ex, int ey, LPREGEN pkRegen = NULL, bool bAggressive_ = false, LPDUNGEON pDungeon = NULL);
|
|
bool SpawnMoveGroup(DWORD dwVnum, int lMapIndex, int sx, int sy, int ex, int ey, int tx, int ty, LPREGEN pkRegen = NULL, bool bAggressive_ = false);
|
|
LPCHARACTER SpawnMobRandomPosition(DWORD dwVnum, int lMapIndex);
|
|
|
|
void SelectStone(LPCHARACTER pkChrStone);
|
|
|
|
NAME_MAP & GetPCMap() { return m_map_pkPCChr; }
|
|
|
|
LPCHARACTER Find(DWORD dwVID);
|
|
LPCHARACTER Find(const VID & vid);
|
|
LPCHARACTER FindPC(const char * name);
|
|
LPCHARACTER FindByPID(DWORD dwPID);
|
|
|
|
bool AddToStateList(LPCHARACTER ch);
|
|
void RemoveFromStateList(LPCHARACTER ch);
|
|
|
|
// DelayedSave: 어떠한 루틴 내에서 저장을 해야 할 짓을 많이 하면 저장
|
|
// 쿼리가 너무 많아지므로 "저장을 한다" 라고 표시만 해두고 잠깐
|
|
// (예: 1 frame) 후에 저장시킨다.
|
|
void DelayedSave(LPCHARACTER ch);
|
|
bool FlushDelayedSave(LPCHARACTER ch); // Delayed 리스트에 있다면 지우고 저장한다. 끊김 처리시 사용 됨.
|
|
void ProcessDelayedSave();
|
|
|
|
template<class Func> Func for_each_pc(Func f);
|
|
|
|
void RegisterForMonsterLog(LPCHARACTER ch);
|
|
void UnregisterForMonsterLog(LPCHARACTER ch);
|
|
void PacketMonsterLog(LPCHARACTER ch, const void* buf, int size);
|
|
|
|
void KillLog(DWORD dwVnum);
|
|
|
|
void RegisterRaceNum(DWORD dwVnum);
|
|
void RegisterRaceNumMap(LPCHARACTER ch);
|
|
void UnregisterRaceNumMap(LPCHARACTER ch);
|
|
bool GetCharactersByRaceNum(DWORD dwRaceNum, CharacterVectorInteractor & i);
|
|
|
|
LPCHARACTER FindSpecifyPC(unsigned int uiJobFlag, int lMapIndex, LPCHARACTER except=NULL, int iMinLevel = 1, int iMaxLevel = PLAYER_MAX_LEVEL_CONST);
|
|
|
|
void SetMobItemRate(int value) { m_iMobItemRate = value; }
|
|
void SetMobDamageRate(int value) { m_iMobDamageRate = value; }
|
|
void SetMobGoldAmountRate(int value) { m_iMobGoldAmountRate = value; }
|
|
void SetMobGoldDropRate(int value) { m_iMobGoldDropRate = value; }
|
|
void SetMobExpRate(int value) { m_iMobExpRate = value; }
|
|
|
|
void SetMobItemRatePremium(int value) { m_iMobItemRatePremium = value; }
|
|
void SetMobGoldAmountRatePremium(int value) { m_iMobGoldAmountRatePremium = value; }
|
|
void SetMobGoldDropRatePremium(int value) { m_iMobGoldDropRatePremium = value; }
|
|
void SetMobExpRatePremium(int value) { m_iMobExpRatePremium = value; }
|
|
|
|
void SetUserDamageRatePremium(int value) { m_iUserDamageRatePremium = value; }
|
|
void SetUserDamageRate(int value ) { m_iUserDamageRate = value; }
|
|
int GetMobItemRate(LPCHARACTER ch);
|
|
int GetMobDamageRate(LPCHARACTER ch);
|
|
int GetMobGoldAmountRate(LPCHARACTER ch);
|
|
int GetMobGoldDropRate(LPCHARACTER ch);
|
|
int GetMobExpRate(LPCHARACTER ch);
|
|
|
|
int GetUserDamageRate(LPCHARACTER ch);
|
|
void SendScriptToMap(int lMapIndex, const std::string & s);
|
|
|
|
bool BeginPendingDestroy();
|
|
void FlushPendingDestroy();
|
|
|
|
private:
|
|
int m_iMobItemRate;
|
|
int m_iMobDamageRate;
|
|
int m_iMobGoldAmountRate;
|
|
int m_iMobGoldDropRate;
|
|
int m_iMobExpRate;
|
|
|
|
int m_iMobItemRatePremium;
|
|
int m_iMobGoldAmountRatePremium;
|
|
int m_iMobGoldDropRatePremium;
|
|
int m_iMobExpRatePremium;
|
|
|
|
int m_iUserDamageRate;
|
|
int m_iUserDamageRatePremium;
|
|
int m_iVIDCount;
|
|
|
|
std::unordered_map<DWORD, LPCHARACTER> m_map_pkChrByVID;
|
|
std::unordered_map<DWORD, LPCHARACTER> m_map_pkChrByPID;
|
|
NAME_MAP m_map_pkPCChr;
|
|
|
|
char dummy1[1024]; // memory barrier
|
|
CHARACTER_SET m_set_pkChrState; // FSM이 돌아가고 있는 놈들
|
|
CHARACTER_SET m_set_pkChrForDelayedSave;
|
|
CHARACTER_SET m_set_pkChrMonsterLog;
|
|
|
|
LPCHARACTER m_pkChrSelectedStone;
|
|
|
|
std::map<DWORD, DWORD> m_map_dwMobKillCount;
|
|
|
|
std::set<DWORD> m_set_dwRegisteredRaceNum;
|
|
std::map<DWORD, CHARACTER_SET> m_map_pkChrByRaceNum;
|
|
|
|
bool m_bUsePendingDestroy;
|
|
CHARACTER_SET m_set_pkChrPendingDestroy;
|
|
|
|
#ifdef M2_USE_POOL
|
|
ObjectPool<CHARACTER> pool_;
|
|
#endif
|
|
};
|
|
|
|
template<class Func>
|
|
Func CHARACTER_MANAGER::for_each_pc(Func f)
|
|
{
|
|
std::unordered_map<DWORD, LPCHARACTER>::iterator it;
|
|
|
|
for (it = m_map_pkChrByPID.begin(); it != m_map_pkChrByPID.end(); ++it)
|
|
f(it->second);
|
|
|
|
return f;
|
|
}
|
|
|
|
class CharacterVectorInteractor : public CHARACTER_VECTOR
|
|
{
|
|
public:
|
|
CharacterVectorInteractor() : m_bMyBegin(false) { }
|
|
|
|
CharacterVectorInteractor(const CHARACTER_SET & r);
|
|
virtual ~CharacterVectorInteractor();
|
|
|
|
private:
|
|
bool m_bMyBegin;
|
|
};
|
|
|
|
#ifndef DEBUG_ALLOC
|
|
#define M2_DESTROY_CHARACTER(ptr) CHARACTER_MANAGER::instance().DestroyCharacter(ptr)
|
|
#else
|
|
#define M2_DESTROY_CHARACTER(ptr) CHARACTER_MANAGER::instance().DestroyCharacter(ptr, __FILE__, __LINE__)
|
|
#endif
|
|
|
|
#endif
|