aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/module-info.java2
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/Driver.java23
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/DiffEditor.java26
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/DiffList.java29
-rw-r--r--src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java5
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/LevelEditor.java54
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/LevelList.java13
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/editor/NotesEditor.java12
-rw-r--r--src/main/java/net/sowgro/npehero/editor/NotesEditor2.java11
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gameplay/Block.java2
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gameplay/SongPlayer.java3
-rw-r--r--src/main/java/net/sowgro/npehero/gui/ControlEditor.java1
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gui/GameOver.java14
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gui/LeaderboardView.java8
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gui/LevelDetails.java4
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gui/LevelSelector.java4
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gui/LevelSurround.java6
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gui/MainMenu.java5
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/gui/SettingsEditor.java3
-rw-r--r--src/main/java/net/sowgro/npehero/levelapi/Difficulties.java127
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/levelapi/Difficulty.java95
-rw-r--r--src/main/java/net/sowgro/npehero/levelapi/Leaderboard.java81
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/levelapi/LeaderboardEntry.java24
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/levelapi/Level.java152
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/levelapi/Levels.java (renamed from src/main/java/net/sowgro/npehero/main/Levels.java)59
-rw-r--r--src/main/java/net/sowgro/npehero/levelapi/Note.java (renamed from src/main/java/net/sowgro/npehero/main/Note.java)12
-rw-r--r--src/main/java/net/sowgro/npehero/levelapi/Notes.java107
-rw-r--r--src/main/java/net/sowgro/npehero/main/Control.java19
-rw-r--r--src/main/java/net/sowgro/npehero/main/Difficulties.java86
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/main/Difficulty.java87
-rw-r--r--src/main/java/net/sowgro/npehero/main/JSONFile.java108
-rw-r--r--src/main/java/net/sowgro/npehero/main/Leaderboard.java94
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/main/LeaderboardEntry.java28
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/main/Level.java137
-rw-r--r--src/main/java/net/sowgro/npehero/main/Notes.java100
-rwxr-xr-xsrc/main/java/net/sowgro/npehero/main/Settings.java28
36 files changed, 819 insertions, 750 deletions
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 09cc9e7..02dcac8 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -3,7 +3,7 @@ module net.sowgro.npehero {
requires javafx.fxml;
requires javafx.media;
requires java.desktop;
- requires com.fasterxml.jackson.databind;
+ requires com.google.gson;
exports net.sowgro.npehero;
} \ No newline at end of file
diff --git a/src/main/java/net/sowgro/npehero/Driver.java b/src/main/java/net/sowgro/npehero/Driver.java
index 3e1bd6e..2845cf4 100755
--- a/src/main/java/net/sowgro/npehero/Driver.java
+++ b/src/main/java/net/sowgro/npehero/Driver.java
@@ -13,12 +13,12 @@ import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Duration;
import net.sowgro.npehero.editor.ErrorDisplay;
+import net.sowgro.npehero.levelapi.Levels;
import net.sowgro.npehero.main.*;
import net.sowgro.npehero.gui.MainMenu;
-import java.io.FileNotFoundException;
+import java.io.IOException;
import java.net.URL;
-import java.util.List;
import java.util.Stack;
@@ -81,21 +81,30 @@ public class Driver extends Application
primaryStage.show();
Stack<String> errors = new Stack<>();
+ System.out.println("Loading settings...");
try {
Settings.read();
+ System.out.println("Settings loaded");
} catch (Exception e) {
+ e.printStackTrace();
errors.push("Failed to load settings from file\n"+e);
}
- try {
- Levels.readData();
- } catch (FileNotFoundException e) {
- errors.push("Failed to load levels: Level folder is missing\n");
- }
+ System.out.println("Loading controls...");
try {
Control.readFromFile();
+ System.out.println("Controls loaded");
} catch (Exception e) {
+ e.printStackTrace();
errors.push("Failed to load controls from file\n"+e);
}
+ System.out.println("Loading levels...");
+ try {
+ Levels.readData();
+ System.out.println("Loaded " + Levels.list.size() + " levels (" + Levels.getValidList().size() + " valid)");
+ } catch (IOException e) {
+ e.printStackTrace();
+ errors.push("Failed to load levels\n");
+ }
Page last = new MainMenu();
while (!errors.empty()) {
last = new ErrorDisplay(errors.pop(), last);
diff --git a/src/main/java/net/sowgro/npehero/editor/DiffEditor.java b/src/main/java/net/sowgro/npehero/editor/DiffEditor.java
index 6940485..0eb4968 100755
--- a/src/main/java/net/sowgro/npehero/editor/DiffEditor.java
+++ b/src/main/java/net/sowgro/npehero/editor/DiffEditor.java
@@ -11,8 +11,12 @@ import net.sowgro.npehero.gameplay.Block;
import net.sowgro.npehero.gui.LevelSurround;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.Note;
import net.sowgro.npehero.main.*;
+import java.io.IOException;
+
public class DiffEditor extends Page
{
Difficulty diff;
@@ -37,13 +41,15 @@ public class DiffEditor extends Page
editNotes.setOnAction(_ -> {
if (diff.level.song == null) {
Driver.setMenu(new ErrorDisplay("You must import a song file before editing the notes!", this));
+ return;
}
if (diff.bpm != 0.0) {
Driver.setMenu(new ErrorDisplay(
- "Note:\nThe new notes editor does not support bpm and beat based songs. If you continue the beats will be converted to seconds.",
+ "Note:\nThe new notes editor does not support bpm and beat based songs. If you continue, the notes will be converted.",
this,
new NotesEditor2(diff, this)
));
+ return;
}
Driver.setMenu(new NotesEditor2(diff, this));
});
@@ -57,7 +63,15 @@ public class DiffEditor extends Page
Label scoresLable = new Label("Scores");
Button editScores = new Button("Clear leaderboard");
- editScores.setOnAction(_ -> diff.leaderboard.entries.clear());
+ editScores.setOnAction(_ -> {
+ diff.leaderboard.entries.clear();
+ try {
+ diff.leaderboard.save();
+ } catch (IOException e) {
+ e.printStackTrace();
+ Driver.setMenu(new ErrorDisplay("Failed to clear the leaderboard:\n"+e, this));
+ }
+ });
Button playLevel = new Button("Play level");
playLevel.setOnAction(_ -> {
@@ -74,7 +88,13 @@ public class DiffEditor extends Page
diff.title = title.getText();
// diff.bpm = Double.parseDouble(bpm.getText());
// diff.numBeats = Integer.parseInt(numBeats.getText());
- diff.write();
+ try {
+ diff.writeMetadata();
+ } catch (IOException e) {
+ e.printStackTrace();
+ //TODO
+ throw new RuntimeException(e);
+ }
});
HBox scrollContent = new HBox();
diff --git a/src/main/java/net/sowgro/npehero/editor/DiffList.java b/src/main/java/net/sowgro/npehero/editor/DiffList.java
index 7017c32..9e2df9b 100755
--- a/src/main/java/net/sowgro/npehero/editor/DiffList.java
+++ b/src/main/java/net/sowgro/npehero/editor/DiffList.java
@@ -9,12 +9,13 @@ import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import net.sowgro.npehero.Driver;
-import net.sowgro.npehero.main.Difficulty;
-import net.sowgro.npehero.main.Level;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.Level;
import net.sowgro.npehero.main.Page;
import net.sowgro.npehero.main.Sound;
import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
import java.util.Collections;
public class DiffList extends Page
@@ -68,6 +69,7 @@ public class DiffList extends Page
try {
level.difficulties.remove(diffs.getSelectionModel().getSelectedItem());
} catch (IOException ex) {
+ ex.printStackTrace();
Driver.setMenu(new ErrorDisplay("Failed to remove difficulty\n"+e, this));
}
});
@@ -76,7 +78,11 @@ public class DiffList extends Page
Button refresh = new Button("Refresh");
refresh.setOnAction(e -> {
-// level.readData();
+ try {
+ level.difficulties.read();
+ } catch (IOException ex) {
+ // TODO
+ }
// diffs.setItems(level.difficulties.list.sorted());
diffs.refresh();
});
@@ -93,7 +99,12 @@ public class DiffList extends Page
return;
}
Collections.swap(diffList, oldIndex, oldIndex-1);
- level.difficulties.saveOrder();
+ try {
+ level.difficulties.saveOrder();
+ } catch (IOException e) {
+ e.printStackTrace();
+ Driver.setMenu(new ErrorDisplay("Failed to move difficulty\n"+e,this));
+ }
});
Button moveDown = new Button("Move Down");
@@ -106,7 +117,12 @@ public class DiffList extends Page
return;
}
Collections.swap(diffList, oldIndex, oldIndex+1);
- level.difficulties.saveOrder();
+ try {
+ level.difficulties.saveOrder();
+ } catch (IOException e) {
+ e.printStackTrace();
+ Driver.setMenu(new ErrorDisplay("Failed to move difficulty\n"+e,this));
+ }
});
VBox buttons = new VBox();
@@ -148,8 +164,11 @@ public class DiffList extends Page
newLevelButton.setOnAction(_ -> {
try {
level.difficulties.add(newLevelEntry.getText());
+ } catch (FileAlreadyExistsException e) {
+ Driver.setMenu(new ErrorDisplay("Failed to add level\nA difficulty already exists with the folder name " + e.getFile(), this));
} catch (IOException e) {
Driver.setMenu(new ErrorDisplay("Failed to add level\n"+e, this));
+ e.printStackTrace();
}
newLevelEntry.clear();
refresh.fire();
diff --git a/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java b/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java
index b3ec751..c07d12f 100644
--- a/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java
+++ b/src/main/java/net/sowgro/npehero/editor/ErrorDisplay.java
@@ -23,9 +23,11 @@ public class ErrorDisplay extends Page {
public ErrorDisplay(String message, Page prev) {
Label main = new Label(message);
main.getStyleClass().add("box");
+ main.setPadding(new Insets(10));
+ main.setWrapText(true);
Button exit = new Button();
- exit.setText("Back");
+ exit.setText("Ok");
exit.setOnAction(e -> {
Sound.playSfx(Sound.BACKWARD);
Driver.setMenu(prev);
@@ -50,6 +52,7 @@ public class ErrorDisplay extends Page {
Label main = new Label(message);
main.getStyleClass().add("box");
main.setPadding(new Insets(10));
+ main.setWrapText(true);
Button exit = new Button();
exit.setText("Cancel");
diff --git a/src/main/java/net/sowgro/npehero/editor/LevelEditor.java b/src/main/java/net/sowgro/npehero/editor/LevelEditor.java
index b3ae2b8..ae56d44 100755
--- a/src/main/java/net/sowgro/npehero/editor/LevelEditor.java
+++ b/src/main/java/net/sowgro/npehero/editor/LevelEditor.java
@@ -1,6 +1,7 @@
package net.sowgro.npehero.editor;
import java.io.File;
+import java.io.IOException;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.geometry.Pos;
@@ -10,10 +11,16 @@ import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
import net.sowgro.npehero.Driver;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.Level;
import net.sowgro.npehero.main.*;
public class LevelEditor extends Page
{
+ private final ValidIndicator songValid = new ValidIndicator();
+ private final ValidIndicator diffsInvalid = new ValidIndicator();
+ Level level;
+
private HBox content = new HBox();
private File selectedSong = null;
@@ -22,6 +29,7 @@ public class LevelEditor extends Page
public LevelEditor(Level level, Page prev)
{
+ this.level = level;
Text folderNameLabel = new Text("Folder name");
TextField folderName = new TextField();
if (level.dir != null) {
@@ -55,10 +63,6 @@ public class LevelEditor extends Page
HBox colorPickerBox = new HBox();
colorPickerBox.getChildren().addAll(colorsPickers);
- ValidIndicator songValid = new ValidIndicator();
- if (level.song == null) {
- songValid.setInvalid("Missing song file!");
- }
HBox filesLabel = new HBox(new Text("Files"), songValid);
FileChooser backgroundChooser = new FileChooser();
@@ -77,10 +81,6 @@ public class LevelEditor extends Page
songButton.setOnAction(_ -> selectedSong = songChooser.showOpenDialog(Driver.primaryStage));
- ValidIndicator diffsInvalid = new ValidIndicator();
- if (level.difficulties.getValidList().isEmpty()) {
- diffsInvalid.setInvalid("This level contains no valid difficulties!");
- }
HBox diffLabel = new HBox(new Text("Difficulties"), diffsInvalid);
diffLabel.setSpacing(5);
@@ -134,18 +134,25 @@ public class LevelEditor extends Page
try {
if (selectedBackground != null && selectedBackground.exists()) {
- level.addFile(selectedBackground, "background." + getFileExtension(selectedBackground));
+ level.addFile(selectedBackground, "background");
}
if (selectedPreview != null && selectedPreview.exists()) {
- level.addFile(selectedPreview, "preview." + getFileExtension(selectedPreview));
+ level.addFile(selectedPreview, "preview");
}
if (selectedSong != null) {
- level.addFile(selectedSong, "song." + getFileExtension(selectedSong));
+ level.addFile(selectedSong, "song");
}
- } catch (Exception _) {
+ } catch (Exception ex) {
+ // TODO
+ ex.printStackTrace();
+ }
+ try {
+ level.writeMetadata();
+ } catch (IOException ex) {
// TODO
+ ex.printStackTrace();
}
- level.writeMetadata();
+ validate();
});
VBox left = new VBox(filesLabel, songButton, previewButton, backgroundButton, colorsLabel, colorPickerBox);
@@ -189,12 +196,19 @@ public class LevelEditor extends Page
return content;
}
- /**
- * Get the extension of a file.
- * @param file The file to return the extension of
- * @return The extension of the file in the format "*.ext"
- */
- public String getFileExtension(File file) {
- return file.getName().substring(file.getName().lastIndexOf('.') + 1);
+ @Override
+ public void onView() {
+ validate();
+ }
+
+ public void validate() {
+ if (level.difficulties.getValidList().isEmpty()) {
+ diffsInvalid.setInvalid("This level contains no valid difficulties!");
+ } else {
+ diffsInvalid.setValid();
+ }
+ if (level.song == null) {
+ songValid.setInvalid("Missing song file!");
+ }
}
} \ No newline at end of file
diff --git a/src/main/java/net/sowgro/npehero/editor/LevelList.java b/src/main/java/net/sowgro/npehero/editor/LevelList.java
index 1bc85dd..86c65b5 100755
--- a/src/main/java/net/sowgro/npehero/editor/LevelList.java
+++ b/src/main/java/net/sowgro/npehero/editor/LevelList.java
@@ -9,13 +9,14 @@ import net.sowgro.npehero.Driver;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import net.sowgro.npehero.gui.MainMenu;
-import net.sowgro.npehero.main.Level;
-import net.sowgro.npehero.main.Levels;
+import net.sowgro.npehero.levelapi.Level;
+import net.sowgro.npehero.levelapi.Levels;
import net.sowgro.npehero.main.Page;
import net.sowgro.npehero.main.Sound;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
public class LevelList extends Page
{
@@ -71,6 +72,7 @@ public class LevelList extends Page
Levels.remove(levels.getSelectionModel().getSelectedItem());
} catch (IOException ex) {
Driver.setMenu(new ErrorDisplay("Failed to remove this level\n"+e.toString(), this));
+ ex.printStackTrace();
}
});
remove.setDisable(true);
@@ -80,8 +82,9 @@ public class LevelList extends Page
refresh.setOnAction(e -> {
try {
Levels.readData();
- } catch (FileNotFoundException ex) {
+ } catch (IOException ex) {
Driver.setMenu(new ErrorDisplay("Failed to load levels: Level folder is missing\n"+e.toString(), this));
+ ex.printStackTrace();
}
levels.setItems(Levels.list);
});
@@ -135,8 +138,12 @@ public class LevelList extends Page
newLevelButton.setOnAction(_ -> {
try {
Levels.add(newLevelEntry.getText());
+ } catch (FileAlreadyExistsException e) {
+ Driver.setMenu(new ErrorDisplay("Failed to add level\nA level already exists with the folder name " + e.getFile(), this));
+ e.printStackTrace();
} catch (IOException e) {
Driver.setMenu(new ErrorDisplay("Failed to create this level\n"+e.toString(), this));
+ e.printStackTrace();
}
newLevelEntry.clear();
refresh.fire();
diff --git a/src/main/java/net/sowgro/npehero/editor/NotesEditor.java b/src/main/java/net/sowgro/npehero/editor/NotesEditor.java
index 133330f..da5af33 100755
--- a/src/main/java/net/sowgro/npehero/editor/NotesEditor.java
+++ b/src/main/java/net/sowgro/npehero/editor/NotesEditor.java
@@ -16,7 +16,7 @@ import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import net.sowgro.npehero.main.Control;
-import net.sowgro.npehero.main.Difficulty;
+import net.sowgro.npehero.levelapi.Difficulty;
import net.sowgro.npehero.main.Page;
import net.sowgro.npehero.main.Sound;
@@ -64,11 +64,11 @@ public class NotesEditor extends Page
content.getChildren().add(centerBox);
content.setAlignment(Pos.CENTER);
- try {
- writer = new PrintWriter(diff.notes.getFile(), "UTF-8");
- } catch (FileNotFoundException | UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
+// try {
+// writer = new PrintWriter(diff.notes.getFile(), "UTF-8");
+// } catch (FileNotFoundException | UnsupportedEncodingException e) {
+// throw new RuntimeException(e);
+// }
Scene scene = Driver.primaryStage.getScene();
scene.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
diff --git a/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java b/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java
index 8d17900..b6810d8 100644
--- a/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java
+++ b/src/main/java/net/sowgro/npehero/editor/NotesEditor2.java
@@ -16,7 +16,6 @@ import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
-import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
@@ -25,9 +24,12 @@ import javafx.util.Duration;
import net.sowgro.npehero.Driver;
import net.sowgro.npehero.gameplay.Block;
import net.sowgro.npehero.gameplay.Target;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.Note;
import net.sowgro.npehero.main.*;
import net.sowgro.npehero.main.Control;
+import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
public class NotesEditor2 extends Page {
@@ -164,7 +166,12 @@ public class NotesEditor2 extends Page {
save.setText("Save");
save.setOnAction(_ -> {
diff.notes.list = noteList;
- diff.notes.writeFile();
+ try {
+ diff.notes.writeFile();
+ } catch (IOException e) {
+ // TODO
+ throw new RuntimeException(e);
+ }
diff.endTime = newEndTime.get();
Sound.playSfx(Sound.BACKWARD);
Driver.setMenu(new DiffEditor(diff, prev.prev));
diff --git a/src/main/java/net/sowgro/npehero/gameplay/Block.java b/src/main/java/net/sowgro/npehero/gameplay/Block.java
index c55a7bf..9d68ab6 100755
--- a/src/main/java/net/sowgro/npehero/gameplay/Block.java
+++ b/src/main/java/net/sowgro/npehero/gameplay/Block.java
@@ -6,7 +6,7 @@ import javafx.scene.effect.BlurType;
import javafx.scene.effect.DropShadow;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
-import net.sowgro.npehero.main.Note;
+import net.sowgro.npehero.levelapi.Note;
/**
* A block is a visual representation of a note on the screen. This is used both in the editor and in during the game play.
diff --git a/src/main/java/net/sowgro/npehero/gameplay/SongPlayer.java b/src/main/java/net/sowgro/npehero/gameplay/SongPlayer.java
index 36f706c..33f9a51 100755
--- a/src/main/java/net/sowgro/npehero/gameplay/SongPlayer.java
+++ b/src/main/java/net/sowgro/npehero/gameplay/SongPlayer.java
@@ -1,6 +1,5 @@
package net.sowgro.npehero.gameplay;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
@@ -14,6 +13,8 @@ import javafx.event.EventHandler;
import javafx.scene.input.KeyEvent;
import javafx.scene.media.Media;
import net.sowgro.npehero.Driver;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.Level;
import net.sowgro.npehero.main.*;
import net.sowgro.npehero.gui.GameOver;
import javafx.geometry.Pos;
diff --git a/src/main/java/net/sowgro/npehero/gui/ControlEditor.java b/src/main/java/net/sowgro/npehero/gui/ControlEditor.java
index 90161e0..7fd288b 100644
--- a/src/main/java/net/sowgro/npehero/gui/ControlEditor.java
+++ b/src/main/java/net/sowgro/npehero/gui/ControlEditor.java
@@ -76,6 +76,7 @@ public class ControlEditor extends Page {
Control.writeToFile();
} catch (IOException e) {
Driver.setMenu(new ErrorDisplay("An error occured while saving your controls\n"+e, this));
+ e.printStackTrace();
}
});
controlButton.setOnAction(_ -> {
diff --git a/src/main/java/net/sowgro/npehero/gui/GameOver.java b/src/main/java/net/sowgro/npehero/gui/GameOver.java
index dd23f5f..b66d0c6 100755
--- a/src/main/java/net/sowgro/npehero/gui/GameOver.java
+++ b/src/main/java/net/sowgro/npehero/gui/GameOver.java
@@ -10,11 +10,14 @@ import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import net.sowgro.npehero.Driver;
-import net.sowgro.npehero.main.Difficulty;
-import net.sowgro.npehero.main.Level;
+import net.sowgro.npehero.editor.ErrorDisplay;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.Level;
import net.sowgro.npehero.main.Page;
import net.sowgro.npehero.main.Sound;
+import java.io.IOException;
+
public class GameOver extends Page
{
HBox content = new HBox();
@@ -67,7 +70,12 @@ public class GameOver extends Page
Sound.playSfx(Sound.FORWARD);
save.setDisable(true);
name.setDisable(true);
- diff.leaderboard.add(name.getText(), score2);
+ try {
+ diff.leaderboard.add(name.getText(), score2);
+ } catch (IOException e) {
+ e.printStackTrace();
+ Driver.setMenu(new ErrorDisplay("Failed to save score to leaderboard:\n"+e, this));
+ }
});
BorderPane b = new BorderPane();
diff --git a/src/main/java/net/sowgro/npehero/gui/LeaderboardView.java b/src/main/java/net/sowgro/npehero/gui/LeaderboardView.java
index 46ce22f..1a87e27 100755
--- a/src/main/java/net/sowgro/npehero/gui/LeaderboardView.java
+++ b/src/main/java/net/sowgro/npehero/gui/LeaderboardView.java
@@ -10,6 +10,8 @@ import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import net.sowgro.npehero.Driver;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.LeaderboardEntry;
import net.sowgro.npehero.main.*;
public class LeaderboardView extends Page
@@ -29,9 +31,9 @@ public class LeaderboardView extends Page
scores.getColumns().add(scoreCol);
scores.getColumns().add(dateCol);
- nameCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().getName()));
- scoreCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().getScore() + ""));
- dateCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().getDate()));
+ nameCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().name));
+ scoreCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().score + ""));
+ dateCol.setCellValueFactory(data -> new ReadOnlyStringWrapper(data.getValue().date));
scores.setItems(diff.leaderboard.entries);
diff --git a/src/main/java/net/sowgro/npehero/gui/LevelDetails.java b/src/main/java/net/sowgro/npehero/gui/LevelDetails.java
index 4bd1e09..55c45bd 100755
--- a/src/main/java/net/sowgro/npehero/gui/LevelDetails.java
+++ b/src/main/java/net/sowgro/npehero/gui/LevelDetails.java
@@ -15,8 +15,8 @@ import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.scene.text.TextFlow;
import net.sowgro.npehero.Driver;
-import net.sowgro.npehero.main.Difficulty;
-import net.sowgro.npehero.main.Level;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.Level;
import net.sowgro.npehero.main.Sound;
public class LevelDetails extends VBox
diff --git a/src/main/java/net/sowgro/npehero/gui/LevelSelector.java b/src/main/java/net/sowgro/npehero/gui/LevelSelector.java
index 3c8f25f..b2c028b 100755
--- a/src/main/java/net/sowgro/npehero/gui/LevelSelector.java
+++ b/src/main/java/net/sowgro/npehero/gui/LevelSelector.java
@@ -9,8 +9,8 @@ import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import net.sowgro.npehero.Driver;
-import net.sowgro.npehero.main.Level;
-import net.sowgro.npehero.main.Levels;
+import net.sowgro.npehero.levelapi.Level;
+import net.sowgro.npehero.levelapi.Levels;
import net.sowgro.npehero.main.Page;
import net.sowgro.npehero.main.Sound;
diff --git a/src/main/java/net/sowgro/npehero/gui/LevelSurround.java b/src/main/java/net/sowgro/npehero/gui/LevelSurround.java
index ea1eb30..8ab722d 100755
--- a/src/main/java/net/sowgro/npehero/gui/LevelSurround.java
+++ b/src/main/java/net/sowgro/npehero/gui/LevelSurround.java
@@ -11,8 +11,8 @@ import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
-import net.sowgro.npehero.main.Difficulty;
-import net.sowgro.npehero.main.Level;
+import net.sowgro.npehero.levelapi.Difficulty;
+import net.sowgro.npehero.levelapi.Level;
import net.sowgro.npehero.gameplay.ScoreController;
import net.sowgro.npehero.main.Page;
import net.sowgro.npehero.main.Sound;
@@ -28,7 +28,7 @@ public class LevelSurround extends Page
Button exit = new Button();
exit.setText("Back");
- exit.setOnAction(e -> {
+ exit.setOnAction(_ -> {
Driver.setMenu(prev);
Sound.playSfx(Sound.BACKWARD);
game.cancel();
diff --git a/src/main/java/net/sowgro/npehero/gui/MainMenu.java b/src/main/java/net/sowgro/npehero/gui/MainMenu.java
index 3b8c8db..6160245 100755
--- a/src/main/java/net/sowgro/npehero/gui/MainMenu.java
+++ b/src/main/java/net/sowgro/npehero/gui/MainMenu.java
@@ -1,5 +1,6 @@
package net.sowgro.npehero.gui;
+import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.effect.BlurType;
@@ -55,8 +56,8 @@ public class MainMenu extends Page {
exit.setOnAction(_ -> {
Sound.playSfx(Sound.BACKWARD);
// Driver.quit();
-// Platform.exit();
- System.exit(0);
+ Platform.exit();
+// System.exit(0);
});
VBox buttonBox = new VBox();
diff --git a/src/main/java/net/sowgro/npehero/gui/SettingsEditor.java b/src/main/java/net/sowgro/npehero/gui/SettingsEditor.java
index 12555ed..efd136a 100755
--- a/src/main/java/net/sowgro/npehero/gui/SettingsEditor.java
+++ b/src/main/java/net/sowgro/npehero/gui/SettingsEditor.java
@@ -95,7 +95,8 @@ public class SettingsEditor extends Page
try {
Settings.save();
} catch (IOException ex) {
- Driver.setMenu(new ErrorDisplay("Failed to save settings"+e, this));
+ ex.printStackTrace();
+ Driver.setMenu(new ErrorDisplay("Failed to save settings"+ex, this));
}
Sound.playSfx(Sound.BACKWARD);
Driver.setMenu(new MainMenu());
diff --git a/src/main/java/net/sowgro/npehero/levelapi/Difficulties.java b/src/main/java/net/sowgro/npehero/levelapi/Difficulties.java
new file mode 100644
index 0000000..cffd95e
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/levelapi/Difficulties.java
@@ -0,0 +1,127 @@
+package net.sowgro.npehero.levelapi;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Responsible for the list of difficulties in a level
+ */
+public class Difficulties {
+
+ public final ObservableList<Difficulty> list = FXCollections.observableArrayList();
+ public final HashMap<String, Exception> problems = new HashMap<>();
+
+ private final Level level;
+
+ /**
+ * Creates a new Difficulties object
+ * @param level the file path of the level
+ * @throws IOException If there is a problem reading in the difficulties
+ */
+ public Difficulties(Level level) throws IOException {
+ this.level = level;
+ read();
+ }
+
+ /**
+ * Loads difficulties
+ * <p>
+ * Creates difficulty objects out of each subfolder in the level and adds it to the list.
+ * @throws IOException If there is a problem reading in the difficulties
+ */
+ public void read() throws IOException {
+ list.clear();
+ File[] fileList = level.dir.listFiles();
+ if (fileList == null) {
+ throw new FileNotFoundException();
+ }
+ for(File cur: fileList) {
+ if (cur.isDirectory()) {
+ try {
+ Difficulty diff = new Difficulty(cur, level);
+ list.add(diff);
+ } catch (IOException e) {
+ problems.put("", e);
+ e.printStackTrace();
+ }
+ }
+ }
+ list.sort(Comparator.naturalOrder());
+ }
+
+ /**
+ * Removes a difficulty
+ * <p>
+ * Recursively deletes the folder and removes it from the list
+ * @param diff: The difficulty to remove.
+ * @throws IOException If there is a problem removing the difficulty.
+ */
+ public void remove(Difficulty diff) throws IOException {
+ File hold = diff.thisDir;
+ Files.walk(hold.toPath())
+ .sorted(Comparator.reverseOrder())
+ .map(Path::toFile)
+ .forEach(File::delete);
+ list.remove(diff);
+ }
+
+ /**
+ * Adds a difficulty
+ * <p>
+ * Creates the directory and required files
+ * @param text The name of the directory
+ * @throws IOException If there is a problem adding the level
+ */
+ public void add(String text) throws IOException {
+ File diffDir = new File(level.dir, text.toLowerCase().replaceAll("\\W+", "-"));
+ if (diffDir.exists()) {
+ throw new FileAlreadyExistsException(diffDir.getName());
+ }
+ if (diffDir.mkdirs()) {
+ Difficulty temp = new Difficulty(diffDir, level);
+ temp.title = text;
+ list.add(temp);
+ list.sort(Comparator.naturalOrder());
+ }
+ else {
+ throw new IOException();
+ }
+ }
+
+ /**
+ * Saves the order of the difficulties in the list
+ * <p>
+ * Updates the order variable of each difficulty in the list to match their index in the list
+ * @throws IOException If there is a problem saving the difficulty's metadata file
+ */
+ public void saveOrder() throws IOException {
+ for (Difficulty d : list) {
+ d.order = list.indexOf(d);
+ d.writeMetadata();
+ }
+ }
+
+ /**
+ * Get a list of only the valid difficulties in the level.
+ * @return A list of the valid difficulties.
+ */
+ public List<Difficulty> getValidList() {
+ ObservableList<Difficulty> validList = FXCollections.observableArrayList();
+ for (Difficulty difficulty : list) {
+ if (difficulty.isValid()) {
+ validList.add(difficulty);
+ }
+ }
+ return validList;
+ }
+}
diff --git a/src/main/java/net/sowgro/npehero/levelapi/Difficulty.java b/src/main/java/net/sowgro/npehero/levelapi/Difficulty.java
new file mode 100755
index 0000000..2e99a7a
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/levelapi/Difficulty.java
@@ -0,0 +1,95 @@
+package net.sowgro.npehero.levelapi;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.ToNumberPolicy;
+
+import java.io.*;
+import java.util.Map;
+
+/**
+ * Represents a difficulty
+ * Responsible for the data in metadata.yml
+ */
+public class Difficulty implements Comparable<Difficulty>
+{
+ public final File thisDir;
+ public final Level level;
+
+ public String title = "Unnamed";
+ public Double bpm = 0.0;
+ public double endTime = 0;
+ public int order = 0;
+
+ public final Leaderboard leaderboard;
+ public final Notes notes;
+
+ private final Gson jsonParser = new GsonBuilder().serializeNulls().setPrettyPrinting().setNumberToNumberStrategy(ToNumberPolicy.DOUBLE).create();
+ private final File jsonFile;
+
+ /**
+ * Creates a new Difficulty
+ * @param newDir: The file path of the Difficulty
+ * @throws IOException If there are any problems reading the metadata or leaderboard files
+ */
+ public Difficulty(File newDir, Level level) throws IOException {
+ thisDir = newDir;
+ this.level = level;
+ jsonFile = new File(thisDir, "metadata.json");
+ readMetadata();
+ notes = new Notes(new File(thisDir, "notes.txt"), this); // needs metadata first
+ leaderboard = new Leaderboard(new File(thisDir, "leaderboard.json"));
+ }
+
+ /**
+ * Read in the data from metadata.json
+ * @throws IOException If there are any problems loading the file.
+ */
+ public void readMetadata() throws IOException {
+ if (!jsonFile.exists()) {
+ return;
+ }
+ Map<String, Object> data = jsonParser.fromJson(new FileReader(jsonFile), Map.class);
+
+ title = (String) data.getOrDefault("title", title);
+ bpm = (Double) data.getOrDefault("bpm", bpm);
+ endTime = (double) data.getOrDefault("endTime", endTime);
+ if (endTime == 0) {
+ int tmp = (int) (double) data.getOrDefault("numBeats", 0.0);
+ if (tmp != 0) {
+ endTime = Notes.beatToSecond(tmp, bpm);
+ }
+ }
+ order = (int) (double) data.getOrDefault("priority", (double) order);
+ }
+
+ /**
+ * Checks the validity of the difficulty
+ * <p>
+ * A valid difficulty has at least one note
+ * @return True if the difficulty is valid
+ */
+ public boolean isValid() {
+ return !notes.list.isEmpty();
+ }
+
+ /**
+ * Writes metadata to json file
+ * @throws IOException If there is a problem writing to the file
+ */
+ public void writeMetadata() throws IOException {
+ jsonFile.createNewFile();
+ Map<String, Object> data = jsonParser.fromJson(new FileReader(jsonFile), Map.class); // start with previous values
+ data.put("title", title);
+ data.put("endTime", endTime);
+ data.put("priority", order);
+ FileWriter fileWriter = new FileWriter(jsonFile);
+ jsonParser.toJson(data, fileWriter);
+ fileWriter.close();
+ }
+
+ @Override
+ public int compareTo(Difficulty d) {
+ return order - d.order;
+ }
+}
diff --git a/src/main/java/net/sowgro/npehero/levelapi/Leaderboard.java b/src/main/java/net/sowgro/npehero/levelapi/Leaderboard.java
new file mode 100644
index 0000000..bb1f30c
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/levelapi/Leaderboard.java
@@ -0,0 +1,81 @@
+package net.sowgro.npehero.levelapi;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Leaderboard {
+
+ public final ObservableList<LeaderboardEntry> entries = FXCollections.observableArrayList();
+ private final Gson json = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
+ private final File file;
+
+ public Leaderboard(File file) throws IOException{
+ this.file = file;
+ read();
+ }
+
+ /**
+ * Adds new leaderboardEntry to list and updates json file
+ * @param name: The players name
+ * @param score The players score
+ * @throws IOException If there is a problem updating the leaderboard file.
+ */
+ public void add(String name, int score) throws IOException {
+ entries.add(new LeaderboardEntry(name, score, LocalDate.now().toString()));
+ save();
+ }
+
+ /**
+ * Writes leaderboard to json file
+ * @throws IOException If there are problems writing to the file.
+ */
+ public void save() throws IOException {
+ file.createNewFile();
+ List<Map<String, Object>> data = json.fromJson(new FileReader(file), List.class);
+ for (LeaderboardEntry cur : entries) {
+ Map<String, Object> obj = new HashMap<>();
+ obj.put("name", cur.name);
+ obj.put("score", cur.score);
+ obj.put("date", cur.date);
+ data.add(obj);
+ }
+ FileWriter fileWriter = new FileWriter(file);
+ json.toJson(data, fileWriter);
+ fileWriter.close();
+ }
+
+ /**
+ * Reads in json leaderboard and assigns populates list with leaderboardEntries
+ * @throws IOException If there are problems reading the file
+ */
+ public void read() throws IOException {
+ if (!file.exists()) {
+ return;
+ }
+ List<Map<String, Object>> data = json.fromJson(new FileReader(file), List.class);
+ if (data == null) {
+ return;
+ }
+ for (Map<String, Object> cur: data) {
+ String name = (String) cur.getOrDefault("name", null);
+ int score = (int) (double) cur.getOrDefault("score", -1);
+ String date = (String) cur.getOrDefault("date", null);
+ if (name == null || score == -1 || date == null) {
+ System.out.println("dbg: bad entry skipped");
+ continue; // discard invalid entries
+ }
+ entries.add(new LeaderboardEntry(name, score, date));
+ }
+ }
+}
diff --git a/src/main/java/net/sowgro/npehero/levelapi/LeaderboardEntry.java b/src/main/java/net/sowgro/npehero/levelapi/LeaderboardEntry.java
new file mode 100755
index 0000000..2b98a29
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/levelapi/LeaderboardEntry.java
@@ -0,0 +1,24 @@
+package net.sowgro.npehero.levelapi;
+
+/**
+ * Represents one players score in the leaderboard
+ */
+public class LeaderboardEntry
+{
+ public final int score;
+ public final String name;
+ public final String date;
+
+ /**
+ * Create a new LeaderboardEntry
+ * @param name The name the player input after completing the level
+ * @param score The score the player earned
+ * @param date The date the player earned this score
+ */
+ public LeaderboardEntry(String name, int score, String date)
+ {
+ this.name = name;
+ this.score = score;
+ this.date = date;
+ }
+}
diff --git a/src/main/java/net/sowgro/npehero/levelapi/Level.java b/src/main/java/net/sowgro/npehero/levelapi/Level.java
new file mode 100755
index 0000000..218779f
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/levelapi/Level.java
@@ -0,0 +1,152 @@
+package net.sowgro.npehero.levelapi;
+
+import java.io.*;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import javafx.scene.image.Image;
+import javafx.scene.media.Media;
+import javafx.scene.paint.Color;
+
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.Map;
+
+public class Level implements Comparable<Level>{
+
+ public final File dir;
+
+ public String title = "Unnamed";
+ public String artist = "Unknown";
+ public String desc;
+ public Color[] colors = {Color.RED,Color.BLUE,Color.GREEN,Color.PURPLE,Color.YELLOW};
+ public Image preview;
+ public Image background;
+ public Media song;
+
+ public Difficulties difficulties;
+
+ private final File jsonFile;
+ private final Gson jsonParser = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
+
+ /**
+ * Creates a new level
+ * @param newDir The path of the Level
+ * @throws IOException If there is a problem reading the metadata file or loading the difficulties
+ */
+ public Level(File newDir) throws IOException
+ {
+ dir = newDir;
+ jsonFile = new File(dir, "metadata.json");
+ readFiles();
+ readMetadata();
+ difficulties = new Difficulties(this);
+ }
+
+ /**
+ * Check for a song file, background file and preview image file
+ */
+ public void readFiles() {
+
+ File[] fileList = dir.listFiles();
+ if (fileList == null) {
+ return;
+ }
+ for (File file : fileList) {
+ String fileName = file.getName();
+ if (fileName.contains("song")) {
+ song = new Media(file.toURI().toString());
+ }
+ else if (fileName.contains("background")) {
+ background = new Image(file.toURI().toString());
+ }
+ else if (fileName.contains("preview")) {
+ preview = new Image(file.toURI().toString());
+ }
+ }
+
+ }
+
+ /**
+ * Read in metadata file
+ * @throws IOException If there is a problem reading the file
+ */
+ public void readMetadata() throws IOException {
+ if (!jsonFile.exists()) {
+ return;
+ }
+ Map<String, Object> data = jsonParser.fromJson(new FileReader(jsonFile), Map.class);
+ title = (String) data.getOrDefault("title", title);
+ artist = (String) data.getOrDefault("artist", artist);
+ desc = (String) data.getOrDefault("desc", desc);
+ colors[0] = Color.web((String) data.getOrDefault("color1", colors[0].toString()));
+ colors[1] = Color.web((String) data.getOrDefault("color2", colors[1].toString()));
+ colors[2] = Color.web((String) data.getOrDefault("color3", colors[2].toString()));
+ colors[3] = Color.web((String) data.getOrDefault("color4", colors[3].toString()));
+ colors[4] = Color.web((String) data.getOrDefault("color5", colors[4].toString()));
+ }
+
+ /**
+ * Checks if the level is valid.
+ * <p>
+ * A valid level has a song file and 1 or more valid difficulties
+ * @return True if the level is valid
+ */
+ public boolean isValid() {
+ if (song == null) {
+ return false;
+ }
+
+ if (difficulties.getValidList().isEmpty()) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Writes metadata to json file
+ * @throws IOException If there is a problem writing to the file.
+ */
+ public void writeMetadata() throws IOException {
+ jsonFile.createNewFile();
+ Map<String, Object> data = jsonParser.fromJson(new FileReader(jsonFile), Map.class);
+ data.put("title", title);
+ data.put("artist", artist);
+ data.put("desc", desc);
+ data.put("color1",colors[0].toString());
+ data.put("color2",colors[1].toString());
+ data.put("color3",colors[2].toString());
+ data.put("color4",colors[3].toString());
+ data.put("color5",colors[4].toString());
+ FileWriter fileWriter = new FileWriter(jsonFile);
+ jsonParser.toJson(data, fileWriter);
+ fileWriter.close();
+ }
+
+
+ /**
+ * Copies a file into the level directory with the name provided. The extension will be inherited from the source file
+ * @param source: the file to be copied
+ * @param name: the new file name EXCLUDING the extension.
+ * @throws IOException If there is a problem adding the file
+ */
+ public void addFile(File source, String name) throws IOException {
+ name = name + "." + getFileExtension(source);
+ Files.copy(source.toPath(), new File(dir, name).toPath(), StandardCopyOption.REPLACE_EXISTING);
+ readFiles();
+ }
+
+ @Override
+ public int compareTo(Level other) {
+ return title.compareTo(other.title);
+ }
+
+ /**
+ * Get the extension of a file.
+ * @param file The file to return the extension of
+ * @return The extension of the file in the format "*.ext"
+ */
+ public String getFileExtension(File file) {
+ return file.getName().substring(file.getName().lastIndexOf('.') + 1);
+ }
+}
diff --git a/src/main/java/net/sowgro/npehero/main/Levels.java b/src/main/java/net/sowgro/npehero/levelapi/Levels.java
index ce720c6..84ffe51 100755
--- a/src/main/java/net/sowgro/npehero/main/Levels.java
+++ b/src/main/java/net/sowgro/npehero/levelapi/Levels.java
@@ -1,39 +1,48 @@
-package net.sowgro.npehero.main;
+package net.sowgro.npehero.levelapi;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
-import java.util.List;
+import java.util.HashMap;
import javafx.collections.FXCollections;
-import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
-public class Levels
-{
+/**
+ * Stores a list of all the levels
+ */
+public class Levels {
+
+ public static final ObservableList<Level> list = FXCollections.observableArrayList();
+ public static final HashMap<String, Exception> problems = new HashMap<>();
+
private static final File dir = new File("levels");
- public static ObservableList<Level> list = FXCollections.observableArrayList();
/**
* Reads contents of the levels folder and creates a level form each subfolder
+ * <p>
* All subfolders in the levels folder are assumed to be levels
- * @throws FileNotFoundException when the levels folder is not present
+ * @throws FileNotFoundException If the levels folder is missing.
+ * @throws IOException If there is a problem reading in the levels.
*/
- public static void readData() throws FileNotFoundException
- {
+ public static void readData() throws IOException {
list.clear();
File[] fileList = dir.listFiles();
if (fileList == null) {
throw new FileNotFoundException();
}
- for (File file: fileList)
- {
- Level level = new Level(file);
- level.readData();
- list.add(level);
+ for (File file: fileList) {
+ try {
+ Level level = new Level(file);
+ list.add(level);
+ } catch (IOException e) {
+ problems.put("", e);
+ e.printStackTrace();
+ }
}
list.sort(Comparator.naturalOrder());
}
@@ -43,9 +52,11 @@ public class Levels
* @param text: the name of the directory and default title
* @throws IOException if there was an error adding the level
*/
- public static void add(String text) throws IOException
- {
- File levelDir = new File(dir,text);
+ public static void add(String text) throws IOException {
+ File levelDir = new File(dir, text.toLowerCase().replaceAll("\\W+", "-"));
+ if (levelDir.exists()) {
+ throw new FileAlreadyExistsException(levelDir.getName());
+ }
if (levelDir.mkdirs()) {
Level temp = new Level(levelDir);
temp.title = text;
@@ -59,23 +70,21 @@ public class Levels
/**
* Removes level from the filesystem then reloads this levelController
* @param level: the level to be removed
- * @throws IOException if there was an error deleting the level
+ * @throws IOException If there is a problem deleting the level
*/
- public static void remove(Level level) throws IOException
- {
+ public static void remove(Level level) throws IOException {
File hold = level.dir;
- list.remove(level);
-
- // delete files recursively
- // TODO clean this up
Files.walk(hold.toPath())
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
-
list.remove(level);
}
+ /**
+ * Gets a list of only the valid levels.
+ * @return A list of the valid levels.
+ */
public static ObservableList<Level> getValidList() {
ObservableList<Level> validList = FXCollections.observableArrayList();
for (Level level : list) {
diff --git a/src/main/java/net/sowgro/npehero/main/Note.java b/src/main/java/net/sowgro/npehero/levelapi/Note.java
index c2c9015..ab93885 100644
--- a/src/main/java/net/sowgro/npehero/main/Note.java
+++ b/src/main/java/net/sowgro/npehero/levelapi/Note.java
@@ -1,17 +1,23 @@
-package net.sowgro.npehero.main;
+package net.sowgro.npehero.levelapi;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
/**
* A note represents a moment in the song when the player should hit a key
+ * <p>
* The key corresponding to the lane the note is in should be pressed
*/
public class Note {
- public DoubleProperty time = new SimpleDoubleProperty();
- public int lane;
+ public final DoubleProperty time = new SimpleDoubleProperty();
+ public final int lane;
+ /**
+ * Creates a new note
+ * @param time The time the player should hit the note.
+ * @param lane The lane the note belongs to.
+ */
public Note(double time, int lane) {
this.time.set(time);
this.lane = lane;
diff --git a/src/main/java/net/sowgro/npehero/levelapi/Notes.java b/src/main/java/net/sowgro/npehero/levelapi/Notes.java
new file mode 100644
index 0000000..1df0248
--- /dev/null
+++ b/src/main/java/net/sowgro/npehero/levelapi/Notes.java
@@ -0,0 +1,107 @@
+package net.sowgro.npehero.levelapi;
+
+import javafx.beans.property.ListProperty;
+import javafx.beans.property.SimpleListProperty;
+import javafx.collections.FXCollections;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
+
+/**
+ * Stores all the notes for a difficulty.
+ */
+public class Notes {
+
+ private final File file;
+ private final Difficulty diff;
+
+ public ListProperty<Note> list = new SimpleListProperty<>(FXCollections.observableArrayList());
+
+ /**
+ * Create a new Notes object
+ * @param file The notes.txt file
+ * @param diff The difficulty these notes belong to
+ * @throws IOException If there is a problem reading the notes file
+ */
+ public Notes(File file, Difficulty diff) throws IOException {
+ this.file = file;
+ this.diff = diff;
+ readFile();
+ }
+
+ /**
+ * Read notes.txt and add the notes to the list
+ * @throws IOException if there is a problem reading the file.
+ */
+ public void readFile() throws IOException {
+ if (!file.exists()) {
+ return;
+ }
+ Scanner scan = new Scanner(file);
+ while (scan.hasNext()) {
+ String input = scan.next();
+ int lane = switch (input.charAt(0)) {
+ case 'd' -> 0;
+ case 'f' -> 1;
+ case 's' -> 2;
+ case 'j' -> 3;
+ case 'k' -> 4;
+ default -> -1;
+ };
+ if (lane == -1) {
+ continue;
+ }
+ double time = Double.parseDouble(input.substring(1));
+
+ if (diff.bpm != 0.0) {
+ time = beatToSecond(time, diff.bpm);
+ }
+ list.add(new Note(time, lane));
+ }
+ }
+
+ /**
+ * Writes the notes to notes.txt
+ * @throws IOException If there is a problem writing to the file.
+ */
+ public void writeFile() throws IOException{
+ var _ = file.createNewFile();
+ PrintWriter writer = new PrintWriter(file, StandardCharsets.UTF_8);
+ for (Note note : list) {
+ Character lane = switch (note.lane) {
+ case 0 -> 'd';
+ case 1 -> 'f';
+ case 2 -> 's';
+ case 3 -> 'j';
+ case 4 -> 'k';
+ default -> null;
+ };
+ if (lane == null) {
+ continue;
+ }
+ writer.println(lane + "" + note.time.get());
+ }
+ writer.close();
+ }
+
+ /**
+ * Converts a beat to a second using the levels bpm
+ * @param beat The beat to convert to seconds
+ * @param bpm The beats per minute to use for conversion
+ * @return The time in seconds the beat was at
+ */
+ public static double beatToSecond(double beat, double bpm) {
+ return beat/(bpm/60);
+ }
+
+ /**
+ * Performs a deep copy of the notes list.
+ * @return a new list of notes with the same notes.
+ */
+ public ListProperty<Note> deepCopyList() {
+ ListProperty<Note> ret = new SimpleListProperty<>(FXCollections.observableArrayList());
+ list.forEach(e -> ret.add(new Note(e)));
+ return ret;
+ }
+}
diff --git a/src/main/java/net/sowgro/npehero/main/Control.java b/src/main/java/net/sowgro/npehero/main/Control.java
index 6e608ec..ece88ac 100644
--- a/src/main/java/net/sowgro/npehero/main/Control.java
+++ b/src/main/java/net/sowgro/npehero/main/Control.java
@@ -1,5 +1,7 @@
package net.sowgro.npehero.main;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.input.KeyCode;
@@ -36,7 +38,8 @@ public enum Control {
entry("Legacy Editor", List.of(LEGACY_PRINT, LEGACY_STOP))
);
- private static final JSONFile jsonFile = new JSONFile(new File("controls.json"));
+ private static final File file = new File("controls.json");
+ private static final Gson json = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
Control(String label, KeyCode key) {
this.label = label;
@@ -80,19 +83,21 @@ public enum Control {
}
public static void writeToFile() throws IOException {
+ Map<String, Object> data = new HashMap<>();
for (Control control : Control.values()) {
- jsonFile.set(control.toString(), control.getKey().toString());
+ data.put(control.toString(), control.getKey().toString());
}
- jsonFile.write();
+ FileWriter fileWriter = new FileWriter(file);
+ json.toJson(data, fileWriter);
+ fileWriter.close();
}
public static void readFromFile() throws Exception {
- jsonFile.read();
+ Map<String, Object> data = json.fromJson(new FileReader(file), Map.class);
for (Control control : Control.values()) {
- if (jsonFile.containsKey(control.toString())) {
- control.setKey(KeyCode.valueOf(jsonFile.getString(control.toString(), null)));
+ if (data.containsKey(control.toString())) {
+ control.setKey(KeyCode.valueOf((String) data.getOrDefault(control.toString(), null)));
}
}
}
-
}
diff --git a/src/main/java/net/sowgro/npehero/main/Difficulties.java b/src/main/java/net/sowgro/npehero/main/Difficulties.java
deleted file mode 100644
index 9549a5a..0000000
--- a/src/main/java/net/sowgro/npehero/main/Difficulties.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package net.sowgro.npehero.main;
-
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Comparator;
-import java.util.List;
-
-public class Difficulties {
-
- public ObservableList<Difficulty> list = FXCollections.observableArrayList();
- Level level;
-
- public Difficulties(Level level) {
- this.level = level;
- }
-
- public void read() {
- list.clear();
- File[] fileList = level.dir.listFiles();
- if (fileList == null) {
- return;
- }
- for(File cur: fileList) //iterates through all files/folders in /levels/LEVEL
- {
- if (cur.isDirectory()) //all subfolders within a level folder are difficulties
- {
- Difficulty diff = new Difficulty(cur,level);
- list.add(diff);
- }
- }
- list.sort(Comparator.naturalOrder());
- }
-
- /**
- * Removes the difficaulty from the filesystem then reloads the level
- * @param diff: the difficulty to be removed
- */
- public void remove(Difficulty diff) throws IOException
- {
- File hold = diff.thisDir;
- Files.walk(hold.toPath())
- .sorted(Comparator.reverseOrder())
- .map(Path::toFile)
- .forEach(File::delete);
- list.remove(diff);
- }
-
- /**
- * Adds a difficulty by creating a directory and required files
- * @param text: the name of the directory and default title
- */
- public void add(String text) throws IOException {
- File diffDir = new File(level.dir, text);
- if (diffDir.mkdirs()) {
- Difficulty temp = new Difficulty(diffDir, level);
- temp.title = text;
- list.add(temp);
- list.sort(Comparator.naturalOrder());
- }
- else {
- throw new IOException();
- }
- }
-
- public void saveOrder() {
- for (Difficulty d : list) {
- d.order = list.indexOf(d);
- d.write();
- }
- }
-
- public List<Difficulty> getValidList() {
- ObservableList<Difficulty> validList = FXCollections.observableArrayList();
- for (Difficulty difficulty : list) {
- if (difficulty.isValid()) {
- validList.add(difficulty);
- }
- }
- return validList;
- }
-}
diff --git a/src/main/java/net/sowgro/npehero/main/Difficulty.java b/src/main/java/net/sowgro/npehero/main/Difficulty.java
deleted file mode 100755
index 0308fac..0000000
--- a/src/main/java/net/sowgro/npehero/main/Difficulty.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package net.sowgro.npehero.main;
-
-import javafx.scene.media.Media;
-
-import java.io.File;
-import java.io.IOException;
-
-public class Difficulty implements Comparable<Difficulty>
-{
- public File thisDir;
- public Level level;
- private final JSONFile metadataYaml;
-
- public String title = "Unnamed";
- public Double bpm = 0.0;
- public double endTime = 0;
- public int order = 0;
-
- public Leaderboard leaderboard;
- public Notes notes;
-
- /**
- * Creates a new Difficulty and gives it a file path
- * @param newDir: The file path of the Difficulty
- */
- public Difficulty(File newDir, Level level) {
- thisDir = newDir;
- this.level = level;
- metadataYaml = new JSONFile(new File(thisDir, "metadata.json"));
- notes = new Notes(new File(thisDir, "notes.txt"), this);
- leaderboard = new Leaderboard(new File(thisDir, "leaderboard.json"));
-
- readData();
- }
-
- public void readData() {
- try {
- metadataYaml.read();
- }
- catch (Exception e) {
- System.err.println(level.title + "/" + title + ": Failed to read metadata.json");
- }
-
- title = metadataYaml.getString("title", title);
- bpm = metadataYaml.getDouble("bpm", bpm);
- endTime = metadataYaml.getDouble("endTime", endTime);
- if (endTime == 0) {
- int tmp = metadataYaml.getInt("numBeats", 0);
- if (tmp != 0) {
- endTime = beatToSecond(tmp);
- }
- }
- order = metadataYaml.getInt("priority", order);
-
- }
-
- public boolean isValid() {
- return !notes.list.isEmpty();
- }
-
- /**
- * Writes metadata to json file
- */
- public void write() {
- metadataYaml.set("title", title);
- metadataYaml.set("endTime", endTime);
- metadataYaml.set("priority", order);
-
- try {
- metadataYaml.write();
- }
- catch (IOException e) {
- System.err.println(level.title + "/" + title + ": Failed to write metadata.json");
- }
- }
-
- @Override
- public int compareTo(Difficulty d) {
- return order - d.order;
- }
-
- private double beatToSecond(double beat) {
- return beat/(bpm/60);
- }
-
-
-}
diff --git a/src/main/java/net/sowgro/npehero/main/JSONFile.java b/src/main/java/net/sowgro/npehero/main/JSONFile.java
deleted file mode 100644
index d06ca1f..0000000
--- a/src/main/java/net/sowgro/npehero/main/JSONFile.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package net.sowgro.npehero.main;
-
-
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import java.io.*;
-
-/**
- * An ergonomic JSON API wrapper inspired by the Bukkit YAML API
- */
-public class JSONFile {
-
- private final File file;
- ObjectMapper objectMapper = new ObjectMapper();
- ObjectNode writeNode = objectMapper.createObjectNode();
- JsonNode readNode;
-
- public JSONFile(File file) {
- try {
- file.createNewFile();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- this.file = file;
- }
-
- public String getString(String key, String def) {
- if (!readNode.has(key)) {
- return def;
- }
- return readNode.get(key).asText();
- }
-
- public int getInt(String key, int def) {
- if (!readNode.has(key)) {
- return def;
- }
- try {
- return Integer.parseInt(readNode.get(key).asText());
- }
- catch (NumberFormatException e) {
- return def;
- }
- }
-
- public double getDouble(String key, double def) {
- if (!readNode.has(key)) {
- return def;
- }
- try {
- return Double.parseDouble(readNode.get(key).asText());
- }
- catch (NumberFormatException e) {
- return def;
- }
- }
-
- public boolean getBoolean(String key, boolean def) {
- if (!readNode.has(key)) {
- return def;
- }
- try {
- return Boolean.parseBoolean(readNode.get(key).asText());
- }
- catch (NumberFormatException e) {
- return def;
- }
- }
-
- public void set(String key, String value) {
- if (value == null) {
- return;
- }
- writeNode.put(key, value);
- }
-
- public void set(String key, int value) {
- writeNode.put(key, value);
- }
-
- public void set(String key, double value) {
- writeNode.put(key, value);
- }
-
- public void set(String key, boolean value) {
- writeNode.put(key, value);
- }
-
- public boolean containsKey(String key) {
- return writeNode.has(key);
- }
-
- public void read() throws Exception {
- if (file.length() == 0) {
- readNode = objectMapper.createObjectNode();
- return;
- }
- readNode = objectMapper.readTree(file);
- }
-
- public void write() throws IOException {
- objectMapper.writeValue(file, writeNode);
- }
-
-}
diff --git a/src/main/java/net/sowgro/npehero/main/Leaderboard.java b/src/main/java/net/sowgro/npehero/main/Leaderboard.java
deleted file mode 100644
index eb4e5f5..0000000
--- a/src/main/java/net/sowgro/npehero/main/Leaderboard.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package net.sowgro.npehero.main;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.time.LocalDate;
-
-public class Leaderboard {
-
- public ObservableList<LeaderboardEntry> entries = FXCollections.observableArrayList();
-// private final JSONFile jsonFile;
- private File file;
-
- public Leaderboard(File file) {
-// jsonFile = new JSONFile(file);
- this.file = file;
- }
-
- /**
- * Adds new leaderboardEntry to list and updates json file
- * @param name: The players name
- * @param score The players score
- */
- public void add(String name, int score) {
- new LeaderboardEntry(name, score, ""+ LocalDate.now());
- }
-
- /**
- * Writes leaderboard to json file
- */
-// public void save()
-// {
-// FileWriter fileWriter;
-// try
-// {
-// fileWriter = new FileWriter(file);
-// //write the settings JSONObject instance to the file
-// JSONArray jsonArray = new JSONArray();
-// for (LeaderboardEntry cur: entries)
-// {
-// JsonNode obj = new ;
-// obj.put("name", cur.getName());
-// obj.put("score", cur.getScore());
-// obj.put("date",cur.getDate());
-// jsonArray.add(obj);
-// }
-// jsonArray.writeJSONString(fileWriter);
-// fileWriter.flush();
-//
-// }
-// catch (IOException e) {
-// e.printStackTrace();
-// }
-// }
-//
-// /**
-// * Reads in json leaderboard and assigns populates list with leaderboardEntries
-// */
-// public boolean parseLeaderboard()
-// {
-// boolean isValid = true;
-// JSONParser jsonParser = new JSONParser(); //parser to read the file
-//
-// try(FileReader reader = new FileReader(file))
-// {
-// Object obj = jsonParser.parse(reader);
-//
-// JSONArray leaderboardStuff = (JSONArray)(obj); //converts read object to a JSONArray
-//
-// for (Object cur: leaderboardStuff)
-// {
-// JSONObject cur2 = (JSONObject) cur;
-//
-// String name = (String) cur2.get("name");
-// int score = Integer.parseInt(""+cur2.get("score"));
-// String date = (String) cur2.get("date");
-// entries.add(new LeaderboardEntry(name, score, date));
-// }
-// }
-// catch (Exception e)
-// {
-// isValid = false;
-// e.printStackTrace();
-// }
-// return isValid;
-// }
-
-
-}
diff --git a/src/main/java/net/sowgro/npehero/main/LeaderboardEntry.java b/src/main/java/net/sowgro/npehero/main/LeaderboardEntry.java
deleted file mode 100755
index 18e657c..0000000
--- a/src/main/java/net/sowgro/npehero/main/LeaderboardEntry.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package net.sowgro.npehero.main;
-
-public class LeaderboardEntry
-{
- private int score;
- private String name;
- private String date;
-
- public LeaderboardEntry(String name, int score, String date)
- {
- this.name = name;
- this.score = score;
- this.date = date;
- }
-
- public int getScore() {
- return score;
- }
-
- public String getName() {
- return name;
- }
-
- public String getDate()
- {
- return date;
- }
-}
diff --git a/src/main/java/net/sowgro/npehero/main/Level.java b/src/main/java/net/sowgro/npehero/main/Level.java
deleted file mode 100755
index 6f66893..0000000
--- a/src/main/java/net/sowgro/npehero/main/Level.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package net.sowgro.npehero.main;
-
-import java.io.File;
-
-import javafx.scene.image.Image;
-import javafx.scene.media.Media;
-import javafx.scene.paint.Color;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
-
-public class Level implements Comparable<Level>{
-
- public File dir;
-
- public String title = "Unnamed";
- public String artist = "Unknown";
- public String desc;
- public Color[] colors = {Color.RED,Color.BLUE,Color.GREEN,Color.PURPLE,Color.YELLOW};//optional, have default colors
-
- public Image preview; //optional
- public Image background; //optional
- public Media song;
-
- public Difficulties difficulties;
-
- private JSONFile metadataJson;
-
- /**
- * Creates a new level
- * @param newDir: The path of the Level
- */
- public Level(File newDir)
- {
- dir = newDir;
- metadataJson = new JSONFile(new File(dir, "metadata.json"));
- difficulties = new Difficulties(this);
- difficulties.read();
- readData();
- }
-
- /**
- * Check for a song file, background file and preview image file
- * Parse metadata.json
- */
- public void readData() {
-
- var fileList = dir.listFiles();
- if (fileList == null) {
- return;
- }
- for (File file : fileList) {
- String fileName = file.getName();
- if (fileName.contains("song")) {
- song = new Media(file.toURI().toString());
- }
- else if (fileName.contains("background")) {
- background = new Image(file.toURI().toString());
- }
- else if (fileName.contains("preview")) {
- preview = new Image(file.toURI().toString());
- }
- }
-
- try {
- metadataJson.read();
- }
- catch (Exception e) {
- // TODO
- }
- title = metadataJson.getString("title", title);
- artist = metadataJson.getString("artist", artist);
- desc = metadataJson.getString("desc", desc);
- colors[0] = Color.web(metadataJson.getString("color1", colors[0].toString()));
- colors[1] = Color.web(metadataJson.getString("color2", colors[1].toString()));
- colors[2] = Color.web(metadataJson.getString("color3", colors[2].toString()));
- colors[3] = Color.web(metadataJson.getString("color4", colors[3].toString()));
- colors[4] = Color.web(metadataJson.getString("color5", colors[4].toString()));
- }
-
- /**
- * Checks if the level is valid.
- * A valid level has a song file and 1 or more valid difficulties
- * @return true if the level is valid
- */
- public boolean isValid() {
- if (song == null) {
-// System.out.println(dir +" is missing song file");
- return false;
- }
-
- if (difficulties.getValidList().isEmpty()) {
-// System.out.println(dir +" contains no valid difficulties");
- return false;
- }
- return true;
- }
-
- /**
- * Writes metadata to json file
- */
- public void writeMetadata()
- {
- metadataJson.set("title", title);
- metadataJson.set("artist", artist);
- metadataJson.set("desc", desc);
- metadataJson.set("color1",colors[0].toString());
- metadataJson.set("color2",colors[1].toString());
- metadataJson.set("color3",colors[2].toString());
- metadataJson.set("color4",colors[3].toString());
- metadataJson.set("color5",colors[4].toString());
- try {
- metadataJson.write();
- }
- catch (IOException e) {
- // TODO
- }
- }
-
-
- /**
- * Copies a file into the level directory
- * @param newFile: the file to be copied
- * @param name: the new file name
- * @throws IOException if there was an error adding the file
- */
- public void addFile(File newFile, String name) throws IOException {
- Files.copy(newFile.toPath(), new File(dir, name).toPath(), StandardCopyOption.REPLACE_EXISTING);
- readData();
- }
-
- @Override
- public int compareTo(Level other) {
- return title.compareTo(other.title);
- }
-}
diff --git a/src/main/java/net/sowgro/npehero/main/Notes.java b/src/main/java/net/sowgro/npehero/main/Notes.java
deleted file mode 100644
index 62a602e..0000000
--- a/src/main/java/net/sowgro/npehero/main/Notes.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package net.sowgro.npehero.main;
-
-import javafx.beans.property.ListProperty;
-import javafx.beans.property.SimpleListProperty;
-import javafx.collections.FXCollections;
-
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.util.Scanner;
-
-public class Notes {
- private File file;
- private Difficulty diff;
-
- public ListProperty<Note> list = new SimpleListProperty<>(FXCollections.observableArrayList());
-
- public Notes(File f, Difficulty diff) {
- try {
- f.createNewFile();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- this.file = f;
- this.diff = diff;
- readFile();
- }
-
- public void readFile() {
- Scanner scan = null; //file reader for reading in the notes from a notes.txt file
- try {
- scan = new Scanner(file);
- }
- catch (FileNotFoundException e) {
- // TODO handle error
- throw new RuntimeException(e);
- }
-
- while (scan.hasNext()) {
- String input = scan.next();
-
- int lane = switch (input.charAt(0)) {
- case 'd' -> 0;
- case 'f' -> 1;
- case 's' -> 2;
- case 'j' -> 3;
- case 'k' -> 4;
- default -> -1;
- };
-
- if (lane == -1) {
- // TODO handle error
- continue;
- }
-
- double time = Double.parseDouble(input.substring(1));
- if (diff.bpm != 0.0) {
- time = beatToSecond(time, diff.bpm);
- }
- list.add(new Note(time, lane));
- }
- }
-
- public void writeFile() {
- try (PrintWriter writer = new PrintWriter(diff.notes.getFile(), StandardCharsets.UTF_8)) {
- for (Note note : list) {
- char lane = switch (note.lane) {
- case 0 -> 'd';
- case 1 -> 'f';
- case 2 -> 's';
- case 3 -> 'j';
- case 4 -> 'k';
- default -> 'e';
- };
-
- if (lane == 'e') {
- // TODO handle error
- }
-
- writer.println(lane + "" + note.time.get());
- }
- }
- catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- private double beatToSecond(double beat, double bpm) {
- return beat/(bpm/60);
- }
-
- public File getFile() {
- return file;
- }
-
- public ListProperty<Note> deepCopyList() {
- ListProperty<Note> ret = new SimpleListProperty<>(FXCollections.observableArrayList());
- list.forEach(e -> ret.add(new Note(e)));
- return ret;
- }
-}
diff --git a/src/main/java/net/sowgro/npehero/main/Settings.java b/src/main/java/net/sowgro/npehero/main/Settings.java
index 8cba8f7..43dce5a 100755
--- a/src/main/java/net/sowgro/npehero/main/Settings.java
+++ b/src/main/java/net/sowgro/npehero/main/Settings.java
@@ -1,8 +1,14 @@
package net.sowgro.npehero.main;
import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleDoubleProperty;
@@ -12,25 +18,29 @@ public class Settings
public static SimpleDoubleProperty musicVol = new SimpleDoubleProperty(1);
public static SimpleBooleanProperty enableMenuMusic = new SimpleBooleanProperty(true);
- private static final JSONFile jsonFile = new JSONFile(new File("settings.json"));
+ private static final Gson jsonParser = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
+ private static final File jsonFile = new File("settings.json");
/**
* Reads json data from settings.json
*/
public static void read() throws Exception {
- jsonFile.read();
- effectsVol.set(jsonFile.getDouble("effectsVol", 1));
- musicVol.set(jsonFile.getDouble("musicVol", 1));
- enableMenuMusic.set(jsonFile.getBoolean("enableMenuMusic", true));
+ Map<String, Object> data = jsonParser.fromJson(new FileReader(jsonFile), Map.class);
+ effectsVol.set((Double) data.getOrDefault("effectsVol", 1.0));
+ musicVol.set((Double) data.getOrDefault("musicVol", 1.0));
+ enableMenuMusic.set((Boolean) data.getOrDefault("enableMenuMusic", true));
}
/**
* Writes json data to settings.json
*/
public static void save() throws IOException {
- jsonFile.set("effectsVol", effectsVol.get());
- jsonFile.set("musicVol", musicVol.get());
- jsonFile.set("enableMenuMusic", enableMenuMusic.get());
- jsonFile.write();
+ Map<String, Object> data = new HashMap<>();
+ data.put("effectsVol", effectsVol.get());
+ data.put("musicVol", musicVol.get());
+ data.put("enableMenuMusic", enableMenuMusic.get());
+ FileWriter fileWriter = new FileWriter(jsonFile);
+ jsonParser.toJson(data, fileWriter);
+ fileWriter.close();
}
}