Jump to content

[1.12.2] Unsure of how to create colour overlay for block.


Recommended Posts

Posted (edited)

I can't really figure out what I need to do in order to colour a block. I've seen some methods that return the colour of a block, and I saw the Block class had a recolorBlock method, but I'm still not entirely sure what I'd have to do.

 

EDIT: so to give the block a colour value, I gave it a TileEntity class. Only issue is,

GameRegistry.registerTileEntity()

This appears to be deprecated, so I'm not sure what I'm supposed to replace it with (assuming I should).

Edited by SeptemberBlue
Posted (edited)
10 minutes ago, diesieben07 said:

There are two versions of registerTileEntity. Only one is deprecated.

I really do not know how you can miss this, do you not use your IDE?

I see two methods, but both appear with strike through. The first two arguments are the same, but one takes a String and the other takes a Resource Location. Am I supposed to use the one with the latter?

EDIT: Yep, changed the second argument and the method no longer appears with a strike through. Thanks!

 

As for your other comment, the only time I've used my IDE (eclipse) is for when I wanted to work on my minecraft mod. So yeah, I don't know too much about my IDE. I've figured some things out though, so I'm not completely clueless.

Edited by SeptemberBlue
Posted

Ok, so now I have my block that's a TileEntity, and it has its own color variable. There's that, and then I set the TintIndex for some of the faces to 0 for the block model.

 

Is there a method I could use which would add a colour overlay to faces with a TintIndex of 0? Also, if I should use that, what should I use in its place?

Posted (edited)
1 hour ago, diesieben07 said:

Subscribe to ColorHandlerEvent.Block and register an IBlockColor instance for your block.

I'm not entirely sure how I'd do this. I see that I have code like this:

	@SubscribeEvent
	public static void onBlockRegister(RegistryEvent.Register<Block> event) {
		event.getRegistry().registerAll(ModBlocks.BLOCKS.toArray(new Block[0]));
	}

So I'm guessing I'd do something similar.

 

Is this on the right track, or do I have this all wrong? Also, anything I should look at to get a better understanding of what you mean?

EDIT: I've found this topic here. I know it's for a later version, but I'm assuming it'll also work for 1.12.2. Looking at their solution there, I have two questions. First off, what does the register method take? I was guessing the variable for the block plus an int for the colour, but that didn't seem to work. Also where can I find the main event bus? Is it that init thing?

 

EDIT 2: IBlockColor doesn't seem to exist. Do I have to create it?

Edited by SeptemberBlue
Posted
54 minutes ago, diesieben07 said:
  • Events are explained in the documentation.
  • You need to subscribe to ColorHandlerEvent.Block, get the BlockColors instance from the event and then register your IBlockColor.
  • Yes, IBlockColor definitely exists, it is in the net.minecraft.client.renderer.color package.

(First off thanks for the documentation!)

 

As for the other two points, I have this so far:

@SubscribeEvent
public static void registerBlockColors(final ColorHandlerEvent.Block event) {
	event.getBlockColors().registerBlockColorHandler(blockColor, ModBlocks.CANVAS);
}

I'm going to replace blockColor. Since IBlockColor is an interface, do I need to make a class that implements it?

Posted
6 hours ago, diesieben07 said:

What are you talking about?

@SideOnly(Side.CLIENT)
public interface IBlockColor
{
    int colorMultiplier(IBlockState state, @Nullable IBlockAccess worldIn, @Nullable BlockPos pos, int tintIndex);
}

The method takes an IBlockState, an IBlockAccess, a BlockPos, and an int. I'm going to set the tintIndex to 0, since that corresponds with the json files. As for the other three, I'm probably going to want the IBlockState, IBlockAccess, and BlockPos for all blocks that need to be coloured (canvas blocks in this case)

Posted
4 minutes ago, SeptemberBlue said:

@SideOnly(Side.CLIENT)
public interface IBlockColor
{
    int colorMultiplier(IBlockState state, @Nullable IBlockAccess worldIn, @Nullable BlockPos pos, int tintIndex);
}

The method takes an IBlockState, an IBlockAccess, a BlockPos, and an int. I'm going to set the tintIndex to 0, since that corresponds with the json files. As for the other three, I'm probably going to want the IBlockState, IBlockAccess, and BlockPos for all blocks that need to be coloured (canvas blocks in this case)

Are you trying to call the method? That's not what you are supposed to do. You need to create an IBlockColor instance and register it.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
1 minute ago, Animefan8888 said:

