1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 11:22:55 +08:00

Merge branch 'better_taiko_keys' into taiko_drumroll_drawable

Conflicts:
	osu.Game.Modes.Taiko/Objects/Drawable/DrawableTaikoHitObject.cs
	osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
This commit is contained in:
smoogipooo 2017-03-25 23:52:41 +09:00
commit e5c674a051
11 changed files with 198 additions and 11 deletions

View File

@ -29,7 +29,7 @@ namespace osu.Game.Modes.Osu
createAutoReplay();
}
internal class LegacyReplayFrameComparer : IComparer<LegacyReplayFrame>
private class LegacyReplayFrameComparer : IComparer<LegacyReplayFrame>
{
public int Compare(LegacyReplayFrame f1, LegacyReplayFrame f2)
{

View File

@ -0,0 +1,85 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using System;
using System.Linq;
using osu.Framework.Input;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public abstract class DrawableAccentedHit : DrawableHit
{
/// <summary>
/// The lenience for the second key press.
/// This does not adjust by map difficulty in ScoreV2 yet.
/// </summary>
private const double second_hit_window = 30;
private double firstHitTime;
private bool firstKeyHeld;
private Key firstHitKey;
protected DrawableAccentedHit(Hit hit)
: base(hit)
{
}
protected override void CheckJudgement(bool userTriggered)
{
if (!Judgement.Result.HasValue)
{
base.CheckJudgement(userTriggered);
return;
}
if (!userTriggered)
return;
// If we get here, we're assured that the key pressed is the correct secondary key
if (Math.Abs(firstHitTime - Time.Current) < second_hit_window)
Judgement.SecondHit = true;
}
protected override bool HandleKeyPress(Key key)
{
// Check if we've handled the first key
if (!Judgement.Result.HasValue)
{
// First key hasn't been handled yet, attempt to handle it
bool handled = base.HandleKeyPress(key);
if (handled)
{
firstHitTime = Time.Current;
firstHitKey = key;
}
return handled;
}
// If we've already hit the second key, don't handle this object any further
if (Judgement.SecondHit)
return false;
// Don't handle represses of the first key
if (firstHitKey == key)
return false;
// Don't handle invalid hit key presses
if (!HitKeys.Contains(key))
return false;
// Assume the intention was to hit the accented hit with both keys only if the first key is still being held down
return firstKeyHeld && UpdateJudgement(true);
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
firstKeyHeld = state.Keyboard.Keys.Contains(firstHitKey);
return base.OnKeyDown(state, args);
}
}
}

View File

@ -0,0 +1,67 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
using System;
using System.Collections.Generic;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public abstract class DrawableHit : DrawableTaikoHitObject
{
/// <summary>
/// A list of keys which can result in hits for this HitObject.
/// </summary>
protected abstract List<Key> HitKeys { get; }
private readonly Hit hit;
/// <summary>
/// Whether the last key pressed is a valid hit key.
/// </summary>
private bool validKeyPressed;
protected DrawableHit(Hit hit)
: base(hit)
{
this.hit = hit;
}
protected override void CheckJudgement(bool userTriggered)
{
if (!userTriggered)
{
if (Judgement.TimeOffset > hit.HitWindowGood)
Judgement.Result = HitResult.Miss;
return;
}
double hitOffset = Math.Abs(Judgement.TimeOffset);
if (hitOffset > hit.HitWindowMiss)
return;
if (!validKeyPressed)
Judgement.Result = HitResult.Miss;
else if (hitOffset < hit.HitWindowGood)
{
Judgement.Result = HitResult.Hit;
Judgement.TaikoResult = hitOffset < hit.HitWindowGreat ? TaikoHitResult.Great : TaikoHitResult.Good;
}
else
Judgement.Result = HitResult.Miss;
}
protected override bool HandleKeyPress(Key key)
{
if (Judgement.Result.HasValue)
return false;
validKeyPressed = HitKeys.Contains(key);
return UpdateJudgement(true);
}
}
}

View File

@ -1,14 +1,23 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using osu.Framework.Graphics;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
using System.Collections.Generic;
using osu.Framework.Input;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public abstract class DrawableTaikoHitObject : DrawableHitObject<TaikoHitObject, TaikoJudgement>
{
/// <summary>
/// A list of keys which this hit object will accept. These are the standard Taiko keys for now.
/// These should be moved to bindings later.
/// </summary>
private readonly List<Key> validKeys = new List<Key>(new[] { Key.D, Key.F, Key.J, Key.K });
protected DrawableTaikoHitObject(TaikoHitObject hitObject)
: base(hitObject)
{
@ -42,5 +51,21 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
{
UpdateScrollPosition(Time.Current);
}
protected virtual bool HandleKeyPress(Key key) { return false; }
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
// Make sure we don't handle held-down keys
if (args.Repeat)
return false;
// Check if we've pressed a valid taiko key
if (!validKeys.Contains(args.Key))
return false;
// Handle it!
return HandleKeyPress(args.Key);
}
}
}

