1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 06:03:08 +08:00

Merge remote-tracking branch 'refs/remotes/ppy/master' into pause_buttons_refactor

This commit is contained in:
Andrey Zavadskiy 2017-04-01 21:03:19 +03:00
commit 3574dac780
167 changed files with 1887 additions and 1044 deletions

@ -1 +1 @@
Subproject commit 51737ec1320b4ea9dce4978f24e1d77a28f0a98e
Subproject commit bf6a3dc40176ee4f921012808070e014fc4a5779

@ -1 +1 @@
Subproject commit e67453159540f5008b5efadfbc12dfb3f4bee1f7
Subproject commit 12bbab717d372dadbd3220d38da862276ac97e98

View File

@ -13,10 +13,10 @@ using osu.Game.Modes.Taiko;
namespace osu.Desktop.Tests
{
[TestFixture]
public class BenchmarkTest
public class VisualTests
{
[Test]
public void TestBenchmark()
public void TestVisualTests()
{
using (var host = new HeadlessGameHost())
{
@ -25,7 +25,7 @@ namespace osu.Desktop.Tests
Ruleset.Register(new ManiaRuleset());
Ruleset.Register(new CatchRuleset());
host.Run(new Benchmark());
host.Run(new AutomatedVisualTestGame());
}
}
}

View File

@ -56,7 +56,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="BenchmarkTest.cs" />
<Compile Include="VisualTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework.Desktop\osu.Framework.Desktop.csproj">

View File

@ -0,0 +1,20 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Game;
namespace osu.Desktop.VisualTests
{
public class AutomatedVisualTestGame : OsuGameBase
{
protected override void LoadComplete()
{
base.LoadComplete();
// Have to construct this here, rather than in the constructor, because
// we depend on some dependencies to be loaded within OsuGameBase.load().
Add(new TestRunner(new TestBrowser()));
}
}
}

View File

@ -1,45 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Screens.Testing;
using osu.Game;
namespace osu.Desktop.VisualTests
{
public class Benchmark : OsuGameBase
{
private const double time_per_test = 200;
[BackgroundDependencyLoader]
private void load()
{
Host.MaximumDrawHz = int.MaxValue;
Host.MaximumUpdateHz = int.MaxValue;
Host.MaximumInactiveHz = int.MaxValue;
}
protected override void LoadComplete()
{
base.LoadComplete();
TestBrowser f = new TestBrowser();
Add(f);
Console.WriteLine($@"{Time}: Running {f.TestCount} tests for {time_per_test}ms each...");
for (int i = 1; i < f.TestCount; i++)
{
int loadableCase = i;
Scheduler.AddDelayed(delegate
{
f.LoadTest(loadableCase);
Console.WriteLine($@"{Time}: Switching to test #{loadableCase}");
}, loadableCase * time_per_test);
}
Scheduler.AddDelayed(Host.Exit, f.TestCount * time_per_test);
}
}
}

View File

@ -27,7 +27,7 @@ namespace osu.Desktop.VisualTests
Ruleset.Register(new CatchRuleset());
if (benchmark)
host.Run(new Benchmark());
host.Run(new AutomatedVisualTestGame());
else
host.Run(new VisualTestGame());
}

View File

@ -3,7 +3,7 @@
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Screens.Select;
namespace osu.Desktop.VisualTests.Tests

View File

@ -3,7 +3,7 @@
using OpenTK.Graphics;
using OpenTK.Input;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Screens.Select.Options;
@ -26,7 +26,7 @@ namespace osu.Desktop.VisualTests.Tests
Add(overlay);
AddButton(@"Toggle", overlay.ToggleVisibility);
AddStep(@"Toggle", overlay.ToggleVisibility);
}
}
}

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.Graphics.Containers;
using osu.Framework.Threading;
using osu.Game.Overlays;

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Overlays;
using osu.Game.Overlays.Dialog;
@ -20,7 +20,7 @@ namespace osu.Desktop.VisualTests.Tests
Add(overlay = new DialogOverlay());
AddButton("dialog #1", () => overlay.Push(new PopupDialog
AddStep("dialog #1", () => overlay.Push(new PopupDialog
{
Icon = FontAwesome.fa_trash_o,
HeaderText = @"Confirm deletion of",
@ -40,7 +40,7 @@ namespace osu.Desktop.VisualTests.Tests
},
}));
AddButton("dialog #2", () => overlay.Push(new PopupDialog
AddStep("dialog #2", () => overlay.Push(new PopupDialog
{
Icon = FontAwesome.fa_gear,
HeaderText = @"What do you want to do with",

View File

@ -2,7 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Screens.Tournament;
using osu.Game.Screens.Tournament.Teams;
using osu.Game.Users;

View File

@ -5,7 +5,7 @@ using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Database;

View File

@ -8,7 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.Timing;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables;
@ -93,19 +93,28 @@ namespace osu.Desktop.VisualTests.Tests
playbackSpeed.TriggerChange();
AddButton(@"circles", () => load(HitObjectType.Circle));
AddButton(@"slider", () => load(HitObjectType.Slider));
AddButton(@"spinner", () => load(HitObjectType.Spinner));
AddStep(@"circles", () => load(HitObjectType.Circle));
AddStep(@"slider", () => load(HitObjectType.Slider));
AddStep(@"spinner", () => load(HitObjectType.Spinner));
AddToggle(@"auto", state => { auto = state; load(mode); });
AddToggleStep(@"auto", state => { auto = state; load(mode); });
ButtonsContainer.Add(new SpriteText { Text = "Playback Speed" });
ButtonsContainer.Add(new BasicSliderBar<double>
Add(new Container
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
Bindable = playbackSpeed
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new SpriteText { Text = "Playback Speed" },
new BasicSliderBar<double>
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
Bindable = playbackSpeed
}
}
});
framedClock.ProcessFrame();

View File

@ -1,16 +1,16 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.Graphics;
using OpenTK.Input;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Configuration;
using osu.Framework.Graphics.Containers;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.MathUtils;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Screens.Play;
namespace osu.Desktop.VisualTests.Tests
@ -38,19 +38,30 @@ namespace osu.Desktop.VisualTests.Tests
};
BindableInt bindable = new BindableInt { MinValue = 0, MaxValue = 200, Default = 50 };
bindable.ValueChanged += delegate { kc.FadeTime = bindable.Value; };
AddButton("Add Random", () =>
AddStep("Add Random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
kc.Add(new KeyCounterKeyboard(key));
});
ButtonsContainer.Add(new SpriteText { Text = "FadeTime" });
ButtonsContainer.Add(new TestSliderBar<int>
Add(new Container
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
Bindable = bindable
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new SpriteText { Text = "FadeTime" },
new TestSliderBar<int>
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
Bindable = bindable
}
}
});
Add(kc);
}
private class TestSliderBar<T> : SliderBar<T> where T : struct

View File

@ -3,7 +3,7 @@
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Modes.Mods;
using osu.Game.Modes.Osu.Mods;
using osu.Game.Modes.Scoring;
@ -218,7 +218,7 @@ namespace osu.Desktop.VisualTests.Tests
Size = new Vector2(550f, 450f),
});
AddButton(@"New Scores", newScores);
AddStep(@"New Scores", newScores);
newScores();
}
}

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Sprites;
using osu.Game.Screens.Menu;

View File

@ -3,7 +3,7 @@
using osu.Framework.Graphics;
using osu.Game.Overlays.Mods;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Modes;
namespace osu.Desktop.VisualTests.Tests
@ -25,11 +25,11 @@ namespace osu.Desktop.VisualTests.Tests
Anchor = Anchor.BottomCentre,
});
AddButton("Toggle", modSelect.ToggleVisibility);
AddButton("osu!", () => modSelect.PlayMode.Value = PlayMode.Osu);
AddButton("osu!taiko", () => modSelect.PlayMode.Value = PlayMode.Taiko);
AddButton("osu!catch", () => modSelect.PlayMode.Value = PlayMode.Catch);
AddButton("osu!mania", () => modSelect.PlayMode.Value = PlayMode.Mania);
AddStep("Toggle", modSelect.ToggleVisibility);
AddStep("osu!", () => modSelect.PlayMode.Value = PlayMode.Osu);
AddStep("osu!taiko", () => modSelect.PlayMode.Value = PlayMode.Taiko);
AddStep("osu!catch", () => modSelect.PlayMode.Value = PlayMode.Catch);
AddStep("osu!mania", () => modSelect.PlayMode.Value = PlayMode.Mania);
}
}
}

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.Graphics;
using osu.Framework.Timing;
using osu.Game.Overlays;
@ -30,7 +30,7 @@ namespace osu.Desktop.VisualTests.Tests
Anchor = Anchor.Centre
};
Add(mc);
AddToggle(@"Show", state => mc.State = state ? Visibility.Visible : Visibility.Hidden);
AddToggleStep(@"Show", state => mc.State = state ? Visibility.Visible : Visibility.Hidden);
}
}
}

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.MathUtils;
using osu.Game.Overlays;
using System.Linq;
@ -30,13 +30,13 @@ namespace osu.Desktop.VisualTests.Tests
Origin = Anchor.TopRight,
});
AddToggle(@"show", state => manager.State = state ? Visibility.Visible : Visibility.Hidden);
AddToggleStep(@"show", state => manager.State = state ? Visibility.Visible : Visibility.Hidden);
AddButton(@"simple #1", sendNotification1);
AddButton(@"simple #2", sendNotification2);
AddButton(@"progress #1", sendProgress1);
AddButton(@"progress #2", sendProgress2);
AddButton(@"barrage", () => sendBarrage());
AddStep(@"simple #1", sendNotification1);
AddStep(@"simple #2", sendNotification2);
AddStep(@"progress #1", sendProgress1);
AddStep(@"progress #2", sendProgress2);
AddStep(@"barrage", () => sendBarrage());
}
private void sendBarrage(int remaining = 100)

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Overlays;
namespace osu.Desktop.VisualTests.Tests

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
using osu.Desktop.VisualTests.Platform;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.MathUtils;
using osu.Game.Database;
using osu.Game.Modes;
@ -23,12 +23,10 @@ namespace osu.Desktop.VisualTests.Tests
public override void Reset()
{
base.Reset();
oldDb = Dependencies.Get<BeatmapDatabase>();
if (db == null)
{
storage = new TestStorage(@"TestCasePlaySongSelect");
db = new BeatmapDatabase(storage);
Dependencies.Cache(db, true);
var sets = new List<BeatmapSetInfo>();
@ -40,19 +38,16 @@ namespace osu.Desktop.VisualTests.Tests
Add(songSelect = new PlaySongSelect());
AddButton(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; });
AddButton(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; });
AddButton(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; });
AddButton(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; });
AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; });
AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; });
AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; });
AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; });
}
protected override void Dispose(bool isDisposing)
{
if (oldDb != null)
{
Dependencies.Cache(oldDb, true);
db = null;
}
base.Dispose(isDisposing);
}

