diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index 89fb1e9e..1e7a6155 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -447,21 +447,37 @@ public class GameData { } /** - * Returns a default/score text symbol image for a character. + * Returns a default text symbol image for a digit. + * @param i the digit [0-9] */ public Image getDefaultSymbolImage(int i) { return defaultSymbols[i]; } + + /** + * Returns a score text symbol image for a character. + * @param c the character [0-9,.%x] + */ public Image getScoreSymbolImage(char c) { return scoreSymbols.get(c); } /** - * Sets or returns the health drain rate. + * Sets the health drain rate. + * @param drainRate the new drain rate [0-10] */ public void setDrainRate(float drainRate) { this.drainRate = drainRate; } + + /** + * Returns the health drain rate. + */ public float getDrainRate() { return drainRate; } /** - * Sets or returns the difficulty. + * Sets the overall difficulty level. + * @param difficulty the new difficulty [0-10] */ public void setDifficulty(float difficulty) { this.difficulty = difficulty; } + + /** + * Returns the overall difficulty level. + */ public float getDifficulty() { return difficulty; } /** @@ -847,7 +863,7 @@ public class GameData { /** * Draws stored hit results and removes them from the list as necessary. - * @param trackPosition the current track position + * @param trackPosition the current track position (in ms) */ public void drawHitResults(int trackPosition) { Iterator iter = hitResultList.iterator(); @@ -930,6 +946,7 @@ public class GameData { /** * Changes health by a given percentage, modified by drainRate. + * @param percent the health percentage */ public void changeHealth(float percent) { // TODO: drainRate formula @@ -941,7 +958,7 @@ public class GameData { } /** - * Returns health percentage. + * Returns the current health percentage. */ public float getHealth() { return health; } @@ -956,6 +973,7 @@ public class GameData { /** * Changes score by a raw value (not affected by other modifiers). + * @param value the score value */ public void changeScore(int value) { score += value; } @@ -965,7 +983,7 @@ public class GameData { * @param hit100 the number of 100s * @param hit50 the number of 50s * @param miss the number of misses - * @return the percentage + * @return the score percentage */ public static float getScorePercent(int hit300, int hit100, int hit50, int miss) { float percent = 0; @@ -1020,7 +1038,7 @@ public class GameData { /** * Returns letter grade based on score data, - * or Grade.NULL if no objects have been processed. + * or {@code Grade.NULL} if no objects have been processed. */ private Grade getGrade() { return getGrade( @@ -1194,6 +1212,23 @@ public class GameData { } } + /** + * Returns the score for a hit based on the following score formula: + *

+ * Score = Hit Value + Hit Value * (Combo * Difficulty * Mod) / 25 + *

+ * @param hitValue the hit value + * @return the score value + */ + private int getScoreForHit(int hitValue) { + return hitValue + (int) (hitValue * (Math.max(combo - 1, 0) * difficulty * GameMod.getScoreMultiplier()) / 25); + } + /** * Handles a hit result and performs all associated calculations. * @param time the object start time @@ -1209,6 +1244,7 @@ public class GameData { */ private int handleHitResult(int time, int result, float x, float y, Color color, boolean end, HitObject hitObject, int repeat, HitObjectType hitResultType) { + // update health, score, and combo streak based on hit result int hitValue = 0; switch (result) { case HIT_300: @@ -1238,15 +1274,9 @@ public class GameData { hitObject.getEdgeHitSoundType(repeat), hitObject.getSampleSet(repeat), hitObject.getAdditionSampleSet(repeat)); - /** - * [SCORE FORMULA] - * Score = Hit Value + Hit Value * (Combo * Difficulty * Mod) / 25 - * - Hit Value: hit result (50, 100, 300), slider ticks, spinner bonus - * - Combo: combo before this hit - 1 (minimum 0) - * - Difficulty: the beatmap difficulty - * - Mod: mod multipliers - */ - score += (hitValue + (hitValue * (Math.max(combo - 1, 0) * difficulty * GameMod.getScoreMultiplier()) / 25)); + + // calculate score and increment combo streak + changeScore(getScoreForHit(hitValue)); incrementComboStreak(); } hitResultCount[result]++; @@ -1385,6 +1415,7 @@ public class GameData { /** * Sets the replay object. + * @param replay the replay */ public void setReplay(Replay replay) { this.replay = replay; } diff --git a/src/itdelatrisu/opsu/GameImage.java b/src/itdelatrisu/opsu/GameImage.java index b569f776..9dbeb55c 100644 --- a/src/itdelatrisu/opsu/GameImage.java +++ b/src/itdelatrisu/opsu/GameImage.java @@ -388,10 +388,13 @@ public enum GameImage { /** The unscaled container height that uiscale is based on. */ private static final int UNSCALED_HEIGHT = 768; + /** Filename suffix for HD images. */ + private static final String HD_SUFFIX = "@2x"; + /** Image HD/SD suffixes. */ private static final String[] - SUFFIXES_HD = new String[] { "@2x", "" }, - SUFFIXES_SD = new String[] { "" }; + SUFFIXES_HD = new String[] { HD_SUFFIX, "" }, + SUFFIXES_SD = new String[] { "" }; /** * Initializes the GameImage class with container dimensions. @@ -562,6 +565,7 @@ public enum GameImage { /** * Sets the image associated with this resource to another image. * The skin image takes priority over the default image. + * @param img the image to set */ public void setImage(Image img) { if (skinImage != null) @@ -573,6 +577,8 @@ public enum GameImage { /** * Sets an image associated with this resource to another image. * The skin image takes priority over the default image. + * @param img the image to set + * @param index the index in the image array */ public void setImage(Image img, int index) { if (skinImages != null) { @@ -615,6 +621,7 @@ public enum GameImage { /** * Sets the associated skin image. * If the path does not contain the image, the default image is used. + * @param dir the image directory to search * @return true if a new skin image is loaded, false otherwise */ public boolean setSkinImage(File dir) { @@ -645,6 +652,7 @@ public enum GameImage { /** * Attempts to load multiple Images from the GameImage. + * @param dir the image directory to search, or null to use the default resource locations * @return an array of the loaded images, or null if not found */ private Image[] loadImageArray(File dir) { @@ -662,7 +670,7 @@ public enum GameImage { // add image to list try { Image img = new Image(name); - if (suffix.equals("@2x")) + if (suffix.equals(HD_SUFFIX)) img = img.getScaledCopy(0.5f); list.add(img); } catch (SlickException e) { @@ -679,6 +687,7 @@ public enum GameImage { /** * Attempts to load a single Image from the GameImage. + * @param dir the image directory to search, or null to use the default resource locations * @return the loaded image, or null if not found */ private Image loadImageSingle(File dir) { @@ -687,7 +696,7 @@ public enum GameImage { if (name != null) { try { Image img = new Image(name); - if (suffix.equals("@2x")) + if (suffix.equals(HD_SUFFIX)) img = img.getScaledCopy(0.5f); return img; } catch (SlickException e) { diff --git a/src/itdelatrisu/opsu/audio/MusicController.java b/src/itdelatrisu/opsu/audio/MusicController.java index af3f3b22..695dbe28 100644 --- a/src/itdelatrisu/opsu/audio/MusicController.java +++ b/src/itdelatrisu/opsu/audio/MusicController.java @@ -228,7 +228,7 @@ public class MusicController { } /** - * Returns the position in the current track, in ms. + * Returns the position in the current track, in milliseconds. * If no track is loaded, 0 will be returned. */ public static int getPosition() { @@ -242,6 +242,7 @@ public class MusicController { /** * Seeks to a position in the current track. + * @param position the new track position (in ms) */ public static boolean setPosition(int position) { return (trackExists() && position >= 0 && player.setPosition(position / 1000f)); @@ -259,6 +260,7 @@ public class MusicController { return -1; if (duration == 0) { + // TAudioFileFormat method only works for MP3s if (lastBeatmap.audioFilename.getName().endsWith(".mp3")) { try { AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(lastBeatmap.audioFilename); @@ -270,6 +272,8 @@ public class MusicController { } } catch (UnsupportedAudioFileException | IOException e) {} } + + // fallback: use beatmap end time (often not the track duration) duration = lastBeatmap.endTime; } return duration; @@ -291,7 +295,7 @@ public class MusicController { /** * Sets the music volume. - * @param volume [0, 1] + * @param volume the new volume [0, 1] */ public static void setVolume(float volume) { SoundStore.get().setMusicVolume((isTrackDimmed()) ? volume * dimLevel : volume); @@ -299,7 +303,7 @@ public class MusicController { /** * Sets the music pitch (and speed). - * @param pitch + * @param pitch the new pitch */ public static void setPitch(float pitch) { SoundStore.get().setMusicPitch(pitch); diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index abc53636..01e840c5 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -1304,7 +1304,7 @@ public class Game extends BasicGameState { /** * Skips the beginning of a track. - * @return true if skipped, false otherwise + * @return {@code true} if skipped, {@code false} otherwise */ private synchronized boolean skipIntro() { int firstObjectTime = beatmap.objects[0].getTime(); @@ -1409,9 +1409,14 @@ public class Game extends BasicGameState { } /** - * Sets/returns whether entering the state will restart it. + * Sets the restart state. + * @param restart the new restart state */ public void setRestart(Restart restart) { this.restart = restart; } + + /** + * Returns the current restart state. + */ public Restart getRestart() { return restart; } /**