REady for v14, with included tools
Release Creation / build (release) Successful in 50s

This commit is contained in:
2026-05-24 17:31:12 +02:00
parent 386cf89d68
commit c3cf8f176d
105 changed files with 931 additions and 530 deletions
+123 -10
View File
@@ -3,18 +3,44 @@ import { syncNpcRollTables } from './npcRollTableSync.js';
import './mgt2eMigration.js';
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
const ChatLogV2 = foundry.applications.sidebar.tabs.ChatLog;
function openNpcDialog(initialTab, options = {}) {
new NpcDialog({ initialTab, ...options }).render(true);
new NpcDialog({ initialTab, ...options }).render({ force: true });
}
function registerNpcCommand(commandName, initialTab) {
if (!ChatLogV2?.CHAT_COMMANDS) {
console.warn(`${MODULE_ID} | ChatLog.CHAT_COMMANDS indisponible, commande /${commandName} non enregistrée`);
return;
}
ChatLogV2.CHAT_COMMANDS[commandName] = {
rgx: new RegExp(`^\\/${commandName}(?:\\s+(.*))?$`, 'i'),
fn: () => {
openNpcDialog(initialTab);
return false;
},
};
console.log(`${MODULE_ID} | Commande /${commandName} enregistrée via ChatLog.CHAT_COMMANDS`);
}
Hooks.once('init', () => {
console.log(`${MODULE_ID} | Outils PNJ initialisés`);
loadTemplates([
`modules/${MODULE_ID}/templates/npc-dialog.hbs`,
`modules/${MODULE_ID}/templates/npc-result.hbs`,
]);
// Pré-charge les templates Handlebars
// Compatibilité v13 et v14
const loadTemplatesFn = foundry.applications?.handlebars?.loadTemplates || loadTemplates;
if (loadTemplatesFn) {
loadTemplatesFn([
`modules/${MODULE_ID}/templates/npc-dialog.hbs`,
`modules/${MODULE_ID}/templates/npc-result.hbs`,
]);
}
registerNpcCommand('pnj', 'npc');
registerNpcCommand('rencontre', 'encounter');
registerNpcCommand('mission', 'mission');
});
Hooks.once('ready', async () => {
@@ -22,20 +48,107 @@ Hooks.once('ready', async () => {
console.log(`${MODULE_ID} | Outils PNJ prêts tapez /pnj, /rencontre ou /mission dans le chat`);
});
Hooks.on('chatMessage', (_chatLog, message, _chatData) => {
const trimmed = message.trim().toLowerCase();
/**
* Solution pour Foundry v14 : Intercepte les commandes AVANT la validation
* Utilise renderChatInput pour modifier le comportement de l'input
* Compatible v13 (jQuery) et v14 (DOM element)
*/
Hooks.on('renderChatInput', (app, html, data) => {
// Foundry v14 passe un objet avec element, v13 passe jQuery
let input;
// Vérifie si html est un objet avec element (v14)
if (html?.element) {
input = $(html.element).find('textarea[name="content"]');
} else if (html?.find) {
// v13 ou déjà jQuery
input = html.find('textarea[name="content"]');
} else {
// Dernier recours : suppose que html est l'élément
input = $(html).find('textarea[name="content"]');
}
// Évite les doublons d'écouteurs
if (input.data('mgt2-npc-listener')) return;
input.data('mgt2-npc-listener', true);
input.on('keydown', (event) => {
// Intercepte Entrée (13) et vérifie si c'est une de nos commandes
if (event.key === 'Enter' && !event.shiftKey) {
const content = input.val()?.trim();
if (content?.startsWith('/pnj')) {
event.preventDefault();
event.stopImmediatePropagation();
openNpcDialog('npc');
input.val('');
} else if (content?.startsWith('/rencontre')) {
event.preventDefault();
event.stopImmediatePropagation();
openNpcDialog('encounter');
input.val('');
} else if (content?.startsWith('/mission')) {
event.preventDefault();
event.stopImmediatePropagation();
openNpcDialog('mission');
input.val('');
}
}
});
});
if (trimmed === '/pnj' || trimmed.startsWith('/pnj ')) {
/**
* Intercepte les messages de chat pour /pnj, /rencontre, /mission
* Utilise preCreateChatMessage pour Foundry v14+ (avant que le message ne soit validé)
* Compatible avec Foundry v13 et v14
*/
Hooks.on('preCreateChatMessage', (message, data, options) => {
const content = message.content?.trim()?.toLowerCase();
if (content === '/pnj' || content?.startsWith('/pnj ')) {
openNpcDialog('npc');
return false; // Empêche la création du message
}
if (content === '/rencontre' || content?.startsWith('/rencontre ')) {
openNpcDialog('encounter');
return false; // Empêche la création du message
}
if (content === '/mission' || content?.startsWith('/mission ')) {
openNpcDialog('mission');
return false; // Empêche la création du message
}
});
// Gardé pour compatibilité v13
Hooks.on('chatMessage', (...args) => {
// Foundry v14 passe un objet ChatMessage en premier paramètre
// Foundry v13 passe (chatLog, message, chatData)
let message;
if (args[0]?.content !== undefined) {
// v14: premier argument est ChatMessage
message = args[0].content;
} else if (typeof args[1] === 'string') {
// v13: deuxième argument est la string message
message = args[1];
} else {
return;
}
const trimmed = message?.trim()?.toLowerCase();
if (trimmed === '/pnj' || trimmed?.startsWith('/pnj ')) {
openNpcDialog('npc');
return false;
}
if (trimmed === '/rencontre' || trimmed.startsWith('/rencontre ')) {
if (trimmed === '/rencontre' || trimmed?.startsWith('/rencontre ')) {
openNpcDialog('encounter');
return false;
}
if (trimmed === '/mission' || trimmed.startsWith('/mission ')) {
if (trimmed === '/mission' || trimmed?.startsWith('/mission ')) {
openNpcDialog('mission');
return false;
}