Package com.pclewis.mcpatcher.mod

Source Code of com.pclewis.mcpatcher.mod.TileOverride$Horizontal

package com.pclewis.mcpatcher.mod;

import com.pclewis.mcpatcher.MCLogger;
import com.pclewis.mcpatcher.MCPatcherUtils;
import com.pclewis.mcpatcher.TexturePackAPI;
import com.pclewis.mcpatcher.WeightedIndex;
import net.minecraft.src.Block;
import net.minecraft.src.IBlockAccess;
import net.minecraft.src.RenderBlocks;

import java.awt.image.BufferedImage;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

abstract class TileOverride {
    private static final MCLogger logger = MCLogger.getLogger(MCPatcherUtils.CONNECTED_TEXTURES, "CTM");

    static final int BOTTOM_FACE = 0; // 0, -1, 0
    static final int TOP_FACE = 1; // 0, 1, 0
    static final int NORTH_FACE = 2; // 0, 0, -1
    static final int SOUTH_FACE = 3; // 0, 0, 1
    static final int WEST_FACE = 4; // -1, 0, 0
    static final int EAST_FACE = 5; // 1, 0, 0

    private static final int[][] ROTATE_UV_MAP = new int[][]{
        {WEST_FACE, EAST_FACE, NORTH_FACE, SOUTH_FACE, TOP_FACE, BOTTOM_FACE, 2, -2, 2, -2, 0, 0},
        {NORTH_FACE, SOUTH_FACE, TOP_FACE, BOTTOM_FACE, WEST_FACE, EAST_FACE, 0, 0, 0, 0, -2, 2},
    };

    private static final int[] GO_DOWN = new int[]{0, -1, 0};
    private static final int[] GO_UP = new int[]{0, 1, 0};
    private static final int[] GO_NORTH = new int[]{0, 0, -1};
    private static final int[] GO_SOUTH = new int[]{0, 0, 1};
    private static final int[] GO_WEST = new int[]{-1, 0, 0};
    private static final int[] GO_EAST = new int[]{1, 0, 0};

    // NEIGHBOR_OFFSETS[a][b][c] = offset from starting block
    // a: face 0-5
    // b: neighbor 0-7
    //    7   6   5
    //    0   *   4
    //    1   2   3
    // c: coordinate (x,y,z) 0-2
    private static final int[][][] NEIGHBOR_OFFSET = new int[][][]{
        // BOTTOM_FACE
        {
            GO_WEST,
            add(GO_WEST, GO_SOUTH),
            GO_SOUTH,
            add(GO_EAST, GO_SOUTH),
            GO_EAST,
            add(GO_EAST, GO_NORTH),
            GO_NORTH,
            add(GO_WEST, GO_NORTH),
        },
        // TOP_FACE
        {
            GO_WEST,
            add(GO_WEST, GO_SOUTH),
            GO_SOUTH,
            add(GO_EAST, GO_SOUTH),
            GO_EAST,
            add(GO_EAST, GO_NORTH),
            GO_NORTH,
            add(GO_WEST, GO_NORTH),
        },
        // NORTH_FACE
        {
            GO_EAST,
            add(GO_EAST, GO_DOWN),
            GO_DOWN,
            add(GO_WEST, GO_DOWN),
            GO_WEST,
            add(GO_WEST, GO_UP),
            GO_UP,
            add(GO_EAST, GO_UP),
        },
        // SOUTH_FACE
        {
            GO_WEST,
            add(GO_WEST, GO_DOWN),
            GO_DOWN,
            add(GO_EAST, GO_DOWN),
            GO_EAST,
            add(GO_EAST, GO_UP),
            GO_UP,
            add(GO_WEST, GO_UP),
        },
        // WEST_FACE
        {
            GO_NORTH,
            add(GO_NORTH, GO_DOWN),
            GO_DOWN,
            add(GO_SOUTH, GO_DOWN),
            GO_SOUTH,
            add(GO_SOUTH, GO_UP),
            GO_UP,
            add(GO_NORTH, GO_UP),
        },
        // EAST_FACE
        {
            GO_SOUTH,
            add(GO_SOUTH, GO_DOWN),
            GO_DOWN,
            add(GO_NORTH, GO_DOWN),
            GO_NORTH,
            add(GO_NORTH, GO_UP),
            GO_UP,
            add(GO_SOUTH, GO_UP),
        },
    };

