Jump to content

[1.9] Forge API of some sort? [UNSOLVED + A few questions]


Recommended Posts

Posted

So with my endeavors of programming I have come across and interesting question which I am not sure has an answer to but I will ask it anyway. With java if you do not understand a specific method or class you can go to Oracle's website and look up API documentation. What I want to know is well, is there a documentation like that for forge. Because someone new coming to forge there are a lot of methods which you must use to register blocks and so on and so forth. Being able to learn from an API I think is very important and its how I fix issues when I cannot figure it out. Plus fixing issues on my own is much more satisfying. So if there is any form of this please link it to me because from my searches I cannot find anything really like it. If there is not however then how do all of you guys learn? Like honestly is it just by scavenging the forums and tutorials?

 

Anyway on to my other questions. For one I have been getting crashes specific to Rendering items when doing durability does anyone know a fix?

 

net.minecraft.util.ReportedException: Rendering screen
at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1174) ~[EntityRenderer.class:?]
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1135) ~[Minecraft.class:?]
at net.minecraft.client.Minecraft.run(Minecraft.java:401) [Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_79]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_79]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.7.0_79]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.7.0_79]
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
at GradleStart.main(GradleStart.java:26) [start/:?]
Caused by: java.lang.NullPointerException
at net.minecraft.client.renderer.RenderItem.renderItemOverlayIntoGUI(RenderItem.java:425) ~[RenderItem.class:?]
at net.minecraft.client.gui.inventory.GuiContainer.drawSlot(GuiContainer.java:319) ~[GuiContainer.class:?]
at net.minecraft.client.gui.inventory.GuiContainer.drawScreen(GuiContainer.java:118) ~[GuiContainer.class:?]
at net.minecraftforge.client.ForgeHooksClient.drawScreen(ForgeHooksClient.java:309) ~[ForgeHooksClient.class:?]
at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1147) ~[EntityRenderer.class:?]

 

This is the class I am using:

 