View File

@ -4,7 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using OpenTK;
using osu.Framework.Graphics.Sprites;

View File

@ -6,7 +6,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Modes.UI;
@ -68,7 +68,7 @@ namespace osu.Desktop.VisualTests.Tests
};
Add(starsLabel);
AddButton(@"Reset all", delegate
AddStep(@"Reset all", delegate
{
score.Current.Value = 0;
comboCounter.Current.Value = 0;
@ -78,7 +78,7 @@ namespace osu.Desktop.VisualTests.Tests
starsLabel.Text = stars.Count.ToString("0.00");
});
AddButton(@"Hit! :D", delegate
AddStep(@"Hit! :D", delegate
{
score.Current.Value += 300 + (ulong)(300.0 * (comboCounter.Current > 0 ? comboCounter.Current - 1 : 0) / 25.0);
comboCounter.Increment();
@ -86,20 +86,20 @@ namespace osu.Desktop.VisualTests.Tests
accuracyCounter.SetFraction(numerator, denominator);
});
AddButton(@"miss...", delegate
AddStep(@"miss...", delegate
{
comboCounter.Current.Value = 0;
denominator++;
accuracyCounter.SetFraction(numerator, denominator);
});
AddButton(@"Alter stars", delegate
AddStep(@"Alter stars", delegate
{
stars.Count = RNG.NextSingle() * (stars.StarCount + 1);
starsLabel.Text = stars.Count.ToString("0.00");
});
AddButton(@"Stop counters", delegate
AddStep(@"Stop counters", delegate
{
score.StopRolling();
comboCounter.StopRolling();

View File

@ -3,7 +3,7 @@
using OpenTK;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Select.Filter;

View File

@ -4,12 +4,9 @@
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;
namespace osu.Desktop.VisualTests.Tests
@ -24,61 +21,73 @@ namespace osu.Desktop.VisualTests.Tests
{
base.Reset();
AddToggle("Kiai", b =>
AddToggleStep("Kiai", b =>
{
kiai = !kiai;
Reset();
});
Add(new CentreHitCircle(new CirclePiece()
Add(new CirclePiece
{
KiaiMode = kiai
})
{
Position = new Vector2(100, 100)
Position = new Vector2(100, 100),
Width = 0,
AccentColour = Color4.DarkRed,
KiaiMode = kiai,
Children = new[]
{
new CentreHitSymbolPiece()
}
});
Add(new CentreHitCircle(new StrongCirclePiece()
Add(new StrongCirclePiece
{
KiaiMode = kiai
})
{
Position = new Vector2(350, 100)
Position = new Vector2(350, 100),
Width = 0,
AccentColour = Color4.DarkRed,
KiaiMode = kiai,
Children = new[]
{
new CentreHitSymbolPiece()
}
});
Add(new RimHitCircle(new CirclePiece()
Add(new CirclePiece
{
KiaiMode = kiai
})
{
Position = new Vector2(100, 300)
Position = new Vector2(100, 300),
Width = 0,
AccentColour = Color4.DarkBlue,
KiaiMode = kiai,
Children = new[]
{
new RimHitSymbolPiece()
}
});
Add(new RimHitCircle(new StrongCirclePiece()
Add(new StrongCirclePiece
{
KiaiMode = kiai
})
{
Position = new Vector2(350, 300)
Position = new Vector2(350, 300),
Width = 0,
AccentColour = Color4.DarkBlue,
KiaiMode = kiai,
Children = new[]
{
new RimHitSymbolPiece()
}
});
Add(new SwellCircle(new CirclePiece()
Add(new CirclePiece
{
KiaiMode = kiai
})
{
Position = new Vector2(100, 500)
Position = new Vector2(100, 500),
Width = 0,
AccentColour = Color4.Orange,
KiaiMode = kiai,
Children = new[]
{
new SwellSymbolPiece()
}
});
Add(new SwellCircle(new StrongCirclePiece()
{
KiaiMode = kiai
})
{
Position = new Vector2(350, 500)
});
Add(new DrumRollCircle(new CirclePiece()
Add(new DrumRollCircle(new CirclePiece
{
KiaiMode = kiai
})
@ -87,7 +96,7 @@ namespace osu.Desktop.VisualTests.Tests
Position = new Vector2(575, 100)
});
Add(new DrumRollCircle(new StrongCirclePiece()
Add(new DrumRollCircle(new StrongCirclePiece
{
KiaiMode = kiai
})
@ -97,28 +106,6 @@ namespace osu.Desktop.VisualTests.Tests
});
}
private class SwellCircle : BaseCircle
{
public SwellCircle(CirclePiece piece)
: base(piece)
{
Piece.Add(new TextAwesome
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
TextSize = SYMBOL_INNER_SIZE,
Icon = FontAwesome.fa_asterisk,
Shadow = false
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Piece.AccentColour = colours.YellowDark;
}
}
private class DrumRollCircle : BaseCircle
{
public DrumRollCircle(CirclePiece piece)
@ -133,72 +120,8 @@ namespace osu.Desktop.VisualTests.Tests
}
}
private class CentreHitCircle : BaseCircle
{
public CentreHitCircle(CirclePiece piece)
: base(piece)
{
Piece.Add(new CircularContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(SYMBOL_INNER_SIZE),
Masking = true,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both
}
}
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Piece.AccentColour = colours.PinkDarker;
}
}
private class RimHitCircle : BaseCircle
{
public RimHitCircle(CirclePiece piece)
: base(piece)
{
Piece.Add(new CircularContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(SYMBOL_SIZE),
BorderThickness = SYMBOL_BORDER,
BorderColour = Color4.White,
Masking = true,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
}
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Piece.AccentColour = colours.BlueDarker;
}
}
private abstract class BaseCircle : Container
{
protected const float SYMBOL_SIZE = TaikoHitObject.CIRCLE_RADIUS * 2f * 0.45f;
protected const float SYMBOL_BORDER = 8;
protected const float SYMBOL_INNER_SIZE = SYMBOL_SIZE - 2 * SYMBOL_BORDER;
protected readonly CirclePiece Piece;
protected BaseCircle(CirclePiece piece)

View File

@ -1,11 +1,15 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.MathUtils;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.Taiko.Objects.Drawable;
using osu.Game.Modes.Taiko.UI;
namespace osu.Desktop.VisualTests.Tests
@ -20,12 +24,23 @@ namespace osu.Desktop.VisualTests.Tests
{
base.Reset();
AddButton("Hit!", addHitJudgement);
AddButton("Miss :(", addMissJudgement);
AddStep("Hit!", addHitJudgement);
AddStep("Miss :(", addMissJudgement);
AddStep("Swell", addSwell);
AddStep("Centre", () => addCentreHit(false));
AddStep("Strong Centre", () => addCentreHit(true));
AddStep("Rim", () => addRimHit(false));
AddStep("Strong Rim", () => addRimHit(true));
Add(playfield = new TaikoPlayfield
Add(new Container
{
Y = 200
RelativeSizeAxes = Axes.X,
Y = 200,
Padding = new MarginPadding { Left = 200 },
Children = new[]
{
playfield = new TaikoPlayfield()
}
});
}
@ -41,7 +56,6 @@ namespace osu.Desktop.VisualTests.Tests
Result = HitResult.Hit,
TaikoResult = hitResult,
TimeOffset = 0,
ComboAtHit = 1,
SecondHit = RNG.Next(10) == 0
}
});
@ -54,12 +68,49 @@ namespace osu.Desktop.VisualTests.Tests
Judgement = new TaikoJudgement
{
Result = HitResult.Miss,
TimeOffset = 0,
ComboAtHit = 0
TimeOffset = 0
}
});
}
private void addSwell()
{
playfield.Add(new DrawableSwell(new Swell
{
StartTime = Time.Current + 1000,
EndTime = Time.Current + 5000,
PreEmpt = 1000
}));
}
private void addCentreHit(bool strong)
{
Hit h = new Hit
{
StartTime = Time.Current + 1000,
PreEmpt = 1000
};
if (strong)
playfield.Add(new DrawableStrongCentreHit(h));
else
playfield.Add(new DrawableCentreHit(h));
}
private void addRimHit(bool strong)
{
Hit h = new Hit
{
StartTime = Time.Current + 1000,
PreEmpt = 1000
};
if (strong)
playfield.Add(new DrawableStrongRimHit(h));
else
playfield.Add(new DrawableRimHit(h));
}
private class DrawableTestHit : DrawableHitObject<TaikoHitObject, TaikoJudgement>
{
public DrawableTestHit(TaikoHitObject hitObject)

View File

@ -2,7 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play;

View File

@ -2,7 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Platform;
using osu.Framework.Screens.Testing;
using osu.Framework.Testing;
using osu.Game;
using osu.Game.Screens.Backgrounds;
@ -24,6 +24,11 @@ namespace osu.Desktop.VisualTests
public override void SetHost(GameHost host)
{
base.SetHost(host);
host.UpdateThread.InactiveHz = host.UpdateThread.ActiveHz;
host.DrawThread.InactiveHz = host.DrawThread.ActiveHz;
host.InputThread.InactiveHz = host.InputThread.ActiveHz;
host.Window.CursorState = CursorState.Hidden;
}
}

View File

@ -150,6 +150,10 @@
<Project>{65dc628f-a640-4111-ab35-3a5652bc1e17}</Project>
<Name>osu.Framework.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework.Testing\osu.Framework.Testing.csproj">
<Project>{007b2356-ab6f-4bd9-96d5-116fc2dce69a}</Project>
<Name>osu.Framework.Testing</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{c76bf5b3-985e-4d39-95fe-97c9c879b83a}</Project>
<Name>osu.Framework</Name>
@ -180,7 +184,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="Benchmark.cs" />
<Compile Include="AutomatedVisualTestGame.cs" />
<Compile Include="Program.cs" />
<Compile Include="Tests\TestCaseChatDisplay.cs" />
<Compile Include="Tests\TestCaseDrawings.cs" />

View File

@ -0,0 +1,29 @@
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
<!-- XQuartz compatibility (X11 on Mac) -->
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>

View File

@ -123,7 +123,10 @@
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4" />
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll</HintPath>
<Private>True</Private>
@ -150,6 +153,7 @@
<None Include="..\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<None Include="OpenTK.dll.config" />
<None Include="osu!.res" />
<None Include="packages.config" />
<None Include="Properties\app.manifest" />

View File

@ -7,6 +7,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
<package id="DeltaCompressionDotNet" version="1.1.0" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net45" />
<package id="ppy.OpenTK" version="2.0.50727.1340" targetFramework="net45" />
<package id="Splat" version="2.0.0" targetFramework="net45" />
<package id="squirrel.windows" version="1.5.2" targetFramework="net45" />
</packages>

View File

@ -19,7 +19,7 @@ namespace osu.Game.Modes.Catch.Scoring
{
}
protected override void OnNewJugement(CatchJudgement judgement)
protected override void OnNewJudgement(CatchJudgement judgement)
{
}
}

View File

@ -19,7 +19,7 @@ namespace osu.Game.Modes.Mania.Scoring
{
}
protected override void OnNewJugement(ManiaJudgement judgement)
protected override void OnNewJudgement(ManiaJudgement judgement)
{
}
}

View File

@ -7,7 +7,6 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
namespace osu.Game.Modes.Osu.Objects.Drawables.Connections
{

View File

@ -3,7 +3,6 @@
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Transforms;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects.Drawables.Pieces;
using OpenTK;
@ -39,7 +38,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
Colour = AccentColour,
Hit = () =>
{
if (Judgement.Result.HasValue) return false;
if (Judgement.Result != HitResult.None) return false;
Judgement.PositionOffset = Vector2.Zero; //todo: set to correct value
UpdateJudgement(true);

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Judgements;
using OpenTK;

View File

@ -7,7 +7,6 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Judgements;

View File

@ -4,7 +4,6 @@
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.MathUtils;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects.Drawables.Pieces;

View File

@ -4,7 +4,6 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using OpenTK.Graphics;

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics.Transforms;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
using osu.Game.Modes.Osu.Objects;
@ -10,11 +9,13 @@ using osu.Game.Modes.Osu.Objects.Drawables;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using osu.Framework.Graphics;
using osu.Game.Modes.Objects.Types;
using osu.Game.Modes.Replays;
namespace osu.Game.Modes.Osu
{
public class OsuAutoReplay : LegacyReplay
public class OsuAutoReplay : Replay
{
private static readonly Vector2 spinner_centre = new Vector2(256, 192);
@ -29,17 +30,20 @@ namespace osu.Game.Modes.Osu
createAutoReplay();
}
private class LegacyReplayFrameComparer : IComparer<LegacyReplayFrame>
private class ReplayFrameComparer : IComparer<ReplayFrame>
{
public int Compare(LegacyReplayFrame f1, LegacyReplayFrame f2)
public int Compare(ReplayFrame f1, ReplayFrame f2)
{
if (f1 == null) throw new NullReferenceException($@"{nameof(f1)} cannot be null");
if (f2 == null) throw new NullReferenceException($@"{nameof(f2)} cannot be null");
return f1.Time.CompareTo(f2.Time);
}
}
private static readonly IComparer<LegacyReplayFrame> replay_frame_comparer = new LegacyReplayFrameComparer();
private static readonly IComparer<ReplayFrame> replay_frame_comparer = new ReplayFrameComparer();
private int findInsertionIndex(LegacyReplayFrame frame)
private int findInsertionIndex(ReplayFrame frame)
{
int index = Frames.BinarySearch(frame, replay_frame_comparer);
@ -59,7 +63,7 @@ namespace osu.Game.Modes.Osu
return index;
}
private void addFrameToReplay(LegacyReplayFrame frame) => Frames.Insert(findInsertionIndex(frame), frame);
private void addFrameToReplay(ReplayFrame frame) => Frames.Insert(findInsertionIndex(frame), frame);
private static Vector2 circlePosition(double t, double radius) => new Vector2((float)(Math.Cos(t) * radius), (float)(Math.Sin(t) * radius));
@ -74,9 +78,9 @@ namespace osu.Game.Modes.Osu
EasingTypes preferredEasing = DelayedMovements ? EasingTypes.InOutCubic : EasingTypes.Out;
addFrameToReplay(new LegacyReplayFrame(-100000, 256, 500, LegacyButtonState.None));
addFrameToReplay(new LegacyReplayFrame(beatmap.HitObjects[0].StartTime - 1500, 256, 500, LegacyButtonState.None));
addFrameToReplay(new LegacyReplayFrame(beatmap.HitObjects[0].StartTime - 1000, 256, 192, LegacyButtonState.None));
addFrameToReplay(new ReplayFrame(-100000, 256, 500, ReplayButtonState.None));
addFrameToReplay(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1500, 256, 500, ReplayButtonState.None));
addFrameToReplay(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, 256, 192, ReplayButtonState.None));
// We are using ApplyModsToRate and not ApplyModsToTime to counteract the speed up / slow down from HalfTime / DoubleTime so that we remain at a constant framerate of 60 fps.
float frameDelay = (float)applyModsToRate(1000.0 / 60.0);
@ -106,18 +110,18 @@ namespace osu.Game.Modes.Osu
//Make the cursor stay at a hitObject as long as possible (mainly for autopilot).
if (h.StartTime - h.HitWindowFor(OsuScoreResult.Miss) > endTime + h.HitWindowFor(OsuScoreResult.Hit50) + 50)
{
if (!(last is Spinner) && h.StartTime - endTime < 1000) addFrameToReplay(new LegacyReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit50), last.EndPosition.X, last.EndPosition.Y, LegacyButtonState.None));
if (!(h is Spinner)) addFrameToReplay(new LegacyReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Miss), h.Position.X, h.Position.Y, LegacyButtonState.None));
if (!(last is Spinner) && h.StartTime - endTime < 1000) addFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit50), last.EndPosition.X, last.EndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) addFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Miss), h.Position.X, h.Position.Y, ReplayButtonState.None));
}
else if (h.StartTime - h.HitWindowFor(OsuScoreResult.Hit50) > endTime + h.HitWindowFor(OsuScoreResult.Hit50) + 50)
{
if (!(last is Spinner) && h.StartTime - endTime < 1000) addFrameToReplay(new LegacyReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit50), last.EndPosition.X, last.EndPosition.Y, LegacyButtonState.None));
if (!(h is Spinner)) addFrameToReplay(new LegacyReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Hit50), h.Position.X, h.Position.Y, LegacyButtonState.None));
if (!(last is Spinner) && h.StartTime - endTime < 1000) addFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit50), last.EndPosition.X, last.EndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) addFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Hit50), h.Position.X, h.Position.Y, ReplayButtonState.None));
}
else if (h.StartTime - h.HitWindowFor(OsuScoreResult.Hit100) > endTime + h.HitWindowFor(OsuScoreResult.Hit100) + 50)
{
if (!(last is Spinner) && h.StartTime - endTime < 1000) addFrameToReplay(new LegacyReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit100), last.EndPosition.X, last.EndPosition.Y, LegacyButtonState.None));
if (!(h is Spinner)) addFrameToReplay(new LegacyReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Hit100), h.Position.X, h.Position.Y, LegacyButtonState.None));
if (!(last is Spinner) && h.StartTime - endTime < 1000) addFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit100), last.EndPosition.X, last.EndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) addFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Hit100), h.Position.X, h.Position.Y, ReplayButtonState.None));
}
}
@ -173,13 +177,13 @@ namespace osu.Game.Modes.Osu
// Do some nice easing for cursor movements
if (Frames.Count > 0)
{
LegacyReplayFrame lastFrame = Frames[Frames.Count - 1];
ReplayFrame lastFrame = Frames[Frames.Count - 1];
// Wait until Auto could "see and react" to the next note.
double waitTime = h.StartTime - Math.Max(0.0, DrawableOsuHitObject.TIME_PREEMPT - reactionTime);
if (waitTime > lastFrame.Time)
{
lastFrame = new LegacyReplayFrame(waitTime, lastFrame.MouseX, lastFrame.MouseY, lastFrame.ButtonState);
lastFrame = new ReplayFrame(waitTime, lastFrame.MouseX, lastFrame.MouseY, lastFrame.ButtonState);
addFrameToReplay(lastFrame);
}
@ -196,7 +200,7 @@ namespace osu.Game.Modes.Osu
for (double time = lastFrame.Time + frameDelay; time < h.StartTime; time += frameDelay)
{
Vector2 currentPosition = Interpolation.ValueAt(time, lastPosition, targetPosition, lastFrame.Time, h.StartTime, easing);
addFrameToReplay(new LegacyReplayFrame((int)time, currentPosition.X, currentPosition.Y, lastFrame.ButtonState));
addFrameToReplay(new ReplayFrame((int)time, currentPosition.X, currentPosition.Y, lastFrame.ButtonState));
}
buttonIndex = 0;
@ -207,12 +211,12 @@ namespace osu.Game.Modes.Osu
}
}
LegacyButtonState button = buttonIndex % 2 == 0 ? LegacyButtonState.Left1 : LegacyButtonState.Right1;
ReplayButtonState button = buttonIndex % 2 == 0 ? ReplayButtonState.Left1 : ReplayButtonState.Right1;
double hEndTime = (h as IHasEndTime)?.EndTime ?? h.StartTime;
LegacyReplayFrame newFrame = new LegacyReplayFrame(h.StartTime, targetPosition.X, targetPosition.Y, button);
LegacyReplayFrame endFrame = new LegacyReplayFrame(hEndTime + endDelay, h.EndPosition.X, h.EndPosition.Y, LegacyButtonState.None);
ReplayFrame newFrame = new ReplayFrame(h.StartTime, targetPosition.X, targetPosition.Y, button);
ReplayFrame endFrame = new ReplayFrame(hEndTime + endDelay, h.EndPosition.X, h.EndPosition.Y, ReplayButtonState.None);
// Decrement because we want the previous frame, not the next one
int index = findInsertionIndex(newFrame) - 1;
@ -220,19 +224,19 @@ namespace osu.Game.Modes.Osu
// Do we have a previous frame? No need to check for < replay.Count since we decremented!
if (index >= 0)
{
LegacyReplayFrame previousFrame = Frames[index];
ReplayFrame previousFrame = Frames[index];
var previousButton = previousFrame.ButtonState;
// If a button is already held, then we simply alternate
if (previousButton != LegacyButtonState.None)
if (previousButton != ReplayButtonState.None)
{
Debug.Assert(previousButton != (LegacyButtonState.Left1 | LegacyButtonState.Right1));
Debug.Assert(previousButton != (ReplayButtonState.Left1 | ReplayButtonState.Right1));
// Force alternation if we have the same button. Otherwise we can just keep the naturally to us assigned button.
if (previousButton == button)
{
button = (LegacyButtonState.Left1 | LegacyButtonState.Right1) & ~button;
newFrame.SetButtonStates(button);
button = (ReplayButtonState.Left1 | ReplayButtonState.Right1) & ~button;
newFrame.ButtonState = button;
}
// We always follow the most recent slider / spinner, so remove any other frames that occur while it exists.
@ -246,7 +250,7 @@ namespace osu.Game.Modes.Osu
{
// Don't affect frames which stop pressing a button!
if (j < Frames.Count - 1 || Frames[j].ButtonState == previousButton)
Frames[j].SetButtonStates(button);
Frames[j].ButtonState = button;
}
}
}
@ -270,13 +274,13 @@ namespace osu.Game.Modes.Osu
t = applyModsToTime(j - h.StartTime) * spinnerDirection;
Vector2 pos = spinner_centre + circlePosition(t / 20 + angle, spin_radius);
addFrameToReplay(new LegacyReplayFrame((int)j, pos.X, pos.Y, button));
addFrameToReplay(new ReplayFrame((int)j, pos.X, pos.Y, button));
}
t = applyModsToTime(s.EndTime - h.StartTime) * spinnerDirection;
Vector2 endPosition = spinner_centre + circlePosition(t / 20 + angle, spin_radius);
addFrameToReplay(new LegacyReplayFrame(s.EndTime, endPosition.X, endPosition.Y, button));
addFrameToReplay(new ReplayFrame(s.EndTime, endPosition.X, endPosition.Y, button));
endFrame.MouseX = endPosition.X;
endFrame.MouseY = endPosition.Y;
@ -288,10 +292,10 @@ namespace osu.Game.Modes.Osu
for (double j = frameDelay; j < s.Duration; j += frameDelay)
{
Vector2 pos = s.PositionAt(j / s.Duration);
addFrameToReplay(new LegacyReplayFrame(h.StartTime + j, pos.X, pos.Y, button));
addFrameToReplay(new ReplayFrame(h.StartTime + j, pos.X, pos.Y, button));
}
addFrameToReplay(new LegacyReplayFrame(s.EndTime, s.EndPosition.X, s.EndPosition.Y, button));
addFrameToReplay(new ReplayFrame(s.EndTime, s.EndPosition.X, s.EndPosition.Y, button));
}
// We only want to let go of our button if we are at the end of the current replay. Otherwise something is still going on after us so we need to keep the button pressed!

