From 69bea4e77dfeadc3d047dacd4426756e5764ccb6 Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sun, 5 May 2024 23:05:04 -0500 Subject: [PATCH] add boost lower and curse --- scripts/basePowers.js | 1 + scripts/powers.js | 142 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 142 insertions(+), 1 deletion(-) diff --git a/scripts/basePowers.js b/scripts/basePowers.js index 73d9fcb..1870e83 100644 --- a/scripts/basePowers.js +++ b/scripts/basePowers.js @@ -73,6 +73,7 @@ export class PowerEffect { get isDamaging () { return false } get additionalRecipientCost () { return 0 } get isTargeted () { return false } + get oneTarget () { return false } get isRaisable () { return true } get hasAoe () { return false } get modifiers () { diff --git a/scripts/powers.js b/scripts/powers.js index 97118a1..69370a3 100644 --- a/scripts/powers.js +++ b/scripts/powers.js @@ -525,6 +525,143 @@ class BoostLowerTraitEffect extends PowerEffect { } } +class BurstEffect extends PowerEffect { + get name () { return 'Blast' } + get icon () { return 'icons/magic/sonic/projectile-shock-wave-blue.webp' } + get duration () { return 0 } + get isTargeted () { return true } + get usePrimaryEffect () { return false } + get isDamaging () { return true } + get basePowerPoints () { return 3 } + get hasAoe () { return true } + get modifiers () { + const mods = super.modifiers + mods.push( + { name: 'Damage', value: 2, id: 'damage', epic: false, effect: false }, + { name: 'Greater Burst', value: 4, id: 'greater', epic: true, effect: false }, + ) + return mods + } + get description () { + const dmgDie = ( + this.data.mods.has('greater') ? 4 : + (this.data.mods.has('damage') ? 3 : 2)) + (this.data.raise ? 1 : 0) + return super.description + ` +

The blast covers a Cone or Stream template and does ${dmgDie}d6 damage

` + } +} + +class ConfusionEffect extends PowerEffect { + get name () { return 'Confusion' } + get icon () { return 'icons/magic/control/hypnosis-mesmerism-swirl.webp' } + get duration () { return 0 } + get isTargeted () { return true } + get usePrimaryEffect () { return false } + get basePowerPoints () { return 2 } + get hasAoe () { return true } + get menuInputs () { + const inputs = super.menuInputs + inputs.push + inputs.push({ type: 'select', label: 'Area of Effect', + options: [ + {html: 'Small Blast Template (0)', value: 's', selected: false}, + {html: 'Medium Blast Template (0)', value: 'm', selected: true}, + {html: 'Large Blast Template (+1)', value: 'l', selected: false}, + ]}) + return inputs + } + get modifiers () { + const mods = super.modifiers + mods.push( + { name: 'Greater Confusion', value: 2, id: 'greater', epic: true, effect: false }, + ) + return mods + } + get powerPoints () { + let total = super.powerPoints + total += (this.data.aoe === 'l' ? 1 : 0) + return total + } + get menuButtons () { + const data = [ + { label: 'Apply with Distracted', value: 'distracted' }, + { label: 'Apply with Vulnerable', value: 'vulnerable' }, + { label: 'Apply with both (raise)', value: 'raise' }, + { label: 'Cancel', value: 'cancel' }, + ] + return data + } + async parseValues () { + await super.parseValues() + this.data.distracted = this.data.button === 'distracted' || this.data.button === 'raise' + this.data.vulnerable = this.data.button === 'vulnerable' || this.data.button === 'raise' + this.data.aoe = this.data.values.shift() + } + get description () { + const size = ( + this.data.aoe === 'l' ? 'LBT' : (this.data.aoe === 's' ? 'SBT' : 'MBT')) + let effect = 'Vulnerable' + if (this.data.raise) { + effect = 'both Distracted and Vulnerable' + } else if (this.data.distracted) { + effect = 'Distracted' + } + if (this.data.mods.has('Greater')) { + effect += ' as well as Shaken' + } + return super.description + ` +

The targets in the ${size} are ${effect}.

` + } + async createSecondaryEffects (maintId) { + const docs = await super.createSecondaryEffects(maintId) + if (this.data.distracted) { + PowerEffect.getStatus('SWADE.Distr', 'Distracted', false).then(v => docs.push(v)) + } + if (this.data.distracted) { + PowerEffect.getStatus('SWADE.Vuln', 'Vulnerable', false).then(v => docs.push(v)) + } + if (this.data.mods.has('greater')) { + PowerEffect.getStatus('SWADE.Shaken', 'Shaken', false).then(v => docs.push(v)) + } + return docs + } +} + +class CurseEffect extends PowerEffect { + get name () { return 'Curse' } + get icon () { return 'icons/magic/control/voodoo-doll-pain-damage-purple.webp' } + get duration () { return 500*24*60*6 } + get isTargeted () { return true } + get oneTarget () { return true } + get basePowerPoints () { return 5 } + get modifiers () { + const mods = super.modifiers + mods.push({ + name: 'Turn to Stone', value: 5, id: 'turntostone', epic: true, effect: false + }) + return mods + } + get description () { + let desc = super.description + desc += `

The victim must defend with a Spirit roll opposed by the + caster's arcane skill roll. Failure means the victim suffers a level + of Fatigue immediately.

` + if (this.data.mods.has('turntostone')) { + desc += `

On every following run the victim must make a Spirit roll + or take a level of Fatigue. When Incapacitated, the victim turns to + stone, with a Hardness equal to his Tougness.

` + } else { + desc += `

At sunset every day, the victim suffers a level of Fatigue. + When Incapacitated by this, he makes a Vigor roll each day to avoid + death.

` + } + desc += `

Breaking the curse: The curse can be lifted by + the original caster at will, and ends if the caster is slain. Dispel at -2 + also removes the curse, but each individual may only try once.

` + return desc + } +} + const PowerClasses = { "arcane-protection": ArcaneProtectionEffect, banish: BanishEffect, @@ -535,8 +672,11 @@ const PowerClasses = { bolt: BoltEffect, "boost-lower-trait": BoostLowerTraitEffect, "boost-trait": BoostLowerTraitEffect, - "lower-trait": BoostLowerTraitEffect, burrow: BurrowEffect, + burst: BurstEffect, + confusion: ConfusionEffect, + curse: CurseEffect, + "lower-trait": BoostLowerTraitEffect, } /* ---------------------------------------------------------------- */