From a40c8b5d311fe422458e05e6962a990f83c9b2ea Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 10 Dec 2016 16:20:50 +0100 Subject: [PATCH] visit every object when multiple objects end during the same update (close #72) --- src/itdelatrisu/opsu/states/Game.java | 7 +++ src/itdelatrisu/opsu/ui/Cursor.java | 71 ++++++++++++++++----------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index 40bbc321..74c25464 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -1018,13 +1018,20 @@ public class Game extends BasicGameState { if (restart != Restart.LOSE) { // update objects (loop in unlikely event of any skipped indexes) boolean keyPressed = keys != ReplayFrame.KEY_NONE; + boolean skippedObject = false; while (objectIndex < gameObjects.length && trackPosition > beatmap.objects[objectIndex].getTime()) { // check if we've already passed the next object's start time boolean overlap = (objectIndex + 1 < gameObjects.length && trackPosition > beatmap.objects[objectIndex + 1].getTime() - hitResultOffset[GameData.HIT_50]); + if (skippedObject && (GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive())) { + Vec2f start = gameObjects[objectIndex - 1].start; + UI.getCursor().setCursorPosition((int) start.x, (int) start.y); + } + // update hit object and check completion status if (gameObjects[objectIndex].update(overlap, delta, mouseX, mouseY, keyPressed, trackPosition)) { + skippedObject = true; objectIndex++; // done, so increment object index sbOverlay.updateIndex(objectIndex); if (objectIndex >= mirrorTo) { diff --git a/src/itdelatrisu/opsu/ui/Cursor.java b/src/itdelatrisu/opsu/ui/Cursor.java index 94e08ff5..d7240a45 100644 --- a/src/itdelatrisu/opsu/ui/Cursor.java +++ b/src/itdelatrisu/opsu/ui/Cursor.java @@ -64,6 +64,8 @@ public class Cursor { /** Stores all previous cursor locations to display a trail. */ private LinkedList trail = new LinkedList(); + private boolean newStyle; + // game-related variables private static GameContainer container; private static StateBasedGame game; @@ -131,16 +133,16 @@ public class Cursor { return; // determine correct cursor image - Image cursor = null, cursorMiddle = null, cursorTrail = null; + Image cursor, cursorMiddle = null, cursorTrail; boolean beatmapSkinned = GameImage.CURSOR.hasBeatmapSkinImage(); - boolean newStyle, hasMiddle; + boolean hasMiddle; Skin skin = Options.getSkin(); if (beatmapSkinned) { newStyle = true; // osu! currently treats all beatmap cursors as new-style cursors hasMiddle = GameImage.CURSOR_MIDDLE.hasBeatmapSkinImage(); } else newStyle = hasMiddle = Options.isNewCursorEnabled(); - if (newStyle || beatmapSkinned) { + if (beatmapSkinned || newStyle) { cursor = GameImage.CURSOR.getImage(); cursorTrail = GameImage.CURSOR_TRAIL.getImage(); } else { @@ -168,33 +170,7 @@ public class Cursor { cursorTrail = cursorTrail.getScaledCopy(cursorScale); } - // TODO: use an image buffer - int removeCount = 0; - float FPSmod = Math.max(container.getFPS(), 1) / 30f; - if (newStyle) { - // new style: add all points between cursor movements - if ((lastPosition.x == 0 && lastPosition.y == 0) || !addCursorPoints(lastPosition.x, lastPosition.y, mouseX, mouseY)) { - trail.add(new Point(mouseX, mouseY)); - } - lastPosition.move(mouseX, mouseY); - - removeCount = (int) (trail.size() / (6 * FPSmod)) + 1; - } else { - // old style: sample one point at a time - trail.add(new Point(mouseX, mouseY)); - - int max = (int) (10 * FPSmod); - if (trail.size() > max) - removeCount = trail.size() - max; - } - - if (Dancer.cursortraillength > 20) { - removeCount = trail.size() - Dancer.cursortraillength; - } - - // remove points from the lists - for (int i = 0; i < removeCount && !trail.isEmpty(); i++) - trail.remove(); + setCursorPosition(mouseX, mouseY); Color filter; if (isMirrored) { @@ -229,6 +205,41 @@ public class Cursor { cursorMiddle.drawCentered(mouseX, mouseY, Dancer.onlycolortrail ? Color.white : filter); } + /** + * Sets the cursor position to given point and updates trail. + * @param mouseX x coordinate to set position to + * @param mouseY y coordinate to set position to + */ + public void setCursorPosition(int mouseX, int mouseY) { + // TODO: use an image buffer + int removeCount = 0; + float FPSmod = Math.max(container.getFPS(), 1) / 30f; + if (newStyle) { + // new style: add all points between cursor movements + if ((lastPosition.x == 0 && lastPosition.y == 0) || !addCursorPoints(lastPosition.x, lastPosition.y, mouseX, mouseY)) { + trail.add(new Point(mouseX, mouseY)); + } + lastPosition.move(mouseX, mouseY); + + removeCount = (int) (trail.size() / (6 * FPSmod)) + 1; + } else { + // old style: sample one point at a time + trail.add(new Point(mouseX, mouseY)); + + int max = (int) (10 * FPSmod); + if (trail.size() > max) + removeCount = trail.size() - max; + } + + if (Dancer.cursortraillength > 20) { + removeCount = trail.size() - Dancer.cursortraillength; + } + + // remove points from the lists + for (int i = 0; i < removeCount && !trail.isEmpty(); i++) + trail.remove(); + } + /** * Adds all points between (x1, y1) and (x2, y2) to the cursor point lists. * @author http://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm#Java