View File

@ -28,7 +28,7 @@ namespace osu.Game.Modes.Osu.Scoring
Accuracy.Value = 1;
}
protected override void OnNewJugement(OsuJudgement judgement)
protected override void OnNewJudgement(OsuJudgement judgement)
{
if (judgement != null)
{

View File

@ -44,7 +44,10 @@ namespace osu.Game.Modes.Taiko.Beatmaps
IHasRepeats repeatsData = original as IHasRepeats;
IHasEndTime endTimeData = original as IHasEndTime;
bool strong = ((original.Sample?.Type ?? SampleType.None) & SampleType.Finish) > 0;
// Old osu! used hit sounding to determine various hit type information
SampleType sample = original.Sample?.Type ?? SampleType.None;
bool strong = (sample & SampleType.Finish) > 0;
if (distanceData != null)
{
@ -71,11 +74,23 @@ namespace osu.Game.Modes.Taiko.Beatmaps
};
}
return new Hit
bool isCentre = (sample & ~(SampleType.Finish | SampleType.Normal)) == 0;
if (isCentre)
{
return new CentreHit
{
StartTime = original.StartTime,
Sample = original.Sample,
IsStrong = strong
};
}
return new RimHit
{
StartTime = original.StartTime,
Sample = original.Sample,
IsStrong = strong
IsStrong = strong,
};
}
}

