From 249452b5143f9a8876c9a959f500a8328cdc95e0 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sun, 18 Feb 2024 01:00:46 -0600 Subject: [PATCH 01/34] Expanded image pulling and now excludes pulling from previous story. --- .../me/piitex/renjava/api/player/Player.java | 8 +++++--- .../me/piitex/renjava/api/scenes/RenScene.java | 1 + .../renjava/api/scenes/types/ImageScene.java | 11 ++++++++--- .../me/piitex/renjava/api/stories/Story.java | 8 +++----- src/main/java/me/piitex/renjava/gui/Menu.java | 17 ++++++++++------- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/player/Player.java b/src/main/java/me/piitex/renjava/api/player/Player.java index 488f262..829e262 100644 --- a/src/main/java/me/piitex/renjava/api/player/Player.java +++ b/src/main/java/me/piitex/renjava/api/player/Player.java @@ -19,7 +19,9 @@ public class Player implements PersistentData { private boolean rightClickMenu; @Data private String currentScene; @Data private String currentStory; - private ImageLoader lastDisplayedImage; + + // Entry to map the story for the image + private Map.Entry lastDisplayedImage; private boolean transitionPlaying = false; private boolean uiToggled = true; @@ -93,11 +95,11 @@ public void setRightClickMenu(boolean rightClickMenu) { this.rightClickMenu = rightClickMenu; } - public ImageLoader getLastDisplayedImage() { + public Map.Entry getLastDisplayedImage() { return lastDisplayedImage; } - public void setLastDisplayedImage(ImageLoader lastDisplayedImage) { + public void setLastDisplayedImage(Map.Entry lastDisplayedImage) { this.lastDisplayedImage = lastDisplayedImage; } diff --git a/src/main/java/me/piitex/renjava/api/scenes/RenScene.java b/src/main/java/me/piitex/renjava/api/scenes/RenScene.java index 994c877..6841a19 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/RenScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/RenScene.java @@ -68,6 +68,7 @@ public abstract class RenScene extends Container { public RenScene(String id, ImageLoader backgroundImage) { this.id = id; this.backgroundImage = backgroundImage; + setStory(RenJava.getInstance().getPlayer().getCurrentStory()); // Update the current story. } public RenScene onStart(SceneStartInterface sceneInterface) { diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java index e4a78ae..c3a49d3 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java @@ -27,6 +27,7 @@ import java.io.File; import java.net.MalformedURLException; +import java.util.AbstractMap; import java.util.LinkedList; @@ -58,7 +59,7 @@ public class ImageScene extends RenScene { private Character character; private String dialogue; - private final ImageLoader backgroundImage; + private ImageLoader backgroundImage; private String characterDisplayName; @@ -81,10 +82,14 @@ public ImageScene(String id, @Nullable Character character, String dialogue, @Nu this.character = character; this.dialogue = dialogue; if (loader == null) { - backgroundImage = renJava.getPlayer().getLastDisplayedImage(); + // Only use last if the story is the same as the last story + if (renJava.getPlayer().getLastDisplayedImage().getKey().equalsIgnoreCase(getStory().getId())) { + backgroundImage = renJava.getPlayer().getLastDisplayedImage().getValue(); + } } else { this.backgroundImage = loader; - renJava.getPlayer().setLastDisplayedImage(backgroundImage); + renJava.getLogger().info("Story: " + getStory().getId()); + renJava.getPlayer().setLastDisplayedImage(new AbstractMap.SimpleEntry<>(getStory().getId(), loader)); } if (character != null) { this.characterDisplayName = character.getDisplayName(); diff --git a/src/main/java/me/piitex/renjava/api/stories/Story.java b/src/main/java/me/piitex/renjava/api/stories/Story.java index 934aac1..f8e3853 100644 --- a/src/main/java/me/piitex/renjava/api/stories/Story.java +++ b/src/main/java/me/piitex/renjava/api/stories/Story.java @@ -112,6 +112,9 @@ public String getId() { */ public void start() { + // Update RenJava Player BEFORE the scenes are added + renJava.getPlayer().setCurrentStory(this.getId()); + init(); // Initialize when starting logger.info("Building scene..."); @@ -125,9 +128,6 @@ public void start() { RenJava.callEvent(buildEvent); renScene.render(menu); - - // Update RenJava Player - renJava.getPlayer().setCurrentStory(this.getId()); } /** @@ -166,7 +166,6 @@ public void addScene(RenScene scene) { int index = sceneIndexMap.size(); sceneIndexMap.put(index, scene); scene.setIndex(index); - scene.setStory(this); // Updates the scene data. } /** @@ -179,7 +178,6 @@ public void addScenes(RenScene... scenes) { int index = sceneIndexMap.size(); sceneIndexMap.put(index, renScene); renScene.setIndex(index); - renScene.setStory(this); } } diff --git a/src/main/java/me/piitex/renjava/gui/Menu.java b/src/main/java/me/piitex/renjava/gui/Menu.java index ebda313..3e9c744 100644 --- a/src/main/java/me/piitex/renjava/gui/Menu.java +++ b/src/main/java/me/piitex/renjava/gui/Menu.java @@ -54,10 +54,12 @@ public Menu(double width, double height) { } public Menu(double width, double height, ImageLoader imageLoader) { - try { - this.backgroundImage = imageLoader.build(); - } catch (ImageNotFoundException e) { - e.printStackTrace(); + if (imageLoader != null) { + try { + this.backgroundImage = imageLoader.build(); + } catch (ImageNotFoundException e) { + e.printStackTrace(); + } } this.width = width; this.height = height; @@ -169,9 +171,10 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { root.setTranslateX(x); root.setTranslateY(y); - Element backgroundImgElement = new Element(new ImageOverlay(backgroundImage, 0, 0)); - - backgroundImgElement.render(root); + if (backgroundImage != null) { + Element backgroundImgElement = new Element(new ImageOverlay(backgroundImage, 0, 0)); + backgroundImgElement.render(root); + } logger.info("Rendering layouts..."); for (Layout layout : layouts) { From 5c3a173d4d61b623d659460a3200eecd390f3160 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sun, 18 Feb 2024 06:21:33 -0600 Subject: [PATCH 02/34] Scenes will now render the textbox when the background image does not exist. --- .../piitex/renjava/api/scenes/RenScene.java | 6 +- .../renjava/api/scenes/types/ImageScene.java | 76 +++++++++---------- .../api/scenes/types/choices/ChoiceScene.java | 13 +++- .../java/me/piitex/renjava/gui/Element.java | 1 + src/main/java/me/piitex/renjava/gui/Menu.java | 16 ++-- .../renjava/gui/overlay/ImageOverlay.java | 7 ++ 6 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/scenes/RenScene.java b/src/main/java/me/piitex/renjava/api/scenes/RenScene.java index 6841a19..154a818 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/RenScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/RenScene.java @@ -47,7 +47,7 @@ */ public abstract class RenScene extends Container { private final String id; - private final ImageLoader backgroundImage; + private ImageLoader backgroundImage; private Story story; private int index; private SceneStartInterface startInterface; @@ -121,6 +121,10 @@ public ImageLoader getBackgroundImage() { return backgroundImage; } + public void setBackgroundImage(ImageLoader backgroundImage) { + this.backgroundImage = backgroundImage; + } + public SceneStartInterface getStartInterface() { return startInterface; } diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java index c3a49d3..c677d39 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java @@ -81,12 +81,7 @@ public ImageScene(String id, @Nullable Character character, String dialogue, @Nu super(id, loader); this.character = character; this.dialogue = dialogue; - if (loader == null) { - // Only use last if the story is the same as the last story - if (renJava.getPlayer().getLastDisplayedImage().getKey().equalsIgnoreCase(getStory().getId())) { - backgroundImage = renJava.getPlayer().getLastDisplayedImage().getValue(); - } - } else { + if (loader != null) { this.backgroundImage = loader; renJava.getLogger().info("Story: " + getStory().getId()); renJava.getPlayer().setLastDisplayedImage(new AbstractMap.SimpleEntry<>(getStory().getId(), loader)); @@ -97,6 +92,15 @@ public ImageScene(String id, @Nullable Character character, String dialogue, @Nu configuration = renJava.getConfiguration(); } + public ImageScene(String id, @Nullable Character character, String dialogue) { + super(id, null); + this.character = character; + this.dialogue = dialogue; + backgroundImage = renJava.getPlayer().getLastDisplayedImage().getValue(); + setBackgroundImage(backgroundImage); + configuration = renJava.getConfiguration(); + } + public Character getCharacter() { return character; } @@ -130,44 +134,34 @@ public Menu build(boolean ui) { } if (dialogue != null && !dialogue.isEmpty()) { - Image textbox = null; - try { - textbox = new ImageLoader("gui/textbox.png").build(); - } catch (ImageNotFoundException e) { - renJava.getLogger().severe(e.getMessage()); - } finally { - if (textbox != null) { - Menu textboxMenu = new Menu(configuration.getWidth(), configuration.getHeight() - textbox.getHeight()); - - try { - ImageOverlay textBoxImage = new ImageOverlay(new ImageLoader("gui/textbox.png").build(), configuration.getDialogueBoxX() + configuration.getDialogueOffsetX(), configuration.getDialogueBoxY() + configuration.getDialogueOffsetY()); - textboxMenu.addOverlay(textBoxImage); - } catch (ImageNotFoundException e) { - renJava.getLogger().severe(e.getMessage()); - } - - LinkedList texts = StringFormatter.formatText(dialogue); - TextFlowBuilder textFlowBuilder; - if (texts.isEmpty()) { - Text text = new Text(dialogue); - text.setFont(renJava.getConfiguration().getDialogueFont().getFont()); - textFlowBuilder = new TextFlowBuilder(text, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); - } else { - textFlowBuilder = new TextFlowBuilder(texts, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); - } - textboxMenu.addOverlay(new TextFlowOverlay(textFlowBuilder, configuration.getTextX() + configuration.getTextOffsetX(), configuration.getTextY() + configuration.getTextOffsetY())); - - characterDisplay.setFont(new FontLoader(renJava.getConfiguration().getDefaultFont().getFont(), configuration.getCharacterTextSize()).getFont()); - characterDisplay.setFill(character.getColor()); - characterDisplay.setX(configuration.getCharacterTextX() + configuration.getCharacterTextOffsetX()); - characterDisplay.setY(configuration.getCharacterTextY() + configuration.getCharacterTextOffsetY()); - - textboxMenu.addOverlay(new TextOverlay(characterDisplay, characterDisplay.getX(), characterDisplay.getY())); - rootMenu.addMenu(textboxMenu); - } + ImageLoader textbox = new ImageLoader("gui/textbox.png"); + Menu textboxMenu = new Menu(configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); + + ImageOverlay textBoxImage = new ImageOverlay(textbox, configuration.getDialogueBoxX() + configuration.getDialogueOffsetX(), configuration.getDialogueBoxY() + configuration.getDialogueOffsetY()); + textboxMenu.addOverlay(textBoxImage); + + LinkedList texts = StringFormatter.formatText(dialogue); + TextFlowBuilder textFlowBuilder; + if (texts.isEmpty()) { + Text text = new Text(dialogue); + text.setFont(renJava.getConfiguration().getDialogueFont().getFont()); + textFlowBuilder = new TextFlowBuilder(text, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); + } else { + textFlowBuilder = new TextFlowBuilder(texts, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); } + textboxMenu.addOverlay(new TextFlowOverlay(textFlowBuilder, configuration.getTextX() + configuration.getTextOffsetX(), configuration.getTextY() + configuration.getTextOffsetY())); + + characterDisplay.setFont(new FontLoader(renJava.getConfiguration().getDefaultFont().getFont(), configuration.getCharacterTextSize()).getFont()); + characterDisplay.setFill(character.getColor()); + characterDisplay.setX(configuration.getCharacterTextX() + configuration.getCharacterTextOffsetX()); + characterDisplay.setY(configuration.getCharacterTextY() + configuration.getCharacterTextOffsetY()); + + textboxMenu.addOverlay(new TextOverlay(characterDisplay, characterDisplay.getX(), characterDisplay.getY())); + rootMenu.addMenu(textboxMenu); } } + + for (File file : getStyleSheets()) { try { RenJava.getInstance().getStage().getScene().getStylesheets().add(file.toURI().toURL().toExternalForm()); diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java index 90e8a2f..0f86372 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java @@ -62,7 +62,7 @@ * @see ChoiceSelectInterface */ public class ChoiceScene extends RenScene { - private final ImageLoader backgroundImage; + private ImageLoader backgroundImage; private ChoiceSelectInterface selectInterface; @@ -84,6 +84,17 @@ public ChoiceScene(String id, ImageLoader backgroundImage) { this.backgroundImage = backgroundImage; } + /** + * Creates a ChoiceScene object with the specified identifier. + * + * @param id The unique identifier for the scene. + */ + public ChoiceScene(String id) { + super(id, null); + this.backgroundImage = RenJava.getInstance().getPlayer().getLastDisplayedImage().getValue(); + setBackgroundImage(backgroundImage); + } + public ChoiceScene addChoice(Choice choice) { choices.add(choice); return this; diff --git a/src/main/java/me/piitex/renjava/gui/Element.java b/src/main/java/me/piitex/renjava/gui/Element.java index ea14d90..529ec43 100644 --- a/src/main/java/me/piitex/renjava/gui/Element.java +++ b/src/main/java/me/piitex/renjava/gui/Element.java @@ -8,6 +8,7 @@ import javafx.scene.layout.Pane; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; +import me.piitex.renjava.RenJava; import me.piitex.renjava.api.scenes.transitions.Transitions; import me.piitex.renjava.gui.overlay.*; diff --git a/src/main/java/me/piitex/renjava/gui/Menu.java b/src/main/java/me/piitex/renjava/gui/Menu.java index 3e9c744..86df2aa 100644 --- a/src/main/java/me/piitex/renjava/gui/Menu.java +++ b/src/main/java/me/piitex/renjava/gui/Menu.java @@ -171,11 +171,19 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { root.setTranslateX(x); root.setTranslateY(y); + // Background fill is used for fade ins. + BackgroundFill backgroundFill = new BackgroundFill(BLACK, new CornerRadii(1), new Insets(0,0,0,0)); + root.setBackground(new Background(backgroundFill)); + if (backgroundImage != null) { Element backgroundImgElement = new Element(new ImageOverlay(backgroundImage, 0, 0)); backgroundImgElement.render(root); } + for (Overlay overlay : overlays) { + new Element(overlay).render(root); + } + logger.info("Rendering layouts..."); for (Layout layout : layouts) { for (Overlay overlay : layout.getOverlays()) { @@ -195,20 +203,12 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { root.getChildren().add(box); } - for (Overlay overlay : overlays) { - new Element(overlay).render(root); - } - for (Menu menu : children) { menu.render(root, renScene); // Renders menu on top of this menu. } rootMenu = this; - // Background fill is used for fade ins. - BackgroundFill backgroundFill = new BackgroundFill(BLACK, new CornerRadii(1), new Insets(0,0,0,0)); - root.setBackground(new Background(backgroundFill)); - Scene scene; if (stage.getScene() != null) { scene = stage.getScene(); diff --git a/src/main/java/me/piitex/renjava/gui/overlay/ImageOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/ImageOverlay.java index 6fc093d..4e8584b 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/ImageOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/ImageOverlay.java @@ -10,6 +10,7 @@ public class ImageOverlay implements Overlay { private final Image image; private double x; private double y; + private final String fileName; private Transitions transitions; @@ -17,11 +18,13 @@ public ImageOverlay(Image image, int x, int y) { this.image = image; this.x = x; this.y = y; + this.fileName = "Unknown"; } public ImageOverlay(ImageLoader imageLoader, double x, double y) { try { this.image = imageLoader.build(); + this.fileName = imageLoader.getFile().getName(); } catch (ImageNotFoundException e) { RenJava.getInstance().getLogger().severe(e.getMessage()); throw new RuntimeException(); @@ -34,6 +37,10 @@ public Image getImage() { return image; } + public String getFileName() { + return fileName; + } + @Override public double x() { return x; From cbc56304a4a0cbcc50c68776d3b4198173ea8077 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sun, 18 Feb 2024 08:04:57 -0600 Subject: [PATCH 03/34] Removed redundant ButtonBuilder and merged it with ButtonOverlay. --- src/main/java/me/piitex/renjava/RenJava.java | 9 +- .../renjava/api/builders/ButtonBuilder.java | 248 ------------------ .../api/scenes/types/choices/Choice.java | 8 +- .../api/scenes/types/choices/ChoiceScene.java | 5 +- .../renjava/gui/overlay/ButtonOverlay.java | 242 ++++++++++++++++- 5 files changed, 249 insertions(+), 263 deletions(-) delete mode 100644 src/main/java/me/piitex/renjava/api/builders/ButtonBuilder.java diff --git a/src/main/java/me/piitex/renjava/RenJava.java b/src/main/java/me/piitex/renjava/RenJava.java index aa8ad1b..606a89c 100644 --- a/src/main/java/me/piitex/renjava/RenJava.java +++ b/src/main/java/me/piitex/renjava/RenJava.java @@ -8,7 +8,6 @@ import javafx.stage.StageStyle; import me.piitex.renjava.addons.Addon; import me.piitex.renjava.addons.AddonLoader; -import me.piitex.renjava.api.builders.ButtonBuilder; import me.piitex.renjava.api.builders.ImageLoader; import me.piitex.renjava.api.music.Tracks; import me.piitex.renjava.api.saves.data.Data; @@ -399,10 +398,10 @@ public Menu buildSideMenu() { Font uiFont = RenJava.getInstance().getConfiguration().getUiFont().getFont(); - ButtonOverlay startButton = new ButtonOverlay(new ButtonBuilder("menu-start-button", "Start", uiFont, Color.BLACK, 1, 1)); - ButtonOverlay loadButton = new ButtonOverlay(new ButtonBuilder("menu-load-button", "Load", uiFont, Color.BLACK, 1, 1)); - ButtonOverlay optionsButton = new ButtonOverlay(new ButtonBuilder("menu-preference-button", "Preferences", uiFont, Color.BLACK, 1, 1)); - ButtonOverlay aboutButton = new ButtonOverlay(new ButtonBuilder("menu-about-button", "About", uiFont, Color.BLACK, 1, 1)); + ButtonOverlay startButton = new ButtonOverlay("menu-start-button", "Start", uiFont, Color.BLACK, 1, 1); + ButtonOverlay loadButton = new ButtonOverlay("menu-load-button", "Load", uiFont, Color.BLACK, 1, 1); + ButtonOverlay optionsButton = new ButtonOverlay("menu-preference-button", "Preferences", uiFont, Color.BLACK, 1, 1); + ButtonOverlay aboutButton = new ButtonOverlay("menu-about-button", "About", uiFont, Color.BLACK, 1, 1); // Create vbox for the buttons. You can also do an HBox VerticalLayout layout = new VerticalLayout(200, 500); diff --git a/src/main/java/me/piitex/renjava/api/builders/ButtonBuilder.java b/src/main/java/me/piitex/renjava/api/builders/ButtonBuilder.java deleted file mode 100644 index db1f2e2..0000000 --- a/src/main/java/me/piitex/renjava/api/builders/ButtonBuilder.java +++ /dev/null @@ -1,248 +0,0 @@ -package me.piitex.renjava.api.builders; - -import javafx.scene.control.Button; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.paint.Color; -import javafx.scene.text.Font; -import me.piitex.renjava.RenJava; -import me.piitex.renjava.events.types.ButtonClickEvent; -import me.piitex.renjava.gui.exceptions.ImageNotFoundException; - -public class ButtonBuilder { - private final String id; - private String text; - private Font font; - private Image image; - private Color color; - - private double x = 1, y = 1; - private final double xScale, yScale; - - public ButtonBuilder(String id, String text, Color color, double xScale, double yScale) { - this.id = id; - this.text = text; - this.color = color; - this.xScale = x; - this.yScale = y; - } - - public ButtonBuilder(String id, String text, Color color, Font font, double xScale, double yScale) { - this.id = id; - this.text = text; - this.color = color; - this.font = font; - this.xScale = x; - this.yScale = y; - } - - /** - * Create a button with only text. - * - * @param id Identifier for the button. - * @param text Text that will be displayed inside the button. - * @param color Color of the text. - * @param x X-Axis position of the button. - * @param y Y-Axis position of the button. - * @param xScale X-Axis scale of the button. - * @param yScale Y-Axis scale of the button. - */ - public ButtonBuilder(String id, String text, Color color, double x, double y, double xScale, double yScale) { - this.id = id; - this.text = text; - this.color = color; - this.x = x; - this.y = y; - this.xScale = xScale; - this.yScale = yScale; - } - - /** - * Create a button with only text with a specific font. - * - * @param id Identifier for the button. - * @param text Text that will be displayed inside the button. - * @param font Font to be used for the text. - * @param color Color of the text. - * @param x X-Axis position of the button. - * @param y Y-Axis position of the button. - * @param xScale X-Axis scale of the button. - * @param yScale Y-Axis scale of the button. - */ - public ButtonBuilder(String id, String text, Font font, Color color, double x, double y, double xScale, double yScale) { - this.id = id; - this.text = text; - this.font = font; - this.color = color; - this.x = x; - this.y = y; - this.xScale = xScale; - this.yScale = yScale; - } - - /** - * Create a button with only text with a specific font. - * - * @param id Identifier for the button. - * @param text Text that will be displayed inside the button. - * @param font Font to be used for the text. - * @param color Color of the text. - * @param xScale X-Axis scale of the button. - * @param yScale Y-Axis scale of the button. - */ - public ButtonBuilder(String id, String text, Font font, Color color, double xScale, double yScale) { - this.id = id; - this.text = text; - this.font = font; - this.color = color; - this.xScale = xScale; - this.yScale = yScale; - } - - /** - * Create a button with only an image. - * - * @param id Identifier for the button. - * @param imageLoader Image to be displayed inside the button. - * @param x X-Axis position of the button. - * @param y Y-Axis position of the button. - * @param xScale X-Axis scale of the button. - * @param yScale Y-Axis scale of the button. - */ - public ButtonBuilder(String id, ImageLoader imageLoader, double x, double y, double xScale, double yScale) { - this.id = id; - try { - this.image = imageLoader.build(); - } catch (ImageNotFoundException e) { - throw new RuntimeException(e); - } - this.x = x; - this.y = y; - this.xScale = xScale; - this.yScale = yScale; - } - - /** - * Create a button with image and text - * - * @param id Identifier for the button. - * @param imageLoader Image to be displayed inside the button. - * @param text Text to be displayed inside the button. - * @param x X-Axis position of the button. - * @param y Y-Axis position of the button. - * @param xScale X-Axis scale of the button. - * @param yScale Y-Axis scale of the button. - */ - public ButtonBuilder(String id, ImageLoader imageLoader, String text, double x, double y, double xScale, double yScale) { - this.id = id; - try { - this.image = imageLoader.build(); - } catch (ImageNotFoundException e) { - throw new RuntimeException(e); - } - this.text = text; - this.x = x; - this.y = y; - this.xScale = xScale; - this.yScale = yScale; - } - - public String getId() { - return id; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public Font getFont() { - return font; - } - - public void setFont(Font font) { - this.font = font; - } - - public Image getImage() { - return image; - } - - public void setImage(Image image) { - this.image = image; - } - - public Color getColor() { - return color; - } - - public void setColor(Color color) { - this.color = color; - } - - public double getX() { - return x; - } - - public void setX(double x) { - this.x = x; - } - - public double getY() { - return y; - } - - public void setY(int y) { - this.y = y; - } - - public double getXScale() { - return xScale; - } - - public double getYScale() { - return yScale; - } - - public Button build() { - Button button = new Button(); - button.setId(id); - if (image != null) { - ImageView imageView = new ImageView(image); - button.setGraphic(imageView); - } - if (text != null && !text.isEmpty()) { - button.setText(text); - } - if (font != null) { - button.setFont(font); - } else { - // Set default font - button.setFont(RenJava.getInstance().getConfiguration().getUiFont().getFont()); - } - if (color != null) { - button.setTextFill(color); - } - if (x != 0 && y != 0) { - button.setTranslateX(x); - button.setTranslateY(y); - } - button.setScaleX(xScale); - button.setScaleY(yScale); - - button.setOnAction(actionEvent -> { - ButtonClickEvent event = new ButtonClickEvent(RenJava.getInstance().getPlayer().getCurrentScene(), button); - RenJava.callEvent(event); - }); - return button; - } - - public static ButtonBuilder copyOf(String id, ButtonBuilder builder) { - ButtonBuilder toReturn = new ButtonBuilder(id, builder.getText(), builder.getFont(), builder.getColor(), builder.getX(), builder.getY(), builder.getXScale(), builder.getYScale()); - toReturn.setImage(builder.getImage()); - return toReturn; - } -} \ No newline at end of file diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/choices/Choice.java b/src/main/java/me/piitex/renjava/api/scenes/types/choices/Choice.java index ab18c6b..1571d37 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/choices/Choice.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/choices/Choice.java @@ -1,6 +1,6 @@ package me.piitex.renjava.api.scenes.types.choices; -import me.piitex.renjava.api.builders.ButtonBuilder; +import me.piitex.renjava.gui.overlay.ButtonOverlay; /** * The Choice class represents a choice in a ChoiceScene within the RenJava framework. @@ -23,7 +23,7 @@ * @see ChoiceScene */ public class Choice { - private ButtonBuilder builder; + private ButtonOverlay buttonOverlay; private final String id; private String text; // This can be final, but maybe someone wants to modify the text in some way? I don't know but that could be cool to see @@ -38,8 +38,8 @@ public Choice(String id, String text) { this.text = text; } - public ButtonBuilder getBuilder() { - return builder; + public ButtonOverlay getBuilder() { + return buttonOverlay; } public String getId() { diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java index 0f86372..d7170cb 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java @@ -11,7 +11,6 @@ import me.piitex.renjava.events.types.SceneStartEvent; import me.piitex.renjava.gui.Menu; import me.piitex.renjava.gui.StageType; -import me.piitex.renjava.api.builders.ButtonBuilder; import me.piitex.renjava.api.builders.ImageLoader; import me.piitex.renjava.gui.exceptions.ImageNotFoundException; import me.piitex.renjava.gui.layouts.impl.VerticalLayout; @@ -179,8 +178,8 @@ public void render(Menu menu) { } private Button getChoiceButton(Choice choice, Image image) { - ButtonBuilder builder = new ButtonBuilder(choice.getId(), choice.getText(), RenJava.getInstance().getConfiguration().getDefaultFont().getFont(), Color.BLACK, 0, 0, 1, 1); - Button button = builder.build(); + ButtonOverlay buttonOverlay = new ButtonOverlay(choice.getId(), choice.getText(), RenJava.getInstance().getConfiguration().getDefaultFont().getFont(), Color.BLACK, 0, 0, 1, 1); + Button button = buttonOverlay.build(); ImageView imageView = new ImageView(image); imageView.setPreserveRatio(true); diff --git a/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java index 56e95bd..54d1357 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java @@ -1,19 +1,205 @@ package me.piitex.renjava.gui.overlay; import javafx.scene.control.Button; -import me.piitex.renjava.api.builders.ButtonBuilder; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.paint.Color; +import javafx.scene.text.Font; +import me.piitex.renjava.RenJava; +import me.piitex.renjava.api.builders.ImageLoader; import me.piitex.renjava.api.scenes.transitions.Transitions; +import me.piitex.renjava.events.types.ButtonClickEvent; +import me.piitex.renjava.gui.exceptions.ImageNotFoundException; public class ButtonOverlay implements Overlay { private final Button button; private Transitions transitions; + private final String id; + private String text; + private Font font; + private Image image; + private Color color; + + private double x = 1, y = 1; + private final double xScale, yScale; + + public ButtonOverlay(String id, String text, Color color, double xScale, double yScale) { + this.id = id; + this.text = text; + this.color = color; + this.xScale = x; + this.yScale = y; + this.button = build(); + } + + public ButtonOverlay(String id, String text, Color color, Font font, double xScale, double yScale) { + this.id = id; + this.text = text; + this.color = color; + this.font = font; + this.xScale = x; + this.yScale = y; + this.button = build(); + } + + /** + * Create a button with only text. + * + * @param id Identifier for the button. + * @param text Text that will be displayed inside the button. + * @param color Color of the text. + * @param x X-Axis position of the button. + * @param y Y-Axis position of the button. + * @param xScale X-Axis scale of the button. + * @param yScale Y-Axis scale of the button. + */ + public ButtonOverlay(String id, String text, Color color, double x, double y, double xScale, double yScale) { + this.id = id; + this.text = text; + this.color = color; + this.x = x; + this.y = y; + this.xScale = xScale; + this.yScale = yScale; + this.button = build(); + } + + /** + * Create a button with only text with a specific font. + * + * @param id Identifier for the button. + * @param text Text that will be displayed inside the button. + * @param font Font to be used for the text. + * @param color Color of the text. + * @param x X-Axis position of the button. + * @param y Y-Axis position of the button. + * @param xScale X-Axis scale of the button. + * @param yScale Y-Axis scale of the button. + */ + public ButtonOverlay(String id, String text, Font font, Color color, double x, double y, double xScale, double yScale) { + this.id = id; + this.text = text; + this.font = font; + this.color = color; + this.x = x; + this.y = y; + this.xScale = xScale; + this.yScale = yScale; + this.button = build(); + } + + /** + * Create a button with only text with a specific font. + * + * @param id Identifier for the button. + * @param text Text that will be displayed inside the button. + * @param font Font to be used for the text. + * @param color Color of the text. + * @param xScale X-Axis scale of the button. + * @param yScale Y-Axis scale of the button. + */ + public ButtonOverlay(String id, String text, Font font, Color color, double xScale, double yScale) { + this.id = id; + this.text = text; + this.font = font; + this.color = color; + this.xScale = xScale; + this.yScale = yScale; + this.button = build(); + } + + /** + * Create a button with only an image. + * + * @param id Identifier for the button. + * @param imageLoader Image to be displayed inside the button. + * @param x X-Axis position of the button. + * @param y Y-Axis position of the button. + * @param xScale X-Axis scale of the button. + * @param yScale Y-Axis scale of the button. + */ + public ButtonOverlay(String id, ImageLoader imageLoader, double x, double y, double xScale, double yScale) { + this.id = id; + try { + this.image = imageLoader.build(); + } catch (ImageNotFoundException e) { + throw new RuntimeException(e); + } + this.x = x; + this.y = y; + this.xScale = xScale; + this.yScale = yScale; + this.button = build(); + } + + /** + * Create a button with image and text + * + * @param id Identifier for the button. + * @param imageLoader Image to be displayed inside the button. + * @param text Text to be displayed inside the button. + * @param x X-Axis position of the button. + * @param y Y-Axis position of the button. + * @param xScale X-Axis scale of the button. + * @param yScale Y-Axis scale of the button. + */ + public ButtonOverlay(String id, ImageLoader imageLoader, String text, double x, double y, double xScale, double yScale) { + this.id = id; + try { + this.image = imageLoader.build(); + } catch (ImageNotFoundException e) { + throw new RuntimeException(e); + } + this.text = text; + this.x = x; + this.y = y; + this.xScale = xScale; + this.yScale = yScale; + this.button = build(); + } + public ButtonOverlay(Button button) { this.button = button; + this.id = button.getId(); + this.xScale = button.getScaleX(); + this.yScale = button.getScaleY(); + } + + public String getId() { + return id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public Font getFont() { + return font; + } + + public void setFont(Font font) { + this.font = font; + } + + public Image getImage() { + return image; + } + + public void setImage(Image image) { + this.image = image; + } + + public Color getColor() { + return color; } - public ButtonOverlay(ButtonBuilder builder) { - this.button = builder.build(); + public void setColor(Color color) { + this.color = color; } @Override @@ -34,8 +220,58 @@ public Transitions getTransition() { public void setTransitions(Transitions transitions) { this.transitions = transitions; } + public void setX(double x) { + this.x = x; + } + + public void setY(int y) { + this.y = y; + } + + public double getXScale() { + return xScale; + } + + public double getYScale() { + return yScale; + } public Button build() { + Button button = new Button(); + button.setId(id); + if (image != null) { + ImageView imageView = new ImageView(image); + button.setGraphic(imageView); + } + if (text != null && !text.isEmpty()) { + button.setText(text); + } + if (font != null) { + button.setFont(font); + } else { + // Set default font + button.setFont(RenJava.getInstance().getConfiguration().getUiFont().getFont()); + } + if (color != null) { + button.setTextFill(color); + } + if (x != 0 && y != 0) { + button.setTranslateX(x); + button.setTranslateY(y); + } + button.setScaleX(xScale); + button.setScaleY(yScale); + + button.setOnAction(actionEvent -> { + ButtonClickEvent event = new ButtonClickEvent(RenJava.getInstance().getPlayer().getCurrentScene(), button); + RenJava.callEvent(event); + }); return button; } + + public static ButtonOverlay copyOf(String id, ButtonOverlay builder) { + ButtonOverlay toReturn = new ButtonOverlay(id, builder.getText(), builder.getFont(), builder.getColor(), builder.x(), builder.y(), builder.getXScale(), builder.getYScale()); + toReturn.setImage(builder.getImage()); + return toReturn; + } } From 68a36357e87605f88df5c6d9bedf09a0c4fbf6a7 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sun, 18 Feb 2024 08:13:32 -0600 Subject: [PATCH 04/34] Removed redundant InputFieldBuilder and TextFlowBuilder and merged it with the corresponding overlay. --- .../api/builders/InputFieldBuilder.java | 37 ----------- .../renjava/api/builders/TextFlowBuilder.java | 53 ---------------- .../renjava/api/scenes/types/ImageScene.java | 19 ++---- .../api/scenes/types/input/InputScene.java | 6 +- .../java/me/piitex/renjava/gui/Element.java | 2 +- .../gui/overlay/InputFieldOverlay.java | 34 ++++++++--- .../renjava/gui/overlay/TextFlowOverlay.java | 61 ++++++++++++++++--- 7 files changed, 86 insertions(+), 126 deletions(-) delete mode 100644 src/main/java/me/piitex/renjava/api/builders/InputFieldBuilder.java delete mode 100644 src/main/java/me/piitex/renjava/api/builders/TextFlowBuilder.java diff --git a/src/main/java/me/piitex/renjava/api/builders/InputFieldBuilder.java b/src/main/java/me/piitex/renjava/api/builders/InputFieldBuilder.java deleted file mode 100644 index d0c8831..0000000 --- a/src/main/java/me/piitex/renjava/api/builders/InputFieldBuilder.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.piitex.renjava.api.builders; - -import javafx.scene.control.TextField; - - -public class InputFieldBuilder { - private final double x; - private final double y; - private final FontLoader fontLoader; - - public InputFieldBuilder(double x, double y, FontLoader fontLoader) { - this.x = x; - this.y = y; - this.fontLoader = fontLoader; - } - - public double getX() { - return x; - } - - public double getY() { - return y; - } - - public FontLoader getFontLoader() { - return fontLoader; - } - - public TextField build() { - TextField textField = new TextField(); - textField.setTranslateX(x); - textField.setTranslateY(y); - textField.setStyle(""); - textField.setStyle("-fx-control-inner-background: transparent; -fx-background-color transparent;"); - return textField; - } -} diff --git a/src/main/java/me/piitex/renjava/api/builders/TextFlowBuilder.java b/src/main/java/me/piitex/renjava/api/builders/TextFlowBuilder.java deleted file mode 100644 index 3a9a97a..0000000 --- a/src/main/java/me/piitex/renjava/api/builders/TextFlowBuilder.java +++ /dev/null @@ -1,53 +0,0 @@ -package me.piitex.renjava.api.builders; - -import javafx.scene.text.Text; -import javafx.scene.text.TextFlow; - -import java.util.LinkedList; - -public class TextFlowBuilder { - private LinkedList texts = new LinkedList<>(); - - private final int width, height; - - public TextFlowBuilder(String text, int width, int height) { - this.width = width; - this.height = height; - texts.add(new Text(text)); - } - - public TextFlowBuilder(Text text, int width, int height) { - this.width = width; - this.height = height; - texts.add(text); - } - - public TextFlowBuilder(LinkedList texts, int width, int height) { - this.width = width; - this.height = height; - this.texts = texts; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public LinkedList getTexts() { - return texts; - } - - public TextFlow build() { - TextFlow textFlow = new TextFlow(); - for (Text text : texts) { - textFlow.getChildren().add(text); - } - - textFlow.setPrefSize(width, height); - - return textFlow; - } -} diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java index c677d39..e79c82d 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java @@ -1,26 +1,17 @@ package me.piitex.renjava.api.scenes.types; -import javafx.animation.Animation; -import javafx.animation.Timeline; -import javafx.scene.image.Image; import javafx.scene.text.*; -import javafx.stage.Stage; import me.piitex.renjava.RenJava; -import me.piitex.renjava.api.builders.TextFlowBuilder; import me.piitex.renjava.api.characters.Character; import me.piitex.renjava.api.scenes.RenScene; -import me.piitex.renjava.api.scenes.animation.AnimationBuilder; import me.piitex.renjava.api.scenes.text.StringFormatter; -import me.piitex.renjava.api.scenes.transitions.Transitions; import me.piitex.renjava.configuration.RenJavaConfiguration; -import me.piitex.renjava.events.types.SceneAnimationStartEvent; import me.piitex.renjava.events.types.SceneBuildEvent; import me.piitex.renjava.events.types.SceneStartEvent; import me.piitex.renjava.gui.Menu; import me.piitex.renjava.gui.StageType; import me.piitex.renjava.api.builders.FontLoader; import me.piitex.renjava.api.builders.ImageLoader; -import me.piitex.renjava.gui.exceptions.ImageNotFoundException; import me.piitex.renjava.gui.overlay.*; import org.jetbrains.annotations.Nullable; @@ -141,15 +132,17 @@ public Menu build(boolean ui) { textboxMenu.addOverlay(textBoxImage); LinkedList texts = StringFormatter.formatText(dialogue); - TextFlowBuilder textFlowBuilder; + TextFlowOverlay textFlowOverlay; if (texts.isEmpty()) { Text text = new Text(dialogue); text.setFont(renJava.getConfiguration().getDialogueFont().getFont()); - textFlowBuilder = new TextFlowBuilder(text, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); + textFlowOverlay = new TextFlowOverlay(text, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); } else { - textFlowBuilder = new TextFlowBuilder(texts, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); + textFlowOverlay = new TextFlowOverlay(texts, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); } - textboxMenu.addOverlay(new TextFlowOverlay(textFlowBuilder, configuration.getTextX() + configuration.getTextOffsetX(), configuration.getTextY() + configuration.getTextOffsetY())); + textFlowOverlay.setX(configuration.getTextX() + configuration.getTextOffsetX()); + textFlowOverlay.setY(configuration.getTextY() + configuration.getTextOffsetY()); + textboxMenu.addOverlay(textFlowOverlay); characterDisplay.setFont(new FontLoader(renJava.getConfiguration().getDefaultFont().getFont(), configuration.getCharacterTextSize()).getFont()); characterDisplay.setFill(character.getColor()); diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/input/InputScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/input/InputScene.java index 410dea9..a672f35 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/input/InputScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/input/InputScene.java @@ -4,8 +4,6 @@ import javafx.scene.text.Text; import me.piitex.renjava.RenJava; import me.piitex.renjava.api.builders.FontLoader; -import me.piitex.renjava.api.builders.InputFieldBuilder; -import me.piitex.renjava.api.characters.Character; import me.piitex.renjava.api.scenes.RenScene; import me.piitex.renjava.api.scenes.types.ImageScene; import me.piitex.renjava.events.types.SceneStartEvent; @@ -73,8 +71,8 @@ public Menu build(boolean ui) { for (Menu otherMenu : menu.getChildren()) { textFlowOverlay = (TextFlowOverlay) otherMenu.getOverlays().stream().filter(overlay -> overlay instanceof TextFlowOverlay).findFirst().orElse(null); if (textFlowOverlay != null) { - Text beforeText = textFlowOverlay.getTextFlowBuilder().getTexts().getLast(); - InputFieldOverlay inputFieldOverlay = new InputFieldOverlay(new InputFieldBuilder(beforeText.getTranslateY() - 30.0, beforeText.getY() + 210.0, new FontLoader(RenJava.getInstance().getConfiguration().getDefaultFont().getFont(), 24.0))); + Text beforeText = textFlowOverlay.getTexts().getLast(); + InputFieldOverlay inputFieldOverlay = new InputFieldOverlay(beforeText.getTranslateY() - 30.0, beforeText.getY() + 210.0, new FontLoader(RenJava.getInstance().getConfiguration().getDefaultFont().getFont(), 24.0)); otherMenu.addOverlay(inputFieldOverlay); } } diff --git a/src/main/java/me/piitex/renjava/gui/Element.java b/src/main/java/me/piitex/renjava/gui/Element.java index 529ec43..a67f5ac 100644 --- a/src/main/java/me/piitex/renjava/gui/Element.java +++ b/src/main/java/me/piitex/renjava/gui/Element.java @@ -36,7 +36,7 @@ public Element(Overlay overlay) { button.setTranslateY(buttonOverlay.y()); this.node = button; } else if (overlay instanceof TextFlowOverlay textFlowOverlay) { - TextFlow textFlow = textFlowOverlay.getTextFlowBuilder().build(); + TextFlow textFlow = textFlowOverlay.build(); textFlow.setTranslateX(textFlowOverlay.x()); textFlow.setTranslateY(textFlowOverlay.y()); this.node = textFlow; diff --git a/src/main/java/me/piitex/renjava/gui/overlay/InputFieldOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/InputFieldOverlay.java index 0aca54e..cb3cd41 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/InputFieldOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/InputFieldOverlay.java @@ -1,28 +1,29 @@ package me.piitex.renjava.gui.overlay; -import me.piitex.renjava.api.builders.InputFieldBuilder; +import javafx.scene.control.TextField; +import me.piitex.renjava.api.builders.FontLoader; import me.piitex.renjava.api.scenes.transitions.Transitions; public class InputFieldOverlay implements Overlay { - private final InputFieldBuilder inputFieldBuilder; + private final double x; + private final double y; + private final FontLoader fontLoader; private Transitions transitions; - public InputFieldOverlay(InputFieldBuilder inputFieldBuilder) { - this.inputFieldBuilder = inputFieldBuilder; - } - - public InputFieldBuilder getInputFieldBuilder() { - return inputFieldBuilder; + public InputFieldOverlay(double x, double y, FontLoader fontLoader) { + this.x = x; + this.y = y; + this.fontLoader = fontLoader; } @Override public double x() { - return inputFieldBuilder.getX(); + return x; } @Override public double y() { - return inputFieldBuilder.getY(); + return y; } @Override @@ -33,4 +34,17 @@ public Transitions getTransition() { public void setTransitions(Transitions transitions) { this.transitions = transitions; } + + public FontLoader getFontLoader() { + return fontLoader; + } + + public TextField build() { + TextField textField = new TextField(); + textField.setTranslateX(x); + textField.setTranslateY(y); + textField.setStyle(""); + textField.setStyle("-fx-control-inner-background: transparent; -fx-background-color transparent;"); + return textField; + } } diff --git a/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java index 2f7568f..29b6635 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java @@ -1,22 +1,36 @@ package me.piitex.renjava.gui.overlay; -import me.piitex.renjava.api.builders.TextFlowBuilder; +import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; import me.piitex.renjava.api.scenes.transitions.Transitions; +import java.util.LinkedList; + public class TextFlowOverlay implements Overlay { - private final TextFlowBuilder textFlowBuilder; private double x; private double y; private Transitions transitions; - public TextFlowOverlay(TextFlowBuilder textFlowBuilder, double x, double y) { - this.textFlowBuilder = textFlowBuilder; - this.x = x; - this.y = y; + private LinkedList texts = new LinkedList<>(); + + private final int width, height; + + public TextFlowOverlay(String text, int width, int height) { + this.width = width; + this.height = height; + texts.add(new Text(text)); + } + + public TextFlowOverlay(Text text, int width, int height) { + this.width = width; + this.height = height; + texts.add(text); } - public TextFlowBuilder getTextFlowBuilder() { - return textFlowBuilder; + public TextFlowOverlay(LinkedList texts, int width, int height) { + this.width = width; + this.height = height; + this.texts = texts; } @Override @@ -24,11 +38,19 @@ public double x() { return x; } + public void setX(double x) { + this.x = x; + } + @Override public double y() { return y; } + public void setY(double y) { + this.y = y; + } + @Override public Transitions getTransition() { return transitions; @@ -37,4 +59,27 @@ public Transitions getTransition() { public void setTransitions(Transitions transitions) { this.transitions = transitions; } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public LinkedList getTexts() { + return texts; + } + + public TextFlow build() { + TextFlow textFlow = new TextFlow(); + for (Text text : texts) { + textFlow.getChildren().add(text); + } + + textFlow.setPrefSize(width, height); + + return textFlow; + } } From 570da0621712a1b773723c42f475e8aeb39af2f3 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Tue, 20 Feb 2024 07:42:34 -0600 Subject: [PATCH 05/34] Fixed character display text not rendering correctly. --- .../renjava/api/scenes/types/ImageScene.java | 8 ++++++-- .../configuration/RenJavaConfiguration.java | 2 +- src/main/java/me/piitex/renjava/gui/Element.java | 5 +++++ src/main/java/me/piitex/renjava/gui/Menu.java | 16 +++++----------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java index e79c82d..b5195e6 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java @@ -144,12 +144,16 @@ public Menu build(boolean ui) { textFlowOverlay.setY(configuration.getTextY() + configuration.getTextOffsetY()); textboxMenu.addOverlay(textFlowOverlay); - characterDisplay.setFont(new FontLoader(renJava.getConfiguration().getDefaultFont().getFont(), configuration.getCharacterTextSize()).getFont()); characterDisplay.setFill(character.getColor()); + TextOverlay characterText = new TextOverlay(characterDisplay, new FontLoader(configuration.getDefaultFont().getFont(), configuration.getCharacterTextSize()), + configuration.getCharacterTextX() + configuration.getCharacterTextOffsetX(), + configuration.getCharacterTextY() + configuration.getCharacterTextOffsetY()); + characterDisplay.setX(configuration.getCharacterTextX() + configuration.getCharacterTextOffsetX()); characterDisplay.setY(configuration.getCharacterTextY() + configuration.getCharacterTextOffsetY()); - textboxMenu.addOverlay(new TextOverlay(characterDisplay, characterDisplay.getX(), characterDisplay.getY())); + textboxMenu.addOverlay(characterText); + rootMenu.addMenu(textboxMenu); } } diff --git a/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java b/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java index 2d3d3e2..0f2a11a 100644 --- a/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java +++ b/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java @@ -35,7 +35,7 @@ public class RenJavaConfiguration { private int textOffsetY = 0; private int characterTextX = 500; - private int characterTextY = 850; + private int characterTextY = 500; private int characterTextOffsetX = 0; private int characterTextOffsetY = 0; diff --git a/src/main/java/me/piitex/renjava/gui/Element.java b/src/main/java/me/piitex/renjava/gui/Element.java index a67f5ac..5e002b1 100644 --- a/src/main/java/me/piitex/renjava/gui/Element.java +++ b/src/main/java/me/piitex/renjava/gui/Element.java @@ -6,6 +6,7 @@ import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.Pane; +import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; import me.piitex.renjava.RenJava; @@ -27,6 +28,10 @@ public Element(Overlay overlay) { this.node = imageView; } else if (overlay instanceof TextOverlay textOverlay) { Text text = textOverlay.getText(); + if (textOverlay.getFontLoader() != null) { + Font font = textOverlay.getFontLoader().getFont(); + text.setFont(font); + } text.setTranslateX(textOverlay.x()); text.setTranslateY(textOverlay.y()); this.node = text; diff --git a/src/main/java/me/piitex/renjava/gui/Menu.java b/src/main/java/me/piitex/renjava/gui/Menu.java index 86df2aa..dd73a8e 100644 --- a/src/main/java/me/piitex/renjava/gui/Menu.java +++ b/src/main/java/me/piitex/renjava/gui/Menu.java @@ -180,10 +180,6 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { backgroundImgElement.render(root); } - for (Overlay overlay : overlays) { - new Element(overlay).render(root); - } - logger.info("Rendering layouts..."); for (Layout layout : layouts) { for (Overlay overlay : layout.getOverlays()) { @@ -203,6 +199,11 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { root.getChildren().add(box); } + for (Overlay overlay : overlays) { + new Element(overlay).render(root); + } + + for (Menu menu : children) { menu.render(root, renScene); // Renders menu on top of this menu. } @@ -218,12 +219,6 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { scene = stage.getScene(); } - try { - scene.getStylesheets().add(new File(System.getProperty("user.dir") + "/game/css/button.css").toURI().toURL().toExternalForm()); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - setInputControls(scene); this.pane = root; @@ -264,5 +259,4 @@ private void setInputControls(Scene scene) { RenJava.callEvent(event); }); } - } \ No newline at end of file From 133d2658c6ea0aa12a6155cca86fd0e9e2cbe6b0 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Tue, 20 Feb 2024 07:43:05 -0600 Subject: [PATCH 06/34] Changed TextOverlay API. --- .../me/piitex/renjava/gui/overlay/TextOverlay.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/me/piitex/renjava/gui/overlay/TextOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/TextOverlay.java index 81b91ce..17f7959 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/TextOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/TextOverlay.java @@ -2,10 +2,12 @@ import javafx.scene.text.Text; +import me.piitex.renjava.api.builders.FontLoader; import me.piitex.renjava.api.scenes.transitions.Transitions; public class TextOverlay implements Overlay { private final Text text; + private FontLoader fontLoader; private double x; private double y; private Transitions transitions; @@ -16,6 +18,13 @@ public TextOverlay(Text text, double x, double y) { this.y = y; } + public TextOverlay(Text text, FontLoader fontLoader, double x, double y) { + this.text = text; + this.fontLoader = fontLoader; + this.x = x; + this.y = y; + } + public Text getText() { return text; } @@ -30,6 +39,10 @@ public double y() { return y; } + public FontLoader getFontLoader() { + return fontLoader; + } + @Override public Transitions getTransition() { return transitions; From 36434026ed25f0710af824ccc72e40c4747df94e Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Tue, 20 Feb 2024 07:44:23 -0600 Subject: [PATCH 07/34] Overhauled ButtonOverlay API. --- .../api/scenes/types/choices/ChoiceScene.java | 11 +- .../events/types/ChoiceButtonBuildEvent.java | 16 ++ .../renjava/gui/overlay/ButtonOverlay.java | 186 ++++++++++++++---- 3 files changed, 175 insertions(+), 38 deletions(-) create mode 100644 src/main/java/me/piitex/renjava/events/types/ChoiceButtonBuildEvent.java diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java index d7170cb..582ca21 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java @@ -8,6 +8,7 @@ import me.piitex.renjava.RenJava; import me.piitex.renjava.api.scenes.RenScene; import me.piitex.renjava.events.types.ButtonClickEvent; +import me.piitex.renjava.events.types.ChoiceButtonBuildEvent; import me.piitex.renjava.events.types.SceneStartEvent; import me.piitex.renjava.gui.Menu; import me.piitex.renjava.gui.StageType; @@ -179,7 +180,15 @@ public void render(Menu menu) { private Button getChoiceButton(Choice choice, Image image) { ButtonOverlay buttonOverlay = new ButtonOverlay(choice.getId(), choice.getText(), RenJava.getInstance().getConfiguration().getDefaultFont().getFont(), Color.BLACK, 0, 0, 1, 1); - Button button = buttonOverlay.build(); + buttonOverlay.setBorderColor(Color.TRANSPARENT); + buttonOverlay.setBackgroundColor(Color.TRANSPARENT); + buttonOverlay.setHover(true); + buttonOverlay.setTextFill(Color.WHITE); + buttonOverlay.setHoverColor(Color.BLUE); + + + ChoiceButtonBuildEvent choiceButtonBuildEvent = new ChoiceButtonBuildEvent(buttonOverlay); + Button button = choiceButtonBuildEvent.getButtonOverlay().build(); ImageView imageView = new ImageView(image); imageView.setPreserveRatio(true); diff --git a/src/main/java/me/piitex/renjava/events/types/ChoiceButtonBuildEvent.java b/src/main/java/me/piitex/renjava/events/types/ChoiceButtonBuildEvent.java new file mode 100644 index 0000000..c8ac659 --- /dev/null +++ b/src/main/java/me/piitex/renjava/events/types/ChoiceButtonBuildEvent.java @@ -0,0 +1,16 @@ +package me.piitex.renjava.events.types; + +import me.piitex.renjava.events.Event; +import me.piitex.renjava.gui.overlay.ButtonOverlay; + +public class ChoiceButtonBuildEvent extends Event { + private final ButtonOverlay buttonOverlay; + + public ChoiceButtonBuildEvent(ButtonOverlay buttonOverlay) { + this.buttonOverlay = buttonOverlay; + } + + public ButtonOverlay getButtonOverlay() { + return buttonOverlay; + } +} diff --git a/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java index 54d1357..f7d60c3 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java @@ -11,36 +11,42 @@ import me.piitex.renjava.events.types.ButtonClickEvent; import me.piitex.renjava.gui.exceptions.ImageNotFoundException; +import java.util.concurrent.atomic.AtomicReference; + public class ButtonOverlay implements Overlay { - private final Button button; + private Button button; private Transitions transitions; private final String id; private String text; private Font font; private Image image; - private Color color; + private Color textFill; + private Color backgroundColor; + private Color borderColor; + private Color hoverColor; + private boolean hover; + private int borderWidth = 0; + private int backgroundRadius = 0; private double x = 1, y = 1; private final double xScale, yScale; - public ButtonOverlay(String id, String text, Color color, double xScale, double yScale) { + public ButtonOverlay(String id, String text, Color textFill, double xScale, double yScale) { this.id = id; this.text = text; - this.color = color; + this.textFill = textFill; this.xScale = x; this.yScale = y; - this.button = build(); } - public ButtonOverlay(String id, String text, Color color, Font font, double xScale, double yScale) { + public ButtonOverlay(String id, String text, Color textFill, Font font, double xScale, double yScale) { this.id = id; this.text = text; - this.color = color; + this.textFill = textFill; this.font = font; this.xScale = x; this.yScale = y; - this.button = build(); } /** @@ -48,21 +54,20 @@ public ButtonOverlay(String id, String text, Color color, Font font, double xSca * * @param id Identifier for the button. * @param text Text that will be displayed inside the button. - * @param color Color of the text. + * @param textFill Color of the text. * @param x X-Axis position of the button. * @param y Y-Axis position of the button. * @param xScale X-Axis scale of the button. * @param yScale Y-Axis scale of the button. */ - public ButtonOverlay(String id, String text, Color color, double x, double y, double xScale, double yScale) { + public ButtonOverlay(String id, String text, Color textFill, double x, double y, double xScale, double yScale) { this.id = id; this.text = text; - this.color = color; + this.textFill = textFill; this.x = x; this.y = y; this.xScale = xScale; this.yScale = yScale; - this.button = build(); } /** @@ -71,22 +76,21 @@ public ButtonOverlay(String id, String text, Color color, double x, double y, do * @param id Identifier for the button. * @param text Text that will be displayed inside the button. * @param font Font to be used for the text. - * @param color Color of the text. + * @param textFill Color of the text. * @param x X-Axis position of the button. * @param y Y-Axis position of the button. * @param xScale X-Axis scale of the button. * @param yScale Y-Axis scale of the button. */ - public ButtonOverlay(String id, String text, Font font, Color color, double x, double y, double xScale, double yScale) { + public ButtonOverlay(String id, String text, Font font, Color textFill, double x, double y, double xScale, double yScale) { this.id = id; this.text = text; this.font = font; - this.color = color; + this.textFill = textFill; this.x = x; this.y = y; this.xScale = xScale; this.yScale = yScale; - this.button = build(); } /** @@ -95,18 +99,40 @@ public ButtonOverlay(String id, String text, Font font, Color color, double x, d * @param id Identifier for the button. * @param text Text that will be displayed inside the button. * @param font Font to be used for the text. - * @param color Color of the text. + * @param textFill Color of the text. * @param xScale X-Axis scale of the button. * @param yScale Y-Axis scale of the button. */ - public ButtonOverlay(String id, String text, Font font, Color color, double xScale, double yScale) { + public ButtonOverlay(String id, String text, Font font, Color textFill, double xScale, double yScale) { this.id = id; this.text = text; this.font = font; - this.color = color; + this.textFill = textFill; this.xScale = xScale; this.yScale = yScale; - this.button = build(); + } + + public ButtonOverlay(String id, String text, Font font, Color textFill, Color backgroundColor, Color borderColor, double xScale, double yScale) { + this.id = id; + this.text = text; + this.font = font; + this.textFill = textFill; + this.xScale = xScale; + this.yScale = yScale; + this.backgroundColor = backgroundColor; + this.borderColor = borderColor; + } + + public ButtonOverlay(String id, String text, Font font, Color textFill, Color backgroundColor, Color borderColor, boolean hover, double xScale, double yScale) { + this.id = id; + this.text = text; + this.font = font; + this.textFill = textFill; + this.xScale = xScale; + this.yScale = yScale; + this.backgroundColor = backgroundColor; + this.borderColor = borderColor; + this.hover = hover; } /** @@ -130,7 +156,6 @@ public ButtonOverlay(String id, ImageLoader imageLoader, double x, double y, dou this.y = y; this.xScale = xScale; this.yScale = yScale; - this.button = build(); } /** @@ -194,22 +219,78 @@ public void setImage(Image image) { this.image = image; } - public Color getColor() { - return color; + public Color getTextFill() { + return textFill; } - public void setColor(Color color) { - this.color = color; + public void setTextFill(Color color) { + this.textFill = color; + } + + public Color getBackgroundColor() { + return backgroundColor; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public Color getBorderColor() { + return borderColor; + } + + public void setBorderColor(Color borderColor) { + this.borderColor = borderColor; + } + + public Color getHoverColor() { + return hoverColor; + } + + public void setHoverColor(Color hoverColor) { + this.hoverColor = hoverColor; + } + + public boolean isHover() { + return hover; + } + + public void setHover(boolean hover) { + this.hover = hover; + } + + public int getBorderWidth() { + return borderWidth; + } + + public void setBorderWidth(int borderWidth) { + this.borderWidth = borderWidth; + } + + public int getBackgroundRadius() { + return backgroundRadius; + } + + public void setBackgroundRadius(int backgroundRadius) { + this.backgroundRadius = backgroundRadius; } @Override public double x() { - return button.getTranslateX(); + return x; + } + + public void setX(double x) { + this.x = x; } @Override public double y() { - return button.getTranslateY(); + return y; + } + + public void setY(double y) { + this.y = y; } @Override @@ -220,13 +301,6 @@ public Transitions getTransition() { public void setTransitions(Transitions transitions) { this.transitions = transitions; } - public void setX(double x) { - this.x = x; - } - - public void setY(int y) { - this.y = y; - } public double getXScale() { return xScale; @@ -237,6 +311,9 @@ public double getYScale() { } public Button build() { + if (button != null) { + return button; + } Button button = new Button(); button.setId(id); if (image != null) { @@ -252,9 +329,34 @@ public Button build() { // Set default font button.setFont(RenJava.getInstance().getConfiguration().getUiFont().getFont()); } - if (color != null) { - button.setTextFill(color); + if (textFill != null) { + button.setTextFill(textFill); } + String inLine = ""; + if (backgroundColor != null) { + inLine += "-fx-background-color: " + cssColor(backgroundColor) + "; "; + } + if (borderColor != null) { + inLine += "-fx-border-color: " + cssColor(borderColor) + "; "; + } + inLine += "-fx-border-width: " + borderWidth + "; "; + inLine += "-fx-background-radius: " + backgroundRadius + ";"; + + // https://stackoverflow.com/questions/30680570/javafx-button-border-and-hover + if (hover) { + AtomicReference attomicInLine = new AtomicReference<>(inLine); + button.setOnMouseEntered(mouseEvent -> { + button.setTextFill(hoverColor); + button.setStyle(attomicInLine.get()); + }); + button.setOnMouseExited(mouseEvent -> { + button.setTextFill(textFill); + button.setStyle(attomicInLine.get()); + }); + } + + button.setStyle(inLine); + if (x != 0 && y != 0) { button.setTranslateX(x); button.setTranslateY(y); @@ -269,8 +371,18 @@ public Button build() { return button; } + // Helper css function + public String cssColor(Color color) { + String webFormat = String.format("rgba(%d, %d, %d, %f)", + (int) (255 * color.getRed()), + (int) (255 * color.getGreen()), + (int) (255 * color.getBlue()), + color.getOpacity()); + return webFormat; + } + public static ButtonOverlay copyOf(String id, ButtonOverlay builder) { - ButtonOverlay toReturn = new ButtonOverlay(id, builder.getText(), builder.getFont(), builder.getColor(), builder.x(), builder.y(), builder.getXScale(), builder.getYScale()); + ButtonOverlay toReturn = new ButtonOverlay(id, builder.getText(), builder.getFont(), builder.getTextFill(), builder.x(), builder.y(), builder.getXScale(), builder.getYScale()); toReturn.setImage(builder.getImage()); return toReturn; } From 77f917a728b1b1214e43da5803e9e1f3a7cd2449 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Tue, 20 Feb 2024 07:44:38 -0600 Subject: [PATCH 08/34] Removed button.css --- src/main/resources/game/css/button.css | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 src/main/resources/game/css/button.css diff --git a/src/main/resources/game/css/button.css b/src/main/resources/game/css/button.css deleted file mode 100644 index 936ba13..0000000 --- a/src/main/resources/game/css/button.css +++ /dev/null @@ -1,10 +0,0 @@ -.button{ - -fx-border-color: transparent; - -fx-border-width: 0; - -fx-background-radius: 0; - -fx-background-color: transparent; - -fx-text-fill: black -} - .button:hover { - -fx-text-fill: blue -} From e195fe954c68d67ba61449cda5934bd323b8f118 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Wed, 21 Feb 2024 04:06:06 -0600 Subject: [PATCH 09/34] Fixed menu and character text alignment issues. --- .../me/piitex/renjava/configuration/RenJavaConfiguration.java | 4 ++-- src/main/java/me/piitex/renjava/gui/Menu.java | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java b/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java index 0f2a11a..dbaad52 100644 --- a/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java +++ b/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java @@ -34,8 +34,8 @@ public class RenJavaConfiguration { private int textOffsetX = 0; private int textOffsetY = 0; - private int characterTextX = 500; - private int characterTextY = 500; + private int characterTextX = 100; + private int characterTextY = 440; private int characterTextOffsetX = 0; private int characterTextOffsetY = 0; diff --git a/src/main/java/me/piitex/renjava/gui/Menu.java b/src/main/java/me/piitex/renjava/gui/Menu.java index dd73a8e..b68d1df 100644 --- a/src/main/java/me/piitex/renjava/gui/Menu.java +++ b/src/main/java/me/piitex/renjava/gui/Menu.java @@ -171,6 +171,8 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { root.setTranslateX(x); root.setTranslateY(y); + root.setPrefSize(width, height); + // Background fill is used for fade ins. BackgroundFill backgroundFill = new BackgroundFill(BLACK, new CornerRadii(1), new Insets(0,0,0,0)); root.setBackground(new Background(backgroundFill)); @@ -189,7 +191,7 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { Pane box = layout.getPane(); box.setTranslateX(layout.getXPosition()); box.setTranslateY(layout.getYPosition()); - box.setPrefSize(layout.getWidth(), layout.getWidth()); + box.setPrefSize(layout.getWidth(), layout.getHeight()); if (box instanceof HBox hBox) { hBox.setSpacing(layout.getSpacing()); } else if (box instanceof VBox vBox) { From aa5b00c7229415294fa5cbfc4b9c40ee9f2597ad Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:53:57 -0600 Subject: [PATCH 10/34] Slight adjustments to the side menu. --- src/main/java/me/piitex/renjava/RenJava.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/me/piitex/renjava/RenJava.java b/src/main/java/me/piitex/renjava/RenJava.java index 606a89c..b7f0bbd 100644 --- a/src/main/java/me/piitex/renjava/RenJava.java +++ b/src/main/java/me/piitex/renjava/RenJava.java @@ -393,20 +393,19 @@ public void buildStage(Stage stage) { public abstract Menu buildTitleScreen(); public Menu buildSideMenu() { - // Don't build background image Menu menu = new Menu(350, 500, new ImageLoader("gui/overlay/main_menu.png")); Font uiFont = RenJava.getInstance().getConfiguration().getUiFont().getFont(); - ButtonOverlay startButton = new ButtonOverlay("menu-start-button", "Start", uiFont, Color.BLACK, 1, 1); - ButtonOverlay loadButton = new ButtonOverlay("menu-load-button", "Load", uiFont, Color.BLACK, 1, 1); - ButtonOverlay optionsButton = new ButtonOverlay("menu-preference-button", "Preferences", uiFont, Color.BLACK, 1, 1); - ButtonOverlay aboutButton = new ButtonOverlay("menu-about-button", "About", uiFont, Color.BLACK, 1, 1); + ButtonOverlay startButton = new ButtonOverlay("menu-start-button", "Start", uiFont, Color.BLACK, Color.TRANSPARENT, Color.TRANSPARENT, Color.BLUE, 1, 1); + ButtonOverlay loadButton = new ButtonOverlay("menu-load-button", "Load", uiFont, Color.BLACK, Color.TRANSPARENT, Color.TRANSPARENT, Color.BLUE, 1, 1); + ButtonOverlay optionsButton = new ButtonOverlay("menu-preference-button", "Preferences", uiFont, Color.BLACK, Color.TRANSPARENT, Color.TRANSPARENT, Color.BLUE, 1, 1); + ButtonOverlay aboutButton = new ButtonOverlay("menu-about-button", "About", uiFont, Color.BLACK, Color.TRANSPARENT, Color.TRANSPARENT, Color.BLUE, 1, 1); // Create vbox for the buttons. You can also do an HBox VerticalLayout layout = new VerticalLayout(200, 500); - layout.setXPosition(50); - layout.setYPosition(250); + layout.setX(50); + layout.setY(250); layout.setSpacing(20); layout.addOverlays(startButton, loadButton, optionsButton, aboutButton); From 81402773cc1b9a2e5cc8fc94e5c11e02ff0ab5ba Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:54:37 -0600 Subject: [PATCH 11/34] Added null check for child menus. --- src/main/java/me/piitex/renjava/gui/Menu.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/me/piitex/renjava/gui/Menu.java b/src/main/java/me/piitex/renjava/gui/Menu.java index b68d1df..a935913 100644 --- a/src/main/java/me/piitex/renjava/gui/Menu.java +++ b/src/main/java/me/piitex/renjava/gui/Menu.java @@ -160,7 +160,6 @@ public Menu addMenu(Menu menu) { * @param renScene The RenScene that is being used. If null, it will be assumed this is a main menu screen. */ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { - // TODO: 2/13/2024 Make an element class which can render every overlay instead of this spaghettiti code. Logger logger = renJava.getLogger(); @@ -189,8 +188,8 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { } Pane box = layout.getPane(); - box.setTranslateX(layout.getXPosition()); - box.setTranslateY(layout.getYPosition()); + box.setTranslateX(layout.getX()); + box.setTranslateY(layout.getY()); box.setPrefSize(layout.getWidth(), layout.getHeight()); if (box instanceof HBox hBox) { hBox.setSpacing(layout.getSpacing()); @@ -207,7 +206,9 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { for (Menu menu : children) { - menu.render(root, renScene); // Renders menu on top of this menu. + if (menu != null) { + menu.render(root, renScene); // Renders menu on top of this menu. + } } rootMenu = this; From e902362062ffa0be8dafb1983d670926d0cae23f Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:55:14 -0600 Subject: [PATCH 12/34] Added more functionality to overlays. --- .../piitex/renjava/gui/overlay/ButtonOverlay.java | 13 +++++++++++++ .../piitex/renjava/gui/overlay/TextFlowOverlay.java | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java index f7d60c3..48b176f 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/ButtonOverlay.java @@ -135,6 +135,19 @@ public ButtonOverlay(String id, String text, Font font, Color textFill, Color ba this.hover = hover; } + public ButtonOverlay(String id, String text, Font font, Color textFill, Color backgroundColor, Color borderColor, Color hoverColor, double xScale, double yScale) { + this.id = id; + this.text = text; + this.font = font; + this.textFill = textFill; + this.xScale = xScale; + this.yScale = yScale; + this.backgroundColor = backgroundColor; + this.borderColor = borderColor; + this.hover = true; + this.hoverColor = hoverColor; + } + /** * Create a button with only an image. * diff --git a/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java index 29b6635..299139f 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java @@ -1,5 +1,6 @@ package me.piitex.renjava.gui.overlay; +import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; import me.piitex.renjava.api.scenes.transitions.Transitions; @@ -10,6 +11,7 @@ public class TextFlowOverlay implements Overlay { private double x; private double y; private Transitions transitions; + private Font font; private LinkedList texts = new LinkedList<>(); @@ -51,6 +53,14 @@ public void setY(double y) { this.y = y; } + public Font getFont() { + return font; + } + + public void setFont(Font font) { + this.font = font; + } + @Override public Transitions getTransition() { return transitions; @@ -75,6 +85,9 @@ public LinkedList getTexts() { public TextFlow build() { TextFlow textFlow = new TextFlow(); for (Text text : texts) { + if (font != null) { + text.setFont(font); + } textFlow.getChildren().add(text); } From e85c12e2ad6f6902b4abb2ff0ebe7b4d9dbf663a Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:55:39 -0600 Subject: [PATCH 13/34] Renamed xPostion and yPosition. --- .../me/piitex/renjava/gui/layouts/Layout.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/me/piitex/renjava/gui/layouts/Layout.java b/src/main/java/me/piitex/renjava/gui/layouts/Layout.java index b4a27f8..e94dfcd 100644 --- a/src/main/java/me/piitex/renjava/gui/layouts/Layout.java +++ b/src/main/java/me/piitex/renjava/gui/layouts/Layout.java @@ -10,8 +10,8 @@ public abstract class Layout { private final Pane pane; // Get's the pane type for javafx private final LinkedHashSet overlays = new LinkedHashSet<>(); - private double xPosition; - private double yPosition; + private double x; + private double y; private int width, height; private double spacing; @@ -23,20 +23,20 @@ public Pane getPane() { return pane; } - public double getXPosition() { - return xPosition; + public double getX() { + return x; } - public void setXPosition(int xPosition) { - this.xPosition = xPosition; + public void setX(double x) { + this.x = x; } - public double getYPosition() { - return yPosition; + public double getY() { + return y; } - public void setYPosition(int yPosition) { - this.yPosition = yPosition; + public void setY(double y) { + this.y = y; } public int getWidth() { From 6bdffbd8c47788c7be26110cf6f88987986172fb Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:56:09 -0600 Subject: [PATCH 14/34] Added right click condition to render event. --- .../renjava/events/types/MainMenuRenderEvent.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/me/piitex/renjava/events/types/MainMenuRenderEvent.java b/src/main/java/me/piitex/renjava/events/types/MainMenuRenderEvent.java index 5d99407..394786f 100644 --- a/src/main/java/me/piitex/renjava/events/types/MainMenuRenderEvent.java +++ b/src/main/java/me/piitex/renjava/events/types/MainMenuRenderEvent.java @@ -5,12 +5,22 @@ public class MainMenuRenderEvent extends Event { private final Menu menu; + private boolean rightClicked = false; public MainMenuRenderEvent(Menu menu) { this.menu = menu; } + public MainMenuRenderEvent(Menu menu, boolean rightClicked) { + this.menu = menu; + this.rightClicked = rightClicked; + } + public Menu getMenu() { return menu; } + + public boolean isRightClicked() { + return rightClicked; + } } From 628680a49c4284db25ba5e36550d7a8281a42f97 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:57:23 -0600 Subject: [PATCH 15/34] Re-write for the saving system. --- .../me/piitex/renjava/api/saves/Load.java | 177 ---------- .../me/piitex/renjava/api/saves/Save.java | 327 +++++++++++++++--- .../renjava/api/saves/SaveFileUtils.java | 30 -- .../piitex/renjava/api/saves/data/Mapper.java | 200 +++++++++++ .../api/saves/file/SectionKeyValue.java | 60 +++- .../defaults/GameFlowEventListener.java | 2 +- .../defaults/MenuClickEventListener.java | 28 +- .../defaults/StoryHandlerEventListener.java | 2 +- 8 files changed, 552 insertions(+), 274 deletions(-) delete mode 100644 src/main/java/me/piitex/renjava/api/saves/Load.java delete mode 100644 src/main/java/me/piitex/renjava/api/saves/SaveFileUtils.java create mode 100644 src/main/java/me/piitex/renjava/api/saves/data/Mapper.java diff --git a/src/main/java/me/piitex/renjava/api/saves/Load.java b/src/main/java/me/piitex/renjava/api/saves/Load.java deleted file mode 100644 index b24e825..0000000 --- a/src/main/java/me/piitex/renjava/api/saves/Load.java +++ /dev/null @@ -1,177 +0,0 @@ -package me.piitex.renjava.api.saves; - -import me.piitex.renjava.RenJava; -import me.piitex.renjava.api.saves.data.PersistentData; -import me.piitex.renjava.api.saves.exceptions.SaveFileNotFound; -import me.piitex.renjava.api.saves.file.SectionKeyValue; -import me.piitex.renjava.api.stories.Story; - -import java.io.File; -import java.io.FileNotFoundException; -import java.lang.reflect.Field; -import java.lang.reflect.Type; -import java.util.Collection; -import java.util.HashSet; -import java.util.Scanner; -import java.util.logging.Logger; - -/** - * Loads a save file. - */ -public class Load { - - public Load(int slot) throws SaveFileNotFound { - File directory = new File(System.getProperty("user.dir") + "/game/saves/" + slot + "/"); - File file = new File(directory,"/save-" + slot + ".dat"); - if (!file.exists()) { - throw new SaveFileNotFound(); - } - - // Mapping - Collection keyValues = new HashSet<>(); - - // Story and Scene - String story = ""; - String scene = ""; - - // Music stuff - String currentTrack = ""; - boolean isPlaying = false; - boolean isLooping = false; - - Logger logger = RenJava.getInstance().getLogger(); - try { - Scanner scanner = new Scanner(file); - SectionKeyValue sectionKeyValue = null; - - // Flags - boolean config = false; - boolean musicTracker = false; - - while (scanner.hasNextLine()) { - // classname@field1;value@field2;value@ect..@ect..;clasname2@field;value@field;value@field;value - String data = scanner.nextLine(); - - if (data.startsWith("configuration")) { - config = true; - } else if (data.contains("me.piitex.renjava.api.music.Tracks")) { - musicTracker = true; - } else { - if (!data.startsWith(" ")) { - data = data.trim(); - if (sectionKeyValue != null) { - keyValues.add(sectionKeyValue); - } - sectionKeyValue = new SectionKeyValue(data.replace(":", "").trim()); - } else if (sectionKeyValue != null) { - String key = data.split(": ")[0].trim(); - String value = data.split(": ")[1].trim(); - sectionKeyValue.addKeyValue(key, value); - } - } - - if (data.startsWith(" ")) { - if (config) { - data = data.trim(); - String[] pairs = data.split(": "); - String key = pairs[0]; - String value = pairs[1]; - if (key.equalsIgnoreCase("storyID")) { - story = value; - } - if (key.equalsIgnoreCase("sceneID")) { - logger.info("Key: " + key); - logger.info("Value: " + value); - scene = value; - // End config - } - if (!story.isEmpty() && !scene.isEmpty()) { - logger.info("Story: " + story); - logger.info("Scene: " + scene); - config = false; - } - } - if (musicTracker) { - data = data.trim(); - String[] pairs = data.split(": "); - String key = pairs[0]; - String value = pairs[1]; - - if (key.equalsIgnoreCase("currentTrack")) { - currentTrack = value; - } - - if (key.equalsIgnoreCase("isPlaying")) { - isPlaying = Boolean.parseBoolean(value); - } - - if (key.equalsIgnoreCase("loop")) { - isLooping = Boolean.parseBoolean(value); - } - } - } - } - // Once the loop is done add the final section - keyValues.add(sectionKeyValue); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - for (PersistentData data : RenJava.getInstance().getRegisteredData()) { - // Loop through data and check if it matches any of the section key data - logger.info("Class: " + data.getClass().getName()); - for (SectionKeyValue sectionKeyValue : keyValues) { - if (sectionKeyValue.getSection().equalsIgnoreCase(data.getClass().getName())) { - sectionKeyValue.getKeyValueMap().forEach((string, string2) -> { - logger.info("Setting fields..."); - - try { - Field field = data.getClass().getField(string); - setField(field, data, string2); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (NoSuchFieldException e) { - // If its no such field see if its a declared field - try { - Field field = data.getClass().getDeclaredField(string); - setField(field, data, string2); - } catch (IllegalAccessException | NoSuchFieldException ignored) { - // This is ignored because it will throw NoSuchFieldException as it loops through ALL saved data in the file. - } - } - }); - } - - keyValues.remove(sectionKeyValue); // this might error - } - } - Story loadedStory = RenJava.getInstance().getPlayer().getStory(story); - loadedStory.init(); // Add scenes and stuff - loadedStory.displayScene(scene); - if (isPlaying) { - RenJava.getInstance().getTracks().play(currentTrack, isLooping); - } - } - - private void setField(Field field, PersistentData data, String string2) throws NoSuchFieldException, IllegalAccessException { - field.setAccessible(true); - Type type = field.getGenericType(); - if (type.getTypeName().toLowerCase().contains("string")) { - field.set(data, string2); - } else if (type.getTypeName().toLowerCase().contains("int")) { - field.set(data, Integer.parseInt(string2)); - } else if (type.getTypeName().toLowerCase().contains("boolean")) { - field.set(data, Boolean.parseBoolean(string2)); - } else if (type.getTypeName().toLowerCase().contains("double")) { - field.set(data, Double.parseDouble(string2)); - } else if (type.getTypeName().toLowerCase().contains("float")) { - field.set(data, Float.parseFloat(string2)); - } else if (type.getTypeName().toLowerCase().contains("long")) { - field.set(data, Long.parseLong(string2)); - } else if (type.getTypeName().toLowerCase().contains("short")) { - field.set(data, Short.parseShort(string2)); - } else if (type.getTypeName().toLowerCase().contains("byte")) { - field.set(data, Byte.parseByte(string2)); - } - } -} \ No newline at end of file diff --git a/src/main/java/me/piitex/renjava/api/saves/Save.java b/src/main/java/me/piitex/renjava/api/saves/Save.java index ef2908b..f86b5a1 100644 --- a/src/main/java/me/piitex/renjava/api/saves/Save.java +++ b/src/main/java/me/piitex/renjava/api/saves/Save.java @@ -1,82 +1,87 @@ package me.piitex.renjava.api.saves; + import me.piitex.renjava.RenJava; import me.piitex.renjava.api.saves.data.Data; import me.piitex.renjava.api.saves.data.PersistentData; -import me.piitex.renjava.api.scenes.RenScene; -import me.piitex.renjava.api.stories.Story; +import me.piitex.renjava.api.saves.file.SectionKeyValue; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.*; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -/** - * Represents a save slot. All data is stored via a .dat file. - */ +// Class which represents a save file. public class Save { - private final Story story; - private final RenScene scene; - - /** - * Creates a current save for the desired slot. - * @param slot Slot to be saved, there is no limit on slots. - */ - public Save(int slot, String storyID, String sceneID) { - this.story = RenJava.getInstance().getPlayer().getStory(storyID); - this.scene = story.getScene(sceneID); - // Slot is needed for the save slot. - File directory = new File(System.getProperty("user.dir") + "/game/saves/" + slot + "/"); - directory.mkdir(); - File file = new File(directory,"/save-" + slot + ".dat"); - if (!file.exists()) { - try { - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } + private final File file; + private int slot; + + public Save(File file) { + this.file = file; + } + + public Save(int slot) { + this.slot = slot; + this.file = new File(System.getProperty("user.dir") + "/game/saves/save-" + slot + ".dat"); + } + + // Writes save file + public void write() { + // First get all PersistentData to write. + // me.piitex.MyDataClass: + // field1: data1 + // map: + // key1: value1 + // key2: value2 + StringBuilder appendString = new StringBuilder(); - Logger logger = RenJava.getInstance().getLogger(); - appendString.append("configuration").append("@@@@").append("storyID").append("!!!!").append(storyID).append("@@@@").append("sceneID").append("!!!!").append(sceneID).append(";;;;"); for (PersistentData data : RenJava.getInstance().getRegisteredData()) { + SectionKeyValue rootSection = new SectionKeyValue(data.getClass().getName()); Class claz = data.getClass(); - appendString.append(claz.getName()); + if (appendString.toString().contains(claz.getName())) { + continue; + } List fields = new ArrayList<>(List.of(claz.getDeclaredFields())); fields.addAll(List.of(claz.getFields())); for (Field field : fields) { + field.setAccessible(true); if (field.isAnnotationPresent(Data.class)) { - appendString.append("@@@@"); - appendString.append(field.getName()); - appendString.append("!!!!"); - field.setAccessible(true); + SectionKeyValue mapSection = handleMap(data, field); + if (mapSection != null) { + System.out.println("Map Section: "); + + System.out.println(mapSection.toString()); + rootSection.addSubSection(mapSection); + + continue; + } + // Handle fields try { Object object = field.get(data); - appendString.append(object.toString()); + rootSection.addKeyValue(field.getName(), object.toString()); } catch (IllegalAccessException e) { - e.printStackTrace(); + throw new RuntimeException(e); + } catch (IllegalArgumentException ignored) { + rootSection.addKeyValue(field.getName(), "null"); } } } - appendString.append(";;;;"); + appendString.append(rootSection); } - // The appendString won't be suitable for the save file. We can still use it to format our data but its best if we do a file format. YAML is a good example - String toWriteToFile = SaveFileUtils.toFormat(appendString.toString()); - logger.info("File: " + toWriteToFile); - FileWriter writer = null; + + FileWriter fileWriter = null; try { - writer = new FileWriter(file); - writer.write(toWriteToFile); + fileWriter = new FileWriter(file); + fileWriter.write(appendString.toString()); } catch (IOException e) { e.printStackTrace(); } finally { - if (writer != null) { + if (fileWriter != null) { try { - writer.close(); + fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } @@ -84,11 +89,227 @@ public Save(int slot, String storyID, String sceneID) { } } - public Story getStory() { - return story; + private SectionKeyValue handleMap(PersistentData data, Field field) { + if (field.getGenericType().getTypeName().contains("Map<")) { + try { + System.out.println("Map type: " + field.getGenericType().getTypeName()); + SectionKeyValue sectionKeyValue = new SectionKeyValue(field.getName()); + reconstructMap(sectionKeyValue, data, field); + return sectionKeyValue; + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + return null; } - public RenScene getScene() { - return scene; + private void reconstructMap(SectionKeyValue sectionKeyValue, PersistentData data, Field field) throws IllegalAccessException { + // I don't think I need to actually re-create the map. Just in case, I will keep the Mapper class for now. + //String typeName = field.getGenericType().getTypeName(); + //typeName = typeName.replace("java.util.Map<", ""); + + // + + //String[] typeSplit = typeName.replace("<", "").replace(">", "").split(","); + //java.lang.String + //java.lang.Integer + + // Conversion is required as the map needs to be set to the actual type in order to save it. + //String key = typeSplit[0]; + //String value = typeSplit[1]; + + + + Map map = (Map) field.get(data); + map.entrySet().forEach(objectObjectEntry -> { + System.out.println("Reconstructing entry..."); + sectionKeyValue.addKeyValue(objectObjectEntry.getKey().toString(), objectObjectEntry.getValue().toString()); + }); + } + + + // Loads save file + public void load() { + // Collect and set string data to class data. + // First loop the registered data and find the string data which corresponds with the data. + + String fullData = null; + try { + fullData = new Scanner(file).useDelimiter("\\Z").next(); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } finally { + if (fullData == null) { + RenJava.getInstance().getLogger().severe("Save file does not exist."); + return; + } + } + + for (PersistentData persistentData : RenJava.getInstance().getRegisteredData()) { + String clazzName = persistentData.getClass().getName(); + SectionKeyValue rootSection = new SectionKeyValue(clazzName); + SectionKeyValue mapSection = null; + + String[] classSplit = fullData.split(clazzName + ":"); + String fields = classSplit[1]; + System.out.println("Class Split: " + classSplit[1]); + String[] fieldSplit = fields.split("\n"); + for (String field : fieldSplit) { + System.out.println("Field: " + field); + if (field.trim().isEmpty()) continue; + String[] keyValueSplit = field.split(":"); + String key = keyValueSplit[0]; + if (keyValueSplit.length == 1) { + if (key.startsWith(" ") || key.startsWith("\t")) { + System.out.println("Mapping found: " + key.trim()); + mapSection = new SectionKeyValue(key.trim()); + rootSection.addSubSection(mapSection); + continue; + } else { + break; + } + } + String value = keyValueSplit[1]; + if ((key.startsWith(" ") || key.startsWith("\t")) && value.trim().isEmpty()) { + System.out.println("Mapping found: " + key.trim()); + mapSection = new SectionKeyValue(key.trim()); + rootSection.addSubSection(mapSection); + } else if (value.trim().isEmpty()) { + break; + } else if (key.startsWith("\t\t") || key.startsWith(" ")) { + if (mapSection != null) { + mapSection.addKeyValue(key.trim(), value.trim()); + } + System.out.println("Mapping entry found: " + key.trim() + "," + value.trim()); + } else if (key.startsWith("\t") || key.startsWith(" ")){ + // Handle generic entry + + // Check if entry is an array + if (value.contains(",")) { + if (value.contains("[")) { + value = value.replace("[", "").replace("]", ""); + } + String[] arraySplit = value.trim().split(","); + rootSection.addArray(key.trim(), arraySplit); + continue; + } + rootSection.addKeyValue(key.trim(), value.trim()); + } + } + processSection(persistentData, rootSection); + } + } + + + public void processSection(PersistentData persistentData, SectionKeyValue rootSection) { + // Data is the full data string + // me.piitex.SomeData: + // field1: value1 + // map: + // key: value + // + + System.out.println("================================================"); + System.out.println(); + System.out.println(rootSection.toString()); + System.out.println(); + System.out.println("================================================"); + + // Next set the mapping to the fields + List fields = new ArrayList<>(List.of(persistentData.getClass().getDeclaredFields())); + fields.addAll(List.of(persistentData.getClass().getFields())); + for (Field field : fields) { + if (field.isAnnotationPresent(Data.class)) { + System.out.println("Processing Field: " + field.getName()); + field.setAccessible(true); + if (field.getGenericType().getTypeName().contains("Map<")) { + // This is a map load. Scan for subsections if the field name matches. Add all data + for (SectionKeyValue subSection : rootSection.getSubSections()) { + if (subSection.getSection().equalsIgnoreCase(field.getName())) { + // Convert Map to whatever the map of the object is + + // Set the current values to whatever the load file is + deconstructMap(subSection, persistentData, field); + + try { + System.out.println("Map: " + field.get(persistentData).toString()); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + + } + } + } + + String keyToSet = (String) rootSection.getKeyValueMap().keySet().stream().filter(key -> key.toString().equalsIgnoreCase(field.getName())).findAny().orElse(null); + if (keyToSet != null) { + System.out.println("Key To Set: " + keyToSet); + try { + + // Casting string might not be a good idea. + String value = (String) rootSection.getKeyValueMap().get(keyToSet); + + System.out.println("Setting values for: " + field.getName()); + setField(field, persistentData, value.strip()); + + // Testing checks + if (field.getName().equalsIgnoreCase("currentStory")) { + System.out.println("Current Story: " + field.get(persistentData)); + } + if (field.getName().equalsIgnoreCase("currentScene")) { + System.out.println("Current Scene: " + field.get(persistentData)); + } + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } else { + System.err.println("Could not set field: " + field.getName()); + } + } + } + } + + private void deconstructMap(SectionKeyValue subSection, PersistentData data, Field field) { + Map objectMap; + try { + objectMap = (Map) field.get(data); + } catch (IllegalAccessException e) { + objectMap = new HashMap<>(); + } + + if (objectMap == null) { + System.out.println("Map was null. Defaulting..."); + objectMap = new HashMap<>(); + } + + Map finalObjectMap = objectMap; + subSection.getKeyValueMap().forEach((key, value) -> { + System.out.println("Setting map..."); + System.out.println(key + ": " + value); + finalObjectMap.put(key, value); + + }); + } + + private void setField(Field field, PersistentData data, String string2) throws NoSuchFieldException, IllegalAccessException { + field.setAccessible(true); + Type type = field.getGenericType(); + if (type.getTypeName().toLowerCase().contains("string")) { + field.set(data, string2); + } else if (type.getTypeName().toLowerCase().contains("int")) { + field.set(data, Integer.parseInt(string2)); + } else if (type.getTypeName().toLowerCase().contains("boolean")) { + field.set(data, Boolean.parseBoolean(string2)); + } else if (type.getTypeName().toLowerCase().contains("double")) { + field.set(data, Double.parseDouble(string2)); + } else if (type.getTypeName().toLowerCase().contains("float")) { + field.set(data, Float.parseFloat(string2)); + } else if (type.getTypeName().toLowerCase().contains("long")) { + field.set(data, Long.parseLong(string2)); + } else if (type.getTypeName().toLowerCase().contains("short")) { + field.set(data, Short.parseShort(string2)); + } else if (type.getTypeName().toLowerCase().contains("byte")) { + field.set(data, Byte.parseByte(string2)); + } } -} \ No newline at end of file +} diff --git a/src/main/java/me/piitex/renjava/api/saves/SaveFileUtils.java b/src/main/java/me/piitex/renjava/api/saves/SaveFileUtils.java deleted file mode 100644 index 640bbdd..0000000 --- a/src/main/java/me/piitex/renjava/api/saves/SaveFileUtils.java +++ /dev/null @@ -1,30 +0,0 @@ -package me.piitex.renjava.api.saves; - -public class SaveFileUtils { - - public static String toFormat(String data) { - StringBuilder builder = new StringBuilder(); - String[] clasz = data.split(";;;;"); - for (String s : clasz) { - String classname = "Unknown"; - String[] fields = s.split("@@@@"); - boolean clazDetect = false; - for (String s1 : fields) { - if (!clazDetect) { - classname = s1; - builder.append(classname).append(":").append("\n"); - clazDetect = true; - } else { - String field = s1.split("!!!!")[0]; - String value = s1.split("!!!!")[1]; - builder.append(" ").append(field).append(": ").append(value); - builder.append("\n"); - System.out.println("Class: " + classname); - System.out.println("Field: " + field); - System.out.println("Value: " + value); - } - } - } - return builder.toString(); - } -} diff --git a/src/main/java/me/piitex/renjava/api/saves/data/Mapper.java b/src/main/java/me/piitex/renjava/api/saves/data/Mapper.java new file mode 100644 index 0000000..9916f7f --- /dev/null +++ b/src/main/java/me/piitex/renjava/api/saves/data/Mapper.java @@ -0,0 +1,200 @@ +package me.piitex.renjava.api.saves.data; + +import java.util.HashMap; +import java.util.Map; + +public class Mapper { + + public static Map toStringMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put(objectObjectEntry.getKey().toString(), objectObjectEntry.getValue().toString()); + }); + return toReturn; + } + + public static Map toStringIntegerMap(Map map) { + System.out.println("Reconstructing map..."); + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put(objectObjectEntry.getKey().toString(), (Integer) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toStringBooleanMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put(objectObjectEntry.getKey().toString(), (Boolean) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toStringDoubleMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put(objectObjectEntry.getKey().toString(), (Double) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toStringLongMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put(objectObjectEntry.getKey().toString(), (Long) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toStringFloatMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put(objectObjectEntry.getKey().toString(), (Float) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toStringShortMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put(objectObjectEntry.getKey().toString(), (Short) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toStringByteMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put(objectObjectEntry.getKey().toString(), (Byte) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toIntergerStringMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Integer) objectObjectEntry.getKey(), objectObjectEntry.getValue().toString()); + }); + return toReturn; + } + + public static Map toInterMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Integer) objectObjectEntry.getKey(), (Integer) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toIntergerBooleanMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Integer) objectObjectEntry.getKey(), (Boolean) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toIntegerDoubleMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Integer) objectObjectEntry.getKey(), (Double) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toIntegerLong(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Integer) objectObjectEntry.getKey(), (Long) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toIntegerFloatMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Integer) objectObjectEntry.getKey(), (Float) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toIntegerShortMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Integer) objectObjectEntry.getKey(), (Short) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toIntegerByteMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Integer) objectObjectEntry.getKey(), (Byte) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toDoubleStringMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Double) objectObjectEntry.getKey(), objectObjectEntry.getValue().toString()); + }); + return toReturn; + } + + public static Map toDoubleIntergerMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Double) objectObjectEntry.getKey(), (Integer) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toDoubleBooleanMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Double) objectObjectEntry.getKey(), (Boolean) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toDoubleMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Double) objectObjectEntry.getKey(), (Double) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toDoubleLongMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Double) objectObjectEntry.getKey(), (Long) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toDoubleFloatMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Double) objectObjectEntry.getKey(), (Float) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toDoubleShortMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Double) objectObjectEntry.getKey(), (Short) objectObjectEntry.getValue()); + }); + return toReturn; + } + + public static Map toDoubleByteMap(Map map) { + Map toReturn = new HashMap<>(); + map.entrySet().forEach(objectObjectEntry -> { + toReturn.put((Double) objectObjectEntry.getKey(), (Byte) objectObjectEntry.getValue()); + }); + return toReturn; + } +} diff --git a/src/main/java/me/piitex/renjava/api/saves/file/SectionKeyValue.java b/src/main/java/me/piitex/renjava/api/saves/file/SectionKeyValue.java index 5cc89d5..98cb344 100644 --- a/src/main/java/me/piitex/renjava/api/saves/file/SectionKeyValue.java +++ b/src/main/java/me/piitex/renjava/api/saves/file/SectionKeyValue.java @@ -1,11 +1,13 @@ package me.piitex.renjava.api.saves.file; -import java.util.HashMap; -import java.util.Map; +import java.util.*; public class SectionKeyValue { private final String section; - private final Map keyValueMap = new HashMap<>(); + private final Map keyValueMap = new HashMap<>(); + private Collection subSection = new HashSet<>(); + + private Map> arrayMap = new HashMap<>(); public SectionKeyValue(String section) { this.section = section; @@ -19,7 +21,55 @@ public void addKeyValue(String key, String value) { keyValueMap.put(key, value); } - public Map getKeyValueMap() { + public void addSubSection(SectionKeyValue sectionKeyValue) { + subSection.add(sectionKeyValue); + } + + public void addArray(String field, String... values) { + ArrayList array = new ArrayList<>(List.of(values)); + arrayMap.put(field, array); + } + + public ArrayList getArray(String key) { + return arrayMap.get(key); + } + + public Collection getSubSections() { + return subSection; + } + + public Map> getArrayMap() { + return arrayMap; + } + + public Map getKeyValueMap() { return keyValueMap; } -} + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(section).append(":"); + keyValueMap.entrySet().forEach(stringStringEntry -> { + stringBuilder.append("\n").append("\t"); + stringBuilder.append(stringStringEntry.getKey()).append(": ").append(stringStringEntry.getValue()); + }); + arrayMap.entrySet().forEach(stringArrayListEntry -> { + stringBuilder.append("\n\t"); + stringBuilder.append(stringArrayListEntry.getKey()).append(": "); + for (int i = 0; i < stringArrayListEntry.getValue().size(); i++) { + stringBuilder.append(stringArrayListEntry.getValue().get(i).toString()); + if (i != stringArrayListEntry.getValue().size()) { + stringBuilder.append(","); + } + } + }); + if (!subSection.isEmpty()) { + for (SectionKeyValue sectionKeyValue : subSection) { + stringBuilder.append("\n\t"); + stringBuilder.append(sectionKeyValue.toString().replace("\t", "\t\t")); + } + } else { + stringBuilder.append("\n"); + } + return stringBuilder.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/me/piitex/renjava/events/defaults/GameFlowEventListener.java b/src/main/java/me/piitex/renjava/events/defaults/GameFlowEventListener.java index 2d8d3af..e7ba27b 100644 --- a/src/main/java/me/piitex/renjava/events/defaults/GameFlowEventListener.java +++ b/src/main/java/me/piitex/renjava/events/defaults/GameFlowEventListener.java @@ -78,7 +78,7 @@ public void onMouseClick(MouseClickEvent event) { menu.render(null, null); player.setRightClickMenu(true); - MainMenuRenderEvent renderEvent = new MainMenuRenderEvent(menu); + MainMenuRenderEvent renderEvent = new MainMenuRenderEvent(menu, true); RenJava.callEvent(renderEvent); } else { diff --git a/src/main/java/me/piitex/renjava/events/defaults/MenuClickEventListener.java b/src/main/java/me/piitex/renjava/events/defaults/MenuClickEventListener.java index 499f2db..45ea881 100644 --- a/src/main/java/me/piitex/renjava/events/defaults/MenuClickEventListener.java +++ b/src/main/java/me/piitex/renjava/events/defaults/MenuClickEventListener.java @@ -4,9 +4,9 @@ import javafx.scene.control.Button; import me.piitex.renjava.RenJava; -import me.piitex.renjava.api.saves.Load; import me.piitex.renjava.api.saves.Save; import me.piitex.renjava.api.saves.exceptions.SaveFileNotFound; +import me.piitex.renjava.api.stories.Story; import me.piitex.renjava.events.EventListener; import me.piitex.renjava.events.Listener; import me.piitex.renjava.events.types.ButtonClickEvent; @@ -20,15 +20,28 @@ public void onButtonClick(ButtonClickEvent event) { Button button = event.getButton(); if (button.getId().equalsIgnoreCase("menu-start-button")) { renJava.getLogger().info("Creating new game..."); + renJava.createBaseData(); + renJava.createStory(); renJava.start(); } if (button.getId().equalsIgnoreCase("menu-load-button")) { // NOTE: 10/20/2023 new LoadScreenView(new ImageLoader("gui/overlay/game_menu.png")).build(renJava.getStage(), true); - try { - new Load(1); - } catch (SaveFileNotFound e) { - throw new RuntimeException(e); - } + new Save(1).load(); + + + // After loading play the current scene and story + String storyID = renJava.getPlayer().getCurrentStoryID(); + System.out.println("Story: " + renJava.getPlayer().getCurrentStoryID()); + + renJava.createStory(); + + // Force update fields + renJava.getPlayer().setCurrentStory(storyID); + renJava.getPlayer().getCurrentStory().init(); // Re-initialize story + + renJava.getPlayer().setCurrentScene(renJava.getPlayer().getCurrentSceneID()); + + renJava.getPlayer().getCurrentStory().displayScene(renJava.getPlayer().getCurrentSceneID()); } if (button.getId().equalsIgnoreCase("menu-preference-button")) { //new PreferenceScreenView(new ImageLoader("gui/overlay/game_menu.png")).build(renJava.getStage(), true); @@ -44,7 +57,8 @@ public void onButtonClick(ButtonClickEvent event) { about.render(null, null); } if (button.getId().equalsIgnoreCase("menu-save-button")) { - new Save(1, renJava.getPlayer().getCurrentStory().getId(), renJava.getPlayer().getCurrentScene().getId()); + //new Save(1, renJava.getPlayer().getCurrentStory().getId(), renJava.getPlayer().getCurrentScene().getId()); + new Save(1).write(); // Writes the save. } if (button.getId().equalsIgnoreCase("menu-quit-button")) { renJava.getAddonLoader().disable(); diff --git a/src/main/java/me/piitex/renjava/events/defaults/StoryHandlerEventListener.java b/src/main/java/me/piitex/renjava/events/defaults/StoryHandlerEventListener.java index 3df1a19..8208142 100644 --- a/src/main/java/me/piitex/renjava/events/defaults/StoryHandlerEventListener.java +++ b/src/main/java/me/piitex/renjava/events/defaults/StoryHandlerEventListener.java @@ -23,7 +23,7 @@ public void onSceneStartEvent(SceneStartEvent event) { scene.getStartInterface().onStart(event); } if (story == null) return; - player.getViewedStories().put(story.getId(), story); + player.getViewedStories().add(story.getId()); // Check to see if this scene is the first scene in the story. if (story.getSceneIndex(scene) == 0) { // 0 means the first entry. // Update the story tracker From 26587d6325a28704581f6c5abf4c53591b289238 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:59:16 -0600 Subject: [PATCH 16/34] Code cleanup. --- .../java/me/piitex/renjava/api/builders/FontLoader.java | 8 +++++++- src/main/java/me/piitex/renjava/api/music/Tracks.java | 2 +- src/main/java/me/piitex/renjava/api/scenes/RenScene.java | 8 -------- .../renjava/api/scenes/types/choices/ChoiceScene.java | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/builders/FontLoader.java b/src/main/java/me/piitex/renjava/api/builders/FontLoader.java index 284a2c1..99bbe7e 100644 --- a/src/main/java/me/piitex/renjava/api/builders/FontLoader.java +++ b/src/main/java/me/piitex/renjava/api/builders/FontLoader.java @@ -19,6 +19,12 @@ public class FontLoader { private static final Map cachedFonts = new HashMap<>(); + public FontLoader(FontLoader font, double size) { + this.name = font.getName(); + this.size = size; + this.font = Font.font(font.getFont().getFamily(), size); + } + public FontLoader(Font font, double size) { this.name = font.getName(); this.size = size; @@ -39,7 +45,7 @@ public FontLoader(Font font, FontPosture posture, double size) { this.font = Font.font(font.getFamily(), posture, size); } - public FontLoader(String name, int size) { + public FontLoader(String name, double size) { this.name = name; File directory = new File(System.getProperty("user.dir") + "/game/fonts/"); File file = new File(directory, name); diff --git a/src/main/java/me/piitex/renjava/api/music/Tracks.java b/src/main/java/me/piitex/renjava/api/music/Tracks.java index 84b3215..d910d73 100644 --- a/src/main/java/me/piitex/renjava/api/music/Tracks.java +++ b/src/main/java/me/piitex/renjava/api/music/Tracks.java @@ -49,7 +49,7 @@ public void play(String fileName, boolean loop) { } public void play(Track track, boolean loop) { - if (currentTrack != null) { + if (getCurrentTrack() != null) { getCurrentTrack().stop(); } setPlaying(true); diff --git a/src/main/java/me/piitex/renjava/api/scenes/RenScene.java b/src/main/java/me/piitex/renjava/api/scenes/RenScene.java index 154a818..6c3adea 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/RenScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/RenScene.java @@ -1,9 +1,5 @@ package me.piitex.renjava.api.scenes; -import javafx.scene.Group; -import javafx.scene.control.Button; -import javafx.scene.image.ImageView; -import javafx.scene.text.Text; import me.piitex.renjava.RenJava; import me.piitex.renjava.api.scenes.animation.AnimationBuilder; import me.piitex.renjava.api.scenes.transitions.Transitions; @@ -19,11 +15,7 @@ import me.piitex.renjava.gui.StageType; import me.piitex.renjava.api.builders.ImageLoader; -import me.piitex.renjava.gui.overlay.ButtonOverlay; -import me.piitex.renjava.gui.overlay.ImageOverlay; import me.piitex.renjava.gui.overlay.Overlay; -import me.piitex.renjava.gui.overlay.TextOverlay; - import java.io.File; import java.util.Collection; diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java index 582ca21..7ac974b 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java @@ -150,8 +150,8 @@ public Menu build(boolean ui) { if (ui) { VerticalLayout layout = new VerticalLayout(500, 500); - layout.setXPosition(((RenJava.getInstance().getConfiguration().getWidth() - layout.getWidth()) / 2) - 600); - layout.setYPosition(((RenJava.getInstance().getConfiguration().getHeight() - layout.getHeight()) / 2) - 200); + layout.setX(((RenJava.getInstance().getConfiguration().getWidth() - layout.getWidth()) / 2) - 600); + layout.setY(((RenJava.getInstance().getConfiguration().getHeight() - layout.getHeight()) / 2) - 200); layout.setSpacing(20.0); ImageLoader choiceBoxImage = new ImageLoader("gui/button/choice_idle_background.png"); From af0b597432bcbc717b9cbb39102b863e5f8c2395 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:59:34 -0600 Subject: [PATCH 17/34] Implemented dialogue font. --- .../piitex/renjava/api/scenes/types/ImageScene.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java index b5195e6..e0af828 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java @@ -51,7 +51,7 @@ public class ImageScene extends RenScene { private Character character; private String dialogue; private ImageLoader backgroundImage; - + private Font font; private String characterDisplayName; private final RenJavaConfiguration configuration; @@ -81,6 +81,7 @@ public ImageScene(String id, @Nullable Character character, String dialogue, @Nu this.characterDisplayName = character.getDisplayName(); } configuration = renJava.getConfiguration(); + font = configuration.getDialogueFont().getFont(); } public ImageScene(String id, @Nullable Character character, String dialogue) { @@ -90,6 +91,7 @@ public ImageScene(String id, @Nullable Character character, String dialogue) { backgroundImage = renJava.getPlayer().getLastDisplayedImage().getValue(); setBackgroundImage(backgroundImage); configuration = renJava.getConfiguration(); + font = configuration.getDialogueFont().getFont(); } public Character getCharacter() { @@ -108,6 +110,14 @@ public void setDialogue(String dialogue) { this.dialogue = dialogue; } + public Font getDialogueFont() { + return font; + } + + public void setDialogueFont(Font font) { + this.font = font; + } + @Override public Menu build(boolean ui) { Menu rootMenu = new Menu(configuration.getWidth(), configuration.getHeight(), backgroundImage); @@ -142,6 +152,7 @@ public Menu build(boolean ui) { } textFlowOverlay.setX(configuration.getTextX() + configuration.getTextOffsetX()); textFlowOverlay.setY(configuration.getTextY() + configuration.getTextOffsetY()); + textFlowOverlay.setFont(font); textboxMenu.addOverlay(textFlowOverlay); characterDisplay.setFill(character.getColor()); From c47c7d16f39355525f2653749463a7b021fc3ae0 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sat, 2 Mar 2024 23:59:59 -0600 Subject: [PATCH 18/34] Added strikeout format. --- .../api/scenes/text/StringFormatter.java | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/scenes/text/StringFormatter.java b/src/main/java/me/piitex/renjava/api/scenes/text/StringFormatter.java index 1251828..9c49f3f 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/text/StringFormatter.java +++ b/src/main/java/me/piitex/renjava/api/scenes/text/StringFormatter.java @@ -17,6 +17,7 @@ public static LinkedList formatText(String dialogue) { boolean italic = false; boolean bold = false; + boolean strikeOut = false; int formatBeginChar = 0; LinkedList parts = new LinkedList<>(); @@ -29,24 +30,33 @@ public static LinkedList formatText(String dialogue) { } else if (c == '{' && dialogue.charAt(i + 1) == 'b') { formatBeginChar = i + 1; bold = true; + } else if (c == '{' && dialogue.charAt(i + 1) == 's') { + formatBeginChar = i + 1; + strikeOut = true; } else if (c == '{' && italic) { String italicText = dialogue.substring(formatBeginChar, i); - parts.add(beforeText.replace(italicText, "").replace("/i}", "").replace("/b}", "")); + parts.add(beforeText.replace(italicText, "").replace("/i}", "").replace("/b}", "").replace("/s}", "")); parts.add("iiii: " + italicText.replace("i}", "")); beforeText = ""; italic = false; } else if (c == '{' && bold) { String boldText = dialogue.substring(formatBeginChar, i); - parts.add(beforeText.replace(boldText, "").replace("/i}", "").replace("/b}", "")); + parts.add(beforeText.replace(boldText, "").replace("/i}", "").replace("/b}", "").replace("/s}", "")); parts.add("bbbb: " + boldText.replace("b}", "")); beforeText = ""; bold = false; + } else if (c == '{' && strikeOut) { + String strikeOutText = dialogue.substring(formatBeginChar, i); + parts.add(beforeText.replace(strikeOutText, "").replace("/s}", "").replace("/b}", "").replace("/i}", "")); + parts.add("ssss: " + strikeOutText.replace("s}", "")); + beforeText = ""; + strikeOut = false; } else { // Process text that is not formatted. beforeText += c; } } - beforeText = beforeText.replace("/i}", "").replace("/b}", ""); + beforeText = beforeText.replace("/i}", "").replace("/b}", "").replace("/s}", ""); parts.add(beforeText); LinkedList texts = new LinkedList<>(); @@ -67,6 +77,12 @@ public static LinkedList formatText(String dialogue) { Text text1 = new Text(s); text1.setFont(italicFont); texts.add(text1); + } else if (s.startsWith("ssss: ")) { + s = s.replace("ssss: ", ""); + Text text1 = new Text(s); + text1.setFont(currentFont); + text1.setStrikethrough(true); + texts.add(text1); } else { Text text1 = new Text(s); text1.setFont(currentFont); @@ -78,10 +94,11 @@ public static LinkedList formatText(String dialogue) { // Testing function. Should be removed later public static void main(String[] args) { - String data = "{i}Heey{/i} I've been waiting for you. You were {b}SUPPOSED{/b} to be here by now."; + String data = "{i}Heey...{/i} {s}I've been waiting for you.{/s} You were {b}SUPPOSED{/b} to be here by now."; boolean italic = false; boolean bold = false; + boolean strikeOut = false; int formatBeginChar = 0; @@ -95,10 +112,13 @@ public static void main(String[] args) { } else if (c == '{' && data.charAt(i + 1) == 'b') { formatBeginChar = i + 1; bold = true; + } else if (c == '{' && data.charAt(i + 1) == 's') { + formatBeginChar = i + 1; + strikeOut = true; } else if (c == '{' && italic) { String italicText = data.substring(formatBeginChar, i); System.out.println("Italic Text: " + italicText); - parts.add(beforeText.replace(italicText, "").replace("/i}", "").replace("/b}", "")); + parts.add(beforeText.replace(italicText, "").replace("/i}", "").replace("/b}", "").replace("/s}", "")); parts.add(italicText.replace("i}", "")); beforeText = ""; italic = false; @@ -106,10 +126,18 @@ public static void main(String[] args) { String boldText = data.substring(formatBeginChar, i); System.out.println("Bold Text: " + boldText); System.out.println("Before Text: " + beforeText); - parts.add(beforeText.replace(boldText, "").replace("/i}", "").replace("/b}", "")); + parts.add(beforeText.replace(boldText, "").replace("/i}", "").replace("/b}", "").replace("/s}", "")); parts.add(boldText.replace("b}", "")); beforeText = ""; bold = false; + } else if (c == '{' && strikeOut) { + String strikeOutText = data.substring(formatBeginChar, i); + System.out.println("StrikeOut Text: " + strikeOutText); + System.out.println("Before Text: " + beforeText); + parts.add(beforeText.replace(strikeOutText, "").replace("/s}", "").replace("/b}", "").replace("/i}", "")); + parts.add(strikeOutText.replace("s}", "")); + beforeText = ""; + strikeOut = false; } else { // Process text that is not formatted. beforeText += c; From f2cd408e07103a14442091e7ee359d2d30babac8 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Sun, 3 Mar 2024 00:00:24 -0600 Subject: [PATCH 19/34] Tagged more data to be saved. --- .../me/piitex/renjava/api/player/Player.java | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/player/Player.java b/src/main/java/me/piitex/renjava/api/player/Player.java index 829e262..2a03806 100644 --- a/src/main/java/me/piitex/renjava/api/player/Player.java +++ b/src/main/java/me/piitex/renjava/api/player/Player.java @@ -7,10 +7,7 @@ import me.piitex.renjava.api.scenes.RenScene; import me.piitex.renjava.api.stories.Story; -import java.util.AbstractMap; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.*; /** * Class that stores player data such as game progress and what scenes they have viewed. Some of the information stored is only useful to the framework but feel free to explore. @@ -28,15 +25,17 @@ public class Player implements PersistentData { private boolean skipAutoScene = false; - private final LinkedHashMap viewedStories = new LinkedHashMap<>(); // Ordered map of what stories the player has viewed. + //StoryID + @Data private LinkedHashSet viewedStories = new LinkedHashSet<>(); // Ordered map of what stories the player has viewed. private final Map viewedStoriesIndex = new HashMap<>(); // Indexing of the viewedStories - private final Map, RenScene> viewedScenes = new HashMap<>(); + // StoryID, SceneID + @Data private Map viewedScenes = new HashMap<>(); private final Map storyIdMap = new HashMap<>(); public boolean hasSeenScene(Story story, String sceneID) { - return viewedScenes.containsValue(story.getScene(sceneID)); + return viewedScenes.containsKey(story.getId()) && viewedScenes.containsValue(sceneID); } public RenScene getCurrentScene() { @@ -46,6 +45,14 @@ public RenScene getCurrentScene() { return null; // No story set has the game started? } + public String getCurrentSceneID() { + return currentScene; + } + + public String getCurrentStoryID() { + return currentStory; + } + public void setCurrentScene(String currentSceneID) { this.currentScene = currentSceneID; } @@ -57,7 +64,7 @@ public Story getCurrentStory() { public void setCurrentStory(String currentStoryID) { this.currentStory = currentStoryID; Story story = getStory(currentStoryID); - viewedStories.put(currentStoryID, story); // When setting story update the viewedStory for rollback. + viewedStories.add(currentStoryID); // When setting story update the viewedStory for rollback. int index = viewedStoriesIndex.size(); viewedStoriesIndex.put(index, story); } @@ -79,14 +86,18 @@ public Story getPreviousStory() { return viewedStoriesIndex.get(viewedStoriesIndex.size()); // Get last story } - public LinkedHashMap getViewedStories() { + public LinkedHashSet getViewedStories() { return viewedStories; } - public Map, RenScene> getViewedScenes() { + public Map getViewedScenes() { return viewedScenes; } + public Map getStoryIdMap() { + return storyIdMap; + } + public boolean isRightClickMenu() { return rightClickMenu; } @@ -129,7 +140,7 @@ public void setTransitionPlaying(boolean transitionPlaying) { public void updateScene(RenScene renScene) { setCurrentScene(renScene.getId()); // Update the scene. - getViewedScenes().put(new AbstractMap.SimpleEntry<>(renScene.getStory(), renScene.getId()), renScene); + getViewedScenes().put(renScene.getStory().getId(), renScene.getId()); setCurrentStory(renScene.getStory()); } } From 6d0fa6a1a2df93ceaf5cb8e4b5a876113b8bbac1 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Fri, 8 Mar 2024 00:25:42 -0600 Subject: [PATCH 20/34] Fixed copy and paste error for character display. --- .../java/me/piitex/renjava/api/scenes/types/ImageScene.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java index e0af828..5539db8 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java @@ -124,7 +124,7 @@ public Menu build(boolean ui) { if (ui) { Text characterDisplay = null; - if (dialogue != null && !dialogue.isEmpty()) { + if (character != null) { if (getCharacterNameDisplay() != null) { // Set character display characterDisplay = new Text(getCharacterNameDisplay()); From 110b419d57c9dc495d0e7b7b9a0239d3a882140a Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:22:50 -0500 Subject: [PATCH 21/34] Addon will now call the abstract method instead of using class functions. --- src/main/java/me/piitex/renjava/addons/AddonLoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/piitex/renjava/addons/AddonLoader.java b/src/main/java/me/piitex/renjava/addons/AddonLoader.java index 0d39e3f..7822b56 100644 --- a/src/main/java/me/piitex/renjava/addons/AddonLoader.java +++ b/src/main/java/me/piitex/renjava/addons/AddonLoader.java @@ -170,7 +170,8 @@ private void initAddon(File file, @Nullable Collection dependencies) thro addon.getDependencies().addAll(dependencies); } addons.add(addon); - clazz.getMethod("onLoad").invoke(object, null); + //clazz.getMethod("onLoad").invoke(object, null); + addon.onLoad(); // Loads addon logger.info("Loaded: " + addon.getName()); } } From 96f1bdf9b45d5e6ebd60939e596b2a8861fb1205 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:23:43 -0500 Subject: [PATCH 22/34] Added more exceptions for logging. --- .../renjava/api/exceptions/InvalidCharacterException.java | 8 ++++++++ .../renjava/api/exceptions/InvalidStoryException.java | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/main/java/me/piitex/renjava/api/exceptions/InvalidCharacterException.java create mode 100644 src/main/java/me/piitex/renjava/api/exceptions/InvalidStoryException.java diff --git a/src/main/java/me/piitex/renjava/api/exceptions/InvalidCharacterException.java b/src/main/java/me/piitex/renjava/api/exceptions/InvalidCharacterException.java new file mode 100644 index 0000000..cfd4729 --- /dev/null +++ b/src/main/java/me/piitex/renjava/api/exceptions/InvalidCharacterException.java @@ -0,0 +1,8 @@ +package me.piitex.renjava.api.exceptions; + +public class InvalidCharacterException extends Exception { + + public InvalidCharacterException(String characterID) { + super("Character '" + characterID + "' does not exist. Make sure the character is registered and created within the framework."); + } +} diff --git a/src/main/java/me/piitex/renjava/api/exceptions/InvalidStoryException.java b/src/main/java/me/piitex/renjava/api/exceptions/InvalidStoryException.java new file mode 100644 index 0000000..d2591b3 --- /dev/null +++ b/src/main/java/me/piitex/renjava/api/exceptions/InvalidStoryException.java @@ -0,0 +1,8 @@ +package me.piitex.renjava.api.exceptions; + +public class InvalidStoryException extends Exception { + + public InvalidStoryException(String id) { + super("Story '" + id + "' does not exist and thus could not be started. Ensure that the story class is registered within the framework. `new MyStoryClass()`"); + } +} From a8226ee7ec3411d9463f2b3879ba6160c2c0a0ce Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:24:20 -0500 Subject: [PATCH 23/34] Removed public access to stop function. --- src/main/java/me/piitex/renjava/api/music/Track.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/piitex/renjava/api/music/Track.java b/src/main/java/me/piitex/renjava/api/music/Track.java index 599c20e..167bbe3 100644 --- a/src/main/java/me/piitex/renjava/api/music/Track.java +++ b/src/main/java/me/piitex/renjava/api/music/Track.java @@ -47,7 +47,7 @@ public boolean isLoop() { return loop; } - public void stop() { + protected void stop() { if (player != null) { player.stop(); } From 445b59adee67ee8d6556aae023353210cfcdad61 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:25:29 -0500 Subject: [PATCH 24/34] Added get method for key-values. --- .../renjava/api/saves/file/SectionKeyValue.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/saves/file/SectionKeyValue.java b/src/main/java/me/piitex/renjava/api/saves/file/SectionKeyValue.java index 98cb344..3bb2f29 100644 --- a/src/main/java/me/piitex/renjava/api/saves/file/SectionKeyValue.java +++ b/src/main/java/me/piitex/renjava/api/saves/file/SectionKeyValue.java @@ -5,9 +5,9 @@ public class SectionKeyValue { private final String section; private final Map keyValueMap = new HashMap<>(); - private Collection subSection = new HashSet<>(); + private final Collection subSection = new HashSet<>(); - private Map> arrayMap = new HashMap<>(); + private final Map> arrayMap = new HashMap<>(); public SectionKeyValue(String section) { this.section = section; @@ -17,7 +17,7 @@ public String getSection() { return section; } - public void addKeyValue(String key, String value) { + public void addKeyValue(String key, Object value) { keyValueMap.put(key, value); } @@ -25,7 +25,7 @@ public void addSubSection(SectionKeyValue sectionKeyValue) { subSection.add(sectionKeyValue); } - public void addArray(String field, String... values) { + public void addArray(String field, Object... values) { ArrayList array = new ArrayList<>(List.of(values)); arrayMap.put(field, array); } @@ -46,6 +46,10 @@ public Map getKeyValueMap() { return keyValueMap; } + public Object get(String key) { + return keyValueMap.get(key); + } + public String toString() { StringBuilder stringBuilder = new StringBuilder(section).append(":"); keyValueMap.entrySet().forEach(stringStringEntry -> { From 2565ab58a4f565c0e80b7404403fba6deb409e19 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:26:31 -0500 Subject: [PATCH 25/34] Added mid-point calculation for alignment of choices. --- .../api/scenes/types/choices/ChoiceScene.java | 12 +++++-- .../configuration/RenJavaConfiguration.java | 32 +++++++++++++++---- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java index 7ac974b..848c89d 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/choices/ChoiceScene.java @@ -18,6 +18,7 @@ import me.piitex.renjava.gui.overlay.ButtonOverlay; import java.util.LinkedHashSet; +import java.util.Map; /** * The ChoiceScene class represents a scene in the RenJava framework that presents the player with multiple choices. @@ -150,8 +151,13 @@ public Menu build(boolean ui) { if (ui) { VerticalLayout layout = new VerticalLayout(500, 500); - layout.setX(((RenJava.getInstance().getConfiguration().getWidth() - layout.getWidth()) / 2) - 600); - layout.setY(((RenJava.getInstance().getConfiguration().getHeight() - layout.getHeight()) / 2) - 200); + //layout.setX(((double) (RenJava.getInstance().getConfiguration().getWidth() - layout.getWidth()) / 2) - 600); + //layout.setY(((double) (RenJava.getInstance().getConfiguration().getHeight() - layout.getHeight()) / 2) - 200); + Map.Entry midPoint = RenJava.getInstance().getConfiguration().getMidPoint(); + System.out.println("Set X: " + midPoint.getKey()); + System.out.println("Set Y: " + midPoint.getValue()); + layout.setX(midPoint.getKey() - 600); + layout.setY(midPoint.getValue() - 200); layout.setSpacing(20.0); ImageLoader choiceBoxImage = new ImageLoader("gui/button/choice_idle_background.png"); @@ -161,7 +167,7 @@ public Menu build(boolean ui) { buttonOverlay = new ButtonOverlay(getChoiceButton(choice, choiceBoxImage.build())); layout.addOverlays(buttonOverlay); } catch (ImageNotFoundException e) { - throw new RuntimeException(e); + RenJava.getInstance().getLogger().severe(e.getMessage()); } } menu.addLayout(layout); diff --git a/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java b/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java index dbaad52..e768da3 100644 --- a/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java +++ b/src/main/java/me/piitex/renjava/configuration/RenJavaConfiguration.java @@ -16,7 +16,8 @@ public class RenJavaConfiguration { private FontLoader defaultFont; private FontLoader dialogueFont; private FontLoader uiFont; - private Paint dialogueColor = Color.BLACK; + private FontLoader characterDisplayFont; + private Color dialogueColor = Color.BLACK; private int dialogueBoxWidth = 1000; private int dialogueBoxHeight = 600; @@ -105,11 +106,19 @@ public void setUiFont(FontLoader uiFont) { this.uiFont = uiFont; } - public Paint getDialogueColor() { + public FontLoader getCharacterDisplayFont() { + return characterDisplayFont; + } + + public void setCharacterDisplayFont(FontLoader characterDisplayFont) { + this.characterDisplayFont = characterDisplayFont; + } + + public Color getDialogueColor() { return dialogueColor; } - public void setDialogueColor(Paint dialogueColor) { + public void setDialogueColor(Color dialogueColor) { this.dialogueColor = dialogueColor; } @@ -257,7 +266,7 @@ public void setCharacterTextOffsetY(int characterTextOffsetY) { // bottom left is 0 on the x and max on the y public Map.Entry getBottomLeft() { - return Map.entry(5, getCurrentHeight()); + return Map.entry(0, getCurrentHeight()); } // Bottom right is max on both @@ -268,11 +277,22 @@ public Map.Entry getBottomRight() { // Top Left is 0,0 public Map.Entry getTopLeft() { - return Map.entry(5, 15); + return Map.entry(0, 0); } + // Top right is max width public Map.Entry getTopRight() { - return Map.entry(getCurrentWidth(), 5); + return Map.entry(getCurrentWidth(), 0); + } + + // Middle point of the screen. + public Map.Entry getMidPoint() { + Map.Entry bottomRight = getBottomRight(); + Map.Entry topLeft = getTopLeft(); + int centerX = (bottomRight.getKey() + topLeft.getKey()) / 2; + int centerY = (bottomRight.getValue() + topLeft.getValue()) / 2; + + return Map.entry(centerX, centerY); } public double getHeightScale() { From dc76aa71f21140f848fb6e02ada171dcff69cf88 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:27:13 -0500 Subject: [PATCH 26/34] Fixed logical error for null conditions. --- .../renjava/api/scenes/types/ImageScene.java | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java index 5539db8..c8cd128 100644 --- a/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java +++ b/src/main/java/me/piitex/renjava/api/scenes/types/ImageScene.java @@ -123,7 +123,7 @@ public Menu build(boolean ui) { Menu rootMenu = new Menu(configuration.getWidth(), configuration.getHeight(), backgroundImage); if (ui) { - Text characterDisplay = null; + Text characterDisplay; if (character != null) { if (getCharacterNameDisplay() != null) { // Set character display @@ -132,40 +132,41 @@ public Menu build(boolean ui) { characterDisplay = new Text(character.getDisplayName()); } characterDisplay.setFill(character.getColor()); - } - - if (dialogue != null && !dialogue.isEmpty()) { - ImageLoader textbox = new ImageLoader("gui/textbox.png"); - Menu textboxMenu = new Menu(configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); - - ImageOverlay textBoxImage = new ImageOverlay(textbox, configuration.getDialogueBoxX() + configuration.getDialogueOffsetX(), configuration.getDialogueBoxY() + configuration.getDialogueOffsetY()); - textboxMenu.addOverlay(textBoxImage); - LinkedList texts = StringFormatter.formatText(dialogue); - TextFlowOverlay textFlowOverlay; - if (texts.isEmpty()) { - Text text = new Text(dialogue); - text.setFont(renJava.getConfiguration().getDialogueFont().getFont()); - textFlowOverlay = new TextFlowOverlay(text, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); - } else { - textFlowOverlay = new TextFlowOverlay(texts, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); + if (dialogue != null && !dialogue.isEmpty()) { + ImageLoader textbox = new ImageLoader("gui/textbox.png"); + Menu textboxMenu = new Menu(configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); + + ImageOverlay textBoxImage = new ImageOverlay(textbox, configuration.getDialogueBoxX() + configuration.getDialogueOffsetX(), configuration.getDialogueBoxY() + configuration.getDialogueOffsetY()); + textboxMenu.addOverlay(textBoxImage); + + LinkedList texts = StringFormatter.formatText(dialogue); + TextFlowOverlay textFlowOverlay; + if (texts.isEmpty()) { + Text text = new Text(dialogue); + text.setFont(renJava.getConfiguration().getDialogueFont().getFont()); + textFlowOverlay = new TextFlowOverlay(text, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); + } else { + textFlowOverlay = new TextFlowOverlay(texts, configuration.getDialogueBoxWidth(), configuration.getDialogueBoxHeight()); + } + textFlowOverlay.setX(configuration.getTextX() + configuration.getTextOffsetX()); + textFlowOverlay.setY(configuration.getTextY() + configuration.getTextOffsetY()); + textFlowOverlay.setTextColor(configuration.getDialogueColor()); + textFlowOverlay.setFont(font); + textboxMenu.addOverlay(textFlowOverlay); + + characterDisplay.setFill(character.getColor()); + TextOverlay characterText = new TextOverlay(characterDisplay, new FontLoader(configuration.getDefaultFont().getFont(), configuration.getCharacterTextSize()), + configuration.getCharacterTextX() + configuration.getCharacterTextOffsetX(), + configuration.getCharacterTextY() + configuration.getCharacterTextOffsetY()); + + characterDisplay.setX(configuration.getCharacterTextX() + configuration.getCharacterTextOffsetX()); + characterDisplay.setY(configuration.getCharacterTextY() + configuration.getCharacterTextOffsetY()); + + textboxMenu.addOverlay(characterText); + + rootMenu.addMenu(textboxMenu); } - textFlowOverlay.setX(configuration.getTextX() + configuration.getTextOffsetX()); - textFlowOverlay.setY(configuration.getTextY() + configuration.getTextOffsetY()); - textFlowOverlay.setFont(font); - textboxMenu.addOverlay(textFlowOverlay); - - characterDisplay.setFill(character.getColor()); - TextOverlay characterText = new TextOverlay(characterDisplay, new FontLoader(configuration.getDefaultFont().getFont(), configuration.getCharacterTextSize()), - configuration.getCharacterTextX() + configuration.getCharacterTextOffsetX(), - configuration.getCharacterTextY() + configuration.getCharacterTextOffsetY()); - - characterDisplay.setX(configuration.getCharacterTextX() + configuration.getCharacterTextOffsetX()); - characterDisplay.setY(configuration.getCharacterTextY() + configuration.getCharacterTextOffsetY()); - - textboxMenu.addOverlay(characterText); - - rootMenu.addMenu(textboxMenu); } } @@ -192,7 +193,6 @@ public void render(Menu menu) { SceneStartEvent event = new SceneStartEvent(this); RenJava.callEvent(event); - } @Override From ed4e11b9f25983c06c364b662c5f7280226f91a2 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:27:43 -0500 Subject: [PATCH 27/34] Maps will now clear values before initialization. --- .../java/me/piitex/renjava/api/stories/Story.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/stories/Story.java b/src/main/java/me/piitex/renjava/api/stories/Story.java index f8e3853..a641497 100644 --- a/src/main/java/me/piitex/renjava/api/stories/Story.java +++ b/src/main/java/me/piitex/renjava/api/stories/Story.java @@ -115,15 +115,15 @@ public void start() { // Update RenJava Player BEFORE the scenes are added renJava.getPlayer().setCurrentStory(this.getId()); + clear(); // Clear previous mappings init(); // Initialize when starting logger.info("Building scene..."); RenScene renScene = getScene(0); // Gets the first scene index. + renJava.getPlayer().updateScene(renScene); // Set to current scene. Menu menu = renScene.build(true); - renJava.getPlayer().updateScene(renScene); // Set to current scene. - SceneBuildEvent buildEvent = new SceneBuildEvent(renScene, menu); RenJava.callEvent(buildEvent); @@ -152,6 +152,11 @@ public void refresh(String sceneID) { scenes.replace(sceneID, scene, scene); } + public void clear() { + scenes.clear(); + sceneIndexMap.clear(); + } + /** * Scenes are ordered the same way they are created. The first scene in a story is the first scene that was created. * @param scene Scene to add the story. @@ -273,11 +278,8 @@ public void displayScene(RenScene scene) { } public void displayNextScene() { - SceneEndEvent event = new SceneEndEvent(getPreviousSceneFromCurrent()); - RenJava.callEvent(event); RenScene renScene = getNextSceneFromCurrent(); - RenJava.getInstance().getPlayer().updateScene(renScene); - renScene.render(renScene.build(true)); + displayScene(renScene); } public LinkedHashMap getScenes() { From df0c8c8cc64c31bde51ff46bc19c8ed584a271ee Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:29:17 -0500 Subject: [PATCH 28/34] Started implementation of the loading and saving screen. --- .../me/piitex/renjava/api/saves/Save.java | 83 ++++++++++++++----- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/src/main/java/me/piitex/renjava/api/saves/Save.java b/src/main/java/me/piitex/renjava/api/saves/Save.java index f86b5a1..a793b30 100644 --- a/src/main/java/me/piitex/renjava/api/saves/Save.java +++ b/src/main/java/me/piitex/renjava/api/saves/Save.java @@ -1,10 +1,17 @@ package me.piitex.renjava.api.saves; +import javafx.scene.image.ImageView; +import javafx.scene.layout.Pane; import me.piitex.renjava.RenJava; +import me.piitex.renjava.api.builders.ImageLoader; import me.piitex.renjava.api.saves.data.Data; import me.piitex.renjava.api.saves.data.PersistentData; import me.piitex.renjava.api.saves.file.SectionKeyValue; +import me.piitex.renjava.api.scenes.RenScene; +import me.piitex.renjava.api.stories.Story; +import me.piitex.renjava.gui.Menu; +import me.piitex.renjava.gui.exceptions.ImageNotFoundException; import java.io.File; import java.io.FileNotFoundException; @@ -19,6 +26,10 @@ public class Save { private final File file; private int slot; + // Some ghetto code + // Map the scene when the load function is called. Easier way to get preview. + private SectionKeyValue sceneSection; + public Save(File file) { this.file = file; } @@ -60,7 +71,12 @@ public void write() { } // Handle fields try { + System.out.println("Processing field: " + field.getName()); Object object = field.get(data); + if (object == null) { + RenJava.getInstance().getLogger().warning("Value for '" + field.getName() + "' is null. Will not process data."); + continue; + } rootSection.addKeyValue(field.getName(), object.toString()); } catch (IllegalAccessException e) { throw new RuntimeException(e); @@ -104,22 +120,6 @@ private SectionKeyValue handleMap(PersistentData data, Field field) { } private void reconstructMap(SectionKeyValue sectionKeyValue, PersistentData data, Field field) throws IllegalAccessException { - // I don't think I need to actually re-create the map. Just in case, I will keep the Mapper class for now. - //String typeName = field.getGenericType().getTypeName(); - //typeName = typeName.replace("java.util.Map<", ""); - - // - - //String[] typeSplit = typeName.replace("<", "").replace(">", "").split(","); - //java.lang.String - //java.lang.Integer - - // Conversion is required as the map needs to be set to the actual type in order to save it. - //String key = typeSplit[0]; - //String value = typeSplit[1]; - - - Map map = (Map) field.get(data); map.entrySet().forEach(objectObjectEntry -> { System.out.println("Reconstructing entry..."); @@ -129,7 +129,7 @@ private void reconstructMap(SectionKeyValue sectionKeyValue, PersistentData data // Loads save file - public void load() { + public void load(boolean process) { // Collect and set string data to class data. // First loop the registered data and find the string data which corresponds with the data. @@ -196,7 +196,14 @@ public void load() { rootSection.addKeyValue(key.trim(), value.trim()); } } - processSection(persistentData, rootSection); + if (process) { + processSection(persistentData, rootSection); + } else { + if (rootSection.getSection().contains("me.piitex.renjava.api.player.Player")) { + System.out.println("Mapping scene..."); + sceneSection = rootSection; + } + } } } @@ -282,12 +289,13 @@ private void deconstructMap(SectionKeyValue subSection, PersistentData data, Fie objectMap = new HashMap<>(); } + + // TODO: 3/3/2024 Convert generic map type to actual type using the Mapper class Map finalObjectMap = objectMap; subSection.getKeyValueMap().forEach((key, value) -> { System.out.println("Setting map..."); System.out.println(key + ": " + value); finalObjectMap.put(key, value); - }); } @@ -312,4 +320,41 @@ private void setField(Field field, PersistentData data, String string2) throws N field.set(data, Byte.parseByte(string2)); } } + + // Builds the preview for saving and loading + public Pane buildPreview() { + Pane pane = new Pane(); + // Get the current scene the save is on. + // Build the scene. + // Scale it to a small box. + if (sceneSection == null) { + // Default image + ImageLoader saveImage = new ImageLoader("gui/button/slot_idle_background.png"); + try { + pane.getChildren().add(new ImageView(saveImage.build())); + } catch (ImageNotFoundException e) { + RenJava.getInstance().getLogger().severe(e.getMessage()); + } + } else { + Story story = RenJava.getInstance().getPlayer().getStory((String) sceneSection.get("currentStory")); + RenScene currentScene = story.getScene((String) sceneSection.get("currentScene")); + Menu menu = currentScene.build(true); + pane = menu.getPane(); + } + + // Scale the pane to fit a small box. + + // 414 x 309 + // 1920 1080 + // 0.2, 0.28 + pane.setMaxWidth(414); + pane.setMaxHeight(309); + + + return pane; + } + + public File getFile() { + return file; + } } From 3fb24f1d6018d7a2324bf08cd97aff94c8db51a0 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:29:24 -0500 Subject: [PATCH 29/34] GameStartEvent is now called when the game actually starts. --- .../events/defaults/MenuClickEventListener.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/piitex/renjava/events/defaults/MenuClickEventListener.java b/src/main/java/me/piitex/renjava/events/defaults/MenuClickEventListener.java index 45ea881..fc77b39 100644 --- a/src/main/java/me/piitex/renjava/events/defaults/MenuClickEventListener.java +++ b/src/main/java/me/piitex/renjava/events/defaults/MenuClickEventListener.java @@ -10,6 +10,7 @@ import me.piitex.renjava.events.EventListener; import me.piitex.renjava.events.Listener; import me.piitex.renjava.events.types.ButtonClickEvent; +import me.piitex.renjava.events.types.GameStartEvent; import me.piitex.renjava.gui.Menu; public class MenuClickEventListener implements EventListener { @@ -22,15 +23,25 @@ public void onButtonClick(ButtonClickEvent event) { renJava.getLogger().info("Creating new game..."); renJava.createBaseData(); renJava.createStory(); + + // Call GameStartEvent + GameStartEvent event1 = new GameStartEvent(renJava); + RenJava.callEvent(event1); + renJava.start(); } if (button.getId().equalsIgnoreCase("menu-load-button")) { // NOTE: 10/20/2023 new LoadScreenView(new ImageLoader("gui/overlay/game_menu.png")).build(renJava.getStage(), true); - new Save(1).load(); + new Save(1).load(true); // After loading play the current scene and story String storyID = renJava.getPlayer().getCurrentStoryID(); + if (storyID == null) { + renJava.getLogger().severe("Save file could not be loaded. The data is either not formatted or corrupted."); + return; + } + System.out.println("Story: " + renJava.getPlayer().getCurrentStoryID()); renJava.createStory(); From 724ab85d4acc8c1c324b53458a7654da95846c16 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:30:00 -0500 Subject: [PATCH 30/34] Layout and Menu overhaul. --- .../java/me/piitex/renjava/gui/Element.java | 1 - .../java/me/piitex/renjava/gui/GuiLoader.java | 9 +- .../me/piitex/renjava/gui/LayoutMenu.java | 92 +++++++++++++++++++ src/main/java/me/piitex/renjava/gui/Menu.java | 33 +++++-- .../piitex/renjava/gui/layouts/Container.java | 2 - .../me/piitex/renjava/gui/layouts/Layout.java | 11 ++- .../renjava/gui/layouts/ScrollPaneMenu.java | 25 +++++ .../gui/layouts/impl/HorizontalLayout.java | 1 - .../renjava/gui/overlay/TextFlowOverlay.java | 12 +++ 9 files changed, 168 insertions(+), 18 deletions(-) create mode 100644 src/main/java/me/piitex/renjava/gui/LayoutMenu.java create mode 100644 src/main/java/me/piitex/renjava/gui/layouts/ScrollPaneMenu.java diff --git a/src/main/java/me/piitex/renjava/gui/Element.java b/src/main/java/me/piitex/renjava/gui/Element.java index 5e002b1..5686ea6 100644 --- a/src/main/java/me/piitex/renjava/gui/Element.java +++ b/src/main/java/me/piitex/renjava/gui/Element.java @@ -9,7 +9,6 @@ import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; -import me.piitex.renjava.RenJava; import me.piitex.renjava.api.scenes.transitions.Transitions; import me.piitex.renjava.gui.overlay.*; diff --git a/src/main/java/me/piitex/renjava/gui/GuiLoader.java b/src/main/java/me/piitex/renjava/gui/GuiLoader.java index 4e408ef..1a4e8f4 100644 --- a/src/main/java/me/piitex/renjava/gui/GuiLoader.java +++ b/src/main/java/me/piitex/renjava/gui/GuiLoader.java @@ -25,8 +25,6 @@ public GuiLoader(Stage stage, RenJava renJava, HostServices services) { this.stage = stage; this.renJava = renJava; renJava.setHost(services); - GameStartEvent event = new GameStartEvent(renJava); - RenJava.callEvent(event); buildSplashScreen(); } @@ -38,7 +36,7 @@ private void buildSplashScreen() { Menu menu = renJava.buildSplashScreen(); if (menu == null) { - renJava.getLogger().warning("Splash screen not found."); + renJava.getLogger().warning("No splash screen was rendered.."); renJavaFrameworkBuild(); return; // Don't create a splash screen if one wasn't set. } @@ -71,6 +69,7 @@ private void buildMainMenu() { renJava.getLogger().severe("No default font set."); renJava.getConfiguration().setDefaultFont(new FontLoader("Arial", 24)); renJava.getConfiguration().setUiFont(new FontLoader("Arial", 26)); + renJava.getConfiguration().setCharacterDisplayFont(new FontLoader("Arial", 26)); } stage = new Stage(); @@ -88,10 +87,8 @@ private void buildMainMenu() { try { menu.setBackgroundImage(new ImageLoader("gui/main_menu.png").build()); } catch (ImageNotFoundException e) { - throw new RuntimeException(e); + logger.severe(e.getMessage()); } - } else { - logger.info("Rendering main menu..."); } Menu sideMenu = renJava.buildSideMenu(); diff --git a/src/main/java/me/piitex/renjava/gui/LayoutMenu.java b/src/main/java/me/piitex/renjava/gui/LayoutMenu.java new file mode 100644 index 0000000..5419058 --- /dev/null +++ b/src/main/java/me/piitex/renjava/gui/LayoutMenu.java @@ -0,0 +1,92 @@ +package me.piitex.renjava.gui; + +import javafx.scene.Node; +import me.piitex.renjava.gui.layouts.Layout; +import me.piitex.renjava.gui.overlay.Overlay; + +import java.util.LinkedHashSet; + +public abstract class LayoutMenu { + private final Menu menu; + private final int width, height; + private int x, y; + + private final LinkedHashSet nodes = new LinkedHashSet<>(); + private final LinkedHashSet layouts = new LinkedHashSet<>(); + private final LinkedHashSet overlays = new LinkedHashSet<>(); + private final LinkedHashSet children = new LinkedHashSet<>(); + + public LayoutMenu(Menu menu, int width, int height) { + this.menu = menu; + this.width = width; + this.height = height; + menu.addParent(this); + } + + public Menu getMenu() { + return menu; + } + + public abstract void render(); + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + public LinkedHashSet getNodes() { + return nodes; + } + + public void addNode(Node node) { + this.nodes.add(node); + } + + public LinkedHashSet getLayouts() { + return layouts; + } + + public LayoutMenu addLayout(Layout layout) { + layouts.add(layout); + return this; + } + + public LinkedHashSet getOverlays() { + return overlays; + } + + public LayoutMenu addOverlay(Overlay overlay) { + overlays.add(overlay); + return this; + } + + public LinkedHashSet getChildren() { + return children; + } + + /* Rendering functions */ + + public LayoutMenu addMenu(Menu menu) { + this.children.add(menu); + return this; + } +} diff --git a/src/main/java/me/piitex/renjava/gui/Menu.java b/src/main/java/me/piitex/renjava/gui/Menu.java index a935913..3f08c94 100644 --- a/src/main/java/me/piitex/renjava/gui/Menu.java +++ b/src/main/java/me/piitex/renjava/gui/Menu.java @@ -5,7 +5,6 @@ import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.layout.*; -import javafx.scene.paint.Color; import javafx.stage.Stage; import me.piitex.renjava.RenJava; @@ -18,8 +17,6 @@ import me.piitex.renjava.gui.overlay.*; import org.jetbrains.annotations.Nullable; -import java.io.File; -import java.net.MalformedURLException; import java.util.LinkedHashSet; import java.util.logging.Logger; @@ -39,7 +36,7 @@ public class Menu { private Image backgroundImage; private final LinkedHashSet nodes = new LinkedHashSet<>(); - + private final LinkedHashSet parents = new LinkedHashSet<>(); private final LinkedHashSet layouts = new LinkedHashSet<>(); private final LinkedHashSet overlays = new LinkedHashSet<>(); private final LinkedHashSet children = new LinkedHashSet<>(); @@ -137,6 +134,14 @@ public Menu addOverlay(Overlay overlay) { return this; } + public LinkedHashSet getParents() { + return parents; + } + + public void addParent(LayoutMenu layoutMenu) { + parents.add(layoutMenu); + } + public LinkedHashSet getChildren() { return children; } @@ -160,7 +165,6 @@ public Menu addMenu(Menu menu) { * @param renScene The RenScene that is being used. If null, it will be assumed this is a main menu screen. */ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { - Logger logger = renJava.getLogger(); if (root == null) { @@ -169,7 +173,6 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { root.setTranslateX(x); root.setTranslateY(y); - root.setPrefSize(width, height); // Background fill is used for fade ins. @@ -186,7 +189,23 @@ public Pane render(@Nullable Pane root, @Nullable RenScene renScene) { for (Overlay overlay : layout.getOverlays()) { new Element(overlay).render(layout.getPane()); } - + for (Layout child : layout.getChildLayouts()) { + // A child layout should be added to a main layout. + for (Overlay overlay : child.getOverlays()) { + new Element(overlay).render(child.getPane()); + } + + Pane childPane = layout.getPane(); + childPane.setTranslateX(child.getX()); + childPane.setTranslateY(child.getY()); + childPane.setPrefSize(child.getWidth(), child.getHeight()); + if (childPane instanceof HBox hBox) { + hBox.setSpacing(layout.getSpacing()); + } else if (childPane instanceof VBox vBox) { + vBox.setSpacing(layout.getSpacing()); + } + layout.getPane().getChildren().add(childPane); // Adds the child layout to the main layout. + } Pane box = layout.getPane(); box.setTranslateX(layout.getX()); box.setTranslateY(layout.getY()); diff --git a/src/main/java/me/piitex/renjava/gui/layouts/Container.java b/src/main/java/me/piitex/renjava/gui/layouts/Container.java index 751c35e..840569b 100644 --- a/src/main/java/me/piitex/renjava/gui/layouts/Container.java +++ b/src/main/java/me/piitex/renjava/gui/layouts/Container.java @@ -2,8 +2,6 @@ import javafx.stage.Stage; import me.piitex.renjava.gui.Menu; -import me.piitex.renjava.gui.layouts.Layout; -import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.HashSet; diff --git a/src/main/java/me/piitex/renjava/gui/layouts/Layout.java b/src/main/java/me/piitex/renjava/gui/layouts/Layout.java index e94dfcd..280da3e 100644 --- a/src/main/java/me/piitex/renjava/gui/layouts/Layout.java +++ b/src/main/java/me/piitex/renjava/gui/layouts/Layout.java @@ -9,11 +9,12 @@ public abstract class Layout { private final Pane pane; // Get's the pane type for javafx - private final LinkedHashSet overlays = new LinkedHashSet<>(); private double x; private double y; private int width, height; private double spacing; + private final LinkedHashSet overlays = new LinkedHashSet<>(); + private final LinkedHashSet childLayouts = new LinkedHashSet<>(); protected Layout(Pane pane) { this.pane = pane; @@ -70,4 +71,12 @@ public Collection getOverlays() { public void addOverlays(Overlay... overlays) { this.overlays.addAll(List.of(overlays)); } + + public void addChildLayout(Layout layout) { + this.childLayouts.add(layout); + } + + public LinkedHashSet getChildLayouts() { + return childLayouts; + } } diff --git a/src/main/java/me/piitex/renjava/gui/layouts/ScrollPaneMenu.java b/src/main/java/me/piitex/renjava/gui/layouts/ScrollPaneMenu.java new file mode 100644 index 0000000..80aa92a --- /dev/null +++ b/src/main/java/me/piitex/renjava/gui/layouts/ScrollPaneMenu.java @@ -0,0 +1,25 @@ +package me.piitex.renjava.gui.layouts; + +import javafx.scene.control.ScrollPane; +import javafx.scene.layout.Pane; + +import me.piitex.renjava.gui.Menu; +import me.piitex.renjava.gui.LayoutMenu; + +public class ScrollPaneMenu extends LayoutMenu { + + public ScrollPaneMenu(Menu menu, int width, int height) { + super(menu, width, height); + } + + @Override + public void render() { + Pane pane = getMenu().getPane(); + ScrollPane scrollPane = new ScrollPane(); + scrollPane.setPrefSize(getWidth(), getHeight()); + scrollPane.setTranslateX(getX()); + scrollPane.setTranslateY(getY()); + + pane.getChildren().add(scrollPane); // Adds to menu + } +} diff --git a/src/main/java/me/piitex/renjava/gui/layouts/impl/HorizontalLayout.java b/src/main/java/me/piitex/renjava/gui/layouts/impl/HorizontalLayout.java index b527d8c..44168f8 100644 --- a/src/main/java/me/piitex/renjava/gui/layouts/impl/HorizontalLayout.java +++ b/src/main/java/me/piitex/renjava/gui/layouts/impl/HorizontalLayout.java @@ -2,7 +2,6 @@ import javafx.scene.layout.HBox; import me.piitex.renjava.gui.layouts.Layout; -import me.piitex.renjava.gui.overlay.Overlay; /** * Groups overlays and elements horizontally. diff --git a/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java b/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java index 299139f..9ce93eb 100644 --- a/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java +++ b/src/main/java/me/piitex/renjava/gui/overlay/TextFlowOverlay.java @@ -1,5 +1,7 @@ package me.piitex.renjava.gui.overlay; +import javafx.scene.paint.Color; +import javafx.scene.paint.Paint; import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.scene.text.TextFlow; @@ -12,6 +14,7 @@ public class TextFlowOverlay implements Overlay { private double y; private Transitions transitions; private Font font; + private Color textColor; private LinkedList texts = new LinkedList<>(); @@ -61,6 +64,14 @@ public void setFont(Font font) { this.font = font; } + public Color getTextColor() { + return textColor; + } + + public void setTextColor(Color textColor) { + this.textColor = textColor; + } + @Override public Transitions getTransition() { return transitions; @@ -88,6 +99,7 @@ public TextFlow build() { if (font != null) { text.setFont(font); } + text.setFill(textColor); textFlow.getChildren().add(text); } From b61079bd879c662ff08b6a0cde12e5141ac1e559 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:30:48 -0500 Subject: [PATCH 31/34] Replaced constructor parameters with runtime annotation. --- src/main/java/me/piitex/renjava/Game.java | 17 ++++ src/main/java/me/piitex/renjava/Launch.java | 57 ++++++------- src/main/java/me/piitex/renjava/RenJava.java | 86 ++++++++++++++++---- 3 files changed, 115 insertions(+), 45 deletions(-) create mode 100644 src/main/java/me/piitex/renjava/Game.java diff --git a/src/main/java/me/piitex/renjava/Game.java b/src/main/java/me/piitex/renjava/Game.java new file mode 100644 index 0000000..89da13f --- /dev/null +++ b/src/main/java/me/piitex/renjava/Game.java @@ -0,0 +1,17 @@ +package me.piitex.renjava; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Used to set default information about the game. Use this annotation to tag the ReJava class constructor. + */ +@Target(ElementType.CONSTRUCTOR) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface Game { + String name() default ("Name"); + String author() default("Author"); + String version() default("1.0"); +} diff --git a/src/main/java/me/piitex/renjava/Launch.java b/src/main/java/me/piitex/renjava/Launch.java index e854703..a7a69b7 100644 --- a/src/main/java/me/piitex/renjava/Launch.java +++ b/src/main/java/me/piitex/renjava/Launch.java @@ -15,49 +15,50 @@ import org.reflections.util.ConfigurationBuilder; import java.util.HashSet; +import java.util.stream.Collectors; public class Launch extends Application { public static void main(String[] args) { // Scans for all classes in all packages. (We need to do all packages because this allows the author the freedom to do their own package scheme.) - Collection allPackagePrefixes = Arrays.stream(Package.getPackages()).map(Package::getName) - .map(s -> s.split("\\.")[0]).distinct().map(ClasspathHelper::forPackage).reduce((c1, c2) -> { - Collection c3 = new HashSet<>(); - c3.addAll(c1); - c3.addAll(c2); - return c3; - }).get(); + Collection allPackagePrefixes = Arrays.stream(Package.getPackages()) + .map(Package::getName) + .map(s -> s.split("\\.")[0]) + .distinct() + .map(ClasspathHelper::forPackage) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); ConfigurationBuilder config = new ConfigurationBuilder().addUrls(allPackagePrefixes) .addScanners(Scanners.SubTypes); Reflections reflections = new Reflections(config); // Detect any classes that extend RenJava - Class renJavaClass = null; for (Class c : reflections.getSubTypesOf(RenJava.class)) { - - // Checks for default RenJava class: This was removed but could be re-added at a later date. - if (c.getName().contains("Example")) { - renJavaClass = c; - } else { - try { - c.getDeclaredConstructor().newInstance(); - launch(args); - } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | - InvocationTargetException e) { - e.printStackTrace(); + try { + Object o = c.getDeclaredConstructor().newInstance(); + RenJava renJava = (RenJava) o; + if (c.getDeclaredConstructor().isAnnotationPresent(Game.class)) { + Game game = c.getDeclaredConstructor().getAnnotation(Game.class); + renJava.name = game.name(); + renJava.author = game.author(); + renJava.version = game.version(); + } else { + System.err.println("Please annotate your main constructor with Game.\n\t\t@Game\n\t\tpublic void " + c.getDeclaredConstructor().getName() + "() { }"); + renJava.name = "Error"; + renJava.author = "Error"; + renJava.version = "Error"; } - return; - } - } - - try { - if (renJavaClass != null) { - renJavaClass.getDeclaredConstructor().newInstance(); + renJava.init(); // Initialize game launch(args); + //c.getDeclaredConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | + InvocationTargetException e) { + e.printStackTrace(); } - } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - e.printStackTrace(); + return; } + + System.err.println("Could not initialize RenJava. Please make a class which extends 'RenJava'."); } @Override diff --git a/src/main/java/me/piitex/renjava/RenJava.java b/src/main/java/me/piitex/renjava/RenJava.java index b7f0bbd..e10d5fd 100644 --- a/src/main/java/me/piitex/renjava/RenJava.java +++ b/src/main/java/me/piitex/renjava/RenJava.java @@ -9,7 +9,9 @@ import me.piitex.renjava.addons.Addon; import me.piitex.renjava.addons.AddonLoader; import me.piitex.renjava.api.builders.ImageLoader; +import me.piitex.renjava.api.exceptions.InvalidCharacterException; import me.piitex.renjava.api.music.Tracks; +import me.piitex.renjava.api.saves.Save; import me.piitex.renjava.api.saves.data.Data; import me.piitex.renjava.api.saves.data.PersistentData; import me.piitex.renjava.api.characters.Character; @@ -26,6 +28,8 @@ import me.piitex.renjava.gui.exceptions.ImageNotFoundException; import me.piitex.renjava.gui.Menu; +import me.piitex.renjava.gui.layouts.Layout; +import me.piitex.renjava.gui.layouts.impl.HorizontalLayout; import me.piitex.renjava.gui.layouts.impl.VerticalLayout; import me.piitex.renjava.gui.overlay.ButtonOverlay; import me.piitex.renjava.gui.StageType; @@ -62,14 +66,14 @@ * Note: Do not call the `RenJava` constructor directly. The framework creates a new instance of your class automatically using reflections. */ public abstract class RenJava { - private final String name; - private final String author; - private final String version; - private final Logger logger; - private final Player player; + protected String name; + protected String author; + protected String version; + private Logger logger; + private Player player; // Audio Tracking - private final Tracks tracks; - private final AddonLoader addonLoader; + private Tracks tracks; + private AddonLoader addonLoader; private Stage stage; // Move this somewhere else. private StageType stageType; @@ -93,16 +97,28 @@ public abstract class RenJava { * Entry point for the RenJava framework. This class is designed to be extended by your own class, which will serve as the entry point for your game. *

* Note: Do not call this constructor directly. The RenJava framework creates a new instance of your class automatically using reflection. + *

+ * Make sure to use {@link Game} to specify the information of the game. + *

{@code
+     * public class YourGame extends RenJava {
      *
-     * @param name    The name of the game, used for displaying the game in the window and other various places.
-     * @param author  The author of the game.
-     * @param version The current version of the game, used to display specific information about the game.
+     *     @Game(name = "Your Game", author = "You", version = "1.0")
+     *     public YourGame() {
+     *
+     *     }
+     * }
+     * }
+ * If you do not specify the game information it will assume default values. + * + * @see Game */ - public RenJava(String name, String author, String version) { + public RenJava() { + // Super is ran first than the superior method is ran. instance = this; - this.name = name; - this.author = author; - this.version = version; + } + + protected void init() { + // Run after super this.player = new Player(); this.tracks = new Tracks(); // Load logger @@ -227,6 +243,10 @@ public Collection getCharacters() { * @see RenJava#registerCharacter(Character) */ public Character getCharacter(String id) { + if (!registeredCharacters.containsKey(id)) { + getLogger().severe(new InvalidCharacterException(id).getMessage()); + return null; + } return registeredCharacters.get(id.toLowerCase()); } @@ -303,7 +323,7 @@ public void buildStage(Stage stage) { } else { stage.setMaximized(true); } - stage.setTitle(getName()); + stage.setTitle(getConfiguration().getGameTitle()); stage.setOnHiding(windowEvent -> { getAddonLoader().disable(); @@ -415,8 +435,40 @@ public Menu buildSideMenu() { return menu; } - public Menu buildLoadMenu() { + public Menu buildLoadMenu(int page) { Menu menu = new Menu(1920, 1080, new ImageLoader("gui/main_menu.png")); + // Setup pagination. + // 6 save slots per page + // 2 Rows + // 3 Columns + // Make this customizable + + int maxSavesPerPage = 6; + + int index = 1; + VerticalLayout rootLayout = new VerticalLayout(1000, 400); // The root is a vertical which stacks the two horizontal layouts. + HorizontalLayout topLayout = new HorizontalLayout(1000, 200); + HorizontalLayout bottomLayout = new HorizontalLayout(1000, 200); + while (index <= maxSavesPerPage) { + // Create a button overlay of the scene that the save file would have been on., + // This will be a little challenging, it should be possible given the api of the Save object. + Save save = new Save(index); + if (save.getFile() != null) { + if (index <= 3) { + // Top layout + + } else { + // Bottom layout + } + } else { + // Process empty slot + } + index++; + } + + rootLayout.addChildLayout(topLayout); + rootLayout.addChildLayout(bottomLayout); + return menu; } @@ -487,7 +539,7 @@ public Menu buildAboutScreen() { * Example usage: *
{@code
      *     // Get the current story from the StoryManager
-     *     Story myStory = this.getStoryManager().getStory("my-story");
+     *     Story myStory = this.getPlayer().getStory("my-story");
      *     // Start the story
      *     myStory.start();
      * }
From a7ae6c5a53a9305dd7e1454257dec2a7cc612d73 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:31:18 -0500 Subject: [PATCH 32/34] Application will auto-shutdown if the game folder does not exist. --- .../java/me/piitex/renjava/RenLoader.java | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/main/java/me/piitex/renjava/RenLoader.java b/src/main/java/me/piitex/renjava/RenLoader.java index e3f25b0..3ffb0a1 100644 --- a/src/main/java/me/piitex/renjava/RenLoader.java +++ b/src/main/java/me/piitex/renjava/RenLoader.java @@ -1,45 +1,50 @@ package me.piitex.renjava; import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collection; import java.util.Properties; -import java.util.stream.Stream; +import javafx.application.Platform; import me.piitex.renjava.api.builders.FontLoader; import me.piitex.renjava.api.music.Track; import me.piitex.renjava.configuration.SettingsProperties; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.DirectoryFileFilter; -import org.apache.commons.io.filefilter.RegexFileFilter; public class RenLoader { private final RenJava renJava; - + boolean shutdown = false; public RenLoader(RenJava renJava) { this.renJava = renJava; renJava.getLogger().info("Starting processes..."); renJava.buildVersion = getVersion(); setupMain(); setupGame(); + if (shutdown) { + // Shutdown application. + renJava.getLogger().severe("Game assets do not exist. Please download default assets and place them inside the 'game' folder."); + Platform.exit(); + System.exit(0); + return; + } startPreProcess(); } private void setupMain() { renJava.getLogger().info("Checking game environment..."); + + File gameDirectory = new File(System.getProperty("user.dir") + "/game/"); if (gameDirectory.mkdir()) { renJava.getLogger().severe("Game directory does not exist. The game will not work properly, please move all assets into the newly created game directory."); + shutdown = true; } File renJavaDirectory = new File(System.getProperty("user.dir") + "/renjava/"); - renJavaDirectory.mkdir(); + if (renJavaDirectory.mkdir()) { + renJava.getLogger().warning("RenJava folder does not exist. User settings will be reset to defaults."); + } File logFile = new File(System.getProperty("user.dir"), "log.txt"); try { logFile.createNewFile(); } catch (IOException e) { - e.printStackTrace(); + renJava.getLogger().warning("Could not create log file. Ensure the application has read and write permissions."); } for (File file : new File(System.getProperty("user.dir")).listFiles()) { if (file.getName().endsWith(".txt.lck")) { @@ -60,11 +65,17 @@ private void setupGame() { } renJava.getLogger().info("Loaded " + audioLoaded + " audio file(s)"); File imageDirectory = new File(directory, "/images/"); - imageDirectory.mkdir(); + if (imageDirectory.mkdir()) { + renJava.getLogger().warning("Images folder does not exist, creating..."); + } File savesDirectory = new File(directory, "/saves/"); - savesDirectory.mkdir(); + if (savesDirectory.mkdir()) { + renJava.getLogger().warning("Saves folder does not exist, creating..."); + } File fontsDirectory = new File(directory, "/fonts/"); - fontsDirectory.mkdir(); + if (fontsDirectory.mkdir()) { + renJava.getLogger().warning("Fonts folder does not exist, creating..."); + } renJava.getLogger().info("Loading fonts..."); int fonts = 0; From 09c165d4a2c27823b3e3d713a8f16cb68cb1bc9f Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:31:53 -0500 Subject: [PATCH 33/34] Pom.xml for next version. --- pom.xml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index db06adb..c574289 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ me.piitex RenJava - 0.0.757-SNAPSHOT + 0.0.802-SNAPSHOT RenJava @@ -102,12 +102,6 @@ 9.0.4 compile - - commons-io - commons-io - 2.15.1 - compile - From 780612df6e5589a91e161f61f34f08429bca0680 Mon Sep 17 00:00:00 2001 From: Hackusate_PvP Date: Thu, 14 Mar 2024 04:32:25 -0500 Subject: [PATCH 34/34] Added api function to start a story. --- .../java/me/piitex/renjava/api/player/Player.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/me/piitex/renjava/api/player/Player.java b/src/main/java/me/piitex/renjava/api/player/Player.java index 2a03806..0f491cd 100644 --- a/src/main/java/me/piitex/renjava/api/player/Player.java +++ b/src/main/java/me/piitex/renjava/api/player/Player.java @@ -1,7 +1,9 @@ package me.piitex.renjava.api.player; +import me.piitex.renjava.RenJava; import me.piitex.renjava.api.APINote; import me.piitex.renjava.api.builders.ImageLoader; +import me.piitex.renjava.api.exceptions.InvalidStoryException; import me.piitex.renjava.api.saves.data.Data; import me.piitex.renjava.api.saves.data.PersistentData; import me.piitex.renjava.api.scenes.RenScene; @@ -98,6 +100,16 @@ public Map getStoryIdMap() { return storyIdMap; } + public void startStory(String id) { + if (!storyIdMap.containsKey(id)) { + RenJava.getInstance().getLogger().severe(new InvalidStoryException(id).getMessage()); + return; + } + RenJava.getInstance().getLogger().info("Starting story '" + id + "'"); + RenJava.getInstance().getPlayer().setCurrentStory(id); + getStory(id).start(); + } + public boolean isRightClickMenu() { return rightClickMenu; }