1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 02:32:55 +08:00

Merge branch 'master' into fix_combo

This commit is contained in:
Dan Balasescu 2018-09-18 12:54:51 +09:00 committed by GitHub
commit 29e023b252
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 143 additions and 17 deletions

View File

@ -27,9 +27,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="System.IO.Packaging" Version="4.5.0" /> <PackageReference Include="System.IO.Packaging" Version="4.5.0" />
<PackageReference Include="ppy.squirrel.windows" Version="1.8.0.5" /> <PackageReference Include="ppy.squirrel.windows" Version="1.8.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.3" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Resources"> <ItemGroup Label="Resources">
<EmbeddedResource Include="lazer.ico" /> <EmbeddedResource Include="lazer.ico" />

View File

@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Catch.UI
private readonly CatcherArea catcherArea; private readonly CatcherArea catcherArea;
protected override bool UserScrollSpeedAdjustment => false;
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation) public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
: base(BASE_WIDTH) : base(BASE_WIDTH)
{ {

View File

@ -20,6 +20,8 @@ namespace osu.Game.Rulesets.Osu.Mods
public override ModType Type => ModType.Fun; public override ModType Type => ModType.Fun;
public override string Description => "Everything rotates. EVERYTHING."; public override string Description => "Everything rotates. EVERYTHING.";
public override double ScoreMultiplier => 1; public override double ScoreMultiplier => 1;
public override Type[] IncompatibleMods => new[] { typeof(OsuModWiggle) };
private float theta; private float theta;
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables) public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)

View File

@ -21,6 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override ModType Type => ModType.Fun; public override ModType Type => ModType.Fun;
public override string Description => "They just won't stay still..."; public override string Description => "They just won't stay still...";
public override double ScoreMultiplier => 1; public override double ScoreMultiplier => 1;
public override Type[] IncompatibleMods => new[] { typeof(OsuModTransform) };
private const int wiggle_duration = 90; // (ms) Higher = fewer wiggles private const int wiggle_duration = 90; // (ms) Higher = fewer wiggles
private const int wiggle_strength = 10; // Higher = stronger wiggles private const int wiggle_strength = 10; // Higher = stronger wiggles

View File

@ -1,9 +1,14 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input.EventArgs;
using osu.Framework.MathUtils; using osu.Framework.MathUtils;
using osu.Framework.Timing;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using OpenTK.Input; using OpenTK.Input;
@ -12,21 +17,30 @@ namespace osu.Game.Tests.Visual
[TestFixture] [TestFixture]
public class TestCaseKeyCounter : OsuTestCase public class TestCaseKeyCounter : OsuTestCase
{ {
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(KeyCounterKeyboard),
typeof(KeyCounterMouse),
typeof(KeyCounterCollection)
};
public TestCaseKeyCounter() public TestCaseKeyCounter()
{ {
KeyCounterKeyboard rewindTestKeyCounterKeyboard;
KeyCounterCollection kc = new KeyCounterCollection KeyCounterCollection kc = new KeyCounterCollection
{ {
Origin = Anchor.Centre, Origin = Anchor.Centre,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Children = new KeyCounter[] Children = new KeyCounter[]
{ {
new KeyCounterKeyboard(Key.Z), rewindTestKeyCounterKeyboard = new KeyCounterKeyboard(Key.X),
new KeyCounterKeyboard(Key.X), new KeyCounterKeyboard(Key.X),
new KeyCounterMouse(MouseButton.Left), new KeyCounterMouse(MouseButton.Left),
new KeyCounterMouse(MouseButton.Right), new KeyCounterMouse(MouseButton.Right),
}, },
}; };
AddStep("Add random", () => AddStep("Add random", () =>
{ {
Key key = (Key)((int)Key.A + RNG.Next(26)); Key key = (Key)((int)Key.A + RNG.Next(26));
@ -34,7 +48,57 @@ namespace osu.Game.Tests.Visual
}); });
AddSliderStep("Fade time", 0, 200, 50, v => kc.FadeTime = v); AddSliderStep("Fade time", 0, 200, 50, v => kc.FadeTime = v);
Key testKey = ((KeyCounterKeyboard)kc.Children.First()).Key;
double time1 = 0;
AddStep($"Press {testKey} key", () =>
{
rewindTestKeyCounterKeyboard.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = testKey, Repeat = false });
rewindTestKeyCounterKeyboard.TriggerOnKeyUp(null, new KeyUpEventArgs { Key = testKey });
});
AddAssert($"Check {testKey} counter after keypress", () => rewindTestKeyCounterKeyboard.CountPresses == 1);
AddStep($"Press {testKey} key", () =>
{
rewindTestKeyCounterKeyboard.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = testKey, Repeat = false });
rewindTestKeyCounterKeyboard.TriggerOnKeyUp(null, new KeyUpEventArgs { Key = testKey });
time1 = Clock.CurrentTime;
});
AddAssert($"Check {testKey} counter after keypress", () => rewindTestKeyCounterKeyboard.CountPresses == 2);
IFrameBasedClock oldClock = null;
AddStep($"Rewind {testKey} counter once", () =>
{
oldClock = rewindTestKeyCounterKeyboard.Clock;
rewindTestKeyCounterKeyboard.Clock = new FramedOffsetClock(new FixedClock(time1 - 10));
});
AddAssert($"Check {testKey} counter after rewind", () => rewindTestKeyCounterKeyboard.CountPresses == 1);
AddStep($"Rewind {testKey} counter to zero", () => rewindTestKeyCounterKeyboard.Clock = new FramedOffsetClock(new FixedClock(0)));
AddAssert($"Check {testKey} counter after rewind", () => rewindTestKeyCounterKeyboard.CountPresses == 0);
AddStep("Restore clock", () => rewindTestKeyCounterKeyboard.Clock = oldClock);
Add(kc); Add(kc);
} }
private class FixedClock : IClock
{
private readonly double time;
public FixedClock(double time)
{
this.time = time;
}
public double CurrentTime => time;
public double Rate => 1;
public bool IsRunning => false;
}
} }
} }