View File

@ -22,7 +22,7 @@ namespace osu.Game.Modes.Taiko.Judgements
/// The result value for the combo portion of the score.
/// </summary>
public int ResultValueForScore => NumericResultForScore(TaikoResult);
/// <summary>
/// The result value for the accuracy portion of the score.
/// </summary>
@ -32,7 +32,7 @@ namespace osu.Game.Modes.Taiko.Judgements
/// The maximum result value for the combo portion of the score.
/// </summary>
public int MaxResultValueForScore => NumericResultForScore(MAX_HIT_RESULT);
/// <summary>
/// The maximum result value for the accuracy portion of the score.
/// </summary>
@ -45,7 +45,7 @@ namespace osu.Game.Modes.Taiko.Judgements
/// <summary>
/// Whether this Judgement has a secondary hit in the case of finishers.
/// </summary>
public bool SecondHit;
public virtual bool SecondHit { get; set; }
/// <summary>
/// Computes the numeric result value for the combo portion of the score.

View File

@ -0,0 +1,25 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Judgements;
namespace osu.Game.Modes.Taiko.Judgements
{
public class TaikoStrongHitJudgement : TaikoJudgement, IPartialJudgement
{
public bool Changed { get; set; }
public override bool SecondHit
{
get { return base.SecondHit; }
set
{
if (base.SecondHit == value)
return;
base.SecondHit = value;
Changed = true;
}
}
}
}

View File

@ -1,7 +1,12 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Modes.Mods;
using osu.Game.Modes.Scoring;
using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.Taiko.Replays;
using osu.Game.Users;
namespace osu.Game.Modes.Taiko.Mods
{
@ -61,4 +66,13 @@ namespace osu.Game.Modes.Taiko.Mods
{
}
public class TaikoModAutoplay : ModAutoplay<TaikoHitObject>
{
protected override Score CreateReplayScore(Beatmap<TaikoHitObject> beatmap) => new Score
{
User = new User { Username = "mekkadosu!" },
Replay = new TaikoAutoReplay(beatmap)
};
}
}

View File

@ -0,0 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Modes.Taiko.Objects
{
public class CentreHit : Hit
{
}
}

View File

@ -0,0 +1,35 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;
using osu.Game.Graphics;
using osu.Framework.Allocation;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public class DrawableCentreHit : DrawableHit
{
protected override Key[] HitKeys { get; } = { Key.F, Key.J };
private readonly CirclePiece circlePiece;
public DrawableCentreHit(Hit hit)
: base(hit)
{
Add(circlePiece = new CirclePiece
{
Children = new[]
{
new CentreHitSymbolPiece()
}
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
circlePiece.AccentColour = colours.PinkDarker;
}
}
}

View File

@ -47,7 +47,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override bool HandleKeyPress(Key key)
{
return !Judgement.Result.HasValue && UpdateJudgement(true);
return Judgement.Result == HitResult.None && UpdateJudgement(true);
}
}
}

View File

