Fixed failing tests and action engine props
This commit is contained in:
@@ -3,8 +3,6 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions';
|
||||||
import { applyTriggers } from '/imports/api/engine/actions/applyTriggers';
|
|
||||||
import ActionContext from '/imports/api/engine/actions/ActionContext';
|
|
||||||
|
|
||||||
const damageProperty = new ValidatedMethod({
|
const damageProperty = new ValidatedMethod({
|
||||||
name: 'creatureProperties.damage',
|
name: 'creatureProperties.damage',
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import { getSingleProperty } from '/imports/api/engine/loadCreatures';
|
|||||||
import ParseNode from '/imports/parser/parseTree/ParseNode';
|
import ParseNode from '/imports/parser/parseTree/ParseNode';
|
||||||
import array from '/imports/parser/parseTree/array';
|
import array from '/imports/parser/parseTree/array';
|
||||||
import constant, { isFiniteNode } from '/imports/parser/parseTree/constant';
|
import constant, { isFiniteNode } from '/imports/parser/parseTree/constant';
|
||||||
|
import resolve from '/imports/parser/resolve';
|
||||||
|
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
||||||
|
import Context from '/imports/parser/types/Context';
|
||||||
|
|
||||||
//set up the collection for creature variables
|
//set up the collection for creature variables
|
||||||
const CreatureVariables = new Mongo.Collection('creatureVariables');
|
const CreatureVariables = new Mongo.Collection('creatureVariables');
|
||||||
@@ -45,6 +48,15 @@ export function getNumberFromScope(name, scope) {
|
|||||||
return parseNode.value;
|
return parseNode.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getConstantValueFromScope(
|
||||||
|
name, scope
|
||||||
|
) {
|
||||||
|
const parseNode = getParseNodeFromScope(name, scope);
|
||||||
|
if (!parseNode) return;
|
||||||
|
if (parseNode.parseType !== 'constant') return;
|
||||||
|
return parseNode.value;
|
||||||
|
}
|
||||||
|
|
||||||
export function getParseNodeFromScope(name, scope): ParseNode | undefined {
|
export function getParseNodeFromScope(name, scope): ParseNode | undefined {
|
||||||
let value = getFromScope(name, scope);
|
let value = getFromScope(name, scope);
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
|||||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
||||||
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions';
|
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions';
|
||||||
import { union } from 'lodash';
|
import { union } from 'lodash';
|
||||||
import ActionContext from '/imports/api/engine/actions/ActionContext';
|
|
||||||
import { applyTriggers } from '/imports/api/engine/actions/applyTriggers';
|
|
||||||
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty';
|
import { damagePropertyWork } from '/imports/api/creature/creatureProperties/methods/damageProperty';
|
||||||
import { getFilter } from '/imports/api/parenting/parentingFunctions';
|
import { getFilter } from '/imports/api/parenting/parentingFunctions';
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,6 @@ import {
|
|||||||
} from '/imports/api/engine/action/functions/actionEngineTest.testFn';
|
} from '/imports/api/engine/action/functions/actionEngineTest.testFn';
|
||||||
import { Mutation, Update } from '/imports/api/engine/action/tasks/TaskResult';
|
import { Mutation, Update } from '/imports/api/engine/action/tasks/TaskResult';
|
||||||
import Alea from 'alea';
|
import Alea from 'alea';
|
||||||
import CreatureVariables from '/imports/api/creature/creatures/CreatureVariables';
|
|
||||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
|
|
||||||
|
|
||||||
process.on('unhandledRejection', (error, p) => {
|
|
||||||
console.dir(error.stack);
|
|
||||||
console.error('Unhandled Rejection at:', p, 'reason:', error)
|
|
||||||
process.exit(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
const [
|
const [
|
||||||
creatureId, targetCreatureId, targetCreature2Id,
|
creatureId, targetCreatureId, targetCreature2Id,
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ async function applyAttackToTarget(
|
|||||||
const targetScope = getVariables(targetId);
|
const targetScope = getVariables(targetId);
|
||||||
const targetArmor = getNumberFromScope('armor', targetScope)
|
const targetArmor = getNumberFromScope('armor', targetScope)
|
||||||
|
|
||||||
if (Number.isFinite(targetArmor)) {
|
if (targetArmor !== undefined) {
|
||||||
let name = criticalHit ? 'Critical Hit!' :
|
let name = criticalHit ? 'Critical Hit!' :
|
||||||
criticalMiss ? 'Critical Miss!' :
|
criticalMiss ? 'Critical Miss!' :
|
||||||
result > targetArmor ? 'Hit!' : 'Miss!';
|
result > targetArmor ? 'Hit!' : 'Miss!';
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export default async function applyBuffProperty(
|
|||||||
//Log the buff
|
//Log the buff
|
||||||
let logValue = prop.description?.value
|
let logValue = prop.description?.value
|
||||||
if (prop.description?.text) {
|
if (prop.description?.text) {
|
||||||
recalculateInlineCalculations(prop.description, action, 'resolve', userInput);
|
recalculateInlineCalculations(prop.description, action, 'reduce', userInput);
|
||||||
logValue = prop.description?.value;
|
logValue = prop.description?.value;
|
||||||
}
|
}
|
||||||
result.appendLog({
|
result.appendLog({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { some, includes, difference, intersection } from 'lodash';
|
import { some, includes, difference, intersection } from 'lodash';
|
||||||
|
|
||||||
import { getParseNodeFromScope } from '/imports/api/creature/creatures/CreatureVariables';
|
import { getConstantValueFromScope } from '/imports/api/creature/creatures/CreatureVariables';
|
||||||
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
||||||
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
|
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
|
||||||
import { getEffectiveActionScope } from '/imports/api/engine/action/functions/getEffectiveActionScope';
|
import { getEffectiveActionScope } from '/imports/api/engine/action/functions/getEffectiveActionScope';
|
||||||
@@ -9,15 +9,16 @@ import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
|||||||
import TaskResult from '/imports/api/engine/action/tasks/TaskResult';
|
import TaskResult from '/imports/api/engine/action/tasks/TaskResult';
|
||||||
import { isFiniteNode } from '/imports/parser/parseTree/constant';
|
import { isFiniteNode } from '/imports/parser/parseTree/constant';
|
||||||
import resolve from '/imports/parser/resolve';
|
import resolve from '/imports/parser/resolve';
|
||||||
import Context from '../../../../parser/types/Context';
|
|
||||||
import toString from '/imports/parser/toString';
|
import toString from '/imports/parser/toString';
|
||||||
import { getPropertiesOfType } from '/imports/api/engine/loadCreatures';
|
import { getPropertiesOfType } from '/imports/api/engine/loadCreatures';
|
||||||
import applyTask from '/imports/api/engine/action/tasks/applyTask';
|
import applyTask from '/imports/api/engine/action/tasks/applyTask';
|
||||||
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
||||||
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags';
|
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags';
|
||||||
|
import Context from '/imports/parser/types/Context';
|
||||||
|
import applySavingThrowProperty from '/imports/api/engine/action/applyProperties/applySavingThrowProperty';
|
||||||
|
|
||||||
export default async function applyDamageProperty(
|
export default async function applyDamageProperty(
|
||||||
task: PropTask, action: EngineAction, result: TaskResult, userInput
|
task: PropTask, action: EngineAction, result: TaskResult, inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
const prop = task.prop;
|
const prop = task.prop;
|
||||||
const scope = getEffectiveActionScope(action);
|
const scope = getEffectiveActionScope(action);
|
||||||
@@ -28,7 +29,7 @@ export default async function applyDamageProperty(
|
|||||||
// Choose target
|
// Choose target
|
||||||
const damageTargets = prop.target === 'self' ? [action.creatureId] : task.targetIds;
|
const damageTargets = prop.target === 'self' ? [action.creatureId] : task.targetIds;
|
||||||
// Determine if the hit is critical
|
// Determine if the hit is critical
|
||||||
const criticalHit = getParseNodeFromScope('~criticalHit', scope)?.value
|
const criticalHit = await getConstantValueFromScope('~criticalHit', scope)
|
||||||
&& prop.damageType !== 'healing'; // Can't critically heal
|
&& prop.damageType !== 'healing'; // Can't critically heal
|
||||||
// Double the damage rolls if the hit is critical
|
// Double the damage rolls if the hit is critical
|
||||||
const context = new Context({
|
const context = new Context({
|
||||||
@@ -40,7 +41,7 @@ export default async function applyDamageProperty(
|
|||||||
const logName = prop.damageType === 'healing' ? 'Healing' : 'Damage';
|
const logName = prop.damageType === 'healing' ? 'Healing' : 'Damage';
|
||||||
|
|
||||||
// roll the dice only and store that string
|
// roll the dice only and store that string
|
||||||
recalculateCalculation(prop.amount, action, 'compile', userInput);
|
recalculateCalculation(prop.amount, action, 'compile', inputProvider);
|
||||||
const { result: rolled } = await resolve('roll', prop.amount.valueNode, scope, context);
|
const { result: rolled } = await resolve('roll', prop.amount.valueNode, scope, context);
|
||||||
if (rolled.parseType !== 'constant') {
|
if (rolled.parseType !== 'constant') {
|
||||||
logValue.push(toString(rolled));
|
logValue.push(toString(rolled));
|
||||||
@@ -72,7 +73,7 @@ export default async function applyDamageProperty(
|
|||||||
typeof damage !== 'number'
|
typeof damage !== 'number'
|
||||||
|| !isFinite(damage)
|
|| !isFinite(damage)
|
||||||
) {
|
) {
|
||||||
return applyDefaultAfterPropTasks(action, prop, damageTargets, userInput);
|
return applyDefaultAfterPropTasks(action, prop, damageTargets, inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round the damage to a whole number
|
// Round the damage to a whole number
|
||||||
@@ -80,7 +81,7 @@ export default async function applyDamageProperty(
|
|||||||
scope['~damage'] = { value: damage };
|
scope['~damage'] = { value: damage };
|
||||||
|
|
||||||
// Convert extra damage into the stored type
|
// Convert extra damage into the stored type
|
||||||
const lastDamageType = getParseNodeFromScope('~lastDamageType')?.value;
|
const lastDamageType = await getConstantValueFromScope('~lastDamageType', scope);
|
||||||
if (prop.damageType === 'extra' && typeof lastDamageType === 'string') {
|
if (prop.damageType === 'extra' && typeof lastDamageType === 'string') {
|
||||||
prop.damageType = lastDamageType;
|
prop.damageType = lastDamageType;
|
||||||
}
|
}
|
||||||
@@ -95,10 +96,10 @@ export default async function applyDamageProperty(
|
|||||||
(prop.damageType !== 'healing' ? ' damage ' : '');
|
(prop.damageType !== 'healing' ? ' damage ' : '');
|
||||||
|
|
||||||
// If there is a save, calculate the save damage
|
// If there is a save, calculate the save damage
|
||||||
let damageOnSave, saveNode, saveRoll;
|
let damageOnSave, saveProp, saveRoll;
|
||||||
if (prop.save) {
|
if (prop.save) {
|
||||||
if (prop.save.damageFunction?.calculation) {
|
if (prop.save.damageFunction?.calculation) {
|
||||||
recalculateCalculation(prop.save.damageFunction, action, 'compile', userInput);
|
recalculateCalculation(prop.save.damageFunction, action, 'compile', inputProvider);
|
||||||
context.errors = [];
|
context.errors = [];
|
||||||
const { result: saveDamageRolled } = await resolve(
|
const { result: saveDamageRolled } = await resolve(
|
||||||
'roll', prop.save.damageFunction.valueNode, scope, context
|
'roll', prop.save.damageFunction.valueNode, scope, context
|
||||||
@@ -112,14 +113,14 @@ export default async function applyDamageProperty(
|
|||||||
if (
|
if (
|
||||||
!isFiniteNode(saveDamageResult)
|
!isFiniteNode(saveDamageResult)
|
||||||
) {
|
) {
|
||||||
return applyDefaultAfterPropTasks(action, prop, damageTargets, userInput);
|
return applyDefaultAfterPropTasks(action, prop, damageTargets, inputProvider);
|
||||||
}
|
}
|
||||||
// Round the damage to a whole number
|
// Round the damage to a whole number
|
||||||
damageOnSave = Math.floor(saveDamageResult.value);
|
damageOnSave = Math.floor(saveDamageResult.value);
|
||||||
} else {
|
} else {
|
||||||
damageOnSave = Math.floor(damage / 2);
|
damageOnSave = Math.floor(damage / 2);
|
||||||
}
|
}
|
||||||
saveNode = {
|
saveProp = {
|
||||||
node: {
|
node: {
|
||||||
...prop.save,
|
...prop.save,
|
||||||
name: prop.save.stat,
|
name: prop.save.stat,
|
||||||
@@ -136,8 +137,11 @@ export default async function applyDamageProperty(
|
|||||||
|
|
||||||
// If there is a saving throw, apply that first
|
// If there is a saving throw, apply that first
|
||||||
if (prop.save) {
|
if (prop.save) {
|
||||||
await applySavingThrow(saveNode, actionContext);
|
await applySavingThrowProperty({
|
||||||
if (getParseNodeFromScope('~saveSucceeded', scope)?.value) {
|
prop: saveProp,
|
||||||
|
targetIds: task.targetIds,
|
||||||
|
}, action, result, inputProvider);
|
||||||
|
if (await getConstantValueFromScope('~saveSucceeded', scope)) {
|
||||||
// Log the total damage
|
// Log the total damage
|
||||||
logValue.push(toString(reduced));
|
logValue.push(toString(reduced));
|
||||||
// Log the save damage
|
// Log the save damage
|
||||||
@@ -165,14 +169,18 @@ export default async function applyDamageProperty(
|
|||||||
|
|
||||||
// Deal the damage to the target
|
// Deal the damage to the target
|
||||||
await dealDamage(
|
await dealDamage(
|
||||||
action, prop, result, userInput, target, prop.damageType, damageToApply
|
action, prop, result, inputProvider, target, prop.damageType, damageToApply
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// There are no targets, just log the result
|
// There are no targets, just log the result
|
||||||
logValue.push(`**${damage}** ${suffix}`);
|
logValue.push(`**${damage}** ${suffix}`);
|
||||||
if (prop.save) {
|
if (prop.save) {
|
||||||
await applySavingThrow(saveNode, actionContext);
|
await applySavingThrowProperty(saveProp, action, result, inputProvider);
|
||||||
|
await applySavingThrowProperty({
|
||||||
|
prop: saveProp,
|
||||||
|
targetIds: task.targetIds,
|
||||||
|
}, action, result, inputProvider);
|
||||||
logValue.push(`**${damageOnSave}** ${suffix} on a successful save`);
|
logValue.push(`**${damageOnSave}** ${suffix} on a successful save`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +189,7 @@ export default async function applyDamageProperty(
|
|||||||
value: logValue.join('\n'),
|
value: logValue.join('\n'),
|
||||||
inline: true,
|
inline: true,
|
||||||
}, damageTargets);
|
}, damageTargets);
|
||||||
return applyDefaultAfterPropTasks(action, prop, damageTargets, userInput);
|
return applyDefaultAfterPropTasks(action, prop, damageTargets, inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
function damageFunctionText(save) {
|
function damageFunctionText(save) {
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
||||||
|
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
||||||
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
|
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
|
||||||
import recalculateInlineCalculations from '/imports/api/engine/action/functions/recalculateInlineCalculations';
|
import recalculateInlineCalculations from '/imports/api/engine/action/functions/recalculateInlineCalculations';
|
||||||
import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
||||||
import TaskResult, { LogContent } from '/imports/api/engine/action/tasks/TaskResult';
|
import TaskResult, { LogContent } from '/imports/api/engine/action/tasks/TaskResult';
|
||||||
|
|
||||||
export default async function applyNoteProperty(
|
export default async function applyNoteProperty(
|
||||||
task: PropTask, action: EngineAction, result: TaskResult, userInput
|
task: PropTask, action: EngineAction, result: TaskResult, inputProvider: InputProvider
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const prop = task.prop;
|
const prop = task.prop;
|
||||||
let contents: LogContent[] | undefined = undefined;
|
let contents: LogContent[] | undefined = undefined;
|
||||||
const logContent: LogContent = {};
|
const logContent: LogContent = {};
|
||||||
if (prop.name) logContent.name = prop.name;
|
if (prop.name) logContent.name = prop.name;
|
||||||
if (prop.summary?.text) {
|
if (prop.summary?.text) {
|
||||||
await recalculateInlineCalculations(prop.summary, action);
|
await recalculateInlineCalculations(prop.summary, action, 'reduce', inputProvider);
|
||||||
logContent.value = prop.summary.value;
|
logContent.value = prop.summary.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ export default async function applyNoteProperty(
|
|||||||
}
|
}
|
||||||
// Log description
|
// Log description
|
||||||
if (prop.description?.text) {
|
if (prop.description?.text) {
|
||||||
await recalculateInlineCalculations(prop.description, action);
|
await recalculateInlineCalculations(prop.description, action, 'reduce', inputProvider);
|
||||||
if (!contents) contents = [];
|
if (!contents) contents = [];
|
||||||
contents.push({ value: prop.description.value });
|
contents.push({ value: prop.description.value });
|
||||||
}
|
}
|
||||||
@@ -31,5 +32,5 @@ export default async function applyNoteProperty(
|
|||||||
targetIds: task.targetIds,
|
targetIds: task.targetIds,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return applyDefaultAfterPropTasks(action, prop, task.targetIds, userInput);
|
return applyDefaultAfterPropTasks(action, prop, task.targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
||||||
|
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
||||||
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
|
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
|
||||||
import { rollAndReduceCalculation } from '/imports/api/engine/action/functions/recalculateCalculation';
|
import { rollAndReduceCalculation } from '/imports/api/engine/action/functions/recalculateCalculation';
|
||||||
import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
||||||
import TaskResult from '/imports/api/engine/action/tasks/TaskResult';
|
import TaskResult from '/imports/api/engine/action/tasks/TaskResult';
|
||||||
|
import { isFiniteNode } from '/imports/parser/parseTree/constant';
|
||||||
import toString from '/imports/parser/toString';
|
import toString from '/imports/parser/toString';
|
||||||
|
|
||||||
export default async function roll(
|
export default async function applyRollProperty(
|
||||||
task: PropTask, action: EngineAction, result: TaskResult, userInput
|
task: PropTask, action: EngineAction, result: TaskResult, inputProvider: InputProvider
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const prop = task.prop;
|
const prop = task.prop;
|
||||||
// If there isn't a calculation, just apply the children instead
|
// If there isn't a calculation, just apply the children instead
|
||||||
if (!prop.roll?.calculation) {
|
if (!prop.roll?.calculation) {
|
||||||
return applyDefaultAfterPropTasks(action, prop, task.targetIds, userInput);
|
return applyDefaultAfterPropTasks(action, prop, task.targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
const logValue: string[] = [];
|
const logValue: string[] = [];
|
||||||
@@ -19,7 +21,7 @@ export default async function roll(
|
|||||||
// roll the dice only and store that string
|
// roll the dice only and store that string
|
||||||
const {
|
const {
|
||||||
rolled, reduced, errors
|
rolled, reduced, errors
|
||||||
} = await rollAndReduceCalculation(prop.roll, action);
|
} = await rollAndReduceCalculation(prop.roll, action, inputProvider);
|
||||||
|
|
||||||
if (rolled.parseType !== 'constant') {
|
if (rolled.parseType !== 'constant') {
|
||||||
logValue.push(toString(rolled));
|
logValue.push(toString(rolled));
|
||||||
@@ -38,8 +40,8 @@ export default async function roll(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we didn't end up with a constant or a number of finite value, give up
|
// If we didn't end up with a constant or a number of finite value, give up
|
||||||
if (reduced?.parseType !== 'constant' || (reduced.valueType === 'number' && !isFinite(reduced.value))) {
|
if (reduced?.parseType !== 'constant' || !isFiniteNode(reduced)) {
|
||||||
return applyDefaultAfterPropTasks(action, prop, task.targetIds, userInput);
|
return applyDefaultAfterPropTasks(action, prop, task.targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
const value = reduced.value;
|
const value = reduced.value;
|
||||||
|
|
||||||
@@ -54,5 +56,5 @@ export default async function roll(
|
|||||||
}, task.targetIds);
|
}, task.targetIds);
|
||||||
|
|
||||||
// Apply children
|
// Apply children
|
||||||
return applyDefaultAfterPropTasks(action, prop, task.targetIds, userInput);
|
return applyDefaultAfterPropTasks(action, prop, task.targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +1,67 @@
|
|||||||
// TODO
|
import { getFromScope } from '/imports/api/creature/creatures/CreatureVariables';
|
||||||
|
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
||||||
|
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
||||||
|
import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
|
||||||
|
import { getEffectiveActionScope } from '/imports/api/engine/action/functions/getEffectiveActionScope';
|
||||||
|
import recalculateCalculation from '/imports/api/engine/action/functions/recalculateCalculation';
|
||||||
|
import { applyUnresolvedEffects } from '/imports/api/engine/action/methods/doCheck';
|
||||||
|
import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
||||||
|
import TaskResult from '/imports/api/engine/action/tasks/TaskResult';
|
||||||
|
import { getVariables } from '/imports/api/engine/loadCreatures';
|
||||||
|
import numberToSignedString from '/imports/api/utility/numberToSignedString';
|
||||||
|
import { isFiniteNode } from '/imports/parser/parseTree/constant';
|
||||||
|
|
||||||
export default function applySavingThrow(node, actionContext) {
|
export default async function applySavingThrowProperty(
|
||||||
applyNodeTriggers(node, 'before', actionContext);
|
task: PropTask, action: EngineAction, result: TaskResult, inputProvider: InputProvider
|
||||||
const prop = node.doc
|
): Promise<void> {
|
||||||
const originalTargets = actionContext.targets;
|
|
||||||
|
|
||||||
let saveTargets = prop.target === 'self' ? [actionContext.creature] : actionContext.targets;
|
const prop = task.prop;
|
||||||
|
const originalTargetIds = task.targetIds;
|
||||||
|
|
||||||
recalculateCalculation(prop.dc, actionContext);
|
const saveTargetIds = prop.target === 'self' ? [action.creatureId] : originalTargetIds;
|
||||||
|
|
||||||
const dc = (prop.dc?.value);
|
if (saveTargetIds.length > 1)
|
||||||
if (!isFinite(dc)) {
|
|
||||||
actionContext.addLog({
|
recalculateCalculation(prop.dc, action, 'reduce', inputProvider);
|
||||||
|
|
||||||
|
if (!isFiniteNode(prop.dc)) {
|
||||||
|
result.appendLog({
|
||||||
name: 'Error',
|
name: 'Error',
|
||||||
value: 'Saving throw requires a DC',
|
value: 'Saving throw requires a DC',
|
||||||
});
|
}, saveTargetIds);
|
||||||
return node.children.forEach(child => applyProperty(child, actionContext));
|
return applyDefaultAfterPropTasks(action, prop, saveTargetIds, inputProvider);
|
||||||
}
|
}
|
||||||
if (!prop.silent) actionContext.addLog({
|
|
||||||
|
const dc = (prop.dc?.value);
|
||||||
|
if (!prop.silent) result.appendLog({
|
||||||
name: prop.name,
|
name: prop.name,
|
||||||
value: `DC **${dc}**`,
|
value: `DC **${dc}**`,
|
||||||
inline: true,
|
inline: true,
|
||||||
});
|
...prop.silent && { silenced: prop.silent }
|
||||||
const scope = actionContext.scope;
|
}, saveTargetIds);
|
||||||
|
const scope = await getEffectiveActionScope(action);
|
||||||
|
|
||||||
// If there are no save targets, apply all children as if the save both
|
// If there are no save targets, apply all children as if the save both
|
||||||
// succeeeded and failed
|
// succeeded and failed
|
||||||
if (!saveTargets?.length) {
|
if (!saveTargetIds?.length) {
|
||||||
scope['~saveFailed'] = { value: true };
|
result.scope = {
|
||||||
scope['~saveSucceeded'] = { value: true };
|
['~saveFailed']: { value: true },
|
||||||
return applyChildren(node, actionContext);
|
['~saveSucceeded']: { value: true },
|
||||||
|
}
|
||||||
|
return applyDefaultAfterPropTasks(action, prop, saveTargetIds, inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Each target makes the saving throw
|
// Each target makes the saving throw
|
||||||
saveTargets.forEach(target => {
|
for (const targetId of saveTargetIds) {
|
||||||
delete scope['~saveFailed'];
|
|
||||||
delete scope['~saveSucceeded'];
|
|
||||||
delete scope['~saveDiceRoll'];
|
|
||||||
delete scope['~saveRoll'];
|
|
||||||
|
|
||||||
const applyChildrenToTarget = function () {
|
const save = getFromScope('save', getVariables(targetId));
|
||||||
actionContext.targets = [target];
|
|
||||||
return applyChildren(node, actionContext);
|
|
||||||
};
|
|
||||||
|
|
||||||
const save = target.variables[prop.stat];
|
|
||||||
|
|
||||||
if (!save) {
|
if (!save) {
|
||||||
actionContext.addLog({
|
result.appendLog({
|
||||||
name: 'Saving throw error',
|
name: 'Saving throw error',
|
||||||
value: 'No saving throw found: ' + prop.stat,
|
value: 'No saving throw found: ' + prop.stat,
|
||||||
});
|
}, [targetId]);
|
||||||
return applyChildrenToTarget();
|
applyDefaultAfterPropTasks(action, prop, [targetId], inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
let rollModifierText = numberToSignedString(save.value, true);
|
let rollModifierText = numberToSignedString(save.value, true);
|
||||||
@@ -60,9 +70,9 @@ export default function applySavingThrow(node, actionContext) {
|
|||||||
rollModifierText += effectString;
|
rollModifierText += effectString;
|
||||||
rollModifier += effectBonus;
|
rollModifier += effectBonus;
|
||||||
|
|
||||||
let value, values, resultPrefix;
|
let value, resultPrefix;
|
||||||
if (save.advantage === 1) {
|
if (save.advantage === 1) {
|
||||||
const [a, b] = rollDice(2, 20);
|
const [[a, b]] = await inputProvider.rollDice([{ number: 2, diceSize: 20 }]);
|
||||||
if (a >= b) {
|
if (a >= b) {
|
||||||
value = a;
|
value = a;
|
||||||
resultPrefix = `Advantage\n1d20 [ ${a}, ~~${b}~~ ] ${rollModifierText}`;
|
resultPrefix = `Advantage\n1d20 [ ${a}, ~~${b}~~ ] ${rollModifierText}`;
|
||||||
@@ -71,7 +81,7 @@ export default function applySavingThrow(node, actionContext) {
|
|||||||
resultPrefix = `Advantage\n1d20 [ ~~${a}~~, ${b} ] ${rollModifierText}`;
|
resultPrefix = `Advantage\n1d20 [ ~~${a}~~, ${b} ] ${rollModifierText}`;
|
||||||
}
|
}
|
||||||
} else if (save.advantage === -1) {
|
} else if (save.advantage === -1) {
|
||||||
const [a, b] = rollDice(2, 20);
|
const [[a, b]] = await inputProvider.rollDice([{ number: 2, diceSize: 20 }]);
|
||||||
if (a <= b) {
|
if (a <= b) {
|
||||||
value = a;
|
value = a;
|
||||||
resultPrefix = `Disadvantage\n1d20 [ ${a}, ~~${b}~~ ] ${rollModifierText}`;
|
resultPrefix = `Disadvantage\n1d20 [ ${a}, ~~${b}~~ ] ${rollModifierText}`;
|
||||||
@@ -80,26 +90,24 @@ export default function applySavingThrow(node, actionContext) {
|
|||||||
resultPrefix = `Disadvantage\n1d20 [ ~~${a}~~, ${b} ] ${rollModifierText}`;
|
resultPrefix = `Disadvantage\n1d20 [ ~~${a}~~, ${b} ] ${rollModifierText}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
values = rollDice(1, 20);
|
const [[rolledValue]] = await inputProvider.rollDice([{ number: 1, diceSize: 20 }]);
|
||||||
value = values[0];
|
value = rolledValue;
|
||||||
resultPrefix = `1d20 [ ${value} ] ${rollModifierText}`
|
resultPrefix = `1d20 [ ${value} ] ${rollModifierText}`
|
||||||
}
|
}
|
||||||
scope['~saveDiceRoll'] = { value };
|
scope['~saveDiceRoll'] = { value };
|
||||||
const result = value + rollModifier || 0;
|
const resultValue = value + rollModifier || 0;
|
||||||
scope['~saveRoll'] = { value: result };
|
scope['~saveRoll'] = { value: resultValue };
|
||||||
const saveSuccess = result >= dc;
|
const saveSuccess = resultValue >= dc;
|
||||||
if (saveSuccess) {
|
if (saveSuccess) {
|
||||||
scope['~saveSucceeded'] = { value: true };
|
scope['~saveSucceeded'] = { value: true };
|
||||||
} else {
|
} else {
|
||||||
scope['~saveFailed'] = { value: true };
|
scope['~saveFailed'] = { value: true };
|
||||||
}
|
}
|
||||||
if (!prop.silent) actionContext.addLog({
|
if (!prop.silent) result.appendLog({
|
||||||
name: saveSuccess ? 'Successful save' : 'Failed save',
|
name: saveSuccess ? 'Successful save' : 'Failed save',
|
||||||
value: resultPrefix + '\n**' + result + '**',
|
value: resultPrefix + '\n**' + resultValue + '**',
|
||||||
inline: true,
|
inline: true,
|
||||||
});
|
}, [targetId]);
|
||||||
return applyChildrenToTarget();
|
return applyDefaultAfterPropTasks(action, prop, [targetId], inputProvider);
|
||||||
});
|
}
|
||||||
// reset the targets after the save to each child
|
|
||||||
actionContext.targets = originalTargets;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
// TODO
|
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
||||||
|
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
||||||
|
import { applyAfterTasksSkipChildren, applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups';
|
||||||
|
import recalculateCalculation from '/imports/api/engine/action/functions/recalculateCalculation';
|
||||||
|
import { PropTask } from '/imports/api/engine/action/tasks/Task';
|
||||||
|
import TaskResult from '/imports/api/engine/action/tasks/TaskResult';
|
||||||
|
|
||||||
export default function applyToggle(node, actionContext) {
|
export default async function applyToggle(
|
||||||
applyNodeTriggers(node, 'before', actionContext);
|
task: PropTask, action: EngineAction, result: TaskResult, inputProvider: InputProvider
|
||||||
const prop = node.doc
|
): Promise<void> {
|
||||||
recalculateCalculation(prop.condition, actionContext);
|
|
||||||
|
const prop = task.prop;
|
||||||
|
await recalculateCalculation(prop.condition, action, 'reduce', inputProvider);
|
||||||
if (prop.condition?.value) {
|
if (prop.condition?.value) {
|
||||||
return applyChildren(node, actionContext);
|
return applyDefaultAfterPropTasks(action, prop, task.targetIds, inputProvider);
|
||||||
|
} else {
|
||||||
|
return applyAfterTasksSkipChildren(action, prop, task.targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { getPropertyChildren, getSingleProperty } from '/imports/api/engine/load
|
|||||||
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
||||||
import applyTask from '../tasks/applyTask';
|
import applyTask from '../tasks/applyTask';
|
||||||
import { PropTask } from '../tasks/Task';
|
import { PropTask } from '../tasks/Task';
|
||||||
|
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the child tasks of a given property
|
* Get all the child tasks of a given property
|
||||||
@@ -13,11 +14,11 @@ import { PropTask } from '../tasks/Task';
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function applyChildren(
|
export async function applyChildren(
|
||||||
action: EngineAction, prop, targetIds: string[], userInput
|
action: EngineAction, prop, targetIds: string[], inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
const children = await getPropertyChildren(action.creatureId, prop);
|
const children = await getPropertyChildren(action.creatureId, prop);
|
||||||
for (const childProp of children) {
|
for (const childProp of children) {
|
||||||
await applyTask(action, { prop: childProp, targetIds }, userInput);
|
await applyTask(action, { prop: childProp, targetIds }, inputProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,24 +29,24 @@ export async function applyChildren(
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function applyAfterChildrenTriggers(
|
export async function applyAfterChildrenTriggers(
|
||||||
action: EngineAction, prop, targetIds: string[], userInput
|
action: EngineAction, prop, targetIds: string[], inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
if (!prop.triggerIds?.afterChildren) return;
|
if (!prop.triggerIds?.afterChildren) return;
|
||||||
for (const triggerId of prop.triggerIds.afterChildren) {
|
for (const triggerId of prop.triggerIds.afterChildren) {
|
||||||
const trigger = await getSingleProperty(action.creatureId, triggerId);
|
const trigger = await getSingleProperty(action.creatureId, triggerId);
|
||||||
if (!trigger) continue;
|
if (!trigger) continue;
|
||||||
await applyTask(action, { prop: trigger, targetIds }, userInput);
|
await applyTask(action, { prop: trigger, targetIds }, inputProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function applyAfterTriggers(
|
export async function applyAfterTriggers(
|
||||||
action: EngineAction, prop, targetIds: string[], userInput
|
action: EngineAction, prop, targetIds: string[], inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
if (!prop.triggerIds?.after) return;
|
if (!prop.triggerIds?.after) return;
|
||||||
for (const triggerId of prop.triggerIds.after) {
|
for (const triggerId of prop.triggerIds.after) {
|
||||||
const trigger = await getSingleProperty(action.creatureId, triggerId);
|
const trigger = await getSingleProperty(action.creatureId, triggerId);
|
||||||
if (!trigger) continue;
|
if (!trigger) continue;
|
||||||
await applyTask(action, { prop: trigger, targetIds }, userInput);
|
await applyTask(action, { prop: trigger, targetIds }, inputProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,11 +61,11 @@ export async function applyAfterTriggers(
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function applyDefaultAfterPropTasks(
|
export async function applyDefaultAfterPropTasks(
|
||||||
action: EngineAction, prop, targetIds: string[], userInput
|
action: EngineAction, prop, targetIds: string[], inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
await applyAfterTriggers(action, prop, targetIds, userInput);
|
await applyAfterTriggers(action, prop, targetIds, inputProvider);
|
||||||
await applyChildren(action, prop, targetIds, userInput);
|
await applyChildren(action, prop, targetIds, inputProvider);
|
||||||
await applyAfterChildrenTriggers(action, prop, targetIds, userInput);
|
await applyAfterChildrenTriggers(action, prop, targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,10 +78,10 @@ export async function applyDefaultAfterPropTasks(
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function applyAfterTasksSkipChildren(
|
export async function applyAfterTasksSkipChildren(
|
||||||
action: EngineAction, prop, targetIds: string[], userInput
|
action: EngineAction, prop, targetIds: string[], inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
await applyAfterTriggers(action, prop, targetIds, userInput);
|
await applyAfterTriggers(action, prop, targetIds, inputProvider);
|
||||||
await applyAfterChildrenTriggers(action, prop, targetIds, userInput);
|
await applyAfterChildrenTriggers(action, prop, targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,11 +94,11 @@ export async function applyAfterTasksSkipChildren(
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function applyAfterPropTasksForSingleChild(
|
export async function applyAfterPropTasksForSingleChild(
|
||||||
action: EngineAction, prop, childProp, targetIds: string[], userInput
|
action: EngineAction, prop, childProp, targetIds: string[], inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
await applyAfterTriggers(action, prop, targetIds, userInput);
|
await applyAfterTriggers(action, prop, targetIds, inputProvider);
|
||||||
await applyTask(action, { prop: childProp, targetIds }, userInput);
|
await applyTask(action, { prop: childProp, targetIds }, inputProvider);
|
||||||
await applyAfterChildrenTriggers(action, prop, targetIds, userInput);
|
await applyAfterChildrenTriggers(action, prop, targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,13 +111,13 @@ export async function applyAfterPropTasksForSingleChild(
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function applyAfterPropTasksForSomeChildren(
|
export async function applyAfterPropTasksForSomeChildren(
|
||||||
action: EngineAction, prop, children, targetIds: string[], userInput
|
action: EngineAction, prop, children, targetIds: string[], inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
await applyAfterTriggers(action, prop, targetIds, userInput);
|
await applyAfterTriggers(action, prop, targetIds, inputProvider);
|
||||||
for (const childProp of children) {
|
for (const childProp of children) {
|
||||||
await applyTask(action, { prop: childProp, targetIds }, userInput);
|
await applyTask(action, { prop: childProp, targetIds }, inputProvider);
|
||||||
}
|
}
|
||||||
await applyAfterChildrenTriggers(action, prop, targetIds, userInput);
|
await applyAfterChildrenTriggers(action, prop, targetIds, inputProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,14 +129,14 @@ export async function applyAfterPropTasksForSomeChildren(
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export async function applyTriggers(
|
export async function applyTriggers(
|
||||||
action: EngineAction, prop, targetIds: string[], triggerPath: string, userInput
|
action: EngineAction, prop, targetIds: string[], triggerPath: string, inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
const triggerIds = get(prop?.triggers, triggerPath);
|
const triggerIds = get(prop?.triggers, triggerPath);
|
||||||
if (!triggerIds) return;
|
if (!triggerIds) return;
|
||||||
for (const triggerId of triggerIds) {
|
for (const triggerId of triggerIds) {
|
||||||
const trigger = await getSingleProperty(action.creatureId, triggerId);
|
const trigger = await getSingleProperty(action.creatureId, triggerId);
|
||||||
if (!trigger) continue;
|
if (!trigger) continue;
|
||||||
await applyTask(action, { prop: trigger, targetIds }, userInput);
|
await applyTask(action, { prop: trigger, targetIds }, inputProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +147,7 @@ export async function applyTriggers(
|
|||||||
* @returns Copies of the task, but with a single target each
|
* @returns Copies of the task, but with a single target each
|
||||||
*/
|
*/
|
||||||
export async function applyTaskToEachTarget(
|
export async function applyTaskToEachTarget(
|
||||||
action: EngineAction, task: PropTask, targetIds: string[] = task.targetIds, userInput
|
action: EngineAction, task: PropTask, targetIds: string[] = task.targetIds, inputProvider: InputProvider
|
||||||
) {
|
) {
|
||||||
if (targetIds.length <= 1) throw 'Must have multiple targets to split a task';
|
if (targetIds.length <= 1) throw 'Must have multiple targets to split a task';
|
||||||
// If there are targets, apply a new task to each target
|
// If there are targets, apply a new task to each target
|
||||||
@@ -154,6 +155,6 @@ export async function applyTaskToEachTarget(
|
|||||||
await applyTask(action, {
|
await applyTask(action, {
|
||||||
...task,
|
...task,
|
||||||
targetIds: [targetId]
|
targetIds: [targetId]
|
||||||
}, userInput);
|
}, inputProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
import embedInlineCalculations from '/imports/api/engine/computation/utility/embedInlineCalculations';
|
import embedInlineCalculations from '/imports/api/engine/computation/utility/embedInlineCalculations';
|
||||||
import recalculateCalculation from './recalculateCalculation'
|
import recalculateCalculation from './recalculateCalculation'
|
||||||
|
import { InlineCalculation } from '/imports/api/properties/subSchemas/inlineCalculationField';
|
||||||
|
import { EngineAction } from '/imports/api/engine/action/EngineActions';
|
||||||
|
import ResolveLevel from '/imports/parser/types/ResolveLevel';
|
||||||
|
import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
||||||
|
|
||||||
export default async function recalculateInlineCalculations(inlineCalcObj, action, parseLevel, userInput) {
|
export default async function recalculateInlineCalculations(
|
||||||
|
inlineCalcObj: InlineCalculation, action: EngineAction,
|
||||||
|
parseLevel: ResolveLevel, userInput: InputProvider
|
||||||
|
) {
|
||||||
// Skip if there are no calculations
|
// Skip if there are no calculations
|
||||||
if (!inlineCalcObj?.inlineCalculations?.length) return;
|
if (!inlineCalcObj?.inlineCalculations?.length) return;
|
||||||
// Recalculate each calculation with the current scope
|
// Recalculate each calculation with the current scope
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ import CreatureProperties from '/imports/api/creature/creatureProperties/Creatur
|
|||||||
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions';
|
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions';
|
||||||
import rollDice from '/imports/parser/rollDice';
|
import rollDice from '/imports/parser/rollDice';
|
||||||
import numberToSignedString from '/imports/api/utility/numberToSignedString';
|
import numberToSignedString from '/imports/api/utility/numberToSignedString';
|
||||||
import { applyTriggers } from '/imports/api/engine/actions/applyTriggers';
|
|
||||||
import ActionContext from '/imports/api/engine/actions/ActionContext';
|
|
||||||
import recalculateCalculation from '../../actions/applyPropertyByType/shared/recalculateCalculation';
|
|
||||||
import { getSingleProperty } from '/imports/api/engine/loadCreatures';
|
import { getSingleProperty } from '/imports/api/engine/loadCreatures';
|
||||||
|
|
||||||
// TODO Migrate this to the new action engine
|
// TODO Migrate this to the new action engine
|
||||||
|
|||||||
@@ -9,16 +9,16 @@ import InputProvider from '/imports/api/engine/action/functions/InputProvider';
|
|||||||
|
|
||||||
// DamagePropTask promises a number of actual damage done
|
// DamagePropTask promises a number of actual damage done
|
||||||
export default async function applyTask(
|
export default async function applyTask(
|
||||||
action: EngineAction, task: DamagePropTask, userInput: InputProvider
|
action: EngineAction, task: DamagePropTask, inputProvider: InputProvider
|
||||||
): Promise<number>
|
): Promise<number>
|
||||||
|
|
||||||
// Other tasks promise nothing
|
// Other tasks promise nothing
|
||||||
export default async function applyTask(
|
export default async function applyTask(
|
||||||
action: EngineAction, task: PropTask | ItemAsAmmoTask, userInput: InputProvider
|
action: EngineAction, task: PropTask | ItemAsAmmoTask, inputProvider: InputProvider
|
||||||
): Promise<void>
|
): Promise<void>
|
||||||
|
|
||||||
export default async function applyTask(
|
export default async function applyTask(
|
||||||
action: EngineAction, task: Task, userInput: InputProvider
|
action: EngineAction, task: Task, inputProvider: InputProvider
|
||||||
): Promise<void | number> {
|
): Promise<void | number> {
|
||||||
action.taskCount += 1;
|
action.taskCount += 1;
|
||||||
if (action.taskCount > 100) throw 'Only 100 properties can be applied at once';
|
if (action.taskCount > 100) throw 'Only 100 properties can be applied at once';
|
||||||
@@ -28,9 +28,9 @@ export default async function applyTask(
|
|||||||
action.results.push(result);
|
action.results.push(result);
|
||||||
switch (task.subtaskFn) {
|
switch (task.subtaskFn) {
|
||||||
case 'damageProp':
|
case 'damageProp':
|
||||||
return applyDamagePropTask(task, action, result, userInput);
|
return applyDamagePropTask(task, action, result, inputProvider);
|
||||||
case 'consumeItemAsAmmo':
|
case 'consumeItemAsAmmo':
|
||||||
return applyItemAsAmmoTask(task, action, result, userInput);
|
return applyItemAsAmmoTask(task, action, result, inputProvider);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Get property
|
// Get property
|
||||||
@@ -47,7 +47,7 @@ export default async function applyTask(
|
|||||||
for (const triggerId of prop.triggerIds.before) {
|
for (const triggerId of prop.triggerIds.before) {
|
||||||
const trigger = await getSingleProperty(action.creatureId, triggerId);
|
const trigger = await getSingleProperty(action.creatureId, triggerId);
|
||||||
if (!trigger) continue;
|
if (!trigger) continue;
|
||||||
await applyTask(action, { prop: trigger, targetIds: task.targetIds }, userInput);
|
await applyTask(action, { prop: trigger, targetIds: task.targetIds }, inputProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +57,6 @@ export default async function applyTask(
|
|||||||
action.results.push(result);
|
action.results.push(result);
|
||||||
|
|
||||||
// Apply the property
|
// Apply the property
|
||||||
return applyProperties[prop.type]?.(task, action, result, userInput);
|
return applyProperties[prop.type]?.(task, action, result, inputProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,4 +11,10 @@ describe('Call Node', function () {
|
|||||||
assert.isEmpty(context.errors)
|
assert.isEmpty(context.errors)
|
||||||
assert.equal(toString(result), 'min(unknownVariable, 3, 3d30)');
|
assert.equal(toString(result), 'min(unknownVariable, 3, 3d30)');
|
||||||
});
|
});
|
||||||
|
it('reduces', async function () {
|
||||||
|
const callNode = parse('min( unknownVariable, 1 + 2, 3d30 )');
|
||||||
|
const { result, context } = await resolve('reduce', callNode, undefined, undefined, inputProviderForTests);
|
||||||
|
assert.isEmpty(context.errors)
|
||||||
|
assert.equal(toString(result), '0');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -173,16 +173,13 @@ const call: CallFactory = {
|
|||||||
expectedType = argumentsExpected[index];
|
expectedType = argumentsExpected[index];
|
||||||
}
|
}
|
||||||
if (expectedType === 'parseNode') return;
|
if (expectedType === 'parseNode') return;
|
||||||
if (
|
failed = !(
|
||||||
node.parseType !== expectedType
|
node.parseType === expectedType
|
||||||
|| (
|
|| (node.parseType === 'constant' && node.valueType === expectedType)
|
||||||
node.parseType === 'constant'
|
);
|
||||||
&& node.valueType !== expectedType
|
|
||||||
)
|
|
||||||
) failed = true;
|
|
||||||
if (failed && fn === 'reduce') {
|
if (failed && fn === 'reduce') {
|
||||||
const typeName = typeof expectedType === 'string' ? expectedType : expectedType.constructor.name;
|
const typeName = typeof expectedType === 'string' ? expectedType : expectedType.constructor.name;
|
||||||
const nodeName = node.parseType;
|
const nodeName = node.parseType === 'constant' ? node.valueType : node.parseType;
|
||||||
context.error(`Incorrect arguments to ${callNode.functionName} function` +
|
context.error(`Incorrect arguments to ${callNode.functionName} function` +
|
||||||
`expected ${typeName} got ${nodeName}`);
|
`expected ${typeName} got ${nodeName}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
process.on('unhandledRejection', (error, p) => {
|
||||||
|
console.dir(error.stack);
|
||||||
|
console.error('Unhandled Rejection at:', p, 'reason:', error)
|
||||||
|
process.exit(1)
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user