209 lines
5.8 KiB
JavaScript
209 lines
5.8 KiB
JavaScript
/**
|
||
* MGT2 – Commandes /sector et /subsector
|
||
*
|
||
* Ouvre l'application interactive SectorMapApp (IFRAME Traveller Map).
|
||
* Compatible Foundry VTT v13 et v14
|
||
*/
|
||
|
||
import { SectorMapApp } from './SectorMapApp.js';
|
||
import { postWorldCardToChat } from './worldCard.js';
|
||
import { CommerceDialog } from './CommerceDialog.js';
|
||
|
||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||
const ChatLogV2 = foundry.applications?.sidebar?.tabs?.ChatLog;
|
||
|
||
let _pendingHandle = false;
|
||
|
||
/* ───── Fonctions partagées ───── */
|
||
|
||
async function openMap(sector, subsector) {
|
||
const app = new SectorMapApp(sector, subsector);
|
||
await app.render({ force: true });
|
||
}
|
||
|
||
async function handleSectorCommand(sector, subsector) {
|
||
if (_pendingHandle) return;
|
||
_pendingHandle = true;
|
||
try {
|
||
if (!game.user?.isGM) {
|
||
ui.notifications.error('Seul le MJ peut utiliser cette commande');
|
||
return;
|
||
}
|
||
await openMap(sector?.trim());
|
||
} catch (err) {
|
||
console.error(`${MODULE_ID} | Erreur /sector :`, err);
|
||
ui.notifications.error(`Erreur : ${err.message}`);
|
||
} finally {
|
||
_pendingHandle = false;
|
||
}
|
||
}
|
||
|
||
async function handleSystemCommand(sector, hex) {
|
||
if (!sector || !hex) {
|
||
ui.notifications.warn('Usage : /system <secteur> <hex> (ex: /system "Spinward Marches" 1910)');
|
||
return;
|
||
}
|
||
await postWorldCardToChat(sector, hex);
|
||
}
|
||
|
||
async function handleSubsectorCommand(raw) {
|
||
if (_pendingHandle) return;
|
||
_pendingHandle = true;
|
||
try {
|
||
const parts = raw?.trim().split(/\s+/);
|
||
if (!parts || parts.length < 2) {
|
||
ui.notifications.warn('Usage : /subsector <secteur> <sous-secteur> (ex: /subsector "Spinward Marches" C)');
|
||
return;
|
||
}
|
||
const sub = parts.pop();
|
||
const sector = parts.join(' ');
|
||
if (!sector || !sub) {
|
||
ui.notifications.warn('Usage : /subsector <secteur> <sous-secteur>');
|
||
return;
|
||
}
|
||
if (!game.user?.isGM) {
|
||
ui.notifications.error('Seul le MJ peut utiliser cette commande');
|
||
return;
|
||
}
|
||
await openMap(sector.trim(), sub.trim());
|
||
} catch (err) {
|
||
console.error(`${MODULE_ID} | Erreur /subsector :`, err);
|
||
ui.notifications.error(`Erreur : ${err.message}`);
|
||
} finally {
|
||
_pendingHandle = false;
|
||
}
|
||
}
|
||
|
||
/* ───── Commande /sector ───── */
|
||
|
||
if (ChatLogV2?.CHAT_COMMANDS) {
|
||
ChatLogV2.CHAT_COMMANDS['sector'] = {
|
||
rgx: /^\/sector(?:\s+(.*))?$/i,
|
||
fn: function() {
|
||
const raw = arguments[1]?.[1]?.trim?.();
|
||
handleSectorCommand(raw || undefined);
|
||
return false;
|
||
},
|
||
};
|
||
console.log(`${MODULE_ID} | Commande /sector enregistrée`);
|
||
|
||
ChatLogV2.CHAT_COMMANDS['subsector'] = {
|
||
rgx: /^\/subsector(?:\s+(.*))?$/i,
|
||
fn: function() {
|
||
const raw = arguments[1]?.[1]?.trim?.();
|
||
if (raw) {
|
||
handleSubsectorCommand(raw);
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
};
|
||
console.log(`${MODULE_ID} | Commande /subsector enregistrée`);
|
||
|
||
ChatLogV2.CHAT_COMMANDS['system'] = {
|
||
rgx: /^\/system\s+(.+?)\s+(\d{4})\s*$/i,
|
||
fn: function() {
|
||
const sector = arguments[1]?.[1]?.trim?.();
|
||
const hex = arguments[1]?.[2]?.trim?.();
|
||
if (sector && hex) {
|
||
handleSystemCommand(sector, hex);
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
};
|
||
console.log(`${MODULE_ID} | Commande /system enregistrée`);
|
||
}
|
||
|
||
/* ───── Hooks de secours (v13 / fallback v14) ───── */
|
||
|
||
Hooks.on('preCreateChatMessage', (message, data, options) => {
|
||
const c = message.content?.trim();
|
||
|
||
let m = c?.match(/^\/sector(?:\s+(.*))?$/i);
|
||
if (m) {
|
||
handleSectorCommand(m[1]?.trim());
|
||
return false;
|
||
}
|
||
|
||
m = c?.match(/^\/subsector(?:\s+(.*))?$/i);
|
||
if (m) {
|
||
handleSubsectorCommand(m[1]?.trim());
|
||
return false;
|
||
}
|
||
|
||
m = c?.match(/^\/system\s+(.+?)\s+(\d{4})\s*$/i);
|
||
if (m) {
|
||
handleSystemCommand(m[1]?.trim(), m[2]?.trim());
|
||
return false;
|
||
}
|
||
});
|
||
|
||
/* ───── Socket (synchronisation MJ → joueurs) ───── */
|
||
|
||
Hooks.once('ready', () => {
|
||
game.socket.on(`module.${MODULE_ID}`, (data) => {
|
||
if (data?.type !== 'sectorMapSync') return;
|
||
if (game.user?.isGM) return;
|
||
openMap(data.sector, data.subsector);
|
||
});
|
||
|
||
// Clics sur les liens de monde dans les journals de trajet
|
||
document.addEventListener('click', (event) => {
|
||
const link = event.target.closest('.mgt2-world-link');
|
||
if (!link) return;
|
||
event.preventDefault();
|
||
const sector = link.dataset.sector;
|
||
const hex = link.dataset.hex;
|
||
if (sector && hex) {
|
||
handleSystemCommand(sector, hex);
|
||
}
|
||
});
|
||
|
||
// Clics sur le bouton Commerce dans les cartes de monde
|
||
document.addEventListener('click', (event) => {
|
||
const btn = event.target.closest('.mgt2-world-commerce');
|
||
if (!btn) return;
|
||
event.preventDefault();
|
||
const uwp = btn.dataset.uwp;
|
||
const zone = btn.dataset.zone;
|
||
const name = btn.dataset.name;
|
||
const sector = btn.dataset.sector;
|
||
const hex = btn.dataset.hex;
|
||
if (uwp) {
|
||
const existing = Object.values(ui.windows).find(w => w.id === 'mgt2-commerce');
|
||
if (existing) { existing.bringToTop(); return; }
|
||
const dialog = new CommerceDialog({
|
||
defaultWorld: { uwp, zone, name, sector, hex },
|
||
initialTab: 'trade',
|
||
});
|
||
dialog.render({ force: true });
|
||
}
|
||
});
|
||
});
|
||
|
||
Hooks.on('chatMessage', (...args) => {
|
||
let msg;
|
||
if (args[0]?.content !== undefined) msg = args[0].content;
|
||
else if (typeof args[1] === 'string') msg = args[1];
|
||
else return;
|
||
|
||
let m = msg?.trim()?.match(/^\/sector(?:\s+(.*))?$/i);
|
||
if (m) {
|
||
handleSectorCommand(m[1]?.trim());
|
||
return false;
|
||
}
|
||
|
||
m = msg?.trim()?.match(/^\/subsector(?:\s+(.*))?$/i);
|
||
if (m) {
|
||
handleSubsectorCommand(m[1]?.trim());
|
||
return false;
|
||
}
|
||
|
||
m = msg?.trim()?.match(/^\/system\s+(.+?)\s+(\d{4})\s*$/i);
|
||
if (m) {
|
||
handleSystemCommand(m[1]?.trim(), m[2]?.trim());
|
||
return false;
|
||
}
|
||
});
|