Jump to content

Recommended Posts

Posted (edited)

Hello world.

 

I'm making a Tree Mod and it turns out, that my leaves won't decay.

  1.  When a tree get generated, all leaves are set with the standard block state (aka with decayable and check_decay set to true).
  2. After the generation most leaves have check_dekay set to false. Since this is also the case with vanilla leaves I guess that's normal though.
  3. When chopping down a tree (minecraft style) the leaves won't decay and after restarting the game the leaves have both decayable and check_decay set to false

 

Things that may be important to notice, is that my Leaves are multitextured. The Blockstate also contains a variant variable.

 

I also don't really know what code I should post here.

Any Suggestions?

 

Edited by TheA13X

Sincerely,

A13XIS

Posted

Show your code for your leaf block

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 (edited)

Wow that was fast. Thanks man ^^

 

Well, first we have the Superclass:

 

public abstract class LeavesBlock extends Block implements net.minecraftforge.common.IShearable
{
	public static final int CAPACITY = 4;
    private static final int METADATA_MASK = CAPACITY - 1;
    int[] surroundings;

    private final ImmutableList<DefinesLeaves> subBlocks;

    protected LeavesBlock(Collection<? extends DefinesLeaves> subBlocks)
    {
        super(Material.LEAVES);
        checkArgument(!subBlocks.isEmpty());
        checkArgument(subBlocks.size() <= CAPACITY);
        this.subBlocks = ImmutableList.copyOf(subBlocks);
        this.setTickRandomly(true);
        this.setHardness(0.2F);
        this.setLightOpacity(1);
        this.setSoundType(SoundType.PLANT);
        setUnlocalizedName("leaves");
    }

    private static int mask(int metadata) {return metadata & METADATA_MASK;}

    protected static String getUnwrappedUnlocalizedName(String unlocalizedName)
    {
        return unlocalizedName.substring(unlocalizedName.indexOf('.') + 1);
    }

    protected final List<DefinesLeaves> subBlocks() { return Collections.unmodifiableList(subBlocks); }

    @Override
    public final Item getItemDropped(IBlockState state, Random unused, int unused2)
    {
        return Item.getItemFromBlock(subBlocks.get(mask(this.getMetaFromState(state))).saplingDefinition().saplingBlock());
    }

    @Override
    public int damageDropped(IBlockState state)
    {
        return subBlocks.get(mask(this.getMetaFromState(state))).saplingDefinition().saplingSubBlockVariant().ordinal();
    }

    public final String[] getSpeciesNames() //func_150125_e
        {
        final List<String> names = Lists.newArrayList();
        for (final DefinesLeaves subBlock : subBlocks)
            names.add(subBlock.speciesName());
        return names.toArray(new String[names.size()]);
    }

    public final String getUnlocalizedName()
    {
        return String.format("tile.%s%s", resourcePrefix(), getUnwrappedUnlocalizedName(super.getUnlocalizedName()));
    }

    public final int getDamageValue(World world, BlockPos pos) { return this.getMetaFromState(world.getBlockState(pos)) & 3; }

    public final void getSubBlocks(Item item, CreativeTabs unused, List subBlocks)
    {
        for (int i = 0; i < this.subBlocks.size(); i++)
            subBlocks.add(new ItemStack(item, 1, i));
    }

    public void registerBlockModels()
    {
        for (DefinesLeaves define : subBlocks())
        {
            ModelResourceLocation typeLocation = new ModelResourceLocation(getRegistryName(),"check_decay=true,decayable=true,variant="+define.leavesSubBlockVariant().name().toLowerCase());
            Item blockItem = Item.getItemFromBlock(define.leavesBlock());
            ModelLoader.setCustomModelResourceLocation(blockItem,define.leavesSubBlockVariant().ordinal(),typeLocation);
        }
    }

    protected abstract String resourcePrefix();

	//Stuff cloned from BlockLeaves...
		public abstract Enum getWoodType(int meta);
	//Stuff cloned from BlockLeaves...
}

 

And then several Mod Classes which only difference is the Enum used for getWoodType()

Here is one of them

 

public final class ModLeavesBlock extends LeavesBlock
{
    public static final PropertyEnum VARIANT = PropertyEnum.create("variant", ModLogBlock.EnumType.class);
   
