diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 4129b5ca..b12bb36f 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -70,8 +70,8 @@ public class Slider implements HitObject { /** The time duration of the slider including repeats, in milliseconds. */ private float sliderTimeTotal = 0f; - /** Whether or not the result of the initial hit circle has been processed. */ - private boolean sliderClicked = false; + /** Whether or not the result of the initial/final hit circles have been processed. */ + private boolean sliderClickedInitial = false, sliderClickedFinal = false; /** Whether or not to show the follow circle. */ private boolean followCircleActive = false; @@ -180,7 +180,7 @@ public class Slider implements HitObject { // start circle hitCircle.drawCentered(x, y, color); hitCircleOverlay.drawCentered(x, y, Utils.COLOR_WHITE_FADE); - if (sliderClicked) + if (sliderClickedInitial) ; // don't draw current combo number if already clicked else data.drawSymbolNumber(hitObject.getComboNumber(), x, y, @@ -266,7 +266,7 @@ public class Slider implements HitObject { @Override public boolean mousePressed(int x, int y) { - if (sliderClicked) // first circle already processed + if (sliderClickedInitial) // first circle already processed return false; double distance = Math.hypot(hitObject.getX() - x, hitObject.getY() - y); @@ -286,7 +286,7 @@ public class Slider implements HitObject { if (result > -1) { data.addHitError(hitObject.getTime(), x,y,trackPosition - hitObject.getTime()); - sliderClicked = true; + sliderClickedInitial = true; data.sliderTickResult(hitObject.getTime(), result, hitObject.getX(), hitObject.getY(), hitObject.getHitSoundType()); return true; @@ -323,12 +323,12 @@ public class Slider implements HitObject { int lastIndex = hitObject.getSliderX().length - 1; boolean isAutoMod = GameMod.AUTO.isActive(); - if (!sliderClicked) { + if (!sliderClickedInitial) { int time = hitObject.getTime(); // start circle time passed if (trackPosition > time + hitResultOffset[GameData.HIT_50]) { - sliderClicked = true; + sliderClickedInitial = true; if (isAutoMod) { // "auto" mod: catch any missed notes due to lag ticksHit++; data.sliderTickResult(time, GameData.HIT_SLIDER30, @@ -342,7 +342,7 @@ public class Slider implements HitObject { else if (isAutoMod) { if (Math.abs(trackPosition - time) < hitResultOffset[GameData.HIT_300]) { ticksHit++; - sliderClicked = true; + sliderClickedInitial = true; data.sliderTickResult(time, GameData.HIT_SLIDER30, hitObject.getX(), hitObject.getY(), hitSound); } @@ -353,19 +353,23 @@ public class Slider implements HitObject { if (overlap || trackPosition > hitObject.getTime() + sliderTimeTotal) { tickIntervals++; - // "auto" mod: send a perfect hit result - if (isAutoMod) - ticksHit++; - // check if cursor pressed and within end circle - else if (Utils.isGameKeyPressed()) { + if (Utils.isGameKeyPressed()) { 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) - ticksHit++; + sliderClickedFinal = true; } + // final circle hit + if (sliderClickedFinal) + ticksHit++; + + // "auto" mod: always send a perfect hit result + if (isAutoMod) + ticksHit = tickIntervals; + // calculate and send slider result hitResult(); return true; @@ -421,6 +425,10 @@ public class Slider implements HitObject { data.sliderTickResult(trackPosition, GameData.HIT_SLIDER10, c[0], c[1], (byte) -1); } + + // held near end of slider + if (!sliderClickedFinal && trackPosition > hitObject.getTime() + sliderTimeTotal - hitResultOffset[GameData.HIT_300]) + sliderClickedFinal = true; } else { followCircleActive = false; diff --git a/src/itdelatrisu/opsu/states/SongMenu.java b/src/itdelatrisu/opsu/states/SongMenu.java index 497b99c3..cfb4679d 100644 --- a/src/itdelatrisu/opsu/states/SongMenu.java +++ b/src/itdelatrisu/opsu/states/SongMenu.java @@ -1106,11 +1106,11 @@ public class SongMenu extends BasicGameState { /** * Sets a new focus node. * @param node the base node; it will be expanded if it isn't already - * @param pos the OsuFile element to focus; if out of bounds, it will be randomly chosen - * @param flag if true, startNode will be set to the first node in the group + * @param osuFileIndex the OsuFile element to focus; if out of bounds, it will be randomly chosen + * @param changeStartNode if true, startNode will be set to the first node in the group * @return the old focus node */ - public OsuGroupNode setFocus(OsuGroupNode node, int pos, boolean flag) { + public OsuGroupNode setFocus(OsuGroupNode node, int osuFileIndex, boolean changeStartNode) { if (node == null) return null; @@ -1126,18 +1126,18 @@ public class SongMenu extends BasicGameState { // if start node was previously expanded, move it if (startNode != null && startNode.index == expandedIndex) - startNode = node; + startNode = OsuGroupList.get().getBaseNode(startNode.index); } - // check pos bounds + // check osuFileIndex bounds int length = node.osuFiles.size(); - if (pos < 0 || pos > length - 1) // set a random pos - pos = (int) (Math.random() * length); + if (osuFileIndex < 0 || osuFileIndex > length - 1) // set a random index + osuFileIndex = (int) (Math.random() * length); // change the focus node - if (flag || (startNode.index == 0 && startNode.osuFileIndex == -1 && startNode.prev == null)) + if (changeStartNode || (startNode.index == 0 && startNode.osuFileIndex == -1 && startNode.prev == null)) startNode = node; - focusNode = OsuGroupList.get().getNode(node, pos); + focusNode = OsuGroupList.get().getNode(node, osuFileIndex); OsuFile osu = focusNode.osuFiles.get(focusNode.osuFileIndex); MusicController.play(osu, true); Utils.loadGlyphs(osu);