Merge branch 'mirror'

This commit is contained in:
yugecin 2016-09-29 23:34:22 +02:00
commit 17c802e6dc
12 changed files with 132 additions and 19 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -638,6 +638,34 @@ public class Options {
} }
}, },
DANCE_MIRROR ("Mirror collage", "MirrorCollage", "Hypnotizing stuff", false) {
@Override
public void click(GameContainer container) {
bool = !bool;
Dancer.mirror = bool;
}
@Override
public void read(String s) {
super.read(s);
Dancer.mirror = bool;
}
},
DANCE_DRAW_APPROACH ("Draw approach circles", "DrawApproach", "Can get a bit busy when using mirror collage", true) {
@Override
public void click(GameContainer container) {
bool = !bool;
Dancer.drawApproach = bool;
}
@Override
public void read(String s) {
super.read(s);
Dancer.drawApproach = bool;
}
},
PIPPI_ENABLE ("Pippi", "Pippi", "Move in circles like dancing pippi (osu! april fools joke 2016)", false) { PIPPI_ENABLE ("Pippi", "Pippi", "Move in circles like dancing pippi (osu! april fools joke 2016)", false) {
// TODO // TODO
}, },

View File

@ -58,6 +58,7 @@ import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display; import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Animation; import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer; import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Input; import org.newdawn.slick.Input;
import org.newdawn.slick.state.StateBasedGame; import org.newdawn.slick.state.StateBasedGame;
@ -575,4 +576,15 @@ public class Utils {
return y < Options.height / 2d ? 1 : 4; return y < Options.height / 2d ? 1 : 4;
} }
public static Color shiftHue(Color color, double H) {
double U = Math.cos(H * Math.PI / 180d);
double W = Math.sin(H * Math.PI / 180d);
Color n = new Color(0, 0, 0);
n.r = (float) ((0.299d + 0.701d * U + 0.168d * W) * color.r + (0.587d - 0.587d * U + 0.330d * W) * color.g + (0.114d - 0.114d * U - 0.497 * W) * color.b);
n.g = (float) ((0.299 + 0.299 * U - 0.328 * W) * color.r + (0.587d - 0.413 * U + 0.035 * W) * color.g + (0.114d - 0.114d * U - 0.292 * W) * color.b);
n.b = (float) ((0.299d + 0.300d * U + 1.250d * W) * color.r + (0.587d - 0.585d * U + 1.050d * W) * color.g + (0.114 - 0.886 * U - 0.203 * W) * color.b);
return n;
}
} }

View File