View File

@ -52,6 +52,8 @@
<Compile Include="Judgements\TaikoDrumRollTickJudgement.cs" />
<Compile Include="Judgements\TaikoJudgement.cs" />
<Compile Include="Judgements\TaikoHitResult.cs" />
<Compile Include="Objects\Drawable\DrawableHit.cs" />
<Compile Include="Objects\Drawable\DrawableAccentedHit.cs" />
<Compile Include="Objects\Drawable\DrawableDrumRoll.cs" />
<Compile Include="Objects\Drawable\DrawableDrumRollTick.cs" />
<Compile Include="Objects\Drawable\DrawableTaikoHitObject.cs" />

View File

@ -101,7 +101,7 @@ namespace osu.Game.Database
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
using (var reader = new StreamReader(lzma))
score.Replay = new LegacyReplay(reader);
score.Replay = score.CreateLegacyReplayFrom(reader);
}
}

View File

@ -46,13 +46,13 @@ namespace osu.Game.Modes
}
}
public override ReplayInputHandler GetInputHandler() => new LegacyReplayInputHandler(Frames);
public override ReplayInputHandler CreateInputHandler() => new LegacyReplayInputHandler(Frames);
/// <summary>
/// The ReplayHandler will take a replay and handle the propagation of updates to the input stack.
/// It handles logic of any frames which *must* be executed.
/// </summary>
public class LegacyReplayInputHandler : ReplayInputHandler
protected class LegacyReplayInputHandler : ReplayInputHandler
{
private readonly List<LegacyReplayFrame> replayContent;
@ -163,7 +163,7 @@ namespace osu.Game.Modes
return currentTime = time;
}
private class ReplayMouseState : MouseState
protected class ReplayMouseState : MouseState
{
public ReplayMouseState(Vector2 position, IEnumerable<MouseButton> list)
{
@ -172,7 +172,7 @@ namespace osu.Game.Modes
}
}
private class ReplayKeyboardState : KeyboardState
protected class ReplayKeyboardState : KeyboardState
{
public ReplayKeyboardState(List<Key> keys)
{
@ -182,7 +182,7 @@ namespace osu.Game.Modes
}
[Flags]
public enum LegacyButtonState
protected enum LegacyButtonState
{
None = 0,
Left1 = 1,
@ -192,7 +192,7 @@ namespace osu.Game.Modes
Smoke = 16
}
public class LegacyReplayFrame
protected class LegacyReplayFrame
{
public Vector2 Position => new Vector2(MouseX, MouseY);

View File

@ -157,7 +157,7 @@ namespace osu.Game.Modes.Mods
public void Apply(HitRenderer<T> hitRenderer)
{
hitRenderer.InputManager.ReplayInputHandler = CreateReplayScore(hitRenderer.Beatmap)?.Replay?.GetInputHandler();
hitRenderer.InputManager.ReplayInputHandler = CreateReplayScore(hitRenderer.Beatmap)?.Replay?.CreateInputHandler();
}
}

View File

@ -7,6 +7,6 @@ namespace osu.Game.Modes
{
public abstract class Replay
{
public virtual ReplayInputHandler GetInputHandler() => null;
public virtual ReplayInputHandler CreateInputHandler() => null;
}
}

View File

@ -6,6 +6,7 @@ using Newtonsoft.Json;
using osu.Game.Database;
using osu.Game.Modes.Mods;
using osu.Game.Users;
using System.IO;
namespace osu.Game.Modes.Scoring
{
@ -43,6 +44,13 @@ namespace osu.Game.Modes.Scoring
[JsonProperty(@"date")]
public DateTime Date;
/// <summary>
/// Creates a legacy replay which is read from a stream.
/// </summary>
/// <param name="reader">The stream reader.</param>
/// <returns>The replay.</returns>
public virtual Replay CreateLegacyReplayFrom(StreamReader reader) => new LegacyReplay(reader);
// [JsonProperty(@"count50")] 0,
//[JsonProperty(@"count100")] 0,
//[JsonProperty(@"count300")] 100,

View File

@ -126,7 +126,7 @@ namespace osu.Game
Beatmap.Value = BeatmapDatabase.GetWorkingBeatmap(s.Beatmap);
menu.Push(new PlayerLoader(new Player { ReplayInputHandler = s.Replay.GetInputHandler() }));
menu.Push(new PlayerLoader(new Player { ReplayInputHandler = s.Replay.CreateInputHandler() }));
}
protected override void LoadComplete()