From b26936d42cec649188eaf6ddb0fb89b79562c151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 15 Jan 2021 14:43:12 +0100 Subject: [PATCH] Allow pistons to shove robots. --- .../li/cil/oc2/common/entity/RobotEntity.java | 9 +++- .../entity/robot/AbstractRobotActionType.java | 3 ++ .../oc2/common/entity/robot/RobotActions.java | 6 +++ .../entity/robot/RobotMovementAction.java | 51 +++++++++++++++---- .../entity/robot/RobotMovementActionType.java | 7 +++ .../entity/robot/RobotRotationActionType.java | 7 +++ 6 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java index de5f8d63..9f2612e9 100644 --- a/src/main/java/li/cil/oc2/common/entity/RobotEntity.java +++ b/src/main/java/li/cil/oc2/common/entity/RobotEntity.java @@ -97,6 +97,7 @@ public final class RobotEntity extends Entity { private final RobotVirtualMachineState state; private final RobotItemStackHandlers items = new RobotItemStackHandlers(); private final RobotBusElement busElement = new RobotBusElement(); + private long lastPistonMovement; /////////////////////////////////////////////////////////////////// @@ -131,6 +132,10 @@ public final class RobotEntity extends Entity { return items; } + public long getLastPistonMovement() { + return lastPistonMovement; + } + public void start() { final World world = getEntityWorld(); if (world == null || world.isRemote()) { @@ -319,7 +324,8 @@ public final class RobotEntity extends Entity { @Override protected Vector3d handlePistonMovement(final Vector3d pos) { - return Vector3d.ZERO; + lastPistonMovement = getEntityWorld().getGameTime(); + return super.handlePistonMovement(pos); } /////////////////////////////////////////////////////////////////// @@ -530,6 +536,7 @@ public final class RobotEntity extends Entity { action.initialize(RobotEntity.this); } } + RobotActions.performServer(RobotEntity.this, action); } } diff --git a/src/main/java/li/cil/oc2/common/entity/robot/AbstractRobotActionType.java b/src/main/java/li/cil/oc2/common/entity/robot/AbstractRobotActionType.java index 79fd1485..939b9be6 100644 --- a/src/main/java/li/cil/oc2/common/entity/robot/AbstractRobotActionType.java +++ b/src/main/java/li/cil/oc2/common/entity/robot/AbstractRobotActionType.java @@ -25,6 +25,9 @@ public abstract class AbstractRobotActionType { public void initializeData(final RobotEntity robot) { } + public void performServer(final RobotEntity robot, final AbstractRobotAction currentAction) { + } + public void performClient(final RobotEntity robot) { } diff --git a/src/main/java/li/cil/oc2/common/entity/robot/RobotActions.java b/src/main/java/li/cil/oc2/common/entity/robot/RobotActions.java index 822e9f83..80320ba2 100644 --- a/src/main/java/li/cil/oc2/common/entity/robot/RobotActions.java +++ b/src/main/java/li/cil/oc2/common/entity/robot/RobotActions.java @@ -32,6 +32,12 @@ public final class RobotActions { } } + public static void performServer(final RobotEntity robot, final AbstractRobotAction currentAction) { + for (final AbstractRobotActionType type : ACTIONS) { + type.performServer(robot, currentAction); + } + } + public static void performClient(final RobotEntity robot) { for (final AbstractRobotActionType type : ACTIONS) { type.performClient(robot); diff --git a/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementAction.java b/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementAction.java index c722ee3a..f86365de 100644 --- a/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementAction.java +++ b/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementAction.java @@ -95,16 +95,9 @@ public final class RobotMovementAction extends AbstractRobotAction { throw new IllegalStateException(); } - moveTowards(robot, targetPos); + validateTarget(robot); - final boolean didCollide = robot.collidedHorizontally || robot.collidedVertically; - if (didCollide && !robot.getEntityWorld().isRemote()) { - final BlockPos newStart = target; - target = start; - start = newStart; - targetPos = getTargetPositionInBlock(target); - robot.getDataManager().set(RobotEntity.TARGET_POSITION, target); - } + moveAndResolveCollisions(robot); if (robot.getPositionVec().squareDistanceTo(targetPos) < TARGET_EPSILON) { if (Objects.equals(target, origin)) { @@ -151,4 +144,44 @@ public final class RobotMovementAction extends AbstractRobotAction { targetPos = getTargetPositionInBlock(target); } } + + private void moveAndResolveCollisions(final RobotEntity robot) { + moveTowards(robot, targetPos); + + final boolean didCollide = robot.collidedHorizontally || robot.collidedVertically; + final long gameTime = robot.getEntityWorld().getGameTime(); + if (didCollide && !robot.getEntityWorld().isRemote() + && robot.getLastPistonMovement() < gameTime - 1) { + final BlockPos newStart = target; + target = start; + start = newStart; + targetPos = getTargetPositionInBlock(target); + robot.getDataManager().set(RobotEntity.TARGET_POSITION, target); + } + } + + private void validateTarget(final RobotEntity robot) { + final BlockPos currentPosition = robot.getPosition(); + if (Objects.equals(currentPosition, start) || Objects.equals(currentPosition, target)) { + return; + } + + // Got pushed out of our original path. Adjust start and target by the least offset. + final BlockPos fromStart = currentPosition.subtract(start); + final BlockPos fromTarget = currentPosition.subtract(target); + + final int deltaStart = fromStart.getX() + fromStart.getY() + fromStart.getZ(); + final int deltaTarget = fromTarget.getX() + fromTarget.getY() + fromTarget.getZ(); + + if (deltaStart < deltaTarget) { + start = currentPosition; + target = target.add(fromStart); + } else { + start = start.add(fromTarget); + target = currentPosition; + } + + targetPos = getTargetPositionInBlock(target); + robot.getDataManager().set(RobotEntity.TARGET_POSITION, target); + } } diff --git a/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementActionType.java b/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementActionType.java index 986d8c8e..b391c95b 100644 --- a/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementActionType.java +++ b/src/main/java/li/cil/oc2/common/entity/robot/RobotMovementActionType.java @@ -23,6 +23,13 @@ public final class RobotMovementActionType extends AbstractRobotActionType { robot.getDataManager().set(RobotEntity.TARGET_POSITION, robot.getPosition()); } + @Override + public void performServer(final RobotEntity robot, final AbstractRobotAction currentAction) { + if (!(currentAction instanceof RobotMovementAction)) { + robot.getDataManager().set(RobotEntity.TARGET_POSITION, robot.getPosition()); + } + } + @Override public void performClient(final RobotEntity robot) { final Vector3d target = RobotMovementAction.getTargetPositionInBlock(robot.getDataManager().get(RobotEntity.TARGET_POSITION)); diff --git a/src/main/java/li/cil/oc2/common/entity/robot/RobotRotationActionType.java b/src/main/java/li/cil/oc2/common/entity/robot/RobotRotationActionType.java index 0488beea..70e714f9 100644 --- a/src/main/java/li/cil/oc2/common/entity/robot/RobotRotationActionType.java +++ b/src/main/java/li/cil/oc2/common/entity/robot/RobotRotationActionType.java @@ -23,6 +23,13 @@ public final class RobotRotationActionType extends AbstractRobotActionType { robot.getDataManager().set(RobotEntity.TARGET_DIRECTION, robot.getHorizontalFacing()); } + @Override + public void performServer(final RobotEntity robot, final AbstractRobotAction currentAction) { + if (!(currentAction instanceof RobotRotationAction)) { + robot.getDataManager().set(RobotEntity.TARGET_DIRECTION, robot.getHorizontalFacing()); + } + } + @Override public void performClient(final RobotEntity robot) { final Direction target = robot.getDataManager().get(RobotEntity.TARGET_DIRECTION);