// ItemRebalanceConverter.cpp : ÄÜ¼Ö ÀÀ¿ë ÇÁ·Î±×·¥¿¡ ´ëÇÑ ÁøÀÔÁ¡À» Á¤ÀÇÇÕ´Ï´Ù. // #define _WIN32_WINNT 0x0500 #include "stdafx.h" #include "OldItemStructure.h" #include #include #include #define INITGUID #define DBINITCONSTANTS #include #include #include #include #include #include #include #include #include #include #include "OldItemMgr.h" #define COPY_AND_ADVANCE_DST(dst, src, size) memcpy((dst), (src), (size)); (dst) += (size) #define COPY_AND_ADVANCE_SRC(dst, src, size) memcpy((dst), (src), (size)); (src) += (size) class COMInitialize { public: static COMInitialize& GetInstance(); private: COMInitialize(); ~COMInitialize(); }; COMInitialize& COMInitialize::GetInstance() { static COMInitialize initialize; return initialize; } COMInitialize::COMInitialize() { CoInitializeEx(NULL, COINIT_MULTITHREADED); } COMInitialize::~COMInitialize() { CoUninitialize(); } class CUserItemDataGet { public: int m_nCID; BYTE m_Equip[sizeof(EQUIP)]; BYTE m_Inven[sizeof(INVEN)]; BYTE m_Extra[sizeof(EXTRA)]; BYTE m_Exchange[sizeof(EXCHANGE)]; DBLENGTH m_EquipLength; DBLENGTH m_InvenLength; DBLENGTH m_ExtraLength; DBLENGTH m_ExchangeLength; void Init() { m_nCID = 0; m_EquipLength = m_InvenLength = m_ExtraLength = m_ExchangeLength = 0; memset(m_Equip, 0, sizeof(EQUIP)); memset(m_Inven, 0, sizeof(INVEN)); memset(m_Extra, 0, sizeof(EXTRA)); memset(m_Exchange, 0, sizeof(EXCHANGE)); } }; class CUserItemDataSet { public: int m_nCID; BYTE m_Equip[sizeof(EQUIP)]; BYTE m_Inven[sizeof(INVEN)]; BYTE m_Extra[sizeof(EXTRA)]; DBLENGTH m_EquipLength; DBLENGTH m_InvenLength; DBLENGTH m_ExtraLength; void Init() { m_nCID = 0; m_EquipLength = m_InvenLength = m_ExtraLength = 0; memset(m_Equip, 0, sizeof(EQUIP)); memset(m_Inven, 0, sizeof(INVEN)); memset(m_Extra, 0, sizeof(EXTRA)); } }; class CUserItemDataSetEx { public: int m_nCID; BYTE m_Exchange[sizeof(EXCHANGE)]; DBLENGTH m_ExchangeLength; void Init() { m_nCID = 0; m_ExchangeLength = 0; memset(m_Exchange, 0, sizeof(EXCHANGE)); } }; class CStoreItemData { public: DBLENGTH m_StoreLength; int m_nUID; BYTE m_Store[sizeof(STORE)]; void Init() { m_StoreLength = 0; m_nUID = 0; memset(m_Store, 0, sizeof(STORE)); } }; class CGetUserItemData : public CUserItemDataGet { public: typedef CCommand< CAccessor< CGetUserItemData >, CRowset, CMultipleResults > Command; BEGIN_COLUMN_MAP(CGetUserItemData) COLUMN_ENTRY(1, m_nCID) COLUMN_ENTRY_LENGTH(2, m_Equip, m_EquipLength) COLUMN_ENTRY_LENGTH(3, m_Inven, m_InvenLength) COLUMN_ENTRY_LENGTH(4, m_Extra, m_ExtraLength) END_COLUMN_MAP() }; class CGetUserItemDataEx : public CUserItemDataGet { public: typedef CCommand< CAccessor< CGetUserItemDataEx >, CRowset, CMultipleResults > Command; BEGIN_COLUMN_MAP(CGetUserItemDataEx) COLUMN_ENTRY(1, m_nCID) COLUMN_ENTRY_LENGTH(2, m_Exchange, m_ExchangeLength) END_COLUMN_MAP() }; class CSetUserItemData : public CUserItemDataSet { public: typedef CCommand< CAccessor< CSetUserItemData >, CNoRowset> Command; BEGIN_PARAM_MAP(CSetUserItemData) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY_LENGTH(1, m_Equip, m_EquipLength) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY_LENGTH(2, m_Inven, m_InvenLength) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY_LENGTH(3, m_Extra, m_ExtraLength) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY(4, m_nCID) END_PARAM_MAP() }; class CSetUserItemDataEx : public CUserItemDataSetEx { public: typedef CCommand< CAccessor< CSetUserItemDataEx >, CNoRowset > Command; BEGIN_PARAM_MAP(CSetUserItemDataEx) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY_LENGTH(1, m_Exchange, m_ExchangeLength); SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY(2, m_nCID) END_PARAM_MAP() }; class CGetStoreItemData : public CStoreItemData { public: typedef CCommand< CAccessor< CGetStoreItemData >, CRowset, CMultipleResults > Command; BEGIN_COLUMN_MAP(CGetStoreItemData) COLUMN_ENTRY(1, m_nUID) COLUMN_ENTRY_LENGTH(2, m_Store, m_StoreLength) END_COLUMN_MAP() }; class CSetStoreItemData : public CStoreItemData { public: typedef CCommand< CAccessor< CSetStoreItemData >, CNoRowset > Command; BEGIN_PARAM_MAP(CSetStoreItemData) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY_LENGTH(1, m_Store, m_StoreLength) SET_PARAM_TYPE(DBPARAMIO_INPUT) COLUMN_ENTRY(2, m_nUID) END_PARAM_MAP() }; void PrintUsage() { printf("Usage : ItemRebalanceConverter DBServerAddr DBName DBAccount DBPassword ServerGroupNum convertCharDelHistory(1/0) writeDB(1/0)"); } int ParseItemData(unsigned long dwUID, unsigned long dwCID, char* szItemData, unsigned long dwSize, char* szOutData, unsigned long& dwOutDataSize); bool CreateAdjustedItem(unsigned long dwUID, unsigned long dwCID, OldItem::ItemData* lpItemData, OldItem::EquipmentInfo* lpEquipmentInfo, unsigned char* lpSocketInfo, OldItem::ItemAttribute* lpAttribute, char* szOutData, unsigned long& dwRemainBufferSize_InOut); Item::Grade::GradeInfo GetGradeInfo(short* wNewAttribute, const int nMaxAttributeNum, const Item::ItemInfo& newItemInfo); const char* GetGradeString(Item::EquipType::Grade grade); #define ERROR_HRESULT_RETURN(ErrorMessage, hr, retVal) \ if(FAILED(hr)) { printf(ErrorMessage" : hr(0x%08x)", (hr)); return (retVal); } int ProcessCharItem(ATL::CSession& readSession, ATL::CSession& writeSession, bool bProcessDelHistory, bool bWriteDB); int ProcessCharItemEx(ATL::CSession& readSession, ATL::CSession& writeSession, bool bProcessDelHistory, bool bWriteDB); int ProcessStore(ATL::CSession& readSession, ATL::CSession& writeSession, int nStoreNum, bool bWriteDB); bool RewriteItemUID(ATL::CSession& writeSession, int nServerGroupNum); const int SHOW_NUM_PER_PROCESS = 1000; int g_GradeNum[Item::EquipType::MAX_GRADE] = { 0, }; unsigned __int64 g_UID = 0; const int MAX_SERVERZONE = 20; unsigned __int64 g_MaxUID[MAX_SERVERZONE] = { 0, }; CServerLog g_ItemLog("ItemLog.log"); int _tmain(int argc, _TCHAR* argv[]) { COMInitialize::GetInstance(); if(argc != 8) { PrintUsage(); return -1; } // ¾ÆÀÌÅÛ ½ºÅ©¸³Æ® Àбâ if(!Item::CItemMgr::GetInstance().LoadItemProtoType("./NewItemScript.txt")) { printf("NewItemScript load failed."); return -1; } // ¾ÆÀÌÅÛ ½ºÅ©¸³Æ® Àбâ if(!OldItem::CItemMgr::GetInstance().LoadItemProtoType("./OldItemScript.txt")) { printf("OldItemScript load failed."); return -1; } int nServerGroupNum = atoi(argv[5]); bool bWriteDB = (0 == strcmp("1", argv[7])); DETLOG0(g_Log, "DBQuery and convert start!"); printf("DBQuery and convert start!\n"); // DB Property ¼³Á¤. ATL::CDBPropSet dsPropSet[2]; dsPropSet[0].SetGUID(DBPROPSET_DBINIT); dsPropSet[0].AddProperty(DBPROP_INIT_DATASOURCE, argv[1]); dsPropSet[0].AddProperty(DBPROP_INIT_CATALOG, argv[2]); dsPropSet[0].AddProperty(DBPROP_AUTH_USERID, argv[3]); dsPropSet[0].AddProperty(DBPROP_AUTH_PASSWORD, argv[4]); dsPropSet[1].SetGUID(DBPROPSET_ROWSET); dsPropSet[1].AddProperty(DBPROP_UPDATABILITY, long(VARIANT_TRUE)); // µ¥ÀÌÅͺ£À̽º ¿ÀÇ ATL::CDataSource dataSource; HRESULT hr = dataSource.Open(CLSID_SQLOLEDB, dsPropSet, 2); ERROR_HRESULT_RETURN("DataSource1 open failed", hr, -1); // µ¥ÀÌÅͺ£À̽º Àб⠼¼¼Ç ¿­±â ATL::CSession readSession; hr = readSession.Open(dataSource); ERROR_HRESULT_RETURN("readSession open failed", hr, -1); // µ¥ÀÌÅͺ£À̽º ¾²±â ¼¼¼Ç ¿­±â ATL::CSession writeSession; hr = writeSession.Open(dataSource); ERROR_HRESULT_RETURN("writeSession open failed", hr, -1); #define LOG_CONVERT(str) DETLOG0(g_Log, (str)); printf(str "\n"); #define LOG_CONVERT1(str, arg1) DETLOG1(g_Log, (str), (arg1)); printf(str "\n", (arg1)); #define LOG_CONVERT2(str, arg1, arg2) DETLOG2(g_Log, (str), (arg1), (arg2)); printf(str "\n", (arg1), (arg2)); LOG_CONVERT("Convert CharItem Start."); ProcessCharItem(readSession, writeSession, false, bWriteDB); LOG_CONVERT("Convert CharItemEx Start."); ProcessCharItemEx(readSession, writeSession, false, bWriteDB); LOG_CONVERT("Convert Store1 Start."); ProcessStore(readSession, writeSession, 1, bWriteDB); LOG_CONVERT("Convert Store2 Start."); ProcessStore(readSession, writeSession, 2, bWriteDB); if(0 == strcmp("1", argv[6])) { LOG_CONVERT("Convert CharDelHistory..CharItem Start."); ProcessCharItem(readSession, writeSession, true, bWriteDB); LOG_CONVERT("Convert CharDelHistory..CharItemEx Start."); ProcessCharItemEx(readSession, writeSession, true, bWriteDB); } LOG_CONVERT1("Grade AAA : %10u", g_GradeNum[Item::EquipType::AAA_GRADE]); LOG_CONVERT1("Grade AA : %10u", g_GradeNum[Item::EquipType::AA_GRADE]); LOG_CONVERT1("Grade A : %10u", g_GradeNum[Item::EquipType::A_GRADE]); LOG_CONVERT1("Grade B : %10u", g_GradeNum[Item::EquipType::B_GRADE]); LOG_CONVERT1("Grade C : %10u", g_GradeNum[Item::EquipType::C_GRADE]); LOG_CONVERT1("Grade D : %10u", g_GradeNum[Item::EquipType::D_GRADE]); LOG_CONVERT1("Grade F : %10u", g_GradeNum[Item::EquipType::F_GRADE]); for(int nCount = 0; nCount < MAX_SERVERZONE; ++nCount) { if(0 != g_MaxUID[nCount]) { LOG_CONVERT2("ServerGroup : %d / Max Old UID : 0x%016I64X", nCount, g_MaxUID[nCount]); } } RewriteItemUID(writeSession, nServerGroupNum); LOG_CONVERT1("Max New UID : %I64u", g_UID); LOG_CONVERT("Convert Complete"); return 0; } bool RewriteItemUID(ATL::CSession& writeSession, int nServerGroupNum) { // ¾ÆÀÌÅÛ ½Ã¸®¾ó ÀüºÎ Áö¿ì°í, Àç±â·ÏÇϱâ. CCommand<> DelCmd; HRESULT hr = DelCmd.Open(writeSession, "Delete from ItemUID"); ERROR_HRESULT_RETURN("readSession open failed", hr, false); SERVER_ID serverID; serverID.sID.Type = CServerSetup::AuthServer; serverID.sID.Group = nServerGroupNum; serverID.sID.Channel = 0; serverID.sID.ID = 0; const int MAX_QUERY_LEN = 512; char szQuery[MAX_QUERY_LEN]; _snprintf(szQuery, MAX_QUERY_LEN - 1, "Insert into ItemUID values (0x%08x, 0x%0I64x)", serverID.dwID, g_UID); hr = DelCmd.Open(writeSession, szQuery); ERROR_HRESULT_RETURN("readSession open failed", hr, false); return true; } int ParseItemData(unsigned long dwUID, unsigned long dwCID, char* szItemData, unsigned long dwSize, char* szOutData, unsigned long& dwOutDataSize) { char* szItemDataPos = szItemData; char* szItemDataEnd = szItemData + dwSize; char* szOutDataPos = szOutData; char* szOutDataEnd = szOutData + dwOutDataSize; for(; szItemDataPos < szItemDataEnd && szOutDataPos < szOutDataEnd; szItemDataPos += reinterpret_cast(szItemDataPos)->m_cItemSize) { OldItem::ItemData* lpItemData = reinterpret_cast(szItemDataPos); if(sizeof(OldItem::ItemData) + sizeof(OldItem::EquipmentInfo) <= lpItemData->m_cItemSize) { // µÚ¿¡ Ãß°¡ Á¤º¸°¡ ÀÖÀ¸¹Ç·Î Àåºñ´Ù. ¿É¼ÇÀ» ¼öÁ¤ÇÑ ÈÄ º¹»çÇØ ÁØ´Ù. OldItem::EquipmentInfo* lpEquipmentInfo = reinterpret_cast( szItemDataPos + sizeof(OldItem::ItemData)); unsigned char* lpSocketInfo = reinterpret_cast(lpEquipmentInfo + 1); OldItem::ItemAttribute* lpAttribute = reinterpret_cast( lpSocketInfo + lpEquipmentInfo->m_cSocketNum); unsigned long dwDataSize = static_cast(szOutDataEnd - szOutDataPos); if(0 == lpEquipmentInfo->m_cReserved) { if(CreateAdjustedItem(dwUID, dwCID, lpItemData, lpEquipmentInfo, lpSocketInfo, lpAttribute, szOutDataPos, dwDataSize)) { szOutDataPos += dwDataSize; } else { // ¹º°¡ ±æÀ̰¡ ÀÌ»óÇÑ ¾ÆÀÌÅÛÀÌ´Ù. DETLOG5(g_Log, "Item recreation failed.\tUID:%10u\tCID:%10u\tItemUID:0x%016I64X\tPrototypeID:%5u\tItemSize:%3u\t", dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_usProtoTypeID, lpItemData->m_cItemSize); } } else { // ÀÌ¹Ì ¸®¹ë·±½ÌµÈ ¾ÆÀÌÅÛÀÌ´Ù. DETLOG5(g_Log, "ÀÌ¹Ì ¸®¹ë·±½ÌµÈ ¾ÆÀÌÅÛÀÔ´Ï´Ù\tUID:%10u\tCID:%10u\tItemUID:0x%016I64X\tPrototypeID:%5u\tItemSize:%3u\t", dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_usProtoTypeID, lpItemData->m_cItemSize); memcpy(szOutDataPos, lpItemData, lpItemData->m_cItemSize); szOutDataPos += lpItemData->m_cItemSize; } } else if(lpItemData->m_cItemSize == sizeof(OldItem::ItemData)) { // Àåºñ°¡ ¾Æ´Ñ ÀâÅÛÀÌ´Ù. ±×³É º¹»çÇØ ÁØ´Ù. memcpy(szOutDataPos, lpItemData, lpItemData->m_cItemSize); szOutDataPos += lpItemData->m_cItemSize; } else { DETLOG5(g_Log, "Item length is invalid. UID:%10u/CID:%10u/ItemUID:0x%016I64X/PrototypeID:%5u/ItemSize:%3u", dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_usProtoTypeID, lpItemData->m_cItemSize); } } dwOutDataSize = static_cast(szOutDataPos - szOutData); return 0; } bool CreateAdjustedItem(unsigned long dwUID, unsigned long dwCID, OldItem::ItemData* lpItemData, OldItem::EquipmentInfo* lpEquipmentInfo, unsigned char* lpSocketInfo, OldItem::ItemAttribute* lpAttribute, char* szOutData, unsigned long& dwRemainBufferSize_InOut) { const int MAX_ATTR_NUM = 7; const OldItem::ItemInfo* lpOldItemInfo = OldItem::CItemMgr::GetInstance().GetItemInfo(lpItemData->m_usProtoTypeID); const Item::ItemInfo* lpNewItemInfo = Item::CItemMgr::GetInstance().GetItemInfo(lpItemData->m_usProtoTypeID); if(0 == lpNewItemInfo || 0 == lpOldItemInfo) { DETLOG3(g_Log, "Script has not this item.\tUID:%10u\tCID:%10u\tPrototypeID:%5u\t", dwUID, dwCID, lpItemData->m_usProtoTypeID); return false; } if(sizeof(OldItem::ItemData) + sizeof(OldItem::EquipmentInfo) + sizeof(OldItem::ItemAttribute) * MAX_ATTR_NUM < dwRemainBufferSize_InOut) { char* szOutDataPos = szOutData; unsigned char cItemType = lpOldItemInfo->m_DetailData.m_cItemType; unsigned short wDropOption = lpNewItemInfo->m_DetailData.m_wDropOption; unsigned char cMaxDurablility = lpEquipmentInfo->m_cDiffMaxDurability + lpOldItemInfo->m_DetailData.m_cDefaultDurabilityOrStack; if(150 < cMaxDurablility) { const int MAX_BUFFER = 1024; char szBuffer[MAX_BUFFER]; int nTotalLength = _snprintf(szBuffer, MAX_BUFFER - 1, "Item durability is invalid.\tUID:%10u\tCID:%10u\tItemUID:0x%016I64X\tItemSize:%3u\tPrototypeID:%5u\tItemType:%20s\tDurability:%d\t", dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_cItemSize, lpItemData->m_usProtoTypeID, OldItem::CItemType::GetInstance().GetItemTypeName()[cItemType].GetTypeName(), cMaxDurablility); DETLOG0(g_Log, szBuffer); cMaxDurablility = 150; } lpEquipmentInfo->m_cDiffMaxDurability = cMaxDurablility - lpOldItemInfo->m_DetailData.m_cDefaultDurabilityOrStack; // ÀÏ´Ü ±âº» µ¥ÀÌÅÍ ºÎºÐÀº ±×³É º¹»çÇÑ´Ù. memcpy(szOutDataPos, lpItemData, sizeof(OldItem::ItemData)); unsigned __int64 nNewItemSerial = ++g_UID; INFLOG4(g_ItemLog, "UID:%10u / CID:%10u / OldItemSerial:0x%0I64X / NewItemSerial:0x%0I64X / ¾ÆÀÌÅÛ ½Ã¸®¾ó º¯°æ", dwUID, dwCID, reinterpret_cast(szOutDataPos)->m_dwUID, nNewItemSerial); reinterpret_cast(szOutDataPos)->m_dwUID = nNewItemSerial; szOutDataPos += sizeof(OldItem::ItemData); int nIndex = static_cast(lpItemData->m_dwUID >> 56); if(nIndex < MAX_SERVERZONE) { if(g_MaxUID[nIndex] < lpItemData->m_dwUID) { g_MaxUID[nIndex] = lpItemData->m_dwUID; } } else { ERRLOG3(g_Log, "Invalid ItemUID : 0x%0I64X / UID:%10d / CID :%10d", lpItemData->m_dwUID, dwUID, dwCID); } lpEquipmentInfo->m_cReserved = 0; COPY_AND_ADVANCE_DST(szOutDataPos, lpEquipmentInfo, sizeof(OldItem::EquipmentInfo)); // ÀÌÁ¦ ¼ÒÄÏ ºÎºÐÀ» º¹»çÇÒ Â÷·ÊÀÌ´Ù. if(0 < lpEquipmentInfo->m_cSocketNum) { // ¼ÒÄÏÀÌ ÀÖÀ¸¸é ¼ÒÄÏÀ» º¹»ç. COPY_AND_ADVANCE_DST(szOutDataPos, lpSocketInfo, sizeof(unsigned char) * lpEquipmentInfo->m_cSocketNum); } // ÀÌÁ¦ ¾ÆÀÌÅÛ ¼Ó¼ºÀ» Áö´ë·Î º¹»çÇÒ Â÷·ÊÀε¥.. // 1. ¾ÆÀÌÅÛ ¼Ó¼º°ªÀ» ¹è¿­¿¡ ´ã´Â´Ù. // 2. ¾÷±×·¹ÀÌµå ¼Ó¼º°ªÀ» Àû¿ëÇÑ´Ù. // 3. Gem¼Ó¼º°ªÀ» Àû¿ëÇÑ´Ù. // 4. ¾ÆÀÌÅÛ Å¸ÀÔº°·Î, À§¿¡¼­ºÎÅÍ Á× ÅyÀ¸¸é¼­ Àû¿ëÇÒ ¼Ó¼º°ª¸¸ °É·¯¼­, °ªÀ» °è»êÇÑ ÈÄ º¹»çÇÑ´Ù. short wAttributeValue[OldItem::Attribute::MAX_ATTRIBUTE_NUM]; short wNewAttributeValue[Item::Attribute::MAX_ATTRIBUTE_NUM]; std::fill_n(wAttributeValue, unsigned short(OldItem::Attribute::MAX_ATTRIBUTE_NUM), 0); std::fill_n(wNewAttributeValue, unsigned short(Item::Attribute::MAX_ATTRIBUTE_NUM), 0); // ¾ÆÀÌÅÛ ¼Ó¼º°ª ¹è¿­¿¡ ´ã±â. OldItem::ItemAttribute* lpAttributePos = lpAttribute; OldItem::ItemAttribute* lpAttributeEnd = lpAttribute + lpEquipmentInfo->m_cAttributeNum; for(; lpAttributePos != lpAttributeEnd; ++lpAttributePos) { if(0 != lpAttributePos->m_cType && lpAttributePos->m_cType < OldItem::Attribute::MAX_ATTRIBUTE_NUM) { wAttributeValue[lpAttributePos->m_cType] += lpAttributePos->m_usValue; } } // ¾÷±×·¹ÀÌµå ¼Ó¼º°ª ¾ò¾î¿Í¼­ ´õÇϱâ. if(0 < lpEquipmentInfo->m_cDiffMaterialType) { OldItem::ItemAttribute attrUpgrade[OldItem::EquipmentInfo::MAX_UPGRADE_ATTRIBUTE]; memset(&attrUpgrade, 0, sizeof(OldItem::ItemAttribute) * OldItem::EquipmentInfo::MAX_UPGRADE_ATTRIBUTE); OldItem::CItemType::GetUpgradeItemAttribute(static_cast(cItemType), attrUpgrade, lpEquipmentInfo->m_cDiffMaterialType, OldItem::EquipmentInfo::MAX_UPGRADE_ATTRIBUTE); lpAttributePos = attrUpgrade; lpAttributeEnd = attrUpgrade + OldItem::EquipmentInfo::MAX_UPGRADE_ATTRIBUTE; for(; lpAttributePos != lpAttributeEnd; ++lpAttributePos) { if(0 != lpAttributePos->m_cType && lpAttributePos->m_cType < OldItem::Attribute::MAX_ATTRIBUTE_NUM) { wAttributeValue[lpAttributePos->m_cType] += lpAttributePos->m_usValue; } } } // ¼ÒÄÏ ¼Ó¼º°ª ¾ò¾î¿Í¼­ ´õÇϱâ. if(0 < lpEquipmentInfo->m_cSocketNum) { OldItem::ItemAttribute attrGems[OldItem::EquipmentInfo::MAX_SOCKET_ATTRIBUTE_NUM]; memset(&attrGems, 0, sizeof(OldItem::ItemAttribute) * OldItem::EquipmentInfo::MAX_SOCKET_ATTRIBUTE_NUM); OldItem::CItemType::GetInstallGemAttribute(lpSocketInfo, attrGems, static_cast(cItemType), lpEquipmentInfo->m_cSocketNum, OldItem::EquipmentInfo::MAX_SOCKET_ATTRIBUTE_NUM); lpAttributePos = attrGems; lpAttributeEnd = attrGems + OldItem::EquipmentInfo::MAX_SOCKET_ATTRIBUTE_NUM; for(; lpAttributePos != lpAttributeEnd; ++lpAttributePos) { if(0 != lpAttributePos->m_cType && lpAttributePos->m_cType < OldItem::Attribute::MAX_ATTRIBUTE_NUM) { wAttributeValue[lpAttributePos->m_cType] += lpAttributePos->m_usValue; } } } #define CHECK_ATTR(nOverflowIndex, MaxValue, Value, nIndex) \ if((MaxValue) < (Value[nIndex])) { (Value[nIndex]) = (MaxValue); (nOverflowIndex) = (nIndex); } bool bInvalidMaxValue = false; bool bInvalidUnknownAttr = false; int nOverflowIndex = OldItem::Attribute::MAX_ATTRIBUTE_NUM; short wInvalidAttribute[OldItem::Attribute::MAX_ATTRIBUTE_NUM]; std::copy(wAttributeValue, wAttributeValue + OldItem::Attribute::MAX_ATTRIBUTE_NUM, wInvalidAttribute); short wOldAttributeValue[OldItem::Attribute::MAX_ATTRIBUTE_NUM]; std::copy(wAttributeValue, wAttributeValue + OldItem::Attribute::MAX_ATTRIBUTE_NUM, wOldAttributeValue); // ÀÌÁ¦, ¾ÆÀÌÅÛ Å¸ÀÔº°·Î °ñ¶ó¼­ º¹»çÇÒ Â÷·Ê°¡ ¿Ô´Ù. switch(lpNewItemInfo->m_DetailData.m_cItemType) { case Item::ItemType::CON_ARMOUR: case Item::ItemType::CON_BODY: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñ ÃÖ´ë°ª. ¹æ¾î·Â ¹æ¾î·Â ±¸ ¹æ¾î·Â * 2.6 72 ¹æ¾îº¸Á¤ ȸÇÇ ±¸ ¹æ¾îº¸Á¤ * 0.7 58 HP Max HP Max ±¸ HP Max * 0.6 54 MP Max HP ȸº¹ ±¸ MP Max * 1.2 69 ÀúÇ×·Â ¸¶¹ýÀúÇ× ±¸ ÀúÇ×·Â * 0.32 + ±¸ ºí·Ï * 0.32 30 ºí·Ï 11 */ CHECK_ATTR(nOverflowIndex, 72, wAttributeValue, OldItem::Attribute::DEFENCE); CHECK_ATTR(nOverflowIndex, 58, wAttributeValue, OldItem::Attribute::DEFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 54, wAttributeValue, OldItem::Attribute::MAX_HP); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::MAX_MP); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MAGIC_RESISTANCE); CHECK_ATTR(nOverflowIndex, 11, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); wNewAttributeValue[Item::Attribute::ARMOR] = static_cast(wAttributeValue[OldItem::Attribute::DEFENCE] * 2.6f); wNewAttributeValue[Item::Attribute::EVADE] = static_cast(wAttributeValue[OldItem::Attribute::DEFENCE_REVISION] * 0.7f); wNewAttributeValue[Item::Attribute::MAX_HP] = static_cast(wAttributeValue[OldItem::Attribute::MAX_HP] * 0.6f); wNewAttributeValue[Item::Attribute::HP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MAX_MP] * 1.2f); wNewAttributeValue[Item::Attribute::MAGIC_RESIST] = static_cast(wAttributeValue[OldItem::Attribute::MAGIC_RESISTANCE] * 0.32f + wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 0.32f); wInvalidAttribute[OldItem::Attribute::DEFENCE] = 0; wInvalidAttribute[OldItem::Attribute::DEFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::MAX_HP] = 0; wInvalidAttribute[OldItem::Attribute::MAX_MP] = 0; wInvalidAttribute[OldItem::Attribute::MAGIC_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; break; case Item::ItemType::DEX_ARMOUR: case Item::ItemType::DEX_BODY: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñ ÃÖ´ë°ª. ¹æ¾î·Â ¹æ¾î·Â ±¸ ¹æ¾î·Â * 2.6 72 ¹æ¾îº¸Á¤ ȸÇÇ ±¸ ¹æ¾îº¸Á¤ * 0.7 58 HP Max HP Max ±¸ HP Max * 0.6 54 MP Max HP ȸº¹ ±¸ MP Max * 1.2 69 ÀúÇ×·Â ¸¶¹ýÀúÇ× ±¸ ÀúÇ×·Â * 0.32 + ±¸ ºí·Ï * 0.32 30 ºí·Ï 11 */ CHECK_ATTR(nOverflowIndex, 72, wAttributeValue, OldItem::Attribute::DEFENCE); CHECK_ATTR(nOverflowIndex, 58, wAttributeValue, OldItem::Attribute::DEFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 54, wAttributeValue, OldItem::Attribute::MAX_HP); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::MAX_MP); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MAGIC_RESISTANCE); CHECK_ATTR(nOverflowIndex, 11, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); wNewAttributeValue[Item::Attribute::ARMOR] = static_cast(wAttributeValue[OldItem::Attribute::DEFENCE] * 2.6f); wNewAttributeValue[Item::Attribute::EVADE] = static_cast(wAttributeValue[OldItem::Attribute::DEFENCE_REVISION] * 0.7f); wNewAttributeValue[Item::Attribute::MAX_HP] = static_cast(wAttributeValue[OldItem::Attribute::MAX_HP] * 0.6f); wNewAttributeValue[Item::Attribute::HP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MAX_MP] * 1.2f); wNewAttributeValue[Item::Attribute::MAGIC_RESIST] = static_cast(wAttributeValue[OldItem::Attribute::MAGIC_RESISTANCE] * 0.32f + wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 0.32f); wInvalidAttribute[OldItem::Attribute::DEFENCE] = 0; wInvalidAttribute[OldItem::Attribute::DEFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::MAX_HP] = 0; wInvalidAttribute[OldItem::Attribute::MAX_MP] = 0; wInvalidAttribute[OldItem::Attribute::MAGIC_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; break; case Item::ItemType::CON_HELM: case Item::ItemType::CON_HEAD: case Item::ItemType::DEX_HELM: case Item::ItemType::DEX_HEAD: /* ±¸Ç׸ñ ½ÅÇ׸ñ º¯°æ±ÔÄ¢ ±¸Ç׸ñ ÃÖ´ë°ª ¹æ¾î·Â DropOption * 0.9 0 ȸÇÇ DropOption * 0.225 0 HP ȸº¹ HP Max ±¸ HP Max * 0.6 39 MP ȸº¹ HP ȸº¹ ±¸ MP Max * 1.2 39 ÀúÇ×·Â ¸¶¹ýÀúÇ× ±¸ ÀúÇ×·Â * 0.5 22 */ CHECK_ATTR(nOverflowIndex, 39, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 39, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 22, wAttributeValue, OldItem::Attribute::MAGIC_RESISTANCE); wNewAttributeValue[Item::Attribute::ARMOR] = static_cast(wDropOption * 0.9); wNewAttributeValue[Item::Attribute::EVADE] = static_cast(wDropOption * 0.225); wNewAttributeValue[Item::Attribute::MAX_HP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6); wNewAttributeValue[Item::Attribute::HP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2); wNewAttributeValue[Item::Attribute::MAGIC_RESIST] = static_cast(wAttributeValue[OldItem::Attribute::MAGIC_RESISTANCE] * 0.5); wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MAGIC_RESISTANCE] = 0; break; case Item::ItemType::DAGGER: case Item::ItemType::OPP_TALON: /* ±¸Ç׸ñ ½ÅÇ׸ñ º¯°æ±ÔÄ¢ ±¸Ç׸ñ ÃÖ´ë°ª mDmg mDmg ±¸ mDmg * 2.2 43 MDmg MDmg ±¸ MDmg * 1.6 64 °ø°Ýº¸Á¤ ¸íÁß ±¸ °ø°Ýº¸Á¤ * 3.8 43 HP ȸº¹ MPMax ±¸ HP ȸº¹ * 0.6 30 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 1.2 30 ºí·Ï ºí·Ï ±¸ ºí·Ï * 1.2 10 Å©¸®Æ¼Äà ũ¸®Æ¼Äà ±¸ Å©¸®Æ¼Äà * 1 20 */ CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::MIN_DAMAGE); CHECK_ATTR(nOverflowIndex, 64, wAttributeValue, OldItem::Attribute::MAX_DAMAGE); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::OFFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 10, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 20, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MIN_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MIN_DAMAGE] * 2.2f); wNewAttributeValue[Item::Attribute::MAX_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MAX_DAMAGE] * 1.6f); wNewAttributeValue[Item::Attribute::HIT_RATE] = static_cast(wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 3.8f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast(wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1.2f); wNewAttributeValue[Item::Attribute::CRITICAL] = wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 1; wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::OFFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; break; case Item::ItemType::SKILL_A_KNIFE: /* ±¸Ç׸ñ ½ÅÇ׸ñ º¯°æ±ÔÄ¢ ±¸Ç׸ñ ÃÖ´ë°ª mDmg mDmg ±¸ mDmg * 2.2 43 MDmg MDmg ±¸ MDmg * 1.6 64 °ø°Ýº¸Á¤ ¸íÁß ±¸ °ø°Ýº¸Á¤ * 1.9 + ±¸ ¹æ¾îº¸Á¤ * 1.9 43 ¹æ¾îº¸Á¤ 43 HP ȸº¹ MPMax ±¸ HP ȸº¹ * 0.6 69 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 1.2 69 ÀúÇ×·Â ºí·Ï ±¸ ÀúÇ×·Â * 0.2 + ±¸ ºí·Ï * 1 8 ºí·Ï ºí·Ï 10 Å©¸®Æ¼Äà ũ¸®Æ¼Äà ±¸ Å©¸®Æ¼Äà * 1 20 */ CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::MIN_DAMAGE); CHECK_ATTR(nOverflowIndex, 64, wAttributeValue, OldItem::Attribute::MAX_DAMAGE); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::OFFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::DEFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 8, wAttributeValue, OldItem::Attribute::MAGIC_RESISTANCE); CHECK_ATTR(nOverflowIndex, 10, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 20, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MIN_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MIN_DAMAGE] * 2.2f); wNewAttributeValue[Item::Attribute::MAX_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MAX_DAMAGE] * 1.6f); wNewAttributeValue[Item::Attribute::HIT_RATE] = static_cast(wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 1.9f + wAttributeValue[OldItem::Attribute::DEFENCE_REVISION] * 1.9f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast( wAttributeValue[OldItem::Attribute::MAGIC_RESISTANCE] * 0.2f + wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1.0f); wNewAttributeValue[Item::Attribute::CRITICAL] = wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 1; wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::OFFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::DEFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MAGIC_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; break; case Item::ItemType::ONEHANDED_SWORD: case Item::ItemType::ONEHANDED_AXE: case Item::ItemType::ONEHANDED_BLUNT: case Item::ItemType::COM_BLUNT: case Item::ItemType::COM_SWORD: case Item::ItemType::OPP_HAMMER: case Item::ItemType::OPP_AXE: case Item::ItemType::OPP_SLUSHER: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñÃÖ´ë°ª mDmg mDmg ±¸ mDmg * 3.2 43 MDmg MDmg ±¸ MDmg * 1.8 64 °ø°Ýº¸Á¤ ¸íÁß ±¸ °ø°Ýº¸Á¤ * 3.8 43 HP ȸº¹ MPMax ±¸ HP ȸº¹ * 0.6 + DropOption * 0.15 30 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 1.2 + DropOption * 0.15 30 ºí·Ï ºí·Ï ±¸ ºí·Ï * 1.2 10 Å©¸®Æ¼Äà ũ¸®Æ¼Äà ±¸ Å©¸®Æ¼Äà * 1 20 */ CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::MIN_DAMAGE); CHECK_ATTR(nOverflowIndex, 64, wAttributeValue, OldItem::Attribute::MAX_DAMAGE); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::OFFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 10, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 20, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MIN_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MIN_DAMAGE] * 3.2); wNewAttributeValue[Item::Attribute::MAX_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MAX_DAMAGE] * 1.8f); wNewAttributeValue[Item::Attribute::HIT_RATE] = static_cast(wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 3.8f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6f + wDropOption * 0.15f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2f + wDropOption * 0.15f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast(wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1.2f); wNewAttributeValue[Item::Attribute::CRITICAL] = wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 1; wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::OFFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; break; case Item::ItemType::BOW: case Item::ItemType::CROSSBOW: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñÃÖ´ë°ª mDmg mDmg ±¸ mDmg * 3.2 43 MDmg MDmg ±¸ MDmg * 1.8 64 °ø°Ýº¸Á¤ ¸íÁß ±¸ °ø°Ýº¸Á¤ * 3.8 43 HP ȸº¹ MPMax ±¸ HP ȸº¹ * 0.6 + DropOption * 0.15 30 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 1.2 + DropOption * 0.15 30 ºí·Ï ºí·Ï ±¸ ºí·Ï * 1.2 10 Å©¸®Æ¼Äà ũ¸®Æ¼Äà ±¸ Å©¸®Æ¼Äà * 1 20 */ CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::MIN_DAMAGE); CHECK_ATTR(nOverflowIndex, 64, wAttributeValue, OldItem::Attribute::MAX_DAMAGE); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::OFFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 10, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 20, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MIN_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MIN_DAMAGE] * 3.2f); wNewAttributeValue[Item::Attribute::MAX_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MAX_DAMAGE] * 1.8f); wNewAttributeValue[Item::Attribute::HIT_RATE] = static_cast(wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 3.8f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6f + wDropOption * 0.15f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2f + wDropOption * 0.15f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast(wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1.2f); wNewAttributeValue[Item::Attribute::CRITICAL] = wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 1; wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::OFFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; break; case Item::ItemType::SKILL_A_ATTACK: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñÃÖ´ë°ª mDmg mDmg ±¸ mDmg * 3.2 43 MDmg MDmg ±¸ MDmg * 1.8 64 °ø°Ýº¸Á¤ ¸íÁß ±¸ °ø°Ýº¸Á¤ * 1.9 + ±¸ ¹æ¾îº¸Á¤ * 1.9 43 ¹æ¾îº¸Á¤ 43 HP ȸº¹ MPMax ±¸ HP ȸº¹ * 0.6 69 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 1.2 69 ºí·Ï ºí·Ï ±¸ ÀúÇ×·Â * 0.2 + ±¸ ºí·Ï * 1 10 ÀúÇ×·Â 30 Å©¸®Æ¼Äà ũ¸®Æ¼Äà ±¸ Å©¸®Æ¼Äà * 1 20 */ CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::MIN_DAMAGE); CHECK_ATTR(nOverflowIndex, 64, wAttributeValue, OldItem::Attribute::MAX_DAMAGE); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::OFFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::DEFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 10, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MAGIC_RESISTANCE); CHECK_ATTR(nOverflowIndex, 20, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MIN_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MIN_DAMAGE] * 3.2f); wNewAttributeValue[Item::Attribute::MAX_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MAX_DAMAGE] * 1.8f); wNewAttributeValue[Item::Attribute::HIT_RATE] = static_cast(wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 1.9f + wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 1.9f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast( wAttributeValue[OldItem::Attribute::MAGIC_RESISTANCE] * 0.2f + wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1); wNewAttributeValue[Item::Attribute::CRITICAL] = wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 1; wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::OFFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::DEFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAGIC_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; break; case Item::ItemType::SKILL_A_GUN: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñÃÖ´ë°ª mDmg mDmg ±¸ mDmg * 3.2 43 MDmg MDmg ±¸ MDmg * 1.8 64 °ø°Ýº¸Á¤ ¸íÁß ±¸ °ø°Ýº¸Á¤ * 1.9 + ±¸ ¹æ¾îº¸Á¤ * 1.9 43 ¹æ¾îº¸Á¤ 43 HP ȸº¹ MPMax ±¸ HP ȸº¹ * 0.6 69 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 1.2 69 ºí·Ï ºí·Ï ±¸ ÀúÇ×·Â * 0.2 + ±¸ ºí·Ï * 1 10 ÀúÇ×·Â 30 Å©¸®Æ¼Äà ũ¸®Æ¼Äà ±¸ Å©¸®Æ¼Äà * 1 20 */ CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::MIN_DAMAGE); CHECK_ATTR(nOverflowIndex, 64, wAttributeValue, OldItem::Attribute::MAX_DAMAGE); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::OFFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::DEFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 10, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MAGIC_RESISTANCE); CHECK_ATTR(nOverflowIndex, 20, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MIN_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MIN_DAMAGE] * 3.2f); wNewAttributeValue[Item::Attribute::MAX_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MAX_DAMAGE] * 1.8f); wNewAttributeValue[Item::Attribute::HIT_RATE] = static_cast(wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 1.9f + wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 1.9f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast( wAttributeValue[OldItem::Attribute::MAGIC_RESISTANCE] * 0.2f + wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1); wNewAttributeValue[Item::Attribute::CRITICAL] = wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 1; wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::OFFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::DEFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAGIC_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; break; case Item::ItemType::TWOHANDED_SWORD: case Item::ItemType::TWOHANDED_AXE: case Item::ItemType::TWOHANDED_BLUNT: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñÃÖ´ë°ª mDmg mDmg ±¸ mDmg * 2.8 43 MDmg MDmg ±¸ MDmg * 3.0 64 °ø°Ýº¸Á¤ ¸íÁß ±¸ °ø°Ýº¸Á¤ * 3.8 43 HP ȸº¹ MPMax ±¸ HP ȸº¹ * 0.6 + DropOption * 0.15 30 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 1.2 + DropOption * 0.15 30 ºí·Ï ºí·Ï ±¸ ºí·Ï * 1.2 10 Å©¸®Æ¼Äà ũ¸®Æ¼Äà ±¸ Å©¸®Æ¼Äà * 1 20 */ CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::MIN_DAMAGE); CHECK_ATTR(nOverflowIndex, 64, wAttributeValue, OldItem::Attribute::MAX_DAMAGE); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::OFFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 10, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 20, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MIN_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MIN_DAMAGE] * 2.8); wNewAttributeValue[Item::Attribute::MAX_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MAX_DAMAGE] * 3.0); wNewAttributeValue[Item::Attribute::HIT_RATE] = static_cast(wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 3.8f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6f + wDropOption * 0.15f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2f + wDropOption * 0.15f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast(wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1.2f); wNewAttributeValue[Item::Attribute::CRITICAL] = wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 1; wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::OFFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; break; case Item::ItemType::STAFF: case Item::ItemType::OPP_SYTHE: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñÃÖ´ë°ª mDmg ¸¶¹ý·Â ±¸ mDmg * 8 43 MDmg MDmg ±¸ MDmg * 3.0 64 °ø°Ýº¸Á¤ ¸íÁß ±¸ °ø°Ýº¸Á¤ * 3.8 43 HP ȸº¹ MPMax ±¸ HP ȸº¹ * 0.6 + DropOption * 0.3 45 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 1.2 + DropOption * 0.3 45 ºí·Ï ºí·Ï ±¸ ºí·Ï * 1.2 10 Å©¸®Æ¼Äà ũ¸®Æ¼Äà ±¸ Å©¸®Æ¼Äà * 1 20 */ CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::MIN_DAMAGE); CHECK_ATTR(nOverflowIndex, 64, wAttributeValue, OldItem::Attribute::MAX_DAMAGE); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::OFFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 45, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 45, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 10, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 20, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MAGIC_POWER] = wAttributeValue[OldItem::Attribute::MIN_DAMAGE] * 8; wNewAttributeValue[Item::Attribute::MAX_DAMAGE] = static_cast(wAttributeValue[OldItem::Attribute::MAX_DAMAGE] * 3.0f); wNewAttributeValue[Item::Attribute::HIT_RATE] = static_cast(wAttributeValue[OldItem::Attribute::OFFENCE_REVISION] * 3.8f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.6f + wDropOption * 0.3f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 1.2f + wDropOption * 0.3f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast(wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1.2f); wNewAttributeValue[Item::Attribute::CRITICAL] = wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 1; wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::OFFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; // ¹«½¬! wInvalidAttribute[OldItem::Attribute::MAX_MP] = 0; break; case Item::ItemType::SHIELD: case Item::ItemType::SKILL_A_GUARD: /* ±¸Ç׸ñ ½ÅÇ׸ñ °è»ê½Ä ±¸Ç׸ñÃÖ´ë°ª ¹æ¾î·Â HPMax ±¸ ¹æ¾î·Â * 0.1 22 HP ȸº¹ HPȸº¹ ±¸ HP ȸº¹ * 0.1 69 ¹æ¾îº¸Á¤ MPMax ±¸ ¹æ¾îº¸Á¤ * 0.1 43 MP ȸº¹ MPȸº¹ ±¸ MP ȸº¹ * 0.1 69 ºí·Ï ºí·Ï ±¸ ºí·Ï * 1 + ±¸ ¸¶¹ý ÀúÇ× * 0.2 + ±¸ Å©¸®Æ¼Äà * 0.2 36 ÀúÇ×·Â 30 Å©¸®Æ¼Äà 15 */ CHECK_ATTR(nOverflowIndex, 22, wAttributeValue, OldItem::Attribute::DEFENCE); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::HP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 43, wAttributeValue, OldItem::Attribute::DEFENCE_REVISION); CHECK_ATTR(nOverflowIndex, 69, wAttributeValue, OldItem::Attribute::MP_REGEN_AMOUNT); CHECK_ATTR(nOverflowIndex, 36, wAttributeValue, OldItem::Attribute::BLOCKING_PERCENTAGE); CHECK_ATTR(nOverflowIndex, 30, wAttributeValue, OldItem::Attribute::MAGIC_RESISTANCE); CHECK_ATTR(nOverflowIndex, 22, wAttributeValue, OldItem::Attribute::CRITICAL_PERCENTAGE); wNewAttributeValue[Item::Attribute::MAX_HP] = static_cast(wAttributeValue[OldItem::Attribute::DEFENCE] * 0.1f); wNewAttributeValue[Item::Attribute::HP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::HP_REGEN_AMOUNT] * 0.1f); wNewAttributeValue[Item::Attribute::MAX_MP] = static_cast(wAttributeValue[OldItem::Attribute::DEFENCE_REVISION] * 0.1f); wNewAttributeValue[Item::Attribute::MP_REGEN] = static_cast(wAttributeValue[OldItem::Attribute::MP_REGEN_AMOUNT] * 0.1f); wNewAttributeValue[Item::Attribute::BLOCK] = static_cast(wAttributeValue[OldItem::Attribute::BLOCKING_PERCENTAGE] * 1.0f + wAttributeValue[OldItem::Attribute::MAGIC_RESISTANCE] * 0.2f + wAttributeValue[OldItem::Attribute::CRITICAL_PERCENTAGE] * 0.2f); // ¹«½¬! wInvalidAttribute[OldItem::Attribute::MIN_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAX_DAMAGE] = 0; wInvalidAttribute[OldItem::Attribute::DEFENCE] = 0; wInvalidAttribute[OldItem::Attribute::DEFENCE_REVISION] = 0; wInvalidAttribute[OldItem::Attribute::HP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::MP_REGEN_AMOUNT] = 0; wInvalidAttribute[OldItem::Attribute::BLOCKING_PERCENTAGE] = 0; wInvalidAttribute[OldItem::Attribute::MAGIC_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::CRITICAL_PERCENTAGE] = 0; break; } // wNewAttributeValue¸¦ 0ÀÌ ¾Æ´Ñ Ç׸ñ¸¸ °ñ¶ó¼­ szOutDataPos¿¡ ÀúÀåÇÑ´Ù. short* lpNewAttributeValuePos = wNewAttributeValue; short* lpNewAttributeValueEnd = wNewAttributeValue + Item::Attribute::MAX_ATTRIBUTE_NUM; for(int nAttrPos = 0; lpNewAttributeValuePos != lpNewAttributeValueEnd; ++lpNewAttributeValuePos, ++nAttrPos) { if(*lpNewAttributeValuePos < 0) { *lpNewAttributeValuePos = 0; } else if(0 < *lpNewAttributeValuePos) { Item::ItemAttribute itemAttribute; itemAttribute.m_cType = nAttrPos; itemAttribute.m_usValue = *lpNewAttributeValuePos; COPY_AND_ADVANCE_DST(szOutDataPos, &itemAttribute, sizeof(Item::ItemAttribute)); } } wInvalidAttribute[OldItem::Attribute::ATTACK_RANGE] = 0; wInvalidAttribute[OldItem::Attribute::FIRE_ATTACK] = 0; wInvalidAttribute[OldItem::Attribute::LIGHTNING_ATTACK] = 0; wInvalidAttribute[OldItem::Attribute::COLD_ATTACK] = 0; wInvalidAttribute[OldItem::Attribute::DRAIN_ATTACK] = 0; wInvalidAttribute[OldItem::Attribute::POISON_ATTACK] = 0; wInvalidAttribute[OldItem::Attribute::FIRE_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::LIGHTNING_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::COLD_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::DRAIN_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::POISON_RESISTANCE] = 0; wInvalidAttribute[OldItem::Attribute::ADD_STR] = 0; wInvalidAttribute[OldItem::Attribute::ADD_DEX] = 0; wInvalidAttribute[OldItem::Attribute::ADD_CON] = 0; wInvalidAttribute[OldItem::Attribute::ADD_INT] = 0; wInvalidAttribute[OldItem::Attribute::ADD_WIS] = 0; if(nOverflowIndex == OldItem::Attribute::MAX_ATTRIBUTE_NUM) { for(nOverflowIndex = 0; nOverflowIndex < OldItem::Attribute::MAX_ATTRIBUTE_NUM; ++nOverflowIndex) { if(0 != wInvalidAttribute[nOverflowIndex]) { break; } } } Item::Grade::GradeInfo gradeInfo = GetGradeInfo(wNewAttributeValue, Item::Attribute::MAX_ATTRIBUTE_NUM, *lpNewItemInfo); ++g_GradeNum[gradeInfo.m_eItemGrade]; if(gradeInfo.m_eItemGrade <= Item::EquipType::B_GRADE) { const int MAX_BUFFER = 1024; char szBuffer[MAX_BUFFER]; int nTotalLength = _snprintf(szBuffer, MAX_BUFFER - 1, "ItemGrade is %s.\tUID:%10u\tCID:%10u\tItemUID:0x%016I64X\tItemSize:%3u\tPrototypeID:%5u\t" "\tItemName:%20s\t%d\tItemType:%20s\t", GetGradeString(gradeInfo.m_eItemGrade), dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_cItemSize, lpItemData->m_usProtoTypeID, lpNewItemInfo->m_SpriteData.m_szName, lpNewItemInfo->m_UseLimit.m_wLimitValue, lpNewItemInfo->m_StringData.m_szTypeName); short* lpAttributeValuePos = wNewAttributeValue; short* lpAttributeValueEnd = wNewAttributeValue + Item::Attribute::MAX_ATTRIBUTE_NUM; Item::EquipType::Grade* lpGradePos = gradeInfo.m_aryAttributeGrade; Item::EquipType::Grade* lpGradeEnd = gradeInfo.m_aryAttributeGrade + Item::Attribute::MAX_ATTRIBUTE_NUM; for(int nCount = 0; lpAttributeValuePos != lpAttributeValueEnd; ++lpAttributeValuePos, ++lpGradePos, ++nCount) { if(*lpGradePos == gradeInfo.m_eItemGrade) { int nLength = _snprintf(szBuffer + nTotalLength, MAX_BUFFER - nTotalLength -1, "%s:%3d(%s)\t", Item::Attribute::Attributes[nCount].GetTypeName(), (*lpAttributeValuePos), GetGradeString(*lpGradePos)); if(0 < nLength) { nTotalLength += nLength; } } } DETLOG0(g_Log, szBuffer); } if(nOverflowIndex != OldItem::Attribute::MAX_ATTRIBUTE_NUM) { const int MAX_BUFFER = 1024; char szBuffer[MAX_BUFFER]; int nTotalLength = _snprintf(szBuffer, MAX_BUFFER - 1, "Item attribute is invalid.\tUID:%10u\tCID:%10u\tItemUID:0x%016I64X\tItemSize:%3u\tPrototypeID:%5u\tItemType:%20s\tInvalidAttr:%s\t", dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_cItemSize, lpItemData->m_usProtoTypeID, OldItem::CItemType::GetInstance().GetItemTypeName()[cItemType].GetTypeName(), OldItem::Attribute::Attributes[nOverflowIndex].GetTypeName()); short* lpAttributeValuePos = wOldAttributeValue; short* lpAttributeValueEnd = wOldAttributeValue + OldItem::Attribute::MAX_ATTRIBUTE_NUM; for(; lpAttributeValuePos != lpAttributeValueEnd; ++lpAttributeValuePos) { int nLength = _snprintf(szBuffer + nTotalLength, MAX_BUFFER - nTotalLength -1, "%3d\t", *lpAttributeValuePos); if(0 < nLength) { nTotalLength += nLength; } } DETLOG0(g_Log, szBuffer); } dwRemainBufferSize_InOut = static_cast(szOutDataPos - szOutData); reinterpret_cast(szOutData)->m_cItemSize = static_cast(dwRemainBufferSize_InOut); } else { DETLOG3(g_Log, "Not enough datasize : UID:%10u/CID:%10u/current(%u)", dwUID, dwCID, dwRemainBufferSize_InOut); return false; } return true; } int ProcessCharItem(ATL::CSession& readSession, ATL::CSession& writeSession, bool bProcessDelHistory, bool bWriteDB) { // µ¥ÀÌÅͺ£À̽º Ä¿¸Çµå »ý¼º - ¾ÆÀÌÅÛ Àбâ. Àåºñ, Àκ¥Å丮, ±âŸ, ±³È¯Ã¢ CGetUserItemData::Command getCharItemCommand; CSetUserItemData::Command setCharItemCommand; int nCount = 0; HRESULT hr = setCharItemCommand.Create(writeSession, bProcessDelHistory ? L"UPDATE CharDelHistory..DelCharItem SET Equip=?, Inventory=?, Extra=? WHERE UID=?" : L"UPDATE CharItem SET Equip=?, Inventory=?, Extra=? WHERE UID=?", DBGUID_SQL); ERROR_HRESULT_RETURN("Create setCharItemCommand failed.", hr, -1); hr = setCharItemCommand.Prepare(); ERROR_HRESULT_RETURN("Prepare setCharItemCommand failed.", hr, -1); hr = getCharItemCommand.Open(readSession, bProcessDelHistory ? L"Select UID, Equip, Inventory, Extra from CharDelHistory..DelCharItem" : L"Select UID, Equip, Inventory, Extra from CharItem"); ERROR_HRESULT_RETURN("Get Equip, Inventory, Extra failed", hr, -1); getCharItemCommand.Init(); setCharItemCommand.Init(); // Àåºñ, Àκ¥, Extra, ±³È¯Ã¢ ÄÁ¹öÆÃ. while (S_OK == getCharItemCommand.MoveNext()) { // µ¥ÀÌÅÍ ¼¼ÆÃ setCharItemCommand.m_nCID = getCharItemCommand.m_nCID; setCharItemCommand.m_EquipLength = getCharItemCommand.m_EquipLength; setCharItemCommand.m_InvenLength = getCharItemCommand.m_InvenLength; setCharItemCommand.m_ExtraLength = getCharItemCommand.m_ExtraLength; // ----------------------------------------------------------------------- // Àåºñ ¼¼ÆÃ ¹× ÄÁ¹öÆÃ EQUIP* lpGetEquip = reinterpret_cast(getCharItemCommand.m_Equip); EQUIP* lpSetEquip = reinterpret_cast(setCharItemCommand.m_Equip); if(sizeof(unsigned long) <= lpGetEquip->dwSize) { lpGetEquip->dwSize -= sizeof(unsigned long); } lpSetEquip->dwSize = EQUIP::MAX_EQUIP_SIZE; ParseItemData(0, getCharItemCommand.m_nCID, lpGetEquip->Data, lpGetEquip->dwSize, lpSetEquip->Data, lpSetEquip->dwSize); lpSetEquip->dwSize += sizeof(unsigned long); // ----------------------------------------------------------------------- // Àκ¥Å丮 ¼¼ÆÃ ¹× ÄÁ¹öÆÃ INVEN* lpGetInven = reinterpret_cast(getCharItemCommand.m_Inven); INVEN* lpSetInven = reinterpret_cast(setCharItemCommand.m_Inven); if(sizeof(unsigned long) <= lpGetInven->dwSize) { lpGetInven->dwSize -= sizeof(unsigned long); } lpSetInven->dwSize = INVEN::MAX_INVEN_SIZE; ParseItemData(0, getCharItemCommand.m_nCID, lpGetInven->Data, lpGetInven->dwSize, lpSetInven->Data, lpSetInven->dwSize); lpSetInven->dwSize += sizeof(unsigned long); // ----------------------------------------------------------------------- // Extra ¼¼ÆÃ ¹× ÄÁ¹öÆÃ EXTRA* lpGetExtra = reinterpret_cast(getCharItemCommand.m_Extra); EXTRA* lpSetExtra = reinterpret_cast(setCharItemCommand.m_Extra); if(sizeof(unsigned long) <= lpGetExtra->dwSize) { lpGetExtra->dwSize -= sizeof(unsigned long); } lpSetExtra->dwSize = EXTRA::MAX_EXTRA_SIZE; ParseItemData(0, getCharItemCommand.m_nCID, lpGetExtra->Data, lpGetExtra->dwSize, lpSetExtra->Data, lpSetExtra->dwSize); lpSetExtra->dwSize += sizeof(unsigned long); // ----------------------------------------------------------------------- // µ¥ÀÌÅÍ ¾÷µ¥ÀÌÆ® ¹× µ¥ÀÌÅÍ ÃʱâÈ­ if (0 != memcmp(lpGetEquip, lpSetEquip, sizeof(EQUIP)) || 0 != memcmp(lpGetInven, lpSetInven, sizeof(INVEN)) || 0 != memcmp(lpGetExtra, lpSetExtra, sizeof(EXTRA))) { // ¾÷µ¥ÀÌÆ® if(bWriteDB) { hr = setCharItemCommand.Open(); if(FAILED(hr)) { ERRLOG2(g_Log, "CharItem : CID:%10u write failed(hr:0x%08x)", getCharItemCommand.m_nCID, hr); } } } // ÃʱâÈ­ getCharItemCommand.Init(); setCharItemCommand.Init(); if(0 == (++nCount % SHOW_NUM_PER_PROCESS)) { printf("%d\n", nCount); } } return 0; } int ProcessCharItemEx(ATL::CSession& readSession, ATL::CSession& writeSession, bool bProcessDelHistory, bool bWriteDB) { CGetUserItemDataEx::Command getCharItemExCommand; CSetUserItemDataEx::Command setCharItemExCommand; int nCount = 0; HRESULT hr = setCharItemExCommand.Create(writeSession, bProcessDelHistory ? L"UPDATE CharDelHistory..DelCharItemEx SET Exchange=? WHERE UID=?" : L"UPDATE CharItemEx SET Exchange=? WHERE UID=?", DBGUID_SQL); ERROR_HRESULT_RETURN("Create setCharItemExCommand failed.", hr, -1); hr = setCharItemExCommand.Prepare(); ERROR_HRESULT_RETURN("Prepare setCharItemCommandEx failed.", hr, -1); hr = getCharItemExCommand.Open(readSession, bProcessDelHistory ? L"Select UID, Exchange from CharDelHistory..DelCharItemEx" : L"Select UID, Exchange from CharItemEx"); ERROR_HRESULT_RETURN("Get Equip, Inventory, Extra failed", hr, -1); getCharItemExCommand.Init(); setCharItemExCommand.Init(); while(S_OK == getCharItemExCommand.MoveNext()) { setCharItemExCommand.m_nCID = getCharItemExCommand.m_nCID; setCharItemExCommand.m_ExchangeLength = getCharItemExCommand.m_ExchangeLength; // ----------------------------------------------------------------------- // Exchage ¼¼ÆÃ ¹× ÄÁ¹öÆÃ EXCHANGE* lpGetExchange = reinterpret_cast(getCharItemExCommand.m_Exchange); EXCHANGE* lpSetExchange = reinterpret_cast(setCharItemExCommand.m_Exchange); if(sizeof(unsigned long) <= lpGetExchange->dwSize) { lpGetExchange->dwSize -= sizeof(unsigned long); } lpSetExchange->dwSize = EXCHANGE::MAX_EXCHANGE_SIZE; ParseItemData(0, getCharItemExCommand.m_nCID, lpGetExchange->Data, lpGetExchange->dwSize, lpSetExchange->Data, lpSetExchange->dwSize); lpSetExchange->dwSize += sizeof(unsigned long); if(0 != memcmp(lpGetExchange, lpSetExchange, sizeof(EXCHANGE))) { // ¾÷µ¥ÀÌÆ® if(bWriteDB) { hr = setCharItemExCommand.Open(); if(FAILED(hr)) { ERRLOG2(g_Log, "CharItemEx : CID:%10u write failed(hr:0x%08x)", getCharItemExCommand.m_nCID, hr); } } } getCharItemExCommand.Init(); setCharItemExCommand.Init(); if(0 == (++nCount % SHOW_NUM_PER_PROCESS)) { printf("%d\n", nCount); } } return 0; } int ProcessStore(ATL::CSession& readSession, ATL::CSession& writeSession, int nStoreNum, bool bWriteDB) { CGetStoreItemData::Command getStoreItemData; CSetStoreItemData::Command setStoreItemData; // µ¥ÀÌÅͺ£À̽º Ä¿¸Çµå »ý¼º - ¾ÆÀÌÅÛ ±â·Ï. LPCWSTR szUpdateQuery = 0; LPCWSTR szSelectQuery = 0; switch (nStoreNum) { case 1: szUpdateQuery = L"UPDATE ItemStore1 SET Store=? WHERE UID=?"; szSelectQuery = L"SELECT UID, Store from ItemStore1"; break; case 2: szUpdateQuery = L"UPDATE ItemStore2 SET Store=? WHERE UID=?"; szSelectQuery = L"SELECT UID, Store from ItemStore2"; break; } if(0 == szUpdateQuery || 0 == szSelectQuery) { return -1; } int nCount = 0; HRESULT hr = setStoreItemData.Create(writeSession, szUpdateQuery, DBGUID_SQL); ERROR_HRESULT_RETURN("Create setStoreItemData failed.", hr, -1); hr = setStoreItemData.Prepare(); ERROR_HRESULT_RETURN("Prepare setStoreItemData failed.", hr, -1); // â°í ÄÁ¹öÆÃ hr = getStoreItemData.Open(readSession, szSelectQuery); ERROR_HRESULT_RETURN("Get Store1, Store2 failed", hr, -1); getStoreItemData.Init(); setStoreItemData.Init(); while(S_OK == getStoreItemData.MoveNext()) { setStoreItemData.m_nUID = getStoreItemData.m_nUID; setStoreItemData.m_StoreLength = getStoreItemData.m_StoreLength; // â°í ÄÁ¹öÆÃ STORE* lpGetStore = reinterpret_cast(getStoreItemData.m_Store); STORE* lpSetStore = reinterpret_cast(setStoreItemData.m_Store); if(sizeof(unsigned long) <= lpGetStore->dwSize) { lpGetStore->dwSize -= sizeof(unsigned long); } lpSetStore->dwSize = STORE::MAX_STORE_SIZE; ParseItemData(0, getStoreItemData.m_nUID, lpGetStore->Data, lpGetStore->dwSize, lpSetStore->Data, lpSetStore->dwSize); lpSetStore->dwSize += sizeof(unsigned long); if(0 != memcmp(lpGetStore, lpSetStore, sizeof(STORE))) { // ¾÷µ¥ÀÌÆ® if(bWriteDB) { hr = setStoreItemData.Open(); if(FAILED(hr)) { ERRLOG2(g_Log, "Store : UID:%10u write failed(hr:0x%08x)", getStoreItemData.m_nUID, hr); } } } getStoreItemData.Init(); setStoreItemData.Init(); if(0 == (++nCount % SHOW_NUM_PER_PROCESS)) { printf("%d\n", nCount); } } return 0; } Item::Grade::GradeInfo GetGradeInfo(short* wNewAttribute, const int nMaxAttributeNum, const Item::ItemInfo& newItemInfo) { using namespace Item; // ------------------------------------------------------------------------------------------------- // °¡Ä¡ ±×·¹À̵å Å×À̺í static const float aryArmorValueGradeTable[EquipType::MAX_GRADE][Attribute::MAX_ATTRIBUTE_NUM] = { // MinDam. MaxDam. Armor HitRate Evade MaxHP HPRegen MaxMP MPRegen Cri. Block Speed M.Power M.Res. { 0, 0, 0, 1.8f, 0, 0.45f, 0.9f, 1.8f, 0, 0, 0, 0, 0, 0, 0.18f }, // Grade AAA { 0, 0, 0, 1.5f, 0, 0.375f, 0.75f, 1.5f, 0, 0, 0, 0, 0, 0, 0.15f }, // Grade AA { 0, 0, 0, 1.2f, 0, 0.3f, 0.6f, 1.2f, 0, 0, 0, 0, 0, 0, 0.12f }, // Grade A { 0, 0, 0, 0.9f, 0, 0.225f, 0.45f, 0.9f, 0, 0, 0, 0, 0, 0, 0.09f }, // Grade B { 0, 0, 0, 0.6f, 0, 0.15f, 0.3f, 0.6f, 0, 0, 0, 0, 0, 0, 0.06f }, // Grade C { 0, 0, 0, 0.3f, 0, 0.075f, 0.15f, 0.3f, 0, 0, 0, 0, 0, 0, 0.03f }, // Grade D { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Grade F }; static const float aryDaggerValueGradeTable[EquipType::MAX_GRADE][Attribute::MAX_ATTRIBUTE_NUM] = { // MinDam. MaxDam. Armor HitRate Evade MaxHP HPRegen MaxMP MPRegen Cri. Block Speed M.Power M.Res. { 0, 0.9f, 1.26f, 0, 1.8f, 0, 0, 0, 0.9f, 1.8f, 0.36f, 0.36f, 0, 0, 0 }, // Grade AAA { 0, 0.75f, 1.05f, 0, 1.5f, 0, 0, 0, 0.75f, 1.5f, 0.3f, 0.3f, 0, 0, 0 }, // Grade AA { 0, 0.6f, 0.84f, 0, 1.2f, 0, 0, 0, 0.6f, 1.2f, 0.24f, 0.24f, 0, 0, 0 }, // Grade A { 0, 0.45f, 0.63f, 0, 0.9f, 0, 0, 0, 0.45f, 0.9f, 0.18f, 0.18f, 0, 0, 0 }, // Grade B { 0, 0.3f, 0.42f, 0, 0.6f, 0, 0, 0, 0.3f, 0.6f, 0.12f, 0.12f, 0, 0, 0 }, // Grade C { 0, 0.15f, 0.21f, 0, 0.3f, 0, 0, 0, 0.15f, 0.3f, 0.06f, 0.06f, 0, 0, 0 }, // Grade D { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Grade F }; static const float aryOneHandedWeaponValueGradeTable[EquipType::MAX_GRADE][Attribute::MAX_ATTRIBUTE_NUM] = { // MinDam. MaxDam. Armor HitRate Evade MaxHP HPRegen MaxMP MPRegen Cri. Block Speed M.Power M.Res. { 0, 1.08f, 1.44f, 0, 1.8f, 0, 0, 0, 0.9f, 1.8f, 0.36f, 0.36f, 0, 0, 0 }, // Grade AAA { 0, 0.9f, 1.2f, 0, 1.5f, 0, 0, 0, 0.75f, 1.5f, 0.3f, 0.3f, 0, 0, 0 }, // Grade AA { 0, 0.72f, 0.96f, 0, 1.2f, 0, 0, 0, 0.6f, 1.2f, 0.24f, 0.24f, 0, 0, 0 }, // Grade A { 0, 0.54f, 0.72f, 0, 0.9f, 0, 0, 0, 0.45f, 0.9f, 0.18f, 0.18f, 0, 0, 0 }, // Grade B { 0, 0.36f, 0.48f, 0, 0.6f, 0, 0, 0, 0.3f, 0.6f, 0.12f, 0.12f, 0, 0, 0 }, // Grade C { 0, 0.18f, 0.24f, 0, 0.3f, 0, 0, 0, 0.15f, 0.3f, 0.06f, 0.06f, 0, 0, 0 }, // Grade D { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Grade F }; static const float aryLongRangeWeaponValueGradeTable[EquipType::MAX_GRADE][Attribute::MAX_ATTRIBUTE_NUM] = { // MinDam. MaxDam. Armor HitRate Evade MaxHP HPRegen MaxMP MPRegen Cri. Block Speed M.Power M.Res. { 0, 1.08f, 1.44f, 0, 1.8f, 0, 0, 0, 0.9f, 1.8f, 0.36f, 0.36f, 0, 0, 0 }, // Grade AAA { 0, 0.9f, 1.2f, 0, 1.5f, 0, 0, 0, 0.75f, 1.5f, 0.3f, 0.3f, 0, 0, 0 }, // Grade AA { 0, 0.72f, 0.96f, 0, 1.2f, 0, 0, 0, 0.6f, 1.2f, 0.24f, 0.24f, 0, 0, 0 }, // Grade A { 0, 0.54f, 0.72f, 0, 0.9f, 0, 0, 0, 0.45f, 0.9f, 0.18f, 0.18f, 0, 0, 0 }, // Grade B { 0, 0.36f, 0.48f, 0, 0.6f, 0, 0, 0, 0.3f, 0.6f, 0.12f, 0.12f, 0, 0, 0 }, // Grade C { 0, 0.18f, 0.24f, 0, 0.3f, 0, 0, 0, 0.15f, 0.3f, 0.06f, 0.06f, 0, 0, 0 }, // Grade D { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Grade F }; static const float aryTwoHandedWeaponValueGradeTable[EquipType::MAX_GRADE][Attribute::MAX_ATTRIBUTE_NUM] = { // MinDam. MaxDam. Armor HitRate Evade MaxHP HPRegen MaxMP MPRegen Cri. Block Speed M.Power M.Res. { 0, 1.08f, 1.8f, 0, 1.8f, 0, 0, 0, 0.9f, 1.8f, 0.36f, 0.36f, 0, 0, 0 }, // Grade AAA { 0, 0.9f, 1.5f, 0, 1.5f, 0, 0, 0, 0.75f, 1.5f, 0.3f, 0.3f, 0, 0, 0 }, // Grade AA { 0, 0.72f, 1.2f, 0, 1.2f, 0, 0, 0, 0.6f, 1.2f, 0.24f, 0.24f, 0, 0, 0 }, // Grade A { 0, 0.54f, 0.9f, 0, 0.9f, 0, 0, 0, 0.45f, 0.9f, 0.18f, 0.18f, 0, 0, 0 }, // Grade B { 0, 0.36f, 0.6f, 0, 0.6f, 0, 0, 0, 0.3f, 0.6f, 0.12f, 0.12f, 0, 0, 0 }, // Grade C { 0, 0.18f, 0.3f, 0, 0.3f, 0, 0, 0, 0.15f, 0.3f, 0.06f, 0.06f, 0, 0, 0 }, // Grade D { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Grade F }; static const float aryStaffValueGradeTable[EquipType::MAX_GRADE][Attribute::MAX_ATTRIBUTE_NUM] = { // MinDam. MaxDam. Armor HitRate Evade MaxHP HPRegen MaxMP MPRegen Cri. Block Speed M.Power M.Res. { 0, 0, 1.8f, 0, 1.8f, 0, 0, 0, 1.8f, 3.6f, 0.36f, 0.36f, 0, 1.8f, 0 }, // Grade AAA { 0, 0, 1.5f, 0, 1.5f, 0, 0, 0, 1.5f, 3.0f, 0.3f, 0.3f, 0, 1.5f, 0 }, // Grade AA { 0, 0, 1.2f, 0, 1.2f, 0, 0, 0, 1.2f, 2.4f, 0.24f, 0.24f, 0, 1.2f, 0 }, // Grade A { 0, 0, 0.9f, 0, 0.9f, 0, 0, 0, 0.9f, 1.8f, 0.18f, 0.18f, 0, 0.9f, 0 }, // Grade B { 0, 0, 0.6f, 0, 0.6f, 0, 0, 0, 0.6f, 1.2f, 0.12f, 0.12f, 0, 0.6f, 0 }, // Grade C { 0, 0, 0.3f, 0, 0.3f, 0, 0, 0, 0.3f, 0.6f, 0.06f, 0.06f, 0, 0.3f, 0 }, // Grade D { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Grade F }; static const float aryShieldValueGradeTable[EquipType::MAX_GRADE][Attribute::MAX_ATTRIBUTE_NUM] = { // MinDam. MaxDam. Armor HitRate Evade MaxHP HPRegen MaxMP MPRegen Cri. Block Speed M.Power M.Res. { 0, 0, 0, 0, 0, 0, 0.45f, 0.9f, 0.45f, 0.9f, 0, 0.36f, 0, 0, 0 }, // Grade AAA { 0, 0, 0, 0, 0, 0, 0.375f, 0.75f, 0.375f, 0.75f, 0, 0.3f, 0, 0, 0 }, // Grade AA { 0, 0, 0, 0, 0, 0, 0.3f, 0.6f, 0.3f, 0.6f, 0, 0.24f, 0, 0, 0 }, // Grade A { 0, 0, 0, 0, 0, 0, 0.225f, 0.45f, 0.225f, 0.45f, 0, 0.18f, 0, 0, 0 }, // Grade B { 0, 0, 0, 0, 0, 0, 0.15f, 0.3f, 0.15f, 0.3f, 0, 0.12f, 0, 0, 0 }, // Grade C { 0, 0, 0, 0, 0, 0, 0.075f, 0.15f, 0.075f, 0.15f, 0, 0.06f, 0, 0, 0 }, // Grade D { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // Grade F }; // ------------------------------------------------------------------------------------------------- if (0 == newItemInfo.m_DetailData.m_wDropOption) { return Item::Grade::GradeInfo(); } float aryUsingValueGradeTable[EquipType::MAX_GRADE][Attribute::MAX_ATTRIBUTE_NUM] = { 0, }; switch (newItemInfo.m_DetailData.m_cItemType) { case ItemType::CON_ARMOUR: case ItemType::DEX_ARMOUR: case ItemType::CON_HELM: case ItemType::DEX_HELM: case ItemType::CON_BODY: case ItemType::DEX_BODY: case ItemType::CON_HEAD: case ItemType::DEX_HEAD: memcpy(aryUsingValueGradeTable, aryArmorValueGradeTable, sizeof(float) * EquipType::MAX_GRADE * Attribute::MAX_ATTRIBUTE_NUM); break; case ItemType::DAGGER: case ItemType::OPP_TALON: case ItemType::SKILL_A_KNIFE: memcpy(aryUsingValueGradeTable, aryDaggerValueGradeTable, sizeof(float) * EquipType::MAX_GRADE * Attribute::MAX_ATTRIBUTE_NUM); break; case ItemType::ONEHANDED_SWORD: case ItemType::ONEHANDED_AXE: case ItemType::ONEHANDED_BLUNT: case ItemType::COM_BLUNT: case ItemType::COM_SWORD: case ItemType::OPP_HAMMER: case ItemType::OPP_SLUSHER: case ItemType::SKILL_A_ATTACK: memcpy(aryUsingValueGradeTable, aryOneHandedWeaponValueGradeTable, sizeof(float) * EquipType::MAX_GRADE * Attribute::MAX_ATTRIBUTE_NUM); break; case ItemType::BOW: case ItemType::CROSSBOW: case ItemType::SKILL_A_GUN: memcpy(aryUsingValueGradeTable, aryLongRangeWeaponValueGradeTable, sizeof(float) * EquipType::MAX_GRADE * Attribute::MAX_ATTRIBUTE_NUM); break; case ItemType::TWOHANDED_SWORD: case ItemType::TWOHANDED_AXE: case ItemType::TWOHANDED_BLUNT: memcpy(aryUsingValueGradeTable, aryTwoHandedWeaponValueGradeTable, sizeof(float) * EquipType::MAX_GRADE * Attribute::MAX_ATTRIBUTE_NUM); break; case ItemType::STAFF: case ItemType::OPP_SYTHE: memcpy(aryUsingValueGradeTable, aryStaffValueGradeTable, sizeof(float) * EquipType::MAX_GRADE * Attribute::MAX_ATTRIBUTE_NUM); break; case ItemType::SHIELD: case ItemType::SKILL_A_GUARD: memcpy(aryUsingValueGradeTable, aryShieldValueGradeTable, sizeof(float) * EquipType::MAX_GRADE * Attribute::MAX_ATTRIBUTE_NUM); break; default: return Item::Grade::GradeInfo(); } // ¾ÆÀÌÅÛÀÇ ±×·¹À̵å Á¤º¸¸¦ ÃʱâÈ­ Item::Grade::GradeInfo resultGradeInfo = Item::Grade::GradeInfo(); for (unsigned char cAttributeIndex = 0; cAttributeIndex < Attribute::MAX_ATTRIBUTE_NUM; ++cAttributeIndex) { // ¼Ó¼º°ªÀÌ B ±×·¹À̵带 ³ÑÀ¸¸é, B±×·¹ÀÌµå °ªÀ¸·Î °íÁ¤ÇÑ´Ù. short wMaxAttribute = static_cast( aryUsingValueGradeTable[EquipType::A_GRADE][cAttributeIndex] * static_cast(newItemInfo.m_DetailData.m_wDropOption)); if(wMaxAttribute < wNewAttribute[cAttributeIndex]) { wNewAttribute[cAttributeIndex] = wMaxAttribute; } const float fGradeFactor = wNewAttribute[cAttributeIndex] / static_cast(newItemInfo.m_DetailData.m_wDropOption); // D ±×·¹À̵带 ÃʰúÇϸé F ±×·¹À̵尡 µÈ´Ù. for (unsigned char cGradeIndex = 0; cGradeIndex <= EquipType::D_GRADE; ++cGradeIndex) { if (0 != aryUsingValueGradeTable[cGradeIndex][cAttributeIndex] && fGradeFactor > aryUsingValueGradeTable[cGradeIndex][cAttributeIndex]) { resultGradeInfo.m_aryAttributeGrade[cAttributeIndex] = static_cast(cGradeIndex); if (resultGradeInfo.m_eItemGrade > resultGradeInfo.m_aryAttributeGrade[cAttributeIndex]) { resultGradeInfo.m_eItemGrade = resultGradeInfo.m_aryAttributeGrade[cAttributeIndex]; resultGradeInfo.m_cPlus = 0; } else { if (resultGradeInfo.m_eItemGrade == resultGradeInfo.m_aryAttributeGrade[cAttributeIndex]) { ++resultGradeInfo.m_cPlus; } } break; } } } return resultGradeInfo; } const char* GetGradeString(Item::EquipType::Grade grade) { switch(grade) { case Item::EquipType::AAA_GRADE: return "AAA"; case Item::EquipType::AA_GRADE: return "AA"; case Item::EquipType::A_GRADE: return "A"; case Item::EquipType::B_GRADE: return "B"; case Item::EquipType::C_GRADE: return "C"; case Item::EquipType::D_GRADE: return "D"; case Item::EquipType::F_GRADE: return "F"; } return "Unknown"; }