Reworked Trade::AddEntity() to allow client-directed movement of stacked items (as close to 'stacking' as I can get it - see changelog.txt)

This commit is contained in:
Uleat 2014-08-20 18:30:19 -04:00
parent 1b6ccca709
commit 5946af88a6
4 changed files with 49 additions and 32 deletions

View File

@ -1,13 +1,18 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50) EQEMu Changelog (Started on Sept 24, 2003 15:50)
------------------------------------------------------- -------------------------------------------------------
== 08/20/2014 ==
Uleat: Rework of Trade::AddEntity() - function used to move items into the trade window. Now accepts argument for 'stack_size' and updates client properly.
Note: I tested trade with Titanium:{SoF,SoD,UF,RoF} in both directions and no client generated an OP_MoveItem event for attempting to place a stackable
onto a partial stack already in the trade window. The only way to achieve stacking is to click on the receiving client. If there is a partial stack remaining
on the cursor after the OP_MoveItem event, and there is room available, the client will generate subsequent events to move the remaining count.
== 08/19/2014 == == 08/19/2014 ==
Akkadius: Implemented a Stop_Return feature (Accidental item handin prevention) that will be symmetrically used with plugin::return_items that I am currently running live testing on EZ before releasing to EQEmu. This does not hurt to have this in the source. Akkadius: Implemented a Stop_Return feature (Accidental item handin prevention) that will be symmetrically used with plugin::return_items that I am currently running live testing on EZ before releasing to EQEmu. This does not hurt to have this in the source.
Akkadius: Fixed crash where 'attacker' validation is not being checked Akkadius: Fixed crash where 'attacker' validation is not being checked
Akkadius: Removed petition console spam that does not follow traditional logging and is useless Akkadius: Removed petition console spam that does not follow traditional logging and is useless
Akkadius: Made fix with SympatheticProcChances where it was checking for TempItem->Focus.Effect instead of TempItemAug->Focus.Effect== 08/18/2014 == Akkadius: Made fix with SympatheticProcChances where it was checking for TempItem->Focus.Effect instead of TempItemAug->Focus.Effect
== 08/18/2014 == == 08/18/2014 ==
Uleat: Fix for https://github.com/EQEmu/Server/issues/127 -- also activated a remarked action in doors.cpp to eliminate a memory leak. Uleat: Fix for https://github.com/EQEmu/Server/issues/127 -- also activated a remarked action in doors.cpp to eliminate a memory leak.
== 08/16/2014 == == 08/16/2014 ==

View File

@ -526,7 +526,7 @@ public:
Mob* With(); Mob* With();
// Add item from cursor slot to trade bucket (automatically does bag data too) // Add item from cursor slot to trade bucket (automatically does bag data too)
void AddEntity(uint16 from_slot_id, uint16 trade_slot_id); void AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_size);
// Audit trade // Audit trade
void LogTrade(); void LogTrade();

View File

@ -1540,7 +1540,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
// Also sends trade information to other client of trade session // Also sends trade information to other client of trade session
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
trade->AddEntity(src_slot_id, dst_slot_id); trade->AddEntity(src_slot_id, dst_slot_id, move_in->number_in_stack);
return true; return true;
} else { } else {

View File

@ -71,8 +71,9 @@ void Trade::Start(uint32 mob_id, bool initiate_with)
} }
// Add item from a given slot to trade bucket (automatically does bag data too) // Add item from a given slot to trade bucket (automatically does bag data too)
void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id) void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_size) {
{ // TODO: review for inventory saves
if (!owner || !owner->IsClient()) { if (!owner || !owner->IsClient()) {
// This should never happen // This should never happen
LogFile->write(EQEMuLog::Debug, "Programming error: NPC's should not call Trade::AddEntity()"); LogFile->write(EQEMuLog::Debug, "Programming error: NPC's should not call Trade::AddEntity()");
@ -87,45 +88,56 @@ void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id)
// Item always goes into trade bucket from cursor // Item always goes into trade bucket from cursor
Client* client = owner->CastToClient(); Client* client = owner->CastToClient();
const ItemInst* inst = client->GetInv().GetItem(MainCursor); ItemInst* inst = client->GetInv().GetItem(MainCursor);
if (!inst) { if (!inst) {
client->Message(13, "Error: Could not find item on your cursor!"); client->Message(13, "Error: Could not find item on your cursor!");
return; return;
} }
_log(TRADING__HOLDER, "%s added item '%s' to trade slot %i", owner->GetName(), inst->GetItem()->Name, trade_slot_id);
ItemInst* inst2 = client->GetInv().GetItem(trade_slot_id); ItemInst* inst2 = client->GetInv().GetItem(trade_slot_id);
int new_charges = 0;
if (!inst2 || !inst2->GetItem()) { // it looks like the original code attempted to allow stacking...
// Send all item data to other client // (it just didn't handle partial stack move actions -U)
SendItemData(inst, trade_slot_id); if (stack_size > 0) {
// Move item on cursor to the trade slots if (!inst->IsStackable() || !inst2 || !inst2->GetItem() || (inst->GetID() != inst2->GetID()) || (stack_size > inst->GetCharges())) {
client->PutItemInInventory(trade_slot_id, *inst);
}
else
{
if (client->GetInv().GetItem(MainCursor)->GetID() != client->GetInv().GetItem(trade_slot_id)->GetID()) {
client->Kick(); client->Kick();
return; return;
} }
new_charges = (inst2->GetCharges()+inst->GetCharges());
if (new_charges < inst2->GetItem()->StackSize) uint32 _stack_size = 0;
{
inst2->SetCharges(new_charges); if ((stack_size + inst2->GetCharges()) > inst2->GetItem()->StackSize) {
new_charges = 0; _stack_size = (stack_size + inst2->GetCharges()) - inst->GetItem()->StackSize;
}
else
{
new_charges = inst->GetCharges()-(inst2->GetItem()->StackSize-inst2->GetCharges()); //Leftover charges = charges - difference
inst2->SetCharges(inst2->GetItem()->StackSize); inst2->SetCharges(inst2->GetItem()->StackSize);
} }
else {
_stack_size = inst->GetCharges() - stack_size;
inst2->SetCharges(stack_size + inst2->GetCharges());
}
_log(TRADING__HOLDER, "%s added partial item '%s' stack (qty: %i) to trade slot %i", owner->GetName(), inst->GetItem()->Name, stack_size, trade_slot_id);
if (_stack_size > 0)
inst->SetCharges(_stack_size);
else
client->DeleteItemInInventory(from_slot_id);
SendItemData(inst2, trade_slot_id); SendItemData(inst2, trade_slot_id);
} }
if (new_charges > 0) else {
client->GetInv().GetItem(from_slot_id)->SetCharges(new_charges); if (inst2 && inst2->GetID()) {
else client->Kick();
client->DeleteItemInInventory(from_slot_id);//, (ItemInst&)trade_inst); return;
}
SendItemData(inst, trade_slot_id);
_log(TRADING__HOLDER, "%s added item '%s' to trade slot %i", owner->GetName(), inst->GetItem()->Name, trade_slot_id);
client->PutItemInInventory(trade_slot_id, *inst);
client->DeleteItemInInventory(from_slot_id);
}
} }
// Retrieve mob the owner is trading with // Retrieve mob the owner is trading with