Jump to content

[1.12.2] Block with an overlay conditional on nearby blocks


Recommended Posts

Posted

Hi all,

 

I'm trying to design a decorative block with a somewhat unusual display: it would show a "border" on every side where it does not connect to a similar block. A picture would make it clearer:

 

overlays.png.cd639ff0bdcdd7dcf8b484606a0f61b0.png

 

if the blue blocks are my blocks and the green blocks are a different type of blocks, I want the overlays for each of those red lines displayed as in the picture above.

 

In order to do that, I've set up properties in my class file:


 

    public static final PropertyBool NORTH = PropertyBool.create("north");
    public static final PropertyBool EAST = PropertyBool.create("east");
    public static final PropertyBool SOUTH = PropertyBool.create("south");
    public static final PropertyBool WEST = PropertyBool.create("west");
    public static final PropertyBool UP = PropertyBool.create("up");
    public static final PropertyBool DOWN = PropertyBool.create("down");

@Override
    public IBlockState getActualState(final IBlockState state, final IBlockAccess worldIn, final BlockPos pos) {

        IBlockState actualState = state.withProperty(NORTH, Boolean.valueOf(this.connectsTo(state, worldIn.getBlockState(pos.north()))));
        actualState = actualState.withProperty(EAST, Boolean.valueOf(this.connectsTo(state, worldIn.getBlockState(pos.east()))));
        actualState = actualState.withProperty(SOUTH, Boolean.valueOf(this.connectsTo(state, worldIn.getBlockState(pos.south()))));
        actualState = actualState.withProperty(WEST, Boolean.valueOf(this.connectsTo(state, worldIn.getBlockState(pos.west()))));
        actualState = actualState.withProperty(UP, Boolean.valueOf(this.connectsTo(state, worldIn.getBlockState(pos.up()))));
        actualState = actualState.withProperty(DOWN, Boolean.valueOf(this.connectsTo(state, worldIn.getBlockState(pos.down()))));

        return actualState;
    }
    
    public final boolean connectsTo(final IBlockState ourState, final IBlockState otherState) {
        return ((otherState.getBlock() instanceof BlockPaintedBricks) && (otherState.getValue(COLOR) == ourState.getValue(COLOR)));
    }

 

And I now need to setup my blockstate and my model so that the appropriate overlay is display on every face where one of my property is false, so each face having multiple textures overlaid on top of each others based on the face it is and the properties I've set in my blockstate.

 

Is that even possible? I've worked with multipart blockstates files before, but only to point to different models. I've used overlays in models, but not conditionality.

 

Any help would be welcomed.

 

 

 

 

Posted

It's called "connected texture" and yes, its possible. It's just bloody complicated. There are 43 possible variations needed.

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

Great... any tutorials around?

 

Otherwise I was looking at BlockFence which actually changes its model based on nearby blocks, but that's actually applying multiple separate models, not just textures. And in my case, in the "worst case" of an isolated block, I'd have to apply one base model plus four models per block side to add up all the overlays if I understand things correctly. Even if it works I'm guessing the rendering of 25 models for a single block is going to hit rendering performance...

Posted (edited)

I haven't seen one...

 

Also, the 43 states include the corners (so diagonal connections or lack of connection) which may or may not be important for your usage.

 

In any case, what it's going to come down to is that you will need to construct an Actual State (regular state: metadata, actual state: includes other world information, extended state: client only variable data, used for fluids mostly) that includes the connected/not-connected status of each adjacent block.

 

You'll then have to create a blockstate JSON with each possible result and supply a model (or model changes) based on which state(s) it represents. This will be the hard part. It may be easiest to treat each "face" of the block as its own model (so like the fence) and use the different adjacency information to change which model is used for each side.

Edited by Draco18s

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

Okay, I have a bunch of ideas.

 

Firstly, if you only want this effect when the block is being highlighted (i.e. the selection block), you can add all the rendering you want in the getSelectedBoundingBox() method of your block. This method is called while already in the middle of rendering so you can just get the Tesselator.instance() and draw anything additional.

 

Otherwise, assuming you want this highlighted all the time, here's some more.

 

Okay, if this is mostly a cosmetic thing I don't think you strictly need it to have states associated with it. You could potentially check for neighbors at time of rendering, but depends on what you're trying to achieve. Even on server side I would suggest it might be easier to check for neighbors when you need to rather than trying to maintain it a state.

 

Next, regarding the "43 different states" if you just check at rendering time you can create all the overlays (i.e. one for each side) separately and on top of each other. You just have to design the graphical highlighting such that it works when drawn on top of one another. In other words, imagine having a texture that was transparent except for a yellow strip along an edge. You would use that single texture and just rotate it and render it for each neighbor.

 

There are actually a couple different approaches that might work better than using block states with standard block models:

a) Make your block a tile entity with a special renderer. In your special renderer, just check the neighbors at the time of rendering, no need to maintain a block state.

b) Use Reflection to replace the BlockModelRenderer in the BlockRendererDispatcher class.

 

It should be pretty obvious how to do (a), but for (b) here is some more details about what I'm thinking:

You can get the BlockRendererDispatcher class with Minecraft.getMinecraft.getBlockRendererDispatcher() getter method and then change the private field to a custom BlockModelRenderer.

 

The custom BlockModelRenderer would extend the vanilla one and copy most of code but in the place where it renders the layers it would then include your code for your additional stuff.

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted

@Draco18s Thanks for the infos. I get the 43 cases, indeed with corners it would come to that much, and while I had not mentioned it I'd ideally want that. I guess I could do that, but that's a lot more work than I had "budgeted"... I have no problems with the creation of the actual state BTW, that part is simple and I've already done it in fact.

 

@jabelar This is intended for an "ordinary" construction block, and it would be used on a large scale so a tile entity isn't an option. Customising BlockModelRenderer is an interesting option, but if I change it Minecraft-wide that's going to be incompatible with anybody else attempting to do the same thing.

 

I feel like I really have two options, either I script something to generate those 42 overlay models or I give up on the idea and do something simpler...

 

Thanks for all the infos.

 

Posted

Yes, anything that general block rendering usually involves a somewhat "heavy" mod. I'm not entirely sure why Forge doesn't provide more hooks but I suspect that it is due to performance concerns. If every mod started mucking around with block rendering it would probably be a disaster.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted
4 minutes ago, jabelar said:

If every mod started mucking around with block rendering it would probably be a disaster.

That's probably almost exactly why.

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.

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



×
×
  • Create New...

Important Information

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