188 lines
5.6 KiB
JavaScript
188 lines
5.6 KiB
JavaScript
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));
|
||
}
|