import { formatCredits } from './tradeHelper.js'; import { createNpcActor, generateClientMission, generateEncounter, generateQuickNpc } from './npcHelper.js'; import { NPC_RELATIONS } from './data/npcTables.js'; const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; const MODULE_ID = 'mgt2-compendium-amiral-denisov'; export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) { static DEFAULT_OPTIONS = { id: 'mgt2-npc', classes: ['mgt2-npc-dialog'], position: { width: 720, height: 'auto', }, window: { title: 'PNJ & Rencontres – MgT2e', resizable: true, }, }; static PARTS = { main: { template: `modules/${MODULE_ID}/templates/npc-dialog.hbs`, root: true, }, }; constructor(options = {}) { super(options); this._activeTab = options.initialTab ?? 'npc'; this._formData = { npc: { relation: options.relation ?? 'contact', experienceBias: 'random', createActor: false, actorName: '', openCreatedActor: true, }, encounter: { context: options.context ?? 'starport', includeFollowUp: true, }, }; } async _prepareContext() { registerHandlebarsHelpers(); return { ...this._formData, activeTab: this._activeTab, relations: Object.entries(NPC_RELATIONS).map(([key, value]) => ({ key, label: value.label })), }; } async _onRender(context, options) { await super._onRender(context, options); const html = this._getForm(); if (!html?.length) return; html.addClass('mgt2-npc-form'); this._applyThemeStyles(html); html.find('[data-action="generate-npc"]').on('click', async (event) => { event.preventDefault(); this._readForm(html); await this._handleNpc(); }); html.find('[data-action="generate-encounter"]').on('click', async (event) => { event.preventDefault(); this._readForm(html); await this._handleEncounter(); }); html.find('[data-action="generate-mission"]').on('click', async (event) => { event.preventDefault(); this._readForm(html); await this._handleMission(); }); html.find('.tabs .item').on('click', (event) => { event.preventDefault(); this._readForm(html); this._activateTab($(event.currentTarget).data('tab')); }); } _getForm() { return $(this.element).find('.window-content'); } _activateTab(tabId) { const html = this._getForm(); if (!html?.length) return; this._activeTab = tabId; html.find('.tabs .item').removeClass('active'); html.find(`.tabs .item[data-tab="${tabId}"]`).addClass('active'); html.find('.tab-content .tab').removeClass('active'); html.find(`.tab-content .tab[data-tab="${tabId}"]`).addClass('active'); this._applyThemeStyles(html); } _applyThemeStyles(html) { html.find('.tabs .item').css({ color: '#d8c79a', 'text-shadow': 'none', 'background-color': '', 'border-bottom-color': 'transparent' }); html.find('.tabs .item.active').css({ color: '#d9b24c', 'text-shadow': 'none', 'background-color': 'rgba(201, 162, 39, 0.18)', 'border-bottom-color': '#c9a227' }); html.find('h3').css({ color: '#5f4300', 'border-bottom-color': '#b78f26', 'text-shadow': 'none' }); html.find('legend').css({ color: '#7a5c00', 'text-shadow': 'none' }); } _readForm(html) { this._formData.npc.relation = html.find('[name="npc.relation"]').val(); this._formData.npc.experienceBias = html.find('[name="npc.experienceBias"]').val(); this._formData.npc.createActor = html.find('[name="npc.createActor"]').is(':checked'); this._formData.npc.actorName = html.find('[name="npc.actorName"]').val(); this._formData.npc.openCreatedActor = html.find('[name="npc.openCreatedActor"]').is(':checked'); this._formData.encounter.context = html.find('[name="encounter.context"]').val(); this._formData.encounter.includeFollowUp = html.find('[name="encounter.includeFollowUp"]').is(':checked'); } async _handleNpc() { const result = await generateQuickNpc(this._formData.npc); if (this._formData.npc.createActor) { const actor = await createNpcActor(result, { name: this._formData.npc.actorName, openSheet: this._formData.npc.openCreatedActor, }); result.createdActor = { id: actor.id, name: actor.name }; ui.notifications.info(`Fiche PNJ créée : ${actor.name}`); } await this._postToChatResult(result); } async _handleEncounter() { const result = await generateEncounter(this._formData.encounter); await this._postToChatResult(result); } async _handleMission() { const result = await generateClientMission(); await this._postToChatResult(result); } async _postToChatResult(data) { registerHandlebarsHelpers(); const html = await foundry.applications.handlebars.renderTemplate(`modules/${MODULE_ID}/templates/npc-result.hbs`, data); await ChatMessage.create({ content: html, speaker: ChatMessage.getSpeaker(), flags: { [MODULE_ID]: { type: 'npc-result' } }, }); } } let helpersRegistered = false; function registerHandlebarsHelpers() { if (helpersRegistered) return; helpersRegistered = true; Handlebars.registerHelper('eq', (a, b) => a === b); Handlebars.registerHelper('join', (arr, sep) => (Array.isArray(arr) ? arr.join(sep) : '')); Handlebars.registerHelper('formatCredits', (amount) => formatCredits(amount)); Handlebars.registerHelper('contains', (text, search) => String(text ?? '').includes(search)); }