Merge branch 'master' into fix-beatmap-options

This commit is contained in:
Thomas Müller 2017-03-19 09:34:53 +01:00 committed by GitHub
commit 44f71b3975
27 changed files with 203 additions and 70 deletions

@ -1 +1 @@
Subproject commit 169cb6485e7ae740a71cbcb7d0d9d08052eb8848 Subproject commit e6394035d443d4498b71e845e5763dd3faf98c7c

View File

@ -105,6 +105,9 @@
<ItemGroup> <ItemGroup>
<Folder Include="Properties\" /> <Folder Include="Properties\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 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 osu.Framework.Platform;
using osu.Framework.Screens.Testing; using osu.Framework.Screens.Testing;
using osu.Game; using osu.Game;
using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Backgrounds;
@ -19,5 +20,11 @@ namespace osu.Desktop.VisualTests
// we depend on some dependencies to be loaded within OsuGameBase.load(). // we depend on some dependencies to be loaded within OsuGameBase.load().
Add(new TestBrowser()); Add(new TestBrowser());
} }
public override void SetHost(GameHost host)
{
base.SetHost(host);
host.Window.CursorState = CursorState.Hidden;
}
} }
} }

View File

@ -43,6 +43,8 @@ namespace osu.Desktop
var desktopWindow = host.Window as DesktopGameWindow; var desktopWindow = host.Window as DesktopGameWindow;
if (desktopWindow != null) if (desktopWindow != null)
{ {
desktopWindow.CursorState = CursorState.Hidden;
desktopWindow.Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location); desktopWindow.Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);
desktopWindow.Title = Name; desktopWindow.Title = Name;

View File

@ -128,9 +128,11 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
case ArmedState.Idle: case ArmedState.Idle:
Delay(duration + TIME_PREEMPT); Delay(duration + TIME_PREEMPT);
FadeOut(TIME_FADEOUT); FadeOut(TIME_FADEOUT);
Expire(true);
break; break;
case ArmedState.Miss: case ArmedState.Miss:
FadeOut(TIME_FADEOUT / 5); FadeOut(TIME_FADEOUT / 5);
Expire();
break; break;
case ArmedState.Hit: case ArmedState.Hit:
const double flash_in = 40; const double flash_in = 40;
@ -150,6 +152,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
FadeOut(800); FadeOut(800);
ScaleTo(Scale * 1.5f, 400, EasingTypes.OutQuad); ScaleTo(Scale * 1.5f, 400, EasingTypes.OutQuad);
Expire();
break; break;
} }
} }

View File

@ -168,6 +168,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
ball.FadeOut(160); ball.FadeOut(160);
FadeOut(800); FadeOut(800);
Expire();
} }
public Drawable ProxiedLayer => initialCircle.ApproachCircle; public Drawable ProxiedLayer => initialCircle.ApproachCircle;

View File

@ -146,9 +146,11 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
{ {
case ArmedState.Hit: case ArmedState.Hit:
ScaleTo(Scale * 1.2f, 320, EasingTypes.Out); ScaleTo(Scale * 1.2f, 320, EasingTypes.Out);
Expire();
break; break;
case ArmedState.Miss: case ArmedState.Miss:
ScaleTo(Scale * 0.8f, 320, EasingTypes.In); ScaleTo(Scale * 0.8f, 320, EasingTypes.In);
Expire();
break; break;
} }
} }

View File

