Jump to content

Applying a tint to certain blocks/altering vanilla block behaviour


DoomFruit

Recommended Posts

A long time ago, a guy named Shockah made a mod called Fluid Warning (was here, but he seems to have removed the link) which tinted stone and obsidian blocks blue or orange if breaking one would expose water or lava, respectivel. He stopped updating it after b1.8.1 (I think), so I took a peek at it with JD-GUI and re-created it for r1.0.0, r1.2.5 and r1.4.7 when I started playing on those versions.

 

The way it worked was a base class edit of blockStone (and therefore blockObsidian, which extends blockStone) which added a colorMultiplier if any of the 6 directly adjacent blocks were lava or water. Here's the exact code which gets put in:

    private static final ArrayList water = new ArrayList(Arrays.asList(new Integer[] {
      Integer.valueOf(, Integer.valueOf(9)
    }));
    private static final ArrayList lava = new ArrayList(Arrays.asList(new Integer[] {
      Integer.valueOf(10), Integer.valueOf(11)
    }));

    public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k)
    {
      if(containsOR(lava, new Integer[] {
Integer.valueOf(iblockaccess.getBlockId(i - 1, j, k)), Integer.valueOf(iblockaccess.getBlockId(i + 1, j, k)), Integer.valueOf(iblockaccess.getBlockId(i, j, k - 1)), Integer.valueOf(iblockaccess.getBlockId(i, j, k + 1)), Integer.valueOf(iblockaccess.getBlockId(i, j - 1, k)), Integer.valueOf(iblockaccess.getBlockId(i, j + 1, k))
      }))
      {
return -22016;
      }
      return !containsOR(water, new Integer[] {
Integer.valueOf(iblockaccess.getBlockId(i - 1, j, k)), Integer.valueOf(iblockaccess.getBlockId(i + 1, j, k)), Integer.valueOf(iblockaccess.getBlockId(i, j, k - 1)), Integer.valueOf(iblockaccess.getBlockId(i, j, k + 1)), Integer.valueOf(iblockaccess.getBlockId(i, j - 1, k)), Integer.valueOf(iblockaccess.getBlockId(i, j + 1, k))
      }) ? -1 : 0xffaaaaff;
    }

    private static boolean containsOR(ArrayList arraylist, Object aobj[])
    {
      Object aobj1[];
      int j = (aobj1 = aobj).length;
      for(int i = 0; i < j; i++)
      {
Object obj = aobj1[i];
if(arraylist.contains(obj))
{
  return true;
}
      }
      
      return false;
    }

 

I know that there are several things which should be changed to update it to modern versions of MC - referencing blocks by name instead of block ID, for instance (along with cleaning up the ugly decompiled copy-pasted code into something a little neater). The big stopper is that I can't figure out how to give blockStone this conditional tinting without a base class edit - I don't see any obvious hooks in the Forge code. Can I add a custom colorMultiplier() function to a pre-existing block type (and in this case, with additional code to check the world around it beforehand) without hacking the base classes?

Link to comment
Share on other sites

Hi

 

I don't think there is any way to change the rendering of vanilla blocks without base class edits.

 

But you might be able to get the same game mechanic a different way.  For example, you could change the appearance of the block you're looking at if it's next to lava or water-  by hooking into RenderWorldLastEvent, checking the block the player is looking at using Minecraft.getMinecraft().entityRenderer.getMouseOver(), and rendering over the top of the block (eg outline, or an alpha-blended box) if appropriate.

 

-TGG

Link to comment
Share on other sites

Hmm. I'm really looking to tint all of the visible blocks so that I can get an instant idea of where it's safe to dig rather than having to go up and touch each one individually. The latter does make sense in terms of a "this block feels hot" thing, but it's not really what I'm after.

Link to comment
Share on other sites

Hmm. I'm really looking to tint all of the visible blocks so that I can get an instant idea of where it's safe to dig rather than having to go up and touch each one individually. The latter does make sense in terms of a "this block feels hot" thing, but it's not really what I'm after.

 

I do think it is a lot easier to just do the block that you've got selected.  There are multiple ways to detect the block that the player is looking at, but perhaps best there is actually an event called onDrawBlockHighlight where you could just record the block and then later handle the RenderPlayerHandEvent and call some rendering.

 

However, I think it may actually be possible to do all blocks (at least that are close to player or in their FOV).  I noticed that there is a public method called drawSelectionBox() in the RenderGlobal class.  The interesting thing is you can pass your own moving position parameter into it, meaning that you don't have to just draw the box for what the player is looking at.  So I think, not sure, you might be able to handle the REnderPlayerHandEvent and do a drawSelectionBox() kind of thing for each block around the player.  Instead of the stock drawSelectionBox() you'd probably want to make your own (copying the code) where you check for lava and go red, etc.  My point with the drawSelectionBox() is that it is easy example of how to find the block rendering cube within the rendered view.  So then you could do other things, like instead of outline could blend in an overlay.

 

I suspect performance might be an issue, but logically it could work I think.  Maybe TheGreyGhost (expert in block rendering) could comment on whether this scheme might work:

1. Handle RenderPlayerHandEvent

2. Calculate moving object positions into enough directions to hit all blocks in close proximity (I think you would just go through array of blocks around player's position.  For perf reasons, might not want to calculate these every tick, but maybe every couple ticks or something.

3. Pass the moving object positions to all a method similar to drawSelectionBox() which would find the cube and either outline it or blend over it based on other checks (for lava and water).

 

 

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

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.

Announcements



×
×
  • Create New...

Important Information

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