View File

@ -84,11 +84,10 @@ namespace osu.Game.Screens.Menu
private const double early_activation = 60; private const double early_activation = 60;
public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks;
public OsuLogo() public OsuLogo()
{ {
// Required to make Schedule calls run in OsuScreen even when we are not visible.
AlwaysPresent = true;
EarlyActivationMilliseconds = early_activation; EarlyActivationMilliseconds = early_activation;
Size = new Vector2(default_size); Size = new Vector2(default_size);

View File

@ -69,7 +69,7 @@ namespace osu.Game.Screens.Play
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Children = new Drawable[] Children = new Drawable[]
{ {
KeyCounter = CreateKeyCounter(), KeyCounter = CreateKeyCounter(adjustableClock as IFrameBasedClock),
HoldToQuit = CreateQuitButton(), HoldToQuit = CreateQuitButton(),
} }
} }
@ -194,12 +194,13 @@ namespace osu.Game.Screens.Play
Margin = new MarginPadding { Top = 20 } Margin = new MarginPadding { Top = 20 }
}; };
protected virtual KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection protected virtual KeyCounterCollection CreateKeyCounter(IFrameBasedClock offsetClock) => new KeyCounterCollection
{ {
FadeTime = 50, FadeTime = 50,
Anchor = Anchor.BottomRight, Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight, Origin = Anchor.BottomRight,
Margin = new MarginPadding(10), Margin = new MarginPadding(10),
AudioClock = offsetClock
}; };
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6) protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)

View File

@ -1,6 +1,8 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
@ -19,6 +21,9 @@ namespace osu.Game.Screens.Play
private Container textLayer; private Container textLayer;
private SpriteText countSpriteText; private SpriteText countSpriteText;
private readonly List<KeyCounterState> states = new List<KeyCounterState>();
private KeyCounterState currentState;
public bool IsCounting { get; set; } = true; public bool IsCounting { get; set; } = true;
private int countPresses; private int countPresses;
public int CountPresses public int CountPresses
@ -45,7 +50,10 @@ namespace osu.Game.Screens.Play
isLit = value; isLit = value;
updateGlowSprite(value); updateGlowSprite(value);
if (value && IsCounting) if (value && IsCounting)
{
CountPresses++; CountPresses++;
saveState();
}
} }
} }
} }
@ -128,6 +136,32 @@ namespace osu.Game.Screens.Play
} }
} }
public void ResetCount() => CountPresses = 0; public void ResetCount()
{
CountPresses = 0;
states.Clear();
}
protected override void Update()
{
base.Update();
if (currentState?.Time > Clock.CurrentTime)
restoreStateTo(Clock.CurrentTime);
}
private void saveState()
{
if (currentState == null || currentState.Time < Clock.CurrentTime)
states.Add(currentState = new KeyCounterState(Clock.CurrentTime, CountPresses));
}
private void restoreStateTo(double time)
{
states.RemoveAll(state => state.Time > time);
currentState = states.LastOrDefault();
CountPresses = currentState?.Count ?? 0;
}
} }
} }