public class ItemCraftingDamage extends Item {
public ItemCraftingDamage() {

	super();
	setMaxStackSize(1);
	setNoRepair();
}

@Override
public boolean hasContainerItem() {
	return true;
}

public ItemStack getContainerItemStack(ItemStack stack) {
	if (stack.getItem() == this) {
		stack.setItemDamage(stack.getItemDamage() + 1);
		return stack;
	} else {
		ItemStack newStack = new ItemStack(this);
		newStack.setItemDamage(newStack.getMaxDamage());
		return newStack;
	}
}

public boolean doesContainerItemLeaveCraftingGrid(ItemStack is) {
	return false;
}

 

Another question I have is now regarding setRegistry and getRegistry. I know that using this is horrible:

item.getUnlocalizedName().substring(5)

But when I try to change it to getRegistry and set Registry it does not find my textures or files. If I had an API to look at I would read up what the differences are between the two. I am pretty sure that the way Registry and Unlocalized names find textures is slightly different but because I have no documentation to fall back to I am asking it here (specifically for Items, I noticed threw other threads that Blocks need to be registered twice for Item and Block but items I am slightly confused with.

 

Lastly I posted this in my other thread but it was farther down so I am too sure many people saw it so I will just copy and past it here:

 

While I am here I may as well go back to my original question on block ids and item ids and ask for help on fixing on of the main functionalities of my mod. The hammer is my tool which could be used in a crafting table or u could right click it on blocks to see a change in the world. This was working but with all the id issues I have tried rewriting it but I cannot figure out how to get around the ids. Here is the code I have right now:

 

Inside the Hammer class:

@Override
public boolean onItemUse(ItemStack par1ItemStack,
		EntityPlayer par2EntityPlayer, World par3World, int par4, int par5,
		int par6, int par7, float par8, float par9, float par10) {
	int id = par3World.getBlockId(par4, par5, par6);
	int meta = par3World.getBlockMetadata(par4, par5, par6);
	ItemStack output = Recipes.getHammerRecipe(id, meta);

	if(output != null) {
		String paricle = "explode";
		par3World.spawnParticle(paricle, par4, par5 + 1D, par6, 0D, 0D, 0D);
		par3World.spawnParticle(paricle, par4 + 1, par5 + 1D, par6, 0D, 0D, 0D);
		par3World.spawnParticle(paricle, par4 + 1, par5 + 1D, par6 + 1, 0D, 0D, 0D);
		par3World.spawnParticle(paricle, par4, par5 + 1D, par6 + 1, 0D, 0D, 0D);

		par3World.setBlock(par4, par5, par6, output.getItem(), Recipes.getIgroneMeta(id, meta) ? meta : output.getItemDamage(), 2);

		if(!par2EntityPlayer.capabilities.isCreativeMode)
			par1ItemStack.damageItem(2, par2EntityPlayer);

		return true;
	}

	return false;
}

Then inside the actual recipe class:

public static HashMap<HammerRecipe, ItemStack> transformBlocks = new HashMap<HammerRecipe, ItemStack>(); 
public static ItemStack getHammerRecipe(int id, int meta) {
	for (Entry<HammerRecipe, ItemStack> entry : transformBlocks.entrySet())
	    if(entry.getKey().id == id && (entry.getKey().meta == meta || entry.getKey().igroneData))
	    	return entry.getValue();
	return null;
}

public static boolean getIgroneMeta(int id, int meta) {
	for (HammerRecipe recipe : transformBlocks.keySet())
	    if(recipe.id == id && (recipe.meta == meta || recipe.igroneData))
	    	return recipe.igroneData;
	return false;
}
public static void addRecipe(HammerRecipe input, HammerRecipe output) {
	if(!input.isItems && !output.isItems)
		transformBlocks.put(input, new ItemStack(output.id, 1, output.meta));

	CraftingManager.getInstance().addShapelessRecipe(new ItemStack(output.id, 1, output.meta),
			new Object[] {new ItemStack(ModItems.hammer, 1, Short.MAX_VALUE), 
		new ItemStack(input.id, 1, input.meta)});
}

public static void addRecipe(HammerRecipe output, HammerRecipe ... input) {
	Object[] objInput = new Object[input.length + 1];
	for(int i = 0; i < input.length; i++) {
		objInput[i] = new ItemStack(input[i].id, 1, input[i].meta);
	}

	objInput[input.length] = new ItemStack(ModItems.hammer, 1, Short.MAX_VALUE);
	CraftingManager.getInstance().addShapelessRecipe(new ItemStack(output.id, 1, output.meta),
			objInput);	
}

public static class HammerRecipe {
	public boolean isItems, igroneData;
	public int id, meta;

	public HammerRecipe(Block Blocks, int meta) {
		this.id = Blocks.BlockID;
		this.meta = meta;
		this.isItems = false;
	}

	public HammerRecipe(Block Blocks) {
		this.id = Blocks.BlockID;
		this.meta = 0;
		this.isItems = false;
	}

	public HammerRecipe(Item Items) {
		this.id = Items.ItemID;
		this.meta = 0;
		this.isItems = true;
	}

	public HammerRecipe(Item Items, int meta) {
		this.id = Items;
		this.meta = meta;
		this.isItems = true;
	}

	public HammerRecipe setIgroneMeta() {
		this.igroneData = true;
		return this;
	}
}

 

So basically I could then create a Hammer Recipe which would now not only work in a crafting table but when I right click for example planks it would convert it to the new plank.

This is what the recipe would look like just for reference:

addRecipe(new HammerRecipe(Blocks.planks, 0), 				new HammerRecipe(Blocks.planks, 1));
	addRecipe(new HammerRecipe(Blocks.planks, 1), 				new HammerRecipe(Blocks.planks, 2));
	addRecipe(new HammerRecipe(Blocks.planks, 2), 				new HammerRecipe(Blocks.planks, 3));
	addRecipe(new HammerRecipe(Blocks.planks, 3), 				new HammerRecipe(Blocks.planks, 0));

I hope what I am trying to do even makes sense. In 1.6 I had all this working and really would love to fix it up and expand with the many more ideas I have for the mod.

(But again you can see how before with planks it was all meta data so I am not even sure if this is possible anymore the way I want to do it. If it is not do you have any suggestions?)

 

I know this is a lot but thanks so much for reading and responding! :)

