add detect-conceal arcana
This commit is contained in:
parent
8c373fcc8b
commit
1877b048d2
139
src/module/powers/detectConcealArcana.js
Normal file
139
src/module/powers/detectConcealArcana.js
Normal file
@ -0,0 +1,139 @@
|
||||
import { PowerEffect } from './basePowers.js';
|
||||
|
||||
export 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({
|
||||
type: 'checkbox',
|
||||
name: 'Alignment Sense (detect)',
|
||||
value: 1,
|
||||
id: 'alignment',
|
||||
epic: false,
|
||||
effect: false,
|
||||
});
|
||||
mods.push({
|
||||
type: 'checkbox',
|
||||
name: 'Identify (detect)',
|
||||
value: 1,
|
||||
id: 'identify',
|
||||
epic: false,
|
||||
effect: false,
|
||||
});
|
||||
mods.push({
|
||||
type: 'checkbox',
|
||||
name: 'Strong (conceal)',
|
||||
value: 1,
|
||||
id: 'strong',
|
||||
epic: false,
|
||||
effect: false,
|
||||
});
|
||||
mods.push({
|
||||
sortOrder: -2,
|
||||
name: 'Detect or Conceal?',
|
||||
id: 'direction',
|
||||
type: 'radio',
|
||||
default: 'Detect',
|
||||
epic: false,
|
||||
choices: { Detect: 'Detect', Conceal: 'Conceal' },
|
||||
effects: { Detect: null, Conceal: null },
|
||||
values: { Detect: 0, Conceal: 0 },
|
||||
});
|
||||
mods.push({
|
||||
name: 'Area of Effect (conceal)',
|
||||
type: 'select',
|
||||
default: 'none',
|
||||
epic: false,
|
||||
choices: { none: 'None', mbt: 'Medium Blast Template', lbt: 'Large Blast Template' },
|
||||
effects: { none: null, mbt: null, lbt: null },
|
||||
values: { none: 0, mbt: 1, lbt: 2 },
|
||||
});
|
||||
return mods;
|
||||
}
|
||||
|
||||
get hasAoe() {
|
||||
return true;
|
||||
}
|
||||
|
||||
async parseValues() {
|
||||
await super.parseValues();
|
||||
this.data.detect = this.data.direction == 'Detect';
|
||||
}
|
||||
|
||||
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 += `<p>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 += `</p><p>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.identify) {
|
||||
desc += `<p>Items detected also give the recipient an idea of their
|
||||
powers and how to activate them.</p>`;
|
||||
}
|
||||
if (this.data.alignment) {
|
||||
desc += `<p>The recipient can also detect the presence and location
|
||||
of supernatural good or evil within range, regardless of line of sight.</p>`;
|
||||
}
|
||||
desc += `</p><p><strong>Invisible Creatures:</strong> The recipient may
|
||||
also ignore ${this.data.raise ? 'all' : 'up to 4 points of'} penalties
|
||||
when attacking invisible or magically concealed foes.</p>`;
|
||||
} 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 += `<p>Conceal ${area} from the Detect Magic ability for
|
||||
one hour. Attempts to <em>detect arcana</em> suffer a
|
||||
${(this.data.strong ? -2 : 0) + this.data.raise ? -2 : -4} penalty.`;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
@ -16,148 +16,7 @@ import { CurseEffect } from './curse.js';
|
||||
import { DamageFieldEffect } from './damageField.js';
|
||||
import { DarksightEffect } from './darksight.js';
|
||||
import { DeflectionEffect } from './deflection.js';
|
||||
|
||||
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 += `<p>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 += `</p><p>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 += `<p>Items detected also give the recipient an idea of their
|
||||
powers and how to activate them.</p>`;
|
||||
}
|
||||
if (this.data.mods.has('alignment')) {
|
||||
desc += `<p>The recipient can also detect the presence and location
|
||||
of supernatural good or evil within range, regardless of line of sight.</p>`;
|
||||
}
|
||||
desc += `</p><p><strong>Invisible Creatures:</strong> The recipient may
|
||||
also ignore ${this.data.raise ? 'all' : 'up to 4 points of'} penalties
|
||||
when attacking invisible or magically concealed foes.</p>`;
|
||||
} 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 += `<p>Conceal ${area} from the Detect Magic ability for
|
||||
one hour. Attempts to <em>detect arcana</em> suffer a
|
||||
${(this.data.mods.has('strong') ? -2 : 0) + this.data.raise ? -2 : -4} penalty.`;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
import { DetectConcealArcanaEffect } from './detectConcealArcana.js';
|
||||
|
||||
class DisguiseEffect extends PowerEffect {
|
||||
get name() {
|
||||
@ -212,16 +71,20 @@ const PowerClasses = {
|
||||
blast: BlastEffect,
|
||||
blind: BlindEffect,
|
||||
bolt: BoltEffect,
|
||||
'boostlower-trait': BoostLowerTraitEffect,
|
||||
'boost-lower-trait': BoostLowerTraitEffect,
|
||||
'boost-trait': BoostLowerTraitEffect,
|
||||
burrow: BurrowEffect,
|
||||
burst: BurstEffect,
|
||||
'conceal-arcana': DetectConcealArcanaEffect,
|
||||
confusion: ConfusionEffect,
|
||||
curse: CurseEffect,
|
||||
'damage-field': DamageFieldEffect,
|
||||
darksight: DarksightEffect,
|
||||
deflection: DeflectionEffect,
|
||||
'detect-arcana': DetectConcealArcanaEffect,
|
||||
'detect-conceal-arcana': DetectConcealArcanaEffect,
|
||||
'detectconceal-arcana': DetectConcealArcanaEffect,
|
||||
disguise: DisguiseEffect,
|
||||
'lower-trait': BoostLowerTraitEffect,
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user