Ajout des commandes de creation de rencontre/NJ
This commit is contained in:
147
scripts/npcRollTableSync.js
Normal file
147
scripts/npcRollTableSync.js
Normal 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 n’a pas pu être mis à jour.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user