From db471b0cb9669da06e44eef7d9faeea27d73a809 Mon Sep 17 00:00:00 2001 From: Mike Bloy Date: Sat, 18 May 2024 14:13:12 -0500 Subject: [PATCH] add dispel and divination --- src/module/powers/dispel.js | 133 ++++++++++++++++++++++++++++++++ src/module/powers/divination.js | 70 +++++++++++++++++ src/module/powers/powers.js | 4 + 3 files changed, 207 insertions(+) create mode 100644 src/module/powers/dispel.js create mode 100644 src/module/powers/divination.js diff --git a/src/module/powers/dispel.js b/src/module/powers/dispel.js new file mode 100644 index 0000000..4ab0ee8 --- /dev/null +++ b/src/module/powers/dispel.js @@ -0,0 +1,133 @@ +import { PowerEffect } from './basePowers.js'; + +export class DispelEffect extends PowerEffect { + get name() { + return 'Dispel'; + } + + get icon() { + return 'icons/magic/symbols/triangle-glowing-green.webp'; + } + + get duration() { + return this?.data?.antiMagic ? 5 : 0; + } + + get usePrimaryEffect() { + return !!this?.data?.antiMagic; + } + + get basePowerPoints() { + return 1; + } + + get isTargeted() { + return true; + } + + get hasAoe() { + return true; + } + + get modifiers() { + return [ + ...super.modifiers, + { + name: 'Anti-Magic Field', + type: 'checkbox', + value: 8, + id: 'antiMagic', + epic: true, + effect: false, + }, + { + type: 'select', + default: 'none', + name: 'Area of Effect', + id: 'aoe', + epic: false, + choices: { + none: 'None', + sbt: 'Small Blast Template', + mbt: 'Medium Blast Template', + lbt: 'Large Blast Template', + }, + effects: { none: null, sbt: null, mbt: null, lbt: null }, + values: { none: 0, sbt: 1, mbt: 2, lbt: 3 }, + }, + { + name: 'Disenchant', + type: 'checkbox', + value: 1, + id: 'disenchant', + epic: true, + effect: false, + }, + { + name: 'Multiple Powers', + type: 'checkbox', + value: 8, + id: 'multiple', + epic: false, + effect: false, + }, + { + name: 'Remove Curse', + type: 'checkbox', + value: 2, + id: 'removeCurse', + epic: true, + effect: false, + }, + ]; + } + + get effectName() { + return this.data.antiMagic ? 'Anti-Magic Field' : super.effectName; + } + + getPrimaryEffectChanges() { + if (this.data.antiMagic) { + const base = 'flags.swade.auras.antiMagicField'; + const priority = 0; + const mode = foundry.CONST.ACTIVE_EFFECT_MODES.OVERRIDE; + return [ + { key: `${base}.enabled`, value: true, priority, mode }, + { key: `${base}.walls`, value: true, priority, mode }, + { key: `${base}.color`, value: '#ff00cc', priority, mode }, + { key: `${base}.alpha`, value: 0.1, priority, mode }, + { key: `${base}.radius`, value: 1.5, priority, mode }, + { key: `${base}.visibleTo`, value: [-1, 0, 1], priority, mode }, + ]; + } + return super.getPrimaryEffectChanges(); + } + + get description() { + let text = super.description; + if (this.data.antiMagic) { + text += `

Magic items, effects, and powers within the anti magic field + have no effect. Summoned creatures must make a Spirit roll each round or + or take a wound.

`; + return text; + } + const multi = this.data.multiple || this.data.aoe; + const affected = `${multi ? 'all' : 'a single'} + ${this.data.disenchant ? 'magic item' : 'power'}${multi ? 's' : ''} + ${this.data.aoe === 'none' ? 'cast by or on the recipient' : 'within a ' + this.data.aoe.toUpperCase()}`; + text += `

Attempt to dispel ${affected}. `; + if (this.data.disenchant) { + text += `The item(s) magical abilities are negated for ${this.data.raise ? 'two rounds' : 'one round'}`; + } else { + text += `Each target must make an opposed arcane skill (spirit for Mystic Powers) + roll or have the power(s) end immediately.`; + } + if (this.data.removeCurse) { + text += `The normal -2 penalty to remove a curse is ignored.`; + } else { + text += `If the effect is a Curse, there is a -2 penalty to the dispeller's roll`; + } + text += '

'; + return text; + } +} diff --git a/src/module/powers/divination.js b/src/module/powers/divination.js new file mode 100644 index 0000000..979f8c3 --- /dev/null +++ b/src/module/powers/divination.js @@ -0,0 +1,70 @@ +import { PowerEffect } from './basePowers.js'; + +export class DivinationEffect extends PowerEffect { + get name() { + return 'Divination'; + } + + get icon() { + return 'icons/magic/perception/orb-crystal-ball-scrying.webp'; + } + + get duration() { + return 0; + } + + get isTargeted() { + return false; + } + + get isRaisable() { + return true; + } + + get basePowerPoints() { + return 5; + } + + get modifiers() { + return [ + { + name: 'Power (sacred ground only)', + type: 'checkbox', + value: 5, + id: 'power', + epic: true, + effect: false, + }, + { + name: 'Sacred Ground', + type: 'checkbox', + value: 0, + id: 'sacred', + epic: false, + effect: false, + }, + ]; + } + + get description() { + let desc = super.description; + desc += `

A brief conversation with a summoned spirit or entity. `; + if (this.data.sacred) { + desc += `There is a +2 to the roll due to being on sacred ground for the + summoned entity. `; + } + if (this.data.raise) { + desc += `The entity will be generally helpful and more direct than usual + in answering questions.i `; + } else { + desc += `The entity will answer questions to the best of its ability, but + usually in a vague or symbolic manner.i `; + } + if (this.data.sacred && this.data.power) { + desc += `The entity will also offer unsolicted advice or information, + according to its nature.`; + } + desc += '

'; + return desc; + } +} diff --git a/src/module/powers/powers.js b/src/module/powers/powers.js index 80d19bc..35b4ae7 100644 --- a/src/module/powers/powers.js +++ b/src/module/powers/powers.js @@ -17,6 +17,8 @@ import { DarksightEffect } from './darksight.js'; import { DeflectionEffect } from './deflection.js'; import { DetectConcealArcanaEffect } from './detectConcealArcana.js'; import { DisguiseEffect } from './disguise.js'; +import { DispelEffect } from './dispel.js'; +import { DivinationEffect } from './divination.js'; const PowerClasses = { 'arcane-protection': ArcaneProtectionEffect, @@ -41,6 +43,8 @@ const PowerClasses = { 'detect-conceal-arcana': DetectConcealArcanaEffect, 'detectconceal-arcana': DetectConcealArcanaEffect, disguise: DisguiseEffect, + dispel: DispelEffect, + divination: DivinationEffect, 'lower-trait': BoostLowerTraitEffect, };