Tests, a lot of textures and bug fixes

This commit is contained in:
2020-07-09 20:27:53 +02:00
parent cb7408b7f1
commit 1cb2bc5da6
29 changed files with 1071 additions and 608 deletions

View File

@@ -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,9 +74,11 @@ public class WhatAStorage {
contentManager.addPack(mainPack);
File[] packDirs = Path.of("packs").toFile().listFiles(File::isDirectory);
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();

View File

@@ -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

View File

@@ -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<ProductType<?>> {
private final Map<String, ProductType<?>> productTypes = new HashMap<>();
@@ -34,7 +34,22 @@ public class ProductManager implements ResourceManager<ProductType<?>> {
}
@Override
@Nullable
public ProductType<?> get(String id) {
return productTypes.get(id);
}
@NotNull
public Collection<ProductType<?>> getTypes() {
return productTypes.values();
}
@Nullable
public Product randomProduct(Random random) {
if (!productTypes.isEmpty()) {
List<ProductType<?>> typeList = new ArrayList<>(productTypes.values());
return typeList.get(random.nextInt(typeList.size())).randomProduct(random);
}
return null;
}
}

View File

@@ -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<T extends Product> {
@Nullable T getProduct(@NotNull String[] values);
@NotNull String getId();
@NotNull String[] getProperties();
@NotNull Product randomProduct(Random random);
}

View File

@@ -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<DynamicProduct> {
return properties;
}
@Override
public @NotNull Product randomProduct(Random random) {
List<DynamicProduct> 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<DynamicProduct> {
result.depth = prototype.depth;
else
result.depth = depth;
if (result.yPredicate != null)
if (prototype.yPredicate != null)
result.yPredicate = prototype.yPredicate;
else
result.yPredicate = yPredicate;

View File

@@ -8,10 +8,4 @@ public interface QuestGenerator extends Enumeration<Quest> {
*/
void restart();
/**
* Returns the next {@link Quest} but doesn't advance
* @return the next {@link Quest}
* @see QuestGenerator#nextElement()
*/
Quest peek();
}

View File

@@ -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)
);
}
}

View File

@@ -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++);

View File

@@ -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;
}
}

View File

@@ -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--) {

View File

@@ -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<String, Image> PRODUCT_IMAGES = new HashMap<>();
private static final Map<String, Image> 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")) {
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;
}
}

View File

