Add judge action fields on_hit and on_miss.

This commit is contained in:
2023-05-20 16:23:59 +08:00
parent d1b9b9607b
commit 25b4f3ccb7
5 changed files with 151 additions and 42 deletions

View File

@@ -20,6 +20,11 @@ namespace Cryville.Crtr {
public JudgeDefinition Definition { get; set; }
public NoteHandler Handler { get; set; }
}
public interface IJudge {
bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth);
void UpdateScore(ScoreOperation op, PdtExpression exp);
}
public class Judge : IJudge {
#region Data
readonly ChartPlayer _sys;
internal readonly PdtEvaluator _etor;
@@ -193,8 +198,7 @@ namespace Cryville.Crtr {
_numbuf2 = (float)hitEvent.EndTime; _numsrc2.Invalidate(); _etor.ContextCascadeUpdate(_var_tn, _numsrc2);
var def = hitEvent.Definition;
if (def == _judgePause) _sys.TogglePause();
if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(hitEvent, (ft + tt) / 2, def.pass);
if (def.on_hit != null) Execute(hitEvent, (ft + tt) / 2, def.on_hit);
if (def.persist != null) _etor.Evaluate(_flagop, def.persist);
else _flag = false;
if (!_flag) {
@@ -209,21 +213,6 @@ namespace Cryville.Crtr {
}
}
}
bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth = 0) {
if (depth >= 16) throw new JudgePropagationException();
foreach (var i in ids) {
var def = _rs.judges.Judges[i];
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
else _flag = true;
if (_flag) {
if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(ev, time, def.pass, depth + 1);
ev.Handler.ReportJudge(ev, time, i);
return true;
}
}
return false;
}
public void Cleanup(Identifier target, float tt) {
lock (_etor) {
Forward(target, tt);
@@ -232,7 +221,7 @@ namespace Cryville.Crtr {
JudgeEvent ev = actlist[i];
if (tt > ev.EndClip) {
actlist.RemoveAt(i);
if (ev.Definition.miss != null) Pass(ev, tt, ev.Definition.miss);
if (ev.Definition.on_miss != null) Execute(ev, tt, ev.Definition.on_miss);
}
}
}
@@ -248,18 +237,34 @@ namespace Cryville.Crtr {
actlist.Insert(index, ev);
}
}
void UpdateScore(PairList<ScoreOperation, PdtExpression> scoreops) {
foreach (var scoreop in scoreops) {
var key = scoreop.Key;
_etor.ContextSelfValue = scoreSrcs[key.name.Key];
_etor.Evaluate(scoreOps[key.name.Key], scoreop.Value);
InvalidateScore(key.name.Key);
foreach (var s in _rs.scores) {
if (s.Value.value != null) {
_etor.ContextSelfValue = scoreSrcs[s.Key.Key];
_etor.Evaluate(scoreOps[s.Key.Key], s.Value.value);
InvalidateScore(s.Key.Key);
}
void Execute(JudgeEvent ev, float time, PairList<JudgeAction, PdtExpression> actions, int depth = 0) {
foreach (var a in actions) {
if (a.Key.Execute(this, ev, time, a.Value, depth)) break;
}
}
bool IJudge.Pass(JudgeEvent ev, float time, Identifier[] ids, int depth) {
if (depth >= 16) throw new JudgePropagationException();
foreach (var i in ids) {
var def = _rs.judges.Judges[i];
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
else _flag = true;
if (_flag) {
if (def.on_hit != null) Execute(ev, time, def.on_hit, depth + 1);
ev.Handler.ReportJudge(ev, time, i);
return true;
}
}
return false;
}
void IJudge.UpdateScore(ScoreOperation op, PdtExpression exp) {
_etor.ContextSelfValue = scoreSrcs[op.name.Key];
_etor.Evaluate(scoreOps[op.name.Key], exp);
InvalidateScore(op.name.Key);
foreach (var s in _rs.scores) {
if (s.Value.value != null) {
_etor.ContextSelfValue = scoreSrcs[s.Key.Key];
_etor.Evaluate(scoreOps[s.Key.Key], s.Value.value);
InvalidateScore(s.Key.Key);
}
}
}