  • Replies 57
  • Created
  • Last Reply

Top Posters In This Topic

Posted

Yes, Forge has documentation. It is called in-source Javadoc.

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

Yes, Forge has documentation. It is called in-source Javadoc.

 

Yes but the javadocs are very bare.... like 1 or 2 line descriptions are not that helpful

Posted

You can blame random people using MCPBot for that.  I find that more often than not that's enough.

Forge-specific comments are much better than the ones on vanilla methods.

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

You can blame random people using MCPBot for that.  I find that more often than not that's enough.

Forge-specific comments are much better than the ones on vanilla methods.

 

Now that is true. I noticed that forge specific is much better. But still. Like when u setUnlocalizedName opposed to setRegistryName. What are the actual differences? By reading the javadocs it hard to see the difference from reading the docs they look the same and the setRegistry even says that it is a replacement for setUnlocalizedName.subString stuff. But it doesn't seem to do the same when replaced. This is my point on docs

Posted

unlocalized name is, well, the unlocalized name. It is used to look up the displayed name in the .lang files. Registry name is the ID of your Item (like "minecraft:stone"). It is the identifier for your stuff (item, block, enchantment, etc) and it needs to stay consistent since it is used to keep the number-based IDs in sync.

Okay so that makes sense thank you. But now I that I know that I still need unlocalized name then to actually get a texture. To do it properly I should be using both unlocalized name and registryname. Correct?

Posted

Not really. I assume by texture you mean model (in 1.8+ you define models, not textures. the model then has one or more textures). To bind your model to an Item you use

ModelLoader.setCustomModelResourceLocation

. What you pass in there can be completely independent of unlocalized- and/or registry name. It can be based on the registry name if you want to (unlocalized doesn't really make sense), but it does not have to. It merely tells Minecraft "hey, use this model file". For Blocks IStateMapper does this association, check the default implementation to see what it does by default.

Okay this explanation made a lot of sense and I have actually been able to switch from UnlocalizedName to RegistryName now and it works. What was broken was the fact that in my

 

Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0,
			new ModelResourceLocation(item.getRegistryName(), "inventory"));

had

Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(item, 0,
			new ModelResourceLocation(Reference.MODID + ":" + item.getRegistryName(), "inventory"));

 

this was causing my mod to not find the textures. I did not realize that Registry name already had my mod id attached to it unlike unlocalized name. However for the en_US file to work a unlocalizedname still needed to be set. But this fixed one of my issues thank you. Anyone got any input for my other issues?

Posted

Okay so I have been working on my ItemCraftingDamage class and got it to not crash anymore and semi work. To fix the error I had to fix

public ItemStack getContainerItemStack(ItemStack stack) {
	...
}

to

public ItemStack getContainerItem(ItemStack stack) {
...
}

 

Now it does not crash and when I craft the durability bar goes down however after the first craft a red ZERO appears in the bottom right of the item as if it does not exist anymore. As long as I do not remove it from the crafting grid I can craft as many times as the durability was set. But if I try to remove it. It just disappears... Any idea's?

Posted

The answer is both:

a) in the content of that method which you have omitted

and

b) the itemstack has a size of freaking zero, what did you expect vanilla to do with it when you tried to pick it up?

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

The answer is both:

a) in the content of that method which you have omitted

and

b) the itemstack has a size of freaking zero, what did you expect vanilla to do with it when you tried to pick it up?

 

