// InventorySlotContainer.cpp: implementation of the CInventorySlotContainer class. // //================================================================================================== #include "stdafx.h" #include "InventorySlotContainer.h" #include "Player.h" #include "QuickManager.h" #include "QuickSlotContainer.h" #include #include "ItemManager.h" #include #include "ItemInfoParser.h" #include #include #include //================================================================================================== // Construction/Destruction CInventorySlotContainer::CInventorySlotContainer() : m_pPlayer(NULL), m_TabNum(0) { // (CHANGES) change input value of MAX_INVENTORY_SLOT_NUM to default size that is 75 // changes real slot_list size by called Resize, to save memory, to use slot_list iterating const POSTYPE kDefaultInventorySize = MAX_INVENTORY_TAB_NUM * MAX_INVENTORY_SLOT_PER_TAB; Init(kDefaultInventorySize, SI_INVENTORY); ZeroMemory(m_InsertRuleBaseSlotList, sizeof(m_InsertRuleBaseSlotList)); } CInventorySlotContainer::~CInventorySlotContainer() { ClearConfiguredSlotList(); } //================================================================================================== // void CInventorySlotContainer::ClearAll() { SCItemSlotContainer::ClearAll(); m_OptionEffectItems.clear(); } BOOL CInventorySlotContainer::CheckPrevInsert(SCItemSlot& rInsertSlot) { const BASE_ITEMINFO* const pItemInfo = rInsertSlot.GetItemInfo(); //if(FALSE == FlowControl::FCAssert(pItemInfo)) // return false; const int add_num = rInsertSlot.GetNum(); // AppliedItemDependencyChain °Ë»ç - Exclusive Item AppliedItemDependencyChain* pAIDChain = AppliedItemDependencyChain::Instance(); if(pAIDChain->IsAcceptableInsert(m_pPlayer, rInsertSlot, add_num)) return true; return false; } //================================================================================================== // RC::eSLOT_INSERT_RESULT CInventorySlotContainer::InsertSlot(POSTYPE at_pos, SCSlot& IN rSlot) { SCItemSlot& rSrcSlot = (SCItemSlot&)rSlot; if(FALSE == CheckPrevInsert(rSrcSlot)) return RC::RC_INSERT_SLOT_FAILED; RC::eSLOT_INSERT_RESULT rt = SCSlotContainer::InsertSlot(at_pos, rSlot); if(RC::RC_INSERT_SLOT_SUCCESS == rt) { SCItemSlot& rCurSlot = (SCItemSlot&)GetSlot(at_pos); SCQuickSlotContainer* quick_container = m_pPlayer->GetQuickManager()->GetQuickSlotContainer(); // for debug section SLOTIDX in_slot_idx = rSrcSlot.GetSlotIdx(); POSTYPE in_slot_pos = rSrcSlot.GetPos(); SLOTCODE in_slot_code = rSrcSlot.GetItemCode(); quick_container->UpdateQuickSlot(in_slot_idx, in_slot_pos, in_slot_code, SI_INVENTORY, at_pos, rCurSlot.GetItemCode()); //m_pPlayer->GetQuickManager()->GetQuickSlotContainer()->UpdateQuickSlot(rCurSlot.GetSlotIdx(), rCurSlot.GetPos(), rCurSlot.GetItemCode(), // SI_INVENTORY, at_pos, rCurSlot.GetItemCode()); if (nsSlot::ItemManagerUpdateImpl* const item_updater_impl = m_pPlayer->GetItemManager()->GetUpdaterImpl()) { item_updater_impl->AddSerialCode(eSERIAL_INVENTORY, GetSlotIdx(), rCurSlot.GetPos(), rCurSlot.GetWorldSerial()); } } return rt; } BOOL CInventorySlotContainer::DeleteSlot(POSTYPE at_pos, SCSlot * pSlotOut) { SCItemSlot temp_delete_item_slot; if(SCSlotContainer::DeleteSlot(at_pos, &temp_delete_item_slot) == 0) return false; // (NOTE) ¹Ì¹¦ÇÑ ÀÎÅÍÆäÀ̽º ŸÀÔ ¹®Á¦°¡ Ç×»ó µµÃ³¿¡ ±ò¸° ÆíÀÌ´Ù. // ±×Àú ¹®Á¦ ¾øÀÌ ±¸ÇöÇϰí, ¹®Á¦°¡ »ý°Üµµ ¹Ù·Î ¾Ë ¼ö Àֱ⸦ ±â¿øÇÒ »ÓÀÌ´Ù. if(pSlotOut) static_cast(pSlotOut)->Copy(temp_delete_item_slot); if (nsSlot::ItemManagerUpdateImpl* const item_updater_impl = m_pPlayer->GetItemManager()->GetUpdaterImpl()) { item_updater_impl->RemoveSerialCode(GetSlotIdx(), at_pos, temp_delete_item_slot.GetWorldSerial()); }; //_NA_004035_20120227_COSTUME_ITEM // Âø¿ë ÇØÁ¦.. if (const BASE_ITEMINFO* item_info = temp_delete_item_slot.GetItemInfo()) { if (eITEMTYPE(item_info->m_wType) == eITEMTYPE_COSTUME) { if (m_pPlayer->GetIsEquippedCostume() == true && m_pPlayer->GetCostumeItemPos() == temp_delete_item_slot.GetPos() && m_pPlayer->GetCostumeItemCode() == temp_delete_item_slot.GetItemCode()) { m_pPlayer->GetCostumeHandler().Equipped(temp_delete_item_slot, false); } } #ifdef _NA_008610_20160104_ADD_DECORATECOSTUME else if (eITEMTYPE(item_info->m_wType) == eITEMTYPE_COSTUME_DECORATE) { if (m_pPlayer->GetIsEquippedDecoCostume() == true && m_pPlayer->GetDecoCostumeItemPos() == temp_delete_item_slot.GetPos() && m_pPlayer->GetDecoCostumeItemCode() == temp_delete_item_slot.GetItemCode()) { m_pPlayer->GetCostumeHandler().Equipped(temp_delete_item_slot, false); } } #endif //_NA_008610_20160104_ADD_DECORATECOSTUME } return TRUE; } void CInventorySlotContainer::OnInsert(SCSlot& IN rSlot) { const BASE_ITEMINFO* item_info = ((SCItemSlot&)rSlot).GetItemInfo(); //for debug if (nsSlot::ItemManagerUpdateImpl* const item_updater_impl = m_pPlayer->GetItemManager()->GetUpdaterImpl()) { item_updater_impl->AddExpirationItem((SCItemSlot &)rSlot); } int changed_num = rSlot.GetNum(); OnUpdate(rSlot, changed_num); } void CInventorySlotContainer::OnDelete(SCSlot& IN rSlot) { const BASE_ITEMINFO* item_info = ((SCItemSlot&)rSlot).GetItemInfo(); //for debug if (nsSlot::ItemManagerUpdateImpl* const item_updater_impl = m_pPlayer->GetItemManager()->GetUpdaterImpl()) { item_updater_impl->RemoveExpirationItem((SCItemSlot &)rSlot); } int changed_num = rSlot.GetNum(); OnUpdate(rSlot, -changed_num); } void CInventorySlotContainer::ApplyEffect(SCItemSlot& item_slot, const int changed_num, const int changed_total_count) { #if defined(_NA_002289_20110322_EQUIPMENTS_CALCULATOR_CHANGES_FOR_IMPROVEMENT) const bool pc_room_status = (m_pPlayer->CanApplyPCBangBenefit(true) != false); InvenItemOptionCalculator::ApplyInvenItemOption(m_pPlayer->GetPlayerAttr(), item_slot, changed_num, pc_room_status, true); if (AppliedItemDependencyChain* dependency_chain = AppliedItemDependencyChain::Instance()) { dependency_chain->CheckAndApplyEffect( m_pPlayer, item_slot, (changed_num >= 0), changed_total_count); }; return; #else int loopCount = changed_num >= 0 ? changed_num : -changed_num; const BOOL bPCBang = m_pPlayer->CanApplyPCBangBenefit(TRUE); ItemAttrCalculator itemCalc(m_pPlayer->GetPlayerAttr(), *this); itemCalc.SetCalcOption(FALSE); BOOLEAN is_inserted = changed_num > 0; for( ; loopCount; --loopCount) { BOOL bDummy; if(is_inserted) itemCalc.Equip(item_slot, bPCBang, TRUE, bDummy); else itemCalc.UnEquip(&item_slot, bPCBang, TRUE, bDummy); } AppliedItemDependencyChain* dependency_chain = AppliedItemDependencyChain::Instance(); dependency_chain->CheckAndApplyEffect(m_pPlayer, item_slot, is_inserted, changed_total_count); #endif } void CInventorySlotContainer::OnUpdate(SCSlot& IN rSlot, int added_num) { SCItemSlot& rItemSlot = static_cast(rSlot); const BASE_ITEMINFO* pItemInfo = rItemSlot.GetItemInfo(); //{__NA_0_CASH_ITEM_RENEWAL_SUPERMASTER if (pItemInfo->m_ChargeSubType == eCHARGE_SUB_FIXED_AMOUNT_EX && rItemSlot.CanEquip() == false) { //Ȱ¼ºÈ­ µÈ ¾ÆÀÌÅÛ¸¸ ¼ÒÀ¯ »óŸ¦ Áõ°¡ÇÑ´Ù. if(added_num > 0) { if(!rItemSlot.IsProgressTime()) return; } //¸¸·á±â°£ÀÌ ³¡³µ°Å³ª Ȱ¼ºÈ­ µÈ ¾ÆÀÌÅÛ¸¸ ¼ÒÀ¯ »óŸ¦ °¨¼ÒÇÑ´Ù. else { if(!rItemSlot.IsExpiredTime() && !rItemSlot.IsProgressTime()) return; } } //}__NA_0_CASH_ITEM_RENEWAL_SUPERMASTER if (rItemSlot.IsUserBlocked()) { if (rItemSlot.IsRiderItem()) { if(m_pPlayer->Rider.SyncNotifyRiderSummon(rItemSlot, m_pPlayer) == false) { rItemSlot.RiderSummonStatus(false); }; } }; // Agent¿¡¼­ ¼ÒÀ¯»óŸ¦ ¾Ë¾Æ¾ßµÇ´Â ¾ÆÀÌÅÛ ItemOwnFlag& rOwnFlag = m_pPlayer->GetItemOwnFlag(); const eITEMTYPE item_type = (eITEMTYPE)pItemInfo->m_wType; if(rOwnFlag.IsSendToAgentServer(item_type)) { if(added_num > 0) rOwnFlag.IncItemInfo(item_type, abs(added_num)); else rOwnFlag.DecItemInfo(item_type, abs(added_num)); MSG_AG_ITEM_CHANGE_SPECIAL_ITEM_OWN_CMD cmdMsg; cmdMsg.m_Apply = added_num > 0; cmdMsg.m_ItemType = pItemInfo->m_wType; cmdMsg.m_Count = abs(added_num); m_pPlayer->SendPacket(&cmdMsg, sizeof(cmdMsg)); } if(added_num == 0) return; BOOST_STATIC_ASSERT(0 < BASE_ITEMINFO::_MAX_OPTION_NUM && BASE_ITEMINFO::_MAX_OPTION_NUM <= sizeof(DWORD64)); typedef util::SEQ_BYTE_MASK \ OPTION_EFFECT_INVEN_MASK; const BOOLEAN isOptionEffectItem = ARR_CHECK_IS_CONTAIN(OPTION_EFFECT_INVEN_MASK::MASK, pItemInfo->m_byOptionExEffect) || ARR_CHECK_IS_CONTAIN(OPTION_EFFECT_INVEN_MASK::MASK, pItemInfo->m_byPCOptionExEffect); if(isOptionEffectItem == 0) return; // ½ÇÁ¦ ¿É¼ÇÀû¿ë¿¡ ¿µÇâÀ» ÁÖ´Â ¾ÆÀÌÅÛ°³¼ö ±¸Çϱâ int& OUT out_effect_items_num = m_OptionEffectItems[ pItemInfo->m_Code ]; int already_applied_num = min(pItemInfo->m_byDupEquipNum, out_effect_items_num); int need_apply_num = min(out_effect_items_num + added_num, pItemInfo->m_byDupEquipNum); if(need_apply_num < 0) { // °¡Áö°í ÀÖ´Â °³¼öº¸´Ù ´õ ¸¹ÀÌ ÁÙ¾îµé¼ö´Â ¾ø´Ù. SUNLOG(eCRITICAL_LOG, "[CInventorySlotContainer::OnUpdate] ResultApplingCount(%u)", need_apply_num); need_apply_num = 0; } int change_num = need_apply_num - already_applied_num; // º¯°æµÈ °³¼ö¸¸Å­ ¾ÆÀÌÅÛ ¿É¼ÇÀ» Àû¿ëÇÑ´Ù. if(change_num) ApplyEffect(rItemSlot, change_num, out_effect_items_num + added_num); out_effect_items_num += added_num; } void CInventorySlotContainer::SetValidState(BOOL v) { BASE_PLAYERINFO* base_char_info = m_pPlayer->GetCharInfo(); base_char_info->m_iInventoryLock = v; SCItemSlotContainer::SetValidState(v); } BOOL CInventorySlotContainer::ValidState() { // (BUGFIX) (091202) (WOPS:5334) Àκ¥Àá±Ý »óÅ¿¡¼­ ¾ÆÀÌÅÛ Á¦°Å °¡´ÉÇÑ Æ¯¼ö ó¸®(PKµå¶ø) ItemManager::TransactionClosure::value_type transaction = m_pPlayer->GetItemManager()->GetCurrentTransactionAction(); if(transaction == ItemManager::TransactionClosure::eTransType_None) { ProtectorInventory& rPROTECT = m_pPlayer->GetWarehouseInventoryProtector().INVENTORY(); if(!rPROTECT.IsUsable()) return false; } if(m_pPlayer->GetCharInfo()->m_iInventoryLock) return false; else return SCItemSlotContainer::ValidState(); } void CInventorySlotContainer::UpdateAttr() { //{__NA_0_CASH_ITEM_RENEWAL_SUPERMASTER // ¹ö±× ¼öÁ¤ ÇØÁÜ. ItemOwnFlag& rOwnFlag = m_pPlayer->GetItemOwnFlag(); rOwnFlag.Init(); //} m_OptionEffectItems.clear(); const POSTYPE upperbound = GetMaxSlotNum(); for(POSTYPE i = 0; i < upperbound; ++i) { if(IsEmpty(i)) continue; SCItemSlot& rItemSlot = static_cast(GetSlot(i)); if(CheckPrevInsert(rItemSlot)) OnUpdate(rItemSlot, rItemSlot.GetNum()); } } // implemented by _NA000023_090323_ENHANCED_INVENTORY_SLOT_FUNCTIONALITY_ //-------------------------------------------------------------------------------------------------- namespace nsSlot { static const struct InventoryConfigMatchNode { nsSlot::InventoryConfig::eInsertRule kRule; int kIndex; } kInventoryConfigMatchNodeList[nsSlot::InventoryConfig::kMaxNumberOfInsertRules] = { { nsSlot::InventoryConfig::eInsertRule_Equip, 0 }, { nsSlot::InventoryConfig::eInsertRule_Quest, 1 }, { nsSlot::InventoryConfig::eInsertRule_AC, 2 }, { nsSlot::InventoryConfig::eInsertRule_Material, 3 }, { nsSlot::InventoryConfig::eInsertRule_Normal, 4 }, { nsSlot::InventoryConfig::eInsertRule_Waste, 5 }, { nsSlot::InventoryConfig::eInsertRule_All, 6 }, }; // (Ref100328) slot linear list array order based on the policy // all configuration use a default SlotList of the SCSlotContainer static const nsSlot::InventoryConfig::SetType kSlotOrderList[nsSlot::InventoryConfig::kMaxNumberOfInsertRules - 1] = { nsSlot::InventoryConfig::eInsertRule_Equip, nsSlot::InventoryConfig::eInsertRule_Quest, nsSlot::InventoryConfig::eInsertRule_AC, nsSlot::InventoryConfig::eInsertRule_Material, nsSlot::InventoryConfig::eInsertRule_Normal, nsSlot::InventoryConfig::eInsertRule_Waste, //InventoryConfig::eInsertRule_All, }; }; //end of namespace //-------------------------------------------------------------------------------------------------- /* const CInventorySlotContainer::SLOT_LINEAR_LIST& CInventorySlotContainer::GetConfiguredSlotList(const nsSlot::InventoryConfig::eInsertRule rule) const { using nsSlot::InventoryConfig; // (Ref100328) slot linear list array based on the policy if (rule == InventoryConfig::eInsertRule_All || rule == static_cast(0)) { // policy for all return GetSlotList(); } #ifdef _DEBUG // require one field set switch (rule) { case InventoryConfig::eInsertRule_Equip: case InventoryConfig::eInsertRule_Quest: case InventoryConfig::eInsertRule_AC: case InventoryConfig::eInsertRule_Material: case InventoryConfig::eInsertRule_Normal: case InventoryConfig::eInsertRule_Waste: break; default: assert(!"Unexpected input argument, must be input the value of the eInsertRule"); return GetSlotList(); } #endif const nsSlot::InventoryConfigMatchNode* it = nsSlot::kInventoryConfigMatchNodeList, * end = &nsSlot::kInventoryConfigMatchNodeList[\ _countof(nsSlot::kInventoryConfigMatchNodeList)]; for (; it != end; ++it) { if (it->kRule != rule) { continue; } if (SLOT_LINEAR_LIST* selected_list = m_InsertRuleBaseSlotList[it->kIndex]) { return *selected_list; } break; } const SLOT_LINEAR_LIST& default_slot_list = GetSlotList(); return default_slot_list; } */ // f100904.4L, The interface to get sorted slot list start/end offset by configurations void CInventorySlotContainer::GetConfiguredSlotList(const nsSlot::InventoryConfig::eInsertRule rule, nsSlot::SearchOffset* result_offset_info) const { using namespace nsSlot; // (Ref100328) slot linear list array based on the policy if (rule == InventoryConfig::eInsertRule_All || rule == static_cast(0)) { // policy for all *result_offset_info = insert_rule_list_offset_[_countof(insert_rule_list_offset_)]; return; } #ifdef _DEBUG // require one field set switch (rule) { case InventoryConfig::eInsertRule_Equip: case InventoryConfig::eInsertRule_Quest: case InventoryConfig::eInsertRule_AC: case InventoryConfig::eInsertRule_Material: case InventoryConfig::eInsertRule_Normal: case InventoryConfig::eInsertRule_Waste: break; default: assert(!"Unexpected input argument, must be input the value of the eInsertRule"); *result_offset_info = insert_rule_list_offset_[_countof(insert_rule_list_offset_)]; return; } #endif const nsSlot::InventoryConfigMatchNode* it = nsSlot::kInventoryConfigMatchNodeList, * end = &nsSlot::kInventoryConfigMatchNodeList[\ _countof(nsSlot::kInventoryConfigMatchNodeList)]; for (; it != end; ++it) { if (it->kRule != rule) { continue; } *result_offset_info = insert_rule_list_offset_[it->kIndex]; return; } *result_offset_info = insert_rule_list_offset_[_countof(insert_rule_list_offset_)]; return; } namespace nsSlot { ; struct SetTypeSortedArray { int tab_index; InventoryConfig::SetType config; int mode; }; }; //end of namespace // update all inventory insert rule configures void CInventorySlotContainer::UpdateInventoryConfiguration(const nsSlot::InventoryConfig& input) { using nsSlot::InventoryConfig; using nsSlot::SetTypeSortedArray; // generally, inputed data structure byte alignment, packet structure, is not be in accord with \ // the best guide of system architecture to support hardware high performance. // additionally, below the data structure has expand slot check field using migration struct InventoryConfigControl : public nsSlot::InventoryConfig { bool checked[kMaxNumberOfConfigurations]; void ClearHistory() { BOOST_STATIC_ASSERT(_countof(configures) == _countof(checked)); ZeroMemory(checked, sizeof(checked)); } void Initialize(nsSlot::InventoryConfig* modified, const nsSlot::InventoryConfig& input) { ZeroMemory(this, sizeof(*this)); InventoryConfig::SetType* dest = modified->configures; InventoryConfig::SetType* it = configures, * end = &configures[_countof(configures)]; const InventoryConfig::SetType* src_it = input.configures; for ( ; it != end; ++it, ++src_it, ++dest) { if (*src_it == 0) { *it = InventoryConfig::eInsertRule_All; } else { *it = (*src_it) & InventoryConfig::eInsertRule_All; } *dest = *it; } }; } configure; // set up 'configure' configure.Initialize(&m_pPlayer->GetCharInfo()->m_InventoryConfig, input); // tab based working storage SetTypeSortedArray set_type_sorted_array[_countof(configure.configures)]; // mask mode operator struct MaskModeOperator { // (CHANGES) fix up a sorting condition which is a different result // related to the 'all' checked state // [0] : and mode (multi-bits except all) // [1] : or (all) // [2] : or (others) __forceinline bool setup_config(int mode, InventoryConfig::SetType config_condition) { if (mode >= 2) { return true; } bool all_configuration = config_condition == InventoryConfig::eInsertRule_All; switch (mode) { case 0: if (all_configuration == false && (config_condition & origin_mask)) { return true; } break; case 1: if (all_configuration) { return true; } break; } return false; } InventoryConfig::SetType origin_mask; }; // const SLOT_LINEAR_LIST& original_list = GetSlotList(); const int current_max_number_of_tabs = original_list.size() / MAX_INVENTORY_SLOT_PER_TAB; // terrible... time complexity O(n^2)... specification = { n * 2 * n + (n * n) } for (int order_index = 0; order_index < _countof(nsSlot::kSlotOrderList); ++order_index) { ZeroMemory(set_type_sorted_array, sizeof(set_type_sorted_array)); SetTypeSortedArray* dest_it = set_type_sorted_array; // configure.ClearHistory(); MaskModeOperator mask_mode = { nsSlot::kSlotOrderList[order_index] }; for (int mode_index = 0; mode_index < 3; ++mode_index) { for (int config_index = 0; (config_index < current_max_number_of_tabs && config_index < _countof(configure.configures)); ++config_index) { if (configure.checked[config_index] != false) { continue; } InventoryConfig::SetType* const config = &configure.configures[config_index]; if (mask_mode.setup_config(mode_index, *config) && configure.checked[config_index] == false) { dest_it->tab_index = static_cast(config - configure.configures); dest_it->config = *config; dest_it->mode = mode_index; // f100904.4L, to support two phase group sorting ++dest_it; configure.checked[config_index] = true; } } } // SLOT_LINEAR_LIST* slot_of_slot_list = m_InsertRuleBaseSlotList[order_index]; if (slot_of_slot_list == NULL) { slot_of_slot_list = TAllocNew(SLOT_LINEAR_LIST); m_InsertRuleBaseSlotList[order_index] = slot_of_slot_list; } slot_of_slot_list->reserve(current_max_number_of_tabs * MAX_INVENTORY_SLOT_PER_TAB); slot_of_slot_list->resize(0); // copy range dest_it = set_type_sorted_array; int number_of_sort_groups[3] = { 0, }; for (int index = 0; (index < current_max_number_of_tabs && dest_it != &set_type_sorted_array[_countof(set_type_sorted_array)]); ++index, ++dest_it) { SLOT_LINEAR_LIST::const_iterator offset_it = original_list.begin(); offset_it += static_cast(dest_it->tab_index * MAX_INVENTORY_SLOT_PER_TAB); // can't use std::copy because of danger, instead of ...what is the replacement? for (int loop = MAX_INVENTORY_SLOT_PER_TAB; loop; --loop, ++offset_it) { slot_of_slot_list->push_back(*offset_it); } // unused field (dest_it->config)... ++number_of_sort_groups[dest_it->mode]; } // f100904.4L, prepare range iterators to support a six phase inversed select operation if (nsSlot::SearchOffset* search_node = &insert_rule_list_offset_[order_index]) { SLOT_LINEAR_LIST::const_iterator list_it = slot_of_slot_list->begin(), list_end = slot_of_slot_list->end(); { for (SLOT_LINEAR_LIST::const_iterator* offset_it = search_node->search_it; offset_it != &search_node->search_it[_countof(search_node->search_it)]; ++offset_it) { *offset_it = list_end; } } { for (SLOT_LINEAR_LIST::const_iterator* offset_it = search_node->search_end; offset_it != &search_node->search_end[_countof(search_node->search_end)]; ++offset_it) { *offset_it = list_end; } } // { SLOT_LINEAR_LIST::const_iterator offset_it = list_it; if (number_of_sort_groups[0]) { search_node->search_it[1] = search_node->search_it[0] = offset_it; offset_it += number_of_sort_groups[0] * MAX_INVENTORY_SLOT_PER_TAB; search_node->search_end[1] = search_node->search_end[0] = offset_it; } if (number_of_sort_groups[1]) { search_node->search_it[3] = search_node->search_it[2] = offset_it; offset_it += number_of_sort_groups[1] * MAX_INVENTORY_SLOT_PER_TAB; search_node->search_end[3] = search_node->search_end[2] = offset_it; } if (number_of_sort_groups[2]) { search_node->search_it[5] = search_node->search_it[4] = offset_it; offset_it += number_of_sort_groups[2] * MAX_INVENTORY_SLOT_PER_TAB; search_node->search_end[5] = search_node->search_end[4] = offset_it; } } }; }; //last section, f100904.4L, 'all' configuration has not sorting policy except an overlapping case if (nsSlot::SearchOffset* search_node = \ &insert_rule_list_offset_[nsSlot::InventoryConfigSwitcher::eSwitch_All]) { SLOT_LINEAR_LIST::const_iterator list_it = original_list.begin(), list_end = original_list.end(); { for (SLOT_LINEAR_LIST::const_iterator* offset_it = search_node->search_it; offset_it != &search_node->search_it[_countof(search_node->search_it)]; ++offset_it) { *offset_it = list_it; } } { for (SLOT_LINEAR_LIST::const_iterator* offset_it = search_node->search_end; offset_it != &search_node->search_end[_countof(search_node->search_end)]; ++offset_it) { *offset_it = list_end; } } } } void CInventorySlotContainer::ClearConfiguredSlotList() { for (SLOT_LINEAR_LIST** it = m_InsertRuleBaseSlotList; it != &m_InsertRuleBaseSlotList[_countof(m_InsertRuleBaseSlotList)]; ++it) { SLOT_LINEAR_LIST* slot_list = *it; if (slot_list) { TAllocDelete(SLOT_LINEAR_LIST, slot_list); } } ZeroMemory(m_InsertRuleBaseSlotList, sizeof(m_InsertRuleBaseSlotList)); }