    private static final int CONNECT_BY_BLOCK = 0;
    private static final int CONNECT_BY_TILE = 1;
    private static final int CONNECT_BY_MATERIAL = 2;

    private static final Method forceMipmapType;

    final String filePrefix;
    final String textureName;
    final int texture;
    final int renderPass;
    final int[] blockIDs;
    final int[] tileIDs;
    final int faces;
    final int metadata;
    final int connectType;
    final int[] tileMap;

    boolean disabled;
    int[] reorient;
    int metamask;
    int rotateUV;
    boolean rotateTop;

    static {
        Method method = null;
        try {
            Class<?> cl = Class.forName(MCPatcherUtils.MIPMAP_HELPER_CLASS);
            method = cl.getDeclaredMethod("forceMipmapType", String.class, Integer.TYPE);
        } catch (ClassNotFoundException e) {
        } catch (NoSuchMethodException e) {
        }
        forceMipmapType = method;
    }

    static TileOverride create(String filePrefix, Properties properties) {
        if (filePrefix == null) {
            return null;
        }
        if (properties == null) {
            properties = TexturePackAPI.getProperties(filePrefix + ".properties");
        }
        if (properties == null) {
            return null;
        }

        String method = properties.getProperty("method", "default").trim().toLowerCase();
        TileOverride override = null;

        if (method.equals("default") || method.equals("glass") || method.equals("ctm")) {
            override = new CTM(filePrefix, properties);
        } else if (method.equals("random")) {
            override = new Random1(filePrefix, properties);
        } else if (method.equals("fixed") || method.equals("static")) {
            override = new Fixed(filePrefix, properties);
        } else if (method.equals("bookshelf") || method.equals("horizontal")) {
            override = new Horizontal(filePrefix, properties);
        } else if (method.equals("vertical")) {
            override = new Vertical(filePrefix, properties);
        } else if (method.equals("sandstone") || method.equals("top")) {
            override = new Top(filePrefix, properties);
        } else if (method.equals("repeat") || method.equals("pattern")) {
            override = new Repeat(filePrefix, properties);
        } else {
            logger.severe("%s.properties: unknown method \"%s\"", filePrefix, method);
        }

        if (override == null || override.disabled) {
        } else if (override.tileMap == null || override.tileMap.length == 0) {
            override.error("no tile map given");
        } else {
            String status = override.checkTileMap();
            if (status != null) {
                override.error("invalid %s tile map: %s", override.getMethod(), status);
            }
        }

        return override == null || override.disabled ? null : override;
    }

    static TileOverride create(BufferedImage image, int tileID) {
        TileOverride override = new CTM(image, tileID);
        return override.disabled ? null : override;
    }

    private TileOverride(BufferedImage image, int tileID) {
        filePrefix = null;
        textureName = null;
        texture = MCPatcherUtils.getMinecraft().renderEngine.allocateAndSetupTexture(image);
        renderPass = -1;
        blockIDs = new int[0];
        tileIDs = new int[]{tileID};
        faces = -1;
        metadata = -1;
        connectType = CONNECT_BY_MATERIAL;
        tileMap = null;
    }

