
SoulBound enchant + Grave Pet = Duped Items
capnkirok opened this issue ยท 7 comments
This bug was reported to Inventory Pets, but not sure what to do from looking at your source code. The basic gist is that if you have the SoulBound Enchantment on an item, and you also use the Grave Pet, the item becomes duped.
On my side, I could try to identify which items have the enchant, but I don't know your enchantID (they look dynamic in the code). Or on your side, you could check to see if a Grave Pet with zero damage is in the hotbar, in which case the item shouldn't respawn.
Any advice is helpful.
I haven't looked at our code for a while, but I was under the impression, that it specifically moves the itemstack around, instead of copying. So it only ever exists in one of the lists. How are you handling the items?
I store the all the dropped items in NBT at death and cancel the drop event. They I load them back in on respawn. I can loop through them during respawn event (and skip any that have SoulBound), but not sure how to identify when it does. Haven't worked much with custom enchants. I am used to just pulling the ID number from vanilla.
ok, try to remove them from the list at the same time you take a copy, not just cancel the event. That should stop the duplication. I can have a look at our code later, doing this from memory now.
PS: Ok, I acknowledge that soulbound should probably ignore the event if it was cancelled already. Fixed that in this PR.
So, I had a look at our code.
ListIterator<EntityItem> iter = evt.drops.listIterator();
while (iter.hasNext()) {
EntityItem ei = iter.next();
ItemStack item = ei.getEntityItem();
if(isSoulBound(item)) {
addToPlayerInventory(evt.entityPlayer, item);
iter.remove();
}
}
We remove the soulbound items from the drops list and put them into the inventory. So, if you want to preserve the inventory, I'd suggest you do the same. If you want to put the drops into a grave, I'd suggest you put them there and remove them from the list. That way there will only ever be one copy if each item.
There's no need to store the items and put them back later, btw. Unless you want to preserve inventory positions, but then you should check in the playerDropsEvent if the items are also in the drops list and remove them (and remove the items that are in your list but not the drops list from your list) for maximum compatibility.
Also, I just noticed it's a problem in our code, handle the case that the player main inventory is full.