mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 16:43:52 +09:00
Merge branch 'master' into local-name-fix
This commit is contained in:
@ -23,6 +23,5 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
MoveRight,
|
MoveRight,
|
||||||
[Description("Engage dash")]
|
[Description("Engage dash")]
|
||||||
Dash,
|
Dash,
|
||||||
PositionUpdate
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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>();
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
Reference in New Issue
Block a user