TheMCJavaFre4k Posted February 24, 2014 Author Posted February 24, 2014 How do i check if the packet handler is making the itemstack on the server side?
coolAlias Posted February 24, 2014 Posted February 24, 2014 I'm not sure what you mean... use if (!world.isRemote) { print "we're on the server!" } ? or if (stack != null) { print "we made a stack!" } http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 24, 2014 Author Posted February 24, 2014 I've added this: if(!Minecraft.getMinecraft().theWorld.isRemote){ Â Â Â Â Â Â Â Â System.out.print("On The Server"); Â Â Â Â Â Â Â Â } Â To my makeReplcement Method an it doesn't print anything. - How would i make it so it is running on the server and not the client side. Because I've been trying many things but I'm still having sync issues that creates the item in slot but when i try to take it it disappears(I'm guessing that these are client /server sync issues).
coolAlias Posted February 24, 2014 Posted February 24, 2014 Minecraft.getMinecraft() ALWAYS returns the CLIENT world. Never use that unless you know for a fact that you are on the client side, such as in a gui. Â I see now what you are asking, you're not sure what side you are on when you receive the packet, correct? That's determined by how you send the packet and parsed automatically by your packet handler, so if you send the packet to the server, you know it's received on the server. Â You mentioned you read the packet handling tutorial, but I think you ought to read it again more carefully; the section titled "Sending the Packet" explicitly covers how to send a packet to the client or server. Â Most packets are only used one-way, so you don't have to bother checking which side you are on, but if you are sending the same packet type to both sides at different times, then you can use the Player variable that is passed in to the packet handler to determine what side you are on, the same way you do everywhere else: if (player.worldObj.isRemote) { // you're on the client } else { // if (!player.worldObj.isRemote) <-- notice the "!" there // you're on the server } http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 24, 2014 Author Posted February 24, 2014 Ok - ive had another read over it and seem to have missed out on the: Side side = FMLCommonHandler.instance().getEffectiveSide(); if (side == Side.SERVER) { Â Â Â Â // We are on the server side. Â Â Â Â EntityPlayerMP player = (EntityPlayerMP) playerEntity; } else if (side == Side.CLIENT) { Â Â Â Â EntityClientPlayerMP player = (EntityClientPlayerMP) playerEntity; Â Â Â Â // We are on the client side. } else { Â Â Â Â // We have an errornous state! } . But since this is in a custom methods to create and send the packet i don't have a playerEntity parameter. - Also if i can add this do i use: player.sendQueue.addToSendQueue(packet); or PacketDispatcher.sendPacketToServer(Packet packet); or can i use either. This is just really confusing and i just can't get it to work.
coolAlias Posted February 24, 2014 Posted February 24, 2014 player.sendQueue.addToSendQueue(packet); PacketDispatcher.sendPacketToServer(Packet packet);  Those are functionally equivalent, though I typically use the latter, for no particular reason. One may be more or less efficient than the other, I honestly have no idea, but they either one gets the job done.  If you're using a custom method to send the packet, you need to pass in an EntityPlayer to your method parameters or you have no way of sending the packet -> EXCEPT, you are on the client, right? Remember I told you never to use Minecraft.getMinecraft()? Well, you CAN use it on the client, so if you have no other way of getting a player object to your custom method - really, if you can, just pass a player in - if you have NO other way, then you can use this ON THE CLIENT ONLY (excuse the excessive caps, but people seem to get confused about this):  // this gives you the client side EntityPlayer object // (actually EntityClientPlayerMP, but that can be used just like EntityPlayer)  Minecraft.getMinecraft().thePlayer  Remember, you can only do that on the client side, and it's better to pass in the player to your method if you can from an existing player object.  http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 24, 2014 Author Posted February 24, 2014 so do i need this code at all: Side side = FMLCommonHandler.instance().getEffectiveSide(); if (side == Side.SERVER) { Â Â Â Â // We are on the server side. Â Â Â Â EntityPlayerMP player = (EntityPlayerMP) playerEntity; } else if (side == Side.CLIENT) { Â Â Â Â EntityClientPlayerMP player = (EntityClientPlayerMP) playerEntity; Â Â Â Â // We are on the client side. } else { Â Â Â Â // We have an errornous state! } Â And i if i don't use that i can just use Minecraft.getMinecraft().thePlayer.sendQueue.addToSendQueue(packet) because its the guy class which is on the client side?
coolAlias Posted February 24, 2014 Posted February 24, 2014 Right, you don't need all that code there unless you're trying to send it to different sides and you don't have anything more sophisticated set up to handle it for you. Â Instead of that super long bit with Minecraft.getMinecraft()..., why not just use "PacketDispatcher.sendPacketToServer(Packet packet);" ? Â It's much shorter when you don't have a player instance readily available. http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 24, 2014 Author Posted February 24, 2014 Ok I've got the other one now but get and error if i have PacketDispatcher.sendPacketToServer(Packet packet) with the two packets but if i just have one it works like the others where i cannot actually pick up the item
TheMCJavaFre4k Posted February 25, 2014 Author Posted February 25, 2014 i don't think that the packet handler is actually creating the item on the server side even though it is done in my packet handler
coolAlias Posted February 25, 2014 Posted February 25, 2014 You need to do something like this: // notice you have a Player object in the parameters no matter what side you are on // that's your ticket to the world... public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) { // packet received // make sure it's the packet you want // read in your data: item id, tile entity x, y, z TileEntity te = player.worldObj.getTileEntity(x, y, z); if (te instanceof YourTileEntity) { ((YourTileEntity) te).setInventorySlotContents(0, new ItemStack(itemID,1,0)); } } If you are still having problems after this, please post your packet handler code, and the code where you create and send the packet. http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 25, 2014 Author Posted February 25, 2014 You need to do something like this: // notice you have a Player object in the parameters no matter what side you are on // that's your ticket to the world... public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) { // packet received // make sure it's the packet you want // read in your data: item id, tile entity x, y, z TileEntity te = player.worldObj.getTileEntity(x, y, z); if (te instanceof YourTileEntity) { ((YourTileEntity) te).setInventorySlotContents(0, new ItemStack(itemID,1,0)); } } If you are still having problems after this, please post your packet handler code, and the code where you create and send the packet. Â Ok i can see where i am probably going wrong. Where you have the Player player in the method params - when i try to access the world object it only comes up with basic class things like" wait(), equals(), getClass(), notify() etc...; so instead I've been using the Minecraft.getMinecraft.theWorld but that probably gets it on the client? Â This is my code: package net.PartyMod.Common; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import net.PartyMod.GUI.TileEntityRecordingUnit; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.INetworkManager; import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.tileentity.TileEntity; import cpw.mods.fml.common.network.IPacketHandler; import cpw.mods.fml.common.network.Player; public class PacketHandler implements IPacketHandler { public int number; public int PosX, PosY, PosZ; TileEntityReplacer te = new TileEntityReplacer(); @Override public void onPacketData(INetworkManager manager, Packet250CustomPayload par1, Player par2) { if (par1.channel.equals("UniqueModID")) { this.handlePacketData(par1); } } private void handlePacketData(Packet250CustomPayload par1) { DataInputStream In = new DataInputStream(new ByteArrayInputStream(par1.data)); try { PosX = In.readInt(); PosY = In.readInt(); PosZ = In.readInt(); number = In.readInt(); } catch (IOException e) { e.printStackTrace(); return; } TileEntity tile = Minecraft.getMinecraft().theWorld.getBlockTileEntity(PosX, PosY, PosZ); ItemStack e = ((TileEntityReplacer) tile).getStackInSlot(0);Â if (tile instanceof TileEntityReplacer) { ((TileEntityReplacer) tile).setInventorySlotContents(0, new ItemStack(Item.appleGold, 1, 0));;Â Â Â ((TileEntityReplacerUnit) tile).onInventoryChanged(); } } } Â The number that is received is going to be used later to determine which button was pressed and what item to give. Â And this is how i create and send the packet: public void constructPacket(TileEntity te, int Number){ int PosX = te.xCoord; int PosY = te.yCoord; int PosZ = te.zCoord; ByteArrayOutputStream bos = new ByteArrayOutputStream(; Â Â Â Â DataOutputStream os = new DataOutputStream(bos); Â Â Â Â try { Â Â Â Â os.writeInt(PosX); Â Â Â Â os.writeInt(PosY); Â Â Â Â os.writeInt(PosZ); Â Â Â Â Â Â Â Â os.writeInt(buttonnumber); Â Â Â Â } catch (Exception ex) { Â Â Â Â Â Â Â Â ex.printStackTrace(); Â Â Â Â } Â Â Â Â Â Â Â Â Packet250CustomPayload packet = new Packet250CustomPayload(); Â Â Â Â packet.channel = "UniqueModID"; Â Â Â Â packet.data = bos.toByteArray(); Â Â Â Â packet.length = bos.size(); Â Â Â Â Â Â Â Â PacketDispatcher.sendPacketToServer(packet); } Â If i am correct and the problem is with getting the world object thru Minecraft.getMinecraft().theWorld Then how would i get the world if using the Player param doesn't work?
coolAlias Posted February 25, 2014 Posted February 25, 2014 This is super basic Java - you have to pass the parameter yourself. Look at your method: // you are passing the packet "par1", why not pass the player too? this.handlePacketData(par1); // here's your method, just add ", EntityPlayer player" inside it private void handlePacketData(Packet250CustomPayload par1) // now those two lines look like this // (after renaming your parameters to meaningful names, which you should always do) handlePacketData(packet, (EntityPlayer) player); private void handlePacketData(Packet250CustomPayload packet, EntityPlayer player) { // voila, you now have access to the server side player and therefore world objects TileEntity te = player.worldObj.getBlockTileEntity(x, y, z); // etc. } Â Please take some time, head over to Oracle's website, the New Boston, or wherever, and brush up on / learn more about Java. You will save yourself a ton of time and frustration that way. http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 25, 2014 Author Posted February 25, 2014 Yea - its just something I've forgotten - Ive got around 2 and a half years of java experience under my belt but haven't been doing it much lately  Ive just tried that and now the item doesn't even appear at all  her is my code now: package net.PartyMod.Common; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import net.PartyMod.GUI.TileEntityRecordingUnit; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.INetworkManager; import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.tileentity.TileEntity; import cpw.mods.fml.common.network.IPacketHandler; import cpw.mods.fml.common.network.Player; public class PacketHandler implements IPacketHandler { public int discNo; public int PosX, PosY, PosZ; TileEntityRecordingUnit te = new TileEntityRecordingUnit(); @Override public void onPacketData(INetworkManager manager, Packet250CustomPayload par1, Player par2) { if (par1.channel.equals("PartyMod1")) { this.handlePacketData(par1, (EntityPlayer) par2); } } private void handlePacketData(Packet250CustomPayload par1, EntityPlayer player) { DataInputStream In = new DataInputStream(new ByteArrayInputStream(par1.data)); try { PosX = In.readInt(); PosY = In.readInt(); PosZ = In.readInt(); discNo = In.readInt(); } catch (IOException e) { e.printStackTrace(); return; } TileEntity tile = player.worldObj.getBlockTileEntity(PosX, PosY, PosZ); ItemStack e = ((TileEntityRecordingUnit) tile).getStackInSlot(0); System.out.print("Step 1"); if (tile instanceof TileEntityRecordingUnit) { System.out.print("Step 2"); ((TileEntityRecordingUnit) tile).setInventorySlotContents(0, new ItemStack(Item.appleGold, 1, 0));;   ((TileEntityRecordingUnit) tile).onInventoryChanged(); } } }  Ive renamed the tile entity to my decided name of the block
coolAlias Posted February 25, 2014 Posted February 25, 2014 What about the code where you send the packet? Not just the part where you write the packet the entire code, because when I see stuff like "TileEntityRecordingUnit te = new TileEntityRecordingUnit();" in your packet handler, it really makes me wonder. http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 25, 2014 Author Posted February 25, 2014 This is my whole Gui class in which the packet is sent: package net.PartyMod.GUI; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import net.PartyMod.Common.Common; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; import org.lwjgl.opengl.GL11; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.network.PacketDispatcher; import cpw.mods.fml.relauncher.Side; public class GuiRecordingUnit extends GuiContainer { public GuiTextField text; public boolean search = false; public int songCount = 0; public int discNo = 0; public int buttonPage = 0; public String searched = ""; protected TileEntityRecordingUnit tile; public GuiRecordingUnit (InventoryPlayer inventoryPlayer, TileEntityRecordingUnit tileEntity) { super(new ContainerRecordingUnit(inventoryPlayer, tileEntity)); tile = tileEntity; } @Override public void initGui(){ super.initGui(); Minecraft.getMinecraft().thePlayer.addChatMessage("Thing " + buttonPage); this.buttonList.clear(); for(int x = 0; x < 100; x++){ this.buttonList.clear(); if(buttonPage == 0){ for(int y = 0; y < 10; y++){ this.buttonList.add(new GuiButton(2 + y, guiLeft - 120 , guiTop + (y*18), 120, 17, Common.songs[y])); } } if(buttonPage == 1){ for(int y = 0; y < 10; y++){ this.buttonList.add(new GuiButton(10 + 2 + y, guiLeft - 120 , guiTop + (y*18), 120, 17, Common.songs[10 + y])); } } if(buttonPage == 2){ for(int y = 0; y < 10; y++){ this.buttonList.add(new GuiButton(20 + 2 + y, guiLeft - 120 , guiTop + (y*18), 120, 17, Common.songs[20 + y])); } } if(buttonPage == 3){ for(int y = 0; y < 10; y++){ this.buttonList.add(new GuiButton(30 + 2 + y, guiLeft - 120 , guiTop + (y*18), 120, 17, Common.songs[30 + y])); } } } this.buttonList.add(new GuiButton(0, guiLeft-120, guiTop - 21, 20, 20, "<")); this.buttonList.add(new GuiButton(1, guiLeft-20, guiTop - 21, 20, 20, ">")); text = new GuiTextField(fontRenderer, guiLeft + xSize + 14, guiTop + 15, 100, 13); text.setFocused(false); } public void keyTyped(char c, int i){ super.keyTyped(c, i); text.textboxKeyTyped(c, i); if(search = true){ searched = text.getText().toString(); } } public void mouseClicked(int i, int j, int k){ super.mouseClicked(i, j, k); text.mouseClicked(i, j, k); search = true; } public void actionPerformed(GuiButton b){ EntityPlayerMP playerEntity; switch(b.id){ case 0: if(buttonPage != 0){ buttonPage--; this.buttonList.clear(); this.initGui(); break; } case 1: if(buttonPage !=10){ buttonPage++; this.buttonList.clear(); this.initGui(); break; } } if(buttonPage == 0){ switch(b.id){ case 2: discNo = 1; this.constructPacket(tile, discNo); break; case 3: discNo = 2; break; case 4: break; case 5: break; case 6: break; case 7: break; case 8: break; case 9: break; case 10: break; case 11: break; case 12: break; } } Â Â Â Â Â Â Â Â Â Â Â Â } public void constructPacket(TileEntity te, int discNumber){ int PosX = te.xCoord; int PosY = te.yCoord; int PosZ = te.zCoord; ByteArrayOutputStream bos = new ByteArrayOutputStream(; Â Â Â Â DataOutputStream os = new DataOutputStream(bos); Â Â Â Â try { Â Â Â Â os.writeInt(PosX); Â Â Â Â os.writeInt(PosY); Â Â Â Â os.writeInt(PosZ); Â Â Â Â Â Â Â Â os.writeInt(discNo); Â Â Â Â } catch (Exception ex) { Â Â Â Â Â Â Â Â ex.printStackTrace(); Â Â Â Â } Â Â Â Â Â Â Â Â Packet250CustomPayload packet = new Packet250CustomPayload(); Â Â Â Â packet.channel = "PartyMod1"; Â Â Â Â packet.data = bos.toByteArray(); Â Â Â Â packet.length = bos.size(); Â Â Â Â Â Â Â Â PacketDispatcher.sendPacketToServer(packet); } @Override protected void drawGuiContainerForegroundLayer(int param1, int param2) { fontRenderer.drawString("Search For Songs", 195, 4, 1111111); fontRenderer.drawString("Recording Unit", 8, 6, 4210752); fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, ySize - 96 + 2, 4210752); } @Override protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) { ResourceLocation textureFile = new ResourceLocation(Common.modid.toLowerCase(), "textures/gui/recordingunit.png"); Minecraft.getMinecraft().getTextureManager().bindTexture(textureFile); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); int x = (this.width - xSize) /2; int y = (this.height - ySize) /2; this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize); text.drawTextBox(); } } Â If you need more just let me know
coolAlias Posted February 25, 2014 Posted February 25, 2014 Hm, well that looks okay actually. In your packet handler, you should remove the "public int posX, posY, posZ" fields and just use local integers in the method itself, as you don't really need them as class fields and certainly not public; it would be really bad if while you were handling the packet somewhere else in your code changed the values. Â Anyway, it looks like your packets should work, so the problem is likely to be in your TileEntity class. Mind posting that? http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 25, 2014 Author Posted February 25, 2014 ok - I've changed the integers even though i checked that they weren't being changed thru system prints  Heres the tile entity code - I haven't changed this much at all really: package net.PartyMod.GUI; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.tileentity.TileEntity; public class TileEntityRecordingUnit extends TileEntity implements IInventory { private ItemStack[] inv; public TileEntityRecordingUnit() { inv = new ItemStack[1]; } @Override public void closeChest() {} @Override public ItemStack decrStackSize(int i, int j) { ItemStack stack = getStackInSlot(i); if (stack != null) { if (stack.stackSize <= j) { setInventorySlotContents(i, null); } else { stack = stack.splitStack(j); if (stack.stackSize == 0) { setInventorySlotContents(i,null); } } } return stack; } @Override public String getInvName() { return "Recording Unit"; } @Override public int getInventoryStackLimit() { return 1; } @Override public int getSizeInventory() { return inv.length; } @Override public ItemStack getStackInSlot(int i) { return inv[i]; } @Override public ItemStack getStackInSlotOnClosing(int i) { ItemStack stack = getStackInSlot(i); if (stack != null) { setInventorySlotContents(i, null); } return stack; } @Override public boolean isInvNameLocalized() { // TODO Auto-generated method stub return false; } @Override public boolean isItemValidForSlot(int i, ItemStack itemstack) { // TODO Auto-generated method stub return false; } @Override public boolean isUseableByPlayer(EntityPlayer entityplayer) { return worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this && entityplayer.getDistanceSq(xCoord+0.5, yCoord+0.5, zCoord+0.5) < 64; } @Override public void openChest() {} @Override public void setInventorySlotContents(int i, ItemStack itemstack) { inv[i] = itemstack; if (itemstack != null && itemstack.stackSize > getInventoryStackLimit()) { itemstack.stackSize = getInventoryStackLimit(); } } @Override public void readFromNBT(NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); NBTTagList tagList = tagCompound.getTagList("Inventory"); for (int i = 0; i < tagList.tagCount(); i++) { NBTTagCompound tag = (NBTTagCompound) tagList.tagAt(i); byte slot = tag.getByte("Slot"); if (slot >= 0 && slot < inv.length) { inv[slot] = ItemStack.loadItemStackFromNBT(tag); } } } @Override public void writeToNBT(NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); NBTTagList itemList = new NBTTagList(); for (int i = 0; i < inv.length; i++) { ItemStack stack = inv[i]; if (stack != null) { NBTTagCompound tag = new NBTTagCompound(); tag.setByte("Slot", (byte)i); stack.writeToNBT(tag); itemList.appendTag(tag); } } tagCompound.setTag("Inventory", itemList); } } Â
coolAlias Posted February 25, 2014 Posted February 25, 2014 Alright, that looks fine, too. If you put a println in your setInventorySlotContents method and print the stack, I'm sure you'll see it's correct. What happens if you press your button, close the inventory, and open it back up again? Is there an apple inside? Whether or not there is, it sounds like your problem is going to be in the Container class - are you using a Container? Â You may want to change the following to return true, even though you are not using it directly: @Override public boolean isItemValidForSlot(int i, ItemStack itemstack) { // TODO Auto-generated method stub return false; } http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 25, 2014 Author Posted February 25, 2014 Ill add the system prints in and get back to you but ill post my container and Gui handler:  Container: package net.PartyMod.GUI; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; public class ContainerRecordingUnit extends Container {     protected TileEntityRecordingUnit tileEntity;     public ContainerRecordingUnit (InventoryPlayer inventoryPlayer, TileEntityRecordingUnit te){         tileEntity = te;                 addSlotToContainer(new Slot(tileEntity, 0, 44 , 35));         bindPlayerInventory(inventoryPlayer);     }     @Override     public boolean canInteractWith(EntityPlayer player) {         return tileEntity.isUseableByPlayer(player);     }     protected void bindPlayerInventory(InventoryPlayer inventoryPlayer) {         for (int i = 0; i < 3; i++) {             for (int j = 0; j < 9; j++) {                 addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9,                         8 + j * 18, 84 + i * 18));             }         }         for (int i = 0; i < 9; i++) {             addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 142));         }     }     @Override     public ItemStack transferStackInSlot(EntityPlayer player, int slot) {         ItemStack stack = null;         Slot slotObject = (Slot) inventorySlots.get(slot);         if (slotObject != null && slotObject.getHasStack()) {             ItemStack stackInSlot = slotObject.getStack();             stack = stackInSlot.copy();             if (slot < 9) {                 if (!this.mergeItemStack(stackInSlot, 0, 35, true)) {                     return null;                 }             }             //places it into the tileEntity is possible since its in the player inventory             else if (!this.mergeItemStack(stackInSlot, 0, 9, false)) {                 return null;             }             if (stackInSlot.stackSize == 0) {                 slotObject.putStack(null);             } else {                 slotObject.onSlotChanged();             }             if (stackInSlot.stackSize == stack.stackSize) {                 return null;             }             slotObject.onPickupFromSlot(player, stackInSlot);         }         return stack;     }    }  and my Gui handler:  package net.PartyMod.GUI; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import cpw.mods.fml.common.network.IGuiHandler; public class GuiHandler implements IGuiHandler {     //returns an instance of the Container you made earlier     @Override     public Object getServerGuiElement(int id, EntityPlayer player, World world,             int x, int y, int z) {                     TileEntity tileEntity = world.getBlockTileEntity(x, y, z);         if(tileEntity instanceof TileEntityRecordingUnit){             return new ContainerRecordingUnit(player.inventory, (TileEntityRecordingUnit) tileEntity);         }         return null;                     }     //returns an instance of the Gui you made earlier     @Override     public Object getClientGuiElement(int id, EntityPlayer player, World world,             int x, int y, int z) {                TileEntity tileEntity = world.getBlockTileEntity(x, y, z);         if(tileEntity instanceof TileEntityRecordingUnit){             return new GuiRecordingUnit(player.inventory, (TileEntityRecordingUnit) tileEntity);         }         return null;     } }  Thanks
coolAlias Posted February 25, 2014 Posted February 25, 2014 That's all looking like it should as well. What happens if you increase the inventory stack max size from 1 to 64? Vanilla's slotClick method is a bit broken when it comes to stack sizes of 1. Here's a rewrite of that method that I wrote for my own use to stop the inventory from having weird ghost stacks and such behavior: Â Â /** * Vanilla method fails to account for stacks of size one, as well as whether stack * is valid for slot */ @Override protected boolean mergeItemStack(ItemStack itemstack, int start, int end, boolean backwards) { boolean flag1 = false; int k = start; Slot slot; ItemStack itemstack1; if (backwards) { k = end - 1; } if (itemstack.isStackable()) { while (itemstack.stackSize > 0 && (!backwards && k < end || backwards && k >= start)) { slot = (Slot) inventorySlots.get(k); itemstack1 = slot.getStack(); if (!slot.isItemValid(itemstack)) { continue; } if (itemstack1 != null && itemstack1.itemID == itemstack.itemID && (!itemstack.getHasSubtypes() || itemstack.getItemDamage() == itemstack1.getItemDamage()) && ItemStack.areItemStackTagsEqual(itemstack, itemstack1)) { int l = itemstack1.stackSize + itemstack.stackSize; if (l <= itemstack.getMaxStackSize() && l <= slot.getSlotStackLimit()) { itemstack.stackSize = 0; itemstack1.stackSize = l; pedestal.onInventoryChanged(); flag1 = true; } else if (itemstack1.stackSize < itemstack.getMaxStackSize() && l < slot.getSlotStackLimit()) { itemstack.stackSize -= itemstack.getMaxStackSize() - itemstack1.stackSize; itemstack1.stackSize = itemstack.getMaxStackSize(); pedestal.onInventoryChanged(); flag1 = true; } } if (backwards) { --k; } else { ++k; } } } if (itemstack.stackSize > 0) { if (backwards) { k = end - 1; } else { k = start; } while (!backwards && k < end || backwards && k >= start) { slot = (Slot) inventorySlots.get(k); itemstack1 = slot.getStack(); if (!slot.isItemValid(itemstack)) { continue; } if (itemstack1 == null) { int l = itemstack.stackSize; if (l <= slot.getSlotStackLimit()) { slot.putStack(itemstack.copy()); itemstack.stackSize = 0; pedestal.onInventoryChanged(); flag1 = true; break; } else { putStackInSlot(k, new ItemStack(itemstack.getItem(), slot.getSlotStackLimit(), itemstack.getItemDamage())); itemstack.stackSize -= slot.getSlotStackLimit(); pedestal.onInventoryChanged(); flag1 = true; } } if (backwards) { --k; } else { ++k; } } } return flag1; } Â That goes in the Container class. Who knows, maybe that's your issue? http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 25, 2014 Author Posted February 25, 2014 Ive just checked if the item appears if the Gui is closed and reopened and it does, And its real item. Is that what the method you wrote stops?
coolAlias Posted February 25, 2014 Posted February 25, 2014 Nope, don't think so, but that means the item IS getting set, but the container is not updating because you aren't using the Container to set the contents, you are doing it manually. This means you must manually tell the client about it as well - try overriding the getDescriptionPacket method in tile entity and you may get lucky; if not, you'll have to send a packet back to the client yourself (you can use the exact same packet) to have it update the contents on the client side, or (don't kill me diesieben!) you could 'set' the contents directly from the gui when you send the packet, as the contents will update automatically anyway the next time you open it. Â That's not ideal, though, as if other players are using your container, they will never know about the contents you set, so if you care about other players seeing what you just put in your tile entity, you'll have to use PacketDispatcher.sendToAllAround with a range of about 64 (squared, so 8 not squared) to make sure anyone else that might be using your inventory are made aware of the changes. That's sent from the server, of course, to the player clients. http://i.imgur.com/NdrFdld.png[/img]
TheMCJavaFre4k Posted February 25, 2014 Author Posted February 25, 2014 Considering that its not a container that is Meant to store things in, Ill get by just setting the Contents in the guy swell. If i get the time i can always add the code to send to the client as well. Also one quick thing (as its just probably using the method already built in I don't think i should open another topic for this) How would i check the slot for a certain item, Would i just use : @Override public ItemStack getStackInSlot(int i) { return inv[i]; } Â or do i do something like: ItemStack e = ((TileEntityRecordingUnit) tile).getStackInSlot(0);Â if(e == new ItemStack(Item.appleGold, 1, 0)){ } Â If you can't help me with this its fine, You've helped me so much already, I can't thank you enough Thanks Soooooooo much for your help.
coolAlias Posted February 25, 2014 Posted February 25, 2014 You're welcome, and dear god no. Comparing with the == operator against a new ItemStack will always return false, because you are comparing identity as in the memory location, but how can a reference to an old location be identical to a new location? Â Get the stack like you were, using ItemStack stack = ((YourInventory) te).getStackInSlot(i), then either compare the items in it OR compare to a new ItemStack using the stack1.isItemEqual(stack2): ItemStack stack2 = new ItemStack(Item.whateverYouWantToCheckFor); 1. if (stack1.getItem() == stack2.getItem()) // you'll want to null check for stack1 if it is capable of being null 2. if (stack1.isItemEqual(stack2)) // again, null check 3. if (ItemStack.areItemStacksEqual(stack1, stack2)) // null check is inherent in the method Of course, in case number 1, you really don't need to create a new itemstack at all, just compare the items directly: if (stack != null && stack.getItem() == Item.whateverYouWant) http://i.imgur.com/NdrFdld.png[/img]
Recommended Posts