1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 14:23:02 +08:00

Merge pull request #656 from smoogipooo/taiko-fixes

Taiko fixes
This commit is contained in:
Dean Herbert 2017-04-20 20:10:29 +09:00 committed by GitHub
commit 6e3125e115
12 changed files with 99 additions and 37 deletions

View File

@ -138,8 +138,7 @@ namespace osu.Game.Rulesets.Osu
if (h is Spinner)
{
targetPosition.X = Frames[Frames.Count - 1].MouseX;
targetPosition.Y = Frames[Frames.Count - 1].MouseY;
targetPosition = Frames[Frames.Count - 1].Position;
Vector2 difference = spinner_centre - targetPosition;
@ -193,7 +192,7 @@ namespace osu.Game.Rulesets.Osu
addFrameToReplay(lastFrame);
}
Vector2 lastPosition = new Vector2(lastFrame.MouseX, lastFrame.MouseY);
Vector2 lastPosition = lastFrame.Position;
double timeDifference = applyModsToTime(h.StartTime - lastFrame.Time);

View File

@ -98,11 +98,11 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
double osuDuration = distance / osuVelocity;
// If the drum roll is to be split into hit circles, assume the ticks are 1/8 spaced within the duration of one beat
double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.Difficulty.SliderTickRate, taikoDuration / repeats) / 8;
double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.Difficulty.SliderTickRate, taikoDuration / repeats);
if (tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength)
{
for (double j = obj.StartTime; j <= distanceData.EndTime + tickSpacing; j += tickSpacing)
for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing)
{
// Todo: This should generate different type of hits (including strongs)
// depending on hitobject sound additions (not implemented fully yet)

View File

@ -27,11 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
protected override void CheckJudgement(bool userTriggered)
{
if (!userTriggered)
{
if (Judgement.TimeOffset > HitObject.HitWindow)
Judgement.Result = HitResult.Miss;
return;
}
if (Math.Abs(Judgement.TimeOffset) < HitObject.HitWindow)
{

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
/// <summary>
/// The size of a tick.
/// </summary>
private const float tick_size = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 4;
private const float tick_size = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 6;
private bool filled;
public bool Filled

View File

@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Taiko.Replays
{
bool hitButton = true;
Frames.Add(new ReplayFrame(-100000, 320, 240, ReplayButtonState.None));
Frames.Add(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, 320, 240, ReplayButtonState.None));
Frames.Add(new ReplayFrame(-100000, null, null, ReplayButtonState.None));
Frames.Add(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, null, null, ReplayButtonState.None));
for (int i = 0; i < beatmap.HitObjects.Count; i++)
{
@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
break;
}
Frames.Add(new ReplayFrame(j, 0, 0, button));
Frames.Add(new ReplayFrame(j, null, null, button));
d = (d + 1) % 4;
if (++count > req)
break;
@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
{
foreach (var tick in drumRoll.Ticks)
{
Frames.Add(new ReplayFrame(tick.StartTime, 0, 0, hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2));
Frames.Add(new ReplayFrame(tick.StartTime, null, null, hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2));
hitButton = !hitButton;
}
}
@ -95,18 +95,18 @@ namespace osu.Game.Rulesets.Taiko.Replays
button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2;
}
Frames.Add(new ReplayFrame(h.StartTime, 0, 0, button));
Frames.Add(new ReplayFrame(h.StartTime, null, null, button));
}
else
throw new Exception("Unknown hit object type.");
Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, 0, 0, ReplayButtonState.None));
Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, null, null, ReplayButtonState.None));
if (i < beatmap.HitObjects.Count - 1)
{
double waitTime = beatmap.HitObjects[i + 1].StartTime - 1000;
if (waitTime > endTime)
Frames.Add(new ReplayFrame(waitTime, 0, 0, ReplayButtonState.None));
Frames.Add(new ReplayFrame(waitTime, null, null, ReplayButtonState.None));
}
hitButton = !hitButton;

View File

@ -108,7 +108,7 @@ namespace osu.Game.Database
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
using (var reader = new StreamReader(lzma))
score.Replay = createReplay(reader);
score.Replay = createLegacyReplay(reader);
}
}
@ -116,11 +116,11 @@ namespace osu.Game.Database
}
/// <summary>
/// Creates a replay which is read from a stream.
/// Creates a legacy replay which is read from a stream.
/// </summary>
/// <param name="reader">The stream reader.</param>
/// <returns>The replay.</returns>
private Replay createReplay(StreamReader reader)
/// <returns>The legacy replay.</returns>
private Replay createLegacyReplay(StreamReader reader)
{
var frames = new List<ReplayFrame>();

View File

@ -80,6 +80,10 @@ namespace osu.Game.Graphics
public Color4 GrayE = FromHex(@"eee");
public Color4 GrayF = FromHex(@"fff");
public Color4 Red = FromHex(@"fc4549");
public Color4 RedLighter = FromHex(@"ffeded");
public Color4 RedLight = FromHex(@"ed7787");
public Color4 Red = FromHex(@"ed1121");
public Color4 RedDark = FromHex(@"ba0011");
public Color4 RedDarker = FromHex(@"870000");
}
}

View File