I omitted the code because I put it higher up and felt it irrelevant to repost it. Lol. And the stack size is getting the item removing some damage and then returning it. What do you mean by its zero? Or am I being stupid and missing something major lol? (I'm gonna assume the latter)

Posted
What do you mean by its zero? Or am I being stupid and missing something major lol? (I'm gonna assume the latter)

 

Fur the love.

 

a red ZERO appears in the bottom right of the item as if it does not exist anymore

 

That means the itemstack size is 0.  ItemStacks can't set themselves to null, it's up to the container/itemUse method/whatever method to detect stacksize of 0 and remove it from there.

 

Try this:

 

	public ItemStack getContainerItemStack(ItemStack stack) {
	stack.damageItem(1,null);
	if(stack.stacksize <= 0)
		stack = null;
	return stack;
}

 

(It literally doesn't matter if you check stack.getItem() == this because it should always be this, if it isn't, that's a serious bug in vanilla that makes no god damn sense and should never happen, because the

getContainerItemStack()

is invoked by doing

stack.getItem().getContainerItemStack(stack)

: the stack invokes its own item's method, passing itself).

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

What do you mean by its zero? Or am I being stupid and missing something major lol? (I'm gonna assume the latter)

 

Fur the love.

 

a red ZERO appears in the bottom right of the item as if it does not exist anymore

 

That means the itemstack size is 0.  ItemStacks can't set themselves to null, it's up to the container/itemUse method/whatever method to detect stacksize of 0 and remove it from there.

 

Try this:

 

	public ItemStack getContainerItemStack(ItemStack stack) {
	stack.damageItem(1,null);
	if(stack.stacksize <= 0)
		stack = null;
	return stack;
}

 

(It literally doesn't matter if you check stack.getItem() == this because it should always be this, if it isn't, that's a serious bug in vanilla that makes no god damn sense and should never happen, because the

getContainerItemStack()

is invoked by doing

stack.getItem().getContainerItemStack(stack)

: the stack invokes its own item's method, passing itself).

 

I tried doing this and but using getContainerItemStack it give me this error:

Description: Rendering screen

java.lang.NullPointerException: Rendering screen
at net.minecraft.client.renderer.RenderItem.renderItemOverlayIntoGUI(RenderItem.java:425)
at net.minecraft.client.gui.inventory.GuiContainer.drawSlot(GuiContainer.java:319)
at net.minecraft.client.gui.inventory.GuiContainer.drawScreen(GuiContainer.java:118)
at net.minecraftforge.client.ForgeHooksClient.drawScreen(ForgeHooksClient.java:309)
at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1147)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1135)
at net.minecraft.client.Minecraft.run(Minecraft.java:401)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:26)

 

and when I leave it as

public ItemStack getContainerItem(ItemStack stack) {
	stack.damageItem(1,null);
	if(stack.stacksize <= 0)
		stack = null;
	return stack;

it give me this error:

Description: Updating screen events

java.lang.NullPointerException: Updating screen events
at net.minecraft.item.ItemStack.damageItem(ItemStack.java:346)
at com.zodsmar.items.ItemCraftingDamage.getContainerItem(ItemCraftingDamage.java:23)
at net.minecraftforge.common.ForgeHooks.getContainerItem(ForgeHooks.java:877)
at net.minecraft.item.crafting.ShapelessRecipes.getRemainingItems(ShapelessRecipes.java:33)
at net.minecraft.item.crafting.CraftingManager.func_180303_b(CraftingManager.java:344)
at net.minecraft.inventory.SlotCrafting.onPickupFromSlot(SlotCrafting.java:130)
at net.minecraft.inventory.Container.func_184996_a(Container.java:337)
at net.minecraft.client.multiplayer.PlayerControllerMP.func_187098_a(PlayerControllerMP.java:553)
at net.minecraft.client.gui.inventory.GuiContainer.handleMouseClick(GuiContainer.java:728)
at net.minecraft.client.gui.inventory.GuiContainer.mouseClicked(GuiContainer.java:447)
at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:616)
at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:582)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1791)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1114)
at net.minecraft.client.Minecraft.run(Minecraft.java:401)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:26)

 

and finally if I do this:

public ItemStack getContainerItem(ItemStack stack) {
		stack.setItemDamage(stack.getItemDamage() + 1);
		if(stack.stackSize <= 0)
			stack = null;
		return stack;}

It still makes the stack 0 after one craft. So yeah

Posted

Copy the stack before you modify and return it.

 

Any idea why not doing it would have the effect it---

 

Oh! I think I remember something about this now: the container item is constantly requested while the UI is open and if you modify the stack in the grid, as opposed to a copy, it ends up overwriting itself until it gets destroyed.

 

(Recipes are weird)

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 so to anyone who has suffered the same issue I has finally solved the problem (thank you guys for the help) the code is as follows.

The actual CrafgtingDamage Class:

public class ItemCraftingDamage extends Item {

public ItemCraftingDamage() {

	super();
	setMaxStackSize(1);

}

public boolean hasContainerItem(ItemStack itemstack) {
	return true;
}

public ItemStack getContainerItem(ItemStack stack) {
	ItemStack stackCopy = stack.copy();
		stackCopy.setItemDamage(stackCopy.getItemDamage() + 1);
		if(stack.stackSize <= 0)
			stackCopy = null;
		return stackCopy;
}

    public boolean doesContainerItemLeaveCraftingGrid(ItemStack is) {
        return false;
    }
}

(Which you just then extend inside the class you want to have crafting damage)

 

The for the actual recipe it is:

new ItemStack(*YOURITEM*, 1, OreDictionary.WILDCARD_VALUE)

 

Thats it.

 

Now does anyone know how to help me with my other issues :P

Posted

Okay so regard to making my item be able to change blocks based on a recipe on right click I was able to get the right click functionality working. Well kinda. So far I have been able to on right click get the position of a block and then change it to air if it is not air already. Here is the code for that:

