Terrain Control

Terrain Control

235k Downloads

Saplings disappearing instead of custom tree spawn

Kiwii opened this issue ยท 4 comments

commented

With custom trees enabled, there is a chance that on sapling-growth no custom tree is found for that biome/conditions and there is nothing grown instead. The sampling than just disappears.

The problem is that the eventhandler does not check if the spawning of a custom tree was successful and always aborts the normal growth event:

// from com/khorn/terraincontrol/bukkit/TCListener.java, lines 39 - 51:

    @EventHandler(priority = EventPriority.NORMAL)
    public void onStructureGrow(StructureGrowEvent event)
    {
        BukkitWorld bukkitWorld = this.tcPlugin.worlds.get(event.getWorld().getUID());
        if (bukkitWorld != null && bukkitWorld.getSettings().HasCustomTrees)
        {
            if (this.random.nextInt(100) < bukkitWorld.getSettings().customTreeChance)
            {
                CustomObjectGen.SpawnCustomTrees(bukkitWorld, this.random, bukkitWorld.getSettings(), event.getLocation().getBlockX(), event.getLocation().getBlockY(), event.getLocation().getBlockZ());
                // SpawnCustomTrees is not guaranteed to actually spawn a tree. 
                // It aborts after the number of tries specified in worldSettings.objectSpawnRatio

                event.getBlocks().clear(); // <--- this aborts the event (I think)
            }
        }
    }

The way that SpawnCustomTree works does not guarantee that an object is spawned. In fact with a decent amount of bo2s the chance for something to get spawned is rather small. This is not a problem when terrain is generated, as there is a huge number of attempts to place custom objects. But for tree growth from saplings it is a problem, because we want a tree to grow from every sapling.

As you can see, the function does not spawn anything if number of attempts is reached which can be very fast when e.g. an object from the wrong biome is chosen or an object that is not allowed to spawn on block or the object has a low rarity value:

// from src/com/khorn/terraincontrol/customobjects/CustomObjectGen.java, lines 127 - 158:

public static boolean SpawnCustomTrees(LocalWorld world, Random rand, WorldConfig worldSettings, int x, int y, int z)
    {

        if (!worldSettings.HasCustomTrees)
            return false;

        String biomeName = world.getLocalBiome(x | 0xF, z | 0xF).getName();

        boolean objectSpawned = false;
        int spawnattemps = 0;
        while (!objectSpawned && spawnattemps < worldSettings.objectSpawnRatio)
        {
            CustomObject SelectedObject = worldSettings.Objects.get(rand.nextInt(worldSettings.Objects.size()));

            spawnattemps++;

            if (SelectedObject.branch || !SelectedObject.canSpawnInBiome(biomeName) || !SelectedObject.tree)
                continue;


            int randomRoll = rand.nextInt(100);

            if (randomRoll < SelectedObject.rarity)
            {
                if (CustomObjectGen.ObjectCanSpawn(world, x, y, z, SelectedObject))
                    objectSpawned = GenerateCustomObject(world, rand, worldSettings, x, y, z, SelectedObject, true);
            }

        }
        return objectSpawned;
    }

Possible solutions would be:

  • only cancel the event in onStructureGrow if SpawnCustomTrees has success (could be checked from return value)
  • to use a different spawn function that is guaranteed to spawn an object (e.g. by first making an array/list of allowed trees and then choosing one of those)
  • adding a seperate "objectSpawnRatio" setting (that defaults to a very much higher number of attempts) for trees that grow from saplings.
commented

Done it new version.

commented

Hm you right ..
I will change this, anyway i some rewriting/thinking about bo2 system.

commented

If you are going to make big changes to the bo2 system you could probably add a feature that was requested earlier: Adding an option in the bo2 file that specifies from which kind of sapling a tree can grow. Something like:

growFromSapling=<stringList> [Default: "All"] [Bound: Only "All", "None", "Oak", "Spruce", "Birch" or "Jungle"]

Maybe you could talk to Ohmusama from BetterBOB and discuss that? I guess a lot of people would appreciate that!

commented

Hmm did not see that before ..
Good point. Need make list for all requested features for bo2 :/