Jump to content

Recommended Posts

Posted

Not with bonemeal or anything

 

My custom sapling block

 

package com.technorcery.common.blocks;

import java.util.Random;

import com.technorcery.common.ModData;
import com.technorcery.common.blocks.PlankBlock.WoodType;
import com.technorcery.common.worldgen.WorldGenTree;

import net.minecraft.block.BlockBush;
import net.minecraft.block.IGrowable;
import net.minecraft.block.SoundType;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenerator;

public class SaplingBlock extends BlockBush implements IGrowable {
private final WoodType type;
    public static final PropertyInteger STAGE = PropertyInteger.create("stage", 0, 1);
    protected static final AxisAlignedBB SAPLING_AABB = new AxisAlignedBB(0.09999999403953552D, 0.0D, 0.09999999403953552D, 0.8999999761581421D, 0.800000011920929D, 0.8999999761581421D);
    
    public SaplingBlock(String name, WoodType type)
    {
    	this.type = type;
	this.setUnlocalizedName(name);
	this.setRegistryName(name);
        this.setSoundType(SoundType.PLANT);
        this.setHardness(0.0F);
        this.setTickRandomly(true);
        this.setDefaultState(this.blockState.getBaseState().withProperty(STAGE, Integer.valueOf(0)));
	this.setCreativeTab(ModData.CREATIVE_TAB);
    }
    
    @Override
    public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (!worldIn.isRemote)
        {
            super.updateTick(worldIn, pos, state, rand);

            if (worldIn.getLightFromNeighbors(pos.up()) >= 9 && rand.nextInt(7) == 0)
            {
                this.grow(worldIn, pos, state, rand);
            }
        }
    }
    
    public void grow(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (((Integer)state.getValue(STAGE)).intValue() == 0)
        {
            worldIn.setBlockState(pos, state.cycleProperty(STAGE), 4);
        }
        else
        {
            this.generateTree(worldIn, pos, state, rand);
        }
    }
    
    @SuppressWarnings("unused")
    public void generateTree(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (!net.minecraftforge.event.terraingen.TerrainGen.saplingGrowTree(worldIn, rand, pos)) return;
	WorldGenerator worldgenerator = new WorldGenTree(true, false, type);
        worldIn.setBlockState(pos, state, 4);
    }
    
    @Override
    public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
    {
        return SAPLING_AABB;
    }

@Override
public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient) {
	return true;
}

@Override
public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state) {
	return (double)worldIn.rand.nextFloat() < 0.45D;
}

@Override
public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state) {
	this.grow(worldIn, pos, state, rand);
}


    @Override
    public IBlockState getStateFromMeta(int meta)
    {
        return this.getDefaultState().withProperty(STAGE, Integer.valueOf((meta &  >> 3));
    }

    @Override
    public int getMetaFromState(IBlockState state)
    {
        int i = 0;
        i = i | ((Integer)state.getValue(STAGE)).intValue() << 3;
        return i;
    }
    
    @Override
    protected BlockStateContainer createBlockState()
    {
        return new BlockStateContainer(this, new IProperty[] {STAGE});
    }
}

 

 

My custom tree worldgen class

 

package com.technorcery.common.worldgen;

import java.util.Random;

import com.technorcery.common.ModBlocks;
import com.technorcery.common.blocks.PlankBlock.WoodType;

import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;

