Files
git 9cb257e7ae Add GameClients drops and keep current 1602 source work.
CN1602 is the local client. KR is the official tree with unpacked Data, System, and Sound. Packed .wpk files stay off git.
2026-08-30 23:24:31 +03:00

1341 lines
55 KiB
C++

#include "stdafx.h"
#include "ItemInfoParser.h"
#include "./Define.h"
#include "./Struct.h"
#include <ItemOptionHeader.h>
#include <SCItemSlot.h>
//==================================================================================================
ItemInfoParser* ItemInfoParser::item_info_parser_static_ = NULL;
ItemInfoParser* ItemInfoParser::CreateInstance()
{
// (NOTE) thread-unsafe singleton
item_info_parser_static_ = new ItemInfoParser;
return item_info_parser_static_;
}
void ItemInfoParser::DestroyInstance()
{
SAFE_DELETE(item_info_parser_static_);
}
//==================================================================================================
#ifdef _SERVER
static void _ItemLoggingForDuplicatedViolation(CODETYPE item_code, int duplicable_num,
const char* category)
{
SUNLOG(eDEV_LOG,
"ItemCode|%u|DupNum(%d) != 1|'%s' DupNum must be 1, cannot stack",
item_code, duplicable_num, category);
}
static void _ItemLoggingForFunctionViolation(CODETYPE item_code,
const char* category,
const char* func_attribute)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|'%s' cannot use '%s'", item_code, category, func_attribute);
}
#define LOG_ITEM_VIOLATION_DUPLICATE(arg0, arg1, arg2) \
_ItemLoggingForDuplicatedViolation(arg0, arg1, arg2)
#define LOG_ITEM_VIOLATION_FUCTION(arg0, arg1, arg2) \
_ItemLoggingForFunctionViolation(arg0, arg1, arg2)
#else //!_SERVER
#define LOG_ITEM_VIOLATION_DUPLICATE(arg0, arg1, arg2)
#define LOG_ITEM_VIOLATION_FUCTION(arg0, arg1, arg2)
#endif //!_SERVER
//==================================================================================================
ItemInfoParser::ItemInfoParser()
: RENDER_EFFECT_ITEMS(render_effect_item_list_)
{
}
ItemInfoParser::~ItemInfoParser()
{
}
void
ItemInfoParser::Release()
{
Unload();
}
void
ItemInfoParser::Init(DWORD unused_arg)
{
__UNUSED(unused_arg);
// (CHANGES) (f100505.1L) changes data structure related to the BASE_ITEMINFO
loaded_ = false;
cool_time_table_.clear();
#if defined (_NA_0_20091208_VENDOR_ITEM_SEARCH) || (defined(_DH_GM_ITEM_WINDOW) && !defined(_SERVER))
item_name_code_table_.clear();
#endif//_NA_0_20091208_VENDOR_ITEM_SEARCH
render_effect_item_list_.clear();
ZeroMemory(&item_table_, sizeof(item_table_));
ZeroMemory(file_name_, sizeof(file_name_));
}
void
ItemInfoParser::Init(DWORD unused_arg, char* pack_file_name)
{
Init(unused_arg);
SetPackFileName(pack_file_name);
}
void
ItemInfoParser::Unload()
{
// (CHANGES) (f100505.1L) changes data structure related to the BASE_ITEMINFO
if (loaded_ == false) {
return;
}
;{ // release all resource in a table
this->SetFirst();
while (BASE_ITEMINFO* item_info = this->GetNext()) {
delete item_info;
};
if (item_table_.seq_total_indexes_) {
::free(const_cast<uint16_t*>(item_table_.seq_total_indexes_));
};
if (item_table_.client_checksum_array_) {
::free(item_table_.client_checksum_array_);
};
ZeroMemory(&item_table_, sizeof(item_table_));
};
//
render_effect_item_list_.clear();
;{ // (NOTE) it has not the usage case at this point in time (100505)
DUP_EQUIP_GROUP_INFO_MAP::const_iterator it = dup_item_group_.begin();
const DUP_EQUIP_GROUP_INFO_MAP::const_iterator end = dup_item_group_.end();
for ( ; it != end; ++it) {
delete it->second;
}
dup_item_group_.clear();
};
#if defined (_NA_0_20091208_VENDOR_ITEM_SEARCH) || (defined(_DH_GM_ITEM_WINDOW) && !defined(_SERVER))
item_name_code_table_.clear();
#endif//_NA_0_20091208_VENDOR_ITEM_SEARCH
//
// must be settled last position
loaded_ = false;
}
// (CHANGES) (f100505.1L) add the item access facility which is supported an O(1) time complexity
bool ItemInfoParser::_AddItemInfo(CODETYPE item_code, BASE_ITEMINFO* item_info)
{
if (item_code == 0 || item_code > USHRT_MAX || item_info == NULL) {
return false;
}
--item_code;
item_table_.array_[item_code] = item_info;
return true;
}
// (CHANGES) (f100505.1L) add the item access facility which is supported an O(1) time complexity
bool ItemInfoParser::_BuildReference(int added_number_of_items)
{
if (added_number_of_items <= 0) {
return false;
}
const int resize_number = item_table_.number_of_total_items_ + added_number_of_items;
if (item_table_.seq_total_indexes_) {
::free(const_cast<uint16_t*>(item_table_.seq_total_indexes_));
}
const int chunk_size = sizeof(uint16_t) * resize_number;
;{
void* ptr = ::malloc(chunk_size);
ZeroMemory(ptr, chunk_size);
item_table_.seq_total_indexes_ = reinterpret_cast<uint16_t*>(ptr);
};
uint16_t* dest_it = const_cast<uint16_t*>(item_table_.seq_total_indexes_);
//
const BASE_ITEMINFO* const * it = item_table_.array_;
const BASE_ITEMINFO* const * const end = &item_table_.array_[_countof(item_table_.array_)];
while (true)
{
while (it < end && (*it) == NULL) {
++it;
}
if (it >= end) {
break;
}
*dest_it = static_cast<uint16_t>(it - item_table_.array_);
++dest_it;
++it;
}
item_table_.number_of_total_items_ = resize_number;
return true;
}
//==================================================================================================
BOOL
ItemInfoParser::_Load(BOOL reloaded)
{
if (FILE* trace = fopen("script_load_trace.txt", "a"))
{
fprintf(trace, "ItemInfo _Load rows=%d file=%s\n", GetRowSize(), GetCurFileName());
fclose(trace);
}
CODETYPE previous_item_code_for_debugging = 0;
if (item_table_.client_checksum_array_ == NULL) {
void* ptr = ::malloc(sizeof(ulong) * USHRT_MAX);
ZeroMemory(ptr, (sizeof(ulong) * USHRT_MAX));
item_table_.client_checksum_array_ = reinterpret_cast<ulong*>(ptr);
};
const int max_rows = GetRowSize();
for (int row_no = 0; row_no < max_rows; ++row_no)
{
const CODETYPE item_code = GetDataDWORD("Code", row_no);
if (!FlowControl::FCAssert(item_code != 0 && item_code <= USHRT_MAX))
{
SUNLOG(eCRITICAL_LOG, _T("["__FUNCTION__"]|item code invalid.|Code=%d|File={%s}|"),
item_code, GetCurFileName());
};
BASE_ITEMINFO* item_info = GetItemInfo(item_code);
if (item_info == NULL)
{
item_info = new BASE_ITEMINFO;
ZeroMemory(item_info, sizeof(*item_info));
_AddItemInfo(item_code, item_info);
}
else
{
if (false == reloaded)
{
SUNLOG(eCRITICAL_LOG,
_T("["__FUNCTION__"]|item code already exists|Code=%d|File={%s}|"),
item_code, GetCurFileName());
}
}
item_info->m_Code = SLOTCODE(item_code);
item_info->m_ChargeType = GetDataBYTE("ChargeType", row_no);
item_info->m_ChargeSubType = GetDataBYTE("ChargeSubType", row_no);
strncpy(item_info->m_pszName, GetDataString("Name", row_no), _countof(item_info->m_pszName));
item_info->m_pszName[_countof(item_info->m_pszName) - 1] = '\0';
item_info->m_NCode = GetDataDWORD("NameCode", row_no);
item_info->m_bUse = (GetDataBYTE("NameColorType", row_no) != 0);
// (NOTE) boundary...
strncpy(item_info->m_szColor, GetDataString("NameColorCode", row_no),
item_info->MAX_COLOR_LENGTH);
item_info->m_SCNCode = GetDataDWORD("NameCode2", row_no);
item_info->m_TDNCode = GetDataDWORD("DNCode3", row_no);
item_info->m_wWICode = GetDataDWORD("WearImageCode", row_no);
#ifdef _NA_002050_20110216_ADD_GENDER
// m_wWICode : ???????????????????
item_info->m_wWICode2 = GetDataDWORD("WearImageCode2", row_no); //???????????????????
#endif //_NA_002050_20110216_ADD_GENDER
item_info->m_wVICode = GetDataDWORD("InvenImageCode", row_no);
item_info->m_wDICode = GetDataDWORD("DropImageCode", row_no);
#ifdef _20220413_ITEM_DROP_EFFECT
item_info->m_wzItemDropEffect = StrToWzID(GetDataString("ItemDropEffect",row_no));
#endif
item_info->m_wType = GetDataWORD("Type", row_no);
item_info->m_byEventCode = GetDataBYTE("Etype", row_no);
item_info->m_nSoundIndex = GetDataInt("ItemSoundIndex", row_no);
// (CHANGES) (091202) (WAVERIX) change type
item_info->m_byEffectPosition = GetDataBYTE("EffectPosition", row_no);
item_info->m_dwEffectCode = StrToWzID(GetDataString("EffectCode", row_no));
// (CHANGES) (091202) (WAVERIX) change type
item_info->m_bEfffectBoneRot = GetDataBYTE("RotBone", row_no);
item_info->m_dwEquipBoneID = StrToWzID(GetDataString("BoneName", row_no));
item_info->m_bEquipRot = (GetDataBYTE("SABoneType", row_no) != 0);
// (REF) eITEMSUBTYPE
item_info->m_wSubType = GetDataWORD("SubType", row_no);
#ifdef _NA_002050_20110216_ADD_GENDER
item_info->gender_type = GetDataBYTE(_T("GenderType"), row_no);
if (item_info->gender_type != GenderType::kAll &&
item_info->gender_type != GenderType::kMale &&
item_info->gender_type != GenderType::kFemale)
{
item_info->gender_type = GenderType::kAll;
SUNLOG(eCRITICAL_LOG,
_T("|%s|Gender setting invalid, initialized to 0.| Item Code=%u, row=%u |"),
__FUNCTION__,
item_info->m_Code,
row_no);
}
#endif // _NA_002050_20110216_ADD_GENDER
// (REF) BASE_ITEMINFO::eSetItemOption
item_info->m_bySetOptionType = GetDataBYTE("SetOptionType", row_no);
item_info->set_group_code = GetDataWORD("SetType", row_no);
item_info->m_LV = GetDataWORD("Level", row_no);
SASSERT(item_info->m_LV > 0, "Item level must be greater than 0. Data error!");
item_info->m_Dura = GetDataBYTE("Dura", row_no);
item_info->m_dwDuraStr = GetDataDWORD("DuraStrenth", row_no);
if (item_info->m_dwDuraStr == 0)
{
// ?????????????0
// if (pInfo->IsWeapon() || pInfo->IsArmor())
// SUNLOG("[???:%u]:DuraStrength?? 0????.\n", pInfo->m_NCode);
}
#ifdef __NA_001062_20080623_STRENGTH_PENALTY
item_info->m_dwStrengthPenaltyIdx = GetDataBYTE("StrengthPenaltyIndex", row_no);
#endif
item_info->m_DropLV = GetDataDWORD64("ItemSellMoney", row_no);
item_info->m_byPopup = GetDataBYTE("Popup", row_no);
item_info->m_byMaterialType = GetDataBYTE("MaterialType", row_no);
item_info->trade_sell_type = GetDataWORD("TradeSellType", row_no);
item_info->m_byMixture = GetDataBYTE("Mixture", row_no);
item_info->m_bPossessionItem = GetDataBYTE("ReversionType", row_no);
//_NA000960_101011_ITEM_CUSTOMIZING_CONTENTS_ADD_RULE_
item_info->etherealization_mode_.value = GetDataBYTE("ExtractType", row_no);
item_info->m_LimitEqLevel = GetDataWORD("LimitEqLevel", row_no);
//__CN_1299_WASTE_ITEM_LEVEL_LIMITE_CHECK
item_info->m_LimitUseLevel = GetDataWORD("LimitUseLevel", row_no);
item_info->m_wLimitStr = GetDataWORD("LimitStr", row_no);
item_info->m_wLimitDex = GetDataWORD("LimitDex", row_no);
item_info->m_wLimitVit = GetDataWORD("LimitVit", row_no);
item_info->m_wLimitInt = GetDataWORD("LimitInt", row_no);
item_info->m_wLimitSpr = GetDataWORD("LimitSpr", row_no);
item_info->m_wLimitSkil1 = GetDataWORD("LimitSkill1", row_no);
item_info->m_wLimitSkil2 = GetDataWORD("LimitSkill2", row_no);
item_info->m_wMinDamage = GetDataWORD("MinDamage", row_no);
item_info->m_wMaxDamage = GetDataWORD("MaxDamage", row_no);
#ifdef _NA001605_EP2_ATTRIBUTES_RENEWAL_
item_info->m_wPhyAttRate = static_cast<uint16_t>(
util::LL_Round(GetDataNumber("PhyAttRate", row_no) * 100.0f));
item_info->m_wPhyAvoid = static_cast<uint16_t>(
util::LL_Round(GetDataNumber("PhyAvoid", row_no) * 100.0f));
#else
item_info->m_wPhyAttRate = GetDataWORD("PhyAttRate", row_no);
item_info->m_wPhyAvoid = GetDataWORD("PhyAvoid", row_no);
#endif
item_info->m_wPhyAttSpeed = GetDataWORD("PhyAttSpeed", row_no);
item_info->m_wPhyDef = GetDataWORD("PhyDef", row_no);
item_info->m_byBaseAttType = GetDataBYTE("BaseAttType", row_no);
item_info->m_byMagicalAttType = GetDataBYTE("MagicalAttType", row_no);
item_info->m_byMeleeType = GetDataBYTE("MeleeType", row_no);
item_info->m_fAttRange = GetDataFloat("AttRange", row_no);
item_info->m_byArmorType = GetDataBYTE("ArmorType", row_no);
item_info->m_wMagicAttMinDamgage = GetDataWORD("MagicAttMinDamgage", row_no);
item_info->m_wMagicAttMaxDamgage = GetDataWORD("MagicAttMaxDamgage", row_no);
item_info->m_wMagicAttSpeed = GetDataWORD("MagicAttSpeed", row_no);
#if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_)
item_info->m_wMagicDef = GetDataWORD("MagicDef", row_no);
#endif
item_info->m_wSpeed = GetDataWORD("Speed", row_no);
;{
// NOTE: f110408.2L, ???????????? = { (1 << eCHAR_BERSERKER) | ... }
item_info->m_wEqClass1 = GetDataWORD("EqClass1", row_no);
item_info->m_wEqClass2 = GetDataWORD("EqClass2", row_no);
item_info->m_wEqClass3 = GetDataWORD("EqClass3", row_no);
item_info->m_wEqClass4 = GetDataWORD("EqClass4", row_no);
item_info->m_wEqClass5 = GetDataWORD("EqClass5", row_no);
// _NA_004965_20120613_NEW_CHARACTER_MYSTIC
item_info->m_wEqClass6 = GetDataWORD("EqClass6", row_no);
#ifdef _NA_000000_20130812_NEW_CHARACTER_HELLROID
item_info->m_wEqClass7 = GetDataWORD("EqClass7", row_no);
#endif //_NA_000000_20130812_NEW_CHARACTER_HELLROID
#ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
item_info->m_wEqClass8 = GetDataWORD("EqClass8", row_no);
#endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
uint16_t composed = 0;
if (item_info->m_wEqClass1) { composed |= (1 << eCHAR_BERSERKER); }
if (item_info->m_wEqClass2) { composed |= (1 << eCHAR_DRAGON); }
if (item_info->m_wEqClass3) { composed |= (1 << eCHAR_SHADOW); }
if (item_info->m_wEqClass4) { composed |= (1 << eCHAR_VALKYRIE); }
if (item_info->m_wEqClass5) { composed |= (1 << eCHAR_ELEMENTALIST); }
// _NA_004965_20120613_NEW_CHARACTER_MYSTIC
if (item_info->m_wEqClass6) { composed |= (1 << eCHAR_MYSTIC); }
#ifdef _NA_000000_20130812_NEW_CHARACTER_HELLROID
if (item_info->m_wEqClass7) { composed |= (1 << eCHAR_HELLROID); }
#endif //_NA_000000_20130812_NEW_CHARACTER_HELLROID
#ifdef _NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
if (item_info->m_wEqClass8) { composed |= (1 << eCHAR_WITCHBLADE); }
#endif //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
item_info->equip_class_bits = composed;
};
// (REF) {eEQUIPCONTAINER_POS, eRIDER_PARTS_POS} ???????+??????????????
item_info->m_wEqPos = GetDataBYTE("EqPos", row_no);
char szName[32];
for (int op = 0; op < _countof(item_info->m_byOptionExEffect); ++op)
{
BYTE& rExcerciseEffect = item_info->m_byOptionExEffect[op];
_snprintf(szName, 32, "ExerciseEffect%d", op + 1);
rExcerciseEffect = GetDataBYTE(szName, row_no);
switch (rExcerciseEffect)
{
case eITEM_EFFECT_NONE: case eITEM_EFFECT_ON_EQUIP: case eITEM_EFFECT_ON_INVEN: break;
default:
SUNLOG(eCRITICAL_LOG,
"[%u]OptionExcerciseEffect value(%u) invalid, fixed to NONE",
item_info->m_Code, rExcerciseEffect);
rExcerciseEffect = eITEM_EFFECT_NONE;
break;
}
_snprintf(szName, 32, "OptionKind%d", op + 1);
item_info->m_wOptionIndex[op] = GetDataWORD(szName, row_no);
_snprintf(szName, 32, "OptionType%d", op + 1);
item_info->m_byOptionType[op] = GetDataBYTE(szName, row_no);
_snprintf(szName, 32, "OptionValue%d", op + 1);
item_info->m_iOptionValue[op] = GetDataInt(szName, row_no);
if (item_info->m_wOptionIndex[op] >= _countof(g_ITEM_OPTION))
{
SUNLOG(eCRITICAL_LOG,
"ItemCode|%u|OptionIndex : OptionValue = %u : %u|out of range",
item_info->m_Code,
item_info->m_wOptionIndex[op], item_info->m_iOptionValue[op]);
}
}
for (int i = 0; i < _countof(item_info->m_byPCOptionExEffect); ++i)
{
BYTE& rExcerciseEffect = item_info->m_byPCOptionExEffect[i];
_snprintf(szName, 32, "PCExerciseEffect%d", i+1);
rExcerciseEffect = GetDataBYTE(szName, row_no);
switch (rExcerciseEffect)
{
case eITEM_EFFECT_NONE: case eITEM_EFFECT_ON_EQUIP: case eITEM_EFFECT_ON_INVEN: break;
default:
SUNLOG(eCRITICAL_LOG,
"ItemCode|%u|OptionExcerciseEffect value (%u) invalid, changed to NONE",
item_info->m_Code, rExcerciseEffect);
rExcerciseEffect = eITEM_EFFECT_NONE;
break;
}
_snprintf(szName, 32, "PCOptionKind%d", i+1);
item_info->m_wPCOptionIndex[i] = GetDataWORD(szName, row_no);
_snprintf(szName, 32, "PCOptionType%d", i+1);
item_info->m_byPCOptionType[i] = GetDataBYTE(szName, row_no);
_snprintf(szName, 32, "PCOptionValue%d", i+1);
item_info->m_iPCOptionValue[i] = GetDataInt(szName, row_no);
if (item_info->m_wPCOptionIndex[i] >= _countof(g_ITEM_OPTION))
{
SUNLOG(eCRITICAL_LOG,
"ItemCode|%u|OptionIndex : OptionValue = %u : %u|out of range",
item_info->m_Code,
item_info->m_wPCOptionIndex[i], item_info->m_iPCOptionValue[i]);
}
}
item_info->m_wMissile = GetDataWORD("Missile", row_no);
item_info->m_bHeadType = GetDataBYTE("HeadType", row_no);
if (item_info->m_bHeadType)
--item_info->m_bHeadType;// (NOTE) what is it?
//-??????????1???????????????????
//??????????????????????????
//-?????????????2????????????
//?????????????????????.?????????????
item_info->m_wCustomize = GetDataWORD("Customize", row_no);
#ifdef _NA_002050_20110216_ADD_GENDER
item_info->m_bHeadType1 = GetDataBYTE("HeadType2", row_no);
if (item_info->m_bHeadType1)
--item_info->m_bHeadType1;
item_info->m_wCustomize1 = GetDataWORD("Customize2", row_no);
#endif //_NA_002050_20110216_ADD_GENDER
item_info->m_byDupNum = GetDataWORD("DupNum", row_no);
if (item_info->m_byDupNum == 0)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|m_byDupNum = 0", item_info->m_Code);
item_info->m_byDupNum = 1;
}
item_info->m_byDupEquipNum = GetDataBYTE("DupEquipNum", row_no);
item_info->m_byDupEquipTypeNum = GetDataBYTE("DupEquipTypeNum", row_no);
item_info->m_byDupEquipGroup = GetDataBYTE("DupEquipGroup", row_no);
item_info->m_byDupEquipGroupNum = GetDataBYTE("DupEquipGroupNum", row_no);
DUP_EQUIP_GROUP_INFO_MAP::const_iterator find_dup_equip = \
dup_item_group_.find(item_info->m_byDupEquipGroup);
// ????????..
if (find_dup_equip != dup_item_group_.end())
{
// ???????????n????.
const DUP_EQUIP_GROUP_INFO* equip_group_info = find_dup_equip->second;
if (equip_group_info->m_byDupEquipGroupNum != item_info->m_byDupEquipGroupNum) {
SUNLOG(eCRITICAL_LOG,
"["__FUNCTION__"]|ItemCode|%d|GroupNum|%d|field [DupEquipGroupNum] invalid",
item_info->m_Code, item_info->m_byDupEquipGroupNum);
}
}
else
{
//???????????????.
DUP_EQUIP_GROUP_INFO* pGroupInfo = new DUP_EQUIP_GROUP_INFO;
pGroupInfo->m_byDupEquipGroup = item_info->m_byDupEquipGroup;
pGroupInfo->m_byDupEquipGroupNum = item_info->m_byDupEquipGroupNum;
dup_item_group_.insert(std::make_pair(pGroupInfo->m_byDupEquipGroup, pGroupInfo));
}
item_info->m_byWasteType = GetDataBYTE("WasteType", row_no);
item_info->m_wCoolTimeType = GetDataWORD("CoolTimeType", row_no);
item_info->m_wHealHP = GetDataWORD("HealHP", row_no);
item_info->m_dwExp = GetDataDWORD64("ExpHP", row_no);
item_info->m_wTimes = GetDataWORD("Times", row_no);
item_info->m_dCoolTime = GetDataDWORD("CoolTime", row_no);
item_info->m_wHealHPTime = GetDataDWORD("HealTime", row_no);
if (0 != item_info->m_wCoolTimeType)
{
ITEM_COOLTIME_ITER it = cool_time_table_.find(item_info->m_wCoolTimeType);
if (it == cool_time_table_.end())
{
ITEM_COOLTIME_INFO item_cooltime_info;
item_cooltime_info.m_wCoolTimeType = item_info->m_wCoolTimeType;
item_cooltime_info.m_dwCoolTime = item_info->m_dCoolTime;
cool_time_table_.insert(\
std::make_pair(item_info->m_wCoolTimeType, item_cooltime_info));
}
else
{
it->second.m_wCoolTimeType = item_info->m_wCoolTimeType;
it->second.m_dwCoolTime = item_info->m_dCoolTime;
}
}
//__NA_1323_CHAO_TIME_DECREASE_ITEM
item_info->m_byChaoTimeDec = GetDataBYTE("ChaoTimeDec", row_no);
// m_wSpecialEffect ??? m_wQuestCode (2006. 8. 7.)
item_info->m_wQuestCode = GetDataWORD("QuestCode", row_no);
// (REF) Lottery index group
item_info->m_MaterialCode = GetDataWORD("MaterialCode", row_no);
// (WARNING) ??????????
//??????????????/MAPCODE/Wax Level?????????????????????????.
item_info->m_wSkillCode = GetDataWORD("SkillCode", row_no);
// _NA_000251_20100727_SOCKET_SYSTEM
item_info->zard_grade = GetDataBYTE(_T("ZardGrade"), row_no);
item_info->zard_item_option_kind = GetDataBYTE(_T("ZardOptionKind"), row_no);
item_info->zard_success_per = GetDataWORD(_T("ZardSuccesPer"), row_no);
item_info->m_ExchangedItem = GetDataWORD("ExchangedItem", row_no);
item_info->m_RidingClass.value = GetDataBYTE("EqRidingClass", row_no);
//------------------------------------------------------------------------------------------
// 2006/3/20 : ???????
item_info->m_wDivLimitStr = GetDataWORD("DivLimitStr", row_no);
item_info->m_wDivLimitDex = GetDataWORD("DivLimitDex", row_no);
item_info->m_wDivLimitVit = GetDataWORD("DivLimitVit", row_no);
item_info->m_wDivLimitInt = GetDataWORD("DivLimitInt", row_no);
item_info->m_wDivLimitSpr = GetDataWORD("DivLimitSpr", row_no);
item_info->m_wDivLimitSkill1 = GetDataWORD("DivLimitSkill1", row_no);
item_info->m_wDivLimitSkill2 = GetDataWORD("DivLimitSkill2", row_no);
item_info->m_wDivPhyMinDamage = GetDataWORD("DivPhyMinDamage", row_no);
item_info->m_wDivPhyMaxDamage = GetDataWORD("DivPhyMaxDamage", row_no);
item_info->m_wDivMagicMinDamage = GetDataWORD("DivMagicMinDamage", row_no);
item_info->m_wDivMagicMaxDamage = GetDataWORD("DivMagicMaxDamage", row_no);
item_info->m_wDivPhyDef = GetDataWORD("DivPhyDef", row_no);
#if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_)
item_info->m_wDivMagicDef = GetDataWORD("DivMagicDef", row_no);
#endif
//------------------------------------------------------------------------------------------
//??????????
// m_wACCode??ep2 AC????????smalltype
item_info->m_wACCode = GetDataBYTE("ACCode", row_no);
item_info->m_byACReferenceID = GetDataBYTE("ACReferenceID", row_no);
if (item_info->m_wACCode == 0 && item_info->m_byACReferenceID != 0)
{
SUNLOG(eCRITICAL_LOG,
"ItemCode|%u|m_wACCode|%d|m_byACReferenceID|%d|"
"If [ref_id] is not 0, [ACcode] must not be 0",
item_info->m_Code, item_info->m_wACCode, item_info->m_byACReferenceID);
}
//------------------------------------------------------------------------------------------
// ?????????
item_info->m_wElitePhyMinDamage = GetDataWORD("ElitePhyMinDamage", row_no);
item_info->m_wElitePhyMaxDamage = GetDataWORD("ElitePhyMaxDamage", row_no);
item_info->m_wEliteMagicMinDamage = GetDataWORD("EliteMagicMinDamage", row_no);
item_info->m_wEliteMagicMaxDamage = GetDataWORD("EliteMagicMaxDamage", row_no);
item_info->m_wElitePhyDef = GetDataWORD("ElitePhyDef", row_no);
#if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_)
item_info->m_wEliteMagicDef = GetDataWORD("EliteMagicDef", row_no);
#endif
//------------------------------------------------------------------------------------------
// ???????????
item_info->m_wUniPhyMinDamage = GetDataWORD("UniPhyMinDamage", row_no);
item_info->m_wUniPhyMaxDamage = GetDataWORD("UniPhyMaxDamage", row_no);
item_info->m_wUniMagicMinDamage = GetDataWORD("UniMagicMinDamage", row_no);
item_info->m_wUniMagicMaxDamage = GetDataWORD("UniMagicMaxDamage", row_no);
item_info->m_wUniPhyDef = GetDataWORD("UniPhyDef", row_no);
#if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_)
item_info->m_wUniMagicDef = GetDataWORD("UniMagicDef", row_no);
#endif
#if SUN_CODE_BACKUP
// ?????:??????????
item_info->m_wItemListType = GetDataWORD("ItemListType", row_no);
#endif
#ifdef _NA_20100307_BETAKEY_SYSTEM
item_info->m_betakey = GetDataInt("BetaKeyCode", row_no);
#endif
//------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
// ?????????
//
//------------------------------------------------------------------------------------------
// ????????????
// Rule: ?????????????????.
switch (item_info->m_ChargeSubType)
{
#ifdef _NA_008440_20150818_ADD_CHARGE_SUB_IMMEDIATELY_USE
case eCHARGE_SUB_IMMEDIATELY_USE:
case eCHARGE_SUB_IMMEDIATELY_USE_AND_DELETE:
#endif // _NA_008440_20150818_ADD_CHARGE_SUB_IMMEDIATELY_USE
case eCHARGE_SUB_FIXED_AMOUNT:
case eCHARGE_SUB_FIXED_AMOUNT_EX:
case eCHARGE_SUB_FIXED_QUANTITY:
case eCHARGE_SUB_COORDINATE: // (WAVERIX) ??????????.
case eCHARGE_SUB_FIXED_AMOUNT_WAIT:
case eCHARGE_SUB_FATE:
case eCHARGE_SUB_COORDINATE_EX:
case eCHARGE_SUB_RIDER_WITH_PART:
case eCHARGE_SUB_RIDER_WITH_PART_NOTIMER: //?????????????????????????????
case eCHARGE_SUB_FIXED_AMOUNT_EX2:
// CN data allows stacked charge items; keep script DupNum.
break;
}
switch (item_info->m_wType)
{
case eITEMTYPE_TWOHANDAXE:
case eITEMTYPE_TWOHANDSWORD:
case eITEMTYPE_ONEHANDSWORD:
case eITEMTYPE_SPEAR:
case eITEMTYPE_WHIP:
case eITEMTYPE_DAGGER:
case eITEMTYPE_ONEHANDCROSSBOW:
case eITEMTYPE_ETHERWEAPON:
case eITEMTYPE_SCIMITAR:
case eITEMTYPE_STAFF:
case eITEMTYPE_ORB:
case eITEMTYPE_GUNTLET: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC
case eITEMTYPE_POLEARM: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC
case eITEMTYPE_HELLROID_1: //_NA_000000_20130812_NEW_CHARACTER_HELLROID
case eITEMTYPE_ARCBLADE: //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
assert(item_info->m_byDupNum == 1);
if (item_info->m_byDupNum != 1) {
LOG_ITEM_VIOLATION_DUPLICATE(item_info->m_Code, item_info->m_byDupNum, "WeaponItem");
item_info->m_byDupNum = 1;
}
break;
// ????
case eITEMTYPE_ARMOR:
case eITEMTYPE_PROTECTOR:
case eITEMTYPE_HELMET:
case eITEMTYPE_PANTS:
case eITEMTYPE_BOOTS:
case eITEMTYPE_GLOVE:
case eITEMTYPE_BELT:
case eITEMTYPE_SHIRTS:
assert(item_info->m_byDupNum == 1);
if (item_info->m_byDupNum != 1) {
LOG_ITEM_VIOLATION_DUPLICATE(item_info->m_Code, item_info->m_byDupNum, "ArmorItem");
item_info->m_byDupNum = 1;
}
break;
// ????
case eITEMTYPE_RING:
case eITEMTYPE_NECKLACE:
assert(item_info->m_byDupNum == 1);
if (item_info->m_byDupNum != 1) {
LOG_ITEM_VIOLATION_DUPLICATE(item_info->m_Code, item_info->m_byDupNum, "Accessory");
item_info->m_byDupNum = 1;
}
break;
case eITEMTYPE_BERSERKER_SACCESSORY :
case eITEMTYPE_DRAGON_SACCESSORY:
case eITEMTYPE_VALKYRIE_SACCESSORY:
case eITEMTYPE_SHADOW_SACCESSORY:
case eITEMTYPE_ELEMENTALIST_SACCESSORY:
case eITEMTYPE_MYSTIC_SPECIAL_ACCESSORY1: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC
case eITEMTYPE_HELLROID_SPECIAL_ACCESSORY1: //_NA_000000_20130812_NEW_CHARACTER_HELLROID
case eITEMTYPE_WITCHBLADE_SPECIAL_ACCESSORY1: //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
case eITEMTYPE_ELEMENTALIST_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_ALLCLASS_CHAOSEYE: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_BERSERKER_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_DRAGON_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_VALKYRIE_SHADOW_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_MYSTIC_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_HELLROID_WITCHBLADE_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
assert(item_info->m_byDupNum == 1);
if (item_info->m_byDupNum != 1) {
LOG_ITEM_VIOLATION_DUPLICATE(item_info->m_Code, item_info->m_byDupNum, "SpecialAccessory");
item_info->m_byDupNum = 1;
}
break;
}; //end 'switch' for modify duplicable item
switch (item_info->m_wType)
{
case eITEMTYPE_TWOHANDAXE:
case eITEMTYPE_TWOHANDSWORD:
case eITEMTYPE_ONEHANDSWORD:
case eITEMTYPE_SPEAR:
case eITEMTYPE_WHIP:
case eITEMTYPE_DAGGER:
case eITEMTYPE_ONEHANDCROSSBOW:
case eITEMTYPE_ETHERWEAPON:
case eITEMTYPE_SCIMITAR:
case eITEMTYPE_STAFF:
case eITEMTYPE_ORB:
case eITEMTYPE_GUNTLET: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC
case eITEMTYPE_POLEARM: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC
case eITEMTYPE_HELLROID_1: //_NA_000000_20130812_NEW_CHARACTER_HELLROID
case eITEMTYPE_ARCBLADE: //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
assert(item_info->m_wEqPos == eEQUIPCONTAINER_WEAPON);
if (item_info->m_wEqPos != eEQUIPCONTAINER_WEAPON)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_WEAPON);
}
break;
// ???
case eITEMTYPE_ARMOR:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_ARMOR);
if (item_info->m_wEqPos != eEQUIPCONTAINER_ARMOR)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_ARMOR);
}
break;
case eITEMTYPE_PROTECTOR:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_PROTECTOR);
if (item_info->m_wEqPos != eEQUIPCONTAINER_PROTECTOR)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_PROTECTOR);
}
break;
case eITEMTYPE_HELMET:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_HELMET);
if (item_info->m_wEqPos != eEQUIPCONTAINER_HELMET)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_HELMET);
}
break;
case eITEMTYPE_PANTS:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_PANTS);
if (item_info->m_wEqPos != eEQUIPCONTAINER_PANTS)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_PANTS);
}
break;
case eITEMTYPE_BOOTS:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_BOOTS);
if (item_info->m_wEqPos != eEQUIPCONTAINER_BOOTS)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_BOOTS);
}
break;
case eITEMTYPE_GLOVE:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_GLOVE);
if (item_info->m_wEqPos != eEQUIPCONTAINER_GLOVE)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_GLOVE);
}
break;
case eITEMTYPE_BELT:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_BELT);
if (item_info->m_wEqPos != eEQUIPCONTAINER_BELT)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_BELT);
}
break;
case eITEMTYPE_SHIRTS:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_SHIRTS);
if (item_info->m_wEqPos != eEQUIPCONTAINER_SHIRTS)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_SHIRTS);
}
break;
// ????
case eITEMTYPE_RING:
if (item_info->m_wEqPos != eEQUIPCONTAINER_RING1 &&
item_info->m_wEqPos != eEQUIPCONTAINER_CHARGE1 &&
item_info->m_wEqPos != eEQUIPCONTAINER_CHARGE2 &&
item_info->m_wEqPos != eEQUIPCONTAINER_CHARGE3 &&
item_info->m_wEqPos != eEQUIPCONTAINER_CHARGE4 &&
item_info->m_wEqPos != eEQUIPCONTAINER_CHARGE5 &&
item_info->m_wEqPos != eEQUIPCONTAINER_PC_ROOM1 &&
item_info->m_wEqPos != eEQUIPCONTAINER_PC_ROOM2 &&
item_info->m_wEqPos != eEQUIPCONTAINER_PC_ROOM3)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_RING1);
}
break;
case eITEMTYPE_NECKLACE:
assert(item_info->m_wEqPos == eEQUIPCONTAINER_NECKLACE);
if (item_info->m_wEqPos != eEQUIPCONTAINER_NECKLACE)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u\n",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_NECKLACE);
}
break;
case eITEMTYPE_BERSERKER_SACCESSORY:
case eITEMTYPE_DRAGON_SACCESSORY:
case eITEMTYPE_VALKYRIE_SACCESSORY:
case eITEMTYPE_SHADOW_SACCESSORY:
case eITEMTYPE_ELEMENTALIST_SACCESSORY:
case eITEMTYPE_MYSTIC_SPECIAL_ACCESSORY1: // _NA_004965_20120613_NEW_CHARACTER_MYSTIC
case eITEMTYPE_HELLROID_SPECIAL_ACCESSORY1: //_NA_000000_20130812_NEW_CHARACTER_HELLROID
case eITEMTYPE_WITCHBLADE_SPECIAL_ACCESSORY1: //_NA_007514_20140828_NEW_CHARACTER_WITCHBLADE
case eITEMTYPE_ALLCLASS_CHAOSEYE: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_ELEMENTALIST_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_BERSERKER_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_DRAGON_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_VALKYRIE_SHADOW_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_MYSTIC_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
case eITEMTYPE_HELLROID_WITCHBLADE_KALVUS_ACCESSORY: //_NA_007827_20141117_ADD_ACCESSORY_TYPE
if (item_info->m_wEqPos != eEQUIPCONTAINER_SACCESSORY1)
{
SUNLOG(eDEV_LOG, "ItemCode|%u|EqPos:%u != value:%u",
item_info->m_Code, item_info->m_wEqPos, eEQUIPCONTAINER_SACCESSORY1);
}
break;
case eITEMTYPE_RIDER_PARTS:
{
const eRIDER_CLASS& rider = item_info->m_RidingClass;
if (!(rider.value == rider.Charger ||
rider.value == rider.Leopard ||
rider.value == rider.OrcPig ||
rider.value == rider.Kalvus))
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|RidingClass(%u) is not a known rider class",
item_info->m_Code, rider.value);
}
if (!(item_info->m_wEqPos == eRIDER_PARTS_POS::HeadPart ||
item_info->m_wEqPos == eRIDER_PARTS_POS::BodyPart ||
item_info->m_wEqPos == eRIDER_PARTS_POS::LegsPart))
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|EqPos:%u is not a rider parts slot",
item_info->m_Code, item_info->m_wEqPos);
}
}
break;
}
// ???????
item_info->m_bApplyItemDistribution = (GetDataBYTE("UseItemDistribution", row_no) != 0);
#ifdef _NA_003033_20110831_DICECAST_ITEM_ROUTING
item_info->dice_cast_type = GetDataBYTE("DiceCast", row_no);
#endif //_NA_003033_20110831_DICECAST_ITEM_ROUTING
#ifdef _NA_003740_20210624_ADDBOXKEY
item_info->m_BoxKeyIndex=GetDataDWORD("BoxKey", row_no); //??????????? by:???????? 2021-07-23
#endif //_NA_003740_20210624_ADDBOXKEY
//------------------------------------------------------------------------------------------
// CHANGES: f110414.1L, ????????? ????SubTypeDetailed???
item_info->_UpdateSubTypeDetailedValue();
//------------------------------------------------------------------------------------------
// Event Handling
//
switch (item_info->m_wType)
{
case eITEMTYPE_RENDER_EFFECT_ITEM:
render_effect_item_list_.push_back((SLOTCODE)item_info->m_Code);
break;
}
#ifdef _DEBUG
static BASE_ITEMINFO* pPreInfo = 0;
pPreInfo = item_info;//???????????????????????!!
#endif
// ?????????.
CheckValidity(item_info);
previous_item_code_for_debugging = item_code;
// CHANGES: f110802.3L
item_table_.client_checksum_array_[item_code - 1] =
util::StreamHashKey::GetMemoryHashKey(item_info, sizeof(*item_info));
}
// (CHANGES) (f100505.1L) ??????? O(1) ??????????????????
if (!FlowControl::FCAssert(_BuildReference(max_rows))) {
return false;
}
loaded_ = true;
return true;
}
//==================================================================================================
void
ItemInfoParser::CheckValidity(BASE_ITEMINFO* item_info)
{
const SLOTCODE item_code = item_info->m_Code;
const eCHARGE_SUB_TYPE charge_sub_type = eCHARGE_SUB_TYPE(item_info->m_ChargeSubType);
//Enchant
if (SCItemSlot::CanUseMixture(item_info, MIXTURE_ENCHANT))
{
if (item_info->IsWeapon() == 0 &&
item_info->IsArmor() == 0 &&
item_info->m_wType != eITEMTYPE_WINGS) // CHANGES: f111007.1L, added rule
{ // + rider parts ???????????????.
LOG_ITEM_VIOLATION_FUCTION(item_code, "Not weapon, armor, or wings", "Enchant");
}
}
//RankUp
if (SCItemSlot::CanUseMixture(item_info, MIXTURE_RANKUP))
{
if (item_info->IsChargeItem()) {
if (charge_sub_type != eCHARGE_SUB_FIXED_AMOUNT_WAIT) {
LOG_ITEM_VIOLATION_FUCTION(item_code, "Charge item", "Rankup");
}
}
if (item_info->IsElite()) {
LOG_ITEM_VIOLATION_FUCTION(item_code, "Elite item", "Rankup");
}
if (item_info->IsUnique()) {
LOG_ITEM_VIOLATION_FUCTION(item_code, "Unique item", "Rankup");
}
if (item_info->IsWeapon() == 0 &&
item_info->IsArmor() == 0 &&
item_info->IsAccessory() == 0)
{
LOG_ITEM_VIOLATION_FUCTION(item_code, \
"Not weapon, armor, or wings", "Rankup");
}
if (item_info->m_wSubType == eITEMSUBTYPE_FATE)
{
LOG_ITEM_VIOLATION_FUCTION(item_code, "Lucky item", "Rankup");
}
}
//Crystalize
if (SCItemSlot::CanUseMixture(item_info, MIXTURE_CRYSTALIZE))
{
if (item_info->IsChargeItem() && (item_info->m_wSubType != eITEMSUBTYPE_FATE))
{
if (item_info->m_ChargeSubType != eCHARGE_SUB_FIXED_AMOUNT_WAIT) {
LOG_ITEM_VIOLATION_FUCTION(item_code, "Charge item", "Crystalize");
}
}
// [10/26/2009 namka199]???????????????????????????????
//??????????????
if (item_info->IsUnique())
{
LOG_ITEM_VIOLATION_FUCTION(item_code, "Unique item", "Crystalize");
}
if (item_info->IsWeapon() == 0 &&
item_info->IsArmor() == 0 &&
item_info->IsAccessory() == 0)
{
LOG_ITEM_VIOLATION_FUCTION(item_code, \
"Not weapon, armor, or wings", "Crystalize");
}
}
//Compose
if (SCItemSlot::CanUseMixture(item_info, MIXTURE_COMPOSE))
{
// noting to do
};
//ExtraStone
if (SCItemSlot::CanUseMixture(item_info, MIXTURE_EXTRASTONE))
{
// ???????????????????????
if (item_info->IsWeapon() == 0 &&
item_info->IsArmor() == 0 &&
item_info->IsAccessory() == 0 &&
item_info->IsSpecialAccessory() == 0)
{
LOG_ITEM_VIOLATION_FUCTION(item_code, \
"Not weapon, armor, accessory, or special accessory", "Extra Stone");
}
}
// ??????????.
/* ????SubType??????LV?????????????????????????????????????. - arycoat 2012.07.20
if (item_info->GetSubTypeDetail() == ItemSubTypeDetail::kInvalid)
{
switch(item_info->m_wSubType)
{
case eITEMSUBTYPE_ELITE_SSQ:
case eITEMSUBTYPE_ELITE:
case eITEMSUBTYPE_UNIQUE:
case eITEMSUBTYPE_FATE:
case eITEMSUBTYPE_RARE:
case eITEMSUBTYPE_GENERAL:
{
SUNLOG(eCRITICAL_LOG,
_T( "|???????????????????
"|ItemCode = %u, SubType = %d, ItemLevel = %u|"),
item_code, item_info->m_wSubType, item_info->m_LV);
} break;
default:
break;
}
}*/
#if !defined(_NA001605_EP2_ATTRIBUTES_RENEWAL_)
// ???????????????
if (item_info->IsWeapon())
{
if (item_info->m_byMeleeType == 0 || item_info->m_byMeleeType >= eMELEE_TYPE_MAX)
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|Field [m_byMeleeType](%d) invalid, valid range [0~%d]!",
item_code, item_info->m_byMeleeType,eMELEE_TYPE_MAX-1);
item_info->m_byMeleeType = 1;
}
}
// ??????????
if (item_info->IsArmor())
{
if (item_info->m_byArmorType == 0 || item_info->m_byArmorType >= eARMOR_TYPE_MAX)
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|Field [m_byArmorType](%d) invalid, valid range [0~%d]!",
item_code, item_info->m_byArmorType,eARMOR_TYPE_MAX-1);
item_info->m_byArmorType = 1;
}
}
#endif
// CHANGES: f110329.5L, ?????????????????
if (item_info->IsExistInvenOptions() && item_info->IsExistEquipOptions())
{
SUNLOG(eDEV_LOG,
_T("ItemCode|%u|Default options should apply to only one slot. ")
_T("ex: apply options on equip, or apply options on inventory?"),
item_code);
}
// ?????????????
for (int op = 0; op < _countof(item_info->m_wOptionIndex); ++op)
{
if (!CheckOptionValidity(item_info->m_wOptionIndex[op],
item_info->m_byOptionType[op],
item_info->m_iOptionValue[op]))
{
SUNLOG(eCRITICAL_LOG,
"|ItemCode=%u|Invalid option field|OptionIndex=%d|OptionType=%d|OptionValue=%d|",
item_code,
item_info->m_wOptionIndex[op],
item_info->m_byOptionType[op],
item_info->m_iOptionValue[op]);
}
}
if (item_info->m_wType == eITEMTYPE_PET)
{
#ifdef _NA_007854_20141127_MODIFY_PET_CHARGE_SUBTYPE
if (charge_sub_type != eCHARGE_SUB_GENERAL &&
charge_sub_type != eCHARGE_SUB_FIXED_QUANTITY &&
charge_sub_type != eCHARGE_SUB_FIXED_AMOUNT)
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|Invalid pet subtype(%u)",
item_code, charge_sub_type);
}
#else
if (charge_sub_type != eCHARGE_SUB_GENERAL &&
charge_sub_type != eCHARGE_SUB_FIXED_QUANTITY)
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|Invalid Pet SubType(%u)",
item_code, charge_sub_type);
}
#endif //_NA_000000_20141127_MODIFY_PET_CHARGE_SUBTYPE
}
if (item_info->m_wType == eITEMTYPE_RIDER || item_info->m_wType == eITEMTYPE_RIDER_PARTS)
{
if (charge_sub_type != eCHARGE_SUB_RIDER_WITH_PART &&
charge_sub_type != eCHARGE_SUB_RIDER_WITH_PART_NOTIMER)
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|Field [ChargeSubType](%u) invalid value",
item_code, charge_sub_type);
}
}
if (item_info->m_bPossessionItem != false)
{
if (item_info->m_byMaterialType == 0)
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|Field [MaterialType](%u) invalid value \n",
item_code, item_info->m_byMaterialType);
}
if (item_info->m_byPopup == 0)
{
SUNLOG(eCRITICAL_LOG, "ItemCode|%u|Field [m_byPopup](%u) invalid value \n",
item_code, item_info->m_byPopup);
}
}
// CN item scripts use combined TradeSellType bitmasks (1, 65, 259, ...).
// Those are loaded as-is; do not spam console for drop-without-trade.
#ifdef _NA002217_100728_EP2_PERK_SYSTEM_
if (item_info->m_wType == eITEMTYPE_PERK_CASH_ITEM)
{ // f100915.3L, ???????????????????????????.
const bool is_desirable_charge_sub_type = \
item_info->m_ChargeSubType == eCHARGE_SUB_FIXED_AMOUNT_EX;
__UNUSED(is_desirable_charge_sub_type);
assert(is_desirable_charge_sub_type);
if (item_info->m_byDupNum != 1 ||
(item_info->IsMaterialWaste() == false))
{
SUNLOG(eCRITICAL_LOG,
_T("|ItemCode=%d|Msg=Perk cash item rule violated, forced correction|")
_T("|DupNum=1<-(%d), MaterialType=2<-(%d)|ChargeSubType=2<-(%d)|"),
item_code, item_info->m_byDupNum,
item_info->m_byMaterialType, item_info->m_ChargeSubType);
//
item_info->m_ChargeSubType = eCHARGE_SUB_FIXED_AMOUNT_EX;
item_info->m_byDupNum = 1;
item_info->m_byMaterialType = eITEM_MATERIAL_TYPE_CAN_USE;
}
};
#endif
// _NA_000251_20100727_SOCKET_SYSTEM
// ???ZARD???.
if (item_info->m_wType == eITEMTYPE_SOCKET_ZARD || item_info->m_wType == eITEMTYPE_SOCKET_ZARD_RINGS) // xiaomi add ItemInfoParser::CheckValidity(BASE_ITEMINFO* item_info)
{
if (item_info->zard_grade >= kZardGradeMax)
{
SUNLOG(eCRITICAL_LOG,
_T("|%s |ZARD grade out of range, initialized to 0.| ItemCode=%u, grade=%d |"),
__FUNCTION__,
item_info->m_Code,
item_info->zard_grade);
item_info->zard_grade = 0;
}
if (item_info->zard_item_option_kind >= _countof(g_ITEM_OPTION))
{
SUNLOG(eCRITICAL_LOG,
_T("|%s |ZARD option out of range, initialized to 0.| ItemCode=%u, option=%d |"),
__FUNCTION__,
item_info->m_Code,
item_info->zard_item_option_kind);
item_info->zard_item_option_kind = 0;
}
}
// ????ZARD???????????.
if (item_info->m_wType == eITEMTYPE_SOCKET_COMPOSE_ADDITIVE)
{
enum { kMaxZardSuccessPer = 1000 };
if (item_info->zard_success_per > kMaxZardSuccessPer)
{
SUNLOG(eCRITICAL_LOG,
_T("|%s |ZARD compose success rate out of range, initialized to 0.| ItemCode=%u, success_rate=%d |"),
__FUNCTION__,
item_info->m_Code,
item_info->zard_success_per);
item_info->zard_success_per = 0;
}
if (item_info->m_byDupNum > 1 && (item_info->IsMaterialWaste() == false))
{
SUNLOG(eCRITICAL_LOG,
_T("|%s |ZARD compose additive is stackable but not consumable, set to consumable| ItemCode=%u, DupNum=%u |"),
__FUNCTION__,
item_info->m_Code,
item_info->m_byDupNum);
item_info->m_byMaterialType = eITEM_MATERIAL_TYPE_CAN_USE;
}
}
// ??????????????.
if (item_info->m_wType == eITEMTYPE_STAT_CHANGE)
{
if (item_info->m_ExchangedItem < 0 || item_info->m_ExchangedItem > SOCKET_MAX)
{
SUNLOG(eCRITICAL_LOG,
_T("|%s |Socket count invalid, initialized to 0.| ItemCode=%u, sockets=%d |"),
__FUNCTION__,
item_info->m_Code,
item_info->m_ExchangedItem);
item_info->m_ExchangedItem = 0;
}
enum { kMaxSocketRatioType = 255 };
const WORD fixed_ratio_type = item_info->m_wSubType;
if (fixed_ratio_type < 0 || fixed_ratio_type >= kMaxSocketRatioType)
{
SUNLOG(eCRITICAL_LOG,
_T("|%s |Socket ratio type invalid, initialized to 0.| ItemCode=%u, ratio_type=%u |"),
__FUNCTION__,
item_info->m_Code,
item_info->m_wSubType);
item_info->m_wSubType = 0;
}
if (item_info->m_byDupNum > 1 && (item_info->IsMaterialWaste() == false))
{
SUNLOG(eCRITICAL_LOG,
_T("|%s |Socket reset item is stackable but not consumable, set to consumable| ItemCode=%u, DupNum=%u |"),
__FUNCTION__,
item_info->m_Code,
item_info->m_byDupNum);
item_info->m_byMaterialType = eITEM_MATERIAL_TYPE_CAN_USE;
}
}
//#ifdef _NA_004035_20120227_COSTUME_ITEM
// // ???????????????????..
// if (item_info->m_wType == eITEMTYPE_COSTUME)
// {
// if (item_info->IsMaterialWaste())
// {
// SUNLOG(eCRITICAL_LOG,
// _T("|%s |%d |????????????????????????????????| ItemCode=%u??MaterialType=%u |"),
// __FUNCTION__,
// __LINE__,
// item_info->m_Code,
// item_info->m_byMaterialType);
// //setting
// item_info->m_byMaterialType = eITEM_MATERIAL_TYPE_CAN_USE_NOT_DELETE;
// }
// }
//#endif // _NA_004035_20120227_COSTUME_ITEM
// last order.
FlowControl::FCAssert(\
nsSlot::ItemRuleInfo::PrefetchRuleInfo(&item_info->item_rule_info, item_info));
}
//==================================================================================================
// CHANGES: f110408.3L, ???????????????????????. _SERVER contents
void ItemInfoParser::ChangeToTimeExpirationItem(CODETYPE item_code)
{
// (CHANGES) (f100505.1L) ??????????+??????????
if (item_code == 0 || item_code > USHRT_MAX) {
assert(!"Index out of range");
return;
}
--item_code;
BASE_ITEMINFO* item_info = item_table_.array_[item_code];
if (item_info == NULL) {
assert(!"Item not found");
return;
};
item_info->time_expiration_item = true;
}
//==================================================================================================
BOOL
ItemInfoParser::LoadScript(eSCRIPT_CODE script_code, BOOL reloaded)
{
switch (script_code)
{
case SCRIPT_ACCESSORYITEMINFO:
case SCRIPT_ARMORITEMINFO:
case SCRIPT_WASTEITEMINFO:
case SCRIPT_WEAPONITEMINFO:
case SCRIPT_CHARGEITEMINFO:
return _Load(reloaded);
}
return false;
}
#if defined (_NA_0_20091208_VENDOR_ITEM_SEARCH) || (defined(_DH_GM_ITEM_WINDOW) && !defined(_SERVER))
void ItemInfoParser::PushItemName(TCHAR* stName, DWORD ItemCode, TCHAR* description_string /*=NULL*/)
{
_ITEM_NAME_INFO temp;
temp.m_stName = stName;
temp.m_dwItemCode = ItemCode;
temp.description_string = description_string;
item_name_code_table_.push_back(temp);
}
DWORD ItemInfoParser::GetItemNameforCode(char *stName)
{
ITEM_NAME_INFO::iterator itr;
for (itr = item_name_code_table_.begin(); itr != item_name_code_table_.end(); ++itr)
{
//sInfo = itr;
//if (itr->m_stName.IndexOf(nStName, 0) != -1)
if (itr->m_stName.find(stName, 0) != std::string::npos)
{
strncpy(stName, itr->m_stName.c_str(), MAX_VENDOR_SEARCH_LENGTH);
return itr->m_dwItemCode;
}
}
return 0;
}
ITEM_NAME_INFO::iterator ItemInfoParser::GetItemNamesBegin()
{
return item_name_code_table_.begin();
}
ITEM_NAME_INFO::iterator ItemInfoParser::GetItemNamesEnd()
{
return item_name_code_table_.end();
}
DWORD ItemInfoParser::GetItemAllCount()
{
return item_name_code_table_.size();
}
#endif//_NA_0_20091208_VENDOR_ITEM_SEARCH
// CHANGES: f110802.3L, _NA000000_SPEED_HACK_PREVENTION_SUPPORT
bool ItemInfoParser::CheckChecksum(CODETYPE item_code) const
{
if (item_code == 0 || item_code > USHRT_MAX) {
return NULL;
}
--item_code;
const BASE_ITEMINFO* item_info = item_table_.array_[item_code];
if (item_info == NULL) {
return true;
};
ulong checksum = item_table_.client_checksum_array_[item_code];
ulong runtime_checksum = util::StreamHashKey::GetMemoryHashKey(item_info, sizeof(*item_info));
if (checksum != runtime_checksum) {
return false;
}
return true;
}