Save game scores to an SQLite database. [Incomplete!]

Implemented basic features (mostly stable).  The remaining features are mostly graphical.
- Added package org.xerial.sqlite-jdbc.  All scores are saved to .opsu_scores.db on table `scores` after a game completes.
- Added "Scores" class to handle all game score data (including database connections).  The "Score" subclass encapsulates all database fields.
- Added "score viewing" constructor to GameData, for use only in the ranking screen.
- Draw the grade of the highest score next to expanded song buttons in the song menu.
- Added "bit" and "abbrev" fields to GameMod, used in storing/displaying scores.
- Hide the retry/exit buttons in the ranking screen when viewing a score.

Other changes:
- Removed "objectCount" field in GameData (no longer necessary).
- Removed "getID()" method in GameMod (no longer used).
- Moved most drawing in GameRanking state to GameData.
- Removed File parameter of "GameData.loadImages()" (leftover, no longer used).

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han
2015-01-28 03:47:24 -05:00
parent f71b2c25f2
commit 0bd72e731a
13 changed files with 693 additions and 133 deletions

View File

@@ -28,6 +28,9 @@ import itdelatrisu.opsu.OsuGroupList;
import itdelatrisu.opsu.OsuGroupNode;
import itdelatrisu.opsu.OsuParser;
import itdelatrisu.opsu.OszUnpacker;
import itdelatrisu.opsu.Scores;
import itdelatrisu.opsu.GameData.Grade;
import itdelatrisu.opsu.Scores.ScoreData;
import itdelatrisu.opsu.SongSort;
import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.audio.HitSound;
@@ -36,6 +39,7 @@ import itdelatrisu.opsu.audio.SoundController;
import itdelatrisu.opsu.audio.SoundEffect;
import java.io.File;
import java.util.Map;
import java.util.Stack;
import org.lwjgl.opengl.Display;
@@ -153,6 +157,9 @@ public class SongMenu extends BasicGameState {
/** Beatmap reloading thread. */
private Thread reloadThread;
/** Current map of scores (Version, ScoreData[]). */
private Map<String, ScoreData[]> scoreMap;
// game-related variables
private GameContainer container;
private StateBasedGame game;
@@ -261,8 +268,16 @@ public class SongMenu extends BasicGameState {
// song buttons
OsuGroupNode node = startNode;
for (int i = 0; i < MAX_BUTTONS && node != null; i++, node = node.next) {
// draw the node
float offset = (i == hoverIndex) ? hoverOffset : 0f;
node.draw(buttonX - offset, buttonY + (i*buttonOffset), (node == focusNode));
ScoreData[] scores = getScoreDataForNode(node);
node.draw(
buttonX - offset, buttonY + (i*buttonOffset),
(scores == null) ? Grade.NULL : scores[0].getGrade(),
(node == focusNode)
);
// load glyphs
Utils.loadGlyphs(node.osuFiles.get(0));
}
@@ -703,11 +718,17 @@ public class SongMenu extends BasicGameState {
// reset game data
if (resetGame) {
((Game) game.getState(Opsu.STATE_GAME)).resetGameData();
// destroy skin images, if any
for (GameImage img : GameImage.values()) {
if (img.isSkinnable())
img.destroySkinImage();
}
// reload scores
if (focusNode != null)
scoreMap = Scores.getMapSetScores(focusNode.osuFiles.get(focusNode.osuFileIndex));
resetGame = false;
}
}
@@ -798,6 +819,9 @@ public class SongMenu extends BasicGameState {
MusicController.play(osu, true);
Utils.loadGlyphs(osu);
// load scores
scoreMap = Scores.getMapSetScores(osu);
// check startNode bounds
while (startNode.index >= OsuGroupList.get().size() + length - MAX_BUTTONS && startNode.prev != null)
startNode = startNode.prev;
@@ -835,6 +859,30 @@ public class SongMenu extends BasicGameState {
*/
public void resetTrackOnLoad() { resetTrack = true; }
/**
* Returns all the score data for an OsuGroupNode from scoreMap.
* If no score data is available for the node, return null.
* @param node the OsuGroupNode
* @return the ScoreData array
*/
private ScoreData[] getScoreDataForNode(OsuGroupNode node) {
if (scoreMap == null || node.osuFileIndex == -1) // node not expanded
return null;
OsuFile osu = node.osuFiles.get(node.osuFileIndex);
ScoreData[] scores = scoreMap.get(osu.version);
if (scores == null || scores.length < 1) // no scores
return null;
ScoreData s = scores[0];
if (osu.beatmapID == s.MID && osu.beatmapSetID == s.MSID &&
osu.title.equals(s.title) && osu.artist.equals(s.artist) &&
osu.creator.equals(s.creator))
return scores;
else
return null; // incorrect map
}
/**
* Starts the game.
* @param osu the OsuFile to send to the game