Jump to content

Recommended Posts

Posted

I'm having a problem where a bunch of subblocks that are essentially different colors of wool are all coming up in the creative tab with the name "Blackstone Cloth". I'm not quite sure how to resolve this matter, as firmly ordering my code to work hasn't helped

 

private final static String[] subNames =

{

"White", "Orange",  "Magenta", "Light Blue", "Yellow", "Lime Green",

"Pink", "Grey", "Light Grey", "Cyan", "Purple", "Blue", "Brown",

"Green", "Red", "Black"

};

 

public void preInit(FMLPreInitializationEvent event) {

                // Stub Method

        GameRegistry.registerBlock(redstoneCloth, "redstoneCloth");

       

        for (int ix = 0; ix < 16; ix++) {

    ItemStack oldRedCloth = new ItemStack(redstoneCloth, 1);

    ItemStack dye = new ItemStack(Item.dyePowder, 1, ix);

    ItemStack redCloth = new ItemStack(redstoneCloth, 1, ix);

   

    GameRegistry.addShapelessRecipe(redCloth, oldRedCloth, dye);

    LanguageRegistry.addName(redCloth, subNames[ix]+"stone Cloth");

    }

        }

Posted

Objects are passed by value (of object reference) in java (unless the argument an expression). It looks like the single reference is getting modified each time through the loop. But, that explanation doesn't make sense. So, ignore me.

 

I probably would have tried something like this first.

LanguageRegistry.addName(new ItemStack(redstoneClock, 1, ix), subNames[ix]+"stone Cloth");

If that didn't work, then I have to dig deeper. Sorry, I cannot be more helpful, not much to go by.

 

[editted for benefit of future readers with similar problem]

Posted

Arguments are passed by reference in java (unless the argument an expression). You are passing the same reference every time in your loop, then altering where it points (not passing a new reference each time).

 

Try this for the LanguageRegistry:

LanguageRegistry.addName(new ItemStack(redstoneClock, 1, ix), subNames[ix]+"stone Cloth");

You can do something similar for the recipe.

