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 ==
Uleat: Updated returns for Inventory and ItemInst const iterators. (const == const)
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 ==
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;
}
// Behavioral change - Limbo is no longer checked due to improper handling of return value
if (where & invWhereCursor) {
// Check cursor queue
slot_id = _HasItem(m_cursor, item_id, quantity);
@ -552,6 +553,7 @@ int16 Inventory::HasItemByUse(uint8 use, uint8 quantity, uint8 where)
return slot_id;
}
// Behavioral change - Limbo is no longer checked due to improper handling of return value
if (where & invWhereCursor) {
// Check cursor queue
slot_id = _HasItemByUse(m_cursor, use, quantity);
@ -597,6 +599,7 @@ int16 Inventory::HasItemByLoreGroup(uint32 loregroup, uint8 where)
return slot_id;
}
// Behavioral change - Limbo is no longer checked due to improper handling of return value
if (where & invWhereCursor) {
// Check cursor queue
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
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 (inst == nullptr) {
//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;
}
}
// We only check the visible cursor due to lack of queue processing ability (client allows duplicate in limbo)
break;
}
return INVALID_INDEX;
@ -1327,6 +1335,9 @@ int16 Inventory::_HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity)
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;
@ -1406,6 +1417,9 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup)
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;

View File

@ -177,13 +177,13 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
}
bool Client::CheckLoreConflict(const Item_Struct* item) {
if (!item)
return false;
if (!(item->LoreFlag))
return false;
bool Client::CheckLoreConflict(const Item_Struct* item)
{
if (!item) { return false; }
if (!item->LoreFlag) { 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);
// If the item has a lore group, we check for other items with the same group and return the result
@ -680,20 +680,37 @@ int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
return INVALID_ID;
}
void Client::SendCursorBuffer() {
void Client::SendCursorBuffer()
{
// Temporary work-around for the RoF+ Client 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.
if (GetClientVersion() >= ClientVersion::RoF)
{
if (!GetInv().CursorEmpty())
{
const ItemInst* inst = GetInv().GetCursorItem();
if (inst)
{
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
if (GetClientVersion() < ClientVersion::RoF) { return; }
if (GetInv().CursorEmpty()) { return; }
auto test_inst = GetInv().GetCursorItem();
if (test_inst == nullptr) { return; }
auto test_item = test_inst->GetItem();
if (test_item == nullptr) { return; }
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;
}
// 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(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;
}