diff --git a/scripts/powerEffects.js b/scripts/powerEffects.js index f86d1c0..0bb816d 100644 --- a/scripts/powerEffects.js +++ b/scripts/powerEffects.js @@ -1036,6 +1036,7 @@ class SummonEffect extends PowerEffect { async prepMenu () { this.menuData.inputs[1].label = `${this.token.name} is summoning...` + this.menuData.buttons = this.menuData.buttons.filter(b => b.value !== 'raise') const actors = await this.prepActors() if (Object.keys(actors).length < 1) { shim.notifications.error('No summonables found') @@ -1196,6 +1197,11 @@ class SummonAllyEffect extends SummonEffect { async prepMenu () { await super.prepMenu() + this.menuData.buttons = [ + this.menuData.buttons[0], + { label: 'Apply with Raise', value: 'raise' }, + this.menuData.buttons[1] + ] this.menuData.inputs = this.menuData.inputs.concat([ { type: 'checkbox', @@ -1374,6 +1380,158 @@ class SummonUndeadEffect extends SummonEffect { } } +class ZombieEffect extends SummonEffect { + get name () { + return 'Zombie' + } + + async prepMenu () { + await super.prepMenu() + this.menuData.buttons = [ + this.menuData.buttons[0], + { label: 'Apply with Raise', value: 'raise' }, + this.menuData.buttons[1] + ] + this.menuData.inputs.pop() + this.menuData.inputs = this.menuData.inputs.concat([ + { + type: 'checkbox', + label: 'Armed (Hand Weapon (Str+d6) or Ranged Weapon (2d6)', + options: false + }, { + type: 'checkbox', + label: '+2 Armor', + options: false + }, { + type: 'info', + label: 'Skeletal creatures +1 per zombie' + } + ]) + } + + async prepResult () { + this.raise = (this.buttons === 'raise') + this.actorId = this.inputs[this.inputIndex] + this.number = this.inputs[this.inputIndex + 1] + this.actor = shim.actors.get(this.actorId) + this.icon = this.actor.prototypeToken.texture.src + this.protoDoc = await this.actor.getTokenDocument() + this.increasedTrait = this.raise + this.armed = this.inputs[this.inputIndex + 2] + this.armor = this.inputs[this.inputIndex + 3] + this.spawnOptions = { + controllingActor: this.token.actor, + duplicates: this.number, + updateOpts: { + embedded: { + Item: { renderSheet: null } + } + }, + crosshairs: { + icon: this.icon, + label: `Summon ${this.actor.name}`, + drawOutline: true, + rememberControlled: true + } + } + this.spawnMutation = { + actor: { + name: `${this.token.name}'s ${this.actor.name}` + }, + token: { + actorLink: false, + name: `${this.token.name}'s ${this.protoDoc.name}`, + disposition: this.token.document.disposition, + sight: { enabled: true } + }, + embedded: { ActiveEffect: {}, Item: {} } + } + if (this.armed && ('armed_template' in this.summonableActors)) { + const armedTemplate = this.summonableActors.armed_template + for (const item of armedTemplate.items) { + const itemDoc = await armedTemplate.getEmbeddedDocument('Item', item.id) + this.spawnMutation.embedded.Item[item.name] = itemDoc + } + } + if (this.armor) { + const effectDoc = shim.createEffectDocument( + 'icons/equipment/chest/breastplate-layered-leather-stitched.webp', + 'Rotting Armor', + 0) + delete effectDoc.duration + delete effectDoc.flags.swade.expiration + effectDoc.changes = [{ + key: 'system.stats.toughness.armor', + mode: CONST.FOUNDRY.ACTIVE_EFFECT_MODES.ADD, + value: '+2', + priority: 0 + }] + this.spawnMutation.embedded.ActiveEffect[effectDoc.name] = effectDoc + } + for (const effectDocument of this.effectDocs) { + this.spawnMutation.embedded.ActiveEffect[effectDocument.name] = effectDocument + } + } + + async prepAdditional () { + if (!this.increasedTrait) { + return + } + const traitMenuOptions = { + title: `${this.name} Raise Trait Increase`, + defaultButton: 'Cancel', + options: {} + } + const skillSet = new Set() + for (const skill of this.actor.items.filter(i => i.type === 'skill')) { + skillSet.add(skill.name) + } + for (const item of Object.values(this.spawnMutation.embedded.Item).filter(i => i.type === 'skill')) { + skillSet.add(item.name) + } + const skillList = Array.from(skillSet) + const attrList = ['Agility', 'Smarts', 'Spirit', 'Strength', 'Vigor'] + skillList.sort() + const traitMenuData = { + inputs: [ + { type: 'header', label: 'Raise! Increase an attribute' } + ], + buttons: [ + { label: 'Apply', value: 'apply' }, + { label: 'Increase no traits', value: 'cancel' } + ] + } + traitMenuData.inputs = traitMenuData.inputs.concat( + attrList.map((x) => { return { type: 'radio', label: x, options: ['trait', false] } })) + traitMenuData.inputs.push({ type: 'header', label: 'Increase Skills (+1 each)' }) + traitMenuData.inputs = traitMenuData.inputs.concat( + skillList.map((x) => { return { type: 'radio', label: x, options: ['trait', false] } })) + const { buttons, inputs } = await shim.warpgateMenu(traitMenuData, traitMenuOptions) + if (!buttons || buttons === 'cancel') { + return + } + const modKeys = [] + for (let i = 0; i < attrList.length; i++) { + if (inputs[i + 1]) { + modKeys.push(`system.attributes.${attrList[i].toLowerCase()}.die.sides`) + } + } + for (let i = 0; i < skillList.length; i++) { + if (inputs[i + 7]) { + modKeys.push(`@Skill{${skillList[i]}}[system.die.sides]`) + } + } + const effectDoc = shim.createEffectDocument( + this.ICON, 'Increased Trait', this.durationRounds) + effectDoc.changes = modKeys.map(key => { + return { + key, mode: CONST.FOUNDRY.ACTIVE_EFFECT_MODES.ADD, value: '+2', priority: 0 + } + }) + this.spawnMutation.embedded.ActiveEffect[effectDoc.name] = effectDoc + } +} + const PowerClasses = { 'arcane protection': ArcaneProtectionEffect, 'arcane-protection': ArcaneProtectionEffect, @@ -1422,7 +1580,7 @@ const PowerClasses = { 'summon-planar-ally': SummonPlanarAllyEffect, 'summon undead': SummonUndeadEffect, 'summon-undead': SummonUndeadEffect, - zombie: SummonUndeadEffect + zombie: ZombieEffect } export async function powerEffects (options = {}) {