@ -2,10 +2,12 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
using System;
using System.Collections.Generic;
using System.Linq;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
@ -14,7 +16,9 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
/// <summary>
/// A list of keys which can result in hits for this HitObject.
/// </summary>
protected abstract List<Key> HitKeys { get; }
protected abstract Key[] HitKeys { get; }
protected override Container<Framework.Graphics.Drawable> Content => bodyContainer;
private readonly Hit hit;
@ -23,10 +27,18 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
/// </summary>
private bool validKeyPressed;
private readonly Container bodyContainer;
protected DrawableHit(Hit hit)
: base(hit)
{
this.hit = hit;
AddInternal(bodyContainer = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
});
}
protected override void CheckJudgement(bool userTriggered)
@ -56,12 +68,37 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override bool HandleKeyPress(Key key)
{
if (Judgement.Result.HasValue)
if (Judgement.Result != HitResult.None)
return false;
validKeyPressed = HitKeys.Contains(key);
return UpdateJudgement(true);
}
protected override void UpdateState(ArmedState state)
{
Delay(HitObject.StartTime - Time.Current + Judgement.TimeOffset, true);
switch (State)
{
case ArmedState.Idle:
Delay(hit.HitWindowMiss);
break;
case ArmedState.Miss:
FadeOut(100);
break;
case ArmedState.Hit:
bodyContainer.ScaleTo(0.8f, 400, EasingTypes.OutQuad);
bodyContainer.MoveToY(-200, 250, EasingTypes.Out);
bodyContainer.Delay(250);
bodyContainer.MoveToY(0, 500, EasingTypes.In);
FadeOut(600);
break;
}
Expire();
}
}
}

View File

