diff --git a/lang/en.json b/lang/en.json index cd8d10ae..1d4544b9 100755 --- a/lang/en.json +++ b/lang/en.json @@ -611,6 +611,9 @@ "insufficientHope": "The initiating character doesn't have enough hope", "createTagTeam": "Create TagTeam Roll", "chatMessageRollTitle": "Roll" + }, + "TokenConfig": { + "actorSizeUsed": "Actor size is set, determining the dimensions" } }, "CLASS": { diff --git a/module/applications/sheets-configs/prototype-token-config.mjs b/module/applications/sheets-configs/prototype-token-config.mjs index 24c9dabb..0bb9703a 100644 --- a/module/applications/sheets-configs/prototype-token-config.mjs +++ b/module/applications/sheets-configs/prototype-token-config.mjs @@ -1,4 +1,18 @@ export default class DhPrototypeTokenConfig extends foundry.applications.sheets.PrototypeTokenConfig { + /** @override */ + static PARTS = { + tabs: super.PARTS.tabs, + identity: super.PARTS.identity, + appearance: { + template: 'systems/daggerheart/templates/sheets-settings/token-config/appearance.hbs', + scrollable: [''] + }, + vision: super.PARTS.vision, + light: super.PARTS.light, + resources: super.PARTS.resources, + footer: super.PARTS.footer + }; + /** @inheritDoc */ async _prepareResourcesTab() { const token = this.token; @@ -17,4 +31,11 @@ export default class DhPrototypeTokenConfig extends foundry.applications.sheets. turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations }; } + + async _prepareAppearanceTab() { + const context = await super._prepareAppearanceTab(); + context.actorSizeUsed = this.token.actor ? Boolean(this.token.actor.system.size) : false; + + return context; + } } diff --git a/module/applications/sheets-configs/token-config.mjs b/module/applications/sheets-configs/token-config.mjs index ee573e5d..5f4e4f56 100644 --- a/module/applications/sheets-configs/token-config.mjs +++ b/module/applications/sheets-configs/token-config.mjs @@ -1,4 +1,18 @@ export default class DhTokenConfig extends foundry.applications.sheets.TokenConfig { + /** @override */ + static PARTS = { + tabs: super.PARTS.tabs, + identity: super.PARTS.identity, + appearance: { + template: 'systems/daggerheart/templates/sheets-settings/token-config/appearance.hbs', + scrollable: [''] + }, + vision: super.PARTS.vision, + light: super.PARTS.light, + resources: super.PARTS.resources, + footer: super.PARTS.footer + }; + /** @inheritDoc */ async _prepareResourcesTab() { const token = this.token; @@ -17,4 +31,11 @@ export default class DhTokenConfig extends foundry.applications.sheets.TokenConf turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations }; } + + async _prepareAppearanceTab() { + const context = await super._prepareAppearanceTab(); + context.actorSizeUsed = this.token.actor ? Boolean(this.token.actor.system.size) : false; + + return context; + } } diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index 6496a459..fdef7d03 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -212,6 +212,11 @@ export const adversaryTraits = { }; export const tokenSize = { + custom: { + id: 'custom', + value: 0, + label: 'DAGGERHEART.GENERAL.custom' + }, tiny: { id: 'tiny', value: 1, diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index e1b40785..37f9c5c8 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -80,9 +80,9 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { if (this.metadata.usesSize) schema.size = new fields.StringField({ required: true, - nullable: true, + nullable: false, choices: CONFIG.DH.ACTOR.tokenSize, - initial: null + initial: CONFIG.DH.ACTOR.tokenSize.custom.id }); return schema; } diff --git a/module/documents/scene.mjs b/module/documents/scene.mjs index 50f520a9..c6cdd2c2 100644 --- a/module/documents/scene.mjs +++ b/module/documents/scene.mjs @@ -7,8 +7,10 @@ export default class DhScene extends Scene { /** Synchronize a token's dimensions with its actor's size category. */ syncTokenDimensions(tokenDoc, tokenSize) { if (!tokenDoc.parent?.tokens.has(tokenDoc.id)) return; + const prototype = tokenDoc.actor?.prototypeToken ?? tokenDoc; this.#sizeSyncBatch.set(tokenDoc.id, { size: tokenSize, + prototypeSize: { width: prototype.width, height: prototype.height }, position: { x: tokenDoc.x, y: tokenDoc.y, elevation: tokenDoc.elevation } }); this.#processSyncBatch(); @@ -20,18 +22,15 @@ export default class DhScene extends Scene { const entries = this.#sizeSyncBatch .entries() .toArray() - .map(([_id, { size, position }]) => { + .map(([_id, { size, prototypeSize, position }]) => { const tokenSize = tokenSizes[size]; - const updatedPosition = DHToken.getSnappedPositionInSquareGrid( - this.grid, - position, - tokenSize, - tokenSize - ); + const width = size !== CONFIG.DH.ACTOR.tokenSize.custom.id ? tokenSize : prototypeSize.width; + const height = size !== CONFIG.DH.ACTOR.tokenSize.custom.id ? tokenSize : prototypeSize.height; + const updatedPosition = DHToken.getSnappedPositionInSquareGrid(this.grid, position, width, height); return { _id, - width: tokenSize, - height: tokenSize, + width, + height, ...updatedPosition }; }); diff --git a/module/documents/token.mjs b/module/documents/token.mjs index b85e46a7..35a86671 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -111,7 +111,7 @@ export default class DHToken extends CONFIG.Token.documentClass { const actor = document.actor; if (actor?.system.metadata.usesSize) { const tokenSize = tokenSizes[actor.system.size]; - if (tokenSize) { + if (tokenSize && tokenSize !== CONFIG.DH.ACTOR.tokenSize.custom.id) { document.updateSource({ width: tokenSize, height: tokenSize @@ -126,12 +126,21 @@ export default class DHToken extends CONFIG.Token.documentClass { super._onRelatedUpdate(update, operation); if (!this.actor?.isOwner) return; + + const updates = Array.isArray(update) ? update : [update]; const activeGM = game.users.activeGM; // Let the active GM take care of updates if available - if (this.actor.system.metadata.usesSize && update.system?.size && activeGM && game.user.id === activeGM.id) { - const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; - const tokenSize = tokenSizes[update.system.size]; - if (tokenSize !== this.width || tokenSize !== this.height) { - this.parent?.syncTokenDimensions(this, update.system.size); + for (let update of updates) { + if ( + this.actor.system.metadata.usesSize && + update.system?.size && + activeGM && + game.user.id === activeGM.id + ) { + const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; + const tokenSize = tokenSizes[update.system.size]; + if (tokenSize !== this.width || tokenSize !== this.height) { + this.parent?.syncTokenDimensions(this, update.system.size); + } } } } @@ -156,8 +165,10 @@ export default class DHToken extends CONFIG.Token.documentClass { if (this.actor?.system.metadata.usesSize) { const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; const tokenSize = tokenSizes[this.actor.system.size]; - width = tokenSize ?? width; - height = tokenSize ?? height; + if (tokenSize && tokenSize !== CONFIG.DH.ACTOR.tokenSize.custom.id) { + width = tokenSize ?? width; + height = tokenSize ?? height; + } } // Round width and height to nearest multiple of 0.5 if not small diff --git a/templates/sheets-settings/token-config/appearance.hbs b/templates/sheets-settings/token-config/appearance.hbs new file mode 100644 index 00000000..0f6019ba --- /dev/null +++ b/templates/sheets-settings/token-config/appearance.hbs @@ -0,0 +1,82 @@ +
{{localize "TOKEN.AnchorHint"}}
+