From 4d44b6c31c95f7f500e5c1db13c2421585618bc4 Mon Sep 17 00:00:00 2001
From: Mike Bloy
Date: Tue, 7 May 2024 19:36:21 -0500
Subject: [PATCH] add detect/conceal arcana
---
scripts/basePowers.js | 4 +-
scripts/powers.js | 91 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 90 insertions(+), 5 deletions(-)
diff --git a/scripts/basePowers.js b/scripts/basePowers.js
index 1870e83..4c6387b 100644
--- a/scripts/basePowers.js
+++ b/scripts/basePowers.js
@@ -125,7 +125,7 @@ export class PowerEffect {
get menuInputs () {
const inputs = [
{ type: 'header', label: `${this.name} Effect` },
- { type: 'info', label: `Apply ${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(',')}`
@@ -265,7 +265,7 @@ export class PowerEffect {
if (!this.usePrimaryEffect) {
icon = this.icon
}
- const doc = this.createEffectDocument(icon, `Maintaining ${this.name}`, [])
+ const doc = this.createEffectDocument(icon, `Maintaining ${this.effectName}`, [])
doc.duration.rounds = this.duration
doc.description += this.description
doc.flags.swade.expiration = CONFIG.SWADE.CONST.STATUS_EFFECT_EXPIRATION.EndOfTurnPrompt
diff --git a/scripts/powers.js b/scripts/powers.js
index b778db2..ba0643a 100644
--- a/scripts/powers.js
+++ b/scripts/powers.js
@@ -51,8 +51,8 @@ class BanishEffect extends PowerEffect {
options: [
{html: 'None', value: 0, selected: true},
{html: 'Small Blast Template (+1)', value: 1, selected: false},
- {html: 'Medium Blast Template (+2)', value: 1, selected: false},
- {html: 'Large Blast Template (+3)', value: 1, selected: false},
+ {html: 'Medium Blast Template (+2)', value: 2, selected: false},
+ {html: 'Large Blast Template (+3)', value: 3, selected: false},
]})
return inputs
}
@@ -718,7 +718,7 @@ class DamageFieldEffect extends PowerEffect {
class DarksightEffect extends PowerEffect {
get name () { return 'Darksight' }
- get icon () { return 'icons/magic/perception/third-eye-blue-red.webp' }
+ get icon () { return 'icons/magic/perception/eye-ringed-glow-angry-small-teal.webp' }
get duration () { return 600 }
get basePowerPoints () { return 1 }
get isTargeted () { return true }
@@ -784,6 +784,90 @@ class DeflectionEffect extends PowerEffect {
}
}
+class DetectConcealArcanaEffect extends PowerEffect {
+ get name () { return 'Detect/Conceal Arcana' }
+ get icon () { return this.data.detect ?
+ 'icons/magic/perception/third-eye-blue-red.webp' :
+ 'icons/magic/perception/silhouette-stealth-shadow.webp' }
+ get duration () { return this.data.detect ? 5 : 600 }
+ get basePowerPoints () { return 2 }
+ get isTargeted () { return true }
+ get hasAdditionalRecipients () { return true }
+ get additionalRecipientCost () { return (this.data?.aoe || 0) > 0 ? 0 : 1 }
+ get modifiers () {
+ const mods = super.modifiers
+ mods.push({name: 'Alignment Sense (detect)', value: 1, id: 'alignment', epic: false, effect: false})
+ mods.push({name: 'Identify (detect)', value: 1, id: 'identify', epic: false, effect: false})
+ mods.push({name: 'Strong (conceal)', value: 1, id: 'strong', epic: false, effect: false})
+ return mods
+ }
+ get hasAoe () { return true }
+ get menuInputs () {
+ const inputs = super.menuInputs
+ inputs.push({ type: 'select', label: 'Area of Effect (conceal)',
+ options: [
+ {html: 'None', value: 0, selected: true},
+ {html: 'Medium Blast Template (+1)', value: 1, selected: false},
+ {html: 'Large Blast Template (+2)', value: 2, selected: false},
+ ]})
+ inputs.push({type: 'info', label: 'Detect or Conceal?'})
+ inputs.push({type: 'radio', label: 'Detect', options: ['isDetect', true]})
+ inputs.push({type: 'radio', label: 'Conceal', options: ['isDetect', false]})
+ return inputs
+ }
+ async parseValues () {
+ await super.parseValues()
+ this.data.aoe = this.data.values.shift()
+ this.data.values.shift()
+ this.data.detect = this.data.values.shift()
+ }
+ get powerPoints () {
+ return super.powerPoints + this.data.aoe
+ }
+ get effectName () {
+ return `${this.data.detect ? 'Detect' : 'Conceal'} Arcana`
+ }
+ get description () {
+ let desc = super.description
+ if (this.data.detect) {
+ desc += `The recipient can see and detect all supernatural persons,
+ objects, or effects in sight. This includes invisible foes, enchanted
+ objects, and so on.`
+ if (this.data.raise) {
+ desc += `Since this was major Detect Arcana, the type of enchantments
+ is also known.`
+ }
+ desc+= `
If cast to learn more about a creature, the caster learns
+ active powers and arcane abilities.`
+ if (this.data.raise) {
+ desc += `As major Detect in this mode, the caster also learns any
+ Weaknesses common to that creature type.`
+ }
+ if (this.data.mods.has('identify')) {
+ desc += `
Items detected also give the recipient an idea of their
+ powers and how to activate them.
`
+ }
+ if (this.data.mods.has('alignment')) {
+ desc += `The recipient can also detect the presence and location
+ of supernatural good or evil within range, regardless of line of sight.
`
+ }
+ desc += `
Invisible Creatures: The recipient may
+ also ignore ${this.data.raise ? 'all' : 'up to 4 points of'} penalties
+ when attacking invisible or magically concealed foes.
`
+ } else {
+ let area = 'one item or being'
+ if (this.data.aoe !== 0) {
+ area = `everything in a sphere the size of a
+ ${this.data.aoe === 1 ? 'Medium' : 'Large'} Blast Template`
+ }
+ desc += `Conceal ${area} from the Detect Magic ability for
+ one hour. Attempts to detect arcana suffer a
+ ${(this.data.mods.has('strong') ? -2 : 0) + this.data.raise ? -2 : -4} penalty.`
+ }
+ return desc
+ }
+}
+
const PowerClasses = {
"arcane-protection": ArcaneProtectionEffect,
banish: BanishEffect,
@@ -801,6 +885,7 @@ const PowerClasses = {
"damage-field": DamageFieldEffect,
darksight: DarksightEffect,
deflection: DeflectionEffect,
+ "detect-conceal-arcana": DetectConcealArcanaEffect,
"lower-trait": BoostLowerTraitEffect,
}