Merge branch 'master' into local-name-fix

This commit is contained in:
ThePyrotechnic
2018-01-22 09:59:45 -05:00
committed by GitHub
10 changed files with 110 additions and 29 deletions

View File

@ -23,6 +23,5 @@ namespace osu.Game.Rulesets.Catch
MoveRight, MoveRight,
[Description("Engage dash")] [Description("Engage dash")]
Dash, Dash,
PositionUpdate
} }
} }

View File

@ -1,9 +1,12 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq; using System.Linq;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Replays;
using osu.Game.Users; using osu.Game.Users;
@ -23,15 +26,78 @@ namespace osu.Game.Rulesets.Catch.Replays
public override Replay Generate() public override Replay Generate()
{ {
// todo: add support for HT DT
const double dash_speed = CatcherArea.Catcher.BASE_SPEED;
const double movement_speed = dash_speed / 2;
float lastPosition = 0.5f;
double lastTime = 0;
// Todo: Realistically this shouldn't be needed, but the first frame is skipped with the way replays are currently handled // Todo: Realistically this shouldn't be needed, but the first frame is skipped with the way replays are currently handled
Replay.Frames.Add(new CatchReplayFrame(-100000, 0)); Replay.Frames.Add(new CatchReplayFrame(-100000, lastPosition));
void moveToNext(CatchHitObject h)
{
float positionChange = Math.Abs(lastPosition - h.X);
double timeAvailable = h.StartTime - lastTime;
//So we can either make it there without a dash or not.
double speedRequired = positionChange / timeAvailable;
bool dashRequired = speedRequired > movement_speed && h.StartTime != 0;
// todo: get correct catcher size, based on difficulty CS.
const float catcher_width_half = CatcherArea.CATCHER_SIZE / CatchPlayfield.BASE_WIDTH * 0.3f * 0.5f;
if (lastPosition - catcher_width_half < h.X && lastPosition + catcher_width_half > h.X)
{
//we are already in the correct range.
lastTime = h.StartTime;
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, lastPosition));
return;
}
if (h is BananaShower.Banana)
{
// auto bananas unrealistically warp to catch 100% combo.
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
}
else if (h.HyperDash)
{
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable, lastPosition, ReplayButtonState.Right1));
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
}
else if (dashRequired)
{
//we do a movement in two parts - the dash part then the normal part...
double timeAtNormalSpeed = positionChange / movement_speed;
double timeWeNeedToSave = timeAtNormalSpeed - timeAvailable;
double timeAtDashSpeed = timeWeNeedToSave / 2;
float midPosition = (float)Interpolation.Lerp(lastPosition, h.X, (float)timeAtDashSpeed / timeAvailable);
//dash movement
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable + 1, lastPosition, ReplayButtonState.Left1));
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeAvailable + timeAtDashSpeed, midPosition));
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
}
else
{
double timeBefore = positionChange / movement_speed;
Replay.Frames.Add(new CatchReplayFrame(h.StartTime - timeBefore, lastPosition, ReplayButtonState.Right1));
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
}
lastTime = h.StartTime;
lastPosition = h.X;
}
foreach (var obj in Beatmap.HitObjects) foreach (var obj in Beatmap.HitObjects)
{ {
switch (obj) switch (obj)
{ {
case Fruit _: case Fruit _:
Replay.Frames.Add(new CatchReplayFrame(obj.StartTime, obj.X)); moveToNext(obj);
break; break;
} }
@ -42,7 +108,7 @@ namespace osu.Game.Rulesets.Catch.Replays
case BananaShower.Banana _: case BananaShower.Banana _:
case TinyDroplet _: case TinyDroplet _:
case Droplet _: case Droplet _:
Replay.Frames.Add(new CatchReplayFrame(nestedObj.StartTime, nestedObj.X)); moveToNext(nestedObj);
break; break;
} }
} }

View File

