mirror of
https://github.com/ppy/osu.git
synced 2024-12-16 01:33:21 +08:00
Merge pull request #788 from smoogipooo/mania-beatmap-conversion
Mania beatmap conversion
This commit is contained in:
commit
9e9df4ada5
@ -85,25 +85,25 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
Clock = new FramedClock(),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuHitRenderer(beatmap)
|
||||
new OsuHitRenderer(beatmap, false)
|
||||
{
|
||||
Scale = new Vector2(0.5f),
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft
|
||||
},
|
||||
new TaikoHitRenderer(beatmap)
|
||||
new TaikoHitRenderer(beatmap, false)
|
||||
{
|
||||
Scale = new Vector2(0.5f),
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight
|
||||
},
|
||||
new CatchHitRenderer(beatmap)
|
||||
new CatchHitRenderer(beatmap, false)
|
||||
{
|
||||
Scale = new Vector2(0.5f),
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft
|
||||
},
|
||||
new ManiaHitRenderer(beatmap)
|
||||
new ManiaHitRenderer(beatmap, false)
|
||||
{
|
||||
Scale = new Vector2(0.5f),
|
||||
Anchor = Anchor.BottomRight,
|
||||
|
@ -43,13 +43,8 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
RelativeCoordinateSpace = new Vector2(1, 10000),
|
||||
Children = new[]
|
||||
{
|
||||
new DrawableNote(new Note
|
||||
{
|
||||
StartTime = 5000
|
||||
})
|
||||
{
|
||||
AccentColour = Color4.Red
|
||||
}
|
||||
new DrawableNote(new Note { StartTime = 5000 }) { AccentColour = Color4.Red },
|
||||
new DrawableNote(new Note { StartTime = 6000 }) { AccentColour = Color4.Red }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,10 +69,7 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
{
|
||||
StartTime = 5000,
|
||||
Duration = 1000
|
||||
})
|
||||
{
|
||||
AccentColour = Color4.Red
|
||||
}
|
||||
}) { AccentColour = Color4.Red }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
public class CatchRuleset : Ruleset
|
||||
{
|
||||
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap) => new CatchHitRenderer(beatmap);
|
||||
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchHitRenderer(beatmap, isForCurrentRuleset);
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
{
|
||||
|
@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
public class CatchHitRenderer : HitRenderer<CatchBaseHit, CatchJudgement>
|
||||
{
|
||||
public CatchHitRenderer(WorkingBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
public CatchHitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(beatmap, isForCurrentRuleset)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,35 +1,153 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using OpenTK;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps.Patterns;
|
||||
using osu.Game.Rulesets.Mania.MathUtils;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
{
|
||||
internal class ManiaBeatmapConverter : BeatmapConverter<ManiaHitObject>
|
||||
public class ManiaBeatmapConverter : BeatmapConverter<ManiaHitObject>
|
||||
{
|
||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
||||
|
||||
private Pattern lastPattern = new Pattern();
|
||||
private FastRandom random;
|
||||
private Beatmap beatmap;
|
||||
private bool isForCurrentRuleset;
|
||||
|
||||
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original, bool isForCurrentRuleset)
|
||||
{
|
||||
this.isForCurrentRuleset = isForCurrentRuleset;
|
||||
|
||||
beatmap = original;
|
||||
|
||||
BeatmapDifficulty difficulty = original.BeatmapInfo.Difficulty;
|
||||
|
||||
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
|
||||
random = new FastRandom(seed);
|
||||
|
||||
return base.ConvertBeatmap(original, isForCurrentRuleset);
|
||||
}
|
||||
|
||||
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
|
||||
{
|
||||
int availableColumns = (int)Math.Round(beatmap.BeatmapInfo.Difficulty.CircleSize);
|
||||
|
||||
var positionData = original as IHasXPosition;
|
||||
|
||||
float localWDivisor = 512.0f / availableColumns;
|
||||
int column = MathHelper.Clamp((int)Math.Floor((positionData?.X ?? 1) / localWDivisor), 0, availableColumns - 1);
|
||||
|
||||
yield return new Note
|
||||
var maniaOriginal = original as ManiaHitObject;
|
||||
if (maniaOriginal != null)
|
||||
{
|
||||
StartTime = original.StartTime,
|
||||
Column = column,
|
||||
};
|
||||
yield return maniaOriginal;
|
||||
yield break;
|
||||
}
|
||||
|
||||
var objects = isForCurrentRuleset ? generateSpecific(original) : generateConverted(original);
|
||||
|
||||
if (objects == null)
|
||||
yield break;
|
||||
|
||||
foreach (ManiaHitObject obj in objects)
|
||||
yield return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method that generates hit objects for osu!mania specific beatmaps.
|
||||
/// </summary>
|
||||
/// <param name="original">The original hit object.</param>
|
||||
/// <returns>The hit objects generated.</returns>
|
||||
private IEnumerable<ManiaHitObject> generateSpecific(HitObject original)
|
||||
{
|
||||
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern);
|
||||
|
||||
Pattern newPattern = generator.Generate();
|
||||
lastPattern = newPattern;
|
||||
|
||||
return newPattern.HitObjects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method that generates hit objects for non-osu!mania beatmaps.
|
||||
/// </summary>
|
||||
/// <param name="original">The original hit object.</param>
|
||||
/// <returns>The hit objects generated.</returns>
|
||||
private IEnumerable<ManiaHitObject> generateConverted(HitObject original)
|
||||
{
|
||||
var endTimeData = original as IHasEndTime;
|
||||
var distanceData = original as IHasDistance;
|
||||
var positionData = original as IHasPosition;
|
||||
|
||||
// Following lines currently commented out to appease resharper
|
||||
|
||||
//Patterns.PatternGenerator conversion = null;
|
||||
|
||||
if (distanceData != null)
|
||||
{
|
||||
// Slider
|
||||
}
|
||||
else if (endTimeData != null)
|
||||
{
|
||||
// Spinner
|
||||
}
|
||||
else if (positionData != null)
|
||||
{
|
||||
// Circle
|
||||
}
|
||||
|
||||
//if (conversion == null)
|
||||
return null;
|
||||
|
||||
//Pattern newPattern = conversion.Generate();
|
||||
//lastPattern = newPattern;
|
||||
|
||||
//return newPattern.HitObjects;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A pattern generator for osu!mania-specific beatmaps.
|
||||
/// </summary>
|
||||
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
|
||||
{
|
||||
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern)
|
||||
: base(random, hitObject, beatmap, previousPattern)
|
||||
{
|
||||
}
|
||||
|
||||
public override Pattern Generate()
|
||||
{
|
||||
var endTimeData = HitObject as IHasEndTime;
|
||||
var positionData = HitObject as IHasXPosition;
|
||||
|
||||
int column = GetColumn(positionData?.X ?? 0);
|
||||
|
||||
var pattern = new Pattern();
|
||||
|
||||
if (endTimeData != null)
|
||||
{
|
||||
pattern.Add(new HoldNote
|
||||
{
|
||||
StartTime = HitObject.StartTime,
|
||||
Samples = HitObject.Samples,
|
||||
Duration = endTimeData.Duration,
|
||||
Column = column,
|
||||
});
|
||||
}
|
||||
else if (positionData != null)
|
||||
{
|
||||
pattern.Add(new Note
|
||||
{
|
||||
StartTime = HitObject.StartTime,
|
||||
Samples = HitObject.Samples,
|
||||
Column = column
|
||||
});
|
||||
}
|
||||
|
||||
return pattern;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,106 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Rulesets.Mania.MathUtils;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
{
|
||||
/// <summary>
|
||||
/// A pattern generator for legacy hit objects.
|
||||
/// </summary>
|
||||
internal abstract class PatternGenerator : Patterns.PatternGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// The column index at which to start generating random notes.
|
||||
/// </summary>
|
||||
protected readonly int RandomStart;
|
||||
|
||||
/// <summary>
|
||||
/// The random number generator to use.
|
||||
/// </summary>
|
||||
protected readonly FastRandom Random;
|
||||
|
||||
protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern)
|
||||
: base(hitObject, beatmap, previousPattern)
|
||||
{
|
||||
Random = random;
|
||||
|
||||
RandomStart = AvailableColumns == 8 ? 1 : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an x-position into a column.
|
||||
/// </summary>
|
||||
/// <param name="position">The x-position.</param>
|
||||
/// <param name="allowSpecial">Whether to treat as 7K + 1.</param>
|
||||
/// <returns>The column.</returns>
|
||||
protected int GetColumn(float position, bool allowSpecial = false)
|
||||
{
|
||||
if (allowSpecial && AvailableColumns == 8)
|
||||
{
|
||||
const float local_x_divisor = 512f / 7;
|
||||
return MathHelper.Clamp((int)Math.Floor(position / local_x_divisor), 0, 6) + 1;
|
||||
}
|
||||
|
||||
float localXDivisor = 512f / AvailableColumns;
|
||||
return MathHelper.Clamp((int)Math.Floor(position / localXDivisor), 0, AvailableColumns - 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a count of notes to be generated from probabilities.
|
||||
/// </summary>
|
||||
/// <param name="p2">Probability for 2 notes to be generated.</param>
|
||||
/// <param name="p3">Probability for 3 notes to be generated.</param>
|
||||
/// <param name="p4">Probability for 4 notes to be generated.</param>
|
||||
/// <param name="p5">Probability for 5 notes to be generated.</param>
|
||||
/// <param name="p6">Probability for 6 notes to be generated.</param>
|
||||
/// <returns>The amount of notes to be generated.</returns>
|
||||
protected int GetRandomNoteCount(double p2, double p3, double p4 = 0, double p5 = 0, double p6 = 0)
|
||||
{
|
||||
double val = Random.NextDouble();
|
||||
if (val >= 1 - p6)
|
||||
return 6;
|
||||
if (val >= 1 - p5)
|
||||
return 5;
|
||||
if (val >= 1 - p4)
|
||||
return 4;
|
||||
if (val >= 1 - p3)
|
||||
return 3;
|
||||
return val >= 1 - p2 ? 2 : 1;
|
||||
}
|
||||
|
||||
private double? conversionDifficulty;
|
||||
/// <summary>
|
||||
/// A difficulty factor used for various conversion methods from osu!stable.
|
||||
/// </summary>
|
||||
protected double ConversionDifficulty
|
||||
{
|
||||
get
|
||||
{
|
||||
if (conversionDifficulty != null)
|
||||
return conversionDifficulty.Value;
|
||||
|
||||
HitObject lastObject = Beatmap.HitObjects.LastOrDefault();
|
||||
HitObject firstObject = Beatmap.HitObjects.FirstOrDefault();
|
||||
|
||||
double drainTime = (lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0);
|
||||
drainTime -= Beatmap.EventInfo.TotalBreakTime;
|
||||
|
||||
if (drainTime == 0)
|
||||
drainTime = 10000;
|
||||
|
||||
BeatmapDifficulty difficulty = Beatmap.BeatmapInfo.Difficulty;
|
||||
conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + Beatmap.HitObjects.Count / drainTime * 9f) / 38f * 5f / 1.15;
|
||||
conversionDifficulty = Math.Min(conversionDifficulty.Value, 12);
|
||||
|
||||
return conversionDifficulty.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of pattern to generate. Used for legacy patterns.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
internal enum PatternType
|
||||
{
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// Keep the same as last row.
|
||||
/// </summary>
|
||||
ForceStack = 1,
|
||||
/// <summary>
|
||||
/// Keep different from last row.
|
||||
/// </summary>
|
||||
ForceNotStack = 2,
|
||||
/// <summary>
|
||||
/// Keep as single note at its original position.
|
||||
/// </summary>
|
||||
KeepSingle = 4,
|
||||
/// <summary>
|
||||
/// Use a lower random value.
|
||||
/// </summary>
|
||||
LowProbability = 8,
|
||||
/// <summary>
|
||||
/// Reserved.
|
||||
/// </summary>
|
||||
Alternate = 16,
|
||||
/// <summary>
|
||||
/// Ignore the repeat count.
|
||||
/// </summary>
|
||||
ForceSigSlider = 32,
|
||||
/// <summary>
|
||||
/// Convert slider to circle.
|
||||
/// </summary>
|
||||
ForceNotSlider = 64,
|
||||
/// <summary>
|
||||
/// Notes gathered together.
|
||||
/// </summary>
|
||||
Gathered = 128,
|
||||
Mirror = 256,
|
||||
/// <summary>
|
||||
/// Change 0 -> 6.
|
||||
/// </summary>
|
||||
Reverse = 512,
|
||||
/// <summary>
|
||||
/// 1 -> 5 -> 1 -> 5 like reverse.
|
||||
/// </summary>
|
||||
Cycle = 1024,
|
||||
/// <summary>
|
||||
/// Next note will be at column + 1.
|
||||
/// </summary>
|
||||
Stair = 2048,
|
||||
/// <summary>
|
||||
/// Next note will be at column - 1.
|
||||
/// </summary>
|
||||
ReverseStair = 4096
|
||||
}
|
||||
}
|
61
osu.Game.Rulesets.Mania/Beatmaps/Patterns/Pattern.cs
Normal file
61
osu.Game.Rulesets.Mania/Beatmaps/Patterns/Pattern.cs
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a pattern containing hit objects.
|
||||
/// </summary>
|
||||
internal class Pattern
|
||||
{
|
||||
private readonly List<ManiaHitObject> hitObjects = new List<ManiaHitObject>();
|
||||
|
||||
/// <summary>
|
||||
/// All the hit objects contained in this pattern.
|
||||
/// </summary>
|
||||
public IEnumerable<ManiaHitObject> HitObjects => hitObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this pattern already contains a hit object in a code.
|
||||
/// </summary>
|
||||
/// <param name="column">The column index.</param>
|
||||
/// <returns>Whether this pattern already contains a hit object in <paramref name="column"/></returns>
|
||||
public bool IsFilled(int column) => hitObjects.Exists(h => h.Column == column);
|
||||
|
||||
/// <summary>
|
||||
/// Amount of columns taken up by hit objects in this pattern.
|
||||
/// </summary>
|
||||
public int ColumnsFilled => HitObjects.GroupBy(h => h.Column).Count();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a hit object to this pattern.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The hit object to add.</param>
|
||||
public void Add(ManiaHitObject hitObject) => hitObjects.Add(hitObject);
|
||||
|
||||
/// <summary>
|
||||
/// Copies hit object from another pattern to this one.
|
||||
/// </summary>
|
||||
/// <param name="other">The other pattern.</param>
|
||||
public void Add(Pattern other)
|
||||
{
|
||||
other.HitObjects.ForEach(Add);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears this pattern, removing all hit objects.
|
||||
/// </summary>
|
||||
public void Clear() => hitObjects.Clear();
|
||||
|
||||
/// <summary>
|
||||
/// Removes a hit object from this pattern.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The hit object to remove.</param>
|
||||
public bool Remove(ManiaHitObject hitObject) => hitObjects.Remove(hitObject);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||
{
|
||||
/// <summary>
|
||||
/// Generator to create a pattern <see cref="Pattern"/> from a hit object.
|
||||
/// </summary>
|
||||
internal abstract class PatternGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of columns available to create the pattern.
|
||||
/// </summary>
|
||||
protected readonly int AvailableColumns;
|
||||
|
||||
/// <summary>
|
||||
/// The last pattern.
|
||||
/// </summary>
|
||||
protected readonly Pattern PreviousPattern;
|
||||
|
||||
/// <summary>
|
||||
/// The hit object to create the pattern for.
|
||||
/// </summary>
|
||||
protected readonly HitObject HitObject;
|
||||
|
||||
/// <summary>
|
||||
/// The beatmap which <see cref="HitObject"/> is a part of.
|
||||
/// </summary>
|
||||
protected readonly Beatmap Beatmap;
|
||||
|
||||
protected PatternGenerator(HitObject hitObject, Beatmap beatmap, Pattern previousPattern)
|
||||
{
|
||||
PreviousPattern = previousPattern;
|
||||
HitObject = hitObject;
|
||||
Beatmap = beatmap;
|
||||
|
||||
AvailableColumns = (int)Math.Round(beatmap.BeatmapInfo.Difficulty.CircleSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the pattern for <see cref="HitObject"/>, filled with hit objects.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="Pattern"/> containing the hit objects.</returns>
|
||||
public abstract Pattern Generate();
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
public class ManiaRuleset : Ruleset
|
||||
{
|
||||
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap) => new ManiaHitRenderer(beatmap);
|
||||
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaHitRenderer(beatmap, isForCurrentRuleset);
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Mania.MathUtils
|
||||
/// </summary>
|
||||
internal class FastRandom
|
||||
{
|
||||
private const double uint_to_real = 1.0 / (int.MaxValue + 1.0);
|
||||
private const double uint_to_real = 1.0 / (uint.MaxValue + 1.0);
|
||||
private const uint int_mask = 0x7FFFFFFF;
|
||||
private const uint y = 842502087;
|
||||
private const uint z = 3579807591;
|
||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
tailPiece = new NotePiece
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre
|
||||
Origin = Anchor.TopCentre
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -61,5 +61,16 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
if (Time.Current > HitObject.StartTime)
|
||||
headPiece.Colour = Color4.Green;
|
||||
if (Time.Current > HitObject.EndTime)
|
||||
{
|
||||
bodyPiece.Colour = Color4.Green;
|
||||
tailPiece.Colour = Color4.Green;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
@ -15,8 +13,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
public new TObject HitObject;
|
||||
|
||||
private readonly Container glowContainer;
|
||||
|
||||
protected DrawableManiaHitObject(TObject hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
@ -24,21 +20,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
|
||||
RelativePositionAxes = Axes.Y;
|
||||
Y = (float)HitObject.StartTime;
|
||||
|
||||
Add(glowContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override Color4 AccentColour
|
||||
@ -49,13 +30,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
if (base.AccentColour == value)
|
||||
return;
|
||||
base.AccentColour = value;
|
||||
|
||||
glowContainer.EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Radius = 5,
|
||||
Colour = value
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
public BodyPiece()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Masking = true;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
|
@ -9,5 +9,11 @@ namespace osu.Game.Rulesets.Mania.Objects
|
||||
public abstract class ManiaHitObject : HitObject, IHasColumn
|
||||
{
|
||||
public int Column { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of other <see cref="ManiaHitObject"/> that start at
|
||||
/// the same time as this hit object.
|
||||
/// </summary>
|
||||
public int Siblings { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
public int? Columns;
|
||||
|
||||
public ManiaHitRenderer(WorkingBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
public ManiaHitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(beatmap, isForCurrentRuleset)
|
||||
{
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
return t;
|
||||
});
|
||||
|
||||
double lastObjectTime = (Objects.Last() as IHasEndTime)?.EndTime ?? Objects.Last().StartTime;
|
||||
double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue;
|
||||
|
||||
// Perform some post processing of the timing changes
|
||||
timingChanges = timingChanges
|
||||
@ -76,6 +76,10 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
protected override DrawableHitObject<ManiaHitObject, ManiaJudgement> GetVisualRepresentation(ManiaHitObject h)
|
||||
{
|
||||
var holdNote = h as HoldNote;
|
||||
if (holdNote != null)
|
||||
return new DrawableHoldNote(holdNote);
|
||||
|
||||
var note = h as Note;
|
||||
if (note != null)
|
||||
return new DrawableNote(note);
|
||||
|
@ -47,7 +47,11 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Beatmaps\Patterns\Legacy\PatternGenerator.cs" />
|
||||
<Compile Include="Beatmaps\Patterns\PatternGenerator.cs" />
|
||||
<Compile Include="Beatmaps\Patterns\Legacy\PatternType.cs" />
|
||||
<Compile Include="Beatmaps\ManiaBeatmapConverter.cs" />
|
||||
<Compile Include="Beatmaps\Patterns\Pattern.cs" />
|
||||
<Compile Include="MathUtils\FastRandom.cs" />
|
||||
<Compile Include="Judgements\HitWindows.cs" />
|
||||
<Compile Include="Judgements\ManiaJudgement.cs" />
|
||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
{
|
||||
public class OsuRuleset : Ruleset
|
||||
{
|
||||
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap) => new OsuHitRenderer(beatmap);
|
||||
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuHitRenderer(beatmap, isForCurrentRuleset);
|
||||
|
||||
public override IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new[]
|
||||
{
|
||||
|
@ -18,8 +18,8 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
public class OsuHitRenderer : HitRenderer<OsuHitObject, OsuJudgement>
|
||||
{
|
||||
public OsuHitRenderer(WorkingBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
public OsuHitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(beatmap, isForCurrentRuleset)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -41,13 +41,13 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
||||
|
||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(HitObject) };
|
||||
|
||||
protected override Beatmap<TaikoHitObject> ConvertBeatmap(Beatmap original)
|
||||
protected override Beatmap<TaikoHitObject> ConvertBeatmap(Beatmap original, bool isForCurrentRuleset)
|
||||
{
|
||||
// Rewrite the beatmap info to add the slider velocity multiplier
|
||||
BeatmapInfo info = original.BeatmapInfo.DeepClone();
|
||||
info.Difficulty.SliderMultiplier *= legacy_velocity_multiplier;
|
||||
|
||||
Beatmap<TaikoHitObject> converted = base.ConvertBeatmap(original);
|
||||
Beatmap<TaikoHitObject> converted = base.ConvertBeatmap(original, isForCurrentRuleset);
|
||||
|
||||
// Post processing step to transform hit objects with the same start time into strong hits
|
||||
converted.HitObjects = converted.HitObjects.GroupBy(t => t.StartTime).Select(x =>
|
||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
public class TaikoRuleset : Ruleset
|
||||
{
|
||||
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap) => new TaikoHitRenderer(beatmap);
|
||||
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoHitRenderer(beatmap, isForCurrentRuleset);
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||
{
|
||||
|
@ -22,8 +22,8 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
public class TaikoHitRenderer : HitRenderer<TaikoHitObject, TaikoJudgement>
|
||||
{
|
||||
public TaikoHitRenderer(WorkingBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
public TaikoHitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(beatmap, isForCurrentRuleset)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Beatmaps.Events;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
@ -17,6 +18,7 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
public BeatmapInfo BeatmapInfo;
|
||||
public TimingInfo TimingInfo = new TimingInfo();
|
||||
public EventInfo EventInfo = new EventInfo();
|
||||
public readonly List<Color4> ComboColors = new List<Color4>
|
||||
{
|
||||
new Color4(17, 136, 170, 255),
|
||||
@ -40,6 +42,7 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
BeatmapInfo = original?.BeatmapInfo ?? BeatmapInfo;
|
||||
TimingInfo = original?.TimingInfo ?? TimingInfo;
|
||||
EventInfo = original?.EventInfo ?? EventInfo;
|
||||
ComboColors = original?.ComboColors ?? ComboColors;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
protected DifficultyCalculator(Beatmap beatmap)
|
||||
{
|
||||
Objects = CreateBeatmapConverter().Convert(beatmap).HitObjects;
|
||||
Objects = CreateBeatmapConverter().Convert(beatmap, true).HitObjects;
|
||||
|
||||
foreach (var h in Objects)
|
||||
h.ApplyDefaults(beatmap.TimingInfo, beatmap.BeatmapInfo.Difficulty);
|
||||
|
@ -3,14 +3,11 @@
|
||||
|
||||
namespace osu.Game.Beatmaps.Events
|
||||
{
|
||||
public enum EventType
|
||||
public class BackgroundEvent : Event
|
||||
{
|
||||
Background = 0,
|
||||
Video = 1,
|
||||
Break = 2,
|
||||
Colour = 3,
|
||||
Sprite = 4,
|
||||
Sample = 5,
|
||||
Animation = 6
|
||||
/// <summary>
|
||||
/// The file name.
|
||||
/// </summary>
|
||||
public string Filename;
|
||||
}
|
||||
}
|
||||
}
|
28
osu.Game/Beatmaps/Events/BreakEvent.cs
Normal file
28
osu.Game/Beatmaps/Events/BreakEvent.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Beatmaps.Events
|
||||
{
|
||||
public class BreakEvent : Event
|
||||
{
|
||||
/// <summary>
|
||||
/// The minimum duration required for a break to have any effect.
|
||||
/// </summary>
|
||||
private const double min_break_duration = 650;
|
||||
|
||||
/// <summary>
|
||||
/// The break end time.
|
||||
/// </summary>
|
||||
public double EndTime;
|
||||
|
||||
/// <summary>
|
||||
/// The duration of the break.
|
||||
/// </summary>
|
||||
public double Duration => EndTime - StartTime;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the break has any effect. Breaks that are too short are culled before they reach the EventInfo.
|
||||
/// </summary>
|
||||
public bool HasEffect => Duration >= min_break_duration;
|
||||
}
|
||||
}
|
13
osu.Game/Beatmaps/Events/Event.cs
Normal file
13
osu.Game/Beatmaps/Events/Event.cs
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Beatmaps.Events
|
||||
{
|
||||
public abstract class Event
|
||||
{
|
||||
/// <summary>
|
||||
/// The event start time.
|
||||
/// </summary>
|
||||
public double StartTime;
|
||||
}
|
||||
}
|
33
osu.Game/Beatmaps/Events/EventInfo.cs
Normal file
33
osu.Game/Beatmaps/Events/EventInfo.cs
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Beatmaps.Events
|
||||
{
|
||||
public class EventInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// All the background events.
|
||||
/// </summary>
|
||||
public readonly List<BackgroundEvent> Backgrounds = new List<BackgroundEvent>();
|
||||
|
||||
/// <summary>
|
||||
/// All the break events.
|
||||
/// </summary>
|
||||
public readonly List<BreakEvent> Breaks = new List<BreakEvent>();
|
||||
|
||||
/// <summary>
|
||||
/// Total duration of all breaks.
|
||||
/// </summary>
|
||||
public double TotalBreakTime => Breaks.Sum(b => b.Duration);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the active background at a time.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to retrieve the background at.</param>
|
||||
/// <returns>The background.</returns>
|
||||
public BackgroundEvent BackgroundAt(double time) => Backgrounds.FirstOrDefault(b => b.StartTime <= time);
|
||||
}
|
||||
}
|
@ -204,23 +204,42 @@ namespace osu.Game.Beatmaps.Formats
|
||||
|
||||
private void handleEvents(Beatmap beatmap, string val)
|
||||
{
|
||||
if (val.StartsWith(@"//"))
|
||||
return;
|
||||
if (val.StartsWith(@" "))
|
||||
return; // TODO
|
||||
string[] split = val.Split(',');
|
||||
|
||||
EventType type;
|
||||
int intType;
|
||||
if (!int.TryParse(split[0], out intType))
|
||||
if (!Enum.TryParse(split[0], out type))
|
||||
throw new InvalidDataException($@"Unknown event type {split[0]}");
|
||||
|
||||
// Todo: Implement the rest
|
||||
switch (type)
|
||||
{
|
||||
if (!Enum.TryParse(split[0], out type))
|
||||
throw new InvalidDataException($@"Unknown event type {split[0]}");
|
||||
case EventType.Video:
|
||||
case EventType.Background:
|
||||
string filename = split[2].Trim('"');
|
||||
|
||||
beatmap.EventInfo.Backgrounds.Add(new BackgroundEvent
|
||||
{
|
||||
StartTime = double.Parse(split[1], NumberFormatInfo.InvariantInfo),
|
||||
Filename = filename
|
||||
});
|
||||
|
||||
if (type == EventType.Background)
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = filename;
|
||||
|
||||
break;
|
||||
case EventType.Break:
|
||||
var breakEvent = new BreakEvent
|
||||
{
|
||||
StartTime = double.Parse(split[1], NumberFormatInfo.InvariantInfo),
|
||||
EndTime = double.Parse(split[2], NumberFormatInfo.InvariantInfo)
|
||||
};
|
||||
|
||||
if (!breakEvent.HasEffect)
|
||||
return;
|
||||
|
||||
beatmap.EventInfo.Breaks.Add(breakEvent);
|
||||
break;
|
||||
}
|
||||
else
|
||||
type = (EventType)intType;
|
||||
// TODO: Parse and store the rest of the event
|
||||
if (type == EventType.Background)
|
||||
beatmap.BeatmapInfo.Metadata.BackgroundFile = split[2].Trim('"');
|
||||
}
|
||||
|
||||
private void handleTimingPoints(Beatmap beatmap, string val)
|
||||
@ -330,6 +349,9 @@ namespace osu.Game.Beatmaps.Formats
|
||||
if (string.IsNullOrEmpty(line))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith(" ") || line.StartsWith("_") || line.StartsWith("//"))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith(@"osu file format v"))
|
||||
{
|
||||
beatmap.BeatmapInfo.BeatmapVersion = int.Parse(line.Substring(17));
|
||||
@ -390,5 +412,16 @@ namespace osu.Game.Beatmaps.Formats
|
||||
Soft = 2,
|
||||
Drum = 3
|
||||
}
|
||||
|
||||
internal enum EventType
|
||||
{
|
||||
Background = 0,
|
||||
Video = 1,
|
||||
Break = 2,
|
||||
Colour = 3,
|
||||
Sprite = 4,
|
||||
Sample = 5,
|
||||
Animation = 6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,19 +26,21 @@ namespace osu.Game.Rulesets.Beatmaps
|
||||
/// Converts a Beatmap using this Beatmap Converter.
|
||||
/// </summary>
|
||||
/// <param name="original">The un-converted Beatmap.</param>
|
||||
/// <param name="isForCurrentRuleset">Whether to assume the beatmap is for the current ruleset.</param>
|
||||
/// <returns>The converted Beatmap.</returns>
|
||||
public Beatmap<T> Convert(Beatmap original)
|
||||
public Beatmap<T> Convert(Beatmap original, bool isForCurrentRuleset)
|
||||
{
|
||||
// We always operate on a clone of the original beatmap, to not modify it game-wide
|
||||
return ConvertBeatmap(new Beatmap(original));
|
||||
return ConvertBeatmap(new Beatmap(original), isForCurrentRuleset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the conversion of a Beatmap using this Beatmap Converter.
|
||||
/// </summary>
|
||||
/// <param name="original">The un-converted Beatmap.</param>
|
||||
/// <param name="isForCurrentRuleset">Whether to assume the beatmap is for the current ruleset.</param>
|
||||
/// <returns>The converted Beatmap.</returns>
|
||||
protected virtual Beatmap<T> ConvertBeatmap(Beatmap original)
|
||||
protected virtual Beatmap<T> ConvertBeatmap(Beatmap original, bool isForCurrentRuleset)
|
||||
{
|
||||
return new Beatmap<T>
|
||||
{
|
||||
|
@ -43,5 +43,10 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
||||
EndTime = endTime
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateHold(Vector2 position, bool newCombo, double endTime)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.Audio;
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects.Legacy
|
||||
{
|
||||
@ -26,7 +27,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
var soundType = (LegacySoundType)int.Parse(split[4]);
|
||||
var bankInfo = new SampleBankInfo();
|
||||
|
||||
HitObject result;
|
||||
HitObject result = null;
|
||||
|
||||
if ((type & ConvertHitObjectType.Circle) > 0)
|
||||
{
|
||||
@ -140,17 +141,20 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
{
|
||||
// Note: Hold is generated by BMS converts
|
||||
|
||||
// Todo: Apparently end time is determined by samples??
|
||||
// Shouldn't need implementation until mania
|
||||
double endTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
|
||||
|
||||
result = new ConvertHold
|
||||
if (split.Length > 5 && !string.IsNullOrEmpty(split[5]))
|
||||
{
|
||||
Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
|
||||
NewCombo = combo
|
||||
};
|
||||
string[] ss = split[5].Split(':');
|
||||
endTime = Convert.ToDouble(ss[0], CultureInfo.InvariantCulture);
|
||||
readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo);
|
||||
}
|
||||
|
||||
result = CreateHold(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, endTime);
|
||||
}
|
||||
else
|
||||
throw new InvalidOperationException($@"Unknown hit object type {type}");
|
||||
|
||||
if (result == null)
|
||||
throw new InvalidOperationException($@"Unknown hit object type {type}.");
|
||||
|
||||
result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
|
||||
result.Samples = convertSoundType(soundType, bankInfo);
|
||||
@ -214,6 +218,14 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
/// <returns>The hit object.</returns>
|
||||
protected abstract HitObject CreateSpinner(Vector2 position, double endTime);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a legacy Hold-type hit object.
|
||||
/// </summary>
|
||||
/// <param name="position">The position of the hit object.</param>
|
||||
/// <param name="newCombo">Whether the hit object creates a new combo.</param>
|
||||
/// <param name="endTime">The hold end time.</param>
|
||||
protected abstract HitObject CreateHold(Vector2 position, bool newCombo, double endTime);
|
||||
|
||||
private SampleInfoList convertSoundType(LegacySoundType type, SampleBankInfo bankInfo)
|
||||
{
|
||||
var soundTypes = new SampleInfoList
|
||||
|
@ -1,22 +0,0 @@
|
||||
// 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;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects.Legacy
|
||||
{
|
||||
/// <summary>
|
||||
/// Legacy Hold-type, used for parsing "specials" in beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class ConvertHold : HitObject, IHasPosition, IHasCombo, IHasHold
|
||||
{
|
||||
public Vector2 Position { get; set; }
|
||||
|
||||
public float X => Position.X;
|
||||
|
||||
public float Y => Position.Y;
|
||||
|
||||
public bool NewCombo { get; set; }
|
||||
}
|
||||
}
|
@ -44,5 +44,14 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
|
||||
EndTime = endTime
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateHold(Vector2 position, bool newCombo, double endTime)
|
||||
{
|
||||
return new ConvertHold
|
||||
{
|
||||
X = position.X,
|
||||
EndTime = endTime
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
16
osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs
Normal file
16
osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects.Legacy.Mania
|
||||
{
|
||||
internal sealed class ConvertHold : HitObject, IHasXPosition, IHasEndTime
|
||||
{
|
||||
public float X { get; set; }
|
||||
|
||||
public double EndTime { get; set; }
|
||||
|
||||
public double Duration => EndTime - StartTime;
|
||||
}
|
||||
}
|
@ -44,5 +44,10 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
EndTime = endTime
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateHold(Vector2 position, bool newCombo, double endTime)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,5 +41,10 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
|
||||
EndTime = endTime
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateHold(Vector2 position, bool newCombo, double endTime)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,5 +8,9 @@ namespace osu.Game.Rulesets.Objects.Types
|
||||
/// </summary>
|
||||
public interface IHasHold
|
||||
{
|
||||
/// <summary>
|
||||
/// The time at which the hold ends.
|
||||
/// </summary>
|
||||
double EndTime { get; }
|
||||
}
|
||||
}
|
||||
|
@ -18,12 +18,13 @@ namespace osu.Game.Rulesets
|
||||
public abstract IEnumerable<Mod> GetModsFor(ModType type);
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to create a HitRenderer for the provided beatmap.
|
||||
/// Attempt to create a hit renderer for a beatmap
|
||||
/// </summary>
|
||||
/// <param name="beatmap"></param>
|
||||
/// <param name="beatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="isForCurrentRuleset">Whether the hit renderer should assume the beatmap is for the current ruleset.</param>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">Unable to successfully load the beatmap to be usable with this ruleset.</exception>
|
||||
/// <returns></returns>
|
||||
public abstract HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap);
|
||||
public abstract HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap, bool isForCurrentRuleset);
|
||||
|
||||
public abstract DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap);
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
protected abstract bool AllObjectsJudged { get; }
|
||||
|
||||
protected HitRenderer()
|
||||
internal HitRenderer()
|
||||
{
|
||||
KeyConversionInputManager = CreateKeyConversionInputManager();
|
||||
KeyConversionInputManager.RelativeSizeAxes = Axes.Both;
|
||||
@ -120,7 +120,12 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
public Beatmap<TObject> Beatmap;
|
||||
|
||||
protected HitRenderer(WorkingBeatmap beatmap)
|
||||
/// <summary>
|
||||
/// Creates a hit renderer for a beatmap.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="isForCurrentRuleset">Whether to assume the beatmap is for the current ruleset.</param>
|
||||
internal HitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
{
|
||||
Debug.Assert(beatmap != null, "HitRenderer initialized with a null beatmap.");
|
||||
|
||||
@ -134,7 +139,7 @@ namespace osu.Game.Rulesets.UI
|
||||
throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can't be converted for the current ruleset.");
|
||||
|
||||
// Convert the beatmap
|
||||
Beatmap = converter.Convert(beatmap.Beatmap);
|
||||
Beatmap = converter.Convert(beatmap.Beatmap, isForCurrentRuleset);
|
||||
|
||||
// Apply defaults
|
||||
foreach (var h in Beatmap.HitObjects)
|
||||
@ -201,8 +206,13 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
private readonly List<DrawableHitObject<TObject, TJudgement>> drawableObjects = new List<DrawableHitObject<TObject, TJudgement>>();
|
||||
|
||||
protected HitRenderer(WorkingBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
/// <summary>
|
||||
/// Creates a hit renderer for a beatmap.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="isForCurrentRuleset">Whether to assume the beatmap is for the current ruleset.</param>
|
||||
protected HitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(beatmap, isForCurrentRuleset)
|
||||
{
|
||||
InputManager.Add(content = new Container
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
try
|
||||
{
|
||||
HitRenderer = rulesetInstance.CreateHitRendererWith(Beatmap);
|
||||
HitRenderer = rulesetInstance.CreateHitRendererWith(Beatmap, ruleset.ID == Beatmap.BeatmapInfo.Ruleset.ID);
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException)
|
||||
{
|
||||
@ -97,7 +97,7 @@ namespace osu.Game.Screens.Play
|
||||
// let's try again forcing the beatmap's ruleset.
|
||||
ruleset = Beatmap.BeatmapInfo.Ruleset;
|
||||
rulesetInstance = ruleset.CreateInstance();
|
||||
HitRenderer = rulesetInstance.CreateHitRendererWith(Beatmap);
|
||||
HitRenderer = rulesetInstance.CreateHitRendererWith(Beatmap, true);
|
||||
}
|
||||
|
||||
if (!HitRenderer.Objects.Any())
|
||||
|
@ -74,6 +74,10 @@
|
||||
<Compile Include="Audio\SampleInfoList.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
|
||||
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
|
||||
<Compile Include="Beatmaps\Events\BackgroundEvent.cs" />
|
||||
<Compile Include="Beatmaps\Events\BreakEvent.cs" />
|
||||
<Compile Include="Beatmaps\Events\Event.cs" />
|
||||
<Compile Include="Beatmaps\Events\EventInfo.cs" />
|
||||
<Compile Include="Online\API\Requests\PostMessageRequest.cs" />
|
||||
<Compile Include="Online\Chat\ErrorMessage.cs" />
|
||||
<Compile Include="Overlays\Chat\ChatTabControl.cs" />
|
||||
@ -125,6 +129,7 @@
|
||||
<Compile Include="Rulesets\Objects\Legacy\ConvertSlider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertHit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertHitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertHold.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertSlider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertSpinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\ConvertHitObjectParser.cs" />
|
||||
@ -161,7 +166,6 @@
|
||||
<Compile Include="Rulesets\Objects\CircularArcApproximator.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\ConvertHit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\ConvertHitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\ConvertHold.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\ConvertSlider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\ConvertSpinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\SliderCurve.cs" />
|
||||
@ -341,7 +345,6 @@
|
||||
<Compile Include="Beatmaps\Formats\BeatmapDecoder.cs" />
|
||||
<Compile Include="Beatmaps\Formats\OsuLegacyDecoder.cs" />
|
||||
<Compile Include="Beatmaps\IO\OszArchiveReader.cs" />
|
||||
<Compile Include="Beatmaps\Events\EventType.cs" />
|
||||
<Compile Include="Graphics\UserInterface\Volume\VolumeMeter.cs" />
|
||||
<Compile Include="Database\BeatmapSetInfo.cs" />
|
||||
<Compile Include="Database\BeatmapMetadata.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user