@@ -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)) {

View File

@@ -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;

View File

@@ -58,7 +58,7 @@
<VBox fx:id="questBox" />
</content>
</ScrollPane>
<VBox alignment="CENTER" onDragDropped="#onTrashDragDropped" onDragOver="#onTrashDragOver" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="TOP">
<VBox alignment="CENTER" onDragDropped="#onTrashDragDropped" onDragEntered="#onTrashDragEntered" onDragExited="#onTrashDragExited" onDragOver="#onTrashDragOver" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="TOP">
<GridPane.margin>
<Insets />
</GridPane.margin>
@@ -114,9 +114,9 @@
<content>
<TableView fx:id="balanceHistoryTable" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn prefWidth="50.666626400416135" styleClass="align-right" text="%game.balance.history.index" />
<TableColumn maxWidth="500.0" prefWidth="100.0" styleClass="align-right" text="%game.balance.history.change" />
<TableColumn maxWidth="1.7976931348623157E308" prefWidth="300.0" text="%game.balance.history.type" />
<TableColumn prefWidth="50.666626400416135" sortable="false" styleClass="align-right" text="%game.balance.history.index" />
<TableColumn maxWidth="500.0" prefWidth="100.0" sortable="false" styleClass="align-right" text="%game.balance.history.change" />
<TableColumn maxWidth="1.7976931348623157E308" prefWidth="300.0" sortable="false" text="%game.balance.history.type" />
</columns>
<placeholder>
<Label text="%game.balance.history.no-data" />

View File

@@ -26,9 +26,9 @@
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<ImageView fx:id="slot0" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.rowSpan="2" />
<ImageView fx:id="slot1" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="1" GridPane.rowSpan="2" />
<ImageView fx:id="slot2" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnSpan="2" GridPane.rowIndex="2" GridPane.rowSpan="2" />
<ImageView fx:id="slot0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.rowSpan="2" />
<ImageView fx:id="slot1" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="1" GridPane.rowSpan="2" />
<ImageView fx:id="slot2" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnSpan="2" GridPane.rowIndex="2" GridPane.rowSpan="2" />
<HBox alignment="CENTER_LEFT" prefHeight="100.0" GridPane.columnIndex="4" GridPane.rowIndex="1">
<children>
<Label fx:id="slot0Title" styleClass="storage-slot-item-title" text="%game.storage.empty">
@@ -36,7 +36,7 @@
<Font name="System Bold" size="12.0" />
</font>
</Label>
<Label fx:id="slot0Description" />
<Label fx:id="slot0Description" textOverrun="CLIP" />
</children>
</HBox>
<HBox alignment="CENTER_LEFT" prefHeight="100.0" GridPane.columnIndex="3" GridPane.columnSpan="2147483647" GridPane.rowIndex="2">

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -8,6 +8,7 @@ game.quest.reward = %d\u20ac
game.trash = M\u00fclltonne
game.trash.hover = Zerst\u00f6ren
game.storage = Lager
game.storage.empty = Leer
game.balance.history = Buchungen
game.balance.history.no-data = Noch keine Buchungen
game.balance.history.index =

View File

@@ -1,4 +1,4 @@
properties = type, weight
type.variants = marble, granite, sandstone
weight.variants = light, medium, heavy
weight.heavy.y = 1
weight.heavy.y = 2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -7,82 +7,110 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="package.svg"
id="svg8"
version="1.1"
viewBox="0 0 132.29166 132.29167"
width="500"
height="500"
width="500">
viewBox="0 0 132.29166 132.29167"
version="1.1"
id="svg8"
sodipodi:docname="package.svg"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
inkscape:export-filename="D:\coding\java\what-a-storage\src\main\resources\content\textures\products\package.png"
inkscape:export-xdpi="95.999992"
inkscape:export-ydpi="95.999992">
<defs
id="defs2" />
id="defs2">
<clipPath
id="clipPath879"
clipPathUnits="userSpaceOnUse">
<path
d="M 26.458333,0 0,26.458333 V 132.29166 h 105.83333 l 26.45833,-26.45833 V 0 Z"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.058;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path881" />
</clipPath>
<clipPath
id="clipPath883"
clipPathUnits="userSpaceOnUse">
<path
d="M 26.458333,0 0,26.458333 V 132.29166 h 105.83333 l 26.45833,-26.45833 V 0 Z"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.058;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path885" />
</clipPath>
<clipPath
id="clipPath887"
clipPathUnits="userSpaceOnUse">
<path
d="M 26.458333,0 0,26.458333 V 132.29166 h 105.83333 l 26.45833,-26.45833 V 0 Z"
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.058;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path889" />
</clipPath>
</defs>
<sodipodi:namedview
inkscape:guide-bbox="true"
inkscape:lockguides="false"
showguides="true"
inkscape:window-maximized="1"
inkscape:window-y="-7"
inkscape:window-x="-7"
inkscape:window-height="1010"
inkscape:window-width="1920"
units="px"
showgrid="false"
inkscape:document-rotation="0"
inkscape:current-layer="layer1"
inkscape:document-units="mm"
inkscape:cy="217.09446"
inkscape:cx="307.26355"
inkscape:zoom="0.7"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
id="base"
pagecolor="#ffffff"
id="base">
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="182.88496"
inkscape:cy="254.64746"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1010"
inkscape:window-x="-7"
inkscape:window-y="-7"
inkscape:window-maximized="1"
showguides="true"
inkscape:lockguides="false"
inkscape:guide-bbox="true">
<sodipodi:guide
inkscape:color="rgb(0,0,255)"
inkscape:locked="false"
inkscape:label=""
position="105.83333,105.83333"
orientation="0,1"
id="guide1410"
orientation="0,1"
position="105.83333,105.83333" />
<sodipodi:guide
inkscape:color="rgb(0,0,255)"
inkscape:locked="false"
inkscape:label=""
inkscape:locked="false"
inkscape:color="rgb(0,0,255)" />
<sodipodi:guide
position="105.83333,105.83333"
orientation="-1,0"
id="guide1412"
orientation="-1,0"
position="105.83333,105.83333" />
<sodipodi:guide
inkscape:color="rgb(0,0,255)"
inkscape:locked="false"
inkscape:label=""
inkscape:locked="false"
inkscape:color="rgb(0,0,255)" />
<sodipodi:guide
position="26.458333,105.83333"
orientation="-1,0"
id="guide1414"
orientation="-1,0"
position="26.458333,105.83333" />
<sodipodi:guide
inkscape:color="rgb(0,0,255)"
inkscape:locked="false"
inkscape:label=""
id="guide1416"
inkscape:locked="false"
inkscape:color="rgb(0,0,255)" />
<sodipodi:guide
position="105.83333,26.458333"
orientation="0,1"
position="105.83333,26.458333" />
id="guide1416"
inkscape:label=""
inkscape:locked="false"
inkscape:color="rgb(0,0,255)" />
<sodipodi:guide
id="guide1418"
position="0,132.29166"
orientation="0,500"
position="0,132.29166" />
id="guide1418" />
<sodipodi:guide
id="guide1420"
position="132.29166,132.29166"
orientation="500,0"
position="132.29166,132.29166" />
id="guide1420" />
<sodipodi:guide
id="guide1422"
position="132.29166,0"
orientation="0,-500"
position="132.29166,0" />
id="guide1422" />
<sodipodi:guide
id="guide1424"
position="0,0"
orientation="-500,0"
position="0,0" />
id="guide1424" />
</sodipodi:namedview>
<metadata
id="metadata5">
@@ -92,29 +120,32 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
id="layer1">
<rect
ry="1.9382317e-06"
y="26.458336"
x="0"
height="105.83333"
width="105.83333"
clip-path="url(#clipPath887)"
style="fill:#d6b285;stroke-width:1.05799995;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-linejoin:bevel"
id="rect1426"
style="fill:#d6b285;stroke-width:0.264583;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
width="105.83333"
height="105.83333"
x="0"
y="26.458336"
ry="1.9382317e-06" />
<path
id="path1428"
clip-path="url(#clipPath883)"
style="fill:#e4ccaf;stroke:#000000;stroke-width:1.05799995;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1;fill-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="M 0,26.458336 26.458333,4.9999997e-6 H 132.29166 L 105.83333,26.458336 H 0"
style="fill:#e4ccaf;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
id="path1428" />
<path
id="path1430"
clip-path="url(#clipPath879)"
style="fill:#ba915e;stroke:#000000;stroke-width:1.05799995;stroke-linecap:butt;stroke-linejoin:bevel;stroke-opacity:1;fill-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 105.83333,132.29166 26.45833,-26.45833 V 4.9999997e-6 L 105.83333,26.458336 Z"
style="fill:#ba915e;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
id="path1430" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -1,2 +0,0 @@
public class Tests {
}

View File

@@ -0,0 +1,39 @@
package de.siphalor.was;
import de.siphalor.was.content.ContentManager;
import de.siphalor.was.content.pack.ContentPack;
import de.siphalor.was.content.pack.JarContentPack;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ContentTests {
static ContentManager contentManager;
static ContentPack contentPack;
@BeforeAll
public static void prepareAll() {
contentManager = new ContentManager();
contentPack = new JarContentPack("jar", "content");
contentManager.addPack(contentPack);
}
@Test
public void areLangsUpToDate() throws IOException {
Properties properties = new Properties();
InputStream inputStream = contentManager.getResource("lang/en_us.lang").orElseThrow().getInputStream();
properties.load(inputStream);
contentManager.getResources("lang", "lang").forEach(resource -> {
if (!resource.getId().equals("lang/en_us.lang")) {
Properties props = new Properties();
Assertions.assertDoesNotThrow(() -> props.load(resource.getInputStream()));
Assertions.assertEquals(properties.keySet(), props.keySet(), "Missing lang keys for " + resource.getId());
}
});
}
}

View File

@@ -0,0 +1,36 @@
package de.siphalor.was;
import de.siphalor.was.content.ContentManager;
import de.siphalor.was.content.lang.Lang;
import de.siphalor.was.dummy.DummyContentPack;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class I18nTests {
static ContentManager contentManager;
static DummyContentPack contentPack;
static Lang lang;
@BeforeAll
public static void prepareAll() {
contentManager = new ContentManager();
contentPack = new DummyContentPack("dummy");
contentManager.addPack(contentPack);
contentPack.content.put("lang/dummy.lang", "abc = missingno\nescaped = \\\\\na.b.c = noop\nformatted = Formatted: %s!\nunicode = \\u20ac");
lang = new Lang("dummy");
lang.load(contentManager);
}
@Test
public void basicTest() {
Assertions.assertEquals("missingno", lang.get("abc"));
Assertions.assertEquals("noop", lang.get("a.b.c"));
Assertions.assertEquals("\\", lang.get("escaped"));
}
@Test
public void unicodeTest() {
Assertions.assertEquals("\u20ac", lang.get("unicode"), "Failed to resolve unicode in lang file");
}
}

View File

@@ -0,0 +1,72 @@
package de.siphalor.was;
import de.siphalor.was.content.product.Product;
import de.siphalor.was.dummy.DummyProduct;
import de.siphalor.was.game.Storage;
import de.siphalor.was.game.StorageSlot;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class StorageTests {
static Storage storage;
static DummyProduct.Type productType;
static Product simpleProduct;
static Product deepProduct;
@BeforeAll
public static void prepareAll() {
storage = new Storage(3, 3, 3);
productType = new DummyProduct.Type("dummy", "one", "two");
simpleProduct = productType.getProduct(new String[]{"simple", "a"});
deepProduct = productType.getProduct(new String[]{"deep", "wood"});
}
@BeforeEach
public void prepare() {
storage.clear();
}
@Test
public void illegalConstructorTest() {
Assertions.assertThrows(IllegalArgumentException.class, () -> new Storage(0, 1, 2), "Illegal storage constructed");
Assertions.assertThrows(IllegalArgumentException.class, () -> new Storage(1, 0, 2), "Illegal storage constructed");
Assertions.assertThrows(IllegalArgumentException.class, () -> new Storage(1, 1, 0), "Illegal storage constructed");
}
@Test
public void clearTest() {
for (int x = 0; x < storage.getWidth(); x++) {
for (int y = 0; y < storage.getHeight(); y++) {
storage.get(x, y).add(productType.getProduct(new String[]{"test", Double.toString(Math.random())}));
}
}
storage.clear();
for (int x = 0; x < storage.getWidth(); x++) {
for (int y = 0; y < storage.getHeight(); y++) {
Assertions.assertNull(storage.get(x, y).front(), "Failed to clear storage");
}
}
}
@Test
public void depthTest() {
StorageSlot slot = storage.get(0, 0);
Assertions.assertEquals(0, slot.add(simpleProduct));
Assertions.assertEquals(1, slot.add(simpleProduct));
Assertions.assertEquals(2, slot.add(simpleProduct));
Assertions.assertEquals(-1, slot.add(simpleProduct), "Can add more products to storage than allowed");
slot.clear();
Assertions.assertEquals(0, slot.add(deepProduct));
Assertions.assertEquals(-1, slot.add(simpleProduct), "Can add more depth to storage than allowed");
slot.clear();
Assertions.assertEquals(0, slot.add(simpleProduct));
Assertions.assertEquals(-1, slot.add(deepProduct), "Can add more depth to storage than allowed");
}
}

View File

@@ -0,0 +1,36 @@
package de.siphalor.was.dummy;
import de.siphalor.was.content.pack.ContentPack;
import de.siphalor.was.content.resource.Resource;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class DummyContentPack implements ContentPack {
public final String id;
public final Map<String, String> content = new HashMap<>();
public DummyContentPack(String id) {
this.id = id;
}
@Override
public @NotNull Stream<Resource> getResources(@NotNull String location, @NotNull String type) {
return content.entrySet().stream().filter(e -> e.getKey().startsWith(location) && e.getKey().endsWith(type)).map(e -> new DummyResource(e.getKey(), e.getValue()));
}
@Override
public @Nullable Resource getResource(@NotNull String location) {
if (content.containsKey(location))
return new DummyResource(location, content.get(location));
return null;
}
@Override
public @NotNull String getId() {
return id;
}
}

View File

@@ -0,0 +1,94 @@
package de.siphalor.was.dummy;
import de.siphalor.was.content.product.Product;
import de.siphalor.was.content.product.ProductType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Random;
import java.util.function.Predicate;
public class DummyProduct implements Product {
public final Type type;
public final Predicate<Integer> yPredicate;
public final int depth;
public final String[] properties;
public DummyProduct(Type type, Predicate<Integer> yPredicate, int depth, String[] properties) {
this.type = type;
this.yPredicate = yPredicate;
this.depth = depth;
this.properties = properties;
}
@Override
public @NotNull String getPropertySpecifier() {
return String.join(", ", properties);
}
@Override
public String[] getProperties() {
return properties;
}
@Override
public int getDepth() {
return depth;
}
@Override
public boolean testY(int y) {
if (yPredicate != null)
return yPredicate.test(y);
return true;
}
@Override
public @NotNull ProductType<?> getType() {
return type;
}
@Override
public boolean equals(Product product) {
return product.getType() == getType() && product.getPropertySpecifier().equals(getPropertySpecifier());
}
public static class Type implements ProductType<DummyProduct> {
public final String id;
public final String[] properties;
public Type(String id, String... properties) {
this.id = id;
this.properties = properties;
}
@NotNull
@Override
public DummyProduct getProduct(@NotNull String[] values) {
Predicate<Integer> yPredicate = null;
int depth = 1;
if (Arrays.binarySearch(values, "deep") >= 0) {
depth = 3;
} else if (Arrays.binarySearch(values, "heavy") >= 0) {
yPredicate = y -> y == 0;
}
return new DummyProduct(this, yPredicate, depth, values);
}
@Override
public @NotNull String getId() {
return id;
}
@Override
public @NotNull String[] getProperties() {
return properties;
}
@Override
public @NotNull Product randomProduct(Random random) {
return null;
}
}
}

View File

@@ -0,0 +1,22 @@
package de.siphalor.was.dummy;
import de.siphalor.was.content.resource.Resource;
import org.jetbrains.annotations.Nullable;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
public class DummyResource extends Resource {
public final String value;
protected DummyResource(String id, String value) {
super(id);
this.value = value;
}
@Override
public @Nullable InputStream getInputStream() {
return new ByteArrayInputStream(value.getBytes(StandardCharsets.UTF_8));
}
}

View File

@@ -0,0 +1,49 @@
package de.siphalor.was.dummy;
import de.siphalor.was.WhatAStorage;
import de.siphalor.was.content.product.Product;
import de.siphalor.was.content.quest.Quest;
import de.siphalor.was.game.Balance;
import de.siphalor.was.visual.Visual;
public class DummyVisual implements Visual {
@Override
public void setup(WhatAStorage whatAStorage) {
}
@Override
public void run() {
}
@Override
public void onScheduleStop() {
}
@Override
public void onBalanceChanged(int budget, Balance.Transaction transaction, int change, 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) {
}
}