Reputation: 41
This question pertains to minecraft version 1.9
I am new to the modding scene and am having trouble with my test wood log block. I've extended the BlockLog class for my test wood block. However, every time I try to place the block in game, my game crashes. Here is my wood log class:
package bravoman.testmod.blocks;
import net.minecraft.block.BlockLog;
public class MangoLog extends BlockLog{
public MangoLog() {
super();
}
}
As of late, I have been following simple tutorials on youtube and this was how i learned to to create a new block. I took it one step further and instead of extending Block
, I went ahead and extended BlockLog
.
I've experimented with the BlockLog class, trying to override certain methods or adding in the enumerated type, but to no avail. I believe that there is a huge chunk of code missing, but without further experience in modding minecraft, I'm stuck here. I've also asked this question on the minecraft forums.Crash log posted below. Any help would be appreciated.
---- Minecraft Crash Report ----
// Why is it breaking :(
Time: 4/25/16 1:22 PM
Description: Unexpected error
java.lang.IllegalArgumentException: Cannot set property PropertyEnum{name=axis, clazz=class net.minecraft.block.BlockLog$EnumAxis, values=[x, y, z, none]} as it does not exist in BlockStateContainer{block=mm:mango_log, properties=[axis]}
at net.minecraft.block.state.BlockStateContainer$StateImplementation.withProperty(BlockStateContainer.java:204)
at net.minecraft.block.BlockLog.onBlockPlaced(BlockLog.java:51)
at net.minecraft.item.ItemBlock.onItemUse(ItemBlock.java:57)
at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:156)
at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:484)
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)
Upvotes: 1
Views: 961
Reputation: 5046
This is due to your use of BlockLog
, which has some state information for its direction but requires the subclass to implement it. They don't fully implement it since logs normally represent several different types, and there isn't a logical base for that. However, it doesn't make the state methods abstract so it isn't clear that this is required.
BlockLog
extends BlockRotatedPillar
, which defines its own state information. However, since logs have an additional state (where it is facing no direction and is bark on all sides), the pillar's state information isn't used and a separate state value is instead used. But BlockLog
doesn't register this and expects subclasses to do so (since they'd register other info anyways, and it would force the info to be overwritten). Since that registration doesn't happen, the wrong axis information is used, and the log tries to set log axis info when the game expects pilar axis info.
To fix it, look at the existing implementations of BlockLog
: BlockOldLog
(which does oak, birch, spruce, and jungle) and BlockNewLog
(which does acacia and dark oak).
For your case (where I assume you don't want to have any variants), the following would probably work (I haven't tested it, though):
package bravoman.testmod.blocks;
import net.minecraft.block.BlockLog;
public class MangoLog extends BlockLog{
public MangoLog()
{
super();
this.setDefaultState(this.blockState.getBaseState().withProperty(LOG_AXIS, BlockLog.EnumAxis.Y));
}
/**
* Convert the given metadata into a BlockState for this Block
*/
public IBlockState getStateFromMeta(int meta)
{
IBlockState state = this.getDefaultState();
switch (meta & 0b1100)
{
case 0b0000:
state = state.withProperty(LOG_AXIS, BlockLog.EnumAxis.Y);
break;
case 0b0100:
state = state.withProperty(LOG_AXIS, BlockLog.EnumAxis.X);
break;
case 0b1000:
state = state.withProperty(LOG_AXIS, BlockLog.EnumAxis.Z);
break;
case 0b1100:
state = state.withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE);
break;
}
return state;
}
/**
* Convert the BlockState into the correct metadata value
*/
public int getMetaFromState(IBlockState state)
{
switch ((BlockLog.EnumAxis)state.getValue(LOG_AXIS))
{
case X: return 0b0100;
case Y: return 0b0000;
case Z: return 0b1000;
case NONE: return 0b1100;
}
}
protected BlockStateContainer createBlockState()
{
return new BlockStateContainer(this, new IProperty[] {LOG_AXIS});
}
}
The important part is that you need to handle the LOG_AXIS
property.
If you do want to have multiple variants, look at BlockOldLog
or BlockNewLog
for an example. Note that with BlockNewLog
, methods like damageDropped
and createStackedBlock
subtract 4 from the variant since it is based off of plank IDs, where acadia and dark oak are IDs 4 and 5 on the same block as oak, birch, jungle, and spruce. With your own logs you won't generally need to do this.
Upvotes: 2