mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 14:12:54 +08:00
Merge branch 'master' into sharpen
This commit is contained in:
commit
c0fe91a84c
@ -2,3 +2,4 @@ M:System.Object.Equals(System.Object,System.Object)~System.Boolean;Don't use obj
|
|||||||
M:System.Object.Equals(System.Object)~System.Boolean;Don't use object.Equals. Use IEquatable<T> or EqualityComparer<T>.Default instead.
|
M:System.Object.Equals(System.Object)~System.Boolean;Don't use object.Equals. Use IEquatable<T> or EqualityComparer<T>.Default instead.
|
||||||
M:System.ValueType.Equals(System.Object)~System.Boolean;Don't use object.Equals(Fallbacks to ValueType). Use IEquatable<T> or EqualityComparer<T>.Default instead.
|
M:System.ValueType.Equals(System.Object)~System.Boolean;Don't use object.Equals(Fallbacks to ValueType). Use IEquatable<T> or EqualityComparer<T>.Default instead.
|
||||||
T:System.IComparable;Don't use non-generic IComparable. Use generic version instead.
|
T:System.IComparable;Don't use non-generic IComparable. Use generic version instead.
|
||||||
|
M:osu.Framework.Graphics.Sprites.SpriteText.#ctor;Use OsuSpriteText.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"msbuild-sdks": {
|
"msbuild-sdks": {
|
||||||
"Microsoft.Build.Traversal": "2.0.19"
|
"Microsoft.Build.Traversal": "2.0.24"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,8 +17,6 @@
|
|||||||
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
|
<AndroidSupportedAbis>armeabi-v7a;x86;arm64-v8a</AndroidSupportedAbis>
|
||||||
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
|
<AndroidEnableSGenConcurrent>true</AndroidEnableSGenConcurrent>
|
||||||
<MandroidI18n>cjk,mideast,other,rare,west</MandroidI18n>
|
<MandroidI18n>cjk,mideast,other,rare,west</MandroidI18n>
|
||||||
<AndroidHttpClientHandlerType>System.Net.Http.HttpClientHandler</AndroidHttpClientHandlerType>
|
|
||||||
<AndroidTlsProvider>legacy</AndroidTlsProvider>
|
|
||||||
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
|
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -56,6 +54,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1010.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.1121.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.1122.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -11,12 +11,12 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
{
|
{
|
||||||
@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Blue
|
Colour = Color4.Blue
|
||||||
},
|
},
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = "custom"
|
Text = "custom"
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
// Longer maps are worth more
|
// Longer maps are worth more
|
||||||
float lengthBonus =
|
float lengthBonus =
|
||||||
0.95f + 0.4f * Math.Min(1.0f, numTotalHits / 3000.0f) +
|
0.95f + 0.4f * Math.Min(1.0f, numTotalHits / 3000.0f) +
|
||||||
(numTotalHits > 3000 ? (float)Math.Log10(numTotalHits / 3000.0f) * 0.5f : 0.0f);
|
(numTotalHits > 3000 ? MathF.Log10(numTotalHits / 3000.0f) * 0.5f : 0.0f);
|
||||||
|
|
||||||
// Longer maps are worth more
|
// Longer maps are worth more
|
||||||
value *= lengthBonus;
|
value *= lengthBonus;
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
|
|
||||||
protected override void UpdateStateTransforms(ArmedState state)
|
protected override void UpdateStateTransforms(ArmedState state)
|
||||||
{
|
{
|
||||||
var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
|
var endTime = HitObject.GetEndTime();
|
||||||
|
|
||||||
using (BeginAbsoluteSequence(endTime, true))
|
using (BeginAbsoluteSequence(endTime, true))
|
||||||
{
|
{
|
||||||
|
@ -99,8 +99,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
const float small_pulp = large_pulp_3 / 2;
|
const float small_pulp = large_pulp_3 / 2;
|
||||||
|
|
||||||
static Vector2 positionAt(float angle, float distance) => new Vector2(
|
static Vector2 positionAt(float angle, float distance) => new Vector2(
|
||||||
distance * (float)Math.Sin(angle * Math.PI / 180),
|
distance * MathF.Sin(angle * MathF.PI / 180),
|
||||||
distance * (float)Math.Cos(angle * Math.PI / 180));
|
distance * MathF.Cos(angle * MathF.PI / 180));
|
||||||
|
|
||||||
switch (representation)
|
switch (representation)
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Tests
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
@ -27,7 +26,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
yield return new ConvertValue
|
yield return new ConvertValue
|
||||||
{
|
{
|
||||||
StartTime = hitObject.StartTime,
|
StartTime = hitObject.StartTime,
|
||||||
EndTime = (hitObject as IHasEndTime)?.EndTime ?? hitObject.StartTime,
|
EndTime = hitObject.GetEndTime(),
|
||||||
Column = ((ManiaHitObject)hitObject).Column
|
Column = ((ManiaHitObject)hitObject).Column
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
{
|
{
|
||||||
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
||||||
|
|
||||||
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
|
int seed = (int)MathF.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)MathF.Round(difficulty.ApproachRate);
|
||||||
Random = new FastRandom(seed);
|
Random = new FastRandom(seed);
|
||||||
|
|
||||||
return base.ConvertBeatmap(original);
|
return base.ConvertBeatmap(original);
|
||||||
|
@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
foreach (var obj in originalPattern.HitObjects)
|
foreach (var obj in originalPattern.HitObjects)
|
||||||
{
|
{
|
||||||
if (!Precision.AlmostEquals(EndTime, (obj as IHasEndTime)?.EndTime ?? obj.StartTime))
|
if (!Precision.AlmostEquals(EndTime, obj.GetEndTime()))
|
||||||
intermediatePattern.Add(obj);
|
intermediatePattern.Add(obj);
|
||||||
else
|
else
|
||||||
endTimePattern.Add(obj);
|
endTimePattern.Add(obj);
|
||||||
|
@ -53,11 +53,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (allowSpecial && TotalColumns == 8)
|
if (allowSpecial && TotalColumns == 8)
|
||||||
{
|
{
|
||||||
const float local_x_divisor = 512f / 7;
|
const float local_x_divisor = 512f / 7;
|
||||||
return Math.Clamp((int)Math.Floor(position / local_x_divisor), 0, 6) + 1;
|
return Math.Clamp((int)MathF.Floor(position / local_x_divisor), 0, 6) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
float localXDivisor = 512f / TotalColumns;
|
float localXDivisor = 512f / TotalColumns;
|
||||||
return Math.Clamp((int)Math.Floor(position / localXDivisor), 0, TotalColumns - 1);
|
return Math.Clamp((int)MathF.Floor(position / localXDivisor), 0, TotalColumns - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Replays
|
namespace osu.Game.Rulesets.Mania.Replays
|
||||||
@ -84,7 +83,7 @@ namespace osu.Game.Rulesets.Mania.Replays
|
|||||||
var currentObject = Beatmap.HitObjects[i];
|
var currentObject = Beatmap.HitObjects[i];
|
||||||
var nextObjectInColumn = GetNextObject(i); // Get the next object that requires pressing the same button
|
var nextObjectInColumn = GetNextObject(i); // Get the next object that requires pressing the same button
|
||||||
|
|
||||||
double endTime = (currentObject as IHasEndTime)?.EndTime ?? currentObject.StartTime;
|
double endTime = currentObject.GetEndTime();
|
||||||
|
|
||||||
bool canDelayKeyUp = nextObjectInColumn == null ||
|
bool canDelayKeyUp = nextObjectInColumn == null ||
|
||||||
nextObjectInColumn.StartTime > endTime + RELEASE_DELAY;
|
nextObjectInColumn.StartTime > endTime + RELEASE_DELAY;
|
||||||
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
static ConvertValue createConvertValue(OsuHitObject obj) => new ConvertValue
|
static ConvertValue createConvertValue(OsuHitObject obj) => new ConvertValue
|
||||||
{
|
{
|
||||||
StartTime = obj.StartTime,
|
StartTime = obj.StartTime,
|
||||||
EndTime = (obj as IHasEndTime)?.EndTime ?? obj.StartTime,
|
EndTime = obj.GetEndTime(),
|
||||||
X = obj.StackedPosition.X,
|
X = obj.StackedPosition.X,
|
||||||
Y = obj.StackedPosition.Y
|
Y = obj.StackedPosition.Y
|
||||||
};
|
};
|
||||||
|
@ -16,9 +16,11 @@ using osu.Game.Audio;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Storyboards;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
@ -75,14 +77,14 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
protected override Player CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin);
|
protected override Player CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin);
|
||||||
|
|
||||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap) => new CustomSkinWorkingBeatmap(beatmap, Clock, audio, testBeatmapSkin);
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new CustomSkinWorkingBeatmap(beatmap, storyboard, Clock, audio, testBeatmapSkin);
|
||||||
|
|
||||||
public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap
|
public class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap
|
||||||
{
|
{
|
||||||
private readonly ISkinSource skin;
|
private readonly ISkinSource skin;
|
||||||
|
|
||||||
public CustomSkinWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin)
|
public CustomSkinWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock frameBasedClock, AudioManager audio, ISkinSource skin)
|
||||||
: base(beatmap, frameBasedClock, audio)
|
: base(beatmap, storyboard, frameBasedClock, audio)
|
||||||
{
|
{
|
||||||
this.skin = skin;
|
this.skin = skin;
|
||||||
}
|
}
|
||||||
@ -124,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
if (!enabled) return null;
|
if (!enabled) return null;
|
||||||
|
|
||||||
return new SpriteText
|
return new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = identifier,
|
Text = identifier,
|
||||||
Font = OsuFont.Default.With(size: 30),
|
Font = OsuFont.Default.With(size: 30),
|
||||||
|
@ -15,6 +15,7 @@ using osu.Game.Tests.Visual;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Game.Storyboards;
|
||||||
using static osu.Game.Tests.Visual.OsuTestScene.ClockBackedTestWorkingBeatmap;
|
using static osu.Game.Tests.Visual.OsuTestScene.ClockBackedTestWorkingBeatmap;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
@ -28,9 +29,9 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
protected override bool Autoplay => true;
|
protected override bool Autoplay => true;
|
||||||
|
|
||||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap)
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||||
{
|
{
|
||||||
var working = new ClockBackedTestWorkingBeatmap(beatmap, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
|
var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
|
||||||
track = (TrackVirtualManual)working.Track;
|
track = (TrackVirtualManual)working.Track;
|
||||||
return working;
|
return working;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
if (objectN is Spinner)
|
if (objectN is Spinner)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
|
double endTime = stackBaseObject.GetEndTime();
|
||||||
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
|
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
|
||||||
|
|
||||||
if (objectN.StartTime - endTime > stackThreshold)
|
if (objectN.StartTime - endTime > stackThreshold)
|
||||||
@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
OsuHitObject objectN = beatmap.HitObjects[n];
|
OsuHitObject objectN = beatmap.HitObjects[n];
|
||||||
if (objectN is Spinner) continue;
|
if (objectN is Spinner) continue;
|
||||||
|
|
||||||
double endTime = (objectN as IHasEndTime)?.EndTime ?? objectN.StartTime;
|
double endTime = objectN.GetEndTime();
|
||||||
|
|
||||||
if (objectI.StartTime - endTime > stackThreshold)
|
if (objectI.StartTime - endTime > stackThreshold)
|
||||||
//We are no longer within stacking range of the previous object.
|
//We are no longer within stacking range of the previous object.
|
||||||
@ -199,7 +199,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
if (currHitObject.StackHeight != 0 && !(currHitObject is Slider))
|
if (currHitObject.StackHeight != 0 && !(currHitObject is Slider))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double startTime = (currHitObject as IHasEndTime)?.EndTime ?? currHitObject.StartTime;
|
double startTime = currHitObject.GetEndTime();
|
||||||
int sliderStack = 0;
|
int sliderStack = 0;
|
||||||
|
|
||||||
for (int j = i + 1; j < beatmap.HitObjects.Count; j++)
|
for (int j = i + 1; j < beatmap.HitObjects.Count; j++)
|
||||||
@ -217,14 +217,14 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.Position) < stack_distance)
|
if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, currHitObject.Position) < stack_distance)
|
||||||
{
|
{
|
||||||
currHitObject.StackHeight++;
|
currHitObject.StackHeight++;
|
||||||
startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[j].StartTime;
|
startTime = beatmap.HitObjects[j].GetEndTime();
|
||||||
}
|
}
|
||||||
else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, position2) < stack_distance)
|
else if (Vector2Extensions.Distance(beatmap.HitObjects[j].Position, position2) < stack_distance)
|
||||||
{
|
{
|
||||||
//Case for sliders - bump notes down and right, rather than up and left.
|
//Case for sliders - bump notes down and right, rather than up and left.
|
||||||
sliderStack++;
|
sliderStack++;
|
||||||
beatmap.HitObjects[j].StackHeight -= sliderStack;
|
beatmap.HitObjects[j].StackHeight -= sliderStack;
|
||||||
startTime = (beatmap.HitObjects[j] as IHasEndTime)?.EndTime ?? beatmap.HitObjects[j].StartTime;
|
startTime = beatmap.HitObjects[j].GetEndTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components
|
|||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
|
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
|
||||||
|
|
||||||
CornerRadius = Size.X / 2;
|
CornerRadius = Size.X / 2;
|
||||||
|
CornerExponent = 2;
|
||||||
|
|
||||||
InternalChild = new RingPiece();
|
InternalChild = new RingPiece();
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
var fadeOutDuration = h.TimePreempt * fade_out_duration_multiplier;
|
var fadeOutDuration = h.TimePreempt * fade_out_duration_multiplier;
|
||||||
|
|
||||||
// new duration from completed fade in to end (before fading out)
|
// new duration from completed fade in to end (before fading out)
|
||||||
var longFadeDuration = ((h as IHasEndTime)?.EndTime ?? h.StartTime) - fadeOutStartTime;
|
var longFadeDuration = h.GetEndTime() - fadeOutStartTime;
|
||||||
|
|
||||||
switch (drawable)
|
switch (drawable)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
float appearDistance = (float)(hitObject.TimePreempt - hitObject.TimeFadeIn) / 2;
|
float appearDistance = (float)(hitObject.TimePreempt - hitObject.TimeFadeIn) / 2;
|
||||||
|
|
||||||
Vector2 originalPosition = drawable.Position;
|
Vector2 originalPosition = drawable.Position;
|
||||||
Vector2 appearOffset = new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta)) * appearDistance;
|
Vector2 appearOffset = new Vector2(MathF.Cos(theta), MathF.Sin(theta)) * appearDistance;
|
||||||
|
|
||||||
//the - 1 and + 1 prevents the hit objects to appear in the wrong position.
|
//the - 1 and + 1 prevents the hit objects to appear in the wrong position.
|
||||||
double appearTime = hitObject.StartTime - hitObject.TimePreempt - 1;
|
double appearTime = hitObject.StartTime - hitObject.TimePreempt - 1;
|
||||||
|
@ -25,11 +25,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.FollowPoint), _ => new Container
|
Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.FollowPoint), _ => new CircularContainer
|
||||||
{
|
{
|
||||||
Masking = true,
|
Masking = true,
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
CornerRadius = width / 2,
|
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
|
@ -6,7 +6,7 @@ using JetBrains.Annotations;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
||||||
@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
|
|
||||||
Vector2 startPosition = osuStart.EndPosition;
|
Vector2 startPosition = osuStart.EndPosition;
|
||||||
Vector2 endPosition = osuEnd.Position;
|
Vector2 endPosition = osuEnd.Position;
|
||||||
double startTime = (osuStart as IHasEndTime)?.EndTime ?? osuStart.StartTime;
|
double startTime = osuStart.GetEndTime();
|
||||||
double endTime = osuEnd.StartTime;
|
double endTime = osuEnd.StartTime;
|
||||||
|
|
||||||
Vector2 distanceVector = endPosition - startPosition;
|
Vector2 distanceVector = endPosition - startPosition;
|
||||||
|
@ -120,7 +120,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float aimRotation = MathHelper.RadiansToDegrees((float)Math.Atan2(aimRotationVector.Y - Position.Y, aimRotationVector.X - Position.X));
|
float aimRotation = MathHelper.RadiansToDegrees(MathF.Atan2(aimRotationVector.Y - Position.Y, aimRotationVector.X - Position.X));
|
||||||
while (Math.Abs(aimRotation - Rotation) > 180)
|
while (Math.Abs(aimRotation - Rotation) > 180)
|
||||||
aimRotation += aimRotation < Rotation ? 360 : -360;
|
aimRotation += aimRotation < Rotation ? 360 : -360;
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
{
|
{
|
||||||
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
|
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
|
||||||
Masking = true;
|
Masking = true;
|
||||||
|
|
||||||
CornerRadius = Size.X / 2;
|
CornerRadius = Size.X / 2;
|
||||||
|
CornerExponent = 2;
|
||||||
|
|
||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
@ -18,10 +18,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
InternalChild = new Container
|
InternalChild = new CircularContainer
|
||||||
{
|
{
|
||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = Size.X / 2,
|
|
||||||
BorderThickness = 10,
|
BorderThickness = 10,
|
||||||
BorderColour = Color4.White,
|
BorderColour = Color4.White,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
@ -20,9 +20,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
const int count = 18;
|
const float count = 18;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (float i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
Add(new Container
|
Add(new Container
|
||||||
{
|
{
|
||||||
@ -40,10 +40,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
Size = new Vector2(60, 10),
|
Size = new Vector2(60, 10),
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Position = new Vector2(
|
Position = new Vector2(
|
||||||
0.5f + (float)Math.Sin((float)i / count * 2 * MathHelper.Pi) / 2 * 0.86f,
|
0.5f + MathF.Sin(i / count * 2 * MathF.PI) / 2 * 0.86f,
|
||||||
0.5f + (float)Math.Cos((float)i / count * 2 * MathHelper.Pi) / 2 * 0.86f
|
0.5f + MathF.Cos(i / count * 2 * MathF.PI) / 2 * 0.86f
|
||||||
),
|
),
|
||||||
Rotation = -(float)i / count * 360 + 90,
|
Rotation = -i / count * 360 + 90,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
|
@ -10,7 +10,7 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||||
using osu.Game.Rulesets.Osu.Scoring;
|
using osu.Game.Rulesets.Osu.Scoring;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
|
|
||||||
private void addDelayedMovements(OsuHitObject h, OsuHitObject prev)
|
private void addDelayedMovements(OsuHitObject h, OsuHitObject prev)
|
||||||
{
|
{
|
||||||
double endTime = (prev as IHasEndTime)?.EndTime ?? prev.StartTime;
|
double endTime = prev.GetEndTime();
|
||||||
|
|
||||||
HitWindows hitWindows = null;
|
HitWindows hitWindows = null;
|
||||||
|
|
||||||
@ -185,14 +185,14 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
{
|
{
|
||||||
Vector2 spinCentreOffset = SPINNER_CENTRE - prevPos;
|
Vector2 spinCentreOffset = SPINNER_CENTRE - prevPos;
|
||||||
float distFromCentre = spinCentreOffset.Length;
|
float distFromCentre = spinCentreOffset.Length;
|
||||||
float distToTangentPoint = (float)Math.Sqrt(distFromCentre * distFromCentre - SPIN_RADIUS * SPIN_RADIUS);
|
float distToTangentPoint = MathF.Sqrt(distFromCentre * distFromCentre - SPIN_RADIUS * SPIN_RADIUS);
|
||||||
|
|
||||||
if (distFromCentre > SPIN_RADIUS)
|
if (distFromCentre > SPIN_RADIUS)
|
||||||
{
|
{
|
||||||
// Previous cursor position was outside spin circle, set startPosition to the tangent point.
|
// Previous cursor position was outside spin circle, set startPosition to the tangent point.
|
||||||
|
|
||||||
// Angle between centre offset and tangent point offset.
|
// Angle between centre offset and tangent point offset.
|
||||||
float angle = (float)Math.Asin(SPIN_RADIUS / distFromCentre);
|
float angle = MathF.Asin(SPIN_RADIUS / distFromCentre);
|
||||||
|
|
||||||
if (angle > 0)
|
if (angle > 0)
|
||||||
{
|
{
|
||||||
@ -204,8 +204,8 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rotate by angle so it's parallel to tangent line
|
// Rotate by angle so it's parallel to tangent line
|
||||||
spinCentreOffset.X = spinCentreOffset.X * (float)Math.Cos(angle) - spinCentreOffset.Y * (float)Math.Sin(angle);
|
spinCentreOffset.X = spinCentreOffset.X * MathF.Cos(angle) - spinCentreOffset.Y * MathF.Sin(angle);
|
||||||
spinCentreOffset.Y = spinCentreOffset.X * (float)Math.Sin(angle) + spinCentreOffset.Y * (float)Math.Cos(angle);
|
spinCentreOffset.Y = spinCentreOffset.X * MathF.Sin(angle) + spinCentreOffset.Y * MathF.Cos(angle);
|
||||||
|
|
||||||
// Set length to distToTangentPoint
|
// Set length to distToTangentPoint
|
||||||
spinCentreOffset.Normalize();
|
spinCentreOffset.Normalize();
|
||||||
@ -275,7 +275,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
var startFrame = new OsuReplayFrame(h.StartTime, new Vector2(startPosition.X, startPosition.Y), action);
|
var startFrame = new OsuReplayFrame(h.StartTime, new Vector2(startPosition.X, startPosition.Y), action);
|
||||||
|
|
||||||
// TODO: Why do we delay 1 ms if the object is a spinner? There already is KEY_UP_DELAY from hEndTime.
|
// TODO: Why do we delay 1 ms if the object is a spinner? There already is KEY_UP_DELAY from hEndTime.
|
||||||
double hEndTime = ((h as IHasEndTime)?.EndTime ?? h.StartTime) + KEY_UP_DELAY;
|
double hEndTime = h.GetEndTime() + KEY_UP_DELAY;
|
||||||
int endDelay = h is Spinner ? 1 : 0;
|
int endDelay = h is Spinner ? 1 : 0;
|
||||||
var endFrame = new OsuReplayFrame(hEndTime + endDelay, new Vector2(h.StackedEndPosition.X, h.StackedEndPosition.Y));
|
var endFrame = new OsuReplayFrame(hEndTime + endDelay, new Vector2(h.StackedEndPosition.X, h.StackedEndPosition.Y));
|
||||||
|
|
||||||
@ -331,7 +331,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
Vector2 difference = startPosition - SPINNER_CENTRE;
|
Vector2 difference = startPosition - SPINNER_CENTRE;
|
||||||
|
|
||||||
float radius = difference.Length;
|
float radius = difference.Length;
|
||||||
float angle = radius == 0 ? 0 : (float)Math.Atan2(difference.Y, difference.X);
|
float angle = radius == 0 ? 0 : MathF.Atan2(difference.Y, difference.X);
|
||||||
|
|
||||||
double t;
|
double t;
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
@ -27,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
yield return new ConvertValue
|
yield return new ConvertValue
|
||||||
{
|
{
|
||||||
StartTime = hitObject.StartTime,
|
StartTime = hitObject.StartTime,
|
||||||
EndTime = (hitObject as IHasEndTime)?.EndTime ?? hitObject.StartTime,
|
EndTime = hitObject.GetEndTime(),
|
||||||
IsRim = hitObject is RimHit,
|
IsRim = hitObject is RimHit,
|
||||||
IsCentre = hitObject is CentreHit,
|
IsCentre = hitObject is CentreHit,
|
||||||
IsDrumRoll = hitObject is DrumRoll,
|
IsDrumRoll = hitObject is DrumRoll,
|
||||||
|
2
osu.Game.Tests/Resources/skin-20.ini
Normal file
2
osu.Game.Tests/Resources/skin-20.ini
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[General]
|
||||||
|
Version: 2
|
2
osu.Game.Tests/Resources/skin-latest.ini
Normal file
2
osu.Game.Tests/Resources/skin-latest.ini
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[General]
|
||||||
|
Version: latest
|
@ -59,5 +59,32 @@ namespace osu.Game.Tests.Skins
|
|||||||
Assert.AreEqual("TestValue", config.ConfigDictionary["TestLookup"]);
|
Assert.AreEqual("TestValue", config.ConfigDictionary["TestLookup"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDecodeSpecifiedVersion()
|
||||||
|
{
|
||||||
|
var decoder = new LegacySkinDecoder();
|
||||||
|
using (var resStream = TestResources.OpenResource("skin-20.ini"))
|
||||||
|
using (var stream = new LineBufferedReader(resStream))
|
||||||
|
Assert.AreEqual(2.0m, decoder.Decode(stream).LegacyVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDecodeLatestVersion()
|
||||||
|
{
|
||||||
|
var decoder = new LegacySkinDecoder();
|
||||||
|
using (var resStream = TestResources.OpenResource("skin-latest.ini"))
|
||||||
|
using (var stream = new LineBufferedReader(resStream))
|
||||||
|
Assert.AreEqual(LegacySkinConfiguration.LATEST_VERSION, decoder.Decode(stream).LegacyVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDecodeNoVersion()
|
||||||
|
{
|
||||||
|
var decoder = new LegacySkinDecoder();
|
||||||
|
using (var resStream = TestResources.OpenResource("skin-empty.ini"))
|
||||||
|
using (var stream = new LineBufferedReader(resStream))
|
||||||
|
Assert.IsNull(decoder.Decode(stream).LegacyVersion);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,14 @@ namespace osu.Game.Tests.Skins
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLegacyVersionLookup()
|
||||||
|
{
|
||||||
|
AddStep("Set source1 version 2.3", () => source1.Configuration.LegacyVersion = 2.3m);
|
||||||
|
AddStep("Set source2 version null", () => source2.Configuration.LegacyVersion = null);
|
||||||
|
AddAssert("Check legacy version lookup", () => requester.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value == 2.3m);
|
||||||
|
}
|
||||||
|
|
||||||
public enum LookupType
|
public enum LookupType
|
||||||
{
|
{
|
||||||
Test
|
Test
|
||||||
|
@ -7,6 +7,7 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Storyboards;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
@ -29,9 +30,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddUntilStep("key counter reset", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
AddUntilStep("key counter reset", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap)
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||||
{
|
{
|
||||||
var working = base.CreateWorkingBeatmap(beatmap);
|
var working = base.CreateWorkingBeatmap(beatmap, storyboard);
|
||||||
|
|
||||||
track = (ClockBackedTestWorkingBeatmap.TrackVirtualManual)working.Track;
|
track = (ClockBackedTestWorkingBeatmap.TrackVirtualManual)working.Track;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ using osu.Game.Rulesets.Judgements;
|
|||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Catch.Scoring;
|
using osu.Game.Rulesets.Catch.Scoring;
|
||||||
using osu.Game.Rulesets.Mania.Scoring;
|
using osu.Game.Rulesets.Mania.Scoring;
|
||||||
using osu.Game.Rulesets.Osu.Scoring;
|
using osu.Game.Rulesets.Osu.Scoring;
|
||||||
@ -85,9 +85,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
new SpriteText { Text = $@"Great: {hitWindows?.WindowFor(HitResult.Great)}" },
|
new OsuSpriteText { Text = $@"Great: {hitWindows?.WindowFor(HitResult.Great)}" },
|
||||||
new SpriteText { Text = $@"Good: {hitWindows?.WindowFor(HitResult.Good)}" },
|
new OsuSpriteText { Text = $@"Good: {hitWindows?.WindowFor(HitResult.Good)}" },
|
||||||
new SpriteText { Text = $@"Meh: {hitWindows?.WindowFor(HitResult.Meh)}" },
|
new OsuSpriteText { Text = $@"Meh: {hitWindows?.WindowFor(HitResult.Meh)}" },
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ using osu.Game.Rulesets.Osu.Objects;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Storyboards;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
@ -35,9 +36,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
private Track track;
|
private Track track;
|
||||||
|
|
||||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap)
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||||
{
|
{
|
||||||
var working = new ClockBackedTestWorkingBeatmap(beatmap, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
|
var working = new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
|
||||||
track = working.Track;
|
track = working.Track;
|
||||||
return working;
|
return working;
|
||||||
}
|
}
|
||||||
|
113
osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs
Normal file
113
osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Storyboards;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
|
{
|
||||||
|
public class TestSceneLeadIn : RateAdjustedBeatmapTestScene
|
||||||
|
{
|
||||||
|
private LeadInPlayer player;
|
||||||
|
|
||||||
|
private const double lenience_ms = 10;
|
||||||
|
|
||||||
|
private const double first_hit_object = 2170;
|
||||||
|
|
||||||
|
[TestCase(1000, 0)]
|
||||||
|
[TestCase(2000, 0)]
|
||||||
|
[TestCase(3000, first_hit_object - 3000)]
|
||||||
|
[TestCase(10000, first_hit_object - 10000)]
|
||||||
|
public void TestLeadInProducesCorrectStartTime(double leadIn, double expectedStartTime)
|
||||||
|
{
|
||||||
|
loadPlayerWithBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo)
|
||||||
|
{
|
||||||
|
BeatmapInfo = { AudioLeadIn = leadIn }
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert($"first frame is {expectedStartTime}", () =>
|
||||||
|
{
|
||||||
|
Debug.Assert(player.FirstFrameClockTime != null);
|
||||||
|
return Precision.AlmostEquals(player.FirstFrameClockTime.Value, expectedStartTime, lenience_ms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(1000, 0)]
|
||||||
|
[TestCase(0, 0)]
|
||||||
|
[TestCase(-1000, -1000)]
|
||||||
|
[TestCase(-10000, -10000)]
|
||||||
|
public void TestStoryboardProducesCorrectStartTime(double firstStoryboardEvent, double expectedStartTime)
|
||||||
|
{
|
||||||
|
var storyboard = new Storyboard();
|
||||||
|
|
||||||
|
var sprite = new StoryboardSprite("unknown", Anchor.TopLeft, Vector2.Zero);
|
||||||
|
sprite.TimelineGroup.Alpha.Add(Easing.None, firstStoryboardEvent, firstStoryboardEvent + 500, 0, 1);
|
||||||
|
|
||||||
|
storyboard.GetLayer("Background").Add(sprite);
|
||||||
|
|
||||||
|
loadPlayerWithBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo), storyboard);
|
||||||
|
|
||||||
|
AddAssert($"first frame is {expectedStartTime}", () =>
|
||||||
|
{
|
||||||
|
Debug.Assert(player.FirstFrameClockTime != null);
|
||||||
|
return Precision.AlmostEquals(player.FirstFrameClockTime.Value, expectedStartTime, lenience_ms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadPlayerWithBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||||
|
{
|
||||||
|
AddStep("create player", () =>
|
||||||
|
{
|
||||||
|
Beatmap.Value = CreateWorkingBeatmap(beatmap, storyboard);
|
||||||
|
LoadScreen(player = new LeadInPlayer());
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("player loaded", () => player.IsLoaded && player.Alpha == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class LeadInPlayer : TestPlayer
|
||||||
|
{
|
||||||
|
public LeadInPlayer()
|
||||||
|
: base(false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public double? FirstFrameClockTime;
|
||||||
|
|
||||||
|
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
|
||||||
|
|
||||||
|
public double GameplayStartTime => DrawableRuleset.GameplayStartTime;
|
||||||
|
|
||||||
|
public double FirstHitObjectTime => DrawableRuleset.Objects.First().StartTime;
|
||||||
|
|
||||||
|
public double GameplayClockTime => GameplayClockContainer.GameplayClock.CurrentTime;
|
||||||
|
|
||||||
|
protected override void UpdateAfterChildren()
|
||||||
|
{
|
||||||
|
base.UpdateAfterChildren();
|
||||||
|
|
||||||
|
if (!FirstFrameClockTime.HasValue)
|
||||||
|
{
|
||||||
|
FirstFrameClockTime = GameplayClockContainer.GameplayClock.CurrentTime;
|
||||||
|
AddInternal(new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = $"GameplayStartTime: {DrawableRuleset.GameplayStartTime} "
|
||||||
|
+ $"FirstHitObjectTime: {FirstHitObjectTime} "
|
||||||
|
+ $"LeadInTime: {Beatmap.Value.BeatmapInfo.AudioLeadIn} "
|
||||||
|
+ $"FirstFrameClockTime: {FirstFrameClockTime}"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ using osu.Framework.Lists;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Storyboards;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
@ -42,9 +43,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap)
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||||
{
|
{
|
||||||
var working = base.CreateWorkingBeatmap(beatmap);
|
var working = base.CreateWorkingBeatmap(beatmap, storyboard);
|
||||||
workingWeakReferences.Add(working);
|
workingWeakReferences.Add(working);
|
||||||
return working;
|
return working;
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Framework.Timing;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -18,25 +18,37 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private SkipOverlay skip;
|
private SkipOverlay skip;
|
||||||
private int requestCount;
|
private int requestCount;
|
||||||
|
|
||||||
|
private double increment;
|
||||||
|
|
||||||
|
private GameplayClockContainer gameplayClockContainer;
|
||||||
|
private GameplayClock gameplayClock;
|
||||||
|
|
||||||
|
private const double skip_time = 6000;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
requestCount = 0;
|
requestCount = 0;
|
||||||
Child = new Container
|
increment = skip_time;
|
||||||
|
|
||||||
|
Child = gameplayClockContainer = new GameplayClockContainer(CreateWorkingBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)), new Mod[] { }, 0)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Clock = new FramedOffsetClock(Clock)
|
|
||||||
{
|
|
||||||
Offset = -Clock.CurrentTime,
|
|
||||||
},
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
skip = new SkipOverlay(6000)
|
skip = new SkipOverlay(skip_time)
|
||||||
{
|
{
|
||||||
RequestSeek = _ => requestCount++
|
RequestSkip = () =>
|
||||||
|
{
|
||||||
|
requestCount++;
|
||||||
|
gameplayClockContainer.Seek(gameplayClock.CurrentTime + increment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gameplayClockContainer.Start();
|
||||||
|
gameplayClock = gameplayClockContainer.GameplayClock;
|
||||||
});
|
});
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -64,19 +76,35 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public void TestClickOnlyActuatesOnce()
|
public void TestClickOnlyActuatesOnce()
|
||||||
{
|
{
|
||||||
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
||||||
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
AddStep("click", () =>
|
||||||
|
{
|
||||||
|
increment = skip_time - gameplayClock.CurrentTime - GameplayClockContainer.MINIMUM_SKIP_TIME / 2;
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
checkRequestCount(1);
|
checkRequestCount(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestClickOnlyActuatesMultipleTimes()
|
||||||
|
{
|
||||||
|
AddStep("set increment lower", () => increment = 3000);
|
||||||
|
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
||||||
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
|
checkRequestCount(2);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestDoesntFadeOnMouseDown()
|
public void TestDoesntFadeOnMouseDown()
|
||||||
{
|
{
|
||||||
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
AddStep("move mouse", () => InputManager.MoveMouseTo(skip.ScreenSpaceDrawQuad.Centre));
|
||||||
AddStep("button down", () => InputManager.PressButton(MouseButton.Left));
|
AddStep("button down", () => InputManager.PressButton(MouseButton.Left));
|
||||||
AddUntilStep("wait for overlay disapper", () => !skip.IsAlive);
|
AddUntilStep("wait for overlay disappear", () => !skip.IsPresent);
|
||||||
AddAssert("ensure button didn't disappear", () => skip.Children.First().Alpha > 0);
|
AddAssert("ensure button didn't disappear", () => skip.Children.First().Alpha > 0);
|
||||||
AddStep("button up", () => InputManager.ReleaseButton(MouseButton.Left));
|
AddStep("button up", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
checkRequestCount(0);
|
checkRequestCount(0);
|
||||||
|
@ -42,6 +42,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(BeatmapAvailability),
|
typeof(BeatmapAvailability),
|
||||||
typeof(BeatmapRulesetSelector),
|
typeof(BeatmapRulesetSelector),
|
||||||
typeof(BeatmapRulesetTabItem),
|
typeof(BeatmapRulesetTabItem),
|
||||||
|
typeof(NotSupporterPlaceholder)
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override bool UseOnlineAPI => true;
|
protected override bool UseOnlineAPI => true;
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Overlays.BeatmapSet;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Mania;
|
||||||
|
using osu.Game.Rulesets.Taiko;
|
||||||
|
using osu.Game.Rulesets.Catch;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneLeaderboardModSelector : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(LeaderboardModSelector),
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestSceneLeaderboardModSelector()
|
||||||
|
{
|
||||||
|
LeaderboardModSelector modSelector;
|
||||||
|
FillFlowContainer<SpriteText> selectedMods;
|
||||||
|
var ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
|
Add(selectedMods = new FillFlowContainer<SpriteText>
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
});
|
||||||
|
|
||||||
|
Add(modSelector = new LeaderboardModSelector
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Ruleset = { BindTarget = ruleset }
|
||||||
|
});
|
||||||
|
|
||||||
|
modSelector.SelectedMods.ItemsAdded += mods =>
|
||||||
|
{
|
||||||
|
mods.ForEach(mod => selectedMods.Add(new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = mod.Acronym,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
modSelector.SelectedMods.ItemsRemoved += mods =>
|
||||||
|
{
|
||||||
|
mods.ForEach(mod =>
|
||||||
|
{
|
||||||
|
foreach (var selected in selectedMods)
|
||||||
|
{
|
||||||
|
if (selected.Text == mod.Acronym)
|
||||||
|
{
|
||||||
|
selectedMods.Remove(selected);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
AddStep("osu ruleset", () => ruleset.Value = new OsuRuleset().RulesetInfo);
|
||||||
|
AddStep("mania ruleset", () => ruleset.Value = new ManiaRuleset().RulesetInfo);
|
||||||
|
AddStep("taiko ruleset", () => ruleset.Value = new TaikoRuleset().RulesetInfo);
|
||||||
|
AddStep("catch ruleset", () => ruleset.Value = new CatchRuleset().RulesetInfo);
|
||||||
|
AddStep("Deselect all", () => modSelector.DeselectAll());
|
||||||
|
AddStep("null ruleset", () => ruleset.Value = null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Overlays.Rankings;
|
using osu.Game.Overlays.Rankings;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -45,7 +46,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Size = new Vector2(30, 20),
|
Size = new Vector2(30, 20),
|
||||||
Country = countryA,
|
Country = countryA,
|
||||||
},
|
},
|
||||||
text = new SpriteText
|
text = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
|
@ -11,7 +11,7 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Rulesets.Mania;
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Taiko;
|
using osu.Game.Rulesets.Taiko;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
@ -94,11 +94,11 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
AddRange(new Drawable[]
|
AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = $@"Username: {user.NewValue?.Username}"
|
Text = $@"Username: {user.NewValue?.Username}"
|
||||||
},
|
},
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = $@"RankedScore: {user.NewValue?.Statistics.RankedScore}"
|
Text = $@"RankedScore: {user.NewValue?.Statistics.RankedScore}"
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -13,6 +14,7 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Beatmaps.Legacy;
|
using osu.Game.Beatmaps.Legacy;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
@ -23,6 +25,9 @@ namespace osu.Game.Tournament.Components
|
|||||||
{
|
{
|
||||||
private BeatmapInfo beatmap;
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||||
|
|
||||||
public BeatmapInfo Beatmap
|
public BeatmapInfo Beatmap
|
||||||
{
|
{
|
||||||
get => beatmap;
|
get => beatmap;
|
||||||
@ -106,6 +111,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
Width = main_width,
|
Width = main_width,
|
||||||
Height = TournamentBeatmapPanel.HEIGHT,
|
Height = TournamentBeatmapPanel.HEIGHT,
|
||||||
CornerRadius = TournamentBeatmapPanel.HEIGHT / 2,
|
CornerRadius = TournamentBeatmapPanel.HEIGHT / 2,
|
||||||
|
CornerExponent = 2,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
@ -126,6 +132,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
{
|
{
|
||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = TournamentBeatmapPanel.HEIGHT / 2,
|
CornerRadius = TournamentBeatmapPanel.HEIGHT / 2,
|
||||||
|
CornerExponent = 2,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
@ -163,7 +170,8 @@ namespace osu.Game.Tournament.Components
|
|||||||
string hardRockExtra = "";
|
string hardRockExtra = "";
|
||||||
string srExtra = "";
|
string srExtra = "";
|
||||||
|
|
||||||
//var ar = beatmap.BaseDifficulty.ApproachRate;
|
var ar = beatmap.BaseDifficulty.ApproachRate;
|
||||||
|
|
||||||
if ((mods & LegacyMods.HardRock) > 0)
|
if ((mods & LegacyMods.HardRock) > 0)
|
||||||
{
|
{
|
||||||
hardRockExtra = "*";
|
hardRockExtra = "*";
|
||||||
@ -172,12 +180,46 @@ namespace osu.Game.Tournament.Components
|
|||||||
|
|
||||||
if ((mods & LegacyMods.DoubleTime) > 0)
|
if ((mods & LegacyMods.DoubleTime) > 0)
|
||||||
{
|
{
|
||||||
//ar *= 1.5f;
|
// temporary local calculation (taken from OsuDifficultyCalculator)
|
||||||
|
double preempt = (int)BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / 1.5;
|
||||||
|
ar = (float)(preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5);
|
||||||
|
|
||||||
bpm *= 1.5f;
|
bpm *= 1.5f;
|
||||||
length /= 1.5f;
|
length /= 1.5f;
|
||||||
srExtra = "*";
|
srExtra = "*";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(string heading, string content)[] stats;
|
||||||
|
|
||||||
|
switch (ruleset.Value.ID)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
stats = new (string heading, string content)[]
|
||||||
|
{
|
||||||
|
("CS", $"{beatmap.BaseDifficulty.CircleSize:0.#}{hardRockExtra}"),
|
||||||
|
("AR", $"{ar:0.#}{hardRockExtra}"),
|
||||||
|
("OD", $"{beatmap.BaseDifficulty.OverallDifficulty:0.#}{hardRockExtra}"),
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
stats = new (string heading, string content)[]
|
||||||
|
{
|
||||||
|
("OD", $"{beatmap.BaseDifficulty.OverallDifficulty:0.#}{hardRockExtra}"),
|
||||||
|
("HP", $"{beatmap.BaseDifficulty.DrainRate:0.#}{hardRockExtra}")
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
stats = new (string heading, string content)[]
|
||||||
|
{
|
||||||
|
("CS", $"{beatmap.BaseDifficulty.CircleSize:0.#}{hardRockExtra}"),
|
||||||
|
("AR", $"{ar:0.#}"),
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
panelContents.Children = new Drawable[]
|
panelContents.Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new DiffPiece(("Length", TimeSpan.FromMilliseconds(length).ToString(@"mm\:ss")))
|
new DiffPiece(("Length", TimeSpan.FromMilliseconds(length).ToString(@"mm\:ss")))
|
||||||
@ -190,12 +232,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.TopLeft
|
Origin = Anchor.TopLeft
|
||||||
},
|
},
|
||||||
new DiffPiece(
|
new DiffPiece(stats)
|
||||||
//("CS", $"{beatmap.BaseDifficulty.CircleSize:0.#}{hardRockExtra}"),
|
|
||||||
//("AR", $"{ar:0.#}{srExtra}"),
|
|
||||||
("OD", $"{beatmap.BaseDifficulty.OverallDifficulty:0.#}{hardRockExtra}"),
|
|
||||||
("HP", $"{beatmap.BaseDifficulty.DrainRate:0.#}{hardRockExtra}")
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreRight,
|
Anchor = Anchor.CentreRight,
|
||||||
Origin = Anchor.BottomRight
|
Origin = Anchor.BottomRight
|
||||||
|
@ -52,6 +52,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
currentMatch.BindTo(ladder.CurrentMatch);
|
currentMatch.BindTo(ladder.CurrentMatch);
|
||||||
|
|
||||||
CornerRadius = HEIGHT / 2;
|
CornerRadius = HEIGHT / 2;
|
||||||
|
CornerExponent = 2;
|
||||||
Masking = true;
|
Masking = true;
|
||||||
|
|
||||||
AddRangeInternal(new Drawable[]
|
AddRangeInternal(new Drawable[]
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
|
|||||||
groups.Add(g);
|
groups.Add(g);
|
||||||
nextGroupName++;
|
nextGroupName++;
|
||||||
|
|
||||||
if (i < (int)Math.Ceiling(numGroups / 2f))
|
if (i < (int)MathF.Ceiling(numGroups / 2f))
|
||||||
topGroups.Add(g);
|
topGroups.Add(g);
|
||||||
else
|
else
|
||||||
bottomGroups.Add(g);
|
bottomGroups.Add(g);
|
||||||
|
@ -100,7 +100,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
|||||||
var diff = Math.Max(score1.Value, score2.Value) - Math.Min(score1.Value, score2.Value);
|
var diff = Math.Max(score1.Value, score2.Value) - Math.Min(score1.Value, score2.Value);
|
||||||
|
|
||||||
losingBar.ResizeWidthTo(0, 400, Easing.OutQuint);
|
losingBar.ResizeWidthTo(0, 400, Easing.OutQuint);
|
||||||
winningBar.ResizeWidthTo(Math.Min(0.4f, (float)Math.Pow(diff / 1500000f, 0.5) / 2), 400, Easing.OutQuint);
|
winningBar.ResizeWidthTo(Math.Min(0.4f, MathF.Pow(diff / 1500000f, 0.5f) / 2), 400, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
@ -12,13 +12,13 @@ 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.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Tournament.IPC;
|
using osu.Game.Tournament.IPC;
|
||||||
using osu.Game.Tournament.Models;
|
using osu.Game.Tournament.Models;
|
||||||
@ -104,7 +104,7 @@ namespace osu.Game.Tournament
|
|||||||
Colour = Color4.Red,
|
Colour = Color4.Red,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = "Please make the window wider",
|
Text = "Please make the window wider",
|
||||||
Font = OsuFont.Default.With(weight: "bold"),
|
Font = OsuFont.Default.With(weight: "bold"),
|
||||||
@ -202,7 +202,8 @@ namespace osu.Game.Tournament
|
|||||||
{
|
{
|
||||||
foreach (var p in t.Players)
|
foreach (var p in t.Players)
|
||||||
{
|
{
|
||||||
PopulateUser(p);
|
if (p.Username == null || p.Statistics == null)
|
||||||
|
PopulateUser(p);
|
||||||
addedInfo = true;
|
addedInfo = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,7 +244,6 @@ namespace osu.Game.Tournament
|
|||||||
{
|
{
|
||||||
user.Username = res.Username;
|
user.Username = res.Username;
|
||||||
user.Statistics = res.Statistics;
|
user.Statistics = res.Statistics;
|
||||||
user.Username = res.Username;
|
|
||||||
user.Country = res.Country;
|
user.Country = res.Country;
|
||||||
user.Cover = res.Cover;
|
user.Cover = res.Cover;
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Beatmaps
|
|||||||
public string MD5Hash { get; set; }
|
public string MD5Hash { get; set; }
|
||||||
|
|
||||||
// General
|
// General
|
||||||
public int AudioLeadIn { get; set; }
|
public double AudioLeadIn { get; set; }
|
||||||
public bool Countdown { get; set; } = true;
|
public bool Countdown { get; set; } = true;
|
||||||
public float StackLeniency { get; set; } = 0.7f;
|
public float StackLeniency { get; set; } = 0.7f;
|
||||||
public bool SpecialStyle { get; set; }
|
public bool SpecialStyle { get; set; }
|
||||||
|
@ -25,7 +25,7 @@ using osu.Game.IO.Archives;
|
|||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
{
|
{
|
||||||
@ -334,7 +334,8 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
var lastObject = b.HitObjects.Last();
|
var lastObject = b.HitObjects.Last();
|
||||||
|
|
||||||
double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
|
//TODO: this isn't always correct (consider mania where a non-last object may last for longer than the last in the list).
|
||||||
|
double endTime = lastObject.GetEndTime();
|
||||||
double startTime = b.HitObjects.First().StartTime;
|
double startTime = b.HitObjects.First().StartTime;
|
||||||
|
|
||||||
return endTime - startTime;
|
return endTime - startTime;
|
||||||
|
11
osu.Game/Configuration/BackgroundSource.cs
Normal file
11
osu.Game/Configuration/BackgroundSource.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
namespace osu.Game.Configuration
|
||||||
|
{
|
||||||
|
public enum BackgroundSource
|
||||||
|
{
|
||||||
|
Skin,
|
||||||
|
Beatmap
|
||||||
|
}
|
||||||
|
}
|
@ -117,6 +117,8 @@ namespace osu.Game.Configuration
|
|||||||
Set(OsuSetting.UIHoldActivationDelay, 200f, 0f, 500f, 50f);
|
Set(OsuSetting.UIHoldActivationDelay, 200f, 0f, 500f, 50f);
|
||||||
|
|
||||||
Set(OsuSetting.IntroSequence, IntroSequence.Triangles);
|
Set(OsuSetting.IntroSequence, IntroSequence.Triangles);
|
||||||
|
|
||||||
|
Set(OsuSetting.MenuBackgroundSource, BackgroundSource.Skin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OsuConfigManager(Storage storage)
|
public OsuConfigManager(Storage storage)
|
||||||
@ -186,6 +188,7 @@ namespace osu.Game.Configuration
|
|||||||
UIScale,
|
UIScale,
|
||||||
IntroSequence,
|
IntroSequence,
|
||||||
UIHoldActivationDelay,
|
UIHoldActivationDelay,
|
||||||
HitLighting
|
HitLighting,
|
||||||
|
MenuBackgroundSource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
osu.Game/Graphics/Backgrounds/BeatmapBackground.cs
Normal file
28
osu.Game/Graphics/Backgrounds/BeatmapBackground.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.Backgrounds
|
||||||
|
{
|
||||||
|
public class BeatmapBackground : Background
|
||||||
|
{
|
||||||
|
public readonly WorkingBeatmap Beatmap;
|
||||||
|
|
||||||
|
private readonly string fallbackTextureName;
|
||||||
|
|
||||||
|
public BeatmapBackground(WorkingBeatmap beatmap, string fallbackTextureName = @"Backgrounds/bg1")
|
||||||
|
{
|
||||||
|
Beatmap = beatmap;
|
||||||
|
this.fallbackTextureName = fallbackTextureName;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
Sprite.Texture = Beatmap?.Background ?? textures.Get(fallbackTextureName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -111,7 +111,7 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
|
|
||||||
float adjustedAlpha = HideAlphaDiscrepancies
|
float adjustedAlpha = HideAlphaDiscrepancies
|
||||||
// Cubically scale alpha to make it drop off more sharply.
|
// Cubically scale alpha to make it drop off more sharply.
|
||||||
? (float)Math.Pow(DrawColourInfo.Colour.AverageColour.Linear.A, 3)
|
? MathF.Pow(DrawColourInfo.Colour.AverageColour.Linear.A, 3)
|
||||||
: 1;
|
: 1;
|
||||||
|
|
||||||
float elapsedSeconds = (float)Time.Elapsed / 1000;
|
float elapsedSeconds = (float)Time.Elapsed / 1000;
|
||||||
|
@ -10,7 +10,7 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
public class DimmedLoadingLayer : VisibilityContainer
|
public class DimmedLoadingLayer : OverlayContainer
|
||||||
{
|
{
|
||||||
private const float transition_duration = 250;
|
private const float transition_duration = 250;
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ namespace osu.Game.Online.API
|
|||||||
private class DisplayableError
|
private class DisplayableError
|
||||||
{
|
{
|
||||||
[JsonProperty("error")]
|
[JsonProperty("error")]
|
||||||
public string ErrorMessage;
|
public string ErrorMessage { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,13 +10,11 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
private readonly BeatmapInfo beatmap;
|
private readonly BeatmapInfo beatmap;
|
||||||
|
|
||||||
private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.MD5Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}";
|
|
||||||
|
|
||||||
public GetBeatmapRequest(BeatmapInfo beatmap)
|
public GetBeatmapRequest(BeatmapInfo beatmap)
|
||||||
{
|
{
|
||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string Target => $@"beatmaps/{lookupString}";
|
protected override string Target => $@"beatmaps/lookup?id={beatmap.OnlineBeatmapID}&checksum={beatmap.MD5Hash}&filename={System.Uri.EscapeUriString(beatmap.Path ?? string.Empty)}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
144
osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs
Normal file
144
osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osuTK;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.BeatmapSet
|
||||||
|
{
|
||||||
|
public class LeaderboardModSelector : CompositeDrawable
|
||||||
|
{
|
||||||
|
public readonly BindableList<Mod> SelectedMods = new BindableList<Mod>();
|
||||||
|
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
|
private readonly FillFlowContainer<ModButton> modsContainer;
|
||||||
|
|
||||||
|
public LeaderboardModSelector()
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
InternalChild = modsContainer = new FillFlowContainer<ModButton>
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Full,
|
||||||
|
Spacing = new Vector2(4),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
Ruleset.BindValueChanged(onRulesetChanged, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRulesetChanged(ValueChangedEvent<RulesetInfo> ruleset)
|
||||||
|
{
|
||||||
|
SelectedMods.Clear();
|
||||||
|
modsContainer.Clear();
|
||||||
|
|
||||||
|
if (ruleset.NewValue == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
modsContainer.Add(new ModButton(new ModNoMod()));
|
||||||
|
modsContainer.AddRange(ruleset.NewValue.CreateInstance().GetAllMods().Where(m => m.Ranked).Select(m => new ModButton(m)));
|
||||||
|
|
||||||
|
modsContainer.ForEach(button => button.OnSelectionChanged = selectionChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(HoverEvent e)
|
||||||
|
{
|
||||||
|
updateHighlighted();
|
||||||
|
return base.OnHover(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
|
{
|
||||||
|
base.OnHoverLost(e);
|
||||||
|
updateHighlighted();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectionChanged(Mod mod, bool selected)
|
||||||
|
{
|
||||||
|
if (selected)
|
||||||
|
SelectedMods.Add(mod);
|
||||||
|
else
|
||||||
|
SelectedMods.Remove(mod);
|
||||||
|
|
||||||
|
updateHighlighted();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHighlighted()
|
||||||
|
{
|
||||||
|
if (SelectedMods.Any())
|
||||||
|
return;
|
||||||
|
|
||||||
|
modsContainer.Children.Where(button => !button.IsHovered).ForEach(button => button.Highlighted.Value = !IsHovered);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeselectAll() => modsContainer.ForEach(mod => mod.Selected.Value = false);
|
||||||
|
|
||||||
|
private class ModButton : ModIcon
|
||||||
|
{
|
||||||
|
private const int duration = 200;
|
||||||
|
|
||||||
|
public readonly BindableBool Highlighted = new BindableBool();
|
||||||
|
public Action<Mod, bool> OnSelectionChanged;
|
||||||
|
|
||||||
|
public ModButton(Mod mod)
|
||||||
|
: base(mod)
|
||||||
|
{
|
||||||
|
Scale = new Vector2(0.4f);
|
||||||
|
Add(new HoverClickSounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Highlighted.BindValueChanged(highlighted =>
|
||||||
|
{
|
||||||
|
if (Selected.Value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.FadeColour(highlighted.NewValue ? Color4.White : Color4.DimGray, duration, Easing.OutQuint);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
Selected.BindValueChanged(selected =>
|
||||||
|
{
|
||||||
|
OnSelectionChanged?.Invoke(Mod, selected.NewValue);
|
||||||
|
Highlighted.TriggerChange();
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnClick(ClickEvent e)
|
||||||
|
{
|
||||||
|
Selected.Toggle();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnHover(HoverEvent e)
|
||||||
|
{
|
||||||
|
Highlighted.Value = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
|
{
|
||||||
|
base.OnHoverLost(e);
|
||||||
|
Highlighted.Value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
osu.Game/Overlays/BeatmapSet/Scores/NoScoresPlaceholder.cs
Normal file
46
osu.Game/Overlays/BeatmapSet/Scores/NoScoresPlaceholder.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||||
|
{
|
||||||
|
public class NoScoresPlaceholder : Container
|
||||||
|
{
|
||||||
|
private readonly SpriteText text;
|
||||||
|
|
||||||
|
public NoScoresPlaceholder()
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
Child = text = new OsuSpriteText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Show() => this.FadeIn(200, Easing.OutQuint);
|
||||||
|
|
||||||
|
public override void Hide() => this.FadeOut(200, Easing.OutQuint);
|
||||||
|
|
||||||
|
public void ShowWithScope(BeatmapLeaderboardScope scope)
|
||||||
|
{
|
||||||
|
Show();
|
||||||
|
|
||||||
|
switch (scope)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
text.Text = @"No scores have been set yet. Maybe you can be the first!";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BeatmapLeaderboardScope.Friend:
|
||||||
|
text.Text = @"None of your friends have set a score on this map yet.";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BeatmapLeaderboardScope.Country:
|
||||||
|
text.Text = @"No one from your country has set a score on this map yet.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osuTK;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||||
|
{
|
||||||
|
public class NotSupporterPlaceholder : Container
|
||||||
|
{
|
||||||
|
public NotSupporterPlaceholder()
|
||||||
|
{
|
||||||
|
LinkFlowContainer text;
|
||||||
|
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
Child = new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 10),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Text = @"You need to be an osu!supporter to access the friend and country rankings!",
|
||||||
|
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||||
|
},
|
||||||
|
text = new LinkFlowContainer(t => t.Font = t.Font.With(size: 12))
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
text.AddText("Click ");
|
||||||
|
text.AddLink("here", "/home/support");
|
||||||
|
text.AddText(" to see all the fancy features that you can get!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,10 @@ using osu.Game.Online.API.Requests.Responses;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Screens.Select.Leaderboards;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapSet.Scores
|
namespace osu.Game.Overlays.BeatmapSet.Scores
|
||||||
{
|
{
|
||||||
@ -20,32 +24,25 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
{
|
{
|
||||||
private const int spacing = 15;
|
private const int spacing = 15;
|
||||||
|
|
||||||
|
public readonly Bindable<BeatmapInfo> Beatmap = new Bindable<BeatmapInfo>();
|
||||||
|
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||||
|
private readonly Bindable<BeatmapLeaderboardScope> scope = new Bindable<BeatmapLeaderboardScope>(BeatmapLeaderboardScope.Global);
|
||||||
|
private readonly Bindable<User> user = new Bindable<User>();
|
||||||
|
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
private readonly ScoreTable scoreTable;
|
private readonly ScoreTable scoreTable;
|
||||||
private readonly FillFlowContainer topScoresContainer;
|
private readonly FillFlowContainer topScoresContainer;
|
||||||
private readonly LoadingAnimation loadingAnimation;
|
private readonly DimmedLoadingLayer loading;
|
||||||
|
private readonly LeaderboardModSelector modSelector;
|
||||||
|
private readonly NoScoresPlaceholder noScoresPlaceholder;
|
||||||
|
private readonly FillFlowContainer content;
|
||||||
|
private readonly NotSupporterPlaceholder notSupporterPlaceholder;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
private GetScoresRequest getScoresRequest;
|
private GetScoresRequest getScoresRequest;
|
||||||
|
|
||||||
private BeatmapInfo beatmap;
|
|
||||||
|
|
||||||
public BeatmapInfo Beatmap
|
|
||||||
{
|
|
||||||
get => beatmap;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (beatmap == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
beatmap = value;
|
|
||||||
|
|
||||||
getScores(beatmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected APILegacyScores Scores
|
protected APILegacyScores Scores
|
||||||
{
|
{
|
||||||
set => Schedule(() =>
|
set => Schedule(() =>
|
||||||
@ -82,7 +79,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
new FillFlowContainer
|
content = new FillFlowContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
@ -90,29 +87,88 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Width = 0.95f,
|
Width = 0.95f,
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
Spacing = new Vector2(0, spacing),
|
|
||||||
Margin = new MarginPadding { Vertical = spacing },
|
Margin = new MarginPadding { Vertical = spacing },
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
topScoresContainer = new FillFlowContainer
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
Spacing = new Vector2(0, 5),
|
Spacing = new Vector2(0, spacing),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new LeaderboardScopeSelector
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Current = { BindTarget = scope }
|
||||||
|
},
|
||||||
|
modSelector = new LeaderboardModSelector
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Ruleset = { BindTarget = ruleset }
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
scoreTable = new ScoreTable
|
new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
AutoSizeAxes = Axes.Y,
|
||||||
Origin = Anchor.TopCentre,
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Margin = new MarginPadding { Vertical = spacing },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
noScoresPlaceholder = new NoScoresPlaceholder
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Alpha = 0,
|
||||||
|
AlwaysPresent = true,
|
||||||
|
Margin = new MarginPadding { Vertical = 10 }
|
||||||
|
},
|
||||||
|
notSupporterPlaceholder = new NotSupporterPlaceholder
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Alpha = 0,
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, spacing),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
topScoresContainer = new FillFlowContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(0, 5),
|
||||||
|
},
|
||||||
|
scoreTable = new ScoreTable
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Masking = true,
|
||||||
|
CornerRadius = 10,
|
||||||
|
Child = loading = new DimmedLoadingLayer(iconScale: 0.8f)
|
||||||
|
{
|
||||||
|
Alpha = 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loadingAnimation = new LoadingAnimation
|
|
||||||
{
|
|
||||||
Alpha = 0,
|
|
||||||
Margin = new MarginPadding(20),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,26 +176,88 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
background.Colour = colours.Gray2;
|
background.Colour = colours.Gray2;
|
||||||
|
|
||||||
|
user.BindTo(api.LocalUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getScores(BeatmapInfo beatmap)
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
scope.BindValueChanged(_ => getScores());
|
||||||
|
ruleset.BindValueChanged(_ => getScores());
|
||||||
|
|
||||||
|
modSelector.SelectedMods.ItemsAdded += _ => getScores();
|
||||||
|
modSelector.SelectedMods.ItemsRemoved += _ => getScores();
|
||||||
|
|
||||||
|
Beatmap.BindValueChanged(onBeatmapChanged);
|
||||||
|
user.BindValueChanged(onUserChanged, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onBeatmapChanged(ValueChangedEvent<BeatmapInfo> beatmap)
|
||||||
|
{
|
||||||
|
var beatmapRuleset = beatmap.NewValue?.Ruleset;
|
||||||
|
|
||||||
|
if (ruleset.Value?.Equals(beatmapRuleset) ?? false)
|
||||||
|
{
|
||||||
|
modSelector.DeselectAll();
|
||||||
|
ruleset.TriggerChange();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ruleset.Value = beatmapRuleset;
|
||||||
|
|
||||||
|
scope.Value = BeatmapLeaderboardScope.Global;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onUserChanged(ValueChangedEvent<User> user)
|
||||||
|
{
|
||||||
|
if (modSelector.SelectedMods.Any())
|
||||||
|
modSelector.DeselectAll();
|
||||||
|
else
|
||||||
|
getScores();
|
||||||
|
|
||||||
|
modSelector.FadeTo(userIsSupporter ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getScores()
|
||||||
{
|
{
|
||||||
getScoresRequest?.Cancel();
|
getScoresRequest?.Cancel();
|
||||||
getScoresRequest = null;
|
getScoresRequest = null;
|
||||||
|
|
||||||
Scores = null;
|
noScoresPlaceholder.Hide();
|
||||||
|
|
||||||
if (beatmap?.OnlineBeatmapID.HasValue != true || beatmap.Status <= BeatmapSetOnlineStatus.Pending)
|
if (Beatmap.Value?.OnlineBeatmapID.HasValue != true || Beatmap.Value.Status <= BeatmapSetOnlineStatus.Pending)
|
||||||
|
{
|
||||||
|
Scores = null;
|
||||||
|
content.Hide();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
loadingAnimation.Show();
|
if (scope.Value != BeatmapLeaderboardScope.Global && !userIsSupporter)
|
||||||
getScoresRequest = new GetScoresRequest(beatmap, beatmap.Ruleset);
|
{
|
||||||
|
Scores = null;
|
||||||
|
notSupporterPlaceholder.Show();
|
||||||
|
loading.Hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
notSupporterPlaceholder.Hide();
|
||||||
|
|
||||||
|
content.Show();
|
||||||
|
loading.Show();
|
||||||
|
|
||||||
|
getScoresRequest = new GetScoresRequest(Beatmap.Value, Beatmap.Value.Ruleset, scope.Value, modSelector.SelectedMods);
|
||||||
getScoresRequest.Success += scores =>
|
getScoresRequest.Success += scores =>
|
||||||
{
|
{
|
||||||
loadingAnimation.Hide();
|
loading.Hide();
|
||||||
Scores = scores;
|
Scores = scores;
|
||||||
|
|
||||||
|
if (!scores.Scores.Any())
|
||||||
|
noScoresPlaceholder.ShowWithScope(scope.Value);
|
||||||
};
|
};
|
||||||
|
|
||||||
api.Queue(getScoresRequest);
|
api.Queue(getScoresRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool userIsSupporter => api.IsLoggedIn && api.LocalUser.Value.IsSupporter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
OsuScrollContainer scroll;
|
OsuScrollContainer scroll;
|
||||||
Info info;
|
Info info;
|
||||||
ScoresContainer scoreContainer;
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -59,7 +58,10 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
Header = new Header(),
|
Header = new Header(),
|
||||||
info = new Info(),
|
info = new Info(),
|
||||||
scoreContainer = new ScoresContainer(),
|
new ScoresContainer
|
||||||
|
{
|
||||||
|
Beatmap = { BindTarget = Header.Picker.Beatmap }
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -71,7 +73,6 @@ namespace osu.Game.Overlays
|
|||||||
Header.Picker.Beatmap.ValueChanged += b =>
|
Header.Picker.Beatmap.ValueChanged += b =>
|
||||||
{
|
{
|
||||||
info.Beatmap = b.NewValue;
|
info.Beatmap = b.NewValue;
|
||||||
scoreContainer.Beatmap = b.NewValue;
|
|
||||||
|
|
||||||
scroll.ScrollToStart();
|
scroll.ScrollToStart();
|
||||||
};
|
};
|
||||||
|
@ -16,6 +16,7 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Chat
|
namespace osu.Game.Overlays.Chat
|
||||||
{
|
{
|
||||||
@ -202,7 +203,7 @@ namespace osu.Game.Overlays.Chat
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = lineHeight,
|
Height = lineHeight,
|
||||||
},
|
},
|
||||||
text = new SpriteText
|
text = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Margin = new MarginPadding { Horizontal = 10 },
|
Margin = new MarginPadding { Horizontal = 10 },
|
||||||
Text = time.ToLocalTime().ToString("dd MMM yyyy"),
|
Text = time.ToLocalTime().ToString("dd MMM yyyy"),
|
||||||
|
@ -10,6 +10,7 @@ using osu.Game.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Comments
|
namespace osu.Game.Overlays.Comments
|
||||||
{
|
{
|
||||||
@ -48,7 +49,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
@ -101,7 +102,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Size = new Vector2(10),
|
Size = new Vector2(10),
|
||||||
},
|
},
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Comments
|
namespace osu.Game.Overlays.Comments
|
||||||
{
|
{
|
||||||
@ -31,7 +32,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
Icon = FontAwesome.Solid.Trash,
|
Icon = FontAwesome.Solid.Trash,
|
||||||
Size = new Vector2(14),
|
Size = new Vector2(14),
|
||||||
},
|
},
|
||||||
countText = new SpriteText
|
countText = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
|
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ using osu.Framework.Graphics.Cursor;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Comments
|
namespace osu.Game.Overlays.Comments
|
||||||
@ -100,6 +101,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
Size = new Vector2(avatar_size),
|
Size = new Vector2(avatar_size),
|
||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = avatar_size / 2f,
|
CornerRadius = avatar_size / 2f,
|
||||||
|
CornerExponent = 2,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -122,7 +124,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
new ParentUsername(comment),
|
new ParentUsername(comment),
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Alpha = comment.IsDeleted ? 1 : 0,
|
Alpha = comment.IsDeleted ? 1 : 0,
|
||||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
|
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
|
||||||
@ -144,7 +146,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
Colour = OsuColour.Gray(0.7f),
|
Colour = OsuColour.Gray(0.7f),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
@ -195,7 +197,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
|
|
||||||
if (comment.EditedAt.HasValue)
|
if (comment.EditedAt.HasValue)
|
||||||
{
|
{
|
||||||
info.Add(new SpriteText
|
info.Add(new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
@ -290,7 +292,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
this.count = count;
|
this.count = count;
|
||||||
|
|
||||||
Alpha = count == 0 ? 0 : 1;
|
Alpha = count == 0 ? 0 : 1;
|
||||||
Child = text = new SpriteText
|
Child = text = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold),
|
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold),
|
||||||
};
|
};
|
||||||
@ -323,7 +325,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
Icon = FontAwesome.Solid.Reply,
|
Icon = FontAwesome.Solid.Reply,
|
||||||
Size = new Vector2(14),
|
Size = new Vector2(14),
|
||||||
},
|
},
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
|
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
|
||||||
Text = parentComment?.User?.Username ?? parentComment?.LegacyName
|
Text = parentComment?.User?.Username ?? parentComment?.LegacyName
|
||||||
|
@ -11,6 +11,7 @@ using osu.Game.Graphics.UserInterface;
|
|||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Comments
|
namespace osu.Game.Overlays.Comments
|
||||||
@ -61,7 +62,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
|
|
||||||
public TabButton(CommentsSortCriteria value)
|
public TabButton(CommentsSortCriteria value)
|
||||||
{
|
{
|
||||||
Add(text = new SpriteText
|
Add(text = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = OsuFont.GetFont(size: 14),
|
Font = OsuFont.GetFont(size: 14),
|
||||||
Text = value.ToString()
|
Text = value.ToString()
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Comments
|
namespace osu.Game.Overlays.Comments
|
||||||
{
|
{
|
||||||
@ -32,7 +33,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
Spacing = new Vector2(5, 0),
|
Spacing = new Vector2(5, 0),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
@ -52,7 +53,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = OsuColour.Gray(0.05f)
|
Colour = OsuColour.Gray(0.05f)
|
||||||
},
|
},
|
||||||
counter = new SpriteText
|
counter = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
@ -110,7 +110,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sideNumber = new SpriteText
|
sideNumber = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreRight,
|
Origin = Anchor.CentreRight,
|
||||||
|
@ -96,7 +96,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foregroundIcon.Highlighted.Value = Selected;
|
foregroundIcon.Selected.Value = Selected;
|
||||||
|
|
||||||
SelectionChanged?.Invoke(SelectedMod);
|
SelectionChanged?.Invoke(SelectedMod);
|
||||||
return true;
|
return true;
|
||||||
|
@ -167,7 +167,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
Spacing = new Vector2(50f, 0f),
|
Spacing = new Vector2(50f, 0f),
|
||||||
Margin = new MarginPadding
|
Margin = new MarginPadding
|
||||||
{
|
{
|
||||||
Top = 6,
|
Top = 20,
|
||||||
},
|
},
|
||||||
AlwaysPresent = true
|
AlwaysPresent = true
|
||||||
},
|
},
|
||||||
|
@ -390,7 +390,7 @@ namespace osu.Game.Overlays
|
|||||||
Vector2 change = e.MousePosition - e.MouseDownPosition;
|
Vector2 change = e.MousePosition - e.MouseDownPosition;
|
||||||
|
|
||||||
// Diminish the drag distance as we go further to simulate "rubber band" feeling.
|
// Diminish the drag distance as we go further to simulate "rubber band" feeling.
|
||||||
change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length;
|
change *= change.Length <= 0 ? 0 : MathF.Pow(change.Length, 0.7f) / change.Length;
|
||||||
|
|
||||||
this.MoveTo(change);
|
this.MoveTo(change);
|
||||||
return true;
|
return true;
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
hoverIcon = new HoverIconContainer(),
|
hoverIcon = new HoverIconContainer(),
|
||||||
header = new SpriteText
|
header = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
|
@ -90,7 +90,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
placeholder.FadeOut(fade_duration, Easing.Out);
|
placeholder.FadeOut(fade_duration, Easing.Out);
|
||||||
|
|
||||||
graph.DefaultValueCount = ranks.Length;
|
graph.DefaultValueCount = ranks.Length;
|
||||||
graph.Values = ranks.Select(x => -(float)Math.Log(x.Value));
|
graph.Values = ranks.Select(x => -MathF.Log(x.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.FadeTo(ranks.Length > 1 ? 1 : 0, fade_duration, Easing.Out);
|
graph.FadeTo(ranks.Length > 1 ? 1 : 0, fade_duration, Easing.Out);
|
||||||
@ -187,7 +187,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
|
|||||||
|
|
||||||
public void HideBar() => bar.FadeOut(fade_duration);
|
public void HideBar() => bar.FadeOut(fade_duration);
|
||||||
|
|
||||||
private int calculateIndex(float mouseXPosition) => (int)Math.Round(mouseXPosition / DrawWidth * (DefaultValueCount - 1));
|
private int calculateIndex(float mouseXPosition) => (int)MathF.Round(mouseXPosition / DrawWidth * (DefaultValueCount - 1));
|
||||||
|
|
||||||
private Vector2 calculateBallPosition(int index)
|
private Vector2 calculateBallPosition(int index)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Graphics;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Rankings
|
namespace osu.Game.Overlays.Rankings
|
||||||
{
|
{
|
||||||
@ -41,13 +42,13 @@ namespace osu.Game.Overlays.Rankings
|
|||||||
Margin = new MarginPadding { Bottom = flag_margin },
|
Margin = new MarginPadding { Bottom = flag_margin },
|
||||||
Size = new Vector2(30, 20),
|
Size = new Vector2(30, 20),
|
||||||
},
|
},
|
||||||
scopeText = new SpriteText
|
scopeText = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Light)
|
Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Light)
|
||||||
},
|
},
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
|
@ -34,6 +34,12 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
Bindable = config.GetBindable<IntroSequence>(OsuSetting.IntroSequence),
|
Bindable = config.GetBindable<IntroSequence>(OsuSetting.IntroSequence),
|
||||||
Items = Enum.GetValues(typeof(IntroSequence)).Cast<IntroSequence>()
|
Items = Enum.GetValues(typeof(IntroSequence)).Cast<IntroSequence>()
|
||||||
},
|
},
|
||||||
|
new SettingsDropdown<BackgroundSource>
|
||||||
|
{
|
||||||
|
LabelText = "Background source",
|
||||||
|
Bindable = config.GetBindable<BackgroundSource>(OsuSetting.MenuBackgroundSource),
|
||||||
|
Items = Enum.GetValues(typeof(BackgroundSource)).Cast<BackgroundSource>()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Settings.Sections.Debug
|
|||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Performance logging",
|
LabelText = "Performance logging",
|
||||||
Bindable = frameworkConfig.GetBindable<bool>(FrameworkSetting.PerformanceLogging)
|
Bindable = config.GetBindable<bool>(DebugSetting.PerformanceLogging)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
|
@ -225,7 +225,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
{
|
{
|
||||||
username = new OsuTextBox
|
username = new OsuTextBox
|
||||||
{
|
{
|
||||||
PlaceholderText = "email address",
|
PlaceholderText = "username",
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Text = api?.ProvidedUsername ?? string.Empty,
|
Text = api?.ProvidedUsername ?? string.Empty,
|
||||||
TabbableContentContainer = this
|
TabbableContentContainer = this
|
||||||
@ -239,7 +239,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Remember email address",
|
LabelText = "Remember username",
|
||||||
Bindable = config.GetBindable<bool>(OsuSetting.SaveUsername),
|
Bindable = config.GetBindable<bool>(OsuSetting.SaveUsername),
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
|
@ -43,6 +43,7 @@ namespace osu.Game.Overlays.Volume
|
|||||||
{
|
{
|
||||||
Content.BorderThickness = 3;
|
Content.BorderThickness = 3;
|
||||||
Content.CornerRadius = HEIGHT / 2;
|
Content.CornerRadius = HEIGHT / 2;
|
||||||
|
Content.CornerExponent = 2;
|
||||||
|
|
||||||
Size = new Vector2(width, HEIGHT);
|
Size = new Vector2(width, HEIGHT);
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -11,5 +13,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override string Name => "No Mod";
|
public override string Name => "No Mod";
|
||||||
public override string Acronym => "NM";
|
public override string Acronym => "NM";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
public override IconUsage Icon => FontAwesome.Solid.Ban;
|
||||||
|
public override ModType Type => ModType.System;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Timing;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
@ -42,7 +41,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
HitObject lastObject = beatmap.HitObjects.LastOrDefault();
|
HitObject lastObject = beatmap.HitObjects.LastOrDefault();
|
||||||
|
|
||||||
beginRampTime = beatmap.HitObjects.FirstOrDefault()?.StartTime ?? 0;
|
beginRampTime = beatmap.HitObjects.FirstOrDefault()?.StartTime ?? 0;
|
||||||
finalRateTime = final_rate_progress * ((lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0);
|
finalRateTime = final_rate_progress * (lastObject?.GetEndTime() ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Update(Playfield playfield)
|
public virtual void Update(Playfield playfield)
|
||||||
|
@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Objects
|
namespace osu.Game.Rulesets.Objects
|
||||||
{
|
{
|
||||||
@ -28,7 +27,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
HitObject lastObject = beatmap.HitObjects.Last();
|
HitObject lastObject = beatmap.HitObjects.Last();
|
||||||
double lastHitTime = 1 + ((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime);
|
double lastHitTime = 1 + lastObject.GetEndTime();
|
||||||
|
|
||||||
var timingPoints = beatmap.ControlPointInfo.TimingPoints;
|
var timingPoints = beatmap.ControlPointInfo.TimingPoints;
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
|
|
||||||
if (Result != null && Result.HasResult)
|
if (Result != null && Result.HasResult)
|
||||||
{
|
{
|
||||||
var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
|
var endTime = HitObject.GetEndTime();
|
||||||
|
|
||||||
if (Result.TimeOffset + endTime > Time.Current)
|
if (Result.TimeOffset + endTime > Time.Current)
|
||||||
{
|
{
|
||||||
@ -460,7 +460,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
throw new InvalidOperationException($"{GetType().ReadableName()} applied a {nameof(JudgementResult)} but did not update {nameof(JudgementResult.Type)}.");
|
throw new InvalidOperationException($"{GetType().ReadableName()} applied a {nameof(JudgementResult)} but did not update {nameof(JudgementResult.Type)}.");
|
||||||
|
|
||||||
// Ensure that the judgement is given a valid time offset, because this may not get set by the caller
|
// Ensure that the judgement is given a valid time offset, because this may not get set by the caller
|
||||||
var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
|
var endTime = HitObject.GetEndTime();
|
||||||
|
|
||||||
Result.TimeOffset = Math.Min(HitObject.HitWindows.WindowFor(HitResult.Miss), Time.Current - endTime);
|
Result.TimeOffset = Math.Min(HitObject.HitWindows.WindowFor(HitResult.Miss), Time.Current - endTime);
|
||||||
|
|
||||||
@ -495,7 +495,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
if (Judged)
|
if (Judged)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
|
var endTime = HitObject.GetEndTime();
|
||||||
CheckForResult(userTriggered, Time.Current - endTime);
|
CheckForResult(userTriggered, Time.Current - endTime);
|
||||||
|
|
||||||
return Judged;
|
return Judged;
|
||||||
|
@ -158,4 +158,17 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
[NotNull]
|
[NotNull]
|
||||||
protected virtual HitWindows CreateHitWindows() => new HitWindows();
|
protected virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class HitObjectExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the end time of this object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This returns the <see cref="IHasEndTime.EndTime"/> where available, falling back to <see cref="HitObject.StartTime"/> otherwise.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="hitObject">The object.</param>
|
||||||
|
/// <returns>The end time of this object.</returns>
|
||||||
|
public static double GetEndTime(this HitObject hitObject) => (hitObject as IHasEndTime)?.EndTime ?? hitObject.StartTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
Playfield.PostProcess();
|
Playfield.PostProcess();
|
||||||
|
|
||||||
foreach (var mod in mods.OfType<IApplicableToDrawableHitObjects>())
|
foreach (var mod in mods.OfType<IApplicableToDrawableHitObjects>())
|
||||||
mod.ApplyToDrawableHitObjects(Playfield.HitObjectContainer.Objects);
|
mod.ApplyToDrawableHitObjects(Playfield.AllHitObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RequestResume(Action continueResume)
|
public override void RequestResume(Action continueResume)
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
public class ModIcon : Container, IHasTooltip
|
public class ModIcon : Container, IHasTooltip
|
||||||
{
|
{
|
||||||
public readonly BindableBool Highlighted = new BindableBool();
|
public readonly BindableBool Selected = new BindableBool();
|
||||||
|
|
||||||
private readonly SpriteIcon modIcon;
|
private readonly SpriteIcon modIcon;
|
||||||
private readonly SpriteIcon background;
|
private readonly SpriteIcon background;
|
||||||
@ -34,9 +34,11 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
public virtual string TooltipText { get; }
|
public virtual string TooltipText { get; }
|
||||||
|
|
||||||
|
protected Mod Mod { get; private set; }
|
||||||
|
|
||||||
public ModIcon(Mod mod)
|
public ModIcon(Mod mod)
|
||||||
{
|
{
|
||||||
if (mod == null) throw new ArgumentNullException(nameof(mod));
|
Mod = mod ?? throw new ArgumentNullException(nameof(mod));
|
||||||
|
|
||||||
type = mod.Type;
|
type = mod.Type;
|
||||||
|
|
||||||
@ -98,13 +100,19 @@ namespace osu.Game.Rulesets.UI
|
|||||||
backgroundColour = colours.Pink;
|
backgroundColour = colours.Pink;
|
||||||
highlightedColour = colours.PinkLight;
|
highlightedColour = colours.PinkLight;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ModType.System:
|
||||||
|
backgroundColour = colours.Gray6;
|
||||||
|
highlightedColour = colours.Gray7;
|
||||||
|
modIcon.Colour = colours.Yellow;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
Highlighted.BindValueChanged(highlighted => background.Colour = highlighted.NewValue ? highlightedColour : backgroundColour, true);
|
Selected.BindValueChanged(selected => background.Colour = selected.NewValue ? highlightedColour : backgroundColour, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Timing;
|
using osu.Game.Rulesets.Timing;
|
||||||
using osu.Game.Rulesets.UI.Scrolling.Algorithms;
|
using osu.Game.Rulesets.UI.Scrolling.Algorithms;
|
||||||
|
|
||||||
@ -112,7 +111,7 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue;
|
double lastObjectTime = Objects.LastOrDefault()?.GetEndTime() ?? double.MaxValue;
|
||||||
double baseBeatLength = TimingControlPoint.DEFAULT_BEAT_LENGTH;
|
double baseBeatLength = TimingControlPoint.DEFAULT_BEAT_LENGTH;
|
||||||
|
|
||||||
if (RelativeScaleBeatLengths)
|
if (RelativeScaleBeatLengths)
|
||||||
|
@ -6,7 +6,6 @@ using System.Threading;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Textures;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
@ -74,7 +73,7 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
|
|
||||||
Schedule(() =>
|
Schedule(() =>
|
||||||
{
|
{
|
||||||
if ((Background as BeatmapBackground)?.Beatmap == beatmap)
|
if ((Background as BeatmapBackground)?.Beatmap.BeatmapInfo.BackgroundEquals(beatmap?.BeatmapInfo) ?? false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cancellationSource?.Cancel();
|
cancellationSource?.Cancel();
|
||||||
@ -107,22 +106,6 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
return base.Equals(other) && beatmap == otherBeatmapBackground.Beatmap;
|
return base.Equals(other) && beatmap == otherBeatmapBackground.Beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class BeatmapBackground : Background
|
|
||||||
{
|
|
||||||
public readonly WorkingBeatmap Beatmap;
|
|
||||||
|
|
||||||
public BeatmapBackground(WorkingBeatmap beatmap)
|
|
||||||
{
|
|
||||||
Beatmap = beatmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(TextureStore textures)
|
|
||||||
{
|
|
||||||
Sprite.Texture = Beatmap?.Background ?? textures.Get(@"Backgrounds/bg1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DimmableBackground : UserDimContainer
|
public class DimmableBackground : UserDimContainer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -6,6 +6,8 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
@ -24,6 +26,10 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
|
|
||||||
private Bindable<User> user;
|
private Bindable<User> user;
|
||||||
private Bindable<Skin> skin;
|
private Bindable<Skin> skin;
|
||||||
|
private Bindable<BackgroundSource> mode;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
||||||
|
|
||||||
public BackgroundScreenDefault(bool animateOnEnter = true)
|
public BackgroundScreenDefault(bool animateOnEnter = true)
|
||||||
: base(animateOnEnter)
|
: base(animateOnEnter)
|
||||||
@ -31,13 +37,16 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(IAPIProvider api, SkinManager skinManager)
|
private void load(IAPIProvider api, SkinManager skinManager, OsuConfigManager config)
|
||||||
{
|
{
|
||||||
user = api.LocalUser.GetBoundCopy();
|
user = api.LocalUser.GetBoundCopy();
|
||||||
skin = skinManager.CurrentSkin.GetBoundCopy();
|
skin = skinManager.CurrentSkin.GetBoundCopy();
|
||||||
|
mode = config.GetBindable<BackgroundSource>(OsuSetting.MenuBackgroundSource);
|
||||||
|
|
||||||
user.ValueChanged += _ => Next();
|
user.ValueChanged += _ => Next();
|
||||||
skin.ValueChanged += _ => Next();
|
skin.ValueChanged += _ => Next();
|
||||||
|
mode.ValueChanged += _ => Next();
|
||||||
|
beatmap.ValueChanged += _ => Next();
|
||||||
|
|
||||||
currentDisplay = RNG.Next(0, background_count);
|
currentDisplay = RNG.Next(0, background_count);
|
||||||
|
|
||||||
@ -66,7 +75,18 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
Background newBackground;
|
Background newBackground;
|
||||||
|
|
||||||
if (user.Value?.IsSupporter ?? false)
|
if (user.Value?.IsSupporter ?? false)
|
||||||
newBackground = new SkinnedBackground(skin.Value, backgroundName);
|
{
|
||||||
|
switch (mode.Value)
|
||||||
|
{
|
||||||
|
case BackgroundSource.Beatmap:
|
||||||
|
newBackground = new BeatmapBackground(beatmap.Value, backgroundName);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
newBackground = new SkinnedBackground(skin.Value, backgroundName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
newBackground = new Background(backgroundName);
|
newBackground = new Background(backgroundName);
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ namespace osu.Game.Screens.Edit.Components
|
|||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
Content.CornerRadius = DrawHeight / 2f;
|
Content.CornerRadius = DrawHeight / 2f;
|
||||||
|
Content.CornerExponent = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
OnUserChange(Current.Value);
|
OnUserChange(Current.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getMappedPosition(float divisor) => (float)Math.Pow((divisor - 1) / (availableDivisors.Last() - 1), 0.90f);
|
private float getMappedPosition(float divisor) => MathF.Pow((divisor - 1) / (availableDivisors.Last() - 1), 0.90f);
|
||||||
|
|
||||||
private class Tick : CompositeDrawable
|
private class Tick : CompositeDrawable
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
float distance = direction.Length;
|
float distance = direction.Length;
|
||||||
|
|
||||||
float radius = DistanceSpacing;
|
float radius = DistanceSpacing;
|
||||||
int radialCount = Math.Clamp((int)Math.Round(distance / radius), 1, MaxIntervals);
|
int radialCount = Math.Clamp((int)MathF.Round(distance / radius), 1, MaxIntervals);
|
||||||
|
|
||||||
Vector2 normalisedDirection = direction * new Vector2(1f / distance);
|
Vector2 normalisedDirection = direction * new Vector2(1f / distance);
|
||||||
Vector2 snappedPosition = CentrePosition + normalisedDirection * radialCount * radius;
|
Vector2 snappedPosition = CentrePosition + normalisedDirection * radialCount * radius;
|
||||||
|
@ -10,7 +10,6 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Compose.Components
|
namespace osu.Game.Screens.Edit.Compose.Components
|
||||||
@ -70,7 +69,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
StartTime = (hitObject as IHasEndTime)?.EndTime ?? hitObject.StartTime;
|
StartTime = hitObject.GetEndTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -206,8 +206,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
float rotation = MathHelper.DegreesToRadians(i / (float)bars_per_visualiser * 360 + j * 360 / visualiser_rounds);
|
float rotation = MathHelper.DegreesToRadians(i / (float)bars_per_visualiser * 360 + j * 360 / visualiser_rounds);
|
||||||
float rotationCos = (float)Math.Cos(rotation);
|
float rotationCos = MathF.Cos(rotation);
|
||||||
float rotationSin = (float)Math.Sin(rotation);
|
float rotationSin = MathF.Sin(rotation);
|
||||||
//taking the cos and sin to the 0..1 range
|
//taking the cos and sin to the 0..1 range
|
||||||
var barPosition = new Vector2(rotationCos / 2 + 0.5f, rotationSin / 2 + 0.5f) * size;
|
var barPosition = new Vector2(rotationCos / 2 + 0.5f, rotationSin / 2 + 0.5f) * size;
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -170,8 +169,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
track.Start();
|
track.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Beatmap.ValueChanged += beatmap_ValueChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool exitConfirmed;
|
private bool exitConfirmed;
|
||||||
@ -220,14 +217,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
seq.OnAbort(_ => buttons.SetOsuLogo(null));
|
seq.OnAbort(_ => buttons.SetOsuLogo(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beatmap_ValueChanged(ValueChangedEvent<WorkingBeatmap> e)
|
|
||||||
{
|
|
||||||
if (!this.IsCurrentScreen())
|
|
||||||
return;
|
|
||||||
|
|
||||||
((BackgroundScreenDefault)Background).Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnSuspending(IScreen next)
|
public override void OnSuspending(IScreen next)
|
||||||
{
|
{
|
||||||
base.OnSuspending(next);
|
base.OnSuspending(next);
|
||||||
|
@ -34,7 +34,6 @@ namespace osu.Game.Screens.Play
|
|||||||
public void ProcessFrame()
|
public void ProcessFrame()
|
||||||
{
|
{
|
||||||
// we do not want to process the underlying clock.
|
// we do not want to process the underlying clock.
|
||||||
// this is handled by PauseContainer.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double ElapsedFrameTime => underlyingClock.ElapsedFrameTime;
|
public double ElapsedFrameTime => underlyingClock.ElapsedFrameTime;
|
||||||
|
@ -41,6 +41,8 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private readonly double gameplayStartTime;
|
private readonly double gameplayStartTime;
|
||||||
|
|
||||||
|
private readonly double firstHitObjectTime;
|
||||||
|
|
||||||
public readonly Bindable<double> UserPlaybackRate = new BindableDouble(1)
|
public readonly Bindable<double> UserPlaybackRate = new BindableDouble(1)
|
||||||
{
|
{
|
||||||
Default = 1,
|
Default = 1,
|
||||||
@ -66,6 +68,7 @@ namespace osu.Game.Screens.Play
|
|||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
this.mods = mods;
|
this.mods = mods;
|
||||||
this.gameplayStartTime = gameplayStartTime;
|
this.gameplayStartTime = gameplayStartTime;
|
||||||
|
this.firstHitObjectTime = beatmap.Beatmap.HitObjects.First().StartTime;
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
@ -89,6 +92,11 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
private double totalOffset => userOffsetClock.Offset + platformOffsetClock.Offset;
|
private double totalOffset => userOffsetClock.Offset + platformOffsetClock.Offset;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Duration before gameplay start time required before skip button displays.
|
||||||
|
/// </summary>
|
||||||
|
public const double MINIMUM_SKIP_TIME = 1000;
|
||||||
|
|
||||||
private readonly BindableDouble pauseFreqAdjust = new BindableDouble(1);
|
private readonly BindableDouble pauseFreqAdjust = new BindableDouble(1);
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -97,9 +105,22 @@ namespace osu.Game.Screens.Play
|
|||||||
userAudioOffset = config.GetBindable<double>(OsuSetting.AudioOffset);
|
userAudioOffset = config.GetBindable<double>(OsuSetting.AudioOffset);
|
||||||
userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true);
|
userAudioOffset.BindValueChanged(offset => userOffsetClock.Offset = offset.NewValue, true);
|
||||||
|
|
||||||
UserPlaybackRate.ValueChanged += _ => updateRate();
|
// sane default provided by ruleset.
|
||||||
|
double startTime = Math.Min(0, gameplayStartTime);
|
||||||
|
|
||||||
Seek(Math.Min(-beatmap.BeatmapInfo.AudioLeadIn, gameplayStartTime));
|
// if a storyboard is present, it may dictate the appropriate start time by having events in negative time space.
|
||||||
|
// this is commonly used to display an intro before the audio track start.
|
||||||
|
startTime = Math.Min(startTime, beatmap.Storyboard.FirstEventTime);
|
||||||
|
|
||||||
|
// some beatmaps specify a current lead-in time which should be used instead of the ruleset-provided value when available.
|
||||||
|
// this is not available as an option in the live editor but can still be applied via .osu editing.
|
||||||
|
if (beatmap.BeatmapInfo.AudioLeadIn > 0)
|
||||||
|
startTime = Math.Min(startTime, firstHitObjectTime - beatmap.BeatmapInfo.AudioLeadIn);
|
||||||
|
|
||||||
|
Seek(startTime);
|
||||||
|
|
||||||
|
adjustableClock.ProcessFrame();
|
||||||
|
UserPlaybackRate.ValueChanged += _ => updateRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Restart()
|
public void Restart()
|
||||||
@ -130,6 +151,23 @@ namespace osu.Game.Screens.Play
|
|||||||
this.TransformBindableTo(pauseFreqAdjust, 1, 200, Easing.In);
|
this.TransformBindableTo(pauseFreqAdjust, 1, 200, Easing.In);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Skip forward to the next valid skip point.
|
||||||
|
/// </summary>
|
||||||
|
public void Skip()
|
||||||
|
{
|
||||||
|
if (GameplayClock.CurrentTime > gameplayStartTime - MINIMUM_SKIP_TIME)
|
||||||
|
return;
|
||||||
|
|
||||||
|
double skipTarget = gameplayStartTime - MINIMUM_SKIP_TIME;
|
||||||
|
|
||||||
|
if (GameplayClock.CurrentTime < 0 && skipTarget > 6000)
|
||||||
|
// double skip exception for storyboards with very long intros
|
||||||
|
skipTarget = 0;
|
||||||
|
|
||||||
|
Seek(skipTarget);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seek to a specific time in gameplay.
|
/// Seek to a specific time in gameplay.
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
|
@ -203,7 +203,7 @@ namespace osu.Game.Screens.Play
|
|||||||
},
|
},
|
||||||
new SkipOverlay(DrawableRuleset.GameplayStartTime)
|
new SkipOverlay(DrawableRuleset.GameplayStartTime)
|
||||||
{
|
{
|
||||||
RequestSeek = GameplayClockContainer.Seek
|
RequestSkip = GameplayClockContainer.Skip
|
||||||
},
|
},
|
||||||
FailOverlay = new FailOverlay
|
FailOverlay = new FailOverlay
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
@ -27,7 +28,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
private readonly double startTime;
|
private readonly double startTime;
|
||||||
|
|
||||||
public Action<double> RequestSeek;
|
public Action RequestSkip;
|
||||||
|
|
||||||
private Button button;
|
private Button button;
|
||||||
private Box remainingTimeBox;
|
private Box remainingTimeBox;
|
||||||
@ -35,6 +36,9 @@ namespace osu.Game.Screens.Play
|
|||||||
private FadeContainer fadeContainer;
|
private FadeContainer fadeContainer;
|
||||||
private double displayTime;
|
private double displayTime;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private GameplayClock gameplayClock { get; set; }
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -45,8 +49,6 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
this.startTime = startTime;
|
this.startTime = startTime;
|
||||||
|
|
||||||
Show();
|
|
||||||
|
|
||||||
RelativePositionAxes = Axes.Both;
|
RelativePositionAxes = Axes.Both;
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
|
||||||
@ -57,13 +59,8 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(OsuColour colours, GameplayClock clock)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
var baseClock = Clock;
|
|
||||||
|
|
||||||
if (clock != null)
|
|
||||||
Clock = clock;
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
fadeContainer = new FadeContainer
|
fadeContainer = new FadeContainer
|
||||||
@ -73,7 +70,6 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
button = new Button
|
button = new Button
|
||||||
{
|
{
|
||||||
Clock = baseClock,
|
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
},
|
},
|
||||||
@ -90,46 +86,42 @@ namespace osu.Game.Screens.Play
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Duration before gameplay start time required before skip button displays.
|
|
||||||
/// </summary>
|
|
||||||
private const double skip_buffer = 1000;
|
|
||||||
|
|
||||||
private const double fade_time = 300;
|
private const double fade_time = 300;
|
||||||
|
|
||||||
private double beginFadeTime => startTime - fade_time;
|
private double fadeOutBeginTime => startTime - GameplayClockContainer.MINIMUM_SKIP_TIME;
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
// skip is not required if there is no extra "empty" time to skip.
|
// skip is not required if there is no extra "empty" time to skip.
|
||||||
if (Clock.CurrentTime > beginFadeTime - skip_buffer)
|
// we may need to remove this if rewinding before the initial player load position becomes a thing.
|
||||||
|
if (fadeOutBeginTime < gameplayClock.CurrentTime)
|
||||||
{
|
{
|
||||||
Alpha = 0;
|
|
||||||
Expire();
|
Expire();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.FadeInFromZero(fade_time);
|
button.Action = () => RequestSkip?.Invoke();
|
||||||
using (BeginAbsoluteSequence(beginFadeTime))
|
displayTime = gameplayClock.CurrentTime;
|
||||||
this.FadeOut(fade_time);
|
|
||||||
|
|
||||||
button.Action = () => RequestSeek?.Invoke(beginFadeTime);
|
Show();
|
||||||
|
|
||||||
displayTime = Time.Current;
|
|
||||||
|
|
||||||
Expire();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopIn() => this.FadeIn();
|
protected override void PopIn() => this.FadeIn(fade_time);
|
||||||
|
|
||||||
protected override void PopOut() => this.FadeOut();
|
protected override void PopOut() => this.FadeOut(fade_time);
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
remainingTimeBox.ResizeWidthTo((float)Math.Max(0, 1 - (Time.Current - displayTime) / (beginFadeTime - displayTime)), 120, Easing.OutQuint);
|
|
||||||
|
var progress = Math.Max(0, 1 - (gameplayClock.CurrentTime - displayTime) / (fadeOutBeginTime - displayTime));
|
||||||
|
|
||||||
|
remainingTimeBox.Width = (float)Interpolation.Lerp(remainingTimeBox.Width, progress, Math.Clamp(Time.Elapsed / 40, 0, 1));
|
||||||
|
|
||||||
|
button.Enabled.Value = progress > 0;
|
||||||
|
State.Value = progress > 0 ? Visibility.Visible : Visibility.Hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnMouseMove(MouseMoveEvent e)
|
protected override bool OnMouseMove(MouseMoveEvent e)
|
||||||
@ -335,13 +327,7 @@ namespace osu.Game.Screens.Play
|
|||||||
box.FlashColour(Color4.White, 500, Easing.OutQuint);
|
box.FlashColour(Color4.White, 500, Easing.OutQuint);
|
||||||
aspect.ScaleTo(1.2f, 2000, Easing.OutQuint);
|
aspect.ScaleTo(1.2f, 2000, Easing.OutQuint);
|
||||||
|
|
||||||
bool result = base.OnClick(e);
|
return base.OnClick(e);
|
||||||
|
|
||||||
// for now, let's disable the skip button after the first press.
|
|
||||||
// this will likely need to be contextual in the future (bound from external components).
|
|
||||||
Enabled.Value = false;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ using System.Linq;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
@ -34,7 +33,8 @@ namespace osu.Game.Screens.Play
|
|||||||
public override bool HandleNonPositionalInput => AllowSeeking;
|
public override bool HandleNonPositionalInput => AllowSeeking;
|
||||||
public override bool HandlePositionalInput => AllowSeeking;
|
public override bool HandlePositionalInput => AllowSeeking;
|
||||||
|
|
||||||
private double lastHitTime => ((objects.Last() as IHasEndTime)?.EndTime ?? objects.Last().StartTime) + 1;
|
//TODO: this isn't always correct (consider mania where a non-last object may last for longer than the last in the list).
|
||||||
|
private double lastHitTime => objects.Last().GetEndTime() + 1;
|
||||||
|
|
||||||
private double firstHitTime => objects.First().StartTime;
|
private double firstHitTime => objects.First().StartTime;
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
@ -26,7 +25,7 @@ namespace osu.Game.Screens.Play
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var firstHit = objects.First().StartTime;
|
var firstHit = objects.First().StartTime;
|
||||||
var lastHit = objects.Max(o => (o as IHasEndTime)?.EndTime ?? o.StartTime);
|
var lastHit = objects.Max(o => o.GetEndTime());
|
||||||
|
|
||||||
if (lastHit == 0)
|
if (lastHit == 0)
|
||||||
lastHit = objects.Last().StartTime;
|
lastHit = objects.Last().StartTime;
|
||||||
@ -35,7 +34,7 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
foreach (var h in objects)
|
foreach (var h in objects)
|
||||||
{
|
{
|
||||||
var endTime = (h as IHasEndTime)?.EndTime ?? h.StartTime;
|
var endTime = h.GetEndTime();
|
||||||
|
|
||||||
Debug.Assert(endTime >= h.StartTime);
|
Debug.Assert(endTime >= h.StartTime);
|
||||||
|
|
||||||
|
@ -36,7 +36,9 @@ namespace osu.Game.Screens.Ranking
|
|||||||
Size = new Vector2(50);
|
Size = new Vector2(50);
|
||||||
|
|
||||||
Masking = true;
|
Masking = true;
|
||||||
|
|
||||||
CornerRadius = 25;
|
CornerRadius = 25;
|
||||||
|
CornerExponent = 2;
|
||||||
|
|
||||||
activeColour = colours.PinkDarker;
|
activeColour = colours.PinkDarker;
|
||||||
inactiveColour = OsuColour.Gray(0.8f);
|
inactiveColour = OsuColour.Gray(0.8f);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user