Implement some sample dialogs | apply BASE engine updates
This commit is contained in:
74
src/main/java/com/bartlomiejpluta/demo/entity/Friend.java
Normal file
74
src/main/java/com/bartlomiejpluta/demo/entity/Friend.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import DB.model.FriendModel;
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.ai.NPC;
|
||||
import com.bartlomiejpluta.base.api.character.Character;
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.lib.ai.NoopAI;
|
||||
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||
import com.bartlomiejpluta.demo.world.item.Item;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Friend extends Creature implements NPC {
|
||||
@Getter
|
||||
private AI strategy = NoopAI.INSTANCE;
|
||||
private AI priorStrategy;
|
||||
private boolean interacting;
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final int dialogNameColor;
|
||||
private Function<Friend, CompletableFuture<Object>> interaction;
|
||||
|
||||
public Friend(@NonNull String id) {
|
||||
this(DB.dao.friend.find(id));
|
||||
}
|
||||
|
||||
public Friend(@NonNull FriendModel template) {
|
||||
super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.byName(template.getCharset()).$));
|
||||
name = template.getName();
|
||||
setSpeed(DiceRoller.roll(template.getSpeed()) / 10f);
|
||||
setBlocking(template.isBlocking());
|
||||
dialogNameColor = Integer.parseInt(template.getDialogColor(), 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeItemFromEquipment(Item item) {
|
||||
|
||||
}
|
||||
|
||||
public CompletableFuture<Object> interact(Character trigger) {
|
||||
if(interaction != null && !interacting) {
|
||||
setFaceDirection(getDirectionTowards(trigger));
|
||||
priorStrategy = strategy;
|
||||
strategy = NoopAI.INSTANCE;
|
||||
interacting = true;
|
||||
|
||||
return interaction.apply(this).thenApply(o -> {
|
||||
strategy = priorStrategy;
|
||||
interacting = false;
|
||||
return o;
|
||||
});
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
public Friend interaction(Function<Friend, CompletableFuture<Object>> interaction) {
|
||||
this.interaction = interaction;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Friend asAnimal() {
|
||||
this.strategy = new RandomMovementAI<>(this, 4f);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,8 @@ public abstract class NamedCharacter extends CharacterDelegate {
|
||||
}
|
||||
|
||||
public abstract String getName();
|
||||
|
||||
public int getDialogNameColor() {
|
||||
return 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
@@ -47,12 +47,22 @@ public class Player extends Creature {
|
||||
for (var i = 0; i < entities.size(); ++i) {
|
||||
var entity = entities.get(i);
|
||||
|
||||
// Use some map object which player is looking at
|
||||
if (entity.getCoordinates().equals(coords) && entity instanceof MapObject object) {
|
||||
object.triggerInteraction();
|
||||
return;
|
||||
if (entity.getCoordinates().equals(coords)) {
|
||||
|
||||
// Use some map object which player is looking at
|
||||
if(entity instanceof MapObject object) {
|
||||
object.triggerInteraction();
|
||||
return;
|
||||
}
|
||||
|
||||
// Interact with friend creature which player is looking at
|
||||
if(entity instanceof Friend friend) {
|
||||
friend.interact(this).thenApply(o -> interactionCooldown = INTERACTION_COOLDOWN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (entity.getCoordinates().equals(getCoordinates())) {
|
||||
|
||||
// Pick some item from the ground
|
||||
@@ -223,7 +233,12 @@ public class Player extends Creature {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Player";
|
||||
return "Luna";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogNameColor() {
|
||||
return 0x00AA00;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import A.fonts;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.TextView;
|
||||
import com.bartlomiejpluta.base.lib.gui.VOptionChoice;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class DialogChoiceWindow extends DecoratedWindow {
|
||||
|
||||
@Ref("speaker")
|
||||
private TextView speaker;
|
||||
|
||||
@Ref("choice")
|
||||
private VOptionChoice choice;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onOpen(WindowManager manager, Object[] args) {
|
||||
super.onOpen(manager, args);
|
||||
|
||||
speaker.setText((String) args[0]);
|
||||
speaker.setColor((int) args[1]);
|
||||
|
||||
var index = 0;
|
||||
choice.removeAllChildren();
|
||||
var options = (String[]) args[2];
|
||||
for(var option : options) {
|
||||
var button = new Button(context, gui, Collections.emptyMap());
|
||||
choice.add(button);
|
||||
button.setText(option);
|
||||
button.setColor(0xFFFFFF);
|
||||
button.setWidthMode(SizeMode.RELATIVE);
|
||||
button.setWidth(1f);
|
||||
button.setFont(fonts.roboto_regular.$);
|
||||
button.setFontSize(20f);
|
||||
button.setAction(onChoose(index));
|
||||
++index;
|
||||
}
|
||||
|
||||
choice.focus();
|
||||
}
|
||||
|
||||
private Runnable onChoose(int index) {
|
||||
return () -> resolve(index);
|
||||
}
|
||||
|
||||
public DialogChoiceWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,18 @@ import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.api.input.Key;
|
||||
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||
import com.bartlomiejpluta.base.lib.gui.PrintedTextView;
|
||||
import com.bartlomiejpluta.base.lib.gui.TextView;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class DialogWindow extends DecoratedWindow {
|
||||
|
||||
@Ref("speaker")
|
||||
private TextView speaker;
|
||||
|
||||
@Ref("message")
|
||||
private TextView text;
|
||||
private PrintedTextView text;
|
||||
|
||||
public DialogWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
@@ -26,6 +30,12 @@ public class DialogWindow extends DecoratedWindow {
|
||||
}
|
||||
|
||||
if (event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS) {
|
||||
if (text.isPrinting()) {
|
||||
text.printAll();
|
||||
event.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
manager.close();
|
||||
event.consume();
|
||||
}
|
||||
@@ -35,11 +45,16 @@ public class DialogWindow extends DecoratedWindow {
|
||||
public void onOpen(WindowManager manager, Object[] args) {
|
||||
super.onOpen(manager, args);
|
||||
|
||||
text.setText((String) args[0]);
|
||||
speaker.setText((String) args[0]);
|
||||
speaker.setColor((int) args[1]);
|
||||
|
||||
if (args.length > 1) {
|
||||
setWindowPosition((WindowPosition) args[1]);
|
||||
text.setText((String) args[2]);
|
||||
|
||||
if (args.length > 3) {
|
||||
setWindowPosition((WindowPosition) args[3]);
|
||||
}
|
||||
|
||||
text.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.gui.Component;
|
||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||
import com.bartlomiejpluta.base.lib.gui.TextView;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PrintTextView extends TextView {
|
||||
|
||||
@Setter
|
||||
private Float duration;
|
||||
|
||||
private float acc;
|
||||
|
||||
private String originalText;
|
||||
|
||||
public void start() {
|
||||
acc = 0f;
|
||||
}
|
||||
|
||||
public boolean isPrinting() {
|
||||
return originalText.length() != super.getText().length();
|
||||
}
|
||||
|
||||
public void printAll() {
|
||||
acc = originalText.length() * duration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String text) {
|
||||
super.setText("");
|
||||
this.originalText = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
super.update(dt);
|
||||
|
||||
acc += dt;
|
||||
super.setText(originalText.substring(0, Math.min(originalText.length(), (int) (acc / duration))));
|
||||
}
|
||||
|
||||
public PrintTextView(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,22 @@
|
||||
package com.bartlomiejpluta.demo.map;
|
||||
|
||||
import A.maps;
|
||||
import com.bartlomiejpluta.base.api.camera.Camera;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.api.gui.Window;
|
||||
import com.bartlomiejpluta.base.api.gui.WindowPosition;
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
import com.bartlomiejpluta.base.api.input.Input;
|
||||
import com.bartlomiejpluta.base.api.input.Key;
|
||||
import com.bartlomiejpluta.base.api.map.handler.MapHandler;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.MapPin;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||
import com.bartlomiejpluta.base.api.move.Direction;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.lib.camera.CameraController;
|
||||
import com.bartlomiejpluta.base.lib.camera.FollowingCameraController;
|
||||
import com.bartlomiejpluta.base.util.input.InputUtil;
|
||||
import com.bartlomiejpluta.base.util.world.CharacterSpawner;
|
||||
import com.bartlomiejpluta.base.util.world.Warp;
|
||||
import com.bartlomiejpluta.demo.entity.Chest;
|
||||
import com.bartlomiejpluta.demo.entity.Door;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.entity.Player;
|
||||
import com.bartlomiejpluta.demo.entity.*;
|
||||
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||
import com.bartlomiejpluta.demo.menu.GuiManager;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
@@ -82,12 +75,16 @@ public abstract class BaseMapHandler implements MapHandler {
|
||||
cameraController.update();
|
||||
}
|
||||
|
||||
public CompletableFuture<Window> dialog(String message, WindowPosition position) {
|
||||
return guiManager.showDialog(message, position);
|
||||
public CompletableFuture<Object> dialog(NamedCharacter speaker, String message, WindowPosition position) {
|
||||
return guiManager.showDialog(speaker.getName(), speaker.getDialogNameColor(), message, position);
|
||||
}
|
||||
|
||||
public CompletableFuture<Window> dialog(String message) {
|
||||
return guiManager.showDialog(message, WindowPosition.BOTTOM);
|
||||
public CompletableFuture<Object> dialog(NamedCharacter speaker, String message) {
|
||||
return guiManager.showDialog(speaker.getName(), speaker.getDialogNameColor(), message, WindowPosition.BOTTOM);
|
||||
}
|
||||
|
||||
public CompletableFuture<Integer> dialogChoice(NamedCharacter speaker, String... choices) {
|
||||
return guiManager.showDialogChoice(speaker.getName(), speaker.getDialogNameColor(), choices);
|
||||
}
|
||||
|
||||
protected <T extends Entity> T addEntity(T entity, MapPin tile) {
|
||||
@@ -100,6 +97,10 @@ public abstract class BaseMapHandler implements MapHandler {
|
||||
return addEntity(new Enemy(id), tile);
|
||||
}
|
||||
|
||||
public Friend friend(@NonNull MapPin tile, @NonNull String id) {
|
||||
return addEntity(new Friend(id), tile);
|
||||
}
|
||||
|
||||
public Chest chest(@NonNull MapPin tile, @NonNull String id) {
|
||||
return addEntity(new Chest(id), tile);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.bartlomiejpluta.demo.map;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.input.Input;
|
||||
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||
import com.bartlomiejpluta.base.api.map.handler.MapHandler;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
|
||||
public class HeroHomeHandler extends BaseMapHandler {
|
||||
|
||||
@Override
|
||||
public void onOpen(Context context, GameMap map) {
|
||||
dialog(player, "Ahhh, another beautiful day for an adventure... Let's go!");
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ public class GuiManager {
|
||||
private final EquipmentWindow equipment;
|
||||
private final LootWindow loot;
|
||||
private final DialogWindow dialog;
|
||||
private final DialogChoiceWindow dialogChoice;
|
||||
private final Consumer<KeyEvent> gameMenuHandler = this::handleGameMenuKeyEvent;
|
||||
|
||||
public GuiManager(@NonNull DemoRunner runner, @NonNull Context context) {
|
||||
@@ -49,6 +50,7 @@ public class GuiManager {
|
||||
this.gameMenu.reference("exit", Button.class).setAction(runner::exit);
|
||||
|
||||
this.dialog = gui.inflateWindow(A.widgets.dialog.$, DialogWindow.class);
|
||||
this.dialogChoice = gui.inflateWindow(A.widgets.dialog_choice.$, DialogChoiceWindow.class);
|
||||
this.loot = gui.inflateWindow(widgets.loot_menu.$, LootWindow.class);
|
||||
}
|
||||
|
||||
@@ -83,7 +85,7 @@ public class GuiManager {
|
||||
return manager.size();
|
||||
}
|
||||
|
||||
public CompletableFuture<Window> showStartMenu() {
|
||||
public CompletableFuture<Object> showStartMenu() {
|
||||
manager.closeAll();
|
||||
return manager.open(startMenu);
|
||||
}
|
||||
@@ -100,19 +102,23 @@ public class GuiManager {
|
||||
manager.setDisplayMode(DisplayMode.DISPLAY_TOP);
|
||||
}
|
||||
|
||||
public CompletableFuture<Window> showDialog(@NonNull String message, @NonNull WindowPosition position) {
|
||||
return manager.open(dialog, message, position);
|
||||
public CompletableFuture<Object> showDialog(@NonNull String speaker, int color, @NonNull String message, @NonNull WindowPosition position) {
|
||||
return manager.open(dialog, speaker, color, message, position);
|
||||
}
|
||||
|
||||
public CompletableFuture<Window> openLootWindow(@NonNull Enemy enemy) {
|
||||
public CompletableFuture<Integer> showDialogChoice(@NonNull String speaker, int color, @NonNull String... choices) {
|
||||
return manager.openForResult(Integer.class, dialogChoice, speaker, color, choices);
|
||||
}
|
||||
|
||||
public CompletableFuture<Object> openLootWindow(@NonNull Enemy enemy) {
|
||||
return manager.open(loot, enemy.getLoot(), "Loot");
|
||||
}
|
||||
|
||||
public CompletableFuture<Window> openChestWindow(@NonNull Chest chest) {
|
||||
public CompletableFuture<Object> openChestWindow(@NonNull Chest chest) {
|
||||
return manager.open(loot, chest.getContent(), chest.getName());
|
||||
}
|
||||
|
||||
public CompletableFuture<Window> openGameMenu() {
|
||||
public CompletableFuture<Object> openGameMenu() {
|
||||
return manager.open(gameMenu);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user