Jump to content

[UNSOLVED 1.7.10] Trees not spawning much


BottleFact

Recommended Posts

[glow=red,2,300]Note: The tree spawning is happening, it just is not happening as common as I want it to be.[/glow]

 

So the problem is that I have trees spawning too rarely and I defined it to be much more common. Here's a pic:

 

TCQUvqB.png

 

The treesPerChunk is set to 10, but this is not reflected in the terrain. Also the chunk provider is the same as Notch's old sky dimension chunk provider code.

 

BiomeGenFloatingIslands [glow=red,2,300]Note: This class is the biome definition. It sets the treesPerChunk and the decorator respects this. Therefore, in theory, the higher treesPerChunk is, the more trees that should spawn. Though I believe the code should do this, for some reason it doesn't. Not even when I use ChunkProviderGenerate.[/glow]

package sqm.minecraft.starfield.dimension;

import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraft.world.gen.feature.WorldGenTaiga2;
import net.minecraft.world.gen.feature.WorldGenerator;
import sqm.minecraft.starfield.common.Starfield;
import sqm.minecraft.starfield.nature.SkyDecorator;

public class BiomeGenFloatingIslands extends BiomeGenBase
{
    private WorldGenerator theWorldGenerator;
    private WorldGenTaiga2 field_150634_aD;
    private int field_150635_aE;
    private int field_150636_aF;
    private int field_150637_aG;
    private int field_150638_aH;
    private static final String __OBFID = "CL_00000168";

    public BiomeGenFloatingIslands(int p_i45373_1_, boolean p_i45373_2_)
    {
        super(p_i45373_1_);
        this.theBiomeDecorator=new SkyDecorator();
        this.theBiomeDecorator.treesPerChunk=10;
        this.spawnableMonsterList.clear();
        this.spawnableCreatureList.clear();
        this.spawnableCaveCreatureList.clear();
        this.spawnableWaterCreatureList.clear();
        this.topBlock=Starfield.getBlock("bluegrass");
        this.fillerBlock=Starfield.getBlock("harddirt");
    }
    
    public void genTerrainBlocks(World p_150573_1_, Random p_150573_2_, Block[] p_150573_3_, byte[] p_150573_4_, int p_150573_5_, int p_150573_6_, double p_150573_7_)
    {
    	this.topBlock=Starfield.getBlock("bluegrass");
        this.fillerBlock=Starfield.getBlock("harddirt");
        this.genBiomeTerrain(p_150573_1_, p_150573_2_, p_150573_3_, p_150573_4_, p_150573_5_, p_150573_6_, p_150573_7_);
    }
}

 

SkyDecorator [glow=red,2,300]Note: This class generates the ores and trees (TallTree.class). The ores are fine; you can see them in the pic on the cliff face. The trees however are too rare.[/glow]

package sqm.minecraft.starfield.nature;

import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE;
import static net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.COAL;
import static net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIAMOND;
import static net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIRT;
import static net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.IRON;

import java.util.Random;

import cpw.mods.fml.common.FMLLog;
import net.minecraft.block.Block;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeDecorator;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.world.gen.feature.WorldGenAbstractTree;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.terraingen.DecorateBiomeEvent;
import net.minecraftforge.event.terraingen.OreGenEvent;
import net.minecraftforge.event.terraingen.TerrainGen;
import sqm.minecraft.starfield.common.PushAttempt;
import sqm.minecraft.starfield.common.Starfield;

public class SkyDecorator extends BiomeDecorator
{
    /** The world the BiomeDecorator is currently decorating */
    public World currentWorld;
    /** The Biome Decorator's random number generator. */
    public Random randomGenerator;
    /** The X-coordinate of the chunk currently being decorated */
    public int chunk_X;
    /** The Z-coordinate of the chunk currently being decorated */
    public int chunk_Z;

    /** The dirt generator. */
    public WorldGenerator dirtGen;
    
    public WorldGenerator coalGen;
    public WorldGenerator ironGen;
    
    /** Field that holds diamond WorldGenMinable */
    public WorldGenerator diamondGen;

