Skip to content

Commit

Permalink
Fission Reactor's ShapeInfo support for Relative Directions (#2576)
Browse files Browse the repository at this point in the history
  • Loading branch information
bruberu authored Aug 14, 2024
1 parent dde9598 commit f8db435
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 98 deletions.
96 changes: 8 additions & 88 deletions src/main/java/gregtech/api/pattern/BlockPattern.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ private PatternMatchContext checkPatternAt(World world, BlockPos centerPos, Enum
for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) {
for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) {
TraceabilityPredicate predicate = this.blockMatches[c][b][a];
BlockPos pos = setActualRelativeOffset(x, y, z, frontFacing, upwardsFacing, isFlipped)
BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, frontFacing, upwardsFacing,
isFlipped, structureDir)
.add(centerPos.getX(), centerPos.getY(), centerPos.getZ());
worldState.update(world, pos, matchContext, globalCount, layerCount, predicate);
TileEntity tileEntity = worldState.getTileEntity();
Expand Down Expand Up @@ -250,9 +251,10 @@ public void autoBuild(EntityPlayer player, MultiblockControllerBase controllerBa
for (int b = 0, y = -centerOffset[1]; b < this.thumbLength; b++, y++) {
for (int a = 0, x = -centerOffset[0]; a < this.palmLength; a++, x++) {
TraceabilityPredicate predicate = this.blockMatches[c][b][a];
BlockPos pos = setActualRelativeOffset(x, y, z, facing, controllerBase.getUpwardsFacing(),
controllerBase.isFlipped())
.add(centerPos.getX(), centerPos.getY(), centerPos.getZ());
BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, facing,
controllerBase.getUpwardsFacing(),
controllerBase.isFlipped(), structureDir)
.add(centerPos.getX(), centerPos.getY(), centerPos.getZ());
worldState.update(world, pos, matchContext, globalCount, layerCount, predicate);
if (!world.getBlockState(pos).getMaterial().isReplaceable()) {
blocks.put(pos, world.getBlockState(pos));
Expand Down Expand Up @@ -571,7 +573,8 @@ public BlockInfo[][][] getPreview(int[] repetition) {
}
}
BlockInfo info = infos == null || infos.length == 0 ? BlockInfo.EMPTY : infos[0];
BlockPos pos = setActualRelativeOffset(z, y, x, EnumFacing.NORTH, EnumFacing.UP, false);
BlockPos pos = RelativeDirection.setActualRelativeOffset(z, y, x, EnumFacing.NORTH,
EnumFacing.UP, false, structureDir);
// TODO
if (info.getTileEntity() instanceof MetaTileEntityHolder) {
MetaTileEntityHolder holder = new MetaTileEntityHolder();
Expand Down Expand Up @@ -624,87 +627,4 @@ public BlockInfo[][][] getPreview(int[] repetition) {
});
return result;
}

private BlockPos setActualRelativeOffset(int x, int y, int z, EnumFacing facing, EnumFacing upwardsFacing,
boolean isFlipped) {
int[] c0 = new int[] { x, y, z }, c1 = new int[3];
if (facing == EnumFacing.UP || facing == EnumFacing.DOWN) {
EnumFacing of = facing == EnumFacing.DOWN ? upwardsFacing : upwardsFacing.getOpposite();
for (int i = 0; i < 3; i++) {
switch (structureDir[i].getActualFacing(of)) {
case UP -> c1[1] = c0[i];
case DOWN -> c1[1] = -c0[i];
case WEST -> c1[0] = -c0[i];
case EAST -> c1[0] = c0[i];
case NORTH -> c1[2] = -c0[i];
case SOUTH -> c1[2] = c0[i];
}
}
int xOffset = upwardsFacing.getXOffset();
int zOffset = upwardsFacing.getZOffset();
int tmp;
if (xOffset == 0) {
tmp = c1[2];
c1[2] = zOffset > 0 ? c1[1] : -c1[1];
c1[1] = zOffset > 0 ? -tmp : tmp;
} else {
tmp = c1[0];
c1[0] = xOffset > 0 ? c1[1] : -c1[1];
c1[1] = xOffset > 0 ? -tmp : tmp;
}
if (isFlipped) {
if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) {
c1[0] = -c1[0]; // flip X-axis
} else {
c1[2] = -c1[2]; // flip Z-axis
}
}
} else {
for (int i = 0; i < 3; i++) {
switch (structureDir[i].getActualFacing(facing)) {
case UP -> c1[1] = c0[i];
case DOWN -> c1[1] = -c0[i];
case WEST -> c1[0] = -c0[i];
case EAST -> c1[0] = c0[i];
case NORTH -> c1[2] = -c0[i];
case SOUTH -> c1[2] = c0[i];
}
}
if (upwardsFacing == EnumFacing.WEST || upwardsFacing == EnumFacing.EAST) {
int xOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getXOffset() :
facing.rotateY().getOpposite().getXOffset();
int zOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getZOffset() :
facing.rotateY().getOpposite().getZOffset();
int tmp;
if (xOffset == 0) {
tmp = c1[2];
c1[2] = zOffset > 0 ? -c1[1] : c1[1];
c1[1] = zOffset > 0 ? tmp : -tmp;
} else {
tmp = c1[0];
c1[0] = xOffset > 0 ? -c1[1] : c1[1];
c1[1] = xOffset > 0 ? tmp : -tmp;
}
} else if (upwardsFacing == EnumFacing.SOUTH) {
c1[1] = -c1[1];
if (facing.getXOffset() == 0) {
c1[0] = -c1[0];
} else {
c1[2] = -c1[2];
}
}
if (isFlipped) {
if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) {
if (facing == EnumFacing.NORTH || facing == EnumFacing.SOUTH) {
c1[0] = -c1[0]; // flip X-axis
} else {
c1[2] = -c1[2]; // flip Z-axis
}
} else {
c1[1] = -c1[1]; // flip Y-axis
}
}
}
return new BlockPos(c1[0], c1[1], c1[2]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ private FactoryBlockPattern(RelativeDirection charDir, RelativeDirection stringD
structureDir[1] = stringDir;
structureDir[2] = aisleDir;
int flags = 0;
for (int i = 0; i < 3; i++) {
for (int i = 0; i < this.structureDir.length; i++) {
switch (structureDir[i]) {
case UP:
case DOWN:
Expand Down
55 changes: 51 additions & 4 deletions src/main/java/gregtech/api/pattern/MultiblockShapeInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@
import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.MetaTileEntityHolder;
import gregtech.api.util.BlockInfo;
import gregtech.api.util.RelativeDirection;

import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;

import static gregtech.api.util.RelativeDirection.*;

public class MultiblockShapeInfo {

/** {@code [x][y][z]} */
Expand All @@ -33,14 +38,48 @@ public BlockInfo[][][] getBlocks() {
}

public static Builder builder() {
return new Builder();
return builder(RIGHT, DOWN, BACK);
}

public static Builder builder(@NotNull RelativeDirection... structureDir) {
if (structureDir.length != 3) throw new IllegalArgumentException("Must have exactly 3 directions!");
return new Builder(structureDir[0], structureDir[1], structureDir[2]);
}

public static class Builder {

private final RelativeDirection[] structureDir = new RelativeDirection[3];

private List<String[]> shape = new ArrayList<>();
private Map<Character, BlockInfo> symbolMap = new HashMap<>();

/**
* Use {@link #builder(RelativeDirection...)}
*
* @param structureDir The directions that the provided block pattern is based upon (character, string, row).
*/
@Deprecated
public Builder(@NotNull RelativeDirection... structureDir) {
this(structureDir[0], structureDir[1], structureDir[2]);
}

@Deprecated
public Builder(@NotNull RelativeDirection one, @NotNull RelativeDirection two,
@NotNull RelativeDirection three) {
this.structureDir[0] = Objects.requireNonNull(one);
this.structureDir[1] = Objects.requireNonNull(two);
this.structureDir[2] = Objects.requireNonNull(three);
int flags = 0;
for (int i = 0; i < this.structureDir.length; i++) {
switch (structureDir[i]) {
case UP, DOWN -> flags |= 0x1;
case LEFT, RIGHT -> flags |= 0x2;
case FRONT, BACK -> flags |= 0x4;
}
}
if (flags != 0x7) throw new IllegalArgumentException("The directions must be on different axes!");
}

public Builder aisle(String... data) {
this.shape.add(data);
return this;
Expand Down Expand Up @@ -85,7 +124,13 @@ private BlockInfo[][][] bakeArray() {
final int maxZ = shape.size();
final int maxY = shape.get(0).length;
final int maxX = shape.get(0)[0].length();
BlockInfo[][][] blockInfos = new BlockInfo[maxX][maxY][maxZ];

BlockPos end = RelativeDirection.setActualRelativeOffset(maxX, maxY, maxZ, EnumFacing.SOUTH, EnumFacing.UP,
true, structureDir);
BlockPos addition = new BlockPos(end.getX() < 0 ? -end.getX() - 1 : 0, end.getY() < 0 ? -end.getY() - 1 : 0,
end.getZ() < 0 ? -end.getZ() - 1 : 0);
BlockPos bound = new BlockPos(Math.abs(end.getX()), Math.abs(end.getY()), Math.abs(end.getZ()));
BlockInfo[][][] blockInfos = new BlockInfo[bound.getX()][bound.getY()][bound.getZ()];
for (int z = 0; z < maxZ; z++) {
String[] aisleEntry = shape.get(z);
for (int y = 0; y < maxY; y++) {
Expand All @@ -103,15 +148,17 @@ private BlockInfo[][][] bakeArray() {
} else if (tileEntity != null) {
info = new BlockInfo(info.getBlockState(), tileEntity);
}
blockInfos[x][y][z] = info;
BlockPos pos = RelativeDirection.setActualRelativeOffset(x, y, z, EnumFacing.SOUTH,
EnumFacing.UP, true, structureDir).add(addition);
blockInfos[pos.getX()][pos.getY()][pos.getZ()] = info;
}
}
}
return blockInfos;
}

public Builder shallowCopy() {
Builder builder = new Builder();
Builder builder = new Builder(this.structureDir);
builder.shape = new ArrayList<>(this.shape);
builder.symbolMap = new HashMap<>(this.symbolMap);
return builder;
Expand Down
87 changes: 87 additions & 0 deletions src/main/java/gregtech/api/util/RelativeDirection.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,91 @@ public static BlockPos offsetPos(BlockPos pos, EnumFacing frontFacing, EnumFacin

return pos.add(oX, oY, oZ);
}

/**
* Offset a BlockPos relatively in any direction by any amount. Pass negative values to offset down, right or
* backwards.
*/
public static BlockPos setActualRelativeOffset(int x, int y, int z, EnumFacing facing, EnumFacing upwardsFacing,
boolean isFlipped, RelativeDirection[] structureDir) {
int[] c0 = new int[] { x, y, z }, c1 = new int[3];
if (facing == EnumFacing.UP || facing == EnumFacing.DOWN) {
EnumFacing of = facing == EnumFacing.DOWN ? upwardsFacing : upwardsFacing.getOpposite();
for (int i = 0; i < 3; i++) {
switch (structureDir[i].getActualFacing(of)) {
case UP -> c1[1] = c0[i];
case DOWN -> c1[1] = -c0[i];
case WEST -> c1[0] = -c0[i];
case EAST -> c1[0] = c0[i];
case NORTH -> c1[2] = -c0[i];
case SOUTH -> c1[2] = c0[i];
}
}
int xOffset = upwardsFacing.getXOffset();
int zOffset = upwardsFacing.getZOffset();
int tmp;
if (xOffset == 0) {
tmp = c1[2];
c1[2] = zOffset > 0 ? c1[1] : -c1[1];
c1[1] = zOffset > 0 ? -tmp : tmp;
} else {
tmp = c1[0];
c1[0] = xOffset > 0 ? c1[1] : -c1[1];
c1[1] = xOffset > 0 ? -tmp : tmp;
}
if (isFlipped) {
if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) {
c1[0] = -c1[0]; // flip X-axis
} else {
c1[2] = -c1[2]; // flip Z-axis
}
}
} else {
for (int i = 0; i < 3; i++) {
switch (structureDir[i].getActualFacing(facing)) {
case UP -> c1[1] = c0[i];
case DOWN -> c1[1] = -c0[i];
case WEST -> c1[0] = -c0[i];
case EAST -> c1[0] = c0[i];
case NORTH -> c1[2] = -c0[i];
case SOUTH -> c1[2] = c0[i];
}
}
if (upwardsFacing == EnumFacing.WEST || upwardsFacing == EnumFacing.EAST) {
int xOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getXOffset() :
facing.rotateY().getOpposite().getXOffset();
int zOffset = upwardsFacing == EnumFacing.WEST ? facing.rotateY().getZOffset() :
facing.rotateY().getOpposite().getZOffset();
int tmp;
if (xOffset == 0) {
tmp = c1[2];
c1[2] = zOffset > 0 ? -c1[1] : c1[1];
c1[1] = zOffset > 0 ? tmp : -tmp;
} else {
tmp = c1[0];
c1[0] = xOffset > 0 ? -c1[1] : c1[1];
c1[1] = xOffset > 0 ? tmp : -tmp;
}
} else if (upwardsFacing == EnumFacing.SOUTH) {
c1[1] = -c1[1];
if (facing.getXOffset() == 0) {
c1[0] = -c1[0];
} else {
c1[2] = -c1[2];
}
}
if (isFlipped) {
if (upwardsFacing == EnumFacing.NORTH || upwardsFacing == EnumFacing.SOUTH) {
if (facing == EnumFacing.NORTH || facing == EnumFacing.SOUTH) {
c1[0] = -c1[0]; // flip X-axis
} else {
c1[2] = -c1[2]; // flip Z-axis
}
} else {
c1[1] = -c1[1]; // flip Y-axis
}
}
}
return new BlockPos(c1[0], c1[1], c1[2]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
import java.util.Comparator;
import java.util.List;

import static gregtech.api.util.RelativeDirection.*;

public class MetaTileEntityElectricBlastFurnace extends RecipeMapMultiblockController implements IHeatingCoil {

private int blastFurnaceTemperature;
Expand Down Expand Up @@ -179,7 +181,7 @@ public SoundEvent getBreakdownSound() {
@Override
public List<MultiblockShapeInfo> getMatchingShapes() {
ArrayList<MultiblockShapeInfo> shapeInfo = new ArrayList<>();
MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder()
MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT)
.aisle("EEM", "CCC", "CCC", "XXX")
.aisle("FXD", "C#C", "C#C", "XHX")
.aisle("ISO", "CCC", "CCC", "XXX")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@

import static gregtech.api.recipes.logic.OverclockingLogic.PERFECT_HALF_DURATION_FACTOR;
import static gregtech.api.recipes.logic.OverclockingLogic.PERFECT_HALF_VOLTAGE_FACTOR;
import static gregtech.api.util.RelativeDirection.*;

public class MetaTileEntityFusionReactor extends RecipeMapMultiblockController
implements IFastRenderMetaTileEntity, IBloomEffect {
Expand Down Expand Up @@ -162,7 +163,7 @@ protected BlockPattern createStructurePattern() {
public List<MultiblockShapeInfo> getMatchingShapes() {
List<MultiblockShapeInfo> shapeInfos = new ArrayList<>();

MultiblockShapeInfo.Builder baseBuilder = MultiblockShapeInfo.builder()
MultiblockShapeInfo.Builder baseBuilder = MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT)
.aisle("###############", "######WGW######", "###############")
.aisle("######DCD######", "####GG###GG####", "######UCU######")
.aisle("####CC###CC####", "###w##EGE##s###", "####CC###CC####")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
import java.util.Set;
import java.util.function.Supplier;

import static gregtech.api.util.RelativeDirection.*;

public class MetaTileEntityHPCA extends MultiblockWithDisplayBase
implements IOpticalComputationProvider, IControllable, IProgressBarMultiblock {

Expand Down Expand Up @@ -229,7 +231,7 @@ private void consumeEnergy() {
@Override
public List<MultiblockShapeInfo> getMatchingShapes() {
List<MultiblockShapeInfo> shapeInfo = new ArrayList<>();
MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder()
MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder(RIGHT, DOWN, FRONT)
.aisle("AA", "EC", "MC", "HC", "AA")
.aisle("VA", "6V", "3V", "0V", "VA")
.aisle("VA", "7V", "4V", "1V", "VA")
Expand Down
Loading

0 comments on commit f8db435

Please sign in to comment.