From 6678c352bbb362268c798c06c77a6f6d31244704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Wed, 31 Aug 2022 23:46:12 +0200 Subject: [PATCH] Improve MapObject to support CompletableFuture actions --- .../bartlomiejpluta/demo/entity/Chest.java | 11 +- .../com/bartlomiejpluta/demo/entity/Door.java | 11 +- .../demo/entity/MapObject.java | 124 +++++++++++++----- 3 files changed, 98 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/bartlomiejpluta/demo/entity/Chest.java b/src/main/java/com/bartlomiejpluta/demo/entity/Chest.java index c83b0b9..ca98056 100644 --- a/src/main/java/com/bartlomiejpluta/demo/entity/Chest.java +++ b/src/main/java/com/bartlomiejpluta/demo/entity/Chest.java @@ -4,6 +4,8 @@ import com.bartlomiejpluta.demo.world.item.Item; import lombok.Getter; import lombok.NonNull; +import java.util.concurrent.CompletableFuture; + public class Chest extends MapObject { @Getter private final Item[] content = new Item[Enemy.MAX_LOOT]; @@ -13,13 +15,8 @@ public class Chest extends MapObject { } @Override - protected void interact() { - runner.getGuiManager().openChestWindow(this); - } - - @Override - protected boolean shouldGoFurther(MapObject object) { - return runner.getGuiManager().openedWindows() == 0; + protected CompletableFuture interact() { + return runner.getGuiManager().openChestWindow(this); } public Chest addItem(Item item) { diff --git a/src/main/java/com/bartlomiejpluta/demo/entity/Door.java b/src/main/java/com/bartlomiejpluta/demo/entity/Door.java index 6cade09..554aebd 100644 --- a/src/main/java/com/bartlomiejpluta/demo/entity/Door.java +++ b/src/main/java/com/bartlomiejpluta/demo/entity/Door.java @@ -4,6 +4,8 @@ import A.maps; import com.bartlomiejpluta.demo.runner.DemoRunner; import lombok.NonNull; +import java.util.concurrent.CompletableFuture; + public class Door extends MapObject { private final String mapUid; private final int targetX; @@ -22,14 +24,13 @@ public class Door extends MapObject { } @Override - protected void interact() { + protected CompletableFuture interact() { context.openMap(mapUid); context.getMap().getObjectLayer(layerId).addEntity(player); player.setCoordinates(targetX, targetY); - } - @Override - protected boolean shouldGoFurther(MapObject object) { - return true; + reset(); + + return CompletableFuture.completedFuture(null); } } diff --git a/src/main/java/com/bartlomiejpluta/demo/entity/MapObject.java b/src/main/java/com/bartlomiejpluta/demo/entity/MapObject.java index dd6a8c9..c82ce32 100644 --- a/src/main/java/com/bartlomiejpluta/demo/entity/MapObject.java +++ b/src/main/java/com/bartlomiejpluta/demo/entity/MapObject.java @@ -7,16 +7,29 @@ import com.bartlomiejpluta.base.util.path.PathExecutor; import lombok.Getter; import lombok.NonNull; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + +import static java.util.Objects.requireNonNull; +import static java.util.concurrent.CompletableFuture.completedFuture; + public abstract class MapObject extends NamedCharacter { - private final PathExecutor pathExecutor = new PathExecutor<>(this); - private final DB.model.MapObjectModel template; - private final Short frame; + private static final float INTERVAL = 0.05f; + private static final float COOLDOWN = 0.5f; + protected final PathExecutor pathExecutor = new PathExecutor<>(this); private final String interactSound; + protected boolean interacting = false; + + private Supplier> beforeAll; + private Supplier> before; + private Supplier> after; + private Supplier> afterAll; + + private CompletableFuture future; @Getter private final String name; - private boolean interacting = false; public MapObject(@NonNull String id) { this(DB.dao.map_object.find(id)); @@ -24,59 +37,90 @@ public abstract class MapObject extends NamedCharacter { public MapObject(@NonNull DB.model.MapObjectModel template) { super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.get(template.getCharset()).uid)); - this.template = template; - this.frame = template.getFrame(); + short frame = requireNonNull(template.getFrame()); this.name = template.getName(); this.interactSound = A.sounds.get(template.getInteractSound()).uid; setBlocking(true); disableAnimation(); - if (frame != null) { - setAnimationFrame(frame); - } + setAnimationFrame(frame); + pathExecutor.setRepeat(1); - pathExecutor.setPath( - frame != null - ? new CharacterPath() - .run(this::startInteraction) - .turn(Direction.LEFT, frame) - .wait(0.05f) - .turn(Direction.RIGHT, frame) - .wait(0.05f) - .turn(Direction.UP, frame) - .wait(0.25f) - .run(this::interact) - .suspend(this::shouldGoFurther) - .wait(0.25f) - .turn(Direction.RIGHT, frame) - .wait(0.05f) - .turn(Direction.LEFT, frame) - .wait(0.05f) - .turn(Direction.DOWN, frame) - .wait(0.5f) - .run(this::finishInteraction) - : new CharacterPath<>() + pathExecutor.setPath(new CharacterPath() + .run(this::startInteraction) + .turn(Direction.LEFT, frame) + .wait(INTERVAL) + .turn(Direction.RIGHT, frame) + .wait(INTERVAL) + .turn(Direction.UP, frame) + .wait(INTERVAL) + .run(this::runInteraction) + .suspend(() -> future) + .wait(INTERVAL) + .turn(Direction.RIGHT, frame) + .wait(INTERVAL) + .turn(Direction.LEFT, frame) + .wait(INTERVAL) + .turn(Direction.DOWN, frame) + .run(this::finishInteraction) + .suspend(() -> future) + .wait(COOLDOWN) + .run(this::completeInteraction) ); } - protected boolean shouldGoFurther(MapObject object) { - return true; + public MapObject beforeAll(@NonNull Supplier> action) { + this.beforeAll = action; + return this; + } + + public MapObject before(@NonNull Supplier> action) { + this.before = action; + return this; + } + + public MapObject after(@NonNull Supplier> action) { + this.after = action; + return this; + } + + public MapObject afterAll(@NonNull Supplier> action) { + this.afterAll = action; + return this; } public void triggerInteraction() { - interacting = true; + if (interacting) { + return; + } + + pathExecutor.reset(); + + if (beforeAll != null) { + beforeAll.get().thenRun(() -> interacting = true); + } else { + interacting = true; + } } - protected abstract void interact(); + private void runInteraction() { + this.future = (before != null ? before.get() : completedFuture(null)) + .thenCompose(v -> interact()) + .thenCompose(v -> (after != null ? after.get() : completedFuture(null))); + } - protected void startInteraction() { + private void startInteraction() { if (interactSound != null) { context.playSound(interactSound); } } - protected void finishInteraction() { + private void finishInteraction() { + this.future = afterAll != null ? afterAll.get() : completedFuture(null); + } + + private void completeInteraction() { interacting = false; } @@ -86,4 +130,12 @@ public abstract class MapObject extends NamedCharacter { pathExecutor.execute(getLayer(), dt); } } + + protected final void reset() { + setFaceDirection(Direction.DOWN); + pathExecutor.reset(); + interacting = false; + } + + protected abstract CompletableFuture interact(); } \ No newline at end of file