basic implementation of sbv2

This commit is contained in:
yugecin 2016-12-25 12:16:32 +01:00
parent fc32040b2f
commit 1803d714a5
7 changed files with 375 additions and 2 deletions

View File

@ -72,6 +72,7 @@ import org.newdawn.slick.state.transition.EmptyTransition;
import org.newdawn.slick.state.transition.FadeInTransition; import org.newdawn.slick.state.transition.FadeInTransition;
import yugecin.opsudance.*; import yugecin.opsudance.*;
import yugecin.opsudance.objects.curves.FakeCombinedCurve; import yugecin.opsudance.objects.curves.FakeCombinedCurve;
import yugecin.opsudance.sbv2.MoveStoryboard;
import yugecin.opsudance.ui.SBOverlay; import yugecin.opsudance.ui.SBOverlay;
/** /**
@ -313,6 +314,7 @@ public class Game extends BasicGameState {
private final int state; private final int state;
private final Cursor mirrorCursor; private final Cursor mirrorCursor;
private MoveStoryboard msb;
private SBOverlay sbOverlay; private SBOverlay sbOverlay;
private FakeCombinedCurve knorkesliders; private FakeCombinedCurve knorkesliders;
@ -363,7 +365,8 @@ public class Game extends BasicGameState {
@Override @Override
public void init(GameContainer container, StateBasedGame game) public void init(GameContainer container, StateBasedGame game)
throws SlickException { throws SlickException {
this.sbOverlay = new SBOverlay(this, container); this.msb = new MoveStoryboard(container);
this.sbOverlay = new SBOverlay(this, msb, container);
this.container = container; this.container = container;
this.game = game; this.game = game;
input = container.getInput(); input = container.getInput();
@ -470,6 +473,12 @@ public class Game extends BasicGameState {
} }
} }
float[] sbPosition = sbOverlay.getPoint(trackPosition);
if (sbPosition != null) {
autoPoint.x = sbPosition[0];
autoPoint.y = sbPosition[1];
}
// set mouse coordinates // set mouse coordinates
autoMousePosition.set(autoPoint.x, autoPoint.y); autoMousePosition.set(autoPoint.x, autoPoint.y);
} }

View File

@ -0,0 +1,33 @@
/*
* opsu!dance - fork of opsu! with cursordance auto
* Copyright (C) 2016 yugecin
*
* opsu!dance is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* opsu!dance is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
*/
package yugecin.opsudance.sbv2;
import org.newdawn.slick.Graphics;
import yugecin.opsudance.sbv2.movers.StoryboardMover;
public interface StoryboardMove {
void add(StoryboardMover mover);
float[] getPointAt(float t);
void update(int delta, int x, int y);
void mousePressed(int x, int y);
void mouseReleased(int x, int y);
void recalculateTimes();
void render(Graphics g);
}

View File

@ -0,0 +1,146 @@
/*
* opsu!dance - fork of opsu! with cursordance auto
* Copyright (C) 2016 yugecin
*
* opsu!dance is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* opsu!dance is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
*/
package yugecin.opsudance.sbv2;
import itdelatrisu.opsu.objects.curves.Vec2f;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import yugecin.opsudance.sbv2.movers.StoryboardMover;
import java.util.ArrayList;
import java.util.List;
public class StoryboardMoveImpl implements StoryboardMove {
private static final int POINTSIZE = 3;
private Vec2f start;
private Vec2f end;
private List<StoryboardMover> movers;
private List<Vec2f> midPoints;
private StoryboardMover nextMover;
private Vec2f currentPoint;
private StoryboardMover prevMover;
private float totalLength;
public StoryboardMoveImpl(Vec2f start, Vec2f end) {
this.start = start;
this.end = end;
movers = new ArrayList<>();
midPoints = new ArrayList<>();
}
@Override
public void add(StoryboardMover mover) {
mover.end = end;
if (movers.size() == 0) {
mover.start = start;
} else {
StoryboardMover lastMover = movers.get(movers.size() - 1);
Vec2f mid = new Vec2f(
(lastMover.start.x + lastMover.end.x) / 2f,
(lastMover.start.y + lastMover.end.y) / 2f
);
midPoints.add(mid);
lastMover.end = mid;
totalLength -= lastMover.getLength();
lastMover.recalculateLength();
totalLength += lastMover.getLength();
mover.start = mid;
}
movers.add(mover);
recalculateTimes();
}
@Override
public float[] getPointAt(float t) {
if (movers.size() == 0) {
return new float[] { end.x, end.y };
}
float cumulativeTime = 0f;
for (StoryboardMover mover : movers) {
cumulativeTime += mover.timeLengthPercentOfTotalTime;
if (cumulativeTime > t) {
return mover.getPointAt((t - (cumulativeTime - mover.timeLengthPercentOfTotalTime)) / mover.timeLengthPercentOfTotalTime);
}
}
return new float[] { end.x, end.y };
}
@Override
public void update(int delta, int x, int y) {
if (currentPoint != null) {
moveCurrentPoint(x, y);
}
}
@Override
public void mousePressed(int x, int y) {
int i = 0;
for (Vec2f point : midPoints) {
if (point.x - POINTSIZE <= x && x <= point.x + POINTSIZE && point.y - POINTSIZE <= y && y <= point.y + POINTSIZE) {
currentPoint = point;
prevMover = movers.get(i);
nextMover = movers.get(i + 1);
break;
}
i++;
}
}
@Override
public void mouseReleased(int x, int y) {
if (currentPoint != null) {
moveCurrentPoint(x, y);
totalLength -= prevMover.getLength() + nextMover.getLength();
prevMover.recalculateLength();
nextMover.recalculateLength();
totalLength += prevMover.getLength() + nextMover.getLength();
currentPoint = null;
recalculateTimes();
}
}
@Override
public void recalculateTimes() {
for (StoryboardMover mover : movers) {
mover.timeLengthPercentOfTotalTime = mover.getLength() / totalLength;
}
}
private void moveCurrentPoint(int x, int y) {
currentPoint.x = x;
currentPoint.y = y;
prevMover.end = currentPoint;
nextMover.start = currentPoint;
}
@Override
public void render(Graphics g) {
for (StoryboardMover mover : movers) {
mover.render(g);
}
g.setColor(Color.cyan);
for (Vec2f point : midPoints) {
g.fillRect(point.x - POINTSIZE, point.y - POINTSIZE, POINTSIZE * 2 + 1, POINTSIZE * 2 + 1);
}
}
}