public EnumActionResult onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
	BlockStateContainer id = worldIn.getBlockState(pos).getBlock().getBlockState();
	ItemStack output = Recipes.getHammerRecipe(id); 
	if(output != null){
	worldIn.spawnParticle(EnumParticleTypes.LAVA, hitX, hitY + 1D, hitZ, 0D, 0D, 0D);
	worldIn.spawnParticle(EnumParticleTypes.LAVA, hitX + 1, hitY + 1D, hitZ, 0D, 0D, 0D);
	worldIn.spawnParticle(EnumParticleTypes.LAVA, hitX + 1, hitY + 1D, hitZ + 1, 0D, 0D, 0D);
	worldIn.spawnParticle(EnumParticleTypes.LAVA, hitX, hitY + 1D, hitY + 1, 0D, 0D, 0D);
	if(!playerIn.capabilities.isCreativeMode)
		stack.damageItem(2, playerIn);

	worldIn.setBlockToAir(pos);
	System.out.println("TEST");
        return EnumActionResult.PASS;
	}
	return EnumActionResult.FAIL;
    }

So the actual ID and output i am not to sure on because what is messing me up in blockstates. Right now I can convert to air. Also the particles are no spawning I do not know why? So any idea's on how to get the block id and meta from block state. Then I want to check it and if it matches a recipe it will change the block to the new one. Based on a recipe. Do you guys see what I am trying to do here???

Posted

So I got the recipe working with no errors and everything seems to kinda be working up until it actually need to change the block. Ill show you guys all the code so you can see whats going on but I can explain it in a little bit more detail. Here is the code first.

public EnumActionResult onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
	BlockStateContainer id = worldIn.getBlockState(pos).getBlock().getBlockState();
	ItemStack output = Recipes.getHammerRecipe(id);
	if(output != null){
	worldIn.spawnParticle(EnumParticleTypes.LAVA, hitX, hitY + 1D, hitZ, 0D, 0D, 0D);
	worldIn.spawnParticle(EnumParticleTypes.LAVA, hitX + 1, hitY + 1D, hitZ, 0D, 0D, 0D);
	worldIn.spawnParticle(EnumParticleTypes.LAVA, hitX + 1, hitY + 1D, hitZ + 1, 0D, 0D, 0D);
	worldIn.spawnParticle(EnumParticleTypes.LAVA, hitX, hitY + 1D, hitY + 1, 0D, 0D, 0D);
	if(!playerIn.capabilities.isCreativeMode)
		stack.damageItem(2, playerIn);

	worldIn.setBlockState(pos, (IBlockState) output.getItem(), 2);
        return EnumActionResult.PASS;
}
	return EnumActionResult.FAIL;
    }

Recipes class:

public static HashMap<HammerRecipe, ItemStack> transformBlocks = new HashMap<HammerRecipe, ItemStack>();

public static ItemStack getHammerRecipe(BlockStateContainer id) {
	for (java.util.Map.Entry<HammerRecipe, ItemStack> entry : transformBlocks.entrySet())
	    if(entry.getKey().id == id)
	    	return entry.getValue();
	return null;
}

public static void addRecipe(HammerRecipe input, HammerRecipe output) {
	if(!input.isItems && !output.isItems)
		transformBlocks.put(input, new ItemStack(output.id.getBlock(), 1));

	GameRegistry.addShapelessRecipe(new ItemStack(output.id.getBlock(), 1),
			new Object[] {new ItemStack(ItemsAF.hammer, 1, Short.MAX_VALUE), 
		new ItemStack(input.id.getBlock(), 1)});
}

Then the actual hammer recipes class:

public class HammerRecipe {
public boolean isItems;
public BlockStateContainer id;

public HammerRecipe(Block Blocks) {
	this.id = Blocks.getBlockState();
	this.isItems = false;
}
}

 

So the code itself is fine up until it hits the worldIn.setBlockState(pos, (IBlockState) output.getItem(), 2); it errors on converting the ItemStack back to a blockstate. I feel like most of the code is good and the idea if sound but just the way Im dealing with blockstates is wrong. Any in sight would be nice. Here is the error just as an FYI:

 

java.lang.ClassCastException: net.minecraft.item.ItemMultiTexture cannot be cast to net.minecraft.block.state.IBlockState
at com.zodsmar.items.Hammer.onItemUse(Hammer.java:77)
at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:156)
at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:459)
at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1597)
at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2268)
at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2052)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1840)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1114)
at net.minecraft.client.Minecraft.run(Minecraft.java:401)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:26)

