Update mechanic authoring persistence
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
type Predicate,
|
||||
type Reducer,
|
||||
type ScenarioInputDefinition,
|
||||
type ValueReference,
|
||||
} from './mechanic.js';
|
||||
|
||||
type DatabaseValue = string | number | bigint | boolean | null | undefined;
|
||||
@@ -257,6 +258,55 @@ function isNumericExpression(value: unknown): value is NumericExpression {
|
||||
);
|
||||
}
|
||||
|
||||
function resolveVariantExpression(
|
||||
value: unknown,
|
||||
variantValue: number,
|
||||
): NumericExpression | null {
|
||||
if (finite(value)) return value;
|
||||
if (!object(value)) return null;
|
||||
if ('ref' in value) {
|
||||
if (
|
||||
object(value.ref) &&
|
||||
value.ref.source === 'variant_value' &&
|
||||
Object.keys(value.ref).length === 1
|
||||
) {
|
||||
return variantValue;
|
||||
}
|
||||
return isValueReference(value.ref)
|
||||
? { ref: value.ref as ValueReference }
|
||||
: null;
|
||||
}
|
||||
if (value.op === 'floor') {
|
||||
const nested = resolveVariantExpression(value.value, variantValue);
|
||||
return nested === null ? null : { op: 'floor', value: nested };
|
||||
}
|
||||
if (value.op === 'clamp') {
|
||||
const nested = resolveVariantExpression(value.value, variantValue);
|
||||
const min = resolveVariantExpression(value.min, variantValue);
|
||||
const max = resolveVariantExpression(value.max, variantValue);
|
||||
return nested === null || min === null || max === null
|
||||
? null
|
||||
: { op: 'clamp', value: nested, min, max };
|
||||
}
|
||||
if (
|
||||
!['add', 'subtract', 'multiply', 'divide', 'min', 'max'].includes(
|
||||
String(value.op),
|
||||
)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const left = resolveVariantExpression(value.left, variantValue);
|
||||
const right = resolveVariantExpression(value.right, variantValue);
|
||||
return left === null || right === null
|
||||
? null
|
||||
: {
|
||||
op: value.op as
|
||||
'add' | 'subtract' | 'multiply' | 'divide' | 'min' | 'max',
|
||||
left,
|
||||
right,
|
||||
};
|
||||
}
|
||||
|
||||
function isPredicate(value: unknown): value is Predicate {
|
||||
if (!object(value) || typeof value.kind !== 'string') return false;
|
||||
if (value.kind === 'true') return true;
|
||||
@@ -673,11 +723,8 @@ function parseOutcome(
|
||||
) {
|
||||
errors.push(`${path} has an unsupported application phase.`);
|
||||
}
|
||||
let value: NumericExpression = requiredNumber(
|
||||
row.value,
|
||||
`${path} value`,
|
||||
errors,
|
||||
);
|
||||
const variantValue = requiredNumber(row.value, `${path} value`, errors);
|
||||
let value: NumericExpression = variantValue;
|
||||
if (
|
||||
row.value_expression_json !== null &&
|
||||
row.value_expression_json !== undefined &&
|
||||
@@ -689,7 +736,8 @@ function parseOutcome(
|
||||
errors,
|
||||
);
|
||||
if (parsed.ok) {
|
||||
if (isNumericExpression(parsed.value)) value = parsed.value;
|
||||
const resolved = resolveVariantExpression(parsed.value, variantValue);
|
||||
if (resolved !== null) value = resolved;
|
||||
else
|
||||
errors.push(
|
||||
`${path} value expression is not a valid numeric expression.`,
|
||||
|
||||
Reference in New Issue
Block a user