2022-10-19 21:06:05 +02:00

181 lines
4.3 KiB
Java

package com.hbm.render.block.ct;
import net.minecraft.block.Block;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
import static com.hbm.render.block.ct.CT.*;
public class CTContext {
public static CTFace[] faces;
//dim 1: 6x faces (forgeDir)
//dim 2: 8x neighbors (TL, TC, TR, CL, CR, BL, BC, BR)
//dim 3: 3x coord (x/y/z, [-1;1])
public static int[][][] access = new int[][][] {
lcfs(ForgeDirection.SOUTH, ForgeDirection.WEST), //DOWN guess
lcfs(ForgeDirection.NORTH, ForgeDirection.WEST), //UP guess
lcfs(ForgeDirection.UP, ForgeDirection.EAST), //NORTH
lcfs(ForgeDirection.UP, ForgeDirection.WEST), //SOUTH
lcfs(ForgeDirection.UP, ForgeDirection.NORTH), //WEST
lcfs(ForgeDirection.UP, ForgeDirection.SOUTH) //EAST
};
//lexical coordinates from side
private static int[][] lcfs(ForgeDirection up, ForgeDirection left) {
ForgeDirection down = up.getOpposite();
ForgeDirection right = left.getOpposite();
int[][] lexicalCoordinates = new int[][] {
cfs(up, left),
cfs(up),
cfs(up, right),
cfs(left),
cfs(right),
cfs(down, left),
cfs(down),
cfs(down, right),
};
return lexicalCoordinates;
}
//coordinates from sides
private static int[] cfs(ForgeDirection... dirs) {
int x = 0;
int y = 0;
int z = 0;
for(ForgeDirection dir : dirs) {
x += dir.offsetX;
y += dir.offsetY;
z += dir.offsetZ;
}
return new int[] {x, y, z};
}
/**
* Generates the six CTFaces and fills the faces array, the faces contain the information on what icon types should be used
* @param world
* @param x
* @param y
* @param z
* @param block
*/
public static void loadContext(IBlockAccess world, int x, int y, int z, Block block) {
faces = new CTFace[6];
for(int i = 0; i < 6; i++) {
boolean[] cons = new boolean[8];
int[][] dirs = access[i];
for(int j = 0; j < 8; j++) {
int[] coord = dirs[j];
Block neighbor = world.getBlock(x + coord[0], y + coord[1], z + coord[2]);
if(neighbor instanceof IBlockCT && ((IBlockCT) neighbor).canConnect(world, x + coord[0], y + coord[1], z + coord[2], (IBlockCT)block)) {
cons[j] = true;
}
}
/*
* 0 1 2
* 3 4
* 5 6 7
*/
int itl = t | l | cornerType(cons[3], cons[0], cons[1]);
int itr = t | r | cornerType(cons[4], cons[2], cons[1]);
int ibl = b | l | cornerType(cons[3], cons[5], cons[6]);
int ibr = b | r | cornerType(cons[4], cons[7], cons[6]);
faces[i] = new CTFace(world, x, y, z, (IBlockCT)block, itl, itr, ibl, ibr);
}
}
/**
* Returns the overarching texture type based on whether the horizontal, vertical and corner are connected
* @param hor
* @param corner
* @param vert
* @return the bitmask for the full texture type that should be used (f/c/j/h/v)
*/
public static int cornerType(boolean hor, boolean corner, boolean vert) {
/*
* C - V
* |
* H
*/
if(vert && hor && corner)
return c;
else if(vert && hor)
return j;
else if(vert)
return v;
else if(hor)
return h;
else
return f;
}
/**
* @return whether there's currently a context available
*/
public static boolean isContextLoaded() {
return faces != null;
}
/**
* Gets rid of the current context
*/
public static void dropContext() {
faces = null;
}
/**
* The buffered context information for a single side. Also stores the block itself for easier access.
* @author hbm
*
*/
public static class CTFace {
IBlockAccess world;
int x;
int y;
int z;
IBlockCT ct;
int index_tl;
int index_tr;
int index_bl;
int index_br;
public CTFace() { }
public CTFace(IBlockAccess world, int x, int y, int z, IBlockCT block, int i, int j, int k, int l) {
this.world = world;
this.x = x;
this.y = y;
this.z = z;
this.ct = block;
this.index_tl = i;
this.index_tr = j;
this.index_bl = k;
this.index_br = l;
}
public IIcon getTopLeft() { return ct.getFragments(world, x, y, z)[index_tl]; }
public IIcon getTopRight() { return ct.getFragments(world, x, y, z)[index_tr]; }
public IIcon getBottomLeft() { return ct.getFragments(world, x, y, z)[index_bl]; }
public IIcon getBottomRight() { return ct.getFragments(world, x, y, z)[index_br]; }
}
}