Jump to content

Recommended Posts

Posted

Heyho Guys!

 

I recently started with 1.8 and came across some issues with the block rendering for blocks with variants. So, I want to ask a few questions to clarify the things I'm unsure about.

 

First question: Which registration method is used for a block with subtypes/variants? I saw both methods here:

Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(block), meta, new ModelResourceLocation(modid + ":" + filename, "inventory"));

ModelBakery.addVariantName(Item.getItemFromBlock(block), "first_file", "second_file", "third_file", "fourth_file");

where all the files define a blockstates file that was created. Which one of those is necessary? What exactly do they do? And where is the file finally searched? And is it possible to use one file for every metadata and differentiate the rendering inside this file with the variants tag?

 

Second question: how is it possible to exclude some properties from the list that is searched for in the blockstates file? I saw that the stained glass pane for instance has the property "color", but this is not used in the blockstates file. There only the north/east/south/west property is checked.

 

Third question: can I register a blockstate file for every possible metadata?

 

I hope, someone can get an answer to one of these questions..

Please write if I need to be more precise on something because I think it might be a bit confusing.

Thanks for every answer!

 

~_Bedrock_Miner_

Posted

Hi

 

The way that MBE03 is coded, it has a line for every possible blockstate.  But the four red blockstates all specify the same red model file, the four blue blockstates all specify the same blue model file, etc.  This controls the way the block renders when you've placed it in the world.

 

mbe03_block_variants.json::
{
    "variants": {
           "colour=red,facing=north": { "model": "minecraftbyexample:mbe03_block_variants_model_red"},
            "colour=red,facing=east": { "model": "minecraftbyexample:mbe03_block_variants_model_red", "y": 90 },
           "colour=red,facing=south": { "model": "minecraftbyexample:mbe03_block_variants_model_red", "y": 180 },
            "colour=red,facing=west": { "model": "minecraftbyexample:mbe03_block_variants_model_red", "y": 270 },
         "colour=green,facing=north": { "model": "minecraftbyexample:mbe03_block_variants_model_green" },
          "colour=green,facing=east": { "model": "minecraftbyexample:mbe03_block_variants_model_green", "y": 90 },
         "colour=green,facing=south": { "model": "minecraftbyexample:mbe03_block_variants_model_green", "y": 180 },
          "colour=green,facing=west": { "model": "minecraftbyexample:mbe03_block_variants_model_green", "y": 270 },
        "colour=yellow,facing=north": { "model": "minecraftbyexample:mbe03_block_variants_model_yellow" },
         "colour=yellow,facing=east": { "model": "minecraftbyexample:mbe03_block_variants_model_yellow", "y": 90 },
        "colour=yellow,facing=south": { "model": "minecraftbyexample:mbe03_block_variants_model_yellow", "y": 180 },
         "colour=yellow,facing=west": { "model": "minecraftbyexample:mbe03_block_variants_model_yellow", "y": 270 },
          "colour=blue,facing=north": { "model": "minecraftbyexample:mbe03_block_variants_model_blue" },
           "colour=blue,facing=east": { "model": "minecraftbyexample:mbe03_block_variants_model_blue", "y": 90 },
          "colour=blue,facing=south": { "model": "minecraftbyexample:mbe03_block_variants_model_blue", "y": 180 },
           "colour=blue,facing=west": { "model": "minecraftbyexample:mbe03_block_variants_model_blue", "y": 270 }
    }
}

 

The stuff in the client proxy with 

ModelBakery.addVariantName(..)

and

Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(itemBlockVariants, BlockVariants.EnumColour.BLUE.getMetadata(), itemModelResourceLocation);

and in the custom Block class

Block.getSubBlocks()

 

is used to pick some of the possible block states to appear in the inventory and as items.  There are only four items, one per colour, because the different 'facing' directions are all the same when you hold them as an item.

 

// create a list of the subBlocks available for this block, i.e. one for each colour
  //  - used to populate items for the creative inventory
  // - the "metadata" value of the block is set to the colours metadata
  @Override
  @SideOnly(Side.CLIENT)
  public void getSubBlocks(Item itemIn, CreativeTabs tab, List list)
  {
    EnumColour[] allColours = EnumColour.values();
    for (EnumColour colour : allColours) {
      list.add(new ItemStack(itemIn, 1, colour.getMetadata()));
    }
  }

 

 

-TGG

Posted

Ok, so I'll just sum up what I understood and you can tell me if I'm wrong.

 

  • The registrations in the ItemModelMesher are only used for the Items and should add a mapping for model files based on all available Item Metadata.
  • The blockstates files dont need registrations and only control the rendering of blocks in the world.
  • In the blockstates file you need to write down the properties (alphabetic order, I guess) and assign corresponding models.

 

I still have two questions left:

  • Is the call of ModelBakery.addVariantName necessary and what does it do?
  • Is it possible to exclude states from being used in the blockstates file?

Posted

Ok, so I'll just sum up what I understood and you can tell me if I'm wrong.

 

  • The registrations in the ItemModelMesher are only used for the Items and should add a mapping for model files based on all available Item Metadata.
  • The blockstates files dont need registrations and only control the rendering of blocks in the world.
  • In the blockstates file you need to write down the properties (alphabetic order, I guess) and assign corresponding models.

Yes that's right.  For modded blocks Forge always looks for the blockstates file with the same name as the block. 

re the alphabetic order:  The lines in your blockstates can be in any order.  The properties within a line, eg colour=red,facing=east vs facing=east,colour=red, are in some order that I don't know.  Maybe alphabetical, maybe something else, never bothered to figure it out.  If you get the order round the wrong way, the console error message will show you.

 

I still have two questions left:

  • Is the call of ModelBakery.addVariantName necessary and what does it do?
  • Is it possible to exclude states from being used in the blockstates file?

If you don't ModelBakery.addVariantName, you will get missing model errors.  It might seem redundant to have to use both ModelBakery and the Mesher, that's just how Vanilla does it...

 

Yes I think you can exclude states, vanilla seems to do it, but I never figured out exactly how.  To be honest, once I figured out that I could get the same effect by listing the 16 blockstates in one blockstates file, I didn't bother looking.  If you work it out, let me know?

 

-TGG

Posted

Thanks for the answer, I made it work now!  ;D

 

I did a bit of search and read in the minecraft code and figured out the following:

  • The excluding magic in Vanilla happens in the method
    BlockModelShapes.registerAllBlocks()

    .
    There, the blocks are registered with the corresponding blockstate names and a StateMap.

  • The exclusion happens in the StateMap. The properties to exclude are saved in the field
    listProperties

    .

  • The StateMap can also map different blockstates to different files. The property which controls the mapping is saved in the
    property

    field. The value of this property (if existent) is used as the name for the blockstates file, if

    property

    is null, the block name is used. The value of the field

    suffix

    is then appended to the name. The property of the mapping is also excluded from the final property map.

  • FINALLY: Doing the exclusion for modded Blocks:
    It's relatively easy as well... During the preInit phase (maybe before the addVariantName method call) you need to execute this method:

ModelLoader.setCustomStateMapper(block, new StateMap.Builder().doWhateverYouWantToDoHere().build());


  • The builder class provides the necessary methods to create a StateMap which can exclude properties or name the blockstate files after one property.

 

Well, I think that's it for now! Thanks for your answers and have fun playing around with exclusion of properties  ;)

 

~BM

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.