mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 04:53:21 +08:00
Merge branch 'master' into mod-fl2
This commit is contained in:
commit
460c943958
@ -27,9 +27,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="System.IO.Packaging" Version="4.5.0" />
|
<PackageReference Include="System.IO.Packaging" Version="4.5.0" />
|
||||||
<PackageReference Include="ppy.squirrel.windows" Version="1.8.0.6" />
|
<PackageReference Include="ppy.squirrel.windows" Version="1.8.0.8" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Resources">
|
<ItemGroup Label="Resources">
|
||||||
<EmbeddedResource Include="lazer.ico" />
|
<EmbeddedResource Include="lazer.ico" />
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -10,6 +10,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
{
|
{
|
||||||
public class OsuBeatmapProcessor : BeatmapProcessor
|
public class OsuBeatmapProcessor : BeatmapProcessor
|
||||||
{
|
{
|
||||||
|
private const int stack_distance = 3;
|
||||||
|
|
||||||
public OsuBeatmapProcessor(IBeatmap beatmap)
|
public OsuBeatmapProcessor(IBeatmap beatmap)
|
||||||
: base(beatmap)
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
@ -18,17 +20,21 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
public override void PostProcess()
|
public override void PostProcess()
|
||||||
{
|
{
|
||||||
base.PostProcess();
|
base.PostProcess();
|
||||||
applyStacking((Beatmap<OsuHitObject>)Beatmap);
|
|
||||||
|
var osuBeatmap = (Beatmap<OsuHitObject>)Beatmap;
|
||||||
|
|
||||||
|
// Reset stacking
|
||||||
|
foreach (var h in osuBeatmap.HitObjects)
|
||||||
|
h.StackHeight = 0;
|
||||||
|
|
||||||
|
if (Beatmap.BeatmapInfo.BeatmapVersion >= 6)
|
||||||
|
applyStacking(osuBeatmap);
|
||||||
|
else
|
||||||
|
applyStackingOld(osuBeatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
||||||
{
|
{
|
||||||
const int stack_distance = 3;
|
|
||||||
|
|
||||||
// Reset stacking
|
|
||||||
for (int i = 0; i <= beatmap.HitObjects.Count - 1; i++)
|
|
||||||
beatmap.HitObjects[i].StackHeight = 0;
|
|
||||||
|
|
||||||
// Extend the end index to include objects they are stacked on
|
// Extend the end index to include objects they are stacked on
|
||||||
int extendedEndIndex = beatmap.HitObjects.Count - 1;
|
int extendedEndIndex = beatmap.HitObjects.Count - 1;
|
||||||
for (int i = beatmap.HitObjects.Count - 1; i >= 0; i--)
|
for (int i = beatmap.HitObjects.Count - 1; i >= 0; i--)
|
||||||
@ -167,5 +173,40 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyStackingOld(Beatmap<OsuHitObject> beatmap)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < beatmap.HitObjects.Count; i++)
|
||||||
|
{
|
||||||
|
OsuHitObject currHitObject = beatmap.HitObjects[i];
|
||||||
|
|
||||||
|
if (currHitObject.StackHeight != 0 && !(currHitObject is Slider))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double startTime = (currHitObject as IHasEndTime)?.EndTime ?? currHitObject.StartTime;
|
||||||
|
int sliderStack = 0;
|
||||||
|
|
||||||
|
for (int j = i + 1; j < beatmap.HitObjects.Count; j++)
|
||||||
|
{
|
||||||
|
double stackThreshold = beatmap.HitObjects[i].TimePreempt * beatmap.BeatmapInfo.StackLeniency;
|
||||||
|
|
||||||
|
if (beatmap.HitObjects[j].StartTime - stackThreshold > startTime)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.Position) < stack_distance)
|
||||||
|
{
|
||||||
|
currHitObject.StackHeight++;
|
||||||
|
startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[i].StartTime;
|
||||||
|
}
|
||||||
|
else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.EndPosition) < stack_distance)
|
||||||
|
{
|
||||||
|
//Case for sliders - bump notes down and right, rather than up and left.
|
||||||
|
sliderStack++;
|
||||||
|
beatmap.HitObjects[j].StackHeight -= sliderStack;
|
||||||
|
startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[i].StartTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
double sectionLength = section_length * timeRate;
|
double sectionLength = section_length * timeRate;
|
||||||
|
|
||||||
// The first object doesn't generate a strain, so we begin with an incremented section end
|
// The first object doesn't generate a strain, so we begin with an incremented section end
|
||||||
double currentSectionEnd = 2 * sectionLength;
|
double currentSectionEnd = Math.Ceiling(beatmap.HitObjects.First().StartTime / sectionLength) * sectionLength;
|
||||||
|
|
||||||
foreach (OsuDifficultyHitObject h in difficultyBeatmap)
|
foreach (OsuDifficultyHitObject h in difficultyBeatmap)
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
||||||
@ -23,8 +24,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
{
|
{
|
||||||
// Sort OsuHitObjects by StartTime - they are not correctly ordered in some cases.
|
// Sort OsuHitObjects by StartTime - they are not correctly ordered in some cases.
|
||||||
// This should probably happen before the objects reach the difficulty calculator.
|
// This should probably happen before the objects reach the difficulty calculator.
|
||||||
objects.Sort((a, b) => a.StartTime.CompareTo(b.StartTime));
|
difficultyObjects = createDifficultyObjectEnumerator(objects.OrderBy(h => h.StartTime).ToList(), timeRate);
|
||||||
difficultyObjects = createDifficultyObjectEnumerator(objects, timeRate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -21,15 +21,25 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
public OsuHitObject BaseObject { get; }
|
public OsuHitObject BaseObject { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Normalized distance from the <see cref="OsuHitObject.StackedPosition"/> of the previous <see cref="OsuDifficultyHitObject"/>.
|
/// Normalized distance from the end position of the previous <see cref="OsuDifficultyHitObject"/> to the start position of this <see cref="OsuDifficultyHitObject"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double Distance { get; private set; }
|
public double JumpDistance { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Normalized distance between the start and end position of the previous <see cref="OsuDifficultyHitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
public double TravelDistance { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Milliseconds elapsed since the StartTime of the previous <see cref="OsuDifficultyHitObject"/>.
|
/// Milliseconds elapsed since the StartTime of the previous <see cref="OsuDifficultyHitObject"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double DeltaTime { get; private set; }
|
public double DeltaTime { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Milliseconds elapsed since the start time of the previous <see cref="OsuDifficultyHitObject"/>, with a minimum of 50ms.
|
||||||
|
/// </summary>
|
||||||
|
public double StrainTime { get; private set; }
|
||||||
|
|
||||||
private readonly OsuHitObject lastObject;
|
private readonly OsuHitObject lastObject;
|
||||||
private readonly double timeRate;
|
private readonly double timeRate;
|
||||||
|
|
||||||
@ -51,31 +61,37 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
private void setDistances()
|
private void setDistances()
|
||||||
{
|
{
|
||||||
// We will scale distances by this factor, so we can assume a uniform CircleSize among beatmaps.
|
// We will scale distances by this factor, so we can assume a uniform CircleSize among beatmaps.
|
||||||
double scalingFactor = normalized_radius / BaseObject.Radius;
|
float scalingFactor = normalized_radius / (float)BaseObject.Radius;
|
||||||
if (BaseObject.Radius < 30)
|
if (BaseObject.Radius < 30)
|
||||||
{
|
{
|
||||||
double smallCircleBonus = Math.Min(30 - BaseObject.Radius, 5) / 50;
|
float smallCircleBonus = Math.Min(30 - (float)BaseObject.Radius, 5) / 50;
|
||||||
scalingFactor *= 1 + smallCircleBonus;
|
scalingFactor *= 1 + smallCircleBonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 lastCursorPosition = lastObject.StackedPosition;
|
Vector2 lastCursorPosition = lastObject.StackedPosition;
|
||||||
float lastTravelDistance = 0;
|
|
||||||
|
|
||||||
var lastSlider = lastObject as Slider;
|
var lastSlider = lastObject as Slider;
|
||||||
if (lastSlider != null)
|
if (lastSlider != null)
|
||||||
{
|
{
|
||||||
computeSliderCursorPosition(lastSlider);
|
computeSliderCursorPosition(lastSlider);
|
||||||
lastCursorPosition = lastSlider.LazyEndPosition ?? lastCursorPosition;
|
lastCursorPosition = lastSlider.LazyEndPosition ?? lastCursorPosition;
|
||||||
lastTravelDistance = lastSlider.LazyTravelDistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Distance = (lastTravelDistance + (BaseObject.StackedPosition - lastCursorPosition).Length) * scalingFactor;
|
// Don't need to jump to reach spinners
|
||||||
|
if (!(BaseObject is Spinner))
|
||||||
|
JumpDistance = (BaseObject.StackedPosition * scalingFactor - lastCursorPosition * scalingFactor).Length;
|
||||||
|
|
||||||
|
// Todo: BUG!!! Last slider's travel distance is considered ONLY IF we ourselves are also a slider!
|
||||||
|
if (BaseObject is Slider)
|
||||||
|
TravelDistance = (lastSlider?.LazyTravelDistance ?? 0) * scalingFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTimingValues()
|
private void setTimingValues()
|
||||||
{
|
{
|
||||||
// Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure.
|
DeltaTime = (BaseObject.StartTime - lastObject.StartTime) / timeRate;
|
||||||
DeltaTime = Math.Max(50, (BaseObject.StartTime - lastObject.StartTime) / timeRate);
|
|
||||||
|
// Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure
|
||||||
|
StrainTime = Math.Max(50, DeltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeSliderCursorPosition(Slider slider)
|
private void computeSliderCursorPosition(Slider slider)
|
||||||
@ -87,8 +103,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
float approxFollowCircleRadius = (float)(slider.Radius * 3);
|
float approxFollowCircleRadius = (float)(slider.Radius * 3);
|
||||||
var computeVertex = new Action<double>(t =>
|
var computeVertex = new Action<double>(t =>
|
||||||
{
|
{
|
||||||
|
double progress = ((int)t - (int)slider.StartTime) / (float)(int)slider.SpanDuration;
|
||||||
|
if (progress % 2 > 1)
|
||||||
|
progress = 1 - progress % 1;
|
||||||
|
else
|
||||||
|
progress = progress % 1;
|
||||||
|
|
||||||
// ReSharper disable once PossibleInvalidOperationException (bugged in current r# version)
|
// ReSharper disable once PossibleInvalidOperationException (bugged in current r# version)
|
||||||
var diff = slider.StackedPositionAt(t) - slider.LazyEndPosition.Value;
|
var diff = slider.StackedPosition + slider.Curve.PositionAt(progress) - slider.LazyEndPosition.Value;
|
||||||
float dist = diff.Length;
|
float dist = diff.Length;
|
||||||
|
|
||||||
if (dist > approxFollowCircleRadius)
|
if (dist > approxFollowCircleRadius)
|
||||||
|
@ -14,6 +14,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|||||||
protected override double SkillMultiplier => 26.25;
|
protected override double SkillMultiplier => 26.25;
|
||||||
protected override double StrainDecayBase => 0.15;
|
protected override double StrainDecayBase => 0.15;
|
||||||
|
|
||||||
protected override double StrainValueOf(OsuDifficultyHitObject current) => Math.Pow(current.Distance, 0.99) / current.DeltaTime;
|
protected override double StrainValueOf(OsuDifficultyHitObject current)
|
||||||
|
=> (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|||||||
|
|
||||||
protected override double StrainValueOf(OsuDifficultyHitObject current)
|
protected override double StrainValueOf(OsuDifficultyHitObject current)
|
||||||
{
|
{
|
||||||
double distance = current.Distance;
|
double distance = current.TravelDistance + current.JumpDistance;
|
||||||
|
|
||||||
double speedValue;
|
double speedValue;
|
||||||
if (distance > single_spacing_threshold)
|
if (distance > single_spacing_threshold)
|
||||||
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|||||||
else
|
else
|
||||||
speedValue = 0.95;
|
speedValue = 0.95;
|
||||||
|
|
||||||
return speedValue / current.DeltaTime;
|
return speedValue / current.StrainTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,11 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
var osuObject = (OsuHitObject)drawable.HitObject;
|
var osuObject = (OsuHitObject)drawable.HitObject;
|
||||||
Vector2 origin = drawable.Position;
|
Vector2 origin = drawable.Position;
|
||||||
|
|
||||||
|
// Wiggle the repeat points with the slider instead of independently.
|
||||||
|
// Also fixes an issue with repeat points being positioned incorrectly.
|
||||||
|
if (osuObject is RepeatPoint)
|
||||||
|
return;
|
||||||
|
|
||||||
Random objRand = new Random((int)osuObject.StartTime);
|
Random objRand = new Random((int)osuObject.StartTime);
|
||||||
|
|
||||||
// Wiggle all objects during TimePreempt
|
// Wiggle all objects during TimePreempt
|
||||||
|
@ -8,26 +8,23 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Lines;
|
using osu.Framework.Graphics.Lines;
|
||||||
using osu.Framework.Graphics.Textures;
|
|
||||||
using OpenTK.Graphics.ES30;
|
using OpenTK.Graphics.ES30;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using SixLabors.ImageSharp;
|
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
public class SliderBody : Container, ISliderProgress
|
public class SliderBody : Container, ISliderProgress
|
||||||
{
|
{
|
||||||
private readonly Path path;
|
private readonly SliderPath path;
|
||||||
private readonly BufferedContainer container;
|
private readonly BufferedContainer container;
|
||||||
|
|
||||||
public float PathWidth
|
public float PathWidth
|
||||||
{
|
{
|
||||||
get { return path.PathWidth; }
|
get => path.PathWidth;
|
||||||
set { path.PathWidth = value; }
|
set => path.PathWidth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -43,48 +40,40 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
public double? SnakedStart { get; private set; }
|
public double? SnakedStart { get; private set; }
|
||||||
public double? SnakedEnd { get; private set; }
|
public double? SnakedEnd { get; private set; }
|
||||||
|
|
||||||
private Color4 accentColour = Color4.White;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to colour the path.
|
/// Used to colour the path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get => path.AccentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (path.AccentColour == value)
|
||||||
return;
|
return;
|
||||||
accentColour = value;
|
path.AccentColour = value;
|
||||||
|
|
||||||
if (LoadState >= LoadState.Ready)
|
container.ForceRedraw();
|
||||||
reloadTexture();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color4 borderColour = Color4.White;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to colour the path border.
|
/// Used to colour the path border.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public new Color4 BorderColour
|
public new Color4 BorderColour
|
||||||
{
|
{
|
||||||
get { return borderColour; }
|
get => path.BorderColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (borderColour == value)
|
if (path.BorderColour == value)
|
||||||
return;
|
return;
|
||||||
borderColour = value;
|
path.BorderColour = value;
|
||||||
|
|
||||||
if (LoadState >= LoadState.Ready)
|
container.ForceRedraw();
|
||||||
reloadTexture();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Quad PathDrawQuad => container.ScreenSpaceDrawQuad;
|
public Quad PathDrawQuad => container.ScreenSpaceDrawQuad;
|
||||||
|
|
||||||
private int textureWidth => (int)PathWidth * 2;
|
|
||||||
|
|
||||||
private Vector2 topLeftOffset;
|
private Vector2 topLeftOffset;
|
||||||
|
|
||||||
private readonly Slider slider;
|
private readonly Slider slider;
|
||||||
@ -101,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
CacheDrawnFrameBuffer = true,
|
CacheDrawnFrameBuffer = true,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
path = new Path
|
path = new SliderPath
|
||||||
{
|
{
|
||||||
Blending = BlendingMode.None,
|
Blending = BlendingMode.None,
|
||||||
},
|
},
|
||||||
@ -134,46 +123,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
reloadTexture();
|
|
||||||
computeSize();
|
computeSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadTexture()
|
|
||||||
{
|
|
||||||
var texture = new Texture(textureWidth, 1);
|
|
||||||
|
|
||||||
//initialise background
|
|
||||||
var raw = new Image<Rgba32>(textureWidth, 1);
|
|
||||||
|
|
||||||
const float aa_portion = 0.02f;
|
|
||||||
const float border_portion = 0.128f;
|
|
||||||
const float gradient_portion = 1 - border_portion;
|
|
||||||
|
|
||||||
const float opacity_at_centre = 0.3f;
|
|
||||||
const float opacity_at_edge = 0.8f;
|
|
||||||
|
|
||||||
for (int i = 0; i < textureWidth; i++)
|
|
||||||
{
|
|
||||||
float progress = (float)i / (textureWidth - 1);
|
|
||||||
|
|
||||||
if (progress <= border_portion)
|
|
||||||
{
|
|
||||||
raw[i, 0] = new Rgba32(BorderColour.R, BorderColour.G, BorderColour.B, Math.Min(progress / aa_portion, 1) * BorderColour.A);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
progress -= border_portion;
|
|
||||||
raw[i, 0] = new Rgba32(AccentColour.R, AccentColour.G, AccentColour.B,
|
|
||||||
(opacity_at_edge - (opacity_at_edge - opacity_at_centre) * progress / gradient_portion) * AccentColour.A);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
texture.SetData(new TextureUpload(raw));
|
|
||||||
path.Texture = texture;
|
|
||||||
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void computeSize()
|
private void computeSize()
|
||||||
{
|
{
|
||||||
// Generate the entire curve
|
// Generate the entire curve
|
||||||
@ -226,5 +178,53 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
SetRange(start, end);
|
SetRange(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class SliderPath : SmoothPath
|
||||||
|
{
|
||||||
|
private const float border_portion = 0.128f;
|
||||||
|
private const float gradient_portion = 1 - border_portion;
|
||||||
|
|
||||||
|
private const float opacity_at_centre = 0.3f;
|
||||||
|
private const float opacity_at_edge = 0.8f;
|
||||||
|
|
||||||
|
private Color4 borderColour = Color4.White;
|
||||||
|
|
||||||
|
public Color4 BorderColour
|
||||||
|
{
|
||||||
|
get => borderColour;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (borderColour == value)
|
||||||
|
return;
|
||||||
|
borderColour = value;
|
||||||
|
|
||||||
|
InvalidateTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color4 accentColour = Color4.White;
|
||||||
|
|
||||||
|
public Color4 AccentColour
|
||||||
|
{
|
||||||
|
get => accentColour;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (accentColour == value)
|
||||||
|
return;
|
||||||
|
accentColour = value;
|
||||||
|
|
||||||
|
InvalidateTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Color4 ColourAt(float position)
|
||||||
|
{
|
||||||
|
if (position <= border_portion)
|
||||||
|
return BorderColour;
|
||||||
|
|
||||||
|
position -= border_portion;
|
||||||
|
return new Color4(AccentColour.R, AccentColour.G, AccentColour.B, (opacity_at_edge - (opacity_at_edge - opacity_at_centre) * position / gradient_portion) * AccentColour.A);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The beat length at this control point.
|
/// The beat length at this control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double BeatLength
|
public virtual double BeatLength
|
||||||
{
|
{
|
||||||
get => beatLength;
|
get => beatLength;
|
||||||
set => beatLength = MathHelper.Clamp(value, 6, 60000);
|
set => beatLength = MathHelper.Clamp(value, 6, 60000);
|
||||||
|
@ -318,12 +318,12 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
|
|
||||||
if (timingChange)
|
if (timingChange)
|
||||||
{
|
{
|
||||||
handleTimingControlPoint(new TimingControlPoint
|
var controlPoint = CreateTimingControlPoint();
|
||||||
{
|
controlPoint.Time = time;
|
||||||
Time = time,
|
controlPoint.BeatLength = beatLength;
|
||||||
BeatLength = beatLength,
|
controlPoint.TimeSignature = timeSignature;
|
||||||
TimeSignature = timeSignature
|
|
||||||
});
|
handleTimingControlPoint(controlPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDifficultyControlPoint(new DifficultyControlPoint
|
handleDifficultyControlPoint(new DifficultyControlPoint
|
||||||
@ -418,6 +418,8 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
|
|
||||||
private double getOffsetTime(double time) => time + (ApplyOffsets ? offset : 0);
|
private double getOffsetTime(double time) => time + (ApplyOffsets ? offset : 0);
|
||||||
|
|
||||||
|
protected virtual TimingControlPoint CreateTimingControlPoint() => new TimingControlPoint();
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
internal enum EffectFlags
|
internal enum EffectFlags
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps.Formats
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="LegacyBeatmapDecoder"/> built for difficulty calculation of legacy <see cref="Beatmap"/>s
|
||||||
|
/// <remarks>
|
||||||
|
/// To use this, the decoder must be registered by the application through <see cref="LegacyDifficultyCalculatorBeatmapDecoder.Register"/>.
|
||||||
|
/// Doing so will override any existing <see cref="Beatmap"/> decoders.
|
||||||
|
/// </remarks>
|
||||||
|
/// </summary>
|
||||||
|
public class LegacyDifficultyCalculatorBeatmapDecoder : LegacyBeatmapDecoder
|
||||||
|
{
|
||||||
|
public LegacyDifficultyCalculatorBeatmapDecoder(int version = LATEST_VERSION)
|
||||||
|
: base(version)
|
||||||
|
{
|
||||||
|
ApplyOffsets = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new static void Register()
|
||||||
|
{
|
||||||
|
AddDecoder<Beatmap>(@"osu file format v", m => new LegacyDifficultyCalculatorBeatmapDecoder(int.Parse(m.Split('v').Last())));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override TimingControlPoint CreateTimingControlPoint()
|
||||||
|
=> new LegacyDifficultyCalculatorControlPoint();
|
||||||
|
|
||||||
|
private class LegacyDifficultyCalculatorControlPoint : TimingControlPoint
|
||||||
|
{
|
||||||
|
public override double BeatLength { get; set; } = 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -69,7 +69,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
Masking = true,
|
Masking = true,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Child = path = new Path { RelativeSizeAxes = Axes.Both, PathWidth = 1 }
|
Child = path = new SmoothPath { RelativeSizeAxes = Axes.Both, PathWidth = 1 }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,10 +196,16 @@ namespace osu.Game.Overlays
|
|||||||
playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint);
|
playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ScheduledDelegate seekDelegate;
|
||||||
|
|
||||||
private void attemptSeek(double progress)
|
private void attemptSeek(double progress)
|
||||||
|
{
|
||||||
|
seekDelegate?.Cancel();
|
||||||
|
seekDelegate = Schedule(() =>
|
||||||
{
|
{
|
||||||
if (!beatmap.Disabled)
|
if (!beatmap.Disabled)
|
||||||
current?.Track.Seek(progress);
|
current?.Track.Seek(progress);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playlistOrderChanged(BeatmapSetInfo beatmapSetInfo, int index)
|
private void playlistOrderChanged(BeatmapSetInfo beatmapSetInfo, int index)
|
||||||
|
@ -105,6 +105,8 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
public override bool HandleNonPositionalInput => !ruleset.Disabled && base.HandleNonPositionalInput;
|
public override bool HandleNonPositionalInput => !ruleset.Disabled && base.HandleNonPositionalInput;
|
||||||
public override bool HandlePositionalInput => !ruleset.Disabled && base.HandlePositionalInput;
|
public override bool HandlePositionalInput => !ruleset.Disabled && base.HandlePositionalInput;
|
||||||
|
|
||||||
|
public override bool PropagatePositionalInputSubTree => !ruleset.Disabled && base.PropagatePositionalInputSubTree;
|
||||||
|
|
||||||
private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300);
|
private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300);
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
@ -13,6 +13,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies this <see cref="IApplicableToDrawableHitObjects"/> to a list of <see cref="DrawableHitObject"/>s.
|
/// Applies this <see cref="IApplicableToDrawableHitObjects"/> to a list of <see cref="DrawableHitObject"/>s.
|
||||||
|
/// This will only be invoked with top-level <see cref="DrawableHitObject"/>s. Access <see cref="DrawableHitObject.NestedHitObjects"/> if adjusting nested objects is necessary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="drawables">The list of <see cref="DrawableHitObject"/>s to apply to.</param>
|
/// <param name="drawables">The list of <see cref="DrawableHitObject"/>s to apply to.</param>
|
||||||
void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables);
|
void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables);
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
|
||||||
using osu.Framework.Lists;
|
using osu.Framework.Lists;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -58,10 +56,10 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public HitWindows HitWindows { get; set; }
|
public HitWindows HitWindows { get; set; }
|
||||||
|
|
||||||
private readonly Lazy<SortedList<HitObject>> nestedHitObjects = new Lazy<SortedList<HitObject>>(() => new SortedList<HitObject>((h1, h2) => h1.StartTime.CompareTo(h2.StartTime)));
|
private readonly SortedList<HitObject> nestedHitObjects = new SortedList<HitObject>(compareObjects);
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IReadOnlyList<HitObject> NestedHitObjects => nestedHitObjects.Value;
|
public IReadOnlyList<HitObject> NestedHitObjects => nestedHitObjects;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies default values to this HitObject.
|
/// Applies default values to this HitObject.
|
||||||
@ -72,18 +70,14 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
{
|
{
|
||||||
ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||||
|
|
||||||
if (nestedHitObjects.IsValueCreated)
|
nestedHitObjects.Clear();
|
||||||
nestedHitObjects.Value.Clear();
|
|
||||||
|
|
||||||
CreateNestedHitObjects();
|
CreateNestedHitObjects();
|
||||||
|
|
||||||
if (nestedHitObjects.IsValueCreated)
|
foreach (var h in nestedHitObjects)
|
||||||
{
|
|
||||||
nestedHitObjects.Value.ForEach(h =>
|
|
||||||
{
|
{
|
||||||
h.HitWindows = HitWindows;
|
h.HitWindows = HitWindows;
|
||||||
h.ApplyDefaults(controlPointInfo, difficulty);
|
h.ApplyDefaults(controlPointInfo, difficulty);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +98,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void AddNested(HitObject hitObject) => nestedHitObjects.Value.Add(hitObject);
|
protected void AddNested(HitObject hitObject) => nestedHitObjects.Add(hitObject);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the <see cref="Judgement"/> that represents the scoring information for this <see cref="HitObject"/>.
|
/// Creates the <see cref="Judgement"/> that represents the scoring information for this <see cref="HitObject"/>.
|
||||||
@ -120,5 +114,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// </para>
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual HitWindows CreateHitWindows() => new HitWindows();
|
protected virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||||
|
|
||||||
|
private static int compareObjects(HitObject first, HitObject second) => first.StartTime.CompareTo(second.StartTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,14 @@ namespace osu.Game.Rulesets.Timing
|
|||||||
public double StartTime;
|
public double StartTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The multiplier which this <see cref="MultiplierControlPoint"/> provides.
|
/// The aggregate multiplier which this <see cref="MultiplierControlPoint"/> provides.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public double Multiplier => 1000 / TimingPoint.BeatLength * DifficultyPoint.SpeedMultiplier;
|
public double Multiplier => Velocity * DifficultyPoint.SpeedMultiplier * 1000 / TimingPoint.BeatLength;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The velocity multiplier.
|
||||||
|
/// </summary>
|
||||||
|
public double Velocity = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="TimingControlPoint"/> that provides the timing information for this <see cref="MultiplierControlPoint"/>.
|
/// The <see cref="TimingControlPoint"/> that provides the timing information for this <see cref="MultiplierControlPoint"/>.
|
||||||
@ -48,18 +53,6 @@ namespace osu.Game.Rulesets.Timing
|
|||||||
StartTime = 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)
|
|
||||||
{
|
|
||||||
TimingPoint = other.TimingPoint;
|
|
||||||
DifficultyPoint = other.DifficultyPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReSharper disable once ImpureMethodCallOnReadonlyValueField
|
// ReSharper disable once ImpureMethodCallOnReadonlyValueField
|
||||||
public int CompareTo(MultiplierControlPoint other) => StartTime.CompareTo(other?.StartTime);
|
public int CompareTo(MultiplierControlPoint other) => StartTime.CompareTo(other?.StartTime);
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
return new MultiplierControlPoint(c.Time)
|
return new MultiplierControlPoint(c.Time)
|
||||||
{
|
{
|
||||||
|
Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier,
|
||||||
TimingPoint = lastTimingPoint,
|
TimingPoint = lastTimingPoint,
|
||||||
DifficultyPoint = lastDifficultyPoint
|
DifficultyPoint = lastDifficultyPoint
|
||||||
};
|
};
|
||||||
@ -78,7 +79,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
|
|
||||||
// If we have no control points, add a default one
|
// If we have no control points, add a default one
|
||||||
if (DefaultControlPoints.Count == 0)
|
if (DefaultControlPoints.Count == 0)
|
||||||
DefaultControlPoints.Add(new MultiplierControlPoint());
|
DefaultControlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier });
|
||||||
|
|
||||||
DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield));
|
DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield));
|
||||||
}
|
}
|
||||||
@ -88,22 +89,5 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
playfield.HitObjects.AddControlPoint(controlPoint);
|
playfield.HitObjects.AddControlPoint(controlPoint);
|
||||||
playfield.NestedPlayfields?.OfType<ScrollingPlayfield>().ForEach(p => applySpeedAdjustment(controlPoint, p));
|
playfield.NestedPlayfields?.OfType<ScrollingPlayfield>().ForEach(p => applySpeedAdjustment(controlPoint, p));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Generates a <see cref="MultiplierControlPoint"/> with the default timing change/difficulty change from the beatmap at a time.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="time">The time to create the control point at.</param>
|
|
||||||
/// <returns>The default <see cref="MultiplierControlPoint"/> at <paramref name="time"/>.</returns>
|
|
||||||
public MultiplierControlPoint CreateControlPointAt(double time)
|
|
||||||
{
|
|
||||||
if (DefaultControlPoints.Count == 0)
|
|
||||||
return new MultiplierControlPoint(time);
|
|
||||||
|
|
||||||
int index = DefaultControlPoints.BinarySearch(new MultiplierControlPoint(time));
|
|
||||||
if (index < 0)
|
|
||||||
return new MultiplierControlPoint(time);
|
|
||||||
|
|
||||||
return new MultiplierControlPoint(time, DefaultControlPoints[index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,11 +327,6 @@ namespace osu.Game.Screens.Select
|
|||||||
TextSize = 14,
|
TextSize = 14,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
textFlow = new OsuTextFlowContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -350,6 +345,8 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool IsPresent => base.IsPresent || textFlow == null; // Visibility is updated in the LoadComponentAsync callback
|
||||||
|
|
||||||
private void setTextAsync(string text)
|
private void setTextAsync(string text)
|
||||||
{
|
{
|
||||||
LoadComponentAsync(new OsuTextFlowContainer(s => s.TextSize = 14)
|
LoadComponentAsync(new OsuTextFlowContainer(s => s.TextSize = 14)
|
||||||
|
@ -14,13 +14,13 @@
|
|||||||
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Humanizer" Version="2.4.2" />
|
<PackageReference Include="Humanizer" Version="2.5.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.4" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2018.1002.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2018.1012.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
Loading…
Reference in New Issue
Block a user