Are you trying to call the method? That's not what you are supposed to do. You need to create an IBlockColor instance and register it.

@SubscribeEvent
public static void registerBlockColors(final ColorHandlerEvent.Block event) {
	event.getBlockColors().registerBlockColorHandler(new IBlockColor.colorMultiplier(0,0,0,0), ModBlocks.CANVAS);
}

So how do I register this interface?

Posted
Just now, SeptemberBlue said:

So how do I register this interface?

You need an instance of the interface. If you don't know what that means look it up on google. It's basic Java.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
1 minute ago, Animefan8888 said:

You need an instance of the interface. If you don't know what that means look it up on google. It's basic Java.

new IBlockColor.colorMultiplier(0,0,0,0)

How is this not a new instance?

Posted
Just now, SeptemberBlue said:

How is this not a new instance?

Look it up. This is not a Java forum. Your IDE should be giving you a red underline right underneath that. Which is a clear clue that it is a Java issue.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
2 minutes ago, Animefan8888 said:

Look it up. This is not a Java forum. Your IDE should be giving you a red underline right underneath that. Which is a clear clue that it is a Java issue.

I'm still not clear which part exactly is wrong.

 

Am I supposed to create a class that implements the interface? Should I give its method the correct arguments? Or is creating an instance not the same as initializing?

Posted
Just now, SeptemberBlue said:

Am I supposed to create a class that implements the interface?

You can definitely do that. Or you can do as diesieben said

11 hours ago, diesieben07 said:

or, since it's a functional interface, you can use a lambda expression.

 

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
Just now, SeptemberBlue said:

I was trying to follow what he said, which would mean that it's not a correct lambda expression. Good to know.

Correct this is what a correct lambda expression looks like.

 

// This way of going about it doesn't require you to use a "return" statement if the method in the interface returns a value.
([PARAMETER NAMES HERE]) -> [SOME CODE WITHIN A SINGLE LINE]

// This way works exactly like you are inside a method.
([PARAMETER NAMES HERE]) -> {
  [MULTILINE CODE HERE]
}

 

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

Sweet, set up the lambda expression, gave it a colour, and now everything works fine!

 

Only issue now is that I want the colour to be set based on the NBT tag of the block, since I made it a tile entity with a color tag. How would I access the tag?

Posted
3 minutes ago, SeptemberBlue said:

How would I access the tag?

If it's in the TileEntity you have access to the IBlockAccess and the BlockPos. You can get the TileEntity and then access your field for the color.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
1 minute ago, Animefan8888 said:

If it's in the TileEntity you have access to the IBlockAccess and the BlockPos. You can get the TileEntity and then access your field for the color.

Before I attempt any of the above, my TileEntity's color variable is private. Should I make a get method, or should I use some preexisting method?

 

As for what you've said, I'm not entirely sure how to go about it. I see that IBlockAccess has a getTileEntity() method, and that takes a BlockPos. I don't really know how I'm supposed to put those together though. Can I use a lambda expression for IBlockAccess, even if it has other methods?

Posted
7 minutes ago, SeptemberBlue said:

Should I make a get method,

This is what you should do. There is no pre-existing method.

 

7 minutes ago, SeptemberBlue said:

Can I use a lambda expression for IBlockAccess, even if it has other methods?

You don't really know what a lambda expression is. Go read up on them seriously, they are greatly useful.

 

8 minutes ago, SeptemberBlue said:

I don't really know how I'm supposed to put those together though.

Do you know how to call a method?

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted (edited)
14 minutes ago, Animefan8888 said:

This is what you should do. There is no pre-existing method.

Done.

14 minutes ago, Animefan8888 said:

You don't really know what a lambda expression is. Go read up on them seriously, they are greatly useful.

My basic understanding of them so far is that you give them the parameters of a function, and then on the other side give it a return value. Will read up on them more though.

14 minutes ago, Animefan8888 said:

Do you know how to call a method?

@Nullable
TileEntity getTileEntity(BlockPos pos);

Not when it looks like this (from IBlockAccess).

 

EDIT: DAMMIT, never thought to use the arguments from the method. I might be able to solve my own problem here.

Edited by SeptemberBlue
Posted (edited)

Alright, it seems to be picking the color of the block, which is good. What's weird though is that I can't change the color. I've used blockdata to try change the color value to something else, but when I check the block again, the color value reset.

 

the class:

public class TileEntityCanvas extends TileEntity {
	private int color;
	
