View Single Post
  #1  
Old 01-08-2009, 09:16 PM
Congdar
Developer
 
Join Date: Jul 2007
Location: my own little world
Posts: 751
Default items disappearing after last charge is used - possible fix, test your items!

This is working for me using the Titanium client, but I read a post where KLS mentioned that the 0.6.2 client handles some things differently. Looking for testers!

\common\item.h existing:
Code:
	// Remove item from inventory
	void DeleteItem(sint16 slot_id, uint8 quantity=0);
\common\item.h change to:
Code:
	// Remove item from inventory
	bool DeleteItem(sint16 slot_id, uint8 quantity=0, bool isEquipment=false);

\common\Item.cpp replace method Inventory::DeleteItem(sint16 slot_id, uint8 quantity) with:
Code:
// Remove item from inventory (with memory delete)
bool Inventory::DeleteItem(sint16 slot_id, uint8 quantity, bool isEquipment)
{
	// Pop item out of inventory map (or queue)
	ItemInst* item_to_delete = PopItem(slot_id);
	
	// Determine if object should be fully deleted, or
	// just a quantity of charges of the item can be deleted
	if (item_to_delete && (quantity > 0)) {
		item_to_delete->SetCharges(item_to_delete->GetCharges() - quantity);
		if((item_to_delete->GetCharges() > 0) || isEquipment) {
			// Charges still exist!  Put back into inventory
			_PutItem(slot_id, item_to_delete);
			return false;
		}
	}
	
	// Item can now be destroyed
	safe_delete(item_to_delete);
	return true;
}



\zone\inventory.cpp replace method Client::DeleteItemInInventory(sint16 slot_id, sint8 quantity, bool client_update) with:
Code:
// Remove item from inventory
void Client::DeleteItemInInventory(sint16 slot_id, sint8 quantity, bool client_update) {
	#if (EQDEBUG >= 5)
		LogFile->write(EQEMuLog::Debug, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true":"false");
	#endif

	bool isDeleted = false;
	const Item_Struct* item = m_inv[slot_id]->GetItem();
	if(
		(m_inv[slot_id]->GetItem()->Click.Type == ET_Expendable) ||
		(m_inv[slot_id]->GetItem()->Click.Type == ET_ClickEffect) ||
		(m_inv[slot_id]->GetItem()->Click.Type == ET_ClickEffect2) ||
		(item->ItemType == ItemTypeFood) ||
		(item->ItemType == ItemTypeDrink) ||
		(item->ItemType == ItemTypeBandage) ||
		(item->ItemType == ItemTypeThrowing) ||
		(item->ItemType == ItemTypeThrowingv2) ||
		(item->ItemType == ItemTypeArrow) ||
		(item->ItemType == ItemTypeFishingBait) ||
		(item->ItemType == ItemTypeAlcohol) ||
		(item->ItemType == ItemTypePoison) ||
		(item->ItemType == ItemTypeStackable)
		) {
			isDeleted = m_inv.DeleteItem(slot_id, quantity);
	}
	else if(m_inv[slot_id]->GetItem()->Click.Type == ET_EquipClick) {
		isDeleted = m_inv.DeleteItem(slot_id, quantity, true);
	}

	const ItemInst* inst=NULL;
	if(slot_id==SLOT_CURSOR) {
		list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
		database.SaveCursor(character_id, s, e);
	}
	else {
		// Save change to database
		inst = m_inv[slot_id];
		database.SaveInventory(character_id, inst, slot_id);
	}

	if(client_update) {
		EQApplicationPacket* outapp;
		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);
		}
	}
}
Reply With Quote