diff --git a/changelog.txt b/changelog.txt index fe471b367..79b156c0b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,15 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 01/15/2015 == +Uleat: Attempted fix for elusive inventory bug: + - Removed 'iter_queue' typedef and converted lcast to explicit or auto defines + - Reworked several functions that manipulate the cursor queue + - Found/corrected one occurrence of post-processing iterator incrementing in an ItemInstQueue handler + - Added many scope declarations in code that handles inventory manipulation (loose macros are bad...) +Uleat: Added Item_Struct pointer checks to ItemInst methods that did not have them +Uleat: Changed IsEquippable(race,class) to use bit-wise 'and' (&) over '(x%2)==1' in conditional check. +Uleat: Changed DyeArmor() assignment of 'armor_color' to use bit-wise 'or' and bit-shifting (|,<<) over multiplication and addition (*,+). + == 01/13/2015 == Uleat: Placed an upper limit on the cursor queue save loop. Trevius: (RoF2) Guild invites now add new members as members instead of recruits, and /guild chat works properly. diff --git a/common/item.cpp b/common/item.cpp index c06df3a89..044d55d3d 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -55,13 +55,10 @@ static inline int32 GetNextItemInstSerialNumber() { // // class ItemInstQueue // -ItemInstQueue::~ItemInstQueue() { - iter_queue cur, end; - cur = m_list.begin(); - end = m_list.end(); - for (; cur != end; ++cur) { - ItemInst *tmp = *cur; - safe_delete(tmp); +ItemInstQueue::~ItemInstQueue() +{ + for (auto iter = m_list.begin(); iter != m_list.end(); ++iter) { + safe_delete(*iter); } m_list.clear(); } @@ -81,7 +78,7 @@ void ItemInstQueue::push_front(ItemInst* inst) // Remove item from front of queue ItemInst* ItemInstQueue::pop() { - if (m_list.size() == 0) + if (m_list.empty()) return nullptr; ItemInst* inst = m_list.front(); @@ -92,7 +89,7 @@ ItemInst* ItemInstQueue::pop() // Remove item from back of queue ItemInst* ItemInstQueue::pop_back() { - if (m_list.size() == 0) + if (m_list.empty()) return nullptr; ItemInst* inst = m_list.back(); @@ -103,53 +100,37 @@ ItemInst* ItemInstQueue::pop_back() // Look at item at front of queue ItemInst* ItemInstQueue::peek_front() const { - return (m_list.size() == 0) ? nullptr : m_list.front(); + return (m_list.empty()) ? nullptr : m_list.front(); } // // class Inventory // -Inventory::~Inventory() { - std::map::iterator cur, end; - - cur = m_worn.begin(); - end = m_worn.end(); - for (; cur != end; ++cur) { - ItemInst *tmp = cur->second; - safe_delete(tmp); +Inventory::~Inventory() +{ + for (auto iter = m_worn.begin(); iter != m_worn.end(); ++iter) { + safe_delete(iter->second); } m_worn.clear(); - cur = m_inv.begin(); - end = m_inv.end(); - for (; cur != end; ++cur) { - ItemInst *tmp = cur->second; - safe_delete(tmp); + for (auto iter = m_inv.begin(); iter != m_inv.end(); ++iter) { + safe_delete(iter->second); } m_inv.clear(); - cur = m_bank.begin(); - end = m_bank.end(); - for (; cur != end; ++cur) { - ItemInst *tmp = cur->second; - safe_delete(tmp); + for (auto iter = m_bank.begin(); iter != m_bank.end(); ++iter) { + safe_delete(iter->second); } m_bank.clear(); - cur = m_shbank.begin(); - end = m_shbank.end(); - for (; cur != end; ++cur) { - ItemInst *tmp = cur->second; - safe_delete(tmp); + for (auto iter = m_shbank.begin(); iter != m_shbank.end(); ++iter) { + safe_delete(iter->second); } m_shbank.clear(); - cur = m_trade.begin(); - end = m_trade.end(); - for (; cur != end; ++cur) { - ItemInst *tmp = cur->second; - safe_delete(tmp); + for (auto iter = m_trade.begin(); iter != m_trade.end(); ++iter) { + safe_delete(iter->second); } m_trade.clear(); } @@ -309,7 +290,8 @@ bool Inventory::DeleteItem(int16 slot_id, uint8 quantity) // the item is not stackable, and is not a charged item, or is expendable, delete it if (item_to_delete->IsStackable() || (!item_to_delete->IsStackable() && - ((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable()))) { + ((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable())) + ) { // Item can now be destroyed Inventory::MarkDirty(item_to_delete); return true; @@ -334,7 +316,8 @@ bool Inventory::CheckNoDrop(int16 slot_id) { if (inst->GetItem()->ItemClass == 1) { for (uint8 i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) { ItemInst* bagitem = GetItem(Inventory::CalcSlotId(slot_id, i)); - if (bagitem && !bagitem->GetItem()->NoDrop) return true; + if (bagitem && !bagitem->GetItem()->NoDrop) + return true; } } return false; @@ -638,8 +621,7 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo if (!for_bag) { for (int16 i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) { const ItemInst* inst = GetItem(i); - if (inst && inst->IsType(ItemClassContainer) - && inst->GetItem()->BagSize >= min_size) + if (inst && inst->IsType(ItemClassContainer) && inst->GetItem()->BagSize >= min_size) { if (inst->GetItem()->BagType == BagTypeQuiver && inst->GetItem()->ItemType != ItemTypeArrow) { @@ -651,18 +633,20 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo uint8 slots = inst->GetItem()->BagSlots; uint8 j; for (j = SUB_BEGIN; jIsType(ItemClassContainer)) { - for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) + for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) { if (!m_inv[free_slot]) return free_slot; + } return MainCursor; // return cursor since bags do not stack and will not fit inside other bags..yet...) } @@ -727,9 +712,10 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { if (!main_inst || (main_inst->GetItem()->BagType != BagTypeQuiver) || !main_inst->IsType(ItemClassContainer)) continue; - for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) + for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) return Inventory::CalcSlotId(free_slot, free_bag_slot); + } } } @@ -741,9 +727,10 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { if (!main_inst || (main_inst->GetItem()->BagType != BagTypeBandolier) || !main_inst->IsType(ItemClassContainer)) continue; - for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) + for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) return Inventory::CalcSlotId(free_slot, free_bag_slot); + } } } @@ -762,9 +749,10 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { if ((main_inst->GetItem()->BagSize < inst->GetItem()->Size) || (main_inst->GetItem()->BagType == BagTypeBandolier) || (main_inst->GetItem()->BagType == BagTypeQuiver)) continue; - for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) + for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) { if (!main_inst->GetItem(free_bag_slot)) return Inventory::CalcSlotId(free_slot, free_bag_slot); + } } } @@ -776,27 +764,26 @@ int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) { int16 Inventory::CalcSlotId(int16 slot_id) { int16 parent_slot_id = INVALID_INDEX; - if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END) - parent_slot_id = EmuConstants::GENERAL_BEGIN + (slot_id - EmuConstants::GENERAL_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; - - else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END) - parent_slot_id = MainCursor; - - /* // this is not a bag range... using this risks over-writing existing items - else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END) - parent_slot_id = EmuConstants::BANK_BEGIN + (slot_id - EmuConstants::BANK_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; - */ - - else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END) - parent_slot_id = EmuConstants::BANK_BEGIN + (slot_id - EmuConstants::BANK_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; - - else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) - parent_slot_id = EmuConstants::SHARED_BANK_BEGIN + (slot_id - EmuConstants::SHARED_BANK_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; - + //else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END) + // parent_slot_id = EmuConstants::BANK_BEGIN + (slot_id - EmuConstants::BANK_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; //else if (slot_id >= 3100 && slot_id <= 3179) should be {3031..3110}..where did this range come from!!? (verified db save range) - else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END) + + if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END) { + parent_slot_id = EmuConstants::GENERAL_BEGIN + (slot_id - EmuConstants::GENERAL_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; + } + else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END) { + parent_slot_id = MainCursor; + } + else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END) { + parent_slot_id = EmuConstants::BANK_BEGIN + (slot_id - EmuConstants::BANK_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; + } + else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) { + parent_slot_id = EmuConstants::SHARED_BANK_BEGIN + (slot_id - EmuConstants::SHARED_BANK_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; + } + else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END) { parent_slot_id = EmuConstants::TRADE_BEGIN + (slot_id - EmuConstants::TRADE_BAGS_BEGIN) / EmuConstants::ITEM_CONTAINER_SIZE; + } return parent_slot_id; } @@ -808,20 +795,21 @@ int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx) { int16 slot_id = INVALID_INDEX; - if (bagslot_id == MainCursor || bagslot_id == 8000) + if (bagslot_id == MainCursor || bagslot_id == 8000) { slot_id = EmuConstants::CURSOR_BAG_BEGIN + bagidx; - - else if (bagslot_id >= EmuConstants::GENERAL_BEGIN && bagslot_id <= EmuConstants::GENERAL_END) + } + else if (bagslot_id >= EmuConstants::GENERAL_BEGIN && bagslot_id <= EmuConstants::GENERAL_END) { slot_id = EmuConstants::GENERAL_BAGS_BEGIN + (bagslot_id - EmuConstants::GENERAL_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE + bagidx; - - else if (bagslot_id >= EmuConstants::BANK_BEGIN && bagslot_id <= EmuConstants::BANK_END) + } + else if (bagslot_id >= EmuConstants::BANK_BEGIN && bagslot_id <= EmuConstants::BANK_END) { slot_id = EmuConstants::BANK_BAGS_BEGIN + (bagslot_id - EmuConstants::BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE + bagidx; - - else if (bagslot_id >= EmuConstants::SHARED_BANK_BEGIN && bagslot_id <= EmuConstants::SHARED_BANK_END) + } + else if (bagslot_id >= EmuConstants::SHARED_BANK_BEGIN && bagslot_id <= EmuConstants::SHARED_BANK_END) { slot_id = EmuConstants::SHARED_BANK_BAGS_BEGIN + (bagslot_id - EmuConstants::SHARED_BANK_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE + bagidx; - - else if (bagslot_id >= EmuConstants::TRADE_BEGIN && bagslot_id <= EmuConstants::TRADE_END) + } + else if (bagslot_id >= EmuConstants::TRADE_BEGIN && bagslot_id <= EmuConstants::TRADE_END) { slot_id = EmuConstants::TRADE_BAGS_BEGIN + (bagslot_id - EmuConstants::TRADE_BEGIN) * EmuConstants::ITEM_CONTAINER_SIZE + bagidx; + } return slot_id; } @@ -829,30 +817,28 @@ int16 Inventory::CalcSlotId(int16 bagslot_id, uint8 bagidx) { uint8 Inventory::CalcBagIdx(int16 slot_id) { uint8 index = 0; - if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END) - index = (slot_id - EmuConstants::GENERAL_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE; - - else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END) - index = (slot_id - EmuConstants::CURSOR_BAG_BEGIN); // % EmuConstants::ITEM_CONTAINER_SIZE; - not needed since range is 10 slots - - /* // this is not a bag range... using this risks over-writing existing items - else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END) - index = (slot_id - EmuConstants::BANK_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE; - */ + //else if (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END) + // index = (slot_id - EmuConstants::BANK_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE; - else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END) + if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END) { + index = (slot_id - EmuConstants::GENERAL_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE; + } + else if (slot_id >= EmuConstants::CURSOR_BAG_BEGIN && slot_id <= EmuConstants::CURSOR_BAG_END) { + index = (slot_id - EmuConstants::CURSOR_BAG_BEGIN); // % EmuConstants::ITEM_CONTAINER_SIZE; - not needed since range is 10 slots + } + else if (slot_id >= EmuConstants::BANK_BAGS_BEGIN && slot_id <= EmuConstants::BANK_BAGS_END) { index = (slot_id - EmuConstants::BANK_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE; - - else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) + } + else if (slot_id >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot_id <= EmuConstants::SHARED_BANK_BAGS_END) { index = (slot_id - EmuConstants::SHARED_BANK_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE; - - else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END) + } + else if (slot_id >= EmuConstants::TRADE_BAGS_BEGIN && slot_id <= EmuConstants::TRADE_BAGS_END) { index = (slot_id - EmuConstants::TRADE_BAGS_BEGIN) % EmuConstants::ITEM_CONTAINER_SIZE; - - // odd..but, ok... (probably a range-slot conversion for ItemInst* Object::item - else if (slot_id >= EmuConstants::WORLD_BEGIN && slot_id <= EmuConstants::WORLD_END) + } + else if (slot_id >= EmuConstants::WORLD_BEGIN && slot_id <= EmuConstants::WORLD_END) { index = (slot_id - EmuConstants::WORLD_BEGIN); // % EmuConstants::ITEM_CONTAINER_SIZE; - not needed since range is 10 slots + } return index; } @@ -914,13 +900,17 @@ uint8 Inventory::CalcMaterialFromSlot(int16 equipslot) bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container) { - if (!ItemToTry || !Container) return false; + if (!ItemToTry || !Container) + return false; - if (ItemToTry->Size > Container->BagSize) return false; + if (ItemToTry->Size > Container->BagSize) + return false; - if ((Container->BagType == BagTypeQuiver) && (ItemToTry->ItemType != ItemTypeArrow)) return false; + if ((Container->BagType == BagTypeQuiver) && (ItemToTry->ItemType != ItemTypeArrow)) + return false; - if ((Container->BagType == BagTypeBandolier) && (ItemToTry->ItemType != ItemTypeSmallThrowing)) return false; + if ((Container->BagType == BagTypeBandolier) && (ItemToTry->ItemType != ItemTypeSmallThrowing)) + return false; return true; } @@ -956,8 +946,11 @@ bool Inventory::SupportsContainers(int16 slot_id) (slot_id >= EmuConstants::GENERAL_BEGIN && slot_id <= EmuConstants::GENERAL_END) || (slot_id >= EmuConstants::BANK_BEGIN && slot_id <= EmuConstants::BANK_END) || (slot_id >= EmuConstants::SHARED_BANK_BEGIN && slot_id <= EmuConstants::SHARED_BANK_END) || - (slot_id >= EmuConstants::TRADE_BEGIN && slot_id <= EmuConstants::TRADE_END)) + (slot_id >= EmuConstants::TRADE_BEGIN && slot_id <= EmuConstants::TRADE_END) + ) { return true; + } + return false; } @@ -1140,8 +1133,7 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst) m_trade[slot_id] = inst; result = slot_id; } - else - { + else { // Slot must be within a bag parentSlot = Inventory::CalcSlotId(slot_id); ItemInst* baginst = GetItem(parentSlot); // Get parent bag @@ -1163,246 +1155,233 @@ int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst) // Internal Method: Checks an inventory bucket for a particular item int16 Inventory::_HasItem(std::map& bucket, uint32 item_id, uint8 quantity) { - iter_inst it; - iter_contents itb; - ItemInst* inst = nullptr; uint8 quantity_found = 0; - // Check item: After failed checks, check bag contents (if bag) - for (it = bucket.begin(); it != bucket.end(); ++it) { - inst = it->second; - if (inst) { - if (inst->GetID() == item_id) { - quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges(); - if (quantity_found >= quantity) - return it->first; - } + for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) { + auto inst = iter->second; + if (inst == nullptr) { continue; } - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - if (inst->GetAugmentItemID(i) == item_id && quantity <= 1) - return legacy::SLOT_AUGMENT; // Only one augment per slot. - } + if (inst->GetID() == item_id) { + quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges(); + if (quantity_found >= quantity) + return iter->first; } - // Go through bag, if bag - if (inst && inst->IsType(ItemClassContainer)) { - for (itb = inst->_begin(); itb != inst->_end(); ++itb) { - ItemInst* baginst = itb->second; - if (baginst && baginst->GetID() == item_id) { - quantity_found += (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges(); - if (quantity_found >= quantity) - return Inventory::CalcSlotId(it->first, itb->first); - } - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - if (baginst && baginst->GetAugmentItemID(i) == item_id && quantity <= 1) - return legacy::SLOT_AUGMENT; // Only one augment per slot. - } + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + if (inst->GetAugmentItemID(index) == item_id && quantity <= 1) + return legacy::SLOT_AUGMENT; + } + + if (!inst->IsType(ItemClassContainer)) { continue; } + + for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + auto bag_inst = bag_iter->second; + if (bag_inst == nullptr) { continue; } + + if (bag_inst->GetID() == item_id) { + quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); + if (quantity_found >= quantity) + return Inventory::CalcSlotId(iter->first, bag_iter->first); + } + + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + if (bag_inst->GetAugmentItemID(index) == item_id && quantity <= 1) + return legacy::SLOT_AUGMENT; } } } - // Not found return INVALID_INDEX; } // Internal Method: Checks an inventory queue type bucket for a particular item int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity) { - iter_queue it; - iter_contents itb; + // The downfall of this (these) queue procedure is that callers presume that when an item is + // found, it is presented as being available on the cursor. In cases of a parity check, this + // is sufficient. However, in cases where referential criteria is considered, this can lead + // to unintended results. Funtionality should be observed when referencing the return value + // of this query -U + uint8 quantity_found = 0; - // Read-only iteration of queue - for (it = iqueue.begin(); it != iqueue.end(); ++it) { - ItemInst* inst = *it; - if (inst) - { - if (inst->GetID() == item_id) { - quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges(); - if (quantity_found >= quantity) - return MainCursor; - } - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - if (inst->GetAugmentItemID(i) == item_id && quantity <= 1) - return legacy::SLOT_AUGMENT; // Only one augment per slot. - } + for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) { + auto inst = *iter; + if (inst == nullptr) { continue; } + + if (inst->GetID() == item_id) { + quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges(); + if (quantity_found >= quantity) + return MainCursor; } - // Go through bag, if bag - if (inst && inst->IsType(ItemClassContainer)) { - for (itb = inst->_begin(); itb != inst->_end(); ++itb) { - ItemInst* baginst = itb->second; - if (baginst && baginst->GetID() == item_id) { - quantity_found += (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges(); - if (quantity_found >= quantity) - return Inventory::CalcSlotId(MainCursor, itb->first); - } - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - if (baginst && baginst->GetAugmentItemID(i) == item_id && quantity <= 1) - return legacy::SLOT_AUGMENT; // Only one augment per slot. - } + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + if (inst->GetAugmentItemID(index) == item_id && quantity <= 1) + return legacy::SLOT_AUGMENT; + } + if (!inst->IsType(ItemClassContainer)) { continue; } + + for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + auto bag_inst = bag_iter->second; + if (bag_inst == nullptr) { continue; } + + if (bag_inst->GetID() == item_id) { + quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); + if (quantity_found >= quantity) + return Inventory::CalcSlotId(MainCursor, bag_iter->first); + } + + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + if (bag_inst->GetAugmentItemID(index) == item_id && quantity <= 1) + return legacy::SLOT_AUGMENT; } } } - // Not found return INVALID_INDEX; } // Internal Method: Checks an inventory bucket for a particular item int16 Inventory::_HasItemByUse(std::map& bucket, uint8 use, uint8 quantity) { - iter_inst it; - iter_contents itb; - ItemInst* inst = nullptr; uint8 quantity_found = 0; - // Check item: After failed checks, check bag contents (if bag) - for (it = bucket.begin(); it != bucket.end(); ++it) { - inst = it->second; - if (inst && inst->IsType(ItemClassCommon) && inst->GetItem()->ItemType == use) { + for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) { + auto inst = iter->second; + if (inst == nullptr) { continue; } + + if (inst->IsType(ItemClassCommon) && inst->GetItem()->ItemType == use) { quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges(); if (quantity_found >= quantity) - return it->first; + return iter->first; } - // Go through bag, if bag - if (inst && inst->IsType(ItemClassContainer)) { + if (!inst->IsType(ItemClassContainer)) { continue; } - for (itb = inst->_begin(); itb != inst->_end(); itb++) { - ItemInst* baginst = itb->second; - if (baginst && baginst->IsType(ItemClassCommon) && baginst->GetItem()->ItemType == use) { - quantity_found += (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges(); - if (quantity_found >= quantity) - return Inventory::CalcSlotId(it->first, itb->first); - } + for (auto bag_iter = bucket.begin(); bag_iter != bucket.end(); ++bag_iter) { + auto bag_inst = bag_iter->second; + if (bag_inst == nullptr) { continue; } + + if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->ItemType == use) { + quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); + if (quantity_found >= quantity) + return Inventory::CalcSlotId(iter->first, bag_iter->first); } } } - // Not found return INVALID_INDEX; } // Internal Method: Checks an inventory queue type bucket for a particular item int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity) { - iter_queue it; - iter_contents itb; uint8 quantity_found = 0; - // Read-only iteration of queue - for (it = iqueue.begin(); it != iqueue.end(); ++it) { - ItemInst* inst = *it; - if (inst && inst->IsType(ItemClassCommon) && inst->GetItem()->ItemType == use) { + for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) { + auto inst = *iter; + if (inst == nullptr) { continue; } + + if (inst->IsType(ItemClassCommon) && inst->GetItem()->ItemType == use) { quantity_found += (inst->GetCharges() <= 0) ? 1 : inst->GetCharges(); if (quantity_found >= quantity) return MainCursor; } - // Go through bag, if bag - if (inst && inst->IsType(ItemClassContainer)) { + if (!inst->IsType(ItemClassContainer)) { continue; } - for (itb = inst->_begin(); itb != inst->_end(); ++itb) { - ItemInst* baginst = itb->second; - if (baginst && baginst->IsType(ItemClassCommon) && baginst->GetItem()->ItemType == use) { - quantity_found += (baginst->GetCharges() <= 0) ? 1 : baginst->GetCharges(); - if (quantity_found >= quantity) - return Inventory::CalcSlotId(MainCursor, itb->first); - } + for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + auto bag_inst = bag_iter->second; + if (bag_inst == nullptr) { continue; } + + if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->ItemType == use) { + quantity_found += (bag_inst->GetCharges() <= 0) ? 1 : bag_inst->GetCharges(); + if (quantity_found >= quantity) + return Inventory::CalcSlotId(MainCursor, bag_iter->first); } } } - // Not found return INVALID_INDEX; } int16 Inventory::_HasItemByLoreGroup(std::map& bucket, uint32 loregroup) { - iter_inst it; - iter_contents itb; - ItemInst* inst = nullptr; + for (auto iter = bucket.begin(); iter != bucket.end(); ++iter) { + auto inst = iter->second; + if (inst == nullptr) { continue; } - // Check item: After failed checks, check bag contents (if bag) - for (it = bucket.begin(); it != bucket.end(); ++it) { - inst = it->second; - if (inst) { - if (inst->GetItem()->LoreGroup == loregroup) - return it->first; + if (inst->GetItem()->LoreGroup == loregroup) + return iter->first; - ItemInst* Aug = nullptr; - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - Aug = inst->GetAugment(i); - if (Aug && Aug->GetItem()->LoreGroup == loregroup) - return legacy::SLOT_AUGMENT; // Only one augment per slot. - } + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + auto aug_inst = inst->GetAugment(index); + if (aug_inst == nullptr) { continue; } + + if (aug_inst->GetItem()->LoreGroup == loregroup) + return legacy::SLOT_AUGMENT; } - // Go through bag, if bag - if (inst && inst->IsType(ItemClassContainer)) { - for (itb = inst->_begin(); itb != inst->_end(); ++itb) { - ItemInst* baginst = itb->second; - if (baginst && baginst->IsType(ItemClassCommon) && baginst->GetItem()->LoreGroup == loregroup) - return Inventory::CalcSlotId(it->first, itb->first); + if (!inst->IsType(ItemClassContainer)) { continue; } - ItemInst* Aug2 = nullptr; - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - Aug2 = baginst->GetAugment(i); - if (Aug2 && Aug2->GetItem()->LoreGroup == loregroup) - return legacy::SLOT_AUGMENT; // Only one augment per slot. - } + for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + auto bag_inst = bag_iter->second; + if (bag_inst == nullptr) { continue; } + + if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->LoreGroup == loregroup) + return Inventory::CalcSlotId(iter->first, bag_iter->first); + + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + auto aug_inst = bag_inst->GetAugment(index); + if (aug_inst == nullptr) { continue; } + + if (aug_inst->GetItem()->LoreGroup == loregroup) + return legacy::SLOT_AUGMENT; } } } - // Not found return INVALID_INDEX; } // Internal Method: Checks an inventory queue type bucket for a particular item int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup) { - iter_queue it; - iter_contents itb; + for (auto iter = iqueue.begin(); iter != iqueue.end(); ++iter) { + auto inst = *iter; + if (inst == nullptr) { continue; } - // Read-only iteration of queue - for (it = iqueue.begin(); it != iqueue.end(); ++it) { - ItemInst* inst = *it; - if (inst) - { - if (inst->GetItem()->LoreGroup == loregroup) - return MainCursor; + if (inst->GetItem()->LoreGroup == loregroup) + return MainCursor; - ItemInst* Aug = nullptr; - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - Aug = inst->GetAugment(i); - if (Aug && Aug->GetItem()->LoreGroup == loregroup) - return legacy::SLOT_AUGMENT; // Only one augment per slot. - } + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + auto aug_inst = inst->GetAugment(index); + if (aug_inst == nullptr) { continue; } + + if (aug_inst->GetItem()->LoreGroup == loregroup) + return legacy::SLOT_AUGMENT; } - // Go through bag, if bag - if (inst && inst->IsType(ItemClassContainer)) { - for (itb = inst->_begin(); itb != inst->_end(); ++itb) { - ItemInst* baginst = itb->second; - if (baginst && baginst->IsType(ItemClassCommon) && baginst->GetItem()->LoreGroup == loregroup) - return Inventory::CalcSlotId(MainCursor, itb->first); + if (!inst->IsType(ItemClassContainer)) { continue; } + for (auto bag_iter = inst->_begin(); bag_iter != inst->_end(); ++bag_iter) { + auto bag_inst = bag_iter->second; + if (bag_inst == nullptr) { continue; } - ItemInst* Aug2 = nullptr; - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - Aug2 = baginst->GetAugment(i); - if (Aug2 && Aug2->GetItem()->LoreGroup == loregroup) - return legacy::SLOT_AUGMENT; // Only one augment per slot. - } + if (bag_inst->IsType(ItemClassCommon) && bag_inst->GetItem()->LoreGroup == loregroup) + return Inventory::CalcSlotId(MainCursor, bag_iter->first); + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + auto aug_inst = bag_inst->GetAugment(index); + if (aug_inst == nullptr) { continue; } + + if (aug_inst->GetItem()->LoreGroup == loregroup) + return legacy::SLOT_AUGMENT; } } } - - // Not found + return INVALID_INDEX; } @@ -1544,10 +1523,12 @@ ItemInst::~ItemInst() // Query item type bool ItemInst::IsType(ItemClassTypes item_class) const { + // IsType() does not protect against 'm_item = nullptr' + // Check usage type if ((m_use_type == ItemInstWorldContainer) && (item_class == ItemClassContainer)) - return true; + if (!m_item) return false; @@ -1557,11 +1538,17 @@ bool ItemInst::IsType(ItemClassTypes item_class) const // Is item stackable? bool ItemInst::IsStackable() const { + if (!m_item) + return false; + return m_item->Stackable; } bool ItemInst::IsCharged() const { + if (!m_item) + return false; + if (m_item->MaxCharges > 1) return true; else @@ -1584,16 +1571,25 @@ bool ItemInst::IsEquipable(int16 slot_id) const return false; // another "shouldn't do" fix..will be fixed in future updates (requires code and database work) - if (slot_id == MainPowerSource) { - slot_id = MainGeneral1; - uint32 slot_mask = (1 << slot_id); - if (slot_mask & m_item->Slots) + int16 use_slot = INVALID_INDEX; + if (slot_id == MainPowerSource) { use_slot = MainGeneral1; } + if ((uint16)slot_id <= EmuConstants::EQUIPMENT_END) { use_slot = slot_id; } + + if (use_slot != INVALID_INDEX) { + if (m_item->Slots & (1 << use_slot)) return true; } - if ((uint16)slot_id <= EmuConstants::EQUIPMENT_END) { - uint32 slot_mask = (1 << slot_id); - if (slot_mask & m_item->Slots) + return false; +} + +bool ItemInst::IsAugmentable() const +{ + if (!m_item) + return false; + + for (int index = 0; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + if (m_item->AugSlotType[index] != NO_ITEM) return true; } @@ -1603,39 +1599,38 @@ bool ItemInst::IsEquipable(int16 slot_id) const bool ItemInst::AvailableWearSlot(uint32 aug_wear_slots) const { // TODO: check to see if incoming 'aug_wear_slots' "switches" bit assignments like above... // (if wrong, would only affect MainAmmo and MainPowerSource augments) - if (m_item->ItemClass != ItemClassCommon || !m_item) + if (!m_item || m_item->ItemClass != ItemClassCommon) return false; - int i; - for (i = EmuConstants::EQUIPMENT_BEGIN; i <= MainGeneral1; i++) { // MainGeneral1 should be EmuConstants::EQUIPMENT_END - if (m_item->Slots & (1 << i)) { - if (aug_wear_slots & (1 << i)) + int index = EmuConstants::EQUIPMENT_BEGIN; + for (; index <= MainGeneral1; ++index) { // MainGeneral1 should be EmuConstants::EQUIPMENT_END + if (m_item->Slots & (1 << index)) { + if (aug_wear_slots & (1 << index)) break; } } - return (i<23) ? true : false; + return (index < 23) ? true : false; } int8 ItemInst::AvailableAugmentSlot(int32 augtype) const { - if (m_item->ItemClass != ItemClassCommon || !m_item) - return -1; - - int i; - for (i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - if (!GetItem(i)) { - if (augtype == -1 || (m_item->AugSlotType[i] && ((1 << (m_item->AugSlotType[i] - 1)) & augtype))) - break; - } + if (!m_item || m_item->ItemClass != ItemClassCommon) + return INVALID_INDEX; + int index = AUG_BEGIN; + for (; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + if (GetItem(index)) { continue; } + if (augtype == -1 || (m_item->AugSlotType[index] && ((1 << (m_item->AugSlotType[index] - 1)) & augtype))) + break; } - return (i < EmuConstants::ITEM_COMMON_SIZE) ? i : INVALID_INDEX; + return (index < EmuConstants::ITEM_COMMON_SIZE) ? index : INVALID_INDEX; } -bool ItemInst::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const { - if (m_item->ItemClass != ItemClassCommon || !m_item) +bool ItemInst::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const +{ + if (!m_item || m_item->ItemClass != ItemClassCommon) return false; if ((!GetItem(slot) && m_item->AugSlotVisible[slot]) && augtype == -1 || (m_item->AugSlotType[slot] && ((1 << (m_item->AugSlotType[slot] - 1)) & augtype))) { @@ -1649,8 +1644,7 @@ ItemInst* ItemInst::GetItem(uint8 index) const { iter_contents it = m_contents.find(index); if (it != m_contents.end()) { - ItemInst* inst = it->second; - return inst; + return it->second; } return nullptr; @@ -1658,12 +1652,11 @@ ItemInst* ItemInst::GetItem(uint8 index) const uint32 ItemInst::GetItemID(uint8 slot) const { - const ItemInst *item; - uint32 id = NO_ITEM; - if ((item = GetItem(slot)) != nullptr) - id = item->GetItem()->ID; + ItemInst *item = GetItem(slot); + if (item) + return item->GetID(); - return id; + return NO_ITEM; } void ItemInst::PutItem(uint8 index, const ItemInst& inst) @@ -1671,7 +1664,6 @@ void ItemInst::PutItem(uint8 index, const ItemInst& inst) // Clean up item already in slot (if exists) DeleteItem(index); - // Delegate to internal method _PutItem(index, inst.Clone()); } @@ -1687,14 +1679,13 @@ void ItemInst::DeleteItem(uint8 index) // Hands over memory ownership to client of this function call ItemInst* ItemInst::PopItem(uint8 index) { - iter_contents it = m_contents.find(index); - if (it != m_contents.end()) { - ItemInst* inst = it->second; + auto iter = m_contents.find(index); + if (iter != m_contents.end()) { + ItemInst* inst = iter->second; m_contents.erase(index); - return inst; + return inst; // Return pointer that needs to be deleted (or otherwise managed) } - - // Return pointer that needs to be deleted (or otherwise managed) + return nullptr; } @@ -1702,12 +1693,8 @@ ItemInst* ItemInst::PopItem(uint8 index) void ItemInst::Clear() { // Destroy container contents - iter_contents cur, end; - cur = m_contents.begin(); - end = m_contents.end(); - for (; cur != end; ++cur) { - ItemInst* inst = cur->second; - safe_delete(inst); + for (auto iter = m_contents.begin(); iter != m_contents.end(); ++iter) { + safe_delete(iter->second); } m_contents.clear(); } @@ -1715,6 +1702,8 @@ void ItemInst::Clear() // Remove all items from container void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent) { + // TODO: This needs work... + // Destroy container contents iter_contents cur, end, del; cur = m_contents.begin(); @@ -1765,6 +1754,9 @@ void ItemInst::ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent) uint8 ItemInst::FirstOpenSlot() const { + if (!m_item) + return INVALID_INDEX; + uint8 slots = m_item->BagSlots, i; for (i = SUB_BEGIN; i < slots; i++) { if (!GetItem(i)) @@ -1778,21 +1770,22 @@ uint8 ItemInst::GetTotalItemCount() const { uint8 item_count = 1; - if (m_item->ItemClass != ItemClassContainer) { return item_count; } + if (m_item && m_item->ItemClass != ItemClassContainer) { return item_count; } - for (int idx = SUB_BEGIN; idx < m_item->BagSlots; idx++) { if (GetItem(idx)) { item_count++; } } + for (int index = SUB_BEGIN; index < m_item->BagSlots; ++index) { if (GetItem(index)) { ++item_count; } } return item_count; } bool ItemInst::IsNoneEmptyContainer() { - if (m_item->ItemClass != ItemClassContainer) + if (!m_item || m_item->ItemClass != ItemClassContainer) return false; - for (int i = SUB_BEGIN; i < m_item->BagSlots; ++i) - if (GetItem(i)) + for (int index = SUB_BEGIN; index < m_item->BagSlots; ++index) { + if (GetItem(index)) return true; + } return false; } @@ -1800,7 +1793,7 @@ bool ItemInst::IsNoneEmptyContainer() // Retrieve augment inside item ItemInst* ItemInst::GetAugment(uint8 slot) const { - if (m_item->ItemClass == ItemClassCommon) + if (m_item && m_item->ItemClass == ItemClassCommon) return GetItem(slot); return nullptr; @@ -1808,23 +1801,23 @@ ItemInst* ItemInst::GetAugment(uint8 slot) const ItemInst* ItemInst::GetOrnamentationAug(int32 ornamentationAugtype) const { - if (ornamentationAugtype > 0) + if (!m_item || m_item->ItemClass != ItemClassCommon) { return nullptr; } + if (ornamentationAugtype == 0) { return nullptr; } + + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) + if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype) { - if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype) + const char *item_IDFile = GetAugment(i)->GetItem()->IDFile; + if ( + (strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0 + || strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0) + && GetAugment(i)->GetItem()->HerosForgeModel == 0 + ) { - const char *item_IDFile = GetAugment(i)->GetItem()->IDFile; - if ( - (strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0 - || strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0) - && GetAugment(i)->GetItem()->HerosForgeModel == 0 - ) - { - continue; - } - return this->GetAugment(i); + continue; } + return this->GetAugment(i); } } @@ -1845,37 +1838,38 @@ uint32 ItemInst::GetOrnamentHeroModel(int32 material_slot) const { } bool ItemInst::UpdateOrnamentationInfo() { + if (!m_item || m_item->ItemClass != ItemClassCommon) + return false; + bool ornamentSet = false; - if (IsType(ItemClassCommon)) + int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); + if (GetOrnamentationAug(ornamentationAugtype)) { - int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType); - if (GetOrnamentationAug(ornamentationAugtype)) + const Item_Struct* ornamentItem; + ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem(); + if (ornamentItem != nullptr) { - const Item_Struct* ornamentItem; - ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem(); - if (ornamentItem != nullptr) + SetOrnamentIcon(ornamentItem->Icon); + SetOrnamentHeroModel(ornamentItem->HerosForgeModel); + if (strlen(ornamentItem->IDFile) > 2) { - SetOrnamentIcon(ornamentItem->Icon); - SetOrnamentHeroModel(ornamentItem->HerosForgeModel); - if (strlen(ornamentItem->IDFile) > 2) - { - SetOrnamentationIDFile(atoi(&ornamentItem->IDFile[2])); - } - else - { - SetOrnamentationIDFile(0); - } - ornamentSet = true; + SetOrnamentationIDFile(atoi(&ornamentItem->IDFile[2])); } - } - else - { - SetOrnamentIcon(0); - SetOrnamentHeroModel(0); - SetOrnamentationIDFile(0); + else + { + SetOrnamentationIDFile(0); + } + ornamentSet = true; } } + else + { + SetOrnamentIcon(0); + SetOrnamentHeroModel(0); + SetOrnamentationIDFile(0); + } + return ornamentSet; } @@ -1927,54 +1921,60 @@ bool ItemInst::CanTransform(const Item_Struct *ItemToTry, const Item_Struct *Con uint32 ItemInst::GetAugmentItemID(uint8 slot) const { - uint32 id = NO_ITEM; - if (m_item->ItemClass == ItemClassCommon) { - return GetItemID(slot); - } + if (!m_item || m_item->ItemClass != ItemClassCommon) + return NO_ITEM; - return id; + return GetItemID(slot); } // Add an augment to the item void ItemInst::PutAugment(uint8 slot, const ItemInst& augment) { - if (m_item->ItemClass == ItemClassCommon) - PutItem(slot, augment); + if (!m_item || m_item->ItemClass != ItemClassCommon) + return; + + PutItem(slot, augment); } void ItemInst::PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id) { - if (item_id != NO_ITEM) { - const ItemInst* aug = db->CreateItem(item_id); - if (aug) - { - PutAugment(slot, *aug); - safe_delete(aug); - } - } + if (item_id == NO_ITEM) { return; } + if (db == nullptr) { return; /* TODO: add log message for nullptr */ } + + const ItemInst* aug = db->CreateItem(item_id); + if (aug) { + PutAugment(slot, *aug); + safe_delete(aug); + } } // Remove augment from item and destroy it void ItemInst::DeleteAugment(uint8 index) { - if (m_item->ItemClass == ItemClassCommon) - DeleteItem(index); + if (!m_item || m_item->ItemClass != ItemClassCommon) + return; + + DeleteItem(index); } // Remove augment from item and return it ItemInst* ItemInst::RemoveAugment(uint8 index) { - if (m_item->ItemClass == ItemClassCommon) - return PopItem(index); - - return nullptr; + if (!m_item || m_item->ItemClass != ItemClassCommon) + return nullptr; + + return PopItem(index); } bool ItemInst::IsAugmented() { - for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; ++i) - if (GetAugmentItemID(i)) + if (!m_item || m_item->ItemClass != ItemClassCommon) + return false; + + for (int index = AUG_BEGIN; index < EmuConstants::ITEM_COMMON_SIZE; ++index) { + if (GetAugmentItemID(index)) return true; + } return false; } @@ -1984,33 +1984,43 @@ bool ItemInst::IsWeapon() const { if (!m_item || m_item->ItemClass != ItemClassCommon) return false; + if (m_item->ItemType == ItemTypeArrow && m_item->Damage != 0) return true; else return ((m_item->Damage != 0) && (m_item->Delay != 0)); } -bool ItemInst::IsAmmo() const { - - if (!m_item) return false; +bool ItemInst::IsAmmo() const +{ + if (!m_item) + return false; if ((m_item->ItemType == ItemTypeArrow) || (m_item->ItemType == ItemTypeLargeThrowing) || - (m_item->ItemType == ItemTypeSmallThrowing)) + (m_item->ItemType == ItemTypeSmallThrowing) + ) { return true; + } return false; } -const Item_Struct* ItemInst::GetItem() const { - if (!m_scaledItem) - return m_item; - else +const Item_Struct* ItemInst::GetItem() const +{ + if (!m_item) + return nullptr; + + if (m_scaledItem) return m_scaledItem; + + return m_item; } -const Item_Struct* ItemInst::GetUnscaledItem() const { +const Item_Struct* ItemInst::GetUnscaledItem() const +{ + // No operator calls and defaults to nullptr return m_item; } @@ -2112,6 +2122,9 @@ void ItemInst::Initialize(SharedDatabase *db) { } void ItemInst::ScaleItem() { + if (!m_item) + return; + if (m_scaledItem) { memcpy(m_scaledItem, m_item, sizeof(Item_Struct)); } @@ -2255,6 +2268,7 @@ EvolveInfo::EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 } EvolveInfo::~EvolveInfo() { + } @@ -2267,18 +2281,13 @@ bool Item_Struct::IsEquipable(uint16 Race, uint16 Class_) const bool IsClass = false; uint32 Classes_ = Classes; - uint32 Races_ = Races; - uint32 Race_ = GetArrayRace(Race); - for (int CurrentClass = 1; CurrentClass <= PLAYER_CLASS_COUNT; ++CurrentClass) - { - if (Classes_ % 2 == 1) - { - if (CurrentClass == Class_) - { - IsClass = true; + for (int CurrentClass = 1; CurrentClass <= PLAYER_CLASS_COUNT; ++CurrentClass) { + if (Classes_ & 1) { + if (CurrentClass == Class_) { + IsClass = true; break; } } @@ -2287,17 +2296,15 @@ bool Item_Struct::IsEquipable(uint16 Race, uint16 Class_) const Race_ = (Race_ == 18 ? 16 : Race_); - for (unsigned int CurrentRace = 1; CurrentRace <= PLAYER_RACE_COUNT; ++CurrentRace) - { - if (Races_ % 2 == 1) - { - if (CurrentRace == Race_) - { - IsRace = true; + for (unsigned int CurrentRace = 1; CurrentRace <= PLAYER_RACE_COUNT; ++CurrentRace) { + if (Races_ & 1) { + if (CurrentRace == Race_) { + IsRace = true; break; } } Races_ >>= 1; } + return (IsRace && IsClass); } diff --git a/common/item.h b/common/item.h index 03182e4dd..888d47d2b 100644 --- a/common/item.h +++ b/common/item.h @@ -34,7 +34,6 @@ class EvolveInfo; // Stores information about an evolving item family #include // Helper typedefs -typedef std::list::const_iterator iter_queue; typedef std::map::const_iterator iter_inst; typedef std::map::const_iterator iter_contents; @@ -87,15 +86,17 @@ public: // Public Methods ///////////////////////// - inline iter_queue begin() { return m_list.begin(); } - inline iter_queue end() { return m_list.end(); } + inline std::list::const_iterator begin() { return m_list.begin(); } + inline std::list::const_iterator end() { return m_list.end(); } + + inline int size() { return static_cast(m_list.size()); } // TODO: change to size_t + inline bool empty() { return m_list.empty(); } void push(ItemInst* inst); void push_front(ItemInst* inst); ItemInst* pop(); ItemInst* pop_back(); ItemInst* peek_front() const; - inline int size() { return static_cast(m_list.size()); } protected: ///////////////////////// @@ -103,7 +104,6 @@ protected: ///////////////////////// std::list m_list; - }; // ######################################## @@ -140,9 +140,11 @@ public: ItemInst* GetItem(int16 slot_id) const; ItemInst* GetItem(int16 slot_id, uint8 bagidx) const; - inline iter_queue cursor_begin() { return m_cursor.begin(); } - inline iter_queue cursor_end() { return m_cursor.end(); } - inline bool CursorEmpty() { return (m_cursor.size() == 0); } + inline std::list::const_iterator cursor_begin() { return m_cursor.begin(); } + inline std::list::const_iterator cursor_end() { return m_cursor.end(); } + + inline int CursorSize() { return m_cursor.size(); } + inline bool CursorEmpty() { return m_cursor.empty(); } // Retrieve a read-only item from inventory inline const ItemInst* operator[](int16 slot_id) const { return GetItem(slot_id); } @@ -291,15 +293,15 @@ public: bool IsEquipable(int16 slot_id) const; // - // Augements + // Augments // - inline bool IsAugmentable() const { return m_item->AugSlotType[0] != 0 || m_item->AugSlotType[1] != 0 || m_item->AugSlotType[2] != 0 || m_item->AugSlotType[3] != 0 || m_item->AugSlotType[4] != 0 || m_item->AugSlotType[5] != 0; } + bool IsAugmentable() const; bool AvailableWearSlot(uint32 aug_wear_slots) const; int8 AvailableAugmentSlot(int32 augtype) const; bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const; - inline int32 GetAugmentType() const { return m_item->AugType; } + inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : NO_ITEM); } - inline bool IsExpendable() const { return ((m_item->Click.Type == ET_Expendable ) || (m_item->ItemType == ItemTypePotion)); } + inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == ET_Expendable ) || (m_item->ItemType == ItemTypePotion)) : false); } // // Contents @@ -337,8 +339,8 @@ public: bool IsAmmo() const; // Accessors - const uint32 GetID() const { return m_item->ID; } - const uint32 GetItemScriptID() const { return m_item->ScriptFileID; } + const uint32 GetID() const { return ((m_item) ? m_item->ID : NO_ITEM); } + const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : NO_ITEM); } const Item_Struct* GetItem() const; const Item_Struct* GetUnscaledItem() const; @@ -351,18 +353,18 @@ public: void SetColor(uint32 color) { m_color = color; } uint32 GetColor() const { return m_color; } - uint32 GetMerchantSlot() const { return m_merchantslot; } + uint32 GetMerchantSlot() const { return m_merchantslot; } void SetMerchantSlot(uint32 slot) { m_merchantslot = slot; } - int32 GetMerchantCount() const { return m_merchantcount; } + int32 GetMerchantCount() const { return m_merchantcount; } void SetMerchantCount(int32 count) { m_merchantcount = count; } int16 GetCurrentSlot() const { return m_currentslot; } void SetCurrentSlot(int16 curr_slot) { m_currentslot = curr_slot; } // Is this item already attuned? - bool IsAttuned() const { return m_attuned; } - void SetAttuned(bool flag) { m_attuned=flag; } + bool IsAttuned() const { return m_attuned; } + void SetAttuned(bool flag) { m_attuned=flag; } std::string GetCustomDataString() const; std::string GetCustomData(std::string identifier); diff --git a/common/shareddb.cpp b/common/shareddb.cpp index b97d5a984..3276bff25 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -110,8 +110,10 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list::const_iter for(auto it = start; it != end; ++it, i++) { if (i > 8999) { break; } // shouldn't be anything in the queue that indexes this high ItemInst *inst = *it; - if (!SaveInventory(char_id,inst,(i == 8000) ? MainCursor : i)) - return false; + int16 use_slot = (i == 8000) ? MainCursor : i; + if (!SaveInventory(char_id, inst, use_slot)) { + return false; + } } return true; @@ -171,8 +173,9 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 s else return UpdateSharedBankSlot(char_id, inst, slot_id); } - else if (!inst) // All other inventory - return DeleteInventorySlot(char_id, slot_id); + else if (!inst) { // All other inventory + return DeleteInventorySlot(char_id, slot_id); + } return UpdateInventorySlot(char_id, inst, slot_id); } @@ -181,11 +184,12 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i // need to check 'inst' argument for valid pointer uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM }; - if (inst->IsType(ItemClassCommon)) - for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - ItemInst *auginst=inst->GetItem(i); - augslot[i]=(auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM; + if (inst->IsType(ItemClassCommon)) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { + ItemInst *auginst = inst->GetItem(i); + augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM; } + } uint16 charges = 0; if(inst->GetCharges() >= 0) @@ -226,11 +230,12 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, // need to check 'inst' argument for valid pointer uint32 augslot[EmuConstants::ITEM_COMMON_SIZE] = { NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM, NO_ITEM }; - if (inst->IsType(ItemClassCommon)) - for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - ItemInst *auginst=inst->GetItem(i); - augslot[i]=(auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM; + if (inst->IsType(ItemClassCommon)) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { + ItemInst *auginst = inst->GetItem(i); + augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : NO_ITEM; } + } // Update/Insert item uint32 account_id = GetAccountIDByChar(char_id); @@ -252,11 +257,12 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, auto results = QueryDatabase(query); // Save bag contents, if slot supports bag contents - if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) + if (inst->IsType(ItemClassContainer) && Inventory::SupportsContainers(slot_id)) { for (uint8 idx = SUB_BEGIN; idx < EmuConstants::ITEM_CONTAINER_SIZE; idx++) { const ItemInst* baginst = inst->GetItem(idx); SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx)); } + } if (!results.Success()) { LogFile->write(EQEmuLog::Error, "UpdateSharedBankSlot query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); @@ -435,9 +441,8 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory* inv, bool is_charid) { ItemInst* inst = CreateBaseItem(item, charges); if (inst && item->ItemClass == ItemClassCommon) { for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { - if (aug[i]) { - inst->PutAugment(this, i, aug[i]); - } + if (aug[i]) + inst->PutAugment(this, i, aug[i]); } } @@ -576,10 +581,12 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory* inv) { else inst->SetCharges(charges); - if (item->ItemClass == ItemClassCommon) - for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) - if (aug[i]) - inst->PutAugment(this, i, aug[i]); + if (item->ItemClass == ItemClassCommon) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { + if (aug[i]) + inst->PutAugment(this, i, aug[i]); + } + } if (slot_id >= 8000 && slot_id <= 8999) { @@ -691,10 +698,12 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv) inst->SetCharges(charges); - if (item->ItemClass == ItemClassCommon) - for(int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) - if (aug[i]) - inst->PutAugment(this, i, aug[i]); + if (item->ItemClass == ItemClassCommon) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { + if (aug[i]) + inst->PutAugment(this, i, aug[i]); + } + } if (slot_id>=8000 && slot_id <= 8999) put_slot_id = inv->PushCursor(*inst); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 734d82de5..1fa18051f 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1837,12 +1837,11 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) if (loaditems) { /* Dont load if a length error occurs */ BulkSendInventoryItems(); /* Send stuff on the cursor which isnt sent in bulk */ - iter_queue it; - for (it = m_inv.cursor_begin(); it != m_inv.cursor_end(); ++it) { + for (auto iter = m_inv.cursor_begin(); iter != m_inv.cursor_end(); ++iter) { /* First item cursor is sent in bulk inventory packet */ - if (it == m_inv.cursor_begin()) + if (iter == m_inv.cursor_begin()) continue; - const ItemInst *inst = *it; + const ItemInst *inst = *iter; SendItemPacket(MainCursor, inst, ItemPacketSummonItem); } } diff --git a/zone/command.cpp b/zone/command.cpp index dd4618c87..140427520 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -2683,7 +2683,7 @@ void command_peekinv(Client *c, const Seperator *sep) } else { int cursorDepth = 0; - for (iter_queue it = targetClient->GetInv().cursor_begin(); (it != targetClient->GetInv().cursor_end()); ++it, ++cursorDepth) { + for (auto it = targetClient->GetInv().cursor_begin(); (it != targetClient->GetInv().cursor_end()); ++it, ++cursorDepth) { inst_main = *it; item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem(); linker.SetItemInst(inst_main); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 433fc9a66..0f0a04c28 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -363,9 +363,10 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( // solar: TODO soulbound items need not be added to corpse, but they need // to go into the regular slots on the player, out of bags - // worn + inventory + cursor + // possessions + // TODO: accomodate soul-bound items std::list removed_list; - bool cursor = false; + //bool cursor = false; for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; i++) { if(i == MainAmmo && client->GetClientVersion() >= EQClientSoF) { item = client->GetInv().GetItem(MainPowerSource); @@ -383,14 +384,18 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( } } +#if 0 + // This will either be re-enabled or deleted at some point. The client doesn't appear + // to like to have items deleted from it's buffer..or, I just haven't figure out how -U + // (Besides, the 'corpse' slots equal the size of MapPossessions..not MapPossessions + MapCorpse) + // cursor queue // (change to first client that supports 'death hover' mode, if not SoF.) if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < EQClientSoF) { // bumped starting assignment to 8001 because any in-memory 'slot 8000' item was moved above as 'slot 30' // this was mainly for client profile state reflection..should match db player inventory entries now. - - iter_queue it; - for (it = client->GetInv().cursor_begin(), i = 8001; it != client->GetInv().cursor_end(); ++it, i++) { + i = 8001; + for (auto it = client->GetInv().cursor_begin(); it != client->GetInv().cursor_end(); ++it, i++) { item = *it; if ((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) { std::list slot_list = MoveItemToCorpse(client, item, i); @@ -399,6 +404,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( } } } +#endif database.TransactionBegin(); if (removed_list.size() != 0) { @@ -421,6 +427,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( database.QueryDatabase(ss.str().c_str()); } +#if 0 if (cursor) { // all cursor items should be on corpse (client < SoF or RespawnFromHover = false) while (!client->GetInv().CursorEmpty()) client->DeleteItemInInventory(MainCursor, 0, false, false); @@ -430,8 +437,13 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( std::list::const_iterator finish = client->GetInv().cursor_end(); database.SaveCursor(client->CharacterID(), start, finish); } +#endif - client->CalcBonuses(); // will only affect offline profile viewing of dead characters..unneeded overhead + auto start = client->GetInv().cursor_begin(); + auto finish = client->GetInv().cursor_end(); + database.SaveCursor(client->CharacterID(), start, finish); + + client->CalcBonuses(); client->Save(); IsRezzed(false); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 42a05e175..20781b749 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -618,7 +618,7 @@ void Client::DropItem(int16 slot_id) // Save client inventory change to database if (slot_id == MainCursor) { SendCursorBuffer(); - std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); database.SaveCursor(CharacterID(), s, e); } else { database.SaveInventory(CharacterID(), nullptr, slot_id); @@ -668,12 +668,12 @@ int32 Client::GetItemIDAt(int16 slot_id) { } // Returns an augment's ID that's in an item (returns INVALID_ID if not found) -// Pass in the slot ID of the item and which augslot you want to check (0-4) +// Pass in the slot ID of the item and which augslot you want to check (0-5) int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) { const ItemInst* inst = m_inv[slot_id]; - if (inst) - if (inst->GetAugmentItemID(augslot)) - return inst->GetAugmentItemID(augslot); + if (inst && inst->GetAugmentItemID(augslot)) { + return inst->GetAugmentItemID(augslot); + } // None found return INVALID_ID; @@ -698,9 +698,9 @@ void Client::SendCursorBuffer() { // Remove item from inventory void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_update, bool update_db) { - #if (EQDEBUG >= 5) - LogFile->write(EQEmuLog::Debug, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true":"false"); - #endif +#if (EQDEBUG >= 5) + LogFile->write(EQEmuLog::Debug, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true" : "false"); +#endif // Added 'IsSlotValid(slot_id)' check to both segments of client packet processing. // - cursor queue slots were slipping through and crashing client @@ -769,9 +769,9 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd bool isDeleted = m_inv.DeleteItem(slot_id, quantity); - const ItemInst* inst=nullptr; + const ItemInst* inst = nullptr; if (slot_id == MainCursor) { - std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); if(update_db) database.SaveCursor(character_id, s, e); } @@ -783,22 +783,25 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd } if(client_update && IsValidSlot(slot_id)) { - EQApplicationPacket* outapp; + EQApplicationPacket* outapp = nullptr; if(inst) { - if(!inst->IsStackable() && !isDeleted) + if (!inst->IsStackable() && !isDeleted) { // Non stackable item with charges = Item with clicky spell effect ? Delete a charge. outapp = new EQApplicationPacket(OP_DeleteCharge, sizeof(MoveItem_Struct)); - else + } + else { // Stackable, arrows, etc ? Delete one from the stack outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(MoveItem_Struct)); + } - DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer; - delitem->from_slot = slot_id; - delitem->to_slot = 0xFFFFFFFF; - delitem->number_in_stack = 0xFFFFFFFF; - for(int loop=0;looppBuffer; + delitem->from_slot = slot_id; + delitem->to_slot = 0xFFFFFFFF; + delitem->number_in_stack = 0xFFFFFFFF; + + for(int loop=0;loopfrom_slot = slot_id; delitem->to_slot = 0xFFFFFFFF; delitem->number_in_stack = 0xFFFFFFFF; + QueuePacket(outapp); safe_delete(outapp); } @@ -821,7 +825,7 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update) SendItemPacket(MainCursor, &inst, ItemPacketSummonItem); } - std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); return database.SaveCursor(CharacterID(), s, e); } @@ -832,10 +836,12 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update) bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update) { mlog(INVENTORY__SLOTS, "Putting item %s (%d) into slot %d", inst.GetItem()->Name, inst.GetItem()->ID, slot_id); - if (slot_id == MainCursor) + if (slot_id == MainCursor) { // don't trust macros before conditional statements... return PushItemOnCursor(inst, client_update); - else + } + else { m_inv.PutItem(slot_id, inst); + } if (client_update) { @@ -843,9 +849,8 @@ bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client //SendWearChange(Inventory::CalcMaterialFromSlot(slot_id)); } - if (slot_id == MainCursor) { - std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); return database.SaveCursor(this->CharacterID(), s, e); } else { @@ -853,6 +858,7 @@ bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client } CalcBonuses(); + // a lot of wasted checks and calls coded above... } void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data) @@ -863,17 +869,17 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI SendLootItemInPacket(&inst, slot_id); if (slot_id == MainCursor) { - std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); database.SaveCursor(this->CharacterID(), s, e); - } else + } + else { database.SaveInventory(this->CharacterID(), &inst, slot_id); + } - if(bag_item_data) // bag contents - { + if(bag_item_data) { // bag contents int16 interior_slot; // solar: our bag went into slot_id, now let's pack the contents in - for(int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) - { + for(int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) { if(bag_item_data[i] == nullptr) continue; const ItemInst *bagitem = database.CreateItem(bag_item_data[i]->item_id, bag_item_data[i]->charges, bag_item_data[i]->aug_1, bag_item_data[i]->aug_2, bag_item_data[i]->aug_3, bag_item_data[i]->aug_4, bag_item_data[i]->aug_5, bag_item_data[i]->aug_6, bag_item_data[i]->attuned); @@ -891,86 +897,74 @@ bool Client::TryStacking(ItemInst* item, uint8 type, bool try_worn, bool try_cur return false; int16 i; uint32 item_id = item->GetItem()->ID; - for (i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) - { + for (i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) { ItemInst* tmp_inst = m_inv.GetItem(i); if(tmp_inst && tmp_inst->GetItem()->ID == item_id && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize){ MoveItemCharges(*item, i, type); CalcBonuses(); - if(item->GetCharges()) // we didn't get them all + if (item->GetCharges()) { // we didn't get them all return AutoPutLootInInventory(*item, try_worn, try_cursor, 0); + } return true; } } - for (i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) - { - for (uint8 j = SUB_BEGIN; j < EmuConstants::ITEM_CONTAINER_SIZE; j++) - { + for (i = EmuConstants::GENERAL_BEGIN; i <= EmuConstants::GENERAL_END; i++) { + for (uint8 j = SUB_BEGIN; j < EmuConstants::ITEM_CONTAINER_SIZE; j++) { uint16 slotid = Inventory::CalcSlotId(i, j); ItemInst* tmp_inst = m_inv.GetItem(slotid); - if(tmp_inst && tmp_inst->GetItem()->ID == item_id && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize){ + if(tmp_inst && tmp_inst->GetItem()->ID == item_id && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize) { MoveItemCharges(*item, slotid, type); CalcBonuses(); - if(item->GetCharges()) // we didn't get them all + if (item->GetCharges()) { // we didn't get them all return AutoPutLootInInventory(*item, try_worn, try_cursor, 0); + } return true; } } } return false; } + // Locate an available space in inventory to place an item // and then put the item there // The change will be saved to the database bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_cursor, ServerLootItem_Struct** bag_item_data) { // #1: Try to auto equip - if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel<=level && (!inst.GetItem()->Attuneable || inst.IsAttuned()) && inst.GetItem()->ItemType != ItemTypeAugmentation) - { + if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel<=level && (!inst.GetItem()->Attuneable || inst.IsAttuned()) && inst.GetItem()->ItemType != ItemTypeAugmentation) { // too messy as-is... - for (int16 i = EmuConstants::EQUIPMENT_BEGIN; i < MainPowerSource; i++) // originally (i < 22) - { + for (int16 i = EmuConstants::EQUIPMENT_BEGIN; i < MainPowerSource; i++) { // originally (i < 22) if (i == EmuConstants::GENERAL_BEGIN) { - if(this->GetClientVersion() >= EQClientSoF) { i = MainPowerSource; } // added power source check for SoF+ clients - else { break; } + // added power source check for SoF+ clients + if (this->GetClientVersion() >= EQClientSoF) + i = MainPowerSource; + else + break; } - if (!m_inv[i]) - { - if( i == MainPrimary && inst.IsWeapon() ) // If item is primary slot weapon - { - if( (inst.GetItem()->ItemType == ItemType2HSlash) || (inst.GetItem()->ItemType == ItemType2HBlunt) || (inst.GetItem()->ItemType == ItemType2HPiercing) ) // and uses 2hs \ 2hb \ 2hp - { - if( m_inv[MainSecondary] ) // and if secondary slot is not empty - { + if (!m_inv[i]) { + if (i == MainPrimary && inst.IsWeapon()) { // If item is primary slot weapon + if ((inst.GetItem()->ItemType == ItemType2HSlash) || (inst.GetItem()->ItemType == ItemType2HBlunt) || (inst.GetItem()->ItemType == ItemType2HPiercing)) { // and uses 2hs \ 2hb \ 2hp + if (m_inv[MainSecondary]) { // and if secondary slot is not empty continue; // Can't auto-equip } } } - if( i== MainSecondary && m_inv[MainPrimary]) // check to see if primary slot is a two hander - { + if (i == MainSecondary && m_inv[MainPrimary]) { // check to see if primary slot is a two hander uint8 use = m_inv[MainPrimary]->GetItem()->ItemType; - if(use == ItemType2HSlash || use == ItemType2HBlunt || use == ItemType2HPiercing) + if (use == ItemType2HSlash || use == ItemType2HBlunt || use == ItemType2HPiercing) continue; } - if - ( - i == MainSecondary && - inst.IsWeapon() && - !CanThisClassDualWield() - ) - { + if (i == MainSecondary && inst.IsWeapon() && !CanThisClassDualWield()) { continue; } - if (inst.IsEquipable(i)) // Equippable at this slot? - { + if (inst.IsEquipable(i)) { // Equippable at this slot? //send worn to everyone... PutLootInInventory(i, inst); uint8 worn_slot_material = Inventory::CalcMaterialFromSlot(i); - if(worn_slot_material != _MaterialInvalid) - { + if (worn_slot_material != _MaterialInvalid) { SendWearChange(worn_slot_material); } @@ -982,17 +976,15 @@ bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_curs } // #2: Stackable item? - if (inst.IsStackable()) - { - if(TryStacking(&inst, ItemPacketTrade, try_worn, try_cursor)) + if (inst.IsStackable()) { + if (TryStacking(&inst, ItemPacketTrade, try_worn, try_cursor)) return true; } // #3: put it in inventory bool is_arrow = (inst.GetItem()->ItemType == ItemTypeArrow) ? true : false; int16 slot_id = m_inv.FindFreeSlot(inst.IsType(ItemClassContainer), try_cursor, inst.GetItem()->Size, is_arrow); - if (slot_id != INVALID_INDEX) - { + if (slot_id != INVALID_INDEX) { PutLootInInventory(slot_id, inst, bag_item_data); return true; } @@ -1005,28 +997,27 @@ void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type) { ItemInst *tmp_inst = m_inv.GetItem(to_slot); - if(tmp_inst && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize) - { + if(tmp_inst && tmp_inst->GetCharges() < tmp_inst->GetItem()->StackSize) { // this is how much room is left on the item we're stacking onto int charge_slots_left = tmp_inst->GetItem()->StackSize - tmp_inst->GetCharges(); // this is how many charges we can move from the looted item to // the item in the inventory - int charges_to_move = - from.GetCharges() < charge_slots_left ? - from.GetCharges() : - charge_slots_left; + int charges_to_move = (from.GetCharges() < charge_slots_left) ? from.GetCharges() : charge_slots_left; tmp_inst->SetCharges(tmp_inst->GetCharges() + charges_to_move); from.SetCharges(from.GetCharges() - charges_to_move); SendLootItemInPacket(tmp_inst, to_slot); - if (to_slot == MainCursor){ - std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + if (to_slot == MainCursor) { + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); database.SaveCursor(this->CharacterID(), s, e); - } else + } + else { database.SaveInventory(this->CharacterID(), tmp_inst, to_slot); + } } } +#if 0 // TODO: needs clean-up to save references bool MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint8 evolving, uint8 evolvedlevel) { //we're sending back the entire "link", minus the null characters & item name @@ -1135,6 +1126,7 @@ bool MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 return false; } } +#endif int Client::GetItemLinkHash(const ItemInst* inst) { //pre-Titanium: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=70&postdays=0&postorder=asc @@ -1281,10 +1273,13 @@ bool Client::IsValidSlot(uint32 slot) { (slot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && slot <= EmuConstants::SHARED_BANK_BAGS_END) || (slot >= EmuConstants::TRADE_BEGIN && slot <= EmuConstants::TRADE_END) || (slot >= EmuConstants::WORLD_BEGIN && slot <= EmuConstants::WORLD_END) || - (slot == MainPowerSource)) + (slot == MainPowerSource) + ) { return true; - else + } + else { return false; + } } bool Client::IsBankSlot(uint32 slot) @@ -1361,11 +1356,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { int16 src_slot_id = (int16)move_in->from_slot; int16 dst_slot_id = (int16)move_in->to_slot; - if(IsBankSlot(src_slot_id) || - IsBankSlot(dst_slot_id) || - IsBankSlot(src_slot_check) || - IsBankSlot(dst_slot_check)) - { + if(IsBankSlot(src_slot_id) || IsBankSlot(dst_slot_id) || IsBankSlot(src_slot_check) || IsBankSlot(dst_slot_check)) { uint32 distance = 0; NPC *banker = entity_list.GetClosestBanker(this, distance); @@ -1555,7 +1546,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { { SendCursorBuffer(); } - std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); database.SaveCursor(character_id, s, e); } else @@ -1708,22 +1699,26 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } // Step 7: Save change to the database - if (src_slot_id == MainCursor){ + if (src_slot_id == MainCursor) { // If not swapping another item to cursor and stacking items were depleted if (dstitemid == 0 || all_to_stack == true) { SendCursorBuffer(); } - std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); database.SaveCursor(character_id, s, e); - } else + } + else { database.SaveInventory(character_id, m_inv.GetItem(src_slot_id), src_slot_id); + } if (dst_slot_id == MainCursor) { - std::list::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); database.SaveCursor(character_id, s, e); - } else + } + else { database.SaveInventory(character_id, m_inv.GetItem(dst_slot_id), dst_slot_id); + } if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in, true); } // QS Audit @@ -1928,16 +1923,17 @@ void Client::QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call) { void Client::DyeArmor(DyeStruct* dye){ int16 slot=0; for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_TINT_END; i++) { - if(m_pp.item_tint[i].rgb.blue!=dye->dye[i].rgb.blue || - m_pp.item_tint[i].rgb.red!=dye->dye[i].rgb.red || - m_pp.item_tint[i].rgb.green != dye->dye[i].rgb.green){ + if (m_pp.item_tint[i].rgb.blue != dye->dye[i].rgb.blue || + m_pp.item_tint[i].rgb.red != dye->dye[i].rgb.red || + m_pp.item_tint[i].rgb.green != dye->dye[i].rgb.green + ) { slot = m_inv.HasItem(32557, 1, invWherePersonal); if (slot != INVALID_INDEX){ DeleteItemInInventory(slot,1,true); uint8 slot2=SlotConvert(i); ItemInst* inst = this->m_inv.GetItem(slot2); if(inst){ - uint32 armor_color = (dye->dye[i].rgb.red * 65536) + (dye->dye[i].rgb.green * 256) + (dye->dye[i].rgb.blue); + uint32 armor_color = ((uint32)dye->dye[i].rgb.red << 16) | ((uint32)dye->dye[i].rgb.green << 8) | ((uint32)dye->dye[i].rgb.blue); inst->SetColor(armor_color); database.SaveCharacterMaterialColor(this->CharacterID(), i, armor_color); database.SaveInventory(CharacterID(),inst,slot2); @@ -1963,7 +1959,8 @@ void Client::DyeArmor(DyeStruct* dye){ } -/*bool Client::DecreaseByItemType(uint32 type, uint8 amt) { +#if 0 +bool Client::DecreaseByItemType(uint32 type, uint8 amt) { const Item_Struct* TempItem = 0; ItemInst* ins; int x; @@ -2012,10 +2009,11 @@ void Client::DyeArmor(DyeStruct* dye){ } } return false; -}*/ +} +#endif bool Client::DecreaseByID(uint32 type, uint8 amt) { - const Item_Struct* TempItem = 0; + const Item_Struct* TempItem = nullptr; ItemInst* ins = nullptr; int x; int num = 0; @@ -2023,7 +2021,7 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) { { if (x == MainCursor + 1) x = EmuConstants::GENERAL_BAGS_BEGIN; - TempItem = 0; + TempItem = nullptr; ins = GetInv().GetItem(x); if (ins) TempItem = ins->GetItem(); @@ -2040,7 +2038,7 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) { { if (x == MainCursor + 1) x = EmuConstants::GENERAL_BAGS_BEGIN; - TempItem = 0; + TempItem = nullptr; ins = GetInv().GetItem(x); if (ins) TempItem = ins->GetItem(); @@ -2063,151 +2061,133 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) { return true; } -void Client::RemoveNoRent(bool client_update) { - int16 slot_id = 0; - - // equipment - for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; +void Client::RemoveNoRent(bool client_update) +{ + for (auto slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; ++slot_id) { + auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); DeleteItemInInventory(slot_id, 0, client_update); } } - // general - for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; + for (auto slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; ++slot_id) { + auto inst = m_inv[slot_id]; if (inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); DeleteItemInInventory(slot_id, 0, client_update); } } - // power source if (m_inv[MainPowerSource]) { - const ItemInst* inst = m_inv[MainPowerSource]; + auto inst = m_inv[MainPowerSource]; if (inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource); DeleteItemInInventory(MainPowerSource, 0, (GetClientVersion() >= EQClientSoF) ? client_update : false); // Ti slot non-existent } } - // containers - for(slot_id = EmuConstants::GENERAL_BAGS_BEGIN; slot_id <= EmuConstants::CURSOR_BAG_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; + for (auto slot_id = EmuConstants::GENERAL_BAGS_BEGIN; slot_id <= EmuConstants::CURSOR_BAG_END; ++slot_id) { + auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); DeleteItemInInventory(slot_id, 0, client_update); } } - // bank - for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; + for (auto slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; ++slot_id) { + auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); DeleteItemInInventory(slot_id, 0, false); // Can't delete from client Bank slots } } - // bank containers - for(slot_id = EmuConstants::BANK_BAGS_BEGIN; slot_id <= EmuConstants::BANK_BAGS_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; + for (auto slot_id = EmuConstants::BANK_BAGS_BEGIN; slot_id <= EmuConstants::BANK_BAGS_END; ++slot_id) { + auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); DeleteItemInInventory(slot_id, 0, false); // Can't delete from client Bank Container slots } } - // shared bank - for(slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; + for (auto slot_id = EmuConstants::SHARED_BANK_BEGIN; slot_id <= EmuConstants::SHARED_BANK_END; ++slot_id) { + auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); DeleteItemInInventory(slot_id, 0, false); // Can't delete from client Shared Bank slots } } - // shared bank containers - for(slot_id = EmuConstants::SHARED_BANK_BAGS_BEGIN; slot_id <= EmuConstants::SHARED_BANK_BAGS_END; slot_id++) { - const ItemInst* inst = m_inv[slot_id]; + for (auto slot_id = EmuConstants::SHARED_BANK_BAGS_BEGIN; slot_id <= EmuConstants::SHARED_BANK_BAGS_END; ++slot_id) { + auto inst = m_inv[slot_id]; if(inst && !inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); DeleteItemInInventory(slot_id, 0, false); // Can't delete from client Shared Bank Container slots } } - // cursor & limbo if (!m_inv.CursorEmpty()) { std::list local; - ItemInst* inst = nullptr; while (!m_inv.CursorEmpty()) { - inst = m_inv.PopItem(MainCursor); - if (inst) - local.push_back(inst); + auto inst = m_inv.PopItem(MainCursor); + if (inst == nullptr) { continue; } + local.push_back(inst); } - std::list::iterator iter = local.begin(); - while (iter != local.end()) { - inst = *iter; - // should probably put a check here for valid pointer..but, that was checked when the item was put into inventory -U - if (!inst->GetItem()->NoRent) + for (auto iter = local.begin(); iter != local.end(); ++iter) { + auto inst = *iter; + if (inst == nullptr) { continue; } + if (!inst->GetItem()->NoRent) { mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from `Limbo`", inst->GetItem()->Name); - else - m_inv.PushCursor(**iter); - - safe_delete(*iter); - iter = local.erase(iter); + } + else { + m_inv.PushCursor(*inst); + } + safe_delete(inst); } - - std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); - database.SaveCursor(this->CharacterID(), s, e); local.clear(); + + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + database.SaveCursor(this->CharacterID(), s, e); } } // Two new methods to alleviate perpetual login desyncs -void Client::RemoveDuplicateLore(bool client_update) { - int16 slot_id = 0; - - // equipment - for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { - ItemInst* inst = m_inv.PopItem(slot_id); - if(inst) { - if(CheckLoreConflict(inst->GetItem())) { - mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); - database.SaveInventory(character_id, nullptr, slot_id); - } - else { - m_inv.PutItem(slot_id, *inst); - } - safe_delete(inst); +void Client::RemoveDuplicateLore(bool client_update) +{ + for (auto slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; ++slot_id) { + auto inst = m_inv.PopItem(slot_id); + if (inst == nullptr) { continue; } + if(CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, slot_id); } + else { + m_inv.PutItem(slot_id, *inst); + } + safe_delete(inst); + } + + for (auto slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; ++slot_id) { + auto inst = m_inv.PopItem(slot_id); + if (inst == nullptr) { continue; } + if (CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, slot_id); + } + else { + m_inv.PutItem(slot_id, *inst); + } + safe_delete(inst); } - // general - for (slot_id = EmuConstants::GENERAL_BEGIN; slot_id <= EmuConstants::GENERAL_END; slot_id++) { - ItemInst* inst = m_inv.PopItem(slot_id); - if (inst) { - if (CheckLoreConflict(inst->GetItem())) { - mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); - database.SaveInventory(character_id, nullptr, slot_id); - } - else { - m_inv.PutItem(slot_id, *inst); - } - safe_delete(inst); - } - } - - // power source if (m_inv[MainPowerSource]) { - ItemInst* inst = m_inv.PopItem(MainPowerSource); + auto inst = m_inv.PopItem(MainPowerSource); if (inst) { if (CheckLoreConflict(inst->GetItem())) { - mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, MainPowerSource); database.SaveInventory(character_id, nullptr, MainPowerSource); } else { @@ -2217,108 +2197,96 @@ void Client::RemoveDuplicateLore(bool client_update) { } } - // containers - for(slot_id = EmuConstants::GENERAL_BAGS_BEGIN; slot_id <= EmuConstants::CURSOR_BAG_END; slot_id++) { - ItemInst* inst = m_inv.PopItem(slot_id); - if(inst) { - if(CheckLoreConflict(inst->GetItem())) { - mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); - database.SaveInventory(character_id, nullptr, slot_id); - } - else { - m_inv.PutItem(slot_id, *inst); - } - safe_delete(inst); + for (auto slot_id = EmuConstants::GENERAL_BAGS_BEGIN; slot_id <= EmuConstants::CURSOR_BAG_END; ++slot_id) { + auto inst = m_inv.PopItem(slot_id); + if (inst == nullptr) { continue; } + if(CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, slot_id); } + else { + m_inv.PutItem(slot_id, *inst); + } + safe_delete(inst); } - // bank - for(slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; slot_id++) { - ItemInst* inst = m_inv.PopItem(slot_id); - if(inst) { - if(CheckLoreConflict(inst->GetItem())) { - mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); - database.SaveInventory(character_id, nullptr, slot_id); - } - else { - m_inv.PutItem(slot_id, *inst); - } - safe_delete(inst); + for (auto slot_id = EmuConstants::BANK_BEGIN; slot_id <= EmuConstants::BANK_END; ++slot_id) { + auto inst = m_inv.PopItem(slot_id); + if (inst == nullptr) { continue; } + if(CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, slot_id); } + else { + m_inv.PutItem(slot_id, *inst); + } + safe_delete(inst); } - // bank containers - for(slot_id = EmuConstants::BANK_BAGS_BEGIN; slot_id <= EmuConstants::BANK_BAGS_END; slot_id++) { - ItemInst* inst = m_inv.PopItem(slot_id); - if(inst) { - if(CheckLoreConflict(inst->GetItem())) { - mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); - database.SaveInventory(character_id, nullptr, slot_id); - } - else { - m_inv.PutItem(slot_id, *inst); - } - safe_delete(inst); + for (auto slot_id = EmuConstants::BANK_BAGS_BEGIN; slot_id <= EmuConstants::BANK_BAGS_END; ++slot_id) { + auto inst = m_inv.PopItem(slot_id); + if (inst == nullptr) { continue; } + if(CheckLoreConflict(inst->GetItem())) { + mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, slot_id); + database.SaveInventory(character_id, nullptr, slot_id); } + else { + m_inv.PutItem(slot_id, *inst); + } + safe_delete(inst); } // Shared Bank and Shared Bank Containers are not checked due to their allowing duplicate lore items -U - // cursor & limbo if (!m_inv.CursorEmpty()) { - std::list local; - ItemInst* inst = nullptr; + std::list local_1; + std::list local_2; while (!m_inv.CursorEmpty()) { - inst = m_inv.PopItem(MainCursor); - if (inst) - local.push_back(inst); + auto inst = m_inv.PopItem(MainCursor); + if (inst == nullptr) { continue; } + local_1.push_back(inst); } - std::list::iterator iter = local.begin(); - while (iter != local.end()) { - inst = *iter; - // probably needs a valid pointer check -U + for (auto iter = local_1.begin(); iter != local_1.end(); ++iter) { + auto inst = *iter; + if (inst == nullptr) { continue; } if (CheckLoreConflict(inst->GetItem())) { mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name); - safe_delete(*iter); - iter = local.erase(iter); + safe_delete(inst); } else { - ++iter; + local_2.push_back(inst); } } + local_1.clear(); - iter = local.begin(); - while (iter != local.end()) { - inst = *iter; + for (auto iter = local_2.begin(); iter != local_2.end(); ++iter) { + auto inst = *iter; + if (inst == nullptr) { continue; } if (!inst->GetItem()->LoreFlag || ((inst->GetItem()->LoreGroup == -1) && (m_inv.HasItem(inst->GetID(), 0, invWhereCursor) == INVALID_INDEX)) || - (inst->GetItem()->LoreGroup && ~inst->GetItem()->LoreGroup && (m_inv.HasItemByLoreGroup(inst->GetItem()->LoreGroup, invWhereCursor) == INVALID_INDEX))) { - - m_inv.PushCursor(**iter); + (inst->GetItem()->LoreGroup && (~inst->GetItem()->LoreGroup) && (m_inv.HasItemByLoreGroup(inst->GetItem()->LoreGroup, invWhereCursor) == INVALID_INDEX)) + ) { + m_inv.PushCursor(*inst); } else { mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name); } - - safe_delete(*iter); - iter = local.erase(iter); + safe_delete(inst); } + local_2.clear(); - std::list::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end(); + auto s = m_inv.cursor_begin(), e = m_inv.cursor_end(); database.SaveCursor(this->CharacterID(), s, e); - local.clear(); } } -void Client::MoveSlotNotAllowed(bool client_update) { - int16 slot_id = 0; - - // equipment - for(slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; slot_id++) { +void Client::MoveSlotNotAllowed(bool client_update) +{ + for (auto slot_id = EmuConstants::EQUIPMENT_BEGIN; slot_id <= EmuConstants::EQUIPMENT_END; ++slot_id) { if(m_inv[slot_id] && !m_inv[slot_id]->IsSlotAllowed(slot_id)) { - ItemInst* inst = m_inv.PopItem(slot_id); + auto inst = m_inv.PopItem(slot_id); bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false; int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow); mlog(INVENTORY__ERROR, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id); @@ -2328,15 +2296,13 @@ void Client::MoveSlotNotAllowed(bool client_update) { } } - // power source - slot_id = MainPowerSource; - if(m_inv[slot_id] && !m_inv[slot_id]->IsSlotAllowed(slot_id)) { - ItemInst* inst = m_inv.PopItem(slot_id); + if (m_inv[MainPowerSource] && !m_inv[MainPowerSource]->IsSlotAllowed(MainPowerSource)) { + auto inst = m_inv.PopItem(MainPowerSource); bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false; int16 free_slot_id = m_inv.FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow); - mlog(INVENTORY__ERROR, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id); + mlog(INVENTORY__ERROR, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, MainPowerSource, free_slot_id); PutItemInInventory(free_slot_id, *inst, (GetClientVersion() >= EQClientSoF) ? client_update : false); - database.SaveInventory(character_id, nullptr, slot_id); + database.SaveInventory(character_id, nullptr, MainPowerSource); safe_delete(inst); } @@ -2371,7 +2337,7 @@ uint32 Client::GetEquipment(uint8 material_slot) const return 0; } -/* +#if 0 int32 Client::GetEquipmentMaterial(uint8 material_slot) { const Item_Struct *item; @@ -2384,24 +2350,16 @@ int32 Client::GetEquipmentMaterial(uint8 material_slot) return 0; } -*/ +#endif uint32 Client::GetEquipmentColor(uint8 material_slot) const { - const Item_Struct *item; - - if(material_slot > EmuConstants::MATERIAL_END) - { + if (material_slot > EmuConstants::MATERIAL_END) return 0; - } - item = database.GetItem(GetEquipment(material_slot)); - if(item != 0) - { - return m_pp.item_tint[material_slot].rgb.use_tint ? - m_pp.item_tint[material_slot].color : - item->Color; - } + const Item_Struct *item = database.GetItem(GetEquipment(material_slot)); + if(item != nullptr) + return ((m_pp.item_tint[material_slot].rgb.use_tint) ? m_pp.item_tint[material_slot].color : item->Color); return 0; } @@ -2435,7 +2393,7 @@ void Client::SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType EQApplicationPacket* Client::ReturnItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type) { if (!inst) - return 0; + return nullptr; // Serialize item into |-delimited string std::string packet = inst->Serialize(slot_id); @@ -2541,8 +2499,9 @@ void Client::SetBandolier(const EQApplicationPacket *app) { if (slot == INVALID_INDEX) { if (m_inv.GetItem(MainCursor)) { if (m_inv.GetItem(MainCursor)->GetItem()->ID == m_pp.bandoliers[bss->number].items[BandolierSlot].item_id && - m_inv.GetItem(MainCursor)->GetCharges() >= 1) // '> 0' the same, but this matches Inventory::_HasItem conditional check + m_inv.GetItem(MainCursor)->GetCharges() >= 1) { // '> 0' the same, but this matches Inventory::_HasItem conditional check slot = MainCursor; + } else if (m_inv.GetItem(MainCursor)->GetItem()->ItemClass == 1) { for(int16 CursorBagSlot = EmuConstants::CURSOR_BAG_BEGIN; CursorBagSlot <= EmuConstants::CURSOR_BAG_END; CursorBagSlot++) { if (m_inv.GetItem(CursorBagSlot)) { @@ -2575,11 +2534,13 @@ void Client::SetBandolier(const EQApplicationPacket *app) { database.SaveInventory(character_id, BandolierItems[BandolierSlot], slot); BandolierItems[BandolierSlot]->SetCharges(1); } - else // Remove the item from the inventory + else { // Remove the item from the inventory database.SaveInventory(character_id, 0, slot); + } } - else // Remove the item from the inventory + else { // Remove the item from the inventory database.SaveInventory(character_id, 0, slot); + } } else { // The player doesn't have the required weapon with them. BandolierItems[BandolierSlot] = 0; @@ -2588,16 +2549,15 @@ void Client::SetBandolier(const EQApplicationPacket *app) { ItemInst *InvItem = m_inv.PopItem(WeaponSlot); if(InvItem) { // If there was an item in that weapon slot, put it in the inventory - _log(INVENTORY__BANDOLIER, "returning item %s in weapon slot %i to inventory", - InvItem->GetItem()->Name, WeaponSlot); - if(MoveItemToInventory(InvItem)) + _log(INVENTORY__BANDOLIER, "returning item %s in weapon slot %i to inventory", InvItem->GetItem()->Name, WeaponSlot); + if (MoveItemToInventory(InvItem)) { database.SaveInventory(character_id, 0, WeaponSlot); - else - _log(INVENTORY__BANDOLIER, "Char: %s, ERROR returning %s to inventory", GetName(), - InvItem->GetItem()->Name); + } + else { + _log(INVENTORY__BANDOLIER, "Char: %s, ERROR returning %s to inventory", GetName(), InvItem->GetItem()->Name); + } safe_delete(InvItem); } - } } } @@ -2627,9 +2587,9 @@ void Client::SetBandolier(const EQApplicationPacket *app) { if(InvItem) { // If there was already an item in that weapon slot that we replaced, find a place to put it - if(!MoveItemToInventory(InvItem)) - _log(INVENTORY__BANDOLIER, "Char: %s, ERROR returning %s to inventory", GetName(), - InvItem->GetItem()->Name); + if (!MoveItemToInventory(InvItem)) { + _log(INVENTORY__BANDOLIER, "Char: %s, ERROR returning %s to inventory", GetName(), InvItem->GetItem()->Name); + } safe_delete(InvItem); } } @@ -2639,14 +2599,14 @@ void Client::SetBandolier(const EQApplicationPacket *app) { // put it in the player's inventory. ItemInst *InvItem = m_inv.PopItem(WeaponSlot); if(InvItem) { - _log(INVENTORY__BANDOLIER, "Bandolier has no item for slot %i, returning item %s to inventory", - WeaponSlot, InvItem->GetItem()->Name); + _log(INVENTORY__BANDOLIER, "Bandolier has no item for slot %i, returning item %s to inventory", WeaponSlot, InvItem->GetItem()->Name); // If there was an item in that weapon slot, put it in the inventory - if(MoveItemToInventory(InvItem)) + if (MoveItemToInventory(InvItem)) { database.SaveInventory(character_id, 0, WeaponSlot); - else - _log(INVENTORY__BANDOLIER, "Char: %s, ERROR returning %s to inventory", GetName(), - InvItem->GetItem()->Name); + } + else { + _log(INVENTORY__BANDOLIER, "Char: %s, ERROR returning %s to inventory", GetName(), InvItem->GetItem()->Name); + } safe_delete(InvItem); } } @@ -2674,7 +2634,9 @@ bool Client::MoveItemToInventory(ItemInst *ItemToReturn, bool UpdateClient) { // depends on current behaviour, this routine operates the same as the client when moving items back to inventory when // swapping bandolier sets. - if(!ItemToReturn) return false; + if (!ItemToReturn) { + return false; + } _log(INVENTORY__SLOTS,"Char: %s Returning %s to inventory", GetName(), ItemToReturn->GetItem()->Name); @@ -2692,8 +2654,7 @@ bool Client::MoveItemToInventory(ItemInst *ItemToReturn, bool UpdateClient) { int ChargeSlotsLeft = InvItem->GetItem()->StackSize - InvItem->GetCharges(); - int ChargesToMove = ItemToReturn->GetCharges() < ChargeSlotsLeft ? ItemToReturn->GetCharges() : - ChargeSlotsLeft; + int ChargesToMove = ItemToReturn->GetCharges() < ChargeSlotsLeft ? ItemToReturn->GetCharges() : ChargeSlotsLeft; InvItem->SetCharges(InvItem->GetCharges() + ChargesToMove); @@ -2723,17 +2684,14 @@ bool Client::MoveItemToInventory(ItemInst *ItemToReturn, bool UpdateClient) { int ChargeSlotsLeft = InvItem->GetItem()->StackSize - InvItem->GetCharges(); - int ChargesToMove = ItemToReturn->GetCharges() < ChargeSlotsLeft - ? ItemToReturn->GetCharges() : ChargeSlotsLeft; + int ChargesToMove = ItemToReturn->GetCharges() < ChargeSlotsLeft ? ItemToReturn->GetCharges() : ChargeSlotsLeft; InvItem->SetCharges(InvItem->GetCharges() + ChargesToMove); if(UpdateClient) - SendItemPacket(BaseSlotID + BagSlot, m_inv.GetItem(BaseSlotID + BagSlot), - ItemPacketTrade); + SendItemPacket(BaseSlotID + BagSlot, m_inv.GetItem(BaseSlotID + BagSlot), ItemPacketTrade); - database.SaveInventory(character_id, m_inv.GetItem(BaseSlotID + BagSlot), - BaseSlotID + BagSlot); + database.SaveInventory(character_id, m_inv.GetItem(BaseSlotID + BagSlot), BaseSlotID + BagSlot); ItemToReturn->SetCharges(ItemToReturn->GetCharges() - ChargesToMove); @@ -2808,30 +2766,45 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool std::map instmap; // build reference map - for (int16 index = MAIN_BEGIN; index < EmuConstants::MAP_POSSESSIONS_SIZE; ++index) - if (m_inv[index]) - instmap[index] = m_inv[index]; - for (int16 index = EmuConstants::TRIBUTE_BEGIN; index <= EmuConstants::TRIBUTE_END; ++index) - if (m_inv[index]) - instmap[index] = m_inv[index]; - for (int16 index = EmuConstants::BANK_BEGIN; index <= EmuConstants::BANK_END; ++index) - if (m_inv[index]) - instmap[index] = m_inv[index]; - for (int16 index = EmuConstants::SHARED_BANK_BEGIN; index <= EmuConstants::SHARED_BANK_END; ++index) - if (m_inv[index]) - instmap[index] = m_inv[index]; - for (int16 index = EmuConstants::TRADE_BEGIN; index <= EmuConstants::TRADE_END; ++index) - if (m_inv[index]) - instmap[index] = m_inv[index]; + for (int16 index = MAIN_BEGIN; index < EmuConstants::MAP_POSSESSIONS_SIZE; ++index) { + auto inst = m_inv[index]; + if (inst == nullptr) { continue; } + instmap[index] = inst; + } + for (int16 index = EmuConstants::TRIBUTE_BEGIN; index <= EmuConstants::TRIBUTE_END; ++index) { + auto inst = m_inv[index]; + if (inst == nullptr) { continue; } + instmap[index] = inst; + } + for (int16 index = EmuConstants::BANK_BEGIN; index <= EmuConstants::BANK_END; ++index) { + auto inst = m_inv[index]; + if (inst == nullptr) { continue; } + instmap[index] = inst; + } + for (int16 index = EmuConstants::SHARED_BANK_BEGIN; index <= EmuConstants::SHARED_BANK_END; ++index) { + auto inst = m_inv[index]; + if (inst == nullptr) { continue; } + instmap[index] = inst; + } + for (int16 index = EmuConstants::TRADE_BEGIN; index <= EmuConstants::TRADE_END; ++index) { + auto inst = m_inv[index]; + if (inst == nullptr) { continue; } + instmap[index] = inst; + } - if (Object* tsobject = GetTradeskillObject()) - for (int16 index = MAIN_BEGIN; index < EmuConstants::MAP_WORLD_SIZE; ++index) - if (tsobject->GetItem(index)) - instmap[EmuConstants::WORLD_BEGIN + index] = tsobject->GetItem(index); + auto tsobject = GetTradeskillObject(); + if (tsobject != nullptr) { + for (int16 index = MAIN_BEGIN; index < EmuConstants::MAP_WORLD_SIZE; ++index) { + auto inst = tsobject->GetItem(index); + if (inst == nullptr) { continue; } + instmap[EmuConstants::WORLD_BEGIN + index] = inst; + } + } int limbo = 0; - for (iter_queue cursor_itr = m_inv.cursor_begin(); cursor_itr != m_inv.cursor_end(); ++cursor_itr, ++limbo) { - if (cursor_itr == m_inv.cursor_begin()) // m_inv.cursor_begin() is referenced as MainCursor in MapPossessions above + for (auto cursor_itr = m_inv.cursor_begin(); cursor_itr != m_inv.cursor_end(); ++cursor_itr, ++limbo) { + // m_inv.cursor_begin() is referenced as MainCursor in MapPossessions above + if (cursor_itr == m_inv.cursor_begin()) continue; instmap[8000 + limbo] = *cursor_itr; @@ -2841,20 +2814,24 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool instmap[MainPowerSource] = m_inv[MainPowerSource]; // call InterrogateInventory_ for error check - for (std::map::iterator instmap_itr = instmap.begin(); (instmap_itr != instmap.end()) && (!error); ++instmap_itr) + for (std::map::iterator instmap_itr = instmap.begin(); (instmap_itr != instmap.end()) && (!error); ++instmap_itr) { InterrogateInventory_(true, requester, instmap_itr->first, INVALID_INDEX, instmap_itr->second, nullptr, log, silent, error, 0); + } if (autolog && error && (!log)) log = true; - if (log) + if (log) { _log(INVENTORY__ERROR, "Client::InterrogateInventory() called for %s by %s with an error state of %s", GetName(), requester->GetName(), (error ? "TRUE" : "FALSE")); - if (!silent) + } + if (!silent) { requester->Message(1, "--- Inventory Interrogation Report for %s (requested by: %s, error state: %s) ---", GetName(), requester->GetName(), (error ? "TRUE" : "FALSE")); + } // call InterrogateInventory_ for report - for (std::map::iterator instmap_itr = instmap.begin(); (instmap_itr != instmap.end()); ++instmap_itr) + for (std::map::iterator instmap_itr = instmap.begin(); (instmap_itr != instmap.end()); ++instmap_itr) { InterrogateInventory_(false, requester, instmap_itr->first, INVALID_INDEX, instmap_itr->second, nullptr, log, silent, error, 0); + } if (error) { Message(13, "An error has been discovered in your inventory!"); @@ -2891,10 +2868,12 @@ void Client::InterrogateInventory_(bool errorcheck, Client* requester, int16 hea error = true; } else { - if (inst) - for (int16 sub = SUB_BEGIN; (sub < EmuConstants::ITEM_CONTAINER_SIZE) && (!error); ++sub) // treat any ItemInst as having the max internal slots available + if (inst) { + for (int16 sub = SUB_BEGIN; (sub < EmuConstants::ITEM_CONTAINER_SIZE) && (!error); ++sub) { // treat any ItemInst as having the max internal slots available if (inst->GetItem(sub)) InterrogateInventory_(true, requester, head, sub, inst->GetItem(sub), inst, log, silent, error, depth + 1); + } + } } } else { @@ -2903,24 +2882,28 @@ void Client::InterrogateInventory_(bool errorcheck, Client* requester, int16 hea std::string p; std::string e; - if (inst) { i = StringFormat("%s (class: %u | augtype: %u)", inst->GetItem()->Name, inst->GetItem()->ItemClass, inst->GetItem()->AugType); } + if (inst) { i = StringFormat("%s (id: %u, cls: %u, aug_t: %u)", inst->GetItem()->Name, inst->GetItem()->ID, inst->GetItem()->ItemClass, inst->GetItem()->AugType); } else { i = "NONE"; } - if (parent) { p = StringFormat("%s (class: %u | augtype: %u), index: %i", parent->GetItem()->Name, parent->GetItem()->ItemClass, parent->GetItem()->AugType, index); } + if (parent) { p = StringFormat("%s (id: %u, cls: %u, aug_t: %u), index: %i", parent->GetItem()->Name, parent->GetItem()->ID, parent->GetItem()->ItemClass, parent->GetItem()->AugType, index); } else { p = "NONE"; } if (localerror) { e = " [ERROR]"; } else { e = ""; } - if (log) + if (log) { _log(INVENTORY__ERROR, "Head: %i, Depth: %i, Instance: %s, Parent: %s%s", - head, depth, i.c_str(), p.c_str(), e.c_str()); - if (!silent) - requester->Message(1, "%i:%i - inst: %s - parent: %s%s", - head, depth, i.c_str(), p.c_str(), e.c_str()); + head, depth, i.c_str(), p.c_str(), e.c_str()); + } + if (!silent) { + requester->Message(6, "%i:%i - inst: %s - parent: %s%s", + head, depth, i.c_str(), p.c_str(), e.c_str()); + } - if (inst) - for (int16 sub = SUB_BEGIN; (sub < EmuConstants::ITEM_CONTAINER_SIZE); ++sub) + if (inst) { + for (int16 sub = SUB_BEGIN; (sub < EmuConstants::ITEM_CONTAINER_SIZE); ++sub) { if (inst->GetItem(sub)) InterrogateInventory_(false, requester, head, sub, inst->GetItem(sub), inst, log, silent, error, depth + 1); + } + } } return;