mirror of
https://github.com/ppy/osu.git
synced 2025-03-23 04:27:18 +08:00
Cleanups + xmldoc rewordings/improvements.
This commit is contained in:
parent
419682b740
commit
ba8014bbd9
osu.Game.Rulesets.Mania
Mods
Timing
osu.Game/Rulesets
@ -7,8 +7,17 @@ using osu.Game.Rulesets.Timing;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Mods
|
||||
{
|
||||
/// <summary>
|
||||
/// A type of mod which generates speed adjustments that scroll the hit objects and bar lines.
|
||||
/// </summary>
|
||||
internal interface IGenerateSpeedAdjustments
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies this mod to a hit renderer.
|
||||
/// </summary>
|
||||
/// <param name="hitRenderer">The hit renderer to apply to.</param>
|
||||
/// <param name="hitObjectTimingChanges">The per-column list of speed adjustments for hit objects.</param>
|
||||
/// <param name="barlineTimingChanges">The list of speed adjustments for bar lines.</param>
|
||||
void ApplyToHitRenderer(ManiaHitRenderer hitRenderer, ref List<SpeedAdjustmentContainer>[] hitObjectTimingChanges, ref List<SpeedAdjustmentContainer> barlineTimingChanges);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ using osu.Game.Rulesets.Mania.UI;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Mania.Timing;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Timing;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
|
||||
@ -23,21 +22,21 @@ namespace osu.Game.Rulesets.Mania.Mods
|
||||
|
||||
public void ApplyToHitRenderer(ManiaHitRenderer hitRenderer, ref List<SpeedAdjustmentContainer>[] hitObjectTimingChanges, ref List<SpeedAdjustmentContainer> barlineTimingChanges)
|
||||
{
|
||||
foreach (HitObject obj in hitRenderer.Objects)
|
||||
// We have to generate one speed adjustment per hit object for gravity
|
||||
foreach (ManiaHitObject obj in hitRenderer.Objects)
|
||||
{
|
||||
var maniaObject = obj as ManiaHitObject;
|
||||
if (maniaObject == null)
|
||||
continue;
|
||||
|
||||
MultiplierControlPoint controlPoint = hitRenderer.CreateControlPointAt(obj.StartTime);
|
||||
// Beat length has too large of an effect for gravity, so we'll force it to a constant value for now
|
||||
controlPoint.TimingPoint.BeatLength = 1000;
|
||||
|
||||
hitObjectTimingChanges[maniaObject.Column].Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity));
|
||||
hitObjectTimingChanges[obj.Column].Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity));
|
||||
}
|
||||
|
||||
// Like with hit objects, we need to generate one speed adjustment per bar line
|
||||
foreach (DrawableBarLine barLine in hitRenderer.BarLines)
|
||||
{
|
||||
var controlPoint = hitRenderer.CreateControlPointAt(barLine.HitObject.StartTime);
|
||||
// Beat length has too large of an effect for gravity, so we'll force it to a constant value for now
|
||||
controlPoint.TimingPoint.BeatLength = 1000;
|
||||
|
||||
barlineTimingChanges.Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity));
|
||||
|
@ -6,21 +6,24 @@ using osu.Game.Rulesets.Timing;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Timing
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="DrawableTimingSection"/> which scrolls relative to the control point start time.
|
||||
/// </summary>
|
||||
internal class BasicScrollingDrawableTimingSection : DrawableTimingSection
|
||||
{
|
||||
private readonly MultiplierControlPoint timingSection;
|
||||
private readonly MultiplierControlPoint controlPoint;
|
||||
|
||||
public BasicScrollingDrawableTimingSection(MultiplierControlPoint timingSection)
|
||||
public BasicScrollingDrawableTimingSection(MultiplierControlPoint controlPoint)
|
||||
: base(Axes.Y)
|
||||
{
|
||||
this.timingSection = timingSection;
|
||||
this.controlPoint = controlPoint;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Y = (float)(timingSection.StartTime - Time.Current);
|
||||
Y = (float)(controlPoint.StartTime - Time.Current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,14 +6,17 @@ using osu.Game.Rulesets.Timing;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Timing
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="DrawableTimingSection"/> that emulates a form of gravity where hit objects speed up over time.
|
||||
/// </summary>
|
||||
internal class GravityScrollingDrawableTimingSection : DrawableTimingSection
|
||||
{
|
||||
private readonly MultiplierControlPoint timingSection;
|
||||
private readonly MultiplierControlPoint controlPoint;
|
||||
|
||||
public GravityScrollingDrawableTimingSection(MultiplierControlPoint timingSection)
|
||||
public GravityScrollingDrawableTimingSection(MultiplierControlPoint controlPoint)
|
||||
: base(Axes.Y)
|
||||
{
|
||||
this.timingSection = timingSection;
|
||||
this.controlPoint = controlPoint;
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
@ -21,9 +24,9 @@ namespace osu.Game.Rulesets.Mania.Timing
|
||||
base.UpdateAfterChildren();
|
||||
|
||||
// The gravity-adjusted start position
|
||||
float startPos = (float)computeGravityTime(timingSection.StartTime);
|
||||
float startPos = (float)computeGravityTime(controlPoint.StartTime);
|
||||
// The gravity-adjusted end position
|
||||
float endPos = (float)computeGravityTime(timingSection.StartTime + RelativeChildSize.Y);
|
||||
float endPos = (float)computeGravityTime(controlPoint.StartTime + RelativeChildSize.Y);
|
||||
|
||||
Y = startPos;
|
||||
Height = endPos - startPos;
|
||||
|
@ -1,7 +1,6 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Caching;
|
||||
@ -24,19 +23,21 @@ namespace osu.Game.Rulesets.Timing
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// This container will auto-size to the total size of its children along the desired auto-sizing axes such that the reasulting size
|
||||
/// of this container will also be a time value.
|
||||
/// This container will auto-size to the total duration of the contained hit objects along the desired auto-sizing axes such that the resulting size
|
||||
/// of this container will be a value representing the total duration of all contained hit objects.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// This container is and must always be relatively-sized and positioned to its such that the parent can utilise
|
||||
/// <see cref="Container{T}.RelativeChildSize"/> and <see cref="Container{T}.RelativeChildOffset"/> to apply further time offsets
|
||||
/// to this collection of hit objects.
|
||||
/// This container is and must always be relatively-sized and positioned to its such that the parent can utilise <see cref="Container{T}.RelativeChildSize"/>
|
||||
/// and <see cref="Container{T}.RelativeChildOffset"/> to apply further time offsets to this collection of hit objects.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public abstract class DrawableTimingSection : Container<DrawableHitObject>
|
||||
{
|
||||
private readonly BindableDouble visibleTimeRange = new BindableDouble();
|
||||
/// <summary>
|
||||
/// Gets or sets the range of time that is visible by the length of this container.
|
||||
/// </summary>
|
||||
public BindableDouble VisibleTimeRange
|
||||
{
|
||||
get { return visibleTimeRange; }
|
||||
@ -57,18 +58,8 @@ namespace osu.Game.Rulesets.Timing
|
||||
{
|
||||
this.autoSizingAxes = autoSizingAxes;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
RelativePositionAxes = Axes.Both;
|
||||
|
||||
// We need a default size since RelativeSizeAxes is overridden
|
||||
Size = Vector2.One;
|
||||
}
|
||||
|
||||
public override Axes AutoSizeAxes { set { throw new InvalidOperationException($"{nameof(DrawableTimingSection)} must always be relatively-sized."); } }
|
||||
|
||||
public override Axes RelativeSizeAxes
|
||||
{
|
||||
get { return Axes.Both; }
|
||||
set { throw new InvalidOperationException($"{nameof(DrawableTimingSection)} must always be relatively-sized."); }
|
||||
}
|
||||
|
||||
public override void InvalidateFromChild(Invalidation invalidation)
|
||||
|
@ -10,27 +10,46 @@ namespace osu.Game.Rulesets.Timing
|
||||
public class MultiplierControlPoint : IJsonSerializable, IComparable<MultiplierControlPoint>
|
||||
{
|
||||
/// <summary>
|
||||
/// The time in milliseconds at which this control point starts.
|
||||
/// The time in milliseconds at which this <see cref="MultiplierControlPoint"/> starts.
|
||||
/// </summary>
|
||||
public readonly double StartTime;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier which this control point provides.
|
||||
/// The multiplier which this <see cref="MultiplierControlPoint"/> provides.
|
||||
/// </summary>
|
||||
public double Multiplier => 1000 / TimingPoint.BeatLength / DifficultyPoint.SpeedMultiplier;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TimingControlPoint"/> that provides the timing information for this <see cref="MultiplierControlPoint"/>.
|
||||
/// </summary>
|
||||
public TimingControlPoint TimingPoint = new TimingControlPoint();
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="DifficultyControlPoint"/> that provides additional difficulty information for this <see cref="MultiplierControlPoint"/>.
|
||||
/// </summary>
|
||||
public DifficultyControlPoint DifficultyPoint = new DifficultyControlPoint();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="MultiplierControlPoint"/>. This is required for JSON serialization
|
||||
/// </summary>
|
||||
public MultiplierControlPoint()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="MultiplierControlPoint"/>.
|
||||
/// </summary>
|
||||
/// <param name="startTime">The start time of this <see cref="MultiplierControlPoint"/>.</param>
|
||||
public MultiplierControlPoint(double startTime)
|
||||
{
|
||||
StartTime = startTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="MultiplierControlPoint"/> by copying another <see cref="MultiplierControlPoint"/>.
|
||||
/// </summary>
|
||||
/// <param name="startTime">The start time of this <see cref="MultiplierControlPoint"/>.</param>
|
||||
/// <param name="other">The <see cref="MultiplierControlPoint"/> to copy.</param>
|
||||
public MultiplierControlPoint(double startTime, MultiplierControlPoint other)
|
||||
: this(startTime)
|
||||
{
|
||||
|
@ -15,14 +15,16 @@ namespace osu.Game.Rulesets.Timing
|
||||
/// A collection of <see cref="SpeedAdjustmentContainer"/>s.
|
||||
///
|
||||
/// <para>
|
||||
/// This container provides <see cref="VisibleTimeRange"/> for the <see cref="SpeedAdjustmentContainer"/>s.
|
||||
/// This container redirects any <see cref="DrawableHitObject"/>'s added to it to the <see cref="SpeedAdjustmentContainer"/>
|
||||
/// which provides the speed adjustment active at the start time of the hit object. Furthermore, this container provides the
|
||||
/// necessary <see cref="VisibleTimeRange"/> for the contained <see cref="SpeedAdjustmentContainer"/>s.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class SpeedAdjustmentCollection : Container<SpeedAdjustmentContainer>
|
||||
{
|
||||
private readonly BindableDouble visibleTimeRange = new BindableDouble();
|
||||
/// <summary>
|
||||
/// The amount of time visible by span of this container.
|
||||
/// Gets or sets the range of time that is visible by the length of this container.
|
||||
/// For example, only hit objects with start time less than or equal to 1000 will be visible with <see cref="VisibleTimeRange"/> = 1000.
|
||||
/// </summary>
|
||||
public Bindable<double> VisibleTimeRange
|
||||
@ -32,15 +34,16 @@ namespace osu.Game.Rulesets.Timing
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a hit object to the most applicable timing section in this container.
|
||||
/// Adds a hit object to the <see cref="SpeedAdjustmentContainer"/> which provides the speed adjustment
|
||||
/// active at the start time of the hit object.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The hit object to add.</param>
|
||||
public void Add(DrawableHitObject hitObject)
|
||||
{
|
||||
var target = timingSectionFor(hitObject);
|
||||
var target = adjustmentContainerFor(hitObject);
|
||||
|
||||
if (target == null)
|
||||
throw new ArgumentException("No timing section could be found that can contain the hit object.", nameof(hitObject));
|
||||
throw new ArgumentException("No speed adjustment could be found that can contain the hit object.", nameof(hitObject));
|
||||
|
||||
target.Add(hitObject);
|
||||
}
|
||||
@ -51,33 +54,34 @@ namespace osu.Game.Rulesets.Timing
|
||||
base.Add(speedAdjustment);
|
||||
}
|
||||
|
||||
protected override IComparer<Drawable> DepthComparer => new TimingSectionReverseStartTimeComparer();
|
||||
protected override IComparer<Drawable> DepthComparer => new SpeedAdjustmentContainerReverseStartTimeComparer();
|
||||
|
||||
/// <summary>
|
||||
/// Finds the most applicable timing section that can contain a hit object. If the hit object occurs before the first (time-wise)
|
||||
/// timing section, then the timing section returned is the first (time-wise) timing section.
|
||||
/// Finds the <see cref="SpeedAdjustmentContainer"/> which provides the speed adjustment active at the start time
|
||||
/// of a hit object. If there is no <see cref="SpeedAdjustmentContainer"/> active at the start time of the hit object,
|
||||
/// then the first (time-wise) speed adjustment is returned.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The hit object to contain.</param>
|
||||
/// <returns>The last (time-wise) timing section which can contain <paramref name="hitObject"/>. Null if no timing section exists.</returns>
|
||||
private SpeedAdjustmentContainer timingSectionFor(DrawableHitObject hitObject) => Children.FirstOrDefault(c => c.CanContain(hitObject)) ?? Children.LastOrDefault();
|
||||
/// <param name="hitObject">The hit object to find the active <see cref="SpeedAdjustmentContainer"/> for.</param>
|
||||
/// <returns>The <see cref="SpeedAdjustmentContainer"/> active at <paramref name="hitObject"/>'s start time. Null if there are no speed adjustments.</returns>
|
||||
private SpeedAdjustmentContainer adjustmentContainerFor(DrawableHitObject hitObject) => Children.FirstOrDefault(c => c.CanContain(hitObject)) ?? Children.LastOrDefault();
|
||||
|
||||
/// <summary>
|
||||
/// Compares two timing sections by their start time, falling back to creation order if their start time is equal.
|
||||
/// This will compare the two timing sections in reverse order.
|
||||
/// Compares two speed adjustment containers by their control point start time, falling back to creation order
|
||||
// if their control point start time is equal. This will compare the two speed adjustment containers in reverse order.
|
||||
/// </summary>
|
||||
private class TimingSectionReverseStartTimeComparer : ReverseCreationOrderDepthComparer
|
||||
private class SpeedAdjustmentContainerReverseStartTimeComparer : ReverseCreationOrderDepthComparer
|
||||
{
|
||||
public override int Compare(Drawable x, Drawable y)
|
||||
{
|
||||
var timingChangeX = x as SpeedAdjustmentContainer;
|
||||
var timingChangeY = y as SpeedAdjustmentContainer;
|
||||
var speedAdjustmentX = x as SpeedAdjustmentContainer;
|
||||
var speedAdjustmentY = y as SpeedAdjustmentContainer;
|
||||
|
||||
// If either of the two drawables are not hit objects, fall back to the base comparer
|
||||
if (timingChangeX?.MultiplierControlPoint == null || timingChangeY?.MultiplierControlPoint == null)
|
||||
if (speedAdjustmentX?.MultiplierControlPoint == null || speedAdjustmentY?.MultiplierControlPoint == null)
|
||||
return base.Compare(x, y);
|
||||
|
||||
// Compare by start time
|
||||
int i = timingChangeY.MultiplierControlPoint.StartTime.CompareTo(timingChangeX.MultiplierControlPoint.StartTime);
|
||||
int i = speedAdjustmentY.MultiplierControlPoint.StartTime.CompareTo(speedAdjustmentX.MultiplierControlPoint.StartTime);
|
||||
|
||||
return i != 0 ? i : base.Compare(x, y);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// 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.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
@ -12,18 +11,29 @@ using OpenTK;
|
||||
namespace osu.Game.Rulesets.Timing
|
||||
{
|
||||
/// <summary>
|
||||
/// A container for hit objects which applies applies the speed adjustments defined by the <see cref="Timing.MultiplierControlPoint"/> properties
|
||||
/// to its <see cref="Container{T}.Content"/> to affect the <see cref="DrawableTimingSection"/> scroll speed.
|
||||
/// A container for hit objects which applies applies the speed adjustments defined by the properties of a <see cref="Timing.MultiplierControlPoint"/>
|
||||
/// to affect the scroll speed of the contained <see cref="DrawableTimingSection"/>.
|
||||
///
|
||||
/// <para>
|
||||
/// This container must always be relatively-sized to its parent to provide the speed adjustments. This container will provide the speed adjustments
|
||||
/// by modifying its size while maintaining a constant <see cref="Container{T}.RelativeChildSize"/> for its children
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public abstract class SpeedAdjustmentContainer : Container<DrawableHitObject>
|
||||
{
|
||||
private readonly Bindable<double> visibleTimeRange = new Bindable<double>();
|
||||
/// <summary>
|
||||
/// Gets or sets the range of time that is visible by the length of this container.
|
||||
/// </summary>
|
||||
public Bindable<double> VisibleTimeRange
|
||||
{
|
||||
get { return visibleTimeRange; }
|
||||
set { visibleTimeRange.BindTo(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MultiplierControlPoint"/> which provides the speed adjustments for this container.
|
||||
/// </summary>
|
||||
public readonly MultiplierControlPoint MultiplierControlPoint;
|
||||
|
||||
protected override Container<DrawableHitObject> Content => content;
|
||||
@ -34,12 +44,14 @@ namespace osu.Game.Rulesets.Timing
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="SpeedAdjustmentContainer"/>.
|
||||
/// </summary>
|
||||
/// <param name="multiplierControlPoint">The multiplier control point that provides the speed adjustments for this container.</param>
|
||||
/// <param name="scrollingAxes">The axes through which this drawable timing section scrolls through.</param>
|
||||
/// <param name="multiplierControlPoint">The <see cref="MultiplierControlPoint"/> which provides the speed adjustments for this container.</param>
|
||||
/// <param name="scrollingAxes">The axes through which the content of this container should scroll through.</param>
|
||||
protected SpeedAdjustmentContainer(MultiplierControlPoint multiplierControlPoint, Axes scrollingAxes)
|
||||
{
|
||||
this.scrollingAxes = scrollingAxes;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
MultiplierControlPoint = multiplierControlPoint;
|
||||
}
|
||||
|
||||
@ -54,12 +66,6 @@ namespace osu.Game.Rulesets.Timing
|
||||
AddInternal(content = timingSection);
|
||||
}
|
||||
|
||||
public override Axes RelativeSizeAxes
|
||||
{
|
||||
get { return Axes.Both; }
|
||||
set { throw new InvalidOperationException($"{nameof(SpeedAdjustmentContainer)} must always be relatively-sized."); }
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
float multiplier = (float)MultiplierControlPoint.Multiplier;
|
||||
@ -77,7 +83,7 @@ namespace osu.Game.Rulesets.Timing
|
||||
/// <summary>
|
||||
/// Creates the container which handles the movement of a collection of hit objects.
|
||||
/// </summary>
|
||||
/// <returns>The drawable timing section.</returns>
|
||||
/// <returns>The <see cref="DrawableTimingSection"/>.</returns>
|
||||
protected abstract DrawableTimingSection CreateTimingSection();
|
||||
}
|
||||
}
|
@ -120,6 +120,11 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
public Beatmap<TObject> Beatmap;
|
||||
|
||||
/// <summary>
|
||||
/// All the converted hit objects contained by this hit renderer.
|
||||
/// </summary>
|
||||
public override IEnumerable<HitObject> Objects => Beatmap.HitObjects;
|
||||
|
||||
/// <summary>
|
||||
/// The mods which are to be applied.
|
||||
/// </summary>
|
||||
@ -206,7 +211,10 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor;
|
||||
|
||||
public override IEnumerable<HitObject> Objects => Beatmap.HitObjects;
|
||||
/// <summary>
|
||||
/// All the converted hit objects contained by this hit renderer.
|
||||
/// </summary>
|
||||
public new IEnumerable<TObject> Objects => Beatmap.HitObjects;
|
||||
|
||||
protected override bool AllObjectsJudged => drawableObjects.All(h => h.Judged);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user