diff --git a/scripts/allPowers.js b/scripts/basePowers.js similarity index 65% rename from scripts/allPowers.js rename to scripts/basePowers.js index 29cf1ee..1e547e3 100644 --- a/scripts/allPowers.js +++ b/scripts/basePowers.js @@ -2,7 +2,7 @@ import { moduleName } from './globals.js' const MAINTAIN_ICON = 'icons/magic/symbols/runes-star-blue.webp' -class PowerEffect { +export class PowerEffect { constructor (token, targets) { this.source = token this.targets = targets @@ -70,47 +70,44 @@ class PowerEffect { get basePowerPoints () { return 0 } get usePrimaryEffect () { return true } get hasAdditionalRecipients () { return false } + get isDamaging () { return false } get additionalRecipientCost () { return 0 } get isTargeted () { return false } get modifiers () { - return [ - { name: 'Glow', - id: 'glow', - value: 1, - epic: false, - effect: true, - icon: 'icons/magic/light/orb-shadow-blue.webp', - changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: -2, - priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ] - }, - { name: 'Shroud', - id: 'shroud', - value: 1, - epic: false, - effect: true, - icon: 'icons/magic/perception/shadow-stealth-eyes-purple.webp', - changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: 1, - priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ] - }, - { name: 'Hinder', - id: 'hinder', - value: 1, - epic: false, - effect: true, + const mods = [] + mods.push({ name: 'Adaptable Caster', id: 'adaptable', + value: 1, epic: false, effect: false }) + mods.push({ name: 'Fatigue', id: 'fatigue', value: 2, epic: false, effect: false }) + mods.push({ name: 'Glow', id: 'glow', value: 1, + epic: false, effect: true, icon: 'icons/magic/light/orb-shadow-blue.webp', + changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: -2, + priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ] + }) + mods.push({ name: 'Shroud', id: 'shroud', value: 1, epic: false, effect: true, + icon: 'icons/magic/perception/shadow-stealth-eyes-purple.webp', + changes: [ { key: '@Skill{Stealth}[system.die.modifier]', value: 1, + priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ] + }) + if (this.isDamaging) { + mods.push({ name: 'Heavy Weapon', id: 'heavyweapon', value: 2, + epic: false, effect: false}) + } + mods.push({ name: 'Hinder', id: 'hinder', value: 1, epic: false, effect: true, icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp', changes: [ { key: 'system.stats.speed.value', value: -2, priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ] - }, - { name: 'Hurry', - id: 'hurry', - value: 1, - epic: false, - effect: true, - icon: 'icons/skills/movement/feet-winged-sandals-tan.webp', - changes: [ { key: 'system.stats.speed.value', value: 2, - priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ] - }, - ] + }) + mods.push({ name: 'Hurry', id: 'hurry', value: 1, epic: false, effect: true, + icon: 'icons/skills/movement/feet-winged-sandals-tan.webp', + changes: [ { key: 'system.stats.speed.value', value: 2, + priority: 0, mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD } ] + }) + if (this.isDamaging) { + mods.push({ name: 'Lingering Damage', id: 'lingeringdamage', value: 2, + epic: false, effect: false}) + } + mods.push({ name: 'Selective', id: 'selective', value: 1, epic: false, effect: false }) + return mods } get menuData () { @@ -131,10 +128,7 @@ class PowerEffect { label += ` (${this.targets.length - 1} additional recipients ` + `+${this.additionalRecipientCost} ea.)` } - data.push({ - type: 'info', - label: label - }) + data.push({ type: 'info', label: label }) } for (const mod of this.modifiers) { data.push({ @@ -145,6 +139,23 @@ class PowerEffect { ), }) } + if (this.isDamaging) { + data.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}, + ] + }) + } + data.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} + ] + }) return data } @@ -195,6 +206,10 @@ class PowerEffect { this.data.mods.add(mod.id) } } + if (this.isDamaging) { + this.data.armorPiercing = this.data.values.shift() + } + this.data.range = this.data.values.shift() } async createSecondaryEffects (maintId) { @@ -206,7 +221,7 @@ class PowerEffect { // set secondary effects of instant spells to expire on victim's next // turn doc.duration.rounds = 1 - doc.flags.swade.expiration = CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.StartOfTurnAuto + doc.flags.swade.expiration = CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.EndOfTurnAuto } else { doc.duration.seconds = 594 doc.flags[moduleName].maintId = maintId @@ -274,6 +289,21 @@ class PowerEffect { } async sideEffects () { + if (this.data.mods.has('fatigue')) { + for (const target of this.targets) { + const actor = target.actor + const update = { + system: { + fatigue: { + value: actor.system.fatigue.value + 1 + } + } + } + if (actor.system.fatigue.value < actor.system.fatigue.max) { + await actor.update(update) + } + } + } } get powerPoints () { @@ -286,37 +316,62 @@ class PowerEffect { if (this.targets.length > 1 && this.hasAdditionalRecipients) { total += (this.targets.length - 1) * this.additionalRecipientCost } + total += this.data.range + if (this.isDamaging) { + total += this.data.ap + } return total } - async chatMessage () { - let text = `Cast ${this.name}` + get chatMessageEffects () { + const list = [] + if (this.hasAdditionalRecipients && this.targets.length > 1) { + list.push(`${this.targets.length - 1} Additional Recipients`) + } + if (this.data.mods.has('adaptable')) { + list.push('Different Trapping (Adaptable Caster)') + } + if (this.data.mods.has('fatigue')) { + list.push('Fatigue (applied to targets') + } + if (this.data.mods.has('heavyweapon')) { + list.push('Heavy Weapon') + } + if (this.data.mods.has('lingeringdamage')) { + list.push('Lingering Damage') + } + if (this.data.mods.has('selective')) { + list.push('Selective') + } + if (this.isDamaging && this.data.armorPiercing > 0) { + list.push(`AP ${this.data.armorPiercing * 2}`) + } + if (this.data.range > 0) { + list.push(`Range ×${this.data.range +1}`) + } + return list + } + + get chatMessageText () { + let text = `
Cast ${this.name}` if (this.targets.length > 0) { text += ` on ${this.targets.map(t => t.name).join(', ')}` } + text += '
' + const effects = this.chatMessageEffects + if (effects.length > 0) { + text += '