diff --git a/src/module/powers/basePowers.js b/src/module/powers/basePowers.js index 3aaea2d..9baa820 100644 --- a/src/module/powers/basePowers.js +++ b/src/module/powers/basePowers.js @@ -94,7 +94,8 @@ export class PowerFormApplication extends HandlebarsApplicationMixin(Application return a.name === b.name ? 0 : a.name < b.name ? -1 : 1; } - _prepareContext() { + async _prepareContext() { + await this.powerEffect.init(); let modifiers = foundry.utils.deepClone(this.powerEffect.modifiers); modifiers.sort(PowerFormApplication.sortMods); for (const modifier of modifiers) { @@ -170,6 +171,10 @@ export class PowerEffect { this.data = {}; } + async init() { + log('Power Effect', this.name, 'Init'); + } + static async getStatus(label, name, favorite = true) { const effect = foundry.utils.deepClone(CONFIG.statusEffects.find((se) => se.label === label || se.name === label)); effect.name = 'name' in effect ? effect.name : effect.label; @@ -773,12 +778,77 @@ export class PowerEffect { } export class ActorFolderEffect extends PowerEffect { + async init() { + await super.init(); + this.packActors = await this.actorFolderPack.getIndex({ fields: ['system.stats.size'] }); + this.data.actors = this.prepActors(); + } + + get actorFolderPackId() { + return 'no.compendium.needs.override'; + } + get actorFolderBase() { - return 'PowerActors'; + return ''; + } + + get actorFolderPack() { + const pack = game.packs.get(this.actorFolderPackId); + if (!pack) { + return undefined; + } + return game.user.isGM || pack.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER) + ? pack + : undefined; } get actorFolder() { - return `${this.actorFolderBase}/${this.name}`; + return `${this.name}`; + } + + getPackFolderByPath(path) { + const names = path.split('/'); + if (names[0] === '') { + names.shift(); + } + let name = names.shift(); + if (!this.actorFolderPack) { + return undefined; + } + let folder = this.actorFolderPack.folders + .filter((f) => f.type === 'Actor' && !f.folder) + .find((f) => f.name === name); + if (!folder) { + return undefined; + } + while (names.length > 0) { + name = names.shift(); + folder = folder.children.find((c) => c.folder.name === name); + if (!folder) { + return undefined; + } + folder = folder.folder; + } + return folder; + } + + getPackActorsInFolder(inFolder) { + const prefixStack = ['']; + const actors = {}; + const folderStack = [inFolder]; + while (folderStack.length > 0) { + const prefix = prefixStack.shift(); + const folder = folderStack.shift(); + for (const actor of this.packActors.filter((pa) => pa.folder === folder.id)) { + actors[`${prefix}${actor.name}`] = actor; + } + for (const child of folder.children) { + const newPrefix = `${prefix}${child.folder.name} | `; + prefixStack.push(newPrefix); + folderStack.push(child.folder); + } + } + return actors; } prepFolders() { @@ -793,7 +863,7 @@ export class ActorFolderEffect extends PowerEffect { `${this.actorFolder}/${this.source.actor.name}`, ]; for (const folderName of folderNames) { - const folder = moduleHelpers.getActorFolderByPath(folderName); + const folder = this.getPackFolderByPath(folderName); if (folder) { log(`Found actor folder ${folderName}`); folders.push(folder); @@ -809,7 +879,7 @@ export class ActorFolderEffect extends PowerEffect { const folders = this.prepFolders(); const actors = {}; for (const folder of folders) { - const folderActors = moduleHelpers.getActorsInFolder(folder); + const folderActors = this.getPackActorsInFolder(folder); for (const key in folderActors) { actors[key] = folderActors[key]; } @@ -823,7 +893,6 @@ export class ActorFolderEffect extends PowerEffect { } getActors() { - this.data.actors = this.prepActors(); const choices = {}; const effects = {}; const values = {}; @@ -831,7 +900,7 @@ export class ActorFolderEffect extends PowerEffect { .filter((k) => !k.includes('_template')) .sort() .forEach((key) => { - const id = this.data.actors[key].id; + const id = this.data.actors[key].uuid; choices[id] = key; effects[id] = null; values[id] = this.actorValue(this.data.actors[key]); @@ -924,7 +993,7 @@ export class ActorFolderEffect extends PowerEffect { async parseValues() { await super.parseValues(); this.data.maintId = foundry.utils.randomID(); - this.targetActor = await game.actors.get(this.data.actorId); + this.targetActor = await game.tcal.importTransientActor(this.data.actorId, { preferExisting: true }); this.targetTokenDoc = await this.targetActor.getTokenDocument(); const perm = CONST?.DOCUMENT_PERMISSION_LEVELS?.OWNER ?? CONST?.DOCUMENT_OWNERSHIP_LEVELS?.OWNER; const sourceUpdates = { diff --git a/src/module/powers/powers.js b/src/module/powers/powers.js index 645416a..8290ae2 100644 --- a/src/module/powers/powers.js +++ b/src/module/powers/powers.js @@ -80,7 +80,7 @@ import { InquisitorJudgementEffect } from './inquisitor.js'; const { DialogV2 } = foundry.applications.api; -const PowerClasses = { +export const PowerClasses = { 'animal-companion': SummonCompanionEffect, 'arcane-protection': ArcaneProtectionEffect, 'baleful-polymorph': BalefulPolymorphEffect, diff --git a/src/module/powers/summon.js b/src/module/powers/summon.js index b7dd5f7..f826e4b 100644 --- a/src/module/powers/summon.js +++ b/src/module/powers/summon.js @@ -240,6 +240,15 @@ class BaseAllyEffect extends BaseSummonEffect { } export class SummonAllyEffect extends BaseAllyEffect { + async init() { + await super.init(); + this.data.templates = {}; + for (let tplName of ['combat-edge_template', 'flight_template', 'raise_template']) { + if (tplName in this.data.actors) { + this.data.templates[tplName] = await foundry.utils.fromUuid(this.data.actors[tplName].uuid); + } + } + } get name() { return 'Summon Ally'; } @@ -274,7 +283,7 @@ export class SummonAllyEffect extends BaseAllyEffect { } get _edges() { - const template = this.data.actors['combat-edge_template']; + const template = this.data.templates['combat-edge_template']; if (!template) { return []; } @@ -294,7 +303,7 @@ export class SummonAllyEffect extends BaseAllyEffect { get modifiers() { const mods = super.modifiers; - if ('flight_template' in this.data.actors) { + if ('flight_template' in this.data.templates) { mods.push({ type: 'checkbox', default: false, @@ -305,7 +314,7 @@ export class SummonAllyEffect extends BaseAllyEffect { effect: false, }); } - if ('combat-edge_template' in this.data.actors) { + if ('combat-edge_template' in this.data.templates) { const { choices, effects, values } = this._edges; for (let i = 1; i <= 3; i++) { mods.push({ @@ -325,8 +334,8 @@ export class SummonAllyEffect extends BaseAllyEffect { async parseValuesMid() { await super.parseValuesMid(); - if (this.data.raise && this.data.actors['raise_template']) { - const raiseTemplate = this.data.actors.raise_template; + if (this.data.raise && this.data.templates['raise_template']) { + const raiseTemplate = this.data.templates.raise_template; for (const item of raiseTemplate.items) { const raiseItemDoc = await raiseTemplate.getEmbeddedDocument('Item', item.id); this.data.embeddedUpdates.Item[item.name] = raiseItemDoc; @@ -396,7 +405,7 @@ export class SummonAllyEffect extends BaseAllyEffect { async parseValues() { await super.parseValues(); - const template = this.data.actors['combat-edge_template']; + const template = this.data.templates['combat-edge_template']; for (let i = 1; i <= 3; i++) { const edgeName = this.data[`combatEdge${i}`]; if (edgeName === 'None') { @@ -406,8 +415,8 @@ export class SummonAllyEffect extends BaseAllyEffect { const edge = await template.getEmbeddedDocument('Item', edgeId); this.data.embeddedUpdates.Item[edgeName] = edge; } - if (this.data.flight && 'flight_template' in this.data.actors) { - const flightTemplate = this.data.actors.flight_template; + if (this.data.flight && 'flight_template' in this.data.templates) { + const flightTemplate = this.data.templates.flight_template; for (const item of flightTemplate.items) { const doc = await flightTemplate.getEmbeddedDocument('Item', item.id); this.data.embeddedUpdates.Item[item.name] = doc;