251 lines
6.0 KiB
JavaScript

import { moduleName } from '../globals.js';
import { PowerEffect } from './basePowers.js';
import { BaseSummonEffect } from './summonSupport.js';
class SpiritualWeaponEffect extends BaseSummonEffect {
get name() {
return 'Spiritual Weapon';
}
get icon() {
return 'icons/weapons/hammers/hammer-double-glowing-yellow.webp';
}
get duration() {
return 5;
}
get basePowerPoints() {
return 4;
}
get modifiers() {
const arcaneSkillSwids = ['faith', 'spellcasting', 'performance', 'alchemy'];
const choices = {};
const values = {};
const effects = {};
const skillList = this.source.actor.items.filter(
(i) => i.type === 'skill' && arcaneSkillSwids.includes(i.system.swid),
);
for (const skill of skillList.map((s) => s.name)) {
choices[skill] = skill;
values[skill] = 0;
effects[skill] = null;
}
return [
...super.modifiers,
{
type: 'select',
name: 'Arcane Skill',
id: 'arcaneSkill',
choices,
values,
effects,
epic: false,
},
];
}
// eslint-disable-next-line no-unused-vars
actorValue(actor) {
return 0;
}
async parseValuesPre() {
await super.parseValuesPre();
this.data.primaryEffectChanges = [];
this.data.actorUpdates = {
name: `${this.source.actor.name}'s ${this.targetActor.name}`,
system: {
wildcard: this.source.actor.system.wildcard,
attributes: {
spirit: {
die: {
sides: this.source.actor.system.attributes.spirit.die.sides,
modifier: this.source.actor.system.attributes.spirit.die.modifier,
},
'wild-die': {
sides: this.source.actor.system.attributes.spirit['wild-die'].sides,
},
},
},
},
};
this.data.tokenUpdates = {
disposition: this.source.document.disposition,
sight: { enabled: false },
actorLink: false,
name: `${this.source.name}'s ${this.targetActor.name}`,
};
const weaponId = this.targetActor.items.find((i) => i.type === 'weapon' && i.system.swid === 'spiritual-weapon').id;
const weaponDoc = await this.targetActor.getEmbeddedDocument('Item', weaponId).clone();
const arcaneSkillId = this.source.actor.items.find(
(i) => i.type === 'skill' && i.name === this.data.arcaneSkill,
).id;
const arcaneDoc = await this.source.actor.getEmbeddedDocument('Item', arcaneSkillId).clone();
weaponDoc.updateSource({
system: {
damage: this.data.raise ? '@spi+d6' : '@spi+d4',
actions: {
trait: arcaneDoc.name,
},
},
});
this.data.embeddedUpdates = {
ActiveEffect: {},
Item: {
[weaponDoc.name]: weaponDoc,
[arcaneDoc.name]: arcaneDoc,
},
};
}
get summonCount() {
return 1;
}
getPrimaryEffectChanges() {
return [...super.getPrimaryEffectChanges(), ...this.data.primaryEffectChanges];
}
get spawnUpdates() {
const updates = super.spawnUpdates;
mergeObject(updates.actor, this.data.actorUpdates);
mergeObject(updates.token, this.data.tokenUpdates);
mergeObject(updates.embedded, this.data.embeddedUpdates);
return updates;
}
get description() {
let text = super.description;
text += `<p>This version of <em>smite</em> summons an enchanted weapon made
of energy within Smarts. The caster can move the spiritual weapon up to 5"
and attack with it as a free action, using their ${this.data.arcaneSkill}
in place of fighting. The weapon does ${this.data.raise ? 'Spr+d6' : 'Spr+d4'}
damage.</p>`;
return text;
}
}
export class SmiteEffect extends PowerEffect {
get name() {
return 'Smite';
}
get duration() {
return 5;
}
get icon() {
return 'systems/swade/assets/icons/status/status_smite.svg';
}
get isDamaging() {
return true;
}
get basePowerPoints() {
return 2;
}
get isTargeted() {
return true;
}
get hasAdditionalRecipients() {
return true;
}
get additionalRecipientCost() {
return 1;
}
get modifiers() {
return [
...super.modifiers,
{
type: 'checkbox',
default: false,
name: 'Greater Smite',
id: 'greater',
value: 2,
epic: true,
effect: false,
},
{
type: 'checkbox',
default: false,
name: 'Spiritual Weapon',
id: 'spiritualWeapon',
value: 2,
epic: true,
effect: false,
},
];
}
async parseValues() {
await super.parseValues();
this.baseDoc = await PowerEffect.getStatus('SWADE.Smite', 'Smite', false);
this.baseDoc.flags = mergeObject(this.baseDoc.flags ?? {}, {
[moduleName]: { powerEffect: true },
});
this.data.bonus = (this.data.raise ? 4 : 2) + (this.data.greater ? 2 : 0);
this.baseDoc.changes = [...this.getPrimaryEffectChanges()];
}
get basePrimaryEffect() {
return this.baseDoc;
}
getPrimaryEffectChanges() {
return [
...super.getPrimaryEffectChanges(),
{
key: 'system.stats.globalMods.damage',
value: this.data.bonus,
priority: 0,
mode: foundry.CONST.ACTIVE_EFFECT_MODES.ADD,
},
];
}
async applySpiritualWeapon() {
const runner = new SpiritualWeaponEffect(this.source, []);
runner.render();
}
async apply() {
if (this.data.spiritualWeapon) {
await this.applySpiritualWeapon();
} else {
super.apply();
}
}
async chatMessage() {
if (this.data.spiritualWeapon) {
return;
}
await super.chatMessage();
}
async sideEffects() {
if (this.data.spiritualWeapon) {
return;
}
await super.sideEffects();
}
get description() {
let text = `
<p>Increase damage by ${this.data.bonus} on one weapon or load of ammunition.
`;
if (this.data.greater) {
text += 'The weapon is considered a Heavy Weapon.';
}
text += '</p>';
return super.description + text;
}
}