From 140381e1d137d80e915c274685a1980c64f5862a Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 1 Jun 2024 23:57:57 -0500 Subject: [PATCH] add sloth/speed --- src/module/powers/basePowers.js | 5 + src/module/powers/powers.js | 5 + src/module/powers/slothSpeed.js | 183 ++++++++++++++++++++++++++++++++ src/templates/powerDialog.html | 2 +- 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 src/module/powers/slothSpeed.js diff --git a/src/module/powers/basePowers.js b/src/module/powers/basePowers.js index 63c6a36..a174f42 100644 --- a/src/module/powers/basePowers.js +++ b/src/module/powers/basePowers.js @@ -108,6 +108,7 @@ export class PowerFormApplication extends FormApplication { data.recipients.count = this.powerEffect.additionalRecipientCount; data.recipients.total = data.recipients.cost * data.recipients.count; data.recipients.epic = this.powerEffect.additionalRecipientsIsEpic; + data.recipients.text = this.powerEffect.additionalRecipientText; } return data; } @@ -217,6 +218,10 @@ export class PowerEffect { return false; } + get additionalRecipientText() { + return 'Additional Recipients'; + } + get additionalRecipientCount() { if (!this.hasAdditionalRecipients) { return 0; diff --git a/src/module/powers/powers.js b/src/module/powers/powers.js index f4e64b2..723b263 100644 --- a/src/module/powers/powers.js +++ b/src/module/powers/powers.js @@ -49,6 +49,7 @@ import { ResurrectionEffect } from './resurrection.js'; import { SanctuaryEffect } from './sanctuary.js'; import { ScryingEffect } from './scrying.js'; import { ShapeChangeEffect } from './shapeChange.js'; +import { SlothSpeedEffect } from './slothSpeed.js'; const PowerClasses = { 'arcane-protection': ArcaneProtectionEffect, @@ -112,6 +113,10 @@ const PowerClasses = { scrying: ScryingEffect, 'shape-change': ShapeChangeEffect, shrink: GrowthShrinkEffect, + slothspeed: SlothSpeedEffect, + 'sloth-speed': SlothSpeedEffect, + sloth: SlothSpeedEffect, + speed: SlothSpeedEffect, }; /* ---------------------------------------------------------------- */ diff --git a/src/module/powers/slothSpeed.js b/src/module/powers/slothSpeed.js new file mode 100644 index 0000000..5f41f2f --- /dev/null +++ b/src/module/powers/slothSpeed.js @@ -0,0 +1,183 @@ +import { PowerEffect } from './basePowers.js'; + +export class SlothSpeedEffect extends PowerEffect { + get name() { + return 'Sloth/Speed'; + } + + get hasAdditionalRecipients() { + return (this?.data?.direction ?? 'Speed') == 'Speed'; + } + + get additionalRecipientCost() { + return 1; + } + + get additionalRecipientText() { + return `${super.additionalRecipientText} (speed only)`; + } + + get icon() { + return this?.data?.direction === 'Sloth' + ? 'icons/magic/control/debuff-energy-snare-brown.webp' + : 'icons/skills/movement/figure-running-gray.webp'; + } + + get duration() { + return this?.data?.direction === 'Sloth' ? 0 : 5; + } + + get isTargeted() { + return true; + } + + get basePowerPoints() { + return 2; + } + + get hasAoe() { + return true; + } + + get modifiers() { + const mods = super.modifiers; + mods.push({ + sortOrder: -2, + name: 'Sloth or Speed?', + id: 'direction', + type: 'radio', + default: 'Sloth', + epic: false, + choices: { Sloth: 'Sloth', Speed: 'Speed' }, + effects: { Sloth: null, Speed: null }, + values: { Sloth: 0, Speed: 0 }, + }); + mods.push({ + type: 'select', + default: 'none', + name: 'Area of Effect (Sloth Only)', + id: 'aoe', + epic: false, + choices: { + none: 'None', + mbt: 'Medium Blast Template', + lbt: 'Large Blast Template', + }, + effects: { none: null, mbt: null, lbt: null }, + values: { none: 0, mbt: 2, lbt: 3 }, + }); + mods.push({ + name: 'Dash (Speed only)', + id: 'dash', + type: 'checkbox', + default: false, + epic: false, + effect: false, + value: 2, + }); + mods.push({ + name: 'Quickness (Speed only)', + id: 'quickness', + type: 'checkbox', + default: false, + epic: false, + effect: false, + value: 2, + }); + mods.push({ + name: 'Strong (Sloth only)', + id: 'strong', + type: 'checkbox', + default: false, + value: 1, + epic: false, + effect: false, + }); + return mods; + } + + getPrimaryEffectChanges() { + const changes = [ + { + key: 'system.stats.speed.value', + value: -1, + priority: 0, + mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD, + }, + ]; + return [...super.getPrimaryEffectChanges(), ...changes]; + } + + async primaryDocForTarget(doc, target) { + const newDoc = await super.primaryDocForTarget(doc, target); + const modValue = this.data.direction === 'Sloth' ? -0.5 : 1; + const idx = newDoc.changes.length - 1; + newDoc.changes[idx].value = Math.ceil(target.actor.system.stats.speed.value * modValue); + return newDoc; + } + + get effectName() { + let name = `${this.data.raise ? 'major' : 'minor'} ${this.data.direction}`; + const parts = []; + if (this.data.direction === 'Sloth' && this.data.strong) { + parts.push('strong'); + } + if (this.data.direction === 'Speed') { + if (this.data.dash) { + parts.push('dash'); + } + if (this.data.quickness) { + parts.push('quickness'); + } + } + if (parts.length > 0) { + name = `${name} (${parts.join(', ')})`; + } + return name; + } + + get description() { + let desc = super.description; + if (this.data.direction === 'Sloth') { + desc += `

Target's pace is reduced by half (round up). `; + if (this.data.raise) { + desc += `For the target, movement is also an action. `; + } + desc += `

The target tries to shake off the effects at the end of + subsequent turns with a Spirit roll${this.data.strong ? ' at -2' : ''}.

`; + } else { + desc += `

Target's pace is doubled. `; + if (this.data.raise) { + desc += `The target also ignores the -2 running penalty. `; + } + if (this.data.dash) { + desc += `When running, the target runs as if they rolled the maximum on + their running die. `; + } + if (this.data.quickness) { + desc += `The target's total Multi-Action penalty each turn is reduced by 2.`; + } + desc += '

'; + } + return desc; + } + + get primaryEffectButtons() { + const buttons = super.primaryEffectButtons; + if (this.data.direction === 'Sloth') { + const mods = []; + if (this.data.strong) { + mods.push({ label: 'Strong', value: -2 }); + } + buttons.push({ + label: `Shake off (Spirit${this.data.strong ? ' -2' : ''})`, + type: 'trait', + rollType: 'attribute', + rollDesc: 'Spirit', + flavor: 'Success shakes off the effects of sloth', + mods, + }); + } + return buttons; + } +} diff --git a/src/templates/powerDialog.html b/src/templates/powerDialog.html index 46d5c99..aea6d96 100644 --- a/src/templates/powerDialog.html +++ b/src/templates/powerDialog.html @@ -19,7 +19,7 @@ Targets: {{#each targets}}{{#if @index}}, {{/if}}{{{this}}}{{/each}} {{#if recipients.cost}} -
({{#if recipients.epic}}⭐ {{/if}}Additional Recipients +
({{#if recipients.epic}}⭐ {{/if}}{{recipients.text}} {{recipients.cost}}pp each × {{recipients.count}} = {{recipients.total}}) {{/if}}