@ -14,15 +14,29 @@ namespace osu.Game.Rulesets.Catch.Replays
{ {
} }
public override List<InputState> GetPendingStates() => new List<InputState> public override List<InputState> GetPendingStates()
{
if (!Position.HasValue) return new List<InputState>();
var action = new List<CatchAction>();
if (CurrentFrame.ButtonState == ReplayButtonState.Left1)
action.Add(CatchAction.Dash);
if (Position.Value.X > CurrentFrame.Position.X)
action.Add(CatchAction.MoveRight);
else if (Position.Value.X < CurrentFrame.Position.X)
action.Add(CatchAction.MoveLeft);
return new List<InputState>
{ {
new CatchReplayState new CatchReplayState
{ {
PressedActions = new List<CatchAction> { CatchAction.PositionUpdate }, PressedActions = action,
CatcherX = ((CatchReplayFrame)CurrentFrame).MouseX CatcherX = Position.Value.X
}, },
new CatchReplayState { PressedActions = new List<CatchAction>() },
}; };
}
public class CatchReplayState : ReplayState<CatchAction> public class CatchReplayState : ReplayState<CatchAction>
{ {

View File

@ -9,8 +9,8 @@ namespace osu.Game.Rulesets.Catch.Replays
{ {
public override bool IsImportant => MouseX > 0; public override bool IsImportant => MouseX > 0;
public CatchReplayFrame(double time, float? x = null) public CatchReplayFrame(double time, float? x = null, ReplayButtonState button = ReplayButtonState.None)
: base(time, x ?? -1, null, ReplayButtonState.None) : base(time, x ?? -1, null, button)
{ {
} }
} }

View File

@ -21,7 +21,7 @@ using OpenTK.Graphics;
namespace osu.Game.Rulesets.Catch.UI namespace osu.Game.Rulesets.Catch.UI
{ {
public class CatcherArea : Container, IKeyBindingHandler<CatchAction> public class CatcherArea : Container
{ {
public const float CATCHER_SIZE = 172; public const float CATCHER_SIZE = 172;
@ -84,16 +84,14 @@ namespace osu.Game.Rulesets.Catch.UI
} }
} }
public bool OnPressed(CatchAction action) protected override void Update()
{ {
if (action != CatchAction.PositionUpdate) return false; base.Update();
CatchFramedReplayInputHandler.CatchReplayState state = (CatchFramedReplayInputHandler.CatchReplayState)GetContainingInputManager().CurrentState; var state = GetContainingInputManager().CurrentState as CatchFramedReplayInputHandler.CatchReplayState;
if (state.CatcherX.HasValue) if (state?.CatcherX != null)
MovableCatcher.X = state.CatcherX.Value; MovableCatcher.X = state.CatcherX.Value;
return true;
} }
public bool OnReleased(CatchAction action) => false; public bool OnReleased(CatchAction action) => false;

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using NUnit.Framework;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -15,6 +16,7 @@ using osu.Game.Screens.Edit.Screens.Compose.Timeline;
namespace osu.Game.Tests.Visual namespace osu.Game.Tests.Visual
{ {
[Ignore("CI regularly hangs on this TestCase...")]
public class TestCaseWaveform : OsuTestCase public class TestCaseWaveform : OsuTestCase
{ {
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>(); private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();

View File

@ -287,15 +287,16 @@ namespace osu.Game.Beatmaps
Import(archive); Import(archive);
downloadNotification.State = ProgressNotificationState.Completed; downloadNotification.State = ProgressNotificationState.Completed;
}, TaskCreationOptions.LongRunning);
currentDownloads.Remove(request); currentDownloads.Remove(request);
}, TaskCreationOptions.LongRunning);
}; };
request.Failure += data => request.Failure += error =>
{ {
if (error is OperationCanceledException) return;
downloadNotification.State = ProgressNotificationState.Completed; downloadNotification.State = ProgressNotificationState.Completed;
Logger.Error(data, "Failed to get beatmap download information"); Logger.Error(error, "Beatmap download failed!");
currentDownloads.Remove(request); currentDownloads.Remove(request);
}; };

View File

@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface
public Color4 FillColour public Color4 FillColour
{ {
set { fill.Colour = value; } set { fill.FadeColour(value, 150, Easing.OutQuint); }
} }
public Color4 BackgroundColour public Color4 BackgroundColour

View File

@ -16,7 +16,6 @@ using osu.Game.Graphics.Sprites;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Framework.Logging;
using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
@ -65,11 +64,14 @@ namespace osu.Game.Overlays.Direct
Colour = Color4.Black.Opacity(0.3f), Colour = Color4.Black.Opacity(0.3f),
}; };
private OsuColour colours;
[BackgroundDependencyLoader(permitNulls: true)] [BackgroundDependencyLoader(permitNulls: true)]
private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay) private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay)
{ {
this.beatmaps = beatmaps; this.beatmaps = beatmaps;
this.beatmapSetOverlay = beatmapSetOverlay; this.beatmapSetOverlay = beatmapSetOverlay;
this.colours = colours;
AddInternal(content = new Container AddInternal(content = new Container
{ {
@ -182,7 +184,6 @@ namespace osu.Game.Overlays.Direct
{ {
progressBar.Current.Value = 0; progressBar.Current.Value = 0;
progressBar.FadeOut(500); progressBar.FadeOut(500);
Logger.Error(e, "Failed to get beatmap download information");
}; };
request.DownloadProgressed += progress => progressBar.Current.Value = progress; request.DownloadProgressed += progress => progressBar.Current.Value = progress;
@ -190,7 +191,7 @@ namespace osu.Game.Overlays.Direct
request.Success += data => request.Success += data =>
{ {
progressBar.Current.Value = 1; progressBar.Current.Value = 1;
progressBar.FadeOut(500); progressBar.FillColour = colours.Yellow;
}; };
} }

View File

@ -298,7 +298,7 @@ namespace osu.Game.Overlays
Task.Run(() => Task.Run(() =>
{ {
var onlineIds = response.Select(r => r.OnlineBeatmapSetID).ToList(); var onlineIds = response.Select(r => r.OnlineBeatmapSetID).ToList();
var presentOnlineIds = beatmaps.QueryBeatmapSets(s => onlineIds.Contains(s.OnlineBeatmapSetID)).Select(r => r.OnlineBeatmapSetID).ToList(); var presentOnlineIds = beatmaps.QueryBeatmapSets(s => onlineIds.Contains(s.OnlineBeatmapSetID) && !s.DeletePending).Select(r => r.OnlineBeatmapSetID).ToList();
var sets = response.Select(r => r.ToBeatmapSet(rulesets)).Where(b => !presentOnlineIds.Contains(b.OnlineBeatmapSetID)).ToList(); var sets = response.Select(r => r.ToBeatmapSet(rulesets)).Where(b => !presentOnlineIds.Contains(b.OnlineBeatmapSetID)).ToList();
// may not need scheduling; loads async internally. // may not need scheduling; loads async internally.