Refactored computation into folders
This commit is contained in:
159
app/imports/api/creature/computation/engine/combineStat.js
Normal file
159
app/imports/api/creature/computation/engine/combineStat.js
Normal file
@@ -0,0 +1,159 @@
|
||||
import computeStat from '/imports/api/creature/computation/engine/computeStat.js';
|
||||
import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js';
|
||||
import evaluateCalculation from '/imports/api/creature/computation/engine/evaluateCalculation.js';
|
||||
|
||||
export default function combineStat(stat, aggregator, memo){
|
||||
if (stat.type === 'attribute'){
|
||||
combineAttribute(stat, aggregator, memo);
|
||||
} else if (stat.type === 'skill'){
|
||||
combineSkill(stat, aggregator, memo);
|
||||
} else if (stat.type === 'damageMultiplier'){
|
||||
combineDamageMultiplier(stat, memo);
|
||||
}
|
||||
}
|
||||
|
||||
function getAggregatorResult(stat, aggregator){
|
||||
let result = (aggregator.base + aggregator.add) * aggregator.mul;
|
||||
if (result < aggregator.min) {
|
||||
result = aggregator.min;
|
||||
}
|
||||
if (result > aggregator.max) {
|
||||
result = aggregator.max;
|
||||
}
|
||||
if (aggregator.set !== undefined) {
|
||||
result = aggregator.set;
|
||||
}
|
||||
if (!stat.decimal && Number.isFinite(result)){
|
||||
result = Math.floor(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function combineAttribute(stat, aggregator, memo){
|
||||
stat.value = getAggregatorResult(stat, aggregator);
|
||||
stat.baseValue = aggregator.statBaseValue;
|
||||
stat.baseValueErrors = aggregator.baseValueErrors;
|
||||
if (stat.attributeType === 'spellSlot'){
|
||||
let {
|
||||
result,
|
||||
context,
|
||||
dependencies
|
||||
} = evaluateCalculation({
|
||||
string: stat.spellSlotLevelCalculation,
|
||||
memo,
|
||||
prop: stat,
|
||||
});
|
||||
stat.spellSlotLevelValue = result.value;
|
||||
stat.spellSlotLevelErrors = context.errors;
|
||||
stat.dependencies.push(...dependencies);
|
||||
}
|
||||
stat.currentValue = stat.value - (stat.damage || 0);
|
||||
// Ability scores get modifiers
|
||||
if (stat.attributeType === 'ability') {
|
||||
stat.modifier = Math.floor((stat.currentValue - 10) / 2);
|
||||
} else {
|
||||
stat.modifier = undefined;
|
||||
}
|
||||
// Hit dice get constitution modifiers
|
||||
stat.constitutionMod = undefined;
|
||||
if (stat.attributeType === 'hitDice') {
|
||||
let conStat = memo.statsByVariableName['constitution'];
|
||||
if (conStat && 'modifier' in conStat){
|
||||
stat.constitutionMod = conStat.modifier;
|
||||
stat.dependencies.push(conStat._id, ...conStat.dependencies);
|
||||
}
|
||||
}
|
||||
// Stats that have no effects can be hidden based on a sheet setting
|
||||
stat.hide = aggregator.hasNoEffects &&
|
||||
stat.baseValue === undefined ||
|
||||
undefined
|
||||
}
|
||||
|
||||
function combineSkill(stat, aggregator, memo){
|
||||
// Skills are based on some ability Modifier
|
||||
let ability = memo.statsByVariableName[stat.ability]
|
||||
if (stat.ability && ability){
|
||||
if (!ability.computationDetails.computed){
|
||||
computeStat(ability, memo);
|
||||
}
|
||||
stat.abilityMod = ability.modifier;
|
||||
stat.dependencies.push(ability._id, ...ability.dependencies);
|
||||
}
|
||||
// Combine all the child proficiencies
|
||||
stat.proficiency = stat.baseProficiency || 0;
|
||||
for (let i in stat.computationDetails.proficiencies){
|
||||
let prof = stat.computationDetails.proficiencies[i];
|
||||
applyToggles(prof, memo);
|
||||
if (
|
||||
!prof.computationDetails.disabledByToggle &&
|
||||
prof.value > stat.proficiency
|
||||
){
|
||||
stat.proficiency = prof.value;
|
||||
stat.dependencies.push(prof._id, ...prof.dependencies);
|
||||
}
|
||||
}
|
||||
// Get the character's proficiency bonus to apply
|
||||
let profBonusStat = memo.statsByVariableName['proficiencyBonus'];
|
||||
let profBonus = profBonusStat && profBonusStat.value;
|
||||
|
||||
if (typeof profBonus !== 'number' && memo.statsByVariableName['level']){
|
||||
let level = memo.statsByVariableName['level'].value;
|
||||
profBonus = Math.ceil(level / 4) + 1;
|
||||
if (level._id) stat.dependencies.push(level._id);
|
||||
if (level.dependencies) stat.dependencies.push(...level.dependencies);
|
||||
} else {
|
||||
stat.dependencies.push(profBonusStat._id, ...profBonusStat.dependencies);
|
||||
}
|
||||
// Multiply the proficiency bonus by the actual proficiency
|
||||
profBonus *= stat.proficiency;
|
||||
// Base value
|
||||
stat.baseValue = aggregator.statBaseValue;
|
||||
stat.baseValueErrors = aggregator.baseValueErrors;
|
||||
// Combine everything to get the final result
|
||||
let result = (aggregator.base + stat.abilityMod + profBonus + aggregator.add) * aggregator.mul;
|
||||
if (result < aggregator.min) result = aggregator.min;
|
||||
if (result > aggregator.max) result = aggregator.max;
|
||||
if (aggregator.set !== undefined) {
|
||||
result = aggregator.set;
|
||||
}
|
||||
if (Number.isFinite(result)){
|
||||
result = Math.floor(result);
|
||||
}
|
||||
stat.value = result;
|
||||
// Advantage/disadvantage
|
||||
if (aggregator.advantage && !aggregator.disadvantage){
|
||||
stat.advantage = 1;
|
||||
} else if (aggregator.disadvantage && !aggregator.advantage){
|
||||
stat.advantage = -1;
|
||||
} else {
|
||||
stat.advantage = 0;
|
||||
}
|
||||
// Passive bonus
|
||||
stat.passiveBonus = aggregator.passiveAdd;
|
||||
// conditional benefits
|
||||
stat.conditionalBenefits = aggregator.conditional;
|
||||
// Roll bonuses
|
||||
stat.rollBonus = aggregator.rollBonus;
|
||||
// Forced to fail
|
||||
stat.fail = aggregator.fail;
|
||||
// Rollbonus
|
||||
stat.rollBonuses = aggregator.rollBonus;
|
||||
// Hide
|
||||
stat.hide = aggregator.hasNoEffects &&
|
||||
stat.baseValue === undefined &&
|
||||
stat.proficiency == 0 ||
|
||||
undefined;
|
||||
}
|
||||
|
||||
function combineDamageMultiplier(stat){
|
||||
if (stat.immunityCount) return 0;
|
||||
let result;
|
||||
if (stat.ressistanceCount && !stat.vulnerabilityCount){
|
||||
result = 0.5;
|
||||
} else if (!stat.ressistanceCount && stat.vulnerabilityCount){
|
||||
result = 2;
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
stat.value = result;
|
||||
}
|
||||
Reference in New Issue
Block a user