159 lines
4.3 KiB
JavaScript
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 !== '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)
|
|
}
|
|
}
|