    private TileOverride(String filePrefix, Properties properties) {
        this.filePrefix = filePrefix;
        textureName = properties.getProperty("source", filePrefix + ".png");

        int pass = 0;
        try {
            pass = Integer.parseInt(properties.getProperty("renderPass", "-1"));
        } catch (NumberFormatException e) {
        }
        renderPass = pass;
        if (forceMipmapType != null) {
            try {
                forceMipmapType.invoke(null, textureName, renderPass > 2 ? 2 : 1);
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }

        texture = CTMUtils.getTexture(textureName);
        if (texture < 0) {
            if (properties.contains("source")) {
                error("source texture %s not found", textureName);
            } else {
                disabled = true;
            }
        }

        blockIDs = getIDList(properties, "blockIDs", "block", Block.blocksList.length - 1);
        tileIDs = getIDList(properties, "tileIDs", "terrain", CTMUtils.NUM_TILES - 1);
        if (blockIDs.length == 0 && tileIDs.length == 0) {
            error("no block or tile IDs matched");
        }

        int flags = 0;
        for (String val : properties.getProperty("faces", "all").trim().toLowerCase().split("\\s+")) {
            if (val.equals("bottom")) {
                flags |= (1 << BOTTOM_FACE);
            } else if (val.equals("top")) {
                flags |= (1 << TOP_FACE);
            } else if (val.equals("north")) {
                flags |= (1 << NORTH_FACE);
            } else if (val.equals("south")) {
                flags |= (1 << SOUTH_FACE);
            } else if (val.equals("east")) {
                flags |= (1 << EAST_FACE);
            } else if (val.equals("west")) {
                flags |= (1 << WEST_FACE);
            } else if (val.equals("side") || val.equals("sides")) {
                flags |= (1 << NORTH_FACE) | (1 << SOUTH_FACE) | (1 << EAST_FACE) | (1 << WEST_FACE);
            } else if (val.equals("all")) {
                flags = -1;
            }
        }
        faces = flags;

        int meta = 0;
        for (int i : MCPatcherUtils.parseIntegerList(properties.getProperty("metadata", "0-31"), 0, 31)) {
            meta |= (1 << i);
        }
        metadata = meta;

        String connectType1 = properties.getProperty("connect", "").trim().toLowerCase();
        if (connectType1.equals("")) {
            connectType = tileIDs.length > 0 ? CONNECT_BY_TILE : CONNECT_BY_BLOCK;
        } else if (connectType1.equals("block")) {
            connectType = CONNECT_BY_BLOCK;
        } else if (connectType1.equals("tile")) {
            connectType = CONNECT_BY_TILE;
        } else if (connectType1.equals("material")) {
            connectType = CONNECT_BY_MATERIAL;
        } else {
            error("invalid connect type %s", connectType1);
            connectType = CONNECT_BY_BLOCK;
        }

        String tileList = properties.getProperty("tiles", "");
        if (tileList.equals("")) {
            tileMap = getDefaultTileMap();
        } else {
            tileMap = MCPatcherUtils.parseIntegerList(tileList, 0, 255);
        }

        if (renderPass > 3) {
            error("renderPass must be 0-3");
        } else if (renderPass >= 0 && tileIDs.length > 0) {
            error("renderPass=%d must be block-based not tile-based", renderPass);
        }
    }

    private int[] getIDList(Properties properties, String key, String type, int maxID) {
        int[] list = MCPatcherUtils.parseIntegerList(properties.getProperty(key, "").trim(), 0, maxID);
        if (list.length > 0) {
            return list;
        }
        Matcher m = Pattern.compile("/" + type + "(\\d+)").matcher(filePrefix);
        if (m.find()) {
            try {
                list = new int[]{Integer.parseInt(m.group(1))};
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    private static int[] add(int[] a, int[] b) {
        if (a.length != b.length) {
            throw new RuntimeException("arrays to add are not same length");
        }
        int[] c = new int[a.length];
        for (int i = 0; i < c.length; i++) {
            c[i] = a[i] + b[i];
        }
        return c;
    }

    int[] getDefaultTileMap() {
        return null;
    }

    String checkTileMap() {
        return null;
    }

    boolean requiresFace() {
        return false;
    }

    @Override
    public String toString() {
        return String.format("%s[%s]", getMethod(), textureName);
    }

    final void error(String format, Object... params) {
        if (filePrefix != null && !filePrefix.equals("/ctm")) {
            logger.severe(filePrefix + ".properties: " + format, params);
        }
        disabled = true;
    }

    final boolean shouldConnect(IBlockAccess blockAccess, Block block, int tileNum, int i, int j, int k, int face, int[] offset) {
        int meta = blockAccess.getBlockMetadata(i, j, k);
        i += offset[0];
        j += offset[1];
        k += offset[2];
        int neighborID = blockAccess.getBlockId(i, j, k);
        Block neighbor = Block.blocksList[neighborID];
        if (exclude(blockAccess, neighbor, tileNum, i, j, k, face)) {
            return false;
        } else if (metamask != -1 && (blockAccess.getBlockMetadata(i, j, k) & ~metamask) != (meta & ~metamask)) {
            return false;
        }
        switch (connectType) {
            case CONNECT_BY_BLOCK:
                return neighborID == block.blockID;

            case CONNECT_BY_TILE:
                return neighbor.getBlockTexture(blockAccess, i, j, k, face) == tileNum;

            case CONNECT_BY_MATERIAL:
                return block.blockMaterial == neighbor.blockMaterial;

            default:
                return false;
        }
    }

    final int reorient(int face) {
        if (face < 0 || face > 5 || reorient == null) {
            return face;
        } else {
            return reorient[face];
        }
    }

    final boolean exclude(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
        if (block == null) {
            return true;
        } else if (RenderPassAPI.instance.skipThisRenderPass(block, renderPass)) {
            return true;
        } else if ((faces & (1 << reorient(face))) == 0) {
            return true;
        } else if (metadata != -1) {
            int meta = blockAccess.getBlockMetadata(i, j, k);
            if (meta >= 0 && meta < 32 && (metadata & ((1 << meta) | (1 << (meta & metamask)))) == 0) {
                return true;
            }
        }
        return false;
    }

    final int getTile(RenderBlocks renderBlocks, IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
        if (face < 0) {
            if (requiresFace()) {
                error("method=%s is not supported for non-standard blocks", getMethod());
                return -1;
            }
        }
        reorient = null;
        metamask = -1;
        rotateUV = 0;
        rotateTop = false;
        if (block.blockID == CTMUtils.BLOCK_ID_LOG) {
            metamask = ~0xc;
            int orientation = blockAccess.getBlockMetadata(i, j, k) & 0xc;
            if (orientation == 4) { // east/west cut
                reorient = ROTATE_UV_MAP[0];
                rotateUV = ROTATE_UV_MAP[0][face + 6];
                rotateTop = true;
            } else if (orientation == 8) { // north/south cut
                reorient = ROTATE_UV_MAP[1];
                rotateUV = ROTATE_UV_MAP[1][face + 6];
            }
        }
        if (exclude(blockAccess, block, origTexture, i, j, k, face)) {
            return -1;
        } else {
            return getTileImpl(blockAccess, block, origTexture, i, j, k, face);
        }
    }

    final int rotateUV(int neighbor) {
        return (neighbor + rotateUV) & 7;
    }

    private static int[] compose(int[] map1, int[] map2) {
        int[] newMap = new int[map2.length];
        for (int i = 0; i < map2.length; i++) {
            newMap[i] = map1[map2[i]];
        }
        return newMap;
    }

    abstract String getMethod();

    abstract int getTileImpl(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face);

    final static class CTM extends TileOverride {
        private static final int[] defaultTileMap = new int[]{
            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
            32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
            48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
        };

        // Index into this array is formed from these bit values:
        // 128 64  32
        // 1   *   16
        // 2   4   8
        private static final int[] neighborMap = new int[]{
            0, 3, 0, 3, 12, 5, 12, 15, 0, 3, 0, 3, 12, 5, 12, 15,
            1, 2, 1, 2, 4, 7, 4, 29, 1, 2, 1, 2, 13, 31, 13, 14,
            0, 3, 0, 3, 12, 5, 12, 15, 0, 3, 0, 3, 12, 5, 12, 15,
            1, 2, 1, 2, 4, 7, 4, 29, 1, 2, 1, 2, 13, 31, 13, 14,
            36, 17, 36, 17, 24, 19, 24, 43, 36, 17, 36, 17, 24, 19, 24, 43,
            16, 18, 16, 18, 6, 46, 6, 21, 16, 18, 16, 18, 28, 9, 28, 22,
            36, 17, 36, 17, 24, 19, 24, 43, 36, 17, 36, 17, 24, 19, 24, 43,
            37, 40, 37, 40, 30, 8, 30, 34, 37, 40, 37, 40, 25, 23, 25, 45,
            0, 3, 0, 3, 12, 5, 12, 15, 0, 3, 0, 3, 12, 5, 12, 15,
            1, 2, 1, 2, 4, 7, 4, 29, 1, 2, 1, 2, 13, 31, 13, 14,
            0, 3, 0, 3, 12, 5, 12, 15, 0, 3, 0, 3, 12, 5, 12, 15,
            1, 2, 1, 2, 4, 7, 4, 29, 1, 2, 1, 2, 13, 31, 13, 14,
            36, 39, 36, 39, 24, 41, 24, 27, 36, 39, 36, 39, 24, 41, 24, 27,
            16, 42, 16, 42, 6, 20, 6, 10, 16, 42, 16, 42, 28, 35, 28, 44,
            36, 39, 36, 39, 24, 41, 24, 27, 36, 39, 36, 39, 24, 41, 24, 27,
            37, 38, 37, 38, 30, 11, 30, 32, 37, 38, 37, 38, 25, 33, 25, 26,
        };

        private final int[] neighborTileMap;

        private CTM(BufferedImage image, int tileID) {
            super(image, tileID);
            neighborTileMap = compose(defaultTileMap, neighborMap);
        }

        private CTM(String filePrefix, Properties properties) {
            super(filePrefix, properties);
            neighborTileMap = compose(tileMap, neighborMap);
        }

        @Override
        String getMethod() {
            return "ctm";
        }

        @Override
        int[] getDefaultTileMap() {
            return defaultTileMap;
        }

        @Override
        String checkTileMap() {
            if (tileMap.length >= 47) {
                return null;
            } else {
                return "requires at least 47 tiles";
            }
        }

        @Override
        boolean requiresFace() {
            return true;
        }

        @Override
        int getTileImpl(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
            int[][] offsets = NEIGHBOR_OFFSET[face];
            int neighborBits = 0;
            for (int bit = 0; bit < 8; bit++) {
                if (shouldConnect(blockAccess, block, origTexture, i, j, k, face, offsets[bit])) {
                    neighborBits |= (1 << bit);
                }
            }
            return neighborTileMap[neighborBits];
        }
    }

    final static class Horizontal extends TileOverride {
        private static final int[] defaultTileMap = new int[]{
            12, 13, 14, 15,
        };

        // Index into this array is formed from these bit values:
        // 1   *   2
        private static final int[] neighborMap = new int[]{
            3, 2, 0, 1,
        };

        private final int[] neighborTileMap;

        private Horizontal(String filePrefix, Properties properties) {
            super(filePrefix, properties);
            neighborTileMap = compose(tileMap, neighborMap);
        }

        @Override
        String getMethod() {
            return "horizontal";
        }

        @Override
        int[] getDefaultTileMap() {
            return defaultTileMap;
        }

        @Override
        String checkTileMap() {
            if (tileMap.length == 4) {
                return null;
            } else {
                return "requires exactly 4 tiles";
            }
        }

        @Override
        int getTileImpl(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
            if (face < 0) {
                face = NORTH_FACE;
            } else if (reorient(face) <= TOP_FACE) {
                return -1;
            }
            int[][] offsets = NEIGHBOR_OFFSET[face];
            int neighborBits = 0;
            if (shouldConnect(blockAccess, block, origTexture, i, j, k, face, offsets[rotateUV(0)])) {
                neighborBits |= 1;
            }
            if (shouldConnect(blockAccess, block, origTexture, i, j, k, face, offsets[rotateUV(4)])) {
                neighborBits |= 2;
            }
            return neighborTileMap[neighborBits];
        }
    }

    final static class Vertical extends TileOverride {
        private static final int[] defaultTileMap = new int[]{
            48, 32, 16, 0,
        };

        // Index into this array is formed from these bit values:
        // 2
        // *
        // 1
        private static final int[] neighborMap = new int[]{
            3, 2, 0, 1,
        };

        private final int[] neighborTileMap;

        private Vertical(String filePrefix, Properties properties) {
            super(filePrefix, properties);
            neighborTileMap = compose(tileMap, neighborMap);
        }

        @Override
        String getMethod() {
            return "vertical";
        }

        @Override
        int[] getDefaultTileMap() {
            return defaultTileMap;
        }

        @Override
        String checkTileMap() {
            if (tileMap.length == 4) {
                return null;
            } else {
                return "requires exactly 4 tiles";
            }
        }

        @Override
        int getTileImpl(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
            if (face < 0) {
                face = NORTH_FACE;
            } else if (reorient(face) <= TOP_FACE) {
                return -1;
            }
            int[][] offsets = NEIGHBOR_OFFSET[face];
            int neighborBits = 0;
            if (shouldConnect(blockAccess, block, origTexture, i, j, k, face, offsets[rotateUV(2)])) {
                neighborBits |= 1;
            }
            if (shouldConnect(blockAccess, block, origTexture, i, j, k, face, offsets[rotateUV(6)])) {
                neighborBits |= 2;
            }
            return neighborTileMap[neighborBits];
        }
    }

    final static class Top extends TileOverride {
        private static final int[] defaultTileMap = new int[]{
            66,
        };

        private Top(String filePrefix, Properties properties) {
            super(filePrefix, properties);
        }

        @Override
        String getMethod() {
            return "top";
        }

        @Override
        int[] getDefaultTileMap() {
            return defaultTileMap;
        }

        @Override
        String checkTileMap() {
            if (tileMap.length == 1) {
                return null;
            } else {
                return "requires exactly 1 tile";
            }
        }

        @Override
        int getTileImpl(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
            if (face < 0) {
                face = NORTH_FACE;
            } else if (reorient(face) <= TOP_FACE) {
                return -1;
            }
            int[][] offsets = NEIGHBOR_OFFSET[face];
            if (shouldConnect(blockAccess, block, origTexture, i, j, k, face, offsets[rotateUV(6)])) {
                return tileMap[0];
            }
            return -1;
        }
    }

    final static class Random1 extends TileOverride {
        private static final long P1 = 0x1c3764a30115L;
        private static final long P2 = 0x227c1adccd1dL;
        private static final long P3 = 0xe0d251c03ba5L;
        private static final long P4 = 0xa2fb1377aeb3L;
        private static final long MULTIPLIER = 0x5deece66dL;
        private static final long ADDEND = 0xbL;

        private final int symmetry;
        private final WeightedIndex chooser;

        private Random1(String filePrefix, Properties properties) {
            super(filePrefix, properties);

            String sym = properties.getProperty("symmetry", "none");
            if (sym.equals("all")) {
                symmetry = 6;
            } else if (sym.equals("opposite")) {
                symmetry = 2;
            } else {
                symmetry = 1;
            }

            chooser = WeightedIndex.create(tileMap.length, properties.getProperty("weights", ""));
            if (chooser == null) {
                error("invalid weights");
            }
        }

        @Override
        String getMethod() {
            return "random";
        }

        @Override
        int getTileImpl(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
            if (tileMap.length == 1) {
                return tileMap[0];
            }
            if (face < 0) {
                face = 0;
            }
            face = reorient(face) / symmetry;
            long n = P1 * i * (i + ADDEND) + P2 * j * (j + ADDEND) + P3 * k * (k + ADDEND) + P4 * face * (face + ADDEND);
            n = MULTIPLIER * (n + i + j + k + face) + ADDEND;
            int index = chooser.choose(n);
            return tileMap[index];
        }
    }

    final static class Repeat extends TileOverride {
        private final int width;
        private final int height;
        private final int symmetry;

        Repeat(String filePrefix, Properties properties) {
            super(filePrefix, properties);
            int w = 0;
            int h = 0;
            try {
                w = Integer.parseInt(properties.getProperty("width", "0"));
                h = Integer.parseInt(properties.getProperty("height", "0"));
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            width = w;
            height = h;
            if (width <= 0 || height <= 0 || width * height > CTMUtils.NUM_TILES) {
                error("invalid width and height (%dx%d)", width, height);
            }

            String sym = properties.getProperty("symmetry", "none");
            if (sym.equals("opposite")) {
                symmetry = ~1;
            } else {
                symmetry = -1;
            }
        }

        @Override
        String getMethod() {
            return "repeat";
        }

        @Override
        String checkTileMap() {
            if (tileMap.length == width * height) {
                return null;
            } else {
                return String.format("requires exactly %dx%d tiles", width, height);
            }
        }

        @Override
        int getTileImpl(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
            if (face < 0) {
                face = 0;
            }
            face &= symmetry;
            int x;
            int y;
            switch (face) {
                case TOP_FACE:
                case BOTTOM_FACE:
                    if (rotateTop) {
                        x = k;
                        y = i;
                    } else {
                        x = i;
                        y = k;
                    }
                    break;

                case NORTH_FACE:
                    x = -i - 1;
                    y = -j;
                    break;

                case SOUTH_FACE:
                    x = i;
                    y = -j;
                    break;

                case WEST_FACE:
                    x = k;
                    y = -j;
                    break;

                case EAST_FACE:
                    x = -k - 1;
                    y = -j;
                    break;

                default:
                    return -1;
            }
            x %= width;
            if (x < 0) {
                x += width;
            }
            y %= height;
            if (y < 0) {
                y += height;
            }
            return tileMap[width * y + x];
        }
    }

    final static class Fixed extends TileOverride {
        private Fixed(String filePrefix, Properties properties) {
            super(filePrefix, properties);
        }

        @Override
        String getMethod() {
            return "fixed";
        }

        @Override
        String checkTileMap() {
            if (tileMap.length == 1) {
                return null;
            } else {
                return "requires exactly 1 tile";
            }
        }

        @Override
        int getTileImpl(IBlockAccess blockAccess, Block block, int origTexture, int i, int j, int k, int face) {
            return tileMap[0];
        }
    }
}
TOP

Related Classes of com.pclewis.mcpatcher.mod.TileOverride$Horizontal

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.