Files
Client/Server/RylServerProject/RylGameLibrary/Map/FieldMap/Cell.h
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

329 lines
10 KiB
C++

#ifndef _CCELL_H_
#define _CCELL_H_
#pragma once
#pragma warning(disable:4800)
#include <list>
#include <algorithm>
#include <climits>
#include <boost/pool/pool_alloc.hpp>
#include <Creature/CreatureStructure.h>
#include <Network/Packet/PacketStruct/CharMovepacket.h>
#include <Network/Packet/PacketStruct/AddressPacket.h>
#include <Network/Packet/PacketStruct/CharAttackPacketStruct.h>
#include <Network/Packet/PacketStruct/CharItemPacketStruct.h>
// 전방 참조
class CParty;
class CCreature;
class CAggresiveCreature;
class CMonster;
class CCharacter;
class CSiegeObject;
class CBuffer;
struct PktBase;
struct PktMVEx;
namespace Item
{
class CItem;
};
class CCell
{
public:
enum ErrorCode
{
S_SUCCESS = 0,
S_AUTO_ROUTING = 1,
E_NOT_ENOUGH_MEMORY = 2,
E_NOT_OWNER_OF_ITEM = 3,
E_NOT_ITEM = 4,
E_CREATE_ITEM_FAIL = 5,
E_NOT_EXIST_GUILD = 6,
E_GOLD_OVERFLOW = 7
};
enum Const
{
CONNECT_NUM = 9,
CHECK_TIME = 100, // 아이템이 사라져야 하는지 체크하는 간격 (10초)
ITEM_RIGHT_TIME = 1600, // 플레이어가 드랍한 아이템의 경우 소유권은 10초, 다시 2분 30초 후엔 사라진다.
ITEM_LIFE_TIME = 1800, // 맵에 아이템이 남아있는 시간 (3분)
NO_OWNER_TIME = 1500, // 아이템에 소유권이 지정되어 있지 않은 시간 (2분 30초)
BROADCASTING_TIME = 10, // 기존 브로드 캐스팅 타임 (1초)
MONEY_BIT = 0x80000000,
TYPE_CHECK_BIT = 0xF0000000,
ITEM_PROTOTYPE_ID_BIT = 0x0000FFFF,
MAX_MONEY_AMOUNT = 0x0FFFFFFF
};
enum TurnConst
{
TURN_OF_CHARACTER = 0,
TURN_OF_SIEGE_OBJECT = 1,
TURN_OF_MONSTER = 2,
TURN_END = 3
};
enum Weather
{
WEATHER_FINE = 0, // 맑음
WEATHER_RAIN = 1, // 비
WEATHER_SNOW = 2, // 눈
MAX_WEATHER = 3
};
enum ItemAutoRouting
{
NONE = 0, // 루팅 하지 않는다.
PARTY = 1, // 파티원에게 루팅
GUILD = 2, // 길드원에게 루팅
};
enum ConnectCell
{
NO = 0,
UP = 1,
DOWN = 2,
LEFT = 3,
RIGHT = 4,
UPPERLEFT = 5,
UPPERRIGHT = 6,
LOWERLEFT = 7,
LOWERRIGHT = 8
};
enum CellSize
{
CELL_SIZE_DEFAULT = 128,
CELL_SIZE_BATTLE_SERVER = 70,
CELL_DISTANCE = 32,
CELL_RESOLUTION = 5
};
static unsigned char ms_CellSize;
struct IDField
{
enum
{
MAX_UID = UCHAR_MAX
};
unsigned long dwUID; // 유니크 ID (생성된 순서에 따라 차례대로...)
unsigned short wMapIndex; // 가상 맵의 경우 그 인덱스
unsigned char cCellX; // 셀 인덱스 X
unsigned char cCellZ; // 셀 인덱스 Z
};
struct ItemInfo
{
Position m_Pos; // 월드맵 상의 위치
union
{
unsigned __int64 m_nUniqueID; // 유니크 ID
IDField m_Field;
} UID;
Item::CItem* m_lpItem; // 아이템
unsigned long m_dwGold; // 돈
unsigned long m_dwOwnerID; // 소유권
unsigned short m_wPulse; // 소멸까지 남은 펄스
unsigned char m_cAutoRouting; // 오토루팅될 아이템인가? (ItemAutoRouting enum 참고)
ItemInfo();
void MakeFieldObject(FieldObject& fieldObject);
};
typedef std::list<CMonster*, boost::fast_pool_allocator<CMonster*> > MonsterList;
typedef std::list<CCharacter*, boost::fast_pool_allocator<CCharacter*> > CharacterList;
typedef std::list<ItemInfo, boost::fast_pool_allocator<ItemInfo> > ItemList;
typedef std::list<CSiegeObject*, boost::fast_pool_allocator<CSiegeObject*> > SiegeObjectList;
//--------------------------------------------------------------------------------------------
// 초기화
CCell();
~CCell();
void Initialize(unsigned char cIndexX, unsigned char cIndexZ); // 셀 좌표를 초기화하고, 소트된 링크를 생성한다.
void SetMapIndex(unsigned short wMapIndex) { m_wMapIndex = wMapIndex; }
unsigned short GetMapIndex() { return m_wMapIndex; }
//--------------------------------------------------------------------------------------------
// interface
CCell* GetConnectCell(unsigned int Dir);
void SetConnectCell(unsigned int Dir, CCell* lpConnectedCell);
bool IsNearCell(CCell* lpNearCell);
//--------------------------------------------------------------------------------------------
// 셀 정보
unsigned char GetIndexX() const { return m_cIndexX; }
unsigned char GetIndexZ() const { return m_cIndexZ; }
size_t GetMonsterNum() const { return m_lstMonster.size(); }
size_t GetCharacterNum() const { return m_lstCharacter.size(); }
size_t GetItemNum() const { return m_lstItem.size(); }
size_t GetSiegeObjectNum() const { return m_lstSiegeObject.size(); }
size_t GetNearCellCharacterNum() const;
//--------------------------------------------------------------------------------------------
// 셀에 크리쳐 추가 및 삭제, 얻어 오기.
void SetCreature(unsigned long dwCID, CCreature* lpCreature, CCell* lpLastLogoutCell = 0);
void DeleteCreature(unsigned long dwCID, CCell* lpPrepareLoginCell = 0);
CCreature* GetCreature(unsigned long dwCID);
CAggresiveCreature* GetFirstAggresiveCreature();
CAggresiveCreature* GetNextAggresiveCreature();
void KillAll(CCharacter* lpAttacker);
//--------------------------------------------------------------------------------------------
// 몬스터 관련 처리
bool IsMonster() const { return !(m_lstMonster.empty()); }
CMonster* GetFirstMonster();
CMonster* GetNextMonster() { return (++m_MonsterIt != m_lstMonster.end()) ? *m_MonsterIt : NULL; }
void LogoutAllMonster() { m_lstMonster.clear(); }
//--------------------------------------------------------------------------------------------
// 공성 오브젝트 관련 처리
bool IsSiegeObject() { return !(m_lstSiegeObject.empty()); }
CSiegeObject* GetFirstAirShip();
CSiegeObject* GetNextAirShip();
CSiegeObject* GetFirstSiegeObject();
CSiegeObject* GetNextSiegeObject();
void UpgradeByEmblem(unsigned long dwCID);
void DegradeByEmblem();
bool IsDetectionCell() { return ( 0 != m_dwCastleEmblemCID ); }
void DetectionAttack(CSiegeObject* lpEmblem, CAggresiveCreature* lpTargetCreature);
bool SendStealthInfo(CCharacter& character, bool bUseStealth);
//--------------------------------------------------------------------------------------------
// 캐릭터 관련 처리
bool IsCharacter() { return !(m_lstCharacter.empty()); }
CCharacter* GetFirstCharacter();
CCharacter* GetNextCharacter() { return (++m_CharacterIt != m_lstCharacter.end()) ? *m_CharacterIt : NULL; }
template<typename FnProcess>
inline void ProcessAllMonster(FnProcess fnProcess)
{
std::for_each(m_lstMonster.begin(), m_lstMonster.end(), fnProcess);
}
template<typename FnProcess>
inline void ProcessAllCharacter(FnProcess fnProcess)
{
std::for_each(m_lstCharacter.begin(), m_lstCharacter.end(), fnProcess);
}
void RespawnAllCharacter(unsigned char cExceptNation);
//--------------------------------------------------------------------------------------------
// 아이템 관련 처리
bool IsItem(void) { return !(m_lstItem.empty()); }
void SetItem(const Position& Pos, Item::CItem* lpItem, unsigned long dwGold,
unsigned long dwOwnerID, unsigned char cAutoRouting, CCell::ItemInfo& cellItemInfo);
CCell::ErrorCode GetItem(unsigned long dwCreatureID, unsigned __int64 nItemInfoID,
Item::CItem** lppItem, unsigned long& dwMoney_Out);
void CheckDeleteItem(void);
void DeleteAllItem(void);
//--------------------------------------------------------------------------------------------
// 셀 관련 브로드 캐스팅
void PrepareBroadCast();
void BroadCast(unsigned long dwCurrentPulse);
// 만든 패킷을, Wrap하지 말고 보낸다(내부에서 Wrap함. srvState나 usError는 넣을수 없다.)
// 패킷 순서가 바뀔 수 있으므로 주의한다.
void SendAllNearCellCharacter(const PktBase* lpPktBase, unsigned short usLength, unsigned char cCMD);
void SendAllCharacter(const PktBase* lpPktBase, unsigned short usLength, unsigned char cCMD);
void SendNowAllNearCellCharacter(const char* szData, unsigned short usLength, unsigned char cCMD);
void SendNowAllCharacter(const char* szData, unsigned short usLength, unsigned char cCMD);
void SendAttackInfo(unsigned long AttackerID_In, const AtType &AtType_In,
unsigned char DefenserNum_In, DefenserNode* lpNode_In);
void SendCastObjectInfo(unsigned long SenderID, unsigned long ReceiverID, CastObject& CastObject_In);
private:
//--------------------------------------------------------------------------------------------
// 패킷 전송 관련 (내부에서만 호출하는 함수들)
void SendPullDownInfo(unsigned long dwOwnerID, ItemInfo& itemInfo);
void SendPickUpInfo(unsigned long dwCreatureID, unsigned __int64 nItemInfoID);
void SendCellLogin(CAggresiveCreature* lpAggresiveCreature, CCell* lpLastLogoutCell);
void SendCellLogout(CAggresiveCreature* lpAggresiveCreature, CCell* lpPrepareLoginCell);
// 버퍼를 전부 Release한다.
static void ReleaseAllBuffer(CBuffer*& lpBuffer);
//--------------------------------------------------------------------------------------------
// 데이터
CCell* m_lpConnectCell[CONNECT_NUM]; // 주변 연결 리스트. 자기 자신도 포함한다.
CCell* m_lpSortedConnectedCell[CONNECT_NUM]; // 주변 연결 리스트를 포인터순으로 소팅한 배열.
CharacterList m_lstCharacter;
MonsterList m_lstMonster;
ItemList m_lstItem;
SiegeObjectList m_lstSiegeObject; // 단지 리스트를 가지고 있을 뿐, 모든 공성 오브젝트는 CSiegeObjectMgr 이 관리한다.
MonsterList::iterator m_MonsterIt; // 범용적... 한 녀석이 다 쓰기 전에 다른 녀석이 달라고 하면 곤란합니다.
CharacterList::iterator m_CharacterIt; // 범용적... 한 녀석이 다 쓰기 전에 다른 녀석이 달라고 하면 곤란합니다.
SiegeObjectList::iterator m_SiegeObjectIt; // 범용적... 한 녀석이 다 쓰기 전에 다른 녀석이 달라고 하면 곤란합니다.
CBuffer* m_lpBroadcast2ndBuffer; // 브로드캐스트 2nd버퍼(새 브로드캐스트 버퍼, 캐릭터 및 아이템용)
unsigned long m_dwCastleEmblemCID; // 성 상징물의 디텍션 범위에 있는 셀이면 상징물의 CID를 가지고 있다.
unsigned short m_wMapIndex; // 맵 인덱스
unsigned char m_cIndexX; // 맵 X좌표
unsigned char m_cIndexZ; // 맵 Z좌표
unsigned char m_cTurnOfGetAggresiveCreature;
CCell::Weather m_eWeather; // 현재 날씨
};
#endif