Excluded limbo (cursor buffer) from HasItem checks

This commit is contained in:
Uleat 2015-02-06 09:58:57 -05:00
parent 5d64012d74
commit 5a619bddaf
3 changed files with 75 additions and 20 deletions

View File

@ -3,6 +3,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50)
== 02/06/2015 == == 02/06/2015 ==
Uleat: Updated returns for Inventory and ItemInst const iterators. (const == const) Uleat: Updated returns for Inventory and ItemInst const iterators. (const == const)
Uleat: Replaced 'iter_inst' and 'iter_contents' typedefs with their stl definitions Uleat: Replaced 'iter_inst' and 'iter_contents' typedefs with their stl definitions
Uleat: Removed 'limbo' from the 'HasItem' series of checks - including lore checks. The client excludes this range and it causes issues when performing item searches - dupe lore checks were added to account for this.
== 02/03/2015 == == 02/03/2015 ==
Trevius: Crashfix for TempName() when numbers are passed at the end of the name. Trevius: Crashfix for TempName() when numbers are passed at the end of the name.

View File

@ -506,6 +506,7 @@ int16 Inventory::HasItem(uint32 item_id, uint8 quantity, uint8 where)
return slot_id; return slot_id;
} }
// Behavioral change - Limbo is no longer checked due to improper handling of return value
if (where & invWhereCursor) { if (where & invWhereCursor) {
// Check cursor queue // Check cursor queue
slot_id = _HasItem(m_cursor, item_id, quantity); slot_id = _HasItem(m_cursor, item_id, quantity);
@ -552,6 +553,7 @@ int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
return slot_id; return slot_id;
} }
// Behavioral change - Limbo is no longer checked due to improper handling of return value
if (where & invWhereCursor) { if (where & invWhereCursor) {
// Check cursor queue // Check cursor queue
slot_id = _HasItemByUse(m_cursor, use, quantity); slot_id = _HasItemByUse(m_cursor, use, quantity);
@ -597,6 +599,7 @@ int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where)
return slot_id; return slot_id;
} }
// Behavioral change - Limbo is no longer checked due to improper handling of return value
if (where & invWhereCursor) { if (where & invWhereCursor) {
// Check cursor queue // Check cursor queue
slot_id = _HasItemByLoreGroup(m_cursor, loregroup); slot_id = _HasItemByLoreGroup(m_cursor, loregroup);
@ -1119,6 +1122,8 @@ ItemInst* Inventory::_GetItem(const std::map<int16, ItemInst*>& bucket, int16 sl
// Assumes item has already been allocated // Assumes item has already been allocated
int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst) int16 Inventory::_PutItem(int16 slot_id, ItemInst* inst)
{ {
// What happens here when we _PutItem(MainCursor)? Bad things..really bad things...
//
// If putting a nullptr into slot, we need to remove slot without memory delete // If putting a nullptr into slot, we need to remove slot without memory delete
if (inst == nullptr) { if (inst == nullptr) {
//Why do we not delete the poped item here???? //Why do we not delete the poped item here????
@ -1263,6 +1268,9 @@ int16 Inventory::_HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity)
return legacy::SLOT_AUGMENT; return legacy::SLOT_AUGMENT;
} }
} }
// We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo)
break;
} }
return INVALID_INDEX; return INVALID_INDEX;
@ -1327,6 +1335,9 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
return Inventory::CalcSlotId(MainCursor, bag_iter->first); return Inventory::CalcSlotId(MainCursor, bag_iter->first);
} }
} }
// We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo)
break;
} }
return INVALID_INDEX; return INVALID_INDEX;
@ -1406,6 +1417,9 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
return legacy::SLOT_AUGMENT; return legacy::SLOT_AUGMENT;
} }
} }
// We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo)
break;
} }
return INVALID_INDEX; return INVALID_INDEX;

View File

