Jump to content

Recommended Posts

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

Posted

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.

Posted

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

Posted

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.

Posted

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.

Posted

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.

Posted

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.

Posted

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

Posted

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.

Posted

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

 

Posted

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

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

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I also just tried with iron's spellbooks removed, since that seemed related, but i am still having the same problem, even in newly created worlds. https://mclo.gs/AtrAfaj 
    • My Gradle Project for my Minecraft mod isn't building. Terminal: * Where: Settings file 'C:\Users\csonn\OneDrive\Desktop\fusionlucky\settings.gradle' line: 2 * What went wrong: Could not compile settings file 'C:\Users\csonn\OneDrive\Desktop\fusionlucky\settings.gradle'. > startup failed:   settings file 'C:\Users\csonn\OneDrive\Desktop\fusionlucky\settings.gradle': 2: The pluginManagement {} block must appear before any other statements in the script.   For more information on the pluginManagement {} block, please refer to https://docs.gradle.org/9.0.0/userguide/plugins.html#sec:plugin_management in the Gradle documentation.    @ line 2, column 1.      pluginManagement {      ^   1 error * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to generate a Build Scan (Powered by Develocity). > Get more help at https://help.gradle.org.   Setting.Gradle File:   rootProject.name = 'fusion-lucky-block' pluginManagement {     repositories {         gradlePluginPortal()         maven { url "https://maven.minecraftforge.net/" }         mavenCentral()     } }
    • no change still. here's a new log  https://mclo.gs/RXwiZmn 
    • Whenever I go to build my it says "Build failed in " how many seconds   Here is what is said in my terminal * Where: Build file 'C:\Users\csonn\OneDrive\Desktop\fusionlucky\build.gradle' line: 3 * What went wrong: Plugin [id: 'net.minecraftforge.gradle', version: '6.1.51'] was not found in any of the following sources: - Gradle Core Plugins (plugin is not in 'org.gradle' namespace) - Included Builds (No included builds contain this plugin) - Plugin Repositories (could not resolve plugin artifact 'net.minecraftforge.gradle:net.minecraftforge.gradle.gradle.plugin:6.1.51')   Searched in the following repositories:     Gradle Central Plugin Repository     MinecraftForge(https://maven.minecraftforge.net/) * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Get more help at https://help.gradle.org.   Here is what is in my build.gradle file plugins {     id 'java'     id 'net.minecraftforge.gradle' version '6.1+' }   group = 'io.github.csonnic03.fusionlucky' version = '1.0.0' archivesBaseName = 'fusionlucky'   java {     toolchain {         languageVersion = JavaLanguageVersion.of(17)     } }   repositories {     mavenCentral()     maven {         name "forgeMaven"         url "https://maven.minecraftforge.net/<repository>" } }   dependencies {     minecraft 'net.minecraftforge:forge:1.20.1-47.1.0' }   minecraft {     mappings channel: 'official', version: '1.20.1'     runs {         client {             workingDirectory project.file('run')         }         server {             workingDirectory project.file('run')         }     } }   tasks.withType(JavaCompile) {     options.encoding = 'UTF-8' }   jar {     manifest {         attributes(             "Specification-Title": "Fusion Lucky Block",             "Specification-Vendor": "example",             "Implementation-Title": project.name,             "Implementation-Version": project.version,             "Implementation-Vendor": "example",             "ModLauncher-TargetFMLVersion": "[47,)"         )     } }  
  • Topics

×
×
  • Create New...

Important Information

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