    /** Amount of waterlilys per chunk. */
    public int waterlilyPerChunk;
    /** The number of trees to attempt to generate per chunk. Up to 10 in forests, none in deserts. */
    public int treesPerChunk;
    /**
     * The number of yellow flower patches to generate per chunk. The game generates much less than this number, since
     * it attempts to generate them at a random altitude.
     */
    public int flowersPerChunk;
    /** The amount of tall grass to generate per chunk. */
    public int grassPerChunk;
    /** The number of dead bushes to generate per chunk. Used in deserts and swamps. */
    public int deadBushPerChunk;
    /**
     * The number of extra mushroom patches per chunk. It generates 1/4 this number in brown mushroom patches, and 1/8
     * this number in red mushroom patches. These mushrooms go beyond the default base number of mushrooms.
     */
    public int mushroomsPerChunk;
    /** The number of reeds to generate per chunk. Reeds won't generate if the randomly selected placement is unsuitable. */
    public int reedsPerChunk;
    /** The number of cactus plants to generate per chunk. Cacti only work on sand. */
    public int cactiPerChunk;
    /** The number of sand patches to generate per chunk. Sand patches only generate when part of it is underwater. */
    public int sandPerChunk;
    /**
     * The number of sand patches to generate per chunk. Sand patches only generate when part of it is underwater. There
     * appear to be two separate fields for this.
     */
    public int sandPerChunk2;
    /** The number of clay patches to generate per chunk. Only generates when part of it is underwater. */
    public int clayPerChunk;
    /** Amount of big mushrooms per chunk */
    public int bigMushroomsPerChunk;
    /** True if decorator should generate surface lava & water */
    public boolean generateLakes;
    private static final String __OBFID = "CL_00000164";

    public SkyDecorator()
    {
        this.flowersPerChunk = 2;
        this.grassPerChunk = 1;
        this.sandPerChunk = 1;
        this.sandPerChunk2 = 3;
        this.clayPerChunk = 1;
        this.generateLakes = false;
    }

    public synchronized void decorateChunk(World p_150512_1_, Random p_150512_2_, BiomeGenBase p_150512_3_, int p_150512_4_, int p_150512_5_)
    {
        	this.dirtGen = new WorldGenMinable(Starfield.getBlock("harddirt"), 32, Starfield.getBlock("purplestone"));
            this.coalGen = new WorldGenMinable(Starfield.getBlock("newcoal"), 16, Starfield.getBlock("purplestone"));
            this.ironGen = new WorldGenMinable(Starfield.getBlock("newiron"), 8, Starfield.getBlock("purplestone"));
            this.diamondGen = new WorldGenMinable(Starfield.getBlock("newdiamond"), 7, Starfield.getBlock("purplestone"));
            this.currentWorld = p_150512_1_;
            this.randomGenerator = p_150512_2_;
            this.chunk_X = p_150512_4_;
            this.chunk_Z = p_150512_5_;
            this.genDecorations(p_150512_3_);
            this.currentWorld = null;
}

    protected void genDecorations(BiomeGenBase p_150513_1_)
    {
    	PushAttempt.updateClients=false;
        MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Pre(currentWorld, randomGenerator, chunk_X, chunk_Z));
        this.generateOres();
        int i;
        int j;
        int k;
        
        i = this.treesPerChunk;

        if (this.randomGenerator.nextInt(10) == 0)
        {
            ++i;
        }

        int l;
        int i1;

