mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 15:44:04 +09:00
Merge remote-tracking branch 'origin/master' into netstandard
This commit is contained in:
@ -2,10 +2,9 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Audio
|
||||
{
|
||||
@ -14,7 +13,9 @@ namespace osu.Game.Rulesets.Taiko.Audio
|
||||
private readonly ControlPointInfo controlPoints;
|
||||
private readonly Dictionary<double, DrumSample> mappings = new Dictionary<double, DrumSample>();
|
||||
|
||||
public DrumSampleMapping(ControlPointInfo controlPoints, AudioManager audio)
|
||||
public readonly List<SkinnableSound> Sounds = new List<SkinnableSound>();
|
||||
|
||||
public DrumSampleMapping(ControlPointInfo controlPoints)
|
||||
{
|
||||
this.controlPoints = controlPoints;
|
||||
|
||||
@ -27,20 +28,34 @@ namespace osu.Game.Rulesets.Taiko.Audio
|
||||
|
||||
foreach (var s in samplePoints)
|
||||
{
|
||||
var centre = s.GetSampleInfo();
|
||||
var rim = s.GetSampleInfo(SampleInfo.HIT_CLAP);
|
||||
|
||||
// todo: this is ugly
|
||||
centre.Namespace = "taiko";
|
||||
rim.Namespace = "taiko";
|
||||
|
||||
mappings[s.Time] = new DrumSample
|
||||
{
|
||||
Centre = s.GetSampleInfo().GetChannel(audio.Sample, "Taiko"),
|
||||
Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample, "Taiko")
|
||||
Centre = addSound(centre),
|
||||
Rim = addSound(rim)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private SkinnableSound addSound(SampleInfo sampleInfo)
|
||||
{
|
||||
var drawable = new SkinnableSound(sampleInfo);
|
||||
Sounds.Add(drawable);
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public DrumSample SampleAt(double time) => mappings[controlPoints.SamplePointAt(time).Time];
|
||||
|
||||
public class DrumSample
|
||||
{
|
||||
public SampleChannel Centre;
|
||||
public SampleChannel Rim;
|
||||
public SkinnableSound Centre;
|
||||
public SkinnableSound Rim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,16 +101,16 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
||||
// The duration of the taiko hit object
|
||||
double taikoDuration = distance / taikoVelocity;
|
||||
|
||||
// For some reason, old osu! always uses speedAdjustment to determine the taiko velocity, but
|
||||
// only uses it to determine osu! velocity if beatmap version < 8. Let's account for that here.
|
||||
if (beatmap.BeatmapInfo.BeatmapVersion >= 8)
|
||||
speedAdjustedBeatLength *= speedAdjustment;
|
||||
|
||||
// The velocity of the osu! hit object - calculated as the velocity of a slider
|
||||
double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength;
|
||||
// The duration of the osu! hit object
|
||||
double osuDuration = distance / osuVelocity;
|
||||
|
||||
// osu-stable always uses the speed-adjusted beatlength to determine the velocities, but
|
||||
// only uses it for tick rate if beatmap version < 8
|
||||
if (beatmap.BeatmapInfo.BeatmapVersion >= 8)
|
||||
speedAdjustedBeatLength *= speedAdjustment;
|
||||
|
||||
// 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.BaseDifficulty.SliderTickRate, taikoDuration / spans);
|
||||
|
||||
|
@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
{
|
||||
public class TaikoModDaycore : ModDaycore
|
||||
{
|
||||
public override double ScoreMultiplier => 0.5;
|
||||
public override double ScoreMultiplier => 0.3;
|
||||
}
|
||||
}
|
||||
|
@ -7,5 +7,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
{
|
||||
public class TaikoModEasy : ModEasy
|
||||
{
|
||||
public override string Description => @"Beats move slower, less accuracy required, and three lives!";
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
{
|
||||
public class TaikoModHalfTime : ModHalfTime
|
||||
{
|
||||
public override double ScoreMultiplier => 0.5;
|
||||
public override double ScoreMultiplier => 0.3;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,5 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
public class TaikoModHardRock : ModHardRock
|
||||
{
|
||||
public override double ScoreMultiplier => 1.06;
|
||||
public override bool Ranked => true;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
{
|
||||
public class TaikoModHidden : ModHidden
|
||||
{
|
||||
public override string Description => @"The notes fade out before you hit them!";
|
||||
public override string Description => @"Beats fade out before you hit them!";
|
||||
public override double ScoreMultiplier => 1.06;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
{
|
||||
public class TaikoModRelax : ModRelax
|
||||
{
|
||||
public override string Description => @"Relax! You will no longer get dizzyfied by ninja-like spinners, demanding drumrolls or unexpected katu's.";
|
||||
public override string Description => @"No ninja-like spinners, demanding drumrolls or unexpected katu's.";
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Width = tracker_width;
|
||||
|
||||
Children = new[]
|
||||
InternalChildren = new[]
|
||||
{
|
||||
Tracker = new Box
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
public DrawableBarLineMajor(BarLine barLine)
|
||||
: base(barLine)
|
||||
{
|
||||
Add(triangleContainer = new Container
|
||||
AddInternal(triangleContainer = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
|
@ -20,11 +20,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
public class DrawableDrumRoll : DrawableTaikoHitObject<DrumRoll>
|
||||
{
|
||||
/// <summary>
|
||||
/// Number of rolling hits required to reach the dark/final accent colour.
|
||||
/// Number of rolling hits required to reach the dark/final colour.
|
||||
/// </summary>
|
||||
private const int rolling_hits_for_dark_accent = 5;
|
||||
|
||||
private Color4 accentDarkColour;
|
||||
private const int rolling_hits_for_engaged_colour = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Rolling number of tick hits. This increases for hits and decreases for misses.
|
||||
@ -53,11 +51,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
|
||||
public override bool OnPressed(TaikoAction action) => false;
|
||||
|
||||
private Color4 colourIdle;
|
||||
private Color4 colourEngaged;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
MainPiece.AccentColour = AccentColour = colours.YellowDark;
|
||||
accentDarkColour = colours.YellowDarker;
|
||||
MainPiece.AccentColour = colourIdle = colours.YellowDark;
|
||||
colourEngaged = colours.YellowDarker;
|
||||
}
|
||||
|
||||
private void onTickJudgement(DrawableHitObject obj, Judgement judgement)
|
||||
@ -67,10 +68,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
else
|
||||
rollingHits--;
|
||||
|
||||
rollingHits = MathHelper.Clamp(rollingHits, 0, rolling_hits_for_dark_accent);
|
||||
rollingHits = MathHelper.Clamp(rollingHits, 0, rolling_hits_for_engaged_colour);
|
||||
|
||||
Color4 newAccent = Interpolation.ValueAt((float)rollingHits / rolling_hits_for_dark_accent, AccentColour, accentDarkColour, 0, 1);
|
||||
MainPiece.FadeAccent(newAccent, 100);
|
||||
Color4 newColour = Interpolation.ValueAt((float)rollingHits / rolling_hits_for_engaged_colour, colourIdle, colourEngaged, 0, 1);
|
||||
MainPiece.FadeAccent(newColour, 100);
|
||||
}
|
||||
|
||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||
@ -82,8 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
return;
|
||||
|
||||
int countHit = NestedHitObjects.Count(o => o.IsHit);
|
||||
|
||||
if (countHit > HitObject.RequiredGoodHits)
|
||||
if (countHit >= HitObject.RequiredGoodHits)
|
||||
{
|
||||
AddJudgement(new TaikoJudgement { Result = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Good });
|
||||
if (HitObject.IsStrong)
|
||||
|
@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Hit:
|
||||
Content.ScaleTo(0, 100, Easing.OutQuint).Expire();
|
||||
this.ScaleTo(0, 100, Easing.OutQuint).Expire();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
const float gravity_time = 300;
|
||||
const float gravity_travel_height = 200;
|
||||
|
||||
Content.ScaleTo(0.8f, gravity_time * 2, Easing.OutQuad);
|
||||
this.ScaleTo(0.8f, gravity_time * 2, Easing.OutQuad);
|
||||
|
||||
this.MoveToY(-gravity_travel_height, gravity_time, Easing.Out)
|
||||
.Then()
|
||||
|
@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
{
|
||||
FillMode = FillMode.Fit;
|
||||
|
||||
Add(bodyContainer = new Container
|
||||
AddInternal(bodyContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Depth = 1,
|
||||
|
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Size = BaseSize = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
|
||||
|
||||
Add(MainPiece = CreateMainPiece());
|
||||
InternalChild = MainPiece = CreateMainPiece();
|
||||
MainPiece.KiaiMode = HitObject.Kiai;
|
||||
}
|
||||
|
||||
|
@ -35,15 +35,13 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
bool hitButton = true;
|
||||
|
||||
Frames.Add(new TaikoReplayFrame(-100000, ReplayButtonState.None));
|
||||
Frames.Add(new TaikoReplayFrame(Beatmap.HitObjects[0].StartTime - 1000, ReplayButtonState.None));
|
||||
Frames.Add(new TaikoReplayFrame(-100000));
|
||||
Frames.Add(new TaikoReplayFrame(Beatmap.HitObjects[0].StartTime - 1000));
|
||||
|
||||
for (int i = 0; i < Beatmap.HitObjects.Count; i++)
|
||||
{
|
||||
TaikoHitObject h = Beatmap.HitObjects[i];
|
||||
|
||||
ReplayButtonState button;
|
||||
|
||||
IHasEndTime endTimeData = h as IHasEndTime;
|
||||
double endTime = endTimeData?.EndTime ?? h.StartTime;
|
||||
|
||||
@ -59,24 +57,26 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
double hitRate = Math.Min(swell_hit_speed, swell.Duration / req);
|
||||
for (double j = h.StartTime; j < endTime; j += hitRate)
|
||||
{
|
||||
TaikoAction action;
|
||||
|
||||
switch (d)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
button = ReplayButtonState.Left1;
|
||||
action = TaikoAction.LeftCentre;
|
||||
break;
|
||||
case 1:
|
||||
button = ReplayButtonState.Right1;
|
||||
action = TaikoAction.LeftRim;
|
||||
break;
|
||||
case 2:
|
||||
button = ReplayButtonState.Left2;
|
||||
action = TaikoAction.RightCentre;
|
||||
break;
|
||||
case 3:
|
||||
button = ReplayButtonState.Right2;
|
||||
action = TaikoAction.RightRim;
|
||||
break;
|
||||
}
|
||||
|
||||
Frames.Add(new TaikoReplayFrame(j, button));
|
||||
Frames.Add(new TaikoReplayFrame(j, action));
|
||||
d = (d + 1) % 4;
|
||||
if (++count == req)
|
||||
break;
|
||||
@ -86,39 +86,39 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
foreach (var tick in drumRoll.NestedHitObjects.OfType<DrumRollTick>())
|
||||
{
|
||||
Frames.Add(new TaikoReplayFrame(tick.StartTime, hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2));
|
||||
Frames.Add(new TaikoReplayFrame(tick.StartTime, hitButton ? TaikoAction.LeftCentre : TaikoAction.RightCentre));
|
||||
hitButton = !hitButton;
|
||||
}
|
||||
}
|
||||
else if (hit != null)
|
||||
{
|
||||
TaikoAction[] actions;
|
||||
|
||||
if (hit is CentreHit)
|
||||
{
|
||||
if (h.IsStrong)
|
||||
button = ReplayButtonState.Right1 | ReplayButtonState.Right2;
|
||||
else
|
||||
button = hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2;
|
||||
actions = h.IsStrong
|
||||
? new[] { TaikoAction.LeftCentre, TaikoAction.RightCentre }
|
||||
: new[] { hitButton ? TaikoAction.LeftCentre : TaikoAction.RightCentre };
|
||||
}
|
||||
else
|
||||
{
|
||||
if (h.IsStrong)
|
||||
button = ReplayButtonState.Left1 | ReplayButtonState.Left2;
|
||||
else
|
||||
button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2;
|
||||
actions = h.IsStrong
|
||||
? new[] { TaikoAction.LeftRim, TaikoAction.RightRim }
|
||||
: new[] { hitButton ? TaikoAction.LeftRim : TaikoAction.RightRim };
|
||||
}
|
||||
|
||||
Frames.Add(new TaikoReplayFrame(h.StartTime, button));
|
||||
Frames.Add(new TaikoReplayFrame(h.StartTime, actions));
|
||||
}
|
||||
else
|
||||
throw new InvalidOperationException("Unknown hit object type.");
|
||||
|
||||
Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY, ReplayButtonState.None));
|
||||
Frames.Add(new TaikoReplayFrame(endTime + KEY_UP_DELAY));
|
||||
|
||||
if (i < Beatmap.HitObjects.Count - 1)
|
||||
{
|
||||
double waitTime = Beatmap.HitObjects[i + 1].StartTime - 1000;
|
||||
if (waitTime > endTime)
|
||||
Frames.Add(new TaikoReplayFrame(waitTime, ReplayButtonState.None));
|
||||
Frames.Add(new TaikoReplayFrame(waitTime));
|
||||
}
|
||||
|
||||
hitButton = !hitButton;
|
||||
|
@ -3,31 +3,20 @@
|
||||
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Input;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
internal class TaikoFramedReplayInputHandler : FramedReplayInputHandler
|
||||
internal class TaikoFramedReplayInputHandler : FramedReplayInputHandler<TaikoReplayFrame>
|
||||
{
|
||||
public TaikoFramedReplayInputHandler(Replay replay)
|
||||
: base(replay)
|
||||
{
|
||||
}
|
||||
|
||||
public override List<InputState> GetPendingStates()
|
||||
{
|
||||
var actions = new List<TaikoAction>();
|
||||
protected override bool IsImportant(TaikoReplayFrame frame) => frame.Actions.Any();
|
||||
|
||||
if (CurrentFrame?.MouseRight1 == true)
|
||||
actions.Add(TaikoAction.LeftCentre);
|
||||
if (CurrentFrame?.MouseRight2 == true)
|
||||
actions.Add(TaikoAction.RightCentre);
|
||||
if (CurrentFrame?.MouseLeft1 == true)
|
||||
actions.Add(TaikoAction.LeftRim);
|
||||
if (CurrentFrame?.MouseLeft2 == true)
|
||||
actions.Add(TaikoAction.RightRim);
|
||||
|
||||
return new List<InputState> { new ReplayState<TaikoAction> { PressedActions = actions } };
|
||||
}
|
||||
public override List<InputState> GetPendingStates() => new List<InputState> { new ReplayState<TaikoAction> { PressedActions = CurrentFrame.Actions } };
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,34 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.Replays.Legacy;
|
||||
using osu.Game.Rulesets.Replays.Types;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Replays
|
||||
{
|
||||
public class TaikoReplayFrame : ReplayFrame
|
||||
public class TaikoReplayFrame : ReplayFrame, IConvertibleReplayFrame
|
||||
{
|
||||
public override bool IsImportant => MouseLeft || MouseRight;
|
||||
public List<TaikoAction> Actions = new List<TaikoAction>();
|
||||
|
||||
public TaikoReplayFrame(double time, ReplayButtonState buttons)
|
||||
: base(time, null, null, buttons)
|
||||
public TaikoReplayFrame()
|
||||
{
|
||||
}
|
||||
|
||||
public TaikoReplayFrame(double time, params TaikoAction[] actions)
|
||||
: base(time)
|
||||
{
|
||||
Actions.AddRange(actions);
|
||||
}
|
||||
|
||||
public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap)
|
||||
{
|
||||
if (legacyFrame.MouseRight1) Actions.Add(TaikoAction.LeftRim);
|
||||
if (legacyFrame.MouseRight2) Actions.Add(TaikoAction.RightRim);
|
||||
if (legacyFrame.MouseLeft1) Actions.Add(TaikoAction.LeftCentre);
|
||||
if (legacyFrame.MouseLeft2) Actions.Add(TaikoAction.RightCentre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,209 @@
|
||||
{
|
||||
"Mappings": [{
|
||||
"StartTime": 500,
|
||||
"Objects": [{
|
||||
"StartTime": 500,
|
||||
"EndTime": 2499,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 3000,
|
||||
"Objects": [{
|
||||
"StartTime": 3000,
|
||||
"EndTime": 4000,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": true,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 4500,
|
||||
"Objects": [{
|
||||
"StartTime": 4500,
|
||||
"EndTime": 5500,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": true,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 6000,
|
||||
"Objects": [{
|
||||
"StartTime": 6000,
|
||||
"EndTime": 6500,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": true,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 7000,
|
||||
"Objects": [{
|
||||
"StartTime": 7000,
|
||||
"EndTime": 7000,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
},
|
||||
{
|
||||
"StartTime": 7249,
|
||||
"EndTime": 7249,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
},
|
||||
{
|
||||
"StartTime": 7499,
|
||||
"EndTime": 7499,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
},
|
||||
{
|
||||
"StartTime": 7749,
|
||||
"EndTime": 7749,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
},
|
||||
{
|
||||
"StartTime": 7999,
|
||||
"EndTime": 7999,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"StartTime": 8500,
|
||||
"Objects": [{
|
||||
"StartTime": 8500,
|
||||
"EndTime": 10999,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 11500,
|
||||
"Objects": [{
|
||||
"StartTime": 11500,
|
||||
"EndTime": 12000,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": true,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 12500,
|
||||
"Objects": [{
|
||||
"StartTime": 12500,
|
||||
"EndTime": 16499,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 17000,
|
||||
"Objects": [{
|
||||
"StartTime": 17000,
|
||||
"EndTime": 17000,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
},
|
||||
{
|
||||
"StartTime": 17249,
|
||||
"EndTime": 17249,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
},
|
||||
{
|
||||
"StartTime": 17499,
|
||||
"EndTime": 17499,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
},
|
||||
{
|
||||
"StartTime": 17749,
|
||||
"EndTime": 17749,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
},
|
||||
{
|
||||
"StartTime": 17999,
|
||||
"EndTime": 17999,
|
||||
"IsRim": false,
|
||||
"IsCentre": true,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"StartTime": 18500,
|
||||
"Objects": [{
|
||||
"StartTime": 18500,
|
||||
"EndTime": 19450,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": false,
|
||||
"IsSwell": true,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 19875,
|
||||
"Objects": [{
|
||||
"StartTime": 19875,
|
||||
"EndTime": 23874,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
27
osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/basic.osu
Normal file
27
osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/basic.osu
Normal file
@ -0,0 +1,27 @@
|
||||
osu file format v14
|
||||
|
||||
[Difficulty]
|
||||
HPDrainRate:6
|
||||
CircleSize:4
|
||||
OverallDifficulty:7
|
||||
ApproachRate:8.3
|
||||
SliderMultiplier:1.6
|
||||
SliderTickRate:1
|
||||
|
||||
[TimingPoints]
|
||||
500,500,4,2,1,50,1,0
|
||||
13426,-100,4,3,1,45,0,0
|
||||
14884,-100,4,2,1,50,0,0
|
||||
|
||||
[HitObjects]
|
||||
96,192,500,6,0,L|416:192,2,320
|
||||
256,192,3000,12,0,4000,0:0:0:0:
|
||||
256,192,4500,12,0,5500,0:0:0:0:
|
||||
256,192,6000,12,0,6500,0:0:0:0:
|
||||
256,128,7000,6,0,L|352:128,4,80
|
||||
32,192,8500,6,0,B|32:384|256:384|256:192|256:192|256:0|512:0|512:192,1,800
|
||||
256,192,11500,12,0,12000,0:0:0:0:
|
||||
512,320,12500,6,0,B|0:256|0:256|512:96|512:96|256:32,1,1280
|
||||
256,256,17000,6,0,L|160:256,4,80
|
||||
256,192,18500,12,0,19450,0:0:0:0:
|
||||
216,231,19875,6,0,B|216:135|280:135|344:135|344:199|344:263|248:327|248:327|120:327|120:327|56:39|408:39|408:39|472:150|408:342,1,1280
|
@ -0,0 +1,87 @@
|
||||
{
|
||||
"Mappings": [{
|
||||
"StartTime": 6590,
|
||||
"Objects": [{
|
||||
"StartTime": 6590,
|
||||
"EndTime": 8320,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 8436,
|
||||
"Objects": [{
|
||||
"StartTime": 8436,
|
||||
"EndTime": 10166,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 10282,
|
||||
"Objects": [{
|
||||
"StartTime": 10282,
|
||||
"EndTime": 12012,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 12128,
|
||||
"Objects": [{
|
||||
"StartTime": 12128,
|
||||
"EndTime": 13858,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 41666,
|
||||
"Objects": [{
|
||||
"StartTime": 41666,
|
||||
"EndTime": 42589,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 62666,
|
||||
"Objects": [{
|
||||
"StartTime": 62666,
|
||||
"EndTime": 63127,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
},
|
||||
{
|
||||
"StartTime": 208743,
|
||||
"Objects": [{
|
||||
"StartTime": 208743,
|
||||
"EndTime": 209204,
|
||||
"IsRim": false,
|
||||
"IsCentre": false,
|
||||
"IsDrumRoll": true,
|
||||
"IsSwell": false,
|
||||
"IsStrong": false
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
osu file format v14
|
||||
|
||||
[Difficulty]
|
||||
HPDrainRate:6
|
||||
CircleSize:4.2
|
||||
OverallDifficulty:9
|
||||
ApproachRate:9.8
|
||||
SliderMultiplier:1.87
|
||||
SliderTickRate:1
|
||||
|
||||
[TimingPoints]
|
||||
6590,461.538461538462,4,2,2,15,1,0
|
||||
6590,-200,4,2,2,15,0,0
|
||||
49051,230.769230769231,4,2,1,15,1,0
|
||||
62666,-200,4,2,1,60,0,0
|
||||
197666,-100,4,2,1,85,0,1
|
||||
|
||||
[HitObjects]
|
||||
88,104,6590,6,0,B|176:156|256:108|256:108|336:60|423:112,1,350.625,6|0,0:0|0:0,0:0:0:0:
|
||||
396,213,8436,2,0,P|277:247|376:172,1,350.625,6|0,0:0|0:0,0:0:0:0:
|
||||
472,220,10282,2,0,P|456:288|220:300,1,350.625,6|0,0:0|0:0,0:0:0:0:
|
||||
277,200,12128,2,0,P|398:225|276:244,1,350.625,6|0,0:0|0:0,0:0:0:0:
|
||||
268,229,41666,2,0,L|473:210,1,187,2|2,0:0|0:0,0:0:0:0:
|
||||
133,342,62666,2,0,B|132:316|132:316|128:316|128:316|130:295|130:295|126:296|126:296|129:275|129:275|125:275|125:275|127:254|127:254|123:255|123:255|125:234|125:234|121:234|121:234|123:213|123:213|119:214|119:214|121:193|121:193|118:193|118:193|118:172,1,187,8|8,0:0|0:0,0:0:0:0:
|
||||
481,338,208743,6,0,P|492:262|383:195,2,187,2|8|2,0:0|0:0|0:0,0:0:0:0:
|
@ -10,6 +10,8 @@ using osu.Game.Rulesets.UI;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.Replays.Types;
|
||||
using osu.Game.Rulesets.Taiko.Replays;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
@ -101,7 +103,9 @@ namespace osu.Game.Rulesets.Taiko
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap);
|
||||
|
||||
public override int LegacyID => 1;
|
||||
public override int? LegacyID => 1;
|
||||
|
||||
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame();
|
||||
|
||||
public TaikoRuleset(RulesetInfo rulesetInfo = null)
|
||||
: base(rulesetInfo)
|
||||
|
73
osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs
Normal file
73
osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
public class TaikoBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||
{
|
||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";
|
||||
|
||||
private bool isForCurrentRuleset;
|
||||
|
||||
[NonParallelizable]
|
||||
[TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2152")]
|
||||
[TestCase("slider-generating-drumroll", false)]
|
||||
public void Test(string name, bool isForCurrentRuleset)
|
||||
{
|
||||
this.isForCurrentRuleset = isForCurrentRuleset;
|
||||
base.Test(name);
|
||||
}
|
||||
|
||||
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
|
||||
{
|
||||
yield return new ConvertValue
|
||||
{
|
||||
StartTime = hitObject.StartTime,
|
||||
EndTime = (hitObject as IHasEndTime)?.EndTime ?? hitObject.StartTime,
|
||||
IsRim = hitObject is RimHit,
|
||||
IsCentre = hitObject is CentreHit,
|
||||
IsDrumRoll = hitObject is DrumRoll,
|
||||
IsSwell = hitObject is Swell,
|
||||
IsStrong = ((TaikoHitObject)hitObject).IsStrong
|
||||
};
|
||||
}
|
||||
|
||||
protected override IBeatmapConverter CreateConverter(Beatmap beatmap) => new TaikoBeatmapConverter(isForCurrentRuleset);
|
||||
}
|
||||
|
||||
public struct ConvertValue : IEquatable<ConvertValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// A sane value to account for osu!stable using ints everwhere.
|
||||
/// </summary>
|
||||
private const float conversion_lenience = 2;
|
||||
|
||||
public double StartTime;
|
||||
public double EndTime;
|
||||
public bool IsRim;
|
||||
public bool IsCentre;
|
||||
public bool IsDrumRoll;
|
||||
public bool IsSwell;
|
||||
public bool IsStrong;
|
||||
|
||||
public bool Equals(ConvertValue other)
|
||||
=> Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience)
|
||||
&& Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience)
|
||||
&& IsRim == other.IsRim
|
||||
&& IsCentre == other.IsCentre
|
||||
&& IsDrumRoll == other.IsDrumRoll
|
||||
&& IsSwell == other.IsSwell
|
||||
&& IsStrong == other.IsStrong;
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
[Ignore("getting CI working")]
|
||||
[TestFixture]
|
||||
public class TestCaseInputDrum : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
|
@ -5,7 +5,7 @@ using NUnit.Framework;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
[Ignore("getting CI working")]
|
||||
[TestFixture]
|
||||
public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints
|
||||
{
|
||||
public TestCasePerformancePoints()
|
||||
|
@ -25,7 +25,6 @@ using osu.Game.Rulesets.Scoring;
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
[Ignore("getting CI working")]
|
||||
public class TestCaseTaikoPlayfield : OsuTestCase
|
||||
{
|
||||
private const double default_duration = 1000;
|
||||
|
@ -15,17 +15,14 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
/// </summary>
|
||||
public class DrawableTaikoJudgement : DrawableJudgement
|
||||
{
|
||||
public readonly DrawableHitObject JudgedObject;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new judgement text.
|
||||
/// </summary>
|
||||
/// <param name="judgedObject">The object which is being judged.</param>
|
||||
/// <param name="judgement">The judgement to visualise.</param>
|
||||
public DrawableTaikoJudgement(DrawableHitObject judgedObject, Judgement judgement)
|
||||
: base(judgement)
|
||||
public DrawableTaikoJudgement(Judgement judgement, DrawableHitObject judgedObject)
|
||||
: base(judgement, judgedObject)
|
||||
{
|
||||
JudgedObject = judgedObject;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
@ -4,7 +4,6 @@
|
||||
using System;
|
||||
using OpenTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
@ -34,9 +33,9 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
private void load()
|
||||
{
|
||||
var sampleMappings = new DrumSampleMapping(controlPoints, audio);
|
||||
var sampleMappings = new DrumSampleMapping(controlPoints);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@ -63,6 +62,8 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
CentreAction = TaikoAction.RightCentre
|
||||
}
|
||||
};
|
||||
|
||||
AddRangeInternal(sampleMappings.Sounds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -16,6 +16,7 @@ using System.Linq;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.UI
|
||||
@ -41,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
|
||||
private readonly Container<HitExplosion> hitExplosionContainer;
|
||||
private readonly Container<KiaiHitExplosion> kiaiExplosionContainer;
|
||||
private readonly Container<DrawableTaikoJudgement> judgementContainer;
|
||||
private readonly JudgementContainer<DrawableTaikoJudgement> judgementContainer;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
private readonly Container content;
|
||||
@ -131,7 +132,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
|
||||
Blending = BlendingMode.Additive
|
||||
},
|
||||
judgementContainer = new Container<DrawableTaikoJudgement>
|
||||
judgementContainer = new JudgementContainer<DrawableTaikoJudgement>
|
||||
{
|
||||
Name = "Judgements",
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
@ -227,7 +228,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
if (judgedObject.DisplayJudgement && judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null)
|
||||
{
|
||||
judgementContainer.Add(new DrawableTaikoJudgement(judgedObject, judgement)
|
||||
judgementContainer.Add(new DrawableTaikoJudgement(judgement, judgedObject)
|
||||
{
|
||||
Anchor = judgement.IsHit ? Anchor.TopLeft : Anchor.CentreLeft,
|
||||
Origin = judgement.IsHit ? Anchor.BottomCentre : Anchor.Centre,
|
||||
|
@ -17,6 +17,7 @@ using osu.Game.Rulesets.Taiko.Replays;
|
||||
using OpenTK;
|
||||
using System.Linq;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Input.Handlers;
|
||||
using osu.Game.Rulesets.UI.Scrolling;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.UI
|
||||
@ -78,7 +79,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector2 GetPlayfieldAspectAdjust()
|
||||
protected override Vector2 GetAspectAdjustedSize()
|
||||
{
|
||||
const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
|
||||
const float default_aspect = 16f / 9f;
|
||||
@ -88,6 +89,8 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
return new Vector2(1, default_relative_height * aspectAdjust);
|
||||
}
|
||||
|
||||
protected override Vector2 PlayfieldArea => Vector2.One;
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
|
||||
|
||||
protected override BeatmapConverter<TaikoHitObject> CreateBeatmapConverter() => new TaikoBeatmapConverter(IsForCurrentRuleset);
|
||||
@ -131,6 +134,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new TaikoFramedReplayInputHandler(replay);
|
||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new TaikoFramedReplayInputHandler(replay);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user