From b5b0ad01f6c45a15677be55ee3736b12af08780c Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sun, 12 May 2024 23:19:36 -0500 Subject: [PATCH] finish base power overhaul --- src/module/powers/arcaneProtection.js | 4 +- src/module/powers/basePowers.js | 187 +++++++++++--------------- src/templates/powerDialog.html | 28 +++- 3 files changed, 100 insertions(+), 119 deletions(-) diff --git a/src/module/powers/arcaneProtection.js b/src/module/powers/arcaneProtection.js index 20444bc..46e7474 100644 --- a/src/module/powers/arcaneProtection.js +++ b/src/module/powers/arcaneProtection.js @@ -40,7 +40,7 @@ export class ArcaneProtectionEffect extends PowerEffect { } get _penaltyAmount() { - return (this.data.raise ? -4 : -2) + (this.data.mods.has('greater') ? -2 : 0); + return (this.data.raise ? -4 : -2) + (this.data.greater ? -2 : 0); } get description() { @@ -51,7 +51,7 @@ export class ArcaneProtectionEffect extends PowerEffect { } get effectName() { - const greater = this.data.mods.has('greater'); + const greater = this.data.greater; const raise = this.data.raise; const amount = this._penaltyAmount; return `${greater ? 'Greater ' : ''}Arcane Protection (${raise ? 'major, ' : ''}${amount})`; diff --git a/src/module/powers/basePowers.js b/src/module/powers/basePowers.js index 3a8d51a..06f49c4 100644 --- a/src/module/powers/basePowers.js +++ b/src/module/powers/basePowers.js @@ -58,19 +58,31 @@ export class PowerFormApplication extends FormApplication { icon: this.powerEffect.icon, basePowerPoints: this.powerEffect.basePowerPoints, modifiers, - additionalRecipientCost: 0, + recipients: { + cost: 0, + number: 0, + total: 0, + }, targets: [], buttons: this.powerEffect.menuButtons, }; if (this.powerEffect.isTargeted) { data.targets = this.powerEffect.targets.map((t) => t.name); } + if (this.powerEffect.hasAdditionalRecipients && this.powerEffect.targets.length > 1) { + data.recipients.cost = this.powerEffect.additionalRecipientCost; + data.recipients.count = this.powerEffect.targets.length - 1; + data.recipients.total = data.recipients.cost * data.recipients.count; + } return data; } async _updateObject(ev, formData) { formData.submit = ev?.submitter?.value ?? 'cancel'; - console.log(ev, formData); + if (formData.submit !== 'cancel') { + this.powerEffect.formData = formData; + await this.powerEffect.applyEffect(); + } } } @@ -218,6 +230,7 @@ export class PowerEffect { effects: { none: null, glow: { + name: 'Glow', icon: 'icons/magic/light/orb-shadow-blue.webp', changes: [ { @@ -229,6 +242,7 @@ export class PowerEffect { ], }, shroud: { + name: 'Shroud', icon: 'icons/magic/perception/shadow-stealth-eyes-purple.webp', changes: [ { @@ -244,6 +258,17 @@ export class PowerEffect { effect: true, }); if (this.isDamaging) { + mods.push({ + name: 'Armor Piercing', + id: 'ap', + type: 'select', + default: 'none', + choices: { none: 'None', 2: 'AP 2', 4: 'AP 4', 6: 'AP 6' }, + values: { none: 0, 2: 1, 4: 2, 6: 3 }, + effects: { none: null, 2: null, 4: null, 6: null }, + epic: false, + isGlobal: true, + }); mods.push({ name: 'Lingering Damage', id: 'lingeringdamage', @@ -269,7 +294,7 @@ export class PowerEffect { name: 'Hinder/Hurry', id: 'hinderhurry', type: 'radio', - default: false, + default: 'none', value: 1, epic: false, effect: true, @@ -279,6 +304,7 @@ export class PowerEffect { effects: { none: null, hinder: { + name: 'Hinder', icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp', changes: [ { @@ -290,6 +316,7 @@ export class PowerEffect { ], }, hurry: { + name: 'Hurry', icon: 'icons/skills/movement/feet-winged-sandals-tan.webp', changes: [ { @@ -314,59 +341,25 @@ export class PowerEffect { isGlobal: true, }); } - return mods; - } - - get menuData() { - return { - inputs: this.menuInputs, - buttons: this.menuButtons, - }; - } - - get menuInputs() { - const inputs = [ - { type: 'header', label: `${this.name} Effect` }, - { - type: 'info', - label: `Apply ${this.name} Effect (base cost ${this.basePowerPoints} pp)`, - }, - ]; - if (this.isTargeted) { - let label = `Targets: ${this.targets.map((t) => t.name).join(',')}`; - if (this.targets.length > 1 && this.hasAdditionalRecipients) { - label += ` (${this.targets.length - 1} additional recipients ` + `+${this.additionalRecipientCost} ea.)`; - } - inputs.push({ type: 'info', label }); - } - for (const mod of this.modifiers) { - inputs.push({ - type: 'checkbox', - label: `${mod.epic ? '⭐ ' : ''}${mod.name} ` + `(${mod.value >= 0 ? '+' : ''}${mod.value})`, - }); - } - if (this.isDamaging) { - inputs.push({ - type: 'select', - label: 'Armor Piercing', - options: [ - { html: 'None', value: 0, selected: true }, - { html: 'AP 2 (+1)', value: 1, selected: false }, - { html: 'AP 4 (+2)', value: 2, selected: false }, - { html: 'AP 6 (+3)', value: 3, selected: false }, - ], - }); - } - inputs.push({ + mods.push({ type: 'select', - label: 'Range', - options: [ - { html: 'Normal Range', value: 0, selected: true }, - { html: 'Range ×2 (+1)', value: 1, selected: false }, - { html: 'Range ×3 (+2)', value: 2, selected: false }, - ], + default: 0, + name: 'Range', + id: 'range', + choices: { + normal: 'Normal Range', + x2: 'Range ×2', + x3: 'Range ×3', + }, + values: { + normal: 0, + x2: 1, + x3: 2, + }, + isGlobal: true, + effects: { normal: null, x2: null, x3: null }, }); - return inputs; + return mods; } get menuButtons() { @@ -379,62 +372,33 @@ export class PowerEffect { return data; } - get menuOptions() { - return { - title: `${this.name} Effect`, - defaultButton: 'Cancel', - options: {}, - }; - } - render() { let app = new PowerFormApplication(this).render(true); } async applyEffect() { - log('Power Effect called'); - log(this); - } - - async powerEffect() { - const { buttons, inputs } = await warpgate.menu(this.menuData, this.menuOptions); - if (buttons && buttons !== 'cancel') { - this.data.button = buttons; - this.data.values = inputs; - await this.parseValues(); - await this.apply(); - await this.sideEffects(); - await this.chatMessage(); - } + await this.parseValues(); + await this.apply(); + await this.sideEffects(); } async parseValues() { - this.data.rawValues = deepClone(this.data.values); - this.data.raise = this.data.button === 'raise'; - for (let i = 0; i < 2; i++) { - this.data.values.shift(); - } - if (this.isTargeted) { - this.data.values.shift(); - } - this.data.mods = new Set(); + this.data.raise = this.formData.submit === 'raise'; + this.data.button = this.formData.submit; for (const mod of this.modifiers) { - const modEnabled = this.data.values.shift(); - if (modEnabled) { - this.data.mods.add(mod.id); - } + this.data[mod.id] = this.formData[mod.id]; } - if (this.isDamaging) { - this.data.armorPiercing = this.data.values.shift(); - } - this.data.range = this.data.values.shift(); } async createSecondaryEffects(maintId) { const docs = []; for (const mod of this.modifiers) { - if (this.data.mods.has(mod.id) && mod.effect) { - const doc = this.createEffectDocument(mod.icon, mod.name, mod.changes); + const modValue = this.data[mod.id]; + if (modValue && (mod?.effect || (mod?.effects?.[modValue] ?? false))) { + const icon = 'effects' in mod ? mod.effects[modValue].icon : mod.icon; + const name = 'effects' in mod ? mod.effects[modValue].name : mod.name; + const changes = 'effects' in mod ? mod.effects[modValue].changes : mod.changes; + const doc = this.createEffectDocument(icon, name, changes); if (this.duration === 0 && !this.usePrimaryEffect) { // set secondary effects of instant spells to expire on victim's next // turn @@ -524,7 +488,7 @@ export class PowerEffect { } async sideEffects() { - if (this.data.mods.has('fatigue') && this.isTargeted) { + if (this.data.fatigue && this.isTargeted) { for (const target of this.targets) { const actor = target.actor; const update = { @@ -544,17 +508,18 @@ export class PowerEffect { get powerPoints() { let total = this.basePowerPoints; for (const mod of this.modifiers) { - if (this.data.mods.has(mod.id)) { - total += mod.value; + const modValue = this.data[mod.id]; + if (modValue) { + if ('values' in mod) { + total += mod.values[modValue]; + } else { + total += mod.value; + } } } if (this.targets.length > 1 && this.hasAdditionalRecipients) { total += (this.targets.length - 1) * this.additionalRecipientCost; } - total += this.data.range; - if (this.isDamaging) { - total += this.data.armorPiercing; - } return total; } @@ -563,26 +528,26 @@ export class PowerEffect { if (this.hasAdditionalRecipients && this.targets.length > 1) { list.push(`${this.targets.length - 1} Additional Recipients`); } - if (this.data.mods.has('adaptable')) { + if (this.data.adaptable) { list.push('Different Trapping (Adaptable Caster)'); } - if (this.data.mods.has('fatigue')) { + if (this.data.fatigue) { list.push('Fatigue (applied to targets'); } - if (this.data.mods.has('heavyweapon')) { + if (this.data.heavyweapon) { list.push('Heavy Weapon'); } - if (this.data.mods.has('lingeringdamage')) { + if (this.data.lingeringdamage) { list.push('Lingering Damage'); } - if (this.data.mods.has('selective')) { + if (this.data.selective) { list.push('Selective'); } - if (this.isDamaging && this.data.armorPiercing > 0) { - list.push(`AP ${this.data.armorPiercing * 2}`); + if (this.isDamaging && this.data.ap > 0) { + list.push(`AP ${this.data.ap}`); } - if (this.data.range > 0) { - list.push(`Range ×${this.data.range + 1}`); + if (this.data.range != 'none') { + list.push(`Range ${this.data.range}`); } return list; } diff --git a/src/templates/powerDialog.html b/src/templates/powerDialog.html index 417d539..284015b 100644 --- a/src/templates/powerDialog.html +++ b/src/templates/powerDialog.html @@ -6,17 +6,33 @@

Apply the affects of {{name}}.

+ {{#if targets.length}}

- {{#if targets.length}} Targets: {{#each targets}}{{#if @index}}, {{/if}}{{this}}{{/each}} {{/if}} + Targets: + {{#each targets}}{{#if @index}}, {{/if}}{{this}}{{/each}} + {{#if recipients.cost}} +
(Additional Recipients {{recipients.cost}}pp each × {{recipients.count}} = {{recipients.total}}) + {{/if}}

+ {{/if}} {{#each modifiers}}
{{#if isCheckbox}} - - - {{/if}} {{#if isRadio}} - - {{radioBoxes id choices checked=default}} {{/if}} + + + {{/if}} + {{#if isSelect}} + + + {{/if}} + {{#if isRadio}} + + {{radioBoxes id choices checked=default}} + {{/if}}
{{/each}}