        boolean doGen = TerrainGen.decorate(currentWorld, randomGenerator, chunk_X, chunk_Z, TREE);
        for (j = 0; doGen && j < i; ++j)
        {
            k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
            l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
            i1 = this.currentWorld.getHeightValue(k, l);
            TallTree worldgenabstracttree = new TallTree(currentWorld, k, i1, l, randomGenerator);
            if(!worldgenabstracttree.generate(this.currentWorld, this.randomGenerator, k, i1, l))
            {
            	System.out.println("Tree generation failed! "+k+" "+i1+" "+l+" Investigate!");
            }
            else
            {
            	System.out.println("Tree generation success! "+k+" "+i1+" "+l+" Investigate!");
            }
        }
        MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
        PushAttempt.updateClients=true;
    }

    /**
     * Standard ore generation helper. Generates most ores.
     */
    protected void genStandardOre1(int p_76795_1_, WorldGenerator p_76795_2_, int p_76795_3_, int p_76795_4_)
    {
        for (int l = 0; l < p_76795_1_; ++l)
        {
            int i1 = this.chunk_X + this.randomGenerator.nextInt(16);
            int j1 = this.randomGenerator.nextInt(p_76795_4_ - p_76795_3_) + p_76795_3_;
            int k1 = this.chunk_Z + this.randomGenerator.nextInt(16);
            p_76795_2_.generate(this.currentWorld, this.randomGenerator, i1, j1, k1);
        }
    }

    /**
     * Standard ore generation helper. Generates Lapis Lazuli.
     */
    protected void genStandardOre2(int p_76793_1_, WorldGenerator p_76793_2_, int p_76793_3_, int p_76793_4_)
    {
        for (int l = 0; l < p_76793_1_; ++l)
        {
            int i1 = this.chunk_X + this.randomGenerator.nextInt(16);
            int j1 = this.randomGenerator.nextInt(p_76793_4_) + this.randomGenerator.nextInt(p_76793_4_) + (p_76793_3_ - p_76793_4_);
            int k1 = this.chunk_Z + this.randomGenerator.nextInt(16);
            p_76793_2_.generate(this.currentWorld, this.randomGenerator, i1, j1, k1);
        }
    }

    /**
     * Generates ores in the current chunk
     */
    protected void generateOres()
    {
        MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Pre(currentWorld, randomGenerator, chunk_X, chunk_Z));
        if (TerrainGen.generateOre(currentWorld, randomGenerator, dirtGen, chunk_X, chunk_Z, DIRT))
        this.genStandardOre1(20, this.dirtGen, 8, 256);
        if (TerrainGen.generateOre(currentWorld, randomGenerator, coalGen, chunk_X, chunk_Z, COAL))
        this.genStandardOre1(20, this.coalGen, 8, 128);
        if (TerrainGen.generateOre(currentWorld, randomGenerator, ironGen, chunk_X, chunk_Z, IRON))
        this.genStandardOre1(20, this.ironGen, 8, 64);
        if (TerrainGen.generateOre(currentWorld, randomGenerator, diamondGen, chunk_X, chunk_Z, DIAMOND))
        this.genStandardOre1(1, this.diamondGen, 8, 24);
        MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
    }

    private int nextInt(int i) {
        if (i <= 1)
            return 0;
        return this.randomGenerator.nextInt(i);
}
}

 

TallTree [glow=red,2,300]Note: This class generates the trees seen in the picture.[/glow]

package sqm.minecraft.starfield.nature;

import java.util.Random;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenerator;
import sqm.minecraft.starfield.common.PushAttempt;
import sqm.minecraft.starfield.common.Starfield;

public class TallTree extends WorldGenerator{

World w;
int x,y,z;
Random rand;

public TallTree(World world,int treeX, int treeY, int treeZ,Random rand) {
	this.w=world;
	this.x=treeX;
	this.y=treeY;
	this.z=treeZ;
	this.rand=rand;
}

public boolean attemptGen(Block trunk, Block leaves, boolean sapling)
{
        boolean isSoil = this.w.getBlock(x, y-1, z) == Starfield.getBlock("bluegrass") || this.w.getBlock(x, y-1, z) == Starfield.getBlock("harddirt");
        if (isSoil)
        {
            
	PushAttempt p = new PushAttempt(this.w);
	int iterations = sapling ? this.rand.nextInt(2)+3 : (this.rand.nextInt(4)==1 ? this.rand.nextInt(1)+1 : this.rand.nextInt(7)+3);
	int baseHeight = iterations<3 ? this.rand.nextInt(10)+10 : (sapling ? this.rand.nextInt(3)+2 : this.rand.nextInt(3)+3);
	int height = baseHeight+iterations*2;
	for(int i=1;i<=height;i++)
	{
		p.setBlock(this.x,this.y+(i-1),this.z,trunk);
	}
	p.setBlock(this.x,this.y+height,this.z,leaves);
	for(int i=baseHeight;i<=height;i++){
	    int extension = (i-baseHeight)%2==1 ? ( (i-baseHeight)%4==1 ? 0 : 2) : 1;
	    for(int j=1;j<=extension;j++){
	    	p.setBlock(this.x+j,this.y+(i-1),this.z,this.rand.nextInt(10)==1 && !sapling ? Starfield.getBlock("fruitleaf") : leaves);
	    	p.setBlock(this.x-j,this.y+(i-1),this.z,this.rand.nextInt(10)==1 && !sapling ? Starfield.getBlock("fruitleaf") : leaves);
	    	p.setBlock(this.x,this.y+(i-1),this.z+j,this.rand.nextInt(10)==1 && !sapling ? Starfield.getBlock("fruitleaf") : leaves);
	    	p.setBlock(this.x,this.y+(i-1),this.z-j,this.rand.nextInt(10)==1 && !sapling ? Starfield.getBlock("fruitleaf") : leaves);
	    }
	}
	return p.push();
        }
        else
        {
        	return false;
        }

}

@Override
public boolean generate(World p_76484_1_, Random p_76484_2_,int p_76484_3_, int p_76484_4_, int p_76484_5_) {
	return attemptGen(Starfield.getBlock("purplelog"),Starfield.getBlock("purpleleaf"),false);
}

public boolean generateAsSapling(World p_76484_1_, Random p_76484_2_,int p_76484_3_, int p_76484_4_, int p_76484_5_) {
	return attemptGen(Starfield.getBlock("purplelog"),Starfield.getBlock("purpleleaf"),true);
}

}

 

