Skip to content

Commit

Permalink
feat: Inventory improvements (#84)
Browse files Browse the repository at this point in the history
* feat: Reading and showing descriptions of collected objects

* docs: Add collect action config instructions to docs

* feat: Enable inventory popup background configuration

* fix: Close popup when mainStage is closed

* fix: Fix action configuration docs
  • Loading branch information
mhawryluk authored Jun 5, 2022
1 parent fea281c commit 9191c50
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"onLeftClick": {
"tag": "dialogue-action",
"type": "collect",
"assetPath": "assets/coin.png"
"assetPath": "assets/key.png",
"description": "A powerful key."
}
}
10 changes: 8 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ As for now we support 5 kinds of actions:
* `location-change`
* `show-description`
* `dialogue`
* `battle`
* `collect`

For each kind configuration differs a bit, because different information is required. Let's take a closer look at the
common part first. Each action consists of following properties
Expand Down Expand Up @@ -206,15 +208,19 @@ Let's look at specific action types:

Aliases: `targetLocation`, `target`
* `show-description`:
* `assetPath` - Path to the image with background for the dialogue window. As any path, it must be eiter absolute or relative to the engine's source root.
* `assetPath` - Path to the image shown in the description popup, presumably depicting the object that the action belongs to. As any path, it must be eiter absolute or relative to the engine's source root.
Aliases: `asset-path`, `asset`.
* `description` - Additional information about the object.
* `dialogue`:
* `statements` - **List** of statements to be said. Right now, **only one statement is supported**, however you must provide it
as a list. Aliases: `text`, `dialogue-statements`, `dialogueStatements`. \\
* `assetPath` - Path to the image with background for the dialogue window. As any path, it must be eiter absolute or relative to the engine's source root.
* `assetPath` - Path to the image displayed in the dialogue popup, presumably depicting the NPC that the action is tied to. As any path, it must be eiter absolute or relative to the engine's source root.
Aliases: `asset-path`, `asset`.
* `battle` -- No props required.
* `collect`:
* `assetPath` - Path to the image that will be shown in a popup after collecting the object, as well as in the Inventory window. As any path, it must be eiter absolute or relative to the engine's source root.
Aliases: `asset-path`, `asset`.
* `description` - Text displayed when the cursor is above the collected item in the Inventory window.

## Condition configuration

Expand Down
7 changes: 3 additions & 4 deletions src/main/java/io/rpg/Initializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@
import io.rpg.util.GameObjectViewFactory;
import io.rpg.view.GameObjectView;
import io.rpg.view.LocationView;
import io.rpg.view.popups.DialoguePopup;
import io.rpg.view.popups.QuestionPopup;
import io.rpg.view.popups.TextImagePopup;
import io.rpg.view.popups.TextPopup;
import io.rpg.view.popups.*;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Iterator;
Expand Down Expand Up @@ -63,6 +61,7 @@ public Result<Game, Exception> initialize() {
TextImagePopup.setButtonPath(gameWorldConfig.getTextImagePopupButton());
DialoguePopup.setBackgroundPath(gameWorldConfig.getDialoguePopupBackground());
DialoguePopup.setNpcFramePath(gameWorldConfig.getNpcFrame());
InventoryPopup.setBackgroundPath(gameWorldConfig.getInventoryPopupBackground());

Controller.Builder controllerBuilder = new Controller.Builder();

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/rpg/config/ConfigLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ private Result<Void, Exception> loadGameObjectsForLocation(LocationConfig locati
return Result.err(new Exception("Validation for game object config with tag: " + gameObjectConfig.getTag()
+ " failed."));
} else {
logger.info("Loaded GameObjectConfig for tag: " + gameObjectConfig.getTag() + ":" + gameObjectConfig);
logger.info("Loaded GameObjectConfig for tag: " + gameObjectConfig.getTag());
}
}

Expand Down Expand Up @@ -272,7 +272,7 @@ Result<GameWorldConfig, Exception> loadRootFile() {
return Result.err(exception);
}

// after loading a object from JSON we should always call the validate method
// after loading an object from JSON we should always call the validate method
// load information from configuration root file
GameWorldConfig gameWorldConfigShell = gson.fromJson(reader, GameWorldConfig.class);

Expand Down
13 changes: 12 additions & 1 deletion src/main/java/io/rpg/config/model/ActionConfigBundle.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public class ActionConfigBundle implements ConfigWithValidation {
/**
* {@link io.rpg.model.actions.GameEndAction} <br>
* {@link io.rpg.model.actions.ShowDescriptionAction} <br>
* {@link io.rpg.model.actions.CollectAction} <br>
* TODO
*/
@Nullable
Expand Down Expand Up @@ -265,7 +266,16 @@ Result<Void, Exception> validateForBattle() {
}

Result<Void, Exception> validateForCollectAction() {
return Result.ok();
ErrorMessageBuilder builder = new ErrorMessageBuilder();
if (description == null) {
builder.append("No description provided");
}
if (assetPath == null) {
builder.append("No asset path provided");
} else if (!Files.isRegularFile(Path.of(assetPath))) {
builder.append("Provided asset path does not point to a regular file");
}
return builder.isEmpty() ? Result.ok() : Result.err(new IllegalStateException(builder.toString()));
}

Result<Void, Exception> validateBasic() {
Expand Down Expand Up @@ -324,6 +334,7 @@ public Result<Void, Exception> validate() {
case Quiz -> { return validateForQuizAction(); }
case ShowDescription -> { return validateForShowDescriptionAction(); }
case Battle -> { return validateForBattle(); }
case Collect -> { return validateForCollectAction(); }
default -> { return Result.err(new RuntimeException("Invalid result returned")); }
}
}
Expand Down
13 changes: 3 additions & 10 deletions src/main/java/io/rpg/controller/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,20 @@
import io.rpg.model.data.MouseClickedEvent;
import io.rpg.model.data.Position;
import io.rpg.model.location.LocationModel;
import io.rpg.model.object.CollectibleGameObject;
import io.rpg.model.object.GameObject;
import io.rpg.model.object.Player;
import io.rpg.model.object.Question;
import io.rpg.util.BattleResult;
import io.rpg.view.GameEndView;
import io.rpg.view.GameObjectView;
import io.rpg.view.InventoryPopup;
import io.rpg.view.LocationView;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import io.rpg.view.popups.TextPopup;
import javafx.stage.WindowEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.List;

Expand Down Expand Up @@ -84,6 +75,8 @@ public void setMainStage(Stage mainStage) {
player.setRightPressed(false);
}
});

