Support target-scoped trauma mechanics
This commit is contained in:
@@ -174,20 +174,43 @@ function requiredNumber(value: DatabaseValue, path: string, errors: string[]) {
|
||||
return result ?? 0;
|
||||
}
|
||||
|
||||
function isEntitySelector(value: unknown) {
|
||||
if (!object(value) || typeof value.kind !== 'string') return false;
|
||||
if (value.kind === 'agent' || value.kind === 'event_actor' || value.kind === 'event_target') {
|
||||
return true;
|
||||
}
|
||||
return value.kind === 'event_field'
|
||||
&& typeof value.path === 'string'
|
||||
&& Boolean(value.path.trim());
|
||||
}
|
||||
|
||||
function isValueReference(value: unknown) {
|
||||
if (!object(value) || typeof value.source !== 'string') return false;
|
||||
if (value.source === 'event' || value.source === 'equipment') {
|
||||
return typeof value.path === 'string' && Boolean(value.path.trim());
|
||||
}
|
||||
if (value.source === 'combat') {
|
||||
return typeof value.path === 'string'
|
||||
&& Boolean(value.path.trim())
|
||||
&& (value.timing === undefined || value.timing === 'pre_event' || value.timing === 'current');
|
||||
}
|
||||
if (value.source === 'attribute') {
|
||||
return typeof value.attributeId === 'string' && Boolean(value.attributeId.trim());
|
||||
}
|
||||
if (value.source === 'scenario') {
|
||||
return typeof value.key === 'string' && Boolean(value.key.trim());
|
||||
}
|
||||
if (value.source === 'reducer') return true;
|
||||
return value.source === 'pool'
|
||||
&& typeof value.pool === 'string'
|
||||
&& Boolean(value.pool.trim())
|
||||
&& (value.entity === undefined || isEntitySelector(value.entity));
|
||||
}
|
||||
|
||||
function isNumericExpression(value: unknown): value is NumericExpression {
|
||||
if (finite(value)) return true;
|
||||
if (!object(value)) return false;
|
||||
if ('ref' in value) {
|
||||
if (!object(value.ref) || typeof value.ref.source !== 'string') return false;
|
||||
const source = value.ref.source;
|
||||
if (source === 'event' || source === 'combat' || source === 'equipment') {
|
||||
return typeof value.ref.path === 'string';
|
||||
}
|
||||
if (source === 'scenario') return typeof value.ref.key === 'string';
|
||||
if (source === 'reducer') return true;
|
||||
if (source === 'pool') return typeof value.ref.pool === 'string';
|
||||
return false;
|
||||
}
|
||||
if ('ref' in value) return isValueReference(value.ref);
|
||||
if (value.op === 'clamp') {
|
||||
return isNumericExpression(value.value)
|
||||
&& isNumericExpression(value.min)
|
||||
@@ -233,14 +256,20 @@ function isReducer(value: unknown): value is Reducer {
|
||||
function isMutation(value: unknown): value is ClauseMutation {
|
||||
if (!object(value) || typeof value.kind !== 'string') return false;
|
||||
if (value.kind === 'none') return true;
|
||||
if (value.kind === 'clear') return typeof value.pool === 'string';
|
||||
if (value.kind === 'clear') {
|
||||
return typeof value.pool === 'string'
|
||||
&& (value.entity === undefined || isEntitySelector(value.entity));
|
||||
}
|
||||
if (value.kind === 'transfer') {
|
||||
return typeof value.pool === 'string' && object(value.from) && object(value.to)
|
||||
return typeof value.pool === 'string'
|
||||
&& isEntitySelector(value.from)
|
||||
&& isEntitySelector(value.to)
|
||||
&& (value.value === undefined || value.value === 'all' || isNumericExpression(value.value));
|
||||
}
|
||||
return ['add', 'set', 'consume', 'derive'].includes(value.kind)
|
||||
&& typeof value.pool === 'string'
|
||||
&& isNumericExpression(value.value);
|
||||
&& isNumericExpression(value.value)
|
||||
&& (value.entity === undefined || isEntitySelector(value.entity));
|
||||
}
|
||||
|
||||
function parseScenarioInputs(
|
||||
|
||||
Reference in New Issue
Block a user