@ -7,12 +7,12 @@ namespace osu.Game.Rulesets.Replays
{
public class ReplayFrame
{
public Vector2 Position => new Vector2(MouseX, MouseY);
public Vector2 Position => new Vector2(MouseX ?? 0, MouseY ?? 0);
public bool IsImportant => MouseLeft || MouseRight;
public bool IsImportant => MouseX.HasValue && MouseY.HasValue && (MouseLeft || MouseRight);
public float MouseX;
public float MouseY;
public float? MouseX;
public float? MouseY;
public bool MouseLeft => MouseLeft1 || MouseLeft2;
public bool MouseRight => MouseRight1 || MouseRight2;
@ -55,10 +55,10 @@ namespace osu.Game.Rulesets.Replays
}
public ReplayFrame(double time, float posX, float posY, ReplayButtonState buttonState)
public ReplayFrame(double time, float? mouseX, float? mouseY, ReplayButtonState buttonState)
{
MouseX = posX;
MouseY = posY;
MouseX = mouseX;
MouseY = mouseY;
ButtonState = buttonState;
Time = time;
}

View File

@ -19,6 +19,11 @@ namespace osu.Game.Rulesets.Scoring
/// </summary>
public event Action Failed;
/// <summary>
/// Invoked when a new judgement has occurred. This occurs after the judgement has been processed by the <see cref="ScoreProcessor"/>.
/// </summary>
public event Action<Judgement> NewJudgement;
/// <summary>
/// The current total score.
/// </summary>
@ -105,6 +110,15 @@ namespace osu.Game.Rulesets.Scoring
Failed?.Invoke();
}
/// <summary>
/// Notifies subscribers of <see cref="NewJudgement"/> that a new judgement has occurred.
/// </summary>
/// <param name="judgement">The judgement to notify subscribers of.</param>
protected void NotifyNewJudgement(Judgement judgement)
{
NewJudgement?.Invoke(judgement);
}
/// <summary>
/// Retrieve a score populated with data for the current play this processor is responsible for.
/// </summary>
@ -177,6 +191,8 @@ namespace osu.Game.Rulesets.Scoring
Judgements.Add(judgement);
OnNewJudgement(judgement);
NotifyNewJudgement(judgement);
}
else
OnJudgementChanged(judgement);

View File

@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.UI
}
}
public void BindProcessor(ScoreProcessor processor)
public virtual void BindProcessor(ScoreProcessor processor)
{
ScoreCounter?.Current.BindTo(processor.TotalScore);
AccuracyCounter?.Current.BindTo(processor.Accuracy);
@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.UI
HealthDisplay?.Current.BindTo(processor.Health);
}
public void BindHitRenderer(HitRenderer hitRenderer)
public virtual void BindHitRenderer(HitRenderer hitRenderer)
{
hitRenderer.InputManager.Add(KeyCounter.GetReceptor());
}

View File

@ -3,15 +3,42 @@
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
using System;
namespace osu.Game.Rulesets.UI
{
public class StandardHealthDisplay : HealthDisplay, IHasAccentColour
{
/// <summary>
/// The base opacity of the glow.
/// </summary>
private const float base_glow_opacity = 0.6f;
/// <summary>
/// The number of sequential hits required within <see cref="glow_fade_delay"/> to reach the maximum glow opacity.
/// </summary>
private const int glow_max_hits = 8;
/// <summary>
/// The amount of time to delay before fading the glow opacity back to <see cref="base_glow_opacity"/>.
/// <para>
/// This is calculated to require a stream snapped to 1/4 at 150bpm to reach the maximum glow opacity with <see cref="glow_max_hits"/> hits.
/// </para>
/// </summary>
private const float glow_fade_delay = 100;
/// <summary>
/// The amount of time to fade the glow to <see cref="base_glow_opacity"/> after <see cref="glow_fade_delay"/>.
/// </summary>
private const double glow_fade_time = 500;
private readonly Container fill;
public Color4 AccentColour
@ -32,9 +59,10 @@ namespace osu.Game.Rulesets.UI
fill.EdgeEffect = new EdgeEffect
{
Colour = glowColour,
Colour = glowColour.Opacity(base_glow_opacity),
Radius = 8,
Type = EdgeEffectType.Glow
Roundness = 4,
Type = EdgeEffectType.Glow,
};
}
}
@ -51,7 +79,7 @@ namespace osu.Game.Rulesets.UI
fill = new Container
{
RelativeSizeAxes = Axes.Both,
Scale = new Vector2(0, 1),
Size = new Vector2(0, 1),
Masking = true,
Children = new[]
{
@ -64,6 +92,16 @@ namespace osu.Game.Rulesets.UI
};
}
protected override void SetHealth(float value) => fill.ScaleTo(new Vector2(value, 1), 200, EasingTypes.OutQuint);
public void Flash(Judgement judgement)
{
if (judgement.Result == HitResult.Miss)
return;
fill.FadeEdgeEffectTo(Math.Min(1, fill.EdgeEffect.Colour.Linear.A + (1f - base_glow_opacity) / glow_max_hits), 50, EasingTypes.OutQuint);
fill.Delay(glow_fade_delay);
fill.FadeEdgeEffectTo(base_glow_opacity, glow_fade_time, EasingTypes.OutQuint);
}
protected override void SetHealth(float value) => fill.ResizeTo(new Vector2(value, 1), 200, EasingTypes.OutQuint);
}
}

View File

@ -3,11 +3,11 @@
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play;
namespace osu.Game.Rulesets.UI
@ -75,8 +75,17 @@ namespace osu.Game.Rulesets.UI
if (shd != null)
{
shd.AccentColour = colours.BlueLighter;
shd.GlowColour = colours.BlueDarker.Opacity(0.6f);
shd.GlowColour = colours.BlueDarker;
}
}
public override void BindProcessor(ScoreProcessor processor)
{
base.BindProcessor(processor);
var shd = HealthDisplay as StandardHealthDisplay;
if (shd != null)
processor.NewJudgement += shd.Flash;
}
}
}