155 lines
4.8 KiB
C#
155 lines
4.8 KiB
C#
using Cryville.Common;
|
|
using Cryville.Crtr.Ruleset;
|
|
using Cryville.Crtr.Skin.Components;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Cryville.Crtr.Event {
|
|
public class NoteHandler : ContainerHandler {
|
|
readonly GroupHandler gh;
|
|
readonly Chart.Note _note;
|
|
public NoteHandler(Chart.Note ev, GroupHandler gh) : base() {
|
|
_note = ev;
|
|
this.gh = gh;
|
|
}
|
|
|
|
public override string TypeName { get { return "note"; } }
|
|
|
|
SectionalGameObject[] sgos;
|
|
readonly Dictionary<Chart.Judge, JudgeState> judges = new();
|
|
class JudgeState {
|
|
static readonly int _var_judge_result = IdentifierManager.Shared.Request("judge_result");
|
|
static readonly int _var_judge_time_absolute = IdentifierManager.Shared.Request("judge_time_absolute");
|
|
static readonly int _var_judge_time_relative = IdentifierManager.Shared.Request("judge_time_relative");
|
|
public Anchor StaticAnchor { get; private set; }
|
|
readonly PropStores.Float _jtabsst = new();
|
|
readonly PropStores.Float _jtrelst = new();
|
|
readonly PropStores.Identifier _resultst = new();
|
|
public JudgeState(NoteHandler handler, int name) {
|
|
StaticAnchor = handler.RegisterAnchor(handler.judge.judgeMap[name], false, 3);
|
|
}
|
|
public void MarkJudged(float abs, float rel, int result) {
|
|
_jtabsst.Value = abs;
|
|
_jtrelst.Value = rel;
|
|
_resultst.Value = result;
|
|
}
|
|
public void InitPropSrcs() {
|
|
StaticAnchor.PropSrcs.Add(_var_judge_result, _resultst.Source);
|
|
StaticAnchor.PropSrcs.Add(_var_judge_time_absolute, _jtabsst.Source);
|
|
StaticAnchor.PropSrcs.Add(_var_judge_time_relative, _jtrelst.Source);
|
|
}
|
|
}
|
|
|
|
public override void PreInit() {
|
|
base.PreInit();
|
|
foreach (var j in _note.judges) {
|
|
judges.Add(j, new JudgeState(this, j.Id.Key));
|
|
}
|
|
}
|
|
public override void Init() {
|
|
base.Init();
|
|
sgos = RootTransform.GetComponentsInChildren<SectionalGameObject>();
|
|
foreach (var judge in judges) judge.Value.InitPropSrcs();
|
|
}
|
|
|
|
public override void StartPhysicalUpdate(ContainerState s) {
|
|
base.StartPhysicalUpdate(s);
|
|
if (s.CloneType == 2) {
|
|
TransformAwake(s);
|
|
}
|
|
}
|
|
protected override void StartGraphicalUpdate(ContainerState s) {
|
|
base.StartGraphicalUpdate(s);
|
|
TransformAwake(s);
|
|
if (RootTransform) {
|
|
if (_note.IsLong) {
|
|
foreach (var i in sgos) {
|
|
i.Reset();
|
|
i.AppendPoint(Position, Rotation);
|
|
}
|
|
}
|
|
else {
|
|
#if UNITY_5_6_OR_NEWER
|
|
RootTransform.SetPositionAndRotation(Position, Rotation);
|
|
#else
|
|
RootTransform.position = Position;
|
|
RootTransform.rotation = Rotation;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
void TransformAwake(ContainerState s) {
|
|
Position = GetFramePoint(s.Parent, s.Track);
|
|
Rotation = GetFrameRotation(s.Parent, s.Track);
|
|
}
|
|
|
|
public override void Update(ContainerState s, StampedEvent ev) {
|
|
if (s.CloneType <= 2) {
|
|
Position = GetFramePoint(s.Parent, s.Track);
|
|
Rotation = GetFrameRotation(s.Parent, s.Track);
|
|
if (s.CloneType == 2 && RootTransform && _note.IsLong) {
|
|
foreach (var i in sgos)
|
|
i.AppendPoint(Position, Rotation);
|
|
}
|
|
}
|
|
else if (s.CloneType == 16) {
|
|
if (ev == null) { }
|
|
else if (ev.Unstamped == null) { }
|
|
else if (ev.Unstamped is Chart.Judge) {
|
|
judge._etor.ContextEvent = ev.Unstamped;
|
|
judge._etor.ContextState = s;
|
|
judge.Prepare(ev, this);
|
|
judge._etor.ContextState = null;
|
|
judge._etor.ContextEvent = null;
|
|
}
|
|
}
|
|
if (s.CloneType == 2 && ev != null && ev.Unstamped is Chart.Judge) {
|
|
var anchor = judges[(Chart.Judge)ev.Unstamped].StaticAnchor;
|
|
#if UNITY_5_6_OR_NEWER
|
|
anchor.Transform.SetPositionAndRotation(Position, Rotation);
|
|
#else
|
|
anchor.Transform.position = Position;
|
|
anchor.Transform.rotation = Rotation;
|
|
#endif
|
|
OpenAnchor(anchor);
|
|
base.Update(s, ev);
|
|
CloseAnchor();
|
|
}
|
|
else base.Update(s, ev);
|
|
}
|
|
|
|
protected override void EndGraphicalUpdate(ContainerState s) {
|
|
if (RootTransform) {
|
|
foreach (var i in sgos) i.Seal();
|
|
}
|
|
base.EndGraphicalUpdate(s);
|
|
}
|
|
|
|
Vector3 GetFramePoint(ContainerState state, float track) {
|
|
return GetFrame(state, track, th => th.Handler.Position);
|
|
}
|
|
|
|
Quaternion GetFrameRotation(ContainerState state, float track) {
|
|
var r = GetFrame(state, track, th => th.Handler.Rotation * Vector3.forward);
|
|
return Quaternion.LookRotation(r, state.Normal);
|
|
}
|
|
|
|
Vector3 GetFrame(ContainerState state, float track, Func<ContainerState, Vector3> func) {
|
|
// TODO
|
|
int id = Mathf.FloorToInt(track);
|
|
if (track == id) {
|
|
var ts0 = state.GetChild(id, typeof(Chart.Track));
|
|
var p1 = func(ts0);
|
|
return p1;
|
|
}
|
|
return gh.GetCurrentFrame(func, track);
|
|
}
|
|
|
|
internal void ReportJudge(JudgeEvent ev, float time, Identifier result) {
|
|
if (!judges.TryGetValue(ev.BaseEvent, out JudgeState state)) return;
|
|
state.MarkJudged(time, (float)(ev.StartTime - time), result.Key);
|
|
}
|
|
}
|
|
}
|