swade-mb-helpers/macros/boost-lower-trait.js

159 lines
4.3 KiB
JavaScript

swadeMBHelpers.runOnTargetOrSelectedTokens(main)
async function main (tokens) {
let traitOptions = [
'Agility', 'Smarts', 'Spirit', 'Strength', 'Vigor'
]
const allSkills = []
const traits = {}
for (const traitName of traitOptions) {
const lower = traitName.toLowerCase()
traits[traitName] = {
name: traitName,
type: 'attribute',
modkey: `system.attributes.${lower}.die.modifier`,
diekey: `system.attributes.${lower}.die.sides`
}
}
const tokenList = tokens.map(t => t.name).join(', ')
for (const token of tokens) {
const skills = token.actor.items.filter(item => item.type === 'skill')
for (const skill of skills) {
const name = skill.name
traits[name] = {
type: 'skill',
name,
modkey: `@Skill{${name}}[system.die.modifier]`,
diekey: `@Skill{${name}}[system.die.sides]`
}
if (name !== 'Unskilled' && !allSkills.find(v => v === name)) {
allSkills.push(name)
}
}
}
traitOptions = traitOptions.concat(allSkills.sort())
const menuOptions = {
title: 'Boost/Lower Trait',
defaultButton: 'Cancel',
options: {}
}
const menuData = {
inputs: [
{ type: 'header', label: 'Boost/Lower Trait' },
{ type: 'info', label: `Affected Tokens ${tokenList}` },
{ type: 'select', label: 'Trait', options: traitOptions },
{ type: 'info', label: 'Boost or Lower?' },
{ type: 'radio', label: 'Boost', options: ['isBoost', true] },
{ type: 'radio', label: 'Lower', options: ['isBoost', false] },
{ type: 'checkbox', label: 'Greater', options: false },
{ type: 'checkbox', label: 'Strong (lower only)', options: false }
],
buttons: [
{ label: 'Apply', value: 'apply' },
{ label: 'Apply with raise', value: 'raise' },
{ label: 'Cancel', value: 'cancel' }
]
}
const { buttons, inputs } = await warpgate.menu(menuData, menuOptions)
if (buttons && buttons !== 'cancel') {
const options = {
action: buttons,
name: inputs[2],
trait: traits[inputs[2]],
direction: inputs[4] || inputs[5],
greater: inputs[6],
strong: inputs[7]
}
createEffect(tokens, options)
}
}
const UPICON = 'icons/magic/life/cross-embers-glow-yellow-purple.webp'
const DOWNICON = 'icons/magic/movement/chevrons-down-yellow.webp'
async function createEffect (tokens, options) {
const raise = (options.action === 'raise')
const icon = (options.direction === 'Boost' ? UPICON : DOWNICON)
let namePart = `${options.direction} ${options.trait.name}`
const mode = CONST.ACTIVE_EFFECT_MODES.ADD
const mods = []
if (options.strong && options.direction === 'Lower') {
mods.push('strong')
}
if (options.greater) {
mods.push('greater')
}
if (mods.length > 0) {
namePart = `${namePart} (${mods.join(', ')})`
}
const minorEffect = {
icon,
id: `minor ${namePart}`,
label: `minor ${namePart}`,
duration: { rounds: 5 },
flags: {
swade: {
expiration: CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.EndOfTurnPrompt,
loseTurnOnHold: true
}
},
changes: [
{
key: options.trait.diekey,
mode,
value: (options.direction === 'Boost' ? '+2' : '-2'),
priority: 0
}
]
}
const majorEffect = {
icon,
id: `major ${namePart}`,
label: `major ${namePart}`,
duration: { rounds: 5 },
flags: {
swade: {
expiration: CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.EndOfTurnPrompt,
loseTurnOnHold: true
}
},
changes: [
{
key: options.trait.diekey,
mode,
value: (options.direction === 'Boost' ? '+2' : '-2'),
priority: 0
}
]
}
if (options.direction === 'Lower' && options.greater === 'Greater') {
minorEffect.changes.push({
key: options.trait.modkey,
mode,
value: '-2',
priority: 0
})
}
const mutate = {
embedded: {
ActiveEffect: {
}
}
}
mutate.embedded.ActiveEffect[minorEffect.id] = minorEffect
if (raise) {
mutate.embedded.ActiveEffect[majorEffect.id] = majorEffect
}
const mutateOptions = {
comparisonKeys: { ActiveEffect: 'label' },
name: namePart,
permanent: true,
description: namePart
}
for (const token of tokens) {
await warpgate.mutate(token.document, mutate, {}, mutateOptions)
}
}