diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/ai/FollowPathAI.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/ai/FollowPathAI.java index 76e4b033..3455478c 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/ai/FollowPathAI.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/ai/FollowPathAI.java @@ -10,10 +10,10 @@ public class FollowPathAI implements AI { private final NPCPath path; public FollowPathAI(NPC npc) { - this(npc, true); + this(npc, null); } - public FollowPathAI(NPC npc, boolean repeat) { + public FollowPathAI(NPC npc, Integer repeat) { var path = new NPCPath(); this.executor = new PathExecutor<>(npc, repeat, path); this.path = path; diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/MoveSegment.java b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/MoveSegment.java index 39634668..5e337f01 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/MoveSegment.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/MoveSegment.java @@ -20,14 +20,18 @@ public class MoveSegment implements PathSegment { } @Override - public boolean perform(T movable, ObjectLayer layer, float dt) { + public PathProgress perform(T movable, ObjectLayer layer, float dt) { + if (movable.isMoving()) { + return PathProgress.ONGOING; + } + var movement = movable.prepareMovement(direction); if (ignore || layer.isTileReachable(movement.getTo())) { layer.pushMovement(movement); - return true; + return PathProgress.SEGMENT_DONE; } - return false; + return PathProgress.SEGMENT_FAILED; } } diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathExecutor.java b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathExecutor.java index 98d39294..d78b99cf 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathExecutor.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathExecutor.java @@ -9,32 +9,42 @@ import java.util.Objects; public class PathExecutor { protected final List> path; private final T movable; - private final boolean repeat; + private final Integer repeat; private int current = 0; + private int iteration = 0; + private boolean updated = false; - public PathExecutor(T movable, boolean repeat, Path path) { + public PathExecutor(T movable, Integer repeat, Path path) { this.movable = movable; this.repeat = repeat; this.path = Objects.requireNonNull(path).getPath(); } - public boolean execute(ObjectLayer layer, float dt) { - if (!repeat && isRetired()) { - return false; + public PathProgress execute(ObjectLayer layer, float dt) { + var size = path.size(); + + if (current == size - 1 && !updated) { + ++iteration; + updated = true; } - if (!movable.isMoving()) { - var item = path.get(current % path.size()); - if (item.perform(movable, layer, dt)) { - ++current; + if (current == size) { + updated = false; + + if (repeat != null && iteration >= repeat) { + return PathProgress.DONE; + } else { + current = 0; + return PathProgress.REPEAT; } } - return true; - } + var result = path.get(current).perform(movable, layer, dt); + if (result == PathProgress.SEGMENT_DONE) { + ++current; + } - private boolean isRetired() { - return current == path.size() - 1; + return result; } } diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathProgress.java b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathProgress.java new file mode 100644 index 00000000..e6c39c20 --- /dev/null +++ b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathProgress.java @@ -0,0 +1,9 @@ +package com.bartlomiejpluta.base.api.util.path; + +public enum PathProgress { + ONGOING, + SEGMENT_DONE, + SEGMENT_FAILED, + REPEAT, + DONE, +} diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathSegment.java b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathSegment.java index 9db646eb..f6f6aadd 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathSegment.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/PathSegment.java @@ -4,5 +4,5 @@ import com.bartlomiejpluta.base.api.game.entity.Movable; import com.bartlomiejpluta.base.api.game.map.layer.object.ObjectLayer; public interface PathSegment { - boolean perform(T movable, ObjectLayer layer, float dt); + PathProgress perform(T movable, ObjectLayer layer, float dt); } diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/RunSegment.java b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/RunSegment.java index 028ec872..d2554130 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/RunSegment.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/RunSegment.java @@ -13,8 +13,8 @@ public class RunSegment implements PathSegment { } @Override - public boolean perform(T movable, ObjectLayer layer, float dt) { + public PathProgress perform(T movable, ObjectLayer layer, float dt) { runnable.run(); - return true; + return PathProgress.SEGMENT_DONE; } } diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/TurnSegment.java b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/TurnSegment.java index cf56b379..c66c5a6d 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/TurnSegment.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/TurnSegment.java @@ -14,8 +14,8 @@ public class TurnSegment implements PathSegment { } @Override - public boolean perform(T npc, ObjectLayer layer, float dt) { + public PathProgress perform(T npc, ObjectLayer layer, float dt) { npc.setFaceDirection(direction); - return true; + return PathProgress.SEGMENT_DONE; } } diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/WaitSegment.java b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/WaitSegment.java index 030b4727..e694a945 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/util/path/WaitSegment.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/util/path/WaitSegment.java @@ -12,14 +12,14 @@ public class WaitSegment implements PathSegment { } @Override - public boolean perform(T movable, ObjectLayer layer, float dt) { + public PathProgress perform(T movable, ObjectLayer layer, float dt) { accumulator += dt; if (accumulator > seconds) { accumulator = 0.0f; - return true; + return PathProgress.SEGMENT_DONE; } - return false; + return PathProgress.ONGOING; } }