Implemented "autopilot" mod.
Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
e362232d5f
commit
c14b4b4822
|
@ -51,7 +51,7 @@ public enum GameMod {
|
||||||
"Flashlight", "Restricted view area."),
|
"Flashlight", "Restricted view area."),
|
||||||
RELAX (Category.SPECIAL, 0, GameImage.MOD_RELAX, "RL", 128, Input.KEY_Z, 0f,
|
RELAX (Category.SPECIAL, 0, GameImage.MOD_RELAX, "RL", 128, Input.KEY_Z, 0f,
|
||||||
"Relax", "You don't need to click.\nGive your clicking/tapping finger a break from the heat of things.\n**UNRANKED**"),
|
"Relax", "You don't need to click.\nGive your clicking/tapping finger a break from the heat of things.\n**UNRANKED**"),
|
||||||
AUTOPILOT (Category.SPECIAL, 1, GameImage.MOD_AUTOPILOT, "AP", 8192, Input.KEY_X, 0f, false,
|
AUTOPILOT (Category.SPECIAL, 1, GameImage.MOD_AUTOPILOT, "AP", 8192, Input.KEY_X, 0f,
|
||||||
"Relax2", "Automatic cursor movement - just follow the rhythm.\n**UNRANKED**"),
|
"Relax2", "Automatic cursor movement - just follow the rhythm.\n**UNRANKED**"),
|
||||||
SPUN_OUT (Category.SPECIAL, 2, GameImage.MOD_SPUN_OUT, "SO", 4096, Input.KEY_V, 0.9f,
|
SPUN_OUT (Category.SPECIAL, 2, GameImage.MOD_SPUN_OUT, "SO", 4096, Input.KEY_V, 0.9f,
|
||||||
"SpunOut", "Spinners will be automatically completed."),
|
"SpunOut", "Spinners will be automatically completed."),
|
||||||
|
|
|
@ -50,6 +50,11 @@ public class Spinner implements HitObject {
|
||||||
/** The amount of time, in milliseconds, to fade in the spinner. */
|
/** The amount of time, in milliseconds, to fade in the spinner. */
|
||||||
private static final int FADE_IN_TIME = 500;
|
private static final int FADE_IN_TIME = 500;
|
||||||
|
|
||||||
|
/** Angle mod multipliers: "auto" (477rpm), "spun out" (287rpm) */
|
||||||
|
private static final float
|
||||||
|
AUTO_MULTIPLIER = 1 / 20f, // angle = 477/60f * delta/1000f * TWO_PI;
|
||||||
|
SPUN_OUT_MULTIPLIER = 1 / 33.25f; // angle = 287/60f * delta/1000f * TWO_PI;
|
||||||
|
|
||||||
/** PI constants. */
|
/** PI constants. */
|
||||||
private static final float
|
private static final float
|
||||||
TWO_PI = (float) (Math.PI * 2),
|
TWO_PI = (float) (Math.PI * 2),
|
||||||
|
@ -176,8 +181,7 @@ public class Spinner implements HitObject {
|
||||||
// TODO: verify ratios
|
// TODO: verify ratios
|
||||||
int result;
|
int result;
|
||||||
float ratio = rotations / rotationsNeeded;
|
float ratio = rotations / rotationsNeeded;
|
||||||
if (ratio >= 1.0f ||
|
if (ratio >= 1.0f || GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive() || GameMod.SPUN_OUT.isActive()) {
|
||||||
GameMod.AUTO.isActive() || GameMod.SPUN_OUT.isActive()) {
|
|
||||||
result = GameData.HIT_300;
|
result = GameData.HIT_300;
|
||||||
SoundController.playSound(SoundEffect.SPINNEROSU);
|
SoundController.playSound(SoundEffect.SPINNEROSU);
|
||||||
} else if (ratio >= 0.9f)
|
} else if (ratio >= 0.9f)
|
||||||
|
@ -213,14 +217,12 @@ public class Spinner implements HitObject {
|
||||||
// http://osu.ppy.sh/wiki/FAQ#Spinners
|
// http://osu.ppy.sh/wiki/FAQ#Spinners
|
||||||
float angle;
|
float angle;
|
||||||
if (GameMod.AUTO.isActive()) {
|
if (GameMod.AUTO.isActive()) {
|
||||||
// "auto" mod (fast: 477rpm)
|
|
||||||
lastAngle = 0;
|
lastAngle = 0;
|
||||||
angle = delta / 20f; // angle = 477/60f * delta/1000f * TWO_PI;
|
angle = delta * AUTO_MULTIPLIER;
|
||||||
isSpinning = true;
|
isSpinning = true;
|
||||||
} else if (GameMod.SPUN_OUT.isActive()) {
|
} else if (GameMod.SPUN_OUT.isActive() || GameMod.AUTOPILOT.isActive()) {
|
||||||
// "spun out" mod (slow: 287rpm)
|
|
||||||
lastAngle = 0;
|
lastAngle = 0;
|
||||||
angle = delta / 33.25f; // angle = 287/60f * delta/1000f * TWO_PI;
|
angle = delta * SPUN_OUT_MULTIPLIER;
|
||||||
isSpinning = true;
|
isSpinning = true;
|
||||||
} else {
|
} else {
|
||||||
angle = (float) Math.atan2(mouseY - (height / 2), mouseX - (width / 2));
|
angle = (float) Math.atan2(mouseY - (height / 2), mouseX - (width / 2));
|
||||||
|
@ -276,7 +278,8 @@ public class Spinner implements HitObject {
|
||||||
timeDiff = trackPosition - hitObject.getTime();
|
timeDiff = trackPosition - hitObject.getTime();
|
||||||
|
|
||||||
// calculate point
|
// calculate point
|
||||||
float angle = timeDiff / 20f - HALF_PI;
|
float multiplier = (GameMod.AUTO.isActive()) ? AUTO_MULTIPLIER : SPUN_OUT_MULTIPLIER;
|
||||||
|
float angle = (timeDiff * multiplier) - HALF_PI;
|
||||||
final float r = height / 10f;
|
final float r = height / 10f;
|
||||||
return new float[] {
|
return new float[] {
|
||||||
(float) (x + r * Math.cos(angle)),
|
(float) (x + r * Math.cos(angle)),
|
||||||
|
|
|
@ -201,6 +201,12 @@ public class Game extends BasicGameState {
|
||||||
/** The current flashlight area radius. */
|
/** The current flashlight area radius. */
|
||||||
private int flashlightRadius;
|
private int flashlightRadius;
|
||||||
|
|
||||||
|
/** The cursor coordinates using the "auto" or "relax" mods. */
|
||||||
|
private int autoMouseX = 0, autoMouseY = 0;
|
||||||
|
|
||||||
|
/** Whether or not the cursor should be pressed using the "auto" mod. */
|
||||||
|
private boolean autoMousePressed;
|
||||||
|
|
||||||
// game-related variables
|
// game-related variables
|
||||||
private GameContainer container;
|
private GameContainer container;
|
||||||
private StateBasedGame game;
|
private StateBasedGame game;
|
||||||
|
@ -263,10 +269,12 @@ public class Game extends BasicGameState {
|
||||||
int firstObjectTime = osu.objects[0].getTime();
|
int firstObjectTime = osu.objects[0].getTime();
|
||||||
int timeDiff = firstObjectTime - trackPosition;
|
int timeDiff = firstObjectTime - trackPosition;
|
||||||
|
|
||||||
// "auto" mod: move cursor automatically
|
// "auto" and "autopilot" mods: move cursor automatically
|
||||||
int autoMouseX = width / 2, autoMouseY = height / 2;
|
// TODO: this should really be in update(), not render()
|
||||||
boolean autoMousePress = false;
|
autoMouseX = width / 2;
|
||||||
if (GameMod.AUTO.isActive()) {
|
autoMouseY = height / 2;
|
||||||
|
autoMousePressed = false;
|
||||||
|
if (GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive()) {
|
||||||
float[] autoXY = null;
|
float[] autoXY = null;
|
||||||
if (isLeadIn()) {
|
if (isLeadIn()) {
|
||||||
// lead-in
|
// lead-in
|
||||||
|
@ -306,11 +314,11 @@ public class Game extends BasicGameState {
|
||||||
int offset300 = hitResultOffset[GameData.HIT_300];
|
int offset300 = hitResultOffset[GameData.HIT_300];
|
||||||
if ((osu.objects[objectIndex].isCircle() && objectTime - trackPosition < offset300) ||
|
if ((osu.objects[objectIndex].isCircle() && objectTime - trackPosition < offset300) ||
|
||||||
(osu.objects[objectIndex - 1].isCircle() && trackPosition - osu.objects[objectIndex - 1].getTime() < offset300))
|
(osu.objects[objectIndex - 1].isCircle() && trackPosition - osu.objects[objectIndex - 1].getTime() < offset300))
|
||||||
autoMousePress = true;
|
autoMousePressed = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
autoXY = hitObjects[objectIndex].getPointAt(trackPosition);
|
autoXY = hitObjects[objectIndex].getPointAt(trackPosition);
|
||||||
autoMousePress = true;
|
autoMousePressed = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// last object
|
// last object
|
||||||
|
@ -342,7 +350,7 @@ public class Game extends BasicGameState {
|
||||||
if (pauseTime > -1 && pausedMouseX > -1 && pausedMouseY > -1) {
|
if (pauseTime > -1 && pausedMouseX > -1 && pausedMouseY > -1) {
|
||||||
mouseX = pausedMouseX;
|
mouseX = pausedMouseX;
|
||||||
mouseY = pausedMouseY;
|
mouseY = pausedMouseY;
|
||||||
} else if (GameMod.AUTO.isActive()) {
|
} else if (GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive()) {
|
||||||
mouseX = autoMouseX;
|
mouseX = autoMouseX;
|
||||||
mouseY = autoMouseY;
|
mouseY = autoMouseY;
|
||||||
} else if (isReplay) {
|
} else if (isReplay) {
|
||||||
|
@ -510,7 +518,9 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GameMod.AUTO.isActive())
|
if (GameMod.AUTO.isActive())
|
||||||
UI.draw(g, autoMouseX, autoMouseY, autoMousePress);
|
UI.draw(g, autoMouseX, autoMouseY, autoMousePressed);
|
||||||
|
else if (GameMod.AUTOPILOT.isActive())
|
||||||
|
UI.draw(g, autoMouseX, autoMouseY, Utils.isGameKeyPressed());
|
||||||
else if (!isReplay)
|
else if (!isReplay)
|
||||||
UI.draw(g);
|
UI.draw(g);
|
||||||
else
|
else
|
||||||
|
@ -522,7 +532,10 @@ public class Game extends BasicGameState {
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
UI.update(delta);
|
UI.update(delta);
|
||||||
int mouseX, mouseY;
|
int mouseX, mouseY;
|
||||||
if (!isReplay) {
|
if (GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive()) {
|
||||||
|
mouseX = autoMouseX;
|
||||||
|
mouseY = autoMouseY;
|
||||||
|
} else if (!isReplay) {
|
||||||
mouseX = input.getMouseX();
|
mouseX = input.getMouseX();
|
||||||
mouseY = input.getMouseY();
|
mouseY = input.getMouseY();
|
||||||
} else {
|
} else {
|
||||||
|
@ -940,16 +953,26 @@ public class Game extends BasicGameState {
|
||||||
if (GameMod.AUTO.isActive() || GameMod.RELAX.isActive())
|
if (GameMod.AUTO.isActive() || GameMod.RELAX.isActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// "autopilot" mod: ignore actual cursor coordinates
|
||||||
|
int cx, cy;
|
||||||
|
if (GameMod.AUTOPILOT.isActive()) {
|
||||||
|
cx = autoMouseX;
|
||||||
|
cy = autoMouseY;
|
||||||
|
} else {
|
||||||
|
cx = x;
|
||||||
|
cy = y;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isReplay)
|
if (!isReplay)
|
||||||
addReplayFrame(x, y, lastKeysPressed | keys);
|
addReplayFrame(cx, cy, lastKeysPressed | keys);
|
||||||
|
|
||||||
// circles
|
// circles
|
||||||
if (hitObject.isCircle() && hitObjects[objectIndex].mousePressed(x, y))
|
if (hitObject.isCircle() && hitObjects[objectIndex].mousePressed(cx, cy))
|
||||||
objectIndex++; // circle hit
|
objectIndex++; // circle hit
|
||||||
|
|
||||||
// sliders
|
// sliders
|
||||||
else if (hitObject.isSlider())
|
else if (hitObject.isSlider())
|
||||||
hitObjects[objectIndex].mousePressed(x, y);
|
hitObjects[objectIndex].mousePressed(cx, cy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1209,6 +1232,9 @@ public class Game extends BasicGameState {
|
||||||
deaths = 0;
|
deaths = 0;
|
||||||
deathTime = -1;
|
deathTime = -1;
|
||||||
replayFrames = null;
|
replayFrames = null;
|
||||||
|
autoMouseX = 0;
|
||||||
|
autoMouseY = 0;
|
||||||
|
autoMousePressed = false;
|
||||||
|
|
||||||
System.gc();
|
System.gc();
|
||||||
}
|
}
|
||||||
|
@ -1415,6 +1441,10 @@ public class Game extends BasicGameState {
|
||||||
* @return the [x,y] coordinates
|
* @return the [x,y] coordinates
|
||||||
*/
|
*/
|
||||||
private float[] getPointAt(float startX, float startY, float endX, float endY, float t) {
|
private float[] getPointAt(float startX, float startY, float endX, float endY, float t) {
|
||||||
|
// "autopilot" mod: move quicker between objects
|
||||||
|
if (GameMod.AUTOPILOT.isActive())
|
||||||
|
t = Utils.clamp(t * 2f, 0f, 1f);
|
||||||
|
|
||||||
float[] xy = new float[2];
|
float[] xy = new float[2];
|
||||||
xy[0] = startX + (endX - startX) * t;
|
xy[0] = startX + (endX - startX) * t;
|
||||||
xy[1] = startY + (endY - startY) * t;
|
xy[1] = startY + (endY - startY) * t;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user