Sorry... but he is already creating a new instance of the ItemStack in each iteration of the loop, that is not the answer (it would be if he wasn't).

 

@OP: Can you post your Block or Item code? I'm guessing your issue is you forgot to designate an ItemBlockWithMetadata or return appropriately distinct unlocalized names for each stack. Check here for an example of a block with subtypes. Using that your language registry will work just fine as it is.

Posted

Arguments are passed by reference in java (unless the argument an expression). You are passing the same reference every time in your loop, then altering where it points (not passing a new reference each time).

 

Try this for the LanguageRegistry:

LanguageRegistry.addName(new ItemStack(redstoneClock, 1, ix), subNames[ix]+"stone Cloth");

You can do something similar for the recipe.

Sorry... but he is already creating a new instance of the ItemStack in each iteration of the loop, that is not the answer (it would be if he wasn't).

 

@OP: Can you post your Block or Item code? I'm guessing your issue is you forgot to designate an ItemBlockWithMetadata or return appropriately distinct unlocalized names for each stack. Check here for an example of a block with subtypes. Using that your language registry will work just fine as it is.

 

You are more likely correct. I am missing something. Sorry.

Posted

Arguments are passed by reference in java (unless the argument an expression). You are passing the same reference every time in your loop, then altering where it points (not passing a new reference each time).

 

Try this for the LanguageRegistry:

LanguageRegistry.addName(new ItemStack(redstoneClock, 1, ix), subNames[ix]+"stone Cloth");

You can do something similar for the recipe.

Your remark indicates your lack of java knowledge. Please learn java and then correct people.

Why can't you just admit when you are wrong? Look:

for (int i = 0; i < 4; ++i) {
ItemStack stack = new ItemStack(someItem);
// stack is declared and instantiated as a new reference each iteration, it is NOT the same reference
// and this code will work fine
LanguageRegistry.addName(stack, "some name");
}

Yes, that is exactly the same as what you suggested but with two lines instead of one, which is exactly what the OP is already doing. If you are so awesome at Java, then please, explain to me how that is wrong. I'm just a hobbyist, after all, whereas you are a self-proclaimed Java and C++ developer; enlighten me.

Posted

You did not run that code. Prove me wrong by running it, or shut up.

<sigh> I have run this code many times just fine, but I doubt you will take my word for it. It's disappointing that you persist in your obstinance rather than either a) showing why I'm wrong, or b) admitting that you are wrong and gracefully accepting it and perhaps learning from it, as I will do if you demonstrate a fault in my code. There is nothing wrong with being wrong except for continuing to be wrong when you know or should know otherwise.

 

Wait.. Are you actually serious? You do realise that coolAlias is one of the best modders out?

Err, I wouldn't say that, but thanks xD There are plenty of things about Java that I have no clue about, but I get by with what I know.

Posted

I explained why it was wrong. A reference to a reference is still a reference. The original reference is easily changed even after passing it to a method. If the method stores the reference, it stores where it points. If that reference is later changed by reassignment, if changes the original as well. Simple java. This is the main reason that objects have a .copy() method. It allows a clean address to be used.

Except Java passes by value, not by reference:

public void aMethod() {
ItemStack stack = new ItemStack(Item.diamond);
bMethod(stack);
System.out.println(stack.toString());
// changing stack to null or anything else here does not affect what becomes of the stack sent
// to bMethod, nor does it change what a reference created in bMethod points to
}

public void bMethod(ItemStack stack) {
ItemStack pointer = stack;
stack = new ItemStack(Item.emerald);
System.out.println(stack.toString()); // prints the emerald stack
System.out.println(pointer .toString()); // prints the diamond stack from aMethod
}

If the stack from aMethod and the pointer from bMethod both point at the same memory location, then whatever one does to that data will be reflected in the other; but changing the location that one of those points to does NOT change what the other one points to. Sorry, but you are still wrong.

Posted

Only if the argument is an expression or native type - like int, float, etc.

In C++ that would be true, but in Java all variables are passed by value; for non-native types, the value is always a copy of the memory address (maybe not always, but I'm pretty sure that's the case). Unlike C++, you cannot pass by reference in Java, even when passing a memory address. Java is "pass by reference by value", as they like to say ;)

 

EDIT: Here is a link that explains it probably better than I am: http://stackoverflow.com/questions/40480/is-java-pass-by-reference

Posted

Only if the argument is an expression or native type - like int, float, etc.

In C++ that would be true, but in Java all variables are passed by value; for non-native types, the value is always a copy of the memory address (maybe not always, but I'm pretty sure that's the case). Unlike C++, you cannot pass by reference in Java, even when passing a memory address. Java is "pass by reference by value", as they like to say ;)

 

EDIT: Here is a link that explains it probably better than I am: http://stackoverflow.com/questions/40480/is-java-pass-by-reference

 

You can test following: Change the stack size of the ItemStack argument -> it is also changed outside of the method:

doSomething() {
    ItemStack stack = new ItemStack(Block.dirt, 1);
    incrStackSize(stack);
    System.out.println(stack.stackSize); // is now 64 here, too!
}
incrStackSize(ItemStack stack) {
    System.out.println(stack.stackSize); // is here 1
    stack.stackSize = 64;
    System.out.println(stack.stackSize); // is now 64
}

 

If you re-assign the "pointer", it will hold the new address of that reference!

doSomething() {
    ItemStack stack = new ItemStack(Block.dirt, 1);
    incrStackSize(stack);
    System.out.println(stack.stackSize); // is still 1!
}
incrStackSize(ItemStack stack) {
    stack = new ItemStack(Block.sand, 64)
    System.out.println(stack.stackSize); // is here 64
}

 

That is true for C++ pointers as well as for Java "pointers"

The only exception is in VB.NET where you can say that a parameter of a method is a direct reference (ByRef) and thus you can actually assign a new reference, but that's another language entirely...

