Jump to content

[Help]System to Register Fluids


nomiknows

Recommended Posts

Hi everyone,

 

So recently I was trying to figure out a way to add lots of fluids and I'm having problems trying to design a system to register these fluids to Minecraft.

 

What has worked for blocks and items is creating a class with static final fields and static methods inside, like the following:

 

public class BlockLoader {
    // BlockA is a type of Block
    public static final BlockA myBlock = new BlockA();

    // ... More Blocks here

    // register each block reference to Minecraft
    public static void registerBlocks() {
        GameRegistry.registerBlock(myBlock, "myBlock");

        // ... Register more blocks here
    }
}

 

This design worked wonderful, because when a new block gets added, all that needs to be done is add the static reference and the call to registerBlock() in the method registerBlocks(). Fluids on the other hand don't work quite as simple.

 

 

Say I have a class like this:

public class LiquidA extends BlockFluidClassic { 
    public LiquidA(Fluid fluid, Material material) {
        super(fluid, material);
    }
}

 

I've tried utilizing the method above by creating a static field of LiquidA and calling super(new Fluid(...), new MaterialLiquid(...));. I continued to bang my head off a desk when I couldn't figure out why the *constructor* for BlockFluidClassic throws an exception. I knew that the Fluid object had to be registered before you registered the BlockFluidClass object, but I didn't know that had to be done *before* the constructor gets called.

 

After about an hour of debugging, it turns out that if the underlying Fluid object isn't registered to the Fluid registry, the constructor throws an exception, which is why you need to register the fluid first before you even try to *create* a BlockFluidClass object.

 

So I think to myself, "Ok, then let's also create static final Fluid references which we can register and then...."

 

lol oh wait, it's impossible to register the fluid before creating the static final LiquidA reference in the class! Since both fields would be initialized before a call to any method would be done. Here's what the code would have to look like with my design (which of course is impossible):

public class LoadFluids {
    public static final Fluid myFluid = new Fluid( ... );

    // Magically register the fluid (impossible)
    FluidRegistry.registerFluid(myFluid);

    // Create the static final reference for the liquid
    public static final LiquidA myLiquid = new LiquidA(myFluid, ... ); // This calls super(Fluid, Material) -> fails!

    // Static method to be called by my mod class to register all liquids that I include in this class
    public static void registerFluids() {
        GameRegistry.registerBlock(myLiquid, "myFluid");
    }
}

 

I could make myLiquid non-final and instantiate it in registerFluids() , but that causes the risk of other people modifying that object and possibly wrecking havoc. However, I can't keep the field final and instantiate it in registerFluids() because that will throw a compiler error. I'm looking for an easy and manageable way to add lots of custom built fluids, in a single class which can be invoked from my mod class (via registerFluids()). Does anyone have any advice on a good way to go about this?

 

I apologize in advance if I missed a detail or something, as it's like 5am at the time of writing, and I'm exhausted. I'll try to provide some clarity if requested.

 

Thank you in advance!  :D

Link to comment
Share on other sites

You should not be creating blocks, items, fluids, etc. anywhere outside of preInit. So you can't easily make the fields final (and if mods want to mess with your stuff they have to use reflection most likely anyways and then

final

is no hurdle).

 

Thanks for the response. So then those

final modifiers

should just be tossed? Come to think of it, if the objects need to be registered there's no reason to keep a reference to them in the class since the registry keeps track of them. Except for maybe the

Fluid

fields because there could be fluids that behave identical to others, and it would make sense to keep one static reference of a

Fluid

rather than create multiple objects with the same properties.

 

Would I be better off changing the

Fluid

fields to

private static

, removing any of the

BlockFluidBase

fields, and register the fluids and blocks in registerFluids()? This way I can be sure that the

Fluid

object will be registered before I try to register the fluid-block. (

registerFluids()

is only supposed to be called from the preInit event in the mod class, and is in a package which screams "DO NOT TOUCH") If the references turn out to be important, I could just make a new class to retrieve it from the registry, but I doubt that I'll need to do that and it sounds a kinda hacky like you had said.

 

I'll also note that I'm fairly new to modding, so if there's something really silly that I have completely missed, please let me know. Thanks again!

Link to comment
Share on other sites

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.



×
×
  • Create New...

Important Information

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