View File

@ -0,0 +1,47 @@
/*
* opsu!dance - fork of opsu! with cursordance auto
* Copyright (C) 2016 yugecin
*
* opsu!dance is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* opsu!dance is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
*/
package yugecin.opsudance.sbv2.movers;
import itdelatrisu.opsu.Utils;
import org.newdawn.slick.Color;
public class LinearStoryboardMover extends StoryboardMover {
public LinearStoryboardMover() {
super(Color.red);
}
@Override
public float[] getPointAt(float t) {
return new float[] {
Utils.lerp(start.x, end.x, t),
Utils.lerp(start.y, end.y, t),
};
}
@Override
public float getLength() {
return length;
}
@Override
public void recalculateLength() {
length = Utils.distance(start.x, start.y, end.x, end.y);
}
}

View File

@ -0,0 +1,53 @@
/*
* opsu!dance - fork of opsu! with cursordance auto
* Copyright (C) 2016 yugecin
*
* opsu!dance is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* opsu!dance is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
*/
package yugecin.opsudance.sbv2.movers;
import itdelatrisu.opsu.objects.curves.Vec2f;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
public abstract class StoryboardMover {
public static final float CALC_DRAW_INTERVAL = 0.05f;
protected float length;
public Vec2f start;
public Vec2f end;
private Color renderColor;
public float timeLengthPercentOfTotalTime;
public StoryboardMover(Color renderColor) {
this.renderColor = renderColor;
}
public abstract float[] getPointAt(float t);
public abstract void recalculateLength();
public float getLength() {
return length;
}
public void render(Graphics g) {
g.setColor(renderColor);
for (float t = 0; t <= 1f; t += StoryboardMover.CALC_DRAW_INTERVAL) {
float[] p = getPointAt(t);
g.fillRect(p[0] - 1, p[1] - 1, 3, 3);
}
}
}

View File