Don't ask for support per PM! They'll get ignored! | If a post helped you, click the "Thank You" button at the top right corner of said post! |

mah twitter

This thread makes me sad because people just post copy-paste-ready code when it's obvious that the OP has little to no programming experience. This is not how learning works.

Posted

~snip~

^^ That's what I was trying to say, though in C++ you can pass a pointer by reference, in which case you can change the original pointer's address... the source of many a C++ coder's nightmares, to be sure :P

 

Pretty sure anyway, it's been many many years since I've touched C++, so I might be terribly wrong about that statement.

Posted

~snip~

^^ That's what I was trying to say, though in C++ you can pass a pointer by reference, in which case you can change the original pointer's address... the source of many a C++ coder's nightmares, to be sure :P

 

Pretty sure anyway, it's been many many years since I've touched C++, so I might be terribly wrong about that statement.

 

Yes, you can use the & as an operator in C++ like method(&pointer);

 

B2T: Can we see your Item class, I'm pretty sure you forgot to override getUnlocalizedName(...)

https://github.com/SanAndreasP/EnderStuffPlus/blob/master/java/sanandreasp/mods/EnderStuffPlus/item/ItemESPPearls.java#L81-L83

 

Also I suggest you don't use the LanguageRegistry anymore, since in 1.7 it's not there anymore and 1.6.4 already supports .lang files in your resource folder

https://github.com/SanAndreasP/EnderStuffPlus/blob/master/resources/assets/enderstuffp/lang/en_US.lang

Don't ask for support per PM! They'll get ignored! | If a post helped you, click the "Thank You" button at the top right corner of said post! |

mah twitter

This thread makes me sad because people just post copy-paste-ready code when it's obvious that the OP has little to no programming experience. This is not how learning works.

Posted

Arguments are passed by reference in java (unless the argument an expression). You are passing the same reference every time in your loop, then altering where it points (not passing a new reference each time).

 

Try this for the LanguageRegistry:

LanguageRegistry.addName(new ItemStack(redstoneClock, 1, ix), subNames[ix]+"stone Cloth");

You can do something similar for the recipe.