@ -0,0 +1,35 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Game.Graphics;
using OpenTK.Input;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public class DrawableRimHit : DrawableHit
{
protected override Key[] HitKeys { get; } = { Key.D, Key.K };
private readonly CirclePiece circlePiece;
public DrawableRimHit(Hit hit)
: base(hit)
{
Add(circlePiece = new CirclePiece
{
Children = new[]
{
new RimHitSymbolPiece()
}
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
circlePiece.AccentColour = colours.BlueDarker;
}
}
}

View File

@ -0,0 +1,35 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;
using osu.Framework.Allocation;
using osu.Game.Graphics;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public class DrawableStrongCentreHit : DrawableStrongHit
{
protected override Key[] HitKeys { get; } = { Key.F, Key.J };
private readonly CirclePiece circlePiece;
public DrawableStrongCentreHit(Hit hit)
: base(hit)
{
Add(circlePiece = new StrongCirclePiece
{
Children = new []
{
new CentreHitSymbolPiece()
}
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
circlePiece.AccentColour = colours.PinkDarker;
}
}
}

View File

@ -5,6 +5,8 @@ using OpenTK.Input;
using System;
using System.Linq;
using osu.Framework.Input;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
@ -25,9 +27,11 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
{
}
protected override TaikoJudgement CreateJudgement() => new TaikoStrongHitJudgement();
protected override void CheckJudgement(bool userTriggered)
{
if (!Judgement.Result.HasValue)
if (Judgement.Result == HitResult.None)
{
base.CheckJudgement(userTriggered);
return;
@ -45,7 +49,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override bool HandleKeyPress(Key key)
{
// Check if we've handled the first key
if (!Judgement.Result.HasValue)
if (Judgement.Result == HitResult.None)
{
// First key hasn't been handled yet, attempt to handle it
bool handled = base.HandleKeyPress(key);

View File

@ -0,0 +1,35 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Game.Graphics;
using OpenTK.Input;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public class DrawableStrongRimHit : DrawableStrongHit
{
protected override Key[] HitKeys { get; } = { Key.D, Key.K };
private readonly CirclePiece circlePiece;
public DrawableStrongRimHit(Hit hit)
: base(hit)
{
Add(circlePiece = new StrongCirclePiece
{
Children = new[]
{
new RimHitSymbolPiece()
}
});
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
circlePiece.AccentColour = colours.BlueDarker;
}
}
}

View File

@ -1,37 +1,160 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Judgements;
using osu.Game.Modes.Taiko.Objects.Drawable.Pieces;
using System;
using System.Linq;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
public class DrawableSwell : DrawableTaikoHitObject
{
/// <summary>
/// Invoked when the swell has reached the hit target, i.e. when CurrentTime >= StartTime.
/// This is only ever invoked once.
/// </summary>
public event Action OnStart;
private const float target_ring_thick_border = 1.4f;
private const float target_ring_thin_border = 1f;
private const float target_ring_scale = 5f;
private const float inner_ring_alpha = 0.65f;
private readonly Swell swell;
private readonly Container bodyContainer;
private readonly CircularContainer targetRing;
private readonly CircularContainer expandingRing;
private readonly CirclePiece circlePiece;
private readonly Key[] rimKeys = { Key.D, Key.K };
private readonly Key[] centreKeys = { Key.F, Key.J };
private Key[] lastKeySet;
/// <summary>
/// The amount of times the user has hit this swell.
/// </summary>
private int userHits;
private readonly Swell swell;
private bool hasStarted;
private readonly SwellSymbolPiece symbol;
public DrawableSwell(Swell swell)
: base(swell)
{
this.swell = swell;
Children = new Framework.Graphics.Drawable[]
{
bodyContainer = new Container
{
Children = new Framework.Graphics.Drawable[]
{
expandingRing = new CircularContainer
{
Name = "Expanding ring",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0,
Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
BlendingMode = BlendingMode.Additive,
Masking = true,
Children = new []
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = inner_ring_alpha,
}
}
},
targetRing = new CircularContainer
{
Name = "Target ring (thick border)",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
Masking = true,
BorderThickness = target_ring_thick_border,
BlendingMode = BlendingMode.Additive,
Children = new Framework.Graphics.Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
},
new CircularContainer
{
Name = "Target ring (thin border)",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = target_ring_thin_border,
BorderColour = Color4.White,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
}
}
}
},
circlePiece = new CirclePiece
{
Children = new []
{
symbol = new SwellSymbolPiece()
}
}
}
}
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
circlePiece.AccentColour = colours.YellowDark;
expandingRing.Colour = colours.YellowLight;
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
}
protected override void CheckJudgement(bool userTriggered)
{
if (userTriggered)
{
if (Time.Current < HitObject.StartTime)
return;
userHits++;
var completion = (float)userHits / swell.RequiredHits;
expandingRing.FadeTo(expandingRing.Alpha + MathHelper.Clamp(completion / 16, 0.1f, 0.6f), 50);
expandingRing.Delay(50);
expandingRing.FadeTo(completion / 8, 2000, EasingTypes.OutQuint);
expandingRing.DelayReset();
symbol.RotateTo((float)(completion * swell.Duration / 8), 4000, EasingTypes.OutQuint);
expandingRing.ScaleTo(1f + Math.Min(target_ring_scale - 1f, (target_ring_scale - 1f) * completion * 1.3f), 260, EasingTypes.OutQuint);
if (userHits == swell.RequiredHits)
{
Judgement.Result = HitResult.Hit;
@ -43,6 +166,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
if (Judgement.TimeOffset < 0)
return;
//TODO: THIS IS SHIT AND CAN'T EXIST POST-TAIKO WORLD CUP
if (userHits > swell.RequiredHits / 2)
{
Judgement.Result = HitResult.Hit;
@ -55,18 +179,61 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override void UpdateState(ArmedState state)
{
const float preempt = 100;
Delay(HitObject.StartTime - Time.Current - preempt, true);
targetRing.ScaleTo(target_ring_scale, preempt * 4, EasingTypes.OutQuint);
Delay(preempt, true);
Delay(Judgement.TimeOffset + swell.Duration, true);
const float out_transition_time = 300;
switch (state)
{
case ArmedState.Hit:
bodyContainer.ScaleTo(1.4f, out_transition_time);
break;
}
FadeOut(out_transition_time, EasingTypes.Out);
Expire();
}
protected override void UpdateScrollPosition(double time)
{
base.UpdateScrollPosition(Math.Min(time, HitObject.StartTime));
// Make the swell stop at the hit target
double t = Math.Min(HitObject.StartTime, time);
if (t == HitObject.StartTime && !hasStarted)
{
OnStart?.Invoke();
hasStarted = true;
}
base.UpdateScrollPosition(t);
}
protected override bool HandleKeyPress(Key key)
{
if (Judgement.Result.HasValue)
if (Judgement.Result != HitResult.None)
return false;
// Don't handle keys before the swell starts
if (Time.Current < HitObject.StartTime)
return false;
// Find the keyset which this key corresponds to
var keySet = rimKeys.Contains(key) ? rimKeys : centreKeys;
// Ensure alternating keysets
if (keySet == lastKeySet)
return false;
lastKeySet = keySet;
UpdateJudgement(true);
return true;

View File

@ -30,7 +30,6 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
protected override void LoadComplete()
{
LifetimeStart = HitObject.StartTime - HitObject.PreEmpt * 2;
LifetimeEnd = HitObject.StartTime + HitObject.PreEmpt;
base.LoadComplete();
}

View File

@ -0,0 +1,31 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using OpenTK;
namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
{
/// <summary>
/// The symbol used for centre hit pieces.
/// </summary>
public class CentreHitSymbolPiece : CircularContainer
{
public CentreHitSymbolPiece()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Size = new Vector2(CirclePiece.SYMBOL_INNER_SIZE);
Masking = true;
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both
}
};
}
}
}

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Backgrounds;
using OpenTK.Graphics;
using System;
using osu.Game.Graphics;
namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
{
@ -18,7 +19,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
/// a rounded (_[-Width-]_) figure such that a regular "circle" is the result of a parent with Width = 0.
/// </para>
/// </summary>
public class CirclePiece : Container
public class CirclePiece : Container, IHasAccentColour
{
public const float SYMBOL_SIZE = TaikoHitObject.CIRCLE_RADIUS * 2f * 0.45f;
public const float SYMBOL_BORDER = 8;

View File

@ -0,0 +1,36 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
{
/// <summary>
/// The symbol used for rim hit pieces.
/// </summary>
public class RimHitSymbolPiece : CircularContainer
{
public RimHitSymbolPiece()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Size = new Vector2(CirclePiece.SYMBOL_SIZE);
BorderThickness = CirclePiece.SYMBOL_BORDER;
BorderColour = Color4.White;
Masking = true;
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
};
}
}
}

View File

@ -0,0 +1,24 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Graphics;
using osu.Framework.Graphics;
namespace osu.Game.Modes.Taiko.Objects.Drawable.Pieces
{
/// <summary>
/// The symbol used for swell pieces.
/// </summary>
public class SwellSymbolPiece : TextAwesome
{
public SwellSymbolPiece()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
UseFullGlyphHeight = true;
TextSize = CirclePiece.SYMBOL_INNER_SIZE;
Icon = FontAwesome.fa_asterisk;
Shadow = false;
}
}
}

View File

@ -0,0 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Modes.Taiko.Objects
{
public class RimHit : Hit
{
}
}

View File

@ -17,7 +17,7 @@ namespace osu.Game.Modes.Taiko.Objects
/// <summary>
/// The number of hits required to complete the swell successfully.
/// </summary>
public int RequiredHits { get; protected set; }
public int RequiredHits { get; protected set; } = 10;
public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
{

View File

@ -12,7 +12,7 @@ namespace osu.Game.Modes.Taiko.Objects
/// <summary>
/// HitCircle radius.
/// </summary>
public const float CIRCLE_RADIUS = 64;
public const float CIRCLE_RADIUS = 42f;
/// <summary>
/// The time to scroll in the HitObject.

View File

@ -0,0 +1,121 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Game.Beatmaps;
using osu.Game.Modes.Objects.Types;
using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.Replays;
namespace osu.Game.Modes.Taiko.Replays
{
public class TaikoAutoReplay : Replay
{
private readonly Beatmap<TaikoHitObject> beatmap;
public TaikoAutoReplay(Beatmap<TaikoHitObject> beatmap)
{
this.beatmap = beatmap;
createAutoReplay();
}
private void createAutoReplay()
{
bool hitButton = true;
Frames.Add(new ReplayFrame(-100000, 320, 240, ReplayButtonState.None));
Frames.Add(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, 320, 240, ReplayButtonState.None));
for (int i = 0; i < beatmap.HitObjects.Count; i++)
{
TaikoHitObject h = beatmap.HitObjects[i];
ReplayButtonState button;
IHasEndTime endTimeData = h as IHasEndTime;
double endTime = endTimeData?.EndTime ?? h.StartTime;
Swell swell = h as Swell;
DrumRoll drumRoll = h as DrumRoll;
Hit hit = h as Hit;
if (swell != null)
{
int d = 0;
int count = 0;
int req = swell.RequiredHits;
double hitRate = swell.Duration / req;
for (double j = h.StartTime; j < endTime; j += hitRate)
{
switch (d)
{
default:
button = ReplayButtonState.Left1;
break;
case 1:
button = ReplayButtonState.Right1;
break;
case 2:
button = ReplayButtonState.Left2;
break;
case 3:
button = ReplayButtonState.Right2;
break;
}
Frames.Add(new ReplayFrame(j, 0, 0, button));
d = (d + 1) % 4;
if (++count > req)
break;
}
}
else if (drumRoll != null)
{
double delay = drumRoll.TickTimeDistance;
double time = drumRoll.StartTime;
for (int j = 0; j < drumRoll.TotalTicks; j++)
{
Frames.Add(new ReplayFrame((int)time, 0, 0, hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2));
time += delay;
hitButton = !hitButton;
}
}
else if (hit != null)
{
if (hit is CentreHit)
{
if (h.IsStrong)
button = ReplayButtonState.Right1 | ReplayButtonState.Right2;
else
button = hitButton ? ReplayButtonState.Right1 : ReplayButtonState.Right2;
}
else
{
if (h.IsStrong)
button = ReplayButtonState.Left1 | ReplayButtonState.Left2;
else
button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2;
}
Frames.Add(new ReplayFrame(h.StartTime, 0, 0, button));
}
else
throw new Exception("Unknown hit object type.");
Frames.Add(new ReplayFrame(endTime + 1, 0, 0, ReplayButtonState.None));
if (i < beatmap.HitObjects.Count - 1)
{
double waitTime = beatmap.HitObjects[i + 1].StartTime - 1000;
if (waitTime > endTime)
Frames.Add(new ReplayFrame(waitTime, 0, 0, ReplayButtonState.None));
}
hitButton = !hitButton;
}
}
}
}

View File

@ -0,0 +1,37 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Replays;
using System.Collections.Generic;
using osu.Framework.Input;
using OpenTK.Input;
namespace osu.Game.Modes.Taiko.Replays
{
internal class TaikoFramedReplayInputHandler : FramedReplayInputHandler
{
public TaikoFramedReplayInputHandler(Replay replay)
: base(replay)
{
}
public override List<InputState> GetPendingStates()
{
var keys = new List<Key>();
if (CurrentFrame?.MouseRight1 == true)
keys.Add(Key.F);
if (CurrentFrame?.MouseRight2 == true)
keys.Add(Key.J);
if (CurrentFrame?.MouseLeft1 == true)
keys.Add(Key.D);
if (CurrentFrame?.MouseLeft2 == true)
keys.Add(Key.K);
return new List<InputState>
{
new InputState { Keyboard = new ReplayKeyboardState(keys) }
};
}
}
}

View File

@ -96,9 +96,9 @@ namespace osu.Game.Modes.Taiko.Scoring
/// <summary>
/// The multiple of the original score added to the combo portion of the score
/// for correctly hitting an accented hit object with both keys.
/// for correctly hitting a strong hit object with both keys.
/// </summary>
private double accentedHitScale;
private double strongHitScale;
private double hpIncreaseTick;
private double hpIncreaseGreat;
@ -128,12 +128,12 @@ namespace osu.Game.Modes.Taiko.Scoring
hpIncreaseGood = hpMultiplierNormal * hp_hit_good;
hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.Difficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max);
var accentedHits = beatmap.HitObjects.FindAll(o => o is Hit && o.IsStrong);
var strongHits = beatmap.HitObjects.FindAll(o => o is Hit && o.IsStrong);
// This is a linear function that awards:
// 10 times bonus points for hitting an accented hit object with both keys with 30 accented hit objects in the map
// 3 times bonus points for hitting an accented hit object with both keys with 120 accented hit objects in the map
accentedHitScale = -7d / 90d * MathHelper.Clamp(accentedHits.Count, 30, 120) + 111d / 9d;
// 10 times bonus points for hitting a strong hit object with both keys with 30 strong hit objects in the map
// 3 times bonus points for hitting a strong hit object with both keys with 120 strong hit objects in the map
strongHitScale = -7d / 90d * MathHelper.Clamp(strongHits.Count, 30, 120) + 111d / 9d;
foreach (var obj in beatmap.HitObjects)
{
@ -179,7 +179,7 @@ namespace osu.Game.Modes.Taiko.Scoring
maxComboPortion = comboPortion;
}
protected override void OnNewJugement(TaikoJudgement judgement)
protected override void OnNewJudgement(TaikoJudgement judgement)
{
bool isTick = judgement is TaikoDrumRollTickJudgement;
@ -187,29 +187,12 @@ namespace osu.Game.Modes.Taiko.Scoring
if (!isTick)
totalHits++;
// Apply combo changes, must be done before the hit score is added
if (!isTick && judgement.Result == HitResult.Hit)
Combo.Value++;
// Apply score changes
if (judgement.Result == HitResult.Hit)
{
double baseValue = judgement.ResultValueForScore;
// Add bonus points for hitting an accented hit object with the second key
if (judgement.SecondHit)
baseValue += baseValue * accentedHitScale;
// Add score to portions
if (isTick)
bonusScore += baseValue;
else
{
Combo.Value++;
// A relevance factor that needs to be applied to make higher combos more relevant
// Value is capped at 400 combo
double comboRelevance = Math.Min(Math.Log(400, combo_base), Math.Max(0.5, Math.Log(Combo.Value, combo_base)));
comboPortion += baseValue * comboRelevance;
}
}
addHitScore(judgement);
// Apply HP changes
switch (judgement.Result)
@ -235,7 +218,43 @@ namespace osu.Game.Modes.Taiko.Scoring
break;
}
// Compute the new score + accuracy
calculateScore();
}
protected override void OnJudgementChanged(TaikoJudgement judgement)
{
// Apply score changes
addHitScore(judgement);
calculateScore();
}
private void addHitScore(TaikoJudgement judgement)
{
if (judgement.Result != HitResult.Hit)
return;
double baseValue = judgement.ResultValueForScore;
// Add increased score for hitting a strong hit object with the second key
if (judgement.SecondHit)
baseValue *= strongHitScale;
// Add score to portions
if (judgement is TaikoDrumRollTickJudgement)
bonusScore += baseValue;
else
{
// A relevance factor that needs to be applied to make higher combos more relevant
// Value is capped at 400 combo
double comboRelevance = Math.Min(Math.Log(400, combo_base), Math.Max(0.5, Math.Log(Combo.Value, combo_base)));
comboPortion += baseValue * comboRelevance;
}
}
private void calculateScore()
{
int scoreForAccuracy = 0;
int maxScoreForAccuracy = 0;

View File

@ -65,7 +65,7 @@ namespace osu.Game.Modes.Taiko
{
Mods = new Mod[]
{
new ModAutoplay(),
new TaikoModAutoplay(),
new ModCinema(),
},
},

View File

@ -7,7 +7,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Graphics;
using osu.Game.Modes.Taiko.Judgements;
using osu.Game.Modes.Taiko.Objects;

View File

@ -18,7 +18,7 @@ namespace osu.Game.Modes.Taiko.UI
/// <summary>
/// Diameter of normal hit object circles.
/// </summary>
private const float normal_diameter = TaikoHitObject.CIRCLE_RADIUS * 2 * TaikoPlayfield.PLAYFIELD_SCALE;
private const float normal_diameter = TaikoHitObject.CIRCLE_RADIUS * 2;
/// <summary>
/// Diameter of finisher hit object circles.
@ -47,7 +47,7 @@ namespace osu.Game.Modes.Taiko.UI
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Y = border_offset,
Size = new Vector2(border_thickness, (TaikoPlayfield.PlayfieldHeight - finisher_diameter) / 2f - border_offset),
Size = new Vector2(border_thickness, (TaikoPlayfield.PLAYFIELD_HEIGHT - finisher_diameter) / 2f - border_offset),
Alpha = 0.1f
},
new CircularContainer
@ -96,7 +96,7 @@ namespace osu.Game.Modes.Taiko.UI
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Y = -border_offset,
Size = new Vector2(border_thickness, (TaikoPlayfield.PlayfieldHeight - finisher_diameter) / 2f - border_offset),
Size = new Vector2(border_thickness, (TaikoPlayfield.PLAYFIELD_HEIGHT - finisher_diameter) / 2f - border_offset),
Alpha = 0.1f
},
};

