Spinner Test2
Improves Score accuracy (still mostly wrong) inital replay seek
This commit is contained in:
parent
fa9accfc88
commit
40e67cedc9
|
@ -267,6 +267,14 @@ public class GameData {
|
|||
/** Beatmap OverallDifficulty value. (0:easy ~ 10:hard) */
|
||||
private float difficulty = 5f;
|
||||
|
||||
/** Beatmap ApproachRate value. (0:easy ~ 10:hard) */
|
||||
private float approachRate = 5f;
|
||||
|
||||
/** Beatmap CircleSize value. (2:big ~ 7:small) */
|
||||
private float circleSize = 5f;
|
||||
|
||||
private int difficultyMultiplier = -1;
|
||||
|
||||
/** Default text symbol images. */
|
||||
private Image[] defaultSymbols;
|
||||
|
||||
|
@ -432,6 +440,18 @@ public class GameData {
|
|||
public void setDifficulty(float difficulty) { this.difficulty = difficulty; }
|
||||
public float getDifficulty() { return difficulty; }
|
||||
|
||||
/**
|
||||
* Sets or returns the approach rate.
|
||||
*/
|
||||
public void setApproachRate(float approachRate) { this.approachRate = approachRate; }
|
||||
public float getApproachRate() { return approachRate; }
|
||||
|
||||
/**
|
||||
* Sets or returns the approach rate.
|
||||
*/
|
||||
public void setCircleSize(float circleSize) { this.circleSize = circleSize; }
|
||||
public float getCircleSize() { return circleSize; }
|
||||
|
||||
/**
|
||||
* Sets the array of hit result offsets.
|
||||
*/
|
||||
|
@ -1118,6 +1138,10 @@ public class GameData {
|
|||
hitResultList.add(new OsuHitObjectResult(time, result, x, y, null, false));
|
||||
}
|
||||
}
|
||||
public void sliderFinalResult(int time, int hitSlider30, float x, float y,
|
||||
OsuHitObject hitObject, int currentRepeats) {
|
||||
score += 30;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a hit result.
|
||||
|
@ -1141,15 +1165,18 @@ public class GameData {
|
|||
changeHealth(5f);
|
||||
break;
|
||||
case HIT_100:
|
||||
System.out.println("100! "+hitObject+" "+hitObject.getTime()+" "+hitObject.getTypeName());
|
||||
hitValue = 100;
|
||||
changeHealth(2f);
|
||||
comboEnd |= 1;
|
||||
break;
|
||||
case HIT_50:
|
||||
System.out.println("50! "+hitObject+" "+hitObject.getTime()+" "+hitObject.getTypeName());
|
||||
hitValue = 50;
|
||||
comboEnd |= 2;
|
||||
break;
|
||||
case HIT_MISS:
|
||||
System.out.println("miss! "+hitObject+" "+hitObject.getTime()+" "+hitObject.getTypeName());
|
||||
hitValue = 0;
|
||||
changeHealth(-10f);
|
||||
comboEnd |= 2;
|
||||
|
@ -1164,6 +1191,7 @@ public class GameData {
|
|||
hitObject.getSampleSet(repeat),
|
||||
hitObject.getAdditionSampleSet(repeat));
|
||||
/**
|
||||
* https://osu.ppy.sh/wiki/Score
|
||||
* [SCORE FORMULA]
|
||||
* Score = Hit Value + Hit Value * (Combo * Difficulty * Mod) / 25
|
||||
* - Hit Value: hit result (50, 100, 300), slider ticks, spinner bonus
|
||||
|
@ -1171,7 +1199,11 @@ public class GameData {
|
|||
* - Difficulty: the beatmap difficulty
|
||||
* - Mod: mod multipliers
|
||||
*/
|
||||
score += (hitValue + (hitValue * (Math.max(combo - 1, 0) * difficulty * GameMod.getScoreMultiplier()) / 25));
|
||||
int comboMulti = Math.max(combo - 1, 0);
|
||||
if(hitObject.isSlider()){
|
||||
comboMulti += 1;
|
||||
}
|
||||
score += (hitValue + (hitValue * (comboMulti * getDifficultyMultiplier() * GameMod.getScoreMultiplier()) / 25));
|
||||
incrementComboStreak();
|
||||
}
|
||||
hitResultCount[result]++;
|
||||
|
@ -1205,6 +1237,23 @@ public class GameData {
|
|||
hitResultList.add(new OsuHitObjectResult(time, result, x, y, color, hitObject.isSpinner()));
|
||||
}
|
||||
|
||||
private int getDifficultyMultiplier() {
|
||||
return difficultyMultiplier;
|
||||
}
|
||||
|
||||
public void calculateDifficultyMultiplier() {
|
||||
//https://osu.ppy.sh/wiki/Score#How_to_calculate_the_Difficulty_multiplier
|
||||
//TODO THE LIES ( difficultyMultiplier )
|
||||
/*
|
||||
924 3x1/4 beat notes 0.14stars
|
||||
924 3x1beat 0.28stars
|
||||
912 3x1beat wth 1 extra note 10 sec away 0.29stars
|
||||
|
||||
seems to be based on hitobject density? (Total Objects/Time)
|
||||
*/
|
||||
|
||||
difficultyMultiplier = (int)((circleSize + difficulty + drainRate) / 6) + 2;
|
||||
}
|
||||
/**
|
||||
* Returns a ScoreData object encapsulating all game data.
|
||||
* If score data already exists, the existing object will be returned
|
||||
|
@ -1235,7 +1284,7 @@ public class GameData {
|
|||
scoreData.perfect = (comboMax == fullObjectCount);
|
||||
scoreData.mods = GameMod.getModState();
|
||||
scoreData.replayString = (replay == null) ? null : replay.getReplayFilename();
|
||||
scoreData.playerName = "OpsuPlayer"; //TODO?
|
||||
scoreData.playerName = "OpsuPlayer"; //TODO GameDataPlayerName?
|
||||
return scoreData;
|
||||
}
|
||||
|
||||
|
|
|
@ -452,7 +452,7 @@ public class Options {
|
|||
private static Resolution resolution = Resolution.RES_1024_768;
|
||||
|
||||
/** Frame limiters. */
|
||||
private static final int[] targetFPS = { 60, 120, 240 };
|
||||
private static final int[] targetFPS = { 60, 120, 240, 30, 20, 15, 12 };
|
||||
|
||||
/** Index in targetFPS[] array. */
|
||||
private static int targetFPSindex = 0;
|
||||
|
@ -830,8 +830,8 @@ public class Options {
|
|||
|
||||
/**
|
||||
* Returns the replay import directory.
|
||||
* If invalid, this will create and return a "SongPacks" directory.
|
||||
* @return the OSZ archive directory
|
||||
* If invalid, this will create and return a "ReplayImport" directory.
|
||||
* @return the replay import directory
|
||||
*/
|
||||
public static File getReplayImportDir() {
|
||||
if (replayImportDir != null && replayImportDir.isDirectory())
|
||||
|
|
|
@ -180,6 +180,7 @@ public class OsuFile implements Comparable<OsuFile> {
|
|||
/** Combo colors (max 8). */
|
||||
public Color[] combo;
|
||||
|
||||
/** md5 hash of this file */
|
||||
public String md5Hash;
|
||||
|
||||
/**
|
||||
|
|
|
@ -57,7 +57,7 @@ public class OsuGroupList {
|
|||
/** Set of all beatmap set IDs for the parsed beatmaps. */
|
||||
private HashSet<Integer> MSIDdb;
|
||||
|
||||
/** Set of all beatmap set IDs for the parsed beatmaps. */
|
||||
/** Map of all hash to OsuFile . */
|
||||
public HashMap<String, OsuFile> beatmapHashesToFile;
|
||||
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ public class ScoreData implements Comparable<ScoreData> {
|
|||
/** The tooltip string. */
|
||||
private String tooltip;
|
||||
|
||||
/** The players Name. */
|
||||
public String playerName;
|
||||
|
||||
/** Drawing values. */
|
||||
|
|
|
@ -244,6 +244,7 @@ public class UI {
|
|||
int FPSmod = (Options.getTargetFPS() / 60);
|
||||
|
||||
// TODO: use an image buffer
|
||||
/*
|
||||
if (newStyle) {
|
||||
// new style: add all points between cursor movements
|
||||
if (lastX < 0) {
|
||||
|
@ -264,7 +265,7 @@ public class UI {
|
|||
int max = 10 * FPSmod;
|
||||
if (cursorX.size() > max)
|
||||
removeCount = cursorX.size() - max;
|
||||
}
|
||||
}*/
|
||||
|
||||
// remove points from the lists
|
||||
for (int i = 0; i < removeCount && !cursorX.isEmpty(); i++) {
|
||||
|
|
|
@ -97,6 +97,11 @@ public class ScoreDB {
|
|||
|
||||
// prepare sql statements
|
||||
try {
|
||||
|
||||
//TODO timestamp as primary key should prevent importing the same replay multiple times
|
||||
//but if for some magical reason two different replays has the same time stamp
|
||||
//it will fail, such as copying replays from another drive? which will reset
|
||||
//the last modified of the file.
|
||||
insertStmt = connection.prepareStatement(
|
||||
"INSERT OR IGNORE INTO scores VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
|
@ -116,7 +121,8 @@ public class ScoreDB {
|
|||
"DELETE FROM scores WHERE " +
|
||||
"timestamp = ? AND MID = ? AND MSID = ? AND title = ? AND artist = ? AND " +
|
||||
"creator = ? AND version = ? AND hit300 = ? AND hit100 = ? AND hit50 = ? AND " +
|
||||
"geki = ? AND katu = ? AND miss = ? AND score = ? AND combo = ? AND perfect = ? AND mods = ?"
|
||||
"geki = ? AND katu = ? AND miss = ? AND score = ? AND combo = ? AND perfect = ? AND mods = ? AND " +
|
||||
"replay = ? AND playerName = ?"
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
ErrorHandler.error("Failed to prepare score statements.", e, true);
|
||||
|
@ -286,6 +292,7 @@ public class ScoreDB {
|
|||
stmt.setInt(15, data.combo);
|
||||
stmt.setBoolean(16, data.perfect);
|
||||
stmt.setInt(17, data.mods);
|
||||
stmt.setString(18, data.replayString);
|
||||
stmt.setString(19, data.playerName);
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package itdelatrisu.opsu.io;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -51,7 +52,7 @@ public class OsuWriter {
|
|||
* @param dest the output stream to write to
|
||||
*/
|
||||
public OsuWriter(OutputStream dest) {
|
||||
this.writer = new DataOutputStream(dest);
|
||||
this.writer = new DataOutputStream(new BufferedOutputStream(dest));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,8 @@ public class Circle implements HitObject {
|
|||
/** The amount of time, in milliseconds, to fade in the circle. */
|
||||
private static final int FADE_IN_TIME = 375;
|
||||
|
||||
private static float diameter;
|
||||
|
||||
/** The associated OsuHitObject. */
|
||||
private OsuHitObject hitObject;
|
||||
|
||||
|
@ -54,17 +56,19 @@ public class Circle implements HitObject {
|
|||
/** Whether or not the circle result ends the combo streak. */
|
||||
private boolean comboEnd;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the Circle data type with map modifiers, images, and dimensions.
|
||||
* @param container the game container
|
||||
* @param circleSize the map's circleSize value
|
||||
*/
|
||||
public static void init(GameContainer container, float circleSize) {
|
||||
int diameter = (int) (104 - (circleSize * 8));
|
||||
diameter = (int) (diameter * OsuHitObject.getXMultiplier()); // convert from Osupixels (640x480)
|
||||
GameImage.HITCIRCLE.setImage(GameImage.HITCIRCLE.getImage().getScaledCopy(diameter, diameter));
|
||||
GameImage.HITCIRCLE_OVERLAY.setImage(GameImage.HITCIRCLE_OVERLAY.getImage().getScaledCopy(diameter, diameter));
|
||||
GameImage.APPROACHCIRCLE.setImage(GameImage.APPROACHCIRCLE.getImage().getScaledCopy(diameter, diameter));
|
||||
diameter = (108 - (circleSize * 8));
|
||||
diameter = (diameter * OsuHitObject.getXMultiplier()); // convert from Osupixels (640x480)
|
||||
int diameterInt = (int)diameter;
|
||||
GameImage.HITCIRCLE.setImage(GameImage.HITCIRCLE.getImage().getScaledCopy(diameterInt, diameterInt));
|
||||
GameImage.HITCIRCLE_OVERLAY.setImage(GameImage.HITCIRCLE_OVERLAY.getImage().getScaledCopy(diameterInt, diameterInt));
|
||||
GameImage.APPROACHCIRCLE.setImage(GameImage.APPROACHCIRCLE.getImage().getScaledCopy(diameterInt, diameterInt));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,16 +117,19 @@ public class Circle implements HitObject {
|
|||
private int hitResult(int time) {
|
||||
int timeDiff = Math.abs(time);
|
||||
|
||||
|
||||
int[] hitResultOffset = game.getHitResultOffsets();
|
||||
int result = -1;
|
||||
if (timeDiff < hitResultOffset[GameData.HIT_300])
|
||||
if (timeDiff <= hitResultOffset[GameData.HIT_300])
|
||||
result = GameData.HIT_300;
|
||||
else if (timeDiff < hitResultOffset[GameData.HIT_100])
|
||||
else if (timeDiff <= hitResultOffset[GameData.HIT_100])
|
||||
result = GameData.HIT_100;
|
||||
else if (timeDiff < hitResultOffset[GameData.HIT_50])
|
||||
else if (timeDiff <= hitResultOffset[GameData.HIT_50])
|
||||
result = GameData.HIT_50;
|
||||
else if (timeDiff < hitResultOffset[GameData.HIT_MISS])
|
||||
else if (timeDiff <= hitResultOffset[GameData.HIT_MISS]){
|
||||
result = GameData.HIT_MISS;
|
||||
System.out.println(timeDiff);
|
||||
}
|
||||
//else not a hit
|
||||
|
||||
return result;
|
||||
|
@ -131,8 +138,7 @@ public class Circle implements HitObject {
|
|||
@Override
|
||||
public boolean mousePressed(int x, int y, int trackPosition) {
|
||||
double distance = Math.hypot(this.x - x, this.y - y);
|
||||
int circleRadius = GameImage.HITCIRCLE.getImage().getWidth() / 2;
|
||||
if (distance < circleRadius) {
|
||||
if (distance < diameter/2) {
|
||||
int timeDiff = trackPosition - hitObject.getTime();
|
||||
int result = hitResult(timeDiff);
|
||||
|
||||
|
@ -152,7 +158,7 @@ public class Circle implements HitObject {
|
|||
int[] hitResultOffset = game.getHitResultOffsets();
|
||||
boolean isAutoMod = GameMod.AUTO.isActive();
|
||||
|
||||
if (overlap || trackPosition > time + hitResultOffset[GameData.HIT_50]) {
|
||||
if (trackPosition > time + hitResultOffset[GameData.HIT_50]) {
|
||||
if (isAutoMod) // "auto" mod: catch any missed notes due to lag
|
||||
data.hitResult(time, GameData.HIT_300, x, y, color, comboEnd, hitObject, 0);
|
||||
|
||||
|
@ -187,4 +193,9 @@ public class Circle implements HitObject {
|
|||
this.x = hitObject.getScaledX();
|
||||
this.y = hitObject.getScaledY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,4 +63,9 @@ public class DummyObject implements HitObject {
|
|||
this.x = hitObject.getScaledX();
|
||||
this.y = hitObject.getScaledY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,4 +69,9 @@ public interface HitObject {
|
|||
* Updates the position of the hit object.
|
||||
*/
|
||||
public void updatePosition();
|
||||
|
||||
/**
|
||||
* Resets the hit object so that it can be reused.
|
||||
*/
|
||||
public void reset();
|
||||
}
|
||||
|
|
|
@ -46,6 +46,10 @@ public class Slider implements HitObject {
|
|||
|
||||
/** Rate at which slider ticks are placed. */
|
||||
private static float sliderTickRate = 1.0f;
|
||||
|
||||
private static float followRadius;
|
||||
|
||||
private static float diameter;
|
||||
|
||||
/** The amount of time, in milliseconds, to fade in the slider. */
|
||||
private static final int FADE_IN_TIME = 375;
|
||||
|
@ -97,6 +101,8 @@ public class Slider implements HitObject {
|
|||
|
||||
/** Container dimensions. */
|
||||
private static int containerWidth, containerHeight;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the Slider data type with images and dimensions.
|
||||
|
@ -107,10 +113,13 @@ public class Slider implements HitObject {
|
|||
public static void init(GameContainer container, float circleSize, OsuFile osu) {
|
||||
containerWidth = container.getWidth();
|
||||
containerHeight = container.getHeight();
|
||||
|
||||
int diameter = (int) (104 - (circleSize * 8));
|
||||
diameter = (int) (diameter * OsuHitObject.getXMultiplier()); // convert from Osupixels (640x480)
|
||||
|
||||
|
||||
diameter = (108 - (circleSize * 8));
|
||||
diameter = (diameter * OsuHitObject.getXMultiplier()); // convert from Osupixels (640x480)
|
||||
int diameterInt = (int)diameter;
|
||||
|
||||
followRadius = diameter / 2 * 3f;
|
||||
|
||||
// slider ball
|
||||
if (GameImage.SLIDER_BALL.hasSkinImages() ||
|
||||
(!GameImage.SLIDER_BALL.hasSkinImage() && GameImage.SLIDER_BALL.getImages() != null))
|
||||
|
@ -118,11 +127,11 @@ public class Slider implements HitObject {
|
|||
else
|
||||
sliderBallImages = new Image[]{ GameImage.SLIDER_BALL.getImage() };
|
||||
for (int i = 0; i < sliderBallImages.length; i++)
|
||||
sliderBallImages[i] = sliderBallImages[i].getScaledCopy(diameter * 118 / 128, diameter * 118 / 128);
|
||||
sliderBallImages[i] = sliderBallImages[i].getScaledCopy(diameterInt * 118 / 128, diameterInt * 118 / 128);
|
||||
|
||||
GameImage.SLIDER_FOLLOWCIRCLE.setImage(GameImage.SLIDER_FOLLOWCIRCLE.getImage().getScaledCopy(diameter * 259 / 128, diameter * 259 / 128));
|
||||
GameImage.REVERSEARROW.setImage(GameImage.REVERSEARROW.getImage().getScaledCopy(diameter, diameter));
|
||||
GameImage.SLIDER_TICK.setImage(GameImage.SLIDER_TICK.getImage().getScaledCopy(diameter / 4, diameter / 4));
|
||||
GameImage.SLIDER_FOLLOWCIRCLE.setImage(GameImage.SLIDER_FOLLOWCIRCLE.getImage().getScaledCopy(diameterInt * 259 / 128, diameterInt * 259 / 128));
|
||||
GameImage.REVERSEARROW.setImage(GameImage.REVERSEARROW.getImage().getScaledCopy(diameterInt, diameterInt));
|
||||
GameImage.SLIDER_TICK.setImage(GameImage.SLIDER_TICK.getImage().getScaledCopy(diameterInt / 4, diameterInt / 4));
|
||||
|
||||
sliderMultiplier = osu.sliderMultiplier;
|
||||
sliderTickRate = osu.sliderTickRate;
|
||||
|
@ -266,6 +275,55 @@ public class Slider implements HitObject {
|
|||
* @return the hit result (GameData.HIT_* constants)
|
||||
*/
|
||||
private int hitResult() {
|
||||
/*
|
||||
time scoredelta score-hit-initial-tick= unaccounted
|
||||
(1/4 - 1) 396 - 300 - 30 46
|
||||
(1+1/4 - 2) 442 - 300 - 30 - 10
|
||||
(2+1/4 - 3) 488 - 300 - 30 - 2*10 896 (408)5x
|
||||
(3+1/4 - 4) 534 - 300 - 30 - 3*10
|
||||
(4+1/4 - 5) 580 - 300 - 30 - 4*10
|
||||
(5+1/4 - 6) 626 - 300 - 30 - 5*10
|
||||
(6+1/4 - 7) 672 - 300 - 30 - 6*10
|
||||
|
||||
difficultyMulti = 3 (+36 per combo)
|
||||
|
||||
score =
|
||||
(t)ticks(10) * nticks +
|
||||
(h)hitValue
|
||||
(c)combo (hitValue/25 * difficultyMultiplier*(combo-1))
|
||||
(i)initialHit (30) +
|
||||
(f)finalHit(30) +
|
||||
|
||||
s t h c i f
|
||||
626 - 10*5 - 300 - 276(-216 - 30 - 30) (all)(7x)
|
||||
240 - 10*5 - 100 - 90 (-60 <- 30>) (no final or initial)(6x)
|
||||
|
||||
218 - 10*4 - 100 - 78 (-36 - 30) (4 tick no initial)(5x)
|
||||
196 - 10*3 - 100 - 66 (-24 - 30 ) (3 tick no initial)(4x)
|
||||
112 - 10*2 - 50 - 42 (-12 - 30 ) (2 tick no initial)(3x)
|
||||
96 - 10 - 50 - 36 ( -6 - 30 ) (1 tick no initial)(2x)
|
||||
|
||||
206 - 10*4 - 100 - 66 (-36 - 30 ) (4 tick no initial)(4x)
|
||||
184 - 10*3 - 100 - 54 (-24 - 30 ) (3 tick no initial)(3x)
|
||||
90 - 10 - 50 - 30 ( - 30 ) (1 tick no initial)(0x)
|
||||
|
||||
194 - 10*4 - 100 - 54 (-24 - 30 ) (4 tick no initial)(3x)
|
||||
|
||||
170 - 10*4 - 100 - 30 ( - 30 ) (4 tick no final)(0x)
|
||||
160 - 10*3 - 100 - 30 ( - 30 ) (3 tick no final)(0x)
|
||||
100 - 10*2 - 50 - 30 ( - 30 ) (2 tick no final)(0x)
|
||||
|
||||
198 - 10*5 - 100 - 48 (-36 ) (no initial and final)(5x)
|
||||
110 - 50 - ( - 30 - 30 ) (final and initial no tick)(0x)
|
||||
80 - 50 - ( <- 30> ) (only final or initial)(0x)
|
||||
|
||||
140 - 10*4 - 100 - 0 (4 ticks only)(0x)
|
||||
80 - 10*3 - 50 - 0 (3 tick only)(0x)
|
||||
70 - 10*2 - 50 - 0 (2 tick only)(0x)
|
||||
60 - 10 - 50 - 0 (1 tick only)(0x)
|
||||
|
||||
|
||||
*/
|
||||
float tickRatio = (float) ticksHit / tickIntervals;
|
||||
|
||||
int result;
|
||||
|
@ -277,7 +335,7 @@ public class Slider implements HitObject {
|
|||
result = GameData.HIT_50;
|
||||
else
|
||||
result = GameData.HIT_MISS;
|
||||
|
||||
|
||||
if (currentRepeats % 2 == 0) { // last circle
|
||||
float[] lastPos = curve.pointAt(1);
|
||||
data.hitResult(hitObject.getTime() + (int) sliderTimeTotal, result,
|
||||
|
@ -296,8 +354,7 @@ public class Slider implements HitObject {
|
|||
return false;
|
||||
|
||||
double distance = Math.hypot(this.x - x, this.y - y);
|
||||
int circleRadius = GameImage.HITCIRCLE.getImage().getWidth() / 2;
|
||||
if (distance < circleRadius) {
|
||||
if (distance < diameter / 2) {
|
||||
int timeDiff = Math.abs(trackPosition - hitObject.getTime());
|
||||
int[] hitResultOffset = game.getHitResultOffsets();
|
||||
|
||||
|
@ -353,26 +410,29 @@ public class Slider implements HitObject {
|
|||
}
|
||||
|
||||
// end of slider
|
||||
if (overlap || trackPosition > hitObject.getTime() + sliderTimeTotal) {
|
||||
if (trackPosition > hitObject.getTime() + sliderTimeTotal) {
|
||||
tickIntervals++;
|
||||
|
||||
// check if cursor pressed and within end circle
|
||||
if (keyPressed || GameMod.RELAX.isActive()) {
|
||||
float[] c = curve.pointAt(getT(trackPosition, false));
|
||||
double distance = Math.hypot(c[0] - mouseX, c[1] - mouseY);
|
||||
int followCircleRadius = GameImage.SLIDER_FOLLOWCIRCLE.getImage().getWidth() / 2;
|
||||
if (distance < followCircleRadius)
|
||||
if (distance < followRadius) //TODO IDK Magic numbers
|
||||
sliderClickedFinal = true;
|
||||
}
|
||||
|
||||
// final circle hit
|
||||
if (sliderClickedFinal)
|
||||
if (sliderClickedFinal){
|
||||
ticksHit++;
|
||||
data.sliderFinalResult(hitObject.getTime(), GameData.HIT_SLIDER30, this.x, this.y, hitObject, currentRepeats);
|
||||
}
|
||||
|
||||
// "auto" mod: always send a perfect hit result
|
||||
if (isAutoMod)
|
||||
ticksHit = tickIntervals;
|
||||
|
||||
//TODO missing the final shouldn't increment the combo
|
||||
|
||||
// calculate and send slider result
|
||||
hitResult();
|
||||
return true;
|
||||
|
@ -405,8 +465,7 @@ public class Slider implements HitObject {
|
|||
// holding slider...
|
||||
float[] c = curve.pointAt(getT(trackPosition, false));
|
||||
double distance = Math.hypot(c[0] - mouseX, c[1] - mouseY);
|
||||
int followCircleRadius = GameImage.SLIDER_FOLLOWCIRCLE.getImage().getWidth() / 2;
|
||||
if (((keyPressed || GameMod.RELAX.isActive()) && distance < followCircleRadius) || isAutoMod) {
|
||||
if (((keyPressed || GameMod.RELAX.isActive()) && distance < followRadius) || isAutoMod) {
|
||||
// mouse pressed and within follow circle
|
||||
followCircleActive = true;
|
||||
data.changeHealth(delta * GameData.HP_DRAIN_MULTIPLIER);
|
||||
|
@ -487,4 +546,16 @@ public class Slider implements HitObject {
|
|||
return (floor % 2 == 0) ? t - floor : floor + 1 - t;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
sliderClickedInitial = false;
|
||||
sliderClickedFinal = false;
|
||||
followCircleActive = false;
|
||||
currentRepeats = 0;
|
||||
tickIndex = 0;
|
||||
ticksHit = 0;
|
||||
tickIntervals = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,12 +40,13 @@ public class Spinner implements HitObject {
|
|||
private static int width, height;
|
||||
|
||||
/** The number of rotation velocities to store. */
|
||||
// note: currently takes about 200ms to spin up (4 * 50)
|
||||
private static final int MAX_ROTATION_VELOCITIES = 50;
|
||||
// note: currently takes about 200ms to spin up (1000/60 * 12)
|
||||
private static final int MAX_ROTATION_VELOCITIES = 12;
|
||||
|
||||
/** The amount of time, in milliseconds, before another velocity is stored. */
|
||||
private static final int DELTA_UPDATE_TIME = 16;
|
||||
private static final float DELTA_UPDATE_TIME = 1000 / 60f;
|
||||
|
||||
|
||||
/** The amount of time, in milliseconds, to fade in the spinner. */
|
||||
private static final int FADE_IN_TIME = 500;
|
||||
|
||||
|
@ -59,6 +60,8 @@ public class Spinner implements HitObject {
|
|||
TWO_PI = (float) (Math.PI * 2),
|
||||
HALF_PI = (float) (Math.PI / 2);
|
||||
|
||||
private static final float MAX_ANG_DIFF = DELTA_UPDATE_TIME * 477 / 60 / 1000 * TWO_PI; // ~95.3
|
||||
|
||||
/** The associated OsuHitObject. */
|
||||
private OsuHitObject hitObject;
|
||||
|
||||
|
@ -78,19 +81,23 @@ public class Spinner implements HitObject {
|
|||
private float rotationsNeeded;
|
||||
|
||||
/** The remaining amount of time that was not used. */
|
||||
private int deltaOverflow;
|
||||
private float deltaOverflow;
|
||||
|
||||
/** The sum of all the velocities in storedVelocities. */
|
||||
private float sumVelocity = 0f;
|
||||
private float sumDeltaAngle = 0f;
|
||||
|
||||
/** Array holding the most recent rotation velocities. */
|
||||
private float[] storedVelocities = new float[MAX_ROTATION_VELOCITIES];
|
||||
private float[] storedDeltaAngle = new float[MAX_ROTATION_VELOCITIES];
|
||||
|
||||
/** True if the mouse cursor is pressed. */
|
||||
private boolean isSpinning;
|
||||
|
||||
/** Current index of the stored velocities in rotations/second. */
|
||||
private int velocityIndex = 0;
|
||||
private int deltaAngleIndex = 0;
|
||||
|
||||
private float deltaAngleOverflow = 0;
|
||||
|
||||
private int drawnRPM = 0;
|
||||
|
||||
/**
|
||||
* Initializes the Spinner data type with images and dimensions.
|
||||
|
@ -112,8 +119,9 @@ public class Spinner implements HitObject {
|
|||
this.data = data;
|
||||
|
||||
// calculate rotations needed
|
||||
float spinsPerMinute = 100 + (data.getDifficulty() * 15);
|
||||
float spinsPerMinute = 94 + (data.getDifficulty() * 15);
|
||||
rotationsNeeded = spinsPerMinute * (hitObject.getEndTime() - hitObject.getTime()) / 60000f;
|
||||
System.out.println("rotationsNeeded "+rotationsNeeded);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -135,12 +143,11 @@ public class Spinner implements HitObject {
|
|||
Utils.COLOR_BLACK_ALPHA.a = oldAlpha;
|
||||
|
||||
// rpm
|
||||
int rpm = Math.abs(Math.round(sumVelocity / storedVelocities.length * 60));
|
||||
Image rpmImg = GameImage.SPINNER_RPM.getImage();
|
||||
rpmImg.setAlpha(alpha);
|
||||
rpmImg.drawCentered(width / 2f, height - rpmImg.getHeight() / 2f);
|
||||
if (timeDiff < 0)
|
||||
data.drawSymbolString(Integer.toString(rpm), (width + rpmImg.getWidth() * 0.95f) / 2f,
|
||||
data.drawSymbolString(Integer.toString(drawnRPM), (width + rpmImg.getWidth() * 0.95f) / 2f,
|
||||
height - data.getScoreSymbolImage('0').getHeight() * 1.025f, 1f, 1f, true);
|
||||
|
||||
// spinner meter (subimage)
|
||||
|
@ -196,7 +203,11 @@ public class Spinner implements HitObject {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean mousePressed(int x, int y, int trackPosition) { return false; } // not used
|
||||
public boolean mousePressed(int x, int y, int trackPosition) {
|
||||
lastAngle = (float) Math.atan2(x - (height / 2), y - (width / 2));
|
||||
System.out.println("lastAngle:"+lastAngle);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(boolean overlap, int delta, int mouseX, int mouseY, boolean keyPressed, int trackPosition) {
|
||||
|
@ -211,22 +222,25 @@ public class Spinner implements HitObject {
|
|||
if (isSpinning && !(keyPressed || GameMod.RELAX.isActive()))
|
||||
isSpinning = false;
|
||||
|
||||
System.out.println("Spinner update "+mouseX+" "+mouseY+" "+deltaOverflow);
|
||||
// spin automatically
|
||||
// http://osu.ppy.sh/wiki/FAQ#Spinners
|
||||
|
||||
|
||||
deltaOverflow += delta;
|
||||
while (deltaOverflow >= DELTA_UPDATE_TIME) {
|
||||
// spin automatically
|
||||
// http://osu.ppy.sh/wiki/FAQ#Spinners
|
||||
float angle;
|
||||
|
||||
float angle = 0;
|
||||
if (deltaOverflow >= DELTA_UPDATE_TIME){
|
||||
if (GameMod.AUTO.isActive()) {
|
||||
lastAngle = 0;
|
||||
angle = delta * AUTO_MULTIPLIER;
|
||||
angle = deltaOverflow * AUTO_MULTIPLIER;
|
||||
isSpinning = true;
|
||||
} else if (GameMod.SPUN_OUT.isActive() || GameMod.AUTOPILOT.isActive()) {
|
||||
lastAngle = 0;
|
||||
angle = delta * SPUN_OUT_MULTIPLIER;
|
||||
angle = deltaOverflow * SPUN_OUT_MULTIPLIER;
|
||||
isSpinning = true;
|
||||
} else {
|
||||
angle = (float) Math.atan2(mouseY - (height / 2), mouseX - (width / 2));
|
||||
|
||||
// set initial angle to current mouse position to skip first click
|
||||
if (!isSpinning && (keyPressed || GameMod.RELAX.isActive())) {
|
||||
lastAngle = angle;
|
||||
|
@ -234,33 +248,45 @@ public class Spinner implements HitObject {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// make angleDiff the smallest angle change possible
|
||||
// (i.e. 1/4 rotation instead of 3/4 rotation)
|
||||
float angleDiff = angle - lastAngle;
|
||||
lastAngle = angle;
|
||||
|
||||
if (angleDiff < -Math.PI)
|
||||
angleDiff += TWO_PI;
|
||||
else if (angleDiff > Math.PI)
|
||||
angleDiff -= TWO_PI;
|
||||
|
||||
System.out.println("AngleDiff "+angleDiff);
|
||||
// spin caused by the cursor
|
||||
float cursorVelocity = 0;
|
||||
if (isSpinning)
|
||||
cursorVelocity = Utils.clamp(angleDiff / TWO_PI / delta * 1000, -8f, 8f);
|
||||
|
||||
sumVelocity -= storedVelocities[velocityIndex];
|
||||
sumVelocity += cursorVelocity;
|
||||
storedVelocities[velocityIndex++] = cursorVelocity;
|
||||
velocityIndex %= storedVelocities.length;
|
||||
deltaOverflow -= DELTA_UPDATE_TIME;
|
||||
deltaAngleOverflow += angleDiff;
|
||||
}
|
||||
|
||||
while (deltaOverflow >= DELTA_UPDATE_TIME) {
|
||||
System.out.println("Spinner update2 "+mouseX+" "+mouseY+" "+deltaAngleOverflow+" "+deltaOverflow);
|
||||
|
||||
float rotationAngle = sumVelocity / storedVelocities.length * TWO_PI * delta / 1000;
|
||||
// spin caused by the cursor
|
||||
float deltaAngle = 0;
|
||||
if (isSpinning){
|
||||
deltaAngle = deltaAngleOverflow * DELTA_UPDATE_TIME / deltaOverflow;
|
||||
deltaAngleOverflow -= deltaAngle;
|
||||
deltaAngle = Utils.clamp(deltaAngle, -MAX_ANG_DIFF, MAX_ANG_DIFF);
|
||||
}
|
||||
sumDeltaAngle -= storedDeltaAngle[deltaAngleIndex];
|
||||
sumDeltaAngle += deltaAngle;
|
||||
storedDeltaAngle[deltaAngleIndex++] = deltaAngle;
|
||||
deltaAngleIndex %= storedDeltaAngle.length;
|
||||
deltaOverflow -= DELTA_UPDATE_TIME;
|
||||
|
||||
float rotationAngle = sumDeltaAngle / MAX_ROTATION_VELOCITIES;
|
||||
rotationAngle = Utils.clamp(rotationAngle, -MAX_ANG_DIFF, MAX_ANG_DIFF);//*0.9650f;
|
||||
float rotationPerSec = rotationAngle * (1000/DELTA_UPDATE_TIME) / TWO_PI;
|
||||
|
||||
drawnRPM = (int)(Math.abs(rotationPerSec * 60));
|
||||
System.out.println("Ang DIFF:"+deltaAngle+" "+rotations+" "+angle+" "+lastAngle+" "+rotationAngle+" "+sumDeltaAngle+" "+MAX_ANG_DIFF);
|
||||
rotate(rotationAngle);
|
||||
if (Math.abs(rotationAngle) > 0.00001f)
|
||||
data.changeHealth(delta * GameData.HP_DRAIN_MULTIPLIER);
|
||||
|
||||
lastAngle = angle;
|
||||
data.changeHealth(DELTA_UPDATE_TIME * GameData.HP_DRAIN_MULTIPLIER);
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -304,15 +330,37 @@ public class Spinner implements HitObject {
|
|||
|
||||
// added one whole rotation...
|
||||
if (Math.floor(newRotations) > rotations) {
|
||||
//TODO seems to give 1100 points per spin but also an extra 100 for some spinners
|
||||
if (newRotations > rotationsNeeded) { // extra rotations
|
||||
data.changeScore(1000);
|
||||
|
||||
SoundController.playSound(SoundEffect.SPINNERBONUS);
|
||||
} else {
|
||||
}
|
||||
data.changeScore(100);
|
||||
SoundController.playSound(SoundEffect.SPINNERSPIN);
|
||||
|
||||
}
|
||||
//*
|
||||
if (Math.floor(newRotations + 0.5f) > rotations + 0.5f) {
|
||||
if (newRotations + 0.5f > rotationsNeeded) { // extra rotations
|
||||
data.changeScore(100);
|
||||
SoundController.playSound(SoundEffect.SPINNERSPIN);
|
||||
}
|
||||
}
|
||||
//*/
|
||||
|
||||
rotations = newRotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
deltaAngleIndex = 0;
|
||||
sumDeltaAngle = 0;
|
||||
for(int i=0; i<storedDeltaAngle.length; i++){
|
||||
storedDeltaAngle[i] = 0;
|
||||
}
|
||||
drawRotation = 0;
|
||||
rotations = 0;
|
||||
deltaOverflow = 0;
|
||||
isSpinning = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,6 +138,11 @@ public class Replay {
|
|||
loaded = true;
|
||||
}
|
||||
|
||||
public void loadHeader() throws IOException {
|
||||
OsuReader reader = new OsuReader(file);
|
||||
loadHeader(reader);
|
||||
reader.close();
|
||||
}
|
||||
/**
|
||||
* Returns a ScoreData object encapsulating all game data.
|
||||
* If score data already exists, the existing object will be returned
|
||||
|
@ -181,7 +186,7 @@ public class Replay {
|
|||
private void loadHeader(OsuReader reader) throws IOException {
|
||||
this.mode = reader.readByte();
|
||||
this.version = reader.readInt();
|
||||
System.out.println("Header:"+file.getName()+" "+mode+" "+version);
|
||||
//System.out.println("Header:"+file.getName()+" "+mode+" "+version);
|
||||
this.beatmapHash = reader.readString();
|
||||
this.playerName = reader.readString();
|
||||
this.replayHash = reader.readString();
|
||||
|
@ -203,6 +208,7 @@ public class Replay {
|
|||
* @throws IOException
|
||||
*/
|
||||
private void loadData(OsuReader reader) throws IOException {
|
||||
//System.out.println("Load Data");
|
||||
// life data
|
||||
String[] lifeData = reader.readString().split(",");
|
||||
List<LifeFrame> lifeFrameList = new ArrayList<LifeFrame>(lifeData.length);
|
||||
|
@ -369,8 +375,8 @@ public class Replay {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
final int LINE_SPLIT = 5;
|
||||
final int MAX_LINES = LINE_SPLIT * 10;
|
||||
final int LINE_SPLIT = 1;
|
||||
final int MAX_LINES = LINE_SPLIT * 99999999;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("File: "); sb.append(file.getName()); sb.append('\n');
|
||||
|
|
|
@ -12,16 +12,22 @@ import java.io.IOException;
|
|||
|
||||
public class ReplayImporter {
|
||||
public static void importAllReplaysFromDir(File dir) {
|
||||
System.out.println(OsuGroupList.get().beatmapHashesToFile);
|
||||
for (File replayToImport : dir.listFiles()) {
|
||||
try {
|
||||
Replay r = new Replay(replayToImport);
|
||||
r.load();
|
||||
r.loadHeader();
|
||||
OsuFile oFile = OsuGroupList.get().getFileFromBeatmapHash(r.beatmapHash);
|
||||
if(oFile != null){
|
||||
File replaydir = Options.getReplayDir();
|
||||
if (!replaydir.isDirectory()) {
|
||||
if (!replaydir.mkdir()) {
|
||||
ErrorHandler.error("Failed to create replay directory.", null, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//ErrorHandler.error("Importing"+replayToImport+" forBeatmap:"+oFile, null, false);
|
||||
ScoreData data = r.getScoreData(oFile);
|
||||
File moveToFile = new File(Options.getReplayDir(),replayToImport.getName());
|
||||
File moveToFile = new File(replaydir, replayToImport.getName());
|
||||
System.out.println("Moving "+replayToImport+" to "+moveToFile);
|
||||
if(
|
||||
!replayToImport.renameTo(moveToFile)
|
||||
|
@ -35,7 +41,6 @@ public class ReplayImporter {
|
|||
//ErrorHandler.error("Could not find beatmap for replay "+replayToImport, null, false);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
//e.printStackTrace();
|
||||
System.out.println(e);
|
||||
}
|
||||
|
|
|
@ -217,6 +217,10 @@ public class Game extends BasicGameState {
|
|||
private Input input;
|
||||
private int state;
|
||||
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
public Game(int state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
@ -228,8 +232,8 @@ public class Game extends BasicGameState {
|
|||
this.game = game;
|
||||
input = container.getInput();
|
||||
|
||||
int width = container.getWidth();
|
||||
int height = container.getHeight();
|
||||
width = container.getWidth();
|
||||
height = container.getHeight();
|
||||
|
||||
// create offscreen graphics
|
||||
offscreen = new Image(width, height);
|
||||
|
@ -597,6 +601,27 @@ public class Game extends BasicGameState {
|
|||
// out of frames, use previous data
|
||||
if (replayIndex >= replay.frames.length)
|
||||
updateGame(replayX, replayY, delta, MusicController.getPosition(), lastKeysPressed);
|
||||
|
||||
//TODO probably should to disable sounds then reseek to the new position
|
||||
if(replayIndex-1 >= 1 && replayIndex < replay.frames.length && trackPosition < replay.frames[replayIndex-1].getTime()){
|
||||
replayIndex = 0;
|
||||
while(objectIndex>=0){
|
||||
hitObjects[objectIndex].reset();
|
||||
objectIndex--;
|
||||
|
||||
}
|
||||
// load the first timingPoint
|
||||
if (!osu.timingPoints.isEmpty()) {
|
||||
OsuTimingPoint timingPoint = osu.timingPoints.get(0);
|
||||
if (!timingPoint.isInherited()) {
|
||||
beatLengthBase = beatLength = timingPoint.getBeatLength();
|
||||
HitSound.setDefaultSampleSet(timingPoint.getSampleType());
|
||||
SoundController.setSampleVolume(timingPoint.getSampleVolume());
|
||||
timingPointIndex++;
|
||||
}
|
||||
}
|
||||
resetGameData();
|
||||
}
|
||||
|
||||
// update and run replay frames
|
||||
while (replayIndex < replay.frames.length && trackPosition >= replay.frames[replayIndex].getTime()) {
|
||||
|
@ -743,7 +768,7 @@ public class Game extends BasicGameState {
|
|||
while (objectIndex < hitObjects.length && trackPosition > osu.objects[objectIndex].getTime()) {
|
||||
// check if we've already passed the next object's start time
|
||||
boolean overlap = (objectIndex + 1 < hitObjects.length &&
|
||||
trackPosition > osu.objects[objectIndex + 1].getTime() - hitResultOffset[GameData.HIT_300]);
|
||||
trackPosition > osu.objects[objectIndex + 1].getTime() - hitResultOffset[GameData.HIT_50]);
|
||||
|
||||
// update hit object and check completion status
|
||||
if (hitObjects[objectIndex].update(overlap, delta, mouseX, mouseY, keyPressed, trackPosition))
|
||||
|
@ -879,6 +904,11 @@ public class Game extends BasicGameState {
|
|||
// only allow skip button
|
||||
if (button != Input.MOUSE_MIDDLE_BUTTON && skipButton.contains(x, y))
|
||||
skipIntro();
|
||||
if(y < 50){
|
||||
float pos = (float)x / width * osu.endTime;
|
||||
System.out.println("Seek to"+pos);
|
||||
MusicController.setPosition((int)pos);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1028,13 +1058,21 @@ public class Game extends BasicGameState {
|
|||
MusicController.setPosition(0);
|
||||
MusicController.pause();
|
||||
|
||||
if (!osu.timingPoints.isEmpty()) {
|
||||
OsuTimingPoint timingPoint = osu.timingPoints.get(0);
|
||||
if (!timingPoint.isInherited()) {
|
||||
beatLengthBase = beatLength = timingPoint.getBeatLength();
|
||||
}
|
||||
}
|
||||
hitObjects = new HitObject[osu.objects.length];
|
||||
|
||||
// initialize object maps
|
||||
for (int i = 0; i < osu.objects.length; i++) {
|
||||
OsuHitObject hitObject = osu.objects[i];
|
||||
|
||||
// is this the last note in the combo?
|
||||
boolean comboEnd = false;
|
||||
if (i + 1 < osu.objects.length && osu.objects[i + 1].isNewCombo())
|
||||
if (i + 1 >= osu.objects.length || osu.objects[i + 1].isNewCombo())
|
||||
comboEnd = true;
|
||||
|
||||
Color color = osu.combo[hitObject.getComboIndex()];
|
||||
|
@ -1086,6 +1124,7 @@ public class Game extends BasicGameState {
|
|||
|
||||
// load replay frames
|
||||
if (isReplay) {
|
||||
//System.out.println(replay.toString());
|
||||
// load mods
|
||||
previousMods = GameMod.getModState();
|
||||
GameMod.loadModState(replay.mods);
|
||||
|
@ -1238,7 +1277,6 @@ public class Game extends BasicGameState {
|
|||
* Resets all game data and structures.
|
||||
*/
|
||||
public void resetGameData() {
|
||||
hitObjects = new HitObject[osu.objects.length];
|
||||
data.clear();
|
||||
objectIndex = 0;
|
||||
breakIndex = 0;
|
||||
|
@ -1376,15 +1414,25 @@ public class Game extends BasicGameState {
|
|||
|
||||
// overallDifficulty (hit result time offsets)
|
||||
hitResultOffset = new int[GameData.HIT_MAX];
|
||||
//*
|
||||
float mult = 0.608f;
|
||||
hitResultOffset[GameData.HIT_300] = (int) ((128 - (overallDifficulty * 9.6))*mult);
|
||||
hitResultOffset[GameData.HIT_100] = (int) ((224 - (overallDifficulty * 12.8))*mult);
|
||||
hitResultOffset[GameData.HIT_50] = (int) ((320 - (overallDifficulty * 16))*mult);
|
||||
hitResultOffset[GameData.HIT_MISS] = (int) ((1000 - (overallDifficulty * 10))*mult);
|
||||
/*/
|
||||
hitResultOffset[GameData.HIT_300] = (int) (78 - (overallDifficulty * 6));
|
||||
hitResultOffset[GameData.HIT_100] = (int) (138 - (overallDifficulty * 8));
|
||||
hitResultOffset[GameData.HIT_50] = (int) (198 - (overallDifficulty * 10));
|
||||
hitResultOffset[GameData.HIT_MISS] = (int) (500 - (overallDifficulty * 10));
|
||||
|
||||
//*/
|
||||
// HPDrainRate (health change), overallDifficulty (scoring)
|
||||
data.setDrainRate(HPDrainRate);
|
||||
data.setDifficulty(overallDifficulty);
|
||||
data.setApproachRate(approachRate);
|
||||
data.setCircleSize(circleSize);
|
||||
data.setHitResultOffset(hitResultOffset);
|
||||
data.calculateDifficultyMultiplier();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1491,6 +1539,7 @@ public class Game extends BasicGameState {
|
|||
* @param keys the keys that are pressed
|
||||
*/
|
||||
private void sendGameKeyPress(int keys, int x, int y, int trackPosition) {
|
||||
System.out.println("Game Key Pressed"+keys+" "+x+" "+y+" "+objectIndex);
|
||||
if (objectIndex >= hitObjects.length) // nothing to do here
|
||||
return;
|
||||
|
||||
|
|
|
@ -18,11 +18,9 @@
|
|||
|
||||
package itdelatrisu.opsu.states;
|
||||
|
||||
import itdelatrisu.opsu.ErrorHandler;
|
||||
import itdelatrisu.opsu.GameImage;
|
||||
import itdelatrisu.opsu.Opsu;
|
||||
import itdelatrisu.opsu.Options;
|
||||
import itdelatrisu.opsu.OsuFile;
|
||||
import itdelatrisu.opsu.OsuGroupList;
|
||||
import itdelatrisu.opsu.OsuParser;
|
||||
import itdelatrisu.opsu.OszUnpacker;
|
||||
|
@ -30,11 +28,9 @@ import itdelatrisu.opsu.UI;
|
|||
import itdelatrisu.opsu.Utils;
|
||||
import itdelatrisu.opsu.audio.MusicController;
|
||||
import itdelatrisu.opsu.audio.SoundController;
|
||||
import itdelatrisu.opsu.replay.Replay;
|
||||
import itdelatrisu.opsu.replay.ReplayImporter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.newdawn.slick.Color;
|
||||
import org.newdawn.slick.GameContainer;
|
||||
|
@ -44,7 +40,6 @@ import org.newdawn.slick.Input;
|
|||
import org.newdawn.slick.SlickException;
|
||||
import org.newdawn.slick.state.BasicGameState;
|
||||
import org.newdawn.slick.state.StateBasedGame;
|
||||
import org.newdawn.slick.util.Log;
|
||||
|
||||
/**
|
||||
* "Splash Screen" state.
|
||||
|
@ -111,6 +106,7 @@ public class Splash extends BasicGameState {
|
|||
// parse song directory
|
||||
OsuParser.parseAllFiles(beatmapDir);
|
||||
|
||||
// import replays
|
||||
ReplayImporter.importAllReplaysFromDir(Options.getReplayImportDir());
|
||||
|
||||
// load sounds
|
||||
|
|
Loading…
Reference in New Issue
Block a user