View File

@ -3,15 +3,16 @@
using System; using System;
using System.Linq; using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using OpenTK.Graphics;
using osu.Framework.Configuration;
using osu.Framework.Allocation;
using osu.Framework.Input.EventArgs; using osu.Framework.Input.EventArgs;
using osu.Framework.Input.States; using osu.Framework.Input.States;
using osu.Framework.Timing;
using osu.Game.Configuration; using osu.Game.Configuration;
using OpenTK; using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Screens.Play namespace osu.Game.Screens.Play
{ {
@ -37,6 +38,9 @@ namespace osu.Game.Screens.Play
key.FadeTime = FadeTime; key.FadeTime = FadeTime;
key.KeyDownTextColor = KeyDownTextColor; key.KeyDownTextColor = KeyDownTextColor;
key.KeyUpTextColor = KeyUpTextColor; key.KeyUpTextColor = KeyUpTextColor;
// Use the same clock object as SongProgress for saving KeyCounter state
if (AudioClock != null)
key.Clock = AudioClock;
} }
public void ResetCount() public void ResetCount()
@ -118,6 +122,8 @@ namespace osu.Game.Screens.Play
public override bool HandleKeyboardInput => receptor == null; public override bool HandleKeyboardInput => receptor == null;
public override bool HandleMouseInput => receptor == null; public override bool HandleMouseInput => receptor == null;
public IFrameBasedClock AudioClock { get; set; }
private Receptor receptor; private Receptor receptor;
public Receptor GetReceptor() public Receptor GetReceptor()

View File

@ -0,0 +1,17 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Screens.Play
{
public class KeyCounterState
{
public KeyCounterState(double time, int count)
{
Time = time;
Count = count;
}
public readonly double Time;
public readonly int Count;
}
}

View File

@ -16,10 +16,10 @@ namespace osu.Game.Storyboards
public bool HasCommands => commands.Count > 0; public bool HasCommands => commands.Count > 0;
private Cached<double> startTimeBacking; private Cached<double> startTimeBacking;
public double StartTime => startTimeBacking.IsValid ? startTimeBacking : (startTimeBacking.Value = HasCommands ? commands.Min(c => c.StartTime) : double.MinValue); public double StartTime => startTimeBacking.IsValid ? startTimeBacking : startTimeBacking.Value = HasCommands ? commands.Min(c => c.StartTime) : double.MinValue;
private Cached<double> endTimeBacking; private Cached<double> endTimeBacking;
public double EndTime => endTimeBacking.IsValid ? endTimeBacking : (endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue); public double EndTime => endTimeBacking.IsValid ? endTimeBacking : endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue;
public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default(T); public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default(T);
public T EndValue => HasCommands ? commands.OrderByDescending(c => c.EndTime).First().EndValue : default(T); public T EndValue => HasCommands ? commands.OrderByDescending(c => c.EndTime).First().EndValue : default(T);

View File

@ -16,7 +16,7 @@
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Humanizer" Version="2.4.2" /> <PackageReference Include="Humanizer" Version="2.4.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="ppy.osu.Framework" Version="2018.913.0" /> <PackageReference Include="ppy.osu.Framework" Version="2018.913.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" /> <PackageReference Include="SharpCompress" Version="0.22.0" />

View File

@ -11,7 +11,7 @@
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" /> <ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Package References"> <ItemGroup Label="Package References">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.3" />
<PackageReference Include="DeepEqual" Version="1.6.0" /> <PackageReference Include="DeepEqual" Version="1.6.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>