diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/move/Direction.java b/api/src/main/java/com/bartlomiejpluta/base/api/move/Direction.java index ac757cb9..8b829f9e 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/move/Direction.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/move/Direction.java @@ -3,6 +3,8 @@ package com.bartlomiejpluta.base.api.move; import org.joml.Vector2i; import org.joml.Vector2ic; +import java.util.Map; + import static java.lang.Math.PI; import static org.joml.Math.atan2; @@ -12,6 +14,13 @@ public enum Direction { LEFT(-1, 0, 180), DOWN(0, 1, 270); + private static final Map PERPENDICULARS = Map.of( + Direction.UP, new Direction[] { Direction.LEFT, Direction.RIGHT }, + Direction.DOWN, new Direction[] { Direction.LEFT, Direction.RIGHT }, + Direction.LEFT, new Direction[] { Direction.UP, Direction.DOWN }, + Direction.RIGHT, new Direction[] { Direction.UP, Direction.DOWN } + ); + public final int x; public final int y; public final int xAngle; @@ -33,6 +42,10 @@ public enum Direction { }; } + public Direction[] perpendiculars() { + return PERPENDICULARS.get(this); + } + public static Direction ofVector(Vector2ic vector) { // X Versor = [1, 0] // dot = 1 * vector.x + 0 * vector.y = vector.x diff --git a/api/src/main/java/com/bartlomiejpluta/base/lib/ai/RandomMovementAI.java b/api/src/main/java/com/bartlomiejpluta/base/lib/ai/RandomMovementAI.java index ee424c84..1345bc5a 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/lib/ai/RandomMovementAI.java +++ b/api/src/main/java/com/bartlomiejpluta/base/lib/ai/RandomMovementAI.java @@ -7,15 +7,15 @@ import com.bartlomiejpluta.base.api.move.Direction; import java.util.Random; -public class RandomMovementAI implements AI { +public class RandomMovementAI implements AI { private final Random random = new Random(); - private final NPC npc; + private final N npc; private final float intervalSeconds; private float accumulator = 0.0f; private float threshold = 0.0f; - public RandomMovementAI(NPC npc, float intervalSeconds) { + public RandomMovementAI(N npc, float intervalSeconds) { this.npc = npc; this.intervalSeconds = intervalSeconds; } diff --git a/api/src/main/java/com/bartlomiejpluta/base/lib/ai/RunawayAI.java b/api/src/main/java/com/bartlomiejpluta/base/lib/ai/RunawayAI.java new file mode 100644 index 00000000..b20edfa4 --- /dev/null +++ b/api/src/main/java/com/bartlomiejpluta/base/lib/ai/RunawayAI.java @@ -0,0 +1,54 @@ +package com.bartlomiejpluta.base.lib.ai; + +import com.bartlomiejpluta.base.api.ai.AI; +import com.bartlomiejpluta.base.api.ai.NPC; +import com.bartlomiejpluta.base.api.entity.Entity; +import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer; +import com.bartlomiejpluta.base.api.move.Direction; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +import java.util.Random; + +@RequiredArgsConstructor +public class RunawayAI implements AI { + @NonNull + private final N npc; + + @NonNull + private final T character; + + private final Random random = new Random(); + + @Override + public void nextActivity(ObjectLayer layer, float dt) { + if (npc.isMoving()) { + return; + } + + var direction = npc.getDirectionTowards(character).opposite(); + if (tryToMove(layer, direction)) { + return; + } + + var perpendiculars = direction.perpendiculars(); + var first = random.nextInt(2); + var second = 1 - first; + + if (tryToMove(layer, perpendiculars[first])) { + return; + } + + tryToMove(layer, perpendiculars[second]); + } + + private boolean tryToMove(ObjectLayer layer, Direction direction) { + var movement = npc.prepareMovement(direction); + if (layer.isTileReachable(movement.getTo())) { + layer.pushMovement(movement); + return true; + } + + return false; + } +} \ No newline at end of file