Added replay saving/loading and score database auto-updater.
- Added 'info' table to score database to store the database version. Upon startup, if the stored version is less than the source version, all update queries defined in ScoreDB.getUpdateQueries() will be run. - Created "Replays" directory to store replay files. Replay files are created after gameplay. - Added 'replay' column to the score database to hold replay file names. - Created a Game.loadOsuFile() method to load game data. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
37c0763f32
commit
712cf30e01
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
/Replays/
|
||||||
/Screenshots/
|
/Screenshots/
|
||||||
/Skins/
|
/Skins/
|
||||||
/SongPacks/
|
/SongPacks/
|
||||||
|
|
|
@ -26,6 +26,7 @@ import itdelatrisu.opsu.downloads.Updater;
|
||||||
import itdelatrisu.opsu.replay.Replay;
|
import itdelatrisu.opsu.replay.Replay;
|
||||||
import itdelatrisu.opsu.replay.ReplayFrame;
|
import itdelatrisu.opsu.replay.ReplayFrame;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -325,7 +326,8 @@ public class GameData {
|
||||||
hitResultCount[HIT_300K] = 0;
|
hitResultCount[HIT_300K] = 0;
|
||||||
hitResultCount[HIT_100K] = s.katu;
|
hitResultCount[HIT_100K] = s.katu;
|
||||||
hitResultCount[HIT_MISS] = s.miss;
|
hitResultCount[HIT_MISS] = s.miss;
|
||||||
this.replay = s.replay;
|
this.replay = (s.replayString == null) ? null :
|
||||||
|
new Replay(new File(Options.getReplayDir(), String.format("%s.osr", s.replayString)));
|
||||||
|
|
||||||
loadImages();
|
loadImages();
|
||||||
}
|
}
|
||||||
|
@ -1197,10 +1199,9 @@ public class GameData {
|
||||||
* If score data already exists, the existing object will be returned
|
* If score data already exists, the existing object will be returned
|
||||||
* (i.e. this will not overwrite existing data).
|
* (i.e. this will not overwrite existing data).
|
||||||
* @param osu the OsuFile
|
* @param osu the OsuFile
|
||||||
* @param frames the replay frames
|
|
||||||
* @return the ScoreData object
|
* @return the ScoreData object
|
||||||
*/
|
*/
|
||||||
public ScoreData getScoreData(OsuFile osu, ReplayFrame[] frames) {
|
public ScoreData getScoreData(OsuFile osu) {
|
||||||
if (scoreData != null)
|
if (scoreData != null)
|
||||||
return scoreData;
|
return scoreData;
|
||||||
|
|
||||||
|
@ -1222,7 +1223,7 @@ public class GameData {
|
||||||
scoreData.combo = comboMax;
|
scoreData.combo = comboMax;
|
||||||
scoreData.perfect = (comboMax == fullObjectCount);
|
scoreData.perfect = (comboMax == fullObjectCount);
|
||||||
scoreData.mods = GameMod.getModState();
|
scoreData.mods = GameMod.getModState();
|
||||||
scoreData.replay = getReplay(frames);
|
scoreData.replayString = (replay == null) ? null : replay.getReplayFilename();
|
||||||
return scoreData;
|
return scoreData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1245,7 +1246,7 @@ public class GameData {
|
||||||
replay.version = Updater.get().getBuildDate();
|
replay.version = Updater.get().getBuildDate();
|
||||||
replay.beatmapHash = ""; // TODO
|
replay.beatmapHash = ""; // TODO
|
||||||
replay.playerName = ""; // TODO
|
replay.playerName = ""; // TODO
|
||||||
replay.replayHash = ""; // TODO
|
replay.replayHash = Long.toString(System.currentTimeMillis()); // TODO
|
||||||
replay.hit300 = (short) hitResultCount[HIT_300];
|
replay.hit300 = (short) hitResultCount[HIT_300];
|
||||||
replay.hit100 = (short) hitResultCount[HIT_100];
|
replay.hit100 = (short) hitResultCount[HIT_100];
|
||||||
replay.hit50 = (short) hitResultCount[HIT_50];
|
replay.hit50 = (short) hitResultCount[HIT_50];
|
||||||
|
@ -1261,6 +1262,7 @@ public class GameData {
|
||||||
replay.frames = frames;
|
replay.frames = frames;
|
||||||
replay.seed = 0; // TODO
|
replay.seed = 0; // TODO
|
||||||
replay.loaded = true;
|
replay.loaded = true;
|
||||||
|
|
||||||
return replay;
|
return replay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,9 @@ public class Options {
|
||||||
/** The screenshot directory (created when needed). */
|
/** The screenshot directory (created when needed). */
|
||||||
private static File screenshotDir;
|
private static File screenshotDir;
|
||||||
|
|
||||||
|
/** The replay directory (created when needed). */
|
||||||
|
private static File replayDir;
|
||||||
|
|
||||||
/** The current skin directory (for user skins). */
|
/** The current skin directory (for user skins). */
|
||||||
private static File skinDir;
|
private static File skinDir;
|
||||||
|
|
||||||
|
@ -819,6 +822,19 @@ public class Options {
|
||||||
return screenshotDir;
|
return screenshotDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the replay directory.
|
||||||
|
* If invalid, this will return a "Replay" directory.
|
||||||
|
* @return the replay directory
|
||||||
|
*/
|
||||||
|
public static File getReplayDir() {
|
||||||
|
if (replayDir != null && replayDir.isDirectory())
|
||||||
|
return replayDir;
|
||||||
|
|
||||||
|
replayDir = new File(DATA_DIR, "Replays/");
|
||||||
|
return replayDir;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current skin directory.
|
* Returns the current skin directory.
|
||||||
* If invalid, this will create a "Skins" folder in the root directory.
|
* If invalid, this will create a "Skins" folder in the root directory.
|
||||||
|
@ -892,6 +908,9 @@ public class Options {
|
||||||
case "ScreenshotDirectory":
|
case "ScreenshotDirectory":
|
||||||
screenshotDir = new File(value);
|
screenshotDir = new File(value);
|
||||||
break;
|
break;
|
||||||
|
case "ReplayDirectory":
|
||||||
|
replayDir = new File(value);
|
||||||
|
break;
|
||||||
case "Skin":
|
case "Skin":
|
||||||
skinDir = new File(value);
|
skinDir = new File(value);
|
||||||
break;
|
break;
|
||||||
|
@ -1054,6 +1073,8 @@ public class Options {
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("ScreenshotDirectory = %s", getScreenshotDir().getAbsolutePath()));
|
writer.write(String.format("ScreenshotDirectory = %s", getScreenshotDir().getAbsolutePath()));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
|
writer.write(String.format("ReplayDirectory = %s", getReplayDir().getAbsolutePath()));
|
||||||
|
writer.newLine();
|
||||||
writer.write(String.format("Skin = %s", getSkinDir().getAbsolutePath()));
|
writer.write(String.format("Skin = %s", getSkinDir().getAbsolutePath()));
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
writer.write(String.format("ThemeSong = %s", themeString));
|
writer.write(String.format("ThemeSong = %s", themeString));
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
package itdelatrisu.opsu;
|
package itdelatrisu.opsu;
|
||||||
|
|
||||||
import itdelatrisu.opsu.GameData.Grade;
|
import itdelatrisu.opsu.GameData.Grade;
|
||||||
import itdelatrisu.opsu.replay.Replay;
|
|
||||||
import itdelatrisu.opsu.states.SongMenu;
|
import itdelatrisu.opsu.states.SongMenu;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
@ -60,8 +59,8 @@ public class ScoreData implements Comparable<ScoreData> {
|
||||||
/** Game mod bitmask. */
|
/** Game mod bitmask. */
|
||||||
public int mods;
|
public int mods;
|
||||||
|
|
||||||
/** The replay. */
|
/** The replay string. */
|
||||||
public Replay replay;
|
public String replayString;
|
||||||
|
|
||||||
/** Time since the score was achieved. */
|
/** Time since the score was achieved. */
|
||||||
private String timeSince;
|
private String timeSince;
|
||||||
|
@ -157,7 +156,7 @@ public class ScoreData implements Comparable<ScoreData> {
|
||||||
this.combo = rs.getInt(15);
|
this.combo = rs.getInt(15);
|
||||||
this.perfect = rs.getBoolean(16);
|
this.perfect = rs.getBoolean(16);
|
||||||
this.mods = rs.getInt(17);
|
this.mods = rs.getInt(17);
|
||||||
// this.replay = ; // TODO
|
this.replayString = rs.getString(18);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -39,6 +40,29 @@ import java.util.Map;
|
||||||
* Handles connections and queries with the scores database.
|
* Handles connections and queries with the scores database.
|
||||||
*/
|
*/
|
||||||
public class ScoreDB {
|
public class ScoreDB {
|
||||||
|
/**
|
||||||
|
* Current database version.
|
||||||
|
* This value should be changed whenever the database format changes.
|
||||||
|
* Add any update queries to the {@link #getUpdateQueries(int)} method.
|
||||||
|
*/
|
||||||
|
private static final int DATABASE_VERSION = 20140311;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of SQL queries to apply, in order, to update from
|
||||||
|
* the given database version to the latest version.
|
||||||
|
* @param version the current version
|
||||||
|
* @return a list of SQL queries
|
||||||
|
*/
|
||||||
|
private static List<String> getUpdateQueries(int version) {
|
||||||
|
List<String> list = new LinkedList<String>();
|
||||||
|
if (version < 20140311)
|
||||||
|
list.add("ALTER TABLE scores ADD COLUMN replay TEXT");
|
||||||
|
|
||||||
|
/* add future updates here */
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/** Database connection. */
|
/** Database connection. */
|
||||||
private static Connection connection;
|
private static Connection connection;
|
||||||
|
|
||||||
|
@ -63,13 +87,16 @@ public class ScoreDB {
|
||||||
if (connection == null)
|
if (connection == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// run any database updates
|
||||||
|
updateDatabase();
|
||||||
|
|
||||||
// create the database
|
// create the database
|
||||||
createDatabase();
|
createDatabase();
|
||||||
|
|
||||||
// prepare sql statements
|
// prepare sql statements
|
||||||
try {
|
try {
|
||||||
insertStmt = connection.prepareStatement(
|
insertStmt = connection.prepareStatement(
|
||||||
"INSERT INTO scores VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
"INSERT INTO scores VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||||
);
|
);
|
||||||
selectMapStmt = connection.prepareStatement(
|
selectMapStmt = connection.prepareStatement(
|
||||||
"SELECT * FROM scores WHERE " +
|
"SELECT * FROM scores WHERE " +
|
||||||
|
@ -109,15 +136,75 @@ public class ScoreDB {
|
||||||
"score INTEGER, " +
|
"score INTEGER, " +
|
||||||
"combo INTEGER, " +
|
"combo INTEGER, " +
|
||||||
"perfect BOOLEAN, " +
|
"perfect BOOLEAN, " +
|
||||||
"mods INTEGER" +
|
"mods INTEGER, " +
|
||||||
|
"replay TEXT" +
|
||||||
|
");" +
|
||||||
|
"CREATE TABLE IF NOT EXISTS info (" +
|
||||||
|
"key TEXT NOT NULL UNIQUE, value TEXT" +
|
||||||
"); " +
|
"); " +
|
||||||
"CREATE INDEX IF NOT EXISTS idx ON scores (MID, MSID, title, artist, creator, version);";
|
"CREATE INDEX IF NOT EXISTS idx ON scores (MID, MSID, title, artist, creator, version);";
|
||||||
stmt.executeUpdate(sql);
|
stmt.executeUpdate(sql);
|
||||||
|
|
||||||
|
// set the version key, if empty
|
||||||
|
sql = String.format("INSERT OR IGNORE INTO info(key, value) VALUES('version', %d)", DATABASE_VERSION);
|
||||||
|
stmt.executeUpdate(sql);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
ErrorHandler.error("Could not create score database.", e, true);
|
ErrorHandler.error("Could not create score database.", e, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies any database updates by comparing the current version to the
|
||||||
|
* stored version. Does nothing if tables have not been created.
|
||||||
|
*/
|
||||||
|
private static void updateDatabase() {
|
||||||
|
try (Statement stmt = connection.createStatement()) {
|
||||||
|
int version = 0;
|
||||||
|
|
||||||
|
// if 'info' table does not exist, assume version 0 and apply all updates
|
||||||
|
String sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'info'";
|
||||||
|
ResultSet rs = stmt.executeQuery(sql);
|
||||||
|
boolean infoExists = rs.isBeforeFirst();
|
||||||
|
rs.close();
|
||||||
|
if (!infoExists) {
|
||||||
|
// if 'scores' table also does not exist, databases not yet created
|
||||||
|
sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'scores'";
|
||||||
|
ResultSet scoresRS = stmt.executeQuery(sql);
|
||||||
|
boolean scoresExists = scoresRS.isBeforeFirst();
|
||||||
|
scoresRS.close();
|
||||||
|
if (!scoresExists)
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// try to retrieve stored version
|
||||||
|
sql = "SELECT value FROM info WHERE key = 'version'";
|
||||||
|
ResultSet versionRS = stmt.executeQuery(sql);
|
||||||
|
String versionString = (versionRS.next()) ? versionRS.getString(1) : "0";
|
||||||
|
versionRS.close();
|
||||||
|
try {
|
||||||
|
version = Integer.parseInt(versionString);
|
||||||
|
} catch (NumberFormatException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// database versions match
|
||||||
|
if (version >= DATABASE_VERSION)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// apply updates
|
||||||
|
for (String query : getUpdateQueries(version))
|
||||||
|
stmt.executeUpdate(query);
|
||||||
|
|
||||||
|
// update version
|
||||||
|
if (infoExists) {
|
||||||
|
PreparedStatement ps = connection.prepareStatement("REPLACE INTO info (key, value) VALUES ('version', ?)");
|
||||||
|
ps.setString(1, Integer.toString(DATABASE_VERSION));
|
||||||
|
ps.executeUpdate();
|
||||||
|
ps.close();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
ErrorHandler.error("Failed to update score database.", e, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the game score to the database.
|
* Adds the game score to the database.
|
||||||
* @param data the GameData object
|
* @param data the GameData object
|
||||||
|
@ -128,6 +215,7 @@ public class ScoreDB {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setStatementFields(insertStmt, data);
|
setStatementFields(insertStmt, data);
|
||||||
|
insertStmt.setString(18, data.replayString);
|
||||||
insertStmt.executeUpdate();
|
insertStmt.executeUpdate();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
ErrorHandler.error("Failed to save score to database.", e, true);
|
ErrorHandler.error("Failed to save score to database.", e, true);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package itdelatrisu.opsu.replay;
|
package itdelatrisu.opsu.replay;
|
||||||
|
|
||||||
import itdelatrisu.opsu.ErrorHandler;
|
import itdelatrisu.opsu.ErrorHandler;
|
||||||
|
import itdelatrisu.opsu.Options;
|
||||||
import itdelatrisu.opsu.OsuReader;
|
import itdelatrisu.opsu.OsuReader;
|
||||||
import itdelatrisu.opsu.OsuWriter;
|
import itdelatrisu.opsu.OsuWriter;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
|
@ -217,10 +218,20 @@ public class Replay {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the replay data to a file.
|
* Saves the replay data to a file in the replays directory.
|
||||||
* @param file the file to write to
|
|
||||||
*/
|
*/
|
||||||
public void save(File file) {
|
public void save() {
|
||||||
|
// create replay directory
|
||||||
|
File dir = Options.getReplayDir();
|
||||||
|
if (!dir.isDirectory()) {
|
||||||
|
if (!dir.mkdir()) {
|
||||||
|
ErrorHandler.error("Failed to create replay directory.", null, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write file
|
||||||
|
File file = new File(dir, String.format("%s.osr", getReplayFilename()));
|
||||||
try (FileOutputStream out = new FileOutputStream(file)) {
|
try (FileOutputStream out = new FileOutputStream(file)) {
|
||||||
OsuWriter writer = new OsuWriter(out);
|
OsuWriter writer = new OsuWriter(out);
|
||||||
|
|
||||||
|
@ -299,6 +310,18 @@ public class Replay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the file name of where the replay should be saved and loaded,
|
||||||
|
* or null if the required fields are not set.
|
||||||
|
*/
|
||||||
|
public String getReplayFilename() {
|
||||||
|
if (replayHash == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return String.format("%s-%d%d%d%d%d%d",
|
||||||
|
replayHash, hit300, hit100, hit50, geki, katu, miss);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final int LINE_SPLIT = 5;
|
final int LINE_SPLIT = 5;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import itdelatrisu.opsu.Opsu;
|
||||||
import itdelatrisu.opsu.Options;
|
import itdelatrisu.opsu.Options;
|
||||||
import itdelatrisu.opsu.OsuFile;
|
import itdelatrisu.opsu.OsuFile;
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
|
import itdelatrisu.opsu.OsuParser;
|
||||||
import itdelatrisu.opsu.OsuTimingPoint;
|
import itdelatrisu.opsu.OsuTimingPoint;
|
||||||
import itdelatrisu.opsu.ScoreData;
|
import itdelatrisu.opsu.ScoreData;
|
||||||
import itdelatrisu.opsu.UI;
|
import itdelatrisu.opsu.UI;
|
||||||
|
@ -35,6 +36,7 @@ import itdelatrisu.opsu.audio.HitSound;
|
||||||
import itdelatrisu.opsu.audio.MusicController;
|
import itdelatrisu.opsu.audio.MusicController;
|
||||||
import itdelatrisu.opsu.audio.SoundController;
|
import itdelatrisu.opsu.audio.SoundController;
|
||||||
import itdelatrisu.opsu.audio.SoundEffect;
|
import itdelatrisu.opsu.audio.SoundEffect;
|
||||||
|
import itdelatrisu.opsu.db.OsuDB;
|
||||||
import itdelatrisu.opsu.db.ScoreDB;
|
import itdelatrisu.opsu.db.ScoreDB;
|
||||||
import itdelatrisu.opsu.objects.Circle;
|
import itdelatrisu.opsu.objects.Circle;
|
||||||
import itdelatrisu.opsu.objects.HitObject;
|
import itdelatrisu.opsu.objects.HitObject;
|
||||||
|
@ -49,6 +51,7 @@ import java.util.Stack;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.lwjgl.input.Keyboard;
|
import org.lwjgl.input.Keyboard;
|
||||||
|
import org.lwjgl.opengl.Display;
|
||||||
import org.newdawn.slick.Animation;
|
import org.newdawn.slick.Animation;
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
import org.newdawn.slick.GameContainer;
|
import org.newdawn.slick.GameContainer;
|
||||||
|
@ -483,16 +486,17 @@ public class Game extends BasicGameState {
|
||||||
// go to ranking screen
|
// go to ranking screen
|
||||||
else {
|
else {
|
||||||
((GameRanking) game.getState(Opsu.STATE_GAMERANKING)).setGameData(data);
|
((GameRanking) game.getState(Opsu.STATE_GAMERANKING)).setGameData(data);
|
||||||
ReplayFrame[] rf = null;
|
|
||||||
if (!isReplay && replayFrames != null) {
|
if (!isReplay && replayFrames != null) {
|
||||||
// finalize replay frames with start/skip frames
|
// finalize replay frames with start/skip frames
|
||||||
if (!replayFrames.isEmpty())
|
if (!replayFrames.isEmpty())
|
||||||
replayFrames.getFirst().setTimeDiff(replaySkipTime * -1);
|
replayFrames.getFirst().setTimeDiff(replaySkipTime * -1);
|
||||||
replayFrames.addFirst(ReplayFrame.getStartFrame(replaySkipTime));
|
replayFrames.addFirst(ReplayFrame.getStartFrame(replaySkipTime));
|
||||||
replayFrames.addFirst(ReplayFrame.getStartFrame(0));
|
replayFrames.addFirst(ReplayFrame.getStartFrame(0));
|
||||||
rf = replayFrames.toArray(new ReplayFrame[replayFrames.size()]);
|
Replay r = data.getReplay(replayFrames.toArray(new ReplayFrame[replayFrames.size()]));
|
||||||
|
if (r != null)
|
||||||
|
r.save();
|
||||||
}
|
}
|
||||||
ScoreData score = data.getScoreData(osu, rf);
|
ScoreData score = data.getScoreData(osu);
|
||||||
|
|
||||||
// add score to database
|
// add score to database
|
||||||
if (!GameMod.AUTO.isActive() && !GameMod.RELAX.isActive() && !GameMod.AUTOPILOT.isActive() && !isReplay)
|
if (!GameMod.AUTO.isActive() && !GameMod.RELAX.isActive() && !GameMod.AUTOPILOT.isActive() && !isReplay)
|
||||||
|
@ -830,8 +834,6 @@ public class Game extends BasicGameState {
|
||||||
public void enter(GameContainer container, StateBasedGame game)
|
public void enter(GameContainer container, StateBasedGame game)
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
UI.enter();
|
UI.enter();
|
||||||
if (restart == Restart.NEW)
|
|
||||||
osu = MusicController.getOsuFile();
|
|
||||||
|
|
||||||
if (osu == null || osu.objects == null)
|
if (osu == null || osu.objects == null)
|
||||||
throw new RuntimeException("Running game with no OsuFile loaded.");
|
throw new RuntimeException("Running game with no OsuFile loaded.");
|
||||||
|
@ -978,6 +980,19 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads all required data from an OsuFile.
|
||||||
|
* @param osu the OsuFile to load
|
||||||
|
*/
|
||||||
|
public void loadOsuFile(OsuFile osu) {
|
||||||
|
this.osu = osu;
|
||||||
|
Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString()));
|
||||||
|
if (osu.timingPoints == null || osu.combo == null)
|
||||||
|
OsuDB.load(osu, OsuDB.LOAD_ARRAY);
|
||||||
|
OsuParser.parseHitObjects(osu);
|
||||||
|
HitSound.setDefaultSampleSet(osu.sampleSet);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets all game data and structures.
|
* Resets all game data and structures.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -163,27 +163,29 @@ public class GameRanking extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// replay
|
// replay
|
||||||
|
Game gameState = (Game) game.getState(Opsu.STATE_GAME);
|
||||||
boolean returnToGame = false;
|
boolean returnToGame = false;
|
||||||
if (replayButton.contains(x, y)) {
|
if (replayButton.contains(x, y)) {
|
||||||
Replay r = data.getReplay(null);
|
Replay r = data.getReplay(null);
|
||||||
if (r != null) {
|
if (r != null) {
|
||||||
r.load();
|
r.load();
|
||||||
((Game) game.getState(Opsu.STATE_GAME)).setReplay(r);
|
gameState.setReplay(r);
|
||||||
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.REPLAY);
|
gameState.setRestart((data.isGameplay()) ? Game.Restart.REPLAY : Game.Restart.NEW);
|
||||||
returnToGame = true;
|
returnToGame = true;
|
||||||
}
|
} else
|
||||||
|
UI.sendBarNotification("Replay file not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// retry
|
// retry
|
||||||
else if (data.isGameplay() && retryButton.contains(x, y)) {
|
else if (data.isGameplay() && retryButton.contains(x, y)) {
|
||||||
((Game) game.getState(Opsu.STATE_GAME)).setReplay(null);
|
gameState.setReplay(null);
|
||||||
((Game) game.getState(Opsu.STATE_GAME)).setRestart(Game.Restart.MANUAL);
|
gameState.setRestart(Game.Restart.MANUAL);
|
||||||
returnToGame = true;
|
returnToGame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnToGame) {
|
if (returnToGame) {
|
||||||
OsuFile osu = MusicController.getOsuFile();
|
OsuFile osu = MusicController.getOsuFile();
|
||||||
Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString()));
|
gameState.loadOsuFile(osu);
|
||||||
SoundController.playSound(SoundEffect.MENUHIT);
|
SoundController.playSound(SoundEffect.MENUHIT);
|
||||||
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
|
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
|
||||||
return;
|
return;
|
||||||
|
@ -211,6 +213,8 @@ public class GameRanking extends BasicGameState {
|
||||||
public void leave(GameContainer container, StateBasedGame game)
|
public void leave(GameContainer container, StateBasedGame game)
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
this.data = null;
|
this.data = null;
|
||||||
|
if (MusicController.isTrackDimmed())
|
||||||
|
MusicController.toggleTrackDimmed(1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,7 +34,6 @@ import itdelatrisu.opsu.ScoreData;
|
||||||
import itdelatrisu.opsu.SongSort;
|
import itdelatrisu.opsu.SongSort;
|
||||||
import itdelatrisu.opsu.UI;
|
import itdelatrisu.opsu.UI;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.audio.HitSound;
|
|
||||||
import itdelatrisu.opsu.audio.MultiClip;
|
import itdelatrisu.opsu.audio.MultiClip;
|
||||||
import itdelatrisu.opsu.audio.MusicController;
|
import itdelatrisu.opsu.audio.MusicController;
|
||||||
import itdelatrisu.opsu.audio.SoundController;
|
import itdelatrisu.opsu.audio.SoundController;
|
||||||
|
@ -1288,17 +1287,10 @@ public class SongMenu extends BasicGameState {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SoundController.playSound(SoundEffect.MENUHIT);
|
SoundController.playSound(SoundEffect.MENUHIT);
|
||||||
OsuFile osu = MusicController.getOsuFile();
|
|
||||||
Display.setTitle(String.format("%s - %s", game.getTitle(), osu.toString()));
|
|
||||||
|
|
||||||
// load any missing data
|
|
||||||
if (osu.timingPoints == null || osu.combo == null)
|
|
||||||
OsuDB.load(osu, OsuDB.LOAD_ARRAY);
|
|
||||||
OsuParser.parseHitObjects(osu);
|
|
||||||
HitSound.setDefaultSampleSet(osu.sampleSet);
|
|
||||||
|
|
||||||
MultiClip.destroyExtraClips();
|
MultiClip.destroyExtraClips();
|
||||||
|
OsuFile osu = MusicController.getOsuFile();
|
||||||
Game gameState = (Game) game.getState(Opsu.STATE_GAME);
|
Game gameState = (Game) game.getState(Opsu.STATE_GAME);
|
||||||
|
gameState.loadOsuFile(osu);
|
||||||
gameState.setRestart(Game.Restart.NEW);
|
gameState.setRestart(Game.Restart.NEW);
|
||||||
gameState.setReplay(null);
|
gameState.setReplay(null);
|
||||||
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
|
game.enterState(Opsu.STATE_GAME, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user