Add some judge functions. Code cleanup.

This commit is contained in:
2022-11-14 13:59:26 +08:00
parent 49431e888c
commit 1f57c299a2
3 changed files with 116 additions and 39 deletions

View File

@@ -284,21 +284,15 @@ namespace Cryville.Crtr {
} }
// Adopted from System.Collections.Generic.ArraySortHelper<T>.InternalBinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer) // Adopted from System.Collections.Generic.ArraySortHelper<T>.InternalBinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer)
internal int BinarySearch(float value) { int BinarySearch(float value) {
int num = 0; int num = 0;
int num2 = RelativeNodes.Count - 1; int num2 = RelativeNodes.Count - 1;
while (num <= num2) { while (num <= num2) {
int num3 = num + (num2 - num >> 1); int num3 = num + (num2 - num >> 1);
int num4 = RelativeNodes[num3].Time.Value.CompareTo(value); int num4 = RelativeNodes[num3].Time.Value.CompareTo(value);
if (num4 == 0) { if (num4 == 0) return num3;
return num3; if (num4 < 0) num = num3 + 1;
} else num2 = num3 - 1;
if (num4 < 0) {
num = num3 + 1;
}
else {
num2 = num3 - 1;
}
} }
return ~num; return ~num;
} }

View File

@@ -134,6 +134,11 @@ namespace Cryville.Crtr {
_ctxops.Add(IdentifierManager.SharedInstance.Request("min"), new func_min(() => ContextSelfValue)); _ctxops.Add(IdentifierManager.SharedInstance.Request("min"), new func_min(() => ContextSelfValue));
_ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue)); _ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue));
_ctxops.Add(IdentifierManager.SharedInstance.Request("abs"), new func_abs(() => ContextSelfValue)); _ctxops.Add(IdentifierManager.SharedInstance.Request("abs"), new func_abs(() => ContextSelfValue));
Func<int, PropSrc> cccb = k => ContextCascadeLookup(k);
_ctxops.Add(IdentifierManager.SharedInstance.Request("attack_timing"), new func_attack_timing(cccb));
_ctxops.Add(IdentifierManager.SharedInstance.Request("enter_timing"), new func_enter_timing(cccb));
_ctxops.Add(IdentifierManager.SharedInstance.Request("release_timing"), new func_release_timing(cccb));
} }
static PdtEvaluator() { static PdtEvaluator() {
_shortops.Add(new PdtOperatorSignature("@", 2), new op_at_2()); _shortops.Add(new PdtOperatorSignature("@", 2), new op_at_2());
@@ -158,6 +163,7 @@ namespace Cryville.Crtr {
} }
#region Operators #region Operators
#pragma warning disable IDE1006 #pragma warning disable IDE1006
#region Basic Operators
class op_add_1 : PdtOperator { class op_add_1 : PdtOperator {
public op_add_1() : base(1) { } public op_add_1() : base(1) { }
protected override void Execute() { protected override void Execute() {
@@ -273,6 +279,8 @@ namespace Cryville.Crtr {
else throw new InvalidOperationException("Not a vector or number"); else throw new InvalidOperationException("Not a vector or number");
} }
} }
#endregion
#region Basic Functions
class func_frame_seq : PdtOperator { class func_frame_seq : PdtOperator {
public func_frame_seq() : base(3) { } public func_frame_seq() : base(3) { }
protected override unsafe void Execute() { protected override unsafe void Execute() {
@@ -303,6 +311,39 @@ namespace Cryville.Crtr {
} }
} }
} }
class func_in_area : PdtOperator {
public func_in_area() : base(1) { }
protected override unsafe void Execute() {
var arg = GetOperand(0);
if (arg.Type == PdtInternalType.Error) {
throw new InvalidOperationException("Error");
}
else if (arg.Type == PdtInternalType.Number && arg.AsNumber() <= 0) {
GetReturnFrame(PdtInternalType.Null, 0);
}
else {
var ret = GetReturnFrame(arg.Type, arg.Length);
arg.CopyTo(ret);
}
}
}
class func_int_map : PdtOperator {
public func_int_map(int pc) : base(pc) {
if (pc < 4) throw new ArgumentOutOfRangeException("Too few parameters for int_map");
}
protected override unsafe void Execute() {
var value = GetOperand(0).AsNumber();
var offset = GetOperand(1).AsNumber();
var step = GetOperand(2).AsNumber();
var index = (int)((value - offset) / step);
if (index < 0 || index >= LoadedOperandCount - 3) index = 0;
var hit = GetOperand(index + 3);
var ret = GetReturnFrame(hit.Type, hit.Length);
hit.CopyTo(ret);
}
}
#endregion
#region Contextual Functions
class func_screen_edge : PdtOperator { class func_screen_edge : PdtOperator {
readonly Func<Transform> _ctxcb; readonly Func<Transform> _ctxcb;
public func_screen_edge(Func<Transform> ctxcb) : base(1) { public func_screen_edge(Func<Transform> ctxcb) : base(1) {
@@ -408,41 +449,61 @@ namespace Cryville.Crtr {
ret.SetNumber(Mathf.Abs(arg)); ret.SetNumber(Mathf.Abs(arg));
} }
} }
class func_in_area : PdtOperator { #endregion
public func_in_area() : base(1) { } #region Judge Functions
protected override unsafe void Execute() { static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
var arg = GetOperand(0); static readonly int _var_tn = IdentifierManager.SharedInstance.Request("tn");
if (arg.Type == PdtInternalType.Error) { static readonly int _var_ft = IdentifierManager.SharedInstance.Request("ft");
throw new InvalidOperationException("Error"); static readonly int _var_tt = IdentifierManager.SharedInstance.Request("tt");
} static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
else if (arg.Type == PdtInternalType.Number && arg.AsNumber() <= 0) { static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv");
GetReturnFrame(PdtInternalType.Null, 0); abstract class JudgeFunction : PdtOperator {
} readonly Func<int, PropSrc> _ctxcb;
else { protected JudgeFunction(int pc, Func<int, PropSrc> ctxcb) : base(pc) {
var ret = GetReturnFrame(arg.Type, arg.Length); _ctxcb = ctxcb;
arg.CopyTo(ret); }
} protected sealed override void Execute() {
var ret = GetReturnFrame(PdtInternalType.Number, sizeof(float));
var fn = oputil.AsNumber(_ctxcb(_var_fn));
var tn = oputil.AsNumber(_ctxcb(_var_tn));
var ft = oputil.AsNumber(_ctxcb(_var_ft));
var tt = oputil.AsNumber(_ctxcb(_var_tt));
var fv = oputil.AsVector(_ctxcb(_var_fv));
var tv = oputil.AsVector(_ctxcb(_var_tv));
ret.SetNumber(ExecuteImpl(fn, tn, ft, tt, fv, tv) ? 1 : 0);
}
protected abstract bool ExecuteImpl(float fn, float tn, float ft, float tt, Vector3? fv, Vector3? tv);
}
class func_attack_timing : JudgeFunction {
public func_attack_timing(Func<int, PropSrc> ctxcb) : base(2, ctxcb) { }
protected override bool ExecuteImpl(float fn, float tn, float ft, float tt, Vector3? fv, Vector3? tv) {
if (fv != null) return false;
var t0 = GetOperand(0).AsNumber() + fn;
var t1 = GetOperand(1).AsNumber() + tn;
return tt > t0 && tt <= t1;
} }
} }
class func_int_map : PdtOperator { class func_enter_timing : JudgeFunction {
public func_int_map(int pc) : base(pc) { public func_enter_timing(Func<int, PropSrc> ctxcb) : base(1, ctxcb) { }
if (pc < 4) throw new ArgumentOutOfRangeException("Too few parameters for int_map"); protected override bool ExecuteImpl(float fn, float tn, float ft, float tt, Vector3? fv, Vector3? tv) {
} if (fv == null || tv == null) return false;
protected override unsafe void Execute() { var t0 = GetOperand(0).AsNumber() + fn;
var value = GetOperand(0).AsNumber(); return ft < t0 && tt >= t0;
var offset = GetOperand(1).AsNumber();
var step = GetOperand(2).AsNumber();
var index = (int)((value - offset) / step);
if (index < 0 || index >= LoadedOperandCount - 3) index = 0;
var hit = GetOperand(index + 3);
var ret = GetReturnFrame(hit.Type, hit.Length);
hit.CopyTo(ret);
} }
} }
class func_release_timing : JudgeFunction {
public func_release_timing(Func<int, PropSrc> ctxcb) : base(2, ctxcb) { }
protected override bool ExecuteImpl(float fn, float tn, float ft, float tt, Vector3? fv, Vector3? tv) {
if (tv != null) return false;
var t0 = GetOperand(0).AsNumber() + fn;
var t1 = GetOperand(1).AsNumber() + tn;
return ft > t0 && ft <= t1;
}
}
#endregion
unsafe static class oputil { unsafe static class oputil {
public static float AsNumber(PropSrc src) { public static float AsNumber(PropSrc src) {
if (src == null) if (src == null) throw new ArgumentNullException("src");
throw new ArgumentNullException("src");
int type; byte[] value; int type; byte[] value;
src.Get(out type, out value); src.Get(out type, out value);
if (type != PdtInternalType.Number) if (type != PdtInternalType.Number)
@@ -451,6 +512,25 @@ namespace Cryville.Crtr {
return *(float*)ptr; return *(float*)ptr;
} }
} }
public static Vector3? AsVector(PropSrc src) {
if (src == null) throw new ArgumentNullException("src");
int type; byte[] value;
src.Get(out type, out value);
if (type == PdtInternalType.Vector) {
fixed (byte* ptr = value) {
return *(Vector3*)ptr;
}
}
else if (type == PdtInternalType.Number) {
fixed (byte* ptr = value) {
return new Vector3(*(float*)ptr, 0, 0);
}
}
else if (type == PdtInternalType.Null) {
return null;
}
else throw new ArgumentException("Not a number");
}
} }
#pragma warning restore IDE1006 #pragma warning restore IDE1006
#endregion #endregion

View File

@@ -37,3 +37,6 @@ using System.Diagnostics.CodeAnalysis;
// Index operator not supported // Index operator not supported
[assembly: SuppressMessage("Style", "IDE0056")] [assembly: SuppressMessage("Style", "IDE0056")]
// Local function not supported
[assembly: SuppressMessage("Style", "IDE0039")]