diff --git a/src/main/java/de/siphalor/was/WhatAStorage.java b/src/main/java/de/siphalor/was/WhatAStorage.java index d65af37..9c232fe 100644 --- a/src/main/java/de/siphalor/was/WhatAStorage.java +++ b/src/main/java/de/siphalor/was/WhatAStorage.java @@ -11,6 +11,7 @@ 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.Balance; +import de.siphalor.was.game.Options; import de.siphalor.was.game.Storage; import de.siphalor.was.util.Util; import de.siphalor.was.visual.JFXVisual; @@ -39,6 +40,8 @@ public class WhatAStorage { private final ProductManager productManager; private final QuestManager questManager; + private final Options options; + private Visual visual; private boolean stopScheduled; @@ -54,6 +57,7 @@ public class WhatAStorage { contentManager.addPack(mainPack); productManager = new ProductManager(); questManager = new QuestManager(); + options = new Options(); visual = new JFXVisual(); } @@ -70,6 +74,10 @@ public class WhatAStorage { return questManager; } + public Options getOptions() { + return options; + } + public void reload() { contentManager.clear(); @@ -102,8 +110,8 @@ public class WhatAStorage { } public void loadGame() { - //questGenerator = questManager.get("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(); @@ -122,6 +130,13 @@ public class WhatAStorage { return balance; } + public String[] getLangs() { + return contentManager.getResources("lang", "properties").map(resource -> { + int index = resource.getId().lastIndexOf('.'); + return resource.getId().substring(Math.max(index, 0)); + }).toArray(String[]::new); + } + private void addTransaction(Balance.Transaction transaction, int change) { balance.add(transaction, change); visual.onBalanceChanged(balance.getBudget(), transaction, change, balance.getTotalIncome(), balance.getTotalLoss()); @@ -213,21 +228,23 @@ public class WhatAStorage { } public boolean resolveQuests(int in, int out) { - int s = quests.size(); - if (in < s && in >= 0 && out < s && out >= 0) { - if (quests.get(in).getType() == Quest.Type.IN && quests.get(out).getType() == Quest.Type.OUT) { - Product product = quests.get(in).getProduct(); - if (product.equals(quests.get(out).getProduct())) { - addTransaction(Balance.Transaction.STORE, quests.get(in).getReward()); - addTransaction(Balance.Transaction.DELIVER, quests.get(out).getReward()); + if (options.getAllowQuestResolving()) { + int s = quests.size(); + if (in < s && in >= 0 && out < s && out >= 0) { + if (quests.get(in).getType() == Quest.Type.IN && quests.get(out).getType() == Quest.Type.OUT) { + Product product = quests.get(in).getProduct(); + if (product.equals(quests.get(out).getProduct())) { + addTransaction(Balance.Transaction.STORE, quests.get(in).getReward()); + addTransaction(Balance.Transaction.DELIVER, quests.get(out).getReward()); - if (out > in) out--; - quests.remove(in); - quests.remove(out); + if (out > in) out--; + quests.remove(in); + quests.remove(out); - visual.onQuestRemoved(in); - visual.onQuestRemoved(out); - return true; + visual.onQuestRemoved(in); + visual.onQuestRemoved(out); + return true; + } } } } 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 3411f2b..9e0f906 100644 --- a/src/main/java/de/siphalor/was/content/lang/I18n.java +++ b/src/main/java/de/siphalor/was/content/lang/I18n.java @@ -20,6 +20,12 @@ public class I18n extends ResourceBundle { @Nullable private Lang lang; + public Lang getLang() { + if (lang != null) + return lang; + return DEFAULT_LANG; + } + public void setLang(@NotNull String code, @NotNull ContentManager contentManager) { if (lang == null || !lang.getCode().equals(code)) { lang = new Lang(code); 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 a385f9c..9f59161 100644 --- a/src/main/java/de/siphalor/was/content/lang/Lang.java +++ b/src/main/java/de/siphalor/was/content/lang/Lang.java @@ -19,13 +19,14 @@ public class Lang { this.code = code; } + @NotNull public String getCode() { return code; } public void load(@NotNull ContentManager contentManager) { properties.clear(); - contentManager.getAllOfResource("lang/" + code + ".lang").forEachOrdered(resource -> { + contentManager.getAllOfResource("lang/" + code + ".properties").forEachOrdered(resource -> { InputStream inputStream = resource.getInputStream(); if (inputStream != null) { try { diff --git a/src/main/java/de/siphalor/was/content/pack/FileContentPack.java b/src/main/java/de/siphalor/was/content/pack/FileContentPack.java index eabf4f4..e668f08 100644 --- a/src/main/java/de/siphalor/was/content/pack/FileContentPack.java +++ b/src/main/java/de/siphalor/was/content/pack/FileContentPack.java @@ -26,8 +26,8 @@ public class FileContentPack implements ContentPack { Path dir = base.resolve(Path.of(location)); if (dir.toFile().isDirectory()) { try { - return Files.find(dir, Integer.MAX_VALUE, (fPath, fileAttributes) -> fileAttributes.isRegularFile() && fPath.endsWith(extension)).map(path -> - new FileResource(Util.pathToId(id, path.relativize(base).toString()), path.toFile()) + return Files.find(dir, Integer.MAX_VALUE, (path, attributes) -> attributes.isRegularFile() && path.getFileName().getName(0).toString().endsWith(extension)).map(path -> + new FileResource(Util.pathToId(id, dir.relativize(path).toString()), path.toFile()) ); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/de/siphalor/was/game/Options.java b/src/main/java/de/siphalor/was/game/Options.java new file mode 100644 index 0000000..904bce6 --- /dev/null +++ b/src/main/java/de/siphalor/was/game/Options.java @@ -0,0 +1,22 @@ +package de.siphalor.was.game; + +public class Options { + private boolean autoRefillQuests; + private boolean allowQuestResolving; + + public boolean getAllowQuestResolving() { + return allowQuestResolving; + } + + public void setAllowQuestResolving(boolean allowQuestResolving) { + this.allowQuestResolving = allowQuestResolving; + } + + public boolean getAutoRefillQuests() { + return autoRefillQuests; + } + + public void setAutoRefillQuests(boolean autoRefillQuests) { + this.autoRefillQuests = autoRefillQuests; + } +} diff --git a/src/main/java/de/siphalor/was/visual/JFXVisual.java b/src/main/java/de/siphalor/was/visual/JFXVisual.java index dbfe26b..3b678bf 100644 --- a/src/main/java/de/siphalor/was/visual/JFXVisual.java +++ b/src/main/java/de/siphalor/was/visual/JFXVisual.java @@ -11,6 +11,7 @@ import de.siphalor.was.game.Balance; import de.siphalor.was.util.Util; import de.siphalor.was.visual.jfx.controller.BalanceController; import de.siphalor.was.visual.jfx.controller.MainController; +import de.siphalor.was.visual.jfx.controller.OptionsController; import de.siphalor.was.visual.jfx.controller.QuestController; import de.siphalor.was.visual.jfx.util.JFXUtil; import de.siphalor.was.visual.jfx.util.StorageSlot; @@ -37,14 +38,15 @@ import java.util.logging.Level; public class JFXVisual extends Application implements Visual { private static Stage primaryStage; - private static final FXMLLoader loader = new FXMLLoader(); private static Scene mainScene; - private static MainController mainController; private static GridPane storageGrid; private static StorageSlot[][] storageSlots; + private static Scene optionsScene; + private static OptionsController optionsController; + private static Stage balanceStage; private static BalanceController balanceController; @@ -115,60 +117,23 @@ public class JFXVisual extends Application implements Visual { primaryStage.setMinHeight(500); primaryStage.setTitle(WhatAStorage.TITLE); - loader.setResources(I18n.getInstance()); - mainController = new MainController(WhatAStorage.getInstance()); - loader.setController(mainController); - - Pane pane = loader.load(AssetsManager.getStream("jfx/game.fxml").get()); - mainScene = new Scene(pane); - mainScene.getStylesheets().add("assets/jfx/main.css"); - loadMainScene(); - - mainController.balanceButton.setOnAction(event -> { - if (balanceStage != null && balanceStage.isShowing()) { - return; - } - - balanceStage = new Stage(); - FXMLLoader balanceLoader = new FXMLLoader(); - balanceLoader.setResources(I18n.getInstance()); - - try { - balanceController = new BalanceController(); - balanceLoader.setController(balanceController); - - Parent parent = balanceLoader.load(AssetsManager.getStream("jfx/balance.fxml").orElseThrow()); - - balanceController.init(); - - Scene balanceScene = new Scene(parent); - balanceScene.getStylesheets().add("assets/jfx/main.css"); - - balanceStage.setOnCloseRequest(e -> { - balanceStage = null; - balanceController = null; - }); - - balanceStage.setAlwaysOnTop(true); - balanceStage.setScene(balanceScene); - balanceStage.setTitle(I18n.getInstance().getString("game.balance")); - balanceStage.show(); - } catch (IOException e) { - e.printStackTrace(); - } - }); + loadOptionsScene(); primaryStage.setOnCloseRequest(event -> { if (balanceStage != null) balanceStage.hide(); }); + primaryStage.setScene(mainScene); + primaryStage.show(); } public void loadMainScene() { - primaryStage.setScene(mainScene); + mainController = new MainController(WhatAStorage.getInstance()); + + mainScene = JFXUtil.loadScene("game", mainController, I18n.getInstance()); prepareStorageGrid(3, 3, 3); @@ -177,6 +142,41 @@ public class JFXVisual extends Application implements Visual { }); onBalanceChanged(0, Balance.Transaction.NOOP, 0, 0, 0); + + mainController.balanceButton.setOnAction(event -> { + if (balanceStage != null && balanceStage.isShowing()) { + return; + } + + balanceStage = new Stage(); + + balanceController = new BalanceController(); + Scene scene = JFXUtil.loadScene("balance", balanceController, I18n.getInstance()); + + balanceController.init(); + + balanceStage.setOnCloseRequest(e -> { + balanceStage = null; + balanceController = null; + }); + + balanceStage.setAlwaysOnTop(true); + balanceStage.setScene(scene); + balanceStage.setTitle(I18n.getInstance().getString("game.balance")); + balanceStage.show(); + }); + + mainController.optionsButton.setOnAction(event -> openOptionsScene()); + } + + private void loadOptionsScene() { + optionsController = new OptionsController(); + optionsScene = JFXUtil.loadScene("options", optionsController, I18n.getInstance()); + } + + private void openOptionsScene() { + optionsController.beforeOpen(() -> primaryStage.setScene(mainScene)); + primaryStage.setScene(optionsScene); } private void addQuest(Quest quest) { diff --git a/src/main/java/de/siphalor/was/visual/jfx/controller/MainController.java b/src/main/java/de/siphalor/was/visual/jfx/controller/MainController.java index a53fe8d..6f38076 100644 --- a/src/main/java/de/siphalor/was/visual/jfx/controller/MainController.java +++ b/src/main/java/de/siphalor/was/visual/jfx/controller/MainController.java @@ -19,6 +19,7 @@ public class MainController { public Label budgetLabel; public Button balanceButton; + public Button optionsButton; public Pane storagePane; diff --git a/src/main/java/de/siphalor/was/visual/jfx/controller/OptionsController.java b/src/main/java/de/siphalor/was/visual/jfx/controller/OptionsController.java new file mode 100644 index 0000000..188460f --- /dev/null +++ b/src/main/java/de/siphalor/was/visual/jfx/controller/OptionsController.java @@ -0,0 +1,71 @@ +package de.siphalor.was.visual.jfx.controller; + +import de.siphalor.was.WhatAStorage; +import de.siphalor.was.content.lang.I18n; +import de.siphalor.was.game.Options; +import javafx.fxml.FXML; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.ToggleButton; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +public class OptionsController { + private Runnable exitRunnable; + + public ChoiceBox languageChoice; + public ToggleButton allowQuestResolvingToggle; + public ToggleButton autoQuestRefillToggle; + + public void beforeOpen(@NotNull Runnable exitRunnable) { + Options options = WhatAStorage.getInstance().getOptions(); + this.exitRunnable = exitRunnable; + + I18n i18n = I18n.getInstance(); + String curLang = i18n.getLang().getCode(); + + languageChoice.getItems().clear(); + String[] langs = WhatAStorage.getInstance().getLangs(); + Arrays.sort(langs); + for (String lang : langs) { + LangEntry langEntry = new LangEntry(lang, i18n.getString("langs." + lang)); + languageChoice.getItems().add(langEntry); + if (curLang.equals(lang)) { + languageChoice.setValue(langEntry); + } + } + + allowQuestResolvingToggle.setSelected(options.getAllowQuestResolving()); + autoQuestRefillToggle.setSelected(options.getAutoRefillQuests()); + } + + @FXML + private void onLeaveClicked() { + Options options = WhatAStorage.getInstance().getOptions(); + + I18n.getInstance().setLang(languageChoice.getValue().getCode(), WhatAStorage.getInstance().getContentManager()); + options.setAllowQuestResolving(allowQuestResolvingToggle.isSelected()); + options.setAutoRefillQuests(autoQuestRefillToggle.isSelected()); + + exitRunnable.run(); + } + + private static class LangEntry { + private final String code; + private final String name; + + private LangEntry(String code, String name) { + this.code = code; + this.name = name; + } + + @Override + public String toString() { + return name; + } + + public String getCode() { + return code; + } + } +} diff --git a/src/main/java/de/siphalor/was/visual/jfx/controller/QuestController.java b/src/main/java/de/siphalor/was/visual/jfx/controller/QuestController.java index e6c8a9a..67dc17b 100644 --- a/src/main/java/de/siphalor/was/visual/jfx/controller/QuestController.java +++ b/src/main/java/de/siphalor/was/visual/jfx/controller/QuestController.java @@ -39,8 +39,10 @@ public class QuestController { if (dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) { DraggedProduct product = (DraggedProduct) dragEvent.getDragboard().getContent(DraggedProduct.FORMAT); if (product instanceof DraggedProduct.Quest) { - DraggedProduct.Quest quest = (DraggedProduct.Quest) product; - return WhatAStorage.getInstance().canQuestsResolve(quest.index, getIndex()); + if (WhatAStorage.getInstance().getOptions().getAllowQuestResolving()) { + DraggedProduct.Quest quest = (DraggedProduct.Quest) product; + return WhatAStorage.getInstance().canQuestsResolve(quest.index, getIndex()); + } } else if (product instanceof DraggedProduct.Slot) { DraggedProduct.Slot slot = (DraggedProduct.Slot) product; return WhatAStorage.getInstance().canDeliverProduct(getIndex(), slot.x, slot.y); diff --git a/src/main/java/de/siphalor/was/visual/jfx/util/JFXUtil.java b/src/main/java/de/siphalor/was/visual/jfx/util/JFXUtil.java index 1ab54f3..d49fa96 100644 --- a/src/main/java/de/siphalor/was/visual/jfx/util/JFXUtil.java +++ b/src/main/java/de/siphalor/was/visual/jfx/util/JFXUtil.java @@ -1,11 +1,18 @@ package de.siphalor.was.visual.jfx.util; +import de.siphalor.was.assets.AssetsManager; +import de.siphalor.was.content.lang.I18n; +import javafx.fxml.FXMLLoader; import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.image.PixelReader; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; +import java.io.IOException; + public class JFXUtil { public static Image scaleTo(Image image, int width) { double scale = image.getWidth() / (double) width; @@ -33,4 +40,19 @@ public class JFXUtil { node.getStyleClass().remove(clazz); } } + + public static Scene loadScene(String fxml, Object controller, I18n i18n) { + FXMLLoader loader = new FXMLLoader(); + loader.setResources(i18n); + loader.setController(controller); + Parent parent = null; + try { + parent = loader.load(AssetsManager.getStream("jfx/" + fxml + ".fxml").orElseThrow()); + } catch (IOException e) { + e.printStackTrace(); + } + Scene scene = new Scene(parent); + scene.getStylesheets().add("assets/jfx/main.css"); + return scene; + } } diff --git a/src/main/resources/assets/jfx/balance.fxml b/src/main/resources/assets/jfx/balance.fxml index 338ecdd..1822cf8 100644 --- a/src/main/resources/assets/jfx/balance.fxml +++ b/src/main/resources/assets/jfx/balance.fxml @@ -3,11 +3,16 @@ - + + + + + - + + @@ -15,7 +20,8 @@ - + + - +