Add state-based effect.

This commit is contained in:
2023-03-01 00:37:22 +08:00
parent dfc3e9ca06
commit ba3cbbd64c
4 changed files with 92 additions and 27 deletions

View File

@@ -1,5 +1,6 @@
using Cryville.Common;
using Cryville.Crtr.Components;
using Cryville.Crtr.Event;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -25,6 +26,7 @@ namespace Cryville.Crtr {
_durationOp = new PropOp.Float(v => _duration = v);
}
public void Rewind(double time) {
_startTime = time;
foreach (var i in _comps) i.Rewind(time);
}
private float m_index;
@@ -36,6 +38,10 @@ namespace Cryville.Crtr {
_indexSrc.Invalidate();
}
}
Identifier _currentStateName = Identifier.Empty;
EffectState _currentState;
ChartEvent _ctxev;
ContainerState _ctxstate;
internal static readonly int _VAR_EFFECT_INDEX = IdentifierManager.SharedInstance.Request("effect_index");
readonly PropSrc _indexSrc;
double _startTime;
@@ -45,17 +51,47 @@ namespace Cryville.Crtr {
public void Tick(double time) {
foreach (var i in _comps) i.Tick(_skinContainer, time);
}
public bool CanEmit() {
return _currentStateName.Key == 0 || _currentState.rewind.Key != 0;
}
public void OnEmit(double time) {
_startTime = time;
_ctxev = ChartPlayer.etor.ContextEvent;
_ctxstate = ChartPlayer.etor.ContextState;
if (_currentStateName.Key == 0) {
EnterState(_def.init, time, true);
}
else {
if (_currentState.rewind.Key == 0) throw new InvalidOperationException("Cannot rewind");
EnterState(_currentState.rewind, time, true);
}
}
void EnterState(Identifier name, double time, bool emitting) {
_currentStateName = name;
_currentState = _def.states[name];
Rewind(time);
RootTransform.gameObject.SetActive(true);
ChartPlayer.etor.ContextCascadeInsert();
ChartPlayer.etor.ContextCascadeUpdate(_VAR_EFFECT_INDEX, _indexSrc);
ChartPlayer.etor.Evaluate(_durationOp, _def.duration);
_skinContainer.MatchDynamic(0);
ChartPlayer.etor.Evaluate(_durationOp, _currentState.duration);
if (emitting) _skinContainer.MatchDynamic(0);
_skinContainer.MatchDynamic(1);
ChartPlayer.etor.ContextCascadeDiscard();
}
public void OnDone() {
RootTransform.gameObject.SetActive(false);
public bool OnStateDone() {
if (_currentState.next.Key == 0) {
RootTransform.gameObject.SetActive(false);
_currentStateName = Identifier.Empty;
_currentState = null;
return false;
}
else {
ChartPlayer.etor.ContextEvent = _ctxev;
ChartPlayer.etor.ContextState = _ctxstate;
EnterState(_currentState.next, EndTime, false);
ChartPlayer.etor.ContextEvent = null;
ChartPlayer.etor.ContextState = null;
return true;
}
}
public void Dispose() {
GameObject.Destroy(RootTransform.gameObject);
@@ -63,7 +99,7 @@ namespace Cryville.Crtr {
public string TypeName { get { throw new InvalidOperationException("Type name undefined"); } }
public SkinContext SkinContext { get; private set; }
public int OpenedAnchorName { get { throw new InvalidOperationException("Anchor not supported"); } }
public int OpenedAnchorName { get { return _currentStateName.Key; } }
public void PushAnchorEvent(double time, int name) {
throw new InvalidOperationException("Anchor not supported");
}