Posted

Okay so no one clearly knows how to solve my issue which is fine don't worry. I am just really hoping someone can answer this. I am trying to get the meta from a block which you have right clicked. The based on that meta check it with the recipe then change the block to a new meta. I have most of it the only thing I am having issues with is the ItemStack to BlockStateContainer. I will show you what I mean:

 

BlockStateContainer output = Recipes.getHammerRecipe(id);

 

public static ItemStack getHammerRecipe(BlockStateContainer id) {
	for (Entry<HammerRecipe, ItemStack> entry : transformBlocks.entrySet())
		if (entry.getKey().id == id)
			return entry.getValue();
	return null;
}

public static void addRecipe(HammerRecipe input, HammerRecipe output) {
	if (!input.isItems && !output.isItems)
		transformBlocks.put(input, new ItemStack(output.id.getBlock(), 1 ,output.meta));

 

The issue resides in Entry<HammerRecipe, ItemStack> because I can only set recipes using itemstack that require a metadata also I do not know how I can go from itemstack back to blockstatecontainer. Unless is there a way to create recipes without using ItemStack for metadata? I hope you understand what I am asking. If you don't please post because I really wanna get this fixed thanks! -Zods

Posted

You haven't included enough code to be able to figure out what that snippet is doing.  You haven't shown the rightClick method where you obtain the BlockState and pass it to this recipe method, or what one of the recipes looks like.

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

Why are you using the

Block

's

BlockStateContainer

as an ID? Use the

Block

(the block type, e.g.

Blocks.stone

), its

RegistryDelegate

(a unique identifier of the

Block

) or a specific

IBlockState

(the

Block

and a map of properties and values, e.g.

Blocks.stone

with its

VARIANT

property set to

GRANITE

).

 

An

ItemStack

isn't an

IBlockState

, you can't cast between them. If the

ItemStack

's

Item

is an

ItemBlock

, use

ItemBlock#getBlock

to get the

Block

,

Item#getMetadata(int)

to get the block metadata corresponding to the

ItemStack

's metadata and

Block#getStateFromMeta

to get the

IBlockState

corresponding to that metadata.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted

Sorry for not posting all the code here is all the code:

public EnumActionResult onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos,
		EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
	double x = pos.getX();
	double y = pos.getY();
	double z = pos.getZ();
	BlockStateContainer id = worldIn.getBlockState(pos).getBlock().getBlockState();
	Block output = Recipes.getHammerRecipe(id);
	IBlockState block = worldIn.getBlockState(pos);
	int meta = worldIn.getBlockState(pos).getBlock().getMetaFromState(block);
	if (output != null) {
		if (worldIn.isRemote) {
			worldIn.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, x, y + 1D, z, 0D, 0D, 0D, 1);
			worldIn.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, x + 1, y + 1D, z, 0D, 0D, 0D, 1);
			worldIn.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, x + 1, y + 1D, z + 1, 0D, 0D, 0D, 1);
			worldIn.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, x, y + 1D, z + 1, 0D, 0D, 0D, 1);
		}
		if (!playerIn.capabilities.isCreativeMode)
			stack.damageItem(2, playerIn);

		worldIn.setBlockState(pos, output.getBlock().getStateFromMeta(meta), 2);
		return EnumActionResult.PASS;
	}
	return EnumActionResult.FAIL;
}

 

		addRecipe(new HammerRecipe(Blocks.stonebrick), new HammerRecipe(Blocks.stone));

}

public static ItemStack getHammerRecipe(BlockStateContainer id) {
	for (Entry<HammerRecipe, ItemStack> entry : transformBlocks.entrySet())
		if (entry.getKey().id == id)
			return entry.getValue();
	return null;
}

public static void addRecipe(HammerRecipe input, HammerRecipe output) {
	if (!input.isItems && !output.isItems)
		transformBlocks.put(input, new ItemStack(output.id.getBlock(), 1 ,output.meta));

	GameRegistry.addShapelessRecipe(new ItemStack(output.id.getBlock(), 1), new Object[] {
			new ItemStack(ItemsAF.hammer, 1, Short.MAX_VALUE), new ItemStack(input.id.getBlock(), 1) });
}

For the recipe tho I wanna be able to do something like addRecipe(new HammerRecipe(Blocks.log , 1, 0), new HammerRecipe(Blocks.log, 1 ,1 ));

