Posted November 6, 201311 yr Is there a way to detect if an item has been removed/placed inside of a slot, and tell what was added to the slot and what was removed? Kain
November 6, 201311 yr Author I linked this up to my PlayerTickHandler to try to do this, but no results. :I for(int i = 0;i < this.lastSlots.length;i++) { try { if(this.lastSlots[i] != this.currentSlots[i]) { if(this.lastSlots[i].getItem() != null && this.lastSlots[i].getItem() instanceof IAccessory) { IAccessory accessory = (IAccessory)this.lastSlots[i].getItem(); accessory.unequipped(player); } if(this.currentSlots[i].getItem() != null && this.currentSlots[i].getItem() instanceof IAccessory) { IAccessory accessory = (IAccessory)this.currentSlots[i].getItem(); accessory.equipped(player); } } } catch(Exception e) { e.printStackTrace(); } } Kain
November 6, 201311 yr Hi I think the basic concept should work fine. Depending on how you are storing the slot contents, the problem might be here if(this.lastSlots != this.currentSlots) i.e. this statement compares two objects, so these might be different objects even if the contents are identical alternatively, perhaps you are not updating lastSlots or currentSlots properly? Have you tried inserting a breakpoint and inspecting them, or logging their contents to stdout? -TGG
November 6, 201311 yr Author Ok, I've switched to a much more efficient way. Instead of doing it every tick, I'm doing it every time a slot changes. My only problem now, is that it detects if it's been equipped. But if I try to remove it, it does nothing. It also only detects if it's equipped when it's the first thing I do in the inventory. I have to close and reopen for it to detect it. My code: public void onInventoryChanged() { for(int i = 0;i < this.getSizeInventory();i++) { if(this.lastSlots[i] != this.slots[i]) { if(this.slots[i] != null && this.slots[i].getItem() instanceof IAccessory) { IAccessory accessory = (IAccessory)this.slots[i].getItem(); accessory.equipped(player); } if(this.lastSlots[i] != null && this.lastSlots[i].getItem() instanceof IAccessory) { IAccessory accessory = (IAccessory)this.lastSlots[i].getItem(); accessory.unequipped(player); } } } this.saveInventoryToNBTTagCompound(player); this.lastSlots = this.slots; } Kain
November 7, 201311 yr Hi I've got a sneaking suspicion that onInventoryChanged is not called for all changes to the inventory. To be honest, I wouldn't worry about your original idea being "inefficient", Java is pretty quick and comparing a few slots for changes takes basically no time at all. I'd suggest you have another go with it because I reckon it should work fine. -TGG
November 7, 201311 yr Author Ok, I've moved the code back into my player tick handler. Currently, it refuses to detect nothing different with the slots. I know it's checking them because of a check I added, but it doesn't detect anything different. http://pastebin.com/fX1yvk0j Kain
November 7, 201311 yr Hi I think this is probably the problem here: this.lastSlots = this.currentSlots; Although it looks like this copies currentSlots into lastSlots, it doesn't. It makes lastSlots refer to the same array as currentSlots does, i.e. they are both the same object. So your comparisons will always be true because you're comparing the same object against itself. You need to copy the elements of the array, eg for (int i = 0;i < 7;i++) { this.lastSlots[i] = this.currentSlots[i]; } or System.arraycopy(this.currentSlots, 0, this.lastSlots, 0, this.lastSlots.length); -TGG
November 8, 201311 yr Author Thanks for all the help, one last problem though. I was testing and saw it earlier and knew the cause, but I had to go do something else. Now I can't figure out why it says that it's equipping and unequipping every tick. package net.gloriarpg.handler; import java.util.EnumSet; import net.gloriarpg.GloriaRPG; import net.gloriarpg.item.IAccessory; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; public class PlayerTickHandler implements ITickHandler { private ItemStack[] currentSlots = new ItemStack[7]; private ItemStack[] lastSlots = new ItemStack[7]; private final EnumSet<TickType> ticksToGet; public PlayerTickHandler(EnumSet<TickType> ticksToGet) { this.ticksToGet = ticksToGet; } @Override public void tickStart(EnumSet<TickType> type, Object... tickData) { playerTick((EntityPlayer) tickData[0]); } @Override public void tickEnd(EnumSet<TickType> type, Object... tickData) { } @Override public EnumSet<TickType> ticks() { return ticksToGet; } @Override public String getLabel() { return "N/A"; } public void playerTick(EntityPlayer player) { NBTTagCompound playerNBT = player.getEntityData(); if(Minecraft.getMinecraft().currentScreen != null) { AccessoriesKeyHandler.pressed = false; } if(AccessoriesKeyHandler.pressed) { player.openGui(GloriaRPG.instance, 2, player.worldObj, (int) player.posX, (int) player.posY, (int) player.posZ); AccessoriesKeyHandler.pressed = false; } if(playerNBT != null) { NBTTagList nbtTag = playerNBT.getTagList("Accessories"); for(int i = 0;i < nbtTag.tagCount();i++) { NBTTagCompound nbt = (NBTTagCompound)nbtTag.tagAt(i); byte slot = nbt.getByte("Slot"); if(slot >= 0 && slot < 7); { ItemStack itemStack = ItemStack.loadItemStackFromNBT(nbt); Item item = itemStack.getItem(); this.currentSlots[i] = itemStack; if(item instanceof IAccessory) { IAccessory accessory = (IAccessory)item; accessory.tick(player); } } } } for(int i = 0;i < 7;i++) { if(this.lastSlots[i] != this.currentSlots[i]) { if(this.currentSlots[i] != null && this.currentSlots[i].getItem() instanceof IAccessory) { IAccessory accessory = (IAccessory)this.currentSlots[i].getItem(); accessory.equipped(player); } if(this.lastSlots[i] != null && this.lastSlots[i].getItem() instanceof IAccessory) { IAccessory accessory = (IAccessory)this.lastSlots[i].getItem(); accessory.unequipped(player); } } } System.arraycopy(this.currentSlots, 0, this.lastSlots, 0, this.lastSlots.length); } } Kain
November 8, 201311 yr Hi I think the problem is the same type as the one we just solved if (this.lastSlots[i] != this.currentSlots[i]) i.e. this statement compares if the two references refer to the same objects, not if the contents of the objects are identical. And since you are filling currentSlots with new ItemStacks every tick.... ItemStack itemStack = ItemStack.loadItemStackFromNBT(nbt); this.currentSlots[i] = itemStack; Two ItemStacks can be compared for equality using ItemStack.areItemStacksEqual (checks if itemID, stackSize, damage, and stackTagCompound are all equal). Or you can just compare this.lastSlots.itemID. Depends on what you mean by "unequip" - eg if your item gets damaged by using it, does this count as an unequip? -TGG
November 8, 201311 yr Author Agghhhhh. Kind of the same problem, but I put it in, it detects equipped, I remove it, nothing. I close and re-open, and it detects nothing. package net.gloriarpg.handler; import java.util.EnumSet; import net.gloriarpg.GloriaRPG; import net.gloriarpg.item.IAccessory; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; public class PlayerTickHandler implements ITickHandler { private ItemStack[] currentSlots = new ItemStack[7]; private ItemStack[] lastSlots = new ItemStack[7]; private final EnumSet<TickType> ticksToGet; public PlayerTickHandler(EnumSet<TickType> ticksToGet) { this.ticksToGet = ticksToGet; } @Override public void tickStart(EnumSet<TickType> type, Object... tickData) { playerTick((EntityPlayer) tickData[0]); } @Override public void tickEnd(EnumSet<TickType> type, Object... tickData) { } @Override public EnumSet<TickType> ticks() { return ticksToGet; } @Override public String getLabel() { return "N/A"; } public void playerTick(EntityPlayer player) { NBTTagCompound playerNBT = player.getEntityData(); if(Minecraft.getMinecraft().currentScreen != null) { AccessoriesKeyHandler.pressed = false; } if(AccessoriesKeyHandler.pressed) { player.openGui(GloriaRPG.instance, 2, player.worldObj, (int) player.posX, (int) player.posY, (int) player.posZ); AccessoriesKeyHandler.pressed = false; } if(playerNBT != null) { NBTTagList nbtTag = playerNBT.getTagList("Accessories"); for(int i = 0;i < nbtTag.tagCount();i++) { NBTTagCompound nbt = (NBTTagCompound)nbtTag.tagAt(i); byte slot = nbt.getByte("Slot"); if(slot >= 0 && slot < 7); { ItemStack itemStack = ItemStack.loadItemStackFromNBT(nbt); Item item = itemStack.getItem(); this.currentSlots[i] = itemStack; if(item instanceof IAccessory) { IAccessory accessory = (IAccessory)item; accessory.tick(player); } } } } for(int i = 0;i < 7;i++) { ItemStack itemStack1 = this.lastSlots[i]; ItemStack itemStack2 = this.currentSlots[i]; if(!ItemStack.areItemStacksEqual(itemStack1, itemStack2)) { if(itemStack2 != null && itemStack2.getItem() instanceof IAccessory) { IAccessory accessory = (IAccessory)this.currentSlots[i].getItem(); accessory.equipped(player); } if(itemStack1 != null && itemStack1.getItem() instanceof IAccessory) { IAccessory accessory = (IAccessory)this.lastSlots[i].getItem(); accessory.unequipped(player); } } } System.arraycopy(this.currentSlots, 0, this.lastSlots, 0, this.lastSlots.length); } } Kain
November 8, 201311 yr Hi Well I'm stumped now. I can't see any problem in the code you've got here. Perhaps if you add a few diagnostic statements it might become clearer, eg see below. If you run it, equip and unequip, then paste the relevant bits of your console output to here, I'll have a look and see if there are any clues... -TGG if(playerNBT != null) { // etc } System.out.print( "lastSlots[0]:" + (this.lastSlots[0] == null) ? "null" : this.lastSlots[0].itemID +", currentSlots[0]:" + (this.currentSlots[0] == null) ? "null" : this.currentSlots[0]); for(int i = 0;i < 7;i++) { ItemStack itemStack1 = this.lastSlots[i]; ItemStack itemStack2 = this.currentSlots[i]; if(!ItemStack.areItemStacksEqual(itemStack1, itemStack2)) { if (i == 0) System.out.print("not equal "); if(itemStack2 != null && itemStack2.getItem() instanceof IAccessory) { if (i == 0) System.out.print(" equip"); IAccessory accessory = (IAccessory)this.currentSlots[i].getItem(); accessory.equipped(player); } if(itemStack1 != null && itemStack1.getItem() instanceof IAccessory) { if (i == 0) System.out.print(" unequip"); IAccessory accessory = (IAccessory)this.lastSlots[i].getItem(); accessory.unequipped(player); } } } System.out.println(" copied"); System.arraycopy(this.currentSlots, 0, this.lastSlots, 0, this.lastSlots.length);
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.