Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

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()?

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.

  • 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

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.

  • Author

And World#markAndNotifyBlock does not work. I have used in by itself and with markBlockForUpdate/markDirty.

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.

  • Author

I didn't know what the flags were, so I just put a 0 there. Is there a list of flags somewhere?

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.

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.

  • 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...

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.

  • 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;
}

 

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.

  • 3 weeks later...
  • 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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.