diff --git a/src/main/java/de/siphalor/was/WhatAStorage.java b/src/main/java/de/siphalor/was/WhatAStorage.java index 1dbc0b9..07cfe89 100644 --- a/src/main/java/de/siphalor/was/WhatAStorage.java +++ b/src/main/java/de/siphalor/was/WhatAStorage.java @@ -9,12 +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.Balance; import de.siphalor.was.game.Storage; import de.siphalor.was.visual.JFXVisual; import de.siphalor.was.visual.Visual; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -75,8 +74,10 @@ public class WhatAStorage { contentManager.addPack(mainPack); File[] packDirs = Path.of("packs").toFile().listFiles(File::isDirectory); - for (File dir : packDirs) { - contentManager.addPack(new FileContentPack(dir.getName(), dir.toPath())); + if (packDirs != null) { + for (File dir : packDirs) { + contentManager.addPack(new FileContentPack(dir.getName(), dir.toPath())); + } } I18n.getInstance().reload(contentManager); @@ -99,7 +100,8 @@ public class WhatAStorage { } public void loadGame() { - questGenerator = questManager.get("normal"); + //questGenerator = questManager.get("normal"); + questGenerator = new RandomQuestGenerator(); quests.clear(); storage = new Storage(GRID_SIZE, GRID_SIZE, GRID_SIZE); balance = new Balance(); diff --git a/src/main/java/de/siphalor/was/content/product/Product.java b/src/main/java/de/siphalor/was/content/product/Product.java index 2e55657..88733b9 100644 --- a/src/main/java/de/siphalor/was/content/product/Product.java +++ b/src/main/java/de/siphalor/was/content/product/Product.java @@ -48,7 +48,7 @@ public interface Product { @NotNull default String getTextureLocation() { - return "textures/products/" + getType().getId() + "/" + getPropertySpecifier(); + return "textures/products/" + getType().getId() + "/" + getPropertySpecifier() + ".png"; } @NotNull diff --git a/src/main/java/de/siphalor/was/content/product/ProductManager.java b/src/main/java/de/siphalor/was/content/product/ProductManager.java index d36d595..db0e1f9 100644 --- a/src/main/java/de/siphalor/was/content/product/ProductManager.java +++ b/src/main/java/de/siphalor/was/content/product/ProductManager.java @@ -4,11 +4,11 @@ import de.siphalor.was.content.ContentManager; import de.siphalor.was.util.ResourceManager; import de.siphalor.was.content.product.dynamic.DynamicProductType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; +import java.util.*; public class ProductManager implements ResourceManager> { private final Map> productTypes = new HashMap<>(); @@ -34,7 +34,22 @@ public class ProductManager implements ResourceManager> { } @Override + @Nullable public ProductType get(String id) { return productTypes.get(id); } + + @NotNull + public Collection> getTypes() { + return productTypes.values(); + } + + @Nullable + public Product randomProduct(Random random) { + if (!productTypes.isEmpty()) { + List> typeList = new ArrayList<>(productTypes.values()); + return typeList.get(random.nextInt(typeList.size())).randomProduct(random); + } + return null; + } } diff --git a/src/main/java/de/siphalor/was/content/product/ProductType.java b/src/main/java/de/siphalor/was/content/product/ProductType.java index 9367f4d..4d75671 100644 --- a/src/main/java/de/siphalor/was/content/product/ProductType.java +++ b/src/main/java/de/siphalor/was/content/product/ProductType.java @@ -3,9 +3,13 @@ package de.siphalor.was.content.product; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Random; + public interface ProductType { @Nullable T getProduct(@NotNull String[] values); @NotNull String getId(); @NotNull String[] getProperties(); + + @NotNull Product randomProduct(Random random); } diff --git a/src/main/java/de/siphalor/was/content/product/dynamic/DynamicProductType.java b/src/main/java/de/siphalor/was/content/product/dynamic/DynamicProductType.java index 0c83da4..da4c517 100644 --- a/src/main/java/de/siphalor/was/content/product/dynamic/DynamicProductType.java +++ b/src/main/java/de/siphalor/was/content/product/dynamic/DynamicProductType.java @@ -1,5 +1,6 @@ package de.siphalor.was.content.product.dynamic; +import de.siphalor.was.content.product.Product; import de.siphalor.was.content.product.ProductType; import de.siphalor.was.util.Util; import org.jetbrains.annotations.NotNull; @@ -125,6 +126,12 @@ public class DynamicProductType implements ProductType { return properties; } + @Override + public @NotNull Product randomProduct(Random random) { + List products = new ArrayList<>(variations.values()); + return products.get(random.nextInt(products.size())); + } + private static class ProductPrototype { String value; @@ -148,7 +155,7 @@ public class DynamicProductType implements ProductType { result.depth = prototype.depth; else result.depth = depth; - if (result.yPredicate != null) + if (prototype.yPredicate != null) result.yPredicate = prototype.yPredicate; else result.yPredicate = yPredicate; diff --git a/src/main/java/de/siphalor/was/content/quest/QuestGenerator.java b/src/main/java/de/siphalor/was/content/quest/QuestGenerator.java index 19603e3..ce4b73a 100644 --- a/src/main/java/de/siphalor/was/content/quest/QuestGenerator.java +++ b/src/main/java/de/siphalor/was/content/quest/QuestGenerator.java @@ -8,10 +8,4 @@ public interface QuestGenerator extends Enumeration { */ void restart(); - /** - * Returns the next {@link Quest} but doesn't advance - * @return the next {@link Quest} - * @see QuestGenerator#nextElement() - */ - Quest peek(); } diff --git a/src/main/java/de/siphalor/was/content/quest/RandomQuestGenerator.java b/src/main/java/de/siphalor/was/content/quest/RandomQuestGenerator.java new file mode 100644 index 0000000..59afab3 --- /dev/null +++ b/src/main/java/de/siphalor/was/content/quest/RandomQuestGenerator.java @@ -0,0 +1,27 @@ +package de.siphalor.was.content.quest; + +import de.siphalor.was.WhatAStorage; + +import java.util.Random; + +public class RandomQuestGenerator implements QuestGenerator { + private static final Random RANDOM = new Random(); + @Override + public void restart() { + + } + + @Override + public boolean hasMoreElements() { + return true; + } + + @Override + public Quest nextElement() { + return new Quest( + RANDOM.nextBoolean() ? Quest.Type.IN : Quest.Type.OUT, + RANDOM.nextInt(15) * 100, + WhatAStorage.getInstance().getProductManager().randomProduct(RANDOM) + ); + } +} diff --git a/src/main/java/de/siphalor/was/content/quest/StaticQuestGenerator.java b/src/main/java/de/siphalor/was/content/quest/StaticQuestGenerator.java index e79afb4..51dc062 100644 --- a/src/main/java/de/siphalor/was/content/quest/StaticQuestGenerator.java +++ b/src/main/java/de/siphalor/was/content/quest/StaticQuestGenerator.java @@ -72,11 +72,6 @@ public class StaticQuestGenerator implements QuestGenerator { index = 0; } - @Override - public Quest peek() { - return quests.get(index); - } - @Override public Quest nextElement() { return quests.get(index++); diff --git a/src/main/java/de/siphalor/was/game/Storage.java b/src/main/java/de/siphalor/was/game/Storage.java index 965a735..89603cc 100644 --- a/src/main/java/de/siphalor/was/game/Storage.java +++ b/src/main/java/de/siphalor/was/game/Storage.java @@ -1,12 +1,14 @@ package de.siphalor.was.game; -import de.siphalor.was.content.product.Product; import org.jetbrains.annotations.NotNull; public class Storage { StorageSlot[][] slots; public Storage(int width, int height, int depth) { + if (width <= 0 || height <= 0 || depth <= 0) { + throw new IllegalArgumentException("Storage lengths must be bigger than zero"); + } slots = new StorageSlot[height][width]; for (StorageSlot[] row : slots) { @@ -21,12 +23,19 @@ public class Storage { return slots[x][y]; } - public int move(int x1, int y1, int x2, int y2) { - StorageSlot slot1 = get(x1, y1); - Product product = slot1.front(); - if (product != null) { - return get(x2, y2).add(product); + public int getWidth() { + return slots.length; + } + + public int getHeight() { + return slots[0].length; + } + + public void clear() { + for (StorageSlot[] row : slots) { + for (StorageSlot slot : row) { + slot.clear(); + } } - return -1; } } diff --git a/src/main/java/de/siphalor/was/game/StorageSlot.java b/src/main/java/de/siphalor/was/game/StorageSlot.java index 5ab57c3..8ce33d7 100644 --- a/src/main/java/de/siphalor/was/game/StorageSlot.java +++ b/src/main/java/de/siphalor/was/game/StorageSlot.java @@ -4,6 +4,8 @@ import de.siphalor.was.content.product.Product; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; + public class StorageSlot { final int depth; final Product[] products; @@ -18,6 +20,10 @@ public class StorageSlot { return products; } + public void clear() { + Arrays.fill(products, null); + } + @Nullable public Product front() { for (int i = products.length - 1; i >= 0; i--) { diff --git a/src/main/java/de/siphalor/was/visual/JFXVisual.java b/src/main/java/de/siphalor/was/visual/JFXVisual.java index 557d797..671d860 100644 --- a/src/main/java/de/siphalor/was/visual/JFXVisual.java +++ b/src/main/java/de/siphalor/was/visual/JFXVisual.java @@ -23,6 +23,7 @@ import javafx.scene.Scene; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.scene.control.TableColumn; +import javafx.scene.control.Tooltip; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.image.Image; import javafx.scene.layout.GridPane; @@ -45,10 +46,10 @@ public class JFXVisual extends Application implements Visual { private static MainController controller; - private static final Map PRODUCT_IMAGES = new HashMap<>(); + private static final Map CACHED_IMAGES = new HashMap<>(); @NotNull public static Image getProductImage(@NotNull Product product, @NotNull ContentManager contentManager) { - return PRODUCT_IMAGES.computeIfAbsent( + return CACHED_IMAGES.computeIfAbsent( product.getTextureLocation(), loc -> loadImage(loc, contentManager).orElseGet(() -> loadImage(Product.getPlaceholderTextureLocation(), contentManager).orElseThrow()) ); @@ -82,8 +83,10 @@ public class JFXVisual extends Application implements Visual { I18n i18n = I18n.getInstance(); controller.budgetLabel.setText(i18n.format("game.budget", budget)); - if (budget < 0 && !controller.budgetLabel.getStyleClass().contains("red")) { - controller.budgetLabel.getStyleClass().add("red"); + if (budget < 0) { + if (!controller.budgetLabel.getStyleClass().contains("red")) { + controller.budgetLabel.getStyleClass().add("red"); + } } else { controller.budgetLabel.getStyleClass().remove("red"); } @@ -237,22 +240,29 @@ public class JFXVisual extends Application implements Visual { default: case 0: slot.slot0.setImage(getProductImage(product, contentManager)); - slot.slot0Description.setText(product.getDescription(i18n)); slot.slot0Title.setText(product.getName(i18n)); + Tooltip.install(slot.slot0, createTooltip(product, i18n)); break; case 1: slot.slot1.setImage(getProductImage(product, contentManager)); - slot.slot1Description.setText(product.getDescription(i18n)); slot.slot1Title.setText(product.getName(i18n)); + Tooltip.install(slot.slot1, createTooltip(product, i18n)); break; case 2: slot.slot2.setImage(getProductImage(product, contentManager)); - slot.slot2Description.setText(product.getDescription(i18n)); slot.slot2Title.setText(product.getName(i18n)); + Tooltip.install(slot.slot2, createTooltip(product, i18n)); break; } } + private Tooltip createTooltip(Product product, I18n i18n) { + Tooltip tooltip = new Tooltip(product.getName(i18n) + ": " + product.getDescription(i18n)); + tooltip.setShowDelay(Duration.millis(100)); + tooltip.setHideDelay(Duration.millis(100)); + return tooltip; + } + @Override public void onProductCleared(int x, int y, int z) { StorageSlotController slot = controller.storageSlotControllers[y][x]; @@ -261,18 +271,18 @@ public class JFXVisual extends Application implements Visual { default: case 0: slot.slot0.setImage(null); - slot.slot0Description.setText(null); slot.slot0Title.setText(empty); + Tooltip.uninstall(slot.slot0, null); break; case 1: slot.slot1.setImage(null); - slot.slot1Description.setText(null); slot.slot1Title.setText(empty); + Tooltip.uninstall(slot.slot1, null); break; case 2: slot.slot2.setImage(null); - slot.slot2Description.setText(null); slot.slot2Title.setText(empty); + Tooltip.uninstall(slot.slot2, null); break; } } diff --git a/src/main/java/de/siphalor/was/visual/jfx/MainController.java b/src/main/java/de/siphalor/was/visual/jfx/MainController.java index 9a06b19..5fec3d1 100644 --- a/src/main/java/de/siphalor/was/visual/jfx/MainController.java +++ b/src/main/java/de/siphalor/was/visual/jfx/MainController.java @@ -1,6 +1,7 @@ package de.siphalor.was.visual.jfx; import de.siphalor.was.WhatAStorage; +import de.siphalor.was.assets.AssetsManager; import javafx.fxml.FXML; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; @@ -8,6 +9,7 @@ import javafx.scene.chart.XYChart; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TableView; +import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.DragEvent; import javafx.scene.input.TransferMode; @@ -47,6 +49,20 @@ public class MainController { was.requestQuest(); } + @FXML + private void onTrashDragEntered(DragEvent dragEvent) { + if (dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) { + AssetsManager.getStream("textures/bin_open.png").ifPresent(inputStream -> { + trash.setImage(new Image(inputStream)); + }); + } + } + @FXML + private void onTrashDragExited(DragEvent dragEvent) { + AssetsManager.getStream("textures/bin_closed.png").ifPresent(inputStream -> { + trash.setImage(new Image(inputStream)); + }); + } @FXML private void onTrashDragOver(DragEvent dragEvent) { if (dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) { diff --git a/src/main/java/de/siphalor/was/visual/jfx/StorageSlotController.java b/src/main/java/de/siphalor/was/visual/jfx/StorageSlotController.java index 74fa1d9..f739f57 100644 --- a/src/main/java/de/siphalor/was/visual/jfx/StorageSlotController.java +++ b/src/main/java/de/siphalor/was/visual/jfx/StorageSlotController.java @@ -18,15 +18,12 @@ public class StorageSlotController { public ImageView slot0; public Label slot0Title; - public Label slot0Description; public ImageView slot1; public Label slot1Title; - public Label slot1Description; public ImageView slot2; public Label slot2Title; - public Label slot2Description; public StorageSlotController(int x, int y) { this.x = x; diff --git a/src/main/resources/assets/jfx/game.fxml b/src/main/resources/assets/jfx/game.fxml index 7e08f6b..328a799 100644 --- a/src/main/resources/assets/jfx/game.fxml +++ b/src/main/resources/assets/jfx/game.fxml @@ -58,7 +58,7 @@ - + @@ -114,9 +114,9 @@ - - - + + +