Implement some sample dialogs | apply BASE engine updates
This commit is contained in:
BIN
charsets/35f770a6-5d94-4ddf-a132-dc3788a3adaf.png
Normal file
BIN
charsets/35f770a6-5d94-4ddf-a132-dc3788a3adaf.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
charsets/4a636044-2dbd-4ef3-8bdf-b63501c85ae3.png
Normal file
BIN
charsets/4a636044-2dbd-4ef3-8bdf-b63501c85ae3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
14
data.sql
14
data.sql
@@ -163,5 +163,19 @@ INSERT INTO "PUBLIC"."ENEMY" VALUES
|
||||
('eagle', 'Eagle', 'Eagle', 'Corpse', '2d4+2', '10d2', TRUE, 'wooden_sword', NULL, NULL, 'Poof', 'Deku death'),
|
||||
('skeleton', 'Skeleton', 'Skeleton', 'Corpse', '2d6+2', '10d2', TRUE, 'wooden_sword', NULL, NULL, 'Poof', 'Deku death'),
|
||||
('skeleton_archer', 'Skeleton Archer', 'Skeleton', 'Corpse', '2d6+2', '10d2', TRUE, 'wooden_dagger', 'wooden_bow,wooden_arrow,2d4+3', NULL, 'Poof', 'Deku death');
|
||||
CREATE MEMORY TABLE "PUBLIC"."FRIEND"(
|
||||
"ID" VARCHAR NOT NULL,
|
||||
"NAME" VARCHAR NOT NULL,
|
||||
"CHARSET" VARCHAR NOT NULL,
|
||||
"SPEED" VARCHAR NOT NULL,
|
||||
"BLOCKING" BOOLEAN DEFAULT FALSE NOT NULL,
|
||||
"DIALOG_COLOR" VARCHAR DEFAULT '0xFFFFFF' NOT NULL
|
||||
);
|
||||
ALTER TABLE "PUBLIC"."FRIEND" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_7C" PRIMARY KEY("ID");
|
||||
-- 3 +/- SELECT COUNT(*) FROM PUBLIC.FRIEND;
|
||||
INSERT INTO "PUBLIC"."FRIEND" VALUES
|
||||
('turtle', 'Turtle', 'Turtle', '10d2', TRUE, 'AA00DD'),
|
||||
('neko', 'Neko', 'Neko', '14', TRUE, 'AA00DD'),
|
||||
('grandma', 'Grandma', 'Grandma', '7', TRUE, 'DD00AA');
|
||||
ALTER TABLE "PUBLIC"."ENEMY_DROP" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_8A" FOREIGN KEY("ENEMY") REFERENCES "PUBLIC"."ENEMY"("ID") NOCHECK;
|
||||
ALTER TABLE "PUBLIC"."ENEMY" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_3F" FOREIGN KEY("MELEE_WEAPON") REFERENCES "PUBLIC"."MELEE_WEAPON"("ID") NOCHECK;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
$1825b6a1-842d-4565-97e0-2005118b2b2b2 ( :+com.bartlomiejpluta.demo.map.ForrestHandler
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
BIN
project.bep
BIN
project.bep
Binary file not shown.
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
margin="20f"
|
||||
width="900f"
|
||||
height="auto">
|
||||
<base:TextView ref="message" alignment="top|left" font="A.fonts.roboto_regular.$" fontSize="40f" width="relative"
|
||||
rows="4" color="0xFFFFFF"/>
|
||||
|
||||
<base:VLayout width="relative" height="auto">
|
||||
<base:TextView ref="speaker" alignment="top|left" font="A.fonts.roboto_regular.$" fontSize="40f" width="relative" color="0x00AA00" />
|
||||
<base:PrintedTextView ref="message" duration="0.01f" alignment="top|left" font="A.fonts.roboto_regular.$" fontSize="40f" width="relative" rows="4" color="0xFFFFFF"/>
|
||||
</base:VLayout>
|
||||
|
||||
</demo:DialogWindow>
|
||||
16
widgets/5a5aea0a-8c8b-4730-8e45-9ec6ccc5c4f6.xml
Normal file
16
widgets/5a5aea0a-8c8b-4730-8e45-9ec6ccc5c4f6.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<demo:DialogChoiceWindow
|
||||
xmlns:base="com.bartlomiejpluta.base.lib.gui"
|
||||
xmlns:demo="com.bartlomiejpluta.demo.gui"
|
||||
windowPosition="bottom"
|
||||
padding="20f"
|
||||
margin="20f"
|
||||
width="900f"
|
||||
height="auto">
|
||||
|
||||
<base:VLayout width="relative" height="auto">
|
||||
<base:TextView ref="speaker" alignment="top|left" font="A.fonts.roboto_regular.$" fontSize="40f" width="relative" color="0x00AA00" />
|
||||
<base:VOptionChoice ref="choice" width="relative" />
|
||||
</base:VLayout>
|
||||
|
||||
</demo:DialogChoiceWindow>
|
||||
Reference in New Issue
Block a user