Skip to content

Commit 62f3067

Browse files
committed
Made it so 't' variable actually works. Continuous easing is now a thing to support it.
1 parent 7502e0a commit 62f3067

1 file changed

Lines changed: 52 additions & 25 deletions

File tree

Sequence/Sequence.js

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ var Sequence = Sequence || (() => {
678678

679679
const validateEasingExpr = (expr) => {
680680
if (!expr || !expr.trim()) return null;
681+
if (expr.trim() === 'continuous') return null; // special keyword — not a curve
681682
const token = parseEasingToken(expr.trim());
682683
if (!token) return `Could not parse easing expression: "${expr}"`;
683684
if (!EASING[token.name]) return `Unknown easing curve: "${token.name}"`;
@@ -975,6 +976,7 @@ var Sequence = Sequence || (() => {
975976
return node.apply(null, [_ctx].concat(args));
976977
};
977978
}
979+
if (node === null || typeof node !== 'object') return node;
978980
var wrapped = {};
979981
Object.keys(node).forEach(function(k) {
980982
wrapped[k] = _wrapNode(node[k]);
@@ -1490,6 +1492,18 @@ var Sequence = Sequence || (() => {
14901492
description: 'Transparent (no tint)',
14911493
});
14921494

1495+
// ── Math constants ────────────────────────────────────────────────────────
1496+
registerPlaybackConstant(SCRIPT_NAME, {
1497+
name: 'PI', namespace: 'core', type: 'number',
1498+
value: Math.PI,
1499+
description: 'π (3.14159…)',
1500+
});
1501+
registerPlaybackConstant(SCRIPT_NAME, {
1502+
name: 'TAU', namespace: 'core', type: 'number',
1503+
value: Math.PI * 2,
1504+
description: '2π (6.28318…) — one full rotation in radians.',
1505+
});
1506+
14931507
// Pre-built query strings for handout dropdown buttons
14941508
// Escape a string for use inside a nested Roll20 ?{} query that is itself
14951509
const EASING_QUERY = () => {
@@ -2873,42 +2887,55 @@ var Sequence = Sequence || (() => {
28732887
// Resolve expression if needed to get the target value
28742888
let nextParsed = nextKf.deltas[attrName];
28752889
if (nextParsed && nextParsed.expr) {
2890+
const srcEasing = prevIdx >= 0 && kfs[prevIdx].easings && kfs[prevIdx].easings[attrName]
2891+
? kfs[prevIdx].easings[attrName]
2892+
: (pb.currentEasings[attrName] || pb.easing || 'linear');
2893+
const isContinuous = srcEasing === 'continuous';
28762894
const orig = pb.initialState[attrName] !== undefined ? pb.initialState[attrName] : 0;
28772895
const prev = prevAbsState[attrName] !== undefined ? prevAbsState[attrName] : orig;
2878-
// curr fetched lazily inside evalExpr via reg+obj
28792896
try {
28802897
const val = evalExpr(nextParsed.expr, orig, prev, undefined,
28812898
{ obj, reg, t: tNorm, cumulative: pb.cumulative || {} });
2882-
nextParsed = nextParsed.mode === 'abs' ? { abs: val }
2899+
let resolved = nextParsed.mode === 'abs' ? { abs: val }
28832900
: nextParsed.mode === 'mul' ? { delta: val }
28842901
: { delta: (nextParsed.sign || 1) * val };
2885-
// Cache the resolved value so all ticks in this segment agree
2886-
if (!pb.resolvedExprs) pb.resolvedExprs = {};
2887-
const key = `${nextIdx}:${attrName}`;
2888-
if (!(key in pb.resolvedExprs)) pb.resolvedExprs[key] = nextParsed;
2889-
nextParsed = pb.resolvedExprs[key];
2902+
if (isContinuous) {
2903+
// Continuous: use resolved value directly, no lerp, no cache
2904+
const shadow = makeShadow(prevAbsState);
2905+
if ('abs' in resolved) reg.set(shadow, resolved.abs);
2906+
else if ('delta' in resolved) reg.apply(shadow, resolved.delta);
2907+
interpolated = shadow._state[attrName];
2908+
} else {
2909+
// Cache the resolved value so all ticks in this segment agree
2910+
if (!pb.resolvedExprs) pb.resolvedExprs = {};
2911+
const key = `${nextIdx}:${attrName}`;
2912+
if (!(key in pb.resolvedExprs)) pb.resolvedExprs[key] = resolved;
2913+
nextParsed = pb.resolvedExprs[key];
2914+
}
28902915
} catch(e) {
28912916
log(`${SCRIPT_NAME}: lerp expr error for ${attrName}: ${e.message}`);
28922917
}
28932918
}
2894-
// Apply resolved delta to prevState shadow to get absolute nextVal
2895-
const shadow = makeShadow(prevAbsState);
2896-
if (nextParsed && 'abs' in nextParsed) reg.set(shadow, nextParsed.abs);
2897-
else if (nextParsed && 'delta' in nextParsed) reg.apply(shadow, nextParsed.delta);
2898-
const nextVal = shadow._state[attrName];
2899-
const prevTime = prevIdx >= 0
2900-
? (pb.resolvedTimes[prevIdx] !== undefined ? pb.resolvedTimes[prevIdx] : (typeof kfs[prevIdx].time === 'number' ? kfs[prevIdx].time : 0))
2901-
: 0;
2902-
const nextTime = pb.resolvedTimes[nextIdx] !== undefined
2903-
? pb.resolvedTimes[nextIdx]
2904-
: (typeof nextKf.time === 'number' ? nextKf.time : prevTime);
2905-
const segDur = nextTime - prevTime;
2906-
const segElapsed = t - prevTime;
2907-
const segT = segDur > 0 ? segElapsed / segDur : 1;
2908-
const srcEasing = prevIdx >= 0 && kfs[prevIdx].easings && kfs[prevIdx].easings[attrName]
2909-
? kfs[prevIdx].easings[attrName]
2910-
: (pb.currentEasings[attrName] || pb.easing || 'linear');
2911-
interpolated = reg.lerp(prevVal, nextVal, getEasing(srcEasing)(segT));
2919+
if (interpolated === undefined) {
2920+
// Normal lerp path (non-continuous expressions or non-expression deltas)
2921+
const shadow = makeShadow(prevAbsState);
2922+
if (nextParsed && 'abs' in nextParsed) reg.set(shadow, nextParsed.abs);
2923+
else if (nextParsed && 'delta' in nextParsed) reg.apply(shadow, nextParsed.delta);
2924+
const nextVal = shadow._state[attrName];
2925+
const prevTime = prevIdx >= 0
2926+
? (pb.resolvedTimes[prevIdx] !== undefined ? pb.resolvedTimes[prevIdx] : (typeof kfs[prevIdx].time === 'number' ? kfs[prevIdx].time : 0))
2927+
: 0;
2928+
const nextTime = pb.resolvedTimes[nextIdx] !== undefined
2929+
? pb.resolvedTimes[nextIdx]
2930+
: (typeof nextKf.time === 'number' ? nextKf.time : prevTime);
2931+
const segDur = nextTime - prevTime;
2932+
const segElapsed = t - prevTime;
2933+
const segT = segDur > 0 ? segElapsed / segDur : 1;
2934+
const lerpEasing = prevIdx >= 0 && kfs[prevIdx].easings && kfs[prevIdx].easings[attrName]
2935+
? kfs[prevIdx].easings[attrName]
2936+
: (pb.currentEasings[attrName] || pb.easing || 'linear');
2937+
interpolated = reg.lerp(prevVal, nextVal, getEasing(lerpEasing)(segT));
2938+
}
29122939
} else {
29132940
interpolated = prevVal;
29142941
}

0 commit comments

Comments
 (0)