2018-01-05 19:21:19 +08:00
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
2017-04-28 23:19:15 +08:00
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK ;
using osu.Game.Beatmaps ;
using osu.Game.Rulesets.Osu.Objects ;
using System ;
using System.Collections.Generic ;
using osu.Game.Rulesets.Replays ;
using osu.Game.Users ;
namespace osu.Game.Rulesets.Osu.Replays
{
2017-04-29 02:08:48 +08:00
public abstract class OsuAutoGeneratorBase : AutoGenerator < OsuHitObject >
2017-04-28 23:19:15 +08:00
{
#region Constants
/// <summary>
/// Constants (for spinners).
/// </summary>
2017-04-29 02:08:48 +08:00
protected static readonly Vector2 SPINNER_CENTRE = new Vector2 ( 256 , 192 ) ;
protected const float SPIN_RADIUS = 50 ;
2017-04-28 23:19:15 +08:00
/// <summary>
/// The time in ms between each ReplayFrame.
/// </summary>
2017-04-29 02:30:34 +08:00
protected readonly double FrameDelay ;
2017-04-28 23:19:15 +08:00
#endregion
2017-04-29 02:08:48 +08:00
#region Construction / Initialisation
2017-04-28 23:19:15 +08:00
2017-04-29 02:08:48 +08:00
protected Replay Replay ;
protected List < ReplayFrame > Frames = > Replay . Frames ;
2017-04-28 23:19:15 +08:00
2017-04-29 02:08:48 +08:00
protected OsuAutoGeneratorBase ( Beatmap < OsuHitObject > beatmap )
: base ( beatmap )
2017-04-29 00:15:53 +08:00
{
2017-04-29 02:08:48 +08:00
Replay = new Replay
2017-04-29 00:15:53 +08:00
{
2017-04-29 02:08:48 +08:00
User = new User
{
Username = @"Autoplay" ,
}
2017-04-29 00:15:53 +08:00
} ;
2017-04-28 23:19:15 +08:00
// 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.
2017-04-29 02:30:34 +08:00
FrameDelay = ApplyModsToRate ( 1000.0 / 60.0 ) ;
2017-04-28 23:19:15 +08:00
}
#endregion
#region Utilities
2017-04-29 02:30:34 +08:00
protected double ApplyModsToTime ( double v ) = > v ;
protected double ApplyModsToRate ( double v ) = > v ;
2017-04-28 23:19:15 +08:00
private class ReplayFrameComparer : IComparer < ReplayFrame >
{
public int Compare ( ReplayFrame f1 , ReplayFrame f2 )
{
2017-05-07 00:38:17 +08:00
if ( f1 = = null ) throw new ArgumentNullException ( nameof ( f1 ) ) ;
if ( f2 = = null ) throw new ArgumentNullException ( nameof ( f2 ) ) ;
2017-04-28 23:19:15 +08:00
return f1 . Time . CompareTo ( f2 . Time ) ;
}
}
private static readonly IComparer < ReplayFrame > replay_frame_comparer = new ReplayFrameComparer ( ) ;
2017-04-29 02:30:34 +08:00
protected int FindInsertionIndex ( ReplayFrame frame )
2017-04-28 23:19:15 +08:00
{
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 ;
}
2017-04-29 02:30:34 +08:00
protected void AddFrameToReplay ( ReplayFrame frame ) = > Frames . Insert ( FindInsertionIndex ( frame ) , frame ) ;
2017-04-28 23:19:15 +08:00
2017-04-29 02:30:34 +08:00
protected static Vector2 CirclePosition ( double t , double radius ) = > new Vector2 ( ( float ) ( Math . Cos ( t ) * radius ) , ( float ) ( Math . Sin ( t ) * radius ) ) ;
2017-04-28 23:19:15 +08:00
#endregion
}
}