diff --git a/src/main/java/com/cricketcraft/chisel/api/IConnectionAccess.java b/src/main/java/com/cricketcraft/chisel/api/IConnectionAccess.java new file mode 100644 index 00000000..5ca27f56 --- /dev/null +++ b/src/main/java/com/cricketcraft/chisel/api/IConnectionAccess.java @@ -0,0 +1,34 @@ +package com.cricketcraft.chisel.api; + +import net.minecraft.block.Block; +import net.minecraft.world.IBlockAccess; + +/** + * To be implemented on an {@link IBlockAccess} that renders blocks which are only part of a block space, so it can + * decide connected textures itself instead of reporting the blocks around it. + *

+ * Connected textures ask this for every location they check, while rendering in this world. Render bounds smaller than + * the block are then a part of the block: they show the matching part of the block's connected texture, instead of the + * whole texture squeezed into the bounds. + */ +public interface IConnectionAccess { + + /** + * Whether the given location shows the block being rendered, as seen from the block being rendered. + * + * @param x X coord of the block to check against. NOT the position of the block being rendered. + * @param y Y coord of the block to check against. + * @param z Z coord of the block to check against. + * @param side The side being rendered, NOT the side being connected from. + *

+ * This value can be -1 if no side is specified. Please handle this appropriately. + * @param fromX X coord of the block being rendered. It is not necessarily adjacent, it can also be diagonal to the + * location. + * @param fromY Y coord of the block being rendered. + * @param fromZ Z coord of the block being rendered. + * @param block The block being rendered. + * @param meta The metadata of the block being rendered. + * @return True if the location shows the given block and metadata. + */ + boolean matches(int x, int y, int z, int side, int fromX, int fromY, int fromZ, Block block, int meta); +} diff --git a/src/main/java/com/cricketcraft/chisel/api/IFacade.java b/src/main/java/com/cricketcraft/chisel/api/IFacade.java index 2def154f..8b2902dd 100644 --- a/src/main/java/com/cricketcraft/chisel/api/IFacade.java +++ b/src/main/java/com/cricketcraft/chisel/api/IFacade.java @@ -36,4 +36,57 @@ public interface IFacade { * @return The metadata of your facade block. */ int getFacadeMetadata(IBlockAccess world, int x, int y, int z, int side); + + /** + * Gets the block this facade is acting as towards the block that is checking for a connection. Implement this if + * the facade can show different blocks to different neighbours. + *

+ * Defaults to {@link #getFacade(IBlockAccess, int, int, int, int)}. + * + * @param world {@link World} + * @param x X coord of your block + * @param y Y coord of your block + * @param z Z coord of your block + * @param side The side being rendered, NOT the side being connected from. + *

+ * This value can be -1 if no side is specified. Please handle this appropriately. + * @param fromX X coord of the block being rendered, which is checking for a connection. NOT the position of + * your block. It is not necessarily adjacent, it can also be diagonal to your block. + * @param fromY Y coord of the block being rendered. + * @param fromZ Z coord of the block being rendered. + * @param fromBlock The block being rendered. + * @param fromMeta The metadata of the block being rendered. + * @return The block inside of your facade block, as seen from the block being rendered. + */ + default Block getFacade(IBlockAccess world, int x, int y, int z, int side, int fromX, int fromY, int fromZ, + Block fromBlock, int fromMeta) { + return getFacade(world, x, y, z, side); + } + + /** + * Gets the metadata of the block that this facade is acting as towards the block that is checking for a + * connection. Implement this together with + * {@link #getFacade(IBlockAccess, int, int, int, int, int, int, int, Block, int)}. + *

+ * Defaults to {@link #getFacadeMetadata(IBlockAccess, int, int, int, int)}. + * + * @param world {@link World} + * @param x X coord of your block + * @param y Y coord of your block + * @param z Z coord of your block + * @param side The side being rendered, NOT the side being connected from. + *

+ * This value can be -1 if no side is specified. Please handle this appropriately. + * @param fromX X coord of the block being rendered, which is checking for a connection. NOT the position of + * your block. It is not necessarily adjacent, it can also be diagonal to your block. + * @param fromY Y coord of the block being rendered. + * @param fromZ Z coord of the block being rendered. + * @param fromBlock The block being rendered. + * @param fromMeta The metadata of the block being rendered. + * @return The metadata of your facade block, as seen from the block being rendered. + */ + default int getFacadeMetadata(IBlockAccess world, int x, int y, int z, int side, int fromX, int fromY, int fromZ, + Block fromBlock, int fromMeta) { + return getFacadeMetadata(world, x, y, z, side); + } } diff --git a/src/main/java/com/cricketcraft/chisel/api/rendering/TextureType.java b/src/main/java/com/cricketcraft/chisel/api/rendering/TextureType.java index c4f1462b..f4cc6512 100644 --- a/src/main/java/com/cricketcraft/chisel/api/rendering/TextureType.java +++ b/src/main/java/com/cricketcraft/chisel/api/rendering/TextureType.java @@ -90,8 +90,8 @@ public enum TextureType { return data.getRight(); Block block = world.getBlock(x, y, z); - boolean topConnected = ctm.isConnected(world, x, y + 1, z, side, block, meta); - boolean botConnected = ctm.isConnected(world, x, y - 1, z, side, block, meta); + boolean topConnected = ctm.isConnected(world, x, y + 1, z, side, x, y, z, block, meta); + boolean botConnected = ctm.isConnected(world, x, y - 1, z, side, x, y, z, block, meta); TextureSubmap map = data.getLeft(); if (topConnected && botConnected) @@ -142,11 +142,11 @@ public enum TextureType { boolean reverse = side == 3 || side == 4; if (side < 4) { - p = ctm.isConnected(world, x - 1, y, z, side, block, meta); - n = ctm.isConnected(world, x + 1, y, z, side, block, meta); + p = ctm.isConnected(world, x - 1, y, z, side, x, y, z, block, meta); + n = ctm.isConnected(world, x + 1, y, z, side, x, y, z, block, meta); } else { - p = ctm.isConnected(world, x, y, z - 1, side, block, meta); - n = ctm.isConnected(world, x, y, z + 1, side, block, meta); + p = ctm.isConnected(world, x, y, z - 1, side, x, y, z, block, meta); + n = ctm.isConnected(world, x, y, z + 1, side, x, y, z, block, meta); } TextureSubmap map = data.getLeft(); diff --git a/src/main/java/team/chisel/ctmlib/CTM.java b/src/main/java/team/chisel/ctmlib/CTM.java index 271c176f..c7abfefb 100644 --- a/src/main/java/team/chisel/ctmlib/CTM.java +++ b/src/main/java/team/chisel/ctmlib/CTM.java @@ -16,6 +16,7 @@ import net.minecraft.world.IBlockAccess; import net.minecraftforge.common.util.ForgeDirection; import com.cricketcraft.chisel.api.IConnectable; +import com.cricketcraft.chisel.api.IConnectionAccess; import com.cricketcraft.chisel.api.IFacade; import com.google.common.base.Optional; import com.google.common.collect.Maps; @@ -191,24 +192,30 @@ public class CTM { } /** - * A simple check for if the given block can connect to the given direction on the given side. + * A check for if the block being rendered can connect to the given location on the given side. Passes the block + * being rendered on to {@link IFacade} blocks, so they can decide per neighbour. * * @param world * @param x The x coordinate of the block to check against. This is not the position of your block. * @param y The y coordinate of the block to check against. This is not the position of your block. * @param z The z coordinate of the block to check against. This is not the position of your block. * @param side The side of the block to check for connection status. This is not the direction to check in. - * @param block The block to check against for connection. - * @param meta The metadata to check against for connection. + * @param fromX The x coordinate of your block, the block being rendered. + * @param fromY The y coordinate of your block, the block being rendered. + * @param fromZ The z coordinate of your block, the block being rendered. + * @param block The block being rendered. + * @param meta The metadata of the block being rendered. * @return True if the given block can connect to the given location on the given side. */ - public boolean isConnected(IBlockAccess world, int x, int y, int z, int side, Block block, int meta) { + public boolean isConnected(IBlockAccess world, int x, int y, int z, int side, int fromX, int fromY, int fromZ, + Block block, int meta) { ForgeDirection dir = ForgeDirection.VALID_DIRECTIONS[side]; - return isConnected(world, x, y, z, dir, block, meta); + return isConnected(world, x, y, z, dir, fromX, fromY, fromZ, block, meta); } /** - * A simple check for if the given block can connect to the given direction on the given side. + * A check for if the block being rendered can connect to the given location on the given side. Passes the block + * being rendered on to {@link IFacade} blocks, so they can decide per neighbour. * * @param world * @param x The x coordinate of the block to check against. This is not the position of your block. @@ -216,41 +223,72 @@ public class CTM { * @param z The z coordinate of the block to check against. This is not the position of your block. * @param dir The {@link ForgeDirection side} of the block to check for connection status. This is not the * direction to check in. - * @param block The block to check against for connection. - * @param meta The metadata to check against for connection. + * @param fromX The x coordinate of your block, the block being rendered. + * @param fromY The y coordinate of your block, the block being rendered. + * @param fromZ The z coordinate of your block, the block being rendered. + * @param block The block being rendered. + * @param meta The metadata of the block being rendered. * @return True if the given block can connect to the given location on the given side. */ - public boolean isConnected(IBlockAccess world, int x, int y, int z, ForgeDirection dir, Block block, int meta) { - + public boolean isConnected(IBlockAccess world, int x, int y, int z, ForgeDirection dir, int fromX, int fromY, + int fromZ, Block block, int meta) { if (CTMLib.chiselLoaded() && connectionBlocked(world, x, y, z, dir.ordinal())) { return false; } + if (!matches(world, x, y, z, dir.ordinal(), fromX, fromY, fromZ, block, meta)) { + return false; + } + + if (disableObscuredFaceCheck.or(disableObscuredFaceCheckConfig)) { + return true; + } + + // check that we aren't already connected outwards from this side int x2 = x + dir.offsetX; int y2 = y + dir.offsetY; int z2 = z + dir.offsetZ; + return !matches(world, x2, y2, z2, dir.ordinal(), fromX, fromY, fromZ, block, meta); + } - boolean disableObscured = disableObscuredFaceCheck.or(disableObscuredFaceCheckConfig); + /** + * Whether the given location shows the block being rendered, as seen from the block being rendered. Asks the world + * if it is an {@link IConnectionAccess}, otherwise compares the block or {@link IFacade} at that location. + * + * @param world + * @param x The x coordinate of the block to check against. This is not the position of your block. + * @param y The y coordinate of the block to check against. This is not the position of your block. + * @param z The z coordinate of the block to check against. This is not the position of your block. + * @param side The side being rendered. -1 for unknown. + * @param fromX The x coordinate of your block, the block being rendered. + * @param fromY The y coordinate of your block, the block being rendered. + * @param fromZ The z coordinate of your block, the block being rendered. + * @param block The block being rendered. + * @param meta The metadata of the block being rendered. + * @return True if the given location shows the given block and metadata. + */ + public boolean matches(IBlockAccess world, int x, int y, int z, int side, int fromX, int fromY, int fromZ, + Block block, int meta) { + if (CTMLib.chiselLoaded()) { + return matchesAccess(world, x, y, z, side, fromX, fromY, fromZ, block, meta); + } + return block.equals(world.getBlock(x, y, z)) && world.getBlockMetadata(x, y, z) == meta; + } - Block con = getBlockOrFacade(world, x, y, z, dir.ordinal()); - Block obscuring = disableObscured ? null : getBlockOrFacade(world, x2, y2, z2, dir.ordinal()); + private boolean matchesAccess(IBlockAccess world, int x, int y, int z, int side, int fromX, int fromY, int fromZ, + Block block, int meta) { + if (world instanceof IConnectionAccess) { + return ((IConnectionAccess) world).matches(x, y, z, side, fromX, fromY, fromZ, block, meta); + } + Block blk = world.getBlock(x, y, z); + Block con = getFacade(blk, world, x, y, z, side, fromX, fromY, fromZ, block, meta); // no block or a bad API user if (con == null) { return false; } - boolean ret = con.equals(block) && getBlockOrFacadeMetadata(world, x, y, z, dir.ordinal()) == meta; - - // no block obscuring this face - if (obscuring == null) { - return ret; - } - - // check that we aren't already connected outwards from this side - ret &= !(obscuring.equals(block) && getBlockOrFacadeMetadata(world, x2, y2, z2, dir.ordinal()) == meta); - - return ret; + return con.equals(block) && getFacadeMeta(blk, world, x, y, z, side, fromX, fromY, fromZ, block, meta) == meta; } private boolean connectionBlocked(IBlockAccess world, int x, int y, int z, int side) { @@ -310,4 +348,20 @@ public class CTM { } return blk; } + + private int getFacadeMeta(Block blk, IBlockAccess world, int x, int y, int z, int side, int fromX, int fromY, + int fromZ, Block fromBlock, int fromMeta) { + if (blk instanceof IFacade) { + return ((IFacade) blk).getFacadeMetadata(world, x, y, z, side, fromX, fromY, fromZ, fromBlock, fromMeta); + } + return world.getBlockMetadata(x, y, z); + } + + private Block getFacade(Block blk, IBlockAccess world, int x, int y, int z, int side, int fromX, int fromY, + int fromZ, Block fromBlock, int fromMeta) { + if (blk instanceof IFacade) { + blk = ((IFacade) blk).getFacade(world, x, y, z, side, fromX, fromY, fromZ, fromBlock, fromMeta); + } + return blk; + } } diff --git a/src/main/java/team/chisel/ctmlib/Dir.java b/src/main/java/team/chisel/ctmlib/Dir.java index 85e1809f..fca5d704 100644 --- a/src/main/java/team/chisel/ctmlib/Dir.java +++ b/src/main/java/team/chisel/ctmlib/Dir.java @@ -61,12 +61,15 @@ public enum Dir { public boolean isConnected(CTM inst, IBlockAccess world, int x, int y, int z, int sideIdx, Block block, int meta) { ForgeDirection side = getOrientation(sideIdx); ForgeDirection[] dirs = getNormalizedDirs(side); + int fromX = x; + int fromY = y; + int fromZ = z; for (ForgeDirection dir : dirs) { x += dir.offsetX; y += dir.offsetY; z += dir.offsetZ; } - return inst.isConnected(world, x, y, z, side, block, meta); + return inst.isConnected(world, x, y, z, side, fromX, fromY, fromZ, block, meta); } private ForgeDirection[] getNormalizedDirs(ForgeDirection normal) { diff --git a/src/main/java/team/chisel/ctmlib/RenderBlocksCTM.java b/src/main/java/team/chisel/ctmlib/RenderBlocksCTM.java index 0f750bc3..08361b91 100644 --- a/src/main/java/team/chisel/ctmlib/RenderBlocksCTM.java +++ b/src/main/java/team/chisel/ctmlib/RenderBlocksCTM.java @@ -58,6 +58,8 @@ import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.IIcon; import net.minecraftforge.common.util.ForgeDirection; +import com.cricketcraft.chisel.api.IConnectionAccess; + import lombok.Getter; public class RenderBlocksCTM extends RenderBlocks { @@ -110,8 +112,13 @@ public class RenderBlocksCTM extends RenderBlocks { this.z = z; } - void render(RenderBlocksCTM inst, ForgeDirection normal, int cacheID) { + double get(int axis) { + return axis == 0 ? x : axis == 1 ? y : z; + } + + void render(RenderBlocksCTM inst, SubSide side, int cacheID) { final Tessellator tessellator = Tessellator.instance; + final ForgeDirection normal = side.normal; if (inst.enableAO) { tessellator.setColorOpaque_F(inst.redCache[cacheID], inst.grnCache[cacheID], inst.bluCache[cacheID]); @@ -121,6 +128,26 @@ public class RenderBlocksCTM extends RenderBlocks { double u = cacheID == 1 || cacheID == 2 ? inst.maxU : inst.minU; double v = cacheID < 2 ? inst.maxV : inst.minV; + if (inst.renderPart) { + // only the part inside the bounds, showing the texture where it lies in the block + double px = Math.min(Math.max(x, inst.renderMinX), inst.renderMaxX); + double py = Math.min(Math.max(y, inst.renderMinY), inst.renderMaxY); + double pz = Math.min(Math.max(z, inst.renderMinZ), inst.renderMaxZ); + double uMoved = Math.abs(normal.offsetX != 0 ? pz - z : px - x); + double vMoved = Math.abs(normal.offsetY != 0 ? pz - z : py - y); + // a sub-side is half a block wide + u += (u == inst.minU ? 2 : -2) * (inst.maxU - inst.minU) * uMoved; + v += (v == inst.minV ? 2 : -2) * (inst.maxV - inst.minV) * vMoved; + if (inst.enableAO) { + // the caches hold the light at the sub-side's corners, the vertex moved, so take the light there + double lightX = inst.boundsFraction(side.lightAxisX, px, py, pz); + double lightY = inst.boundsFraction(side.lightAxisY, px, py, pz); + inst.mixLight(side.lightRisingX ? lightX : 1 - lightX, side.lightRisingY ? lightY : 1 - lightY); + } + tessellator.addVertexWithUV(px, py, pz, u, v); + return; + } + double uDiff = inst.maxU - inst.minU; double vDiff = inst.maxV - inst.minV; @@ -181,6 +208,9 @@ public class RenderBlocksCTM extends RenderBlocks { // @formatter:on private final Vert xmin, xmax, ymin, ymax; private final ForgeDirection normal; + /** The block axes the light maps' x and y run along, and whether they run towards 1. */ + private final int lightAxisX, lightAxisY; + private final boolean lightRisingX, lightRisingY; SubSide(Vert xmin, Vert ymin, Vert ymax, Vert xmax) { this.xmin = xmin; @@ -188,6 +218,15 @@ public class RenderBlocksCTM extends RenderBlocks { this.ymax = ymax; this.xmax = xmax; this.normal = calcNormal(); + // the caches step along the light maps' x from xmin to ymin, and along their y from xmin to xmax + this.lightAxisX = axis(xmin, ymin); + this.lightAxisY = axis(xmin, xmax); + this.lightRisingX = ymin.get(lightAxisX) > xmin.get(lightAxisX); + this.lightRisingY = xmax.get(lightAxisY) > xmin.get(lightAxisY); + } + + private static int axis(Vert from, Vert to) { + return from.x != to.x ? 0 : from.y != to.y ? 1 : 2; } private ForgeDirection calcNormal() { @@ -205,10 +244,10 @@ public class RenderBlocksCTM extends RenderBlocks { } void render(RenderBlocksCTM inst) { - xmin.render(inst, normal, 0); - ymin.render(inst, normal, 1); - ymax.render(inst, normal, 2); - xmax.render(inst, normal, 3); + xmin.render(inst, this, 0); + ymin.render(inst, this, 1); + ymax.render(inst, this, 2); + xmax.render(inst, this, 3); } } @@ -247,6 +286,12 @@ public class RenderBlocksCTM extends RenderBlocks { @Getter protected boolean inWorld = false; + /** + * Whether the render bounds are a part of the block, which shows its part of the block's texture instead of the + * whole texture squeezed in. Set when rendering in an {@link IConnectionAccess}. + */ + protected boolean renderPart = false; + @Override public boolean renderStandardBlock(Block block, int x, int y, int z) { bx = x; @@ -258,7 +303,9 @@ public class RenderBlocksCTM extends RenderBlocks { tessellator.setColorOpaque_F(1.0F, 1.0F, 1.0F); tessellator.addTranslation(x, y, z); inWorld = true; + renderPart = CTMLib.chiselLoaded() && blockAccess instanceof IConnectionAccess; boolean res = super.renderStandardBlock(block, x, y, z); + renderPart = false; inWorld = false; tessellator.addTranslation(-x, -y, -z); @@ -356,6 +403,39 @@ public class RenderBlocksCTM extends RenderBlocks { | ((sunlightBitChannel / lightVals.length) & 0xF00000); } + /** + * @return where the point lies between the render bounds along the axis, from 0 at their min to 1 at their max + */ + protected double boundsFraction(int axis, double x, double y, double z) { + double min = axis == 0 ? renderMinX : axis == 1 ? renderMinY : renderMinZ; + double max = axis == 0 ? renderMaxX : axis == 1 ? renderMaxY : renderMaxZ; + double pos = axis == 0 ? x : axis == 1 ? y : z; + return max > min ? (pos - min) / (max - min) : 0; + } + + /** + * Sets the color and brightness at a point of the face, mixed from the corners of the light maps, which are the + * corners of the render bounds. The point is given in the maps' x and y, from 0 to 1. + */ + protected void mixLight(double x, double y) { + double w00 = (1 - x) * (1 - y); + double w20 = x * (1 - y); + double w22 = x * y; + double w02 = (1 - x) * y; + final Tessellator tessellator = Tessellator.instance; + tessellator.setColorOpaque_F( + mixColor(redmap, w00, w20, w22, w02), + mixColor(grnmap, w00, w20, w22, w02), + mixColor(blumap, w00, w20, w22, w02)); + // vanilla mixes the corners of partial bounds the same way + tessellator.setBrightness( + mixAoBrightness(lightmap[0][0], lightmap[2][0], lightmap[2][2], lightmap[0][2], w00, w20, w22, w02)); + } + + private static float mixColor(float[][] map, double w00, double w20, double w22, double w02) { + return (float) (map[0][0] * w00 + map[2][0] * w20 + map[2][2] * w22 + map[0][2] * w02); + } + protected void side(Block block, SubSide side, int iconIndex) { // If we have an overridden texture when we're supposed to render a CTM texture, diff --git a/src/main/java/team/chisel/ctmlib/RenderBlocksColumn.java b/src/main/java/team/chisel/ctmlib/RenderBlocksColumn.java index a4613aac..5ae95969 100644 --- a/src/main/java/team/chisel/ctmlib/RenderBlocksColumn.java +++ b/src/main/java/team/chisel/ctmlib/RenderBlocksColumn.java @@ -23,9 +23,8 @@ public class RenderBlocksColumn extends RenderBlocks { super(); } - boolean connected(IBlockAccess world, int x, int y, int z, Block block, int meta) { - Block inWorld = ctm.getBlockOrFacade(world, x, y, z, -1); - return inWorld != null && inWorld.equals(block) && ctm.getBlockOrFacadeMetadata(world, x, y, z, -1) == meta; + boolean connected(IBlockAccess world, int x, int y, int z, int fromX, int fromY, int fromZ, Block block, int meta) { + return ctm.matches(world, x, y, z, -1, fromX, fromY, fromZ, block, meta); } @Override @@ -33,8 +32,8 @@ public class RenderBlocksColumn extends RenderBlocks { int metadata = blockAccess.getBlockMetadata(x, y, z); inWorld = true; - boolean yp = connected(blockAccess, x, y + 1, z, block, metadata); - boolean yn = connected(blockAccess, x, y - 1, z, block, metadata); + boolean yp = connected(blockAccess, x, y + 1, z, x, y, z, block, metadata); + boolean yn = connected(blockAccess, x, y - 1, z, x, y, z, block, metadata); if (yp || yn) { sides[0] = iconTop; @@ -46,13 +45,13 @@ public class RenderBlocksColumn extends RenderBlocks { sides[3] = sides[4] = sides[5] = sides[2]; } else { - boolean xp = connected(blockAccess, x + 1, y, z, block, metadata); - boolean xn = connected(blockAccess, x - 1, y, z, block, metadata); + boolean xp = connected(blockAccess, x + 1, y, z, x, y, z, block, metadata); + boolean xn = connected(blockAccess, x - 1, y, z, x, y, z, block, metadata); - if (xp && (connected(blockAccess, x + 1, y + 1, z, block, metadata) - || connected(blockAccess, x + 1, y - 1, z, block, metadata))) xp = false; - if (xn && (connected(blockAccess, x - 1, y + 1, z, block, metadata) - || connected(blockAccess, x - 1, y - 1, z, block, metadata))) xn = false; + if (xp && (connected(blockAccess, x + 1, y + 1, z, x + 1, y, z, block, metadata) + || connected(blockAccess, x + 1, y - 1, z, x + 1, y, z, block, metadata))) xp = false; + if (xn && (connected(blockAccess, x - 1, y + 1, z, x - 1, y, z, block, metadata) + || connected(blockAccess, x - 1, y - 1, z, x - 1, y, z, block, metadata))) xn = false; if (xp || xn) { uvRotateEast = 2; @@ -76,17 +75,17 @@ public class RenderBlocksColumn extends RenderBlocks { } sides[2] = sides[3] = sides[1]; } else { - boolean zp = connected(blockAccess, x, y, z + 1, block, metadata); - boolean zn = connected(blockAccess, x, y, z - 1, block, metadata); + boolean zp = connected(blockAccess, x, y, z + 1, x, y, z, block, metadata); + boolean zn = connected(blockAccess, x, y, z - 1, x, y, z, block, metadata); - if (zp && (connected(blockAccess, x, y + 1, z + 1, block, metadata) - || connected(blockAccess, x, y - 1, z + 1, block, metadata))) zp = false; - if (zp && (connected(blockAccess, x + 1, y, z + 1, block, metadata) - || connected(blockAccess, x - 1, y, z + 1, block, metadata))) zp = false; - if (zn && (connected(blockAccess, x, y + 1, z - 1, block, metadata) - || connected(blockAccess, x, y - 1, z - 1, block, metadata))) zn = false; - if (zn && (connected(blockAccess, x + 1, y, z - 1, block, metadata) - || connected(blockAccess, x - 1, y, z - 1, block, metadata))) zn = false; + if (zp && (connected(blockAccess, x, y + 1, z + 1, x, y, z + 1, block, metadata) + || connected(blockAccess, x, y - 1, z + 1, x, y, z + 1, block, metadata))) zp = false; + if (zp && (connected(blockAccess, x + 1, y, z + 1, x, y, z + 1, block, metadata) + || connected(blockAccess, x - 1, y, z + 1, x, y, z + 1, block, metadata))) zp = false; + if (zn && (connected(blockAccess, x, y + 1, z - 1, x, y, z - 1, block, metadata) + || connected(blockAccess, x, y - 1, z - 1, x, y, z - 1, block, metadata))) zn = false; + if (zn && (connected(blockAccess, x + 1, y, z - 1, x, y, z - 1, block, metadata) + || connected(blockAccess, x - 1, y, z - 1, x, y, z - 1, block, metadata))) zn = false; if (zp || zn) { uvRotateSouth = 1;