diff --git a/.gitignore b/.gitignore index ae6fbf1..00c2387 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ build/ # Logs *.log +*.log.* *.log.lck diff --git a/src/main/java/de/siphalor/was/WhatAStorage.java b/src/main/java/de/siphalor/was/WhatAStorage.java index 0e24726..e43f271 100644 --- a/src/main/java/de/siphalor/was/WhatAStorage.java +++ b/src/main/java/de/siphalor/was/WhatAStorage.java @@ -9,9 +9,11 @@ import de.siphalor.was.content.product.ProductManager; import de.siphalor.was.content.quest.Quest; import de.siphalor.was.content.quest.QuestGenerator; import de.siphalor.was.content.quest.QuestManager; +import de.siphalor.was.content.quest.RandomQuestGenerator; import de.siphalor.was.game.*; import de.siphalor.was.util.Pair; import de.siphalor.was.util.Util; +import de.siphalor.was.visual.ConsoleVisual; import de.siphalor.was.visual.JFXVisual; import de.siphalor.was.visual.Visual; import org.jetbrains.annotations.NotNull; @@ -58,7 +60,7 @@ public class WhatAStorage { questManager = new QuestManager(); options = new Options(); - visual = new JFXVisual(); + visual = new ConsoleVisual(); } public ContentManager getContentManager() { @@ -109,13 +111,13 @@ public class WhatAStorage { } public void startGame() { - questGenerator = questManager.get("example.test"); - //questGenerator = new RandomQuestGenerator(); + //questGenerator = questManager.get("example.test"); + questGenerator = new RandomQuestGenerator(); quests.clear(); storage = new Storage(GRID_SIZE, GRID_SIZE, GRID_SIZE); balance = new Balance(); - visual.onGameStart(); + visual.onGameStart(GRID_SIZE, GRID_SIZE, GRID_SIZE); if (options.getAutoRefillQuests()) { for (int i = 0; i < MAX_QUESTS; i++) { diff --git a/src/main/java/de/siphalor/was/content/lang/I18n.java b/src/main/java/de/siphalor/was/content/lang/I18n.java index 9e0f906..6be24fe 100644 --- a/src/main/java/de/siphalor/was/content/lang/I18n.java +++ b/src/main/java/de/siphalor/was/content/lang/I18n.java @@ -26,11 +26,15 @@ public class I18n extends ResourceBundle { return DEFAULT_LANG; } - public void setLang(@NotNull String code, @NotNull ContentManager contentManager) { + public boolean setLang(@NotNull String code, @NotNull ContentManager contentManager) { if (lang == null || !lang.getCode().equals(code)) { - lang = new Lang(code); - lang.load(contentManager); + Lang l = new Lang(code); + if (l.load(contentManager)) { + lang = l; + return true; + } } + return false; } public void reload(@NotNull ContentManager contentManager) { diff --git a/src/main/java/de/siphalor/was/content/lang/Lang.java b/src/main/java/de/siphalor/was/content/lang/Lang.java index 9f59161..fd72806 100644 --- a/src/main/java/de/siphalor/was/content/lang/Lang.java +++ b/src/main/java/de/siphalor/was/content/lang/Lang.java @@ -24,7 +24,7 @@ public class Lang { return code; } - public void load(@NotNull ContentManager contentManager) { + public boolean load(@NotNull ContentManager contentManager) { properties.clear(); contentManager.getAllOfResource("lang/" + code + ".properties").forEachOrdered(resource -> { InputStream inputStream = resource.getInputStream(); @@ -45,7 +45,9 @@ public class Lang { if (properties.isEmpty()) { Util.LOGGER.log(Level.SEVERE, "Failed to load lang file for " + code); + return false; } + return true; } @Nullable diff --git a/src/main/java/de/siphalor/was/visual/ConsoleVisual.java b/src/main/java/de/siphalor/was/visual/ConsoleVisual.java new file mode 100644 index 0000000..bba8910 --- /dev/null +++ b/src/main/java/de/siphalor/was/visual/ConsoleVisual.java @@ -0,0 +1,233 @@ +package de.siphalor.was.visual; + +import de.siphalor.was.WhatAStorage; +import de.siphalor.was.content.lang.I18n; +import de.siphalor.was.content.product.Product; +import de.siphalor.was.content.quest.Quest; +import de.siphalor.was.game.Balance; +import de.siphalor.was.game.Transaction; + +import java.util.Arrays; +import java.util.Scanner; +import java.util.stream.Collectors; + +public class ConsoleVisual implements Visual { + private final int CELL_WIDTH = 16; + + private WhatAStorage was; + private Scanner scanner; + + private State state; + + private String[][][] storage; + private int budget; + + private enum State { + MENU, GAME, + } + + @Override + public void setup(WhatAStorage whatAStorage) { + state = State.MENU; + was = whatAStorage; + scanner = new Scanner(System.in); + } + + @Override + public void run() { + loop: + while (true) { + String input = scanner.nextLine(); + String[] parts = input.split(" "); + if (parts.length == 0) continue; + switch (state) { + case MENU: + switch (parts[0]) { + case "help": { + I18n i18n = I18n.getInstance(); + System.out.println("start: " + i18n.getString("menu.start-game")); + System.out.println("exit: " + i18n.getString("game.quit")); + break; + } + case "start": + was.startGame(); + break; + case "exit": + was.scheduleStop(); + break loop; + default: + printInvalidInput(); + break; + } + break; + case GAME: + switch (parts[0]) { + case "help": { + I18n i18n = I18n.getInstance(); + System.out.println("status: " + i18n.getString("game.storage")); + System.out.println("budget: " + i18n.getString("game.budget")); + System.out.println("options: " + i18n.getString("menu.options")); + System.out.println("exit: " + i18n.getString("game.quit")); + break; + } + case "status": { + showGame(); + System.out.println(); + Balance balance = WhatAStorage.getInstance().getBalance(); + showBudget(balance.getBudget(), balance.getTotalIncome(), balance.getTotalLoss()); + break; + } + case "budget": { + Balance balance = WhatAStorage.getInstance().getBalance(); + showBudget(balance.getBudget(), balance.getTotalIncome(), balance.getTotalLoss()); + break; + } + case "exit": + was.scheduleStop(); + break loop; + case "options": + if (parts.length == 1) { + System.out.println(I18n.getInstance().getString("menu.options.available")); + System.out.println("lang"); + } else { + switch (parts[1]) { + case "lang": + if (parts.length == 2) { + System.out.println(Arrays.stream(WhatAStorage.getInstance().getLangs()).map(s -> + s + ": " + I18n.getInstance().getString("langs." + s) + ).collect(Collectors.joining(", "))); + } else { + if (I18n.getInstance().setLang(parts[2], WhatAStorage.getInstance().getContentManager())) { + invalidateI18n(); + WhatAStorage.getInstance().getOptions().save(); + } else { + printInvalidInput(); + } + } + break; + default: + printInvalidInput(); + break; + } + } + break; + default: + printInvalidInput(); + break; + } + break; + } + } + } + + private void showGame() { + int width = storage.length; + int height = storage[0].length; + int depth = storage[0][0].length; + int index = 1; + + final String empty = I18n.getInstance().getString("game.storage.empty"); + for (int y = 0; y < height; y++) { + { + StringBuilder stringBuilder = new StringBuilder(); + for (int x = 0; x < width; x++) { + stringBuilder.append(index); + stringBuilder.append("."); + stringBuilder.append(" ".repeat(CELL_WIDTH * (x + 1) + x * 3 - stringBuilder.length())); + if (x < width - 1) { + stringBuilder.append(" | "); + } + + index++; + } + System.out.println(stringBuilder.toString()); + } + + for (int z = 0; z < depth; z++) { + StringBuilder stringBuilder = new StringBuilder(); + for (int x = 0; x < width; x++) { + if (storage[x][y][z] != null) { + stringBuilder.append(I18n.getInstance().getString(storage[x][y][z])); + } else { + stringBuilder.append(empty); + } + stringBuilder.append(" ".repeat(CELL_WIDTH * (x + 1) + x * 3 - stringBuilder.length())); + if (x < width - 1) { + stringBuilder.append(" | "); + } + } + System.out.println(stringBuilder.toString()); + } + + if (y < height - 1) { + StringBuilder stringBuilder = new StringBuilder(); + for (int x = 0; x < width; x++) { + stringBuilder.append("-".repeat(CELL_WIDTH)); + if (x < width - 1) { + stringBuilder.append("-+-"); + } + } + System.out.println(stringBuilder.toString()); + } + } + } + + private void showBudget(int budget, int totalIncome, int totalLoss) { + I18n i18n = I18n.getInstance(); + + System.out.println(i18n.format("game.budget.label", budget) + + " " + + i18n.format("game.balance.total-income", totalIncome) + + " " + + i18n.format("game.balance.total-loss", totalLoss)); + } + + private void printInvalidInput() { + System.out.println(I18n.getInstance().getString("general.invalid-input")); + } + + @Override + public void onGameStart(int width, int height, int depth) { + storage = new String[width][height][depth]; + state = State.GAME; + + showGame(); + System.out.println(); + showBudget(0, 0, 0); + } + + @Override + public void onScheduleStop() { + + } + + @Override + public void invalidateI18n() { + + } + + @Override + public void onBalanceChanged(int budget, Transaction transaction, int totalIncome, int totalLoss) { + + } + + @Override + public void onQuestAdded(Quest newQuest, boolean canCreateMore) { + + } + + @Override + public void onQuestRemoved(int index) { + + } + + @Override + public void onProductSet(int x, int y, int z, Product product) { + + } + + @Override + public void onProductCleared(int x, int y, int z, Product product) { + + } +} diff --git a/src/main/java/de/siphalor/was/visual/JFXVisual.java b/src/main/java/de/siphalor/was/visual/JFXVisual.java index c3e4cf8..73ad62b 100644 --- a/src/main/java/de/siphalor/was/visual/JFXVisual.java +++ b/src/main/java/de/siphalor/was/visual/JFXVisual.java @@ -44,6 +44,7 @@ public class JFXVisual extends Application implements Visual { private static GameController gameController; private static GridPane storageGrid; private static JFXStorageSlot[][] storageSlots; + private static int width, height, depth; private static Scene optionsScene; private static OptionsController optionsController; @@ -79,7 +80,11 @@ public class JFXVisual extends Application implements Visual { } @Override - public void onGameStart() { + public void onGameStart(int width, int height, int depth) { + JFXVisual.width = width; + JFXVisual.height = height; + JFXVisual.depth = depth; + loadGameScene(); changeScene(gameScene); } @@ -99,7 +104,7 @@ public class JFXVisual extends Application implements Visual { public void onBalanceChanged(int budget, Transaction transaction, int totalIncome, int totalLoss) { I18n i18n = I18n.getInstance(); - gameController.budgetLabel.setText(i18n.format("game.budget", budget)); + gameController.budgetLabel.setText(i18n.format("game.budget.label", budget)); JFXUtil.setStyleClass(gameController.budgetLabel, "red", budget < 0); if (balanceController != null) { @@ -141,7 +146,6 @@ public class JFXVisual extends Application implements Visual { primaryStage.setMinWidth(850); primaryStage.setMinHeight(500); - loadGameScene(); loadOptionsScene(); primaryStage.setOnCloseRequest(event -> { @@ -163,7 +167,7 @@ public class JFXVisual extends Application implements Visual { gameScene = JFXUtil.loadScene("game", gameController, I18n.getInstance()); - prepareStorageGrid(3, 3, 3); + prepareStorageGrid(); AssetsManager.getStream("textures/bin_closed.png").ifPresent(inputStream -> { gameController.trash.setImage(new Image(inputStream)); @@ -262,7 +266,7 @@ public class JFXVisual extends Application implements Visual { }); } - private void prepareStorageGrid(int width, int height, int depth) { + private void prepareStorageGrid() { storageGrid = new GridPane(); storageGrid.setId("storage-grid"); storageGrid.setPadding(new Insets(5D)); diff --git a/src/main/java/de/siphalor/was/visual/Visual.java b/src/main/java/de/siphalor/was/visual/Visual.java index b7f7539..68996c9 100644 --- a/src/main/java/de/siphalor/was/visual/Visual.java +++ b/src/main/java/de/siphalor/was/visual/Visual.java @@ -8,7 +8,7 @@ import de.siphalor.was.game.Transaction; public interface Visual { void setup(WhatAStorage whatAStorage); void run(); - void onGameStart(); + void onGameStart(int width, int height, int depth); void onScheduleStop(); void invalidateI18n(); diff --git a/src/main/resources/assets/jfx/game.fxml b/src/main/resources/assets/jfx/game.fxml index 218c864..c6a85f5 100644 --- a/src/main/resources/assets/jfx/game.fxml +++ b/src/main/resources/assets/jfx/game.fxml @@ -22,7 +22,7 @@