Merge branch 'master' of https://github.com/itdelatrisu/opsu into 'upstream'
# Conflicts: # README.md # src/itdelatrisu/opsu/Opsu.java # src/itdelatrisu/opsu/Utils.java # src/itdelatrisu/opsu/render/CurveRenderState.java # src/itdelatrisu/opsu/states/Game.java
This commit is contained in:
@@ -47,8 +47,6 @@ import itdelatrisu.opsu.ui.UI;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.sound.sampled.LineEvent;
|
||||
import javax.sound.sampled.LineListener;
|
||||
@@ -663,15 +661,18 @@ public class DownloadsMenu extends BasicGameState {
|
||||
SoundController.stopTrack();
|
||||
} else {
|
||||
// play preview
|
||||
try {
|
||||
final URL url = new URL(serverMenu.getSelectedItem().getPreviewURL(node.getID()));
|
||||
MusicController.pause();
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
previewID = -1;
|
||||
SoundController.playTrack(url, true, new LineListener() {
|
||||
final String url = serverMenu.getSelectedItem().getPreviewURL(node.getID());
|
||||
MusicController.pause();
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
previewID = -1;
|
||||
boolean playing = SoundController.playTrack(
|
||||
url,
|
||||
Integer.toString(node.getID()),
|
||||
true,
|
||||
new LineListener() {
|
||||
@Override
|
||||
public void update(LineEvent event) {
|
||||
if (event.getType() == LineEvent.Type.STOP) {
|
||||
@@ -681,18 +682,16 @@ public class DownloadsMenu extends BasicGameState {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
if (playing)
|
||||
previewID = node.getID();
|
||||
} catch (SlickException e) {
|
||||
UI.sendBarNotification("Failed to load track preview. See log for details.");
|
||||
Log.error(e);
|
||||
}
|
||||
} catch (SlickException e) {
|
||||
UI.sendBarNotification("Failed to load track preview. See log for details.");
|
||||
Log.error(e);
|
||||
}
|
||||
}.start();
|
||||
} catch (MalformedURLException e) {
|
||||
UI.sendBarNotification("Could not load track preview (bad URL).");
|
||||
Log.error(e);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,6 +100,12 @@ public class Game extends BasicGameState {
|
||||
/** Maximum rotation, in degrees, over fade out upon death. */
|
||||
private static final float MAX_ROTATION = 90f;
|
||||
|
||||
/** The duration of the score changing animation. */
|
||||
private static final float SCOREBOARD_ANIMATION_TIME = 500f;
|
||||
|
||||
/** The time the scoreboard takes to fade in. */
|
||||
private static final float SCOREBOARD_FADE_IN_TIME = 300f;
|
||||
|
||||
/** Minimum time before start of song, in milliseconds, to process skip-related actions. */
|
||||
private static final int SKIP_OFFSET = 2000;
|
||||
|
||||
@@ -265,6 +271,21 @@ public class Game extends BasicGameState {
|
||||
private float epiImgY;
|
||||
private int epiImgTime;
|
||||
|
||||
/** The previous scores. */
|
||||
private ScoreData[] previousScores;
|
||||
|
||||
/** The current rank in the scores. */
|
||||
private int currentRank;
|
||||
|
||||
/** The time the rank was last updated. */
|
||||
private int lastRankUpdateTime;
|
||||
|
||||
/** Whether the scoreboard is visible. */
|
||||
private boolean scoreboardVisible;
|
||||
|
||||
/** The current alpha of the scoreboard. */
|
||||
private float currentScoreboardAlpha;
|
||||
|
||||
/** Music position bar background colors. */
|
||||
private static final Color
|
||||
MUSICBAR_NORMAL = new Color(12, 9, 10, 0.25f),
|
||||
@@ -603,6 +624,46 @@ public class Game extends BasicGameState {
|
||||
drawHitObjects(g, trackPosition);
|
||||
}
|
||||
|
||||
// in-game scoreboard
|
||||
if (previousScores != null && trackPosition >= firstObjectTime && !GameMod.RELAX.isActive() && !GameMod.AUTOPILOT.isActive()) {
|
||||
ScoreData currentScore = data.getCurrentScoreData(beatmap, true);
|
||||
while (currentRank > 0 && previousScores[currentRank - 1].score < currentScore.score) {
|
||||
currentRank--;
|
||||
lastRankUpdateTime = trackPosition;
|
||||
}
|
||||
|
||||
float animation = AnimationEquation.IN_OUT_QUAD.calc(
|
||||
Utils.clamp((trackPosition - lastRankUpdateTime) / SCOREBOARD_ANIMATION_TIME, 0f, 1f)
|
||||
);
|
||||
int scoreboardPosition = 2 * container.getHeight() / 3;
|
||||
|
||||
if (currentRank < 4) {
|
||||
// draw the (new) top 5 ranks
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int index = i + (i >= currentRank ? 1 : 0);
|
||||
if (i < previousScores.length) {
|
||||
float position = index + (i == currentRank ? animation - 3f : -2f);
|
||||
previousScores[i].drawSmall(g, scoreboardPosition, index + 1, position, data, currentScoreboardAlpha, false);
|
||||
}
|
||||
}
|
||||
currentScore.drawSmall(g, scoreboardPosition, currentRank + 1, currentRank - 1f - animation, data, currentScoreboardAlpha, true);
|
||||
} else {
|
||||
// draw the top 2 and next 2 ranks
|
||||
previousScores[0].drawSmall(g, scoreboardPosition, 1, -2f, data, currentScoreboardAlpha, false);
|
||||
previousScores[1].drawSmall(g, scoreboardPosition, 2, -1f, data, currentScoreboardAlpha, false);
|
||||
previousScores[currentRank - 2].drawSmall(
|
||||
g, scoreboardPosition, currentRank - 1, animation - 1f, data, currentScoreboardAlpha * animation, false
|
||||
);
|
||||
previousScores[currentRank - 1].drawSmall(g, scoreboardPosition, currentRank, animation, data, currentScoreboardAlpha, false);
|
||||
currentScore.drawSmall(g, scoreboardPosition, currentRank + 1, 2f, data, currentScoreboardAlpha, true);
|
||||
if (animation < 1.0f && currentRank < previousScores.length) {
|
||||
previousScores[currentRank].drawSmall(
|
||||
g, scoreboardPosition, currentRank + 2, 1f + 5 * animation, data, currentScoreboardAlpha * (1f - animation), false
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Dancer.hideui && GameMod.AUTO.isActive())
|
||||
GameImage.UNRANKED.getImage().drawCentered(width / 2, height * 0.077f);
|
||||
|
||||
@@ -677,6 +738,7 @@ public class Game extends BasicGameState {
|
||||
if (isReplay || GameMod.AUTO.isActive())
|
||||
playbackSpeed.getButton().hoverUpdate(delta, mouseX, mouseY);
|
||||
int trackPosition = MusicController.getPosition();
|
||||
int firstObjectTime = beatmap.objects[0].getTime();
|
||||
|
||||
// returning from pause screen: must click previous mouse position
|
||||
if (pauseTime > -1) {
|
||||
@@ -782,6 +844,20 @@ public class Game extends BasicGameState {
|
||||
}
|
||||
}
|
||||
|
||||
// update in-game scoreboard
|
||||
if (previousScores != null && trackPosition > firstObjectTime) {
|
||||
// show scoreboard if selected, and always in break
|
||||
if (scoreboardVisible || breakTime > 0) {
|
||||
currentScoreboardAlpha += 1f / SCOREBOARD_FADE_IN_TIME * delta;
|
||||
if (currentScoreboardAlpha > 1f)
|
||||
currentScoreboardAlpha = 1f;
|
||||
} else {
|
||||
currentScoreboardAlpha -= 1f / SCOREBOARD_FADE_IN_TIME * delta;
|
||||
if (currentScoreboardAlpha < 0f)
|
||||
currentScoreboardAlpha = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
data.updateDisplays(delta);
|
||||
}
|
||||
|
||||
@@ -1057,6 +1133,9 @@ public class Game extends BasicGameState {
|
||||
case Input.KEY_F12:
|
||||
Utils.takeScreenShot();
|
||||
break;
|
||||
case Input.KEY_TAB:
|
||||
scoreboardVisible = !scoreboardVisible;
|
||||
break;
|
||||
case Input.KEY_M:
|
||||
if (Dancer.mirror) {
|
||||
mirrorTo = objectIndex;
|
||||
@@ -1407,6 +1486,14 @@ public class Game extends BasicGameState {
|
||||
leadInTime = beatmap.audioLeadIn + approachTime;
|
||||
restart = Restart.FALSE;
|
||||
|
||||
// fetch previous scores
|
||||
previousScores = ScoreDB.getMapScoresExcluding(beatmap, replay == null ? null : replay.getReplayFilename());
|
||||
lastRankUpdateTime = -1000;
|
||||
if (previousScores != null)
|
||||
currentRank = previousScores.length;
|
||||
scoreboardVisible = true;
|
||||
currentScoreboardAlpha = 0f;
|
||||
|
||||
// needs to play before setting position to resume without lag later
|
||||
MusicController.play(false);
|
||||
MusicController.setPosition(0);
|
||||
|
||||
Reference in New Issue
Block a user