public class WorldGenTree extends WorldGenAbstractTree {
private final WoodType type;
    private final boolean useExtraRandomHeight;

public WorldGenTree(boolean notify, boolean useExtraRandomHeightIn, WoodType type) {
	super(notify);
        this.type = type;
        this.useExtraRandomHeight = useExtraRandomHeightIn;
}

@Override
public boolean generate(World worldIn, Random rand, BlockPos position)
    {
        int i = rand.nextInt(3) + 5;
        IBlockState LOG = ModBlocks.LOG_APPLE.getDefaultState();
        IBlockState LEAF = ModBlocks.LEAF_APPLE.getDefaultState();
        
        if (type == WoodType.ELDER)
        {
        	LOG = ModBlocks.LOG_ELDER.getDefaultState();
        	LEAF = ModBlocks.LEAF_ELDER.getDefaultState();
        }

        if (this.useExtraRandomHeight)
        {
            i += rand.nextInt(2);
        }

        boolean flag = true;

        if (position.getY() >= 1 && position.getY() + i + 1 <= 256)
        {
            for (int j = position.getY(); j <= position.getY() + 1 + i; ++j)
            {
                int k = 1;

                if (j == position.getY())
                {
                    k = 0;
                }

                if (j >= position.getY() + 1 + i - 2)
                {
                    k = 2;
                }

                BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();

                for (int l = position.getX() - k; l <= position.getX() + k && flag; ++l)
                {
                    for (int i1 = position.getZ() - k; i1 <= position.getZ() + k && flag; ++i1)
                    {
                        if (j >= 0 && j < worldIn.getHeight())
                        {
                            if (!this.isReplaceable(worldIn, blockpos$mutableblockpos.setPos(l, j, i1)))
                            {
                                flag = false;
                            }
                        }
                        else
                        {
                            flag = false;
                        }
                    }
                }
            }

            if (!flag)
            {
                return false;
            }
            else
            {
                BlockPos down = position.down();
                IBlockState state = worldIn.getBlockState(down);
                boolean isSoil = state.getBlock().canSustainPlant(state, worldIn, down, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.SAPLING);

                if (isSoil && position.getY() < worldIn.getHeight() - i - 1)
                {
                    state.getBlock().onPlantGrow(state, worldIn, down, position);

                    for (int i2 = position.getY() - 3 + i; i2 <= position.getY() + i; ++i2)
                    {
                        int k2 = i2 - (position.getY() + i);
                        int l2 = 1 - k2 / 2;

                        for (int i3 = position.getX() - l2; i3 <= position.getX() + l2; ++i3)
                        {
                            int j1 = i3 - position.getX();

                            for (int k1 = position.getZ() - l2; k1 <= position.getZ() + l2; ++k1)
                            {
                                int l1 = k1 - position.getZ();

                                if (Math.abs(j1) != l2 || Math.abs(l1) != l2 || rand.nextInt(2) != 0 && k2 != 0)
                                {
                                    BlockPos blockpos = new BlockPos(i3, i2, k1);
                                    IBlockState state2 = worldIn.getBlockState(blockpos);

                                    if (state2.getBlock().isAir(state2, worldIn, blockpos) || state2.getBlock().isAir(state2, worldIn, blockpos))
                                    {
                                        this.setBlockAndNotifyAdequately(worldIn, blockpos, LEAF);
                                    }
                                }
                            }
                        }
                    }

                    for (int j2 = 0; j2 < i; ++j2)
                    {
                        BlockPos upN = position.up(j2);
                        IBlockState state2 = worldIn.getBlockState(upN);

                        if (state2.getBlock().isAir(state2, worldIn, upN) || state2.getBlock().isLeaves(state2, worldIn, upN))
                        {
                            this.setBlockAndNotifyAdequately(worldIn, position.up(j2), LOG);
                        }
                    }

                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        else
        {
            return false;
        }
    }

}

 

Disclaimer:  I been told to keep my opinions to myself, to shut up and that I am spreading lies and misinformation or even that my methods are unorthodox and or too irregular. Here are my suggestions take it or leave it.

Posted

Is it cause I need to register something? Maybe tree worldgen needs registering??

Disclaimer:  I been told to keep my opinions to myself, to shut up and that I am spreading lies and misinformation or even that my methods are unorthodox and or too irregular. Here are my suggestions take it or leave it.

Posted

But how do I register it?

 

The GameRegistry.RegisterWorldGenerator only registers IWorldGenerator and not WorldGenerator for my custom tree gen.

 

Seems other mods don't register their custom tree gen.

 

I'm thinking my problem may be somewhere else maybe my grow function in my sapling is broken.

Disclaimer:  I been told to keep my opinions to myself, to shut up and that I am spreading lies and misinformation or even that my methods are unorthodox and or too irregular. Here are my suggestions take it or leave it.

Posted

But how do I register it?

 

The GameRegistry.RegisterWorldGenerator only registers IWorldGenerator and not WorldGenerator for my custom tree gen.

 

Seems other mods don't register their custom tree gen.

 

I'm thinking my problem may be somewhere else maybe my grow function in my sapling is broken.

Doesn't WorldGenAbstractTree implement IWorldGenerator and you never call the generation method you just create a new instance then never do anything.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

WorldGenAbstractTree extends WorldGenerator

 

Nope it implements WorldGenerator not IWorldGenerator.

 

 

Whatever code I have up there it does not bonemeal and will not grow ever. There's some issue somewhere. I have a feeling the sapling is broken.

Disclaimer:  I been told to keep my opinions to myself, to shut up and that I am spreading lies and misinformation or even that my methods are unorthodox and or too irregular. Here are my suggestions take it or leave it.

Posted

WorldGenAbstractTree extends WorldGenerator

 

Nope it implements WorldGenerator not IWorldGenerator.

And WorldGenerator implements IWorldGenerator

 

Whatever code I have up there it does not bonemeal and will not grow ever. There's some issue somewhere. I have a feeling the sapling is broken.

 

you never call the generation method you just create a new instance then never do anything.

Here I meant in your growTreeMethod(...).

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

And WorldGenerator implements IWorldGenerator
No, it doesn't.

Really? Wow, is IWorldGenerator just provided by forge as a better alternative? I have never looked at WorldGenerator as I have not needed it.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
IWorldGenerator

is added by Forge to make custom world generation easier. Vanilla code is generated in

BiomeDecorator

, and the custom generation is called from

Chunk#populateChunk

.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

IWorldGenerator

is added by Forge to make custom world generation easier. Vanilla code is generated in

BiomeDecorator

, and the custom generation is called from

Chunk#populateChunk

.

Good to know. Still shows that I have much more to learn.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

WorldGenerator does not implements or extends anything. IWorldGenerator and WorldGenerator are not compatible.

 

 

So how do I fix my custom tree?

Disclaimer:  I been told to keep my opinions to myself, to shut up and that I am spreading lies and misinformation or even that my methods are unorthodox and or too irregular. Here are my suggestions take it or leave it.

Posted

I figured it out guys.  I was right my sapling was incorrect.

 

Gen tree was wrong. I fixed it like so

 

   public void generateTree(World worldIn, BlockPos pos, IBlockState state, Random rand)
    {
        if (!net.minecraftforge.event.terraingen.TerrainGen.saplingGrowTree(worldIn, rand, pos)) return;
	WorldGenerator worldgenerator = new WorldGenTree(true, false, type);

        IBlockState iblockstate2 = Blocks.AIR.getDefaultState();
        worldIn.setBlockState(pos, iblockstate2, 4);
        
        if (!worldgenerator.generate(worldIn, rand, pos.add(0, 0, 0)))
        {
        	 worldIn.setBlockState(pos, state, 4);
        }
    }

 

 

Note the

        IBlockState iblockstate2 = Blocks.AIR.getDefaultState();

        worldIn.setBlockState(pos, iblockstate2, 4);

       

        if (!worldgenerator.generate(worldIn, rand, pos.add(0, 0, 0)))

        {

        worldIn.setBlockState(pos, state, 4);

        }

 

seems like you need to set the state of air block to 4 before you can spawn the tree.

Disclaimer:  I been told to keep my opinions to myself, to shut up and that I am spreading lies and misinformation or even that my methods are unorthodox and or too irregular. Here are my suggestions take it or leave it.

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello all. I'm currently grappling with the updateShape method in a custom class extending Block.  My code currently looks like this: The conditionals in CheckState are there to switch blockstate properties, which is working fine, as it functions correctly every time in getStateForPlacement.  The problem I'm running into is that when I update a state, the blocks seem to call CheckState with the position of the block which was changed updated last.  If I build a wall I can see the same change propagate across. My question thus is this: is updateShape sending its return to the neighbouring block?  Is each block not independently executing the updateShape method, thus inserting its own current position?  The first statement appears to be true, and the second false (each block is not independently executing the method). I have tried to fix this by saving the block's own position to a variable myPos at inception, and then feeding this in as CheckState(myPos) but this causes a worse outcome, where all blocks take the update of the first modified block, rather than just their neighbour.  This raises more questions than it answers, obviously: how is a different instance's variable propagating here?  I also tried changing it so that CheckState did not take a BlockPos, but had myPos built into the body - same problem. I have previously looked at neighbourUpdate and onNeighbourUpdate, but could not find a way to get this to work at all.  One post on here about updatePostPlacement and other methods has proven itself long superceded.  All other sources on the net seem to be out of date. Many thanks in advance for any help you might offer me, it's been several days now of trying to get this work and several weeks of generally trying to get round this roadblock.  - Sandermall
    • sorry, I might be stupid, but how do I open it? because the only options I have are too X out, copy it, which doesn't work and send crash report, which doesn't show it to me, also, sorry for taking so long.
    • Can you reproduce this with version 55.0.21? A whole lot of plant placement issues were just fixed in this PR.
    • Necro'ing that thread to ask if you found a solution ? I'm encountering the same crash on loading the world. I created the world in Creative to test my MP, went into survival to test combat, died, crashed on respawn and since then crash on loading the world. Deactivating Oculus isn't fixing it either, and I don't have Optifine (Twilight forest is incompatible)
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.