Package com.khorn.terraincontrol.forge.events

Source Code of com.khorn.terraincontrol.forge.events.SaplingListener

package com.khorn.terraincontrol.forge.events;

import com.khorn.terraincontrol.LocalBiome;
import com.khorn.terraincontrol.LocalMaterialData;
import com.khorn.terraincontrol.LocalWorld;
import com.khorn.terraincontrol.TerrainControl;
import com.khorn.terraincontrol.exception.BiomeNotFoundException;
import com.khorn.terraincontrol.forge.util.WorldHelper;
import com.khorn.terraincontrol.generator.resource.SaplingGen;
import com.khorn.terraincontrol.generator.resource.SaplingType;
import com.khorn.terraincontrol.logging.LogMarker;
import com.khorn.terraincontrol.util.minecraftTypes.DefaultMaterial;
import cpw.mods.fml.common.eventhandler.Event.Result;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.player.BonemealEvent;
import net.minecraftforge.event.terraingen.SaplingGrowTreeEvent;

import java.util.Random;

public class SaplingListener
{
    private static class SaplingGrower
    {
        private final LocalWorld world;
        private final LocalMaterialData material;
        private final SaplingType saplingType;

        private int x;
        private final int y;
        private int z;

        private SaplingGrower(LocalWorld world, int x, int y, int z)
        {
            this.world = world;
            this.material = world.getMaterial(x, y, z);
            this.x = x;
            this.y = y;
            this.z = z;

            // Check whether block is a sapling
            if (!this.material.isMaterial(DefaultMaterial.SAPLING))
            {
                this.saplingType = null;
                return;
            }

            // Try to find big (2x2) sapling
            SaplingType bigSaplingType = getBigSaplingType(this.material.getBlockData());
            if (bigSaplingType != null)
            {
                if (findFourSaplings())
                {
                    this.saplingType = bigSaplingType;
                    return;
                }
            }

            // Try to find small sapling
            this.saplingType = getSmallSaplingType(this.material.getBlockData());
        }

        /**
         * Gets whether the saplings are placed in a 2x2 pattern. If successful,
         * it adjusts {@link SaplingGrower#x} and {@link SaplingGrower#z} to
         * represent the top left sapling (with the lowest x and z).
         *
         * @return Whether the saplings are placed in a 2x2 pattern.
         */
        private boolean findFourSaplings()
        {
            for (int treeOffsetX = 0; treeOffsetX >= -1; --treeOffsetX)
            {
                for (int treeOffsetZ = 0; treeOffsetZ >= -1; --treeOffsetZ)
                {
                    if (isSameSapling(material, world.getMaterial(x + treeOffsetX, y, z + treeOffsetZ))
                            && isSameSapling(material, world.getMaterial(x + treeOffsetX + 1, y, z + treeOffsetZ))
                            && isSameSapling(material, world.getMaterial(x + treeOffsetX, y, z + treeOffsetZ + 1))
                            && isSameSapling(material, world.getMaterial(x + treeOffsetX + 1, y, z + treeOffsetZ + 1)))
                    {
                        // Found! Adjust internal position
                        x = x + treeOffsetX;
                        z = z + treeOffsetZ;
                        return true;
                    }
                }
            }
            return false;
        }
       
        /**
         * Checks if the sapling types are the same, ignoring growth stages.
         * @param sapling1 The first material to compare.
         * @param sapling2 The second material to compare.
         * @return True if both materials are saplings and are of the same type.
         */
        private boolean isSameSapling(LocalMaterialData sapling1, LocalMaterialData sapling2)
        {
            return sapling1.isMaterial(DefaultMaterial.SAPLING)
                    && sapling2.isMaterial(DefaultMaterial.SAPLING)
                    &&  sapling1.getBlockData() % 8 == sapling2.getBlockData() % 8;
        }

        /**
         * Gets the sapling type, based on the assumption that the sapling is
         * not placed in a 2x2 pattern.
         *
         * @param data
         *            The block data of the sapling block.
         * @return The sapling type, or null if not found.
         */
        private SaplingType getSmallSaplingType(int data)
        {
            switch (data % 8)
            { // % 8 makes it ignore growth stage
                case 0:
                    return SaplingType.Oak;
                case 1:
                    return SaplingType.Redwood;
                case 2:
                    return SaplingType.Birch;
                case 3:
                    return SaplingType.SmallJungle;
                case 4:
                    return SaplingType.Acacia;
            }
            return null;
        }

        /**
         * Gets the sapling type, based on the assumption that the saplings must
         * be placed in a 2x2 pattern. Will never return one of the smaller
         * sapling types.
         *
         * @param data
         *            The block data of the sapling block.
         * @return The sapling type, or null if not found.
         */
        private SaplingType getBigSaplingType(int data)
        {
            switch (data % 8)
            { // % 8 makes it ignore growth stage
                case 1:
                    return SaplingType.HugeRedwood;
                case 3:
                    return SaplingType.BigJungle;
                case 5:
                    return SaplingType.DarkOak;
            }
            return null;
        }
    }