Sorry... but he is already creating a new instance of the ItemStack in each iteration of the loop, that is not the answer (it would be if he wasn't).

 

@OP: Can you post your Block or Item code? I'm guessing your issue is you forgot to designate an ItemBlockWithMetadata or return appropriately distinct unlocalized names for each stack. Check here for an example of a block with subtypes. Using that your language registry will work just fine as it is.

 

package wrink.dappercraft;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockColored;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemDye;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;

public class RedstoneClothItem extends ItemBlock
{
    public RedstoneClothItem(int par1)
    {
        super(par1);
        this.setMaxDamage(0);
        this.setHasSubtypes(true);
    }

    @SideOnly(Side.CLIENT)

    /**
     * Gets an icon index based on an item's damage value
     */
    public Icon getIconFromDamage(int par1)
    {
        return Block.cloth.getIcon(2, BlockColored.getBlockFromDye(par1));
    }

    /**
     * Returns the metadata of the block which this Item (ItemBlock) can place
     */
    public int getMetadata(int par1)
    {
        return par1;
    }

    @Override
    /**
     * Returns the unlocalized name of this item. This version accepts an ItemStack so different stacks can have
     * different names based on their damage or NBT.
     */
    public String getUnlocalizedName(ItemStack par1ItemStack)
    {
        return super.getUnlocalizedName() + "." + ItemDye.dyeColorNames[RedstoneCloth.getBlockFromDye(par1ItemStack.getItemDamage())];
    }
}

 

package wrink.dappercraft;

import java.util.List;
import java.util.Random;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemDye;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import net.minecraft.world.World;

public class RedstoneCloth extends ClothBlock
{

private Icon[] iconArray;

public RedstoneCloth(int par1, Material par2Material) {
	super(par1, par2Material);
	setUnlocalizedName("redCloth").setTextureName("dappercraft:redstoneCloth").setCreativeTab(CreativeTabs.tabBlock);
}

@SideOnly(Side.CLIENT)

    /**
     * From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
     */
    public Icon getIcon(int par1, int par2)
    {
        return this.iconArray[par2 % this.iconArray.length];
    }

    /**
     * Determines the damage on the item the block drops. Used in cloth and wood.
     */
    public int damageDropped(int par1)
    {
        return par1;
    }

    /**
     * Takes a dye damage value and returns the block damage value to match
     */
    public static int getBlockFromDye(int par0)
    {
        return ~par0 & 15;
    }

    /**
     * Takes a block damage value and returns the dye damage value to match
     */
    public static int getDyeFromBlock(int par0)
    {
        return ~par0 & 15;
    }

    @SideOnly(Side.CLIENT)

    /**
     * returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
     */
    public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List)
    {
        for (int j = 0; j < 16; ++j)
        {
            par3List.add(new ItemStack(par1, 1, j));
        }
    }

    @SideOnly(Side.CLIENT)

    /**
     * When this method is called, your block should register all the icons it needs with the given IconRegister. This
     * is the only chance you get to register icons.
     */
    public void registerIcons(IconRegister par1IconRegister)
    {
        this.iconArray = new Icon[16];

        for (int i = 0; i < this.iconArray.length; ++i)
        {
            this.iconArray[i] = par1IconRegister.registerIcon(this.getTextureName() + "_" + ItemDye.dyeItemNames[getDyeFromBlock(i)]);
        }
    }
    
    @SideOnly(Side.CLIENT)
    public void randomDisplayTick(World world, int x, int y, int z, Random random)
    {
    	float f1 = (float)x+.5f;
    	float f2 = (float)y+1.1f;
    	float f3 = (float)z+.5f;
    	float f4 = random.nextFloat()*1.4f-.7f;
    	float f5 = (random.nextFloat()*-1.4f+.7f);
    	
    	world.spawnParticle("reddust", (double) f1+f4, f2, f3+f5, 0, 0, 0);
    }
}

 

Posted

Simple, without one you see a block's name something like this, for instance:

 

"tile.blockName.name"

 

In the .lang file, you just need to put that equal to the correct value like:

 

tile.blockName.name=My Real Block Name

 

If all's well and it's in the right place, the name in game should be:

 

"My Real Block Name"

 

Hope that helped! :D

-Mitchellbrine

 

Minecraft can do ANYTHING, it's coded in Java and you got the full power of Java behind you when you code. So nothing is impossible.

It may be freaking fucking hard though, but still possible ;)

 

If you create a topic on Modder Support, live by this motto:

I don't want your charity, I want your information
Posted

but it's a multiblock. how would I add different names for different metadata?

 

Also, I changed my code and now all the blocks I added have the proper names except for redstone cloth, which is still blackstone cloth. apparently I typed

 

GameRegistry.registerBlock(redstoneCloth, "redstoneCloth");

 

instead of

 

GameRegistry.registerBlock(redstoneCloth, RedstoneClothItem.class);

Posted

You can either a) have an entry in your lang file for each metadata version of the block (based on the unlocalized name that you return), or b) have one entry for the name of your block and override the getItemStackDisplayName method to return a combination of your block's translated name plus the dye color's translated name.

 

Example:

@Override
public String getItemStackDisplayName(ItemStack stack) {
return StatCollector.translateToLocal(getUnlocalizedName()) + ItemDye.dyeItemNames[stack.getItemDamage() % ItemDye.dyeItemNames.length];
}

Posted

public class RedstoneClothItem extends ItemBlock

 

idk if this is related to the names problem,

but shouldnt that be ItemBlockWithMetadata for the subtyping of the items?

 

I was having issues with block subtypes not long ago

and after reading a CoolAlias post elsewhere about IBWMD

a bunch of my problems cleared up

with proper metadata passing between Block form and Item form of the thing

 

maybe this will help, maybe not

but it sounds like you are having Subtype issues (name in particular) and the IBWMD helps take care of meta/subtype issues

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.