Try this new code out. I've fixed the Spinechill Silk combine and the Spellbook Scribe crash.
If somebody could list some thing to test or items that currently go away when the charges are used but aren't supposed to, that would be great.
Things I've tested with this new update:
Tradeskills:
Created Fish Rolls by combining 1 Fresh Fish and 1 Bat Wings. Stacked supplies correctly subtracted.
Created Spinechill Silk by combining 1 Spinechill Ichor Vial and 2 Spinechill Silk. Unstackable supplies correctly subtracted.
Worn items with charges:
Cleric/Paladin Shield - Aegis of Life 1 charge of Superior Healing. Charge used, Item not deleted.
Journeyman's Boots. Unlimited charges, not deleted.
Inventory items with charges:
Prayers of Life 5 charges of Word of Healing. Charges used, Item deleted.
Crystalized Pumice 5 charges of Nullify Magic. Charges used, Item deleted.
Stack of 10 Cloudy Potions. Stack decremented correctly and last one deleted.
5 Dose Cloudy Potion. Charges used, Item deleted.
Stack of Bandages. Took some damage and used Bind Wound skill. Bandages decremented correctly.
Spell Scribing:
Wizard memorized Gate spell. Spell scroll deleted, no crash.
Merchants:
Purchased stackable items
Purchased unstackable items
Sold stackable items
Sold unstackable items
Bots:
Trade with bots to give them equipment works.
#bot inventory remove used successfully
GM:
#si [itemid] worked.
#nukeitem [itemid] worked.
You will still need the item.h and Item.cpp changes from the first post.
This is the spell scribing fix:
\zone\client_process.cpp void Client::OPMemorizeSpell(const EQApplicationPacket* app)
Replace the case statement for memSpellScribing:
Code:
case memSpellScribing: { // scribing spell to book
ItemInst* inst = m_inv.PopItem(SLOT_CURSOR);
if(inst && inst->IsType(ItemClassCommon))
{
const Item_Struct* item = inst->GetItem();
if(item && item->Scroll.Effect == (sint32)(memspell->spell_id))
{
ScribeSpell(memspell->spell_id, memspell->slot);
// Destroy scroll on cursor
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
MoveItem_Struct* spellmoveitem = (MoveItem_Struct*) outapp->pBuffer;
spellmoveitem->from_slot = SLOT_CURSOR;
spellmoveitem->to_slot = SLOT_INVALID;
spellmoveitem->number_in_stack = 0;
QueuePacket(outapp);
safe_delete(outapp);
DeleteItemInInventory(SLOT_CURSOR);
}
else
Message(0,"Scribing spell: inst exists but item does not or spell ids do not match.");
}
else
Message(0,"Scribing a spell without an inst on your cursor?");
break;
}
with
Code:
case memSpellScribing: { // scribing spell to book
const ItemInst* inst = m_inv[SLOT_CURSOR];
if(inst && inst->IsType(ItemClassCommon))
{
const Item_Struct* item = inst->GetItem();
if(item && item->Scroll.Effect == (sint32)(memspell->spell_id))
{
ScribeSpell(memspell->spell_id, memspell->slot);
DeleteItemInInventory(SLOT_CURSOR, 1, true);
}
else
Message(0,"Scribing spell: inst exists but item does not or spell ids do not match.");
}
else
Message(0,"Scribing a spell without an inst on your cursor?");
break;
}
Here's a complete replacement again for the method \zone\inventory.cpp Client::DeleteItemInInventory(sint16 slot_id, sint8 quantity, bool client_update)
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
if(!m_inv[slot_id]) {
return;
}
bool isDeleted = false;
if(m_inv[slot_id]->GetItem()->Click.Type == ET_EquipClick) {
isDeleted = m_inv.DeleteItem(slot_id, quantity, true);
}
else {
isDeleted = m_inv.DeleteItem(slot_id, quantity);
}
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);
}
}
}