Posted August 28, 201213 yr So I'm trying to update my mods to 1.3.2. I have everything working but one single bug: whenever I try to put a stack of items inside a custom inventory, the stack is duplicated, and whenever I try to remove it, it totally disappears. Example: I have a stack of 2, I try to place it in a slot in my custom inventory and the stack size is now 4, I remove it and it disappears. This is very strange as the same code worked in 1.2.5. This is my code: InventoryResearch: package jimmynator.researchcraft; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; import cpw.mods.fml.client.FMLClientHandler; import net.minecraft.client.Minecraft; import net.minecraft.src.Block; import net.minecraft.src.CraftingManager; import net.minecraft.src.EntityPlayer; import net.minecraft.src.IInvBasic; import net.minecraft.src.IInventory; import net.minecraft.src.IRecipe; import net.minecraft.src.InventoryBasic; import net.minecraft.src.InventoryPlayer; import net.minecraft.src.ItemStack; import net.minecraft.src.NBTTagCompound; import net.minecraft.src.NBTTagList; import net.minecraft.src.StringTranslate; public class InventoryResearch implements IInventory { public ItemStack[] itemStacks = new ItemStack[9]; public InventoryPlayer inventoryPlayer; public GuiResearchButton researchButton; public int researchProgress = 0; public boolean isResearching = false; public String recipeToShow = ""; public InventoryResearch(InventoryPlayer inventoryplayer) { this.inventoryPlayer = inventoryplayer; } public void setIsResearching(GuiResearchButton guibutton, boolean flag) { if (flag) { researchProgress = 0; recipeToShow = ""; } if (guibutton != null) { researchButton = guibutton; } isResearching = !isResearching; researchButton.enabled = !isResearching; } public void updateInventory() { if (isResearching) { if (researchProgress < 12000) { if (inventoryPlayer.player.getFoodStats().getFoodLevel() - 10 > 0) { researchProgress += (inventoryPlayer.player.getFoodStats().getFoodLevel() - 10)*10; inventoryPlayer.player.addExhaustion(0.0025F); } } else { Random rand = inventoryPlayer.player.worldObj.rand; researchProgress = 12000; List recipelist = new ArrayList(); recipelist.add(10); List recipes = CraftingManager.getInstance().getRecipeList(); for (int index = 0; index < recipes.size(); index++) { String recipe = ResearchCraft.dataHandler.getRecipeString((IRecipe)recipes.get(index)); if (recipe == null) { continue; } ItemStack[] stacks = ResearchCraft.dataHandler.getStacksFromString(recipe); int itemok = 0; int size = 0; for (int i = 1; i < stacks.length; i++) { if (stacks[i] != null) { size++; for (int j = 36; j < 36 + getSizeInventory(); j++) { if (getStackInSlot(j) != null && stacks[i].itemID == getStackInSlot(j).itemID) { if (stacks[i].itemID < Block.blocksList.length || !(stacks[i].isItemStackDamageable())) { if (stacks[i].getItemDamage() != -1) { if (stacks[i].getItemDamage() == getStackInSlot(j).getItemDamage()) { itemok++; break; } } else { itemok++; break; } } else { itemok++; break; } } } } else { itemok++; } } if (itemok == stacks.length - 1) { if (!ResearchCraft.dataHandler.getIsResearched(recipe, inventoryPlayer.player)) { if (recipe.contains("#@58:0") || (recipe.contains("#@54:0") && ResearchCraft.dataHandler.getIsResearched("#@58:0", inventoryPlayer.player)) || (recipe.contains("#@61:0") && ResearchCraft.dataHandler.getIsResearched("#@58:0", inventoryPlayer.player)) || (recipe.contains("#@355:0") && ResearchCraft.dataHandler.getIsResearched("#@58:0", inventoryPlayer.player))) { recipelist = new ArrayList(); recipelist.add(size); recipelist.add(recipe); break; } else if (size < (Integer) recipelist.get(0)) { recipelist = new ArrayList(); recipelist.add(size); recipelist.add(recipe); } else if (size == (Integer) recipelist.get(0)) { recipelist.add(recipe); } } } } if (recipelist.size() > 1) { if (rand.nextBoolean()) { if (!ResearchCraft.dataHandler.getPlayerString(inventoryPlayer.player).contains("#")) { inventoryPlayer.player.addStat(ResearchCraft.instance.achievements[0], 1); } recipeToShow = (String) recipelist.get(rand.nextInt(recipelist.size() - 1) + 1); if (!ResearchCraft.dataHandler.getPlayerString(inventoryPlayer.player).contains(recipeToShow)) { ResearchCraft.dataHandler.setPlayerString(inventoryPlayer.player, ResearchCraft.dataHandler.getPlayerString(inventoryPlayer.player).concat(recipeToShow)); PacketHandler.sendRecipeResearch(recipeToShow); } setIsResearching(researchButton, false); ItemStack stack = ResearchCraft.dataHandler.getStacksFromString(recipeToShow)[0]; Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(stack.getItem().getItemDisplayName(stack) + ". " + StringTranslate.getInstance().translateKey("gui.yes") + "!"); } else { for (int i = 36; i < 36 + getSizeInventory(); i++) { if (getStackInSlot(i) != null) { if (rand.nextBoolean()) { if (getStackInSlot(i).stackSize > 1) { getStackInSlot(i).stackSize -= 1; setInventorySlotContents(i, getStackInSlot(i)); } else { setInventorySlotContents(i, null); } PacketHandler.sendReduceResearch(i); } } } if (isResearching) { setIsResearching(researchButton, false); setIsResearching(researchButton, true); } else { setIsResearching(researchButton, true); } } } else { for (int i = 36; i < 36 + getSizeInventory(); i++) { if (getStackInSlot(i) != null) { if (rand.nextBoolean()) { if (getStackInSlot(i).stackSize > 1) { getStackInSlot(i).stackSize -= 1; setInventorySlotContents(i, getStackInSlot(i)); } else { setInventorySlotContents(i, null); } PacketHandler.sendReduceResearch(i); } } } if (isResearching) { setIsResearching(researchButton, true); Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(StringTranslate.getInstance().translateKey("potion.prefix.uninteresting") + "..."); } } } } } public int getResearchProgressScaled(int par1) { return (int) (par1 * (researchProgress / 12000F)); } @Override public int getSizeInventory() { return 9; } @Override public ItemStack getStackInSlot(int var1) { return itemStacks[var1 - 36]; } @Override public ItemStack decrStackSize(int var1, int var2) { System.out.println("lol2? " + var1 + " " + var2); if (this.itemStacks[var1 - 36] != null) { ItemStack var3; if (this.itemStacks[var1 - 36].stackSize <= var2) { var3 = this.itemStacks[var1 - 36]; this.itemStacks[var1 - 36] = null; this.onInventoryChanged(); return var3; } else { var3 = this.itemStacks[var1 - 36].splitStack(var2); if (this.itemStacks[var1 - 36].stackSize == 0) { this.itemStacks[var1 - 36] = null; } this.onInventoryChanged(); return var3; } } else { return null; } } @Override public ItemStack getStackInSlotOnClosing(int var1) { return null; } @Override public void setInventorySlotContents(int var1, ItemStack var2) { System.out.println("lol? " + var1 + " " + var2); this.itemStacks[var1 - 36] = var2; this.onInventoryChanged(); } @Override public String getInvName() { return "Research Inventory"; } @Override public int getInventoryStackLimit() { return 64; } @Override public void onInventoryChanged() {} @Override public boolean isUseableByPlayer(EntityPlayer var1) { return this.inventoryPlayer.player.isDead ? false : var1.getDistanceSqToEntity(this.inventoryPlayer.player) <= 64.0D; } @Override public void openChest() {} @Override public void closeChest() {} } ContainerResearch: package jimmynator.researchcraft; import net.minecraft.src.Container; import net.minecraft.src.EntityPlayer; import net.minecraft.src.IInventory; import net.minecraft.src.InventoryPlayer; import net.minecraft.src.ItemStack; import net.minecraft.src.Slot; public class ContainerResearch extends Container { public IInventory researchInventory; public ContainerResearch(InventoryPlayer inventoryplayer, InventoryResearch inventoryresearch) { researchInventory = inventoryresearch; int var3; int var4; this.addSlotToContainer(new Slot(inventoryresearch, 36, 6, 16)); this.addSlotToContainer(new Slot(inventoryresearch, 37, 27, 6)); this.addSlotToContainer(new Slot(inventoryresearch, 38, 50, ); this.addSlotToContainer(new Slot(inventoryresearch, 39, 11, 38)); this.addSlotToContainer(new Slot(inventoryresearch, 40, 34, 30)); this.addSlotToContainer(new Slot(inventoryresearch, 41, 59, 35)); this.addSlotToContainer(new Slot(inventoryresearch, 42, 13, 60)); this.addSlotToContainer(new Slot(inventoryresearch, 43, 32, 53)); this.addSlotToContainer(new Slot(inventoryresearch, 44, 53, 61)); for (var3 = 0; var3 < 3; ++var3) { for (var4 = 0; var4 < 9; ++var4) { this.addSlotToContainer(new Slot(inventoryplayer, var4 + (var3 + 1) * 9, 8 + var4 * 18, 84 + var3 * 18)); } } for (var3 = 0; var3 < 9; ++var3) { this.addSlotToContainer(new Slot(inventoryplayer, var3, 8 + var3 * 18, 142)); } } @Override public boolean canInteractWith(EntityPlayer var1) { return true; } @Override public ItemStack transferStackInSlot(int par1) { ItemStack var2 = null; Slot var3 = (Slot)this.inventorySlots.get(par1); if (var3 != null && var3.getHasStack()) { ItemStack var4 = var3.getStack(); var2 = var4.copy(); if (par1 == 0) { if (!this.mergeItemStack(var4, 9, 45, true)) { return null; } var3.onSlotChange(var4, var2); } else if (par1 >= 9 && par1 < 36) { if (!this.mergeItemStack(var4, 36, 45, false)) { return null; } } else if (par1 >= 36 && par1 < 45) { if (!this.mergeItemStack(var4, 9, 36, false)) { return null; } } else if (!this.mergeItemStack(var4, 9, 45, false)) { return null; } if (var4.stackSize == 0) { var3.putStack((ItemStack)null); } else { var3.onSlotChanged(); } if (var4.stackSize == var2.stackSize) { return null; } var3.onPickupFromSlot(var4); } return var2; } } GuiResearch (only client side): package jimmynator.researchcraft; import net.minecraft.src.EntityPlayer; import net.minecraft.src.GuiButton; import net.minecraft.src.GuiContainer; import net.minecraft.src.InventoryPlayer; import net.minecraft.src.ItemStack; import net.minecraft.src.OpenGlHelper; import net.minecraft.src.RenderHelper; import net.minecraft.src.ScaledResolution; import net.minecraft.src.Slot; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; public class GuiResearch extends GuiContainer { private static ContainerResearch container = null; public GuiResearchButton startResearch; public InventoryPlayer inventoryPlayer; public InventoryResearch inventoryResearch; public GuiResearch(EntityPlayer par1EntityPlayer) { super(new ContainerResearch(par1EntityPlayer.inventory, ResearchCraft.dataHandler.getInventoryResearch(par1EntityPlayer))); inventoryPlayer = par1EntityPlayer.inventory; inventoryResearch = ResearchCraft.dataHandler.getInventoryResearch(par1EntityPlayer); } @Override public void initGui() { super.initGui(); guiLeft = (width - xSize) / 2; guiTop = (height - ySize) / 2; controlList.clear(); startResearch = new GuiResearchButton(0, guiLeft + 87, guiTop + 61, 18, 18, ""); inventoryResearch.setIsResearching(startResearch, false); inventoryResearch.setIsResearching(startResearch, false); controlList.add(startResearch); } @Override protected void actionPerformed(GuiButton guibutton) { if (guibutton.id == 0) { inventoryResearch.setIsResearching((GuiResearchButton) guibutton, true); } } @Override protected void drawGuiContainerForegroundLayer() { this.fontRenderer.drawString("Research", 118, 68, 4210752); } @Override protected void drawGuiContainerBackgroundLayer(float f, int i, int j) { int r = mc.renderEngine.getTexture("/textures/researchcraft_research.png"); GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.5F); mc.renderEngine.bindTexture(r); int w = (width - xSize) / 2; int h = (height - ySize) / 2; //GUI drawTexturedModalRect(w, h, 0, 0, xSize, ySize); //Bulb int scaledProgress = inventoryResearch.getResearchProgressScaled(31); drawTexturedModalRect(w + 86, h + 27 + (31 - scaledProgress), 176, 0 + (31 - scaledProgress), 20, scaledProgress); //Button if (startResearch.drawButton) { ScaledResolution var13 = new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight); int var14 = var13.getScaledWidth(); int var15 = var13.getScaledHeight(); int var16 = Mouse.getX() * var14 / mc.displayWidth; int var17 = var15 - Mouse.getY() * var15 / mc.displayHeight - 1; boolean var5 = var16 >= startResearch.xPosition && var17 >= startResearch.yPosition && var16 < startResearch.xPosition + startResearch.width && var17 < startResearch.yPosition + startResearch.height; int var6 = startResearch.getHoverState(var5); drawTexturedModalRect(w + 87, h + 61, 176, 32 + var6 * 18, startResearch.width, startResearch.height); startResearch.mouseDragged(mc, var16, var17); } //Research recipe if (inventoryResearch.researchProgress >= 12000 && inventoryResearch.recipeToShow != "") { ItemStack[] stacks = ResearchCraft.dataHandler.getStacksFromString(inventoryResearch.recipeToShow); drawStackInventory(stacks[0], 88, ; drawStackInventory(stacks[1], 116, ; drawStackInventory(stacks[2], 134, ; drawStackInventory(stacks[3], 152, ; drawStackInventory(stacks[4], 116, 26); drawStackInventory(stacks[5], 134, 26); drawStackInventory(stacks[6], 152, 26); drawStackInventory(stacks[7], 116, 44); drawStackInventory(stacks[8], 134, 44); drawStackInventory(stacks[9], 152, 44); } } private void drawStackInventory(ItemStack itemstack, int x, int y) { ItemStack newitem = null; if (itemstack != null) { newitem = itemstack.copy(); if (itemstack.getItemDamage() == -1) { newitem.setItemDamage(0); } } RenderHelper.enableGUIStandardItemLighting(); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); GL11.glEnable(GL12.GL_RESCALE_NORMAL); GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); Slot var6 = null; short var7 = 240; short var8 = 240; OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)var7 / 1.0F, (float)var8 / 1.0F); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); zLevel = 100.0F; itemRenderer.zLevel = 100.0F; if (itemstack != null) { itemRenderer.renderItemIntoGUI(fontRenderer, mc.renderEngine, newitem, guiLeft + x, guiTop + y); itemRenderer.renderItemOverlayIntoGUI(fontRenderer, mc.renderEngine, newitem, guiLeft + x, guiTop + y); } itemRenderer.zLevel = 0.0F; zLevel = 0.0F; GL11.glDisable(GL12.GL_RESCALE_NORMAL); RenderHelper.disableStandardItemLighting(); GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_DEPTH_TEST); } @Override protected void keyTyped(char par1, int par2) { if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode || par2 == ClientKeyHandler.Research.keyCode) { this.mc.thePlayer.closeScreen(); } } } http://i.imgur.com/XS3Vf.png[/img]
August 29, 201213 yr I too have this exact issue! Something that happens to me (that I don't think you said) is that when I click to place the item, it wont "drop" the item into the inventory - it will put 2x as much as how many I place in, and i'll still be holding the item. I've re-written my classes twice now, to no avail. Perhaps the answer is something to do with packet handling?
August 29, 201213 yr Author This is very strange... Actually, when I use a stack of 64 items, it creates a "ghost" stack in the inventory and a real one in my hand. This is obvioulsy a sync issue, but I can't find where the problem is! http://i.imgur.com/XS3Vf.png[/img]
August 30, 201213 yr Had any luck fixing it? I've not yet found anything. If I do, I'll post the answer here.
September 1, 201213 yr I'm quite surprised no one has answered this yet. I've looked in all the vanilla mc container classes, player's inventory class, the related gui classes; there's nothing they have that mine don't. I've even removed some of my own features- nada. It's been 4 days, i'm surprised no one has anything constructive that might even point us in the right direction. $10 donation from me via paypal to the first person to solve this.
September 2, 201213 yr Never fear! 1. You need to do something with a statCollector to render the items, or at least I do. 2. Is this inventory attached to a block? 2a. If so, make it a TE, easier to use. 3. If not, I have no idea. You don't need to pay me. So, what would happen if I did push that shiny red button over there? ... Really? ... Can I try it? ... Damn.
September 2, 201213 yr The issue isn't that the items aren't being rendered, rather, the itemstacks added aren't updating the inventory - if you add one, it's added to the gui, so it looks like it's in the inventory, but if you click it and move it out the inventory gui, it disappears. Also you keep a copy of the item in your hand. But hey, thanks for trying
September 2, 201213 yr The issue isn't that the items aren't being rendered, rather, the itemstacks added aren't updating the inventory - if you add one, it's added to the gui, so it looks like it's in the inventory, but if you click it and move it out the inventory gui, it disappears. Also you keep a copy of the item in your hand. But hey, thanks for trying Well, it was worth a shot... And I always attach inventories to TE's for my machines, so I'm not much help. So, what would happen if I did push that shiny red button over there? ... Really? ... Can I try it? ... Damn.
September 2, 201213 yr you have to attach them to a te as that does all the syncing as it scans the ivn that you set for the te and contatiner to use and then it does syncing (no idea how it does this, probaly does a time based sync) if you need any help with getting it to use a te just ask, i might make a tutorial latter on how to make a machine like a furnace but with as many slots as you want, and does what ever you want.
September 2, 201213 yr you have to attach them to a te as that does all the syncing as it scans the ivn that you set for the te and contatiner to use and then it does syncing (no idea how it does this, probaly does a time based sync) if you need any help with getting it to use a te just ask, i might make a tutorial latter on how to make a machine like a furnace but with as many slots as you want, and does what ever you want. Well, I send the data between client and server, so, you have to sync it. So, what would happen if I did push that shiny red button over there? ... Really? ... Can I try it? ... Damn.
September 2, 201213 yr you have to attach them to a te as that does all the syncing as it scans the ivn that you set for the te and contatiner to use and then it does syncing (no idea how it does this, probaly does a time based sync) if you need any help with getting it to use a te just ask, i might make a tutorial latter on how to make a machine like a furnace but with as many slots as you want, and does what ever you want. A tile entity? Even though both Jimmynator and myself aren't using blocks? (His I believe is for the player, mine is for a mob)
September 2, 201213 yr How are you handling the sending and receiving of update packets for it then? Beacuse to me it sounds like the client belives it is giving and/or taking an item from the inventory, but the server does not know of this and therefore inr eality nothing has happened. If you guys dont get it.. then well ya.. try harder...
September 2, 201213 yr Author Finally, I fixed it, I had to sync the slot clicking in the container for it to work. This was synced automatically in 1.2.5, I don't know why has this changed. Code: ContainerX: @Override public ItemStack slotClick (int slot, int button, boolean flag, EntityPlayer player) { ItemStack stack = super.slotClick(slot, button, flag, player); if (Minecraft.getMinecraft() != null && slot > 35) { PacketHandlerX.syncStack(stack, slot); } return stack; } PacketHandlerX: public void onPacketData(NetworkManager manager, Packet250CustomPayload packet, Player player) { if (packet.channel.equals("channelX")) { DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(packet.data)); EntityPlayer entityplayer = (EntityPlayer) player; int id = -1; try { id = dataStream.readInt(); switch (id) { case -1: break; case 0: ItemStack stack; int slot = dataStream.readInt(); int itemID = dataStream.readInt(); if (itemID < 0) { stack = null; } else { int stacksize = dataStream.readInt(); int damage = dataStream.readInt(); boolean bool = dataStream.readBoolean(); stack = new ItemStack(itemID, stacksize, damage); if (!bool) { NBTTagCompound tags = (NBTTagCompound) NBTTagCompound.readNamedTag(dataStream); stack.setTagCompound(tags); } } ((((inventoryYouWantToUpdate)))).setInventorySlotContents(slot, stack); break; } } catch(IOException e) { e.printStackTrace(); } } } public static void syncStack(ItemStack stack, int slot) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); DataOutputStream data = new DataOutputStream(bytes); try { data.writeInt(0); data.writeInt(slot); if (stack == null) { data.writeInt(-1); } else { data.writeInt(stack.itemID); data.writeInt(stack.stackSize); data.writeInt(stack.getItemDamage()); data.writeBoolean(stack.getTagCompound() == null); if (stack.getTagCompound() != null) { stack.getTagCompound().writeNamedTag(stack.getTagCompound(), data); } } } catch(IOException e) { e.printStackTrace(); } Packet250CustomPayload packet = new Packet250CustomPayload(); packet.channel = "channelX"; packet.data = bytes.toByteArray(); packet.length = packet.data.length; PacketDispatcher.sendPacketToServer(packet); } I don't know if this is what it is supposed to be like, but it works. http://i.imgur.com/XS3Vf.png[/img]
September 3, 201213 yr This can't be completely right. I have been running into this issue as well but it appears to be intermittent. I'm actually seeing a whole host of network related issues. My log pile containers work about 50% of the time. When I'm actually able to open the gui, the slot click actions work perfectly. I don't need to do the custom workaround. However when I try to use my custom workbench, I get the error every time. I've gone over the code countless times and the two containers are very similar yet one lets my pick up items and the other doesn't. Also upon stepping through the code what I think is happening is that its sending two packets. One for picking up the item and another for placing it back down. So you're canceling out your own action. That's what I think is occurring at least.
September 3, 201213 yr Author This can't be completely right. I have been running into this issue as well but it appears to be intermittent. I'm actually seeing a whole host of network related issues. My log pile containers work about 50% of the time. When I'm actually able to open the gui, the slot click actions work perfectly. I don't need to do the custom workaround. However when I try to use my custom workbench, I get the error every time. I've gone over the code countless times and the two containers are very similar yet one lets my pick up items and the other doesn't. Also upon stepping through the code what I think is happening is that its sending two packets. One for picking up the item and another for placing it back down. So you're canceling out your own action. That's what I think is occurring at least. Yeah, I'm sure this shouldn't be the code to make things work, but the only packets I send are those sync packets I've put here, and it works this way. If someone comes up with the actual code we should be using, it'd be much appreciated. About your container isues, as you're using tile entities you should take a look at cpw's code in it's ironchests github. I remember the packets you used had some kind of sync issues back in 1.2.5. http://i.imgur.com/XS3Vf.png[/img]
September 3, 201213 yr Yeah my code is based off of the ironchest code. As far as the clicking thing. I stepped through it and its definitely doing more than its supposed to. In my working logpile container I see the slotClick method fire off twice. Once on the server and once on the client. But in the workbench where I'm getting the same issue as you, the method is firing 4 times. twice for picking the item up(client and server) and twice again(which can only mean that its placing the item back). The fact that the containers work with one container type but not with another is the other oddity
September 3, 201213 yr Author That's some strange things happening. My code kind of works when it is fired 4 times. At least it does for my container http://i.imgur.com/XS3Vf.png[/img]
September 3, 201213 yr jimmy is your Gui by chance extending a custom GuiContainer class? Mine was. As soon as I had it extend the base GuiContainer class it works perfectly. The old 1.2.5 code was mucking it up
September 4, 201213 yr Author No, it is extending the base GuiContainer. This might be a problem with inventories that aren't using tile entities. It's great that you solved it, how's your mod going? http://i.imgur.com/XS3Vf.png[/img]
September 5, 201213 yr I have another gui, specifically GuiKnapping for rock knapping, it does not use a tileentity, and it works perfectly bud. You can check it out Here and the associated container Here. It doesn't really do much except act as a 5x5 crafting area but maybe it'll help. TFC is coming along nicely. I dare say that most of my code isn't as crappy as it used to be
September 5, 201213 yr Author Great! Thanks for the code, but it is a crafting inventory, so the server doesn't have to know the items in each slot. Mine, however, needs to sync with the server. http://i.imgur.com/XS3Vf.png[/img]
September 7, 201213 yr The server should be handling everything. All the client is there for, is to display information. If your items are existing clientside and you're trying to tell the server about them then you're probably doing something wrong. Never ever trust the client.
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.