mirror of
https://github.com/osukey/osukey.git
synced 2025-08-07 16:43:52 +09:00
Move some common functionality to OsuAutoReplayBase.cs
This commit is contained in:
@ -14,95 +14,51 @@ using osu.Game.Rulesets.Objects.Types;
|
|||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu
|
namespace osu.Game.Rulesets.Osu.Replays
|
||||||
{
|
{
|
||||||
public class OsuAutoReplay : Replay
|
public class OsuAutoReplay : OsuAutoReplayBase
|
||||||
{
|
{
|
||||||
private static readonly Vector2 spinner_centre = new Vector2(256, 192);
|
// Options
|
||||||
|
|
||||||
private const float spin_radius = 50;
|
/// <summary>
|
||||||
|
/// If delayed movements should be used, causing the cursor to stay on each hitobject for as long as possible.
|
||||||
|
/// Mainly for Autopilot.
|
||||||
|
/// </summary>
|
||||||
|
public readonly bool DelayedMovements; // ModManager.CheckActive(Mods.Relax2);
|
||||||
|
|
||||||
private readonly Beatmap<OsuHitObject> beatmap;
|
|
||||||
|
|
||||||
// ms between each ReplayFrame
|
// Local constants
|
||||||
private readonly float frameDelay;
|
|
||||||
|
|
||||||
// ms between 'seeing' a new hitobject and auto moving to 'react' to it
|
/// <summary>
|
||||||
private readonly int reactionTime;
|
/// The "reaction time" in ms between "seeing" a new hit object and moving to "react" to it.
|
||||||
|
/// </summary>
|
||||||
|
private double reactionTime;
|
||||||
|
|
||||||
// What easing to use when moving between hitobjects
|
/// <summary>
|
||||||
private EasingTypes preferredEasing;
|
/// What easing to use when moving between hitobjects
|
||||||
|
/// </summary>
|
||||||
|
private EasingTypes preferredEasing => DelayedMovements ? EasingTypes.InOutCubic : EasingTypes.Out;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Which button (left or right) to use for the current hitobject.
|
||||||
|
/// Even means LMB will be used to click, odd means RMB will be used.
|
||||||
|
/// This keeps track of the button previously used for alt/singletap logic.
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
// Even means LMB will be used to click, odd means RMB will be used.
|
|
||||||
// This keeps track of the button previously used for alt/singletap logic.
|
|
||||||
private int buttonIndex;
|
private int buttonIndex;
|
||||||
|
|
||||||
public OsuAutoReplay(Beatmap<OsuHitObject> beatmap)
|
protected override void Initialise()
|
||||||
{
|
{
|
||||||
this.beatmap = beatmap;
|
base.Initialise();
|
||||||
|
|
||||||
User = new User
|
|
||||||
{
|
|
||||||
Username = @"Autoplay",
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
frameDelay = (float)applyModsToRate(1000.0 / 60.0);
|
|
||||||
|
|
||||||
// Already superhuman, but still somewhat realistic
|
// Already superhuman, but still somewhat realistic
|
||||||
reactionTime = (int)applyModsToRate(100);
|
reactionTime = applyModsToRate(100);
|
||||||
|
|
||||||
createAutoReplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ReplayFrameComparer : IComparer<ReplayFrame>
|
protected override void CreateAutoReplay()
|
||||||
{
|
|
||||||
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<ReplayFrame> replay_frame_comparer = new ReplayFrameComparer();
|
|
||||||
|
|
||||||
private int findInsertionIndex(ReplayFrame frame)
|
|
||||||
{
|
|
||||||
int index = Frames.BinarySearch(frame, replay_frame_comparer);
|
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
{
|
|
||||||
index = ~index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Go to the first index which is actually bigger
|
|
||||||
while (index < Frames.Count && frame.Time == Frames[index].Time)
|
|
||||||
{
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
|
|
||||||
private double applyModsToTime(double v) => v;
|
|
||||||
private double applyModsToRate(double v) => v;
|
|
||||||
|
|
||||||
public bool DelayedMovements; // ModManager.CheckActive(Mods.Relax2);
|
|
||||||
|
|
||||||
private void createAutoReplay()
|
|
||||||
{
|
{
|
||||||
buttonIndex = 0;
|
buttonIndex = 0;
|
||||||
|
|
||||||
preferredEasing = DelayedMovements ? EasingTypes.InOutCubic : EasingTypes.Out;
|
|
||||||
|
|
||||||
addFrameToReplay(new ReplayFrame(-100000, 256, 500, ReplayButtonState.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 - 1500, 256, 500, ReplayButtonState.None));
|
||||||
addFrameToReplay(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, 256, 192, ReplayButtonState.None));
|
addFrameToReplay(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, 256, 192, ReplayButtonState.None));
|
||||||
@ -112,12 +68,6 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
{
|
{
|
||||||
OsuHitObject h = beatmap.HitObjects[i];
|
OsuHitObject h = beatmap.HitObjects[i];
|
||||||
|
|
||||||
//if (h.EndTime < InputManager.ReplayStartTime)
|
|
||||||
//{
|
|
||||||
// h.IsHit = true;
|
|
||||||
// continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (DelayedMovements && i > 0)
|
if (DelayedMovements && i > 0)
|
||||||
{
|
{
|
||||||
OsuHitObject prev = beatmap.HitObjects[i - 1];
|
OsuHitObject prev = beatmap.HitObjects[i - 1];
|
||||||
@ -126,9 +76,6 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
addHitObjectReplay(h);
|
addHitObjectReplay(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Player.currentScore.Replay = InputManager.ReplayScore.Replay;
|
|
||||||
//Player.currentScore.PlayerName = "osu!";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDelayedMovements(OsuHitObject h, OsuHitObject prev)
|
private void addDelayedMovements(OsuHitObject h, OsuHitObject prev)
|
114
osu.Game.Rulesets.Osu/Replays/OsuAutoReplayBase.cs
Normal file
114
osu.Game.Rulesets.Osu/Replays/OsuAutoReplayBase.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// 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 osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Replays
|
||||||
|
{
|
||||||
|
public abstract class OsuAutoReplayBase : Replay
|
||||||
|
{
|
||||||
|
#region Constants
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constants (for spinners).
|
||||||
|
/// </summary>
|
||||||
|
protected static readonly Vector2 spinner_centre = new Vector2(256, 192);
|
||||||
|
protected const float spin_radius = 50;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The beatmap we're making a replay out of.
|
||||||
|
/// </summary>
|
||||||
|
protected readonly Beatmap<OsuHitObject> beatmap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The time in ms between each ReplayFrame.
|
||||||
|
/// </summary>
|
||||||
|
protected double frameDelay;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Construction
|
||||||
|
|
||||||
|
public OsuAutoReplayBase(Beatmap<OsuHitObject> beatmap)
|
||||||
|
{
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
Initialise();
|
||||||
|
CreateAutoReplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialise this instance. Called before CreateAutoReplay.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void Initialise()
|
||||||
|
{
|
||||||
|
User = new User
|
||||||
|
{
|
||||||
|
Username = @"Autoplay",
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
frameDelay = applyModsToRate(1000.0 / 60.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the auto replay. Every OsuAutoReplayBase subclass should implement this!
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void CreateAutoReplay();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Utilities
|
||||||
|
protected double applyModsToTime(double v) => v;
|
||||||
|
protected double applyModsToRate(double v) => v;
|
||||||
|
|
||||||
|
private class ReplayFrameComparer : IComparer<ReplayFrame>
|
||||||
|
{
|
||||||
|
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<ReplayFrame> replay_frame_comparer = new ReplayFrameComparer();
|
||||||
|
|
||||||
|
protected int findInsertionIndex(ReplayFrame frame)
|
||||||
|
{
|
||||||
|
int index = Frames.BinarySearch(frame, replay_frame_comparer);
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
index = ~index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Go to the first index which is actually bigger
|
||||||
|
while (index < Frames.Count && frame.Time == Frames[index].Time)
|
||||||
|
{
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addFrameToReplay(ReplayFrame frame) => Frames.Insert(findInsertionIndex(frame), frame);
|
||||||
|
|
||||||
|
protected static Vector2 circlePosition(double t, double radius) => new Vector2((float)(Math.Cos(t) * radius), (float)(Math.Sin(t) * radius));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -69,7 +69,6 @@
|
|||||||
<Compile Include="Objects\Drawables\Pieces\SliderBody.cs" />
|
<Compile Include="Objects\Drawables\Pieces\SliderBody.cs" />
|
||||||
<Compile Include="Objects\OsuHitObjectDifficulty.cs" />
|
<Compile Include="Objects\OsuHitObjectDifficulty.cs" />
|
||||||
<Compile Include="Objects\SliderTick.cs" />
|
<Compile Include="Objects\SliderTick.cs" />
|
||||||
<Compile Include="OsuAutoReplay.cs" />
|
|
||||||
<Compile Include="OsuDifficultyCalculator.cs" />
|
<Compile Include="OsuDifficultyCalculator.cs" />
|
||||||
<Compile Include="OsuKeyConversionInputManager.cs" />
|
<Compile Include="OsuKeyConversionInputManager.cs" />
|
||||||
<Compile Include="Scoring\OsuScoreProcessor.cs" />
|
<Compile Include="Scoring\OsuScoreProcessor.cs" />
|
||||||
@ -83,6 +82,8 @@
|
|||||||
<Compile Include="Objects\Spinner.cs" />
|
<Compile Include="Objects\Spinner.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Mods\OsuMod.cs" />
|
<Compile Include="Mods\OsuMod.cs" />
|
||||||
|
<Compile Include="Replays\OsuAutoReplay.cs" />
|
||||||
|
<Compile Include="Replays\OsuAutoReplayBase.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
|
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
|
||||||
@ -102,6 +103,9 @@
|
|||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Replays\" />
|
||||||
|
</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.
|
||||||
|
Reference in New Issue
Block a user