diff --git a/app/imports/api/creature/creatures/CreatureVariables.ts b/app/imports/api/creature/creatures/CreatureVariables.ts index 2578edfa..07a35e71 100644 --- a/app/imports/api/creature/creatures/CreatureVariables.ts +++ b/app/imports/api/creature/creatures/CreatureVariables.ts @@ -3,7 +3,7 @@ import ParseNode from '/imports/parser/parseTree/ParseNode'; import array from '/imports/parser/parseTree/array'; import constant, { isFiniteNode } from '/imports/parser/parseTree/constant'; import resolve from '/imports/parser/resolve'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; import Context from '/imports/parser/types/Context'; //set up the collection for creature variables diff --git a/app/imports/api/engine/action/ActionEngine.test.ts b/app/imports/api/engine/action/ActionEngine.test.ts index f2e3ea82..973e7492 100644 --- a/app/imports/api/engine/action/ActionEngine.test.ts +++ b/app/imports/api/engine/action/ActionEngine.test.ts @@ -9,7 +9,7 @@ import { loadCreature } from '/imports/api/engine/loadCreatures'; import EngineActions, { EngineAction } from '/imports/api/engine/action/EngineActions'; import applyAction from '/imports/api/engine/action/functions/applyAction'; import { LogContent, Removal, Update } from '/imports/api/engine/action/tasks/TaskResult'; -import inputProvider from '/imports/api/engine/action/functions/inputProviderForTests.testFn'; +import inputProvider from './functions/userInput/inputProviderForTests.testFn'; const creatureId = Random.id(); const targetId = Random.id(); diff --git a/app/imports/api/engine/action/EngineActions.ts b/app/imports/api/engine/action/EngineActions.ts index 2f7e33d9..4d60063c 100644 --- a/app/imports/api/engine/action/EngineActions.ts +++ b/app/imports/api/engine/action/EngineActions.ts @@ -9,6 +9,7 @@ export interface EngineAction { _id?: string; _isSimulation?: boolean; _stepThrough?: boolean; + _choices?: any[], creatureId: string; rootPropId: string; targetIds?: string[]; diff --git a/app/imports/api/engine/action/applyProperties/applyActionProperty.ts b/app/imports/api/engine/action/applyProperties/applyActionProperty.ts index 5af826a4..47a07011 100644 --- a/app/imports/api/engine/action/applyProperties/applyActionProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyActionProperty.ts @@ -11,7 +11,7 @@ import recalculateCalculation from '/imports/api/engine/action/functions/recalcu import { getEffectiveActionScope } from '/imports/api/engine/action/functions/getEffectiveActionScope'; import numberToSignedString from '/imports/api/utility/numberToSignedString'; import { getConstantValueFromScope, getNumberFromScope } from '/imports/api/creature/creatures/CreatureVariables'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; import { CalculatedField } from '/imports/api/properties/subSchemas/computedField'; export default async function applyActionProperty( diff --git a/app/imports/api/engine/action/applyProperties/applyAdjustmentProperty.ts b/app/imports/api/engine/action/applyProperties/applyAdjustmentProperty.ts index 09f38171..9b531edd 100644 --- a/app/imports/api/engine/action/applyProperties/applyAdjustmentProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyAdjustmentProperty.ts @@ -1,5 +1,5 @@ import { EngineAction } from '/imports/api/engine/action/EngineActions'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; import { applyDefaultAfterPropTasks, applyTaskToEachTarget } 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'; diff --git a/app/imports/api/engine/action/applyProperties/applyBranchProperty.ts b/app/imports/api/engine/action/applyProperties/applyBranchProperty.ts index e828fa44..8c41ce79 100644 --- a/app/imports/api/engine/action/applyProperties/applyBranchProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyBranchProperty.ts @@ -1,6 +1,6 @@ import { filter } from 'lodash'; import { EngineAction } from '/imports/api/engine/action/EngineActions'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; import { applyAfterPropTasksForSingleChild, applyAfterPropTasksForSomeChildren, applyAfterTasksSkipChildren, applyDefaultAfterPropTasks, applyTaskToEachTarget } 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'; diff --git a/app/imports/api/engine/action/applyProperties/applyBuffProperty.ts b/app/imports/api/engine/action/applyProperties/applyBuffProperty.ts index 56d36a0d..8b1d9d19 100644 --- a/app/imports/api/engine/action/applyProperties/applyBuffProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyBuffProperty.ts @@ -18,7 +18,7 @@ import recalculateInlineCalculations from '/imports/api/engine/action/functions/ import getPropertyTitle from '/imports/api/utility/getPropertyTitle'; import INLINE_CALCULATION_REGEX from '/imports/constants/INLINE_CALCULTION_REGEX'; import { applyAfterTasksSkipChildren } from '/imports/api/engine/action/functions/applyTaskGroups'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; export default async function applyBuffProperty( task: PropTask, action: EngineAction, result: TaskResult, userInput: InputProvider diff --git a/app/imports/api/engine/action/applyProperties/applyDamageProperty.ts b/app/imports/api/engine/action/applyProperties/applyDamageProperty.ts index f55272f5..eb6cccf0 100644 --- a/app/imports/api/engine/action/applyProperties/applyDamageProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyDamageProperty.ts @@ -12,7 +12,7 @@ import resolve from '/imports/parser/resolve'; import toString from '/imports/parser/toString'; import { getPropertiesOfType } from '/imports/api/engine/loadCreatures'; 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/userInput/InputProvider'; 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'; diff --git a/app/imports/api/engine/action/applyProperties/applyNoteProperty.ts b/app/imports/api/engine/action/applyProperties/applyNoteProperty.ts index d139c950..655b6654 100644 --- a/app/imports/api/engine/action/applyProperties/applyNoteProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyNoteProperty.ts @@ -1,5 +1,5 @@ import { EngineAction } from '/imports/api/engine/action/EngineActions'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups'; import recalculateInlineCalculations from '/imports/api/engine/action/functions/recalculateInlineCalculations'; import { PropTask } from '/imports/api/engine/action/tasks/Task'; diff --git a/app/imports/api/engine/action/applyProperties/applyRollProperty.ts b/app/imports/api/engine/action/applyProperties/applyRollProperty.ts index ef1d2b2c..120eb88f 100644 --- a/app/imports/api/engine/action/applyProperties/applyRollProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyRollProperty.ts @@ -1,5 +1,5 @@ import { EngineAction } from '/imports/api/engine/action/EngineActions'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; import { applyDefaultAfterPropTasks } from '/imports/api/engine/action/functions/applyTaskGroups'; import { rollAndReduceCalculation } from '/imports/api/engine/action/functions/recalculateCalculation'; import { PropTask } from '/imports/api/engine/action/tasks/Task'; diff --git a/app/imports/api/engine/action/applyProperties/applySavingThrowProperty.ts b/app/imports/api/engine/action/applyProperties/applySavingThrowProperty.ts index f6bbc9cb..e8c53c96 100644 --- a/app/imports/api/engine/action/applyProperties/applySavingThrowProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applySavingThrowProperty.ts @@ -1,6 +1,6 @@ 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 InputProvider from '/imports/api/engine/action/functions/userInput/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'; diff --git a/app/imports/api/engine/action/applyProperties/applyToggleProperty.ts b/app/imports/api/engine/action/applyProperties/applyToggleProperty.ts index ac2a6946..f348e8b3 100644 --- a/app/imports/api/engine/action/applyProperties/applyToggleProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyToggleProperty.ts @@ -1,5 +1,5 @@ import { EngineAction } from '/imports/api/engine/action/EngineActions'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/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'; diff --git a/app/imports/api/engine/action/functions/actionEngineTest.testFn.ts b/app/imports/api/engine/action/functions/actionEngineTest.testFn.ts index 37dd5a77..485347c4 100644 --- a/app/imports/api/engine/action/functions/actionEngineTest.testFn.ts +++ b/app/imports/api/engine/action/functions/actionEngineTest.testFn.ts @@ -8,7 +8,7 @@ import { loadCreature } from '/imports/api/engine/loadCreatures'; import EngineActions, { EngineAction } from '/imports/api/engine/action/EngineActions'; import applyAction from '/imports/api/engine/action/functions/applyAction'; import { LogContent, Mutation, Removal, Update } from '/imports/api/engine/action/tasks/TaskResult'; -import inputProvider from '/imports/api/engine/action/functions/inputProviderForTests.testFn'; +import inputProvider from './userInput/inputProviderForTests.testFn'; /** * Removes all creatures, properties, and creatureVariable documents from the database */ diff --git a/app/imports/api/engine/action/functions/applyAction.ts b/app/imports/api/engine/action/functions/applyAction.ts index 0e00d547..a7b1451f 100644 --- a/app/imports/api/engine/action/functions/applyAction.ts +++ b/app/imports/api/engine/action/functions/applyAction.ts @@ -1,7 +1,8 @@ import { EngineAction } from '/imports/api/engine/action/EngineActions'; import { getSingleProperty } from '/imports/api/engine/loadCreatures'; 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/userInput/InputProvider'; +import saveInputChoices from './userInput/saveInputChoices'; // TODO create a function to get the effective value of a property, // simulating all the result updates in the action so far @@ -17,6 +18,16 @@ export default async function applyAction(action: EngineAction, userInput: Input if (!simulate && stepThrough) throw 'Cannot step through unless simulating'; if (simulate && !userInput) throw 'Must provide a function to get user input when simulating'; + if (action._isSimulation || action._stepThrough) { + console.error('_isSimulation and _stepThrough should not be set on the action, rather call\ + applyAction with the appropriate options'); + } + + // If we are simulating, save the user input choices + if (simulate) { + userInput = saveInputChoices(action, userInput); + } + action._stepThrough = stepThrough; action._isSimulation = simulate; action.taskCount = 0; diff --git a/app/imports/api/engine/action/functions/applyTaskGroups.ts b/app/imports/api/engine/action/functions/applyTaskGroups.ts index 1d378b93..e291595d 100644 --- a/app/imports/api/engine/action/functions/applyTaskGroups.ts +++ b/app/imports/api/engine/action/functions/applyTaskGroups.ts @@ -4,7 +4,7 @@ import { getPropertyChildren, getSingleProperty } from '/imports/api/engine/load import { EngineAction } from '/imports/api/engine/action/EngineActions'; import applyTask from '../tasks/applyTask'; import { PropTask } from '../tasks/Task'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; /** * Get all the child tasks of a given property diff --git a/app/imports/api/engine/action/functions/recalculateCalculation.ts b/app/imports/api/engine/action/functions/recalculateCalculation.ts index 15a217e5..7e01b481 100644 --- a/app/imports/api/engine/action/functions/recalculateCalculation.ts +++ b/app/imports/api/engine/action/functions/recalculateCalculation.ts @@ -9,7 +9,7 @@ import resolve from '/imports/parser/resolve'; import { getEffectiveActionScope } from '/imports/api/engine/action/functions/getEffectiveActionScope'; import { CalculatedField } from '/imports/api/properties/subSchemas/computedField'; import { ResolveLevel } from '/imports/parser/parseTree/NodeFactory'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; import { EngineAction } from '/imports/api/engine/action/EngineActions'; // TODO Redo the work of diff --git a/app/imports/api/engine/action/functions/recalculateInlineCalculations.ts b/app/imports/api/engine/action/functions/recalculateInlineCalculations.ts index b1d9500b..02d7e5e1 100644 --- a/app/imports/api/engine/action/functions/recalculateInlineCalculations.ts +++ b/app/imports/api/engine/action/functions/recalculateInlineCalculations.ts @@ -3,7 +3,7 @@ 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'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; export default async function recalculateInlineCalculations( inlineCalcObj: InlineCalculation, action: EngineAction, diff --git a/app/imports/api/engine/action/functions/InputProvider.ts b/app/imports/api/engine/action/functions/userInput/InputProvider.ts similarity index 95% rename from app/imports/api/engine/action/functions/InputProvider.ts rename to app/imports/api/engine/action/functions/userInput/InputProvider.ts index 51244a25..90f23f57 100644 --- a/app/imports/api/engine/action/functions/InputProvider.ts +++ b/app/imports/api/engine/action/functions/userInput/InputProvider.ts @@ -30,7 +30,7 @@ type InputProvider = { /** * Get the details of a check or save */ - check(suggestedParams: CheckParams): Promise; + //check(suggestedParams: CheckParams): Promise; } export type Advantage = 0 | 1 | -1; diff --git a/app/imports/api/engine/action/functions/userInput/getDeterministicDiceRoller.ts b/app/imports/api/engine/action/functions/userInput/getDeterministicDiceRoller.ts new file mode 100644 index 00000000..b8532d83 --- /dev/null +++ b/app/imports/api/engine/action/functions/userInput/getDeterministicDiceRoller.ts @@ -0,0 +1,28 @@ +import Alea from 'alea'; + +/** + * Return a function that can be be used as InputProvider.rollDice + * this function instance must be used for the entire action + */ +export default function getDeterministicDiceRoller( + actionId: string +): (dice: { number: number, diceSize: number }[]) => Promise { + // Create a random number generator seeded on the ID of the action + if (!actionId) throw new Meteor.Error('Id Required', 'action ID can not be ' + actionId) + const randFrac = Alea(actionId); + return (dice) => { + const results: number[][] = []; + for (const diceRoll of dice) { + const values: number[] = []; + if (diceRoll.number > 100) { + throw new Meteor.Error('Too many dice', 'can only roll up to 100 dice at once'); + } + for (let i = 0; i < diceRoll.number; i++) { + const rolledValue = ~~(randFrac() * diceRoll.diceSize) + 1 + values.push(rolledValue); + } + results.push(values); + } + return Promise.resolve(results); + } +} diff --git a/app/imports/api/engine/action/functions/userInput/getReplayChoicesInputProvider.ts b/app/imports/api/engine/action/functions/userInput/getReplayChoicesInputProvider.ts new file mode 100644 index 00000000..2690612f --- /dev/null +++ b/app/imports/api/engine/action/functions/userInput/getReplayChoicesInputProvider.ts @@ -0,0 +1,26 @@ +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; +import getDeterministicDiceRoller from '/imports/api/engine/action/functions/userInput/getDeterministicDiceRoller'; + +// This assumes the user's choices are in exactly the order they will be requested +// Dice rolls are done fresh, no cheating +export default function getReplayChoicesInputProvider(actionId: string, decisions: any[]): + InputProvider { + const dRoller = getDeterministicDiceRoller(actionId); + const replaySavedInput: InputProvider = { + nextStep() { + return Promise.resolve(); + }, + // To roll dice, ignore the user and use the deterministic dice roller again + rollDice(dice) { + decisions.pop(); + return dRoller(dice); + }, + choose() { + return Promise.resolve(decisions.pop()); + }, + advantage() { + return Promise.resolve(decisions.pop()); + } + } + return replaySavedInput; +} diff --git a/app/imports/api/engine/action/functions/inputProviderForTests.testFn.ts b/app/imports/api/engine/action/functions/userInput/inputProviderForTests.testFn.ts similarity index 98% rename from app/imports/api/engine/action/functions/inputProviderForTests.testFn.ts rename to app/imports/api/engine/action/functions/userInput/inputProviderForTests.testFn.ts index 9b45948b..c2a2a682 100644 --- a/app/imports/api/engine/action/functions/inputProviderForTests.testFn.ts +++ b/app/imports/api/engine/action/functions/userInput/inputProviderForTests.testFn.ts @@ -1,4 +1,4 @@ -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; const inputProviderForTests: InputProvider = { /** diff --git a/app/imports/api/engine/action/functions/userInput/saveInputChoices.ts b/app/imports/api/engine/action/functions/userInput/saveInputChoices.ts new file mode 100644 index 00000000..112b6ee0 --- /dev/null +++ b/app/imports/api/engine/action/functions/userInput/saveInputChoices.ts @@ -0,0 +1,28 @@ +import { EngineAction } from '/imports/api/engine/action/EngineActions'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; + +/** + * Create a new version of the user input function, that saves the user's choices to an array + * before returning them + */ +export default function saveInputChoices(action: EngineAction, userInput: InputProvider): InputProvider { + const newInputProvider: Partial = {}; + + if (!action._choices) { + action._choices = []; + } + + // For every function in the given input provider + for (const key in userInput) { + const oldFn = userInput[key]; + // Make a new function that does the same thing, but saves the result to action._choices + const newFn = (...args) => { + const result = oldFn(...args); + action._choices.push(result); + return result; + } + newInputProvider[key] = newFn; + } + + return newInputProvider as InputProvider; +} diff --git a/app/imports/api/engine/action/methods/runAction.ts b/app/imports/api/engine/action/methods/runAction.ts index 1fd2c531..52e9dc81 100644 --- a/app/imports/api/engine/action/methods/runAction.ts +++ b/app/imports/api/engine/action/methods/runAction.ts @@ -5,6 +5,7 @@ import { assertEditPermission } from '/imports/api/sharing/sharingPermissions'; import { getCreature } from '/imports/api/engine/loadCreatures'; import applyAction from '/imports/api/engine/action/functions/applyAction'; import writeChangedAction from '../functions/writeChangedAction'; +import getReplayChoicesInputProvider from '/imports/api/engine/action/functions/userInput/getReplayChoicesInputProvider'; export const runAction = new ValidatedMethod({ name: 'actions.runAction', @@ -13,23 +14,32 @@ export const runAction = new ValidatedMethod({ type: Object, blackbox: true, }, - userInput: { + decisions: { + type: Array, + }, + 'decisions.$': { type: Object, blackbox: true, - optional: true, }, - stepThrough: { - type: Boolean, - optional: true, - } }).validator(), - run: async function ({ actionId, userInput }: { actionId: string, userInput?: any }) { + run: async function ({ actionId, decisions }: { actionId: string, decisions: any[] }) { + // Get the action const action = await EngineActions.findOneAsync(actionId); - if (!action) throw 'Action not found'; + if (!action) throw new Meteor.Error('not-found', 'Action not found'); + + // Permissions assertEditPermission(getCreature(action.creatureId), this.userId); + + // Keep a copy of the original so that a diff can be done later to store what changed const originalAction = EJSON.clone(action); + + // Replay the user's decisions as user input + const userInput = getReplayChoicesInputProvider(actionId, decisions); + + // Apply the action applyAction(action, userInput); - // Persist changes to the action + + // Persist changes const writePromise = writeChangedAction(originalAction, action); return writePromise; }, diff --git a/app/imports/api/engine/action/tasks/applyCheckTask.ts b/app/imports/api/engine/action/tasks/applyCheckTask.ts index e7fab1af..16084f8a 100644 --- a/app/imports/api/engine/action/tasks/applyCheckTask.ts +++ b/app/imports/api/engine/action/tasks/applyCheckTask.ts @@ -1,6 +1,6 @@ import { getFromScope } from '/imports/api/creature/creatures/CreatureVariables'; import { EngineAction } from '/imports/api/engine/action/EngineActions'; -import InputProvider, { CheckParams } from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider, { CheckParams } from '/imports/api/engine/action/functions/userInput/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'; diff --git a/app/imports/api/engine/action/tasks/applyTask.ts b/app/imports/api/engine/action/tasks/applyTask.ts index 1a9e4e16..ff3ee0fa 100644 --- a/app/imports/api/engine/action/tasks/applyTask.ts +++ b/app/imports/api/engine/action/tasks/applyTask.ts @@ -5,7 +5,7 @@ import applyDamagePropTask from '/imports/api/engine/action/tasks/applyDamagePro import applyItemAsAmmoTask from '/imports/api/engine/action/tasks/applyItemAsAmmoTask'; import { getSingleProperty } from '/imports/api/engine/loadCreatures'; import applyProperties from '/imports/api/engine/action/applyProperties'; -import InputProvider from '/imports/api/engine/action/functions/InputProvider'; +import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider'; // DamagePropTask promises a number of actual damage done export default async function applyTask( diff --git a/app/imports/client/ui/creature/actions/ActionDialog.vue b/app/imports/client/ui/creature/actions/ActionDialog.vue index 6f729382..4737ccaf 100644 --- a/app/imports/client/ui/creature/actions/ActionDialog.vue +++ b/app/imports/client/ui/creature/actions/ActionDialog.vue @@ -5,18 +5,7 @@ Action - + + {{ 'Apply Results' }} + + - {{ actionDone ? 'Apply Results' : 'Start' }} + {{ 'Start' }} @@ -58,11 +56,16 @@ import DialogBase from '/imports/client/ui/dialogStack/DialogBase.vue'; import EngineActions from '/imports/api/engine/action/EngineActions'; import applyAction from '/imports/api/engine/action/functions/applyAction'; import AdvantageInput from '/imports/client/ui/creature/actions/input/AdvantageInput.vue'; +import RollInput from '/imports/client/ui/creature/actions/input/RollInput.vue'; +import getDeterministicDiceRoller from '/imports/api/engine/action/functions/userInput/getDeterministicDiceRoller'; +import LogContent from '/imports/client/ui/log/LogContent.vue'; export default { components: { DialogBase, AdvantageInput, + RollInput, + LogContent, }, props: { actionId: { @@ -89,13 +92,34 @@ export default { }, resultJson() { return JSON.stringify(this.actionResult, null, 2); - } + }, + allLogContent() { + const action = this.actionResult; + const contents = []; + action?.results?.forEach(result => { + result.mutations?.forEach(mutation => { + mutation.contents?.forEach(logContent => { + contents.push(logContent); + }); + }); + }); + return contents; + }, }, meteor: { action() { return EngineActions.findOne(this.actionId); }, }, + watch: { + resultAction(val) { + console.log(val); + } + }, + mounted() { + this.deterministicDiceRoller = getDeterministicDiceRoller(this.actionId); + this.startAction({ stepThrough: false }); + }, methods: { startAction({ stepThrough }) { this.actionBusy = true; @@ -108,6 +132,7 @@ export default { applyAction( this.actionResult, this, { simulate: true, stepThrough } ).then(() => { + console.log('action is done'); this.actionDone = true }); }, @@ -123,6 +148,9 @@ export default { } this.resumeActionFn?.(); }, + finishAction() { + this.$store.dispatch('popDialogStack'); + }, promiseInput() { return new Promise(resolve => { this.resumeActionFn = () => { @@ -143,28 +171,38 @@ export default { this.$store.dispatch('popDialogStack'); }, // inputProvider methods - async rollDice(diceArray) { - console.log({diceArray}); + async rollDice(dice) { + console.log('Waiting for dice roll'); + this.activeInputParams = { + deterministicDiceRoller: this.deterministicDiceRoller, + dice + }; + this.activeInput = 'roll-input'; return this.promiseInput(); }, async nextStep(task) { - console.log({task}); + console.log('waiting for next step'); + console.log({ task }); return this.promiseInput(); }, async choose(choices, quantity) { + console.log('Waiting for choice'); console.log({choices, quantity}); return this.promiseInput(); }, async advantage(suggestedAdvantage) { + console.log('Waiting for advantage'); this.userInput = suggestedAdvantage; this.activeInput = 'advantage-input'; this.userInputReady = true; return this.promiseInput(); }, async check(suggestedParams) { + console.log('Waiting for check'); console.log({ suggestedParams }) return this.promiseInput(); }, } }; +../../../../api/engine/action/functions/userInput/getDeterministicDiceRoller \ No newline at end of file diff --git a/app/imports/client/ui/creature/actions/input/RollInput.vue b/app/imports/client/ui/creature/actions/input/RollInput.vue index 1e2056bb..3d515250 100644 --- a/app/imports/client/ui/creature/actions/input/RollInput.vue +++ b/app/imports/client/ui/creature/actions/input/RollInput.vue @@ -2,7 +2,14 @@
+ > +

+ {{ die.number }}d{{ die.diceSize }} +

+