mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 09:27:29 +08:00
Merge branch 'master' into tourney-asset-refactor
This commit is contained in:
commit
9639ebdd97
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||
<configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -15,7 +15,7 @@
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||
<configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -15,7 +15,7 @@
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||
<configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -15,7 +15,7 @@
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||
<configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Taiko.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -15,7 +15,7 @@
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
||||
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="--tournament" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -14,7 +14,7 @@
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Tournament (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
||||
<configuration default="false" name="Tournament (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Tournament" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tournament.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -15,7 +15,7 @@
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -14,7 +14,7 @@
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="osu! SDL" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||
<configuration default="false" name="osu! SDL" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="--sdl" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,9 +12,9 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||
<configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -14,7 +14,7 @@
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
<option name="Build" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
@ -51,7 +51,7 @@
|
||||
<Reference Include="Java.Interop" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.602.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.619.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.622.1" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.623.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -0,0 +1,10 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
Mode: 3
|
||||
|
||||
[TimingPoints]
|
||||
0,300,4,0,2,100,1,0
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,2,0:0:0:0:
|
@ -0,0 +1,10 @@
|
||||
osu file format v14
|
||||
|
||||
[General]
|
||||
Mode: 3
|
||||
|
||||
[TimingPoints]
|
||||
0,300,4,0,2,100,1,0
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,1,0:0:0:0:
|
@ -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 System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
public class TestSceneManiaHitObjectSamples : HitObjectSampleTest
|
||||
{
|
||||
protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset();
|
||||
protected override IResourceStore<byte[]> Resources => new DllResourceStore(Assembly.GetAssembly(typeof(TestSceneManiaHitObjectSamples)));
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when a normal sample bank is used, the normal hitsound will be looked up.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestManiaHitObjectNormalSampleBank()
|
||||
{
|
||||
const string expected_sample = "normal-hitnormal2";
|
||||
|
||||
SetupSkins(expected_sample, expected_sample);
|
||||
|
||||
CreateTestWithBeatmap("mania-hitobject-beatmap-normal-sample-bank.osu");
|
||||
|
||||
AssertBeatmapLookup(expected_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when a custom sample bank is used, layered hitsounds are not played
|
||||
/// (only the sample from the custom bank is looked up).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestManiaHitObjectCustomSampleBank()
|
||||
{
|
||||
const string expected_sample = "normal-hitwhistle2";
|
||||
const string unwanted_sample = "normal-hitnormal2";
|
||||
|
||||
SetupSkins(expected_sample, unwanted_sample);
|
||||
|
||||
CreateTestWithBeatmap("mania-hitobject-beatmap-custom-sample-bank.osu");
|
||||
|
||||
AssertBeatmapLookup(expected_sample);
|
||||
AssertNoLookup(unwanted_sample);
|
||||
}
|
||||
}
|
||||
}
|
@ -25,8 +25,10 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
||||
return 200;
|
||||
|
||||
case HitResult.Great:
|
||||
case HitResult.Perfect:
|
||||
return 300;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 320;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Skinning;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Objects.Legacy;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Skinning
|
||||
{
|
||||
@ -129,6 +132,15 @@ namespace osu.Game.Rulesets.Mania.Skinning
|
||||
return this.GetAnimation(filename, true, true);
|
||||
}
|
||||
|
||||
public override SampleChannel GetSample(ISampleInfo sampleInfo)
|
||||
{
|
||||
// layered hit sounds never play in mania
|
||||
if (sampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacySample && legacySample.IsLayered)
|
||||
return new SampleChannelVirtual();
|
||||
|
||||
return Source.GetSample(sampleInfo);
|
||||
}
|
||||
|
||||
public override IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup)
|
||||
{
|
||||
if (lookup is ManiaSkinConfigurationLookup maniaLookup)
|
||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
if (!drawableRepeat.IsHit)
|
||||
Child.ScaleTo(1.3f).ScaleTo(1f, timingPoint.BeatLength, Easing.Out);
|
||||
|
@ -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 osu.Framework.Audio.Track;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -8,7 +9,6 @@ using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osuTK.Graphics;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
if (!effectPoint.KiaiMode)
|
||||
return;
|
||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||
|
||||
|
@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
lastObjectHit = result.IsHit;
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
kiaiMode = effectPoint.KiaiMode;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
textureAnimation.Seek(0);
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
// assume that if the animation is playing on its own, it's independent from the beat and doesn't need to be touched.
|
||||
if (textureAnimation.FrameCount == 0 || textureAnimation.IsPlaying)
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Tests.Resources;
|
||||
|
||||
@ -167,5 +168,64 @@ namespace osu.Game.Tests.Gameplay
|
||||
|
||||
AssertBeatmapLookup(expected_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when a custom sample bank is used, both the normal and additional sounds will be looked up.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestHitObjectCustomSampleBank()
|
||||
{
|
||||
string[] expectedSamples =
|
||||
{
|
||||
"normal-hitnormal2",
|
||||
"normal-hitwhistle2"
|
||||
};
|
||||
|
||||
SetupSkins(expectedSamples[0], expectedSamples[1]);
|
||||
|
||||
CreateTestWithBeatmap("hitobject-beatmap-custom-sample-bank.osu");
|
||||
|
||||
AssertBeatmapLookup(expectedSamples[0]);
|
||||
AssertUserLookup(expectedSamples[1]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when a custom sample bank is used, but <see cref="GlobalSkinConfiguration.LayeredHitSounds"/> is disabled,
|
||||
/// only the additional sound will be looked up.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestHitObjectCustomSampleBankWithoutLayered()
|
||||
{
|
||||
const string expected_sample = "normal-hitwhistle2";
|
||||
const string unwanted_sample = "normal-hitnormal2";
|
||||
|
||||
SetupSkins(expected_sample, unwanted_sample);
|
||||
disableLayeredHitSounds();
|
||||
|
||||
CreateTestWithBeatmap("hitobject-beatmap-custom-sample-bank.osu");
|
||||
|
||||
AssertBeatmapLookup(expected_sample);
|
||||
AssertNoLookup(unwanted_sample);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when a normal sample bank is used and <see cref="GlobalSkinConfiguration.LayeredHitSounds"/> is disabled,
|
||||
/// the normal sound will be looked up anyway.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestHitObjectNormalSampleBankWithoutLayered()
|
||||
{
|
||||
const string expected_sample = "normal-hitnormal";
|
||||
|
||||
SetupSkins(expected_sample, expected_sample);
|
||||
disableLayeredHitSounds();
|
||||
|
||||
CreateTestWithBeatmap("hitobject-beatmap-sample.osu");
|
||||
|
||||
AssertBeatmapLookup(expected_sample);
|
||||
}
|
||||
|
||||
private void disableLayeredHitSounds()
|
||||
=> AddStep("set LayeredHitSounds to false", () => Skin.Configuration.ConfigDictionary[GlobalSkinConfiguration.LayeredHitSounds.ToString()] = "0");
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,10 @@ using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards;
|
||||
@ -70,6 +72,50 @@ namespace osu.Game.Tests.Gameplay
|
||||
AddUntilStep("sample playback succeeded", () => sample.LifetimeEnd < double.MaxValue);
|
||||
}
|
||||
|
||||
[TestCase(typeof(OsuModDoubleTime), 1.5)]
|
||||
[TestCase(typeof(OsuModHalfTime), 0.75)]
|
||||
[TestCase(typeof(ModWindUp), 1.5)]
|
||||
[TestCase(typeof(ModWindDown), 0.75)]
|
||||
[TestCase(typeof(OsuModDoubleTime), 2)]
|
||||
[TestCase(typeof(OsuModHalfTime), 0.5)]
|
||||
[TestCase(typeof(ModWindUp), 2)]
|
||||
[TestCase(typeof(ModWindDown), 0.5)]
|
||||
public void TestSamplePlaybackWithRateMods(Type expectedMod, double expectedRate)
|
||||
{
|
||||
GameplayClockContainer gameplayContainer = null;
|
||||
TestDrawableStoryboardSample sample = null;
|
||||
|
||||
Mod testedMod = Activator.CreateInstance(expectedMod) as Mod;
|
||||
|
||||
switch (testedMod)
|
||||
{
|
||||
case ModRateAdjust m:
|
||||
m.SpeedChange.Value = expectedRate;
|
||||
break;
|
||||
|
||||
case ModTimeRamp m:
|
||||
m.InitialRate.Value = m.FinalRate.Value = expectedRate;
|
||||
break;
|
||||
}
|
||||
|
||||
AddStep("setup storyboard sample", () =>
|
||||
{
|
||||
Beatmap.Value = new TestCustomSkinWorkingBeatmap(new OsuRuleset().RulesetInfo, Audio);
|
||||
SelectedMods.Value = new[] { testedMod };
|
||||
|
||||
Add(gameplayContainer = new GameplayClockContainer(Beatmap.Value, SelectedMods.Value, 0));
|
||||
|
||||
gameplayContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1))
|
||||
{
|
||||
Clock = gameplayContainer.GameplayClock
|
||||
});
|
||||
});
|
||||
|
||||
AddStep("start", () => gameplayContainer.Start());
|
||||
|
||||
AddAssert("sample playback rate matches mod rates", () => sample.Channel.AggregateFrequency.Value == expectedRate);
|
||||
}
|
||||
|
||||
private class TestSkin : LegacySkin
|
||||
{
|
||||
public TestSkin(string resourceName, AudioManager audioManager)
|
||||
@ -99,5 +145,28 @@ namespace osu.Game.Tests.Gameplay
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class TestCustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap
|
||||
{
|
||||
private readonly AudioManager audio;
|
||||
|
||||
public TestCustomSkinWorkingBeatmap(RulesetInfo ruleset, AudioManager audio)
|
||||
: base(ruleset, null, audio)
|
||||
{
|
||||
this.audio = audio;
|
||||
}
|
||||
|
||||
protected override ISkin GetSkin() => new TestSkin("test-sample", audio);
|
||||
}
|
||||
|
||||
private class TestDrawableStoryboardSample : DrawableStoryboardSample
|
||||
{
|
||||
public TestDrawableStoryboardSample(StoryboardSampleInfo sampleInfo)
|
||||
: base(sampleInfo)
|
||||
{
|
||||
}
|
||||
|
||||
public new SampleChannel Channel => base.Channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
osu file format v14
|
||||
|
||||
[TimingPoints]
|
||||
0,300,4,0,2,100,1,0
|
||||
|
||||
[HitObjects]
|
||||
444,320,1000,5,2,0:0:0:0:
|
5
osu.Game.Tests/Resources/skin-zero-alpha-colour.ini
Normal file
5
osu.Game.Tests/Resources/skin-zero-alpha-colour.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[General]
|
||||
Version: latest
|
||||
|
||||
[Colours]
|
||||
Combo1: 255,255,255,0
|
@ -108,5 +108,15 @@ namespace osu.Game.Tests.Skins
|
||||
using (var stream = new LineBufferedReader(resStream))
|
||||
Assert.That(decoder.Decode(stream).LegacyVersion, Is.EqualTo(1.0m));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDecodeColourWithZeroAlpha()
|
||||
{
|
||||
var decoder = new LegacySkinDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("skin-zero-alpha-colour.ini"))
|
||||
using (var stream = new LineBufferedReader(resStream))
|
||||
Assert.That(decoder.Decode(stream).ComboColours[0].A, Is.EqualTo(1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,9 +174,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Test]
|
||||
public void TestExitFromGameplay()
|
||||
{
|
||||
AddStep("exit", () => Player.Exit());
|
||||
confirmPaused();
|
||||
|
||||
// an externally triggered exit should immediately exit, skipping all pause logic.
|
||||
AddStep("exit", () => Player.Exit());
|
||||
confirmExited();
|
||||
}
|
||||
|
15
osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs
Normal file
15
osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs
Normal file
@ -0,0 +1,15 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Screens.Menu;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Menus
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneIntroWelcome : IntroTestScene
|
||||
{
|
||||
protected override IScreen CreateScreen() => new IntroWelcome();
|
||||
}
|
||||
}
|
@ -17,11 +17,12 @@ using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Select.Carousel;
|
||||
using osu.Game.Screens.Select.Filter;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Tests.Visual.SongSelect
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneBeatmapCarousel : OsuTestScene
|
||||
public class TestSceneBeatmapCarousel : OsuManualInputManagerTestScene
|
||||
{
|
||||
private TestBeatmapCarousel carousel;
|
||||
private RulesetStore rulesets;
|
||||
@ -39,6 +40,43 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
this.rulesets = rulesets;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestKeyRepeat()
|
||||
{
|
||||
loadBeatmaps();
|
||||
advanceSelection(false);
|
||||
|
||||
AddStep("press down arrow", () => InputManager.PressKey(Key.Down));
|
||||
|
||||
BeatmapInfo selection = null;
|
||||
|
||||
checkSelectionIterating(true);
|
||||
|
||||
AddStep("press up arrow", () => InputManager.PressKey(Key.Up));
|
||||
|
||||
checkSelectionIterating(true);
|
||||
|
||||
AddStep("release down arrow", () => InputManager.ReleaseKey(Key.Down));
|
||||
|
||||
checkSelectionIterating(true);
|
||||
|
||||
AddStep("release up arrow", () => InputManager.ReleaseKey(Key.Up));
|
||||
|
||||
checkSelectionIterating(false);
|
||||
|
||||
void checkSelectionIterating(bool isIterating)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
AddStep("store selection", () => selection = carousel.SelectedBeatmap);
|
||||
if (isIterating)
|
||||
AddUntilStep("selection changed", () => carousel.SelectedBeatmap != selection);
|
||||
else
|
||||
AddUntilStep("selection not changed", () => carousel.SelectedBeatmap == selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRecommendedSelection()
|
||||
{
|
||||
|
@ -177,7 +177,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
timeSinceLastBeat.Value = TimeSinceLastBeat;
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||
|
||||
|
@ -9,7 +9,7 @@ using osu.Game.Tournament.Screens.Gameplay.Components;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Components
|
||||
{
|
||||
public class TestSceneMatchScoreDisplay : LadderTestScene
|
||||
public class TestSceneMatchScoreDisplay : TournamentTestScene
|
||||
{
|
||||
[Cached(Type = typeof(MatchIPCInfo))]
|
||||
private MatchIPCInfo matchInfo = new MatchIPCInfo();
|
||||
|
@ -8,12 +8,11 @@ using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osu.Game.Tournament.Components;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Components
|
||||
{
|
||||
public class TestSceneTournamentBeatmapPanel : OsuTestScene
|
||||
public class TestSceneTournamentBeatmapPanel : TournamentTestScene
|
||||
{
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
@ -1,146 +0,0 @@
|
||||
// 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.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tournament.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public abstract class LadderTestScene : TournamentTestScene
|
||||
{
|
||||
[Cached]
|
||||
protected LadderInfo Ladder { get; private set; } = new LadderInfo();
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesetStore { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Ladder.Ruleset.Value ??= rulesetStore.AvailableRulesets.First();
|
||||
|
||||
Ruleset.BindTo(Ladder.Ruleset);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
TournamentMatch match = CreateSampleMatch();
|
||||
|
||||
Ladder.Rounds.Add(match.Round.Value);
|
||||
Ladder.Matches.Add(match);
|
||||
Ladder.Teams.Add(match.Team1.Value);
|
||||
Ladder.Teams.Add(match.Team2.Value);
|
||||
|
||||
Ladder.CurrentMatch.Value = match;
|
||||
}
|
||||
|
||||
public static TournamentMatch CreateSampleMatch() => new TournamentMatch
|
||||
{
|
||||
Team1 =
|
||||
{
|
||||
Value = new TournamentTeam
|
||||
{
|
||||
FlagName = { Value = "JP" },
|
||||
FullName = { Value = "Japan" },
|
||||
LastYearPlacing = { Value = 10 },
|
||||
Seed = { Value = "Low" },
|
||||
SeedingResults =
|
||||
{
|
||||
new SeedingResult
|
||||
{
|
||||
Mod = { Value = "NM" },
|
||||
Seed = { Value = 10 },
|
||||
Beatmaps =
|
||||
{
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 12345672,
|
||||
Seed = { Value = 24 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 1234567,
|
||||
Seed = { Value = 12 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 1234567,
|
||||
Seed = { Value = 16 },
|
||||
}
|
||||
}
|
||||
},
|
||||
new SeedingResult
|
||||
{
|
||||
Mod = { Value = "DT" },
|
||||
Seed = { Value = 5 },
|
||||
Beatmaps =
|
||||
{
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 234567,
|
||||
Seed = { Value = 3 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 234567,
|
||||
Seed = { Value = 6 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 234567,
|
||||
Seed = { Value = 12 },
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Players =
|
||||
{
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 12 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 16 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 20 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 30 } } },
|
||||
}
|
||||
}
|
||||
},
|
||||
Team2 =
|
||||
{
|
||||
Value = new TournamentTeam
|
||||
{
|
||||
FlagName = { Value = "US" },
|
||||
FullName = { Value = "United States" },
|
||||
Players =
|
||||
{
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
}
|
||||
}
|
||||
},
|
||||
Round =
|
||||
{
|
||||
Value = new TournamentRound { Name = { Value = "Quarterfinals" } }
|
||||
}
|
||||
};
|
||||
|
||||
public static BeatmapInfo CreateSampleBeatmapInfo() =>
|
||||
new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist", ID = RNG.Next(0, 1000000) } };
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ using osu.Game.Tournament.Screens.Editors;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneLadderEditorScreen : LadderTestScene
|
||||
public class TestSceneLadderEditorScreen : TournamentTestScene
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
|
@ -8,7 +8,7 @@ using osu.Game.Tournament.Screens.Ladder;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneLadderScreen : LadderTestScene
|
||||
public class TestSceneLadderScreen : TournamentTestScene
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
|
@ -12,7 +12,7 @@ using osu.Game.Tournament.Screens.MapPool;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneMapPoolScreen : LadderTestScene
|
||||
public class TestSceneMapPoolScreen : TournamentTestScene
|
||||
{
|
||||
private MapPoolScreen screen;
|
||||
|
||||
|
@ -5,7 +5,7 @@ using osu.Game.Tournament.Screens.Editors;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneRoundEditorScreen : LadderTestScene
|
||||
public class TestSceneRoundEditorScreen : TournamentTestScene
|
||||
{
|
||||
public TestSceneRoundEditorScreen()
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ using osu.Game.Tournament.Screens.Editors;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneSeedingEditorScreen : LadderTestScene
|
||||
public class TestSceneSeedingEditorScreen : TournamentTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly LadderInfo ladder = new LadderInfo();
|
||||
|
@ -8,7 +8,7 @@ using osu.Game.Tournament.Screens.TeamIntro;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneSeedingScreen : LadderTestScene
|
||||
public class TestSceneSeedingScreen : TournamentTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly LadderInfo ladder = new LadderInfo();
|
||||
|
@ -5,7 +5,7 @@ using osu.Game.Tournament.Screens.Editors;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneTeamEditorScreen : LadderTestScene
|
||||
public class TestSceneTeamEditorScreen : TournamentTestScene
|
||||
{
|
||||
public TestSceneTeamEditorScreen()
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ using osu.Game.Tournament.Screens.TeamIntro;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneTeamIntroScreen : LadderTestScene
|
||||
public class TestSceneTeamIntroScreen : TournamentTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly LadderInfo ladder = new LadderInfo();
|
||||
|
@ -4,25 +4,19 @@
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.TeamWin;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneTeamWinScreen : LadderTestScene
|
||||
public class TestSceneTeamWinScreen : TournamentTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly LadderInfo ladder = new LadderInfo();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var match = new TournamentMatch();
|
||||
match.Team1.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "USA");
|
||||
match.Team2.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "JPN");
|
||||
var match = Ladder.CurrentMatch.Value;
|
||||
|
||||
match.Round.Value = Ladder.Rounds.FirstOrDefault(g => g.Name.Value == "Finals");
|
||||
match.Completed.Value = true;
|
||||
ladder.CurrentMatch.Value = match;
|
||||
|
||||
Add(new TeamWinScreen
|
||||
{
|
||||
|
@ -1,13 +1,151 @@
|
||||
// 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.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osu.Game.Tournament.IPC;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tournament.Tests
|
||||
{
|
||||
public abstract class TournamentTestScene : OsuTestScene
|
||||
{
|
||||
[Cached]
|
||||
protected LadderInfo Ladder { get; private set; } = new LadderInfo();
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesetStore { get; set; }
|
||||
|
||||
[Cached]
|
||||
protected MatchIPCInfo IPCInfo { get; private set; } = new MatchIPCInfo();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(Storage storage)
|
||||
{
|
||||
Ladder.Ruleset.Value ??= rulesetStore.AvailableRulesets.First();
|
||||
|
||||
TournamentMatch match = CreateSampleMatch();
|
||||
|
||||
Ladder.Rounds.Add(match.Round.Value);
|
||||
Ladder.Matches.Add(match);
|
||||
Ladder.Teams.Add(match.Team1.Value);
|
||||
Ladder.Teams.Add(match.Team2.Value);
|
||||
|
||||
Ladder.CurrentMatch.Value = match;
|
||||
|
||||
Ruleset.BindTo(Ladder.Ruleset);
|
||||
Dependencies.CacheAs(new StableInfo(storage));
|
||||
}
|
||||
|
||||
public static TournamentMatch CreateSampleMatch() => new TournamentMatch
|
||||
{
|
||||
Team1 =
|
||||
{
|
||||
Value = new TournamentTeam
|
||||
{
|
||||
Acronym = { Value = "JPN" },
|
||||
FlagName = { Value = "JP" },
|
||||
FullName = { Value = "Japan" },
|
||||
LastYearPlacing = { Value = 10 },
|
||||
Seed = { Value = "Low" },
|
||||
SeedingResults =
|
||||
{
|
||||
new SeedingResult
|
||||
{
|
||||
Mod = { Value = "NM" },
|
||||
Seed = { Value = 10 },
|
||||
Beatmaps =
|
||||
{
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 12345672,
|
||||
Seed = { Value = 24 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 1234567,
|
||||
Seed = { Value = 12 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 1234567,
|
||||
Seed = { Value = 16 },
|
||||
}
|
||||
}
|
||||
},
|
||||
new SeedingResult
|
||||
{
|
||||
Mod = { Value = "DT" },
|
||||
Seed = { Value = 5 },
|
||||
Beatmaps =
|
||||
{
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 234567,
|
||||
Seed = { Value = 3 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 234567,
|
||||
Seed = { Value = 6 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = CreateSampleBeatmapInfo(),
|
||||
Score = 234567,
|
||||
Seed = { Value = 12 },
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Players =
|
||||
{
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 12 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 16 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 20 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 30 } } },
|
||||
}
|
||||
}
|
||||
},
|
||||
Team2 =
|
||||
{
|
||||
Value = new TournamentTeam
|
||||
{
|
||||
Acronym = { Value = "USA" },
|
||||
FlagName = { Value = "US" },
|
||||
FullName = { Value = "United States" },
|
||||
Players =
|
||||
{
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
}
|
||||
}
|
||||
},
|
||||
Round =
|
||||
{
|
||||
Value = new TournamentRound { Name = { Value = "Quarterfinals" } }
|
||||
}
|
||||
};
|
||||
|
||||
public static BeatmapInfo CreateSampleBeatmapInfo() =>
|
||||
new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist", ID = RNG.Next(0, 1000000) } };
|
||||
|
||||
protected override ITestSceneTestRunner CreateRunner() => new TournamentTestSceneTestRunner();
|
||||
|
||||
public class TournamentTestSceneTestRunner : TournamentGameBase, ITestSceneTestRunner
|
||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Tournament
|
||||
|
||||
public const float STREAM_AREA_WIDTH = 1366;
|
||||
|
||||
public const double REQUIRED_WIDTH = TournamentSceneManager.CONTROL_AREA_WIDTH * 2 + TournamentSceneManager.STREAM_AREA_WIDTH;
|
||||
public const double REQUIRED_WIDTH = CONTROL_AREA_WIDTH * 2 + STREAM_AREA_WIDTH;
|
||||
|
||||
[Cached]
|
||||
private TournamentMatchChatDisplay chat = new TournamentMatchChatDisplay();
|
||||
|
@ -103,7 +103,12 @@ namespace osu.Game.Beatmaps.Formats
|
||||
|
||||
try
|
||||
{
|
||||
colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), split.Length == 4 ? byte.Parse(split[3]) : (byte)255);
|
||||
byte alpha = split.Length == 4 ? byte.Parse(split[3]) : (byte)255;
|
||||
|
||||
if (alpha == 0)
|
||||
alpha = 255;
|
||||
|
||||
colour = new Color4(byte.Parse(split[0]), byte.Parse(split[1]), byte.Parse(split[2]), alpha);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
/// </summary>
|
||||
public static class Parsing
|
||||
{
|
||||
public const int MAX_COORDINATE_VALUE = 65536;
|
||||
public const int MAX_COORDINATE_VALUE = 131072;
|
||||
|
||||
public const double MAX_PARSE_VALUE = int.MaxValue;
|
||||
|
||||
|
@ -6,6 +6,7 @@ namespace osu.Game.Configuration
|
||||
public enum IntroSequence
|
||||
{
|
||||
Circles,
|
||||
Welcome,
|
||||
Triangles,
|
||||
Random
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Graphics.Containers
|
||||
private TimingControlPoint lastTimingPoint;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time before a beat we should fire <see cref="OnNewBeat(int, TimingControlPoint, EffectControlPoint, TrackAmplitudes)"/>.
|
||||
/// The amount of time before a beat we should fire <see cref="OnNewBeat(int, TimingControlPoint, EffectControlPoint, ChannelAmplitudes)"/>.
|
||||
/// This allows for adding easing to animations that may be synchronised to the beat.
|
||||
/// </summary>
|
||||
protected double EarlyActivationMilliseconds;
|
||||
@ -50,7 +50,6 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
private TimingControlPoint defaultTiming;
|
||||
private EffectControlPoint defaultEffect;
|
||||
private TrackAmplitudes defaultAmplitudes;
|
||||
|
||||
protected bool IsBeatSyncedWithTrack { get; private set; }
|
||||
|
||||
@ -107,7 +106,7 @@ namespace osu.Game.Graphics.Containers
|
||||
return;
|
||||
|
||||
using (BeginDelayedSequence(-TimeSinceLastBeat, true))
|
||||
OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? defaultAmplitudes);
|
||||
OnNewBeat(beatIndex, timingPoint, effectPoint, track?.CurrentAmplitudes ?? ChannelAmplitudes.Empty);
|
||||
|
||||
lastBeat = beatIndex;
|
||||
lastTimingPoint = timingPoint;
|
||||
@ -128,16 +127,9 @@ namespace osu.Game.Graphics.Containers
|
||||
KiaiMode = false,
|
||||
OmitFirstBarLine = false
|
||||
};
|
||||
|
||||
defaultAmplitudes = new TrackAmplitudes
|
||||
{
|
||||
FrequencyAmplitudes = new float[256],
|
||||
LeftChannel = 0,
|
||||
RightChannel = 0
|
||||
};
|
||||
}
|
||||
|
||||
protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ using JetBrains.Annotations;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Input.Events;
|
||||
using osuTK.Input;
|
||||
using osu.Framework.Utils;
|
||||
|
||||
namespace osu.Game.Graphics.Cursor
|
||||
@ -74,17 +73,15 @@ namespace osu.Game.Graphics.Cursor
|
||||
protected override bool OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
// only trigger animation for main mouse buttons
|
||||
if (e.Button <= MouseButton.Right)
|
||||
{
|
||||
activeCursor.Scale = new Vector2(1);
|
||||
activeCursor.ScaleTo(0.90f, 800, Easing.OutQuint);
|
||||
activeCursor.Scale = new Vector2(1);
|
||||
activeCursor.ScaleTo(0.90f, 800, Easing.OutQuint);
|
||||
|
||||
activeCursor.AdditiveLayer.Alpha = 0;
|
||||
activeCursor.AdditiveLayer.FadeInFromZero(800, Easing.OutQuint);
|
||||
}
|
||||
activeCursor.AdditiveLayer.Alpha = 0;
|
||||
activeCursor.AdditiveLayer.FadeInFromZero(800, Easing.OutQuint);
|
||||
|
||||
if (e.Button == MouseButton.Left && cursorRotate.Value)
|
||||
if (cursorRotate.Value && dragRotationState != DragRotationState.Rotating)
|
||||
{
|
||||
// if cursor is already rotating don't reset its rotate origin
|
||||
dragRotationState = DragRotationState.DragStarted;
|
||||
positionMouseDown = e.MousePosition;
|
||||
}
|
||||
@ -94,17 +91,16 @@ namespace osu.Game.Graphics.Cursor
|
||||
|
||||
protected override void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
if (!e.IsPressed(MouseButton.Left) && !e.IsPressed(MouseButton.Right))
|
||||
if (!e.HasAnyButtonPressed)
|
||||
{
|
||||
activeCursor.AdditiveLayer.FadeOutFromOne(500, Easing.OutQuint);
|
||||
activeCursor.ScaleTo(1, 500, Easing.OutElastic);
|
||||
}
|
||||
|
||||
if (e.Button == MouseButton.Left)
|
||||
{
|
||||
if (dragRotationState == DragRotationState.Rotating)
|
||||
if (dragRotationState != DragRotationState.NotDragging)
|
||||
{
|
||||
activeCursor.RotateTo(0, 600 * (1 + Math.Abs(activeCursor.Rotation / 720)), Easing.OutElasticHalf);
|
||||
dragRotationState = DragRotationState.NotDragging;
|
||||
dragRotationState = DragRotationState.NotDragging;
|
||||
}
|
||||
}
|
||||
|
||||
base.OnMouseUp(e);
|
||||
|
@ -147,7 +147,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
if (!hasSelection)
|
||||
this.FadeTo(0.7f).FadeTo(0.4f, timingPoint.BeatLength, Easing.InOutSine);
|
||||
|
@ -230,7 +230,7 @@ namespace osu.Game.Graphics.UserInterface
|
||||
};
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||
|
||||
|
9
osu.Game/Rulesets/Mods/IApplicableToAudio.cs
Normal file
9
osu.Game/Rulesets/Mods/IApplicableToAudio.cs
Normal file
@ -0,0 +1,9 @@
|
||||
// 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.Rulesets.Mods
|
||||
{
|
||||
public interface IApplicableToAudio : IApplicableToTrack, IApplicableToSample
|
||||
{
|
||||
}
|
||||
}
|
15
osu.Game/Rulesets/Mods/IApplicableToSample.cs
Normal file
15
osu.Game/Rulesets/Mods/IApplicableToSample.cs
Normal file
@ -0,0 +1,15 @@
|
||||
// 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.Audio.Sample;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for mods that make adjustments to a sample.
|
||||
/// </summary>
|
||||
public interface IApplicableToSample : IApplicableMod
|
||||
{
|
||||
void ApplyToSample(SampleChannel sample);
|
||||
}
|
||||
}
|
@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Mods
|
||||
|
||||
private const int bars_per_segment = 4;
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||
|
||||
|
@ -2,12 +2,13 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
public abstract class ModRateAdjust : Mod, IApplicableToTrack
|
||||
public abstract class ModRateAdjust : Mod, IApplicableToAudio
|
||||
{
|
||||
public abstract BindableNumber<double> SpeedChange { get; }
|
||||
|
||||
@ -16,6 +17,11 @@ namespace osu.Game.Rulesets.Mods
|
||||
track.AddAdjustment(AdjustableProperty.Tempo, SpeedChange);
|
||||
}
|
||||
|
||||
public virtual void ApplyToSample(SampleChannel sample)
|
||||
{
|
||||
sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange);
|
||||
}
|
||||
|
||||
public override string SettingDescription => SpeedChange.IsDefault ? string.Empty : $"{SpeedChange.Value:N2}x";
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,11 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Framework.Audio.Sample;
|
||||
|
||||
namespace osu.Game.Rulesets.Mods
|
||||
{
|
||||
public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToBeatmap, IApplicableToTrack
|
||||
public abstract class ModTimeRamp : Mod, IUpdatableByPlayfield, IApplicableToBeatmap, IApplicableToAudio
|
||||
{
|
||||
/// <summary>
|
||||
/// The point in the beatmap at which the final ramping rate should be reached.
|
||||
@ -58,6 +59,11 @@ namespace osu.Game.Rulesets.Mods
|
||||
AdjustPitch.TriggerChange();
|
||||
}
|
||||
|
||||
public void ApplyToSample(SampleChannel sample)
|
||||
{
|
||||
sample.AddAdjustment(AdjustableProperty.Frequency, SpeedChange);
|
||||
}
|
||||
|
||||
public virtual void ApplyToBeatmap(IBeatmap beatmap)
|
||||
{
|
||||
HitObject lastObject = beatmap.HitObjects.LastOrDefault();
|
||||
|
@ -12,6 +12,7 @@ using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects.Legacy
|
||||
{
|
||||
@ -356,7 +357,10 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
Bank = bankInfo.Normal,
|
||||
Name = HitSampleInfo.HIT_NORMAL,
|
||||
Volume = bankInfo.Volume,
|
||||
CustomSampleBank = bankInfo.CustomSampleBank
|
||||
CustomSampleBank = bankInfo.CustomSampleBank,
|
||||
// if the sound type doesn't have the Normal flag set, attach it anyway as a layered sample.
|
||||
// None also counts as a normal non-layered sample: https://osu.ppy.sh/help/wiki/osu!_File_Formats/Osu_(file_format)#hitsounds
|
||||
IsLayered = type != LegacyHitSoundType.None && !type.HasFlag(LegacyHitSoundType.Normal)
|
||||
}
|
||||
};
|
||||
|
||||
@ -409,7 +413,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
public SampleBankInfo Clone() => (SampleBankInfo)MemberwiseClone();
|
||||
}
|
||||
|
||||
internal class LegacyHitSampleInfo : HitSampleInfo
|
||||
public class LegacyHitSampleInfo : HitSampleInfo
|
||||
{
|
||||
private int customSampleBank;
|
||||
|
||||
@ -424,6 +428,15 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
Suffix = value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether this hit sample is layered.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Layered hit samples are automatically added in all modes (except osu!mania), but can be disabled
|
||||
/// using the <see cref="GlobalSkinConfiguration.LayeredHitSounds"/> skin config option.
|
||||
/// </remarks>
|
||||
public bool IsLayered { get; set; }
|
||||
}
|
||||
|
||||
private class FileHitSampleInfo : LegacyHitSampleInfo
|
||||
|
@ -13,6 +13,7 @@ using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
@ -82,6 +83,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
foreach (var o in args.OldItems)
|
||||
SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect();
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -250,6 +252,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
blueprint.Deselected -= onBlueprintDeselected;
|
||||
|
||||
SelectionBlueprints.Remove(blueprint);
|
||||
|
||||
if (movementBlueprint == blueprint)
|
||||
finishSelectionMovement();
|
||||
}
|
||||
|
||||
protected virtual void AddBlueprintFor(HitObject hitObject)
|
||||
@ -320,10 +325,22 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
foreach (var blueprint in SelectionBlueprints)
|
||||
{
|
||||
if (blueprint.IsAlive && blueprint.IsPresent && rect.Contains(blueprint.ScreenSpaceSelectionPoint))
|
||||
blueprint.Select();
|
||||
else
|
||||
blueprint.Deselect();
|
||||
// only run when utmost necessary to avoid unnecessary rect computations.
|
||||
bool isValidForSelection() => blueprint.IsAlive && blueprint.IsPresent && rect.Contains(blueprint.ScreenSpaceSelectionPoint);
|
||||
|
||||
switch (blueprint.State)
|
||||
{
|
||||
case SelectionState.NotSelected:
|
||||
if (isValidForSelection())
|
||||
blueprint.Select();
|
||||
break;
|
||||
|
||||
case SelectionState.Selected:
|
||||
// if the editor is playing, we generally don't want to deselect objects even if outside the selection area.
|
||||
if (!editorClock.IsRunning && !isValidForSelection())
|
||||
blueprint.Deselect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
}
|
||||
};
|
||||
|
||||
private RectangleF? dragRectangle;
|
||||
|
||||
/// <summary>
|
||||
/// Handle a forwarded mouse event.
|
||||
/// </summary>
|
||||
@ -66,15 +68,14 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
var dragQuad = new Quad(dragStartPosition.X, dragStartPosition.Y, dragPosition.X - dragStartPosition.X, dragPosition.Y - dragStartPosition.Y);
|
||||
|
||||
// We use AABBFloat instead of RectangleF since it handles negative sizes for us
|
||||
var dragRectangle = dragQuad.AABBFloat;
|
||||
var rec = dragQuad.AABBFloat;
|
||||
dragRectangle = rec;
|
||||
|
||||
var topLeft = ToLocalSpace(dragRectangle.TopLeft);
|
||||
var bottomRight = ToLocalSpace(dragRectangle.BottomRight);
|
||||
var topLeft = ToLocalSpace(rec.TopLeft);
|
||||
var bottomRight = ToLocalSpace(rec.BottomRight);
|
||||
|
||||
Box.Position = topLeft;
|
||||
Box.Size = bottomRight - topLeft;
|
||||
|
||||
PerformSelection?.Invoke(dragRectangle);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -93,7 +94,19 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void Hide() => State = Visibility.Hidden;
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (dragRectangle != null)
|
||||
PerformSelection?.Invoke(dragRectangle.Value);
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
{
|
||||
State = Visibility.Hidden;
|
||||
dragRectangle = null;
|
||||
}
|
||||
|
||||
public override void Show() => State = Visibility.Visible;
|
||||
|
||||
|
@ -51,6 +51,9 @@ namespace osu.Game.Screens
|
||||
case IntroSequence.Circles:
|
||||
return new IntroCircles();
|
||||
|
||||
case IntroSequence.Welcome:
|
||||
return new IntroWelcome();
|
||||
|
||||
default:
|
||||
return new IntroTriangles();
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
@ -15,7 +16,6 @@ using osuTK.Graphics;
|
||||
using osuTK.Input;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input.Events;
|
||||
@ -132,7 +132,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private bool rightward;
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Screens.Menu
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
if (MenuVoice.Value)
|
||||
welcome = audio.Samples.Get(@"welcome");
|
||||
welcome = audio.Samples.Get(@"Intro/welcome");
|
||||
}
|
||||
|
||||
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||
|
@ -51,6 +51,8 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private SampleChannel seeya;
|
||||
|
||||
protected virtual string SeeyaSampleName => "Intro/seeya";
|
||||
|
||||
private LeasedBindable<WorkingBeatmap> beatmap;
|
||||
|
||||
private MainMenu mainMenu;
|
||||
@ -72,7 +74,7 @@ namespace osu.Game.Screens.Menu
|
||||
MenuVoice = config.GetBindable<bool>(OsuSetting.MenuVoice);
|
||||
MenuMusic = config.GetBindable<bool>(OsuSetting.MenuMusic);
|
||||
|
||||
seeya = audio.Samples.Get(@"seeya");
|
||||
seeya = audio.Samples.Get(SeeyaSampleName);
|
||||
|
||||
BeatmapSetInfo setInfo = null;
|
||||
|
||||
|
@ -47,7 +47,7 @@ namespace osu.Game.Screens.Menu
|
||||
private void load()
|
||||
{
|
||||
if (MenuVoice.Value && !UsingThemedIntro)
|
||||
welcome = audio.Samples.Get(@"welcome");
|
||||
welcome = audio.Samples.Get(@"Intro/welcome");
|
||||
}
|
||||
|
||||
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||
|
150
osu.Game/Screens/Menu/IntroWelcome.cs
Normal file
150
osu.Game/Screens/Menu/IntroWelcome.cs
Normal file
@ -0,0 +1,150 @@
|
||||
// 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 osuTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Screens.Backgrounds;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
public class IntroWelcome : IntroScreen
|
||||
{
|
||||
protected override string BeatmapHash => "64e00d7022195959bfa3109d09c2e2276c8f12f486b91fcf6175583e973b48f2";
|
||||
protected override string BeatmapFile => "welcome.osz";
|
||||
private const double delay_step_two = 2142;
|
||||
private SampleChannel welcome;
|
||||
private SampleChannel pianoReverb;
|
||||
protected override string SeeyaSampleName => "Intro/Welcome/seeya";
|
||||
|
||||
protected override BackgroundScreen CreateBackground() => background = new BackgroundScreenDefault(false)
|
||||
{
|
||||
Alpha = 0,
|
||||
};
|
||||
|
||||
private BackgroundScreenDefault background;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
{
|
||||
if (MenuVoice.Value)
|
||||
welcome = audio.Samples.Get(@"Intro/Welcome/welcome");
|
||||
|
||||
pianoReverb = audio.Samples.Get(@"Intro/Welcome/welcome_piano");
|
||||
}
|
||||
|
||||
protected override void LogoArriving(OsuLogo logo, bool resuming)
|
||||
{
|
||||
base.LogoArriving(logo, resuming);
|
||||
|
||||
if (!resuming)
|
||||
{
|
||||
LoadComponentAsync(new WelcomeIntroSequence
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
}, intro =>
|
||||
{
|
||||
PrepareMenuLoad();
|
||||
|
||||
intro.LogoVisualisation.AddAmplitudeSource(pianoReverb);
|
||||
|
||||
AddInternal(intro);
|
||||
|
||||
welcome?.Play();
|
||||
pianoReverb?.Play();
|
||||
|
||||
Scheduler.AddDelayed(() =>
|
||||
{
|
||||
StartTrack();
|
||||
|
||||
const float fade_in_time = 200;
|
||||
|
||||
logo.ScaleTo(1);
|
||||
logo.FadeIn(fade_in_time);
|
||||
|
||||
background.FadeIn(fade_in_time);
|
||||
|
||||
LoadMenu();
|
||||
}, delay_step_two);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResuming(IScreen last)
|
||||
{
|
||||
base.OnResuming(last);
|
||||
background.FadeOut(100);
|
||||
}
|
||||
|
||||
private class WelcomeIntroSequence : Container
|
||||
{
|
||||
private Sprite welcomeText;
|
||||
private Container scaleContainer;
|
||||
|
||||
public LogoVisualisation LogoVisualisation { get; private set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Origin = Anchor.Centre;
|
||||
Anchor = Anchor.Centre;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
scaleContainer = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
LogoVisualisation = new LogoVisualisation
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Alpha = 0.5f,
|
||||
AccentColour = Color4.DarkBlue,
|
||||
Size = new Vector2(0.96f)
|
||||
},
|
||||
new Circle
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(480),
|
||||
Colour = Color4.Black
|
||||
},
|
||||
welcomeText = new Sprite
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Texture = textures.Get(@"Intro/Welcome/welcome_text")
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
using (BeginDelayedSequence(0, true))
|
||||
{
|
||||
scaleContainer.ScaleTo(0.9f).ScaleTo(1, delay_step_two).OnComplete(_ => Expire());
|
||||
scaleContainer.FadeInFromZero(1800);
|
||||
|
||||
welcomeText.ScaleTo(new Vector2(1, 0)).ScaleTo(Vector2.One, 400, Easing.Out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,11 @@ using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Utils;
|
||||
|
||||
@ -65,6 +69,11 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
public Color4 AccentColour { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The relative movement of bars based on input amplification. Defaults to 1.
|
||||
/// </summary>
|
||||
public float Magnitude { get; set; } = 1;
|
||||
|
||||
private readonly float[] frequencyAmplitudes = new float[256];
|
||||
|
||||
private IShader shader;
|
||||
@ -76,6 +85,13 @@ namespace osu.Game.Screens.Menu
|
||||
Blending = BlendingParameters.Additive;
|
||||
}
|
||||
|
||||
private readonly List<IHasAmplitudes> amplitudeSources = new List<IHasAmplitudes>();
|
||||
|
||||
public void AddAmplitudeSource(IHasAmplitudes amplitudeSource)
|
||||
{
|
||||
amplitudeSources.Add(amplitudeSource);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ShaderManager shaders, IBindable<WorkingBeatmap> beatmap)
|
||||
{
|
||||
@ -83,27 +99,28 @@ namespace osu.Game.Screens.Menu
|
||||
shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED);
|
||||
}
|
||||
|
||||
private readonly float[] temporalAmplitudes = new float[ChannelAmplitudes.AMPLITUDES_SIZE];
|
||||
|
||||
private void updateAmplitudes()
|
||||
{
|
||||
var track = beatmap.Value.TrackLoaded ? beatmap.Value.Track : null;
|
||||
var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null;
|
||||
var effect = beatmap.Value.BeatmapLoaded && beatmap.Value.TrackLoaded
|
||||
? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(beatmap.Value.Track.CurrentTime)
|
||||
: null;
|
||||
|
||||
float[] temporalAmplitudes = track?.CurrentAmplitudes.FrequencyAmplitudes;
|
||||
for (int i = 0; i < temporalAmplitudes.Length; i++)
|
||||
temporalAmplitudes[i] = 0;
|
||||
|
||||
if (beatmap.Value.TrackLoaded)
|
||||
addAmplitudesFromSource(beatmap.Value.Track);
|
||||
|
||||
foreach (var source in amplitudeSources)
|
||||
addAmplitudesFromSource(source);
|
||||
|
||||
for (int i = 0; i < bars_per_visualiser; i++)
|
||||
{
|
||||
if (track?.IsRunning ?? false)
|
||||
{
|
||||
float targetAmplitude = (temporalAmplitudes?[(i + indexOffset) % bars_per_visualiser] ?? 0) * (effect?.KiaiMode == true ? 1 : 0.5f);
|
||||
if (targetAmplitude > frequencyAmplitudes[i])
|
||||
frequencyAmplitudes[i] = targetAmplitude;
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = (i + index_change) % bars_per_visualiser;
|
||||
if (frequencyAmplitudes[index] > frequencyAmplitudes[i])
|
||||
frequencyAmplitudes[i] = frequencyAmplitudes[index];
|
||||
}
|
||||
float targetAmplitude = (temporalAmplitudes[(i + indexOffset) % bars_per_visualiser]) * (effect?.KiaiMode == true ? 1 : 0.5f);
|
||||
if (targetAmplitude > frequencyAmplitudes[i])
|
||||
frequencyAmplitudes[i] = targetAmplitude;
|
||||
}
|
||||
|
||||
indexOffset = (indexOffset + index_change) % bars_per_visualiser;
|
||||
@ -136,6 +153,19 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
protected override DrawNode CreateDrawNode() => new VisualisationDrawNode(this);
|
||||
|
||||
private void addAmplitudesFromSource([NotNull] IHasAmplitudes source)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException(nameof(source));
|
||||
|
||||
var amplitudes = source.CurrentAmplitudes.FrequencyAmplitudes.Span;
|
||||
|
||||
for (int i = 0; i < amplitudes.Length; i++)
|
||||
{
|
||||
if (i < temporalAmplitudes.Length)
|
||||
temporalAmplitudes[i] += amplitudes[i];
|
||||
}
|
||||
}
|
||||
|
||||
private class VisualisationDrawNode : DrawNode
|
||||
{
|
||||
protected new LogoVisualisation Source => (LogoVisualisation)base.Source;
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
@ -16,6 +15,7 @@ using osu.Game.Skinning;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Users;
|
||||
using System;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
@ -89,7 +89,7 @@ namespace osu.Game.Screens.Menu
|
||||
skin.BindValueChanged(_ => updateColour(), true);
|
||||
}
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
if (beatIndex < 0)
|
||||
return;
|
||||
@ -100,7 +100,7 @@ namespace osu.Game.Screens.Menu
|
||||
flash(rightBox, timingPoint.BeatLength, effectPoint.KiaiMode, amplitudes);
|
||||
}
|
||||
|
||||
private void flash(Drawable d, double beatLength, bool kiai, TrackAmplitudes amplitudes)
|
||||
private void flash(Drawable d, double beatLength, bool kiai, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
d.FadeTo(Math.Max(0, ((ReferenceEquals(d, leftBox) ? amplitudes.LeftChannel : amplitudes.RightChannel) - amplitude_dead_zone) / (kiai ? kiai_multiplier : alpha_multiplier)), box_fade_in_time)
|
||||
.Then()
|
||||
|
@ -264,7 +264,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private int lastBeatIndex;
|
||||
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
|
||||
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
|
||||
{
|
||||
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
|
||||
|
||||
|
@ -656,12 +656,6 @@ namespace osu.Game.Screens.Play
|
||||
return true;
|
||||
}
|
||||
|
||||
if (canPause)
|
||||
{
|
||||
Pause();
|
||||
return true;
|
||||
}
|
||||
|
||||
// GameplayClockContainer performs seeks / start / stop operations on the beatmap's track.
|
||||
// as we are no longer the current screen, we cannot guarantee the track is still usable.
|
||||
GameplayClockContainer?.StopUsingBeatmapClock();
|
||||
|
@ -19,6 +19,7 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Input.Bindings;
|
||||
@ -301,6 +302,9 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private void selectNextDifficulty(int direction)
|
||||
{
|
||||
if (selectedBeatmap == null)
|
||||
return;
|
||||
|
||||
var unfilteredDifficulties = selectedBeatmapSet.Children.Where(s => !s.Filtered.Value).ToList();
|
||||
|
||||
int index = unfilteredDifficulties.IndexOf(selectedBeatmap);
|
||||
@ -452,32 +456,49 @@ namespace osu.Game.Screens.Select
|
||||
/// </summary>
|
||||
public void ScrollToSelected() => scrollPositionCache.Invalidate();
|
||||
|
||||
#region Key / button selection logic
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Left:
|
||||
SelectNext(-1, true);
|
||||
if (!e.Repeat)
|
||||
beginRepeatSelection(() => SelectNext(-1, true), e.Key);
|
||||
return true;
|
||||
|
||||
case Key.Right:
|
||||
SelectNext(1, true);
|
||||
if (!e.Repeat)
|
||||
beginRepeatSelection(() => SelectNext(1, true), e.Key);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void OnKeyUp(KeyUpEvent e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Left:
|
||||
case Key.Right:
|
||||
endRepeatSelection(e.Key);
|
||||
break;
|
||||
}
|
||||
|
||||
base.OnKeyUp(e);
|
||||
}
|
||||
|
||||
public bool OnPressed(GlobalAction action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.SelectNext:
|
||||
SelectNext(1, false);
|
||||
beginRepeatSelection(() => SelectNext(1, false), action);
|
||||
return true;
|
||||
|
||||
case GlobalAction.SelectPrevious:
|
||||
SelectNext(-1, false);
|
||||
beginRepeatSelection(() => SelectNext(-1, false), action);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -486,8 +507,44 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
public void OnReleased(GlobalAction action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.SelectNext:
|
||||
case GlobalAction.SelectPrevious:
|
||||
endRepeatSelection(action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private ScheduledDelegate repeatDelegate;
|
||||
private object lastRepeatSource;
|
||||
|
||||
/// <summary>
|
||||
/// Begin repeating the specified selection action.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to perform.</param>
|
||||
/// <param name="source">The source of the action. Used in conjunction with <see cref="endRepeatSelection"/> to only cancel the correct action (most recently pressed key).</param>
|
||||
private void beginRepeatSelection(Action action, object source)
|
||||
{
|
||||
endRepeatSelection();
|
||||
|
||||
lastRepeatSource = source;
|
||||
repeatDelegate = this.BeginKeyRepeat(Scheduler, action);
|
||||
}
|
||||
|
||||
private void endRepeatSelection(object source = null)
|
||||
{
|
||||
// only the most recent source should be able to cancel the current action.
|
||||
if (source != null && !EqualityComparer<object>.Default.Equals(lastRepeatSource, source))
|
||||
return;
|
||||
|
||||
repeatDelegate?.Cancel();
|
||||
repeatDelegate = null;
|
||||
lastRepeatSource = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
@ -12,7 +12,7 @@ namespace osu.Game.Screens.Select
|
||||
public ImportFromStablePopup(Action importFromStable)
|
||||
{
|
||||
HeaderText = @"You have no beatmaps!";
|
||||
BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps, skins and scores?";
|
||||
BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps, skins and scores?\nThis will create a second copy of all files on disk.";
|
||||
|
||||
Icon = FontAwesome.Solid.Plane;
|
||||
|
||||
|
@ -5,6 +5,7 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
public enum GlobalSkinConfiguration
|
||||
{
|
||||
AnimationFramerate
|
||||
AnimationFramerate,
|
||||
LayeredHitSounds,
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Objects.Legacy;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
@ -28,7 +29,17 @@ namespace osu.Game.Skinning
|
||||
|
||||
public Texture GetTexture(string componentName) => Source.GetTexture(componentName);
|
||||
|
||||
public virtual SampleChannel GetSample(ISampleInfo sampleInfo) => Source.GetSample(sampleInfo);
|
||||
public virtual SampleChannel GetSample(ISampleInfo sampleInfo)
|
||||
{
|
||||
if (!(sampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacySample))
|
||||
return Source.GetSample(sampleInfo);
|
||||
|
||||
var playLayeredHitSounds = GetConfig<GlobalSkinConfiguration, bool>(GlobalSkinConfiguration.LayeredHitSounds);
|
||||
if (legacySample.IsLayered && playLayeredHitSounds?.Value == false)
|
||||
return new SampleChannelVirtual();
|
||||
|
||||
return Source.GetSample(sampleInfo);
|
||||
}
|
||||
|
||||
public abstract IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup);
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
@ -17,7 +20,8 @@ namespace osu.Game.Storyboards.Drawables
|
||||
private const double allowable_late_start = 100;
|
||||
|
||||
private readonly StoryboardSampleInfo sampleInfo;
|
||||
private SampleChannel channel;
|
||||
|
||||
protected SampleChannel Channel { get; private set; }
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
|
||||
@ -28,12 +32,16 @@ namespace osu.Game.Storyboards.Drawables
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IBindable<WorkingBeatmap> beatmap)
|
||||
private void load(IBindable<WorkingBeatmap> beatmap, IBindable<IReadOnlyList<Mod>> mods)
|
||||
{
|
||||
channel = beatmap.Value.Skin.GetSample(sampleInfo);
|
||||
Channel = beatmap.Value.Skin.GetSample(sampleInfo);
|
||||
if (Channel == null)
|
||||
return;
|
||||
|
||||
if (channel != null)
|
||||
channel.Volume.Value = sampleInfo.Volume / 100.0;
|
||||
Channel.Volume.Value = sampleInfo.Volume / 100.0;
|
||||
|
||||
foreach (var mod in mods.Value.OfType<IApplicableToSample>())
|
||||
mod.ApplyToSample(Channel);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
@ -44,7 +52,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
if (Time.Current < sampleInfo.StartTime)
|
||||
{
|
||||
// We've rewound before the start time of the sample
|
||||
channel?.Stop();
|
||||
Channel?.Stop();
|
||||
|
||||
// In the case that the user fast-forwards to a point far beyond the start time of the sample,
|
||||
// we want to be able to fall into the if-conditional below (therefore we must not have a life time end)
|
||||
@ -56,7 +64,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
// We've passed the start time of the sample. We only play the sample if we're within an allowable range
|
||||
// from the sample's start, to reduce layering if we've been fast-forwarded far into the future
|
||||
if (Time.Current - sampleInfo.StartTime < allowable_late_start)
|
||||
channel?.Play();
|
||||
Channel?.Play();
|
||||
|
||||
// In the case that the user rewinds to a point far behind the start time of the sample,
|
||||
// we want to be able to fall into the if-conditional above (therefore we must not have a life time start)
|
||||
@ -67,7 +75,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
channel?.Stop();
|
||||
Channel?.Stop();
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ namespace osu.Game.Tests.Beatmaps
|
||||
public abstract class HitObjectSampleTest : PlayerTestScene
|
||||
{
|
||||
protected abstract IResourceStore<byte[]> Resources { get; }
|
||||
protected LegacySkin Skin { get; private set; }
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesetStore { get; set; }
|
||||
|
||||
private readonly SkinInfo userSkinInfo = new SkinInfo();
|
||||
|
||||
@ -64,6 +68,9 @@ namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
using (var reader = new LineBufferedReader(Resources.GetStream($"Resources/SampleLookups/{filename}")))
|
||||
currentTestBeatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||
|
||||
// populate ruleset for beatmap converters that require it to be present.
|
||||
currentTestBeatmap.BeatmapInfo.Ruleset = rulesetStore.GetRuleset(currentTestBeatmap.BeatmapInfo.RulesetID);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -91,7 +98,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
};
|
||||
|
||||
// Need to refresh the cached skin source to refresh the skin resource store.
|
||||
dependencies.SkinSource = new SkinProvidingContainer(new LegacySkin(userSkinInfo, userSkinResourceStore, Audio));
|
||||
dependencies.SkinSource = new SkinProvidingContainer(Skin = new LegacySkin(userSkinInfo, userSkinResourceStore, Audio));
|
||||
});
|
||||
}
|
||||
|
||||
@ -101,6 +108,9 @@ namespace osu.Game.Tests.Beatmaps
|
||||
protected void AssertUserLookup(string name) => AddAssert($"\"{name}\" looked up from user skin",
|
||||
() => !beatmapSkinResourceStore.PerformedLookups.Contains(name) && userSkinResourceStore.PerformedLookups.Contains(name));
|
||||
|
||||
protected void AssertNoLookup(string name) => AddAssert($"\"{name}\" not looked up",
|
||||
() => !beatmapSkinResourceStore.PerformedLookups.Contains(name) && !userSkinResourceStore.PerformedLookups.Contains(name));
|
||||
|
||||
private class SkinSourceDependencyContainer : IReadOnlyDependencyContainer
|
||||
{
|
||||
public ISkinSource SkinSource;
|
||||
|
@ -24,8 +24,8 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.619.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.602.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.623.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.622.1" />
|
||||
<PackageReference Include="Sentry" Version="2.1.3" />
|
||||
<PackageReference Include="SharpCompress" Version="0.25.1" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
|
@ -70,8 +70,8 @@
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.619.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.602.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.623.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.622.1" />
|
||||
</ItemGroup>
|
||||
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
@ -80,7 +80,7 @@
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.619.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2020.623.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.25.1" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
|
Loading…
Reference in New Issue
Block a user