Posted June 4, 20169 yr I have a TE that, when in single player, works perfectly. Such as that I click the block, logic happens and the appearance changes instantly. I thought that was it for the TE. When I complied a test mod for my brother to try with me, we noticed that whenever one of us click on the TE block, the changes occur some seconds later. The change occurs instantly after the other player (the one who did not click the block) updates the chunk by destroying/placing another block nearby. Now I know to force TE updates that I need to use TE.getWorld().markBlockforUpdate() wheverever I want the update to occur. For good measures I place markDirty() beneath that too. In my TE class, I have both getDescriptionPacket() and onDataPacket() defined. As far as I read, those two methods would allow for updates across the server and all the clients. I have only one field in the NBT (intArray) and I need the entire field, so again from reading about, it seems that getDescriptionPacket()/ondataPacket() is what I need. Relevant code: ItemPaintbrush.class @Override public boolean onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ) { //Get block Block block = worldIn.getBlockState(pos).getBlock(); //Check block against target blocks if (block instanceof CBlock) { TileEntity te = worldIn.getTileEntity(pos); if (te instanceof CBlock_TE) { CBlock_TE tile = (CBlock_TE) te; NBTTagCompound nbt = stack.getTagCompound(); if (nbt != null && nbt.hasKey("rgb")) { int[] rgb = nbt.getIntArray("rgb"); tile.setColor(rgb[0], rgb[1], rgb[2]); tile.getWorld().markBlockForUpdate(pos); tile.markDirty(); stack.damageItem(1, playerIn); return true; } else { return false; } } } .. .. TE.class @Override public Packet getDescriptionPacket() { NBTTagCompound nbtTagCompound = new NBTTagCompound(); this.writeToNBT(nbtTagCompound); int metadata = getBlockMetadata(); return new S35PacketUpdateTileEntity(this.pos, metadata, nbtTagCompound); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { readFromNBT(pkt.getNbtCompound()); } @Override public void writeToNBT(NBTTagCompound parentNBTTagCompound) { super.writeToNBT(parentNBTTagCompound); parentNBTTagCompound.setIntArray("rgb", RGB); } @Override public void readFromNBT(NBTTagCompound parentNBTTagCompound) { super.readFromNBT(parentNBTTagCompound); int[] rgbIn = DEFAULT_RGB; if (parentNBTTagCompound.hasKey("rgb")) { rgbIn = parentNBTTagCompound.getIntArray("rgb"); } RGB = rgbIn; } .. .. I mean shouldn't this work? Item forces an update, which calls getDescriptionPacket() which sends out to clients that receive it through onDataPacket()?
June 4, 20169 yr 1. Process which changes the World should be done on server. Check for isRemote. 2. World#markAndNotifyBlock will mark the change and notify it to the client. I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
June 4, 20169 yr Author So would something like this do? Block block = worldIn.getBlockState(pos).getBlock(); //Check block against target blocks if (block instanceof CBlock) { TileEntity te = worldIn.getTileEntity(pos); if (te instanceof CBlock_TE) { CBlock_TE tile = (CBlock_TE) te; NBTTagCompound nbt = stack.getTagCompound(); if (nbt != null && nbt.hasKey("rgb")) { if (!worldIn.isRemote) { int[] rgb = nbt.getIntArray("rgb"); tile.setColor(rgb[0], rgb[1], rgb[2]); tile.getWorld().markBlockForUpdate(pos); tile.markDirty(); stack.damageItem(1, playerIn); return true; } } else { return false; } } } and for World#markAndNotifyblock....the last param is int flags. What are the flags I could use? EDIT: Nevermind it doesn't. I tried a couple different ways to place world.isremote in the code and every way doesn't work. The closest thing I got was that both test clients updated at the same time...but there was still a huge delay before the update occured. Also from reading into world.isremote, if isremote is false, then it means dedicated server right? If its true then its a 'combined client'? To get it to work on both sides, wouldn't I have to make two clauses, one for dedicated and one for combined? But they would both have to be the same code in order to work correctly; as in in the combined clause, in order for it to work the same in single player and lan, wouldn't the code have to be the same as the dedicated clause? Because it works fine for single player, but when opened to lan the game world should still be combined (isremote true)? And when in lan (combined) the update delay still occurs so I need to use the dedicated server clause code to fix it? Does anyone get what I mean? Or did I just completely overthink and confuse myself (and possibly others)? lol
June 4, 20169 yr I said that you should use World#markAndNotifyBlock, or something similar. I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
June 4, 20169 yr Author And World#markAndNotifyBlock does not work. I have used in by itself and with markBlockForUpdate/markDirty.
June 4, 20169 yr What did you used for flags? And, world.isRemote is false for the server thread. It does exist on the Combined Client. I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
June 4, 20169 yr Author I didn't know what the flags were, so I just put a 0 there. Is there a list of flags somewhere?
June 4, 20169 yr It's the same flag list as world.setBlock You generally want flag 3 (combination of flags 1 and 2, but not 4) Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
June 4, 20169 yr So, it seems that it does not update because you used 0, which won't do anything. From the World#setBlockState, it's same for markAndNotifyBlock. /** * Sets the block state at a given location. Flag 1 will cause a block update. Flag 2 will send the change to * clients (you almost always want this). Flag 4 prevents the block from being re-rendered, if this is a client * world. Flags can be added together. */ I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
June 4, 20169 yr Author Ok so I now got: Block block = worldIn.getBlockState(pos).getBlock(); //Check block against target blocks if (block instanceof CBlock) { TileEntity te = worldIn.getTileEntity(pos); if (te instanceof CBlock_TE) { CBlock_TE tile = (CBlock_TE) te; NBTTagCompound nbt = stack.getTagCompound(); if (nbt != null && nbt.hasKey("rgb")) { int[] rgb = nbt.getIntArray("rgb"); tile.setColor(rgb[0], rgb[1], rgb[2]); worldIn.markAndNotifyBlock(pos, worldIn.getChunkFromBlockCoords(pos), block.getDefaultState(), block.getDefaultState(), 3); stack.damageItem(1, playerIn); return true; } else { return false; } } } Same thing as the original problem. Updates instantly for one player, but the other is delayed...
June 4, 20169 yr Why don't you check World#isRemote? If adding it changes something, than the problem is in your block/tileentity. I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP) II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.
June 5, 20169 yr Author I don't really understand where I should put World#isRemote. Should it be placed just after where I check the block instance? After I get the TE instance? After I check the NBT compound? Only around the code where I handle the TE? I just tried after getting the NBT tag, and I got the same result I had earlier where the changes would not occur right away for both players, but they do update at the same time. I'll post my TE class (sigh ): TE.class @Override public Packet getDescriptionPacket() { NBTTagCompound nbtTagCompound = new NBTTagCompound(); this.writeToNBT(nbtTagCompound); int metadata = getBlockMetadata(); return new S35PacketUpdateTileEntity(this.pos, metadata, nbtTagCompound); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { readFromNBT(pkt.getNbtCompound()); } @Override public void writeToNBT(NBTTagCompound parentNBTTagCompound) { super.writeToNBT(parentNBTTagCompound); parentNBTTagCompound.setIntArray("rgb", RGB); } @Override public void readFromNBT(NBTTagCompound parentNBTTagCompound) { super.readFromNBT(parentNBTTagCompound); int[] rgbIn = DEFAULT_RGB; if (parentNBTTagCompound.hasKey("rgb")) { rgbIn = parentNBTTagCompound.getIntArray("rgb"); } RGB = rgbIn; }
June 5, 20169 yr How about the first place you use a World reference? Also, why are you writing the block metadata to your TE's description packet? You don't DO anything with it and the client should already know. Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
June 22, 20169 yr Author How about the first place you use a World reference? Also, why are you writing the block metadata to your TE's description packet? You don't DO anything with it and the client should already know. Sorry for the wait, I've been pretty busy over the last few weeks and kinda forgot about Minecraft. Anyways, I saw a tutorial somewhere online that included the metadata.
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.