diff --git a/src/itdelatrisu/opsu/Options.java b/src/itdelatrisu/opsu/Options.java index 86d9a0c6..65c08178 100644 --- a/src/itdelatrisu/opsu/Options.java +++ b/src/itdelatrisu/opsu/Options.java @@ -56,9 +56,11 @@ import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.Win32Exception; import com.sun.jna.platform.win32.WinReg; import yugecin.opsudance.*; +import yugecin.opsudance.movers.CubicBezierMover; import yugecin.opsudance.movers.QuadraticBezierMover; import yugecin.opsudance.movers.factories.AutoMoverFactory; import yugecin.opsudance.movers.factories.QuadraticBezierMoverFactory; +import yugecin.opsudance.movers.slidermovers.DefaultSliderMoverController; import yugecin.opsudance.spinners.Spinner; import yugecin.opsudance.ui.SBOverlay; @@ -649,6 +651,75 @@ public class Options { } }, + DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR ("Slider exit aggressiveness factor", "CubBezSliderExitAgr", "AKA initial D factor for sliderexits", 40, 0, 100) { + @Override + public String getValueString() { + return val / 10 + ""; + } + + @Override + public void drag(GameContainer container, int d) { + super.drag(container, d); + QuadraticBezierMover.sliderExitAggressivenessfactor = val / 10; + } + + @Override + public boolean showCondition() { + return DANCE_QUAD_BEZ_AGGRESSIVENESS.showCondition() + && Dancer.sliderMoverController instanceof DefaultSliderMoverController; + } + + @Override + public void read(String s) { + super.read(s); + QuadraticBezierMover.sliderExitAggressivenessfactor = val / 10; + } + }, + + DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS ("Use cubic bezier before sliders", "QuadBezCubicSliders", "Slider entry looks better using this", true) { + @Override + public void click(GameContainer container) { + super.click(container); + QuadraticBezierMoverFactory.cubicForSliderEntries = bool; + } + + @Override + public boolean showCondition() { + return DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR.showCondition(); + } + + @Override + public void read(String s) { + super.read(s); + QuadraticBezierMoverFactory.cubicForSliderEntries = bool; + } + }, + + DANCE_QUAD_BEZ_CUBIC_AGGRESSIVENESS_FACTOR ("Slider entry aggressiveness factor", "CubBezSliderEntryAgr", "AKA initial D factor for sliderentries", 40, 0, 100) { + @Override + public String getValueString() { + return val / 10 + ""; + } + + @Override + public void drag(GameContainer container, int d) { + super.drag(container, d); + CubicBezierMover.aggressivenessfactor = val / 10; + } + + @Override + public boolean showCondition() { + return DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS.showCondition() + && DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS.getBooleanValue(); + } + + @Override + public void read(String s) { + super.read(s); + CubicBezierMover.aggressivenessfactor = val / 10; + } + }, + DANCE_MOVER_DIRECTION ("Mover direction", "MoverDirection", "The direction the mover goes" ) { @Override public String getValueString() { diff --git a/src/itdelatrisu/opsu/states/OptionsMenu.java b/src/itdelatrisu/opsu/states/OptionsMenu.java index c26265ec..a41cb1a5 100644 --- a/src/itdelatrisu/opsu/states/OptionsMenu.java +++ b/src/itdelatrisu/opsu/states/OptionsMenu.java @@ -114,6 +114,9 @@ public class OptionsMenu extends BasicGameState { DANCE ("Dance", new GameOption[] { GameOption.DANCE_MOVER, GameOption.DANCE_QUAD_BEZ_AGGRESSIVENESS, + GameOption.DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR, + GameOption.DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS, + GameOption.DANCE_QUAD_BEZ_CUBIC_AGGRESSIVENESS_FACTOR, GameOption.DANCE_MOVER_DIRECTION, GameOption.DANCE_SLIDER_MOVER_TYPE, GameOption.DANCE_SPINNER, @@ -606,14 +609,14 @@ public class OptionsMenu extends BasicGameState { if (index >= currentTab.options.length) return null; - int i = index; - while (i >= 0) { - if (!currentTab.options[i--].showCondition()) { - if (++index >= currentTab.options.length) { - return null; - } + for (GameOption option : currentTab.options) { + if (option.showCondition()) { + index--; + } + if (index < 0) { + return option; } } - return currentTab.options[index]; + return null; } } diff --git a/src/yugecin/opsudance/Dancer.java b/src/yugecin/opsudance/Dancer.java index b8b63d94..25be5acf 100644 --- a/src/yugecin/opsudance/Dancer.java +++ b/src/yugecin/opsudance/Dancer.java @@ -40,6 +40,8 @@ import yugecin.opsudance.movers.slidermovers.InheritedSliderMoverController; import yugecin.opsudance.movers.slidermovers.SliderMoverController; import yugecin.opsudance.spinners.*; +import java.awt.*; + public class Dancer { public static MoverFactory[] moverFactories = new MoverFactory[] { @@ -219,6 +221,16 @@ public class Dancer { c.start = new Vec2f((float) spinnerStartPoint[0], (float) spinnerStartPoint[1]); } + // specific mover stuff + if (p.isSlider() && sliderMoverController instanceof DefaultSliderMoverController) { + Vec2f st = p.getPointAt(p.getEndTime() - 10); + Vec2f en = p.getPointAt(p.getEndTime()); + //double atan = Math.atan2(en.y - st.y, en.x - st.x); + double distance = Utils.distance(st.x, st.y, en.x, en.y); + QuadraticBezierMover.p = new Point((int) st.x, (int) st.y); + QuadraticBezierMover.setPrevspeed(distance, 10); + } + createNewMover(); } diff --git a/src/yugecin/opsudance/movers/CubicBezierMover.java b/src/yugecin/opsudance/movers/CubicBezierMover.java new file mode 100644 index 00000000..3b73764e --- /dev/null +++ b/src/yugecin/opsudance/movers/CubicBezierMover.java @@ -0,0 +1,73 @@ +/* + * 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 . + */ +package yugecin.opsudance.movers; + +import itdelatrisu.opsu.Utils; +import itdelatrisu.opsu.objects.GameObject; +import itdelatrisu.opsu.objects.Slider; +import itdelatrisu.opsu.objects.curves.Vec2f; + +import java.awt.*; + +public class CubicBezierMover extends Mover { + + public static int aggressivenessfactor = 4; + + private static Point p2 = new Point(0, 0); + private static Point p1 = new Point(0, 0); + + private int startTime; + private int totalTime; + + public CubicBezierMover(GameObject start, GameObject end, int dir) { + super(start, end, dir); + + if (end instanceof Slider) { + Slider s = (Slider) end; + double ang = s.getCurve().getStartAngle() * Math.PI / 180d + Math.PI; + Vec2f nextpos = s.getPointAt(s.getTime() + 10); + double dist = Utils.distance(end.start.x, end.start.y, nextpos.x, nextpos.y); + double speed = dist * QuadraticBezierMover.aggressiveness * aggressivenessfactor / 10; + p2.x = (int) (end.start.x + Math.cos(ang) * speed); + p2.y = (int) (end.start.y + Math.sin(ang) * speed); + } + + this.startTime = start.getEndTime(); + this.totalTime = end.getTime() - startTime; + + double startAngle = Math.atan2(startY - QuadraticBezierMover.p.y, startX - QuadraticBezierMover.p.x); + p1.x = (int) (startX + Math.cos(startAngle) * QuadraticBezierMover.getPrevspeed()); + p1.y = (int) (startY + Math.sin(startAngle) * QuadraticBezierMover.getPrevspeed()); + } + + @Override + public double[] getPointAt(int time) { + double t = (double) (time - startTime) / totalTime; + double ct = (1 - t); + return new double[] { + ct * ct * ct * startX + 3 * ct * ct * t * p1.x + 3 * ct * t * t * p2.x + t * t * t * endX, + ct * ct * ct * startY + 3 * ct * ct * t * p1.y + 3 * ct * t * t * p2.y + t * t * t * endY, + }; + } + + @Override + public String getName() { + return "Quadratic Bezier"; + } + +} diff --git a/src/yugecin/opsudance/movers/QuadraticBezierMover.java b/src/yugecin/opsudance/movers/QuadraticBezierMover.java index bedfd953..0df78422 100644 --- a/src/yugecin/opsudance/movers/QuadraticBezierMover.java +++ b/src/yugecin/opsudance/movers/QuadraticBezierMover.java @@ -24,8 +24,9 @@ import java.awt.*; public class QuadraticBezierMover extends Mover { + public static int sliderExitAggressivenessfactor = 4; public static int aggressiveness = 50; - private static Point p; + public static Point p; private static double prevspeed; public static void reset() { @@ -33,6 +34,14 @@ public class QuadraticBezierMover extends Mover { prevspeed = 0; } + public static void setPrevspeed(double distance, int timedelta) { + prevspeed = distance * aggressiveness * sliderExitAggressivenessfactor / timedelta; + } + + public static double getPrevspeed() { + return prevspeed; + } + private int startTime; private int totalTime; @@ -42,13 +51,7 @@ public class QuadraticBezierMover extends Mover { this.totalTime = end.getTime() - startTime; double startAngle = Math.atan2(startY - p.y, startX - p.x); - double angDiff = Math.atan2(startY - endY, startX - endX) - startAngle; - while (angDiff < 0) angDiff += Math.PI; - while (angDiff > Math.PI) angDiff -= Math.PI; - angDiff -= Math.PI / 2; - if (angDiff < 0) angDiff = -angDiff; double dist = Utils.distance(startX, startY, endX, endY); - //double speed = dist / 10 + dist * (Math.PI - angDiff) / Math.PI; p.x = (int) (startX + Math.cos(startAngle) * prevspeed); p.y = (int) (startY + Math.sin(startAngle) * prevspeed); prevspeed = (dist / totalTime) * aggressiveness; diff --git a/src/yugecin/opsudance/movers/factories/QuadraticBezierMoverFactory.java b/src/yugecin/opsudance/movers/factories/QuadraticBezierMoverFactory.java index d37c2710..2b3ac083 100644 --- a/src/yugecin/opsudance/movers/factories/QuadraticBezierMoverFactory.java +++ b/src/yugecin/opsudance/movers/factories/QuadraticBezierMoverFactory.java @@ -18,13 +18,19 @@ package yugecin.opsudance.movers.factories; import itdelatrisu.opsu.objects.GameObject; +import yugecin.opsudance.movers.CubicBezierMover; import yugecin.opsudance.movers.Mover; import yugecin.opsudance.movers.QuadraticBezierMover; public class QuadraticBezierMoverFactory implements MoverFactory { + public static boolean cubicForSliderEntries = true; + @Override public Mover create(GameObject start, GameObject end, int dir) { + if (cubicForSliderEntries && end.isSlider()) { + return new CubicBezierMover(start, end, dir); + } return new QuadraticBezierMover(start, end, dir); } diff --git a/src/yugecin/opsudance/ui/OptionsOverlay.java b/src/yugecin/opsudance/ui/OptionsOverlay.java index d9cd3d91..e366da4d 100644 --- a/src/yugecin/opsudance/ui/OptionsOverlay.java +++ b/src/yugecin/opsudance/ui/OptionsOverlay.java @@ -37,6 +37,9 @@ public class OptionsOverlay { private static Options.GameOption[] options = new Options.GameOption[] { Options.GameOption.DANCE_MOVER, Options.GameOption.DANCE_QUAD_BEZ_AGGRESSIVENESS, + Options.GameOption.DANCE_QUAD_BEZ_SLIDER_AGGRESSIVENESS_FACTOR, + Options.GameOption.DANCE_QUAD_BEZ_USE_CUBIC_ON_SLIDERS, + Options.GameOption.DANCE_QUAD_BEZ_CUBIC_AGGRESSIVENESS_FACTOR, Options.GameOption.DANCE_MOVER_DIRECTION, Options.GameOption.DANCE_SLIDER_MOVER_TYPE, Options.GameOption.DANCE_SPINNER, @@ -127,15 +130,15 @@ public class OptionsOverlay { if (index >= options.length) { return -1; } - int i = index; - while (i >= 0) { - if (!options[i--].showCondition()) { - if (++index >= options.length) { - return -1; - } + for (int i = 0; i < options.length; i++) { + if (options[i].showCondition()) { + index--; + } + if (index < 0) { + return i; } } - return index; + return -1; } public void update(int mouseX, int mouseY) {