Inventory possessions beta testing

This commit is contained in:
Uleat
2018-08-13 22:32:36 -04:00
parent 54abeba1ce
commit 509a2b30a5
45 changed files with 2842 additions and 1443 deletions
+273 -122
View File
@@ -44,23 +44,9 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
DeleteItemInInventory(i, 0, true);
DeleteItemInInventory(i, 0, ((((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask) != 0));
}
}
if (GetItemIDAt(EQEmu::invslot::SLOT_POWER_SOURCE) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(EQEmu::invslot::SLOT_POWER_SOURCE) != INVALID_ID)) {
cur = m_inv.GetItem(EQEmu::invslot::SLOT_POWER_SOURCE);
if(cur && cur->GetItem()->Stackable) {
x += cur->GetCharges();
} else {
x++;
}
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, true);
else
DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, false); // Prevents Titanium crash
}
}
if(where_to_check & invWhereCursor) {
@@ -99,7 +85,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
DeleteItemInInventory(i, 0, true);
DeleteItemInInventory(i, 0, ((((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask) != 0));
}
}
@@ -112,7 +98,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
DeleteItemInInventory(i, 0, true);
DeleteItemInInventory(i, 0, ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((i - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0));
}
}
}
@@ -127,7 +113,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
DeleteItemInInventory(i, 0, true);
DeleteItemInInventory(i, 0, ((i - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]));
}
}
@@ -140,7 +126,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
x++;
}
DeleteItemInInventory(i, 0, true);
DeleteItemInInventory(i, 0, (((i - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]));
}
}
}
@@ -554,8 +540,8 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
inst->SetOrnamentHeroModel(ornament_hero_model);
// check to see if item is usable in requested slot
if (enforceusable && (((to_slot >= EQEmu::invslot::slotCharm) && (to_slot <= EQEmu::invslot::slotAmmo)) || (to_slot == EQEmu::invslot::SLOT_POWER_SOURCE))) {
uint32 slottest = (to_slot == EQEmu::invslot::SLOT_POWER_SOURCE) ? 22 : to_slot; // can't change '22' just yet...
if (enforceusable && (to_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && to_slot <= EQEmu::invslot::EQUIPMENT_END)) {
uint32 slottest = to_slot;
if(!(slots & ((uint32)1 << slottest))) {
Message(0, "This item is not equipable at slot %u - moving to cursor.", to_slot);
@@ -716,6 +702,25 @@ void Client::DropInst(const EQEmu::ItemInstance* inst)
// Returns a slot's item ID (returns INVALID_ID if not found)
int32 Client::GetItemIDAt(int16 slot_id) {
if (slot_id <= EQEmu::invslot::POSSESSIONS_END && slot_id >= EQEmu::invslot::POSSESSIONS_BEGIN) {
if ((((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask) == 0)
return INVALID_ID;
}
else if (slot_id <= EQEmu::invbag::GENERAL_BAGS_END && slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
return INVALID_ID;
}
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
return INVALID_ID;
}
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
return INVALID_ID;
}
const EQEmu::ItemInstance* inst = m_inv[slot_id];
if (inst)
return inst->GetItem()->ID;
@@ -727,6 +732,25 @@ 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-5)
int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
if (slot_id <= EQEmu::invslot::POSSESSIONS_END && slot_id >= EQEmu::invslot::POSSESSIONS_BEGIN) {
if ((((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask) == 0)
return INVALID_ID;
}
else if (slot_id <= EQEmu::invbag::GENERAL_BAGS_END && slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
return INVALID_ID;
}
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
return INVALID_ID;
}
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
return INVALID_ID;
}
const EQEmu::ItemInstance* inst = m_inv[slot_id];
if (inst && inst->GetAugmentItemID(augslot)) {
return inst->GetAugmentItemID(augslot);
@@ -963,7 +987,7 @@ void Client::PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst,
}
if (bag_item_data) {
for (int index = 0; index < EQEmu::invbag::SLOT_COUNT; ++index) {
for (int index = EQEmu::invbag::SLOT_BEGIN; index <= EQEmu::invbag::SLOT_END; ++index) {
if (bag_item_data[index] == nullptr)
continue;
@@ -1003,12 +1027,15 @@ void Client::PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst,
CalcBonuses();
}
bool Client::TryStacking(EQEmu::ItemInstance* item, uint8 type, bool try_worn, bool try_cursor){
bool Client::TryStacking(EQEmu::ItemInstance* item, uint8 type, bool try_worn, bool try_cursor) {
if(!item || !item->IsStackable() || item->GetCharges()>=item->GetItem()->StackSize)
return false;
int16 i;
uint32 item_id = item->GetItem()->ID;
for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) {
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
EQEmu::ItemInstance* 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);
@@ -1020,6 +1047,9 @@ bool Client::TryStacking(EQEmu::ItemInstance* item, uint8 type, bool try_worn, b
}
}
for (i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) {
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
for (uint8 j = EQEmu::invbag::SLOT_BEGIN; j <= EQEmu::invbag::SLOT_END; j++) {
uint16 slotid = EQEmu::InventoryProfile::CalcSlotId(i, j);
EQEmu::ItemInstance* tmp_inst = m_inv.GetItem(slotid);
@@ -1044,15 +1074,9 @@ bool Client::AutoPutLootInInventory(EQEmu::ItemInstance& inst, bool try_worn, bo
{
// #1: Try to auto equip
if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel <= level && (!inst.GetItem()->Attuneable || inst.IsAttuned()) && inst.GetItem()->ItemType != EQEmu::item::ItemTypeAugmentation) {
// too messy as-is... <watch>
for (int16 i = EQEmu::invslot::EQUIPMENT_BEGIN; i < EQEmu::invslot::SLOT_POWER_SOURCE; i++) { // originally (i < 22)
if (i == EQEmu::invslot::GENERAL_BEGIN) {
// added power source check for SoF+ clients
if (this->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
i = EQEmu::invslot::SLOT_POWER_SOURCE;
else
break;
}
for (int16 i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invslot::EQUIPMENT_END; i++) {
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
if (!m_inv[i]) {
if (i == EQEmu::invslot::slotPrimary && inst.IsWeapon()) { // If item is primary slot weapon
@@ -1373,23 +1397,34 @@ void Client::SendLootItemInPacket(const EQEmu::ItemInstance* inst, int16 slot_id
}
bool Client::IsValidSlot(uint32 slot) {
if ((slot == (uint32)INVALID_INDEX) ||
(slot >= EQEmu::invslot::POSSESSIONS_BEGIN && slot <= EQEmu::invslot::POSSESSIONS_END) ||
(slot >= EQEmu::invbag::GENERAL_BAGS_BEGIN && slot <= EQEmu::invbag::CURSOR_BAG_END) ||
(slot >= EQEmu::invslot::TRIBUTE_BEGIN && slot <= EQEmu::invslot::TRIBUTE_END) ||
(slot >= EQEmu::invslot::BANK_BEGIN && slot <= EQEmu::invslot::BANK_END) ||
(slot >= EQEmu::invbag::BANK_BAGS_BEGIN && slot <= EQEmu::invbag::BANK_BAGS_END) ||
(slot >= EQEmu::invslot::SHARED_BANK_BEGIN && slot <= EQEmu::invslot::SHARED_BANK_END) ||
(slot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN && slot <= EQEmu::invbag::SHARED_BANK_BAGS_END) ||
(slot >= EQEmu::invslot::TRADE_BEGIN && slot <= EQEmu::invslot::TRADE_END) ||
(slot >= EQEmu::invslot::WORLD_BEGIN && slot <= EQEmu::invslot::WORLD_END) ||
(slot == EQEmu::invslot::SLOT_POWER_SOURCE)
) {
if (slot <= EQEmu::invslot::POSSESSIONS_END && slot >= EQEmu::invslot::POSSESSIONS_BEGIN) {
return ((((uint64)1 << slot) & GetInv().GetLookup()->PossessionsBitmask) != 0);
}
else if (slot <= EQEmu::invbag::GENERAL_BAGS_END && slot >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
return ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) != 0);
}
else if (slot <= EQEmu::invslot::BANK_END && slot >= EQEmu::invslot::BANK_BEGIN) {
return ((slot - EQEmu::invslot::BANK_BEGIN) < GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]);
}
else if (slot <= EQEmu::invbag::BANK_BAGS_END && slot >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
return (temp_slot < GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank]);
}
else if (
(slot == (uint32)INVALID_INDEX) ||
(slot == (uint32)EQEmu::invslot::slotCursor) ||
(slot <= EQEmu::invbag::CURSOR_BAG_END && slot >= EQEmu::invbag::CURSOR_BAG_BEGIN) ||
(slot <= EQEmu::invslot::TRIBUTE_END && slot >= EQEmu::invslot::TRIBUTE_BEGIN) ||
(slot <= EQEmu::invslot::SHARED_BANK_END && slot >= EQEmu::invslot::SHARED_BANK_BEGIN) ||
(slot <= EQEmu::invbag::SHARED_BANK_BAGS_END && slot >= EQEmu::invbag::SHARED_BANK_BAGS_BEGIN) ||
(slot <= EQEmu::invslot::TRADE_END && slot >= EQEmu::invslot::TRADE_BEGIN) ||
(slot <= EQEmu::invslot::WORLD_END && slot >= EQEmu::invslot::WORLD_BEGIN)
) {
return true;
}
else {
return false;
}
return false;
}
bool Client::IsBankSlot(uint32 slot)
@@ -1481,10 +1516,14 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
return true; // Item deletion
}
}
if (auto_attack && (move_in->from_slot == EQEmu::invslot::slotPrimary || move_in->from_slot == EQEmu::invslot::slotSecondary || move_in->from_slot == EQEmu::invslot::slotRange))
SetAttackTimer();
else if (auto_attack && (move_in->to_slot == EQEmu::invslot::slotPrimary || move_in->to_slot == EQEmu::invslot::slotSecondary || move_in->to_slot == EQEmu::invslot::slotRange))
SetAttackTimer();
if (auto_attack) {
if (move_in->from_slot == EQEmu::invslot::slotPrimary || move_in->from_slot == EQEmu::invslot::slotSecondary || move_in->from_slot == EQEmu::invslot::slotRange)
SetAttackTimer();
else if (move_in->to_slot == EQEmu::invslot::slotPrimary || move_in->to_slot == EQEmu::invslot::slotSecondary || move_in->to_slot == EQEmu::invslot::slotRange)
SetAttackTimer();
}
// Step 1: Variables
int16 src_slot_id = (int16)move_in->from_slot;
int16 dst_slot_id = (int16)move_in->to_slot;
@@ -1530,13 +1569,11 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
uint32 srcbagid =0;
uint32 dstbagid = 0;
//if (src_slot_id >= 250 && src_slot_id < 330) {
if (src_slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN && src_slot_id <= EQEmu::invbag::GENERAL_BAGS_END) {
srcbag = m_inv.GetItem(((int)(src_slot_id / 10)) - 3);
if (srcbag)
srcbagid = srcbag->GetItem()->ID;
}
//if (dst_slot_id >= 250 && dst_slot_id < 330) {
if (dst_slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN && dst_slot_id <= EQEmu::invbag::GENERAL_BAGS_END) {
dstbag = m_inv.GetItem(((int)(dst_slot_id / 10)) - 3);
if (dstbag)
@@ -1808,7 +1845,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
else {
// Not dealing with charges - just do direct swap
if (src_inst && (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END || dst_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) && dst_slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) {
if (src_inst && (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END) && dst_slot_id >= EQEmu::invslot::EQUIPMENT_BEGIN) {
if (src_inst->GetItem()->Attuneable) {
src_inst->SetAttuned(true);
}
@@ -1840,7 +1877,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
Log(Logs::Detail, Logs::Inventory, "Moving entire item from slot %d to slot %d", src_slot_id, dst_slot_id);
if (src_slot_id <= EQEmu::invslot::EQUIPMENT_END || src_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) {
if (src_slot_id <= EQEmu::invslot::EQUIPMENT_END) {
if(src_inst) {
parse->EventItem(EVENT_UNEQUIP_ITEM, this, src_inst, nullptr, "", src_slot_id);
}
@@ -1850,7 +1887,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
}
if (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END || dst_slot_id == EQEmu::invslot::SLOT_POWER_SOURCE) {
if (dst_slot_id <= EQEmu::invslot::EQUIPMENT_END) {
if(dst_inst) {
parse->EventItem(EVENT_UNEQUIP_ITEM, this, dst_inst, nullptr, "", dst_slot_id);
}
@@ -1904,7 +1941,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
Log(Logs::Detail, Logs::Inventory, "Inventory desyncronization. (charname: %s, source: %i, destination: %i)", GetName(), move_slots->from_slot, move_slots->to_slot);
Message(15, "Inventory Desyncronization detected: Resending slot data...");
if ((move_slots->from_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->from_slot <= EQEmu::invbag::CURSOR_BAG_END) || move_slots->from_slot == EQEmu::invslot::SLOT_POWER_SOURCE) {
if (move_slots->from_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->from_slot <= EQEmu::invbag::CURSOR_BAG_END) {
int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot);
if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) {
// This prevents the client from crashing when closing any 'phantom' bags
@@ -1947,7 +1984,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); }
}
if ((move_slots->to_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->to_slot <= EQEmu::invbag::CURSOR_BAG_END) || move_slots->to_slot == EQEmu::invslot::SLOT_POWER_SOURCE) {
if (move_slots->to_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->to_slot <= EQEmu::invbag::CURSOR_BAG_END) {
int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->to_slot);
if (IsValidSlot(resync_slot) && resync_slot != INVALID_INDEX) {
const EQEmu::ItemData* token_struct = database.GetItem(22292); // 'Copper Coin'
@@ -2182,47 +2219,118 @@ bool Client::DecreaseByID(uint32 type, uint8 amt) {
EQEmu::ItemInstance* ins = nullptr;
int x;
int num = 0;
for(x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; x++)
{
if (x == EQEmu::invslot::slotCursor + 1)
x = EQEmu::invbag::GENERAL_BAGS_BEGIN;
for (x = EQEmu::invslot::POSSESSIONS_BEGIN; x <= EQEmu::invslot::POSSESSIONS_END; ++x) {
if (num >= amt)
break;
if (((uint64)1 << x) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
TempItem = nullptr;
ins = GetInv().GetItem(x);
if (ins)
TempItem = ins->GetItem();
if (TempItem && TempItem->ID == type)
{
num += ins->GetCharges();
if (num >= amt)
break;
}
}
for (x = EQEmu::invbag::GENERAL_BAGS_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; ++x) {
if (num >= amt)
break;
if ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((x - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0)
continue;
TempItem = nullptr;
ins = GetInv().GetItem(x);
if (ins)
TempItem = ins->GetItem();
if (TempItem && TempItem->ID == type)
num += ins->GetCharges();
}
for (x = EQEmu::invbag::CURSOR_BAG_BEGIN; x <= EQEmu::invbag::CURSOR_BAG_END; ++x) {
if (num >= amt)
break;
TempItem = nullptr;
ins = GetInv().GetItem(x);
if (ins)
TempItem = ins->GetItem();
if (TempItem && TempItem->ID == type)
num += ins->GetCharges();
}
if (num < amt)
return false;
for(x = EQEmu::invslot::EQUIPMENT_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; x++) // should this be CURSOR_BAG_END?
{
if (x == EQEmu::invslot::slotCursor + 1)
x = EQEmu::invbag::GENERAL_BAGS_BEGIN;
for (x = EQEmu::invslot::POSSESSIONS_BEGIN; x <= EQEmu::invslot::POSSESSIONS_END; ++x) {
if (amt < 1)
break;
if (((uint64)1 << x) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
TempItem = nullptr;
ins = GetInv().GetItem(x);
if (ins)
TempItem = ins->GetItem();
if (TempItem && TempItem->ID == type)
{
if (ins->GetCharges() < amt)
{
amt -= ins->GetCharges();
DeleteItemInInventory(x,amt,true);
}
else
{
DeleteItemInInventory(x,amt,true);
amt = 0;
}
if (amt < 1)
break;
if (TempItem && TempItem->ID != type)
continue;
if (ins->GetCharges() < amt) {
amt -= ins->GetCharges();
DeleteItemInInventory(x, amt, true);
}
else {
DeleteItemInInventory(x, amt, true);
amt = 0;
}
}
for (x = EQEmu::invbag::GENERAL_BAGS_BEGIN; x <= EQEmu::invbag::GENERAL_BAGS_END; ++x) {
if (amt < 1)
break;
if ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((x - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0)
continue;
TempItem = nullptr;
ins = GetInv().GetItem(x);
if (ins)
TempItem = ins->GetItem();
if (TempItem && TempItem->ID != type)
continue;
if (ins->GetCharges() < amt) {
amt -= ins->GetCharges();
DeleteItemInInventory(x, amt, true);
}
else {
DeleteItemInInventory(x, amt, true);
amt = 0;
}
}
for (x = EQEmu::invbag::CURSOR_BAG_BEGIN; x <= EQEmu::invbag::CURSOR_BAG_END; ++x) {
if (amt < 1)
break;
TempItem = nullptr;
ins = GetInv().GetItem(x);
if (ins)
TempItem = ins->GetItem();
if (TempItem && TempItem->ID != type)
continue;
if (ins->GetCharges() < amt) {
amt -= ins->GetCharges();
DeleteItemInInventory(x, amt, true);
}
else {
DeleteItemInInventory(x, amt, true);
amt = 0;
}
}
return true;
}
@@ -2299,6 +2407,9 @@ static bool CopyBagContents(EQEmu::ItemInstance* new_bag, const EQEmu::ItemInsta
void Client::DisenchantSummonedBags(bool client_update)
{
for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) {
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue; // not useable this session - will be disenchanted once player logs in on client that doesn't exclude affected slots
auto inst = m_inv[slot_id];
if (!inst) { continue; }
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
@@ -2320,6 +2431,9 @@ void Client::DisenchantSummonedBags(bool client_update)
}
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
continue;
auto inst = m_inv[slot_id];
if (!inst) { continue; }
if (!IsSummonedBagID(inst->GetItem()->ID)) { continue; }
@@ -2410,6 +2524,9 @@ void Client::DisenchantSummonedBags(bool client_update)
void Client::RemoveNoRent(bool client_update)
{
for (auto slot_id = EQEmu::invslot::EQUIPMENT_BEGIN; slot_id <= EQEmu::invslot::EQUIPMENT_END; ++slot_id) {
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
auto inst = m_inv[slot_id];
if(inst && !inst->GetItem()->NoRent) {
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
@@ -2418,6 +2535,9 @@ void Client::RemoveNoRent(bool client_update)
}
for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) {
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
auto inst = m_inv[slot_id];
if (inst && !inst->GetItem()->NoRent) {
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
@@ -2425,15 +2545,11 @@ void Client::RemoveNoRent(bool client_update)
}
}
if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]) {
auto inst = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE];
if (inst && !inst->GetItem()->NoRent) {
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE);
DeleteItemInInventory(EQEmu::invslot::SLOT_POWER_SOURCE, 0, (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) ? client_update : false); // Ti slot non-existent
}
}
for (auto slot_id = EQEmu::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::invbag::CURSOR_BAG_END; ++slot_id) {
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
continue;
auto inst = m_inv[slot_id];
if(inst && !inst->GetItem()->NoRent) {
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
@@ -2442,6 +2558,9 @@ void Client::RemoveNoRent(bool client_update)
}
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
continue;
auto inst = m_inv[slot_id];
if(inst && !inst->GetItem()->NoRent) {
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
@@ -2450,6 +2569,10 @@ void Client::RemoveNoRent(bool client_update)
}
for (auto slot_id = EQEmu::invbag::BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::BANK_BAGS_END; ++slot_id) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
continue;
auto inst = m_inv[slot_id];
if(inst && !inst->GetItem()->NoRent) {
Log(Logs::Detail, Logs::Inventory, "NoRent Timer Lapse: Deleting %s from slot %i", inst->GetItem()->Name, slot_id);
@@ -2504,6 +2627,9 @@ void Client::RemoveNoRent(bool client_update)
void Client::RemoveDuplicateLore(bool client_update)
{
for (auto slot_id = EQEmu::invslot::EQUIPMENT_BEGIN; slot_id <= EQEmu::invslot::EQUIPMENT_END; ++slot_id) {
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
auto inst = m_inv.PopItem(slot_id);
if (inst == nullptr) { continue; }
if(CheckLoreConflict(inst->GetItem())) {
@@ -2517,6 +2643,9 @@ void Client::RemoveDuplicateLore(bool client_update)
}
for (auto slot_id = EQEmu::invslot::GENERAL_BEGIN; slot_id <= EQEmu::invslot::GENERAL_END; ++slot_id) {
if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
auto inst = m_inv.PopItem(slot_id);
if (inst == nullptr) { continue; }
if (CheckLoreConflict(inst->GetItem())) {
@@ -2529,21 +2658,11 @@ void Client::RemoveDuplicateLore(bool client_update)
safe_delete(inst);
}
if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]) {
auto inst = m_inv.PopItem(EQEmu::invslot::SLOT_POWER_SOURCE);
if (inst) {
if (CheckLoreConflict(inst->GetItem())) {
Log(Logs::Detail, Logs::Inventory, "Lore Duplication Error: Deleting %s from slot %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE);
database.SaveInventory(character_id, nullptr, EQEmu::invslot::SLOT_POWER_SOURCE);
}
else {
m_inv.PutItem(EQEmu::invslot::SLOT_POWER_SOURCE, *inst);
}
safe_delete(inst);
}
}
for (auto slot_id = EQEmu::invbag::GENERAL_BAGS_BEGIN; slot_id <= EQEmu::invbag::CURSOR_BAG_END; ++slot_id) {
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
continue;
auto inst = m_inv.PopItem(slot_id);
if (inst == nullptr) { continue; }
if(CheckLoreConflict(inst->GetItem())) {
@@ -2557,6 +2676,9 @@ void Client::RemoveDuplicateLore(bool client_update)
}
for (auto slot_id = EQEmu::invslot::BANK_BEGIN; slot_id <= EQEmu::invslot::BANK_END; ++slot_id) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
continue;
auto inst = m_inv.PopItem(slot_id);
if (inst == nullptr) { continue; }
if(CheckLoreConflict(inst->GetItem())) {
@@ -2570,6 +2692,10 @@ void Client::RemoveDuplicateLore(bool client_update)
}
for (auto slot_id = EQEmu::invbag::BANK_BAGS_BEGIN; slot_id <= EQEmu::invbag::BANK_BAGS_END; ++slot_id) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
continue;
auto inst = m_inv.PopItem(slot_id);
if (inst == nullptr) { continue; }
if(CheckLoreConflict(inst->GetItem())) {
@@ -2642,15 +2768,21 @@ void Client::MoveSlotNotAllowed(bool client_update)
}
}
if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE] && !m_inv[EQEmu::invslot::SLOT_POWER_SOURCE]->IsSlotAllowed(EQEmu::invslot::SLOT_POWER_SOURCE)) {
auto inst = m_inv.PopItem(EQEmu::invslot::SLOT_POWER_SOURCE);
bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false;
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow);
Log(Logs::Detail, Logs::Inventory, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, EQEmu::invslot::SLOT_POWER_SOURCE, free_slot_id);
PutItemInInventory(free_slot_id, *inst, (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) ? client_update : false);
database.SaveInventory(character_id, nullptr, EQEmu::invslot::SLOT_POWER_SOURCE);
safe_delete(inst);
}
// added this check to move any client-based excluded slots
//for (auto slot_id = EQEmu::invslot::POSSESSIONS_BEGIN; slot_id <= EQEmu::invslot::POSSESSIONS_END; ++slot_id) {
// if (((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask != 0)
// continue;
// if (m_inv[slot_id]) { // this is currently dangerous for bag-based movements since limbo does not save bag slots
// auto inst = m_inv.PopItem(slot_id);
// bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false;
// int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow);
// Log(Logs::Detail, Logs::Inventory, "Slot Assignment Error: Moving %s from slot %i to %i", inst->GetItem()->Name, slot_id, free_slot_id);
// PutItemInInventory(free_slot_id, *inst, client_update);
// database.SaveInventory(character_id, nullptr, slot_id);
// safe_delete(inst);
// }
//}
// No need to check inventory, cursor, bank or shared bank since they allow max item size and containers
// Code can be added to check item size vs. container size, but it is left to attrition for now.
@@ -2716,7 +2848,26 @@ void Client::SendItemPacket(int16 slot_id, const EQEmu::ItemInstance* inst, Item
if (!inst)
return;
// Serialize item into |-delimited string
if (slot_id <= EQEmu::invslot::POSSESSIONS_END && slot_id >= EQEmu::invslot::POSSESSIONS_BEGIN) {
if ((((uint64)1 << slot_id) & GetInv().GetLookup()->PossessionsBitmask) == 0)
return;
}
else if (slot_id <= EQEmu::invbag::GENERAL_BAGS_END && slot_id >= EQEmu::invbag::GENERAL_BAGS_BEGIN) {
auto temp_slot = EQEmu::invslot::GENERAL_BEGIN + ((slot_id - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT);
if ((((uint64)1 << temp_slot) & GetInv().GetLookup()->PossessionsBitmask) == 0)
return;
}
else if (slot_id <= EQEmu::invslot::BANK_END && slot_id >= EQEmu::invslot::BANK_BEGIN) {
if ((slot_id - EQEmu::invslot::BANK_BEGIN) >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
return;
}
else if (slot_id <= EQEmu::invbag::BANK_BAGS_END && slot_id >= EQEmu::invbag::BANK_BAGS_BEGIN) {
auto temp_slot = (slot_id - EQEmu::invbag::BANK_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT;
if (temp_slot >= GetInv().GetLookup()->InventoryTypeSize[EQEmu::invtype::typeBank])
return;
}
// Serialize item into |-delimited string (Titanium- uses '|' delimiter .. newer clients use pure data serialization)
std::string packet = inst->Serialize(slot_id);
EmuOpcode opcode = OP_Unknown;
@@ -3000,6 +3151,8 @@ bool Client::MoveItemToInventory(EQEmu::ItemInstance *ItemToReturn, bool UpdateC
if(ItemToReturn->IsStackable()) {
for (int16 i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++) { // changed slot max to 30 from 29. client will stack into slot 30 (bags too) before moving.
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
EQEmu::ItemInstance* InvItem = m_inv.GetItem(i);
@@ -3059,6 +3212,8 @@ bool Client::MoveItemToInventory(EQEmu::ItemInstance *ItemToReturn, bool UpdateC
// We have tried stacking items, now just try and find an empty slot.
for (int16 i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::slotCursor; i++) { // changed slot max to 30 from 29. client will move into slot 30 (bags too) before pushing onto cursor.
if (((uint64)1 << i) & GetInv().GetLookup()->PossessionsBitmask == 0)
continue;
EQEmu::ItemInstance* InvItem = m_inv.GetItem(i);
@@ -3119,7 +3274,7 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool
std::map<int16, const EQEmu::ItemInstance*> instmap;
// build reference map
for (int16 index = EQEmu::invslot::EQUIPMENT_BEGIN; index <= EQEmu::invslot::POSSESSIONS_END; ++index) {
for (int16 index = EQEmu::invslot::POSSESSIONS_BEGIN; index <= EQEmu::invslot::POSSESSIONS_END; ++index) {
auto inst = m_inv[index];
if (inst == nullptr) { continue; }
instmap[index] = inst;
@@ -3163,9 +3318,6 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool
instmap[8000 + limbo] = *cursor_itr;
}
if (m_inv[EQEmu::invslot::SLOT_POWER_SOURCE])
instmap[EQEmu::invslot::SLOT_POWER_SOURCE] = m_inv[EQEmu::invslot::SLOT_POWER_SOURCE];
// call InterrogateInventory_ for error check
for (auto 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);
@@ -3270,8 +3422,7 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQEmu::It
(head >= EQEmu::invslot::EQUIPMENT_BEGIN && head <= EQEmu::invslot::EQUIPMENT_END) ||
(head >= EQEmu::invslot::TRIBUTE_BEGIN && head <= EQEmu::invslot::TRIBUTE_END) ||
(head >= EQEmu::invslot::WORLD_BEGIN && head <= EQEmu::invslot::WORLD_END) ||
(head >= 8000 && head <= 8101) ||
(head == EQEmu::invslot::SLOT_POWER_SOURCE)) {
(head >= 8000 && head <= 8101)) {
switch (depth)
{
case 0: // requirement: inst is extant