@ -177,16 +177,16 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
} }
bool Client::CheckLoreConflict(const Item_Struct* item) { bool Client::CheckLoreConflict(const Item_Struct* item)
if (!item) {
return false; if (!item) { return false; }
if (!(item->LoreFlag)) if (!item->LoreFlag) { return false; }
return false; if (item->LoreGroup == 0) { return false; }
if (item->LoreGroup == -1) // Standard lore items; look everywhere except the shared bank, return the result if (item->LoreGroup == 0xFFFFFFFF) // Standard lore items; look everywhere except the shared bank, return the result
return (m_inv.HasItem(item->ID, 0, ~invWhereSharedBank) != INVALID_INDEX); return (m_inv.HasItem(item->ID, 0, ~invWhereSharedBank) != INVALID_INDEX);
//If the item has a lore group, we check for other items with the same group and return the result // If the item has a lore group, we check for other items with the same group and return the result
return (m_inv.HasItemByLoreGroup(item->LoreGroup, ~invWhereSharedBank) != INVALID_INDEX); return (m_inv.HasItemByLoreGroup(item->LoreGroup, ~invWhereSharedBank) != INVALID_INDEX);
} }
@ -680,20 +680,37 @@ int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
return INVALID_ID; return INVALID_ID;
} }
void Client::SendCursorBuffer() { void Client::SendCursorBuffer()
{
// Temporary work-around for the RoF+ Client Buffer // Temporary work-around for the RoF+ Client Buffer
// Instead of dealing with client moving items in cursor buffer, // Instead of dealing with client moving items in cursor buffer,
// we can just send the next item in the cursor buffer to the cursor. // we can just send the next item in the cursor buffer to the cursor.
if (GetClientVersion() >= ClientVersion::RoF) if (GetClientVersion() < ClientVersion::RoF) { return; }
{ if (GetInv().CursorEmpty()) { return; }
if (!GetInv().CursorEmpty())
{ auto test_inst = GetInv().GetCursorItem();
const ItemInst* inst = GetInv().GetCursorItem(); if (test_inst == nullptr) { return; }
if (inst) auto test_item = test_inst->GetItem();
{ if (test_item == nullptr) { return; }
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
bool lore_pass = true;
if (test_item->LoreGroup == 0xFFFFFFFF) {
lore_pass = (m_inv.HasItem(test_item->ID, 0, ~(invWhereSharedBank | invWhereCursor)) == INVALID_INDEX);
} }
else if (test_item->LoreGroup != 0) {
lore_pass = (m_inv.HasItemByLoreGroup(test_item->LoreGroup, ~(invWhereSharedBank | invWhereCursor)) == INVALID_INDEX);
} }
if (!lore_pass) {
Log.Out(Logs::General, Logs::Inventory, "(%s) Duplicate lore items are not allowed - destroying item %s(id:%u) on cursor",
GetName(), test_item->Name, test_item->ID);
Message_StringID(MT_LootMessages, 290);
parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0);
DeleteItemInInventory(MainCursor);
SendCursorBuffer();
}
else {
SendItemPacket(MainCursor, test_inst, ItemPacketSummonItem);
} }
} }
@ -1320,10 +1337,33 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
return false; return false;
} }
// This could be expounded upon at some point to let the server know that
// the client has moved a buffered cursor item onto the active cursor -U
if (move_in->from_slot == move_in->to_slot) { // Item summon, no further processing needed if (move_in->from_slot == move_in->to_slot) { // Item summon, no further processing needed
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
if (GetClientVersion() >= ClientVersion::RoF) { return true; } // Can't do RoF+
if (move_in->to_slot == MainCursor) {
auto test_inst = m_inv.GetItem(MainCursor);
if (test_inst == nullptr) { return true; }
auto test_item = test_inst->GetItem();
if (test_item == nullptr) { return true; }
if (!test_item->LoreFlag) { return true; }
bool lore_pass = true;
if (test_item->LoreGroup == 0xFFFFFFFF) {
lore_pass = (m_inv.HasItem(test_item->ID, 0, ~(invWhereSharedBank | invWhereCursor)) == INVALID_INDEX);
}
else if (test_item->LoreGroup != 0) {
lore_pass = (m_inv.HasItemByLoreGroup(test_item->LoreGroup, ~(invWhereSharedBank | invWhereCursor)) == INVALID_INDEX);
}
if (!lore_pass) {
Log.Out(Logs::General, Logs::Inventory, "(%s) Duplicate lore items are not allowed - destroying item %s(id:%u) on cursor",
GetName(), test_item->Name, test_item->ID);
Message_StringID(MT_LootMessages, 290);
parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0);
DeleteItemInInventory(MainCursor, 0, true);
}
}
return true; return true;
} }