mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 15:47:26 +08:00
Create "AutoGenerator" base class and interface.
This commit is contained in:
parent
2af6c7aa00
commit
9b8b88601f
@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
protected override Score CreateReplayScore(Beatmap<OsuHitObject> beatmap) => new Score
|
protected override Score CreateReplayScore(Beatmap<OsuHitObject> beatmap) => new Score
|
||||||
{
|
{
|
||||||
Replay = new OsuAutoReplay(beatmap)
|
Replay = new OsuAutoGenerator(beatmap).Generate()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,80 +7,82 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Replays
|
namespace osu.Game.Rulesets.Osu.Replays
|
||||||
{
|
{
|
||||||
public class OsuAutoReplay : OsuAutoReplayBase
|
public class OsuAutoGenerator : OsuAutoGeneratorBase
|
||||||
{
|
{
|
||||||
// Options
|
#region Parameters
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If delayed movements should be used, causing the cursor to stay on each hitobject for as long as possible.
|
/// If delayed movements should be used, causing the cursor to stay on each hitobject for as long as possible.
|
||||||
/// Mainly for Autopilot.
|
/// Mainly for Autopilot.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly bool DelayedMovements; // ModManager.CheckActive(Mods.Relax2);
|
public bool DelayedMovements; // ModManager.CheckActive(Mods.Relax2);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
// Local constants
|
#region Constants
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The "reaction time" in ms between "seeing" a new hit object and moving to "react" to it.
|
/// The "reaction time" in ms between "seeing" a new hit object and moving to "react" to it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private double reactionTime;
|
private readonly double reactionTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// What easing to use when moving between hitobjects
|
/// What easing to use when moving between hitobjects
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private EasingTypes preferredEasing => DelayedMovements ? EasingTypes.InOutCubic : EasingTypes.Out;
|
private EasingTypes preferredEasing => DelayedMovements ? EasingTypes.InOutCubic : EasingTypes.Out;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Construction / Initialisation
|
||||||
|
|
||||||
|
public OsuAutoGenerator(Beatmap<OsuHitObject> beatmap)
|
||||||
|
: base(beatmap)
|
||||||
|
{
|
||||||
|
// Already superhuman, but still somewhat realistic
|
||||||
|
reactionTime = applyModsToRate(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Generator
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Which button (left or right) to use for the current hitobject.
|
/// 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.
|
/// 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.
|
/// This keeps track of the button previously used for alt/singletap logic.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
private int buttonIndex;
|
private int buttonIndex;
|
||||||
|
|
||||||
public OsuAutoReplay(Beatmap<OsuHitObject> beatmap)
|
public override Replay Generate()
|
||||||
: base(beatmap)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Initialise()
|
|
||||||
{
|
|
||||||
base.Initialise();
|
|
||||||
|
|
||||||
// Already superhuman, but still somewhat realistic
|
|
||||||
reactionTime = applyModsToRate(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void CreateAutoReplay()
|
|
||||||
{
|
{
|
||||||
buttonIndex = 0;
|
buttonIndex = 0;
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < beatmap.HitObjects.Count; i++)
|
for (int i = 0; i < Beatmap.HitObjects.Count; i++)
|
||||||
{
|
{
|
||||||
OsuHitObject h = beatmap.HitObjects[i];
|
OsuHitObject h = Beatmap.HitObjects[i];
|
||||||
|
|
||||||
if (DelayedMovements && i > 0)
|
if (DelayedMovements && i > 0)
|
||||||
{
|
{
|
||||||
OsuHitObject prev = beatmap.HitObjects[i - 1];
|
OsuHitObject prev = Beatmap.HitObjects[i - 1];
|
||||||
addDelayedMovements(h, prev);
|
addDelayedMovements(h, prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
addHitObjectReplay(h);
|
addHitObjectReplay(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Replay;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDelayedMovements(OsuHitObject h, OsuHitObject prev)
|
private void addDelayedMovements(OsuHitObject h, OsuHitObject prev)
|
||||||
@ -119,9 +121,9 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
{
|
{
|
||||||
calcSpinnerStartPosAndDirection(Frames[Frames.Count - 1].Position, out startPosition, out spinnerDirection);
|
calcSpinnerStartPosAndDirection(Frames[Frames.Count - 1].Position, out startPosition, out spinnerDirection);
|
||||||
|
|
||||||
Vector2 spinCentreOffset = spinner_centre - Frames[Frames.Count - 1].Position;
|
Vector2 spinCentreOffset = SPINNER_CENTRE - Frames[Frames.Count - 1].Position;
|
||||||
|
|
||||||
if (spinCentreOffset.Length > spin_radius)
|
if (spinCentreOffset.Length > SPIN_RADIUS)
|
||||||
{
|
{
|
||||||
// If moving in from the outside, don't ease out (default eases out). This means auto will "start" spinning immediately after moving into position.
|
// If moving in from the outside, don't ease out (default eases out). This means auto will "start" spinning immediately after moving into position.
|
||||||
easing = EasingTypes.In;
|
easing = EasingTypes.In;
|
||||||
@ -139,19 +141,22 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
addHitObjectClickFrames(h, startPosition, spinnerDirection);
|
addHitObjectClickFrames(h, startPosition, spinnerDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Helper subroutines
|
||||||
|
|
||||||
private static void calcSpinnerStartPosAndDirection(Vector2 prevPos, out Vector2 startPosition, out float spinnerDirection)
|
private static void calcSpinnerStartPosAndDirection(Vector2 prevPos, out Vector2 startPosition, out float spinnerDirection)
|
||||||
{
|
{
|
||||||
Vector2 spinCentreOffset = spinner_centre - prevPos;
|
Vector2 spinCentreOffset = SPINNER_CENTRE - prevPos;
|
||||||
float distFromCentre = spinCentreOffset.Length;
|
float distFromCentre = spinCentreOffset.Length;
|
||||||
float distToTangentPoint = (float)Math.Sqrt(distFromCentre * distFromCentre - spin_radius * spin_radius);
|
float distToTangentPoint = (float)Math.Sqrt(distFromCentre * distFromCentre - SPIN_RADIUS * SPIN_RADIUS);
|
||||||
|
|
||||||
if (distFromCentre > spin_radius)
|
if (distFromCentre > SPIN_RADIUS)
|
||||||
{
|
{
|
||||||
// Previous cursor position was outside spin circle, set startPosition to the tangent point.
|
// Previous cursor position was outside spin circle, set startPosition to the tangent point.
|
||||||
|
|
||||||
// Angle between centre offset and tangent point offset.
|
// Angle between centre offset and tangent point offset.
|
||||||
float angle = (float)Math.Asin(spin_radius / distFromCentre);
|
float angle = (float)Math.Asin(SPIN_RADIUS / distFromCentre);
|
||||||
|
|
||||||
if (angle > 0)
|
if (angle > 0)
|
||||||
{
|
{
|
||||||
@ -176,13 +181,13 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
else if (spinCentreOffset.Length > 0)
|
else if (spinCentreOffset.Length > 0)
|
||||||
{
|
{
|
||||||
// Previous cursor position was inside spin circle, set startPosition to the nearest point on spin circle.
|
// Previous cursor position was inside spin circle, set startPosition to the nearest point on spin circle.
|
||||||
startPosition = spinner_centre - spinCentreOffset * (spin_radius / spinCentreOffset.Length);
|
startPosition = SPINNER_CENTRE - spinCentreOffset * (SPIN_RADIUS / spinCentreOffset.Length);
|
||||||
spinnerDirection = 1;
|
spinnerDirection = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Degenerate case where cursor position is exactly at the centre of the spin circle.
|
// Degenerate case where cursor position is exactly at the centre of the spin circle.
|
||||||
startPosition = spinner_centre + new Vector2(0, -spin_radius);
|
startPosition = SPINNER_CENTRE + new Vector2(0, -SPIN_RADIUS);
|
||||||
spinnerDirection = 1;
|
spinnerDirection = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,7 +288,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
{
|
{
|
||||||
Spinner s = h as Spinner;
|
Spinner s = h as Spinner;
|
||||||
|
|
||||||
Vector2 difference = startPosition - spinner_centre;
|
Vector2 difference = startPosition - SPINNER_CENTRE;
|
||||||
|
|
||||||
float radius = difference.Length;
|
float radius = difference.Length;
|
||||||
float angle = radius == 0 ? 0 : (float)Math.Atan2(difference.Y, difference.X);
|
float angle = radius == 0 ? 0 : (float)Math.Atan2(difference.Y, difference.X);
|
||||||
@ -294,12 +299,12 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
{
|
{
|
||||||
t = applyModsToTime(j - h.StartTime) * spinnerDirection;
|
t = applyModsToTime(j - h.StartTime) * spinnerDirection;
|
||||||
|
|
||||||
Vector2 pos = spinner_centre + circlePosition(t / 20 + angle, spin_radius);
|
Vector2 pos = SPINNER_CENTRE + circlePosition(t / 20 + angle, SPIN_RADIUS);
|
||||||
addFrameToReplay(new ReplayFrame((int)j, pos.X, pos.Y, button));
|
addFrameToReplay(new ReplayFrame((int)j, pos.X, pos.Y, button));
|
||||||
}
|
}
|
||||||
|
|
||||||
t = applyModsToTime(s.EndTime - h.StartTime) * spinnerDirection;
|
t = applyModsToTime(s.EndTime - h.StartTime) * spinnerDirection;
|
||||||
Vector2 endPosition = spinner_centre + circlePosition(t / 20 + angle, spin_radius);
|
Vector2 endPosition = SPINNER_CENTRE + circlePosition(t / 20 + angle, SPIN_RADIUS);
|
||||||
|
|
||||||
addFrameToReplay(new ReplayFrame(s.EndTime, endPosition.X, endPosition.Y, button));
|
addFrameToReplay(new ReplayFrame(s.EndTime, endPosition.X, endPosition.Y, button));
|
||||||
|
|
||||||
@ -323,5 +328,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
if (Frames[Frames.Count - 1].Time <= endFrame.Time)
|
if (Frames[Frames.Count - 1].Time <= endFrame.Time)
|
||||||
addFrameToReplay(endFrame);
|
addFrameToReplay(endFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,70 +2,52 @@
|
|||||||
// 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 OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.MathUtils;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
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.Rulesets.Replays;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Replays
|
namespace osu.Game.Rulesets.Osu.Replays
|
||||||
{
|
{
|
||||||
public abstract class OsuAutoReplayBase : Replay
|
public abstract class OsuAutoGeneratorBase : AutoGenerator<OsuHitObject>
|
||||||
{
|
{
|
||||||
#region Constants
|
#region Constants
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constants (for spinners).
|
/// Constants (for spinners).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected static readonly Vector2 spinner_centre = new Vector2(256, 192);
|
protected static readonly Vector2 SPINNER_CENTRE = new Vector2(256, 192);
|
||||||
protected const float spin_radius = 50;
|
protected const float SPIN_RADIUS = 50;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The beatmap we're making a replay out of.
|
|
||||||
/// </summary>
|
|
||||||
protected readonly Beatmap<OsuHitObject> beatmap;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time in ms between each ReplayFrame.
|
/// The time in ms between each ReplayFrame.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected double frameDelay;
|
protected readonly double frameDelay;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Construction
|
#region Construction / Initialisation
|
||||||
|
|
||||||
public OsuAutoReplayBase(Beatmap<OsuHitObject> beatmap)
|
protected Replay Replay;
|
||||||
|
protected List<ReplayFrame> Frames => Replay.Frames;
|
||||||
|
|
||||||
|
protected OsuAutoGeneratorBase(Beatmap<OsuHitObject> beatmap)
|
||||||
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
this.beatmap = beatmap;
|
Replay = new Replay
|
||||||
Initialise();
|
|
||||||
CreateAutoReplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initialise this instance. Called before CreateAutoReplay.
|
|
||||||
/// </summary>
|
|
||||||
protected virtual void Initialise()
|
|
||||||
{
|
{
|
||||||
User = new User
|
User = new User
|
||||||
{
|
{
|
||||||
Username = @"Autoplay",
|
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.
|
// 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);
|
frameDelay = applyModsToRate(1000.0 / 60.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates the auto replay. Every OsuAutoReplayBase subclass should implement this!
|
|
||||||
/// </summary>
|
|
||||||
protected abstract void CreateAutoReplay();
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Utilities
|
#region Utilities
|
@ -82,8 +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\OsuAutoGenerator.cs" />
|
||||||
<Compile Include="Replays\OsuAutoReplayBase.cs" />
|
<Compile Include="Replays\OsuAutoGeneratorBase.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
|
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
|
||||||
|
@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
protected override Score CreateReplayScore(Beatmap<TaikoHitObject> beatmap) => new Score
|
protected override Score CreateReplayScore(Beatmap<TaikoHitObject> beatmap) => new Score
|
||||||
{
|
{
|
||||||
User = new User { Username = "mekkadosu!" },
|
User = new User { Username = "mekkadosu!" },
|
||||||
Replay = new TaikoAutoReplay(beatmap)
|
Replay = new TaikoAutoReplay(beatmap).Generate(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// 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 System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
@ -9,29 +10,28 @@ using osu.Game.Rulesets.Replays;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Replays
|
namespace osu.Game.Rulesets.Taiko.Replays
|
||||||
{
|
{
|
||||||
public class TaikoAutoReplay : Replay
|
public class TaikoAutoReplay : AutoGenerator<TaikoHitObject>
|
||||||
{
|
{
|
||||||
private const double swell_hit_speed = 50;
|
private const double swell_hit_speed = 50;
|
||||||
|
|
||||||
private readonly Beatmap<TaikoHitObject> beatmap;
|
|
||||||
|
|
||||||
public TaikoAutoReplay(Beatmap<TaikoHitObject> beatmap)
|
public TaikoAutoReplay(Beatmap<TaikoHitObject> beatmap)
|
||||||
|
: base(beatmap)
|
||||||
{
|
{
|
||||||
this.beatmap = beatmap;
|
|
||||||
|
|
||||||
createAutoReplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAutoReplay()
|
protected Replay Replay;
|
||||||
|
protected List<ReplayFrame> Frames => Replay.Frames;
|
||||||
|
|
||||||
|
public override Replay Generate()
|
||||||
{
|
{
|
||||||
bool hitButton = true;
|
bool hitButton = true;
|
||||||
|
|
||||||
Frames.Add(new ReplayFrame(-100000, null, null, ReplayButtonState.None));
|
Frames.Add(new ReplayFrame(-100000, null, null, ReplayButtonState.None));
|
||||||
Frames.Add(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, null, null, ReplayButtonState.None));
|
Frames.Add(new ReplayFrame(Beatmap.HitObjects[0].StartTime - 1000, null, null, ReplayButtonState.None));
|
||||||
|
|
||||||
for (int i = 0; i < beatmap.HitObjects.Count; i++)
|
for (int i = 0; i < Beatmap.HitObjects.Count; i++)
|
||||||
{
|
{
|
||||||
TaikoHitObject h = beatmap.HitObjects[i];
|
TaikoHitObject h = Beatmap.HitObjects[i];
|
||||||
|
|
||||||
ReplayButtonState button;
|
ReplayButtonState button;
|
||||||
|
|
||||||
@ -105,15 +105,17 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
|||||||
|
|
||||||
Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, null, null, ReplayButtonState.None));
|
Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, null, null, ReplayButtonState.None));
|
||||||
|
|
||||||
if (i < beatmap.HitObjects.Count - 1)
|
if (i < Beatmap.HitObjects.Count - 1)
|
||||||
{
|
{
|
||||||
double waitTime = beatmap.HitObjects[i + 1].StartTime - 1000;
|
double waitTime = Beatmap.HitObjects[i + 1].StartTime - 1000;
|
||||||
if (waitTime > endTime)
|
if (waitTime > endTime)
|
||||||
Frames.Add(new ReplayFrame(waitTime, null, null, ReplayButtonState.None));
|
Frames.Add(new ReplayFrame(waitTime, null, null, ReplayButtonState.None));
|
||||||
}
|
}
|
||||||
|
|
||||||
hitButton = !hitButton;
|
hitButton = !hitButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Replay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
osu.Game/Rulesets/Replays/AutoGenerator.cs
Normal file
36
osu.Game/Rulesets/Replays/AutoGenerator.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Replays
|
||||||
|
{
|
||||||
|
public abstract class AutoGenerator<T> : IAutoGenerator
|
||||||
|
where T : HitObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the auto replay and returns it.
|
||||||
|
/// Every subclass of OsuAutoGeneratorBase should implement this!
|
||||||
|
/// </summary>
|
||||||
|
public abstract Replay Generate();
|
||||||
|
|
||||||
|
#region Parameters
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The beatmap we're making.
|
||||||
|
/// </summary>
|
||||||
|
protected Beatmap<T> Beatmap;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public AutoGenerator(Beatmap<T> beatmap)
|
||||||
|
{
|
||||||
|
Beatmap = beatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Constants
|
||||||
|
|
||||||
|
// Shared amongst all modes
|
||||||
|
protected const double KEY_UP_DELAY = 50;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
9
osu.Game/Rulesets/Replays/IAutoGenerator.cs
Normal file
9
osu.Game/Rulesets/Replays/IAutoGenerator.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
|
namespace osu.Game
|
||||||
|
{
|
||||||
|
public interface IAutoGenerator
|
||||||
|
{
|
||||||
|
Replay Generate();
|
||||||
|
}
|
||||||
|
}
|
@ -8,8 +8,6 @@ namespace osu.Game.Rulesets.Replays
|
|||||||
{
|
{
|
||||||
public class Replay
|
public class Replay
|
||||||
{
|
{
|
||||||
protected const double KEY_UP_DELAY = 50;
|
|
||||||
|
|
||||||
public User User;
|
public User User;
|
||||||
|
|
||||||
public List<ReplayFrame> Frames = new List<ReplayFrame>();
|
public List<ReplayFrame> Frames = new List<ReplayFrame>();
|
||||||
|
@ -421,6 +421,8 @@
|
|||||||
<Compile Include="Screens\Select\BeatmapDetailArea.cs" />
|
<Compile Include="Screens\Select\BeatmapDetailArea.cs" />
|
||||||
<Compile Include="Graphics\UserInterface\OsuTabControlCheckbox.cs" />
|
<Compile Include="Graphics\UserInterface\OsuTabControlCheckbox.cs" />
|
||||||
<Compile Include="Screens\Select\BeatmapDetailAreaTabControl.cs" />
|
<Compile Include="Screens\Select\BeatmapDetailAreaTabControl.cs" />
|
||||||
|
<Compile Include="Rulesets\Replays\IAutoGenerator.cs" />
|
||||||
|
<Compile Include="Rulesets\Replays\AutoGenerator.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="$(SolutionDir)\osu-framework\osu.Framework\osu.Framework.csproj">
|
<ProjectReference Include="$(SolutionDir)\osu-framework\osu.Framework\osu.Framework.csproj">
|
||||||
|
Loading…
Reference in New Issue
Block a user