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>
343 lines
10 KiB
C++
343 lines
10 KiB
C++
#include "stdafx.h"
|
|
#include "Item.h"
|
|
#include "..\Skill\SkillStructure.h"
|
|
|
|
static Item::ItemInfo NullProtoType;
|
|
|
|
Item::CItem::CItem()
|
|
: m_ItemInfo(NullProtoType)
|
|
{
|
|
m_ItemData.m_dwUID = 0;
|
|
m_ItemData.m_usProtoTypeID = 0;
|
|
|
|
m_ItemData.m_ItemPos.m_cPos = 0;
|
|
m_ItemData.m_ItemPos.m_cIndex = 0;
|
|
|
|
m_ItemData.m_cItemSize = sizeof(ItemData);
|
|
m_ItemData.m_cNumOrDurability = 0;
|
|
m_cMaxNumOrDurability = 0;
|
|
m_dwStallPrice = 0;
|
|
}
|
|
|
|
|
|
Item::CItem::CItem(unsigned __int64 dwItemUID, const ItemInfo& itemInfo)
|
|
: m_ItemInfo(itemInfo)
|
|
{
|
|
m_ItemData.m_dwUID = dwItemUID;
|
|
m_ItemData.m_usProtoTypeID = itemInfo.m_usProtoTypeID;
|
|
|
|
m_ItemData.m_ItemPos.m_cPos = 0;
|
|
m_ItemData.m_ItemPos.m_cIndex = 0;
|
|
|
|
m_ItemData.m_cItemSize = sizeof(ItemData);
|
|
m_ItemData.m_cNumOrDurability = itemInfo.m_DetailData.m_cDefaultDurabilityOrStack;
|
|
m_cMaxNumOrDurability = itemInfo.m_DetailData.m_cMaxDurabilityOrStack;
|
|
m_dwStallPrice = 0;
|
|
}
|
|
|
|
Item::CItem::~CItem()
|
|
{
|
|
|
|
}
|
|
|
|
bool Item::CItem::SerializeOut(char* lpSerializeItem_Out, size_t& nBufferLength_InOut)
|
|
{
|
|
if(nBufferLength_InOut >= sizeof(ItemData))
|
|
{
|
|
m_ItemData.m_cItemSize = sizeof(ItemData);
|
|
nBufferLength_InOut = sizeof(ItemData);
|
|
|
|
*reinterpret_cast<ItemData*>(lpSerializeItem_Out) = m_ItemData;
|
|
return true;
|
|
}
|
|
|
|
nBufferLength_InOut = 0;
|
|
return false;
|
|
}
|
|
|
|
bool Item::CItem::SerializeIn(const char* lpSerializeItem_In, size_t& nBufferLength_InOut)
|
|
{
|
|
if(sizeof(ItemData) <= nBufferLength_InOut)
|
|
{
|
|
const ItemData& itemData = *reinterpret_cast<const Item::ItemData*>(lpSerializeItem_In);
|
|
nBufferLength_InOut = itemData.m_cItemSize;
|
|
|
|
if(itemData.m_usProtoTypeID == m_ItemInfo.m_usProtoTypeID)
|
|
{
|
|
m_ItemData = itemData;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
|
|
Item::CEquipment::CEquipment(unsigned __int64 dwItemUID, const ItemInfo& itemInfo)
|
|
: CItem(dwItemUID, itemInfo),
|
|
m_usRuneSocket(0), m_cMaterialType(itemInfo.m_DetailData.m_cMaterialType),
|
|
m_cSocketNum(0), m_cReserved(0), m_cReserved2(0)
|
|
{
|
|
if(1 == m_ItemInfo.m_DetailData.m_cXSize && 1 == m_ItemInfo.m_DetailData.m_cYSize)
|
|
{
|
|
m_cMaxSocket = Item::EquipmentInfo::MAX_MINSIZE_SOCKET_NUM;
|
|
m_cMaxAttribute = Item::EquipmentInfo::MAX_MINSIZE_ATTRIBUTE_NUM;
|
|
}
|
|
else
|
|
{
|
|
m_cMaxSocket = Item::EquipmentInfo::MAX_SOCKET_NUM;
|
|
m_cMaxAttribute = Item::EquipmentInfo::MAX_ATTRIBUTE_NUM;
|
|
}
|
|
|
|
m_cMaxSocket = (itemInfo.m_DetailData.m_cMaxSocketNum < m_cMaxSocket) ?
|
|
itemInfo.m_DetailData.m_cMaxSocketNum : m_cMaxSocket;
|
|
|
|
m_ItemData.m_cItemSize += sizeof(EquipmentInfo);
|
|
|
|
std::fill_n(m_cSocket, unsigned char(Item::EquipmentInfo::MAX_SOCKET_NUM), 0);
|
|
InitializeAttribute();
|
|
}
|
|
|
|
Item::CEquipment::~CEquipment()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void Item::CEquipment::InitializeAttribute()
|
|
{
|
|
for(unsigned int nIndex = 0; nIndex < Item::Attribute::MAX_ATTRIBUTE_NUM; ++nIndex)
|
|
{
|
|
m_usAttribute[nIndex] =
|
|
m_ItemInfo.m_EquipAttribute.m_usAttributeValue[nIndex];
|
|
}
|
|
}
|
|
|
|
|
|
bool Item::CEquipment::SerializeOut(char* lpSerializeItem_Out, size_t& nBufferLength_InOut)
|
|
{
|
|
const size_t nMaxItemSize = sizeof(ItemData) + sizeof(EquipmentInfo) +
|
|
Item::EquipmentInfo::MAX_SOCKET_NUM * sizeof(unsigned char) +
|
|
Item::EquipmentInfo::MAX_ATTRIBUTE_NUM * sizeof(ItemAttribute);
|
|
|
|
if(nMaxItemSize <= nBufferLength_InOut)
|
|
{
|
|
unsigned int nIndex = 0, nSocketIndex = 0, nAttributeIndex = 0;
|
|
|
|
// 기본 정보 복사
|
|
ItemData& itemData = *reinterpret_cast<ItemData*>(lpSerializeItem_Out);
|
|
itemData = m_ItemData;
|
|
|
|
EquipmentInfo& equipmentInfo = *reinterpret_cast<EquipmentInfo*>(lpSerializeItem_Out + sizeof(ItemData));
|
|
char* lpSocketInfo = lpSerializeItem_Out + sizeof(ItemData) + sizeof(EquipmentInfo);
|
|
|
|
// 아이템 소켓 정보 복사
|
|
for(nIndex = 0, nSocketIndex = 0;
|
|
nIndex < Item::EquipmentInfo::MAX_SOCKET_NUM && nSocketIndex < m_cMaxSocket; ++nIndex)
|
|
{
|
|
if(0 != m_cSocket[nIndex])
|
|
{
|
|
lpSocketInfo[nSocketIndex] = m_cSocket[nIndex];
|
|
++nSocketIndex;
|
|
}
|
|
}
|
|
|
|
// 아이템 속성 정보 복사
|
|
ItemAttribute* lpAttribute = reinterpret_cast<ItemAttribute*>(
|
|
lpSocketInfo + (nSocketIndex * sizeof(unsigned char)));
|
|
|
|
for(nIndex = 0, nAttributeIndex = 0;
|
|
nIndex < Item::Attribute::MAX_ATTRIBUTE_NUM && nAttributeIndex < m_cMaxAttribute; ++nIndex)
|
|
{
|
|
const short usDiffAttribute = m_usAttribute[nIndex] -
|
|
m_ItemInfo.m_EquipAttribute.m_usAttributeValue[nIndex];
|
|
|
|
if(0 != usDiffAttribute)
|
|
{
|
|
lpAttribute[nAttributeIndex].m_cType = nIndex;
|
|
lpAttribute[nAttributeIndex].m_usValue = usDiffAttribute;
|
|
++nAttributeIndex;
|
|
}
|
|
}
|
|
|
|
// 개수 및 크기 정보 복사
|
|
m_ItemData.m_cItemSize = itemData.m_cItemSize = sizeof(ItemData) + sizeof(EquipmentInfo) +
|
|
nSocketIndex * sizeof(unsigned char) + nAttributeIndex * sizeof(ItemAttribute);
|
|
|
|
equipmentInfo.m_cRuneSocket = m_usRuneSocket;
|
|
equipmentInfo.m_cDiffMaterialType = m_cMaterialType - m_ItemInfo.m_DetailData.m_cMaterialType;
|
|
|
|
equipmentInfo.m_cDiffMaxSocket = m_cMaxSocket - m_ItemInfo.m_DetailData.m_cMaxSocketNum;
|
|
equipmentInfo.m_cSocketNum = nSocketIndex;
|
|
|
|
equipmentInfo.m_cAttributeNum = nAttributeIndex;
|
|
equipmentInfo.m_cReserved = 0;
|
|
|
|
equipmentInfo.m_cDiffMaxDurability = m_cMaxNumOrDurability - m_ItemInfo.m_DetailData.m_cMaxDurabilityOrStack;
|
|
equipmentInfo.m_cReserved2 = m_cReserved2;
|
|
|
|
nBufferLength_InOut = m_ItemData.m_cItemSize;
|
|
return true;
|
|
}
|
|
|
|
nBufferLength_InOut = 0;
|
|
return false;
|
|
}
|
|
|
|
|
|
bool Item::CEquipment::SerializeIn(const char* lpSerializeItem_In, size_t& nBufferLength_InOut)
|
|
{
|
|
if(CItem::SerializeIn(lpSerializeItem_In, nBufferLength_InOut))
|
|
{
|
|
const Item::EquipmentInfo& equipmentInfo =
|
|
*reinterpret_cast<const Item::EquipmentInfo*>(lpSerializeItem_In + sizeof(ItemData));
|
|
|
|
m_usRuneSocket = equipmentInfo.m_cRuneSocket; // 룬 소켓
|
|
m_cMaterialType = m_ItemInfo.m_DetailData.m_cMaterialType + equipmentInfo.m_cDiffMaterialType; // 재질값
|
|
m_cMaxSocket = m_ItemInfo.m_DetailData.m_cMaxSocketNum + equipmentInfo.m_cDiffMaxSocket; // 최대 소켓 개수
|
|
m_cSocketNum = equipmentInfo.m_cSocketNum;
|
|
m_cReserved = equipmentInfo.m_cReserved;
|
|
|
|
m_cMaxNumOrDurability = m_ItemInfo.m_DetailData.m_cMaxDurabilityOrStack + equipmentInfo.m_cDiffMaxDurability;
|
|
m_cReserved2 = equipmentInfo.m_cReserved2;
|
|
|
|
const unsigned char* lpSocketIndex = reinterpret_cast<const unsigned char*>(&equipmentInfo + 1);
|
|
const unsigned char* lpSocketPastEnd = lpSocketIndex + m_cSocketNum;
|
|
std::copy(lpSocketIndex, lpSocketPastEnd, m_cSocket);
|
|
|
|
const Item::ItemAttribute* lpItemAttribute =
|
|
reinterpret_cast<const Item::ItemAttribute*>(lpSocketPastEnd);
|
|
|
|
for(unsigned int nIndex = 0; nIndex < equipmentInfo.m_cAttributeNum; ++nIndex)
|
|
{
|
|
unsigned char cType = lpItemAttribute[nIndex].m_cType;
|
|
if(cType < Item::Attribute::MAX_ATTRIBUTE_NUM)
|
|
{
|
|
m_usAttribute[cType] = m_ItemInfo.m_EquipAttribute.m_usAttributeValue[cType] + lpItemAttribute[nIndex].m_usValue;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
// InstallSocket
|
|
Item::CEquipment::EQUIPMENT_ERROR Item::CEquipment::InstallSocket(CItem& Gem)
|
|
{
|
|
using namespace Item;
|
|
|
|
// 현재 아이템에 남아 있는 소켓 개수 검사. 소켓이 전부 차면 더 못 박도록 함.
|
|
if (Item::EquipmentInfo::MAX_SOCKET_NUM <= m_cMaxSocket ||
|
|
m_cMaxSocket <= m_cSocketNum)
|
|
{
|
|
return EQUIPMENT_ERROR::E_OVER_MAX_SOCKET;
|
|
}
|
|
|
|
// 아이템이 보석이 맞는가 확인.
|
|
unsigned short usGemTypeID = Gem.GetPrototypeID();
|
|
if(usGemTypeID < EtcItemID::GEM_START_ID || EtcItemID::GEM_END_ID < usGemTypeID)
|
|
{
|
|
return EQUIPMENT_ERROR::E_NOT_GEM;
|
|
}
|
|
|
|
unsigned char cGemType = usGemTypeID - EtcItemID::GEM_START_ID;
|
|
|
|
// 젬 속성 얻기.
|
|
ItemAttribute attribute = CItemType::GetInstallGemAttribute(cGemType,
|
|
m_ItemInfo.m_DetailData.m_cItemType);
|
|
|
|
++m_cSocketNum;
|
|
return EQUIPMENT_ERROR::E_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
// UpgradeItem
|
|
Item::CEquipment::EQUIPMENT_ERROR Item::CEquipment::UpgradeItem(CItem& Mineral)
|
|
{
|
|
|
|
|
|
|
|
return EQUIPMENT_ERROR::E_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
Item::CUseItem::CUseItem(unsigned __int64 dwItemUID, const ItemInfo& itemInfo)
|
|
: CItem(dwItemUID, itemInfo)
|
|
{
|
|
|
|
|
|
}
|
|
|
|
Item::CUseItem::~CUseItem()
|
|
{
|
|
|
|
|
|
}
|
|
|
|
Item::CSkillItem::CSkillItem()
|
|
: CItem(0, m_ItemInfoInstance)
|
|
{
|
|
m_cMaxDurability = 0;
|
|
}
|
|
|
|
bool Item::CSkillItem::SetSkillInfo(const Skill::ProtoType *lpSkillInfo)
|
|
{
|
|
/* char m_szEffectFileName[MAX_FILE_NAME];
|
|
char m_szHitFileName[MAX_FILE_NAME];
|
|
char m_szCastingFileName[MAX_FILE_NAME];
|
|
|
|
//-----------------------------------
|
|
|
|
Type::Type m_eSkillType; // See Namespace Type
|
|
Target::Type m_eTargetType; // See Namespace Target
|
|
UseLimit::Type m_eUseLimit; // See Namespace UseLimit
|
|
|
|
unsigned char m_StatusLimitType[MAX_LIMIT_NUM];
|
|
char m_StatusLimitValue[MAX_LIMIT_NUM];
|
|
|
|
//-----------------------------------
|
|
|
|
unsigned short m_usSkill_ID;
|
|
unsigned short m_StartMP;
|
|
unsigned short m_LevelMP;
|
|
unsigned short m_StartTick;
|
|
|
|
//-----------------------------------
|
|
|
|
unsigned short m_LevelTick;
|
|
unsigned short m_usCoolDownTime;
|
|
|
|
//-----------------------------------
|
|
|
|
float m_EffectDistance;
|
|
float m_EffectExtent;
|
|
|
|
//-----------------------------------
|
|
|
|
bool m_bProtection;
|
|
bool m_bGauge;
|
|
bool m_bIsClassSkill;
|
|
bool m_bInterrupt;
|
|
unsigned char m_cEndScript;
|
|
unsigned char m_cEndCoolDown;
|
|
unsigned char m_cMinRange;
|
|
unsigned char m_cMaxRange;
|
|
|
|
//-----------------------------------
|
|
|
|
unsigned char m_cStrikeNum;
|
|
unsigned char m_cSpell_LockCount;
|
|
unsigned char m_cPadding[6];*/
|
|
|
|
m_ItemInfoInstance.m_SpriteData = lpSkillInfo->m_SpriteInfo;
|
|
|
|
return true;
|
|
} |