diff --git a/app/imports/api/creature/actions/applyProperties.js b/app/imports/api/creature/actions/applyProperties.js
index aa6355eb..b6a34f31 100644
--- a/app/imports/api/creature/actions/applyProperties.js
+++ b/app/imports/api/creature/actions/applyProperties.js
@@ -5,6 +5,7 @@ import applyBuff from '/imports/api/creature/actions/applyBuff.js';
import applyDamage from '/imports/api/creature/actions/applyDamage.js';
import applyRoll from '/imports/api/creature/actions/applyRoll.js';
import applyToggle from '/imports/api/creature/actions/applyToggle.js';
+import applySave from '/imports/api/creature/actions/applySave.js';
function applyProperty(options){
let prop = options.prop;
@@ -46,8 +47,7 @@ function applyProperty(options){
applyRoll(options);
break;
case 'savingThrow':
- // applySavingThrow(options);
- break;
+ return applySave(options);
}
return true;
}
diff --git a/app/imports/api/creature/actions/applySave.js b/app/imports/api/creature/actions/applySave.js
new file mode 100644
index 00000000..1773c296
--- /dev/null
+++ b/app/imports/api/creature/actions/applySave.js
@@ -0,0 +1,78 @@
+import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
+import CreaturesProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
+import roll from '/imports/parser/roll.js';
+
+export default function applySave({
+ prop,
+ creature,
+ actionContext,
+ log,
+}){
+ let scope = {
+ ...creature.variables,
+ ...actionContext,
+ };
+ try {
+ // Calculate the DC
+ var {result, errors} = evaluateString(prop.dc, scope, 'reduce');
+ let dc = result;
+ log.content.push({
+ name: prop.name,
+ resultPrefix: ' DC ',
+ result,
+ });
+ if (errors.length) {
+ log.content.push({
+ error: errors.join(', '),
+ });
+ return false;
+ }
+ if (prop.target === 'self'){
+ let save = CreaturesProperties.findOne({
+ 'ancestors.id': creature._id,
+ type: 'skill',
+ skillType: 'save',
+ variableName: prop.stat,
+ removed: {$ne: true},
+ inactive: {$ne: true},
+ });
+ if (!save){
+ log.content.push({
+ error: 'No saving throw found: ' + prop.stat,
+ });
+ return;
+ }
+ let value, values, resultPrefix;
+ if (save.advantage === 1){
+ values = roll(2, 20).sort().reverse();
+ value = values[0];
+ resultPrefix = `Advantage: 1d20 [${values[0]},~~${values[1]}~~] + ${save.value} = `
+ } else if (save.advantage === -1){
+ values = roll(2, 20).sort();
+ value = values[0];
+ resultPrefix = `Disadvantage: 1d20 [${values[0]},~~${values[1]}~~] + ${save.value} = `
+ } else {
+ values = roll(1, 20);
+ value = values[0];
+ resultPrefix = `1d20 [${value}] + ${save.value} = `
+ }
+ actionContext.savingThrowRoll = {value};
+ let result = value + save.value;
+ actionContext.savingThrow = {value: result};
+ let saveSuccess = result >= dc;
+ log.content.push({
+ name: 'Save',
+ resultPrefix,
+ result,
+ details: saveSuccess ? 'Passed' : 'Failed'
+ });
+ return !saveSuccess;
+ } else {
+ // TODO
+ }
+ } catch (e){
+ log.content.push({
+ error: e.toString(),
+ });
+ }
+}
diff --git a/app/imports/api/properties/SavingThrows.js b/app/imports/api/properties/SavingThrows.js
index f24735fc..911dae9f 100644
--- a/app/imports/api/properties/SavingThrows.js
+++ b/app/imports/api/properties/SavingThrows.js
@@ -8,11 +8,22 @@ let SavingThrowSchema = new SimpleSchema ({
type: String,
optional: true,
},
+ // The computed DC
dc: {
type: String,
optional: true,
},
- // The variable name of ability the save to roll
+ // Who this saving throw applies to
+ target: {
+ type: String,
+ defaultValue: 'every',
+ allowedValues: [
+ 'self', // the character who took the action
+ 'each', // rolled once for `each` target
+ 'every', // rolled once and applied to `every` target
+ ],
+ },
+ // The variable name of save to roll
stat: {
type: String,
optional: true,
diff --git a/app/imports/ui/properties/forms/SavingThrowForm.vue b/app/imports/ui/properties/forms/SavingThrowForm.vue
index 1f471a7f..18bc2458 100644
--- a/app/imports/ui/properties/forms/SavingThrowForm.vue
+++ b/app/imports/ui/properties/forms/SavingThrowForm.vue
@@ -8,6 +8,7 @@
@change="change('name', ...arguments)"
/>
+