diff --git a/lang/en.json b/lang/en.json index 54e2dd7..48355ee 100644 --- a/lang/en.json +++ b/lang/en.json @@ -309,6 +309,9 @@ "Specialty": "Specialty", "AdventuringBehavior": "Adventuring Behavior", "CombatBehavior": "Combat Behavior", + "RollBehavior": "Roll Behavior", + "NoTableLinked": "No behavior table is linked.", + "TableNotFound": "The linked behavior table could not be found.", "FIELDS": { "abilities": { "label": "Abilities", @@ -358,11 +361,11 @@ "specialtyText": { "label": "Specialty" }, - "adventuringBehavior": { - "label": "Adventuring Behavior" + "adventuringBehaviorUuid": { + "label": "Adventuring Behavior Table" }, - "combatBehavior": { - "label": "Combat Behavior" + "combatBehaviorUuid": { + "label": "Combat Behavior Table" }, "upkeep": { "label": "Upkeep" diff --git a/module/applications/sheets/companion-sheet.mjs b/module/applications/sheets/companion-sheet.mjs index 8e924c6..2d73c1a 100644 --- a/module/applications/sheets/companion-sheet.mjs +++ b/module/applications/sheets/companion-sheet.mjs @@ -7,9 +7,84 @@ export default class MGNECompanionSheet extends MGNEActorSheet { width: 820, height: 700, }, + actions: { + rollAdventuringBehavior: MGNECompanionSheet.prototype._rollAdventuringBehavior, + clearAdventuringBehavior: MGNECompanionSheet.prototype._clearAdventuringBehavior, + openAdventuringBehavior: MGNECompanionSheet.prototype._openAdventuringBehavior, + rollCombatBehavior: MGNECompanionSheet.prototype._rollCombatBehavior, + clearCombatBehavior: MGNECompanionSheet.prototype._clearCombatBehavior, + openCombatBehavior: MGNECompanionSheet.prototype._openCombatBehavior, + }, } static PARTS = { main: { template: "systems/fvtt-machine-gods-noxian-expanse/templates/companion-main.hbs" }, } + + async _prepareContext() { + const context = await super._prepareContext() + + const resolveTable = async (uuid) => { + if (!uuid) return null + const table = await fromUuid(uuid).catch(() => null) + return table ? { name: table.name, uuid } : null + } + + context.adventuringTable = await resolveTable(this.document.system.adventuringBehaviorUuid) + context.combatTable = await resolveTable(this.document.system.combatBehaviorUuid) + + return context + } + + async _onDrop(event) { + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event) + if (data?.type === "RollTable") { + const table = await fromUuid(data.uuid) + if (!table) return super._onDrop(event) + + // Determine drop target by proximity to each section + const target = event.target.closest("[data-behavior-slot]") + const slot = target?.dataset.behaviorSlot + if (slot === "adventuring") { + await this.document.update({ "system.adventuringBehaviorUuid": data.uuid }) + return + } + if (slot === "combat") { + await this.document.update({ "system.combatBehaviorUuid": data.uuid }) + return + } + // Fallback: first empty slot, then adventuring + const sys = this.document.system + if (!sys.adventuringBehaviorUuid) { + await this.document.update({ "system.adventuringBehaviorUuid": data.uuid }) + } else { + await this.document.update({ "system.combatBehaviorUuid": data.uuid }) + } + return + } + return super._onDrop(event) + } + + async _rollAdventuringBehavior() { await this._rollTable("adventuringBehaviorUuid") } + async _clearAdventuringBehavior() { await this.document.update({ "system.adventuringBehaviorUuid": "" }) } + async _openAdventuringBehavior() { await this._openTable("adventuringBehaviorUuid") } + + async _rollCombatBehavior() { await this._rollTable("combatBehaviorUuid") } + async _clearCombatBehavior() { await this.document.update({ "system.combatBehaviorUuid": "" }) } + async _openCombatBehavior() { await this._openTable("combatBehaviorUuid") } + + async _rollTable(uuidField) { + const uuid = this.document.system[uuidField] + if (!uuid) return ui.notifications.warn(game.i18n.localize("MGNE.Companion.NoTableLinked")) + const table = await fromUuid(uuid).catch(() => null) + if (!table) return ui.notifications.warn(game.i18n.localize("MGNE.Companion.TableNotFound")) + await table.draw() + } + + async _openTable(uuidField) { + const uuid = this.document.system[uuidField] + if (!uuid) return + const table = await fromUuid(uuid).catch(() => null) + if (table) table.sheet.render(true) + } } diff --git a/module/models/companion.mjs b/module/models/companion.mjs index 94fd13d..eaa949a 100644 --- a/module/models/companion.mjs +++ b/module/models/companion.mjs @@ -18,8 +18,8 @@ export default class MGNECompanion extends foundry.abstract.TypeDataModel { valueText: stringField(""), traitText: stringField(""), specialtyText: stringField(""), - adventuringBehavior: htmlField(""), - combatBehavior: htmlField(""), + adventuringBehaviorUuid: stringField(""), + combatBehaviorUuid: stringField(""), upkeep: stringField("3d10c per full rest"), description: htmlField(""), notes: htmlField(""), @@ -28,4 +28,12 @@ export default class MGNECompanion extends foundry.abstract.TypeDataModel { /** @override */ static LOCALIZATION_PREFIXES = ["MGNE.Companion"] + + /** @override */ + static migrateData(source) { + // Remove old html behavior fields if present + if ("adventuringBehavior" in source) delete source.adventuringBehavior + if ("combatBehavior" in source) delete source.combatBehavior + return super.migrateData(source) + } } diff --git a/templates/companion-main.hbs b/templates/companion-main.hbs index ece76af..0566161 100644 --- a/templates/companion-main.hbs +++ b/templates/companion-main.hbs @@ -81,21 +81,61 @@