diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index 3e735760..11aac0a3 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -913,7 +913,9 @@ public class GameData { float oldColorAlpha = hitResult.color.a; Colors.WHITE_FADE.a = alpha; hitResult.color.a = alpha; - //hitResult.curve.draw(hitResult.color); + if (!Options.isShrinkingSliders()) { + hitResult.curve.draw(hitResult.color); + } Colors.WHITE_FADE.a = oldWhiteAlpha; hitResult.color.a = oldColorAlpha; } diff --git a/src/itdelatrisu/opsu/Options.java b/src/itdelatrisu/opsu/Options.java index 37f6efb9..cfc6a366 100644 --- a/src/itdelatrisu/opsu/Options.java +++ b/src/itdelatrisu/opsu/Options.java @@ -502,7 +502,14 @@ public class Options { FORCE_DEFAULT_PLAYFIELD ("Force Default Playfield", "ForceDefaultPlayfield", "Override the song background with the default playfield background.", false), IGNORE_BEATMAP_SKINS ("Ignore All Beatmap Skins", "IgnoreBeatmapSkins", "Never use skin element overrides provided by beatmaps.", false), SNAKING_SLIDERS ("Snaking sliders", "SnakingSliders", "Sliders gradually snake out from their starting point.", true), + SHRINKING_SLIDERS ("Shrinking sliders", "ShrinkingSliders", "Sliders shrinks when sliderball passes - unstable!", false), FALLBACK_SLIDERS ("Fallback sliders", "FallbackSliders", "Enable this if sliders won't render", false), + MERGING_SLIDERS ("Merging sliders", "MergingSliders", "Merge sliders (aka knorkesliders) - unstable!", false) { + @Override + public boolean showCondition() { + return !FALLBACK_SLIDERS.bool; + } + }, SHOW_HIT_LIGHTING ("Show Hit Lighting", "HitLighting", "Adds an effect behind hit explosions.", true), SHOW_COMBO_BURSTS ("Show Combo Bursts", "ComboBurst", "A character image is displayed at combo milestones.", true), SHOW_PERFECT_HIT ("Show Perfect Hits", "PerfectHit", "Whether to show perfect hit result bursts (300s, slider ticks).", true), @@ -1775,6 +1782,9 @@ public class Options { public static boolean isFallbackSliders() { return GameOption.FALLBACK_SLIDERS.getBooleanValue(); } + public static boolean isShrinkingSliders() { return GameOption.SHRINKING_SLIDERS.getBooleanValue(); } + public static boolean isMergingSliders() { return !isFallbackSliders() && GameOption.MERGING_SLIDERS.getBooleanValue(); } + /** * Returns the fixed circle size override, if any. * @return the CS value (0, 10], 0f if disabled diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 0157b4dc..c2064bbb 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -195,6 +195,9 @@ public class Slider extends GameObject { @Override public void draw(Graphics g, int trackPosition, boolean mirror) { + if (trackPosition > getEndTime()) { + return; + } Color orig = color; if (mirror) { color = mirrorColor; @@ -219,15 +222,9 @@ public class Slider extends GameObject { if (GameMod.HIDDEN.isActive() && trackPosition > getTime()) { curveAlpha = Math.max(0f, 1f - ((float) (trackPosition - getTime()) / (getEndTime() - getTime())) * 1.05f); } - curveColor.a = curveAlpha; - float curveInterval = Options.isSliderSnaking() ? alpha : 1f; - //curve.draw(curveColor, curveInterval); - float sliderprogress = (float) (trackPosition - getTime()) / sliderTimeTotal; - if (sliderprogress > 0) { - game.setSlidercurveFrom(baseSliderFrom + (int) (sliderprogress * curve.getCurvePoints().length)); - } - game.setSlidercurveTo(baseSliderFrom + (int) (curveInterval * curve.getCurvePoints().length)); + curveColor.a = curveAlpha; + boolean isCurveCompletelyDrawn = drawSliderTrack(trackPosition, alpha); color.a = alpha; g.pushTransform(); @@ -292,7 +289,7 @@ public class Slider extends GameObject { g.popTransform(); // repeats - if (curveInterval == 1.0f) { + if (isCurveCompletelyDrawn) { for (int tcurRepeat = currentRepeats; tcurRepeat <= currentRepeats + 1; tcurRepeat++) { if (hitObject.getRepeatCount() - 1 > tcurRepeat) { Image arrow = GameImage.REVERSEARROW.getImage(); @@ -376,6 +373,26 @@ public class Slider extends GameObject { color = orig; } + private boolean drawSliderTrack(int trackPosition, float snakingSliderProgress) { + float curveIntervalTo = Options.isSliderSnaking() ? snakingSliderProgress : 1f; + float curveIntervalFrom = 0f; + if (Options.isShrinkingSliders()) { + float sliderprogress = (float) (trackPosition - getTime()) / sliderTimeTotal; + if (sliderprogress > 0) { + curveIntervalFrom = sliderprogress; + } + } + if (Options.isMergingSliders()) { + if (Options.isShrinkingSliders() && curveIntervalFrom > 0) { + game.setSlidercurveFrom(baseSliderFrom + (int) (curveIntervalFrom * curve.getCurvePoints().length)); + } + game.setSlidercurveTo(baseSliderFrom + (int) (curveIntervalTo * curve.getCurvePoints().length)); + } else { + curve.draw(curveColor, curveIntervalFrom, curveIntervalTo); + } + return curveIntervalTo == 1f; + } + /** * Calculates the slider hit result. * @return the hit result (GameData.HIT_* constants) @@ -557,7 +574,9 @@ public class Slider extends GameObject { // calculate and send slider result hitResult(); - game.setSlidercurveFrom(baseSliderFrom + curve.getCurvePoints().length); + if (Options.isMergingSliders()) { + game.setSlidercurveFrom(baseSliderFrom + curve.getCurvePoints().length); + } return true; } diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index 2a211beb..8509b637 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -126,7 +126,8 @@ public abstract class Curve { /** * Draws the curve in the range [0, t] (where the full range is [0, 1]) to the graphics context. * @param color the color filter - * @param t set the curve interval to [0, t] + * @param t1 interval to draw from + * @param t2 interval to draw to */ public void draw(Color color, float t1, float t2) { if (curve == null) @@ -145,7 +146,7 @@ public abstract class Curve { hitCircleOverlay.drawCentered(curve[i].x, curve[i].y, Colors.WHITE_FADE); float a = fallbackSliderColor.a; fallbackSliderColor.a = color.a; - for (int i = 0; i < drawUpTo; i++) + for (int i = drawFrom; i < drawUpTo; i++) hitCircle.drawCentered(curve[i].x, curve[i].y, fallbackSliderColor); fallbackSliderColor.a = a; } @@ -154,7 +155,7 @@ public abstract class Curve { else { if (renderState == null) renderState = new CurveRenderState(hitObject, curve); - renderState.draw(color, borderColor, t1, t2); + renderState.draw(color, borderColor, t1, t2); // TODO } } diff --git a/src/itdelatrisu/opsu/render/CurveRenderState.java b/src/itdelatrisu/opsu/render/CurveRenderState.java index c4275a4a..d44665f1 100644 --- a/src/itdelatrisu/opsu/render/CurveRenderState.java +++ b/src/itdelatrisu/opsu/render/CurveRenderState.java @@ -143,6 +143,8 @@ public class CurveRenderState { GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); } if (firstPointDrawn != drawFrom) { + GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); firstPointDrawn = drawFrom; this.renderCurve(color, borderColor, drawFrom, drawUpTo, true); } else { diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index d18ca304..7c177319 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -1455,15 +1455,17 @@ public class Game extends BasicGameState { this.leadInTime += epiImgTime; SoundController.mute(false); - // let's create knorkesliders - List curvepoints = new ArrayList<>(); - for (GameObject gameObject : gameObjects) { - if (gameObject.isSlider()) { - ((Slider) gameObject).baseSliderFrom = curvepoints.size(); - curvepoints.addAll(Arrays.asList(((Slider) gameObject).getCurve().getCurvePoints())); + if (Options.isMergingSliders()) { + // let's create knorkesliders + List curvepoints = new ArrayList<>(); + for (GameObject gameObject : gameObjects) { + if (gameObject.isSlider()) { + ((Slider) gameObject).baseSliderFrom = curvepoints.size(); + curvepoints.addAll(Arrays.asList(((Slider) gameObject).getCurve().getCurvePoints())); + } } + knorkesliders = new FakeCombinedCurve(curvepoints.toArray(new Vec2f[curvepoints.size()])); } - knorkesliders = new FakeCombinedCurve(curvepoints.toArray(new Vec2f[curvepoints.size()])); } slidercurveFrom = 0; @@ -1527,7 +1529,9 @@ public class Game extends BasicGameState { * @param trackPosition the track position */ private void drawHitObjects(Graphics g, int trackPosition) { - knorkesliders.draw(Color.white, this.slidercurveFrom, this.slidercurveTo); + if (Options.isMergingSliders()) { + knorkesliders.draw(Color.white, this.slidercurveFrom, this.slidercurveTo); + } // include previous object in follow points int lastObjectIndex = -1; if (objectIndex > 0 && objectIndex < beatmap.objects.length && diff --git a/src/itdelatrisu/opsu/states/OptionsMenu.java b/src/itdelatrisu/opsu/states/OptionsMenu.java index a41cb1a5..6f0cb44b 100644 --- a/src/itdelatrisu/opsu/states/OptionsMenu.java +++ b/src/itdelatrisu/opsu/states/OptionsMenu.java @@ -82,7 +82,9 @@ public class OptionsMenu extends BasicGameState { GameOption.FORCE_DEFAULT_PLAYFIELD, GameOption.IGNORE_BEATMAP_SKINS, GameOption.SNAKING_SLIDERS, + GameOption.SHRINKING_SLIDERS, GameOption.FALLBACK_SLIDERS, + GameOption.MERGING_SLIDERS, GameOption.SHOW_HIT_LIGHTING, GameOption.SHOW_COMBO_BURSTS, GameOption.SHOW_PERFECT_HIT,