@ -7,13 +7,13 @@ using System.Collections.Generic;
namespace osu.Game.Modes.Taiko.Beatmaps namespace osu.Game.Modes.Taiko.Beatmaps
{ {
internal class TaikoBeatmapConverter : IBeatmapConverter<TaikoBaseHit> internal class TaikoBeatmapConverter : IBeatmapConverter<TaikoHitObject>
{ {
public Beatmap<TaikoBaseHit> Convert(Beatmap original) public Beatmap<TaikoHitObject> Convert(Beatmap original)
{ {
return new Beatmap<TaikoBaseHit>(original) return new Beatmap<TaikoHitObject>(original)
{ {
HitObjects = new List<TaikoBaseHit>() // Todo: Implement HitObjects = new List<TaikoHitObject>() // Todo: Implement
}; };
} }
} }

View File

@ -6,13 +6,13 @@ using osu.Game.Modes.Taiko.Objects;
namespace osu.Game.Modes.Taiko.Beatmaps namespace osu.Game.Modes.Taiko.Beatmaps
{ {
internal class TaikoBeatmapProcessor : IBeatmapProcessor<TaikoBaseHit> internal class TaikoBeatmapProcessor : IBeatmapProcessor<TaikoHitObject>
{ {
public void SetDefaults(TaikoBaseHit hitObject, Beatmap<TaikoBaseHit> beatmap) public void SetDefaults(TaikoHitObject hitObject, Beatmap<TaikoHitObject> beatmap)
{ {
} }
public void PostProcess(Beatmap<TaikoBaseHit> beatmap) public void PostProcess(Beatmap<TaikoHitObject> beatmap)
{ {
} }
} }

View File

@ -12,9 +12,9 @@ namespace osu.Game.Modes.Taiko.Objects.Drawable
{ {
internal class DrawableTaikoHit : Sprite internal class DrawableTaikoHit : Sprite
{ {
private TaikoBaseHit h; private TaikoHitObject h;
public DrawableTaikoHit(TaikoBaseHit h) public DrawableTaikoHit(TaikoHitObject h)
{ {
this.h = h; this.h = h;

View File

@ -1,20 +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 osu.Game.Modes.Objects;
namespace osu.Game.Modes.Taiko.Objects
{
public class TaikoBaseHit : HitObject
{
public float Scale = 1;
public TaikoColour Type;
}
public enum TaikoColour
{
Red,
Blue
}
}

View File

@ -0,0 +1,59 @@
// 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.Timing;
using osu.Game.Database;
using osu.Game.Modes.Objects;
namespace osu.Game.Modes.Taiko.Objects
{
public class TaikoHitObject : HitObject
{
/// <summary>
/// HitCircle radius.
/// </summary>
public const float CIRCLE_RADIUS = 64;
/// <summary>
/// The hit window that results in a "GREAT" hit.
/// </summary>
public double HitWindowGreat = 35;
/// <summary>
/// The hit window that results in a "GOOD" hit.
/// </summary>
public double HitWindowGood = 80;
/// <summary>
/// The hit window that results in a "MISS".
/// </summary>
public double HitWindowMiss = 95;
/// <summary>
/// The time to scroll in the HitObject.
/// </summary>
public double PreEmpt;
/// <summary>
/// Whether this HitObject is in Kiai time.
/// </summary>
public bool Kiai;
public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
{
base.ApplyDefaults(timing, difficulty);
PreEmpt = 600 / (timing.SliderVelocityAt(StartTime) * difficulty.SliderMultiplier) * 1000;
ControlPoint overridePoint;
Kiai = timing.TimingPointAt(StartTime, out overridePoint).KiaiMode;
if (overridePoint != null)
Kiai |= overridePoint.KiaiMode;
HitWindowGreat = BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 50, 35, 20);
HitWindowGood = BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 120, 80, 50);
HitWindowMiss = BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 135, 95, 70);
}
}
}

View File

@ -0,0 +1,21 @@
// 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;
namespace osu.Game.Modes.Taiko.Objects
{
[Flags]
public enum TaikoHitType
{
None = 0,
CentreHit = 1 << 0,
RimHit = 1 << 1,
DrumRoll = 1 << 2,
DrumRollTick = 1 << 3,
Bash = 1 << 4,
Finisher = 1 << 5,
Hit = CentreHit | RimHit
}
}

View File

@ -8,7 +8,7 @@ using System.Collections.Generic;
namespace osu.Game.Modes.Taiko namespace osu.Game.Modes.Taiko
{ {
public class TaikoDifficultyCalculator : DifficultyCalculator<TaikoBaseHit> public class TaikoDifficultyCalculator : DifficultyCalculator<TaikoHitObject>
{ {
public TaikoDifficultyCalculator(Beatmap beatmap) : base(beatmap) public TaikoDifficultyCalculator(Beatmap beatmap) : base(beatmap)
{ {
@ -19,6 +19,6 @@ namespace osu.Game.Modes.Taiko
return 0; return 0;
} }
protected override IBeatmapConverter<TaikoBaseHit> CreateBeatmapConverter() => new TaikoBeatmapConverter(); protected override IBeatmapConverter<TaikoHitObject> CreateBeatmapConverter() => new TaikoBeatmapConverter();
} }
} }

View File

@ -7,13 +7,13 @@ using osu.Game.Modes.UI;
namespace osu.Game.Modes.Taiko namespace osu.Game.Modes.Taiko
{ {
internal class TaikoScoreProcessor : ScoreProcessor<TaikoBaseHit, TaikoJudgementInfo> internal class TaikoScoreProcessor : ScoreProcessor<TaikoHitObject, TaikoJudgementInfo>
{ {
public TaikoScoreProcessor() public TaikoScoreProcessor()
{ {
} }
public TaikoScoreProcessor(HitRenderer<TaikoBaseHit, TaikoJudgementInfo> hitRenderer) public TaikoScoreProcessor(HitRenderer<TaikoHitObject, TaikoJudgementInfo> hitRenderer)
: base(hitRenderer) : base(hitRenderer)
{ {
} }

View File

@ -10,7 +10,7 @@ using osu.Game.Modes.UI;
namespace osu.Game.Modes.Taiko.UI namespace osu.Game.Modes.Taiko.UI
{ {
public class TaikoHitRenderer : HitRenderer<TaikoBaseHit, TaikoJudgementInfo> public class TaikoHitRenderer : HitRenderer<TaikoHitObject, TaikoJudgementInfo>
{ {
public TaikoHitRenderer(WorkingBeatmap beatmap) public TaikoHitRenderer(WorkingBeatmap beatmap)
: base(beatmap) : base(beatmap)
@ -19,12 +19,12 @@ namespace osu.Game.Modes.Taiko.UI
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this); public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
protected override IBeatmapConverter<TaikoBaseHit> CreateBeatmapConverter() => new TaikoBeatmapConverter(); protected override IBeatmapConverter<TaikoHitObject> CreateBeatmapConverter() => new TaikoBeatmapConverter();
protected override IBeatmapProcessor<TaikoBaseHit> CreateBeatmapProcessor() => new TaikoBeatmapProcessor(); protected override IBeatmapProcessor<TaikoHitObject> CreateBeatmapProcessor() => new TaikoBeatmapProcessor();
protected override Playfield<TaikoBaseHit, TaikoJudgementInfo> CreatePlayfield() => new TaikoPlayfield(); protected override Playfield<TaikoHitObject, TaikoJudgementInfo> CreatePlayfield() => new TaikoPlayfield();
protected override DrawableHitObject<TaikoBaseHit, TaikoJudgementInfo> GetVisualRepresentation(TaikoBaseHit h) => null; protected override DrawableHitObject<TaikoHitObject, TaikoJudgementInfo> GetVisualRepresentation(TaikoHitObject h) => null;
} }
} }

View File

@ -13,7 +13,7 @@ using osu.Game.Modes.Taiko.Judgements;
namespace osu.Game.Modes.Taiko.UI namespace osu.Game.Modes.Taiko.UI
{ {
public class TaikoPlayfield : Playfield<TaikoBaseHit, TaikoJudgementInfo> public class TaikoPlayfield : Playfield<TaikoHitObject, TaikoJudgementInfo>
{ {
public TaikoPlayfield() public TaikoPlayfield()
{ {

View File

@ -50,9 +50,10 @@
<Compile Include="Beatmaps\TaikoBeatmapConverter.cs" /> <Compile Include="Beatmaps\TaikoBeatmapConverter.cs" />
<Compile Include="Beatmaps\TaikoBeatmapProcessor.cs" /> <Compile Include="Beatmaps\TaikoBeatmapProcessor.cs" />
<Compile Include="Judgements\TaikoJudgementInfo.cs" /> <Compile Include="Judgements\TaikoJudgementInfo.cs" />
<Compile Include="Objects\TaikoHitType.cs" />
<Compile Include="TaikoDifficultyCalculator.cs" /> <Compile Include="TaikoDifficultyCalculator.cs" />
<Compile Include="Objects\Drawable\DrawableTaikoHit.cs" /> <Compile Include="Objects\Drawable\DrawableTaikoHit.cs" />
<Compile Include="Objects\TaikoBaseHit.cs" /> <Compile Include="Objects\TaikoHitObject.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TaikoScoreProcessor.cs" /> <Compile Include="TaikoScoreProcessor.cs" />
<Compile Include="UI\TaikoHitRenderer.cs" /> <Compile Include="UI\TaikoHitRenderer.cs" />

View File

@ -43,21 +43,6 @@ namespace osu.Game.Beatmaps
TimingInfo = original?.TimingInfo ?? TimingInfo; TimingInfo = original?.TimingInfo ?? TimingInfo;
ComboColors = original?.ComboColors ?? ComboColors; ComboColors = original?.ComboColors ?? ComboColors;
} }
/// <summary>
/// Finds the slider velocity at a time.
/// </summary>
/// <param name="time">The time to find the slider velocity at.</param>
/// <returns>The slider velocity in positional length units.</returns>
public double SliderVelocityAt(double time)
{
double scoringDistance = 100 * BeatmapInfo.Difficulty.SliderMultiplier;
double beatDistance = TimingInfo.BeatDistanceAt(time);
if (beatDistance > 0)
return scoringDistance / beatDistance * 1000;
return scoringDistance;
}
} }
/// <summary> /// <summary>
@ -70,5 +55,14 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
/// <returns>The star difficulty.</returns> /// <returns>The star difficulty.</returns>
public double CalculateStarDifficulty() => Ruleset.GetRuleset(BeatmapInfo.Mode).CreateDifficultyCalculator(this).Calculate(); public double CalculateStarDifficulty() => Ruleset.GetRuleset(BeatmapInfo.Mode).CreateDifficultyCalculator(this).Calculate();
/// <summary>
/// Constructs a new beatmap.
/// </summary>
/// <param name="original">The original beatmap to use the parameters of.</param>
public Beatmap(Beatmap original = null)
: base(original)
{
}
} }
} }

View File

@ -10,6 +10,7 @@ using osu.Game.Beatmaps.Samples;
using osu.Game.Beatmaps.Timing; using osu.Game.Beatmaps.Timing;
using osu.Game.Modes; using osu.Game.Modes;
using osu.Game.Modes.Objects; using osu.Game.Modes.Objects;
using osu.Game.Beatmaps.Legacy;
namespace osu.Game.Beatmaps.Formats namespace osu.Game.Beatmaps.Formats
{ {
@ -244,6 +245,16 @@ namespace osu.Game.Beatmaps.Formats
} }
} }
protected override Beatmap ParseFile(TextReader stream)
{
return new LegacyBeatmap(base.ParseFile(stream));
}
public override Beatmap Decode(TextReader stream)
{
return new LegacyBeatmap(base.Decode(stream));
}
protected override void ParseFile(TextReader stream, Beatmap beatmap) protected override void ParseFile(TextReader stream, Beatmap beatmap)
{ {
HitObjectParser parser = null; HitObjectParser parser = null;

View File

@ -0,0 +1,21 @@
// 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.Beatmaps.Legacy
{
/// <summary>
/// A type of Beatmap loaded from a legacy .osu beatmap file (version &lt;=15).
/// </summary>
public class LegacyBeatmap : Beatmap
{
/// <summary>
/// Constructs a new beatmap.
/// </summary>
/// <param name="original">The original beatmap to use the parameters of.</param>
internal LegacyBeatmap(Beatmap original = null)
: base(original)
{
HitObjects = original?.HitObjects;
}
}
}

View File

@ -102,5 +102,21 @@ namespace osu.Game.Beatmaps.Timing
return timingPoint ?? ControlPoint.Default; return timingPoint ?? ControlPoint.Default;
} }
/// <summary>
/// Finds the slider velocity at a time.
/// </summary>
/// <param name="time">The time to find the slider velocity at.</param>
/// <returns>The slider velocity in milliseconds.</returns>
public double SliderVelocityAt(double time)
{
const double base_scoring_distance = 100;
double beatDistance = BeatDistanceAt(time);
if (beatDistance > 0)
return base_scoring_distance / beatDistance * 1000;
return base_scoring_distance;
}
} }
} }

View File

@ -20,6 +20,25 @@ namespace osu.Game.Graphics.Cursor
{ {
protected override Drawable CreateCursor() => new Cursor(); protected override Drawable CreateCursor() => new Cursor();
protected override bool OnMouseMove(InputState state)
{
if (state.Mouse.HasMainButtonPressed)
{
Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown ?? state.Mouse.Delta;
float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f;
// Always rotate in the direction of least distance
float diff = (degrees - ActiveCursor.Rotation) % 360;
if (diff < -180) diff += 360;
if (diff > 180) diff -= 360;
degrees = ActiveCursor.Rotation + diff;
ActiveCursor.RotateTo(degrees, 600, EasingTypes.OutQuint);
}
return base.OnMouseMove(state);
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{ {
ActiveCursor.Scale = new Vector2(1); ActiveCursor.Scale = new Vector2(1);
@ -35,7 +54,7 @@ namespace osu.Game.Graphics.Cursor
if (!state.Mouse.HasMainButtonPressed) if (!state.Mouse.HasMainButtonPressed)
{ {
((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, EasingTypes.OutQuint); ((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, EasingTypes.OutQuint);
ActiveCursor.RotateTo(0, 200, EasingTypes.OutQuint); ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), EasingTypes.OutElasticHalf);
ActiveCursor.ScaleTo(1, 500, EasingTypes.OutElastic); ActiveCursor.ScaleTo(1, 500, EasingTypes.OutElastic);
} }
@ -49,12 +68,6 @@ namespace osu.Game.Graphics.Cursor
return base.OnClick(state); return base.OnClick(state);
} }
protected override bool OnDragStart(InputState state)
{
ActiveCursor.RotateTo(-30, 600, EasingTypes.OutElastic);
return base.OnDragStart(state);
}
protected override void PopIn() protected override void PopIn()
{ {
ActiveCursor.FadeTo(1, 250, EasingTypes.OutQuint); ActiveCursor.FadeTo(1, 250, EasingTypes.OutQuint);

View File

@ -34,12 +34,11 @@ namespace osu.Game.Modes.Objects.Drawables
set set
{ {
if (state == value) return; if (state == value)
return;
state = value; state = value;
UpdateState(state); UpdateState(state);
if (IsLoaded)
Expire();
if (State == ArmedState.Hit) if (State == ArmedState.Hit)
PlaySample(); PlaySample();
@ -63,8 +62,6 @@ namespace osu.Game.Modes.Objects.Drawables
//force application of the state that was set before we loaded. //force application of the state that was set before we loaded.
UpdateState(State); UpdateState(State);
Expire(true);
} }
} }

View File

@ -65,7 +65,7 @@ namespace osu.Game.Overlays
Vector2 change = state.Mouse.Position - state.Mouse.PositionMouseDown.Value; Vector2 change = state.Mouse.Position - state.Mouse.PositionMouseDown.Value;
// Diminish the drag distance as we go further to simulate "rubber band" feeling. // Diminish the drag distance as we go further to simulate "rubber band" feeling.
change *= (float)Math.Pow(change.Length, 0.7f) / change.Length; change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length;
dragContainer.MoveTo(change); dragContainer.MoveTo(change);
return base.OnDrag(state); return base.OnDrag(state);

View File

@ -21,7 +21,7 @@ namespace osu.Game.Screens.Menu
internal override bool ShowOverlays => false; internal override bool ShowOverlays => false;
internal override bool HasLocalCursorDisplayed => false; internal override bool HasLocalCursorDisplayed => true;
public Disclaimer() public Disclaimer()
{ {

View File

@ -75,6 +75,7 @@
<Compile Include="Beatmaps\DifficultyCalculator.cs" /> <Compile Include="Beatmaps\DifficultyCalculator.cs" />
<Compile Include="Beatmaps\IBeatmapCoverter.cs" /> <Compile Include="Beatmaps\IBeatmapCoverter.cs" />
<Compile Include="Beatmaps\IBeatmapProcessor.cs" /> <Compile Include="Beatmaps\IBeatmapProcessor.cs" />
<Compile Include="Beatmaps\Legacy\LegacyBeatmap.cs" />
<Compile Include="Beatmaps\Timing\TimingInfo.cs" /> <Compile Include="Beatmaps\Timing\TimingInfo.cs" />
<Compile Include="Database\ScoreDatabase.cs" /> <Compile Include="Database\ScoreDatabase.cs" />
<Compile Include="Graphics\Backgrounds\Triangles.cs" /> <Compile Include="Graphics\Backgrounds\Triangles.cs" />