    public ModLeavesBlock(Iterable<? extends DefinesLeaves> subBlocks)
    {
        super(ImmutableList.copyOf(subBlocks));
        setCreativeTab(TheMod.INSTANCE.creativeTab());
        this.setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, ModLogBlock.EnumType.ACEMUS).withProperty(CHECK_DECAY, Boolean.TRUE).withProperty(DECAYABLE, Boolean.TRUE));
    }

    @Override
    public int quantityDropped(Random random)
    {
        final int rarity = Settings.INSTANCE.saplingDropRarity();
        return rarity == 0 || random.nextInt(rarity) != 0 ? 0 : 1;
    }

    @Override
    protected BlockStateContainer createBlockState(){
        BlockStateContainer bs = new BlockStateContainer(this, new IProperty[]{VARIANT,CHECK_DECAY,DECAYABLE});

        return bs;
    }

    @Override
    public ModLogBlock.EnumType getWoodType(int meta) {
       return ModLogBlock.EnumType.fromId(meta);
    }

    @Override
    protected String resourcePrefix() { return TheMod.getResourcePrefix(); }

    @Override
    public List<ItemStack> onSheared(ItemStack item, IBlockAccess world, BlockPos pos, int fortune) {
        ArrayList<ItemStack> list=new ArrayList<ItemStack>();
        list.add(new ItemStack(Item.getItemFromBlock(this),1,getMetaFromState(world.getBlockState(pos))));
        return list;
    }

    @Override
    public IBlockState getStateFromMeta(int meta) {
        IBlockState state = getDefaultState();
        switch(meta/4){
            case 0:
                state = state.withProperty(CHECK_DECAY,true).withProperty(DECAYABLE,true);
            break;
            case 1:
                state = state.withProperty(CHECK_DECAY,true).withProperty(DECAYABLE,false);
            break;
            case 2:
                state = state.withProperty(CHECK_DECAY,false).withProperty(DECAYABLE,true);
            break;
            case 3:
                state = state.withProperty(CHECK_DECAY,false).withProperty(DECAYABLE,false);
            break;
        }
        state = state.withProperty(VARIANT,ModLogBlock.EnumType.fromId(meta%4));
        return state;
    }

    @Override
    public int getMetaFromState(IBlockState state) {
        ModLogBlock.EnumType type = (ModLogBlock.EnumType) state.getValue(ModLogBlock.VARIANT);
        boolean check = (Boolean) state.getValue(CHECK_DECAY);
        boolean dcable = (Boolean) state.getValue(CHECK_DECAY);
        int par = check?dcable?0:1:dcable?2:3;
        return par*4+type.ordinal();
    }

    protected boolean needMask(){
        return false;
    }

    @Override
    public int damageDropped(IBlockState state) {
        return getMetaFromState(state.withProperty(CHECK_DECAY,true).withProperty(DECAYABLE,true));
    }

    @Override
    protected int getSaplingDropChance(IBlockState state)
    {
        return Settings.INSTANCE.saplingDropRarity();
    }
}

 

Edited by TheA13X

Sincerely,

A13XIS

Posted (edited)
13 hours ago, diesieben07 said:
  • Next, if you don't want your leaves to decay, why do you have two properties called CHECK_DECAY and DECAYABLE? Speaking of them, where are they even coming from? They certainly aren't defined in the code that you posted.

You misunderstood me. They do NOT Decay, but I want them to. Also I just noticed I forgot to paste the properties in there. It's fixed now.

 

13 hours ago, diesieben07 said:
  • First of all please remove all that unlocalized name dancing. You don't need it. You should not be getting the unlocalized name for anything. Even when displaying a block's name getLocalizedName should be used.
  • Also in this category: What is this getResourcePrefix thing? You don't need it.
  • Another thing I noticed, you are using Collections.unmodifiableList on an ImmutableList, this is pointless.
  • registerBlockModels should not be in your Block class. You must register models in your client proxy.

I just updated 1.7.10 code from another author.

I thought about recoding it completely to make it more uncomplicated, but this can wait.

Also registerBlockModelsis called from the client proxy. It's just positioned in the block class to allow different behaviour for every single block.

It's just clearer that way.

 

13 hours ago, diesieben07 said:
  • Why are you calling setTickRandomly(true)? You are not overriding randomTick, so it's just wasting resources.

Like the comments say I cloned MCs BlockLeaves Class and cut out the old functions, since they are the same, as the ones from the original.

The randomTick function is there.

Edited by TheA13X

Sincerely,

A13XIS

Posted
1 hour ago, diesieben07 said:

Clearer or not, it's broken. You cannot have references to client-only classes (ModelLoader) in common code (your block class).

Yes  I can. Sure it's a matter of trust since it could break if someone calls the function outside of a client-only class, but I'm the only author, so it won't happen.

 

1 hour ago, diesieben07 said:

And no, there is no randomTick method in either of the block classes you posted.

It's in the part of the class I left out and replaced it with

 

20 hours ago, TheA13X said:

//Stuff cloned from BlockLeaves...

 

 

2 hours ago, Jay Avery said:

Why don't you just extend BlockLeaves if you want so much of the same functionality?

I  don't even know anymore. Let me check this

Sincerely,

A13XIS

Posted (edited)

So there's an abstract function called getWoodtype which returns a BlockPlanks.EnumType and I wanted to return the enum type of my Mod's   Planks, but that's completely unnecessary. I extended the class and it works now (apart from a visual glich due to the transparency, but that's another story)

 

Thanks

Edited by TheA13X

Sincerely,

A13XIS

Posted
3 hours ago, TheA13X said:

it could break if someone calls the function outside of a client-only class

As the 7 implied, that's not what side-only means. Side-only is about class-loading, not mere class execution. If your mod (or code copied from it for another mod) is ever used on a dedicated server, it will crash during the loading phase, before it ever gets a chance to run. In single-player mode, your error may be hidden because SP has a virtual client that loads the client's side-only classes in the JVM.

 

Because bad habits are hard to unlearn, we encourage modders to learn correct form (and understanding) from the start. Just look at how many class def not found threads there are in this forum and kindly not set yourself up to burden us with another..

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Posted
2 hours ago, jeffryfisher said:

As the 7 implied, that's not what side-only means. Side-only is about class-loading, not mere class execution. If your mod (or code copied from it for another mod) is ever used on a dedicated server, it will crash during the loading phase, before it ever gets a chance to run...

That said, if you yourself are only invoking the method client side (through your proxy!) you can safely annotate it with @SideOnly(Side.CLIENT), which is the annotation's proper use.

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.

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.