mainStage.getScene().getWindow().addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST, (event) -> popupController.hidePopup());
}

public void setCurrentModel(@NotNull LocationModel model) {
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/io/rpg/controller/PopupController.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
import io.rpg.view.popups.DialoguePopup;
import io.rpg.view.popups.QuestionPopup;
import io.rpg.model.data.Inventory;
import io.rpg.view.InventoryPopup;
import io.rpg.view.popups.InventoryPopup;
import io.rpg.view.popups.TextImagePopup;
import io.rpg.view.popups.TextPopup;
import javafx.event.EventHandler;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/io/rpg/model/actions/ActionEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import io.rpg.model.object.GameObject;
import io.rpg.model.object.Player;
import io.rpg.util.BattleResult;
import io.rpg.view.GameObjectView;
import io.rpg.view.InventoryGameObjectView;
import io.rpg.view.LocationView;
import javafx.application.Platform;
import javafx.scene.image.Image;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -124,10 +124,10 @@ public void onAction(BattleAction action) {
public void onAction(CollectAction action) {
actionGuard(action, () -> {
var controller = controller();
controller.getPopupController().openTextImagePopup("Picked up an item!", new Image("file:" + action.getAssetPath()),
controller.getPopupController().openTextImagePopup("Picked up an item!", new Image(GameObjectView.resolvePathToJFXFormat(action.getAssetPath())),
controller.getWindowCenterX(), controller.getWindowCenterY());
controller.getPlayerController().getPlayer().getInventory()
.add(new InventoryGameObjectView(action.getOwner(), action.getAssetPath()));
.add(new InventoryGameObjectView(action.getAssetPath(), action.getDescription()));
controller.removeObjectFromModel(action.getOwner());
});
}
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/io/rpg/model/actions/CollectAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

public class CollectAction extends BaseAction {
private final String assetPath;
private final String description;

public CollectAction(String assetPath, @Nullable Condition condition) {
public CollectAction(String assetPath, String description, @Nullable Condition condition) {
super(condition);
this.assetPath = assetPath;
this.description = description;
}

public GameObject getOwner() {
Expand All @@ -24,5 +26,9 @@ public void acceptActionEngine(ActionEngine engine) {
public String getAssetPath() {
return assetPath;
}

public String getDescription() {
return description;
}
}

8 changes: 2 additions & 6 deletions src/main/java/io/rpg/util/ActionFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import io.rpg.config.model.ActionConfigBundle;
import io.rpg.model.actions.*;
import io.rpg.model.actions.condition.ConditionFactory;
import io.rpg.model.object.Question;
import javafx.scene.image.Image;

public class ActionFactory {
Expand Down Expand Up @@ -49,11 +48,8 @@ private static Action actionByType(ActionConfigBundle config) {
case Collect -> {
return collectActionFromConfig(config);
}
default -> {
throw new IllegalArgumentException("Unexpected action type!");
}
default -> throw new IllegalArgumentException("Unexpected action type!");
}

}

private static QuizAction quizActionFromConfig(ActionConfigBundle config) {
Expand Down Expand Up @@ -97,6 +93,6 @@ private static void initBeforeAndAfterActions(Action action, ActionConfigBundle
}

private static CollectAction collectActionFromConfig(ActionConfigBundle config) {
return new CollectAction(config.getAssetPath(), ConditionFactory.fromConfig(config.getCondition()));
return new CollectAction(config.getAssetPath(), config.getDescription(), ConditionFactory.fromConfig(config.getCondition()));
}
}
9 changes: 5 additions & 4 deletions src/main/java/io/rpg/view/InventoryGameObjectView.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package io.rpg.view;

import io.rpg.model.object.GameObject;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

public class InventoryGameObjectView extends ImageView {
GameObject collectibleGameObject;

public InventoryGameObjectView(GameObject collectibleGameObject, String assetPath) {
this.collectibleGameObject = collectibleGameObject;
public final String description;

public InventoryGameObjectView(String assetPath, String description) {
Image image = new Image(GameObjectView.resolvePathToJFXFormat(assetPath));
setImage(image);

this.description = description;
}
}
97 changes: 0 additions & 97 deletions src/main/java/io/rpg/view/InventoryPopup.java

This file was deleted.

Loading

0 comments on commit 9191c50

Please sign in to comment.