const fields = foundry.data.fields; export default class DHSummonField extends fields.SchemaField { /** * Action Workflow order */ static order = 130; constructor(options = {}, context = {}) { const transformFields = { actorUUID: new fields.DocumentUUIDField({ type: 'Actor', required: true }), resourceRefresh: new fields.SchemaField({ hitPoints: new fields.BooleanField({ initial: true }), stress: new fields.BooleanField({ initial: true }) }) }; super(transformFields, options, context); } static async execute() { if (!this.transform.actorUUID) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.noTransformActor')); return false; } const baseActor = await foundry.utils.fromUuid(this.transform.actorUUID); if (!baseActor) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.transformActorMissing')); return false; } if (!canvas.scene) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.canvasError')); return false; } const activeTokens = this.actor.getActiveTokens().map(x => x.document); const controlledMatchingTokens = canvas.tokens.controlled .filter(x => x.actor && x.actor.uuid === this.actor.uuid) .map(x => x.document); const token = this.actor.token ?? ( activeTokens.length === 1 ? activeTokens[0] : (controlledMatchingTokens.length === 1 ? controlledMatchingTokens[0] : null) ); if (!this.actor.token && !token) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.linkedSelectedError')); return false; } if (!token) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.transform.prototypeError')); return false; } const actor = await DHSummonField.getWorldActor(baseActor); const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; const tokenSize = actor?.system.metadata.usesSize ? tokenSizes[actor.system.size] : actor.prototypeToken.width; await token.update( { ...actor.prototypeToken.toJSON(), actorLink: false, actorId: actor.id, width: tokenSize, height: tokenSize }, { diff: false, recursive: false, noHook: true } ); if (token.combatant) { token.combatant.update({ actorId: actor.id, img: actor.prototypeToken.texture.src }); } const marks = { hitPoints: 0, stress: 0 }; if (!this.transform.resourceRefresh.hitPoints) { marks.hitPoints = Math.min( this.actor.system.resources.hitPoints.value, token.actor.system.resources.hitPoints.max - 1 ); } if (!this.transform.resourceRefresh.stress) { marks.stress = Math.min( this.actor.system.resources.stress.value, token.actor.system.resources.stress.max - 1 ); } if (marks.hitPoints || marks.stress) { token.actor.update({ 'system.resources': { hitPoints: { value: marks.hitPoints }, stress: { value: marks.stress } } }); } const prevPosition = { ...this.actor.sheet.position }; this.actor.sheet.close(); token.actor.sheet.render({ force: true, position: prevPosition }); } /* Check for any available instances of the actor present in the world, or create a world actor based on compendium */ static async getWorldActor(baseActor) { if (!baseActor.inCompendium) return baseActor; const dataType = game.system.api.data.actors[`Dh${baseActor.type.capitalize()}`]; if (dataType && baseActor.img === dataType.DEFAULT_ICON) { const worldActorCopy = game.actors.find(x => x.name === baseActor.name); if (worldActorCopy) return worldActorCopy; } const worldActor = await game.system.api.documents.DhpActor.create(baseActor.toObject()); return worldActor; } }