@ -28,6 +28,7 @@ import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input; import org.newdawn.slick.Input;
import yugecin.opsudance.ObjectColorOverrides; import yugecin.opsudance.ObjectColorOverrides;
import yugecin.opsudance.sbv2.MoveStoryboard;
import yugecin.opsudance.ui.OptionsOverlay.OptionTab; import yugecin.opsudance.ui.OptionsOverlay.OptionTab;
import java.util.*; import java.util.*;
@ -109,6 +110,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
private int index; private int index;
private final Game game; private final Game game;
private final MoveStoryboard msb;
private final OptionsOverlay overlay; private final OptionsOverlay overlay;
static { static {
@ -117,8 +119,9 @@ public class SBOverlay implements OptionsOverlay.Parent {
} }
} }
public SBOverlay(Game game, GameContainer container) { public SBOverlay(Game game, MoveStoryboard msb, GameContainer container) {
this.game = game; this.game = game;
this.msb = msb;
initialOptions = new HashMap<>(); initialOptions = new HashMap<>();
overlay = new OptionsOverlay(this, options, 2, container); overlay = new OptionsOverlay(this, options, 2, container);
this.width = container.getWidth(); this.width = container.getWidth();
@ -131,6 +134,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
if (!Options.isEnableSB() || hide) { if (!Options.isEnableSB() || hide) {
return; return;
} }
msb.render(g);
int lh = Fonts.SMALL.getLineHeight(); int lh = Fonts.SMALL.getLineHeight();
Fonts.SMALL.drawString(10, height - 50 + lh, "save position: ctrl+s, load position: ctrl+l", Color.cyan); Fonts.SMALL.drawString(10, height - 50 + lh, "save position: ctrl+s, load position: ctrl+l", Color.cyan);
Fonts.SMALL.drawString(10, height - 50, "speed: C " + (speed / 10f) + " V", Color.cyan); Fonts.SMALL.drawString(10, height - 50, "speed: C " + (speed / 10f) + " V", Color.cyan);
@ -163,6 +167,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
if (Options.isEnableSB() && menu) { if (Options.isEnableSB() && menu) {
overlay.update(delta, mouseX, mouseY); overlay.update(delta, mouseX, mouseY);
} }
msb.update(delta, mouseX, mouseY);
} }
public boolean keyPressed(int key, char c) { public boolean keyPressed(int key, char c) {
@ -234,6 +239,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
public void setGameObjects(GameObject[] gameObjects) { public void setGameObjects(GameObject[] gameObjects) {
if (this.gameObjects.length != gameObjects.length) { if (this.gameObjects.length != gameObjects.length) {
optionsMap = new HashMap[gameObjects.length]; optionsMap = new HashMap[gameObjects.length];
msb.setGameObjects(gameObjects);
} }
if (optionsMap.length > 0) { if (optionsMap.length > 0) {
// copy all current settings in first obj map // copy all current settings in first obj map
@ -246,6 +252,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
} }
public boolean mousePressed(int button, int x, int y) { public boolean mousePressed(int button, int x, int y) {
msb.mousePressed(x, y);
if (!menu) { if (!menu) {
return false; return false;
} }
@ -270,6 +277,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
if (index >= optionsMap.length) { if (index >= optionsMap.length) {
return; return;
} }
msb.setIndex(index);
for (; this.index <= index; this.index++) { for (; this.index <= index; this.index++) {
HashMap options = optionsMap[this.index]; HashMap options = optionsMap[this.index];
if (options == null) { if (options == null) {
@ -289,6 +297,7 @@ public class SBOverlay implements OptionsOverlay.Parent {
overlay.mouseReleased(button, x, y); overlay.mouseReleased(button, x, y);
return true; return true;
} }
msb.mouseReleased(x, y);
if (x > 10 || index >= optionsMap.length || optionsMap[index] == null) { if (x > 10 || index >= optionsMap.length || optionsMap[index] == null) {
return false; return false;
} }
@ -348,6 +357,10 @@ public class SBOverlay implements OptionsOverlay.Parent {
} }
} }
public float[] getPoint(int trackPosition) {
return msb.getPoint(trackPosition);
}
@Override @Override
public void onLeave() { public void onLeave() {
menu = false; menu = false;

View File

@ -0,0 +1,72 @@
/*
* opsu!dance - fork of opsu! with cursordance auto
* Copyright (C) 2016 yugecin
*
* opsu!dance is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* opsu!dance is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with opsu!dance. If not, see <http://www.gnu.org/licenses/>.
*/
package yugecin.opsudance.ui;
import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.Graphics;
import java.awt.Rectangle;
public class SimpleButton {
private final Color bg;
private final Color fg;
private final Color border;
private final Color hoverBorder;
private final Font font;
private String text;
private int textY;
private Rectangle hitbox;
private boolean isHovered;
public SimpleButton(int x, int y, int width, int height, Font font, String text, Color bg, Color fg, Color border, Color hoverBorder) {
this.bg = bg;
this.fg = fg;
this.border = border;
this.hoverBorder = hoverBorder;
this.hitbox = new Rectangle(x, y, width, height);
this.font = font;
this.text = text;
this.textY = y + (height - font.getLineHeight()) / 2;
}
public void render(Graphics g) {
g.setLineWidth(2f);
g.setColor(bg);
g.fillRect(hitbox.x, hitbox.y, hitbox.width, hitbox.height);
g.setColor(fg);
font.drawString(hitbox.x + 20, textY, text);
if (isHovered) {
g.setColor(hoverBorder);
} else {
g.setColor(border);
}
g.drawRect(hitbox.x, hitbox.y, hitbox.width, hitbox.height);
}
public void update(int x, int y) {
isHovered = hitbox.contains(x, y);
}
public boolean isHovered() {
return isHovered;
}
}