Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/itdelatrisu/opsu/GameData.java
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ else if (Options.isHitLightingEnabled() && !hitResult.hideResult && hitResult.re
float oldColorAlpha = hitResult.color.a;
Colors.WHITE_FADE.a = alpha;
hitResult.color.a = alpha;
hitResult.curve.draw(hitResult.color);
hitResult.curve.draw(hitResult.color,1.0f);
Colors.WHITE_FADE.a = oldWhiteAlpha;
hitResult.color.a = oldColorAlpha;
}
Expand Down
7 changes: 7 additions & 0 deletions src/itdelatrisu/opsu/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ public void drag(GameContainer container, int d) {
BACKGROUND_DIM ("Background Dim", "DimLevel", "Percentage to dim the background image during gameplay.", 50, 0, 100),
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),
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),
Expand Down Expand Up @@ -941,6 +942,12 @@ public static void setDisplayMode(Container app) {
*/
public static boolean isBeatmapSkinIgnored() { return GameOption.IGNORE_BEATMAP_SKINS.getBooleanValue(); }

/**
* Returns whether or not sliders should snake in or just appear fully at once.
* @return true if sliders should snake in
*/
public static boolean isSliderSnaking() { return GameOption.SNAKING_SLIDERS.getBooleanValue(); }

/**
* Returns the fixed circle size override, if any.
* @return the CS value (0, 10], 0f if disabled
Expand Down
67 changes: 43 additions & 24 deletions src/itdelatrisu/opsu/objects/Slider.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import itdelatrisu.opsu.objects.curves.Vec2f;
import itdelatrisu.opsu.states.Game;
import itdelatrisu.opsu.ui.Colors;
import itdelatrisu.opsu.ui.animations.AnimationEquation;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
Expand Down Expand Up @@ -179,20 +180,27 @@ public void draw(Graphics g, int trackPosition) {
float approachScale = 1 + scale * 3;
float fadeinScale = (timeDiff - approachTime + fadeInTime) / (float) fadeInTime;
float alpha = Utils.clamp(1 - fadeinScale, 0, 1);
float decorationsAlpha = Utils.clamp(-2.0f * fadeinScale, 0, 1);
boolean overlayAboveNumber = Options.getSkin().isHitCircleOverlayAboveNumber();

float oldAlpha = Colors.WHITE_FADE.a;
Colors.WHITE_FADE.a = color.a = alpha;
Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage();
Image hitCircle = GameImage.HITCIRCLE.getImage();
Vec2f endPos = curve.pointAt(1);

curve.draw(color);
float curveInterval;
if(Options.isSliderSnaking()){
curveInterval = alpha;
} else {
curveInterval = 1.0f;
}
curve.draw(color,curveInterval);
color.a = alpha;

// end circle
hitCircle.drawCentered(endPos.x, endPos.y, color);
hitCircleOverlay.drawCentered(endPos.x, endPos.y, Colors.WHITE_FADE);
Vec2f endCircPos = curve.pointAt(curveInterval);
hitCircle.drawCentered(endCircPos.x, endCircPos.y, color);
hitCircleOverlay.drawCentered(endCircPos.x, endCircPos.y, Colors.WHITE_FADE);

// start circle
hitCircle.drawCentered(x, y, color);
Expand All @@ -201,10 +209,13 @@ public void draw(Graphics g, int trackPosition) {

// ticks
if (ticksT != null) {
Image tick = GameImage.SLIDER_TICK.getImage();
float tickScale = 0.5f + 0.5f*AnimationEquation.OUT_BACK.calc(decorationsAlpha);
Image tick = GameImage.SLIDER_TICK.getImage().getScaledCopy(tickScale);
for (int i = 0; i < ticksT.length; i++) {
Vec2f c = curve.pointAt(ticksT[i]);
tick.drawCentered(c.x, c.y, Colors.WHITE_FADE);
Colors.WHITE_FADE.a = decorationsAlpha;
tick.drawCentered(c.x , c.y , Colors.WHITE_FADE);
Colors.WHITE_FADE.a = alpha;
}
}
if (GameMod.HIDDEN.isActive()) {
Expand All @@ -224,24 +235,32 @@ public void draw(Graphics g, int trackPosition) {
hitCircleOverlay.drawCentered(x, y, Colors.WHITE_FADE);

// repeats
for (int tcurRepeat = currentRepeats; tcurRepeat <= currentRepeats + 1; tcurRepeat++) {
if (hitObject.getRepeatCount() - 1 > tcurRepeat) {
Image arrow = GameImage.REVERSEARROW.getImage();
if (tcurRepeat != currentRepeats) {
if (sliderTime == 0)
continue;
float t = Math.max(getT(trackPosition, true), 0);
arrow.setAlpha((float) (t - Math.floor(t)));
} else
arrow.setAlpha(1f);
if (tcurRepeat % 2 == 0) {
// last circle
arrow.setRotation(curve.getEndAngle());
arrow.drawCentered(endPos.x, endPos.y);
} else {
// first circle
arrow.setRotation(curve.getStartAngle());
arrow.drawCentered(x, y);
if (curveInterval == 1.0f) {
for (int tcurRepeat = currentRepeats; tcurRepeat <= currentRepeats + 1; tcurRepeat++) {
if (hitObject.getRepeatCount() - 1 > tcurRepeat) {
Image arrow = GameImage.REVERSEARROW.getImage();
if (tcurRepeat != currentRepeats) {
if (sliderTime == 0) {
continue;
}
float t = Math.max(getT(trackPosition, true), 0);
arrow.setAlpha((float) (t - Math.floor(t)));
} else {
if(Options.isSliderSnaking()){
arrow.setAlpha(decorationsAlpha);
} else {
arrow.setAlpha(1f);
}
}
if (tcurRepeat % 2 == 0) {
// last circle
arrow.setRotation(curve.getEndAngle());
arrow.drawCentered(endPos.x, endPos.y);
} else {
// first circle
arrow.setRotation(curve.getStartAngle());
arrow.drawCentered(x, y);
}
}
}
}
Expand Down
16 changes: 10 additions & 6 deletions src/itdelatrisu/opsu/objects/curves/Curve.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import itdelatrisu.opsu.GameImage;
import itdelatrisu.opsu.Options;
import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.beatmap.HitObject;
import itdelatrisu.opsu.render.CurveRenderState;
import itdelatrisu.opsu.skins.Skin;
Expand Down Expand Up @@ -111,28 +112,31 @@ public static void init(int width, int height, float circleDiameter, Color borde
public abstract Vec2f pointAt(float t);

/**
* Draws the full curve to the graphics context.
* 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]
*/
public void draw(Color color) {
public void draw(Color color, float t) {
if (curve == null)
return;

t = Utils.clamp(t, 0.0f, 1.0f);
// peppysliders
if (Options.getSkin().getSliderStyle() == Skin.STYLE_PEPPYSLIDER || !mmsliderSupported) {
int drawUpTo = (int)(curve.length*t);
Image hitCircle = GameImage.HITCIRCLE.getImage();
Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage();
for (int i = 0; i < curve.length; i++)
for (int i = 0; i < drawUpTo; i++)
hitCircleOverlay.drawCentered(curve[i].x, curve[i].y, Colors.WHITE_FADE);
for (int i = 0; i < curve.length; i++)
for (int i = 0; i < drawUpTo; i++)
hitCircle.drawCentered(curve[i].x, curve[i].y, color);
}

// mmsliders
else {
if (renderState == null)
renderState = new CurveRenderState(hitObject);
renderState.draw(color, borderColor, curve);
renderState = new CurveRenderState(hitObject,curve);
renderState.draw(color, borderColor, t);
}
}

Expand Down
Loading