    @SubscribeEvent
    public void onSaplingGrow(SaplingGrowTreeEvent event)
    {
        World world = event.world;
        LocalWorld localWorld = WorldHelper.toLocalWorld(world);

        if (localWorld == null)
        {
            // World not managed by Terrain Control
            return;
        }

        SaplingGrower saplingGrower = new SaplingGrower(localWorld, event.x, event.y, event.z);
       
        if (saplingGrower.saplingType == null)
        {
            // Unsupported sapling
            return;
        }

        // Get the sapling generator
        SaplingGen saplingGen = this.getSaplingGen(localWorld, saplingGrower.saplingType, saplingGrower.x, saplingGrower.z);
        if (saplingGen == null)
        {
            // No sapling generator set for this sapling
            return;
        }

        // When we have reached this point, we know that we have to handle the
        // event ourselves
        // So cancel it
        event.setResult(Result.DENY);

        // Remove saplings
        if (saplingGrower.saplingType.requiresFourSaplings())
        {
            world.setBlock(saplingGrower.x, saplingGrower.y, saplingGrower.z, Blocks.air);
            world.setBlock(saplingGrower.x + 1, saplingGrower.y, saplingGrower.z, Blocks.air);
            world.setBlock(saplingGrower.x, saplingGrower.y, saplingGrower.z + 1, Blocks.air);
            world.setBlock(saplingGrower.x + 1, saplingGrower.y, saplingGrower.z + 1, Blocks.air);
        } else
        {
            world.setBlock(saplingGrower.x, saplingGrower.y, saplingGrower.z, Blocks.air);
        }

        // Try ten times to grow sapling
        boolean saplingGrown = false;
        for (int i = 0; i < 10; i++)
        {
            if (saplingGen.growSapling(localWorld, new Random(), saplingGrower.x, saplingGrower.y, saplingGrower.z))
            {
                saplingGrown = true;
                break;
            }
        }

        if (!saplingGrown)
        {
            // Restore sapling
            if (saplingGrower.saplingType.requiresFourSaplings())
            {
                localWorld.setBlock(saplingGrower.x, saplingGrower.y, saplingGrower.z, saplingGrower.material);
                localWorld.setBlock(saplingGrower.x + 1, saplingGrower.y, saplingGrower.z, saplingGrower.material);
                localWorld.setBlock(saplingGrower.x, saplingGrower.y, saplingGrower.z + 1, saplingGrower.material);
                localWorld.setBlock(saplingGrower.x + 1, saplingGrower.y, saplingGrower.z + 1, saplingGrower.material);
            } else
            {
                localWorld.setBlock(saplingGrower.x, saplingGrower.y, saplingGrower.z, saplingGrower.material);
            }
        }

    }

    @SubscribeEvent
    public void onBonemealUse(BonemealEvent event)
    {
        LocalWorld localWorld = WorldHelper.toLocalWorld(event.world);
        if (localWorld == null)
        {
            // World not managed by Terrain Control
            return;
        }

        // Get sapling gen
        SaplingGen gen = null;
        if (event.block == Blocks.red_mushroom_block)
        {
            gen = getSaplingGen(localWorld, SaplingType.RedMushroom, event.x, event.z);
        } else if (event.block == Blocks.brown_mushroom_block)
        {
            gen = getSaplingGen(localWorld, SaplingType.BrownMushroom, event.x, event.z);
        }
        if (gen == null)
        {
            // No sapling gen specified for this type
            return;
        }

        // Generate mushroom
        event.setResult(Result.ALLOW);
        event.world.setBlock(event.x, event.y, event.z, Blocks.air);

        boolean mushroomGrown = false;
        Random random = new Random();
        for (int i = 0; i < 10; i++)
        {
            if (gen.growSapling(localWorld, random, event.x, event.y, event.z))
            {
                mushroomGrown = true;
                break;
            }
        }
        if (!mushroomGrown)
        {
            // Restore mushroom
            event.world.setBlock(event.x, event.y, event.z, event.block, 0, 3);
        }
    }

    // Can return null
    public SaplingGen getSaplingGen(LocalWorld world, SaplingType type, int x, int z)
    {
        try
        {
            LocalBiome biome = world.getSavedBiome(x, z);
            TerrainControl.log(LogMarker.INFO, "Biome: {}" + biome.getName());
            return biome.getBiomeConfig().getSaplingGen(type);
        } catch (BiomeNotFoundException e)
        {
            return null;
        }
    }
}
TOP

Related Classes of com.khorn.terraincontrol.forge.events.SaplingListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.