mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-18 03:28:24 +00:00
OP_MoveItem encode/decode for RoF2, disabled other patches for now (until i get rof2 packets and mechanics working well enough to go back and fix those)
This commit is contained in:
+3
-3
@@ -813,9 +813,9 @@ public:
|
||||
bool PushItemOnCursor(const ItemInst& inst, bool client_update = false);
|
||||
void SendCursorBuffer();
|
||||
void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true);
|
||||
bool SwapItem(MoveItem_Struct* move_in);
|
||||
void SwapItemResync(MoveItem_Struct* move_slots);
|
||||
void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false);
|
||||
bool SwapItem(MoveItemOld_Struct* move_in);
|
||||
void SwapItemResync(MoveItemOld_Struct* move_slots);
|
||||
void QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call = false);
|
||||
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
|
||||
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
|
||||
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = MainCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
|
||||
|
||||
+64
-55
@@ -9586,68 +9586,77 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (app->size != sizeof(MoveItem_Struct)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Wrong size: OP_MoveItem, size=%i, expected %i", app->size, sizeof(MoveItem_Struct));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MoveItem_Struct* mi = (MoveItem_Struct*)app->pBuffer;
|
||||
if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id))
|
||||
{
|
||||
if (mi->from_slot != mi->to_slot && (mi->from_slot <= EmuConstants::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot))
|
||||
{
|
||||
char *detect = nullptr;
|
||||
const ItemInst *itm_from = GetInv().GetItem(mi->from_slot);
|
||||
const ItemInst *itm_to = GetInv().GetItem(mi->to_slot);
|
||||
MakeAnyLenString(&detect, "Player issued a move item from %u(item id %u) to %u(item id %u) while casting %u.",
|
||||
mi->from_slot,
|
||||
itm_from ? itm_from->GetID() : 0,
|
||||
mi->to_slot,
|
||||
itm_to ? itm_to->GetID() : 0,
|
||||
casting_spell_id);
|
||||
database.SetMQDetectionFlag(AccountName(), GetName(), detect, zone->GetShortName());
|
||||
safe_delete_array(detect);
|
||||
Kick(); // Kick client to prevent client and server from getting out-of-sync inventory slots
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto res = m_inventory.Swap(EQEmu::InventorySlot(mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot),
|
||||
EQEmu::InventorySlot(mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot),
|
||||
mi->number_in_stack);
|
||||
|
||||
// Illegal bagslot usage checks. Currently, user only receives a message if this check is triggered.
|
||||
bool mi_hack = false;
|
||||
//printf("%i %i %i %i --> %i %i %i %i (%u)\n",
|
||||
// mi->from_type, mi->from_slot, mi->from_bag_slot, mi->from_aug_slot,
|
||||
// mi->to_type, mi->to_slot, mi->to_bag_slot, mi->to_aug_slot,
|
||||
// mi->number_in_stack);
|
||||
|
||||
if (mi->from_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->from_slot <= EmuConstants::CURSOR_BAG_END) {
|
||||
if (mi->from_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; }
|
||||
else {
|
||||
int16 from_parent = m_inv.CalcSlotId(mi->from_slot);
|
||||
if (!m_inv[from_parent]) { mi_hack = true; }
|
||||
else if (!m_inv[from_parent]->IsType(ItemClassContainer)) { mi_hack = true; }
|
||||
else if (m_inv.CalcBagIdx(mi->from_slot) >= m_inv[from_parent]->GetItem()->BagSlots) { mi_hack = true; }
|
||||
}
|
||||
}
|
||||
|
||||
if (mi->to_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->to_slot <= EmuConstants::CURSOR_BAG_END) {
|
||||
if (mi->to_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; }
|
||||
else {
|
||||
int16 to_parent = m_inv.CalcSlotId(mi->to_slot);
|
||||
if (!m_inv[to_parent]) { mi_hack = true; }
|
||||
else if (!m_inv[to_parent]->IsType(ItemClassContainer)) { mi_hack = true; }
|
||||
else if (m_inv.CalcBagIdx(mi->to_slot) >= m_inv[to_parent]->GetItem()->BagSlots) { mi_hack = true; }
|
||||
}
|
||||
}
|
||||
|
||||
if (mi_hack) { Message(15, "Caution: Illegal use of inaccessible bag slots!"); }
|
||||
|
||||
if (!SwapItem(mi) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) {
|
||||
SwapItemResync(mi);
|
||||
|
||||
bool error = false;
|
||||
InterrogateInventory(this, false, true, false, error, false);
|
||||
if (error)
|
||||
InterrogateInventory(this, true, false, true, error);
|
||||
}
|
||||
|
||||
return;
|
||||
//if (spellend_timer.Enabled() && casting_spell_id && !IsBardSong(casting_spell_id))
|
||||
//{
|
||||
// if (mi->from_slot != mi->to_slot && (mi->from_slot <= EmuConstants::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot))
|
||||
// {
|
||||
// char *detect = nullptr;
|
||||
// const ItemInst *itm_from = GetInv().GetItem(mi->from_slot);
|
||||
// const ItemInst *itm_to = GetInv().GetItem(mi->to_slot);
|
||||
// MakeAnyLenString(&detect, "Player issued a move item from %u(item id %u) to %u(item id %u) while casting %u.",
|
||||
// mi->from_slot,
|
||||
// itm_from ? itm_from->GetID() : 0,
|
||||
// mi->to_slot,
|
||||
// itm_to ? itm_to->GetID() : 0,
|
||||
// casting_spell_id);
|
||||
// database.SetMQDetectionFlag(AccountName(), GetName(), detect, zone->GetShortName());
|
||||
// safe_delete_array(detect);
|
||||
// Kick(); // Kick client to prevent client and server from getting out-of-sync inventory slots
|
||||
// return;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// Illegal bagslot usage checks. Currently, user only receives a message if this check is triggered.
|
||||
//bool mi_hack = false;
|
||||
//
|
||||
//if (mi->from_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->from_slot <= EmuConstants::CURSOR_BAG_END) {
|
||||
// if (mi->from_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; }
|
||||
// else {
|
||||
// int16 from_parent = m_inv.CalcSlotId(mi->from_slot);
|
||||
// if (!m_inv[from_parent]) { mi_hack = true; }
|
||||
// else if (!m_inv[from_parent]->IsType(ItemClassContainer)) { mi_hack = true; }
|
||||
// else if (m_inv.CalcBagIdx(mi->from_slot) >= m_inv[from_parent]->GetItem()->BagSlots) { mi_hack = true; }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//if (mi->to_slot >= EmuConstants::GENERAL_BAGS_BEGIN && mi->to_slot <= EmuConstants::CURSOR_BAG_END) {
|
||||
// if (mi->to_slot >= EmuConstants::CURSOR_BAG_BEGIN) { mi_hack = true; }
|
||||
// else {
|
||||
// int16 to_parent = m_inv.CalcSlotId(mi->to_slot);
|
||||
// if (!m_inv[to_parent]) { mi_hack = true; }
|
||||
// else if (!m_inv[to_parent]->IsType(ItemClassContainer)) { mi_hack = true; }
|
||||
// else if (m_inv.CalcBagIdx(mi->to_slot) >= m_inv[to_parent]->GetItem()->BagSlots) { mi_hack = true; }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//if (mi_hack) { Message(15, "Caution: Illegal use of inaccessible bag slots!"); }
|
||||
//
|
||||
//if (!SwapItem(mi) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) {
|
||||
// SwapItemResync(mi);
|
||||
//
|
||||
// bool error = false;
|
||||
// InterrogateInventory(this, false, true, false, error, false);
|
||||
// if (error)
|
||||
// InterrogateInventory(this, true, false, true, error);
|
||||
//}
|
||||
//
|
||||
//return;
|
||||
}
|
||||
|
||||
void Client::Handle_OP_OpenContainer(const EQApplicationPacket *app)
|
||||
|
||||
+71
-71
@@ -3119,77 +3119,77 @@ void command_listpetition(Client *c, const Seperator *sep)
|
||||
|
||||
void command_equipitem(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint32 slot_id = atoi(sep->arg[1]);
|
||||
if (sep->IsNumber(1) && ((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) || (slot_id == MainPowerSource))) {
|
||||
const ItemInst* from_inst = c->GetInv().GetItem(MainCursor);
|
||||
const ItemInst* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
|
||||
bool partialmove = false;
|
||||
int16 movecount;
|
||||
|
||||
if (from_inst && from_inst->IsType(ItemClassCommon)) {
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
||||
MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer;
|
||||
mi->from_slot = MainCursor;
|
||||
mi->to_slot = slot_id;
|
||||
// mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking
|
||||
|
||||
// crude stackable check to only 'move' the difference count on client instead of entire stack when applicable
|
||||
if (to_inst && to_inst->IsStackable() &&
|
||||
(to_inst->GetItem()->ID == from_inst->GetItem()->ID) &&
|
||||
(to_inst->GetCharges() < to_inst->GetItem()->StackSize) &&
|
||||
(from_inst->GetCharges() > to_inst->GetItem()->StackSize - to_inst->GetCharges())) {
|
||||
movecount = to_inst->GetItem()->StackSize - to_inst->GetCharges();
|
||||
mi->number_in_stack = (uint32)movecount;
|
||||
partialmove = true;
|
||||
}
|
||||
else
|
||||
mi->number_in_stack = from_inst->GetCharges();
|
||||
|
||||
// Save move changes
|
||||
// Added conditional check to packet send..would have sent change even on a swap failure..whoops!
|
||||
|
||||
if (partialmove) { // remove this con check if someone can figure out removing charges from cursor stack issue below
|
||||
// mi->number_in_stack is always from_inst->GetCharges() when partialmove is false
|
||||
c->Message(13, "Error: Partial stack added to existing stack exceeds allowable stacksize");
|
||||
return;
|
||||
}
|
||||
else if(c->SwapItem(mi)) {
|
||||
c->FastQueuePacket(&outapp);
|
||||
|
||||
// if the below code is still needed..just send an an item trade packet to each slot..it should overwrite the client instance
|
||||
|
||||
// below code has proper logic, but client does not like to have cursor charges changed
|
||||
// (we could delete the cursor item and resend, but issues would arise if there are queued items)
|
||||
//if (partialmove) {
|
||||
// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
||||
// DeleteItem_Struct* di = (DeleteItem_Struct*)outapp2->pBuffer;
|
||||
// di->from_slot = SLOT_CURSOR;
|
||||
// di->to_slot = 0xFFFFFFFF;
|
||||
// di->number_in_stack = 0xFFFFFFFF;
|
||||
|
||||
// c->Message(0, "Deleting %i charges from stack", movecount); // debug line..delete
|
||||
|
||||
// for (int16 deletecount=0; deletecount < movecount; deletecount++)
|
||||
// have to use 'movecount' because mi->number_in_stack is 'ENCODED' at this point (i.e., 99 charges returns 22...)
|
||||
// c->QueuePacket(outapp2);
|
||||
|
||||
// safe_delete(outapp2);
|
||||
//}
|
||||
}
|
||||
else {
|
||||
c->Message(13, "Error: Unable to equip current item");
|
||||
}
|
||||
safe_delete(outapp);
|
||||
|
||||
// also send out a wear change packet?
|
||||
}
|
||||
else if (from_inst == nullptr)
|
||||
c->Message(13, "Error: There is no item on your cursor");
|
||||
else
|
||||
c->Message(13, "Error: Item on your cursor cannot be equipped");
|
||||
}
|
||||
else
|
||||
c->Message(0, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position");
|
||||
// uint32 slot_id = atoi(sep->arg[1]);
|
||||
// if (sep->IsNumber(1) && ((slot_id >= EmuConstants::EQUIPMENT_BEGIN) && (slot_id <= EmuConstants::EQUIPMENT_END) || (slot_id == MainPowerSource))) {
|
||||
// const ItemInst* from_inst = c->GetInv().GetItem(MainCursor);
|
||||
// const ItemInst* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
|
||||
// bool partialmove = false;
|
||||
// int16 movecount;
|
||||
//
|
||||
// if (from_inst && from_inst->IsType(ItemClassCommon)) {
|
||||
// EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
||||
// MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer;
|
||||
// mi->from_slot = MainCursor;
|
||||
// mi->to_slot = slot_id;
|
||||
// // mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking
|
||||
//
|
||||
// // crude stackable check to only 'move' the difference count on client instead of entire stack when applicable
|
||||
// if (to_inst && to_inst->IsStackable() &&
|
||||
// (to_inst->GetItem()->ID == from_inst->GetItem()->ID) &&
|
||||
// (to_inst->GetCharges() < to_inst->GetItem()->StackSize) &&
|
||||
// (from_inst->GetCharges() > to_inst->GetItem()->StackSize - to_inst->GetCharges())) {
|
||||
// movecount = to_inst->GetItem()->StackSize - to_inst->GetCharges();
|
||||
// mi->number_in_stack = (uint32)movecount;
|
||||
// partialmove = true;
|
||||
// }
|
||||
// else
|
||||
// mi->number_in_stack = from_inst->GetCharges();
|
||||
//
|
||||
// // Save move changes
|
||||
// // Added conditional check to packet send..would have sent change even on a swap failure..whoops!
|
||||
//
|
||||
// if (partialmove) { // remove this con check if someone can figure out removing charges from cursor stack issue below
|
||||
// // mi->number_in_stack is always from_inst->GetCharges() when partialmove is false
|
||||
// c->Message(13, "Error: Partial stack added to existing stack exceeds allowable stacksize");
|
||||
// return;
|
||||
// }
|
||||
// else if(c->SwapItem(mi)) {
|
||||
// c->FastQueuePacket(&outapp);
|
||||
//
|
||||
// // if the below code is still needed..just send an an item trade packet to each slot..it should overwrite the client instance
|
||||
//
|
||||
// // below code has proper logic, but client does not like to have cursor charges changed
|
||||
// // (we could delete the cursor item and resend, but issues would arise if there are queued items)
|
||||
// //if (partialmove) {
|
||||
// // EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
||||
// // DeleteItem_Struct* di = (DeleteItem_Struct*)outapp2->pBuffer;
|
||||
// // di->from_slot = SLOT_CURSOR;
|
||||
// // di->to_slot = 0xFFFFFFFF;
|
||||
// // di->number_in_stack = 0xFFFFFFFF;
|
||||
//
|
||||
// // c->Message(0, "Deleting %i charges from stack", movecount); // debug line..delete
|
||||
//
|
||||
// // for (int16 deletecount=0; deletecount < movecount; deletecount++)
|
||||
// // have to use 'movecount' because mi->number_in_stack is 'ENCODED' at this point (i.e., 99 charges returns 22...)
|
||||
// // c->QueuePacket(outapp2);
|
||||
//
|
||||
// // safe_delete(outapp2);
|
||||
// //}
|
||||
// }
|
||||
// else {
|
||||
// c->Message(13, "Error: Unable to equip current item");
|
||||
// }
|
||||
// safe_delete(outapp);
|
||||
//
|
||||
// // also send out a wear change packet?
|
||||
// }
|
||||
// else if (from_inst == nullptr)
|
||||
// c->Message(13, "Error: There is no item on your cursor");
|
||||
// else
|
||||
// c->Message(13, "Error: Item on your cursor cannot be equipped");
|
||||
// }
|
||||
// else
|
||||
// c->Message(0, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position");
|
||||
}
|
||||
|
||||
void command_zonelock(Client *c, const Seperator *sep)
|
||||
|
||||
+119
-119
@@ -716,122 +716,122 @@ void Client::SendCursorBuffer()
|
||||
|
||||
// Remove item from inventory
|
||||
void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_update, bool update_db) {
|
||||
#if (EQDEBUG >= 5)
|
||||
Log.Out(Logs::General, Logs::None, "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
|
||||
if(!m_inv[slot_id]) {
|
||||
// Make sure the client deletes anything in this slot to match the server.
|
||||
if(client_update && IsValidSlot(slot_id)) {
|
||||
EQApplicationPacket* outapp;
|
||||
outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
||||
DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer;
|
||||
delitem->from_slot = slot_id;
|
||||
delitem->to_slot = 0xFFFFFFFF;
|
||||
delitem->number_in_stack = 0xFFFFFFFF;
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// start QS code
|
||||
if(RuleB(QueryServ, PlayerLogDeletes)) {
|
||||
uint16 delete_count = 0;
|
||||
|
||||
if(m_inv[slot_id]) { delete_count += m_inv.GetItem(slot_id)->GetTotalItemCount(); }
|
||||
|
||||
ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogDeletes, sizeof(QSPlayerLogDelete_Struct) + (sizeof(QSDeleteItems_Struct) * delete_count));
|
||||
QSPlayerLogDelete_Struct* qsaudit = (QSPlayerLogDelete_Struct*)qspack->pBuffer;
|
||||
uint16 parent_offset = 0;
|
||||
|
||||
qsaudit->char_id = character_id;
|
||||
qsaudit->stack_size = quantity;
|
||||
qsaudit->char_count = delete_count;
|
||||
|
||||
qsaudit->items[parent_offset].char_slot = slot_id;
|
||||
qsaudit->items[parent_offset].item_id = m_inv[slot_id]->GetID();
|
||||
qsaudit->items[parent_offset].charges = m_inv[slot_id]->GetCharges();
|
||||
qsaudit->items[parent_offset].aug_1 = m_inv[slot_id]->GetAugmentItemID(1);
|
||||
qsaudit->items[parent_offset].aug_2 = m_inv[slot_id]->GetAugmentItemID(2);
|
||||
qsaudit->items[parent_offset].aug_3 = m_inv[slot_id]->GetAugmentItemID(3);
|
||||
qsaudit->items[parent_offset].aug_4 = m_inv[slot_id]->GetAugmentItemID(4);
|
||||
qsaudit->items[parent_offset].aug_5 = m_inv[slot_id]->GetAugmentItemID(5);
|
||||
|
||||
if(m_inv[slot_id]->IsType(ItemClassContainer)) {
|
||||
for(uint8 bag_idx = SUB_BEGIN; bag_idx < m_inv[slot_id]->GetItem()->BagSlots; bag_idx++) {
|
||||
ItemInst* bagitem = m_inv[slot_id]->GetItem(bag_idx);
|
||||
|
||||
if(bagitem) {
|
||||
int16 bagslot_id = InventoryOld::CalcSlotId(slot_id, bag_idx);
|
||||
|
||||
qsaudit->items[++parent_offset].char_slot = bagslot_id;
|
||||
qsaudit->items[parent_offset].item_id = bagitem->GetID();
|
||||
qsaudit->items[parent_offset].charges = bagitem->GetCharges();
|
||||
qsaudit->items[parent_offset].aug_1 = bagitem->GetAugmentItemID(1);
|
||||
qsaudit->items[parent_offset].aug_2 = bagitem->GetAugmentItemID(2);
|
||||
qsaudit->items[parent_offset].aug_3 = bagitem->GetAugmentItemID(3);
|
||||
qsaudit->items[parent_offset].aug_4 = bagitem->GetAugmentItemID(4);
|
||||
qsaudit->items[parent_offset].aug_5 = bagitem->GetAugmentItemID(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qspack->Deflate();
|
||||
if(worldserver.Connected()) { worldserver.SendPacket(qspack); }
|
||||
safe_delete(qspack);
|
||||
}
|
||||
// end QS code
|
||||
|
||||
bool isDeleted = m_inv.DeleteItem(slot_id, quantity);
|
||||
|
||||
const ItemInst* inst = nullptr;
|
||||
if (slot_id == MainCursor) {
|
||||
auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend();
|
||||
if(update_db)
|
||||
database.SaveCursor(character_id, s, e);
|
||||
}
|
||||
else {
|
||||
// Save change to database
|
||||
inst = m_inv[slot_id];
|
||||
if(update_db)
|
||||
database.SaveInventory(character_id, inst, slot_id);
|
||||
}
|
||||
|
||||
if(client_update && IsValidSlot(slot_id)) {
|
||||
EQApplicationPacket* outapp = nullptr;
|
||||
if(inst) {
|
||||
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 {
|
||||
// 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;loop<quantity;loop++)
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
else {
|
||||
outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
||||
MoveItem_Struct* delitem = (MoveItem_Struct*)outapp->pBuffer;
|
||||
delitem->from_slot = slot_id;
|
||||
delitem->to_slot = 0xFFFFFFFF;
|
||||
delitem->number_in_stack = 0xFFFFFFFF;
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
}
|
||||
// #if (EQDEBUG >= 5)
|
||||
// Log.Out(Logs::General, Logs::None, "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
|
||||
// if(!m_inv[slot_id]) {
|
||||
// // Make sure the client deletes anything in this slot to match the server.
|
||||
// if(client_update && IsValidSlot(slot_id)) {
|
||||
// EQApplicationPacket* outapp;
|
||||
// outapp = new EQApplicationPacket(OP_DeleteItem, sizeof(DeleteItem_Struct));
|
||||
// DeleteItem_Struct* delitem = (DeleteItem_Struct*)outapp->pBuffer;
|
||||
// delitem->from_slot = slot_id;
|
||||
// delitem->to_slot = 0xFFFFFFFF;
|
||||
// delitem->number_in_stack = 0xFFFFFFFF;
|
||||
// QueuePacket(outapp);
|
||||
// safe_delete(outapp);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // start QS code
|
||||
// if(RuleB(QueryServ, PlayerLogDeletes)) {
|
||||
// uint16 delete_count = 0;
|
||||
//
|
||||
// if(m_inv[slot_id]) { delete_count += m_inv.GetItem(slot_id)->GetTotalItemCount(); }
|
||||
//
|
||||
// ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogDeletes, sizeof(QSPlayerLogDelete_Struct) + (sizeof(QSDeleteItems_Struct) * delete_count));
|
||||
// QSPlayerLogDelete_Struct* qsaudit = (QSPlayerLogDelete_Struct*)qspack->pBuffer;
|
||||
// uint16 parent_offset = 0;
|
||||
//
|
||||
// qsaudit->char_id = character_id;
|
||||
// qsaudit->stack_size = quantity;
|
||||
// qsaudit->char_count = delete_count;
|
||||
//
|
||||
// qsaudit->items[parent_offset].char_slot = slot_id;
|
||||
// qsaudit->items[parent_offset].item_id = m_inv[slot_id]->GetID();
|
||||
// qsaudit->items[parent_offset].charges = m_inv[slot_id]->GetCharges();
|
||||
// qsaudit->items[parent_offset].aug_1 = m_inv[slot_id]->GetAugmentItemID(1);
|
||||
// qsaudit->items[parent_offset].aug_2 = m_inv[slot_id]->GetAugmentItemID(2);
|
||||
// qsaudit->items[parent_offset].aug_3 = m_inv[slot_id]->GetAugmentItemID(3);
|
||||
// qsaudit->items[parent_offset].aug_4 = m_inv[slot_id]->GetAugmentItemID(4);
|
||||
// qsaudit->items[parent_offset].aug_5 = m_inv[slot_id]->GetAugmentItemID(5);
|
||||
//
|
||||
// if(m_inv[slot_id]->IsType(ItemClassContainer)) {
|
||||
// for(uint8 bag_idx = SUB_BEGIN; bag_idx < m_inv[slot_id]->GetItem()->BagSlots; bag_idx++) {
|
||||
// ItemInst* bagitem = m_inv[slot_id]->GetItem(bag_idx);
|
||||
//
|
||||
// if(bagitem) {
|
||||
// int16 bagslot_id = InventoryOld::CalcSlotId(slot_id, bag_idx);
|
||||
//
|
||||
// qsaudit->items[++parent_offset].char_slot = bagslot_id;
|
||||
// qsaudit->items[parent_offset].item_id = bagitem->GetID();
|
||||
// qsaudit->items[parent_offset].charges = bagitem->GetCharges();
|
||||
// qsaudit->items[parent_offset].aug_1 = bagitem->GetAugmentItemID(1);
|
||||
// qsaudit->items[parent_offset].aug_2 = bagitem->GetAugmentItemID(2);
|
||||
// qsaudit->items[parent_offset].aug_3 = bagitem->GetAugmentItemID(3);
|
||||
// qsaudit->items[parent_offset].aug_4 = bagitem->GetAugmentItemID(4);
|
||||
// qsaudit->items[parent_offset].aug_5 = bagitem->GetAugmentItemID(5);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// qspack->Deflate();
|
||||
// if(worldserver.Connected()) { worldserver.SendPacket(qspack); }
|
||||
// safe_delete(qspack);
|
||||
// }
|
||||
// // end QS code
|
||||
//
|
||||
// bool isDeleted = m_inv.DeleteItem(slot_id, quantity);
|
||||
//
|
||||
// const ItemInst* inst = nullptr;
|
||||
// if (slot_id == MainCursor) {
|
||||
// auto s = m_inv.cursor_cbegin(), e = m_inv.cursor_cend();
|
||||
// if(update_db)
|
||||
// database.SaveCursor(character_id, s, e);
|
||||
// }
|
||||
// else {
|
||||
// // Save change to database
|
||||
// inst = m_inv[slot_id];
|
||||
// if(update_db)
|
||||
// database.SaveInventory(character_id, inst, slot_id);
|
||||
// }
|
||||
//
|
||||
// if(client_update && IsValidSlot(slot_id)) {
|
||||
// EQApplicationPacket* outapp = nullptr;
|
||||
// if(inst) {
|
||||
// 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 {
|
||||
// // 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;loop<quantity;loop++)
|
||||
// QueuePacket(outapp);
|
||||
// safe_delete(outapp);
|
||||
// }
|
||||
// else {
|
||||
// outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
|
||||
// MoveItem_Struct* delitem = (MoveItem_Struct*)outapp->pBuffer;
|
||||
// delitem->from_slot = slot_id;
|
||||
// delitem->to_slot = 0xFFFFFFFF;
|
||||
// delitem->number_in_stack = 0xFFFFFFFF;
|
||||
//
|
||||
// QueuePacket(outapp);
|
||||
// safe_delete(outapp);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update)
|
||||
@@ -1315,7 +1315,7 @@ bool Client::IsBankSlot(uint32 slot)
|
||||
|
||||
// Moves items around both internally and in the database
|
||||
// In the future, this can be optimized by pushing all changes through one database REPLACE call
|
||||
bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
bool Client::SwapItem(MoveItemOld_Struct* move_in) {
|
||||
|
||||
uint32 src_slot_check = move_in->from_slot;
|
||||
uint32 dst_slot_check = move_in->to_slot;
|
||||
@@ -1788,7 +1788,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Client::SwapItemResync(MoveItem_Struct* move_slots) {
|
||||
void Client::SwapItemResync(MoveItemOld_Struct* move_slots) {
|
||||
// wow..this thing created a helluva memory leak...
|
||||
// with any luck..this won't be needed in the future
|
||||
|
||||
@@ -1883,7 +1883,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) {
|
||||
}
|
||||
}
|
||||
|
||||
void Client::QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call) {
|
||||
void Client::QSSwapItemAuditor(MoveItemOld_Struct* move_in, bool postaction_call) {
|
||||
int16 from_slot_id = static_cast<int16>(move_in->from_slot);
|
||||
int16 to_slot_id = static_cast<int16>(move_in->to_slot);
|
||||
int16 move_amount = static_cast<int16>(move_in->number_in_stack);
|
||||
|
||||
+403
-403
@@ -1333,68 +1333,68 @@ uint16 Client::FindTraderItem(int32 SerialNumber, uint16 Quantity){
|
||||
}
|
||||
|
||||
void Client::NukeTraderItem(uint16 Slot,int16 Charges,uint16 Quantity,Client* Customer,uint16 TraderSlot, int32 SerialNumber, int32 itemid) {
|
||||
|
||||
if(!Customer)
|
||||
return;
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Trading, "NukeTraderItem(Slot %i, Charges %i, Quantity %i", Slot, Charges, Quantity);
|
||||
|
||||
if(Quantity < Charges)
|
||||
{
|
||||
Customer->SendSingleTraderItem(this->CharacterID(), SerialNumber);
|
||||
m_inv.DeleteItem(Slot, Quantity);
|
||||
}
|
||||
else
|
||||
{
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderDelItem,sizeof(TraderDelItem_Struct));
|
||||
TraderDelItem_Struct* tdis = (TraderDelItem_Struct*)outapp->pBuffer;
|
||||
|
||||
tdis->Unknown000 = 0;
|
||||
tdis->TraderID = Customer->GetID();
|
||||
if (Customer->GetClientVersion() >= ClientVersion::RoF)
|
||||
{
|
||||
// RoF+ use Item IDs for now
|
||||
tdis->ItemID = itemid;
|
||||
}
|
||||
else
|
||||
{
|
||||
tdis->ItemID = SerialNumber;
|
||||
}
|
||||
tdis->Unknown012 = 0;
|
||||
|
||||
|
||||
Customer->QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
m_inv.DeleteItem(Slot);
|
||||
}
|
||||
// This updates the trader. Removes it from his trading bags.
|
||||
//
|
||||
const ItemInst* Inst = m_inv[Slot];
|
||||
|
||||
database.SaveInventory(CharacterID(), Inst, Slot);
|
||||
|
||||
EQApplicationPacket* outapp2;
|
||||
|
||||
if(Quantity < Charges)
|
||||
outapp2 = new EQApplicationPacket(OP_DeleteItem,sizeof(MoveItem_Struct));
|
||||
else
|
||||
outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct));
|
||||
|
||||
MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer;
|
||||
mis->from_slot = Slot;
|
||||
mis->to_slot = 0xFFFFFFFF;
|
||||
mis->number_in_stack = 0xFFFFFFFF;
|
||||
|
||||
if(Quantity >= Charges)
|
||||
Quantity = 1;
|
||||
|
||||
for(int i = 0; i < Quantity; i++) {
|
||||
|
||||
this->QueuePacket(outapp2);
|
||||
}
|
||||
safe_delete(outapp2);
|
||||
|
||||
//
|
||||
// if(!Customer)
|
||||
// return;
|
||||
//
|
||||
// Log.Out(Logs::Detail, Logs::Trading, "NukeTraderItem(Slot %i, Charges %i, Quantity %i", Slot, Charges, Quantity);
|
||||
//
|
||||
// if(Quantity < Charges)
|
||||
// {
|
||||
// Customer->SendSingleTraderItem(this->CharacterID(), SerialNumber);
|
||||
// m_inv.DeleteItem(Slot, Quantity);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// EQApplicationPacket* outapp = new EQApplicationPacket(OP_TraderDelItem,sizeof(TraderDelItem_Struct));
|
||||
// TraderDelItem_Struct* tdis = (TraderDelItem_Struct*)outapp->pBuffer;
|
||||
//
|
||||
// tdis->Unknown000 = 0;
|
||||
// tdis->TraderID = Customer->GetID();
|
||||
// if (Customer->GetClientVersion() >= ClientVersion::RoF)
|
||||
// {
|
||||
// // RoF+ use Item IDs for now
|
||||
// tdis->ItemID = itemid;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// tdis->ItemID = SerialNumber;
|
||||
// }
|
||||
// tdis->Unknown012 = 0;
|
||||
//
|
||||
//
|
||||
// Customer->QueuePacket(outapp);
|
||||
// safe_delete(outapp);
|
||||
//
|
||||
// m_inv.DeleteItem(Slot);
|
||||
// }
|
||||
// // This updates the trader. Removes it from his trading bags.
|
||||
// //
|
||||
// const ItemInst* Inst = m_inv[Slot];
|
||||
//
|
||||
// database.SaveInventory(CharacterID(), Inst, Slot);
|
||||
//
|
||||
// EQApplicationPacket* outapp2;
|
||||
//
|
||||
// if(Quantity < Charges)
|
||||
// outapp2 = new EQApplicationPacket(OP_DeleteItem,sizeof(MoveItem_Struct));
|
||||
// else
|
||||
// outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct));
|
||||
//
|
||||
// MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer;
|
||||
// mis->from_slot = Slot;
|
||||
// mis->to_slot = 0xFFFFFFFF;
|
||||
// mis->number_in_stack = 0xFFFFFFFF;
|
||||
//
|
||||
// if(Quantity >= Charges)
|
||||
// Quantity = 1;
|
||||
//
|
||||
// for(int i = 0; i < Quantity; i++) {
|
||||
//
|
||||
// this->QueuePacket(outapp2);
|
||||
// }
|
||||
// safe_delete(outapp2);
|
||||
//
|
||||
}
|
||||
void Client::TraderUpdate(uint16 SlotID,uint32 TraderID){
|
||||
// This method is no longer used.
|
||||
@@ -2507,347 +2507,347 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
void Client::SellToBuyer(const EQApplicationPacket *app) {
|
||||
|
||||
char* Buf = (char *)app->pBuffer;
|
||||
|
||||
char ItemName[64];
|
||||
|
||||
/*uint32 Action =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused
|
||||
uint32 Quantity = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
uint32 BuyerID = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
uint32 BuySlot = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
uint32 UnknownByte = VARSTRUCT_DECODE_TYPE(uint8, Buf);
|
||||
uint32 ItemID = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
/* ItemName */ VARSTRUCT_DECODE_STRING(ItemName, Buf);
|
||||
/*uint32 Unknown2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused
|
||||
uint32 QtyBuyerWants = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
UnknownByte = VARSTRUCT_DECODE_TYPE(uint8, Buf);
|
||||
uint32 Price = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
/*uint32 BuyerID2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused
|
||||
/*uint32 Unknown3 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused
|
||||
|
||||
const ItemData *item = database.GetItem(ItemID);
|
||||
|
||||
if(!item || !Quantity || !Price || !QtyBuyerWants) return;
|
||||
|
||||
if (m_inv.HasItem(ItemID, Quantity, invWhereWorn | invWherePersonal | invWhereCursor) == INVALID_INDEX) {
|
||||
Message(13, "You do not have %i %s on you.", Quantity, item->Name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Client *Buyer = entity_list.GetClientByID(BuyerID);
|
||||
|
||||
if(!Buyer || !Buyer->IsBuyer()) {
|
||||
Message(13, "The Buyer has gone away.");
|
||||
return;
|
||||
}
|
||||
|
||||
// For Stackable items, HasSpaceForItem will try check if there is space to stack with existing stacks in
|
||||
// the buyer inventory.
|
||||
if(!(Buyer->GetInv().HasSpaceForItem(item, Quantity))) {
|
||||
Message(13, "The Buyer does not have space for %i %s", Quantity, item->Name);
|
||||
return;
|
||||
}
|
||||
|
||||
if((static_cast<uint64>(Quantity) * static_cast<uint64>(Price)) > MAX_TRANSACTION_VALUE) {
|
||||
Message(13, "That would exceed the single transaction limit of %u platinum.", MAX_TRANSACTION_VALUE / 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!Buyer->HasMoney(Quantity * Price)) {
|
||||
Message(13, "The Buyer does not have sufficient money to purchase that quantity of %s.", item->Name);
|
||||
Buyer->Message(13, "%s tried to sell you %i %s, but you have insufficient funds.", GetName(), Quantity, item->Name);
|
||||
return;
|
||||
}
|
||||
|
||||
if(Buyer->CheckLoreConflict(item)) {
|
||||
Message(13, "That item is LORE and the Buyer already has one.");
|
||||
Buyer->Message(13, "%s tried to sell you %s but this item is LORE and you already have one.",
|
||||
GetName(), item->Name);
|
||||
return;
|
||||
}
|
||||
|
||||
if(item->NoDrop == 0) {
|
||||
Message(13, "That item is NODROP.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!item->Stackable) {
|
||||
|
||||
for(uint32 i = 0; i < Quantity; i++) {
|
||||
|
||||
int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor);
|
||||
|
||||
// This shouldn't happen, as we already checked there was space in the Buyer's inventory
|
||||
if (SellerSlot == INVALID_INDEX) {
|
||||
|
||||
if(i > 0) {
|
||||
// Set the Quantity to the actual number we successfully transferred.
|
||||
Quantity = i;
|
||||
break;
|
||||
}
|
||||
Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
Message(13, "Internal error while processing transaction.");
|
||||
return;
|
||||
}
|
||||
|
||||
ItemInst* ItemToTransfer = m_inv.PopItem(SellerSlot);
|
||||
|
||||
if(!ItemToTransfer || !Buyer->MoveItemToInventory(ItemToTransfer, true)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
Message(13, "Internal error while processing transaction.");
|
||||
|
||||
if(ItemToTransfer)
|
||||
safe_delete(ItemToTransfer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
database.SaveInventory(CharacterID(), 0, SellerSlot);
|
||||
|
||||
safe_delete(ItemToTransfer);
|
||||
|
||||
// Remove the item from inventory, clientside
|
||||
//
|
||||
EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct));
|
||||
|
||||
MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer;
|
||||
mis->from_slot = SellerSlot;
|
||||
mis->to_slot = 0xFFFFFFFF;
|
||||
mis->number_in_stack = 0xFFFFFFFF;
|
||||
|
||||
QueuePacket(outapp2);
|
||||
safe_delete(outapp2);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Stackable
|
||||
//
|
||||
uint32 QuantityMoved = 0;
|
||||
|
||||
while(QuantityMoved < Quantity) {
|
||||
|
||||
// Find the slot on the seller that has a stack of at least 1 of the item
|
||||
int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor);
|
||||
|
||||
if (SellerSlot == INVALID_INDEX) {
|
||||
Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
Message(13, "Internal error while processing transaction.");
|
||||
return;
|
||||
}
|
||||
|
||||
ItemInst* ItemToTransfer = m_inv.PopItem(SellerSlot);
|
||||
|
||||
if(!ItemToTransfer) {
|
||||
Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
Message(13, "Internal error while processing transaction.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If the stack we found has less than the quantity we are selling ...
|
||||
if(ItemToTransfer->GetCharges() <= (Quantity - QuantityMoved)) {
|
||||
// Transfer the entire stack
|
||||
|
||||
QuantityMoved += ItemToTransfer->GetCharges();
|
||||
|
||||
if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
Message(13, "Internal error while processing transaction.");
|
||||
safe_delete(ItemToTransfer);
|
||||
return;
|
||||
}
|
||||
// Delete the entire stack from the seller's inventory
|
||||
database.SaveInventory(CharacterID(), 0, SellerSlot);
|
||||
|
||||
safe_delete(ItemToTransfer);
|
||||
|
||||
// and tell the client to do the same.
|
||||
EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct));
|
||||
|
||||
MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer;
|
||||
mis->from_slot = SellerSlot;
|
||||
mis->to_slot = 0xFFFFFFFF;
|
||||
mis->number_in_stack = 0xFFFFFFFF;
|
||||
|
||||
QueuePacket(outapp2);
|
||||
safe_delete(outapp2);
|
||||
}
|
||||
else {
|
||||
//Move the amount we need, and put the rest of the stack back in the seller's inventory
|
||||
//
|
||||
int QuantityToRemoveFromStack = Quantity - QuantityMoved;
|
||||
|
||||
ItemToTransfer->SetCharges(ItemToTransfer->GetCharges() - QuantityToRemoveFromStack);
|
||||
|
||||
m_inv.PutItem(SellerSlot, *ItemToTransfer);
|
||||
|
||||
database.SaveInventory(CharacterID(), ItemToTransfer, SellerSlot);
|
||||
|
||||
ItemToTransfer->SetCharges(QuantityToRemoveFromStack);
|
||||
|
||||
if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
Message(13, "Internal error while processing transaction.");
|
||||
safe_delete(ItemToTransfer);
|
||||
return;
|
||||
}
|
||||
|
||||
safe_delete(ItemToTransfer);
|
||||
|
||||
EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem,sizeof(MoveItem_Struct));
|
||||
|
||||
MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer;
|
||||
mis->from_slot = SellerSlot;
|
||||
mis->to_slot = 0xFFFFFFFF;
|
||||
mis->number_in_stack = 0xFFFFFFFF;
|
||||
|
||||
for(int i = 0; i < QuantityToRemoveFromStack; i++)
|
||||
QueuePacket(outapp2);
|
||||
|
||||
safe_delete(outapp2);
|
||||
|
||||
QuantityMoved = Quantity;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Buyer->TakeMoneyFromPP(Quantity * Price);
|
||||
|
||||
AddMoneyToPP(Quantity * Price, false);
|
||||
|
||||
if(RuleB(Bazaar, AuditTrail))
|
||||
BazaarAuditTrail(GetName(), Buyer->GetName(), ItemName, Quantity, Quantity * Price, 1);
|
||||
|
||||
// We now send a packet to the Seller, which causes it to display 'You have sold <Qty> <Item> to <Player> for <money>'
|
||||
//
|
||||
// The PacketLength of 1016 is from the only instance of this packet I have seen, which is from Live, November 2008
|
||||
// The Titanium/6.2 struct is slightly different in that it appears to use fixed length strings instead of variable
|
||||
// length as used on Live. The extra space in the packet is also likely to be used for Item compensation, if we ever
|
||||
// implement that.
|
||||
//
|
||||
uint32 PacketLength = 1016;
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Barter, PacketLength);
|
||||
|
||||
Buf = (char *)outapp->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_SellerTransactionComplete);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price);
|
||||
|
||||
if(GetClientVersion() >= ClientVersion::SoD)
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price
|
||||
}
|
||||
|
||||
sprintf(Buf, "%s", Buyer->GetName()); Buf += 64;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00);
|
||||
|
||||
sprintf(Buf, "%s", ItemName); Buf += 64;
|
||||
|
||||
QueuePacket(outapp);
|
||||
|
||||
// This next packet goes to the Buyer and produces the 'You've bought <Qty> <Item> from <Seller> for <money>'
|
||||
//
|
||||
|
||||
Buf = (char *)outapp->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerTransactionComplete);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price);
|
||||
|
||||
if(Buyer->GetClientVersion() >= ClientVersion::SoD)
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price
|
||||
}
|
||||
|
||||
sprintf(Buf, "%s", GetName()); Buf += 64;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00);
|
||||
|
||||
sprintf(Buf, "%s", ItemName); Buf += 64;
|
||||
|
||||
Buyer->QueuePacket(outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
// Next we update the buyer table in the database to reflect the reduced quantity the Buyer wants to buy.
|
||||
//
|
||||
database.UpdateBuyLine(Buyer->CharacterID(), BuySlot, QtyBuyerWants - Quantity);
|
||||
|
||||
// Next we update the Seller's Barter Window to reflect the reduced quantity the Buyer is now looking to buy.
|
||||
//
|
||||
EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_Barter, 936);
|
||||
|
||||
Buf = (char *)outapp3->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerInspectWindow);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf,ItemID);
|
||||
VARSTRUCT_ENCODE_STRING(Buf, ItemName);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, QtyBuyerWants - Quantity);
|
||||
|
||||
// If the amount we have just sold completely satisfies the quantity the Buyer was looking for,
|
||||
// setting the next byte to 0 will remove the item from the Barter Window.
|
||||
//
|
||||
if(QtyBuyerWants - Quantity > 0) {
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // 0 = Toggle Off, 1 = Toggle On
|
||||
}
|
||||
else {
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0); // 0 = Toggle Off, 1 = Toggle On
|
||||
}
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Buyer->GetID());
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0);
|
||||
|
||||
VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName());
|
||||
|
||||
QueuePacket(outapp3);
|
||||
safe_delete(outapp3);
|
||||
|
||||
// The next packet updates the /buyer window with the reduced quantity, and toggles the buy line off if the
|
||||
// quantity they wanted to buy has been met.
|
||||
//
|
||||
EQApplicationPacket* outapp4 = new EQApplicationPacket(OP_Barter, 936);
|
||||
|
||||
Buf = (char*)outapp4->pBuffer;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerItemUpdate);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, ItemID);
|
||||
VARSTRUCT_ENCODE_STRING(Buf, ItemName);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, QtyBuyerWants - Quantity);
|
||||
|
||||
if((QtyBuyerWants - Quantity) > 0) {
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // 0 = Toggle Off, 1 = Toggle On
|
||||
}
|
||||
else {
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0); // 0 = Toggle Off, 1 = Toggle On
|
||||
}
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x08f4); // Unknown
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0);
|
||||
VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName());
|
||||
|
||||
Buyer->QueuePacket(outapp4);
|
||||
safe_delete(outapp4);
|
||||
|
||||
return;
|
||||
//
|
||||
// char* Buf = (char *)app->pBuffer;
|
||||
//
|
||||
// char ItemName[64];
|
||||
//
|
||||
// /*uint32 Action =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused
|
||||
// uint32 Quantity = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
// uint32 BuyerID = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
// uint32 BuySlot = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
// uint32 UnknownByte = VARSTRUCT_DECODE_TYPE(uint8, Buf);
|
||||
// uint32 ItemID = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
// /* ItemName */ VARSTRUCT_DECODE_STRING(ItemName, Buf);
|
||||
// /*uint32 Unknown2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused
|
||||
// uint32 QtyBuyerWants = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
// UnknownByte = VARSTRUCT_DECODE_TYPE(uint8, Buf);
|
||||
// uint32 Price = VARSTRUCT_DECODE_TYPE(uint32, Buf);
|
||||
// /*uint32 BuyerID2 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused
|
||||
// /*uint32 Unknown3 =*/ VARSTRUCT_SKIP_TYPE(uint32, Buf); //unused
|
||||
//
|
||||
// const ItemData *item = database.GetItem(ItemID);
|
||||
//
|
||||
// if(!item || !Quantity || !Price || !QtyBuyerWants) return;
|
||||
//
|
||||
// if (m_inv.HasItem(ItemID, Quantity, invWhereWorn | invWherePersonal | invWhereCursor) == INVALID_INDEX) {
|
||||
// Message(13, "You do not have %i %s on you.", Quantity, item->Name);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Client *Buyer = entity_list.GetClientByID(BuyerID);
|
||||
//
|
||||
// if(!Buyer || !Buyer->IsBuyer()) {
|
||||
// Message(13, "The Buyer has gone away.");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // For Stackable items, HasSpaceForItem will try check if there is space to stack with existing stacks in
|
||||
// // the buyer inventory.
|
||||
// if(!(Buyer->GetInv().HasSpaceForItem(item, Quantity))) {
|
||||
// Message(13, "The Buyer does not have space for %i %s", Quantity, item->Name);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if((static_cast<uint64>(Quantity) * static_cast<uint64>(Price)) > MAX_TRANSACTION_VALUE) {
|
||||
// Message(13, "That would exceed the single transaction limit of %u platinum.", MAX_TRANSACTION_VALUE / 1000);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(!Buyer->HasMoney(Quantity * Price)) {
|
||||
// Message(13, "The Buyer does not have sufficient money to purchase that quantity of %s.", item->Name);
|
||||
// Buyer->Message(13, "%s tried to sell you %i %s, but you have insufficient funds.", GetName(), Quantity, item->Name);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(Buyer->CheckLoreConflict(item)) {
|
||||
// Message(13, "That item is LORE and the Buyer already has one.");
|
||||
// Buyer->Message(13, "%s tried to sell you %s but this item is LORE and you already have one.",
|
||||
// GetName(), item->Name);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(item->NoDrop == 0) {
|
||||
// Message(13, "That item is NODROP.");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(!item->Stackable) {
|
||||
//
|
||||
// for(uint32 i = 0; i < Quantity; i++) {
|
||||
//
|
||||
// int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor);
|
||||
//
|
||||
// // This shouldn't happen, as we already checked there was space in the Buyer's inventory
|
||||
// if (SellerSlot == INVALID_INDEX) {
|
||||
//
|
||||
// if(i > 0) {
|
||||
// // Set the Quantity to the actual number we successfully transferred.
|
||||
// Quantity = i;
|
||||
// break;
|
||||
// }
|
||||
// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
// Message(13, "Internal error while processing transaction.");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// ItemInst* ItemToTransfer = m_inv.PopItem(SellerSlot);
|
||||
//
|
||||
// if(!ItemToTransfer || !Buyer->MoveItemToInventory(ItemToTransfer, true)) {
|
||||
// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
// Message(13, "Internal error while processing transaction.");
|
||||
//
|
||||
// if(ItemToTransfer)
|
||||
// safe_delete(ItemToTransfer);
|
||||
//
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// database.SaveInventory(CharacterID(), 0, SellerSlot);
|
||||
//
|
||||
// safe_delete(ItemToTransfer);
|
||||
//
|
||||
// // Remove the item from inventory, clientside
|
||||
// //
|
||||
// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct));
|
||||
//
|
||||
// MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer;
|
||||
// mis->from_slot = SellerSlot;
|
||||
// mis->to_slot = 0xFFFFFFFF;
|
||||
// mis->number_in_stack = 0xFFFFFFFF;
|
||||
//
|
||||
// QueuePacket(outapp2);
|
||||
// safe_delete(outapp2);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// // Stackable
|
||||
// //
|
||||
// uint32 QuantityMoved = 0;
|
||||
//
|
||||
// while(QuantityMoved < Quantity) {
|
||||
//
|
||||
// // Find the slot on the seller that has a stack of at least 1 of the item
|
||||
// int16 SellerSlot = m_inv.HasItem(ItemID, 1, invWhereWorn|invWherePersonal|invWhereCursor);
|
||||
//
|
||||
// if (SellerSlot == INVALID_INDEX) {
|
||||
// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
// Message(13, "Internal error while processing transaction.");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// ItemInst* ItemToTransfer = m_inv.PopItem(SellerSlot);
|
||||
//
|
||||
// if(!ItemToTransfer) {
|
||||
// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
// Message(13, "Internal error while processing transaction.");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // If the stack we found has less than the quantity we are selling ...
|
||||
// if(ItemToTransfer->GetCharges() <= (Quantity - QuantityMoved)) {
|
||||
// // Transfer the entire stack
|
||||
//
|
||||
// QuantityMoved += ItemToTransfer->GetCharges();
|
||||
//
|
||||
// if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) {
|
||||
// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
// Message(13, "Internal error while processing transaction.");
|
||||
// safe_delete(ItemToTransfer);
|
||||
// return;
|
||||
// }
|
||||
// // Delete the entire stack from the seller's inventory
|
||||
// database.SaveInventory(CharacterID(), 0, SellerSlot);
|
||||
//
|
||||
// safe_delete(ItemToTransfer);
|
||||
//
|
||||
// // and tell the client to do the same.
|
||||
// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_MoveItem,sizeof(MoveItem_Struct));
|
||||
//
|
||||
// MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer;
|
||||
// mis->from_slot = SellerSlot;
|
||||
// mis->to_slot = 0xFFFFFFFF;
|
||||
// mis->number_in_stack = 0xFFFFFFFF;
|
||||
//
|
||||
// QueuePacket(outapp2);
|
||||
// safe_delete(outapp2);
|
||||
// }
|
||||
// else {
|
||||
// //Move the amount we need, and put the rest of the stack back in the seller's inventory
|
||||
// //
|
||||
// int QuantityToRemoveFromStack = Quantity - QuantityMoved;
|
||||
//
|
||||
// ItemToTransfer->SetCharges(ItemToTransfer->GetCharges() - QuantityToRemoveFromStack);
|
||||
//
|
||||
// m_inv.PutItem(SellerSlot, *ItemToTransfer);
|
||||
//
|
||||
// database.SaveInventory(CharacterID(), ItemToTransfer, SellerSlot);
|
||||
//
|
||||
// ItemToTransfer->SetCharges(QuantityToRemoveFromStack);
|
||||
//
|
||||
// if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) {
|
||||
// Log.Out(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer.");
|
||||
// Message(13, "Internal error while processing transaction.");
|
||||
// safe_delete(ItemToTransfer);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// safe_delete(ItemToTransfer);
|
||||
//
|
||||
// EQApplicationPacket* outapp2 = new EQApplicationPacket(OP_DeleteItem,sizeof(MoveItem_Struct));
|
||||
//
|
||||
// MoveItem_Struct* mis = (MoveItem_Struct*)outapp2->pBuffer;
|
||||
// mis->from_slot = SellerSlot;
|
||||
// mis->to_slot = 0xFFFFFFFF;
|
||||
// mis->number_in_stack = 0xFFFFFFFF;
|
||||
//
|
||||
// for(int i = 0; i < QuantityToRemoveFromStack; i++)
|
||||
// QueuePacket(outapp2);
|
||||
//
|
||||
// safe_delete(outapp2);
|
||||
//
|
||||
// QuantityMoved = Quantity;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// Buyer->TakeMoneyFromPP(Quantity * Price);
|
||||
//
|
||||
// AddMoneyToPP(Quantity * Price, false);
|
||||
//
|
||||
// if(RuleB(Bazaar, AuditTrail))
|
||||
// BazaarAuditTrail(GetName(), Buyer->GetName(), ItemName, Quantity, Quantity * Price, 1);
|
||||
//
|
||||
// // We now send a packet to the Seller, which causes it to display 'You have sold <Qty> <Item> to <Player> for <money>'
|
||||
// //
|
||||
// // The PacketLength of 1016 is from the only instance of this packet I have seen, which is from Live, November 2008
|
||||
// // The Titanium/6.2 struct is slightly different in that it appears to use fixed length strings instead of variable
|
||||
// // length as used on Live. The extra space in the packet is also likely to be used for Item compensation, if we ever
|
||||
// // implement that.
|
||||
// //
|
||||
// uint32 PacketLength = 1016;
|
||||
//
|
||||
// EQApplicationPacket* outapp = new EQApplicationPacket(OP_Barter, PacketLength);
|
||||
//
|
||||
// Buf = (char *)outapp->pBuffer;
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_SellerTransactionComplete);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price);
|
||||
//
|
||||
// if(GetClientVersion() >= ClientVersion::SoD)
|
||||
// {
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price
|
||||
// }
|
||||
//
|
||||
// sprintf(Buf, "%s", Buyer->GetName()); Buf += 64;
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00);
|
||||
//
|
||||
// sprintf(Buf, "%s", ItemName); Buf += 64;
|
||||
//
|
||||
// QueuePacket(outapp);
|
||||
//
|
||||
// // This next packet goes to the Buyer and produces the 'You've bought <Qty> <Item> from <Seller> for <money>'
|
||||
// //
|
||||
//
|
||||
// Buf = (char *)outapp->pBuffer;
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerTransactionComplete);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Quantity * Price);
|
||||
//
|
||||
// if(Buyer->GetClientVersion() >= ClientVersion::SoD)
|
||||
// {
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0); // Think this is the upper 32 bits of a 64 bit price
|
||||
// }
|
||||
//
|
||||
// sprintf(Buf, "%s", GetName()); Buf += 64;
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0x01);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x00);
|
||||
//
|
||||
// sprintf(Buf, "%s", ItemName); Buf += 64;
|
||||
//
|
||||
// Buyer->QueuePacket(outapp);
|
||||
//
|
||||
// safe_delete(outapp);
|
||||
//
|
||||
// // Next we update the buyer table in the database to reflect the reduced quantity the Buyer wants to buy.
|
||||
// //
|
||||
// database.UpdateBuyLine(Buyer->CharacterID(), BuySlot, QtyBuyerWants - Quantity);
|
||||
//
|
||||
// // Next we update the Seller's Barter Window to reflect the reduced quantity the Buyer is now looking to buy.
|
||||
// //
|
||||
// EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_Barter, 936);
|
||||
//
|
||||
// Buf = (char *)outapp3->pBuffer;
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerInspectWindow);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // Unknown
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf,ItemID);
|
||||
// VARSTRUCT_ENCODE_STRING(Buf, ItemName);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, QtyBuyerWants - Quantity);
|
||||
//
|
||||
// // If the amount we have just sold completely satisfies the quantity the Buyer was looking for,
|
||||
// // setting the next byte to 0 will remove the item from the Barter Window.
|
||||
// //
|
||||
// if(QtyBuyerWants - Quantity > 0) {
|
||||
// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // 0 = Toggle Off, 1 = Toggle On
|
||||
// }
|
||||
// else {
|
||||
// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0); // 0 = Toggle Off, 1 = Toggle On
|
||||
// }
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Buyer->GetID());
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0);
|
||||
//
|
||||
// VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName());
|
||||
//
|
||||
// QueuePacket(outapp3);
|
||||
// safe_delete(outapp3);
|
||||
//
|
||||
// // The next packet updates the /buyer window with the reduced quantity, and toggles the buy line off if the
|
||||
// // quantity they wanted to buy has been met.
|
||||
// //
|
||||
// EQApplicationPacket* outapp4 = new EQApplicationPacket(OP_Barter, 936);
|
||||
//
|
||||
// Buf = (char*)outapp4->pBuffer;
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerItemUpdate);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, BuySlot);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, ItemID);
|
||||
// VARSTRUCT_ENCODE_STRING(Buf, ItemName);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, item->Icon);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, QtyBuyerWants - Quantity);
|
||||
//
|
||||
// if((QtyBuyerWants - Quantity) > 0) {
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 1); // 0 = Toggle Off, 1 = Toggle On
|
||||
// }
|
||||
// else {
|
||||
// VARSTRUCT_ENCODE_TYPE(uint8, Buf, 0); // 0 = Toggle Off, 1 = Toggle On
|
||||
// }
|
||||
//
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, Price);
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0x08f4); // Unknown
|
||||
// VARSTRUCT_ENCODE_TYPE(uint32, Buf, 0);
|
||||
// VARSTRUCT_ENCODE_STRING(Buf, Buyer->GetName());
|
||||
//
|
||||
// Buyer->QueuePacket(outapp4);
|
||||
// safe_delete(outapp4);
|
||||
//
|
||||
// return;
|
||||
}
|
||||
|
||||
void Client::SendBuyerPacket(Client* Buyer) {
|
||||
|
||||
Reference in New Issue
Block a user