@ -32,6 +32,7 @@ import itdelatrisu.opsu.ui.Colors;
import org.newdawn.slick.Color; import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer; import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import yugecin.opsudance.Dancer;
/** /**
* Data type representing a circle object. * Data type representing a circle object.
@ -89,7 +90,12 @@ public class Circle extends GameObject {
} }
@Override @Override
public void draw(Graphics g, int trackPosition) { public void draw(Graphics g, int trackPosition, boolean mirror) {
Color orig = color;
if (mirror) {
color = Utils.shiftHue(color, 180d);
}
int timeDiff = hitObject.getTime() - trackPosition; int timeDiff = hitObject.getTime() - trackPosition;
final int approachTime = game.getApproachTime(); final int approachTime = game.getApproachTime();
final int fadeInTime = game.getFadeInTime(); final int fadeInTime = game.getFadeInTime();
@ -98,6 +104,11 @@ public class Circle extends GameObject {
float fadeinScale = (timeDiff - approachTime + fadeInTime) / (float) fadeInTime; float fadeinScale = (timeDiff - approachTime + fadeInTime) / (float) fadeInTime;
float alpha = Utils.clamp(1 - fadeinScale, 0, 1); float alpha = Utils.clamp(1 - fadeinScale, 0, 1);
g.pushTransform();
if (mirror) {
g.rotate(x, y, -180f);
}
if (GameMod.HIDDEN.isActive()) { if (GameMod.HIDDEN.isActive()) {
final int hiddenDecayTime = game.getHiddenDecayTime(); final int hiddenDecayTime = game.getHiddenDecayTime();
final int hiddenTimeDiff = game.getHiddenTimeDiff(); final int hiddenTimeDiff = game.getHiddenTimeDiff();
@ -110,7 +121,7 @@ public class Circle extends GameObject {
float oldAlpha = Colors.WHITE_FADE.a; float oldAlpha = Colors.WHITE_FADE.a;
Colors.WHITE_FADE.a = color.a = alpha; Colors.WHITE_FADE.a = color.a = alpha;
if (timeDiff >= 0 && !GameMod.HIDDEN.isActive()) if (timeDiff >= 0 && !GameMod.HIDDEN.isActive() && Dancer.drawApproach)
GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale).drawCentered(x, y, color); GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale).drawCentered(x, y, color);
GameImage.HITCIRCLE.getImage().drawCentered(x, y, color); GameImage.HITCIRCLE.getImage().drawCentered(x, y, color);
boolean overlayAboveNumber = Options.getSkin().isHitCircleOverlayAboveNumber(); boolean overlayAboveNumber = Options.getSkin().isHitCircleOverlayAboveNumber();
@ -122,6 +133,9 @@ public class Circle extends GameObject {
GameImage.HITCIRCLE_OVERLAY.getImage().drawCentered(x, y, Colors.WHITE_FADE); GameImage.HITCIRCLE_OVERLAY.getImage().drawCentered(x, y, Colors.WHITE_FADE);
Colors.WHITE_FADE.a = oldAlpha; Colors.WHITE_FADE.a = oldAlpha;
g.popTransform();
color = orig;
} }
/** /**

View File

@ -43,7 +43,7 @@ public class DummyObject extends GameObject {
} }
@Override @Override
public void draw(Graphics g, int trackPosition) {} public void draw(Graphics g, int trackPosition, boolean mirror) {}
@Override @Override
public boolean update(boolean overlap, int delta, int mouseX, int mouseY, boolean keyPressed, int trackPosition) { public boolean update(boolean overlap, int delta, int mouseX, int mouseY, boolean keyPressed, int trackPosition) {

View File

@ -43,7 +43,7 @@ public abstract class GameObject {
* @param g the graphics context * @param g the graphics context
* @param trackPosition the current track position * @param trackPosition the current track position
*/ */
public abstract void draw(Graphics g, int trackPosition); public abstract void draw(Graphics g, int trackPosition, boolean mirrored);
/** /**
* Updates the hit object. * Updates the hit object.

View File

@ -32,10 +32,12 @@ import itdelatrisu.opsu.states.Game;
import itdelatrisu.opsu.ui.Colors; import itdelatrisu.opsu.ui.Colors;
import itdelatrisu.opsu.ui.animations.AnimationEquation; import itdelatrisu.opsu.ui.animations.AnimationEquation;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Color; import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer; import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image; import org.newdawn.slick.Image;
import yugecin.opsudance.Dancer;
/** /**
* Data type representing a slider object. * Data type representing a slider object.
@ -109,6 +111,8 @@ public class Slider extends GameObject {
private int repeats; private int repeats;
private static Color curveColor = new Color(0, 0, 0, 20);
/** /**
* Initializes the Slider data type with images and dimensions. * Initializes the Slider data type with images and dimensions.
* @param container the game container * @param container the game container
@ -176,7 +180,12 @@ public class Slider extends GameObject {
} }
@Override @Override
public void draw(Graphics g, int trackPosition) { public void draw(Graphics g, int trackPosition, boolean mirror) {
Color orig = color;
if (mirror) {
color = Utils.shiftHue(color, 180d);
}
int timeDiff = hitObject.getTime() - trackPosition; int timeDiff = hitObject.getTime() - trackPosition;
final int approachTime = game.getApproachTime(); final int approachTime = game.getApproachTime();
final int fadeInTime = game.getFadeInTime(); final int fadeInTime = game.getFadeInTime();
@ -193,9 +202,14 @@ public class Slider extends GameObject {
Vec2f endPos = curve.pointAt(1); Vec2f endPos = curve.pointAt(1);
float curveInterval = Options.isSliderSnaking() ? alpha : 1f; float curveInterval = Options.isSliderSnaking() ? alpha : 1f;
curve.draw(color,curveInterval); curve.draw(curveColor, curveInterval);
color.a = alpha; color.a = alpha;
g.pushTransform();
if (mirror) {
g.rotate(x, y, -180f);
}
/* /*
// end circle // end circle
Vec2f endCircPos = curve.pointAt(curveInterval); Vec2f endCircPos = curve.pointAt(curveInterval);
@ -208,6 +222,8 @@ public class Slider extends GameObject {
if (!overlayAboveNumber) if (!overlayAboveNumber)
hitCircleOverlay.drawCentered(x, y, Colors.WHITE_FADE); hitCircleOverlay.drawCentered(x, y, Colors.WHITE_FADE);
g.popTransform();
// ticks // ticks
if (ticksT != null) { if (ticksT != null) {
float tickScale = 0.5f + 0.5f * AnimationEquation.OUT_BACK.calc(decorationsAlpha); float tickScale = 0.5f + 0.5f * AnimationEquation.OUT_BACK.calc(decorationsAlpha);
@ -215,10 +231,21 @@ public class Slider extends GameObject {
for (int i = 0; i < ticksT.length; i++) { for (int i = 0; i < ticksT.length; i++) {
Vec2f c = curve.pointAt(ticksT[i]); Vec2f c = curve.pointAt(ticksT[i]);
Colors.WHITE_FADE.a = decorationsAlpha; Colors.WHITE_FADE.a = decorationsAlpha;
g.pushTransform();
if (mirror) {
g.rotate(c.x, c.y, -180f);
}
tick.drawCentered(c.x, c.y, Colors.WHITE_FADE); tick.drawCentered(c.x, c.y, Colors.WHITE_FADE);
g.popTransform();
Colors.WHITE_FADE.a = alpha; Colors.WHITE_FADE.a = alpha;
} }
} }
g.pushTransform();
if (mirror) {
g.rotate(x, y, -180f);
}
if (GameMod.HIDDEN.isActive()) { if (GameMod.HIDDEN.isActive()) {
final int hiddenDecayTime = game.getHiddenDecayTime(); final int hiddenDecayTime = game.getHiddenDecayTime();
final int hiddenTimeDiff = game.getHiddenTimeDiff(); final int hiddenTimeDiff = game.getHiddenTimeDiff();
@ -235,6 +262,8 @@ public class Slider extends GameObject {
if (overlayAboveNumber) if (overlayAboveNumber)
hitCircleOverlay.drawCentered(x, y, Colors.WHITE_FADE); hitCircleOverlay.drawCentered(x, y, Colors.WHITE_FADE);
g.popTransform();
// repeats // repeats
if (curveInterval == 1.0f) { if (curveInterval == 1.0f) {
for (int tcurRepeat = currentRepeats; tcurRepeat <= currentRepeats + 1; tcurRepeat++) { for (int tcurRepeat = currentRepeats; tcurRepeat <= currentRepeats + 1; tcurRepeat++) {
@ -264,8 +293,14 @@ public class Slider extends GameObject {
if (timeDiff >= 0) { if (timeDiff >= 0) {
// approach circle // approach circle
if (!GameMod.HIDDEN.isActive()) g.pushTransform();
if (mirror) {
g.rotate(x, y, -180f);
}
if (!GameMod.HIDDEN.isActive() && Dancer.drawApproach) {
GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale).drawCentered(x, y, color); GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale).drawCentered(x, y, color);
}
g.popTransform();
} else { } else {
// Since update() might not have run before drawing during a replay, the // Since update() might not have run before drawing during a replay, the
// slider time may not have been calculated, which causes NAN numbers and flicker. // slider time may not have been calculated, which causes NAN numbers and flicker.
@ -303,6 +338,8 @@ public class Slider extends GameObject {
} }
Colors.WHITE_FADE.a = oldAlpha; Colors.WHITE_FADE.a = oldAlpha;
color = orig;
} }
/** /**

View File

@ -175,7 +175,10 @@ public class Spinner extends GameObject {
} }
@Override @Override
public void draw(Graphics g, int trackPosition) { public void draw(Graphics g, int trackPosition, boolean mirror) {
if (mirror) {
return;
}
// only draw spinners shortly before start time // only draw spinners shortly before start time
int timeDiff = hitObject.getTime() - trackPosition; int timeDiff = hitObject.getTime() - trackPosition;
final int fadeInTime = game.getFadeInTime(); final int fadeInTime = game.getFadeInTime();

View File

@ -394,8 +394,8 @@ public class CurveRenderState {
ByteBuffer buff = BufferUtils.createByteBuffer(slider.getWidth() * 4); ByteBuffer buff = BufferUtils.createByteBuffer(slider.getWidth() * 4);
for (int i = 0; i < slider.getWidth(); ++i) { for (int i = 0; i < slider.getWidth(); ++i) {
Color col = slider.getColor(i, 0); Color col = slider.getColor(i, 0);
buff.put((byte) (255 * col.r)); buff.put((byte) (255 * col.b));
buff.put((byte) (255 * col.g)); buff.put((byte) (255 * col.b)); // I know this looks strange...
buff.put((byte) (255 * col.b)); buff.put((byte) (255 * col.b));
buff.put((byte) (255 * col.a)); buff.put((byte) (255 * col.a));
} }

View File

@ -47,10 +47,7 @@ import itdelatrisu.opsu.render.FrameBufferCache;
import itdelatrisu.opsu.replay.PlaybackSpeed; import itdelatrisu.opsu.replay.PlaybackSpeed;
import itdelatrisu.opsu.replay.Replay; import itdelatrisu.opsu.replay.Replay;
import itdelatrisu.opsu.replay.ReplayFrame; import itdelatrisu.opsu.replay.ReplayFrame;
import itdelatrisu.opsu.ui.Colors; import itdelatrisu.opsu.ui.*;
import itdelatrisu.opsu.ui.Fonts;
import itdelatrisu.opsu.ui.MenuButton;
import itdelatrisu.opsu.ui.UI;
import itdelatrisu.opsu.ui.animations.AnimationEquation; import itdelatrisu.opsu.ui.animations.AnimationEquation;
import java.io.File; import java.io.File;
@ -269,8 +266,11 @@ public class Game extends BasicGameState {
private Input input; private Input input;
private final int state; private final int state;
private final Cursor mirrorCursor;
public Game(int state) { public Game(int state) {
this.state = state; this.state = state;
mirrorCursor = new Cursor();
} }
@Override @Override
@ -599,8 +599,16 @@ public class Game extends BasicGameState {
if (isReplay) if (isReplay)
UI.draw(g, replayX, replayY, replayKeyPressed); UI.draw(g, replayX, replayY, replayKeyPressed);
else if (GameMod.AUTO.isActive()) else if (GameMod.AUTO.isActive()) {
UI.draw(g, (int) autoMousePosition.x, (int) autoMousePosition.y, autoMousePressed); UI.draw(g, (int) autoMousePosition.x, (int) autoMousePosition.y, autoMousePressed);
if (Dancer.mirror) {
double dx = autoMousePosition.x - Options.width / 2d;
double dy = autoMousePosition.y - Options.height / 2d;
double d = Math.sqrt(dx * dx + dy * dy);
double a = Math.atan2(dy, dx) + Math.PI;
mirrorCursor.draw((int) (Math.cos(a) * d + Options.width / 2), (int) (Math.sin(a) * d + Options.height / 2), autoMousePressed);
}
}
else if (GameMod.AUTOPILOT.isActive()) else if (GameMod.AUTOPILOT.isActive())
UI.draw(g, (int) autoMousePosition.x, (int) autoMousePosition.y, Utils.isGameKeyPressed()); UI.draw(g, (int) autoMousePosition.x, (int) autoMousePosition.y, Utils.isGameKeyPressed());
else else
@ -1389,9 +1397,15 @@ public class Game extends BasicGameState {
GameObject gameObj = gameObjects[idx]; GameObject gameObj = gameObjects[idx];
// normal case // normal case
if (!loseState) if (!loseState) {
gameObj.draw(g, trackPosition); gameObj.draw(g, trackPosition, false);
if (Dancer.mirror) {
g.pushTransform();
g.rotate(Options.width / 2f, Options.height / 2f, 180f);
gameObj.draw(g, trackPosition, true);
g.popTransform();
}
}
// death: make objects "fall" off the screen // death: make objects "fall" off the screen
else { else {
// time the object began falling // time the object began falling
@ -1417,7 +1431,7 @@ public class Game extends BasicGameState {
g.translate(0, dt * dt * container.getHeight()); g.translate(0, dt * dt * container.getHeight());
Vec2f rotationCenter = gameObj.getPointAt(beatmap.objects[idx].getTime()); Vec2f rotationCenter = gameObj.getPointAt(beatmap.objects[idx].getTime());
g.rotate(rotationCenter.x, rotationCenter.y, rotSpeed * dt); g.rotate(rotationCenter.x, rotationCenter.y, rotSpeed * dt);
gameObj.draw(g, trackPosition); gameObj.draw(g, trackPosition, false);
g.popTransform(); g.popTransform();
} }

View File

@ -110,6 +110,8 @@ public class OptionsMenu extends BasicGameState {
GameOption.DANCE_LAZY_SLIDERS, GameOption.DANCE_LAZY_SLIDERS,
GameOption.DANCE_CIRCLE_STREAMS, GameOption.DANCE_CIRCLE_STREAMS,
GameOption.DANCE_ONLY_CIRCLE_STACKS, GameOption.DANCE_ONLY_CIRCLE_STACKS,
GameOption.DANCE_MIRROR,
GameOption.DANCE_DRAW_APPROACH,
}), }),
PIPPI ("Pippi", new GameOption[] { PIPPI ("Pippi", new GameOption[] {
GameOption.PIPPI_ENABLE, GameOption.PIPPI_ENABLE,

View File

@ -50,6 +50,9 @@ public class Dancer {
public static Dancer instance = new Dancer(); public static Dancer instance = new Dancer();
public static boolean mirror; // this should really get its own place somewhere...
public static boolean drawApproach; // this should really get its own place somewhere...
private int dir; private int dir;
private GameObject p; private GameObject p;
private Random rand; private Random rand;