diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/AllConnections.java b/src/main/java/com/simibubi/create/content/contraptions/solver/AllConnections.java index 5b5473ed6..0c61ca27e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/AllConnections.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/AllConnections.java @@ -6,60 +6,89 @@ import com.simibubi.create.content.contraptions.solver.KineticConnections.Type; import com.simibubi.create.content.contraptions.solver.KineticConnections.Entry; import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.core.Vec3i; import java.util.LinkedList; import java.util.List; +import static net.minecraft.world.level.block.state.properties.BlockStateProperties.AXIS; + public class AllConnections { - private static Direction pos(Direction.Axis axis) { + public static record ValueType(Object value) implements Type { + @Override + public boolean compatible(Type other) { + return this == other; + } + + public static LazyMap map() { + return new LazyMap<>(ValueType::new); + } + } + + public static final LazyMap + TYPE_SHAFT = ValueType.map(), + TYPE_LARGE_COG = ValueType.map(), + TYPE_SMALL_COG = ValueType.map(); + + + private static Direction pos(Axis axis) { return Direction.get(Direction.AxisDirection.POSITIVE, axis); } - private static Direction neg(Direction.Axis axis) { + private static Direction neg(Axis axis) { return Direction.get(Direction.AxisDirection.NEGATIVE, axis); } + private static Entry largeToLarge(Vec3i diff, Axis from, Axis to) { + int fromDiff = from.choose(diff.getX(), diff.getY(), diff.getZ()); + int toDiff = to.choose(diff.getX(), diff.getY(), diff.getZ()); + float ratio = fromDiff > 0 ^ toDiff > 0 ? -1 : 1; + return new Entry(diff, TYPE_LARGE_COG.apply(from), TYPE_LARGE_COG.apply(to), ratio); + } + + public static final KineticConnections EMPTY = new KineticConnections(); - public static final LazyMap HALF_SHAFT - = new LazyMap<>(dir -> new KineticConnections(new Entry(dir.getNormal(), Type.SHAFT))); + public static final LazyMap + HALF_SHAFT = new LazyMap<>(dir -> + new KineticConnections(new Entry(dir.getNormal(), TYPE_SHAFT.apply(dir.getAxis())))); - public static final LazyMap FULL_SHAFT - = new LazyMap<>(axis -> HALF_SHAFT.apply(pos(axis)).merge(HALF_SHAFT.apply(neg(axis)))); + public static final LazyMap + FULL_SHAFT = new LazyMap<>(axis -> HALF_SHAFT.apply(pos(axis)).merge(HALF_SHAFT.apply(neg(axis)))), - public static final LazyMap LARGE_COG - = new LazyMap<>(axis -> { + LARGE_COG = new LazyMap<>(axis -> { + Type large = TYPE_LARGE_COG.apply(axis); + Type small = TYPE_SMALL_COG.apply(axis); List out = new LinkedList<>(); Direction cur = DirectionHelper.getPositivePerpendicular(axis); for (int i = 0; i < 4; i++) { Direction next = DirectionHelper.rotateAround(cur, axis); - out.add(new Entry(cur.getNormal().multiply(2), Type.LARGE_COG, -1)); - out.add(new Entry(cur.getNormal().relative(pos(axis)), Type.LARGE_COG, -1)); - out.add(new Entry(cur.getNormal().relative(neg(axis)), Type.LARGE_COG, -1)); - out.add(new Entry(cur.getNormal().relative(next), Type.LARGE_COG, Type.SMALL_COG, -2)); + out.add(largeToLarge(cur.getNormal().relative(pos(axis)), axis, cur.getAxis())); + out.add(largeToLarge(cur.getNormal().relative(neg(axis)), axis, cur.getAxis())); + out.add(new Entry(cur.getNormal().relative(next), large, small, -2)); cur = next; } return new KineticConnections(out); - }); + }), - public static final LazyMap SMALL_COG - = new LazyMap<>(axis -> { + SMALL_COG = new LazyMap<>(axis -> { + Type large = TYPE_LARGE_COG.apply(axis); + Type small = TYPE_SMALL_COG.apply(axis); List out = new LinkedList<>(); Direction cur = DirectionHelper.getPositivePerpendicular(axis); for (int i = 0; i < 4; i++) { Direction next = DirectionHelper.rotateAround(cur, axis); - out.add(new Entry(cur.getNormal(), Type.SMALL_COG, -1)); - out.add(new Entry(cur.getNormal().relative(next), Type.SMALL_COG, Type.LARGE_COG, -0.5f)); + out.add(new Entry(cur.getNormal(), small, -1)); + out.add(new Entry(cur.getNormal().relative(next), small, large, -0.5f)); cur = next; } return new KineticConnections(out); - }); + }), - public static final LazyMap LARGE_COG_FULL_SHAFT - = new LazyMap<>(axis -> LARGE_COG.apply(axis).merge(FULL_SHAFT.apply(axis))); + LARGE_COG_FULL_SHAFT = new LazyMap<>(axis -> LARGE_COG.apply(axis).merge(FULL_SHAFT.apply(axis))), - public static final LazyMap SMALL_COG_FULL_SHAFT - = new LazyMap<>(axis -> SMALL_COG.apply(axis).merge(FULL_SHAFT.apply(axis))); + SMALL_COG_FULL_SHAFT = new LazyMap<>(axis -> SMALL_COG.apply(axis).merge(FULL_SHAFT.apply(axis))); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnections.java b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnections.java index 947c17848..66b39c0c6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnections.java +++ b/src/main/java/com/simibubi/create/content/contraptions/solver/KineticConnections.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.solver; import net.minecraft.core.Vec3i; +import net.minecraft.util.Mth; import java.util.Arrays; import java.util.Collection; @@ -14,19 +15,22 @@ import java.util.stream.Stream; public class KineticConnections { - public enum Type { - SHAFT, SMALL_COG, LARGE_COG, BELT + public interface Type { + boolean compatible(Type other); } public static record Entry(Vec3i offset, Value value) { public Entry(Vec3i offset, Type from, Type to, float ratio) { this(offset, new Value(from, to, ratio)); } + public Entry(Vec3i offset, Type from, Type to) { + this(offset, from, to, 1); + } public Entry(Vec3i offset, Type type, float ratio) { this(offset, type, type, ratio); } public Entry(Vec3i offset, Type type) { - this(offset, type, 1); + this(offset, type, type, 1); } } @@ -61,7 +65,8 @@ public class KineticConnections { Value toValue = to.connections.get(offset.multiply(-1)); if (toValue == null) return Optional.empty(); - if (fromValue.from.equals(toValue.to) && fromValue.to.equals(toValue.from)) + if (fromValue.from.compatible(toValue.to) && fromValue.to.compatible(toValue.from) + && (Mth.equal(fromValue.ratio, 1/toValue.ratio) || (Mth.equal(toValue.ratio, 1/fromValue.ratio)))) return Optional.of(fromValue.ratio); return Optional.empty(); }