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)
-------------------------------------------------------
== 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 ==
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: 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 ==
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 ==

View File

@ -526,7 +526,7 @@ public:
Mob* With();
// 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
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
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;
} 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)
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()) {
// This should never happen
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
Client* client = owner->CastToClient();
const ItemInst* inst = client->GetInv().GetItem(MainCursor);
ItemInst* inst = client->GetInv().GetItem(MainCursor);
if (!inst) {
client->Message(13, "Error: Could not find item on your cursor!");
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);
int new_charges = 0;
if (!inst2 || !inst2->GetItem()) {
// Send all item data to other client
SendItemData(inst, trade_slot_id);
// Move item on cursor to the trade slots
client->PutItemInInventory(trade_slot_id, *inst);
}
else
{
if (client->GetInv().GetItem(MainCursor)->GetID() != client->GetInv().GetItem(trade_slot_id)->GetID()) {
// it looks like the original code attempted to allow stacking...
// (it just didn't handle partial stack move actions -U)
if (stack_size > 0) {
if (!inst->IsStackable() || !inst2 || !inst2->GetItem() || (inst->GetID() != inst2->GetID()) || (stack_size > inst->GetCharges())) {
client->Kick();
return;
}
new_charges = (inst2->GetCharges()+inst->GetCharges());
if (new_charges < inst2->GetItem()->StackSize)
{
inst2->SetCharges(new_charges);
new_charges = 0;
}
else
{
new_charges = inst->GetCharges()-(inst2->GetItem()->StackSize-inst2->GetCharges()); //Leftover charges = charges - difference
uint32 _stack_size = 0;
if ((stack_size + inst2->GetCharges()) > inst2->GetItem()->StackSize) {
_stack_size = (stack_size + inst2->GetCharges()) - inst->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);
}
if (new_charges > 0)
client->GetInv().GetItem(from_slot_id)->SetCharges(new_charges);
else
client->DeleteItemInInventory(from_slot_id);//, (ItemInst&)trade_inst);
else {
if (inst2 && inst2->GetID()) {
client->Kick();
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