2025-05-28 15:36:51 -07:00

86 lines
3.5 KiB
JavaScript

import { AbilityAccessors } from '../Ability';
import { RuleDataAccessors } from '../RuleData';
import { getInitialMaxUses, getNumberUsed, getOperator, getStatModifierUsesId, getUseProficiencyBonus, getProficiencyBonusOperator, } from './accessors';
import { EntityLimitedUseScaleOperatorEnum } from './constants';
import { isLimitedUseContract } from './utils';
/**
*
* @param limitedUse
* @param abilityLookup
* @param ruleData
* @param proficiencyBonus
*/
export function deriveMaxUses(limitedUse, abilityLookup, ruleData, proficiencyBonus) {
let initialMaxUses = getInitialMaxUses(limitedUse);
let minimumUses = RuleDataAccessors.getMinimumLimitedUseMaxUse(ruleData);
const statModifierUsesId = getStatModifierUsesId(limitedUse);
let scaledMaxUses = 0;
// If we are using a stat modifier
if (statModifierUsesId) {
const ability = abilityLookup[statModifierUsesId];
const abilityModifier = AbilityAccessors.getModifier(ability);
if (abilityModifier !== null) {
scaledMaxUses = abilityModifier;
// If it uses the multiplication operator, the min uses is the multiplier, there is no
// fixed value anymore since it is the multiplier now
if (isLimitedUseContract(limitedUse) &&
getOperator(limitedUse) === EntityLimitedUseScaleOperatorEnum.MULTIPLICATION) {
scaledMaxUses *= initialMaxUses;
minimumUses = initialMaxUses;
initialMaxUses = 0;
}
}
// If proficiency bonus flag is turned on
if (isLimitedUseContract(limitedUse) && getUseProficiencyBonus(limitedUse)) {
// If we are multiplying the proficiency bonus
if (getProficiencyBonusOperator(limitedUse) === EntityLimitedUseScaleOperatorEnum.MULTIPLICATION) {
// If we need to add the initial bonus, do that now before we reset it
// for the multiplication math
if (getOperator(limitedUse) === EntityLimitedUseScaleOperatorEnum.ADDITION) {
scaledMaxUses += initialMaxUses;
}
scaledMaxUses *= proficiencyBonus;
minimumUses = initialMaxUses;
initialMaxUses = 0;
}
else {
// then we are adding the proficiency bonus
scaledMaxUses += proficiencyBonus;
}
}
}
else {
// Not using stat modifier, check for proficiency bonus use
if (isLimitedUseContract(limitedUse) && getUseProficiencyBonus(limitedUse)) {
// If proficiency bonus flag is turned on
if (getProficiencyBonusOperator(limitedUse) === EntityLimitedUseScaleOperatorEnum.MULTIPLICATION) {
scaledMaxUses = initialMaxUses * proficiencyBonus;
minimumUses = initialMaxUses;
initialMaxUses = 0;
}
else {
// Add proficiency bonus
scaledMaxUses += proficiencyBonus;
}
}
}
return Math.max(minimumUses, initialMaxUses + scaledMaxUses);
}
/**
*
* @param limitedUse
* @param abilityLookup
* @param ruleData
*/
export function deriveHasUsesAvailable(limitedUse, abilityLookup, ruleData, proficiencyBonus) {
if (!limitedUse) {
return true;
}
const maxUses = deriveMaxUses(limitedUse, abilityLookup, ruleData, proficiencyBonus);
const numberUsed = getNumberUsed(limitedUse);
if (numberUsed < maxUses) {
return true;
}
return false;
}