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.world.gen;
018
019import net.tridentsdk.base.Block;
020import net.tridentsdk.base.Substance;
021import net.tridentsdk.world.ChunkLocation;
022
023import java.util.concurrent.atomic.AtomicReferenceArray;
024
025/**
026 * An overlay generate is a block populator that is used to lay blocks or structures once the chunk has been generated
027 *
028 * @author The TridentSDK Team
029 */
030public abstract class FeatureGenerator {
031    protected final long seed;
032
033    public FeatureGenerator(long seed) {
034        this.seed = seed;
035    }
036
037    /**
038     * Obtains the chunk generation seed
039     *
040     * @return the seed
041     */
042    public long seed() {
043        return this.seed;
044    }
045
046    /**
047     * Brushes the terrain
048     *
049     * @param location the location of the chunk to generate
050     * @param relX the relative chunk X of the chunk
051     * @param relZ the relative Z
052     * @param random the generator random
053     * @param heights the height array to edit
054     * @param manipulator the tool used to set block types in the chunk and to cross
055     *                    chunk boundaries if needed
056     */
057    public abstract void generate(ChunkLocation location,
058                                  int relX,
059                                  int relZ,
060                                  GeneratorRandom random,
061                                  AtomicReferenceArray<Integer> heights,
062                                  ChunkManipulator manipulator);
063
064    /**
065     * Provides special functionality for chunk manipulation
066     *
067     * @author The TridentSDK Team
068     */
069    public interface ChunkManipulator {
070        /**
071         * Manipulates the chunk
072         *
073         * @param relX the relative x, can be out of 0-15 range
074         * @param y the y coordinate
075         * @param relZ the relative z, can be out of 0-15 range
076         * @param substance the substance to set
077         * @param data the data to set
078         */
079        void manipulate(int relX, int y, int relZ, Substance substance, byte data);
080
081        /**
082         * Obtains the block at the relative location
083         *
084         * @param relX the relative x
085         * @param y the y
086         * @param relZ the relative z
087         * @return the block
088         */
089        Block blockAt(int relX, int y, int relZ);
090
091        /**
092         * Ensures that the particular feature fits within the bounds of the chunk
093         *
094         * @param relX  the relative x
095         * @param relZ  the relative z
096         * @param bound the range from the center non-inclusively counting the last block
097         * @return {@code true} if the node is within bound
098         */
099        default boolean nodeFits(int relX, int relZ, int bound) {
100            return relX - bound >= 0 && relX + bound <= 15
101                    && relZ - bound >= 0 && relZ + bound <= 15;
102        }
103    }
104}