Naming subblocks of any metablock with a single class?

1

I'm trying to make only one class be required to name the subblocks of any metablock that use this class at the time of the record, that is, name them as if they were parameter values, but without using one.

Although this revolves around an API (Minecraft Forge), I think the problem is more of Java, so here is a brief explanation of how it works what I intend to do.

A metablock is made up of subblocks, which are variations of the same block (for example, the same block, but only changes the texture and name). Each subblock needs a name to identify it. These names are listed in the ExemploItemBlock class in a String[] , and are then named in nomeDoMetablock.nomeDoSubBlock format (eg ExemploMetablock.azul , ExemploMetablock.verde , etc.)

// Classe ExemploItemBlock

public static final String[] SUBNAMES = new String[] {"azul", "verde", "amarelo"};

@Override
public String getUnlocalizedName(ItemStack itemStack) 
{
    int i = itemStack.getItemDamage();
    return getUnlocalizedName() + "." + SUBNAMES[i];
}

Then the ExemploMetaBlock metablock is instantiated and registered with

// Classe onde são feitos os registros   

public static Block ExemploMetaBlock = new ExemploMetaBlock(); 

GameRegistry.registerBlock(ExemploMetaBlock, ExemploItemBlock.class, "ExemploMetaBlock");

After this, everything works without problems, however I would have to create an ItemBlock class for each new metablock I want to do, and I do not find this very practical or appropriate, thinking better to create a single class to be used by any future metablock .

As you can see, the second parameter of the GameRegistry.registerBlock() method (which is an API method) requires a value of type Class . And that's where the problem is: how do I make the class ExemploItemBlock dynamic without using instances?

I even tried to add a String [] parameter in the ExemploItemBlock constructor and use an instance with the names in place of the class name, but, as expected, accused type mismatch, as it is only Class o type accepted.

I searched everywhere for a way to do this, but I only found two ways:

1. create an ItemBlock class for each new metablock; 2. change SUBNAMES[i] in getUnlocalizedName() by i or itemStack.getItemDamage() naming so the subblocks by numbers instead of names (eg ExemploMetaBlock.0 , ExemploMetaBlock.1 , etc.), without having to use String [] or anything and becoming a universal class. But this way is also very antipractical, because then it is very difficult to identify which subblock is which.

So my question is: is there any way to get a Universal ItemBlock class, but naming the subblocks by names (words)?

Class Content: ExampleBetaBlock , ExampleItemBlock .

    
asked by anonymous 01.02.2016 / 22:41

1 answer

1

I ended up finding the solution in Forge itself, how can it be matched here .

But for the sake of information, I'll give you an explanation of the solution.

I did not know, but the GameRegistry.registerBlock() method also accepts a fourth parameter, of type Object[] . So just put the list with the names inside the Object[] , just start the String[] variable from the ExemploMetablock , and pass the values set in the Object [] parameter to the String[] variable. Staying like this:

public static String[] SUBNAMES;
private IIcon[] icon;

public ExemploMetaBlock(Material material, String name, CreativeTabs tab, String[] subnames)
{
    super(material, name, tab);
    SUBNAMES = subnames;
}

And instead of using the ExemploItemBlock class, a class created separately, in the parameter Class , I recommend that you instead use a class that already exists in the Minecraft code itself and does almost the same thing as ExemploItemBlock , which is the class ItemMultiTexture (if you do not have anything else that does not have ItemMultiTexture ). Getting the record like this:

public static final String[] SubNames = new String[] {"azul", "verde", "amarelo", "vermelho"}; 
public static Block ExemploMetablock = new ExemploMetablock(Material.rock, "ExemploMetablock", Tabs.ExemploModTab, SubNames); 

GameRegistry.registerBlock(ExemploMetablock, ItemMultiTexture.class, "ExemploMetablock", new Object[]{SubNames});

However, this will not compile. The error NoSuchMethodException will occur in the registry line ( GameRegistry.registerBlock ....).

The constructor of class ItemMultiTexture takes the values set in the parameters of the registerBlock() method, which correspond to the types of the parameters of its constructor, which are Block, Block, String[] .

Have you been informed String[] ? Yes. Was Block informed? Yes. Was it reported a second Block ? No. "There is no such method", there is no constructor of ItemMultiTexture with parameters Block, String[] .

This happens because, as we said, the constructor of class ItemMultiTexture requires two values Block .

To solve this, simply create a new class (or replace ExemploItemBlock ) by extending ItemMultiTexture and that super the two Block s in the parameter. Staying like this:

public class ItemMultiTextureHelper extends ItemMultiTexture
{
    public ItemMultiTextureHelper(Block block, String[] names)
    {
        super(block, block, names);
    }
}

And the registerBlock() like this:

GameRegistry.registerBlock(ExemploMetablock, ItemMultiTextureHelper.class, "ExemploMetablock", new Object[]{SubNames});

And one last thing, but not least: remove the static modifier from SUBNAMES , otherwise this will cause the biggest mess in future metablocks, such as all sub- blocks of metablocks being named with the names of the first created metablock, repeated sub-blocks, etc. (I've gone through these problems right now, and I've fixed removing static .) So the correct one is actually like this:

public String[] SUBNAMES;
    
03.02.2016 / 01:49