View File

@ -9,7 +9,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using osu.Game.Graphics;
@ -22,7 +21,7 @@ namespace osu.Game.Modes.Taiko.UI
{
public InputDrum()
{
Size = new Vector2(TaikoPlayfield.PlayfieldHeight);
Size = new Vector2(TaikoPlayfield.PLAYFIELD_HEIGHT);
const float middle_split = 10;

View File

@ -3,10 +3,12 @@
using osu.Game.Beatmaps;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Replays;
using osu.Game.Modes.Scoring;
using osu.Game.Modes.Taiko.Beatmaps;
using osu.Game.Modes.Taiko.Judgements;
using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.Taiko.Replays;
using osu.Game.Modes.Taiko.Scoring;
using osu.Game.Modes.UI;
@ -28,5 +30,7 @@ namespace osu.Game.Modes.Taiko.UI
protected override Playfield<TaikoHitObject, TaikoJudgement> CreatePlayfield() => new TaikoPlayfield();
protected override DrawableHitObject<TaikoHitObject, TaikoJudgement> GetVisualRepresentation(TaikoHitObject h) => null;
protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new TaikoFramedReplayInputHandler(replay);
}
}

View File

@ -14,31 +14,22 @@ using osu.Game.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics.Primitives;
using osu.Game.Modes.Taiko.Objects.Drawable;
namespace osu.Game.Modes.Taiko.UI
{
public class TaikoPlayfield : Playfield<TaikoHitObject, TaikoJudgement>
{
/// <summary>
/// The default play field height.
/// The play field height. This is relative to the size of hit objects
/// such that the playfield is just a bit larger than finishers.
/// </summary>
public const float PLAYFIELD_BASE_HEIGHT = 242;
/// <summary>
/// The play field height scale.
/// This also uniformly scales the notes to match the new playfield height.
/// </summary>
public const float PLAYFIELD_SCALE = 0.65f;
/// <summary>
/// The play field height after scaling.
/// </summary>
public static float PlayfieldHeight => PLAYFIELD_BASE_HEIGHT * PLAYFIELD_SCALE;
public const float PLAYFIELD_HEIGHT = TaikoHitObject.CIRCLE_RADIUS * 2 * 2;
/// <summary>
/// The offset from <see cref="left_area_size"/> which the center of the hit target lies at.
/// </summary>
private const float hit_target_offset = 80;
private const float hit_target_offset = TaikoHitObject.CIRCLE_RADIUS * 1.5f + 40;
/// <summary>
/// The size of the left area of the playfield. This area contains the input drum.
@ -52,7 +43,7 @@ namespace osu.Game.Modes.Taiko.UI
private readonly Container<DrawableTaikoJudgement> judgementContainer;
private readonly Container hitObjectContainer;
//private Container topLevelHitContainer;
private readonly Container topLevelHitContainer;
private readonly Container leftBackgroundContainer;
private readonly Container rightBackgroundContainer;
private readonly Box leftBackground;
@ -61,7 +52,7 @@ namespace osu.Game.Modes.Taiko.UI
public TaikoPlayfield()
{
RelativeSizeAxes = Axes.X;
Height = PlayfieldHeight;
Height = PLAYFIELD_HEIGHT;
AddInternal(new Drawable[]
{
@ -102,7 +93,6 @@ namespace osu.Game.Modes.Taiko.UI
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
Scale = new Vector2(PLAYFIELD_SCALE),
BlendingMode = BlendingMode.Additive
},
//barLineContainer = new Container<DrawableBarLine>
@ -129,7 +119,7 @@ namespace osu.Game.Modes.Taiko.UI
},
leftBackgroundContainer = new Container
{
Size = new Vector2(left_area_size, PlayfieldHeight),
Size = new Vector2(left_area_size, PLAYFIELD_HEIGHT),
BorderThickness = 1,
Children = new Drawable[]
{
@ -154,10 +144,10 @@ namespace osu.Game.Modes.Taiko.UI
},
}
},
//topLevelHitContainer = new Container
//{
// RelativeSizeAxes = Axes.Both,
//}
topLevelHitContainer = new Container
{
RelativeSizeAxes = Axes.Both,
}
});
}
@ -174,9 +164,13 @@ namespace osu.Game.Modes.Taiko.UI
public override void Add(DrawableHitObject<TaikoHitObject, TaikoJudgement> h)
{
h.Depth = (float)h.HitObject.StartTime;
h.Scale = new Vector2(PLAYFIELD_SCALE);
base.Add(h);
// Swells should be moved at the very top of the playfield when they reach the hit target
var swell = h as DrawableSwell;
if (swell != null)
swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
}
public override void OnJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> judgedObject)

View File

@ -50,20 +50,32 @@
<Compile Include="Beatmaps\TaikoBeatmapConverter.cs" />
<Compile Include="Beatmaps\TaikoBeatmapProcessor.cs" />
<Compile Include="Judgements\TaikoDrumRollTickJudgement.cs" />
<Compile Include="Judgements\TaikoStrongHitJudgement.cs" />
<Compile Include="Judgements\TaikoJudgement.cs" />
<Compile Include="Judgements\TaikoHitResult.cs" />
<Compile Include="Objects\CentreHit.cs" />
<Compile Include="Objects\Drawable\DrawableRimHit.cs" />
<Compile Include="Objects\Drawable\DrawableStrongRimHit.cs" />
<Compile Include="Objects\Drawable\DrawableCentreHit.cs" />
<Compile Include="Objects\Drawable\DrawableHit.cs" />
<Compile Include="Objects\Drawable\DrawableStrongCentreHit.cs" />
<Compile Include="Objects\Drawable\DrawableStrongHit.cs" />
<Compile Include="Objects\Drawable\Pieces\CentreHitSymbolPiece.cs" />
<Compile Include="Objects\Drawable\DrawableDrumRoll.cs" />
<Compile Include="Objects\Drawable\DrawableDrumRollTick.cs" />
<Compile Include="Objects\Drawable\DrawableSwell.cs" />
<Compile Include="Objects\Drawable\DrawableTaikoHitObject.cs" />
<Compile Include="Objects\Drawable\Pieces\RimHitSymbolPiece.cs" />
<Compile Include="Objects\Drawable\Pieces\StrongCirclePiece.cs" />
<Compile Include="Objects\Drawable\Pieces\CirclePiece.cs" />
<Compile Include="Objects\Drawable\Pieces\SwellSymbolPiece.cs" />
<Compile Include="Objects\DrumRoll.cs" />
<Compile Include="Objects\DrumRollTick.cs" />
<Compile Include="Objects\Hit.cs" />
<Compile Include="Objects\RimHit.cs" />
<Compile Include="Objects\Swell.cs" />
<Compile Include="Replays\TaikoFramedReplayInputHandler.cs" />
<Compile Include="Replays\TaikoAutoReplay.cs" />
<Compile Include="Objects\TaikoHitObject.cs" />
<Compile Include="TaikoDifficultyCalculator.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@ -102,4 +114,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

View File

@ -33,12 +33,26 @@ namespace osu.Game.Beatmaps.Drawables
Children = new Drawable[]
{
new DelayedLoadContainer
{
RelativeSizeAxes = Axes.Both,
TimeBeforeLoad = 300,
FinishedLoading = d => d.FadeInFromZero(400, EasingTypes.Out),
Children = new[]
{
new PanelBackground(beatmap)
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
}
}
},
new FillFlowContainer
{
Direction = FillDirection.Vertical,
Padding = new MarginPadding { Top = 5, Left = 18, Right = 10, Bottom = 10 },
AutoSizeAxes = Axes.Both,
Children = new[]
Children = new Drawable[]
{
title = new OsuSpriteText
{
@ -71,23 +85,13 @@ namespace osu.Game.Beatmaps.Drawables
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, OsuGameBase game)
private void load(OsuConfigManager config)
{
this.config = config;
preferUnicode = config.GetBindable<bool>(OsuConfig.ShowUnicode);
preferUnicode.ValueChanged += preferUnicode_changed;
preferUnicode_changed(preferUnicode, null);
new PanelBackground(beatmap)
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
}.LoadAsync(game, b =>
{
Add(b);
b.FadeInFromZero(200);
});
}
private void preferUnicode_changed(object sender, EventArgs e)

View File

@ -4,7 +4,6 @@
using osu.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using OpenTK;
using OpenTK.Graphics;

View File

@ -101,7 +101,7 @@ namespace osu.Game.Database
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
using (var reader = new StreamReader(lzma))
score.Replay = score.CreateLegacyReplayFrom(reader);
score.Replay = score.CreateReplay(reader);
}
}