So to go from like Oak to Birch or something like that right now using BlockStateContainer I got it to work with stone to stonebrick. But I am not sure how to do it for blocks with meta. With the code does this make more sense now?

 

Oops also here is the HammerRecipe class:

public class HammerRecipe {
public boolean isItems;
public BlockStateContainer id;
public int meta;

public HammerRecipe(Block Blocks) {
	this.id = Blocks.getBlockState();
	this.isItems = false;
}

public HammerRecipe(Block Blocks, int meta) {
	this.id = Blocks.getBlockState();
	this.meta = meta;
	this.isItems = false;
}
}

Posted

Why are you using the

Block

's

BlockStateContainer

as an ID? Use the

Block

(the block type, e.g.

Blocks.stone

), its

RegistryDelegate

(a unique identifier of the

Block

) or a specific

IBlockState

(the

Block

and a map of properties and values, e.g.

Blocks.stone

with its

VARIANT

property set to

GRANITE

).

 

An

ItemStack

isn't an

IBlockState

, you can't cast between them. If the

ItemStack

's

Item

is an

ItemBlock

, use

ItemBlock#getBlock

to get the

Block

,

Item#getMetadata(int)

to get the block metadata corresponding to the

ItemStack

's metadata and

Block#getStateFromMeta

to get the

IBlockState

corresponding to that metadata.

 

Based on what you said here I was actually able to figure out everything I needed to everything works except now I need to figure out a way to limit only certain blocks like logs to be able to go when right clicking up to 15 meta (because this way I can get every type of wood ) but in a crafting grid it starts to give purple and black because minecraft doesn't actually have items for them in game so yeah. But for anyone wanting to see how I achieved this here is the code:

public static ItemBlock getHammerRecipe(Block id, int meta) {
	for (Entry<HammerRecipe, ItemStack> entry : transformBlocks.entrySet())
		if (entry.getKey().id == id && (entry.getKey().meta == meta || entry.getKey().igroneData))
			return (ItemBlock) entry.getValue().getItem();
	return null;
}
public static int getHammerRecipeMeta(Block id, int meta) { 
	for (Entry<HammerRecipe, ItemStack> entry : transformBlocks.entrySet())
		if (entry.getKey().id == id && (entry.getKey().meta == meta || entry.getKey().igroneData))
			return entry.getValue().getItemDamage();
	return 0;
}


public static boolean getIgroneMeta(Block id, int meta) {
	for (HammerRecipe recipe : transformBlocks.keySet())
	    if(recipe.id == id && (recipe.meta == meta || recipe.igroneData))
	    	return recipe.igroneData;
	return false;
}

public class HammerRecipe {
public boolean isItems;
public Block id;
public int meta;
boolean igroneData;

public HammerRecipe(Block Blocks) {
	this.id = Blocks.getBlockState().getBlock();
	this.isItems = false;
}

public HammerRecipe(Block Blocks, int meta) {
	this.id = Blocks.getBlockState().getBlock();
	this.meta = meta;
	this.isItems = false;
}

public HammerRecipe setIgroneMeta() {
	this.igroneData = true;
	return this;
}
}

 

	public EnumActionResult onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos,
		EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
	double x = pos.getX();
	double y = pos.getY();
	double z = pos.getZ();
	IBlockState block = worldIn.getBlockState(pos);
	Block id = worldIn.getBlockState(pos).getBlock();
	ItemBlock output = Recipes.getHammerRecipe(id, id.getMetaFromState(block));
	int meta = Recipes.getHammerRecipeMeta(id, id.getMetaFromState(block));

	if (output != null) {
		if (worldIn.isRemote) {
			worldIn.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, x, y + 1D, z, 0D, 0D, 0D, 1);
			worldIn.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, x + 1, y + 1D, z, 0D, 0D, 0D, 1);
			worldIn.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, x + 1, y + 1D, z + 1, 0D, 0D, 0D, 1);
			worldIn.spawnParticle(EnumParticleTypes.EXPLOSION_NORMAL, x, y + 1D, z + 1, 0D, 0D, 0D, 1);
		}
		if (!playerIn.capabilities.isCreativeMode)
			stack.damageItem(2, playerIn);

		worldIn.setBlockState(pos, output.getBlock().getStateFromMeta(meta), 2);
		return EnumActionResult.PASS;
	}
	return EnumActionResult.FAIL;
}

 

