Ajout des commandes de creation de rencontre/NJ

This commit is contained in:
2026-04-17 16:34:16 +02:00
commit 90911c2e60
232 changed files with 53843 additions and 0 deletions

147
scripts/npcRollTableSync.js Normal file
View File

@@ -0,0 +1,147 @@
import { NPC_ROLLTABLE_DEFINITIONS } from './data/npcTables.js';
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
const PACK_ID = `${MODULE_ID}.tables-pnj`;
const WORLD_FOLDER_NAME = 'MGT2 — Tables PNJ';
const ROLLTABLES_VERSION = 1;
function entryText(entry) {
if (typeof entry.d66 === 'number') return `[${entry.d66}] ${entry.text}`;
if (typeof entry.roll === 'number') return `[${entry.roll}] ${entry.text}`;
return entry.text;
}
function buildTableResults(entries) {
return entries.map((entry, index) => ({
type: CONST.TABLE_RESULT_TYPES.TEXT,
text: entryText(entry),
weight: 1,
range: [index + 1, index + 1],
drawn: false,
}));
}
function buildTableData(definition, extra = {}) {
return {
name: definition.name,
description: 'Table synchronisée automatiquement depuis les règles PNJ du module.',
formula: definition.formula,
replacement: true,
displayRoll: true,
results: buildTableResults(definition.entries),
flags: {
[MODULE_ID]: {
tableKey: definition.key,
syncVersion: ROLLTABLES_VERSION,
},
},
...extra,
};
}
function normalizeResults(results) {
return results.map((result) => ({
type: result.type,
text: result.name ?? result.description ?? result.text ?? '',
weight: result.weight,
range: Array.from(result.range),
}));
}
function needsSync(existing, wanted) {
if (!existing) return true;
if (existing.name !== wanted.name) return true;
if (existing.formula !== wanted.formula) return true;
if (existing.replacement !== wanted.replacement) return true;
const currentVersion = existing.getFlag(MODULE_ID, 'syncVersion');
if (currentVersion !== ROLLTABLES_VERSION) return true;
return JSON.stringify(normalizeResults(existing.results.contents)) !== JSON.stringify(normalizeResults(wanted.results));
}
function getExistingKey(document) {
return document.getFlag(MODULE_ID, 'tableKey') ?? document.name;
}
async function syncCompendiumPack() {
const pack = game.packs.get(PACK_ID);
if (!pack) throw new Error(`Pack introuvable : ${PACK_ID}`);
await pack.getIndex();
const existingDocs = await pack.getDocuments();
const existingByKey = new Map(existingDocs.map((doc) => [getExistingKey(doc), doc]));
const toCreate = [];
const toUpdate = [];
const wasLocked = pack.locked;
try {
if (wasLocked && typeof pack.configure === 'function') await pack.configure({ locked: false });
for (const definition of NPC_ROLLTABLE_DEFINITIONS) {
const wanted = buildTableData(definition);
const existing = existingByKey.get(definition.key);
if (!existing) {
toCreate.push(wanted);
continue;
}
if (needsSync(existing, wanted)) {
toUpdate.push({
_id: existing.id,
...wanted,
});
}
}
if (toCreate.length) await RollTable.createDocuments(toCreate, { pack: pack.collection });
if (toUpdate.length) await RollTable.updateDocuments(toUpdate, { pack: pack.collection });
} finally {
if (wasLocked && typeof pack.configure === 'function') await pack.configure({ locked: true });
}
}
async function getWorldFolder() {
let folder = game.folders.find((entry) => entry.type === 'RollTable' && entry.name === WORLD_FOLDER_NAME);
if (folder) return folder;
return Folder.create({
name: WORLD_FOLDER_NAME,
type: 'RollTable',
color: '#c9a227',
});
}
async function syncWorldFallback() {
const folder = await getWorldFolder();
const existingDocs = game.tables.filter((doc) => doc.folder?.id === folder.id);
const existingByKey = new Map(existingDocs.map((doc) => [getExistingKey(doc), doc]));
const toCreate = [];
const toUpdate = [];
for (const definition of NPC_ROLLTABLE_DEFINITIONS) {
const wanted = buildTableData(definition, { folder: folder.id });
const existing = existingByKey.get(definition.key);
if (!existing) {
toCreate.push(wanted);
continue;
}
if (needsSync(existing, wanted)) {
toUpdate.push({
_id: existing.id,
...wanted,
});
}
}
if (toCreate.length) await RollTable.createDocuments(toCreate);
if (toUpdate.length) await RollTable.updateDocuments(toUpdate);
}
export async function syncNpcRollTables() {
if (!game.user?.isGM) return;
try {
await syncCompendiumPack();
} catch (error) {
console.error(`${MODULE_ID} | Échec de synchronisation du pack RollTable`, error);
await syncWorldFallback();
ui.notifications.warn('Tables PNJ synchronisées dans le monde courant (fallback) — le pack de compendium na pas pu être mis à jour.');
}
}