//////////////////////////////////////////////////////////////////////////////////////////////////// /// /// @file RandomItemParser.cpp /// @author hukim /// @email silped@gmail.com /// @brief [2011/11/22 by hukim] This is created.\n /// //////////////////////////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include ".\RandomItemParser.h" // header #include "SCSlotHeader.h" #include "SCItemSlot.h" #include "SCItemSlotContainer.h" #include "ItemInfoParser.h" #include "PacketStruct_CG.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // REGION : Constructor & Destructor //////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef _SERVER #ifdef _NA_000000_20140103_MALLOC_CHANGE_TO_TALLOCATE_CREATEITEM RandomItemParser::RandomItemParser() { } #else RandomItemParser::RandomItemParser() : item_info_pool_(kItemInfoPoolSize) { } #endif //_NA_000000_20140103_MALLOC_CHANGE_TO_TALLOCATE_CREATEITEM #else RandomItemParser::RandomItemParser() { } #endif // _SERVER RandomItemParser::~RandomItemParser() { } //////////////////////////////////////////////////////////////////////////////////////////////////// // REGION : Public //////////////////////////////////////////////////////////////////////////////////////////////////// BOOL RandomItemParser::LoadScript(eSCRIPT_CODE script_code, BOOL is_reload) { created_item_infos_.clear(); const bool reload = (is_reload == TRUE); switch (script_code) { case SCRIPT_RANDOM_ITEM_VALUE: if (!FlowControl::FCAssert(value_manager_.LoadScript(*this, reload))) { return FALSE; } break; case SCRIPT_RANDOM_ITEM_OPTION_TYPE: if (!FlowControl::FCAssert(option_manager_.LoadScript(*this, reload))) { return FALSE; } break; case SCRIPT_RANDOM_ITEM_INFO: if (!FlowControl::FCAssert(item_manager_.LoadScript(*this, reload))) { return FALSE; } break; case SCRIPT_RANDOM_ITEM_KEY: if (!FlowControl::FCAssert(key_manager_.LoadScript(*this, reload))) { return FALSE; } break; default: return FALSE; } return TRUE; } bool RandomItemParser::EnableRandomize(const BASE_ITEMINFO& item_info) const { return (item_manager_.GetItem(item_info.m_Code) != NULL); } RandomItemParser::OptionParam RandomItemParser::RandomizeOption( const RandomValueTypeGrade::Value value_type_grade, const BASE_ITEMINFO& item_info) const { OptionParam param; const RandomItem* const random_item = item_manager_.GetItem(item_info.m_Code); if (random_item == NULL) { return param; } STLX_HASH_SET sel_option_kinds; const RandomItem::Options& options = random_item->options; for (RandomItem::Options::const_iterator it = options.begin(); it != options.end(); ++it) { const RandomOption* const option = *it; if (option == NULL) { return param; } RatioSelector option_part_selector; const RandomOption::Parts& option_parts = option->parts; for (RandomOption::Parts::const_iterator it2 = option_parts.begin(); it2 != option_parts.end(); ++it2) { const RandomOptionPart& option_part = *it2; if (!option_part_selector.Add(option_part.order, option_part.ratio)) { return param; } } const RandomOptionPart* option_part(NULL); while (option_part_selector.GetCount() > 0) { const RandomOptionPart::Ratio ratio = rand() % option_part_selector.GetTotalRatio(); RandomOptionPart::Order part_order = 0; if (!option_part_selector.Select(ratio, part_order)) { return param; } option_part = option->GetPart(part_order); if (option_part == NULL) { return param; } if (option_part->is_empty) { break; } if (sel_option_kinds.find(option_part->kind) == sel_option_kinds.end()) { sel_option_kinds.insert(option_part->kind); break; } if (!option_part_selector.Remove(part_order)) { return param; } option_part = NULL; } if (option_part == NULL) { return param; } const RandomOption::Index option_index = option->index; const RandomOptionPart::Order option_order = option_part->order; RandomValue::Index value_index = 0; RandomValuePart::Order value_order = 0; if (option_part->is_empty == false) { const RandomValue* const random_value = option_part->GetValue(value_type_grade); if (random_value == NULL) { return param; } value_index = random_value->index; const RandomValuePart* const value_part = random_value->SelectPart(); if (value_part == NULL) { return param; } value_order = value_part->order; } const RandomKey* const random_key = key_manager_.GetKey(option_index, option_order, value_index, value_order); if (random_key == NULL) { return param; } if (param.size >= _countof(param.keys)) { return param; } param.keys[param.size] = random_key->key; ++param.size; } param.is_valid = true; return param; } namespace local { void ClearOptionPart(BASE_ITEMINFO& OUT item_info) { ::ZeroMemory(item_info.m_byOptionExEffect, sizeof(item_info.m_byOptionExEffect)); ::ZeroMemory(item_info.m_wOptionIndex, sizeof(item_info.m_wOptionIndex)); ::ZeroMemory(item_info.m_byOptionType, sizeof(item_info.m_byOptionType)); ::ZeroMemory(item_info.m_iOptionValue, sizeof(item_info.m_iOptionValue)); } } bool RandomItemParser::CreateOption(OptionParam& INOUT param, BASE_ITEMINFO& OUT item_info) const { if (param.is_valid == false || param.size == 0 || param.size > _countof(param.keys)) { return false; } local::ClearOptionPart(item_info); uint8_t not_empty_option_size = 0; for (uint8_t i = 0; i < param.size; ++i) { const OptionParam::Key param_key = param.keys[i]; const RandomKey* const random_key = key_manager_.GetKey(param_key); if (random_key == NULL) { local::ClearOptionPart(item_info); return false; } const RandomOptionPart* const option_part = random_key->option_part; if (option_part == NULL) { local::ClearOptionPart(item_info); return false; } if (option_part->is_empty) { continue; } const RandomValuePart* const value_part = random_key->value_part; if (value_part == NULL) { local::ClearOptionPart(item_info); return false; } if (ns_formula::CheckOptionValidity( option_part->kind, option_part->value_type, value_part->my_value) == false) { local::ClearOptionPart(item_info); return false; } item_info.m_byOptionExEffect[not_empty_option_size] = option_part->active_type; item_info.m_wOptionIndex[not_empty_option_size] = option_part->kind; item_info.m_byOptionType[not_empty_option_size] = option_part->value_type; item_info.m_iOptionValue[not_empty_option_size] = value_part->my_value; param.grades[not_empty_option_size] = value_part->grade; ++not_empty_option_size; } return true; } namespace local { bool IsValidItemState(const SCItemSlot& item) { #ifdef _SERVER return (!item.IsLocked() && !item.IsBlocked() && !item.IsUserBlocked() && item.IsContainValidItem()); #else return (!item.IsBlocked() && !item.IsUserBlocked() && item.IsContainValidItem()); #endif } } bool RandomItemParser::EnableItemRandomize( const SCItemSlotContainer& inventory, const POSTYPE request_item_pos, const POSTYPE target_item_pos, SCItemSlot*& OUT _request_item, SCItemSlot*& OUT _target_item) const { if (inventory.GetSlotType() != SI_INVENTORY) { return false; } if (inventory.ValidStateByConst() == false) { return false; } if (inventory.ValidPos(request_item_pos) == false) { return false; } if (inventory.ValidPos(target_item_pos) == false) { return false; } SCItemSlot* const request_item = static_cast(inventory.GetValidSlotPtr(NULL, request_item_pos)); if (request_item == NULL) { return false; } if (local::IsValidItemState(*request_item) == false) { return false; } const BASE_ITEMINFO* const request_item_info = request_item->GetItemInfo(); if (request_item_info->m_wType != eITEMTYPE_RANDOMIZE_ITEM) { return false; } if (request_item_info->m_wSubType < RandomValueTypeGrade::kMinGrade || request_item_info->m_wSubType > RandomValueTypeGrade::kMaxGrade) { return false; } SCItemSlot* const target_item = static_cast(inventory.GetValidSlotPtr(NULL, target_item_pos)); if (target_item == NULL) { return false; } if (local::IsValidItemState(*target_item) == false) { return false; } if (target_item->EnableRandomize() == false) { return false; } _request_item = request_item; _target_item = target_item; return true; } bool RandomItemParser::GetItemRandomizeRequest( const SCItemSlotContainer& inventory, const POSTYPE request_item_pos, const POSTYPE target_item_pos, MSG_CG_ITEM_RANDOMIZE_SYN& OUT request) const { SCItemSlot* request_item(NULL); SCItemSlot* target_item(NULL); if (EnableItemRandomize(inventory, request_item_pos, target_item_pos, request_item, target_item) == false) { return false; } request.Init(); request.request_item_pos = request_item_pos; request.target_item_pos = target_item_pos; return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// // REGION : Private //////////////////////////////////////////////////////////////////////////////////////////////////// bool RandomItemParser::RandomValueManager::LoadScript( const RandomItemParser& parser, const bool is_reload) { if (is_reload) { random_values_.clear(); } RandomValue::Index prev_index = 0; const int row_size = parser.GetRowSize(); for (int row = 0; row < row_size; ++row) { const RandomValue::Index index = parser.GetDataWORD(_T("Index"), row); if (index < RandomValue::kMinIndex || index > RandomValue::kMaxIndex) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|索引无效.|行 = %d, 索引 = %d|"), __FUNCTION__, __LINE__, row, index ); assert(false); return false; } const RandomValuePart::Order order = parser.GetDataBYTE(_T("Order"), row); if (order < RandomValuePart::kMinOrder || order > RandomValuePart::kMaxOrder) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|订单无效.|行 = %d, 订单 = %d|"), __FUNCTION__, __LINE__, row, order ); assert(false); return false; } const RandomValuePart::Value my_value = parser.GetDataInt(_T("Value"), row); if (my_value < RandomValuePart::kMinValue || my_value > RandomValuePart::kMaxValue) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|值无效.|行 = %d, 值 = %d|"), __FUNCTION__, __LINE__, row, my_value ); assert(false); return false; } const RandomValuePart::Ratio ratio = parser.GetDataWORD(_T("Ratio"), row); if (ratio < RandomValuePart::kMinRatio || ratio > RandomValuePart::kMaxRatio) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|比率无效.|行 = %d, 比率 = %d|"), __FUNCTION__, __LINE__, row, ratio ); assert(false); return false; } const uint8_t grade = parser.GetDataBYTE(_T("Grade"), row); if (grade < RandomValueGrade::kMinGrade || grade > RandomValueGrade::kMaxGrade) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|等级无效.|行 = %d, 等级 = %d|"), __FUNCTION__, __LINE__, row, grade ); assert(false); return false; } const bool is_new_index = (prev_index != index); if (is_new_index) { RandomValues::const_iterator prev_values_it = random_values_.find(prev_index); if (prev_values_it != random_values_.end()) { const RandomValue& prev_random_value = prev_values_it->second; const size_t part_size = prev_random_value.parts.size(); if (part_size < RandomValuePart::kMinOrder || part_size > RandomValuePart::kMaxOrder) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|值部分大小无效.|索引 = %d, 大小 = %d|"), __FUNCTION__, __LINE__, prev_index, part_size ); assert(false); return false; } const RandomValuePart::Ratio ratio_sum = prev_random_value.part_selector.GetTotalRatio(); if (ratio_sum != RandomValuePart::kMaxRatio) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|比率总和无效.|索引 = %d, 总和 = %d|"), __FUNCTION__, __LINE__, prev_index, ratio_sum ); assert(false); return false; } } if (random_values_.find(index) != random_values_.end()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|索引已经存在.|行 = %d, 索引 = %d|"), __FUNCTION__, __LINE__, row, index ); assert(false); return false; } RandomValue random_value; random_value.index = index; random_values_[index] = random_value; prev_index = index; } RandomValues::iterator values_it = random_values_.find(index); if (values_it == random_values_.end()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|未找到索引.|行 = %d, 索引 = %d|"), __FUNCTION__, __LINE__, row, index ); assert(false); return false; } RandomValue& random_value = values_it->second; RandomValue::Parts& parts = random_value.parts; if (order != (parts.size()+1)) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|订单无效.|行 = %d, 订单 = %d|"), __FUNCTION__, __LINE__, row, order ); assert(false); return false; } RandomValuePart part; part.order = order; part.my_value = my_value; part.ratio = ratio; part.grade = static_cast(grade); parts.push_back(part); if (!random_value.part_selector.Add(order, ratio)) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|无法添加比例.|行 = %d, 索引 = %d, 订单 = %d|"), __FUNCTION__, __LINE__, row, index, order ); assert(false); return false; } } return true; } bool RandomItemParser::RandomOptionManager::LoadScript( const RandomItemParser& parser, const bool is_reload) { if (is_reload) { random_options_.clear(); } RandomValue::Index prev_index = 0; const int row_size = parser.GetRowSize(); for (int row = 0; row < row_size; ++row) { const RandomOption::Index index = parser.GetDataWORD(_T("Index"), row); if (index < RandomOption::kMinIndex || index > RandomOption::kMaxIndex) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|索引无效.|行 = %d, 索引 = %d|"), __FUNCTION__, __LINE__, row, index ); assert(false); return false; } const RandomOptionPart::Order order = parser.GetDataBYTE(_T("Order"), row); if (order < RandomOptionPart::kMinOrder || order > RandomOptionPart::kMaxOrder) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|订单无效.|行 = %d, 订单 = %d|"), __FUNCTION__, __LINE__, row, order ); assert(false); return false; } const RandomOptionPart::ActiveType active_type = parser.GetDataBYTE(_T("ExerciseEffect"), row); if (active_type < eITEM_EFFECT_NONE || active_type >= eITEM_EFFECT_UPPERBOUND) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|ExerciseEffect无效.|行 = %d, ExerciseEffect = %d|"), __FUNCTION__, __LINE__, row, active_type ); assert(false); return false; } const RandomOptionPart::Kind kind = parser.GetDataWORD(_T("OptionKind"), row); const RandomOptionPart::ValueType value_type = parser.GetDataBYTE(_T("OptionValueType"), row); const bool is_empty_option = (active_type == eITEM_EFFECT_NONE); if (is_empty_option) { if (kind != 0) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|OptionKind 不为 0.|行 = %d, OptionKind = %d|"), __FUNCTION__, __LINE__, row, kind ); assert(false); return false; } if (value_type != 0) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|OptionValueType 不为 0.|行 = %d, OptionValueType = %d|"), __FUNCTION__, __LINE__, row, value_type ); assert(false); return false; } } else { const eATTR_TYPE attr_kind = g_ITEM_OPTION[kind]; if (kind >= _countof(g_ITEM_OPTION) ) // || attr_kind == eATTR_TYPE_INVALID xiaomi change { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|OptionKind 无效.|行 = %d, OptionKind = %d|"), __FUNCTION__, __LINE__, row, kind ); assert(false); return false; } if (value_type != VALUE_TYPE_VALUE && value_type != VALUE_TYPE_PERCENT_PER_CUR && value_type != VALUE_TYPE_PERCENT_PER_MAX && value_type != VALUE_TYPE_RATIO_VALUE) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|OptionValueType is not valid..|行号= %d, OptionValueType = %d|"), __FUNCTION__, __LINE__, row, value_type ); assert(false); return false; } } const RandomValue* random_values[RandomOptionPart::kValueGradeSize]; ::ZeroMemory(random_values, sizeof(random_values)); RandomValue::Index value_indexes[_countof(random_values)]; ::ZeroMemory(value_indexes, sizeof(value_indexes)); value_indexes[RandomOptionPart::kValueGrade0] = parser.GetDataWORD(_T("RandomValueIndex1"), row); value_indexes[RandomOptionPart::kValueGrade1] = parser.GetDataWORD(_T("RandomValueIndex2"), row); for (int i = 0; i < _countof(value_indexes); ++i) { const RandomValue::Index value_index = value_indexes[i]; if (is_empty_option) { if (value_index != 0) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|RandomValueIndex is not valid.|行号= %d, RandomValueIndex = %d|"), __FUNCTION__, __LINE__, row, value_index ); assert(false); return false; } continue; } const RandomValue* const random_value = (parser.value_manager_).GetValue(value_index); if (random_value == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|RandomValueIndex is not valid.|行号= %d, RandomValueIndex = %d|"), __FUNCTION__, __LINE__, row, value_index ); assert(false); return false; } const RandomValue::Parts& random_value_parts = random_value->parts; RandomValue::Parts::const_iterator value_parts_it = random_value_parts.begin(); for (; value_parts_it != random_value_parts.end(); ++value_parts_it) { const RandomValuePart& part = *value_parts_it; if (ns_formula::CheckOptionValidity(kind, value_type, part.my_value) == false) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|RandomValue is not valid.|行号= %d, RandomValueIndex = %d, RandomValueOrder = %d, Value = %d|"), __FUNCTION__, __LINE__, row, value_index, part.order, part.my_value ); assert(false); return false; } } random_values[i] = random_value; } const RandomOptionPart::Ratio ratio = parser.GetDataWORD(_T("Ratio"), row); if (ratio < RandomOptionPart::kMinRatio || ratio > RandomOptionPart::kMaxRatio) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Ratio is not valid.|行号= %d, Ratio = %d|"), __FUNCTION__, __LINE__, row, ratio ); assert(false); return false; } const bool is_new_index = (prev_index != index); if (is_new_index) { RandomOptions::const_iterator prev_options_it = random_options_.find(prev_index); if (prev_options_it != random_options_.end()) { const RandomOption& prev_random_option = prev_options_it->second; const RandomOptionPart::Ratio ratio_sum = prev_random_option.part_selector.GetTotalRatio(); if (ratio_sum != RandomOptionPart::kMaxRatio) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Ratio sum is not valid.|Index = %d, Sum = %d|"), __FUNCTION__, __LINE__, prev_index, ratio_sum ); assert(false); return false; } } if (random_options_.find(index) != random_options_.end()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Index is already exist.|行号= %d, Index = %d|"), __FUNCTION__, __LINE__, row, index ); assert(false); return false; } RandomOption random_option; random_option.index = index; random_options_[index] = random_option; prev_index = index; } RandomOptions::iterator options_it = random_options_.find(index); if (options_it == random_options_.end()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Index is not find.|行号= %d, Index = %d|"), __FUNCTION__, __LINE__, row, index ); assert(false); return false; } RandomOption& random_option = options_it->second; RandomOption::Parts& parts = random_option.parts; if (order != (parts.size()+1)) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Order is not valid.|行号= %d, Order = %d|"), __FUNCTION__, __LINE__, row, order ); assert(false); return false; } if (is_empty_option != false) { for (RandomOption::Parts::const_iterator it = parts.begin(); it != parts.end(); ++it) { const RandomOptionPart& part = *it; if (part.kind == kind) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|OptionKind is already exist.|行号= %d, OptionKind = %d|"), __FUNCTION__, __LINE__, row, kind ); assert(false); return false; } } } RandomOptionPart part; part.order = order; part.active_type = active_type; part.kind = kind; part.value_type = value_type; ::CopyMemory(part.random_values, random_values, sizeof(random_values)); part.ratio = ratio; part.is_empty = is_empty_option; parts.push_back(part); if (!random_option.part_selector.Add(order, ratio)) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Fail to add ratio.|行号= %d, Index = %d, Order = %d|"), __FUNCTION__, __LINE__, row, index, order ); assert(false); return false; } } return true; } bool RandomItemParser::RandomItemManager::LoadScript( const RandomItemParser& parser, const bool is_reload) { if (is_reload) { random_items_.clear(); } #ifdef _NA_003740_20210624_ADDITEMRANDOM_ITEM6 const TCHAR* option_index_name[RandomItem::kMaxOptionSize] = { _T("RandomOptionTypeIndex1"), _T("RandomOptionTypeIndex2"), _T("RandomOptionTypeIndex3"), _T("RandomOptionTypeIndex4"), _T("RandomOptionTypeIndex5"), _T("RandomOptionTypeIndex6") }; #else const TCHAR* option_index_name[RandomItem::kMaxOptionSize] = { _T("RandomOptionTypeIndex1"), _T("RandomOptionTypeIndex2"), _T("RandomOptionTypeIndex3"), _T("RandomOptionTypeIndex4"), _T("RandomOptionTypeIndex5") }; #endif const int row_size = parser.GetRowSize(); for (int row = 0; row < row_size; ++row) { const RandomItem::ItemCode item_code = parser.GetDataDWORD(_T("ItemCode"), row); if ((ItemInfoParser::Instance())->GetItemInfo(item_code) == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|ItemCode is not valid.|行号= %d, ItemCode = %d|"), __FUNCTION__, __LINE__, row, item_code ); assert(false); return false; } RandomItem random_item; random_item.item_code = item_code; for (int i = 0; i < _countof(option_index_name); ++i) { const RandomOption::Index option_index = parser.GetDataWORD(option_index_name[i], row); if (option_index == 0) { break; } const RandomOption* const option = (parser.option_manager_).GetOption(option_index); if (option == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|RandomOptionTypeIndex%d is not valid.|行号= %d, RandomOptionTypeIndex = %d|"), __FUNCTION__, __LINE__, i, row, option_index ); assert(false); return false; } (random_item.options).push_back(option); } if ((random_item.options).empty()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|OptionTypeIndex is empty.|行号= %d, ItemCode = %d|"), __FUNCTION__, __LINE__, row, item_code ); assert(false); return false; } if (random_items_.find(item_code) != random_items_.end()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|ItemCode is already exist.|行号= %d, ItemCode = %d|"), __FUNCTION__, __LINE__, row, item_code ); assert(false); return false; } random_items_[item_code] = random_item; } return true; } bool RandomItemParser::RandomKeyManager::LoadScript( RandomItemParser& parser, const bool is_reload) { if (is_reload) { key_datas_.clear(); random_keys_.clear(); } const int row_size = parser.GetRowSize(); for (int row = 0; row < row_size; ++row) { const RandomKey::Key key = parser.GetDataWORD(_T("Key"), row); if (key < RandomKey::kMinKey || key > RandomKey::kMaxKey || random_keys_.find(key) != random_keys_.end()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Key is not valid.|行号= %d, Key = %d|"), __FUNCTION__, __LINE__, row, key ); assert(false); return false; } const RandomOption::Index option_index = parser.GetDataWORD(_T("OptionTypeIndex"), row); const RandomOption* const option = (parser.option_manager_).GetOption(option_index); if (option == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|OptionTypeIndex is not valid.|行号= %d, OptionTypeIndex = %d|"), __FUNCTION__, __LINE__, row, option_index ); assert(false); return false; } const RandomOptionPart::Order option_order = parser.GetDataBYTE(_T("OptionTypeOrder"), row); const RandomOptionPart* const option_part = option->GetPart(option_order); if (option_part == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|OptionTypeOrder is not valid.|行号= %d, OptionTypeOrder = %d|"), __FUNCTION__, __LINE__, row, option_order ); assert(false); return false; } const RandomValue::Index value_index = parser.GetDataWORD(_T("ValueIndex"), row); const RandomValuePart::Order value_order = parser.GetDataBYTE(_T("ValueOrder"), row); const RandomValuePart* value_part(NULL); if (option_part->is_empty == false) { const RandomValue* random_value = option_part->GetValue(RandomValueTypeGrade::kGrade1); if (random_value == NULL) { random_value = option_part->GetValue(RandomValueTypeGrade::kGrade2); if (random_value == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|ValueIndex is not valid.|行号= %d, ValueIndex = %d|"), __LINE__, __FUNCTION__, row, value_index ); } assert(false); return false; } value_part = random_value->GetPart(value_order); if (value_part == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|ValueOrder is not valid.|行号= %d, ValueOrder = %d|"), __FUNCTION__, __LINE__, row, value_order ); assert(false); return false; } } const KeyData key_data = CreateKeyData(option_index, option_order, value_index, value_order); if (key_datas_.find(key_data) != key_datas_.end()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|KeyData is already exist.|行号= %d, KeyData = %I64|"), __FUNCTION__, __LINE__, row, key_data ); assert(false); return false; } RandomKey random_key; random_key.key = key; random_key.option_part = option_part; random_key.value_part = value_part; random_keys_[key] = random_key; RandomKeys::const_iterator it = random_keys_.find(key); if (it == random_keys_.end()) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|Fail to insert random key.|行号= %d, Key = %d|"), __FUNCTION__, __LINE__, row, key ); assert(false); return false; } const RandomKey* const inserted_random_key = &(it->second); key_datas_[key_data] = inserted_random_key; } if (InsertKeysToOption(parser) == false) { return false; } return true; } bool RandomItemParser::RandomKeyManager::InsertKeysToOption(RandomItemParser& parser) const { RandomItemManager::RandomItems& random_items = parser.item_manager_.random_items_; for (RandomItemManager::RandomItems::iterator it = random_items.begin(); it != random_items.end(); ++it) { RandomItem& random_item = it->second; // item code const RandomItem::ItemCode item_code = random_item.item_code; const RandomItem::Options& random_options = random_item.options; for (RandomItem::Options::const_iterator it2 = random_options.begin(); it2 != random_options.end(); ++it2) { RandomOption* const random_option = const_cast(*it2); if (random_option == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|RandomOption is null.|ItemCode = %d|"), __FUNCTION__, __LINE__, random_item.item_code ); return false; } // option index const RandomOption::Index option_index = random_option->index; const RandomOption::Parts& option_parts = random_option->parts; for (RandomOption::Parts::const_iterator it3 = option_parts.begin(); it3 != option_parts.end(); ++it3) { const RandomOptionPart& option_part = *it3; // option order const RandomOptionPart::Order option_order = option_part.order; if (option_part.is_empty) { const int value_grade = 0; // value grade const RandomValue::Index value_index = 0; // value index const RandomValuePart::Order value_order = 0; // value order const RandomKey* const random_key = GetKey(option_index, option_order, value_index, value_order); if (random_key == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|RandomKey is not registered.|ItemCode = %d, OptionIndex = %d, OptionOrder = %d, ValueGrade = %d, ValueIndex = %d, ValueOrder = %d|"), __FUNCTION__, __LINE__, item_code, option_index, option_order, value_grade, value_index, value_order ); continue; //return false; } random_option->keys[random_key->key] = random_key; continue; } for (int i = 0; i < _countof(option_part.random_values); ++i) { const RandomValue* const random_value = option_part.random_values[i]; if (random_value == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|RandomValue is null.|OptionIndex = %d, OptionOrder = %d|"), __FUNCTION__, __LINE__, option_index, option_order ); return false; } // value grade const int value_grade = i; // value index const RandomValue::Index value_index = random_value->index; const RandomValue::Parts& value_parts = random_value->parts; for (RandomValue::Parts::const_iterator it4 = value_parts.begin(); it4 != value_parts.end(); ++it4) { const RandomValuePart& value_part = *it4; // value order const RandomValuePart::Order value_order = value_part.order; const RandomKey* const random_key = GetKey(option_index, option_order, value_index, value_order); if (random_key == NULL) { SUNLOG( eCRITICAL_LOG, _T("|%s|%d|RandomKey is not registered.|ItemCode = %d, OptionIndex = %d, OptionOrder = %d, ValueGrade = %d, ValueIndex = %d, ValueOrder = %d|"), __FUNCTION__, __LINE__, item_code, option_index, option_order, value_grade, value_index, value_order ); continue; //return false; } random_option->keys[random_key->key] = random_key; } } } } } return true; }