	public TileEntityCanvas() {
	}
	
	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound compound) {
		super.writeToNBT(compound);
		compound.setInteger("color", color);
		return compound;
	}
	
	@Override
	public void readFromNBT(NBTTagCompound compound) {
		super.readFromNBT(compound);
	}
	
	public int getColor() {
		return color;
	}
	
	public void setColor (int c) {
		color=c;
	}
}

EDIT: Pretty sure this has to do with the writeToNBT, will add an if statement to check if the "color" value changed. Looking for a method that gets an NBT value.

 

EDIT 2:

	@Override
	public NBTTagCompound writeToNBT(NBTTagCompound compound) {
		super.writeToNBT(compound);
		if (!compound.hasKey("color") || compound.getInteger("color") != color) compound.setInteger("color", color);
		return compound;
	}

For some reason, the color variable still won't change.

Edited by SeptemberBlue
Posted
16 minutes ago, SeptemberBlue said:

Is there some way I can call the event every time the color gets updated?

No that won't do anything.

 

16 minutes ago, SeptemberBlue said:

but the block does not actually change colour.

The Block has a model which is built into a mesh which is rendered. The mesh is not updated until a block in the world changes. Hence it doesn't update dynamically. You need to add a dummy BooleanProperty to your BlockState. And switch between those when the color is changed.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted (edited)
3 minutes ago, Animefan8888 said:

You need to add a dummy BooleanProperty to your BlockState.

So wait, do I add that to my BlockState json?

 

3 minutes ago, Animefan8888 said:

No that won't do anything. 

How would that not do anything? I was thinking I'd add an if statement to the readNBT part that checks if the colour changed, and if it did, call the event to change accordingly. Or are you saying that if I did try to call the event, nothing would happen?

