mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-26 21:07:58 +01:00
Continue work on solver
This commit is contained in:
parent
760bffe343
commit
69d33525f6
13 changed files with 294 additions and 98 deletions
|
@ -1,78 +0,0 @@
|
||||||
package com.simibubi.create.content.contraptions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
|
|
||||||
public class KineticSolver {
|
|
||||||
|
|
||||||
private final Map<BlockPos, Connection> connectionsFrom = new HashMap<>();
|
|
||||||
private final Map<BlockPos, Connection> connectionsTo = new HashMap<>();
|
|
||||||
|
|
||||||
private final List<Goal> goals = new ArrayList<>();
|
|
||||||
|
|
||||||
private boolean needsUpdate;
|
|
||||||
|
|
||||||
public void solve() {
|
|
||||||
if (!needsUpdate) return;
|
|
||||||
needsUpdate = false;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addFact(BlockPos pos) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addGoal(Goal goal) {
|
|
||||||
goals.add(goal);
|
|
||||||
needsUpdate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface SolverBlock {
|
|
||||||
void created(KineticSolver solver, Level level, BlockPos pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class Connection {
|
|
||||||
public final BlockPos from;
|
|
||||||
public final BlockPos to;
|
|
||||||
|
|
||||||
public Connection(BlockPos from, BlockPos to) {
|
|
||||||
this.from = from;
|
|
||||||
this.to = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean isCompatible(Connection that);
|
|
||||||
|
|
||||||
public static final class Shaft extends Connection {
|
|
||||||
|
|
||||||
public Shaft(BlockPos pos, Direction face) {
|
|
||||||
super(pos, pos.relative(face));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCompatible(Connection that) {
|
|
||||||
return that instanceof Shaft;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Goal {
|
|
||||||
public final Connection connection;
|
|
||||||
|
|
||||||
public Goal(Connection connection) {
|
|
||||||
this.connection = connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class EqualSpeed extends Goal {
|
|
||||||
public EqualSpeed(Connection connection) {
|
|
||||||
super(connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,7 +36,7 @@ public class RotationPropagator {
|
||||||
* Determines the change in rotation between two attached kinetic entities. For
|
* Determines the change in rotation between two attached kinetic entities. For
|
||||||
* instance, an axis connection returns 1 while a 1-to-1 gear connection
|
* instance, an axis connection returns 1 while a 1-to-1 gear connection
|
||||||
* reverses the rotation and therefore returns -1.
|
* reverses the rotation and therefore returns -1.
|
||||||
*
|
*
|
||||||
* @param from
|
* @param from
|
||||||
* @param to
|
* @param to
|
||||||
* @return
|
* @return
|
||||||
|
@ -201,21 +201,21 @@ public class RotationPropagator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert the added position to the kinetic network.
|
* Insert the added position to the kinetic network.
|
||||||
*
|
*
|
||||||
* @param worldIn
|
* @param worldIn
|
||||||
* @param pos
|
* @param pos
|
||||||
*/
|
*/
|
||||||
public static void handleAdded(Level worldIn, BlockPos pos, KineticTileEntity addedTE) {
|
public static void handleAdded(Level worldIn, BlockPos pos, KineticTileEntity addedTE) {
|
||||||
if (worldIn.isClientSide)
|
// if (worldIn.isClientSide)
|
||||||
return;
|
// return;
|
||||||
if (!worldIn.isLoaded(pos))
|
// if (!worldIn.isLoaded(pos))
|
||||||
return;
|
// return;
|
||||||
propagateNewSource(addedTE);
|
// propagateNewSource(addedTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search for sourceless networks attached to the given entity and update them.
|
* Search for sourceless networks attached to the given entity and update them.
|
||||||
*
|
*
|
||||||
* @param currentTE
|
* @param currentTE
|
||||||
*/
|
*/
|
||||||
private static void propagateNewSource(KineticTileEntity currentTE) {
|
private static void propagateNewSource(KineticTileEntity currentTE) {
|
||||||
|
@ -230,7 +230,7 @@ public class RotationPropagator {
|
||||||
|
|
||||||
if (newSpeed == 0 && oppositeSpeed == 0)
|
if (newSpeed == 0 && oppositeSpeed == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
boolean incompatible =
|
boolean incompatible =
|
||||||
Math.signum(newSpeed) != Math.signum(speedOfNeighbour) && (newSpeed != 0 && speedOfNeighbour != 0);
|
Math.signum(newSpeed) != Math.signum(speedOfNeighbour) && (newSpeed != 0 && speedOfNeighbour != 0);
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ public class RotationPropagator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the given entity from the network.
|
* Remove the given entity from the network.
|
||||||
*
|
*
|
||||||
* @param worldIn
|
* @param worldIn
|
||||||
* @param pos
|
* @param pos
|
||||||
* @param removedTE
|
* @param removedTE
|
||||||
|
@ -333,7 +333,7 @@ public class RotationPropagator {
|
||||||
/**
|
/**
|
||||||
* Clear the entire subnetwork depending on the given entity and find a new
|
* Clear the entire subnetwork depending on the given entity and find a new
|
||||||
* source
|
* source
|
||||||
*
|
*
|
||||||
* @param updateTE
|
* @param updateTE
|
||||||
*/
|
*/
|
||||||
private static void propagateMissingSource(KineticTileEntity updateTE) {
|
private static void propagateMissingSource(KineticTileEntity updateTE) {
|
||||||
|
|
|
@ -18,6 +18,8 @@ import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||||
import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation;
|
import com.simibubi.create.content.contraptions.goggles.IHaveHoveringInformation;
|
||||||
import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel;
|
import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel;
|
||||||
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxBlock;
|
import com.simibubi.create.content.contraptions.relays.gearbox.GearboxBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.KineticSolver;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.SolverBlock;
|
||||||
import com.simibubi.create.foundation.block.BlockStressValues;
|
import com.simibubi.create.foundation.block.BlockStressValues;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.item.TooltipHelper;
|
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||||
|
@ -344,6 +346,12 @@ public class KineticTileEntity extends SmartTileEntity
|
||||||
|
|
||||||
public void attachKinetics() {
|
public void attachKinetics() {
|
||||||
updateSpeed = false;
|
updateSpeed = false;
|
||||||
|
KineticSolver solver = KineticSolver.getSolver(level);
|
||||||
|
|
||||||
|
BlockState state = getBlockState();
|
||||||
|
if (state.getBlock() instanceof SolverBlock sb) {
|
||||||
|
sb.created(solver, level, worldPosition);
|
||||||
|
}
|
||||||
RotationPropagator.handleAdded(level, worldPosition, this);
|
RotationPropagator.handleAdded(level, worldPosition, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@ package com.simibubi.create.content.contraptions.components.motor;
|
||||||
import com.simibubi.create.AllShapes;
|
import com.simibubi.create.AllShapes;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
|
import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.GeneratorGoal;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.KineticSolver;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.SolverBlock;
|
||||||
import com.simibubi.create.foundation.block.ITE;
|
import com.simibubi.create.foundation.block.ITE;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -10,6 +13,7 @@ import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.Direction.Axis;
|
import net.minecraft.core.Direction.Axis;
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LevelReader;
|
import net.minecraft.world.level.LevelReader;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
@ -17,7 +21,7 @@ import net.minecraft.world.level.pathfinder.PathComputationType;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
|
||||||
public class CreativeMotorBlock extends DirectionalKineticBlock implements ITE<CreativeMotorTileEntity> {
|
public class CreativeMotorBlock extends DirectionalKineticBlock implements ITE<CreativeMotorTileEntity>, SolverBlock {
|
||||||
|
|
||||||
public CreativeMotorBlock(Properties properties) {
|
public CreativeMotorBlock(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
|
@ -54,7 +58,7 @@ public class CreativeMotorBlock extends DirectionalKineticBlock implements ITE<C
|
||||||
public boolean hideStressImpact() {
|
public boolean hideStressImpact() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
|
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -69,5 +73,9 @@ public class CreativeMotorBlock extends DirectionalKineticBlock implements ITE<C
|
||||||
public BlockEntityType<? extends CreativeMotorTileEntity> getTileEntityType() {
|
public BlockEntityType<? extends CreativeMotorTileEntity> getTileEntityType() {
|
||||||
return AllTileEntities.MOTOR.get();
|
return AllTileEntities.MOTOR.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void created(KineticSolver solver, Level level, BlockPos pos) {
|
||||||
|
solver.addGoal(new GeneratorGoal(pos, 16));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,12 @@ import java.util.function.Predicate;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllShapes;
|
import com.simibubi.create.AllShapes;
|
||||||
import com.simibubi.create.content.contraptions.KineticSolver;
|
import com.simibubi.create.content.contraptions.solver.KineticSolver;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock;
|
import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.Connection;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.ConnectionGoal;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.SolverBlock;
|
||||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||||
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
import com.simibubi.create.foundation.utility.placement.IPlacementHelper;
|
||||||
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
|
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
|
||||||
|
@ -27,7 +30,7 @@ import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
|
||||||
public class ShaftBlock extends AbstractShaftBlock implements KineticSolver.SolverBlock {
|
public class ShaftBlock extends AbstractShaftBlock implements SolverBlock {
|
||||||
|
|
||||||
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
|
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
|
||||||
|
|
||||||
|
@ -92,11 +95,11 @@ public class ShaftBlock extends AbstractShaftBlock implements KineticSolver.Solv
|
||||||
|
|
||||||
Direction positive = Direction.fromAxisAndDirection(axis, Direction.AxisDirection.POSITIVE);
|
Direction positive = Direction.fromAxisAndDirection(axis, Direction.AxisDirection.POSITIVE);
|
||||||
|
|
||||||
KineticSolver.Connection.Shaft c1 = new KineticSolver.Connection.Shaft(pos, positive);
|
Connection.Shaft c1 = new Connection.Shaft(pos, positive);
|
||||||
KineticSolver.Connection.Shaft c2 = new KineticSolver.Connection.Shaft(pos, positive.getOpposite());
|
Connection.Shaft c2 = new Connection.Shaft(pos, positive.getOpposite());
|
||||||
|
|
||||||
solver.addGoal(new KineticSolver.Goal.EqualSpeed(c1));
|
solver.addGoal(new ConnectionGoal.EqualSpeed(c1));
|
||||||
solver.addGoal(new KineticSolver.Goal.EqualSpeed(c2));
|
solver.addGoal(new ConnectionGoal.EqualSpeed(c2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.simibubi.create.content.contraptions.solver;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
|
||||||
|
public abstract class Connection {
|
||||||
|
public final BlockPos from;
|
||||||
|
public final BlockPos to;
|
||||||
|
|
||||||
|
public Connection(BlockPos from, BlockPos to) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract boolean isCompatible(Connection that);
|
||||||
|
|
||||||
|
public static final class Shaft extends Connection {
|
||||||
|
|
||||||
|
public Shaft(BlockPos pos, Direction face) {
|
||||||
|
super(pos, pos.relative(face));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCompatible(Connection that) {
|
||||||
|
return that instanceof Shaft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.simibubi.create.content.contraptions.solver;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
|
public abstract class ConnectionGoal implements Goal {
|
||||||
|
public final Connection connection;
|
||||||
|
|
||||||
|
public ConnectionGoal(Connection connection) {
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdded(KineticSolver.PropertyMap solver) {
|
||||||
|
solver.addConnection(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EqualSpeed extends ConnectionGoal {
|
||||||
|
public EqualSpeed(Connection connection) {
|
||||||
|
super(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getPos() {
|
||||||
|
return connection.from;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SolveResult solve(KineticSolver.PropertyMap solver) {
|
||||||
|
if (solver.isComplete(connection)) {
|
||||||
|
Value toSpeed = solver.getOrCreateProperty(connection.to, "speed");
|
||||||
|
Value fromSpeed = solver.getOrCreateProperty(connection.from, "speed");
|
||||||
|
if (toSpeed instanceof Value.Known toValue && fromSpeed instanceof Value.Known fromValue) {
|
||||||
|
if (toValue.value != fromValue.value) {
|
||||||
|
return Goal.SolveResult.CONTRADICTION;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
solver.setProperty(connection.to, "speed", fromSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Goal.SolveResult.OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.simibubi.create.content.contraptions.solver;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
|
public final class GeneratorGoal implements Goal {
|
||||||
|
public final BlockPos me;
|
||||||
|
public final float speed;
|
||||||
|
|
||||||
|
public GeneratorGoal(BlockPos me, float speed) {
|
||||||
|
this.me = me;
|
||||||
|
this.speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getPos() {
|
||||||
|
return me;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SolveResult solve(KineticSolver.PropertyMap solver) {
|
||||||
|
solver.setProperty(me, "speed", new Value.Known(speed));
|
||||||
|
return Goal.SolveResult.OK;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.simibubi.create.content.contraptions.solver;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
|
public interface Goal {
|
||||||
|
BlockPos getPos();
|
||||||
|
|
||||||
|
SolveResult solve(KineticSolver.PropertyMap solver);
|
||||||
|
|
||||||
|
default void onAdded(KineticSolver.PropertyMap solver) {
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SolveResult {
|
||||||
|
CONTRADICTION,
|
||||||
|
OK,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.simibubi.create.content.contraptions.solver;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.WorldAttached;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
public class KineticSolver {
|
||||||
|
|
||||||
|
private static final WorldAttached<KineticSolver> SOLVERS = new WorldAttached<>($ -> new KineticSolver());
|
||||||
|
|
||||||
|
public static KineticSolver getSolver(Level level) {
|
||||||
|
return SOLVERS.get(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final PropertyMap properties = new PropertyMap();
|
||||||
|
|
||||||
|
private final List<Goal> goals = new ArrayList<>();
|
||||||
|
|
||||||
|
public static class PropertyMap {
|
||||||
|
private final Map<BlockPos, Map<String, Value>> properties = new HashMap<>();
|
||||||
|
private final Map<BlockPos, Set<Connection>> connections = new HashMap<>();
|
||||||
|
|
||||||
|
public Optional<Value> getProperty(BlockPos pos, String property) {
|
||||||
|
Map<String, Value> map = properties.get(pos);
|
||||||
|
|
||||||
|
if (map != null) {
|
||||||
|
return Optional.of(map.computeIfAbsent(property, $ -> new Value.Unknown()));
|
||||||
|
} else {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Value getOrCreateProperty(BlockPos pos, String property) {
|
||||||
|
return properties.computeIfAbsent(pos, $ -> new HashMap<>())
|
||||||
|
.computeIfAbsent(property, $ -> new Value.Unknown());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperty(BlockPos pos, String property, Value value) {
|
||||||
|
properties.computeIfAbsent(pos, $ -> new HashMap<>())
|
||||||
|
.put(property, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isComplete(Connection connection) {
|
||||||
|
Set<Connection> connections = this.connections.get(connection.to);
|
||||||
|
|
||||||
|
if (connections == null) return false;
|
||||||
|
|
||||||
|
for (Connection other : connections) {
|
||||||
|
if (connection.isCompatible(other) && other.to.equals(connection.from)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addConnection(Connection connection) {
|
||||||
|
properties.computeIfAbsent(connection.from, $ -> new HashMap<>());
|
||||||
|
connections.computeIfAbsent(connection.from, $ -> new HashSet<>()).add(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
properties.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean needsUpdate;
|
||||||
|
|
||||||
|
public List<BlockPos> solve() {
|
||||||
|
if (!needsUpdate) return Collections.emptyList();
|
||||||
|
needsUpdate = false;
|
||||||
|
|
||||||
|
List<BlockPos> troublemakers = new ArrayList<>();
|
||||||
|
|
||||||
|
outer:
|
||||||
|
while (true) {
|
||||||
|
properties.clear();
|
||||||
|
|
||||||
|
for (Goal goal : goals) {
|
||||||
|
Goal.SolveResult result = goal.solve(properties);
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case CONTRADICTION -> {
|
||||||
|
troublemakers.add(goal.getPos());
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
case OK -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return troublemakers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addGoal(Goal goal) {
|
||||||
|
goals.add(goal);
|
||||||
|
needsUpdate = true;
|
||||||
|
goal.onAdded(properties);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.simibubi.create.content.contraptions.solver;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
public interface SolverBlock {
|
||||||
|
void created(KineticSolver solver, Level level, BlockPos pos);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.simibubi.create.content.contraptions.solver;
|
||||||
|
|
||||||
|
public sealed class Value {
|
||||||
|
public static final class Unknown extends Value {
|
||||||
|
private static int nextID = 0;
|
||||||
|
|
||||||
|
public final int id;
|
||||||
|
|
||||||
|
public Unknown() {
|
||||||
|
this.id = nextID++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Known extends Value {
|
||||||
|
public final float value;
|
||||||
|
|
||||||
|
public Known(float value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.tra
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
|
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
|
||||||
import com.simibubi.create.content.contraptions.fluids.recipe.FluidTransferRecipes;
|
import com.simibubi.create.content.contraptions.fluids.recipe.FluidTransferRecipes;
|
||||||
import com.simibubi.create.content.contraptions.fluids.recipe.PotionMixingRecipeManager;
|
import com.simibubi.create.content.contraptions.fluids.recipe.PotionMixingRecipeManager;
|
||||||
|
import com.simibubi.create.content.contraptions.solver.KineticSolver;
|
||||||
import com.simibubi.create.content.contraptions.wrench.WrenchItem;
|
import com.simibubi.create.content.contraptions.wrench.WrenchItem;
|
||||||
import com.simibubi.create.content.curiosities.toolbox.ToolboxHandler;
|
import com.simibubi.create.content.curiosities.toolbox.ToolboxHandler;
|
||||||
import com.simibubi.create.content.curiosities.weapons.PotatoProjectileTypeManager;
|
import com.simibubi.create.content.curiosities.weapons.PotatoProjectileTypeManager;
|
||||||
|
@ -110,6 +111,8 @@ public class CommonEvents {
|
||||||
CapabilityMinecartController.tick(world);
|
CapabilityMinecartController.tick(world);
|
||||||
CouplingPhysics.tick(world);
|
CouplingPhysics.tick(world);
|
||||||
LinkedControllerServerHandler.tick(world);
|
LinkedControllerServerHandler.tick(world);
|
||||||
|
|
||||||
|
KineticSolver.getSolver(world).solve();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
Loading…
Reference in a new issue