Skip to content

Commit

Permalink
Merge branch 'master' into tournament-display-team-seed
Browse files Browse the repository at this point in the history
  • Loading branch information
peppy authored Oct 31, 2023
2 parents feeb95e + 3060cf1 commit bb6555c
Show file tree
Hide file tree
Showing 48 changed files with 737 additions and 109 deletions.
2 changes: 1 addition & 1 deletion Templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Templates for use when creating osu! dependent projects. Create a fully-testable
```bash
# install (or update) templates package.
# this only needs to be done once
dotnet new -i ppy.osu.Game.Templates
dotnet new install ppy.osu.Game.Templates

# create an empty freeform ruleset
dotnet new ruleset -n MyCoolRuleset
Expand Down
2 changes: 1 addition & 1 deletion osu.Android.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.1012.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.1030.0" />
</ItemGroup>
<PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Version: 2.5
[Mania]
Keys: 4
ColumnLineWidth: 3,1,3,1,1
LightFramePerSecond: 15
// some skins found in the wild had configuration keys where the @2x suffix was included in the values.
// the expected compatibility behaviour is that the presence of the @2x suffix shouldn't change anything
// if @2x assets are present.
Expand All @@ -15,5 +16,6 @@ Hit300: mania/hit300@2x
Hit300g: mania/hit300g@2x
StageLeft: mania/stage-left
StageRight: mania/stage-right
StageLight: mania/stage-light
NoteImage0L: LongNoteTailWang
NoteImage1L: LongNoteTailWang
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private void load(ISkinSource skin, IScrollingInfo scrollingInfo, DrawableHitObj
direction.BindTo(scrollingInfo.Direction);
isHitting.BindTo(holdNote.IsHitting);

bodySprite = skin.GetAnimation(imageName, wrapMode, wrapMode, true, true).With(d =>
bodySprite = skin.GetAnimation(imageName, wrapMode, wrapMode, true, true, frameLength: 30).With(d =>
{
if (d == null)
return;
Expand Down
22 changes: 11 additions & 11 deletions osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Rulesets.UI.Scrolling;
Expand All @@ -20,7 +19,7 @@ public partial class LegacyColumnBackground : LegacyManiaColumnElement, IKeyBind
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();

private Container lightContainer = null!;
private Sprite light = null!;
private Drawable light = null!;

public LegacyColumnBackground()
{
Expand All @@ -39,23 +38,24 @@ private void load(ISkinSource skin, IScrollingInfo scrollingInfo)
Color4 lightColour = GetColumnSkinConfig<Color4>(skin, LegacyManiaSkinConfigurationLookups.ColumnLightColour)?.Value
?? Color4.White;

int lightFramePerSecond = skin.GetManiaSkinConfig<int>(LegacyManiaSkinConfigurationLookups.LightFramePerSecond)?.Value ?? 60;

InternalChildren = new[]
{
lightContainer = new Container
{
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Bottom = lightPosition },
Child = light = new Sprite
Child = light = skin.GetAnimation(lightImage, true, true, frameLength: 1000d / lightFramePerSecond)?.With(l =>
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Colour = LegacyColourCompatibility.DisallowZeroAlpha(lightColour),
Texture = skin.GetTexture(lightImage),
RelativeSizeAxes = Axes.X,
Width = 1,
Alpha = 0
}
l.Anchor = Anchor.BottomCentre;
l.Origin = Anchor.BottomCentre;
l.Colour = LegacyColourCompatibility.DisallowZeroAlpha(lightColour);
l.RelativeSizeAxes = Axes.X;
l.Width = 1;
l.Alpha = 0;
}) ?? Empty(),
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ private Drawable getResult(HitResult result)
string filename = this.GetManiaSkinConfig<string>(hit_result_mapping[result])?.Value
?? default_hit_result_skin_filenames[result];

var animation = this.GetAnimation(filename, true, true);
var animation = this.GetAnimation(filename, true, true, frameLength: 1000 / 20d);
return animation == null ? null : new LegacyManiaJudgementPiece(result, animation);
}

Expand Down
79 changes: 59 additions & 20 deletions osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderVelocityAdjust.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// 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.

#nullable disable

using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Input;
Expand All @@ -24,15 +21,15 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
{
public partial class TestSceneSliderVelocityAdjust : OsuGameTestScene
{
private Screens.Edit.Editor editor => Game.ScreenStack.CurrentScreen as Screens.Edit.Editor;
private Screens.Edit.Editor? editor => Game.ScreenStack.CurrentScreen as Screens.Edit.Editor;

private EditorBeatmap editorBeatmap => editor.ChildrenOfType<EditorBeatmap>().FirstOrDefault();
private EditorBeatmap editorBeatmap => editor.ChildrenOfType<EditorBeatmap>().FirstOrDefault()!;

private EditorClock editorClock => editor.ChildrenOfType<EditorClock>().FirstOrDefault();
private EditorClock editorClock => editor.ChildrenOfType<EditorClock>().FirstOrDefault()!;

private Slider slider => editorBeatmap.HitObjects.OfType<Slider>().FirstOrDefault();
private Slider? slider => editorBeatmap.HitObjects.OfType<Slider>().FirstOrDefault();

private TimelineHitObjectBlueprint blueprint => editor.ChildrenOfType<TimelineHitObjectBlueprint>().FirstOrDefault();
private TimelineHitObjectBlueprint blueprint => editor.ChildrenOfType<TimelineHitObjectBlueprint>().FirstOrDefault()!;

private DifficultyPointPiece difficultyPointPiece => blueprint.ChildrenOfType<DifficultyPointPiece>().First();

Expand All @@ -47,7 +44,7 @@ public void TestVelocityChangeSavesCorrectly(bool adjustVelocity)
double? velocity = null;

AddStep("enter editor", () => Game.ScreenStack.Push(new EditorLoader()));
AddUntilStep("wait for editor load", () => editor?.ReadyForUse == true);
AddUntilStep("wait for editor load", () => editor?.ReadyForUse, () => Is.True);

AddStep("seek to first control point", () => editorClock.Seek(editorBeatmap.ControlPointInfo.TimingPoints.First().Time));
AddStep("enter slider placement mode", () => InputManager.Key(Key.Number3));
Expand All @@ -60,36 +57,78 @@ public void TestVelocityChangeSavesCorrectly(bool adjustVelocity)

AddStep("exit placement mode", () => InputManager.Key(Key.Number1));

AddAssert("slider placed", () => slider != null);
AddAssert("slider placed", () => slider, () => Is.Not.Null);

AddStep("select slider", () => editorBeatmap.SelectedHitObjects.Add(slider));

AddAssert("ensure one slider placed", () => slider != null);
AddAssert("ensure one slider placed", () => slider, () => Is.Not.Null);

AddStep("store velocity", () => velocity = slider.Velocity);
AddStep("store velocity", () => velocity = slider!.Velocity);

if (adjustVelocity)
{
AddStep("open velocity adjust panel", () => difficultyPointPiece.TriggerClick());
AddStep("change velocity", () => velocityTextBox.Current.Value = 2);

AddAssert("velocity adjusted", () =>
{
Debug.Assert(velocity != null);
return Precision.AlmostEquals(velocity.Value * 2, slider.Velocity);
});
AddAssert("velocity adjusted", () => slider!.Velocity,
() => Is.EqualTo(velocity!.Value * 2).Within(Precision.DOUBLE_EPSILON));

AddStep("store velocity", () => velocity = slider.Velocity);
AddStep("store velocity", () => velocity = slider!.Velocity);
}

AddStep("save", () => InputManager.Keys(PlatformAction.Save));
AddStep("exit", () => InputManager.Key(Key.Escape));

AddStep("enter editor (again)", () => Game.ScreenStack.Push(new EditorLoader()));
AddUntilStep("wait for editor load", () => editor?.ReadyForUse, () => Is.True);

AddStep("seek to slider", () => editorClock.Seek(slider!.StartTime));
AddAssert("slider has correct velocity", () => slider!.Velocity, () => Is.EqualTo(velocity));
}

[Test]
public void TestVelocityUndo()
{
double? velocityBefore = null;
double? durationBefore = null;

AddStep("enter editor", () => Game.ScreenStack.Push(new EditorLoader()));
AddUntilStep("wait for editor load", () => editor?.ReadyForUse == true);

AddStep("seek to slider", () => editorClock.Seek(slider.StartTime));
AddAssert("slider has correct velocity", () => slider.Velocity == velocity);
AddStep("seek to first control point", () => editorClock.Seek(editorBeatmap.ControlPointInfo.TimingPoints.First().Time));
AddStep("enter slider placement mode", () => InputManager.Key(Key.Number3));

AddStep("move mouse to centre", () => InputManager.MoveMouseTo(editor.ChildrenOfType<Playfield>().First().ScreenSpaceDrawQuad.Centre));
AddStep("start placement", () => InputManager.Click(MouseButton.Left));

AddStep("move mouse to bottom right", () => InputManager.MoveMouseTo(editor.ChildrenOfType<Playfield>().First().ScreenSpaceDrawQuad.BottomRight - new Vector2(10)));
AddStep("end placement", () => InputManager.Click(MouseButton.Right));

AddStep("exit placement mode", () => InputManager.Key(Key.Number1));

AddAssert("slider placed", () => slider, () => Is.Not.Null);
AddStep("select slider", () => editorBeatmap.SelectedHitObjects.Add(slider));

AddStep("store velocity", () =>
{
velocityBefore = slider!.Velocity;
durationBefore = slider.Duration;
});

AddStep("open velocity adjust panel", () => difficultyPointPiece.TriggerClick());
AddStep("change velocity", () => velocityTextBox.Current.Value = 2);

AddAssert("velocity adjusted", () => slider!.Velocity, () => Is.EqualTo(velocityBefore!.Value * 2).Within(Precision.DOUBLE_EPSILON));

AddStep("undo", () =>
{
InputManager.PressKey(Key.ControlLeft);
InputManager.Key(Key.Z);
InputManager.ReleaseKey(Key.ControlLeft);
});

AddAssert("slider has correct velocity", () => slider!.Velocity, () => Is.EqualTo(velocityBefore));
AddAssert("slider has correct duration", () => slider!.Duration, () => Is.EqualTo(durationBefore));
}
}
}
6 changes: 3 additions & 3 deletions osu.Game.Rulesets.Osu.Tests/LegacyMainCirclePieceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void TestTexturePriorities(string[] textureFilenames, string priorityLook
Child = piece = new TestLegacyMainCirclePiece(priorityLookup),
};

var sprites = this.ChildrenOfType<Sprite>().Where(s => !string.IsNullOrEmpty(s.Texture.AssetName)).DistinctBy(s => s.Texture.AssetName).ToArray();
var sprites = this.ChildrenOfType<Sprite>().Where(s => !string.IsNullOrEmpty(s.Texture?.AssetName)).DistinctBy(s => s.Texture.AssetName).ToArray();
Debug.Assert(sprites.Length <= 2);
});

Expand All @@ -103,8 +103,8 @@ public void TestTexturePriorities(string[] textureFilenames, string priorityLook

private partial class TestLegacyMainCirclePiece : LegacyMainCirclePiece
{
public new Sprite? CircleSprite => base.CircleSprite.ChildrenOfType<Sprite>().DistinctBy(s => s.Texture.AssetName).SingleOrDefault();
public new Sprite? OverlaySprite => base.OverlaySprite.ChildrenOfType<Sprite>().DistinctBy(s => s.Texture.AssetName).SingleOrDefault();
public new Sprite? CircleSprite => base.CircleSprite.ChildrenOfType<Sprite>().Where(s => !string.IsNullOrEmpty(s.Texture?.AssetName)).DistinctBy(s => s.Texture.AssetName).SingleOrDefault();
public new Sprite? OverlaySprite => base.OverlaySprite.ChildrenOfType<Sprite>().Where(s => !string.IsNullOrEmpty(s.Texture?.AssetName)).DistinctBy(s => s.Texture.AssetName).SingleOrDefault();

public TestLegacyMainCirclePiece(string? priorityLookupPrefix)
: base(priorityLookupPrefix, false)
Expand Down
31 changes: 31 additions & 0 deletions osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerInput.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
Expand All @@ -10,6 +11,8 @@
using osu.Game.Beatmaps;
using osu.Game.Replays;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Replays;
Expand Down Expand Up @@ -47,6 +50,7 @@ protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storybo
public void Setup() => Schedule(() =>
{
manualClock = null;
SelectedMods.Value = Array.Empty<Mod>();
});

/// <summary>
Expand Down Expand Up @@ -102,6 +106,33 @@ public void TestVibrateWithoutSpinningOnCentre()
assertSpinnerHit(false);
}

[Test]
public void TestVibrateWithoutSpinningOnCentreWithDoubleTime()
{
List<ReplayFrame> frames = new List<ReplayFrame>();

const int rate = 2;
// the track clock is going to be playing twice as fast,
// so the vibration time in clock time needs to be twice as long
// to keep constant speed in real time.
const int vibrate_time = 50 * rate;

int direction = -1;

for (double i = time_spinner_start; i <= time_spinner_end; i += vibrate_time)
{
frames.Add(new OsuReplayFrame(i, new Vector2(centre_x + direction * 50, centre_y), OsuAction.LeftButton));
frames.Add(new OsuReplayFrame(i + vibrate_time, new Vector2(centre_x - direction * 50, centre_y), OsuAction.LeftButton));

direction *= -1;
}

AddStep("set DT", () => SelectedMods.Value = new[] { new OsuModDoubleTime { SpeedChange = { Value = rate } } });
performTest(frames);

assertSpinnerHit(false);
}

/// <summary>
/// Spins in a single direction.
/// </summary>
Expand Down
8 changes: 2 additions & 6 deletions osu.Game.Rulesets.Osu/Objects/Slider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,9 @@ public SliderPath Path
set
{
path.ControlPoints.Clear();
path.ExpectedDistance.Value = null;
path.ControlPoints.AddRange(value.ControlPoints.Select(c => new PathControlPoint(c.Position, c.Type)));

if (value != null)
{
path.ControlPoints.AddRange(value.ControlPoints.Select(c => new PathControlPoint(c.Position, c.Type)));
path.ExpectedDistance.Value = value.ExpectedDistance.Value;
}
path.ExpectedDistance.Value = value.ExpectedDistance.Value;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ public void AddRotation(float delta)
rotationTransferred = true;
}

Debug.Assert(Math.Abs(delta) <= 180);

double rate = gameplayClock?.GetTrueGameplayRate() ?? Clock.Rate;
delta = (float)(delta * Math.Abs(rate));

Debug.Assert(Math.Abs(delta) <= 180);

currentRotation += delta;
drawableSpinner.Result.History.ReportDelta(Time.Current, delta);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Osu.Skinning.Legacy
Expand Down Expand Up @@ -62,12 +63,14 @@ private void load()
// otherwise fall back to the default prefix "hitcircle".
string circleName = (priorityLookupPrefix != null && skin.GetTexture(priorityLookupPrefix) != null) ? priorityLookupPrefix : @"hitcircle";

Vector2 maxSize = OsuHitObject.OBJECT_DIMENSIONS * 2;

// at this point, any further texture fetches should be correctly using the priority source if the base texture was retrieved using it.
// the conditional above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist.
// expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png.
InternalChildren = new[]
{
CircleSprite = new LegacyKiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(circleName)?.WithMaximumSize(OsuHitObject.OBJECT_DIMENSIONS * 2) })
CircleSprite = new LegacyKiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(circleName)?.WithMaximumSize(maxSize) })
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Expand All @@ -76,7 +79,7 @@ private void load()
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Child = OverlaySprite = new LegacyKiaiFlashingDrawable(() => skin.GetAnimation(@$"{circleName}overlay", true, true, frameLength: 1000 / 2d, maxSize: OsuHitObject.OBJECT_DIMENSIONS * 2))
Child = OverlaySprite = new LegacyKiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(@$"{circleName}overlay")?.WithMaximumSize(maxSize) })
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Expand Down
10 changes: 6 additions & 4 deletions osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
Expand Down Expand Up @@ -41,11 +42,12 @@ private void load(DrawableHitObject drawableObject, ISkinSource skinSource)

var skin = skinSource.FindProvider(s => s.GetTexture(lookupName) != null);

InternalChild = arrow = (skin?.GetAnimation(lookupName, true, true, maxSize: OsuHitObject.OBJECT_DIMENSIONS * 2) ?? Empty()).With(d =>
InternalChild = arrow = new Sprite
{
d.Anchor = Anchor.Centre;
d.Origin = Anchor.Centre;
});
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Texture = skin?.GetTexture(lookupName)?.WithMaximumSize(maxSize: OsuHitObject.OBJECT_DIMENSIONS * 2),
};

textureIsDefaultSkin = skin is ISkinTransformer transformer && transformer.Skin is DefaultLegacySkin;

Expand Down
Loading

0 comments on commit bb6555c

Please sign in to comment.