Edited by SeptemberBlue

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

    • After reinstalling and rebuilding server, now I get another error which is Internal Exception: io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(2829) + length(1) exceeds writerIndex(2829): UnpooledHeapByteBuf(ridx: 2829, widx: 2829, cap: 2829/2829)
    • In 1.20.1, while creating an addon(mod) for Epic Fight, I tried to runclient and it crashed with the following error rg.spongepowered.asm.mixin.throwables.MixinApplyError: Mixin [mixins.epicfight.json:MixinEntityRenderer] from phase [DEFAULT] in config [ mixins.epicfight.json] FAILED during APPLY Could you please tell me how to solve this problem? build.gradle   plugins { id 'eclipse' id 'idea' id 'maven-publish' id 'net.minecraftforge.gradle' version '[6.0,6.2)' //id 'org.parchmentmc.librarian.forgegradle' version '1.+' //id 'org.spongepowerd.mixin' version '0.8.5' } version = mod_version group = mod_group_id base { archivesName = mod_id } // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" minecraft { // The mappings can be changed at any time and must be in the following format. // Channel: Version: // official MCVersion Official field/method names from Mojang mapping files // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official // // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md // // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge // Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started // // Use non-default mappings at your own risk. They may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. mappings channel: mapping_channel, version: mapping_version // When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game. // In most cases, it is not necessary to enable. // enableEclipsePrepareRuns = true // enableIdeaPrepareRuns = true // This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game. // It is REQUIRED to be set to true for this template to function. // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html copyIdeResources = true // When true, this property will add the folder name of all declared run configurations to generated IDE run configurations. // The folder name can be set on a run configuration using the "folderName" property. // By default, the folder name of a run configuration is the name of the Gradle project containing it. // generateRunFolders = true // This property enables access transformers for use in development. // They will be applied to the Minecraft artifact. // The access transformer file can be anywhere in the project. // However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge. // This default location is a best practice to automatically put the file in the right place in the final jar. // See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information. // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Default run configurations. // These can be tweaked, removed, or duplicated as needed. runs { // applies to all the run configs below configureEach { workingDirectory project.file('run') // Recommended logging data for a userdev environment // The markers can be added/remove as needed separated by commas. // "SCAN": For mods scan. // "REGISTRIES": For firing of registry events. // "REGISTRYDUMP": For getting the contents of all registries. property 'forge.logging.markers', 'REGISTRIES' // Recommended logging level for the console // You can set various levels here. // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' mods { "${mod_id}" { source sourceSets.main } } } client { // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. property 'forge.enabledGameTestNamespaces', mod_id } server { property 'forge.enabledGameTestNamespaces', mod_id args '--nogui' } // This run config launches GameTestServer and runs all registered gametests, then exits. // By default, the server will crash when no gametests are provided. // The gametest system is also enabled by default for other run configs under the /test command. gameTestServer { property 'forge.enabledGameTestNamespaces', mod_id } data { // example of overriding the workingDirectory set in configureEach above workingDirectory project.file('run-data') // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') } } } // Include resources generated by data generators. sourceSets.main.resources { srcDir 'src/generated/resources' } repositories { // Put repositories for dependencies here // ForgeGradle automatically adds the Forge maven and Maven Central for you maven { url "https://cursemaven.com" content { includeGroup "curse.maven" } } // If you have mod jar dependencies in ./libs, you can declare them as a repository like so. // See https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver // flatDir { // dir 'libs' // } } dependencies { // Specify the version of Minecraft to use. // Any artifact can be supplied so long as it has a "userdev" classifier artifact and is a compatible patcher artifact. // The "userdev" classifier will be requested and setup by ForgeGradle. // If the group id is "net.minecraft" and the artifact id is one of ["client", "server", "joined"], // then special handling is done to allow a setup of a vanilla dependency without the use of an external repository. minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" // Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}") // compileOnly fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}") // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}-forge:${jei_version}") implementation fg.deobf("curse.maven:epic-fight-mod-405076:5922122") annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' // Example mod dependency using a mod jar from ./libs with a flat dir repository // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar // The group id is ignored when searching -- in this case, it is "blank" // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") // For more info: // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html // http://www.gradle.org/docs/current/userguide/dependency_management.html } // This block of code expands all declared replace properties in the specified resource targets. // A missing property will result in an error. Properties are expanded using ${} Groovy notation. // When "copyIdeResources" is enabled, this will also run before the game launches in IDE environments. // See https://docs.gradle.org/current/dsl/org.gradle.language.jvm.tasks.ProcessResources.html tasks.named('processResources', ProcessResources).configure { var replaceProperties = [ minecraft_version: minecraft_version, minecraft_version_range: minecraft_version_range, forge_version: forge_version, forge_version_range: forge_version_range, loader_version_range: loader_version_range, mod_id: mod_id, mod_name: mod_name, mod_license: mod_license, mod_version: mod_version, mod_authors: mod_authors, mod_description: mod_description, ] inputs.properties replaceProperties filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) { expand replaceProperties + [project: project] } } // Example for how to get properties into the manifest for reading at runtime. tasks.named('jar', Jar).configure { manifest { attributes([ 'Specification-Title' : mod_id, 'Specification-Vendor' : mod_authors, 'Specification-Version' : '1', // We are version 1 of ourselves 'Implementation-Title' : project.name, 'Implementation-Version' : project.jar.archiveVersion, 'Implementation-Vendor' : mod_authors, 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) } // This is the preferred method to reobfuscate your jar file finalizedBy 'reobfJar' } // However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing: // tasks.named('publish').configure { // dependsOn 'reobfJar' // } // Example configuration to allow publishing using the maven-publish plugin publishing { publications { register('mavenJava', MavenPublication) { artifact jar } } repositories { maven { url "file://${project.projectDir}/mcmodsrepo" } maven { url "https://cursemaven.com" content { includeGroup "curse.maven" } } } } tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation }  
    • I have a custom 3d model which works perfectly. BUT I want it to be held diffrently on the players hand when the item is being used. My JSON file under assets/examplemod/items looks like this: { "model": { "type": "minecraft:condition", "on_false": { "type": "minecraft:model", "model": "examplemod:item/example_item" }, "on_true": { "type": "minecraft:model", "model": "examplemod:item/example_item_using" }, "property": "minecraft:using_item" } }   This works fine until the item is used. The correct model will be displayed but with a full black texture instead of the actuall texture. Any idea why? (I want to use the exact same texture for both items, because their model is the same just diffrent displays on firstperson_righthand and firstperson_lefthand). The models JSON's are fully blockbench files inlcuding the elements, display, textures with texture_size.   Also is this the correct way to do it? Because it feels so dumb to change the exact same model just for a diffrent right- and lefthand view.   (fyi: ItemUseAnimation is BLOCK for this item)
    • I just backed up my world then tried to create new mod with currently equipped mod but with new world still made same error. Sooo I think it's not world error. also It's working fine on singleplayer. + but it made some another weird error with new world
    • Maybe the file is too large - you can upload the log file via Mediafire
  • Topics

  • Who's Online (See full list)

    • There are no registered users currently online
×
×
  • Create New...

Important Information

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