And an actual example of the recipes (And what I meant with logs LOL):

		addRecipe(new HammerRecipe(Blocks.log, 0), 					new HammerRecipe(Blocks.log, 1));
	addRecipe(new HammerRecipe(Blocks.log, 1), 					new HammerRecipe(Blocks.log, 2));
	addRecipe(new HammerRecipe(Blocks.log, 2), 					new HammerRecipe(Blocks.log, 3));
	addRecipe(new HammerRecipe(Blocks.log, 3), 					new HammerRecipe(Blocks.log, 4));
	addRecipe(new HammerRecipe(Blocks.log, 4), 					new HammerRecipe(Blocks.log, 5));
	addRecipe(new HammerRecipe(Blocks.log, 5), 					new HammerRecipe(Blocks.log, 6));
	addRecipe(new HammerRecipe(Blocks.log, 6), 					new HammerRecipe(Blocks.log, 7));
	addRecipe(new HammerRecipe(Blocks.log, 7), 					new HammerRecipe(Blocks.log, );
	addRecipe(new HammerRecipe(Blocks.log, , 					new HammerRecipe(Blocks.log, 9));
	addRecipe(new HammerRecipe(Blocks.log, 9), 					new HammerRecipe(Blocks.log, 10));
	addRecipe(new HammerRecipe(Blocks.log, 10), 				new HammerRecipe(Blocks.log, 11));
	addRecipe(new HammerRecipe(Blocks.log, 11), 				new HammerRecipe(Blocks.log, 12));
	addRecipe(new HammerRecipe(Blocks.log, 12), 				new HammerRecipe(Blocks.log, 13));
	addRecipe(new HammerRecipe(Blocks.log, 13), 				new HammerRecipe(Blocks.log, 14));
	addRecipe(new HammerRecipe(Blocks.log, 14), 				new HammerRecipe(Blocks.log, 15));
	addRecipe(new HammerRecipe(Blocks.log, 15), 				new HammerRecipe(Blocks.log, 0));

Posted

Okay so I got a new question. On rightclick I want to spawn a bolt of lightning where I am looking. However if its a block that can be converted via a recipe then do not do lightning but the recipe. Here is my code from 1.6 but I am un sure because Vec3 does not exist anymore.

 

	 public ItemStack onItemRightClick(ItemStack itemstack, World worldObj, EntityPlayer entityplayer)
 {
 if(itemstack.getItemDamage() >= 0){
	 float f = 1.0F;
	 float f1 = entityplayer.prevRotationPitch + (entityplayer.rotationPitch - entityplayer.prevRotationPitch) * f;
	 float f2 = entityplayer.prevRotationYaw + (entityplayer.rotationYaw - entityplayer.prevRotationYaw) * f;
	 double d = entityplayer.prevPosX + (entityplayer.posX - entityplayer.prevPosX) * (double)f;
	 double d1 = (entityplayer.prevPosY + (entityplayer.posY - entityplayer.prevPosY) * (double)f + 1.6200000000000001D) - (double)entityplayer.yOffset;
 	double d2 = entityplayer.prevPosZ + (entityplayer.posZ - entityplayer.prevPosZ) * (double)f;
 Vec3 vec3d = Vec3.createVectorHelper(d, d1, d2);
 	float f3 = MathHelper.cos(-f2 * 0.01745329F - 3.141593F);
 	float f4 = MathHelper.sin(-f2 * 0.01745329F - 3.141593F);
 	float f5 = -MathHelper.cos(-f1 * 0.01745329F);
 	float f6 = MathHelper.sin(-f1 * 0.01745329F);
 	float f7 = f4 * f5;
 	float f8 = f6;
 	float f9 = f3 * f5;
 	double d3 = 5000D;
 Vec3 vec3d1 = vec3d.addVector((double)f7 * d3, (double)f8 * d3 + 1, (double)f9 * d3);
 MovingObjectPosition movingobjectposition = worldObj.rayTraceBlocks_do_do(vec3d, vec3d1, false, true);
 if (movingobjectposition == null)
 	{
	 return itemstack;
 	}
 if (movingobjectposition.typeOfHit == EnumMovingObjectType.TILE)
 {
	 int i = movingobjectposition.blockX;
	 int j = movingobjectposition.blockY;
	 int k = movingobjectposition.blockZ;
	 world.spawnEntityInWorld(new EntityLightningBolt(world, i, j, k));
 }
 	itemstack.setItemDamage(0);
 }
 	return itemstack;
 }

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.