Files
Client/Server/RylServerProject/RylGameLibrary/Creature/CreatureStructure.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

537 lines
15 KiB
C++

#ifndef _CREATURE_STRUCTURE_H_
#define _CREATURE_STRUCTURE_H_
#include <winsock2.h>
#include <windows.h>
#include <cmath>
#include <DB/DBDefine.h>
// 전방 참조
struct CreatureStatus;
struct CharacterStatus;
struct SKILL;
namespace Item
{
class CItem;
class CEquipment;
namespace EquipType
{
enum DoubleSwordType;
}
}
namespace BattleInclination
{
enum Const
{
IS_PEACEMODE = ( 1 << 0 ), // 평화모드인 경우 세팅
IS_SAFETY_ZONE = ( 1 << 1 ), // 세이프티 존 내부에 있는 경우 세팅
HAS_CAMP = ( 1 << 2 ), // 길드 요새를 가진 길드에 속해 있을 경우 세팅
HAS_DEVELOPING_CAMP = ( 1 << 3 ), // 건설중인 길드 요새를 가진 길드에 속해 있을 경우 세팅
IS_CASTLE_OBJECT = ( 1 << 4 ), // 공성 Object이면서 수성병기인 경우만 세팅
IS_CASTLE_NPC = ( 1 << 5 ), // 공성 Object이면서 수성 병기의 병기 관리 NPC 와 뒷문 NPC
IS_GOD_MODE = ( 1 << 6 ), // G모드인 경우 세팅
IS_TEAM_BATTLE = ( 1 << 7 ), // 팀배틀 중인 경우 세팅
};
enum VSType
{
VS_CHARACTER = ( 1 << 0 ), // PvP
VS_PARTY = ( 1 << 1 ), // 파티간 배틀
VS_GUILD = ( 1 << 2 ), // 길드간 배틀
};
// 피아식별시 주체가 되는 캐릭터 정보
// 여기서 데이터 추가하거나 삭제하는 경우,
// 브로드캐스팅 시, 채팅서버로 데이터 전송하는 부분도 수정해야한다.
struct CharData
{
bool IsPeaceMode(void) const { return 0 != (m_cFlags & IS_PEACEMODE); } // 평화모드인 경우
bool IsSafetyZone(void) const { return 0 != (m_cFlags & IS_SAFETY_ZONE); } // 내가 Safety존 내부에 있는지
bool HasCamp(void) const { return 0 != (m_cFlags & HAS_CAMP); } // 속한 길드가 길드 요새를 가지고 있는지...
bool HasDevelopingCamp(void) const { return 0 != (m_cFlags & HAS_DEVELOPING_CAMP); } // 속한 길드가 길드 요새를 건설중인지...
bool IsCastleObject(void) const { return 0 != (m_cFlags & IS_CASTLE_OBJECT); } // 공성병기인 경우, 수성병기인지...
bool IsCastleNPC(void) const { return 0 != (m_cFlags & IS_CASTLE_NPC); } // 수성 NPC 인 경우
bool IsGODMode(void) const { return 0 != (m_cFlags & IS_GOD_MODE); } // G모드인 경우
bool IsTeamBattle(void) const { return 0 != (m_cFlags & IS_TEAM_BATTLE); } // 팀배틀 중인 경우
void SetPeaceMode(bool bPeaceMode) { m_cFlags |= bPeaceMode ? IS_PEACEMODE : 0; }
void SetSafetyZone(bool bInSafetyZone) { m_cFlags |= bInSafetyZone ? IS_SAFETY_ZONE : 0; }
void SetHasCamp(bool bHasCamp) { m_cFlags |= bHasCamp ? HAS_CAMP : 0; }
void SetHasDevelopingCamp(bool bHasDevelopingCamp) { m_cFlags |= bHasDevelopingCamp ? HAS_DEVELOPING_CAMP : 0; }
void SetCastleObject(bool bCastleObject) { m_cFlags |= bCastleObject ? IS_CASTLE_OBJECT : 0; }
void SetCastleNPC(bool bCastleNPC) { m_cFlags |= bCastleNPC ? IS_CASTLE_NPC : 0; }
void SetGODMode(bool bGODMode) { m_cFlags |= bGODMode ? IS_GOD_MODE : 0; }
void SetTeamBattle(bool bTeamBattle) { m_cFlags |= bTeamBattle ? IS_TEAM_BATTLE : 0; }
unsigned long m_dwCID; // 캐릭터 CID
unsigned long m_dwGID; // 캐릭터 GID
unsigned long m_dwCastleID; // 공성 병기인 경우, 속한 성의 ID를 넣는다.
unsigned char m_cSiegeState; // 공성 병기인 경우, 공성 병기 상태를 넣는다.
unsigned char m_cNation; // 캐릭터 국적
unsigned char m_cAdminLevel; // 운영자 레벨
unsigned char m_cFlags; // 기타 정보
unsigned long m_dwPID; // 캐릭터에 파티 정보
unsigned char m_cTacticsFlag; // 캐릭터에 용병 정보
unsigned char m_cRealmWarFlag;
unsigned char m_cGuildWarFlag;
unsigned char m_cCreatureType; // 크리쳐 타입
unsigned short m_wObjectType; // 스트럭쳐 정보
unsigned short m_wKind; // 스트럭쳐 종류
unsigned char m_cRide; // 병기에 탑승 여부.
};
// 피아식별시 쓰이는 캐릭터간의 관계 (일단은 채팅 서버까진 갈 필요 없는 정보로 구성)
struct RelationData
{
unsigned char m_cVSFlag; // PvP, 팀배틀 정보
bool m_bHostileGuild; // 적대 길드인가?
};
};
namespace Creature
{
enum Const
{
PC_MAX_LEVEL = 100, // 캐릭터 최대 레벨
MONSTER_MAX_LEVEL = 150, // 몬스터 최대 레벨
// edith 2008.02.27 길드가입 레벨 제한 제거
LEVEL_ABLE_WAR = 1 // 전쟁이 가능한 최소 레벨 (길드 가입/전쟁 모드 제한)
};
enum IdentifyCIDBit
{
MONSTER_KIND_BIT = 0x0000FFFF,
MONSTER_BIT = 0x80000000,
NPC_BIT = 0x40000000,
SIEGE_OBJECT_BIT = 0x10000000,
SUMMON_MONSTER_BIT = 0xA0000000, // MONSTER_BIT (0x80000000) + 0x20000000
NPC_LINK_BIT = 0x50000000, // 소환 완료된 석상의 경우 이 비트가 세트된 NPC와 링크되어 메달상점의 역할을 한다.
// NPC_BIT (0x40000000) + 0x10000000
// 석상 KID (MonsterStructure.h 에도 정의되어 있음)
MIN_STATUE_KID = 4001,
MAX_STATUE_KID = 4070
};
enum CreatureType
{
CT_PC = 0,
CT_NPC = 1,
CT_MONSTER = 2,
CT_SUMMON = 3,
CT_STRUCT = 4,
CT_SIEGE_OBJECT = 5,
CT_NONE_TYPE = 99
};
enum Nation
{
STATELESS = 0, // 무국적 (몬스터, NPC)
KARTERANT = 1, // 카르테란트
MERKADIA = 2, // 메르카디아
ALMIGHTY_PIRATE = 3, // 신의해적단
MAX_NATION = 4
};
enum WarFlag
{
WAR_OFF = 0, // 전쟁 참여 안함
WAR_ON = 1, // 전쟁 참여
WAR_INSTANCE = 2 // 인스턴스 전쟁 참여
};
enum StatusType
{
RIGHT_PASSIVE_TYPE = 0, // 패시브 스킬이 적용된 오른손 장비 스탯 (기본값으로 CreatureStatus에 바로 사용된다.)
LEFT_PASSIVE_TYPE = 1, // 패시브 스킬이 적용된 왼손 장비 스탯 (이도류)
RIGHT_NON_PASSIVE_TYPE = 2, // 패시브 스킬이 적용되지 않은 오른손 장비 스탯 (오른손 무기를 사용하는 스킬)
LEFT_NON_PASSIVE_TYPE = 3, // 패시브 스킬이 적용되지 않은 왼손 장비 스탯 (왼손 무기(스킬암)를 사용하는 스킬)
MAX_STATUS_TYPE = 4
};
// 서버에서 사용하는 Creature 판별 함수들
// 클라이언트에서는 CRYLGameData::GetClientIdentity() 함수 사용!!
static bool IsSummonMonster(unsigned long dwCID)
{
return (Creature::SUMMON_MONSTER_BIT == (dwCID & Creature::SUMMON_MONSTER_BIT));
}
static bool IsStruct(unsigned long dwCID)
{
unsigned short wKID = static_cast<unsigned short>(dwCID & Creature::MONSTER_KIND_BIT);
return (wKID >= MIN_STATUE_KID && wKID <= MAX_STATUE_KID);
}
static bool IsLinkedNPC(unsigned long dwCID)
{
return (Creature::NPC_LINK_BIT == (dwCID & Creature::NPC_LINK_BIT));
}
static CreatureType GetCreatureType(unsigned long dwCID)
{
if (dwCID & Creature::MONSTER_BIT)
{
if (IsSummonMonster(dwCID)) return Creature::CT_SUMMON;
else if (IsStruct(dwCID)) return Creature::CT_STRUCT;
return Creature::CT_MONSTER;
}
else if (dwCID & Creature::NPC_BIT) return Creature::CT_NPC;
else if (dwCID & Creature::SIEGE_OBJECT_BIT) return Creature::CT_SIEGE_OBJECT;
return Creature::CT_PC;
}
inline static const char* GetNationName(unsigned char cNation)
{
switch(cNation)
{
case KARTERANT: return "KARTERANT";
case MERKADIA: return "MERKADIA";
case ALMIGHTY_PIRATE: return "ALMIGHTY_PIRATE";
}
return "STATELESS";
}
inline static const char* GetShortNationName(unsigned char cNation)
{
switch(cNation)
{
case KARTERANT: return "KR";
case MERKADIA: return "ME";
case ALMIGHTY_PIRATE: return "AP";
}
return "ST";
}
};
// 엘리트 보너스 정보
namespace EliteBonus
{
enum Const
{
MAX_BONUS_LEVEL = 10,
MAX_BONUS_DROP_ITEM = 3
};
// 엘리트 보너스에 의한 경험치/드랍률 보너스가 제거되었습니다. (2004-09-17 by 로딘)
static short usBonusExp[MAX_BONUS_LEVEL] = {
100 + 0,
100 + 0,
100 + 0,
100 + 0,
100 + 0,
100 + 0,
100 + 0,
100 + 0,
100 + 0,
100 + 0
};
static unsigned char usBonusItemDropRate[MAX_BONUS_LEVEL][MAX_BONUS_DROP_ITEM] = {
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
};
struct EliteBonusData
{
char m_cNation;
unsigned char m_cLevel;
EliteBonusData();
EliteBonusData(char cNation, unsigned char cLevel);
};
}
// 맵 이동 정보
struct Position
{
float m_fPointX; // Point X 좌표
float m_fPointY; // Point Y 좌표
float m_fPointZ; // Point Z 좌표
inline Position();
inline Position(const POS& Pos);
inline Position(const Position& Pos);
inline Position(float fPointX, float fPointY, float fPointZ);
inline POS PositionToPOS() const;
inline unsigned long GetDistance(const Position& rhs) const
{
return static_cast<unsigned long>(sqrt(
(m_fPointX - rhs.m_fPointX) * (m_fPointX - rhs.m_fPointX) +
(m_fPointY - rhs.m_fPointY) * (m_fPointY - rhs.m_fPointY) +
(m_fPointZ - rhs.m_fPointZ) * (m_fPointZ - rhs.m_fPointZ)));
}
inline unsigned long GetSquaredDistance(const Position& rhs) const
{
return static_cast<unsigned long>(
(m_fPointX - rhs.m_fPointX) * (m_fPointX - rhs.m_fPointX) +
(m_fPointY - rhs.m_fPointY) * (m_fPointY - rhs.m_fPointY) +
(m_fPointZ - rhs.m_fPointZ) * (m_fPointZ - rhs.m_fPointZ));
}
inline bool operator == (const Position& rhs) const
{
if ( m_fPointX == rhs.m_fPointX && m_fPointY == rhs.m_fPointY && m_fPointZ == rhs.m_fPointZ )
{
return true;
}
return false;
}
inline bool operator != (const Position& rhs) const
{
if ( m_fPointX != rhs.m_fPointX || m_fPointY != rhs.m_fPointY || m_fPointZ != rhs.m_fPointZ )
{
return true;
}
return false;
}
inline void operator () (const Position& rhs)
{
m_fPointX = rhs.m_fPointX;
m_fPointY = rhs.m_fPointY;
m_fPointZ = rhs.m_fPointZ;
}
};
inline Position::Position()
: m_fPointX(0.0f), m_fPointY(0.0f), m_fPointZ(0.0f) { }
inline Position::Position(const POS& Pos)
: m_fPointX(Pos.fPointX), m_fPointY(Pos.fPointY), m_fPointZ(Pos.fPointZ) { }
inline Position::Position(const Position& Pos)
: m_fPointX(Pos.m_fPointX), m_fPointY(Pos.m_fPointY), m_fPointZ(Pos.m_fPointZ) { }
inline Position::Position(float fPointX, float fPointY, float fPointZ)
: m_fPointX(fPointX), m_fPointY(fPointY), m_fPointZ(fPointZ) { }
inline POS Position::PositionToPOS() const
{
POS stPos;
stPos.fPointX = m_fPointX;
stPos.fPointY = m_fPointY;
stPos.fPointZ = m_fPointZ;
return stPos;
}
// 동작 정보
struct MotionInfo
{
float m_fDirection; // 바라보는 방향
float m_fVelocity; // 속도
unsigned short m_wAction; // 취하는 행동
unsigned long m_dwFrame; // 모션 프레임 ( 몬스터, NPC가 사용 )
MotionInfo();
};
// 인챈트 정보
struct EnchantInfo
{
enum
{
ULONG_BIT = 32, // unsigned long (32바이트)
MAX_ARRAY = 4 // 스펠의 종류는 UCHAR_BIT * MAX_ARRAY
};
unsigned long m_dwStatusFlag[MAX_ARRAY]; // 챈트/인챈트 플래그
EnchantInfo();
EnchantInfo( const EnchantInfo& Info ) // 대입을 위한 복사 생성자
{
for( int i = 0 ; i < MAX_ARRAY ; ++i )
{
m_dwStatusFlag[ i ] = Info.m_dwStatusFlag[ i ];
}
}
void SetFlag(unsigned char cSpellKind);
void ResetFlag(unsigned char cSpellKind);
void ClearFlag(void);
bool GetFlag(unsigned char cSpellKind) const;
};
// 데미지 계산시의 추가 효과 정보
struct CalculateDamageInfo
{
bool m_bForceDRC; // '참'이면 기본 DRC를 무시하고 추가 DRC로 대체
float m_fDRC; // 추가 DRC
short m_nOffenceRevision; // 추가 공격보정
short m_nMinDamage; // 추가 최소데미지
short m_nMaxDamage; // 추가 최대데미지
CalculateDamageInfo()
: m_bForceDRC(false), m_fDRC(0.0f), m_nOffenceRevision(0), m_nMinDamage(0), m_nMaxDamage(0)
{ }
CalculateDamageInfo(bool bForceDRC, float fDRC, short nOffenceRevision, short nMinDamage, short nMaxDamage)
: m_bForceDRC(bForceDRC), m_fDRC(fDRC),
m_nOffenceRevision(nOffenceRevision), m_nMinDamage(nMinDamage), m_nMaxDamage(nMaxDamage)
{ }
};
typedef CalculateDamageInfo* LPCalculateDamageInfo;
// 캐릭터에 대한 속성
struct CharacterStatus
{
short m_nSTR; // 캐릭터 STR
short m_nDEX; // 캐릭터 DEX
short m_nCON; // 캐릭터 CON
short m_nINT; // 캐릭터 INT
short m_nWIS; // 캐릭터 WIS
CharacterStatus();
CharacterStatus(CHAR_INFOST& characterDBData);
void Init(CHAR_INFOST& characterDBData);
};
typedef CharacterStatus* LPCharacterStatus;
struct FightStatus
{
// 계산 상태 (중복 계산 방지)
enum CalculateState
{
CS_NONE = 0, // 초기화
CS_BASE_INFO = 1, // 기본 스탯으로 계산을 완료한 상태
CS_EQUIP_INFO = 2, // 장비 효과를 추가 계산한 상태
CS_ENCHANT_INFO = 3 // 인챈트 효과를 받은 상태
};
enum Const
{
MAX_INCHANT_HP = 15000,
MAX_INCHANT_MP = 15000
};
long m_lMinDamage; // 최소데미지
long m_lMaxDamage; // 최대데미지
short m_wArmor; // 방어력
short m_wHitRate; // 명중
short m_wEvade; // 회피
unsigned short m_nMaxHP; // HP 최대값
short m_wHPRegen; // HP 회복
unsigned short m_nMaxMP; // MP 최대값
short m_wMPRegen; // MP 회복
short m_wCritical; // 크리티컬
short m_wBlock; // 블록
short m_wSpeed; // 속도
short m_wCoolDownRevision; // 쿨다운보정
short m_wSkillPoint; // 스킬포인트
short m_wMagicPower; // 마법력
short m_wMagicResist; // 마법저항
int m_wLuck; // 행운값
//--// start..
short m_wFrost; // 냉기/정지 속성
short m_wFire; // 불/독 속성
short m_wElectro; // 전지/충격 속성
short m_wDarkness; // 암흑/빛 속성
//--// end..
float m_fDefenceRate; // 방어%
float m_fCriticalMagnification; // 크리티컬배율
float m_fCriticalRate; // 크리티컬%
float m_fBlockRate; // 블럭률%
float m_fSpeedRate; // 속도%
float m_fCoolDownRevisionRate; // 쿨다운보정%
float m_fMagicResistRate; // 마법저항%
float m_fLuckResistRate; // 럭키찬스%
float m_fLevelExplosion; // 레벨 익스플로젼
unsigned char m_cCriticalType; // 크리티컬 타입
unsigned char m_cComboCount; // 공격 콤보 횟수
unsigned char m_cCalculateState; // 계산 상태
FightStatus();
bool CalculateBaseInfo(const CharacterStatus& characterStatus, const unsigned short wLevel, const unsigned char cClass);
bool CalculateEquipInfo(const Item::CEquipment** ppEquip, const bool bFirstWeaponSlot, const bool bRightHand, const bool bRideFlag,
const SKILL& skill, const unsigned char cLevel, const unsigned short wRiderAbility, const unsigned short wLuckAbility, const unsigned short wLevelAbility,
const CharacterStatus& characterStatus, const unsigned char cClass, FightStatus& resultStatus) const;
bool CalculateEnchantInfo(const unsigned short* aryEnchantLevel, FightStatus& resultStatus) const;
void CalculateSubStatus(void);
static bool CheckEquipable(const Item::CEquipment* lpEquip, const CharacterStatus& characterStatus,
const unsigned char cClass, const unsigned char cLevel, const unsigned short wLevelAbility); //--//
};
#pragma pack(8)
//------------------------------------------------------------------------------------
// TODO : memory alignment 주의할 것.
// : 4byte단위로 alignment 가 되도록 할 것.
// : 메모리 부족시에는 크기가 많이 필요 없는 멤버는 short등으로 줄일 것.
// 무기나 도구에 의해서 영향을 받은 능력치를 저장 (게임상에서 모든 계산은 이것으로 함)
struct CreatureStatus
{
__int64 m_nExp; // 사람인 경우는 자신의 경험점, 몬스터인 경우는 나누어 줄 경험점
int m_nLevel; // 레벨
unsigned short m_nNowHP; // 현재 HP
unsigned short m_nNowMP; // 현재 MP (몬스터의 경우는 무조건 최대값으로 초기화)
FightStatus m_StatusInfo; // 대부분의 정보가 이곳에 있음
CreatureStatus();
CreatureStatus(CHAR_INFOST& characterDBData);
void Init(CHAR_INFOST& characterDBData);
};
typedef CreatureStatus* LPCreatureStatus;
#pragma pack()
#endif