001/*
002 * Trident - A Multithreaded Server Alternative
003 * Copyright 2014 The TridentSDK Team
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package net.tridentsdk.server.world.gen.brush;
018
019import net.tridentsdk.base.Substance;
020import net.tridentsdk.server.world.WorldUtils;
021import net.tridentsdk.world.ChunkLocation;
022import net.tridentsdk.world.gen.FeatureGenerator;
023import net.tridentsdk.world.gen.GeneratorRandom;
024
025import java.util.concurrent.atomic.AtomicReferenceArray;
026
027/**
028 * Generates oak trees in the world
029 *
030 * @author The TridentSDK Team
031 */
032public class OakTreeBrush extends FeatureGenerator {
033    public OakTreeBrush(long seed) {
034        super(seed);
035    }
036
037    @Override
038    public void generate(ChunkLocation location, int relX, int relZ, GeneratorRandom random, AtomicReferenceArray<Integer> heights, ChunkManipulator manipulator) {
039        if (!manipulator.nodeFits(relX, relZ, 2)) return;
040
041        int heightIndex = WorldUtils.heightIndex(relX, relZ);
042        int top = heights.get(heightIndex);
043        Substance substance = manipulator.blockAt(relX, top, relZ).substance();
044        if (random.under(230) < 4 && (substance == Substance.GRASS || substance == Substance.DIRT)) {
045            for (int i = 1; i < 7; i++) {
046                if (i <= 2) {
047                    manipulator.manipulate(relX, top + i, relZ, Substance.LOG, (byte) 0x00);
048                } else if (i > 2 && i <= 4) {
049                    manipulator.manipulate(relX, top + i, relZ, Substance.LOG, (byte) 0x00);
050                    /*
051                     -2, 2 L L L L L 2,2
052                           L L L L L
053                           L L O L L       L = Leaves
054                           L L L L L       O = Oak
055                     -2,-2 L L L L L 2,-2
056                     */
057
058                    for (int x = relX - 2; x <= relX + 2; x++) {
059                        for (int z = relZ - 2; z <= relZ + 2; z++) {
060                            if (x == relX && z == relZ) {
061                                manipulator.manipulate(relX, top + i, relZ, Substance.LOG, (byte) 0x00);
062                            } else {
063                                manipulator.manipulate(x, top + i, z, Substance.LEAVES, (byte) 0x00);
064                            }
065                        }
066                    }
067                } else if (i > 4) {
068                    if (i != 6) {
069                        manipulator.manipulate(relX, top + i, relZ, Substance.LOG, (byte) 0x00);
070                    } else {
071                        manipulator.manipulate(relX, top + i, relZ, Substance.LEAVES, (byte) 0x00);
072                    }
073                    manipulator.manipulate(relX + 1, top + i, relZ, Substance.LEAVES, (byte) 0x00);
074                    manipulator.manipulate(relX - 1, top + i, relZ, Substance.LEAVES, (byte) 0x00);
075                    manipulator.manipulate(relX, top + i, relZ + 1, Substance.LEAVES, (byte) 0x00);
076                    manipulator.manipulate(relX, top + i, relZ - 1, Substance.LEAVES, (byte) 0x00);
077                }
078            }
079        }
080    }
081}