001/*
002 * This file is part of Baritone.
003 *
004 * Baritone is free software: you can redistribute it and/or modify
005 * it under the terms of the GNU Lesser General Public License as published by
006 * the Free Software Foundation, either version 3 of the License, or
007 * (at your option) any later version.
008 *
009 * Baritone is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public License
015 * along with Baritone.  If not, see <https://www.gnu.org/licenses/>.
016 */
017
018package baritone.api.schematic;
019
020import net.minecraft.block.state.IBlockState;
021import net.minecraft.util.EnumFacing;
022
023import java.util.List;
024
025/**
026 * Basic representation of a schematic. Provides the dimensions and the desired state for a given position relative to
027 * the origin.
028 *
029 * @author leijurv
030 */
031public interface ISchematic {
032
033    /**
034     * Does the block at this coordinate matter to the schematic?
035     * <p>
036     * Normally just a check for if the coordinate is in the cube.
037     * <p>
038     * However, in the case of something like a map art, anything that's below the level of the map art doesn't matter,
039     * so this function should return false in that case. (i.e. it doesn't really have to be air below the art blocks)
040     *
041     * @param x            The x position of the block, relative to the origin
042     * @param y            The y position of the block, relative to the origin
043     * @param z            The z position of the block, relative to the origin
044     * @param currentState The current state of that block in the world, or null
045     * @return Whether or not the specified position is within the bounds of this schematic
046     */
047    default boolean inSchematic(int x, int y, int z, IBlockState currentState) {
048        return x >= 0 && x < widthX() && y >= 0 && y < heightY() && z >= 0 && z < lengthZ();
049    }
050
051    default int size(EnumFacing.Axis axis) {
052        switch (axis) {
053            case X:
054                return widthX();
055            case Y:
056                return heightY();
057            case Z:
058                return lengthZ();
059            default:
060                throw new UnsupportedOperationException(axis + "");
061        }
062    }
063
064    /**
065     * Returns the desired block state at a given (X, Y, Z) position relative to the origin (0, 0, 0).
066     *
067     * @param x               The x position of the block, relative to the origin
068     * @param y               The y position of the block, relative to the origin
069     * @param z               The z position of the block, relative to the origin
070     * @param current         The current state of that block in the world, or null
071     * @param approxPlaceable The list of blockstates estimated to be placeable
072     * @return The desired block state at the specified position
073     */
074    IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable);
075
076    /**
077     * Resets possible caches to avoid wrong behavior when moving the schematic around
078     */
079    default void reset() {}
080
081    /**
082     * @return The width (X axis length) of this schematic
083     */
084    int widthX();
085
086    /**
087     * @return The height (Y axis length) of this schematic
088     */
089    int heightY();
090
091    /**
092     * @return The length (Z axis length) of this schematic
093     */
094    int lengthZ();
095}