218 lines
6.0 KiB
C#
218 lines
6.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Cryville.Crtr {
|
|
public abstract class StateBase<T> {
|
|
public int EventId;
|
|
public float Time;
|
|
public Chart chart;
|
|
public List<T> events;
|
|
|
|
bool breakflag = false;
|
|
|
|
public StateBase(Chart c, List<T> evs) {
|
|
chart = c;
|
|
events = evs;
|
|
EventId = 0;
|
|
/*float leadin = chart.BeatPosition;
|
|
Time = leadin * 60 / (float)c.sigs[0].tempo;*/
|
|
Time = 0;
|
|
}
|
|
|
|
public virtual StateBase<T> Clone() {
|
|
return (StateBase<T>)base.MemberwiseClone();
|
|
}
|
|
|
|
public virtual void CopyTo(StateBase<T> dest) {
|
|
dest.EventId = EventId;
|
|
dest.Time = Time;
|
|
dest.breakflag = breakflag;
|
|
}
|
|
|
|
public virtual void Break() {
|
|
breakflag = true;
|
|
}
|
|
|
|
public void Forward(Action<T> callback = null) {
|
|
ForwardToTime(float.PositiveInfinity, ev => {
|
|
if (callback != null)
|
|
callback(ev);
|
|
});
|
|
}
|
|
|
|
public void ForwardByTime(float time, Action<T> callback = null) {
|
|
ForwardToTime(Time + time, ev => {
|
|
if (callback != null)
|
|
callback(ev);
|
|
});
|
|
}
|
|
|
|
public void ForwardOnceByTime(float time, Action<T> callback = null) {
|
|
ForwardOnceToTime(Time + time, callback);
|
|
}
|
|
|
|
public void ForwardToTime(float toTime, Action<T> callback = null) {
|
|
breakflag = false;
|
|
ForwardOnceToTime(Time, callback);
|
|
while (Time < toTime) {
|
|
// if (Time == toTime) breakflag = true;
|
|
ForwardOnceToTime(toTime, callback);
|
|
if (breakflag) break;
|
|
}
|
|
}
|
|
|
|
public void ForwardStepByTime(float time, float step, Action<T> callback = null) {
|
|
ForwardStepToTime(Time + time, step, callback);
|
|
}
|
|
|
|
public void ForwardStepToTime(float toTime, float step, Action<T> callback = null) {
|
|
breakflag = false;
|
|
ForwardOnceToTime(Time, callback);
|
|
while (Time < toTime) {
|
|
float next = Time + step;
|
|
ForwardOnceToTime(next < toTime ? next : toTime, callback);
|
|
if (breakflag) break;
|
|
}
|
|
}
|
|
|
|
public abstract void ForwardOnceToTime(float toTime, Action<T> callback = null);
|
|
}
|
|
|
|
/*public abstract class ChartEventStateBase : StateBase<Chart.Event> {
|
|
public float Beat;
|
|
public float Tempo;
|
|
|
|
public bool Visible = false;
|
|
|
|
/*public Vector2 Point = Vector2.zero;
|
|
public Vector2 Point2 = Vector2.zero;
|
|
public Vector2 EndPoint = Vector2.zero;
|
|
public Chart.Rotation Direction = Chart.Rotation.Zero;
|
|
public Chart.Rotation Rotation = Chart.Rotation.Zero;
|
|
|
|
public PointMotion PointMotion = null;
|
|
public PointMotion Point2Motion = null;
|
|
public PointMotion EndPointMotion = null;
|
|
public RotationMotion DirectionMotion = null;
|
|
public RotationMotion RotationMotion = null;
|
|
|
|
Chart.Point pevp = Chart.Point.Zero;
|
|
Chart.Point pevp2 = Chart.Point.Zero;
|
|
Chart.Point pevep = Chart.Point.Zero;
|
|
Chart.Rotation pevd = Chart.Rotation.Zero;
|
|
Chart.Rotation pevr = Chart.Rotation.Zero;*
|
|
|
|
protected List<Chart.Motion> PlayingMotions = new List<Chart.Motion>();
|
|
protected Dictionary<string, MotionValue> Values = new Dictionary<string, MotionValue>();
|
|
|
|
bool breakflag = false;
|
|
|
|
public ChartEventStateBase(Chart c, IEnumerable<Chart.Event> evs) : base(c, evs.ToList()) {
|
|
float leadin = chart.leadin;
|
|
|
|
Tempo = (float)c.signs[0].tempo;
|
|
Beat = -leadin;
|
|
|
|
foreach (var ev in evs)
|
|
if (ev.duration > 0)
|
|
events.Add(ev.ReleaseEvent);
|
|
|
|
events.Sort((a, b) => a.BeatPosition.CompareTo(b.BeatPosition));
|
|
|
|
Values.Add("dir", new MotionValue(typeof(Vec1), 3));
|
|
Values.Add("rot", new MotionValue(typeof(Vec1), 3));
|
|
Values.Add("pdirz", new MotionValue(typeof(Vec1), 1));
|
|
Values.Add("protz", new MotionValue(typeof(Vec1), 1));
|
|
Values.Add("pivot", new MotionValue(typeof(Vec2), 2));
|
|
Values.Add("pt", new MotionValue(typeof(Vec2), 2));
|
|
Values.Add("pt2", new MotionValue(typeof(Vec2), 2));
|
|
Values.Add("visible", new MotionValue(typeof(Vec1), 1));
|
|
Values.Add("sv", new MotionValue(typeof(Vec1), 1));
|
|
Values.Add("tint", new MotionValue(typeof(Vec1), 3));
|
|
Values.Add("corner", new MotionValue(typeof(Vec1), 3));
|
|
Values.Add("ctrl", new MotionValue(typeof(Vec2), 2));
|
|
Values.Add("ctrlz", new MotionValue(typeof(Vec1), 1));
|
|
}
|
|
|
|
public override sealed void ForwardOnceToTime(float toTime, Action<Chart.Event> callback = null) {
|
|
float toBeat = Beat + (toTime - Time) * Tempo / 60f;
|
|
if (EventId >= events.Count)
|
|
goto return_ahead;
|
|
float ebeat = events[EventId].BeatPosition;
|
|
float etime = (ebeat - Beat) / Tempo * 60f + Time;
|
|
if (etime > toTime)
|
|
goto return_ahead;
|
|
var bunch = GetEventBunch();
|
|
Time = etime;
|
|
Beat = ebeat;
|
|
bool flag = false;
|
|
foreach (var ev in bunch) {
|
|
Handle(ev);
|
|
if (callback != null && ev.Priority >= 0) {
|
|
callback(ev);
|
|
flag = true;
|
|
}
|
|
}
|
|
if (callback != null && !flag) callback(bunch.First());
|
|
return;
|
|
return_ahead:
|
|
Time = toTime;
|
|
Beat = toBeat;
|
|
// UpdateMotions();
|
|
if (callback != null) callback(null);
|
|
}
|
|
|
|
protected virtual void Handle(Chart.Event ev) {
|
|
if (ev is Chart.Motion) {
|
|
var tev = (Chart.Motion)ev;
|
|
tev._initValues = Values;
|
|
PlayingMotions.Add(tev);
|
|
// UpdateMotions();
|
|
}
|
|
else if (ev is Chart.InstantEvent) {
|
|
var tev = (Chart.InstantEvent)ev;
|
|
if (tev.IsRelease) {
|
|
var nev = tev.Original;
|
|
if (nev is Chart.Motion) {
|
|
var tnev = (Chart.Motion)nev;
|
|
PlayingMotions.Remove(tnev);
|
|
}
|
|
}
|
|
}
|
|
EventId++;
|
|
}
|
|
|
|
/*void UpdateMotions() {
|
|
foreach (var m in PlayingMotions) {
|
|
var mv = m[Time];
|
|
}
|
|
/*if (PointMotion != null)
|
|
Point = PointMotion.Lerp(Time);
|
|
if (EndPointMotion != null)
|
|
EndPoint = EndPointMotion.Lerp(Time);
|
|
if (Point2Motion != null)
|
|
Point2 = Point2Motion.Lerp(Time);
|
|
if (DirectionMotion != null)
|
|
Direction = DirectionMotion.Lerp(Time);
|
|
if (RotationMotion != null)
|
|
Rotation = RotationMotion.Lerp(Time);
|
|
}*
|
|
|
|
IOrderedEnumerable<Chart.Event> GetEventBunch() {
|
|
float cbeat = events[EventId].BeatPosition;
|
|
int b = EventId;
|
|
while (events[b].BeatPosition == cbeat) {
|
|
b--;
|
|
if (b == -1) break;
|
|
}
|
|
int a = EventId;
|
|
while (events[a].BeatPosition == cbeat) {
|
|
a++;
|
|
if (a == events.Count) break;
|
|
}
|
|
return events.GetRange(b + 1, a - b - 1).OrderBy(ev => ev.Priority);
|
|
}
|
|
}*/
|
|
|
|
}
|