View File

@ -6,7 +6,6 @@ using osu.Framework.Graphics;
using osu.Framework.Input;
using OpenTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Transforms;
using osu.Game.Configuration;
using osu.Framework.Configuration;

View File

@ -10,7 +10,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using osu.Game.Configuration;
using System;

View File

@ -12,7 +12,6 @@ using osu.Framework.Input;
using osu.Game.Configuration;
using System;
using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms;
namespace osu.Game.Graphics.Cursor
{

View File

@ -0,0 +1,34 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Game.Graphics.Transforms;
namespace osu.Game.Graphics
{
/// <summary>
/// A type of drawable that has an accent colour.
/// The accent colour is used to colorize various objects inside a drawable
/// without colorizing the drawable itself.
/// </summary>
public interface IHasAccentColour : IDrawable
{
Color4 AccentColour { get; set; }
}
public static class AccentedColourExtensions
{
/// <summary>
/// Tweens the accent colour of a drawable to another colour.
/// </summary>
/// <param name="accentedDrawable">The drawable to apply the accent colour to.</param>
/// <param name="newColour">The new accent colour.</param>
/// <param name="duration">The tween duration.</param>
/// <param name="easing">The tween easing.</param>
public static void FadeAccent(this IHasAccentColour accentedDrawable, Color4 newColour, double duration = 0, EasingTypes easing = EasingTypes.None)
{
accentedDrawable.TransformTo(accentedDrawable.AccentColour, newColour, duration, easing, new TransformAccent());
}
}
}

View File

@ -0,0 +1,37 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Transforms;
using osu.Framework.MathUtils;
namespace osu.Game.Graphics.Transforms
{
public class TransformAccent : Transform<Color4>
{
/// <summary>
/// Current value of the transformed colour in linear colour space.
/// </summary>
public override Color4 CurrentValue
{
get
{
double time = Time?.Current ?? 0;
if (time < StartTime) return StartValue;
if (time >= EndTime) return EndValue;
return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
}
}
public override void Apply(Drawable d)
{
base.Apply(d);
var accented = d as IHasAccentColour;
if (accented != null)
accented.AccentColour = CurrentValue;
}
}
}

View File

@ -4,7 +4,6 @@
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Containers;

View File

@ -8,12 +8,11 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface
{
public class Nub : CircularContainer, IStateful<CheckBoxState>
public class Nub : CircularContainer, IStateful<CheckboxState>
{
public const float COLLAPSED_SIZE = 20;
public const float EXPANDED_SIZE = 40;
@ -85,9 +84,9 @@ namespace osu.Game.Graphics.UserInterface
}
}
private CheckBoxState state;
private CheckboxState state;
public CheckBoxState State
public CheckboxState State
{
get
{
@ -99,10 +98,10 @@ namespace osu.Game.Graphics.UserInterface
switch (state)
{
case CheckBoxState.Checked:
case CheckboxState.Checked:
fill.FadeIn(200, EasingTypes.OutQuint);
break;
case CheckBoxState.Unchecked:
case CheckboxState.Unchecked:
fill.FadeTo(0.01f, 200, EasingTypes.OutQuint); //todo: remove once we figure why containers aren't drawing at all times
break;
}

View File

@ -6,7 +6,6 @@ using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics.Backgrounds;

View File

@ -16,7 +16,7 @@ using OpenTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
public class OsuCheckbox : CheckBox
public class OsuCheckbox : Checkbox
{
private Bindable<bool> bindable;
@ -29,9 +29,9 @@ namespace osu.Game.Graphics.UserInterface
bindable = value;
if (bindable != null)
{
bool state = State == CheckBoxState.Checked;
bool state = State == CheckboxState.Checked;
if (state != bindable.Value)
State = bindable.Value ? CheckBoxState.Checked : CheckBoxState.Unchecked;
State = bindable.Value ? CheckboxState.Checked : CheckboxState.Unchecked;
bindable.ValueChanged += bindableValueChanged;
}
@ -88,7 +88,7 @@ namespace osu.Game.Graphics.UserInterface
private void bindableValueChanged(object sender, EventArgs e)
{
State = bindable.Value ? CheckBoxState.Checked : CheckBoxState.Unchecked;
State = bindable.Value ? CheckboxState.Checked : CheckboxState.Unchecked;
}
protected override void Dispose(bool isDisposing)
@ -122,7 +122,7 @@ namespace osu.Game.Graphics.UserInterface
protected override void OnChecked()
{
sampleChecked?.Play();
nub.State = CheckBoxState.Checked;
nub.State = CheckboxState.Checked;
if (bindable != null)
bindable.Value = true;
@ -131,7 +131,7 @@ namespace osu.Game.Graphics.UserInterface
protected override void OnUnchecked()
{
sampleUnchecked?.Play();
nub.State = CheckBoxState.Unchecked;
nub.State = CheckboxState.Unchecked;
if (bindable != null)
bindable.Value = false;

View File

@ -6,7 +6,6 @@ using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface

View File

@ -4,7 +4,6 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using OpenTK;
using OpenTK.Graphics;

View File

@ -8,7 +8,6 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
@ -51,7 +50,7 @@ namespace osu.Game.Graphics.UserInterface
nub = new Nub
{
Origin = Anchor.TopCentre,
State = CheckBoxState.Unchecked,
State = CheckboxState.Unchecked,
Expanded = true,
}
};
@ -95,13 +94,13 @@ namespace osu.Game.Graphics.UserInterface
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
nub.State = CheckBoxState.Checked;
nub.State = CheckboxState.Checked;
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
nub.State = CheckBoxState.Unchecked;
nub.State = CheckboxState.Unchecked;
return base.OnMouseUp(state, args);
}

View File

@ -11,7 +11,6 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;

View File

@ -9,7 +9,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
@ -17,15 +16,15 @@ using osu.Game.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
{
/// <summary>
/// A checkbox styled to be placed in line with an <see cref="OsuTabControl{T}"/>
/// A Checkbox styled to be placed in line with an <see cref="OsuTabControl{T}"/>
/// </summary>
public class OsuTabControlCheckBox : CheckBox
public class OsuTabControlCheckbox : Checkbox
{
private readonly Box box;
private readonly SpriteText text;
private readonly TextAwesome icon;
public event EventHandler<CheckBoxState> Action;
public event EventHandler<CheckboxState> Action;
private Color4? accentColour;
public Color4 AccentColour
@ -35,7 +34,7 @@ namespace osu.Game.Graphics.UserInterface
{
accentColour = value;
if (State != CheckBoxState.Checked)
if (State != CheckboxState.Checked)
{
text.Colour = AccentColour;
icon.Colour = AccentColour;
@ -85,7 +84,7 @@ namespace osu.Game.Graphics.UserInterface
protected override void OnHoverLost(InputState state)
{
if (State == CheckBoxState.Unchecked)
if (State == CheckboxState.Unchecked)
fadeOut();
base.OnHoverLost(state);
@ -98,7 +97,7 @@ namespace osu.Game.Graphics.UserInterface
AccentColour = colours.Blue;
}
public OsuTabControlCheckBox()
public OsuTabControlCheckbox()
{
AutoSizeAxes = Axes.Both;

View File

@ -47,7 +47,7 @@ namespace osu.Game.Graphics.UserInterface
protected class TransformAccuracy : Transform<double>
{
protected override double CurrentValue
public override double CurrentValue
{
get
{

View File

@ -51,7 +51,7 @@ namespace osu.Game.Graphics.UserInterface
protected class TransformScore : Transform<double>
{
protected override double CurrentValue
public override double CurrentValue
{
get
{

View File

@ -4,7 +4,6 @@
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.MathUtils;
using System;

View File

@ -5,7 +5,6 @@ using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
using OpenTK;

View File

@ -7,7 +7,6 @@ using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes.Objects.Drawables;

View File

@ -0,0 +1,26 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Scoring;
namespace osu.Game.Modes.Judgements
{
/// <summary>
/// Inidicates that the judgement this is attached to is a partial judgement and the scoring value may change.
/// <para>
/// This judgement will be continually processed by <see cref="DrawableHitObject{TObject, TJudgement}.CheckJudgement(bool)"/>
/// unless the result is a miss and will trigger a full re-process of the <see cref="ScoreProcessor"/> when changed.
/// </para>
/// </summary>
public interface IPartialJudgement
{
/// <summary>
/// Indicates that this partial judgement has changed and requires a full re-process of the <see cref="ScoreProcessor"/>.
/// <para>
/// This is set to false once the judgement has been re-processed.
/// </para>
/// </summary>
bool Changed { get; set; }
}
}

View File

@ -10,7 +10,7 @@ namespace osu.Game.Modes.Judgements
/// <summary>
/// Whether this judgement is the result of a hit or a miss.
/// </summary>
public HitResult? Result;
public HitResult Result;
/// <summary>
/// The offset at which this judgement occurred.
@ -20,7 +20,7 @@ namespace osu.Game.Modes.Judgements
/// <summary>
/// The combo after this judgement was processed.
/// </summary>
public ulong? ComboAtHit;
public int ComboAtHit;
/// <summary>
/// The string representation for the result achieved.

Some files were not shown because too many files have changed in this diff Show More