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 += `

This version of smite 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.

`; 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 = `

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 += '

'; return super.description + text; } }