PushAttempt [glow=red,2,300]Note: This is a class that stores setBlock() statements and then places them into the world on request. push() will place the structure, but only if all the blocks can be placed without overwriting another block. pushIfAvailable() is similar, but is per-block, not for the whole model. So that it only places blocks that are not obstructed by existing terrain. pushForce() just places in all the blocks, overwrite or not. Also, PushAttemptBlocks.class and PushAttemptMeta.class are just storage classes. They store an x, y and z int, and either a Block var or another int representing metadata. PushOperation.class should just redirect the setBlockTo() call to the PushAttempt's setBlock() method.[/glow]

package sqm.minecraft.starfield.common;

import java.util.ArrayList;

import net.minecraft.block.Block;
import net.minecraft.world.World;

public class PushAttempt {

private World world;
public static boolean updateClients = true;
private boolean valid=true;
private ArrayList<PushAttemptBlocks> blocks = new ArrayList<PushAttemptBlocks>();
private ArrayList<PushAttemptMeta> meta = new ArrayList<PushAttemptMeta>();

public PushAttempt(World w) {
	this.world=w;
}

public void setBlock(int x, int y, int z, Block b)
{
	this.setBlock(x,y,z,b,0);
}

public void setBlock(int x, int y, int z, Block b, int i)
{
	boolean valid = this.world!=null ? this.world.getBlock(x,y,z).isReplaceable(this.world, x, y, z) : true;
	this.blocks.add(new PushAttemptBlocks(x,y,z,b,valid));
	this.meta.add(new PushAttemptMeta(x,y,z,i,valid));
	if(!valid){this.valid=false;}
}

public boolean push()
{
	if(!this.valid){return false;}
	for(int i=0;i<this.blocks.size();i++)
	{
		PushAttemptBlocks p = this.blocks.get(i);
		PushAttemptMeta p2 = this.meta.get(i);
		try{
		this.world.setBlock(p.x,p.y,p.z,p.b,p2.b,updateClients?2:4);
		}catch(Exception e){};
	}
	return true;
}

public boolean pushIfAvailable()
{
	for(int i=0;i<this.blocks.size();i++)
	{
		PushAttemptBlocks p = this.blocks.get(i);
		PushAttemptMeta p2 = this.meta.get(i);
		if(p.v)
		{
			try{
				this.world.setBlock(p.x,p.y,p.z,p.b,p2.b,updateClients?2:4);
				}catch(Exception e){};
		}
	}
	return true;
}

public boolean pushForce()
{
	for(int i=0;i<this.blocks.size();i++)
	{
		PushAttemptBlocks p = this.blocks.get(i);
		PushAttemptMeta p2 = this.meta.get(i);
		try{
		this.world.setBlock(p.x,p.y,p.z,p.b,p2.b,updateClients?2:4);
		}catch(Exception e){};
	}
	return true;
}

public PushAttempt clone(World w, int x, int y, int z)
{
	return this.clone(w, x, y, z, new PushOperationDef());
}

public PushAttempt clone(World w, int x, int y, int z, PushOperation o)
{
	PushAttempt p = new PushAttempt(w);
	for(int i=0;i<this.blocks.size();i++)
	{
		PushAttemptBlocks p2 = this.blocks.get(i);
		PushAttemptMeta p3 = this.meta.get(i);
		o.setBlockTo(p, p2.x,p2.y,p2.z,p2.b,p3.b);
	}
	PushAttempt p4 = new PushAttempt(w);
	for(int i=0;i<this.blocks.size();i++)
	{
		PushAttemptBlocks p2 = p.blocks.get(i);
		PushAttemptMeta p3 = p.meta.get(i);
		p4.setBlock(p2.x+x,p2.y+y,p2.z+z,p2.b,p3.b);
	}
	return p4;
}

}

 

Thanks in advance!

Creator of the Starfield Mod.

Link to comment
Share on other sites

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.