add illusion, invisibility, intangibility
This commit is contained in:
parent
b4fd301a4f
commit
3d6a561929
@ -81,6 +81,7 @@ export class PowerFormApplication extends FormApplication {
|
|||||||
data.recipients.cost = this.powerEffect.additionalRecipientCost;
|
data.recipients.cost = this.powerEffect.additionalRecipientCost;
|
||||||
data.recipients.count = this.powerEffect.targets.length - 1;
|
data.recipients.count = this.powerEffect.targets.length - 1;
|
||||||
data.recipients.total = data.recipients.cost * data.recipients.count;
|
data.recipients.total = data.recipients.cost * data.recipients.count;
|
||||||
|
data.recipients.epic = this.powerEffect.additionalRecipientsIsEpic;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -186,6 +187,10 @@ export class PowerEffect {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get additionalRecipientsIsEpic() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
get additionalRecipientCost() {
|
get additionalRecipientCost() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
113
src/module/powers/illusion.js
Normal file
113
src/module/powers/illusion.js
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { PowerEffect } from './basePowers.js';
|
||||||
|
|
||||||
|
export class IllusionEffect extends PowerEffect {
|
||||||
|
get name() {
|
||||||
|
return 'Illusion';
|
||||||
|
}
|
||||||
|
|
||||||
|
get icon() {
|
||||||
|
return 'icons/magic/defensive/illusion-evasion-echo-purple.webp';
|
||||||
|
}
|
||||||
|
|
||||||
|
get duration() {
|
||||||
|
return this.data.duration ? 50 : 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isTargeted() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isRaisable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get usePrimaryEffect() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get basePowerPoints() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
get modifiers() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'Area of Effect',
|
||||||
|
type: 'checkbox',
|
||||||
|
value: 1,
|
||||||
|
id: 'aoe',
|
||||||
|
epic: false,
|
||||||
|
effect: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deadly Illusion',
|
||||||
|
type: 'checkbox',
|
||||||
|
value: 3,
|
||||||
|
id: 'deadly',
|
||||||
|
epic: true,
|
||||||
|
effect: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Duration',
|
||||||
|
type: 'checkbox',
|
||||||
|
value: 2,
|
||||||
|
id: 'duration',
|
||||||
|
epic: true,
|
||||||
|
effect: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Mobility',
|
||||||
|
type: 'select',
|
||||||
|
default: 'none',
|
||||||
|
id: 'mobility',
|
||||||
|
choices: {
|
||||||
|
none: 'None',
|
||||||
|
12: 'Move and fly at Pace 12',
|
||||||
|
24: 'Move and fly at Pace 24',
|
||||||
|
},
|
||||||
|
values: { none: 0, 12: 1, 24: 2 },
|
||||||
|
effects: { none: null, 12: null, 24: null },
|
||||||
|
epic: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Sound',
|
||||||
|
id: 'sound',
|
||||||
|
type: 'checkbox',
|
||||||
|
epic: false,
|
||||||
|
effect: false,
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Strong',
|
||||||
|
id: 'strong',
|
||||||
|
type: 'checkbox',
|
||||||
|
epic: false,
|
||||||
|
effect: false,
|
||||||
|
value: 2,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
get description() {
|
||||||
|
const size = this.data.aoe ? 'LBT' : 'MBT';
|
||||||
|
const penalty = (this.data.raise ? -2 : 0) + (this.data.strong ? -2 : 0);
|
||||||
|
const motion = this.data.mobility === 'none' ? '(stationary)' : `that can move at pace ${this.data.mobility}`;
|
||||||
|
let text =
|
||||||
|
super.description +
|
||||||
|
`<p>
|
||||||
|
Create an illusion ${motion} ${this.data.sound ? 'with sound' : ''}.
|
||||||
|
Its effects must remain within a sphere the size of a ${size}. </p>
|
||||||
|
<p>Creatures can actively disbelieve in the illusion with a Smarts roll
|
||||||
|
${penalty === 0 ? '' : `at ${penalty}`}.</p>
|
||||||
|
`;
|
||||||
|
if (this.data.deadly) {
|
||||||
|
text += `<p>The caster can 'attack' targets while the illusion is active
|
||||||
|
with an opposed roll of the caster's arcane skill versus the target's
|
||||||
|
Smarts${penalty === 0 ? '' : ` at ${penalty}`}. If the caster wins the
|
||||||
|
target is Shaken (cannot incapacitate). With a raise, the target suffers
|
||||||
|
a Wound.</p>.
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
70
src/module/powers/intangibility.js
Normal file
70
src/module/powers/intangibility.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { moduleName } from '../globals.js';
|
||||||
|
import { PowerEffect } from './basePowers.js';
|
||||||
|
|
||||||
|
export class IntangibilityEffect extends PowerEffect {
|
||||||
|
get name() {
|
||||||
|
return 'Intangility';
|
||||||
|
}
|
||||||
|
|
||||||
|
get duration() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
get icon() {
|
||||||
|
return 'icons/magic/control/debuff-energy-hold-levitate-blue-yellow.webp';
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasAdditionalRecipients() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get additionalRecipientCost() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
get additionalRecipientsIsEpic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get basePowerPoints() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isTargeted() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isRaisable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get modifiers() {
|
||||||
|
const mods = super.modifiers;
|
||||||
|
mods.push({
|
||||||
|
name: 'Duration',
|
||||||
|
type: 'checkbox',
|
||||||
|
id: 'Duration',
|
||||||
|
value: 3,
|
||||||
|
epic: true,
|
||||||
|
effect: false,
|
||||||
|
});
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description() {
|
||||||
|
let text =
|
||||||
|
super.description +
|
||||||
|
`<p>
|
||||||
|
The subject becomes incorporeal. Non magical weapons and walls can't
|
||||||
|
affect him. The character may affect other incorporeal beings, and is still
|
||||||
|
susceptible to supernatural attacks. Unwilling targets resist with Spirit,
|
||||||
|
and shake off the effect with a Spirit roll at the end of following turns.</p>
|
||||||
|
<p>The being is Stunned and shunted to an open space if it is within
|
||||||
|
something solid when the power ends.</p>
|
||||||
|
`;
|
||||||
|
if (this.data.raise) {
|
||||||
|
text += '<p>Reduce damage taken from supernatural effects and magic weapons by 4.</p>';
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
80
src/module/powers/invisibility.js
Normal file
80
src/module/powers/invisibility.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { moduleName } from '../globals.js';
|
||||||
|
import { PowerEffect } from './basePowers.js';
|
||||||
|
|
||||||
|
export class InvisibliltyEffect extends PowerEffect {
|
||||||
|
get name() {
|
||||||
|
return 'Invisibility';
|
||||||
|
}
|
||||||
|
|
||||||
|
get duration() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
get icon() {
|
||||||
|
return 'icons/svg/invisible.svg';
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasAdditionalRecipients() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get additionalRecipientCost() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
get basePowerPoints() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isTargeted() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isRaisable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get modifiers() {
|
||||||
|
const mods = super.modifiers;
|
||||||
|
mods.push({
|
||||||
|
name: 'Duration',
|
||||||
|
type: 'checkbox',
|
||||||
|
id: 'Duration',
|
||||||
|
value: 2,
|
||||||
|
epic: true,
|
||||||
|
effect: false,
|
||||||
|
});
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
get description() {
|
||||||
|
let text =
|
||||||
|
super.description +
|
||||||
|
`
|
||||||
|
<p>The subject is invisible, except for a vague blur or outline.
|
||||||
|
Any action taken against it that requires sight is made at
|
||||||
|
${this.data.raise ? -6 : -4}, including Notice rolls. This penalty is
|
||||||
|
reduced by 2 if the invisible character's position is given away by some
|
||||||
|
environmental circumstance.</p>
|
||||||
|
`;
|
||||||
|
if (this.data.duration) {
|
||||||
|
text += `<p>This long-duration invisibility ends immediately if the subject
|
||||||
|
attempts a damage-causing attack or targets an unwilling character with a
|
||||||
|
power.</p>`;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
async parseValues() {
|
||||||
|
await super.parseValues();
|
||||||
|
const doc = await PowerEffect.getStatus('EFFECT.StatusInvisible', 'Invisible');
|
||||||
|
doc.description = `<p>From <strong>${this.source.name}</strong> casting <em>${this.name}</em></p>`;
|
||||||
|
doc.flags = mergeObject(doc.flags ?? {}, { [moduleName]: { powerEffect: true } });
|
||||||
|
(doc.duration = { rounds: 99 }), (this.baseEffectDoc = doc);
|
||||||
|
this.basePrimaryEffectDoc = doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
get basePrimaryEffect() {
|
||||||
|
return this.basePrimaryEffectDoc;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -31,6 +31,9 @@ import { FlyEffect } from './fly.js';
|
|||||||
import { GrowthShrinkEffect } from './growthShrink.js';
|
import { GrowthShrinkEffect } from './growthShrink.js';
|
||||||
import { HavocEffect } from './havoc.js';
|
import { HavocEffect } from './havoc.js';
|
||||||
import { HealingEffect } from './healing.js';
|
import { HealingEffect } from './healing.js';
|
||||||
|
import { IllusionEffect } from './illusion.js';
|
||||||
|
import { IntangibilityEffect } from './intangibility.js';
|
||||||
|
import { InvisibliltyEffect } from './invisibility.js';
|
||||||
|
|
||||||
const PowerClasses = {
|
const PowerClasses = {
|
||||||
'arcane-protection': ArcaneProtectionEffect,
|
'arcane-protection': ArcaneProtectionEffect,
|
||||||
@ -71,6 +74,9 @@ const PowerClasses = {
|
|||||||
growthshrink: GrowthShrinkEffect,
|
growthshrink: GrowthShrinkEffect,
|
||||||
havoc: HavocEffect,
|
havoc: HavocEffect,
|
||||||
healing: HealingEffect,
|
healing: HealingEffect,
|
||||||
|
illusion: IllusionEffect,
|
||||||
|
intangibility: IntangibilityEffect,
|
||||||
|
invisibility: InvisibliltyEffect,
|
||||||
'lower-trait': BoostLowerTraitEffect,
|
'lower-trait': BoostLowerTraitEffect,
|
||||||
shrink: GrowthShrinkEffect,
|
shrink: GrowthShrinkEffect,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -19,7 +19,8 @@
|
|||||||
<strong>Targets</strong>:
|
<strong>Targets</strong>:
|
||||||
{{#each targets}}{{#if @index}}, {{/if}}{{this}}{{/each}}
|
{{#each targets}}{{#if @index}}, {{/if}}{{this}}{{/each}}
|
||||||
{{#if recipients.cost}}
|
{{#if recipients.cost}}
|
||||||
<br>(Additional Recipients {{recipients.cost}}pp each × {{recipients.count}} = {{recipients.total}})
|
<br>({{#if recipients.epic}}⭐ {{/if}}Additional Recipients
|
||||||
|
{{recipients.cost}}pp each × {{recipients.count}} = {{recipients.total}})
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</p>
|
</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user