Mise à jour des compendiums et scripts pour v14
- Mise à jour des manifestes et logs des packs - Modification des scripts NPC (NpcDialog.js, travellerNpcGenerator.js, npc.js) - Mise à jour de la description du module pour refléter l'onglet 'PNJ Détaillé' Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
+174
-2
@@ -1,6 +1,19 @@
|
||||
import { formatCredits } from './tradeHelper.js';
|
||||
import { createNpcActor, generateClientMission, generateEncounter, generateQuickNpc } from './npcHelper.js';
|
||||
import { NPC_RELATIONS } from './data/npcTables.js';
|
||||
import { generateAndCreateTravellerNpc } from './travellerNpcGenerator.js';
|
||||
import { generateRandomName } from './data/travellerNpcGenerator.js';
|
||||
import {
|
||||
CITIZEN_CATEGORY_LIST,
|
||||
EXPERIENCE_LEVEL_LIST,
|
||||
ROLE_LIST,
|
||||
GENDER_LIST,
|
||||
DEFAULT_OPTIONS,
|
||||
CITIZEN_CATEGORY_LABELS_FR,
|
||||
EXPERIENCE_LEVEL_LABELS_FR,
|
||||
ROLE_LABELS_FR,
|
||||
GENDER_LABELS_FR
|
||||
} from './data/travellerNpcGenerator.js';
|
||||
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
@@ -41,6 +54,19 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
context: options.context ?? 'starport',
|
||||
includeFollowUp: true,
|
||||
},
|
||||
mission: {},
|
||||
traveller: {
|
||||
citizenCategory: DEFAULT_OPTIONS.citizenCategory,
|
||||
experience: DEFAULT_OPTIONS.experience,
|
||||
role: DEFAULT_OPTIONS.role,
|
||||
gender: DEFAULT_OPTIONS.gender,
|
||||
firstName: '',
|
||||
surname: '',
|
||||
useRandomName: true,
|
||||
createActor: DEFAULT_OPTIONS.createActor,
|
||||
actorName: '',
|
||||
openCreatedActor: DEFAULT_OPTIONS.openCreatedActor,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,6 +76,25 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
...this._formData,
|
||||
activeTab: this._activeTab,
|
||||
relations: Object.entries(NPC_RELATIONS).map(([key, value]) => ({ key, label: value.label })),
|
||||
citizenCategories: CITIZEN_CATEGORY_LIST.map(c => ({
|
||||
key: c.key,
|
||||
label: CITIZEN_CATEGORY_LABELS_FR[c.key] || c.label,
|
||||
description: c.description
|
||||
})),
|
||||
experienceLevels: EXPERIENCE_LEVEL_LIST.map(e => ({
|
||||
key: e.key,
|
||||
label: EXPERIENCE_LEVEL_LABELS_FR[e.key] || e.label,
|
||||
description: e.description
|
||||
})),
|
||||
roles: ROLE_LIST.map(r => ({
|
||||
key: r.key,
|
||||
label: ROLE_LABELS_FR[r.key] || r.label,
|
||||
description: r.description
|
||||
})),
|
||||
genders: GENDER_LIST.map(g => ({
|
||||
key: g.key,
|
||||
label: GENDER_LABELS_FR[g.key] || g.label
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -84,6 +129,27 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
this._readForm(html);
|
||||
this._activateTab($(event.currentTarget).data('tab'));
|
||||
});
|
||||
|
||||
// Gestion des événements pour l'onglet PNJ Détaillé (Traveller)
|
||||
html.find('[data-action="generate-traveller-npc"]').on('click', async (event) => {
|
||||
event.preventDefault();
|
||||
this._readForm(html);
|
||||
await this._handleTravellerNpc();
|
||||
});
|
||||
|
||||
html.find('[data-action="randomize-name"]').on('click', (event) => {
|
||||
event.preventDefault();
|
||||
this._randomizeTravellerName(html);
|
||||
});
|
||||
|
||||
html.find('[name="traveller.useRandomName"]').on('change', (event) => {
|
||||
const useRandom = event.target.checked;
|
||||
this._formData.traveller.useRandomName = useRandom;
|
||||
html.find('.traveller-name-fields').toggleClass('hidden', useRandom);
|
||||
});
|
||||
|
||||
// Initialiser l'affichage des champs de nom pour l'onglet Traveller
|
||||
html.find('.traveller-name-fields').toggleClass('hidden', this._formData.traveller.useRandomName);
|
||||
}
|
||||
|
||||
_getForm() {
|
||||
@@ -137,6 +203,18 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
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');
|
||||
|
||||
// Données pour l'onglet PNJ Détaillé (Traveller)
|
||||
this._formData.traveller.citizenCategory = html.find('[name="traveller.citizenCategory"]').val();
|
||||
this._formData.traveller.experience = html.find('[name="traveller.experience"]').val();
|
||||
this._formData.traveller.role = html.find('[name="traveller.role"]').val();
|
||||
this._formData.traveller.gender = html.find('[name="traveller.gender"]').val();
|
||||
this._formData.traveller.firstName = html.find('[name="traveller.firstName"]').val();
|
||||
this._formData.traveller.surname = html.find('[name="traveller.surname"]').val();
|
||||
this._formData.traveller.useRandomName = html.find('[name="traveller.useRandomName"]').is(':checked');
|
||||
this._formData.traveller.createActor = html.find('[name="traveller.createActor"]').is(':checked');
|
||||
this._formData.traveller.actorName = html.find('[name="traveller.actorName"]').val();
|
||||
this._formData.traveller.openCreatedActor = html.find('[name="traveller.openCreatedActor"]').is(':checked');
|
||||
}
|
||||
|
||||
async _handleNpc() {
|
||||
@@ -162,14 +240,75 @@ export class NpcDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
await this._postToChatResult(result);
|
||||
}
|
||||
|
||||
async _handleTravellerNpc() {
|
||||
const button = $(this.element).find('[data-action="generate-traveller-npc"]');
|
||||
const originalLabel = button.html();
|
||||
|
||||
try {
|
||||
button.prop('disabled', true).html('<i class="fas fa-spinner fa-spin"></i> Génération...');
|
||||
|
||||
const generateOptions = {
|
||||
citizenCategory: this._formData.traveller.citizenCategory,
|
||||
experience: this._formData.traveller.experience,
|
||||
role: this._formData.traveller.role,
|
||||
gender: this._formData.traveller.gender,
|
||||
createActor: this._formData.traveller.createActor,
|
||||
actorName: this._formData.traveller.actorName,
|
||||
openCreatedActor: this._formData.traveller.openCreatedActor
|
||||
};
|
||||
|
||||
if (!this._formData.traveller.useRandomName && this._formData.traveller.firstName && this._formData.traveller.surname) {
|
||||
generateOptions.firstName = this._formData.traveller.firstName;
|
||||
generateOptions.surname = this._formData.traveller.surname;
|
||||
}
|
||||
|
||||
const result = await generateAndCreateTravellerNpc(generateOptions);
|
||||
|
||||
if (result.success) {
|
||||
await this._postToChatResult(result);
|
||||
if (result.createdActor) {
|
||||
ui.notifications.info(`Fiche PNJ Traveller créée : ${result.createdActor.name}`);
|
||||
}
|
||||
} else {
|
||||
ui.notifications.error('Erreur lors de la génération du PNJ Traveller');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`${MODULE_ID} | Erreur lors de la génération du PNJ Traveller:`, error);
|
||||
ui.notifications.error(`Erreur: ${error.message}`);
|
||||
} finally {
|
||||
button.prop('disabled', false).html(originalLabel);
|
||||
}
|
||||
}
|
||||
|
||||
_randomizeTravellerName(html) {
|
||||
const name = generateRandomName(this._formData.traveller.gender);
|
||||
html.find('[name="traveller.firstName"]').val(name.firstName);
|
||||
html.find('[name="traveller.surname"]').val(name.surname);
|
||||
this._formData.traveller.firstName = name.firstName;
|
||||
this._formData.traveller.surname = name.surname;
|
||||
this._formData.traveller.useRandomName = false;
|
||||
html.find('[name="traveller.useRandomName"]').prop('checked', false);
|
||||
html.find('.traveller-name-fields').removeClass('hidden');
|
||||
}
|
||||
|
||||
async _postToChatResult(data) {
|
||||
registerHandlebarsHelpers();
|
||||
const html = await foundry.applications.handlebars.renderTemplate(`modules/${MODULE_ID}/templates/npc-result.hbs`, data);
|
||||
|
||||
// Déterminer quel template utiliser en fonction du type de données
|
||||
let template = `modules/${MODULE_ID}/templates/npc-result.hbs`;
|
||||
let resultType = 'npc-result';
|
||||
|
||||
if (data.type === 'traveller-npc' || data?.flags?.[MODULE_ID]?.type === 'traveller-npc-result') {
|
||||
template = `modules/${MODULE_ID}/templates/traveller-npc-result.hbs`;
|
||||
resultType = 'traveller-npc-result';
|
||||
}
|
||||
|
||||
const html = await foundry.applications.handlebars.renderTemplate(template, data);
|
||||
|
||||
await ChatMessage.create({
|
||||
content: html,
|
||||
speaker: ChatMessage.getSpeaker(),
|
||||
flags: { [MODULE_ID]: { type: 'npc-result' } },
|
||||
flags: { [MODULE_ID]: { type: resultType } },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -180,8 +319,41 @@ function registerHandlebarsHelpers() {
|
||||
if (helpersRegistered) return;
|
||||
helpersRegistered = true;
|
||||
|
||||
// Helpers existants pour NPC
|
||||
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));
|
||||
|
||||
// Helpers pour Traveller NPC
|
||||
Handlebars.registerHelper('gt', (a, b) => a > b);
|
||||
|
||||
// Helper pour afficher le niveau de compétence avec un symbole
|
||||
Handlebars.registerHelper('skillLevelSymbol', (level) => {
|
||||
if (level === 0) return '';
|
||||
if (level === 1) return '★';
|
||||
if (level === 2) return '★★';
|
||||
if (level === 3) return '★★★';
|
||||
return `+${level}`;
|
||||
});
|
||||
|
||||
// Helper pour formater le DM (Difficulté Modificateur)
|
||||
Handlebars.registerHelper('formatDm', (value) => {
|
||||
const dm = Math.floor((value - 6) / 3);
|
||||
return dm >= 0 ? `+${dm}` : `${dm}`;
|
||||
});
|
||||
|
||||
// Helper pour obtenir la classe CSS du niveau de compétence
|
||||
Handlebars.registerHelper('skillLevelClass', (level) => {
|
||||
if (level === 3) return 'skill-level-3';
|
||||
if (level === 2) return 'skill-level-2';
|
||||
if (level === 1) return 'skill-level-1';
|
||||
return 'skill-level-0';
|
||||
});
|
||||
|
||||
// Helper pour lookup dans un objet
|
||||
Handlebars.registerHelper('lookup', (obj, key) => {
|
||||
if (!obj || !key) return '';
|
||||
return obj[key] !== undefined ? obj[key] : '';
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user