Attacks can now critical hit. criticalHitTarget overrides the roll required
This commit is contained in:
@@ -4,13 +4,19 @@ export default function applyAttack({
|
|||||||
prop,
|
prop,
|
||||||
log,
|
log,
|
||||||
actionContext,
|
actionContext,
|
||||||
|
creature,
|
||||||
}){
|
}){
|
||||||
let value = roll(1, 20)[0];
|
let value = roll(1, 20)[0];
|
||||||
actionContext.attackRoll = {value};
|
actionContext.attackRoll = {value};
|
||||||
|
let criticalHitTarget = creature.variables.criticalHitTarget &&
|
||||||
|
creature.variables.criticalHitTarget.currentValue || 20;
|
||||||
|
let criticalHit = value >= criticalHitTarget;
|
||||||
|
if (criticalHit) actionContext.criticalHit = {value: true};
|
||||||
let result = value + prop.rollBonusResult;
|
let result = value + prop.rollBonusResult;
|
||||||
actionContext.toHit = {value: result};
|
actionContext.toHit = {value: result};
|
||||||
|
|
||||||
log.content.push({
|
log.content.push({
|
||||||
name: 'To Hit',
|
name: criticalHit ? 'Critical Hit!' : 'To Hit',
|
||||||
resultPrefix: `1d20 [${value}] + ${prop.rollBonusResult} = `,
|
resultPrefix: `1d20 [${value}] + ${prop.rollBonusResult} = `,
|
||||||
result,
|
result,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
import evaluateString from '/imports/api/creature/computation/afterComputation/evaluateString.js';
|
||||||
import dealDamage from '/imports/api/creature/creatureProperties/methods/dealDamage.js';
|
import dealDamage from '/imports/api/creature/creatureProperties/methods/dealDamage.js';
|
||||||
import {insertCreatureLog} from '/imports/api/creature/log/CreatureLogs.js';
|
import {insertCreatureLog} from '/imports/api/creature/log/CreatureLogs.js';
|
||||||
|
import { CompilationContext } from '/imports/parser/parser.js';
|
||||||
|
|
||||||
export default function applyDamage({
|
export default function applyDamage({
|
||||||
prop,
|
prop,
|
||||||
@@ -14,8 +15,19 @@ export default function applyDamage({
|
|||||||
...creature.variables,
|
...creature.variables,
|
||||||
...actionContext,
|
...actionContext,
|
||||||
};
|
};
|
||||||
|
if (targets.length === 1){
|
||||||
|
scope.target = targets[0].variables;
|
||||||
|
}
|
||||||
|
let criticalHit = !!(
|
||||||
|
actionContext.criticalHit &&
|
||||||
|
actionContext.criticalHit.value &&
|
||||||
|
prop.damageType !== 'healing' // Can't critically heal
|
||||||
|
);
|
||||||
|
let context = new CompilationContext({
|
||||||
|
doubleRolls: criticalHit,
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
var {result, errors} = evaluateString(prop.amount, scope, 'reduce');
|
var {result, errors} = evaluateString(prop.amount, scope, 'reduce', context);
|
||||||
if (typeof result !== 'number') {
|
if (typeof result !== 'number') {
|
||||||
log.content.push({
|
log.content.push({
|
||||||
error: errors.join(', '),
|
error: errors.join(', '),
|
||||||
@@ -26,11 +38,13 @@ export default function applyDamage({
|
|||||||
error: e.toString(),
|
error: e.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
let suffix = (criticalHit ? ' critical ' : '') +
|
||||||
|
prop.damageType +
|
||||||
|
(prop.damageType !== 'healing' ? ' damage': '');
|
||||||
|
|
||||||
if (damageTargets && damageTargets.length) {
|
if (damageTargets && damageTargets.length) {
|
||||||
damageTargets.forEach(target => {
|
damageTargets.forEach(target => {
|
||||||
let name = prop.damageType === 'healing' ? 'Healing' : 'Damage';
|
let name = prop.damageType === 'healing' ? 'Healing' : 'Damage';
|
||||||
let suffix = prop.damageType +
|
|
||||||
prop.damageType !== 'healing' ? ' damage': '';
|
|
||||||
if (prop.target === 'each'){
|
if (prop.target === 'each'){
|
||||||
result = evaluateString(prop.amount, scope, 'reduce');
|
result = evaluateString(prop.amount, scope, 'reduce');
|
||||||
}
|
}
|
||||||
@@ -69,7 +83,7 @@ export default function applyDamage({
|
|||||||
log.content.push({
|
log.content.push({
|
||||||
name: prop.damageType === 'healing' ? 'Healing' : 'Damage',
|
name: prop.damageType === 'healing' ? 'Healing' : 'Damage',
|
||||||
result,
|
result,
|
||||||
details: `${prop.damageType}${prop.damageType !== 'healing'? ' damage': ''}`,
|
details: suffix,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,30 +52,29 @@ function applyProperty(options){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function applyProperties({
|
function applyPropertyAndWalkChildren({prop, child, targets, ...options}){
|
||||||
forest,
|
let shouldKeepWalking = applyProperty({ prop, targets, ...options });
|
||||||
creature,
|
if (shouldKeepWalking){
|
||||||
targets,
|
applyProperties({ forest: child.children, targets, ...options,});
|
||||||
actionContext,
|
}
|
||||||
log,
|
}
|
||||||
}){
|
|
||||||
|
export default function applyProperties({ forest, targets, ...options}){
|
||||||
forest.forEach(child => {
|
forest.forEach(child => {
|
||||||
let walkChildren = applyProperty({
|
let prop = child.node;
|
||||||
prop: child.node,
|
if (shouldSplit(prop)){
|
||||||
children: child.children,
|
targets.forEach(target => {
|
||||||
creature,
|
let targets = [target]
|
||||||
targets,
|
applyPropertyAndWalkChildren({ targets, prop, child, ...options});
|
||||||
actionContext,
|
|
||||||
log,
|
|
||||||
});
|
|
||||||
if (walkChildren){
|
|
||||||
applyProperties({
|
|
||||||
forest: child.children,
|
|
||||||
creature,
|
|
||||||
targets,
|
|
||||||
actionContext,
|
|
||||||
log,
|
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
applyPropertyAndWalkChildren({prop, child, targets, ...options});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shouldSplit(prop){
|
||||||
|
if (prop.target === 'each'){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { parse, CompilationContext } from '/imports/parser/parser.js';
|
import { parse, CompilationContext } from '/imports/parser/parser.js';
|
||||||
import ConstantNode from '/imports/parser/parseTree/ConstantNode.js';
|
import ConstantNode from '/imports/parser/parseTree/ConstantNode.js';
|
||||||
|
|
||||||
export default function evaluateString(string, scope, fn = 'compile'){
|
export default function evaluateString(string, scope, fn = 'compile', context){
|
||||||
let errors = [];
|
let errors = [];
|
||||||
if (!string){
|
if (!string){
|
||||||
errors.push('No string provided');
|
errors.push('No string provided');
|
||||||
@@ -18,7 +18,9 @@ export default function evaluateString(string, scope, fn = 'compile'){
|
|||||||
errors.push(e);
|
errors.push(e);
|
||||||
return {result: string, errors};
|
return {result: string, errors};
|
||||||
}
|
}
|
||||||
let context = new CompilationContext();
|
if (!context){
|
||||||
|
context = new CompilationContext({});
|
||||||
|
}
|
||||||
let result = node[fn](scope, context);
|
let result = node[fn](scope, context);
|
||||||
if (result instanceof ConstantNode){
|
if (result instanceof ConstantNode){
|
||||||
return {result: result.value, errors: context.errors}
|
return {result: result.value, errors: context.errors}
|
||||||
|
|||||||
Reference in New Issue
Block a user