summon ally reworked to use transient actors

This commit is contained in:
Mike Bloy 2025-06-03 23:59:44 -05:00
parent 0560cc5778
commit b41fd8833b
3 changed files with 95 additions and 17 deletions

View File

@ -94,7 +94,8 @@ export class PowerFormApplication extends HandlebarsApplicationMixin(Application
return a.name === b.name ? 0 : a.name < b.name ? -1 : 1; 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); let modifiers = foundry.utils.deepClone(this.powerEffect.modifiers);
modifiers.sort(PowerFormApplication.sortMods); modifiers.sort(PowerFormApplication.sortMods);
for (const modifier of modifiers) { for (const modifier of modifiers) {
@ -170,6 +171,10 @@ export class PowerEffect {
this.data = {}; this.data = {};
} }
async init() {
log('Power Effect', this.name, 'Init');
}
static async getStatus(label, name, favorite = true) { static async getStatus(label, name, favorite = true) {
const effect = foundry.utils.deepClone(CONFIG.statusEffects.find((se) => se.label === label || se.name === label)); const effect = foundry.utils.deepClone(CONFIG.statusEffects.find((se) => se.label === label || se.name === label));
effect.name = 'name' in effect ? effect.name : effect.label; effect.name = 'name' in effect ? effect.name : effect.label;
@ -773,12 +778,77 @@ export class PowerEffect {
} }
export class ActorFolderEffect extends 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() { 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() { 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() { prepFolders() {
@ -793,7 +863,7 @@ export class ActorFolderEffect extends PowerEffect {
`${this.actorFolder}/${this.source.actor.name}`, `${this.actorFolder}/${this.source.actor.name}`,
]; ];
for (const folderName of folderNames) { for (const folderName of folderNames) {
const folder = moduleHelpers.getActorFolderByPath(folderName); const folder = this.getPackFolderByPath(folderName);
if (folder) { if (folder) {
log(`Found actor folder ${folderName}`); log(`Found actor folder ${folderName}`);
folders.push(folder); folders.push(folder);
@ -809,7 +879,7 @@ export class ActorFolderEffect extends PowerEffect {
const folders = this.prepFolders(); const folders = this.prepFolders();
const actors = {}; const actors = {};
for (const folder of folders) { for (const folder of folders) {
const folderActors = moduleHelpers.getActorsInFolder(folder); const folderActors = this.getPackActorsInFolder(folder);
for (const key in folderActors) { for (const key in folderActors) {
actors[key] = folderActors[key]; actors[key] = folderActors[key];
} }
@ -823,7 +893,6 @@ export class ActorFolderEffect extends PowerEffect {
} }
getActors() { getActors() {
this.data.actors = this.prepActors();
const choices = {}; const choices = {};
const effects = {}; const effects = {};
const values = {}; const values = {};
@ -831,7 +900,7 @@ export class ActorFolderEffect extends PowerEffect {
.filter((k) => !k.includes('_template')) .filter((k) => !k.includes('_template'))
.sort() .sort()
.forEach((key) => { .forEach((key) => {
const id = this.data.actors[key].id; const id = this.data.actors[key].uuid;
choices[id] = key; choices[id] = key;
effects[id] = null; effects[id] = null;
values[id] = this.actorValue(this.data.actors[key]); values[id] = this.actorValue(this.data.actors[key]);
@ -924,7 +993,7 @@ export class ActorFolderEffect extends PowerEffect {
async parseValues() { async parseValues() {
await super.parseValues(); await super.parseValues();
this.data.maintId = foundry.utils.randomID(); 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(); this.targetTokenDoc = await this.targetActor.getTokenDocument();
const perm = CONST?.DOCUMENT_PERMISSION_LEVELS?.OWNER ?? CONST?.DOCUMENT_OWNERSHIP_LEVELS?.OWNER; const perm = CONST?.DOCUMENT_PERMISSION_LEVELS?.OWNER ?? CONST?.DOCUMENT_OWNERSHIP_LEVELS?.OWNER;
const sourceUpdates = { const sourceUpdates = {

View File

@ -80,7 +80,7 @@ import { InquisitorJudgementEffect } from './inquisitor.js';
const { DialogV2 } = foundry.applications.api; const { DialogV2 } = foundry.applications.api;
const PowerClasses = { export const PowerClasses = {
'animal-companion': SummonCompanionEffect, 'animal-companion': SummonCompanionEffect,
'arcane-protection': ArcaneProtectionEffect, 'arcane-protection': ArcaneProtectionEffect,
'baleful-polymorph': BalefulPolymorphEffect, 'baleful-polymorph': BalefulPolymorphEffect,

View File

@ -240,6 +240,15 @@ class BaseAllyEffect extends BaseSummonEffect {
} }
export class SummonAllyEffect extends BaseAllyEffect { 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() { get name() {
return 'Summon Ally'; return 'Summon Ally';
} }
@ -274,7 +283,7 @@ export class SummonAllyEffect extends BaseAllyEffect {
} }
get _edges() { get _edges() {
const template = this.data.actors['combat-edge_template']; const template = this.data.templates['combat-edge_template'];
if (!template) { if (!template) {
return []; return [];
} }
@ -294,7 +303,7 @@ export class SummonAllyEffect extends BaseAllyEffect {
get modifiers() { get modifiers() {
const mods = super.modifiers; const mods = super.modifiers;
if ('flight_template' in this.data.actors) { if ('flight_template' in this.data.templates) {
mods.push({ mods.push({
type: 'checkbox', type: 'checkbox',
default: false, default: false,
@ -305,7 +314,7 @@ export class SummonAllyEffect extends BaseAllyEffect {
effect: false, effect: false,
}); });
} }
if ('combat-edge_template' in this.data.actors) { if ('combat-edge_template' in this.data.templates) {
const { choices, effects, values } = this._edges; const { choices, effects, values } = this._edges;
for (let i = 1; i <= 3; i++) { for (let i = 1; i <= 3; i++) {
mods.push({ mods.push({
@ -325,8 +334,8 @@ export class SummonAllyEffect extends BaseAllyEffect {
async parseValuesMid() { async parseValuesMid() {
await super.parseValuesMid(); await super.parseValuesMid();
if (this.data.raise && this.data.actors['raise_template']) { if (this.data.raise && this.data.templates['raise_template']) {
const raiseTemplate = this.data.actors.raise_template; const raiseTemplate = this.data.templates.raise_template;
for (const item of raiseTemplate.items) { for (const item of raiseTemplate.items) {
const raiseItemDoc = await raiseTemplate.getEmbeddedDocument('Item', item.id); const raiseItemDoc = await raiseTemplate.getEmbeddedDocument('Item', item.id);
this.data.embeddedUpdates.Item[item.name] = raiseItemDoc; this.data.embeddedUpdates.Item[item.name] = raiseItemDoc;
@ -396,7 +405,7 @@ export class SummonAllyEffect extends BaseAllyEffect {
async parseValues() { async parseValues() {
await super.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++) { for (let i = 1; i <= 3; i++) {
const edgeName = this.data[`combatEdge${i}`]; const edgeName = this.data[`combatEdge${i}`];
if (edgeName === 'None') { if (edgeName === 'None') {
@ -406,8 +415,8 @@ export class SummonAllyEffect extends BaseAllyEffect {
const edge = await template.getEmbeddedDocument('Item', edgeId); const edge = await template.getEmbeddedDocument('Item', edgeId);
this.data.embeddedUpdates.Item[edgeName] = edge; this.data.embeddedUpdates.Item[edgeName] = edge;
} }
if (this.data.flight && 'flight_template' in this.data.actors) { if (this.data.flight && 'flight_template' in this.data.templates) {
const flightTemplate = this.data.actors.flight_template; const flightTemplate = this.data.templates.flight_template;
for (const item of flightTemplate.items) { for (const item of flightTemplate.items) {
const doc = await flightTemplate.getEmbeddedDocument('Item', item.id); const doc = await flightTemplate.getEmbeddedDocument('Item', item.id);
this.data.embeddedUpdates.Item[item.name] = doc; this.data.embeddedUpdates.Item[item.name] = doc;