diff --git a/css/cde-theme.css b/css/cde-theme.css index c5c03fd..cd0397b 100644 --- a/css/cde-theme.css +++ b/css/cde-theme.css @@ -4400,3 +4400,59 @@ ol.item-list li.item .item-controls a.item-control:hover { color: #7d94b8; text-align: center; } +.cde-welcome-message { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + padding: 12px 16px; + background: #101622; + border: 1px solid #263853; + border-radius: 8px; + text-align: center; +} +.cde-welcome-logo { + width: 120px; + height: auto; + object-fit: contain; + filter: drop-shadow(0 0 8px rgba(74, 158, 255, 0.4)); +} +.cde-welcome-title { + margin: 0; + font-size: 15px; + font-weight: 700; + color: #4a9eff; + text-shadow: 0 0 8px rgba(74, 158, 255, 0.5); +} +.cde-welcome-links { + margin: 0; + font-size: 12px; + color: #7d94b8; +} +.cde-welcome-links a { + color: #00d4d4; + text-decoration: none; + border-bottom: 1px solid rgba(0, 212, 212, 0.4); +} +.cde-welcome-links a:hover { + color: #fff; + border-bottom-color: #fff; +} +.cde-welcome-help-btn { + display: inline-flex; + align-items: center; + gap: 6px; + margin-top: 4px; + padding: 7px 18px; + background: #4a9eff; + border: none; + border-radius: 6px; + color: #fff; + font-size: 12px; + font-weight: 700; + cursor: pointer; + transition: filter 0.15s; +} +.cde-welcome-help-btn:hover { + filter: brightness(1.2); +} diff --git a/css/cde-theme.less b/css/cde-theme.less index fd285cb..8d528d3 100644 --- a/css/cde-theme.less +++ b/css/cde-theme.less @@ -4586,3 +4586,71 @@ ol.item-list { color: @cde-muted; text-align: center; } + +// ============================================================ +// Welcome message +// ============================================================ + +.cde-welcome-message { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + padding: 12px 16px; + background: @cde-surface; + border: 1px solid @cde-border-hi; + border-radius: 8px; + text-align: center; +} + +.cde-welcome-logo { + width: 120px; + height: auto; + object-fit: contain; + filter: drop-shadow(0 0 8px fade(@cde-spell, 40%)); +} + +.cde-welcome-title { + margin: 0; + font-size: 15px; + font-weight: 700; + color: @cde-spell; + text-shadow: 0 0 8px fade(@cde-spell, 50%); +} + +.cde-welcome-links { + margin: 0; + font-size: 12px; + color: @cde-muted; + + a { + color: @cde-item; + text-decoration: none; + border-bottom: 1px solid fade(@cde-item, 40%); + + &:hover { + color: #fff; + border-bottom-color: #fff; + } + } +} + +.cde-welcome-help-btn { + display: inline-flex; + align-items: center; + gap: 6px; + margin-top: 4px; + padding: 7px 18px; + background: @cde-spell; + border: none; + border-radius: 6px; + color: #fff; + font-size: 12px; + font-weight: 700; + cursor: pointer; + transition: filter 0.15s; + + &:hover { + filter: brightness(1.2); + } +} diff --git a/dist/system.js b/dist/system.js index 96dd095..45056f8 100644 --- a/dist/system.js +++ b/dist/system.js @@ -602,9 +602,36 @@ function registerSettings() { type: Number, default: 0 }); + game.settings.register(SYSTEM_ID, "welcomeSceneLoaded", { + scope: "world", + config: false, + type: Boolean, + default: false + }); } async function migrateIfNeeded() { } +async function loadWelcomeSceneIfNeeded() { + if (!game.user.isGM) return; + if (game.settings.get(SYSTEM_ID, "welcomeSceneLoaded")) return; + try { + const pack = game.packs.get(`${SYSTEM_ID}.cde-scenes`); + if (!pack) return; + const index = await pack.getIndex(); + const entry = index.find((e) => e.name === "Accueil"); + if (!entry) return; + const existing = game.scenes.find((s) => s.name === "Accueil"); + let scene = existing; + if (!scene) { + const doc = await pack.getDocument(entry._id); + [scene] = await Scene.createDocuments([doc.toObject()]); + } + await game.settings.set(SYSTEM_ID, "welcomeSceneLoaded", true); + await scene.activate(); + } catch (err) { + console.error("CHRONIQUESDELETRANGE | loadWelcomeSceneIfNeeded failed:", err); + } +} // src/config/localize.js function preLocalizeConfig() { @@ -3018,6 +3045,47 @@ function refreshAllRollActions() { }); } +// src/ui/apps/welcome.js +var HELP_JOURNAL_UUID = `Compendium.${SYSTEM_ID}.cde-help.JournalEntry.CDEGuideMain0001`; +async function showWelcomeMessage() { + const logo = `systems/${SYSTEM_ID}/images/logo_jeu.webp`; + const content = ` +
+ +

Les Chroniques de l'\xC9trange

+ + + +
`; + await ChatMessage.create({ + content, + speaker: { alias: "Les Chroniques de l'\xC9trange" }, + flags: { [SYSTEM_ID]: { welcome: true } } + }); +} +function injectWelcomeActions(_message, html) { + const el = html instanceof HTMLElement ? html : html[0] ?? html; + const btn = el?.querySelector?.("[data-action='open-cde-help']"); + if (!btn) return; + btn.addEventListener("click", async () => { + try { + const doc = await fromUuid(HELP_JOURNAL_UUID); + doc?.sheet?.render(true); + } catch { + game.packs.get(`${SYSTEM_ID}.cde-help`)?.render(true); + } + }); +} + // src/system.js Hooks.once("i18nInit", preLocalizeConfig); Hooks.once("init", async () => { @@ -3103,7 +3171,9 @@ Hooks.once("init", async () => { }); Hooks.once("ready", async () => { await migrateIfNeeded(); + await loadWelcomeSceneIfNeeded(); CDEWheelApp.registerHooks(); + if (game.user.isGM) showWelcomeMessage(); }); Hooks.on("renderChatLog", (_app, html) => { const el = html instanceof HTMLElement ? html : html[0] ?? html; @@ -3133,6 +3203,7 @@ Hooks.on("renderChatLog", (_app, html) => { }); Hooks.on("renderChatMessageHTML", (message, html) => { injectRollActions(message, html); + if (message.flags?.[SYSTEM_ID]?.welcome) injectWelcomeActions(message, html); }); Hooks.on("updateSetting", (setting) => { if (!setting.key) return; diff --git a/dist/system.js.map b/dist/system.js.map index 0830a44..dd1fb13 100644 --- a/dist/system.js.map +++ b/dist/system.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../src/config/constants.js", "../src/migration/migrator.js", "../src/ui/apps/migration-app.js", "../src/config/settings.js", "../src/config/localize.js", "../src/config/runtime.js", "../src/data/actors/character.js", "../src/data/actors/npc.js", "../src/data/items/item.js", "../src/data/items/kungfu.js", "../src/data/items/spell.js", "../src/data/items/supernatural.js", "../src/data/items/weapon.js", "../src/data/items/armor.js", "../src/data/items/sanhei.js", "../src/data/items/ingredient.js", "../src/documents/chat-message.js", "../src/documents/actor.js", "../src/documents/item.js", "../src/ui/dice.js", "../src/ui/helpers.js", "../src/ui/templates.js", "../src/ui/initiative.js", "../src/ui/apps/singletons.js", "../src/ui/rolling.js", "../src/ui/sheets/actors/base.js", "../src/ui/sheets/actors/character.js", "../src/ui/sheets/actors/npc.js", "../src/ui/sheets/items/base.js", "../src/ui/sheets/items/item.js", "../src/ui/sheets/items/kungfu.js", "../src/ui/sheets/items/spell.js", "../src/ui/sheets/items/supernatural.js", "../src/ui/sheets/items/weapon.js", "../src/ui/sheets/items/armor.js", "../src/ui/sheets/items/sanhei.js", "../src/ui/sheets/items/ingredient.js", "../src/ui/apps/loksyu-app.js", "../src/ui/apps/tinji-app.js", "../src/documents/combat.js", "../src/ui/apps/wheel-app.js", "../src/ui/roll-actions.js", "../src/system.js"], - "sourcesContent": ["/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport const SYSTEM_ID = \"fvtt-chroniques-de-l-etrange\"\n\nexport const ACTOR_TYPES = {\n character: \"character\",\n npc: \"npc\",\n}\n\nexport const ITEM_TYPES = {\n item: \"item\",\n kungfu: \"kungfu\",\n spell: \"spell\",\n supernatural: \"supernatural\",\n weapon: \"weapon\",\n armor: \"armor\",\n sanhei: \"sanhei\",\n ingredient: \"ingredient\",\n}\n\nexport const SUBTYPES = {\n weapon: { id: \"weapon\", label: \"CDE.Weapon\" },\n armor: { id: \"armor\", label: \"CDE.Armor\" },\n sanhei: { id: \"sanhei\", label: \"CDE.Sanhei\" },\n other: { id: \"other\", label: \"CDE.Other\" },\n}\n\nexport const MAGICS = {\n internalcinnabar: {\n id: \"internalcinnabar\",\n background: \"linear-grey\",\n label: \"CDE.InternalCinnabar\",\n aspectlabel: \"CDE.Metal\",\n speciality: {\n essence: { label: \"CDE.Essence\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n mind: { label: \"CDE.Mind\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n purification: { label: \"CDE.Purification\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n manipulation: { label: \"CDE.Manipulation\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n aura: { label: \"CDE.Aura\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n alchemy: {\n id: \"alchemy\",\n background: \"linear-blue\",\n label: \"CDE.Alchemy\",\n aspectlabel: \"CDE.Water\",\n speciality: {\n acupuncture: { label: \"CDE.Acupuncture\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n elixirs: { label: \"CDE.Elixirs\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n poisons: { label: \"CDE.Poisons\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n arsenal: { label: \"CDE.Arsenal\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n potions: { label: \"CDE.Potions\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n masteryoftheway: {\n id: \"masteryoftheway\",\n background: \"linear-brown\",\n label: \"CDE.MasteryOfTheWay\",\n aspectlabel: \"CDE.Earth\",\n speciality: {\n curse: { label: \"CDE.Curse\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n transfiguration: { label: \"CDE.Transfiguration\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n necromancy: { label: \"CDE.Necromancy\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n climatecontrol: { label: \"CDE.ClimateControl\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n goldenmagic: { label: \"CDE.GoldenMagic\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n exorcism: {\n id: \"exorcism\",\n background: \"linear-red\",\n label: \"CDE.Exorcism\",\n aspectlabel: \"CDE.Fire\",\n speciality: {\n invocation: { label: \"CDE.Invocation\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n tracking: { label: \"CDE.Tracking\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n protection: { label: \"CDE.Protection\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n punishment: { label: \"CDE.Punishment\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n domination: { label: \"CDE.Domination\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n geomancy: {\n id: \"geomancy\",\n background: \"linear-green\",\n label: \"CDE.Geomancy\",\n aspectlabel: \"CDE.Wood\",\n speciality: {\n neutralization: { label: \"CDE.Neutralization\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n divination: { label: \"CDE.Divination\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n earthlyprayer: { label: \"CDE.EarthlyPrayer\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n heavenlyprayer: { label: \"CDE.HeavenlyPrayer\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n fungseoi: { label: \"CDE.Fungseoi\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n}\n\n/** Map aspect name \u2192 i18n label key */\nexport const ASPECT_LABELS = {\n metal: \"CDE.Metal\",\n water: \"CDE.Water\",\n earth: \"CDE.Earth\",\n fire: \"CDE.Fire\",\n wood: \"CDE.Wood\",\n}\n\n/** Map aspect name \u2192 image path */\nexport const ASPECT_ICONS = {\n metal: \"systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n water: \"systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n earth: \"systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n fire: \"systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n wood: \"systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n}\n\n/** Map aspect name \u2192 die face pair [yin, yang] (face=10 stored as 0) */\nexport const ASPECT_FACES = {\n metal: [3, 8],\n water: [1, 6],\n earth: [0, 5], // 0 = face \"10\"\n fire: [2, 7],\n wood: [4, 9],\n}\n\n/** Ordered aspect names by index (metal=0, water=1, earth=2, fire=3, wood=4) */\nexport const ASPECT_NAMES = [\"metal\", \"water\", \"earth\", \"fire\", \"wood\"]\n\n/**\n * Wu Xing generating/overcoming cycle.\n * For each active aspect, the five result categories in order:\n * [successes, auspicious, noxious, loksyu, tinji]\n */\nexport const WU_XING_CYCLE = {\n wood: [\"wood\", \"fire\", \"water\", \"earth\", \"metal\"],\n fire: [\"fire\", \"earth\", \"wood\", \"metal\", \"water\"],\n earth: [\"earth\", \"metal\", \"fire\", \"water\", \"wood\"],\n metal: [\"metal\", \"water\", \"earth\", \"wood\", \"fire\"],\n water: [\"water\", \"wood\", \"metal\", \"fire\", \"earth\"],\n}\n\nexport const TEMPLATE_PARTIALS = [\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-skills.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-magics.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-nghang.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-treasures.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-items.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-kungfus.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-spells.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-supernaturals.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-spells.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-kungfus.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-items.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-loksyu-app.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-tinji-app.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html\",\n]\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Migrates actor JSON from the legacy CDE system to the current system format.\n *\n * This module is pure logic \u2014 it does not interact with Foundry APIs directly.\n * All transformation is done in-memory; the caller is responsible for creating\n * Foundry documents from the returned data.\n */\n\n// \u2500\u2500 Element label \u2192 key \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ELEMENT_LABEL_TO_KEY = {\n \"m\u00E9tal\": \"metal\",\n \"metal\": \"metal\",\n \"eau\": \"eau\",\n \"terre\": \"terre\",\n \"feu\": \"feu\",\n \"bois\": \"bois\",\n}\n\n/** Normalise a French element label to its system key (e.g. \"M\u00E9tal\" \u2192 \"metal\"). */\nfunction elementKey(label = \"\") {\n return ELEMENT_LABEL_TO_KEY[label.toLowerCase().trim()] ?? \"metal\"\n}\n\n// \u2500\u2500 Hei polarity label \u2192 key \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction heiKey(label = \"\") {\n const l = label.toLowerCase().trim()\n if (l === \"yin/yang\" || l === \"yinyang\") return \"yinyang\"\n if (l === \"yang\") return \"yang\"\n return \"yin\"\n}\n\n// \u2500\u2500 Spell discipline inference from speciality name \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Maps French speciality labels (lowercase, accents stripped) \u2192 school key. */\nconst SPECIALITY_TO_DISCIPLINE = {\n // internalcinnabar\n \"essence\": \"internalcinnabar\",\n \"esprit\": \"internalcinnabar\",\n \"mind\": \"internalcinnabar\",\n \"purification\": \"internalcinnabar\",\n \"manipulation\": \"internalcinnabar\",\n \"aura\": \"internalcinnabar\",\n // alchemy\n \"acupuncture\": \"alchemy\",\n \"\u00E9lixirs\": \"alchemy\",\n \"elixirs\": \"alchemy\",\n \"poisons\": \"alchemy\",\n \"arsenal\": \"alchemy\",\n \"potions\": \"alchemy\",\n // masteryoftheway\n \"mal\u00E9diction\": \"masteryoftheway\",\n \"malediction\": \"masteryoftheway\",\n \"transfiguration\": \"masteryoftheway\",\n \"n\u00E9cromancie\": \"masteryoftheway\",\n \"necromancie\": \"masteryoftheway\",\n \"contr\u00F4le climatique\": \"masteryoftheway\",\n \"controle climatique\": \"masteryoftheway\",\n \"magie d'or\": \"masteryoftheway\",\n \"magie dor\": \"masteryoftheway\",\n // exorcism\n \"invocation\": \"exorcism\",\n \"pistage\": \"exorcism\",\n \"tra\u00E7age\": \"exorcism\",\n \"tracage\": \"exorcism\",\n \"protection\": \"exorcism\",\n \"ch\u00E2timent\": \"exorcism\",\n \"chatiment\": \"exorcism\",\n \"domination\": \"exorcism\",\n // geomancy\n \"neutralisation\": \"geomancy\",\n \"divination\": \"geomancy\",\n \"pri\u00E8re terrestre\": \"geomancy\",\n \"priere terrestre\": \"geomancy\",\n \"pri\u00E8re c\u00E9leste\": \"geomancy\",\n \"priere celeste\": \"geomancy\",\n \"g\u00E9omancie\": \"geomancy\",\n \"geomancie\": \"geomancy\",\n \"feng shui\": \"geomancy\",\n \"fungseoi\": \"geomancy\",\n}\n\n/**\n * Attempt to infer the magic school (discipline) from a spell's speciality name.\n * Falls back to scanning the item name for school keywords if needed.\n */\nfunction inferDiscipline(specialityName = \"\", itemName = \"\") {\n const key = specialityName.toLowerCase().trim()\n if (SPECIALITY_TO_DISCIPLINE[key]) return SPECIALITY_TO_DISCIPLINE[key]\n\n // Fuzzy fallback: check item name for school markers\n const name = itemName.toLowerCase()\n if (name.includes(\"exorcis\")) return \"exorcism\"\n if (name.includes(\"g\u00E9omanci\") || name.includes(\"geomanci\")) return \"geomancy\"\n if (name.includes(\"alchimi\")) return \"alchemy\"\n if (name.includes(\"cinnabre\") || name.includes(\"interne\")) return \"internalcinnabar\"\n if (name.includes(\"ma\u00EEtrise\") || name.includes(\"maitrise\") || name.includes(\"tao\")) return \"masteryoftheway\"\n\n return \"internalcinnabar\"\n}\n\n// \u2500\u2500 KungFu activation mapping \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction mapActivation(oldActivation = \"\") {\n const s = oldActivation.toLowerCase()\n if (s.includes(\"inflig\u00E9s\") || s.includes(\"infliges\")) return \"damage-inflicted\"\n if (s.includes(\"re\u00E7us\") || s.includes(\"recus\")) return \"damage-received\"\n if (s.includes(\"r\u00E9action\") || s.includes(\"reaction\")) return \"reaction\"\n if (s.includes(\"d\u00E9s-fastes\") || s.includes(\"des-fastes\") || s.includes(\"fastes\")) return \"dice\"\n if (s.includes(\"aide\")) return \"action-aid\"\n if (s.includes(\"attaque\") && s.includes(\"d\u00E9fense\")) return \"action-attack-defense\"\n if (s.includes(\"attaque\") && s.includes(\"defense\")) return \"action-attack-defense\"\n if (s.includes(\"attaque\")) return \"action-attack\"\n if (s.includes(\"d\u00E9fense\") || s.includes(\"defense\")) return \"action-defense\"\n return \"action-attack\"\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst DEFAULT_ACTOR_IMG = \"icons/svg/mystery-man.svg\"\nconst DEFAULT_ITEM_IMG = \"icons/svg/item-bag.svg\"\n\n// \u2500\u2500 Item migration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction migrateEquipmentItem(oldItem) {\n const s = oldItem.system ?? {}\n return {\n name: oldItem.name,\n type: \"item\",\n img: oldItem.img || DEFAULT_ITEM_IMG,\n system: {\n reference: s.reference ?? \"\",\n description: s.description ?? \"\",\n quantity: Number(s.quantity ?? 1),\n weight: Number(s.weight ?? 0),\n notes: s.notes ?? \"\",\n },\n }\n}\n\nfunction migrateKungfuItem(oldItem) {\n const s = oldItem.system ?? {}\n const techs = s.techniques ?? {}\n\n const migratedTechs = {}\n for (const key of [\"technique1\", \"technique2\", \"technique3\"]) {\n const t = techs[key] ?? {}\n migratedTechs[key] = {\n check: Boolean(t.check),\n name: t.name ?? \"\",\n activation: mapActivation(t.activation ?? \"\"),\n technique: t.technique ?? \"\",\n }\n }\n\n return {\n name: oldItem.name,\n type: \"kungfu\",\n img: oldItem.img || DEFAULT_ITEM_IMG,\n system: {\n reference: s.reference ?? \"\",\n description: s.description ?? \"\",\n orientation: s.orientation || \"yin\",\n aspect: s.aspect || \"metal\",\n skill: s.skill || \"kungfu\",\n speciality: s.speciality ?? \"\",\n style: s.style ?? \"\",\n techniques: migratedTechs,\n notes: s.notes ?? \"\",\n },\n }\n}\n\nfunction migrateSpellItem(oldItem) {\n const s = oldItem.system ?? {}\n return {\n name: oldItem.name,\n type: \"spell\",\n img: oldItem.img || DEFAULT_ITEM_IMG,\n system: {\n reference: s.reference ?? \"\",\n description: s.description ?? \"\",\n specialityname: s.specialityname ?? \"\",\n associatedelement: elementKey(s.associatedelement ?? \"\"),\n heiType: heiKey(s.hei ?? \"\"),\n heiCost: Number(s.heiCost ?? 0),\n difficulty: Number(s.difficulty ?? 0),\n realizationtimeritual: s.realizationtimeritual ?? \"\",\n realizationtimeaccelerated: s.realizationtimeaccelerated ?? \"\",\n flashback: s.flashback ?? \"\",\n components: s.components ?? \"\",\n effects: s.effects ?? \"\",\n examples: s.examples ?? \"\",\n notes: s.notes ?? \"\",\n discipline: inferDiscipline(s.specialityname ?? \"\", oldItem.name ?? \"\"),\n },\n }\n}\n\nfunction migrateSupernaturalItem(oldItem) {\n const s = oldItem.system ?? {}\n // Old system stored a nested `supernatural: { reference }` \u2014 prefer that reference if top-level is empty\n const nestedRef = s.supernatural?.reference ?? \"\"\n return {\n name: oldItem.name,\n type: \"supernatural\",\n img: oldItem.img || DEFAULT_ITEM_IMG,\n system: {\n reference: s.reference || nestedRef,\n description: s.description ?? \"\",\n notes: s.notes ?? \"\",\n heiType: \"yin\",\n heiCost: 0,\n trigger: \"\",\n effects: \"\",\n },\n }\n}\n\nfunction migrateItem(oldItem) {\n switch (oldItem.type) {\n case \"item\": return migrateEquipmentItem(oldItem)\n case \"kungfu\": return migrateKungfuItem(oldItem)\n case \"spell\": return migrateSpellItem(oldItem)\n case \"supernatural\": return migrateSupernaturalItem(oldItem)\n default:\n // Unknown item type: keep as generic equipment\n return migrateEquipmentItem({ ...oldItem, type: \"item\" })\n }\n}\n\n// \u2500\u2500 Actor migration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction migrateCharacter(old) {\n const s = old.system ?? {}\n\n // aspects: keep only { chinese, label, value }\n const aspect = {}\n for (const [k, v] of Object.entries(s.aspect ?? {})) {\n aspect[k] = { chinese: v.chinese ?? \"\", label: v.label ?? \"\", value: Number(v.value ?? 0) }\n }\n\n // skills: keep { label, specialities, value }\n const skills = {}\n for (const [k, v] of Object.entries(s.skills ?? {})) {\n skills[k] = { label: v.label ?? \"\", specialities: v.specialities ?? \"\", value: Number(v.value ?? 0) }\n }\n\n // resources: keep { label, specialities, value, debt }\n const resources = {}\n for (const [k, v] of Object.entries(s.resources ?? {})) {\n resources[k] = { label: v.label ?? \"\", specialities: v.specialities ?? \"\", value: Number(v.value ?? 0), debt: Boolean(v.debt) }\n }\n\n // components: keep { value }\n const component = {}\n for (const [k, v] of Object.entries(s.component ?? {})) {\n component[k] = { value: v.value ?? \"\" }\n }\n\n // magics: keep { visible, value, speciality: { [key]: { check } } }\n const MAGIC_SPECIALITIES = {\n internalcinnabar: [\"essence\", \"mind\", \"purification\", \"manipulation\", \"aura\"],\n alchemy: [\"acupuncture\", \"elixirs\", \"poisons\", \"arsenal\", \"potions\"],\n masteryoftheway: [\"curse\", \"transfiguration\", \"necromancy\", \"climatecontrol\", \"goldenmagic\"],\n exorcism: [\"invocation\", \"tracking\", \"protection\", \"punishment\", \"domination\"],\n geomancy: [\"neutralization\", \"divination\", \"earthlyprayer\", \"heavenlyprayer\", \"fungseoi\"],\n }\n const magics = {}\n for (const [school, specs] of Object.entries(MAGIC_SPECIALITIES)) {\n const om = s.magics?.[school] ?? {}\n const speciality = {}\n for (const spec of specs) {\n speciality[spec] = { check: Boolean(om.speciality?.[spec]?.check) }\n }\n magics[school] = { visible: Boolean(om.visible), value: Number(om.value ?? 0), speciality }\n }\n\n // threetreasures: strip `min` from heiyang/heiyin; keep dicelevel as-is\n const tt = s.threetreasures ?? {}\n const threetreasures = {\n heiyang: { value: Number(tt.heiyang?.value ?? 0), max: Number(tt.heiyang?.max ?? 0) },\n heiyin: { value: Number(tt.heiyin?.value ?? 0), max: Number(tt.heiyin?.max ?? 0) },\n dicelevel: {\n level0d: {\n san: { value: Number(tt.dicelevel?.level0d?.san?.value ?? 0), max: Number(tt.dicelevel?.level0d?.san?.max ?? 0) },\n zing: { value: Number(tt.dicelevel?.level0d?.zing?.value ?? 0), max: Number(tt.dicelevel?.level0d?.zing?.max ?? 0) },\n },\n level1d: {\n san: { value: Number(tt.dicelevel?.level1d?.san?.value ?? 0), max: Number(tt.dicelevel?.level1d?.san?.max ?? 0) },\n zing: { value: Number(tt.dicelevel?.level1d?.zing?.value ?? 0), max: Number(tt.dicelevel?.level1d?.zing?.max ?? 0) },\n },\n level2d: {\n san: { value: Number(tt.dicelevel?.level2d?.san?.value ?? 0), max: Number(tt.dicelevel?.level2d?.san?.max ?? 0) },\n zing: { value: Number(tt.dicelevel?.level2d?.zing?.value ?? 0), max: Number(tt.dicelevel?.level2d?.zing?.max ?? 0) },\n },\n },\n }\n\n // biography (old separate field) merged into description\n const description = s.description || s.biography || \"\"\n\n return {\n name: old.name,\n type: \"character\",\n img: old.img || DEFAULT_ACTOR_IMG,\n system: {\n concept: s.concept ?? \"\",\n guardian: parseInt(s.guardian ?? \"0\") || 0,\n initiative: Number(s.initiative ?? 1),\n anti_initiative: Number(s.anti_initiative ?? 24),\n description,\n aspect,\n skills,\n resources,\n component,\n magics,\n threetreasures,\n experience: {\n value: Number(s.experience?.value ?? 0),\n max: Number(s.experience?.max ?? 0),\n min: Number(s.experience?.min ?? 0),\n },\n },\n items: (old.items ?? []).map(migrateItem),\n }\n}\n\nfunction migrateNpc(old) {\n const s = old.system ?? {}\n\n const aptitudes = {}\n for (const [k, v] of Object.entries(s.aptitudes ?? {})) {\n aptitudes[k] = { value: Number(v.value ?? 0), speciality: v.speciality ?? \"\" }\n }\n\n return {\n name: old.name,\n type: \"npc\",\n img: old.img || DEFAULT_ACTOR_IMG,\n system: {\n type: s.type ?? \"\",\n // Old system had separate `levelofthreat`/`powerofnuisance` as numbers\n // and string copies `threat`/`nuisance` \u2014 use the numeric fields\n threat: Number(s.levelofthreat ?? s.threat ?? 0),\n nuisance: Number(s.powerofnuisance ?? s.nuisance ?? 0),\n initiative: Number(s.initiative ?? 1),\n anti_initiative: Number(s.anti_initiative ?? 24),\n aptitudes,\n vitality: {\n value: Number(s.vitality?.value ?? 0),\n calcul: Number(s.vitality?.calcul ?? 0),\n note: s.vitality?.note ?? \"\",\n },\n hei: {\n value: Number(s.hei?.value ?? 0),\n calcul: Number(s.hei?.calcul ?? 0),\n note: s.hei?.note ?? \"\",\n },\n description: s.description ?? \"\",\n },\n items: (old.items ?? []).map(migrateItem),\n }\n}\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Migrate a single legacy actor JSON to the current system format.\n *\n * @param {object} oldJson Parsed JSON from the old system export\n * @returns {{ name: string, type: string, img: string, system: object, items: object[] }}\n * @throws {Error} if the actor type is unrecognised\n */\nexport function migrateActor(oldJson) {\n switch (oldJson.type) {\n case \"character\": return migrateCharacter(oldJson)\n case \"npc\": return migrateNpc(oldJson)\n default:\n throw new Error(`Unknown actor type \"${oldJson.type}\" in \"${oldJson.name}\"`)\n }\n}\n\n/**\n * Parse one or more legacy JSON strings and return migrated actor data.\n * Accepts a single actor object or an array of actor objects in one file.\n *\n * @param {string} jsonText Raw JSON text from a file\n * @returns {Array<{ name, type, img, system, items }>}\n */\nexport function parseLegacyJson(jsonText) {\n const parsed = JSON.parse(jsonText)\n if (typeof parsed !== \"object\" || parsed === null) {\n throw new Error(\"Le fichier JSON doit contenir un objet acteur ou un tableau d'acteurs\")\n }\n const actors = Array.isArray(parsed) ? parsed : [parsed]\n return actors.map(migrateActor)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { parseLegacyJson } from \"../../migration/migrator.js\"\n\nconst MIGRATION_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-migration-app.html\"\n\n/**\n * Dialog for importing legacy CDE actor JSON files into the current system.\n *\n * Accessible via the System Settings menu (registerMenu).\n * Supports multi-file selection and shows a preview table before importing.\n */\nexport class CDEMigrationApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-migration-app\",\n classes: [\"cde-migration-app\"],\n tag: \"div\",\n window: {\n title: \"CDE.MigrationTitle\",\n icon: \"fas fa-file-import\",\n resizable: false,\n },\n position: { width: 560, height: \"auto\" },\n actions: {\n clearFiles: CDEMigrationApp.#clearFiles,\n doImport: CDEMigrationApp.#doImport,\n },\n }\n\n static PARTS = {\n form: { template: MIGRATION_TEMPLATE },\n }\n\n /** @type {Array<{name: string, type: string, img: string, system: object, items: object[], _srcFile: string}>} */\n #pending = []\n\n /** @type {string[]} - error messages per file */\n #errors = []\n\n async _prepareContext(options) {\n return {\n pending: this.#pending,\n errors: this.#errors,\n hasPending: this.#pending.length > 0,\n hasErrors: this.#errors.length > 0,\n count: this.#pending.length,\n }\n }\n\n /** After render, wire up the file input. */\n _onRender(context, options) {\n super._onRender(context, options)\n const input = this.element.querySelector(\".cde-migration-file-input\")\n input?.addEventListener(\"change\", this.#onFileChange.bind(this))\n\n const dropZone = this.element.querySelector(\".cde-migration-drop-zone\")\n if (dropZone) {\n dropZone.addEventListener(\"dragover\", (e) => { e.preventDefault(); dropZone.classList.add(\"is-dragover\") })\n dropZone.addEventListener(\"dragleave\", () => dropZone.classList.remove(\"is-dragover\"))\n dropZone.addEventListener(\"drop\", (e) => {\n e.preventDefault()\n dropZone.classList.remove(\"is-dragover\")\n this.#processFiles(Array.from(e.dataTransfer.files))\n })\n }\n }\n\n async #onFileChange(event) {\n const files = Array.from(event.target.files ?? [])\n event.target.value = \"\"\n await this.#processFiles(files)\n }\n\n async #processFiles(files) {\n for (const file of files) {\n if (!file.name.endsWith(\".json\")) {\n this.#errors.push(game.i18n.format(\"CDE.MigrationErrorNotJson\", { file: file.name }))\n continue\n }\n try {\n const text = await file.text()\n const actors = parseLegacyJson(text)\n for (const actor of actors) {\n actor._srcFile = file.name\n // Avoid duplicates by name\n if (!this.#pending.some(p => p.name === actor.name)) {\n this.#pending.push(actor)\n }\n }\n } catch (err) {\n this.#errors.push(game.i18n.format(\"CDE.MigrationErrorParse\", { file: file.name, error: err.message }))\n }\n }\n this.render()\n }\n\n static async #clearFiles() {\n this.#pending = []\n this.#errors = []\n this.render()\n }\n\n static async #doImport() {\n if (!this.#pending.length) return\n\n const created = []\n const failed = []\n\n for (const data of this.#pending) {\n try {\n const { _srcFile, ...actorData } = data\n const actor = await Actor.create(actorData)\n created.push(actor.name)\n } catch (err) {\n failed.push(`${data.name}: ${err.message}`)\n console.error(`CHRONIQUESDELETRANGE | Migration failed for \"${data.name}\":`, err)\n }\n }\n\n this.#pending = []\n this.#errors = failed\n this.render()\n\n if (created.length) {\n ui.notifications.info(\n game.i18n.format(\"CDE.MigrationSuccess\", { count: created.length, names: created.join(\", \") })\n )\n }\n if (failed.length) {\n ui.notifications.warn(\n game.i18n.format(\"CDE.MigrationPartialError\", { count: failed.length })\n )\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { SYSTEM_ID } from \"./constants.js\"\nimport { CDEMigrationApp } from \"../ui/apps/migration-app.js\"\n\n/**\n * Register all world/client settings for the system.\n * Called during the \"init\" hook before sheets and data-models are set up.\n */\nexport function registerSettings() {\n game.settings.registerMenu(SYSTEM_ID, \"migrationTool\", {\n name: \"CDE.MigrationTitle\",\n label: \"CDE.MigrationMenuLabel\",\n hint: \"CDE.MigrationMenuHint\",\n icon: \"fas fa-file-import\",\n type: CDEMigrationApp,\n restricted: true,\n })\n\n game.settings.register(SYSTEM_ID, \"loksyuData\", {\n scope: \"world\",\n config: false,\n type: Object,\n default: {\n wood: { yin: 0, yang: 0 },\n fire: { yin: 0, yang: 0 },\n earth: { yin: 0, yang: 0 },\n metal: { yin: 0, yang: 0 },\n water: { yin: 0, yang: 0 },\n },\n })\n\n game.settings.register(SYSTEM_ID, \"tinjiData\", {\n scope: \"world\",\n config: false,\n type: Number,\n default: 0,\n })\n}\n\n/**\n * Run any pending data migrations on the \"ready\" hook.\n * Reserved for future schema migrations.\n */\nexport async function migrateIfNeeded() {\n // No migrations required yet.\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS, SUBTYPES } from \"./constants.js\"\n\nexport function preLocalizeConfig() {\n const localizeConfigObject = (obj, keys) => {\n for (const o of Object.values(obj)) {\n for (const key of keys) {\n o[key] = game.i18n.localize(o[key])\n }\n }\n }\n\n localizeConfigObject(SUBTYPES, [\"label\"])\n Object.values(MAGICS).forEach((magic) => {\n magic.label = game.i18n.localize(magic.label)\n magic.aspectlabel = game.i18n.localize(magic.aspectlabel)\n Object.values(magic.speciality).forEach((spec) => {\n spec.label = game.i18n.localize(spec.label)\n spec.labelelement = game.i18n.localize(spec.labelelement)\n })\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport function configureRuntime() {\n CONFIG.Actor.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/actor-banner.webp\"\n CONFIG.Adventure.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/adventure-banner.webp\"\n CONFIG.Cards.compendiumBanner = \"ui/banners/cards-banner.webp\"\n CONFIG.Item.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/item-banner.webp\"\n CONFIG.JournalEntry.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/journalentry-banner.webp\"\n CONFIG.Macro.compendiumBanner = \"ui/banners/macro-banner.webp\"\n CONFIG.Playlist.compendiumBanner = \"ui/banners/playlist-banner.webp\"\n CONFIG.RollTable.compendiumBanner = \"ui/banners/rolltable-banner.webp\"\n CONFIG.Scene.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/scene-banner.webp\"\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class CharacterDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n const aspectField = (label, chinese) =>\n new fields.SchemaField({\n chinese: stringField(chinese),\n label: stringField(label),\n value: numberField(15, { min: 0 }),\n })\n\n const skillField = (label) =>\n new fields.SchemaField({\n label: stringField(label),\n specialities: stringField(\"\"),\n value: numberField(0, { min: 0 }),\n })\n\n const resourceField = (label) =>\n new fields.SchemaField({\n label: stringField(label),\n specialities: stringField(\"\"),\n value: numberField(0, { min: 0 }),\n debt: boolField(false),\n })\n\n const componentField = () =>\n new fields.SchemaField({\n value: stringField(\"\"),\n })\n\n const magicSpecialityField = () =>\n new fields.SchemaField({\n check: boolField(false),\n })\n\n const magicField = () =>\n new fields.SchemaField({\n visible: boolField(true),\n value: numberField(0, { min: 0 }),\n speciality: new fields.SchemaField({\n essence: magicSpecialityField(),\n mind: magicSpecialityField(),\n purification: magicSpecialityField(),\n manipulation: magicSpecialityField(),\n aura: magicSpecialityField(),\n acupuncture: magicSpecialityField(),\n elixirs: magicSpecialityField(),\n poisons: magicSpecialityField(),\n arsenal: magicSpecialityField(),\n potions: magicSpecialityField(),\n curse: magicSpecialityField(),\n transfiguration: magicSpecialityField(),\n necromancy: magicSpecialityField(),\n climatecontrol: magicSpecialityField(),\n goldenmagic: magicSpecialityField(),\n invocation: magicSpecialityField(),\n tracking: magicSpecialityField(),\n protection: magicSpecialityField(),\n punishment: magicSpecialityField(),\n domination: magicSpecialityField(),\n neutralization: magicSpecialityField(),\n divination: magicSpecialityField(),\n earthlyprayer: magicSpecialityField(),\n heavenlyprayer: magicSpecialityField(),\n fungseoi: magicSpecialityField(),\n }),\n })\n\n const treasureBranch = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n max: numberField(0, { min: 0 }),\n min: numberField(0, { min: 0 }),\n })\n\n const treasureLevel = () =>\n new fields.SchemaField({\n san: treasureBranch(),\n zing: treasureBranch(),\n })\n\n const schema = {\n concept: stringField(\"\"),\n guardian: numberField(0, { min: 0, max: 5 }),\n initiative: numberField(1, { min: 0 }),\n anti_initiative: numberField(24, { min: 0 }),\n description: htmlField(\"\"),\n prefs: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(true),\n choice: stringField(\"0\"),\n }),\n }),\n prompt: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(true),\n choice: stringField(\"0\"),\n }),\n configure: new fields.SchemaField({\n numberofdice: numberField(0),\n aspect: numberField(0),\n bonus: numberField(0),\n bonusauspiciousdice: numberField(0),\n typeofthrow: numberField(0),\n aspectskill: numberField(0),\n bonusmalusskill: numberField(0),\n aspectspeciality: numberField(0),\n rolldifficulty: numberField(0),\n bonusmalusspeciality: numberField(0),\n }),\n }),\n aspect: new fields.SchemaField({\n fire: aspectField(\"CDE.Fire\", \"\u328B\"),\n earth: aspectField(\"CDE.Earth\", \"\u328F\"),\n metal: aspectField(\"CDE.Metal\", \"\u328E\"),\n water: aspectField(\"CDE.Water\", \"\u328C\"),\n wood: aspectField(\"CDE.Wood\", \"\u328D\"),\n }),\n skills: new fields.SchemaField({\n art: skillField(\"CDE.Art\"),\n investigation: skillField(\"CDE.Investigation\"),\n erudition: skillField(\"CDE.Erudition\"),\n knavery: skillField(\"CDE.Knavery\"),\n wordliness: skillField(\"CDE.Wordliness\"),\n prowess: skillField(\"CDE.Prowess\"),\n sciences: skillField(\"CDE.Sciences\"),\n technologies: skillField(\"CDE.Technologies\"),\n kungfu: skillField(\"CDE.KungFu\"),\n rangedcombat: skillField(\"CDE.RangedCombat\"),\n }),\n resources: new fields.SchemaField({\n supply: resourceField(\"CDE.Supply\"),\n inquiry: resourceField(\"CDE.Inquiry\"),\n influence: resourceField(\"CDE.Influence\"),\n }),\n component: new fields.SchemaField({\n one: componentField(),\n two: componentField(),\n three: componentField(),\n four: componentField(),\n five: componentField(),\n six: componentField(),\n seven: componentField(),\n eight: componentField(),\n nine: componentField(),\n zero: componentField(),\n }),\n magics: new fields.SchemaField({\n internalcinnabar: magicField(),\n alchemy: magicField(),\n masteryoftheway: magicField(),\n exorcism: magicField(),\n geomancy: magicField(),\n }),\n threetreasures: new fields.SchemaField({\n heiyang: new fields.SchemaField({ value: numberField(0, { min: 0 }), max: numberField(0, { min: 0 }) }),\n heiyin: new fields.SchemaField({ value: numberField(0, { min: 0 }), max: numberField(0, { min: 0 }) }),\n dicelevel: new fields.SchemaField({\n level0d: treasureLevel(),\n level1d: treasureLevel(),\n level2d: treasureLevel(),\n }),\n }),\n experience: new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n max: numberField(0, { min: 0 }),\n min: numberField(0, { min: 0 }),\n }),\n }\n\n return schema\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class NpcDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n const aptitudeField = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n speciality: stringField(\"\"),\n })\n\n const trackedField = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n calcul: numberField(0, { min: 0 }),\n note: stringField(\"\"),\n })\n\n return {\n type: stringField(\"\"),\n threat: numberField(0, { min: 0, max: 4 }), // profane(0) | apprentice(1) | initiate(2) | accomplished(3) | renowned(4)\n nuisance: numberField(0, { min: 0, max: 5 }), // figurant(0) | minion(1) | adversary(2) | ally(3) | boss(4) | divinity(5)\n initiative: numberField(1, { min: 0 }),\n anti_initiative: numberField(24, { min: 0 }),\n aptitudes: new fields.SchemaField({\n physical: aptitudeField(),\n martial: aptitudeField(),\n mental: aptitudeField(),\n social: aptitudeField(),\n spiritual: aptitudeField(),\n }),\n vitality: trackedField(),\n hei: trackedField(),\n description: htmlField(\"\"),\n prefs: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(false),\n choice: stringField(\"0\"),\n }),\n }),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class EquipmentDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n quantity: numberField(1, { min: 0 }),\n weight: numberField(0, { min: 0 }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class KungfuDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n\n const techniqueField = () =>\n new fields.SchemaField({\n check: boolField(false),\n name: stringField(\"\"),\n activation: stringField(\"action-attack\"), // action-attack | action-defense | action-aid | action-attack-defense | reaction | dice | damage-inflicted | damage-received\n technique: htmlField(\"\"),\n })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n orientation: stringField(\"yin\"), // yin | yang | yinyang\n aspect: stringField(\"metal\"), // metal | eau | terre | feu | bois\n skill: stringField(\"kungfu\"), // kungfu | rangedcombat\n speciality: stringField(\"\"),\n style: stringField(\"\"),\n techniques: new fields.SchemaField({\n technique1: techniqueField(),\n technique2: techniqueField(),\n technique3: techniqueField(),\n }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SpellDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n specialityname: stringField(\"\"),\n associatedelement: stringField(\"metal\"), // metal | eau | terre | feu | bois\n hei: stringField(\"\"),\n realizationtimeritual: stringField(\"\"),\n realizationtimeaccelerated: stringField(\"\"),\n flashback: stringField(\"\"),\n components: htmlField(\"\"),\n effects: htmlField(\"\"),\n examples: htmlField(\"\"),\n notes: htmlField(\"\"),\n discipline: stringField(\"internalcinnabar\"),\n heiType: stringField(\"yin\"),\n heiCost: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 1 }),\n difficulty: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 1 }),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SupernaturalDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n notes: htmlField(\"\"),\n heiType: stringField(\"yin\"),\n heiCost: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 0 }),\n trigger: stringField(\"\"),\n effects: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class WeaponDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n weaponType: stringField(\"melee\"),\n material: stringField(\"\"),\n damageAspect: stringField(\"metal\"),\n damageBase: intField(1),\n range: stringField(\"contact\"), // contact | courte | mediane | longue | extreme\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class ArmorDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n protectionValue: intField(0),\n domain: stringField(\"\"),\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SanheiDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n const propertySchema = () => new fields.SchemaField({\n name: stringField(\"\"),\n heiCost: intField(0),\n heiType: stringField(\"yin\"),\n description: htmlField(\"\"),\n })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n heiType: stringField(\"yin\"),\n properties: new fields.SchemaField({\n prop1: propertySchema(),\n prop2: propertySchema(),\n prop3: propertySchema(),\n }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class IngredientDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n school: stringField(\"all\"),\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport class CDEMessage extends ChatMessage {\n async renderHTML({ canDelete, canClose = false, ...rest } = {}) {\n const html = await super.renderHTML({ canDelete, canClose, ...rest })\n this.#enrichChatCard(html)\n return html\n }\n\n getAssociatedActor() {\n if (this.speaker.scene && this.speaker.token) {\n const scene = game.scenes.get(this.speaker.scene)\n const token = scene?.tokens.get(this.speaker.token)\n if (token) return token.actor\n }\n return game.actors.get(this.speaker.actor)\n }\n\n #enrichChatCard(html) {\n const actor = this.getAssociatedActor()\n\n let img\n let nameText\n if (this.isContentVisible) {\n img = actor?.img ?? this.author.avatar\n nameText = this.alias\n } else {\n img = this.author.avatar\n nameText = this.author.name\n }\n\n const avatar = document.createElement(\"a\")\n avatar.classList.add(\"avatar\")\n if (actor) avatar.dataset.uuid = actor.uuid\n const avatarImg = document.createElement(\"img\")\n Object.assign(avatarImg, { src: img, alt: nameText })\n avatar.append(avatarImg)\n\n const name = document.createElement(\"span\")\n name.classList.add(\"name-stacked\")\n const title = document.createElement(\"span\")\n title.classList.add(\"title\")\n title.append(nameText)\n name.append(title)\n\n const sender = html.querySelector(\".message-sender\")\n sender?.replaceChildren(avatar, name)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { ACTOR_TYPES } from \"../config/constants.js\"\n\nexport class CDEActor extends Actor {\n getRollData() {\n const data = this.toObject(false).system\n return data\n }\n\n prepareBaseData() {\n super.prepareBaseData()\n\n if (this.type === ACTOR_TYPES.character) {\n this.system.anti_initiative = 25 - (this.system.initiative ?? 0)\n }\n\n if (this.type === ACTOR_TYPES.npc) {\n this.system.vitality.calcul = (this.system.aptitudes.physical.value ?? 0) * 4\n this.system.hei.calcul = (this.system.aptitudes.spiritual.value ?? 0) * 4\n this.system.anti_initiative = 25 - (this.system.initiative ?? 0)\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/** Default icons per item type. */\nconst DEFAULT_ICONS = {\n kungfu: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-kungfu.svg\",\n spell: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-spell.svg\",\n supernatural: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-supernatural.svg\",\n weapon: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-weapon.svg\",\n armor: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-armor.svg\",\n sanhei: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-sanhei.svg\",\n ingredient: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-ingredient.svg\",\n item: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-item.svg\",\n};\n\nexport class CDEItem extends Item {\n\n /** @override */\n async _preCreate(data, options, userId) {\n await super._preCreate(data, options, userId);\n const defaultIcon = DEFAULT_ICONS[this.type];\n if (defaultIcon && (!data.img || data.img === Item.DEFAULT_ICON)) {\n this.updateSource({ img: defaultIcon });\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst DIGIT_LABELS = [\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-1.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-2.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-3.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-4.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-5.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-6.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-7.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-8.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-9.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-10.webp\",\n]\n\nconst CLASSIC_LABELS = [\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-1.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-2.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-3.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-4.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-5.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-6.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-7.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-8.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-9.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-10.webp\",\n]\n\nexport function registerDice() {\n Hooks.once(\"diceSoNiceReady\", (dice3d) => {\n dice3d.addColorset(\n {\n name: \"cde\",\n description: \"CdE\",\n foreground: \"#000000\",\n background: \"#ffffff\",\n edge: \"#ffffff\",\n font: \"DeliusUnicase\",\n texture: \"ice\",\n material: \"plastic\",\n },\n \"preferred\",\n )\n\n dice3d.addSystem({ id: \"fvtt-chroniques-de-l-etrangedigit\", name: \"Chroniques de l'\u00E9trange digits\" }, \"preferred\")\n dice3d.addDicePreset({ type: \"d10\", labels: DIGIT_LABELS, system: \"fvtt-chroniques-de-l-etrangedigit\" })\n\n dice3d.addSystem({ id: \"fvtt-chroniques-de-l-etrange\", name: \"Chroniques de l'\u00E9trange\" }, \"preferred\")\n dice3d.addDicePreset({ type: \"d10\", labels: CLASSIC_LABELS, system: \"fvtt-chroniques-de-l-etrange\" })\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS } from \"../config/constants.js\"\n\nexport function registerHandlebarsHelpers() {\n const { Handlebars } = globalThis\n if (!Handlebars) return\n\n Handlebars.registerHelper(\"select\", function (selected, options) {\n const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected))\n const rgx = new RegExp(` value=[\"']${escapedValue}[\"']`)\n const html = options.fn(this)\n return html.replace(rgx, \"$& selected\")\n })\n\n Handlebars.registerHelper(\"getMagicBackground\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.background ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicLabel\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.label ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicAspectLabel\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.aspectlabel ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabel\", function (magic, speciality) {\n return game.i18n.localize(MAGICS[magic]?.speciality?.[speciality]?.label ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityClassIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.classicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.icon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityElementIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.elementicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabelIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.labelicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabelElement\", function (magic, speciality) {\n return game.i18n.localize(MAGICS[magic]?.speciality?.[speciality]?.labelelement ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicAspectIcon\", function (magic) {\n const icons = {\n internalcinnabar: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n alchemy: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n masteryoftheway: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n exorcism: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n geomancy: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n }\n return icons[magic] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getElementIcon\", function (aspect) {\n const icons = {\n metal: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n water: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n earth: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n fire: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n wood: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n // legacy French keys\n eau: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n terre: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n feu: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n bois: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n }\n return icons[aspect] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getOrientationIcon\", function (orientation) {\n const icons = {\n yin: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\",\n yang: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\",\n yinyang: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\",\n }\n return icons[orientation] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getOrientationLabel\", function (orientation) {\n const keys = {\n yin: \"CDE.OrientationYin\",\n yang: \"CDE.OrientationYang\",\n yinyang: \"CDE.OrientationYinYang\",\n }\n return game.i18n.localize(keys[orientation] ?? \"CDE.Orientation\")\n })\n\n Handlebars.registerHelper(\"getActivationLabel\", function (activation) {\n const keys = {\n \"action-attack\": \"CDE.ActivationAttack\",\n \"action-defense\": \"CDE.ActivationDefense\",\n \"action-aid\": \"CDE.ActivationAid\",\n \"action-attack-defense\": \"CDE.ActivationAttackOrDefense\",\n reaction: \"CDE.ActivationReaction\",\n dice: \"CDE.ActivationDice\",\n \"damage-inflicted\": \"CDE.ActivationDamageInflicted\",\n \"damage-received\": \"CDE.ActivationDamageReceived\",\n }\n return game.i18n.localize(keys[activation] ?? \"CDE.Activation\")\n })\n\n /**\n * Compute the SVG x,y coordinates for a cran on the initiative wheel.\n * Cran 1\u201324 are arranged counter-clockwise from the bottom (reference at 6 o'clock).\n * angle = 90\u00B0 + cran * 15\u00B0 (counter-clockwise = positive in standard math, negative in SVG).\n * In SVG coords: x = cx + r*cos(a), y = cy - r*sin(a) [y-axis is flipped in SVG].\n */\n Handlebars.registerHelper(\"cranPosition\", function (cran, cx, cy, r) {\n const angleDeg = 90 + cran * 15 // counter-clockwise from bottom\n const angleRad = (angleDeg * Math.PI) / 180\n const x = Math.round(cx + r * Math.cos(angleRad))\n const y = Math.round(cy - r * Math.sin(angleRad))\n return { x, y }\n })\n\n /** X offset for overlapping fighters on the same cran. Centres a 30px image on the cran cx. */\n Handlebars.registerHelper(\"fighterX\", function (cx, index, total) {\n const offset = total > 1 ? (index - (total - 1) / 2) * 34 : 0\n return Math.round(cx - 15 + offset)\n })\n\n /** Y offset for fighters \u2014 positions image just above the cran circle. */\n Handlebars.registerHelper(\"fighterY\", function (cy, index, total) {\n return Math.round(cy - 50)\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { TEMPLATE_PARTIALS } from \"../config/constants.js\"\n\nexport async function preloadPartials() {\n return foundry.applications.handlebars.loadTemplates(TEMPLATE_PARTIALS)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Initiative determination system for Chroniques de l'\u00C9trange.\n *\n * PJ formula: Initiative = Prouesse + Premi\u00E8re action (comp\u00E9tence/ressource/magie)\n * PNJ formula: Initiative = Aptitude physique + Premi\u00E8re action (aptitude)\n *\n * Range 1-24 ; anti-initiative = 25 \u2212 initiative.\n * Combat order is ascending (low initiative acts first).\n */\n\nconst PC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-prompt.html\"\nconst NPC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-prompt-npc.html\"\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-result.html\"\n\n/** Skills, resources and magics available as \"premi\u00E8re action\" for a PC. */\nfunction buildPCOptions(sys) {\n const sk = sys.skills ?? {}\n const rs = sys.resources ?? {}\n const mg = sys.magics ?? {}\n return [\n { key: \"art\", label: game.i18n.localize(\"CDE.Art\"), value: sk.art?.value ?? 0 },\n { key: \"investigation\", label: game.i18n.localize(\"CDE.Investigation\"), value: sk.investigation?.value ?? 0 },\n { key: \"erudition\", label: game.i18n.localize(\"CDE.Erudition\"), value: sk.erudition?.value ?? 0 },\n { key: \"knavery\", label: game.i18n.localize(\"CDE.Knavery\"), value: sk.knavery?.value ?? 0 },\n { key: \"wordliness\", label: game.i18n.localize(\"CDE.Wordliness\"), value: sk.wordliness?.value ?? 0 },\n { key: \"prowess\", label: game.i18n.localize(\"CDE.Prowess\"), value: sk.prowess?.value ?? 0 },\n { key: \"sciences\", label: game.i18n.localize(\"CDE.Sciences\"), value: sk.sciences?.value ?? 0 },\n { key: \"technologies\", label: game.i18n.localize(\"CDE.Technologies\"), value: sk.technologies?.value ?? 0 },\n { key: \"kungfu\", label: game.i18n.localize(\"CDE.KungFu\"), value: sk.kungfu?.value ?? 0 },\n { key: \"rangedcombat\", label: game.i18n.localize(\"CDE.RangedCombat\"), value: sk.rangedcombat?.value ?? 0 },\n { key: \"supply\", label: game.i18n.localize(\"CDE.Supply\"), value: rs.supply?.value ?? 0 },\n { key: \"inquiry\", label: game.i18n.localize(\"CDE.Inquiry\"), value: rs.inquiry?.value ?? 0 },\n { key: \"influence\", label: game.i18n.localize(\"CDE.Influence\"), value: rs.influence?.value ?? 0 },\n { key: \"internalcinnabar\", label: game.i18n.localize(\"CDE.InternalCinnabar\"), value: mg.internalcinnabar?.value ?? 0 },\n { key: \"alchemy\", label: game.i18n.localize(\"CDE.Alchemy\"), value: mg.alchemy?.value ?? 0 },\n { key: \"masteryoftheway\", label: game.i18n.localize(\"CDE.MasteryOfTheWay\"), value: mg.masteryoftheway?.value ?? 0 },\n { key: \"exorcism\", label: game.i18n.localize(\"CDE.Exorcism\"), value: mg.exorcism?.value ?? 0 },\n { key: \"geomancy\", label: game.i18n.localize(\"CDE.Geomancy\"), value: mg.geomancy?.value ?? 0 },\n ]\n}\n\n/** Aptitudes available as \"premi\u00E8re action\" for an NPC. */\nfunction buildNPCOptions(sys) {\n const ap = sys.aptitudes ?? {}\n return [\n { key: \"physical\", label: game.i18n.localize(\"CDE.Physical\"), value: ap.physical?.value ?? 0 },\n { key: \"martial\", label: game.i18n.localize(\"CDE.Martial\"), value: ap.martial?.value ?? 0 },\n { key: \"mental\", label: game.i18n.localize(\"CDE.Mental\"), value: ap.mental?.value ?? 0 },\n { key: \"social\", label: game.i18n.localize(\"CDE.Social\"), value: ap.social?.value ?? 0 },\n { key: \"spiritual\", label: game.i18n.localize(\"CDE.Spiritual\"), value: ap.spiritual?.value ?? 0 },\n ]\n}\n\n/** Parse the dialog element and extract firstaction + modifier. */\nfunction readInitFields(dialog) {\n const root = dialog.element ?? dialog\n const selectedKey = root.querySelector(\"select[name='firstaction']\")?.value ?? \"\"\n const modifier = parseInt(root.querySelector(\"input[name='modifier']\")?.value ?? \"0\", 10) || 0\n return { selectedKey, modifier }\n}\n\n/** Post a styled initiative chat message. */\nasync function sendInitChatMessage({ actor, baseName, baseValue, actionName, actionValue, modifier, initiative, antiInitiative }) {\n const html = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, {\n actorName: actor.name,\n actorImg: actor.img,\n baseName,\n baseValue,\n actionName,\n actionValue,\n modifier,\n hasModifier: modifier !== 0,\n initiative,\n antiInitiative,\n })\n await ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor }),\n content: html,\n })\n}\n\n/**\n * Open the PC initiative dialog, compute initiative (Prouesse + Premi\u00E8re action + modificateur)\n * and update the actor, then post a chat card.\n */\nexport async function rollInitiativePC(actor) {\n const sys = actor.system\n const prowess = sys.skills?.prowess?.value ?? 0\n const options = buildPCOptions(sys)\n const baseName = game.i18n.localize(\"CDE.Prowess\")\n\n const content = await foundry.applications.handlebars.renderTemplate(PC_PROMPT_TEMPLATE, {\n prowessValue: prowess,\n options,\n modifier: 0,\n })\n\n const result = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.InitiativeRoll\") },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => readInitFields(dialog),\n },\n })\n if (!result) return\n\n const { selectedKey, modifier } = result\n const selected = options.find((o) => o.key === selectedKey) ?? options[0]\n const rawValue = prowess + selected.value + modifier\n const initiative = Math.max(1, Math.min(24, rawValue))\n const antiInit = 25 - initiative\n\n await actor.update({ \"system.initiative\": initiative })\n await sendInitChatMessage({\n actor,\n baseName,\n baseValue: prowess,\n actionName: selected.label,\n actionValue: selected.value,\n modifier,\n initiative,\n antiInitiative: antiInit,\n })\n}\n\n/**\n * Open the NPC initiative dialog, compute initiative (Aptitude physique + Premi\u00E8re action + modificateur)\n * and update the actor, then post a chat card.\n */\nexport async function rollInitiativeNPC(actor) {\n const sys = actor.system\n const physical = sys.aptitudes?.physical?.value ?? 0\n const options = buildNPCOptions(sys)\n const baseName = game.i18n.localize(\"CDE.Physical\")\n\n const content = await foundry.applications.handlebars.renderTemplate(NPC_PROMPT_TEMPLATE, {\n physicalValue: physical,\n options,\n modifier: 0,\n })\n\n const result = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.InitiativeRoll\") },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => readInitFields(dialog),\n },\n })\n if (!result) return\n\n const { selectedKey, modifier } = result\n const selected = options.find((o) => o.key === selectedKey) ?? options[0]\n const rawValue = physical + selected.value + modifier\n const initiative = Math.max(1, Math.min(24, rawValue))\n const antiInit = 25 - initiative\n\n await actor.update({ \"system.initiative\": initiative })\n await sendInitChatMessage({\n actor,\n baseName,\n baseValue: physical,\n actionName: selected.label,\n actionValue: selected.value,\n modifier,\n initiative,\n antiInitiative: antiInit,\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Loksyu / TinJi settings-based helpers.\n *\n * Data is stored as world settings instead of singleton Actor documents.\n */\n\nimport { SYSTEM_ID, WU_XING_CYCLE, ASPECT_FACES } from \"../../config/constants.js\"\n\n/** Read the current loksyu data object from world settings */\nexport function getLoksyuData() {\n return game.settings.get(SYSTEM_ID, \"loksyuData\") ?? {\n wood: {yin:0,yang:0}, fire: {yin:0,yang:0}, earth: {yin:0,yang:0}, metal: {yin:0,yang:0}, water: {yin:0,yang:0},\n }\n}\n\n/** Write the loksyu data object to world settings */\nexport async function setLoksyuData(data) {\n await game.settings.set(SYSTEM_ID, \"loksyuData\", data)\n Hooks.callAll(\"cde:loksyuUpdated\", data)\n}\n\n/** Read current TinJi value from world settings */\nexport function getTinjiValue() {\n return game.settings.get(SYSTEM_ID, \"tinjiData\") ?? 0\n}\n\n/** Write TinJi value to world settings */\nexport async function setTinjiValue(value) {\n await game.settings.set(SYSTEM_ID, \"tinjiData\", Math.max(0, value))\n Hooks.callAll(\"cde:tinjiUpdated\", Math.max(0, value))\n}\n\n/**\n * After a WuXing roll, add the loksyu faces (yin + yang) of the relevant\n * aspect to the loksyu settings data.\n *\n * @param {string} activeAspect - e.g. \"fire\"\n * @param {Object} faces - Die face counts { 0: n, 1: n, \u2026, 9: n }\n */\nexport async function updateLoksyuFromRoll(activeAspect, faces) {\n const cycle = WU_XING_CYCLE[activeAspect]\n if (!cycle) return\n\n const lokAspect = cycle[3]\n const [yinFace, yangFace] = ASPECT_FACES[lokAspect] ?? []\n if (yinFace === undefined) return\n\n const yinCount = faces[yinFace] ?? 0\n const yangCount = faces[yangFace] ?? 0\n if (yinCount === 0 && yangCount === 0) return\n\n const data = getLoksyuData()\n const current = data[lokAspect] ?? { yin: 0, yang: 0 }\n data[lokAspect] = {\n yin: (current.yin ?? 0) + yinCount,\n yang: (current.yang ?? 0) + yangCount,\n }\n await setLoksyuData(data)\n}\n\n/**\n * After a WuXing roll, add tinji faces to the TinJi settings.\n *\n * @param {number} count - Number of tinji faces rolled\n */\nexport async function updateTinjiFromRoll(count) {\n if (!count || count <= 0) return\n const current = getTinjiValue()\n await setTinjiValue(current + count)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Wu Xing rolling system for Chroniques de l'\u00C9trange.\n *\n * The Wu Xing cycle maps each aspect (by index 0-4) to die face groups:\n * - metal=0 : faces 3,8\n * - water=1 : faces 1,6\n * - earth=2 : faces 0/10,5\n * - fire=3 : faces 2,7\n * - wood=4 : faces 4,9\n *\n * For a given active aspect the five result categories are:\n * successes / auspicious / noxious / loksyu (yin face, yang face) / tinji\n * Each category is associated with one of the five aspects in Wu Xing cycle order.\n */\n\nimport { MAGICS, ASPECT_LABELS, ASPECT_ICONS, ASPECT_FACES, ASPECT_NAMES, WU_XING_CYCLE } from \"../config/constants.js\"\nimport { updateLoksyuFromRoll, updateTinjiFromRoll } from \"./apps/singletons.js\"\n\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html\"\nconst SKILL_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-skill-dice-prompt.html\"\nconst SKILL_SPECIAL_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-skill-special-dice-prompt.html\"\nconst MAGIC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-magic-dice-prompt.html\"\nconst WEAPON_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-weapon-dice-prompt.html\"\n\n/** Maps i18n element label \u2192 aspect name (for speciality default aspect lookup) */\nconst LABELELEMENT_TO_ASPECT = {\n \"CDE.Metal\": \"metal\",\n \"CDE.Water\": \"water\",\n \"CDE.Earth\": \"earth\",\n \"CDE.Fire\": \"fire\",\n \"CDE.Wood\": \"wood\",\n}\n\n/** Maps weapon range string \u2192 dice malus applied to the attack pool */\nconst RANGE_MALUS = {\n contact: 0,\n courte: 0,\n mediane: -1,\n longue: -2,\n extreme: -3,\n}\n\n/** Maps weapon type string \u2192 default skill key */\nconst WEAPON_TYPE_SKILL = {\n melee: \"kungfu\",\n thrown: \"rangedcombat\",\n ranged: \"rangedcombat\",\n firearm: \"rangedcombat\",\n}\n\n/** Maps weapon damageAspect name \u2192 ASPECT_NAMES index */\nconst WEAPON_ASPECT_INDEX = { metal: 0, eau: 1, water: 1, terre: 2, earth: 2, feu: 3, fire: 3, bois: 4, wood: 4 }\n\n/** Count how many times each die face appeared in the roll results */\nfunction countFaces(rollResults) {\n const counts = { 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 0:0 }\n for (const die of rollResults) {\n const face = die.result === 10 ? 0 : die.result\n counts[face]++\n }\n return counts\n}\n\n/**\n * Compute Wu Xing result categories from face counts and active aspect.\n * Returns { successesdice, auspiciousdice, noxiousdice, loksyudice, tinjidice, loksyurepartition }\n */\nfunction computeWuXingResults(faces, aspectName, bonusAuspicious = 0) {\n const cycle = WU_XING_CYCLE[aspectName]\n if (!cycle) return null\n\n const [succAspect, ausAspect, noxAspect, lokAspect, tinAspect] = cycle\n const [succYin, succYang] = ASPECT_FACES[succAspect]\n const [ausYin, ausYang] = ASPECT_FACES[ausAspect]\n const [noxYin, noxYang] = ASPECT_FACES[noxAspect]\n const [lokYin, lokYang] = ASPECT_FACES[lokAspect]\n const [tinYin, tinYang] = ASPECT_FACES[tinAspect]\n\n const yin = game.i18n.localize(\"CDE.Yin\")\n const yang = game.i18n.localize(\"CDE.Yang\")\n\n return {\n successesdice: faces[succYin] + faces[succYang],\n auspiciousdice: faces[ausYin] + faces[ausYang] + bonusAuspicious,\n noxiousdice: faces[noxYin] + faces[noxYang],\n loksyudice: faces[lokYin] + faces[lokYang],\n loksyurepartition: `[${yin}(${faces[lokYin]}) ${yang}(${faces[lokYang]})]`,\n tinjidice: faces[tinYin] + faces[tinYang],\n }\n}\n\n/** Read a named field from a dialog DOM element */\nfunction readField(dlg, name) {\n const el = dlg.querySelector(`[name=\"${name}\"]`)\n if (!el) return null\n return el.type === \"checkbox\" ? el.checked : el.value\n}\n\n/**\n * Open a DialogV2.prompt with the given template + data and return the resolved form values.\n * The callback receives the DialogV2 application instance; fields are read from its .element.\n * @returns {Promise|null>}\n */\nasync function showRollPrompt({ title, template, data, fields }) {\n const content = await foundry.applications.handlebars.renderTemplate(template, data)\n return foundry.applications.api.DialogV2.prompt({\n window: { title },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (event, button, dialog) => {\n // In AppV2, dialog is the application instance; .element is the root HTMLElement\n const root = dialog.element ?? dialog\n const result = {}\n for (const field of fields) {\n result[field] = readField(root, field)\n }\n return result\n },\n },\n })\n}\n\n/**\n * Open the skill roll prompt and return the user-confirmed parameters.\n * @param {object} params - Initial values\n * @returns {Promise}\n */\nasync function showSkillPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: params.isSpecial ? SKILL_SPECIAL_PROMPT_TEMPLATE : SKILL_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice,\n aspect: Number(params.aspect ?? 0),\n bonusmalus: params.bonusmalus ?? 0,\n woundmalus: params.woundmalus ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"aspect\", \"bonusmalus\", \"woundmalus\", \"bonusauspiciousdice\", \"typeofthrow\"],\n })\n}\n\n/**\n * Open the magic roll prompt and return the user-confirmed parameters.\n */\nasync function showMagicPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: MAGIC_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice ?? 0,\n aspectskill: Number(params.aspectskill ?? 0),\n bonusmalusskill: params.bonusmalusskill ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n aspectspeciality: Number(params.aspectspeciality ?? 0),\n rolldifficulty: params.rolldifficulty ?? 1,\n bonusmalusspeciality: params.bonusmalusspeciality ?? 0,\n heispend: params.heispend ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"aspectskill\", \"bonusmalusskill\", \"bonusauspiciousdice\",\n \"aspectspeciality\", \"rolldifficulty\", \"bonusmalusspeciality\",\n \"heispend\", \"typeofthrow\"],\n })\n}\n\n/**\n * Open the weapon attack roll prompt and return user-confirmed parameters.\n */\nasync function showWeaponPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: WEAPON_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice ?? 0,\n weaponName: params.weaponName ?? \"\",\n weaponTypeLabel: params.weaponTypeLabel ?? \"CDE.Weapon\",\n weaponAspectIcon: params.weaponAspectIcon ?? \"\",\n weaponAspectLabel: params.weaponAspectLabel ?? \"\",\n damageBase: params.damageBase ?? 1,\n weaponskill: params.weaponskill ?? \"kungfu\",\n aspect: Number(params.aspect ?? 0),\n effectiverange: params.effectiverange ?? \"contact\",\n bonusmalus: params.bonusmalus ?? 0,\n woundmalus: params.woundmalus ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"weaponskill\", \"aspect\", \"effectiverange\", \"bonusmalus\", \"woundmalus\",\n \"bonusauspiciousdice\", \"typeofthrow\"],\n })\n}\n\n/**\n * Build and send a single enriched ChatMessage containing both the roll\n * (for Dice So Nice) and the Wu Xing result card.\n */\nasync function sendResultMessage(actor, resultData, roll, rollMode) {\n const html = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, resultData)\n return ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor }),\n content: html,\n rolls: [roll],\n rollMode,\n flags: {\n \"fvtt-chroniques-de-l-etrange\": { rollResult: { ...resultData } },\n },\n })\n}\n\nconst ROLL_MODES = [\"roll\", \"gmroll\", \"blindroll\", \"selfroll\"]\n\n/**\n * Main entry point: roll dice for a given actor.\n *\n * @param {Actor} actor\n * @param {string} rollKey - e.g. \"prowess-skill\", \"fire-aspect\", \"alchemy-magic-elixirs\"\n */\nexport async function rollForActor(actor, rollKey) {\n const parts = rollKey.split(\"-\")\n const skillLibel = parts[0]\n const typeLibel = parts[1]\n const specialLibel = parts[2] ?? null\n\n const sys = actor.system\n const typeOfThrow = Number(sys.prefs?.typeofthrow?.choice ?? 0)\n\n let numberofdice = 0\n let title = \"\"\n let isSpecial = false\n let isMagic = false\n let isMagicSpecial = false\n let kfDefaultAspect = -1 // set in \"itemkungfu\" case, used when computing defaultAspect\n\n // ---- Determine dice count + title ----\n const MAGIC_I18N_KEYS = {\n internalcinnabar: \"CDE.InternalCinnabar\",\n alchemy: \"CDE.Alchemy\",\n masteryoftheway: \"CDE.MasteryOfTheWay\",\n exorcism: \"CDE.Exorcism\",\n geomancy: \"CDE.Geomancy\",\n }\n\n switch (typeLibel) {\n case \"aspect\":\n numberofdice = sys.aspect[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.aspect[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"aptitude\":\n // NPC aptitude roll \u2014 flat pool with WuXing prompt\n numberofdice = sys.aptitudes?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(`CDE.${skillLibel.charAt(0).toUpperCase() + skillLibel.slice(1)}`)\n break\n case \"skill\":\n numberofdice = sys.skills?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.skills?.[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"special\":\n numberofdice = sys.skills?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.skills?.[skillLibel]?.label ?? \"CDE.Roll\")\n title += ` [${game.i18n.localize(\"CDE.Speciality\")}]`\n isSpecial = true\n if (!sys.skills?.[skillLibel]?.specialities) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error2\"))\n return\n }\n break\n case \"resource\":\n numberofdice = sys.resources?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.resources?.[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"field\":\n numberofdice = sys.resources?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.resources?.[skillLibel]?.label ?? \"CDE.Roll\")\n title += ` [${game.i18n.localize(\"CDE.Field\")}]`\n isSpecial = true\n if (!sys.resources?.[skillLibel]?.specialities) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error4\"))\n return\n }\n break\n case \"magic\":\n numberofdice = sys.magics?.[skillLibel]?.value ?? 0\n isMagic = true\n title = game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? \"CDE.Magics\")\n break\n case \"magicspecial\":\n numberofdice = sys.magics?.[skillLibel]?.value ?? 0\n isMagicSpecial = true\n isMagic = true\n if (!sys.magics?.[skillLibel]?.speciality?.[specialLibel]?.check) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error6\"))\n return\n }\n title = `${game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? \"CDE.Magics\")} [${game.i18n.localize(MAGICS?.[skillLibel]?.speciality?.[specialLibel]?.label ?? \"\")}]`\n break\n case \"itemkungfu\": {\n // skillLibel = item._id \u2014 look up the kungfu item to find which skill + aspect to use\n const kfItem = actor.items.get(skillLibel)\n if (!kfItem) { ui.notifications.warn(game.i18n.localize(\"CDE.Error0\")); return }\n const kfSkill = kfItem.system.skill ?? \"kungfu\"\n numberofdice = sys.skills?.[kfSkill]?.value ?? 0\n title = `${kfItem.name} [${game.i18n.localize(sys.skills?.[kfSkill]?.label ?? \"CDE.KungFu\")}]`\n kfDefaultAspect = ASPECT_NAMES.indexOf(kfItem.system.aspect ?? \"metal\")\n if (kfDefaultAspect < 0) kfDefaultAspect = 0\n break\n }\n case \"itemweapon\": {\n // skillLibel = item._id \u2014 look up the weapon item to find type + aspect + damage\n const wpItem = actor.items.get(skillLibel)\n if (!wpItem) { ui.notifications.warn(game.i18n.localize(\"CDE.Error0\")); return }\n\n const wpType = wpItem.system.weaponType ?? \"melee\"\n const wpSkill = WEAPON_TYPE_SKILL[wpType] ?? \"kungfu\"\n numberofdice = sys.skills?.[wpSkill]?.value ?? 0\n\n const wpAspectRaw = wpItem.system.damageAspect ?? \"metal\"\n const wpAspectIdx = WEAPON_ASPECT_INDEX[wpAspectRaw] ?? 0\n const wpRange = wpItem.system.range ?? \"contact\"\n\n const WEAPON_TYPE_LABELS = {\n melee: \"CDE.WeaponMelee\",\n thrown: \"CDE.WeaponThrown\",\n ranged: \"CDE.WeaponRanged\",\n firearm: \"CDE.WeaponFirearm\",\n }\n\n // Show weapon-specific prompt\n const wParams = await showWeaponPrompt({\n title: `${wpItem.name} [${game.i18n.localize(sys.skills?.[wpSkill]?.label ?? \"CDE.WeaponRoll\")}]`,\n numberofdice,\n weaponName: wpItem.name,\n weaponTypeLabel: WEAPON_TYPE_LABELS[wpType] ?? \"CDE.Weapon\",\n weaponAspectIcon: ASPECT_ICONS[ASPECT_NAMES[wpAspectIdx]] ?? \"\",\n weaponAspectLabel: game.i18n.localize(ASPECT_LABELS[ASPECT_NAMES[wpAspectIdx]] ?? \"\"),\n damageBase: wpItem.system.damageBase ?? 1,\n weaponskill: wpSkill,\n aspect: wpAspectIdx,\n effectiverange: wpRange,\n bonusmalus: 0,\n woundmalus: 0,\n bonusauspiciousdice: 0,\n typeofthrow: typeOfThrow,\n })\n\n if (!wParams) return // cancelled\n\n // Resolve final pool from weapon prompt values\n const wpChosenSkill = wParams.weaponskill ?? wpSkill\n const wpSkillDice = sys.skills?.[wpChosenSkill]?.value ?? 0\n const wpAspFinal = Number(wParams.aspect ?? wpAspectIdx)\n const wpAspectDice = sys.aspect[ASPECT_NAMES[wpAspFinal]]?.value ?? 0\n const wpRangeMalus = RANGE_MALUS[wParams.effectiverange ?? \"contact\"] ?? 0\n const wpBonusMalus = Number(wParams.bonusmalus ?? 0)\n const wpWoundMalus = Number(wParams.woundmalus ?? 0)\n const wpBonusAusp = Number(wParams.bonusauspiciousdice ?? 0)\n const wpThrowMode = Number(wParams.typeofthrow ?? 0)\n const wpDamageBase = wpItem.system.damageBase ?? 1\n\n const wpTotalDice = wpSkillDice + wpAspectDice + wpRangeMalus + wpBonusMalus - wpWoundMalus\n if (wpTotalDice <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n const wpRoll = new Roll(`${wpTotalDice}d10`)\n await wpRoll.evaluate()\n\n const wpAspectName = ASPECT_NAMES[wpAspFinal] ?? \"metal\"\n const wpFaces = countFaces(wpRoll.dice[0]?.results ?? [])\n const wpResults = computeWuXingResults(wpFaces, wpAspectName, wpBonusAusp)\n if (!wpResults) return\n\n const wpModParts = []\n if (wpRangeMalus !== 0) wpModParts.push(`${wpRangeMalus} ${game.i18n.localize(\"CDE.RangePenalty\")}`)\n if (wpBonusMalus !== 0) wpModParts.push(`${wpBonusMalus > 0 ? \"+\" : \"\"}${wpBonusMalus} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (wpWoundMalus !== 0) wpModParts.push(`-${wpWoundMalus} ${game.i18n.localize(\"CDE.WoundMalus\")}`)\n if (wpBonusAusp !== 0) wpModParts.push(`+${wpBonusAusp} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n\n const wpMsg = await sendResultMessage(actor, {\n rollLabel: `${wpItem.name}`,\n aspectName: wpAspectName,\n aspectLabel: game.i18n.localize(ASPECT_LABELS[wpAspectName] ?? \"\"),\n aspectIcon: ASPECT_ICONS[wpAspectName] ?? \"\",\n totalDice: wpTotalDice,\n modifiersText: wpModParts.length ? wpModParts.join(\" \u00B7 \") : \"\",\n spellPower: null,\n rollDifficulty: null,\n actorName: actor.name ?? \"\",\n actorImg: actor.img ?? \"\",\n // weapon-specific\n weaponName: wpItem.name,\n damageBase: wpDamageBase,\n totalDamage: wpResults.successesdice * wpDamageBase,\n ...wpResults,\n aspect: wpAspectName,\n d1: wpFaces[1], d2: wpFaces[2], d3: wpFaces[3], d4: wpFaces[4], d5: wpFaces[5],\n d6: wpFaces[6], d7: wpFaces[7], d8: wpFaces[8], d9: wpFaces[9], d0: wpFaces[0],\n }, wpRoll, ROLL_MODES[wpThrowMode] ?? \"roll\")\n\n if (game.modules.get(\"dice-so-nice\")?.active && wpMsg?.id) {\n await game.dice3d.waitFor3DAnimationByMessageID(wpMsg.id)\n }\n // Auto-update Loksyu/TinJi singletons from weapon roll faces\n if ((wpResults.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wpAspectName, wpFaces)\n if ((wpResults.tinjidice ?? 0) > 0) await updateTinjiFromRoll(wpResults.tinjidice)\n return\n }\n default:\n ui.notifications.warn(`Unknown roll type: ${typeLibel}`)\n return\n }\n\n // For magic rolls the prompt allows adding HEI dice, so don't block early.\n // For itemkungfu, allow 0 base dice (user can add bonus dice in the prompt).\n if (numberofdice <= 0 && typeLibel !== \"aspect\" && typeLibel !== \"itemkungfu\" && !isMagic) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n // ---- Pre-compute default aspect for magic based on skill ----\n const MAGIC_ASPECTS = {\n internalcinnabar: 0, // metal\n alchemy: 1, // water\n masteryoftheway: 2, // earth\n exorcism: 3, // fire\n geomancy: 4, // wood\n }\n\n let defaultAspect = typeLibel === \"aspect\"\n ? [\"metal\",\"water\",\"earth\",\"fire\",\"wood\"].indexOf(skillLibel)\n : 0\n if (isMagic && MAGIC_ASPECTS[skillLibel] !== undefined) {\n defaultAspect = MAGIC_ASPECTS[skillLibel]\n }\n if (kfDefaultAspect >= 0) {\n defaultAspect = kfDefaultAspect\n }\n\n let defaultSpecialAspect = 0\n if (isMagicSpecial && specialLibel) {\n // Look up the speciality's element from the MAGICS config constant\n const specialCfg = MAGICS?.[skillLibel]?.speciality?.[specialLibel]\n const aspectName = LABELELEMENT_TO_ASPECT[specialCfg?.labelelement]\n if (aspectName) {\n defaultSpecialAspect = ASPECT_NAMES.indexOf(aspectName)\n }\n }\n\n // ---- Show roll prompt ----\n let params\n\n if (isMagic) {\n params = await showMagicPrompt({\n title,\n numberofdice,\n aspectskill: defaultAspect,\n bonusmalusskill: 0,\n bonusauspiciousdice: 0,\n aspectspeciality: defaultSpecialAspect,\n rolldifficulty: 1,\n bonusmalusspeciality: 0,\n heispend: 0,\n typeofthrow: typeOfThrow,\n })\n } else {\n params = await showSkillPrompt({\n title,\n numberofdice,\n aspect: defaultAspect,\n bonusmalus: 0,\n woundmalus: 0,\n bonusauspiciousdice: 0,\n typeofthrow: typeOfThrow,\n isSpecial,\n })\n }\n\n if (!params) return // cancelled\n\n // ---- Compute total dice and roll ----\n let aspectIndex, bonusMalus, bonusAuspicious, throwMode\n let spellAspectIndex = null // magic only: aspect of the speciality for Wu Xing\n let rollDifficulty = 1 // magic only: multiplier applied to successes\n\n if (isMagic) {\n const skillAspectIndex = Number(params.aspectskill ?? 0)\n spellAspectIndex = Number(params.aspectspeciality ?? skillAspectIndex)\n aspectIndex = skillAspectIndex // used only for skill dice pool\n bonusMalus = Number(params.bonusmalusskill ?? 0)\n bonusAuspicious = Number(params.bonusauspiciousdice ?? 0)\n rollDifficulty = Math.max(1, Number(params.rolldifficulty ?? 1))\n throwMode = Number(params.typeofthrow ?? 0)\n // magic: magic skill + aspect + bonuses + 1 (speciality base) + HEI spent\n const aspectDice = sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0\n const bonusSpec = Number(params.bonusmalusspeciality ?? 0)\n const heiDice = Number(params.heispend ?? 0)\n numberofdice = numberofdice + aspectDice + bonusMalus + 1 + bonusSpec + heiDice\n } else {\n aspectIndex = Number(params.aspect ?? 0)\n bonusMalus = Number(params.bonusmalus ?? 0)\n const woundMalus = Number(params.woundmalus ?? 0)\n bonusAuspicious = Number(params.bonusauspiciousdice ?? 0)\n throwMode = Number(params.typeofthrow ?? 0)\n\n const aspectDice = (typeLibel !== \"aspect\")\n ? (sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0)\n : 0\n\n numberofdice = numberofdice + aspectDice + bonusMalus - woundMalus\n if (isSpecial) numberofdice += 1 // +1d for speciality\n }\n\n if (numberofdice <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n // ---- Roll ----\n const roll = new Roll(`${numberofdice}d10`)\n await roll.evaluate()\n\n const rollModeKey = ROLL_MODES[throwMode] ?? \"roll\"\n\n // ---- Compute Wu Xing results ----\n // For magic rolls, the spell's aspect (aspectspeciality) governs the Wu Xing\n // cycle (which faces count as successes/auspicious/etc.), not the skill aspect.\n const wuXingAspectName = spellAspectIndex !== null\n ? ASPECT_NAMES[spellAspectIndex]\n : ASPECT_NAMES[aspectIndex]\n const allResults = roll.dice[0]?.results ?? []\n const faces = countFaces(allResults)\n const results = computeWuXingResults(faces, wuXingAspectName, bonusAuspicious)\n if (!results) return\n\n // For magic, successesdice \u00D7 rollDifficulty = spell power\n const spellPower = isMagic ? results.successesdice * rollDifficulty : null\n\n // ---- Build modifier summary text ----\n const modParts = []\n if (isMagic) {\n const bm = Number(params.bonusmalusskill ?? 0)\n const bs = Number(params.bonusmalusspeciality ?? 0)\n const hs = Number(params.heispend ?? 0)\n const ba = Number(params.bonusauspiciousdice ?? 0)\n if (bm !== 0) modParts.push(`${bm > 0 ? \"+\" : \"\"}${bm} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (bs !== 0) modParts.push(`${bs > 0 ? \"+\" : \"\"}${bs} ${game.i18n.localize(\"CDE.SpellBonus\")}`)\n if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n if (hs !== 0) modParts.push(`${hs} ${game.i18n.localize(\"CDE.HeiSpend\")}`)\n if (rollDifficulty !== 1) modParts.push(`\u00D7${rollDifficulty} ${game.i18n.localize(\"CDE.RollDifficulty\")}`)\n } else {\n const bm = Number(params.bonusmalus ?? 0)\n const wm = Number(params.woundmalus ?? 0)\n const ba = Number(params.bonusauspiciousdice ?? 0)\n if (bm !== 0) modParts.push(`${bm > 0 ? \"+\" : \"\"}${bm} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (wm !== 0) modParts.push(`-${wm} ${game.i18n.localize(\"CDE.WoundMalus\")}`)\n if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n }\n\n // ---- Send single enriched ChatMessage (roll + result card) ----\n const msg = await sendResultMessage(actor, {\n // Roll identity\n rollLabel: title,\n aspectName: wuXingAspectName,\n aspectLabel: game.i18n.localize(ASPECT_LABELS[wuXingAspectName] ?? \"\"),\n aspectIcon: ASPECT_ICONS[wuXingAspectName] ?? \"\",\n totalDice: numberofdice,\n modifiersText: modParts.length ? modParts.join(\" \u00B7 \") : \"\",\n // Spell power (magic only)\n spellPower,\n rollDifficulty: isMagic ? rollDifficulty : null,\n // Actor info\n actorName: actor.name ?? \"\",\n actorImg: actor.img ?? \"\",\n // Wu Xing results\n aspect: wuXingAspectName,\n ...results,\n // Die face counts\n d1: faces[1], d2: faces[2], d3: faces[3], d4: faces[4], d5: faces[5],\n d6: faces[6], d7: faces[7], d8: faces[8], d9: faces[9], d0: faces[0],\n }, roll, rollModeKey)\n\n // ---- Wait for Dice So Nice animation ----\n if (game.modules.get(\"dice-so-nice\")?.active && msg?.id) {\n await game.dice3d.waitFor3DAnimationByMessageID(msg.id)\n }\n\n // ---- Auto-update Loksyu / TinJi singletons ----\n if ((results.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wuXingAspectName, faces)\n if ((results.tinjidice ?? 0) > 0) await updateTinjiFromRoll(results.tinjidice)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst { HandlebarsApplicationMixin } = foundry.applications.api\n\nexport class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {\n static DEFAULT_OPTIONS = {\n classes: [\"fvtt-chroniques-de-l-etrange\", \"actor\"],\n position: { width: 920, height: 800 },\n window: { resizable: true },\n form: { submitOnChange: true },\n dragDrop: [{ dragSelector: \".item, [data-drag='true']\", dropSelector: null }],\n actions: {\n create: CDEBaseActorSheet.#onItemCreate,\n edit: CDEBaseActorSheet.#onItemEdit,\n delete: CDEBaseActorSheet.#onItemDelete,\n editImage: CDEBaseActorSheet.#onEditImage,\n },\n }\n\n tabGroups = { primary: \"description\" }\n\n get title() {\n return this.document.name\n }\n\n async _prepareContext() {\n const descriptionHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? \"\", { async: true })\n const cssClass = this.options.classes?.join(\" \") ?? \"\"\n return {\n actor: this.document,\n system: this.document.system,\n systemData: this.document.system,\n systemFields: this.document.system.schema.fields,\n items: this.document.items.contents,\n descriptionHTML,\n editable: this.isEditable,\n cssClass,\n }\n }\n\n // Restore the active tab after every render (including re-renders from submitOnChange).\n // AppV2 does NOT preserve tab state natively \u2014 we must re-apply it from this.tabGroups,\n // which is dynamically updated by changeTab() when the user clicks a tab.\n _onRender(context, options) {\n super._onRender?.(context, options)\n for (const [group, tab] of Object.entries(this.tabGroups)) {\n this.changeTab(tab, group, { force: true })\n }\n }\n\n static async #onItemCreate(event, target) {\n const type = target.dataset.type ?? \"item\"\n const cls = getDocumentClass(\"Item\")\n const labels = {\n item: \"CDE.ItemNew\",\n weapon: \"CDE.WeaponNew\",\n armor: \"CDE.ArmorNew\",\n sanhei: \"CDE.SanheiNew\",\n ingredient: \"CDE.IngredientNew\",\n kungfu: \"CDE.KFNew\",\n spell: \"CDE.SpellNew\",\n supernatural: \"CDE.SupernaturalNew\",\n }\n const name = game.i18n.localize(labels[type] ?? \"CDE.ItemNew\")\n const systemData = {}\n if (type === \"spell\" && target.dataset.discipline) {\n systemData.discipline = target.dataset.discipline\n }\n return cls.create({ name, type, system: systemData }, { parent: this.document })\n }\n\n static #onItemEdit(event, target) {\n const itemId = target.dataset.itemId ?? target.closest(\"[data-item-id]\")?.dataset.itemId\n const item = this.document.items.get(itemId)\n if (item) item.sheet.render(true)\n }\n\n static #onItemDelete(event, target) {\n const itemId = target.dataset.itemId ?? target.closest(\"[data-item-id]\")?.dataset.itemId\n const item = this.document.items.get(itemId)\n if (item) item.delete()\n }\n\n static async #onEditImage(event, target) {\n const attr = target.dataset.edit\n const current = foundry.utils.getProperty(this.document, attr)\n const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}\n const fp = new FilePicker({\n current,\n type: \"image\",\n redirectToRoot: img ? [img] : [],\n callback: (path) => this.document.update({ [attr]: path }),\n top: this.position.top + 40,\n left: this.position.left + 10,\n })\n return fp.browse()\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS, SUBTYPES } from \"../../../config/constants.js\"\nimport { rollInitiativePC } from \"../../initiative.js\"\nimport { rollForActor } from \"../../rolling.js\"\nimport { CDEBaseActorSheet } from \"./base.js\"\n\nexport class CDECharacterSheet extends CDEBaseActorSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"character\"],\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-character-sheet.html\" },\n }\n\n tabGroups = { primary: \"description\" }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n context.equipments = context.items.filter((item) => item.type === \"item\")\n context.weapons = context.items.filter((item) => item.type === \"weapon\")\n context.armors = context.items.filter((item) => item.type === \"armor\")\n context.sanheis = context.items.filter((item) => item.type === \"sanhei\")\n context.ingredients = context.items.filter((item) => item.type === \"ingredient\")\n context.spells = context.items.filter((item) => item.type === \"spell\")\n context.kungfus = context.items.filter((item) => item.type === \"kungfu\")\n context.CDE = { MAGICS, SUBTYPES }\n\n // Group spells by discipline key (matches MAGICS keys)\n const spellsByDiscipline = {}\n for (const spell of context.spells) {\n const disc = spell.system?.discipline ?? \"internalcinnabar\"\n if (!spellsByDiscipline[disc]) spellsByDiscipline[disc] = []\n spellsByDiscipline[disc].push(spell)\n }\n\n // Build magicsDisplay: only include the 5 relevant specialities per magic type + grimoire\n const systemMagics = context.systemData.magics ?? {}\n context.magicsDisplay = Object.fromEntries(\n Object.entries(MAGICS).map(([magicKey, magicDef]) => {\n const magicData = systemMagics[magicKey] ?? {}\n return [\n magicKey,\n {\n value: magicData.value ?? 0,\n visible: magicData.visible ?? false,\n speciality: Object.fromEntries(\n Object.keys(magicDef.speciality).map((specKey) => [\n specKey,\n { check: magicData.speciality?.[specKey]?.check ?? false },\n ])\n ),\n grimoire: spellsByDiscipline[magicKey] ?? [],\n },\n ]\n })\n )\n\n return context\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInitiativeControls()\n this.#bindPrefs()\n this.#bindRollButtons()\n this.#bindComponentRandomize()\n this.#bindDiagramZoom()\n }\n\n #bindInitiativeControls() {\n const buttons = this.element?.querySelectorAll(\".click-initiative\")\n if (!buttons?.length) return\n buttons.forEach((button) => {\n button.addEventListener(\"click\", async () => {\n const action = button.dataset.libelId\n let initiative = this.document.system.initiative ?? 1\n if (action === \"plus\") {\n initiative = initiative >= 24 ? 1 : initiative + 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"minus\") {\n initiative = initiative <= 1 ? 24 : initiative - 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"create\") {\n await rollInitiativePC(this.document)\n }\n })\n })\n }\n\n #bindPrefs() {\n const button = this.element?.querySelector(\".click-prefs\")\n if (!button) return\n button.addEventListener(\"click\", async () => {\n const current = this.document.system.prefs?.typeofthrow ?? { choice: \"0\", check: true }\n const html = `\n
\n
\n \n \n
\n
\n \n \n
\n
`\n const prefs = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.Preferences\") },\n content: html,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => {\n const root = dialog.element ?? dialog\n const choice = root.querySelector(\"select[name='choice']\")?.value ?? \"0\"\n const check = root.querySelector(\"input[name='check']\")?.checked ?? false\n return { choice, check }\n },\n },\n })\n if (prefs) {\n await this.document.update({\n \"system.prefs.typeofthrow.choice\": String(prefs.choice),\n \"system.prefs.typeofthrow.check\": !!prefs.check,\n })\n }\n })\n }\n\n #bindRollButtons() {\n const cells = this.element?.querySelectorAll(\"td.click[data-libel-id], td.click2[data-libel-id], .cde-roll-trigger[data-libel-id]\")\n if (!cells?.length) return\n cells.forEach((cell) => {\n cell.addEventListener(\"click\", (event) => {\n event.preventDefault()\n const rollKey = cell.dataset.libelId\n if (rollKey) rollForActor(this.document, rollKey)\n })\n })\n }\n\n #bindDiagramZoom() {\n const img = this.element?.querySelector(\"[data-action='zoom-diagram']\")\n if (!img) return\n img.addEventListener(\"click\", () => {\n new ImagePopout(img.src, {\n title: game.i18n.localize(\"CDE.NghangDiagramTitle\"),\n shareable: false,\n }).render(true)\n })\n }\n\n #bindComponentRandomize() {\n const btn = this.element?.querySelector(\"[data-action='randomize-component']\")\n if (!btn) return\n btn.addEventListener(\"click\", async () => {\n const roll = new Roll(\"1d10\")\n await roll.evaluate()\n const face = roll.total === 10 ? 0 : roll.total\n const COMPONENT_KEYS = { 1:\"one\", 2:\"two\", 3:\"three\", 4:\"four\", 5:\"five\",\n 6:\"six\", 7:\"seven\", 8:\"eight\", 9:\"nine\", 0:\"zero\" }\n const componentKey = COMPONENT_KEYS[face]\n const componentValue = this.document.system.component?.[componentKey]?.value ?? \"\"\n const label = componentValue\n ? `${componentValue}`\n : `${game.i18n.localize(\"CDE.Component\")}${face}`\n const content = `\n
\n ${game.i18n.localize(\"CDE.ChanceThrowResult\")}\n ${label}\n
`\n await ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor: this.document }),\n content,\n rolls: [roll],\n rollMode: game.settings.get(\"core\", \"rollMode\") ?? \"roll\",\n })\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { rollInitiativeNPC } from \"../../initiative.js\"\nimport { rollForActor } from \"../../rolling.js\"\nimport { CDEBaseActorSheet } from \"./base.js\"\n\nexport class CDENpcSheet extends CDEBaseActorSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"npc\"],\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-npc-sheet.html\" },\n }\n\n tabGroups = { primary: \"description\" }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n context.supernaturals = context.items.filter((item) => item.type === \"supernatural\")\n context.spells = context.items.filter((item) => item.type === \"spell\")\n context.kungfus = context.items.filter((item) => item.type === \"kungfu\")\n context.weapons = context.items.filter((item) => item.type === \"weapon\")\n context.armors = context.items.filter((item) => item.type === \"armor\")\n context.equipments = context.items.filter((item) => item.type === \"item\")\n return context\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInitiativeControls()\n this.#bindRollButtons()\n }\n\n #bindRollButtons() {\n const cells = this.element?.querySelectorAll(\".cde-roll-trigger[data-libel-id]\")\n if (!cells?.length) return\n cells.forEach((cell) => {\n cell.addEventListener(\"click\", (event) => {\n event.preventDefault()\n const rollKey = cell.dataset.libelId\n if (rollKey) rollForActor(this.document, rollKey)\n })\n })\n }\n\n #bindInitiativeControls() {\n const buttons = this.element?.querySelectorAll(\".click-initiative-npc\")\n if (!buttons?.length) return\n buttons.forEach((button) => {\n button.addEventListener(\"click\", async () => {\n const action = button.dataset.libelId\n let initiative = this.document.system.initiative ?? 1\n if (action === \"plus\") {\n initiative = initiative >= 24 ? 1 : initiative + 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"minus\") {\n initiative = initiative <= 1 ? 24 : initiative - 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"create\") {\n await rollInitiativeNPC(this.document)\n }\n })\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst { HandlebarsApplicationMixin } = foundry.applications.api\n\nexport class CDEBaseItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {\n static DEFAULT_OPTIONS = {\n classes: [\"fvtt-chroniques-de-l-etrange\", \"item\"],\n position: { width: 520, height: \"auto\" },\n window: { resizable: true },\n form: { submitOnChange: true },\n actions: {\n editImage: CDEBaseItemSheet.#onEditImage,\n },\n }\n\n tabGroups = { primary: \"details\" }\n\n get title() {\n return this.document.name\n }\n\n async _prepareContext() {\n const cssClass = this.options.classes?.join(\" \") ?? \"\"\n const enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? \"\", { async: true })\n const enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes ?? \"\", { async: true })\n return {\n item: this.document,\n system: this.document.system,\n systemData: this.document.system,\n systemFields: this.document.system.schema.fields,\n editable: this.isEditable,\n cssClass,\n enrichedDescription,\n enrichedNotes,\n descriptionHTML: enrichedDescription,\n notesHTML: enrichedNotes,\n }\n }\n\n // Restore the active tab after every render (including re-renders from submitOnChange).\n _onRender(context, options) {\n super._onRender?.(context, options)\n for (const [group, tab] of Object.entries(this.tabGroups)) {\n this.changeTab(tab, group, { force: true })\n }\n }\n\n static async #onEditImage(event, target) {\n const attr = target.dataset.edit\n const current = foundry.utils.getProperty(this.document, attr)\n const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}\n const fp = new FilePicker({\n current,\n type: \"image\",\n redirectToRoot: img ? [img] : [],\n callback: (path) => this.document.update({ [attr]: path }),\n top: this.position.top + 40,\n left: this.position.left + 10,\n })\n return fp.browse()\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEItemSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"equipment\"],\n position: { width: 560, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-item-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEKungfuSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"kungfu\"],\n position: { width: 720, height: 680 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-kungfu-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const techniques = this.document.system.techniques ?? {}\n const enrich = (value) => foundry.applications.ux.TextEditor.implementation.enrichHTML(value ?? \"\", { async: true })\n context.descriptionTechnique1HTML = await enrich(techniques.technique1?.technique)\n context.descriptionTechnique2HTML = await enrich(techniques.technique2?.technique)\n context.descriptionTechnique3HTML = await enrich(techniques.technique3?.technique)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESpellSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"spell\"],\n position: { width: 660, height: 680 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-spell-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n context.spellDescriptionHTML = await enrich(this.document.system.description)\n context.componentsDescriptionHTML = await enrich(this.document.system.components)\n context.effectsDescriptionHTML = await enrich(this.document.system.effects)\n context.examplesDescriptionHTML = await enrich(this.document.system.examples)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESupernaturalSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"supernatural\"],\n position: { width: 560, height: 520 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-supernatural-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n context.effectsHTML = await enrich(this.document.system.effects)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEWeaponSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"weapon\"],\n position: { width: 580, height: 520 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-weapon-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEArmorSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"armor\"],\n position: { width: 520, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-armor-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESanheiSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"sanhei\"],\n position: { width: 580, height: 620 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-sanhei-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n const props = this.document.system.properties\n context.prop1DescriptionHTML = await enrich(props.prop1.description)\n context.prop2DescriptionHTML = await enrich(props.prop2.description)\n context.prop3DescriptionHTML = await enrich(props.prop3.description)\n context.propFields = this.document.system.schema.fields.properties.fields\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEIngredientSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"ingredient\"],\n position: { width: 520, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-ingredient-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { getLoksyuData, setLoksyuData } from \"./singletons.js\"\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nexport class CDELoksyuApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-loksyu-app\",\n tag: \"div\",\n window: {\n title: \"CDE.Loksyu\",\n icon: \"fas fa-yin-yang\",\n resizable: false,\n },\n classes: [\"cde-app\", \"cde-loksyu-standalone\"],\n position: { width: 520, height: \"auto\" },\n actions: {\n resetElement: CDELoksyuApp.#onResetElement,\n resetAll: CDELoksyuApp.#onResetAll,\n zoomVisual: CDELoksyuApp.#onZoomVisual,\n },\n }\n\n static PARTS = {\n main: {\n template: `systems/${SYSTEM_ID}/templates/apps/cde-loksyu-app.html`,\n },\n }\n\n /** @type {Function|null} bound hook handler */\n _updateHook = null\n\n /** Singleton accessor \u2014 open or bring to front */\n static open() {\n const existing = Array.from(foundry.applications.instances.values()).find(\n (app) => app instanceof CDELoksyuApp\n )\n if (existing) { existing.bringToFront(); return existing }\n const app = new CDELoksyuApp()\n app.render(true)\n return app\n }\n\n async _prepareContext() {\n const sys = getLoksyuData()\n const ELEMENTS = [\n { key: \"wood\", nameKey: \"CDE.Wood\", qualKey: \"CDE.WoodQualities\", img: `systems/${SYSTEM_ID}/images/cde_bois.webp` },\n { key: \"fire\", nameKey: \"CDE.Fire\", qualKey: \"CDE.FireQualities\", img: `systems/${SYSTEM_ID}/images/cde_feu.webp` },\n { key: \"earth\", nameKey: \"CDE.Earth\", qualKey: \"CDE.EarthQualities\", img: `systems/${SYSTEM_ID}/images/cde_terre.webp` },\n { key: \"metal\", nameKey: \"CDE.Metal\", qualKey: \"CDE.MetalQualities\", img: `systems/${SYSTEM_ID}/images/cde_metal.webp` },\n { key: \"water\", nameKey: \"CDE.Water\", qualKey: \"CDE.WaterQualities\", img: `systems/${SYSTEM_ID}/images/cde_eau.webp` },\n ]\n\n return {\n canEdit: game.user.isGM,\n elements: ELEMENTS.map((el) => ({\n ...el,\n yang: sys[el.key]?.yang ?? 0,\n yin: sys[el.key]?.yin ?? 0,\n })),\n }\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInputs()\n\n this._updateHook = Hooks.on(\"cde:loksyuUpdated\", () => this.render())\n }\n\n _onClose(options) {\n if (this._updateHook !== null) {\n Hooks.off(\"cde:loksyuUpdated\", this._updateHook)\n this._updateHook = null\n }\n super._onClose(options)\n }\n\n #bindInputs() {\n const inputs = this.element?.querySelectorAll(\"input[data-field]\")\n if (!inputs?.length) return\n inputs.forEach((input) => {\n input.addEventListener(\"change\", async (ev) => {\n const field = ev.currentTarget.dataset.field\n const val = parseInt(ev.currentTarget.value, 10)\n if (!field || isNaN(val)) return\n // field is like \"wood.yin\" or \"fire.yang\"\n const [aspect, dim] = field.split(\".\")\n if (!aspect || !dim) return\n const data = getLoksyuData()\n if (!data[aspect]) data[aspect] = { yin: 0, yang: 0 }\n data[aspect][dim] = Math.max(0, val)\n await setLoksyuData(data)\n })\n })\n }\n\n static async #onResetElement(event, target) {\n const key = target.dataset.element\n if (!key) return\n const data = getLoksyuData()\n data[key] = { yin: 0, yang: 0 }\n await setLoksyuData(data)\n }\n\n static async #onResetAll(_event, _target) {\n const KEYS = [\"wood\", \"fire\", \"earth\", \"metal\", \"water\"]\n const data = getLoksyuData()\n for (const k of KEYS) data[k] = { yin: 0, yang: 0 }\n await setLoksyuData(data)\n }\n\n static #onZoomVisual(_event, target) {\n new ImagePopout(target.src, {\n title: game.i18n.localize(\"CDE.LoksyuDiagramTitle\"),\n shareable: false,\n }).render(true)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { getTinjiValue, setTinjiValue } from \"./singletons.js\"\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nexport class CDETinjiApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-tinji-app\",\n tag: \"div\",\n window: {\n title: \"CDE.TinJi2\",\n icon: \"fas fa-star\",\n resizable: false,\n },\n classes: [\"cde-app\", \"cde-tinji-standalone\"],\n position: { width: 380, height: \"auto\" },\n actions: {\n increment: CDETinjiApp.#onIncrement,\n decrement: CDETinjiApp.#onDecrement,\n reset: CDETinjiApp.#onReset,\n spend: CDETinjiApp.#onSpend,\n },\n }\n\n static PARTS = {\n main: {\n template: `systems/${SYSTEM_ID}/templates/apps/cde-tinji-app.html`,\n },\n }\n\n /** @type {Function|null} */\n _updateHook = null\n\n static open() {\n const existing = Array.from(foundry.applications.instances.values()).find(\n (app) => app instanceof CDETinjiApp\n )\n if (existing) { existing.bringToFront(); return existing }\n const app = new CDETinjiApp()\n app.render(true)\n return app\n }\n\n async _prepareContext() {\n return {\n canEdit: game.user.isGM,\n value: getTinjiValue(),\n }\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindDirectInput()\n this._updateHook = Hooks.on(\"cde:tinjiUpdated\", () => this.render())\n }\n\n _onClose(options) {\n if (this._updateHook !== null) {\n Hooks.off(\"cde:tinjiUpdated\", this._updateHook)\n this._updateHook = null\n }\n super._onClose(options)\n }\n\n #bindDirectInput() {\n const input = this.element?.querySelector(\"input.cde-tinji-direct\")\n if (!input) return\n input.addEventListener(\"change\", async (ev) => {\n const val = parseInt(ev.currentTarget.value, 10)\n if (!isNaN(val)) await setTinjiValue(val)\n })\n }\n\n static async #onIncrement() {\n await setTinjiValue(getTinjiValue() + 1)\n }\n\n static async #onDecrement() {\n const current = getTinjiValue()\n if (current <= 0) return\n await setTinjiValue(current - 1)\n }\n\n static async #onReset() {\n await setTinjiValue(0)\n }\n\n static async #onSpend() {\n const current = getTinjiValue()\n if (current <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.TinjiEmpty\"))\n return\n }\n await setTinjiValue(current - 1)\n ChatMessage.create({\n user: game.user.id,\n content: `
\n \n ${game.i18n.localize(\"CDE.TinJi2\")}\n ${game.i18n.format(\"CDE.TinjiSpent\", { name: game.user.name })}\n (${current - 1} ${game.i18n.localize(\"CDE.TinjiRemaining\")})\n
`,\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { rollInitiativePC, rollInitiativeNPC } from \"../ui/initiative.js\"\nimport { ACTOR_TYPES } from \"../config/constants.js\"\n\n/**\n * Custom Combat document for Chroniques de l'\u00C9trange.\n *\n * The initiative wheel has 24 crans (positions). The character with the\n * highest initiative acts first (furthest counter-clockwise from reference).\n * After each action, their position advances clockwise by the action's cran cost\n * (initiative decreases, wrapping from 1 \u2192 24).\n *\n * Sort order: descending by initiative (highest acts first).\n */\nexport class CDECombat extends Combat {\n\n /**\n * Override rollInitiative to open the PC or NPC initiative dialog\n * for each selected combatant, then sync the result to the Combatant document.\n */\n async rollInitiative(ids, options = {}) {\n const combatantIds = typeof ids === \"string\" ? [ids] : ids\n for (const id of combatantIds) {\n const combatant = this.combatants.get(id)\n if (!combatant) continue\n const actor = combatant.actor\n if (!actor) continue\n\n if (actor.type === ACTOR_TYPES.character) {\n await rollInitiativePC(actor)\n } else {\n await rollInitiativeNPC(actor)\n }\n // combatant.initiative is synced by the updateActor hook in system.js\n // (triggered by actor.update inside rollInitiativePC/NPC)\n }\n return this\n }\n\n /**\n * Sort combatants: highest initiative first (furthest counter-clockwise = acts first).\n * Ties: PCs before NPCs; among PCs, by name; among NPCs, by name.\n * Calls super.setupTurns() first to ensure this.current is properly initialized.\n */\n setupTurns() {\n super.setupTurns()\n this.turns = this.turns.slice().sort((a, b) => {\n const ia = a.initiative ?? 0\n const ib = b.initiative ?? 0\n if (ia !== ib) return ib - ia // descending \u2014 highest acts first\n\n // Tie-break: PCs before NPCs\n const aIsPC = a.actor?.type === ACTOR_TYPES.character ? 1 : 0\n const bIsPC = b.actor?.type === ACTOR_TYPES.character ? 1 : 0\n if (aIsPC !== bIsPC) return bIsPC - aIsPC\n\n return (a.name ?? \"\").localeCompare(b.name ?? \"\")\n })\n return this.turns\n }\n}\n\n/**\n * Advance a combatant's wheel position by the given action cran cost.\n * Position wraps: after reaching 1, it continues from 24.\n *\n * @param {Combatant} combatant\n * @param {number} cranCost\n */\nexport async function advanceCombatantPosition(combatant, cranCost) {\n const current = combatant.initiative ?? combatant.actor?.system?.initiative ?? 1\n const newValue = ((current - cranCost - 1 + 48) % 24) + 1\n // Update combatant only; the updateCombatant hook in system.js syncs actor.initiative.\n await combatant.update({ initiative: newValue })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { advanceCombatantPosition } from \"../../documents/combat.js\"\n\nconst WHEEL_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html\"\n\n/**\n * Action costs for common combat actions (in crans).\n * Listed in order from cheapest to most expensive.\n */\nexport const ACTION_COSTS = [\n { key: \"draw\", label: \"CDE.ActionCostDraw\", cost: 1 },\n { key: \"changestyle\", label: \"CDE.ActionCostChangeStyle\", cost: 1 },\n { key: \"defense\", label: \"CDE.ActionCostDefense\", cost: 1 },\n { key: \"aim\", label: \"CDE.ActionCostAim\", cost: 2 },\n { key: \"help\", label: \"CDE.ActionCostHelp\", cost: 2 },\n { key: \"defally\", label: \"CDE.ActionCostDefendAlly\", cost: 2 },\n { key: \"move\", label: \"CDE.ActionCostMove\", cost: 2 },\n { key: \"attack\", label: \"CDE.ActionCostAttack\", cost: 3 },\n { key: \"delay\", label: \"CDE.ActionCostDelay\", cost: 6 },\n]\n\n/**\n * Wu Xing color segments for the 24-cran wheel.\n * 6 colors \u00D7 4 crans = 24. Each colour covers crans [start..start+3].\n * An effect lasting 6 crans returns to the same colour.\n */\nconst WHEEL_SEGMENTS = [\n { label: \"M\u00E9tal\", color: \"#b8c4cc\", textColor: \"#1a1a1a\", crans: [1, 2, 3, 4] },\n { label: \"Eau\", color: \"#3a7bd5\", textColor: \"#ffffff\", crans: [5, 6, 7, 8] },\n { label: \"Terre\", color: \"#c8a84b\", textColor: \"#1a1a1a\", crans: [9, 10, 11, 12] },\n { label: \"Feu\", color: \"#d94f3d\", textColor: \"#ffffff\", crans: [13, 14, 15, 16] },\n { label: \"Bois\", color: \"#4a9b5a\", textColor: \"#ffffff\", crans: [17, 18, 19, 20] },\n { label: \"Rep\u00E8re\", color: \"#1a1a2e\", textColor: \"#aaaaaa\", crans: [21, 22, 23, 24] },\n]\n\n/** Return the segment data for a given cran (1\u201324). */\nfunction segmentForCran(cran) {\n return WHEEL_SEGMENTS.find(s => s.crans.includes(cran)) ?? WHEEL_SEGMENTS[0]\n}\n\n/**\n * Roue d'Initiative \u2014 visual initiative wheel for CDE combat.\n *\n * Shows all combatants in the current combat scene on a 24-cran wheel.\n * Provides action-cost buttons to advance a combatant's position.\n *\n * Singleton: open via CDEWheelApp.open().\n */\nexport class CDEWheelApp extends foundry.applications.api.ApplicationV2 {\n static DEFAULT_OPTIONS = {\n id: \"cde-wheel-app\",\n classes: [\"cde-wheel-app\"],\n tag: \"div\",\n window: {\n title: \"CDE.InitiativeWheel\",\n icon: \"fas fa-circle-notch\",\n resizable: true,\n },\n position: { width: 820, height: 620 },\n actions: {\n advanceCran: CDEWheelApp.#advanceCran,\n setSurprised: CDEWheelApp.#setSurprised,\n rollInitiative: CDEWheelApp.#rollInitiative,\n },\n }\n\n /** @type {CDEWheelApp|null} */\n static #instance = null\n\n /** Open (or bring to front) the singleton instance. */\n static open() {\n if (!CDEWheelApp.#instance || CDEWheelApp.#instance.rendered === false) {\n CDEWheelApp.#instance = new CDEWheelApp()\n CDEWheelApp.#instance.render(true)\n } else {\n CDEWheelApp.#instance.bringToFront()\n }\n return CDEWheelApp.#instance\n }\n\n /** Currently selected combatant id (for action panel). */\n #selectedId = null\n\n async _prepareContext(options) {\n const combat = game.combat\n const combatants = combat ? [...combat.combatants.values()] : []\n const sorted = [...combatants].sort((a, b) => (b.initiative ?? 0) - (a.initiative ?? 0))\n const cranData = this.#buildCranData(combatants)\n const selected = this.#selectedId\n ? combatants.find(c => c.id === this.#selectedId)\n : null\n const actionCosts = ACTION_COSTS.map(a => ({\n ...a,\n label: game.i18n.localize(a.label),\n }))\n\n return {\n hasCombat: !!combat,\n combatants: sorted.map(c => ({\n id: c.id,\n name: c.name,\n img: c.token?.texture?.src ?? c.actor?.img ?? \"icons/svg/mystery-man.svg\",\n initiative: c.initiative ?? \"\u2014\",\n segment: segmentForCran(c.initiative ?? 1),\n isActive: combat?.current?.combatantId === c.id,\n isSelected: c.id === this.#selectedId,\n hasInitiative: c.initiative != null,\n })),\n cranData,\n selected,\n selectedName: selected?.name ?? null,\n actionCosts,\n }\n }\n\n async _renderHTML(context, options) {\n return foundry.applications.handlebars.renderTemplate(WHEEL_TEMPLATE, context)\n }\n\n _replaceHTML(result, content, options) {\n content.innerHTML = result\n this.#bindEvents(content)\n }\n\n /** Build per-cran data for the SVG wheel. */\n #buildCranData(combatants) {\n const data = []\n for (let cran = 1; cran <= 24; cran++) {\n const segment = segmentForCran(cran)\n const fighters = combatants.filter(c => Math.round(c.initiative) === cran)\n data.push({ cran, segment, fighters })\n }\n return data\n }\n\n /** Bind click events for combatant selection. */\n #bindEvents(content) {\n content.querySelectorAll(\"[data-select-combatant]\").forEach(el => {\n el.addEventListener(\"click\", () => {\n this.#selectedId = el.dataset.selectCombatant\n this.render()\n })\n })\n }\n\n /** Action: advance selected combatant by given cran cost. */\n static async #advanceCran(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const cost = parseInt(element.dataset.cost, 10)\n if (!cost || isNaN(cost)) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n await advanceCombatantPosition(combatant, cost)\n }\n\n /** Action: set selected combatant to surprised (position 1 = reference). */\n static async #setSurprised(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n // Update combatant only \u2014 updateCombatant hook in system.js syncs actor\n await combatant.update({ initiative: 1 })\n }\n\n /** Action: open the initiative dialog for the selected combatant. */\n static async #rollInitiative(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n await game.combat.rollInitiative([app.#selectedId])\n }\n\n /** Re-render when combat state changes. */\n static registerHooks() {\n const refresh = () => {\n if (CDEWheelApp.#instance?.rendered) CDEWheelApp.#instance.render()\n }\n Hooks.on(\"updateCombat\", refresh)\n Hooks.on(\"updateCombatant\", refresh)\n Hooks.on(\"createCombatant\", refresh)\n Hooks.on(\"deleteCombatant\", refresh)\n Hooks.on(\"updateActor\", (_actor, diff) => {\n if (foundry.utils.hasProperty(diff, \"system.initiative\")) refresh()\n })\n Hooks.on(\"deleteCombat\", () => {\n if (CDEWheelApp.#instance?.rendered) CDEWheelApp.#instance.render()\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Post-roll interactive action buttons injected into dice result chat messages.\n * Allows players to pull dice from the Loksyu (as Successes or d\u00E9s-fastes)\n * and allows the GM to spend Tin Ji to intervene.\n *\n * After a draw, the originating roll result message is updated in-place\n * with the new counts, without creating noise.\n */\n\nimport { getLoksyuData, setLoksyuData, getTinjiValue, setTinjiValue } from \"./apps/singletons.js\"\nimport { SYSTEM_ID, WU_XING_CYCLE, ASPECT_LABELS, ASPECT_ICONS } from \"../config/constants.js\"\n\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html\"\n\n/**\n * Inject or refresh post-roll action buttons in the given chat message HTML element.\n * Called from renderChatMessageHTML hook.\n * @param {ChatMessage} message\n * @param {HTMLElement} html - the chat message HTML element (li.chat-message)\n */\nexport function injectRollActions(message, html) {\n const rollCard = html.querySelector(\".cde-roll-result\")\n if (!rollCard) return\n const aspect = rollCard.dataset.aspect\n if (!aspect || !WU_XING_CYCLE[aspect]) return\n refreshRollActions(rollCard, aspect, message)\n}\n\n/**\n * Re-render the action buttons section based on current Loksyu / TinJi state.\n */\nfunction refreshRollActions(rollCard, aspect, message) {\n rollCard.querySelector(\".cde-roll-actions\")?.remove()\n\n const cycle = WU_XING_CYCLE[aspect]\n const fasteAspect = cycle[1]\n\n const loksyu = getLoksyuData()\n const tinji = getTinjiValue()\n\n const successAvail = (loksyu[aspect]?.yin ?? 0) + (loksyu[aspect]?.yang ?? 0)\n const fasteAvail = (loksyu[fasteAspect]?.yin ?? 0) + (loksyu[fasteAspect]?.yang ?? 0)\n const isGM = game.user.isGM\n\n const hasSomething = successAvail > 0 || fasteAvail > 0 || (isGM && tinji > 0)\n if (!hasSomething) return\n\n const aspLabel = game.i18n.localize(ASPECT_LABELS[aspect])\n const fasteLabel = game.i18n.localize(ASPECT_LABELS[fasteAspect])\n\n let btns = \"\"\n\n if (successAvail > 0) {\n btns += ``\n }\n\n if (fasteAvail > 0) {\n btns += ``\n }\n\n if (isGM && tinji > 0) {\n btns += ``\n }\n\n const wrapper = document.createElement(\"div\")\n wrapper.className = \"cde-roll-actions\"\n wrapper.innerHTML = `\n
\n \n ${game.i18n.localize(\"CDE.PostRollActions\")}\n
\n
${btns}
\n `\n rollCard.appendChild(wrapper)\n\n wrapper.addEventListener(\"click\", async ev => {\n const btn = ev.target.closest(\"[data-action]\")\n if (!btn || btn.disabled) return\n const action = btn.dataset.action\n if (action === \"loksyu-success\") {\n await _drawFromLoksyu(message, aspect, \"success\", aspLabel)\n } else if (action === \"loksyu-faste\") {\n await _drawFromLoksyu(message, fasteAspect, \"faste\", fasteLabel)\n } else if (action === \"tinji\") {\n await _spendTinjiPostRoll()\n }\n // Buttons will be re-injected automatically via renderChatMessageHTML\n // after message.update(). For tinji (no message update), refresh manually.\n if (action === \"tinji\") refreshRollActions(rollCard, aspect, message)\n })\n}\n\n/**\n * Pull one die from a given Loksyu aspect slot, update Loksyu settings,\n * and update the originating roll-result message in-place.\n *\n * @param {ChatMessage} message - the roll result chat message to update\n * @param {string} aspect - which Loksyu aspect slot to draw from\n * @param {\"success\"|\"faste\"} type\n * @param {string} aspectLabel - localised aspect name for the notification\n */\nasync function _drawFromLoksyu(message, aspect, type, aspectLabel) {\n const data = getLoksyuData()\n const entry = data[aspect] ?? { yin: 0, yang: 0 }\n const total = entry.yin + entry.yang\n if (total <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.LoksyuEmpty\"))\n return\n }\n\n // Remove 1 die (prefer yang first)\n if (entry.yang > 0) entry.yang--\n else entry.yin--\n data[aspect] = entry\n await setLoksyuData(data)\n\n // Update the roll-result message in-place if it has stored flags\n const flags = message?.flags?.[SYSTEM_ID]\n if (flags?.rollResult && message.isOwner) {\n const updated = foundry.utils.deepClone(flags.rollResult)\n if (type === \"success\") {\n updated.successesdice = (updated.successesdice ?? 0) + 1\n updated.loksyuBonusSuc = (updated.loksyuBonusSuc ?? 0) + 1\n // Recalculate weapon damage if applicable\n if (updated.damageBase) updated.totalDamage = updated.successesdice * updated.damageBase\n } else {\n updated.auspiciousdice = (updated.auspiciousdice ?? 0) + 1\n updated.loksyuBonusFaste = (updated.loksyuBonusFaste ?? 0) + 1\n }\n const newHtml = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, updated)\n await message.update({\n content: newHtml,\n [`flags.${SYSTEM_ID}.rollResult`]: updated,\n })\n // renderChatMessageHTML hook fires automatically \u2192 buttons re-injected\n }\n\n const remain = entry.yin + entry.yang\n const typeLabel = type === \"success\"\n ? game.i18n.localize(\"CDE.Successes\")\n : game.i18n.localize(\"CDE.AuspiciousDie\")\n\n ChatMessage.create({\n user: game.user.id,\n content: `
\n
\n \"${aspectLabel}\"/\n ${game.user.name}\n ${game.i18n.localize(\"CDE.LoksyuDrawsA\")}\n ${typeLabel}\n ${game.i18n.localize(\"CDE.LoksyuFromAspect\")} ${aspectLabel}\n
\n
\n \n ${game.i18n.localize(\"CDE.Loksyu\")} ${aspectLabel} : \n ${remain} ${game.i18n.localize(\"CDE.LoksyuRemaining\")}\n
\n
`,\n })\n}\n\n/**\n * Spend 1 Tin Ji point (GM only) and post a notification.\n */\nasync function _spendTinjiPostRoll() {\n if (!game.user.isGM) return\n const current = getTinjiValue()\n if (current <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.TinjiEmpty\"))\n return\n }\n await setTinjiValue(current - 1)\n ChatMessage.create({\n user: game.user.id,\n content: `
\n \u5929\n \n ${game.user.name} ${game.i18n.localize(\"CDE.TinjiSpent\").replace(\"{name}\", game.user.name)}\n \n (${current - 1} ${game.i18n.localize(\"CDE.TinjiRemaining\")})\n
`,\n })\n}\n\n/**\n * Refresh all visible roll-result buttons when Loksyu or TinJi settings change.\n * Wired up via Hooks.on(\"updateSetting\", ...) in system.js.\n */\nexport function refreshAllRollActions() {\n document.querySelectorAll(\".chat-message .cde-roll-result[data-aspect]\").forEach(card => {\n const aspect = card.dataset.aspect\n if (!aspect || !WU_XING_CYCLE[aspect]) return\n // Find the ChatMessage document from the ancestor element's data-message-id\n const msgEl = card.closest(\"[data-message-id]\")\n const msgId = msgEl?.dataset?.messageId\n const message = msgId ? game.messages.get(msgId) : null\n refreshRollActions(card, aspect, message)\n })\n}\n\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { ACTOR_TYPES, ITEM_TYPES, MAGICS, SUBTYPES, SYSTEM_ID } from \"./config/constants.js\"\nimport { registerSettings, migrateIfNeeded } from \"./config/settings.js\"\nimport { preLocalizeConfig } from \"./config/localize.js\"\nimport { configureRuntime } from \"./config/runtime.js\"\nimport { CharacterDataModel, NpcDataModel } from \"./data/actors/index.js\"\nimport { EquipmentDataModel, KungfuDataModel, SpellDataModel, SupernaturalDataModel, WeaponDataModel, ArmorDataModel, SanheiDataModel, IngredientDataModel } from \"./data/items/index.js\"\nimport { CDEMessage } from \"./documents/chat-message.js\"\nimport { CDEActor } from \"./documents/actor.js\"\nimport { CDEItem } from \"./documents/item.js\"\nimport { registerDice } from \"./ui/dice.js\"\nimport { registerHandlebarsHelpers } from \"./ui/helpers.js\"\nimport { preloadPartials } from \"./ui/templates.js\"\nimport { CDECharacterSheet, CDENpcSheet } from \"./ui/sheets/actors/index.js\"\nimport { CDEItemSheet, CDEKungfuSheet, CDESpellSheet, CDESupernaturalSheet, CDEWeaponSheet, CDEArmorSheet, CDESanheiSheet, CDEIngredientSheet } from \"./ui/sheets/items/index.js\"\nimport { CDELoksyuApp } from \"./ui/apps/loksyu-app.js\"\nimport { CDETinjiApp } from \"./ui/apps/tinji-app.js\"\nimport { CDEWheelApp } from \"./ui/apps/wheel-app.js\"\nimport { injectRollActions, refreshAllRollActions } from \"./ui/roll-actions.js\"\nimport { CDECombat } from \"./documents/combat.js\"\n\nHooks.once(\"i18nInit\", preLocalizeConfig)\n\nHooks.once(\"init\", async () => {\n console.info(`CHRONIQUESDELETRANGE | Initializing ${SYSTEM_ID}`)\n\n registerSettings()\n\n game.system.CONST = { MAGICS, SUBTYPES }\n\n // Expose standalone apps globally for macros\n game.cde = { CDELoksyuApp, CDETinjiApp, CDEWheelApp }\n\n CONFIG.Combat.documentClass = CDECombat\n\n CONFIG.Actor.dataModels = {\n [ACTOR_TYPES.character]: CharacterDataModel,\n [ACTOR_TYPES.npc]: NpcDataModel,\n }\n CONFIG.Item.dataModels = {\n [ITEM_TYPES.item]: EquipmentDataModel,\n [ITEM_TYPES.kungfu]: KungfuDataModel,\n [ITEM_TYPES.spell]: SpellDataModel,\n [ITEM_TYPES.supernatural]: SupernaturalDataModel,\n [ITEM_TYPES.weapon]: WeaponDataModel,\n [ITEM_TYPES.armor]: ArmorDataModel,\n [ITEM_TYPES.sanhei]: SanheiDataModel,\n [ITEM_TYPES.ingredient]: IngredientDataModel,\n }\n\n CONFIG.Actor.documentClass = CDEActor\n CONFIG.Item.documentClass = CDEItem\n CONFIG.ChatMessage.documentClass = CDEMessage\n\n configureRuntime()\n\n foundry.applications.apps.DocumentSheetConfig.unregisterSheet(Actor, \"core\", foundry.appv1.sheets.ActorSheet)\n foundry.applications.apps.DocumentSheetConfig.unregisterSheet(Item, \"core\", foundry.appv1.sheets.ItemSheet)\n\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, SYSTEM_ID, CDECharacterSheet, {\n types: [ACTOR_TYPES.character],\n makeDefault: true,\n label: \"CDE Character Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, SYSTEM_ID, CDENpcSheet, {\n types: [ACTOR_TYPES.npc],\n makeDefault: true,\n label: \"CDE NPC Sheet (V2)\",\n })\n\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEItemSheet, {\n types: [ITEM_TYPES.item],\n makeDefault: true,\n label: \"CDE Item Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEKungfuSheet, {\n types: [ITEM_TYPES.kungfu],\n makeDefault: true,\n label: \"CDE KungFu Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESpellSheet, {\n types: [ITEM_TYPES.spell],\n makeDefault: true,\n label: \"CDE Spell Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESupernaturalSheet, {\n types: [ITEM_TYPES.supernatural],\n makeDefault: true,\n label: \"CDE Supernatural Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEWeaponSheet, {\n types: [ITEM_TYPES.weapon],\n makeDefault: true,\n label: \"CDE Weapon Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEArmorSheet, {\n types: [ITEM_TYPES.armor],\n makeDefault: true,\n label: \"CDE Armor Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESanheiSheet, {\n types: [ITEM_TYPES.sanhei],\n makeDefault: true,\n label: \"CDE Sanhei Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEIngredientSheet, {\n types: [ITEM_TYPES.ingredient],\n makeDefault: true,\n label: \"CDE Ingredient Sheet (V2)\",\n })\n\n await preloadPartials()\n registerHandlebarsHelpers()\n registerDice()\n\n console.info(`CHRONIQUESDELETRANGE | Initialized`)\n})\n\nHooks.once(\"ready\", async () => {\n await migrateIfNeeded()\n CDEWheelApp.registerHooks()\n})\n\n/** Add Loksyu + Tin Ji quick-access buttons to the chat panel (FoundryVTT v13) */\nHooks.on(\"renderChatLog\", (_app, html) => {\n const el = html instanceof HTMLElement ? html : (html[0] ?? html)\n if (!el?.querySelector) return\n\n // Avoid double-injection on re-renders\n if (el.querySelector(\".cde-chat-app-buttons\")) return\n\n const wrapper = document.createElement(\"div\")\n wrapper.classList.add(\"cde-chat-app-buttons\")\n wrapper.innerHTML = `\n \n \n \n `\n\n // Use event delegation to avoid being swallowed by Foundry's own handlers\n wrapper.addEventListener(\"click\", (ev) => {\n if (ev.target.closest(\".cde-chat-btn--loksyu\")) CDELoksyuApp.open()\n if (ev.target.closest(\".cde-chat-btn--tinji\")) CDETinjiApp.open()\n if (ev.target.closest(\".cde-chat-btn--wheel\")) CDEWheelApp.open()\n })\n\n // Insert before the chat form \u2014 works on v12 and v13\n const anchor = el.querySelector(\".chat-form\")\n ?? el.querySelector(\".chat-message-form\")\n ?? el.querySelector(\"form\")\n if (anchor) anchor.parentElement.insertBefore(wrapper, anchor)\n else el.appendChild(wrapper)\n})\n\n/** Inject Loksyu / TinJi action buttons into roll-result chat messages */\nHooks.on(\"renderChatMessageHTML\", (message, html) => {\n injectRollActions(message, html)\n})\n\n/** Refresh all visible roll-result buttons whenever Loksyu or TinJi settings change */\nHooks.on(\"updateSetting\", setting => {\n if (!setting.key) return\n if (setting.key.includes(\"loksyuData\") || setting.key.includes(\"tinjiData\")) {\n refreshAllRollActions()\n }\n})\n\n/**\n * When an actor's initiative changes (via +/- buttons on the sheet),\n * sync the corresponding combatant in the active combat.\n */\nHooks.on(\"updateActor\", (actor, diff) => {\n if (!foundry.utils.hasProperty(diff, \"system.initiative\")) return\n if (!game.combat) return\n const initiative = actor.system.initiative\n const combatant = game.combat.combatants.find(c => c.actor?.id === actor.id)\n if (combatant && combatant.initiative !== initiative) {\n combatant.update({ initiative }).catch(() => {})\n }\n})\n\n/**\n * When a combatant's initiative changes (via wheel action buttons),\n * sync the actor's system.initiative to match.\n * Uses setTimeout to defer until after Foundry's update chain resolves,\n * avoiding concurrent #recordPreviousState errors on the combat document.\n */\nHooks.on(\"updateCombatant\", (combatant, diff) => {\n if (!(\"initiative\" in diff)) return\n const initiative = combatant.initiative\n if (initiative == null) return\n setTimeout(() => {\n const actor = combatant.actor\n if (actor && actor.system?.initiative !== initiative) {\n actor.update({ \"system.initiative\": initiative }).catch(() => {})\n }\n }, 0)\n})\n"], - "mappings": "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", + "sources": ["../src/config/constants.js", "../src/migration/migrator.js", "../src/ui/apps/migration-app.js", "../src/config/settings.js", "../src/config/localize.js", "../src/config/runtime.js", "../src/data/actors/character.js", "../src/data/actors/npc.js", "../src/data/items/item.js", "../src/data/items/kungfu.js", "../src/data/items/spell.js", "../src/data/items/supernatural.js", "../src/data/items/weapon.js", "../src/data/items/armor.js", "../src/data/items/sanhei.js", "../src/data/items/ingredient.js", "../src/documents/chat-message.js", "../src/documents/actor.js", "../src/documents/item.js", "../src/ui/dice.js", "../src/ui/helpers.js", "../src/ui/templates.js", "../src/ui/initiative.js", "../src/ui/apps/singletons.js", "../src/ui/rolling.js", "../src/ui/sheets/actors/base.js", "../src/ui/sheets/actors/character.js", "../src/ui/sheets/actors/npc.js", "../src/ui/sheets/items/base.js", "../src/ui/sheets/items/item.js", "../src/ui/sheets/items/kungfu.js", "../src/ui/sheets/items/spell.js", "../src/ui/sheets/items/supernatural.js", "../src/ui/sheets/items/weapon.js", "../src/ui/sheets/items/armor.js", "../src/ui/sheets/items/sanhei.js", "../src/ui/sheets/items/ingredient.js", "../src/ui/apps/loksyu-app.js", "../src/ui/apps/tinji-app.js", "../src/documents/combat.js", "../src/ui/apps/wheel-app.js", "../src/ui/roll-actions.js", "../src/ui/apps/welcome.js", "../src/system.js"], + "sourcesContent": ["/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport const SYSTEM_ID = \"fvtt-chroniques-de-l-etrange\"\n\nexport const ACTOR_TYPES = {\n character: \"character\",\n npc: \"npc\",\n}\n\nexport const ITEM_TYPES = {\n item: \"item\",\n kungfu: \"kungfu\",\n spell: \"spell\",\n supernatural: \"supernatural\",\n weapon: \"weapon\",\n armor: \"armor\",\n sanhei: \"sanhei\",\n ingredient: \"ingredient\",\n}\n\nexport const SUBTYPES = {\n weapon: { id: \"weapon\", label: \"CDE.Weapon\" },\n armor: { id: \"armor\", label: \"CDE.Armor\" },\n sanhei: { id: \"sanhei\", label: \"CDE.Sanhei\" },\n other: { id: \"other\", label: \"CDE.Other\" },\n}\n\nexport const MAGICS = {\n internalcinnabar: {\n id: \"internalcinnabar\",\n background: \"linear-grey\",\n label: \"CDE.InternalCinnabar\",\n aspectlabel: \"CDE.Metal\",\n speciality: {\n essence: { label: \"CDE.Essence\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n mind: { label: \"CDE.Mind\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n purification: { label: \"CDE.Purification\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n manipulation: { label: \"CDE.Manipulation\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n aura: { label: \"CDE.Aura\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n alchemy: {\n id: \"alchemy\",\n background: \"linear-blue\",\n label: \"CDE.Alchemy\",\n aspectlabel: \"CDE.Water\",\n speciality: {\n acupuncture: { label: \"CDE.Acupuncture\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n elixirs: { label: \"CDE.Elixirs\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n poisons: { label: \"CDE.Poisons\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n arsenal: { label: \"CDE.Arsenal\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n potions: { label: \"CDE.Potions\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n masteryoftheway: {\n id: \"masteryoftheway\",\n background: \"linear-brown\",\n label: \"CDE.MasteryOfTheWay\",\n aspectlabel: \"CDE.Earth\",\n speciality: {\n curse: { label: \"CDE.Curse\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n transfiguration: { label: \"CDE.Transfiguration\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n necromancy: { label: \"CDE.Necromancy\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n climatecontrol: { label: \"CDE.ClimateControl\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n goldenmagic: { label: \"CDE.GoldenMagic\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n exorcism: {\n id: \"exorcism\",\n background: \"linear-red\",\n label: \"CDE.Exorcism\",\n aspectlabel: \"CDE.Fire\",\n speciality: {\n invocation: { label: \"CDE.Invocation\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n tracking: { label: \"CDE.Tracking\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n protection: { label: \"CDE.Protection\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n punishment: { label: \"CDE.Punishment\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n domination: { label: \"CDE.Domination\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n geomancy: {\n id: \"geomancy\",\n background: \"linear-green\",\n label: \"CDE.Geomancy\",\n aspectlabel: \"CDE.Wood\",\n speciality: {\n neutralization: { label: \"CDE.Neutralization\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n divination: { label: \"CDE.Divination\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n earthlyprayer: { label: \"CDE.EarthlyPrayer\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n heavenlyprayer: { label: \"CDE.HeavenlyPrayer\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n fungseoi: { label: \"CDE.Fungseoi\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n}\n\n/** Map aspect name \u2192 i18n label key */\nexport const ASPECT_LABELS = {\n metal: \"CDE.Metal\",\n water: \"CDE.Water\",\n earth: \"CDE.Earth\",\n fire: \"CDE.Fire\",\n wood: \"CDE.Wood\",\n}\n\n/** Map aspect name \u2192 image path */\nexport const ASPECT_ICONS = {\n metal: \"systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n water: \"systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n earth: \"systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n fire: \"systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n wood: \"systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n}\n\n/** Map aspect name \u2192 die face pair [yin, yang] (face=10 stored as 0) */\nexport const ASPECT_FACES = {\n metal: [3, 8],\n water: [1, 6],\n earth: [0, 5], // 0 = face \"10\"\n fire: [2, 7],\n wood: [4, 9],\n}\n\n/** Ordered aspect names by index (metal=0, water=1, earth=2, fire=3, wood=4) */\nexport const ASPECT_NAMES = [\"metal\", \"water\", \"earth\", \"fire\", \"wood\"]\n\n/**\n * Wu Xing generating/overcoming cycle.\n * For each active aspect, the five result categories in order:\n * [successes, auspicious, noxious, loksyu, tinji]\n */\nexport const WU_XING_CYCLE = {\n wood: [\"wood\", \"fire\", \"water\", \"earth\", \"metal\"],\n fire: [\"fire\", \"earth\", \"wood\", \"metal\", \"water\"],\n earth: [\"earth\", \"metal\", \"fire\", \"water\", \"wood\"],\n metal: [\"metal\", \"water\", \"earth\", \"wood\", \"fire\"],\n water: [\"water\", \"wood\", \"metal\", \"fire\", \"earth\"],\n}\n\nexport const TEMPLATE_PARTIALS = [\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-skills.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-magics.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-nghang.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-treasures.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-items.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-kungfus.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-spells.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-supernaturals.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-spells.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-kungfus.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-items.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-loksyu-app.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-tinji-app.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html\",\n]\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Migrates actor JSON from the legacy CDE system to the current system format.\n *\n * This module is pure logic \u2014 it does not interact with Foundry APIs directly.\n * All transformation is done in-memory; the caller is responsible for creating\n * Foundry documents from the returned data.\n */\n\n// \u2500\u2500 Element label \u2192 key \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ELEMENT_LABEL_TO_KEY = {\n \"m\u00E9tal\": \"metal\",\n \"metal\": \"metal\",\n \"eau\": \"eau\",\n \"terre\": \"terre\",\n \"feu\": \"feu\",\n \"bois\": \"bois\",\n}\n\n/** Normalise a French element label to its system key (e.g. \"M\u00E9tal\" \u2192 \"metal\"). */\nfunction elementKey(label = \"\") {\n return ELEMENT_LABEL_TO_KEY[label.toLowerCase().trim()] ?? \"metal\"\n}\n\n// \u2500\u2500 Hei polarity label \u2192 key \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction heiKey(label = \"\") {\n const l = label.toLowerCase().trim()\n if (l === \"yin/yang\" || l === \"yinyang\") return \"yinyang\"\n if (l === \"yang\") return \"yang\"\n return \"yin\"\n}\n\n// \u2500\u2500 Spell discipline inference from speciality name \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Maps French speciality labels (lowercase, accents stripped) \u2192 school key. */\nconst SPECIALITY_TO_DISCIPLINE = {\n // internalcinnabar\n \"essence\": \"internalcinnabar\",\n \"esprit\": \"internalcinnabar\",\n \"mind\": \"internalcinnabar\",\n \"purification\": \"internalcinnabar\",\n \"manipulation\": \"internalcinnabar\",\n \"aura\": \"internalcinnabar\",\n // alchemy\n \"acupuncture\": \"alchemy\",\n \"\u00E9lixirs\": \"alchemy\",\n \"elixirs\": \"alchemy\",\n \"poisons\": \"alchemy\",\n \"arsenal\": \"alchemy\",\n \"potions\": \"alchemy\",\n // masteryoftheway\n \"mal\u00E9diction\": \"masteryoftheway\",\n \"malediction\": \"masteryoftheway\",\n \"transfiguration\": \"masteryoftheway\",\n \"n\u00E9cromancie\": \"masteryoftheway\",\n \"necromancie\": \"masteryoftheway\",\n \"contr\u00F4le climatique\": \"masteryoftheway\",\n \"controle climatique\": \"masteryoftheway\",\n \"magie d'or\": \"masteryoftheway\",\n \"magie dor\": \"masteryoftheway\",\n // exorcism\n \"invocation\": \"exorcism\",\n \"pistage\": \"exorcism\",\n \"tra\u00E7age\": \"exorcism\",\n \"tracage\": \"exorcism\",\n \"protection\": \"exorcism\",\n \"ch\u00E2timent\": \"exorcism\",\n \"chatiment\": \"exorcism\",\n \"domination\": \"exorcism\",\n // geomancy\n \"neutralisation\": \"geomancy\",\n \"divination\": \"geomancy\",\n \"pri\u00E8re terrestre\": \"geomancy\",\n \"priere terrestre\": \"geomancy\",\n \"pri\u00E8re c\u00E9leste\": \"geomancy\",\n \"priere celeste\": \"geomancy\",\n \"g\u00E9omancie\": \"geomancy\",\n \"geomancie\": \"geomancy\",\n \"feng shui\": \"geomancy\",\n \"fungseoi\": \"geomancy\",\n}\n\n/**\n * Attempt to infer the magic school (discipline) from a spell's speciality name.\n * Falls back to scanning the item name for school keywords if needed.\n */\nfunction inferDiscipline(specialityName = \"\", itemName = \"\") {\n const key = specialityName.toLowerCase().trim()\n if (SPECIALITY_TO_DISCIPLINE[key]) return SPECIALITY_TO_DISCIPLINE[key]\n\n // Fuzzy fallback: check item name for school markers\n const name = itemName.toLowerCase()\n if (name.includes(\"exorcis\")) return \"exorcism\"\n if (name.includes(\"g\u00E9omanci\") || name.includes(\"geomanci\")) return \"geomancy\"\n if (name.includes(\"alchimi\")) return \"alchemy\"\n if (name.includes(\"cinnabre\") || name.includes(\"interne\")) return \"internalcinnabar\"\n if (name.includes(\"ma\u00EEtrise\") || name.includes(\"maitrise\") || name.includes(\"tao\")) return \"masteryoftheway\"\n\n return \"internalcinnabar\"\n}\n\n// \u2500\u2500 KungFu activation mapping \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction mapActivation(oldActivation = \"\") {\n const s = oldActivation.toLowerCase()\n if (s.includes(\"inflig\u00E9s\") || s.includes(\"infliges\")) return \"damage-inflicted\"\n if (s.includes(\"re\u00E7us\") || s.includes(\"recus\")) return \"damage-received\"\n if (s.includes(\"r\u00E9action\") || s.includes(\"reaction\")) return \"reaction\"\n if (s.includes(\"d\u00E9s-fastes\") || s.includes(\"des-fastes\") || s.includes(\"fastes\")) return \"dice\"\n if (s.includes(\"aide\")) return \"action-aid\"\n if (s.includes(\"attaque\") && s.includes(\"d\u00E9fense\")) return \"action-attack-defense\"\n if (s.includes(\"attaque\") && s.includes(\"defense\")) return \"action-attack-defense\"\n if (s.includes(\"attaque\")) return \"action-attack\"\n if (s.includes(\"d\u00E9fense\") || s.includes(\"defense\")) return \"action-defense\"\n return \"action-attack\"\n}\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst DEFAULT_ACTOR_IMG = \"icons/svg/mystery-man.svg\"\nconst DEFAULT_ITEM_IMG = \"icons/svg/item-bag.svg\"\n\n// \u2500\u2500 Item migration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction migrateEquipmentItem(oldItem) {\n const s = oldItem.system ?? {}\n return {\n name: oldItem.name,\n type: \"item\",\n img: oldItem.img || DEFAULT_ITEM_IMG,\n system: {\n reference: s.reference ?? \"\",\n description: s.description ?? \"\",\n quantity: Number(s.quantity ?? 1),\n weight: Number(s.weight ?? 0),\n notes: s.notes ?? \"\",\n },\n }\n}\n\nfunction migrateKungfuItem(oldItem) {\n const s = oldItem.system ?? {}\n const techs = s.techniques ?? {}\n\n const migratedTechs = {}\n for (const key of [\"technique1\", \"technique2\", \"technique3\"]) {\n const t = techs[key] ?? {}\n migratedTechs[key] = {\n check: Boolean(t.check),\n name: t.name ?? \"\",\n activation: mapActivation(t.activation ?? \"\"),\n technique: t.technique ?? \"\",\n }\n }\n\n return {\n name: oldItem.name,\n type: \"kungfu\",\n img: oldItem.img || DEFAULT_ITEM_IMG,\n system: {\n reference: s.reference ?? \"\",\n description: s.description ?? \"\",\n orientation: s.orientation || \"yin\",\n aspect: s.aspect || \"metal\",\n skill: s.skill || \"kungfu\",\n speciality: s.speciality ?? \"\",\n style: s.style ?? \"\",\n techniques: migratedTechs,\n notes: s.notes ?? \"\",\n },\n }\n}\n\nfunction migrateSpellItem(oldItem) {\n const s = oldItem.system ?? {}\n return {\n name: oldItem.name,\n type: \"spell\",\n img: oldItem.img || DEFAULT_ITEM_IMG,\n system: {\n reference: s.reference ?? \"\",\n description: s.description ?? \"\",\n specialityname: s.specialityname ?? \"\",\n associatedelement: elementKey(s.associatedelement ?? \"\"),\n heiType: heiKey(s.hei ?? \"\"),\n heiCost: Number(s.heiCost ?? 0),\n difficulty: Number(s.difficulty ?? 0),\n realizationtimeritual: s.realizationtimeritual ?? \"\",\n realizationtimeaccelerated: s.realizationtimeaccelerated ?? \"\",\n flashback: s.flashback ?? \"\",\n components: s.components ?? \"\",\n effects: s.effects ?? \"\",\n examples: s.examples ?? \"\",\n notes: s.notes ?? \"\",\n discipline: inferDiscipline(s.specialityname ?? \"\", oldItem.name ?? \"\"),\n },\n }\n}\n\nfunction migrateSupernaturalItem(oldItem) {\n const s = oldItem.system ?? {}\n // Old system stored a nested `supernatural: { reference }` \u2014 prefer that reference if top-level is empty\n const nestedRef = s.supernatural?.reference ?? \"\"\n return {\n name: oldItem.name,\n type: \"supernatural\",\n img: oldItem.img || DEFAULT_ITEM_IMG,\n system: {\n reference: s.reference || nestedRef,\n description: s.description ?? \"\",\n notes: s.notes ?? \"\",\n heiType: \"yin\",\n heiCost: 0,\n trigger: \"\",\n effects: \"\",\n },\n }\n}\n\nfunction migrateItem(oldItem) {\n switch (oldItem.type) {\n case \"item\": return migrateEquipmentItem(oldItem)\n case \"kungfu\": return migrateKungfuItem(oldItem)\n case \"spell\": return migrateSpellItem(oldItem)\n case \"supernatural\": return migrateSupernaturalItem(oldItem)\n default:\n // Unknown item type: keep as generic equipment\n return migrateEquipmentItem({ ...oldItem, type: \"item\" })\n }\n}\n\n// \u2500\u2500 Actor migration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction migrateCharacter(old) {\n const s = old.system ?? {}\n\n // aspects: keep only { chinese, label, value }\n const aspect = {}\n for (const [k, v] of Object.entries(s.aspect ?? {})) {\n aspect[k] = { chinese: v.chinese ?? \"\", label: v.label ?? \"\", value: Number(v.value ?? 0) }\n }\n\n // skills: keep { label, specialities, value }\n const skills = {}\n for (const [k, v] of Object.entries(s.skills ?? {})) {\n skills[k] = { label: v.label ?? \"\", specialities: v.specialities ?? \"\", value: Number(v.value ?? 0) }\n }\n\n // resources: keep { label, specialities, value, debt }\n const resources = {}\n for (const [k, v] of Object.entries(s.resources ?? {})) {\n resources[k] = { label: v.label ?? \"\", specialities: v.specialities ?? \"\", value: Number(v.value ?? 0), debt: Boolean(v.debt) }\n }\n\n // components: keep { value }\n const component = {}\n for (const [k, v] of Object.entries(s.component ?? {})) {\n component[k] = { value: v.value ?? \"\" }\n }\n\n // magics: keep { visible, value, speciality: { [key]: { check } } }\n const MAGIC_SPECIALITIES = {\n internalcinnabar: [\"essence\", \"mind\", \"purification\", \"manipulation\", \"aura\"],\n alchemy: [\"acupuncture\", \"elixirs\", \"poisons\", \"arsenal\", \"potions\"],\n masteryoftheway: [\"curse\", \"transfiguration\", \"necromancy\", \"climatecontrol\", \"goldenmagic\"],\n exorcism: [\"invocation\", \"tracking\", \"protection\", \"punishment\", \"domination\"],\n geomancy: [\"neutralization\", \"divination\", \"earthlyprayer\", \"heavenlyprayer\", \"fungseoi\"],\n }\n const magics = {}\n for (const [school, specs] of Object.entries(MAGIC_SPECIALITIES)) {\n const om = s.magics?.[school] ?? {}\n const speciality = {}\n for (const spec of specs) {\n speciality[spec] = { check: Boolean(om.speciality?.[spec]?.check) }\n }\n magics[school] = { visible: Boolean(om.visible), value: Number(om.value ?? 0), speciality }\n }\n\n // threetreasures: strip `min` from heiyang/heiyin; keep dicelevel as-is\n const tt = s.threetreasures ?? {}\n const threetreasures = {\n heiyang: { value: Number(tt.heiyang?.value ?? 0), max: Number(tt.heiyang?.max ?? 0) },\n heiyin: { value: Number(tt.heiyin?.value ?? 0), max: Number(tt.heiyin?.max ?? 0) },\n dicelevel: {\n level0d: {\n san: { value: Number(tt.dicelevel?.level0d?.san?.value ?? 0), max: Number(tt.dicelevel?.level0d?.san?.max ?? 0) },\n zing: { value: Number(tt.dicelevel?.level0d?.zing?.value ?? 0), max: Number(tt.dicelevel?.level0d?.zing?.max ?? 0) },\n },\n level1d: {\n san: { value: Number(tt.dicelevel?.level1d?.san?.value ?? 0), max: Number(tt.dicelevel?.level1d?.san?.max ?? 0) },\n zing: { value: Number(tt.dicelevel?.level1d?.zing?.value ?? 0), max: Number(tt.dicelevel?.level1d?.zing?.max ?? 0) },\n },\n level2d: {\n san: { value: Number(tt.dicelevel?.level2d?.san?.value ?? 0), max: Number(tt.dicelevel?.level2d?.san?.max ?? 0) },\n zing: { value: Number(tt.dicelevel?.level2d?.zing?.value ?? 0), max: Number(tt.dicelevel?.level2d?.zing?.max ?? 0) },\n },\n },\n }\n\n // biography (old separate field) merged into description\n const description = s.description || s.biography || \"\"\n\n return {\n name: old.name,\n type: \"character\",\n img: old.img || DEFAULT_ACTOR_IMG,\n system: {\n concept: s.concept ?? \"\",\n guardian: parseInt(s.guardian ?? \"0\") || 0,\n initiative: Number(s.initiative ?? 1),\n anti_initiative: Number(s.anti_initiative ?? 24),\n description,\n aspect,\n skills,\n resources,\n component,\n magics,\n threetreasures,\n experience: {\n value: Number(s.experience?.value ?? 0),\n max: Number(s.experience?.max ?? 0),\n min: Number(s.experience?.min ?? 0),\n },\n },\n items: (old.items ?? []).map(migrateItem),\n }\n}\n\nfunction migrateNpc(old) {\n const s = old.system ?? {}\n\n const aptitudes = {}\n for (const [k, v] of Object.entries(s.aptitudes ?? {})) {\n aptitudes[k] = { value: Number(v.value ?? 0), speciality: v.speciality ?? \"\" }\n }\n\n return {\n name: old.name,\n type: \"npc\",\n img: old.img || DEFAULT_ACTOR_IMG,\n system: {\n type: s.type ?? \"\",\n // Old system had separate `levelofthreat`/`powerofnuisance` as numbers\n // and string copies `threat`/`nuisance` \u2014 use the numeric fields\n threat: Number(s.levelofthreat ?? s.threat ?? 0),\n nuisance: Number(s.powerofnuisance ?? s.nuisance ?? 0),\n initiative: Number(s.initiative ?? 1),\n anti_initiative: Number(s.anti_initiative ?? 24),\n aptitudes,\n vitality: {\n value: Number(s.vitality?.value ?? 0),\n calcul: Number(s.vitality?.calcul ?? 0),\n note: s.vitality?.note ?? \"\",\n },\n hei: {\n value: Number(s.hei?.value ?? 0),\n calcul: Number(s.hei?.calcul ?? 0),\n note: s.hei?.note ?? \"\",\n },\n description: s.description ?? \"\",\n },\n items: (old.items ?? []).map(migrateItem),\n }\n}\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Migrate a single legacy actor JSON to the current system format.\n *\n * @param {object} oldJson Parsed JSON from the old system export\n * @returns {{ name: string, type: string, img: string, system: object, items: object[] }}\n * @throws {Error} if the actor type is unrecognised\n */\nexport function migrateActor(oldJson) {\n switch (oldJson.type) {\n case \"character\": return migrateCharacter(oldJson)\n case \"npc\": return migrateNpc(oldJson)\n default:\n throw new Error(`Unknown actor type \"${oldJson.type}\" in \"${oldJson.name}\"`)\n }\n}\n\n/**\n * Parse one or more legacy JSON strings and return migrated actor data.\n * Accepts a single actor object or an array of actor objects in one file.\n *\n * @param {string} jsonText Raw JSON text from a file\n * @returns {Array<{ name, type, img, system, items }>}\n */\nexport function parseLegacyJson(jsonText) {\n const parsed = JSON.parse(jsonText)\n if (typeof parsed !== \"object\" || parsed === null) {\n throw new Error(\"Le fichier JSON doit contenir un objet acteur ou un tableau d'acteurs\")\n }\n const actors = Array.isArray(parsed) ? parsed : [parsed]\n return actors.map(migrateActor)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { parseLegacyJson } from \"../../migration/migrator.js\"\n\nconst MIGRATION_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-migration-app.html\"\n\n/**\n * Dialog for importing legacy CDE actor JSON files into the current system.\n *\n * Accessible via the System Settings menu (registerMenu).\n * Supports multi-file selection and shows a preview table before importing.\n */\nexport class CDEMigrationApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-migration-app\",\n classes: [\"cde-migration-app\"],\n tag: \"div\",\n window: {\n title: \"CDE.MigrationTitle\",\n icon: \"fas fa-file-import\",\n resizable: false,\n },\n position: { width: 560, height: \"auto\" },\n actions: {\n clearFiles: CDEMigrationApp.#clearFiles,\n doImport: CDEMigrationApp.#doImport,\n },\n }\n\n static PARTS = {\n form: { template: MIGRATION_TEMPLATE },\n }\n\n /** @type {Array<{name: string, type: string, img: string, system: object, items: object[], _srcFile: string}>} */\n #pending = []\n\n /** @type {string[]} - error messages per file */\n #errors = []\n\n async _prepareContext(options) {\n return {\n pending: this.#pending,\n errors: this.#errors,\n hasPending: this.#pending.length > 0,\n hasErrors: this.#errors.length > 0,\n count: this.#pending.length,\n }\n }\n\n /** After render, wire up the file input. */\n _onRender(context, options) {\n super._onRender(context, options)\n const input = this.element.querySelector(\".cde-migration-file-input\")\n input?.addEventListener(\"change\", this.#onFileChange.bind(this))\n\n const dropZone = this.element.querySelector(\".cde-migration-drop-zone\")\n if (dropZone) {\n dropZone.addEventListener(\"dragover\", (e) => { e.preventDefault(); dropZone.classList.add(\"is-dragover\") })\n dropZone.addEventListener(\"dragleave\", () => dropZone.classList.remove(\"is-dragover\"))\n dropZone.addEventListener(\"drop\", (e) => {\n e.preventDefault()\n dropZone.classList.remove(\"is-dragover\")\n this.#processFiles(Array.from(e.dataTransfer.files))\n })\n }\n }\n\n async #onFileChange(event) {\n const files = Array.from(event.target.files ?? [])\n event.target.value = \"\"\n await this.#processFiles(files)\n }\n\n async #processFiles(files) {\n for (const file of files) {\n if (!file.name.endsWith(\".json\")) {\n this.#errors.push(game.i18n.format(\"CDE.MigrationErrorNotJson\", { file: file.name }))\n continue\n }\n try {\n const text = await file.text()\n const actors = parseLegacyJson(text)\n for (const actor of actors) {\n actor._srcFile = file.name\n // Avoid duplicates by name\n if (!this.#pending.some(p => p.name === actor.name)) {\n this.#pending.push(actor)\n }\n }\n } catch (err) {\n this.#errors.push(game.i18n.format(\"CDE.MigrationErrorParse\", { file: file.name, error: err.message }))\n }\n }\n this.render()\n }\n\n static async #clearFiles() {\n this.#pending = []\n this.#errors = []\n this.render()\n }\n\n static async #doImport() {\n if (!this.#pending.length) return\n\n const created = []\n const failed = []\n\n for (const data of this.#pending) {\n try {\n const { _srcFile, ...actorData } = data\n const actor = await Actor.create(actorData)\n created.push(actor.name)\n } catch (err) {\n failed.push(`${data.name}: ${err.message}`)\n console.error(`CHRONIQUESDELETRANGE | Migration failed for \"${data.name}\":`, err)\n }\n }\n\n this.#pending = []\n this.#errors = failed\n this.render()\n\n if (created.length) {\n ui.notifications.info(\n game.i18n.format(\"CDE.MigrationSuccess\", { count: created.length, names: created.join(\", \") })\n )\n }\n if (failed.length) {\n ui.notifications.warn(\n game.i18n.format(\"CDE.MigrationPartialError\", { count: failed.length })\n )\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { SYSTEM_ID } from \"./constants.js\"\nimport { CDEMigrationApp } from \"../ui/apps/migration-app.js\"\n\n/**\n * Register all world/client settings for the system.\n * Called during the \"init\" hook before sheets and data-models are set up.\n */\nexport function registerSettings() {\n game.settings.registerMenu(SYSTEM_ID, \"migrationTool\", {\n name: \"CDE.MigrationTitle\",\n label: \"CDE.MigrationMenuLabel\",\n hint: \"CDE.MigrationMenuHint\",\n icon: \"fas fa-file-import\",\n type: CDEMigrationApp,\n restricted: true,\n })\n\n game.settings.register(SYSTEM_ID, \"loksyuData\", {\n scope: \"world\",\n config: false,\n type: Object,\n default: {\n wood: { yin: 0, yang: 0 },\n fire: { yin: 0, yang: 0 },\n earth: { yin: 0, yang: 0 },\n metal: { yin: 0, yang: 0 },\n water: { yin: 0, yang: 0 },\n },\n })\n\n game.settings.register(SYSTEM_ID, \"tinjiData\", {\n scope: \"world\",\n config: false,\n type: Number,\n default: 0,\n })\n\n game.settings.register(SYSTEM_ID, \"welcomeSceneLoaded\", {\n scope: \"world\",\n config: false,\n type: Boolean,\n default: false,\n })\n}\n\n/**\n * Run any pending data migrations on the \"ready\" hook.\n * Reserved for future schema migrations.\n */\nexport async function migrateIfNeeded() {\n // No migrations required yet.\n}\n\n/**\n * On first startup, import the \"Accueil\" scene from the cde-scenes compendium\n * into the world and activate it. Only runs once (tracked via the\n * `welcomeSceneLoaded` setting). GM-only.\n */\nexport async function loadWelcomeSceneIfNeeded() {\n if (!game.user.isGM) return\n if (game.settings.get(SYSTEM_ID, \"welcomeSceneLoaded\")) return\n\n try {\n const pack = game.packs.get(`${SYSTEM_ID}.cde-scenes`)\n if (!pack) return\n\n const index = await pack.getIndex()\n const entry = index.find(e => e.name === \"Accueil\")\n if (!entry) return\n\n // Check if the scene already exists in the world (e.g. manually imported)\n const existing = game.scenes.find(s => s.name === \"Accueil\")\n let scene = existing\n\n if (!scene) {\n const doc = await pack.getDocument(entry._id)\n ;[scene] = await Scene.createDocuments([doc.toObject()])\n }\n\n await game.settings.set(SYSTEM_ID, \"welcomeSceneLoaded\", true)\n await scene.activate()\n } catch (err) {\n console.error(\"CHRONIQUESDELETRANGE | loadWelcomeSceneIfNeeded failed:\", err)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS, SUBTYPES } from \"./constants.js\"\n\nexport function preLocalizeConfig() {\n const localizeConfigObject = (obj, keys) => {\n for (const o of Object.values(obj)) {\n for (const key of keys) {\n o[key] = game.i18n.localize(o[key])\n }\n }\n }\n\n localizeConfigObject(SUBTYPES, [\"label\"])\n Object.values(MAGICS).forEach((magic) => {\n magic.label = game.i18n.localize(magic.label)\n magic.aspectlabel = game.i18n.localize(magic.aspectlabel)\n Object.values(magic.speciality).forEach((spec) => {\n spec.label = game.i18n.localize(spec.label)\n spec.labelelement = game.i18n.localize(spec.labelelement)\n })\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport function configureRuntime() {\n CONFIG.Actor.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/actor-banner.webp\"\n CONFIG.Adventure.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/adventure-banner.webp\"\n CONFIG.Cards.compendiumBanner = \"ui/banners/cards-banner.webp\"\n CONFIG.Item.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/item-banner.webp\"\n CONFIG.JournalEntry.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/journalentry-banner.webp\"\n CONFIG.Macro.compendiumBanner = \"ui/banners/macro-banner.webp\"\n CONFIG.Playlist.compendiumBanner = \"ui/banners/playlist-banner.webp\"\n CONFIG.RollTable.compendiumBanner = \"ui/banners/rolltable-banner.webp\"\n CONFIG.Scene.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/scene-banner.webp\"\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class CharacterDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n const aspectField = (label, chinese) =>\n new fields.SchemaField({\n chinese: stringField(chinese),\n label: stringField(label),\n value: numberField(15, { min: 0 }),\n })\n\n const skillField = (label) =>\n new fields.SchemaField({\n label: stringField(label),\n specialities: stringField(\"\"),\n value: numberField(0, { min: 0 }),\n })\n\n const resourceField = (label) =>\n new fields.SchemaField({\n label: stringField(label),\n specialities: stringField(\"\"),\n value: numberField(0, { min: 0 }),\n debt: boolField(false),\n })\n\n const componentField = () =>\n new fields.SchemaField({\n value: stringField(\"\"),\n })\n\n const magicSpecialityField = () =>\n new fields.SchemaField({\n check: boolField(false),\n })\n\n const magicField = () =>\n new fields.SchemaField({\n visible: boolField(true),\n value: numberField(0, { min: 0 }),\n speciality: new fields.SchemaField({\n essence: magicSpecialityField(),\n mind: magicSpecialityField(),\n purification: magicSpecialityField(),\n manipulation: magicSpecialityField(),\n aura: magicSpecialityField(),\n acupuncture: magicSpecialityField(),\n elixirs: magicSpecialityField(),\n poisons: magicSpecialityField(),\n arsenal: magicSpecialityField(),\n potions: magicSpecialityField(),\n curse: magicSpecialityField(),\n transfiguration: magicSpecialityField(),\n necromancy: magicSpecialityField(),\n climatecontrol: magicSpecialityField(),\n goldenmagic: magicSpecialityField(),\n invocation: magicSpecialityField(),\n tracking: magicSpecialityField(),\n protection: magicSpecialityField(),\n punishment: magicSpecialityField(),\n domination: magicSpecialityField(),\n neutralization: magicSpecialityField(),\n divination: magicSpecialityField(),\n earthlyprayer: magicSpecialityField(),\n heavenlyprayer: magicSpecialityField(),\n fungseoi: magicSpecialityField(),\n }),\n })\n\n const treasureBranch = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n max: numberField(0, { min: 0 }),\n min: numberField(0, { min: 0 }),\n })\n\n const treasureLevel = () =>\n new fields.SchemaField({\n san: treasureBranch(),\n zing: treasureBranch(),\n })\n\n const schema = {\n concept: stringField(\"\"),\n guardian: numberField(0, { min: 0, max: 5 }),\n initiative: numberField(1, { min: 0 }),\n anti_initiative: numberField(24, { min: 0 }),\n description: htmlField(\"\"),\n prefs: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(true),\n choice: stringField(\"0\"),\n }),\n }),\n prompt: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(true),\n choice: stringField(\"0\"),\n }),\n configure: new fields.SchemaField({\n numberofdice: numberField(0),\n aspect: numberField(0),\n bonus: numberField(0),\n bonusauspiciousdice: numberField(0),\n typeofthrow: numberField(0),\n aspectskill: numberField(0),\n bonusmalusskill: numberField(0),\n aspectspeciality: numberField(0),\n rolldifficulty: numberField(0),\n bonusmalusspeciality: numberField(0),\n }),\n }),\n aspect: new fields.SchemaField({\n fire: aspectField(\"CDE.Fire\", \"\u328B\"),\n earth: aspectField(\"CDE.Earth\", \"\u328F\"),\n metal: aspectField(\"CDE.Metal\", \"\u328E\"),\n water: aspectField(\"CDE.Water\", \"\u328C\"),\n wood: aspectField(\"CDE.Wood\", \"\u328D\"),\n }),\n skills: new fields.SchemaField({\n art: skillField(\"CDE.Art\"),\n investigation: skillField(\"CDE.Investigation\"),\n erudition: skillField(\"CDE.Erudition\"),\n knavery: skillField(\"CDE.Knavery\"),\n wordliness: skillField(\"CDE.Wordliness\"),\n prowess: skillField(\"CDE.Prowess\"),\n sciences: skillField(\"CDE.Sciences\"),\n technologies: skillField(\"CDE.Technologies\"),\n kungfu: skillField(\"CDE.KungFu\"),\n rangedcombat: skillField(\"CDE.RangedCombat\"),\n }),\n resources: new fields.SchemaField({\n supply: resourceField(\"CDE.Supply\"),\n inquiry: resourceField(\"CDE.Inquiry\"),\n influence: resourceField(\"CDE.Influence\"),\n }),\n component: new fields.SchemaField({\n one: componentField(),\n two: componentField(),\n three: componentField(),\n four: componentField(),\n five: componentField(),\n six: componentField(),\n seven: componentField(),\n eight: componentField(),\n nine: componentField(),\n zero: componentField(),\n }),\n magics: new fields.SchemaField({\n internalcinnabar: magicField(),\n alchemy: magicField(),\n masteryoftheway: magicField(),\n exorcism: magicField(),\n geomancy: magicField(),\n }),\n threetreasures: new fields.SchemaField({\n heiyang: new fields.SchemaField({ value: numberField(0, { min: 0 }), max: numberField(0, { min: 0 }) }),\n heiyin: new fields.SchemaField({ value: numberField(0, { min: 0 }), max: numberField(0, { min: 0 }) }),\n dicelevel: new fields.SchemaField({\n level0d: treasureLevel(),\n level1d: treasureLevel(),\n level2d: treasureLevel(),\n }),\n }),\n experience: new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n max: numberField(0, { min: 0 }),\n min: numberField(0, { min: 0 }),\n }),\n }\n\n return schema\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class NpcDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n const aptitudeField = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n speciality: stringField(\"\"),\n })\n\n const trackedField = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n calcul: numberField(0, { min: 0 }),\n note: stringField(\"\"),\n })\n\n return {\n type: stringField(\"\"),\n threat: numberField(0, { min: 0, max: 4 }), // profane(0) | apprentice(1) | initiate(2) | accomplished(3) | renowned(4)\n nuisance: numberField(0, { min: 0, max: 5 }), // figurant(0) | minion(1) | adversary(2) | ally(3) | boss(4) | divinity(5)\n initiative: numberField(1, { min: 0 }),\n anti_initiative: numberField(24, { min: 0 }),\n aptitudes: new fields.SchemaField({\n physical: aptitudeField(),\n martial: aptitudeField(),\n mental: aptitudeField(),\n social: aptitudeField(),\n spiritual: aptitudeField(),\n }),\n vitality: trackedField(),\n hei: trackedField(),\n description: htmlField(\"\"),\n prefs: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(false),\n choice: stringField(\"0\"),\n }),\n }),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class EquipmentDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n quantity: numberField(1, { min: 0 }),\n weight: numberField(0, { min: 0 }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class KungfuDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n\n const techniqueField = () =>\n new fields.SchemaField({\n check: boolField(false),\n name: stringField(\"\"),\n activation: stringField(\"action-attack\"), // action-attack | action-defense | action-aid | action-attack-defense | reaction | dice | damage-inflicted | damage-received\n technique: htmlField(\"\"),\n })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n orientation: stringField(\"yin\"), // yin | yang | yinyang\n aspect: stringField(\"metal\"), // metal | eau | terre | feu | bois\n skill: stringField(\"kungfu\"), // kungfu | rangedcombat\n speciality: stringField(\"\"),\n style: stringField(\"\"),\n techniques: new fields.SchemaField({\n technique1: techniqueField(),\n technique2: techniqueField(),\n technique3: techniqueField(),\n }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SpellDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n specialityname: stringField(\"\"),\n associatedelement: stringField(\"metal\"), // metal | eau | terre | feu | bois\n hei: stringField(\"\"),\n realizationtimeritual: stringField(\"\"),\n realizationtimeaccelerated: stringField(\"\"),\n flashback: stringField(\"\"),\n components: htmlField(\"\"),\n effects: htmlField(\"\"),\n examples: htmlField(\"\"),\n notes: htmlField(\"\"),\n discipline: stringField(\"internalcinnabar\"),\n heiType: stringField(\"yin\"),\n heiCost: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 1 }),\n difficulty: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 1 }),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SupernaturalDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n notes: htmlField(\"\"),\n heiType: stringField(\"yin\"),\n heiCost: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 0 }),\n trigger: stringField(\"\"),\n effects: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class WeaponDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n weaponType: stringField(\"melee\"),\n material: stringField(\"\"),\n damageAspect: stringField(\"metal\"),\n damageBase: intField(1),\n range: stringField(\"contact\"), // contact | courte | mediane | longue | extreme\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class ArmorDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n protectionValue: intField(0),\n domain: stringField(\"\"),\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SanheiDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n const propertySchema = () => new fields.SchemaField({\n name: stringField(\"\"),\n heiCost: intField(0),\n heiType: stringField(\"yin\"),\n description: htmlField(\"\"),\n })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n heiType: stringField(\"yin\"),\n properties: new fields.SchemaField({\n prop1: propertySchema(),\n prop2: propertySchema(),\n prop3: propertySchema(),\n }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class IngredientDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n school: stringField(\"all\"),\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport class CDEMessage extends ChatMessage {\n async renderHTML({ canDelete, canClose = false, ...rest } = {}) {\n const html = await super.renderHTML({ canDelete, canClose, ...rest })\n this.#enrichChatCard(html)\n return html\n }\n\n getAssociatedActor() {\n if (this.speaker.scene && this.speaker.token) {\n const scene = game.scenes.get(this.speaker.scene)\n const token = scene?.tokens.get(this.speaker.token)\n if (token) return token.actor\n }\n return game.actors.get(this.speaker.actor)\n }\n\n #enrichChatCard(html) {\n const actor = this.getAssociatedActor()\n\n let img\n let nameText\n if (this.isContentVisible) {\n img = actor?.img ?? this.author.avatar\n nameText = this.alias\n } else {\n img = this.author.avatar\n nameText = this.author.name\n }\n\n const avatar = document.createElement(\"a\")\n avatar.classList.add(\"avatar\")\n if (actor) avatar.dataset.uuid = actor.uuid\n const avatarImg = document.createElement(\"img\")\n Object.assign(avatarImg, { src: img, alt: nameText })\n avatar.append(avatarImg)\n\n const name = document.createElement(\"span\")\n name.classList.add(\"name-stacked\")\n const title = document.createElement(\"span\")\n title.classList.add(\"title\")\n title.append(nameText)\n name.append(title)\n\n const sender = html.querySelector(\".message-sender\")\n sender?.replaceChildren(avatar, name)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { ACTOR_TYPES } from \"../config/constants.js\"\n\nexport class CDEActor extends Actor {\n getRollData() {\n const data = this.toObject(false).system\n return data\n }\n\n prepareBaseData() {\n super.prepareBaseData()\n\n if (this.type === ACTOR_TYPES.character) {\n this.system.anti_initiative = 25 - (this.system.initiative ?? 0)\n }\n\n if (this.type === ACTOR_TYPES.npc) {\n this.system.vitality.calcul = (this.system.aptitudes.physical.value ?? 0) * 4\n this.system.hei.calcul = (this.system.aptitudes.spiritual.value ?? 0) * 4\n this.system.anti_initiative = 25 - (this.system.initiative ?? 0)\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/** Default icons per item type. */\nconst DEFAULT_ICONS = {\n kungfu: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-kungfu.svg\",\n spell: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-spell.svg\",\n supernatural: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-supernatural.svg\",\n weapon: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-weapon.svg\",\n armor: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-armor.svg\",\n sanhei: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-sanhei.svg\",\n ingredient: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-ingredient.svg\",\n item: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-item.svg\",\n};\n\nexport class CDEItem extends Item {\n\n /** @override */\n async _preCreate(data, options, userId) {\n await super._preCreate(data, options, userId);\n const defaultIcon = DEFAULT_ICONS[this.type];\n if (defaultIcon && (!data.img || data.img === Item.DEFAULT_ICON)) {\n this.updateSource({ img: defaultIcon });\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst DIGIT_LABELS = [\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-1.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-2.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-3.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-4.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-5.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-6.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-7.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-8.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-9.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-10.webp\",\n]\n\nconst CLASSIC_LABELS = [\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-1.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-2.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-3.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-4.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-5.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-6.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-7.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-8.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-9.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-10.webp\",\n]\n\nexport function registerDice() {\n Hooks.once(\"diceSoNiceReady\", (dice3d) => {\n dice3d.addColorset(\n {\n name: \"cde\",\n description: \"CdE\",\n foreground: \"#000000\",\n background: \"#ffffff\",\n edge: \"#ffffff\",\n font: \"DeliusUnicase\",\n texture: \"ice\",\n material: \"plastic\",\n },\n \"preferred\",\n )\n\n dice3d.addSystem({ id: \"fvtt-chroniques-de-l-etrangedigit\", name: \"Chroniques de l'\u00E9trange digits\" }, \"preferred\")\n dice3d.addDicePreset({ type: \"d10\", labels: DIGIT_LABELS, system: \"fvtt-chroniques-de-l-etrangedigit\" })\n\n dice3d.addSystem({ id: \"fvtt-chroniques-de-l-etrange\", name: \"Chroniques de l'\u00E9trange\" }, \"preferred\")\n dice3d.addDicePreset({ type: \"d10\", labels: CLASSIC_LABELS, system: \"fvtt-chroniques-de-l-etrange\" })\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS } from \"../config/constants.js\"\n\nexport function registerHandlebarsHelpers() {\n const { Handlebars } = globalThis\n if (!Handlebars) return\n\n Handlebars.registerHelper(\"select\", function (selected, options) {\n const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected))\n const rgx = new RegExp(` value=[\"']${escapedValue}[\"']`)\n const html = options.fn(this)\n return html.replace(rgx, \"$& selected\")\n })\n\n Handlebars.registerHelper(\"getMagicBackground\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.background ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicLabel\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.label ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicAspectLabel\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.aspectlabel ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabel\", function (magic, speciality) {\n return game.i18n.localize(MAGICS[magic]?.speciality?.[speciality]?.label ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityClassIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.classicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.icon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityElementIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.elementicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabelIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.labelicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabelElement\", function (magic, speciality) {\n return game.i18n.localize(MAGICS[magic]?.speciality?.[speciality]?.labelelement ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicAspectIcon\", function (magic) {\n const icons = {\n internalcinnabar: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n alchemy: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n masteryoftheway: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n exorcism: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n geomancy: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n }\n return icons[magic] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getElementIcon\", function (aspect) {\n const icons = {\n metal: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n water: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n earth: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n fire: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n wood: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n // legacy French keys\n eau: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n terre: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n feu: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n bois: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n }\n return icons[aspect] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getOrientationIcon\", function (orientation) {\n const icons = {\n yin: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\",\n yang: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\",\n yinyang: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\",\n }\n return icons[orientation] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getOrientationLabel\", function (orientation) {\n const keys = {\n yin: \"CDE.OrientationYin\",\n yang: \"CDE.OrientationYang\",\n yinyang: \"CDE.OrientationYinYang\",\n }\n return game.i18n.localize(keys[orientation] ?? \"CDE.Orientation\")\n })\n\n Handlebars.registerHelper(\"getActivationLabel\", function (activation) {\n const keys = {\n \"action-attack\": \"CDE.ActivationAttack\",\n \"action-defense\": \"CDE.ActivationDefense\",\n \"action-aid\": \"CDE.ActivationAid\",\n \"action-attack-defense\": \"CDE.ActivationAttackOrDefense\",\n reaction: \"CDE.ActivationReaction\",\n dice: \"CDE.ActivationDice\",\n \"damage-inflicted\": \"CDE.ActivationDamageInflicted\",\n \"damage-received\": \"CDE.ActivationDamageReceived\",\n }\n return game.i18n.localize(keys[activation] ?? \"CDE.Activation\")\n })\n\n /**\n * Compute the SVG x,y coordinates for a cran on the initiative wheel.\n * Cran 1\u201324 are arranged counter-clockwise from the bottom (reference at 6 o'clock).\n * angle = 90\u00B0 + cran * 15\u00B0 (counter-clockwise = positive in standard math, negative in SVG).\n * In SVG coords: x = cx + r*cos(a), y = cy - r*sin(a) [y-axis is flipped in SVG].\n */\n Handlebars.registerHelper(\"cranPosition\", function (cran, cx, cy, r) {\n const angleDeg = 90 + cran * 15 // counter-clockwise from bottom\n const angleRad = (angleDeg * Math.PI) / 180\n const x = Math.round(cx + r * Math.cos(angleRad))\n const y = Math.round(cy - r * Math.sin(angleRad))\n return { x, y }\n })\n\n /** X offset for overlapping fighters on the same cran. Centres a 30px image on the cran cx. */\n Handlebars.registerHelper(\"fighterX\", function (cx, index, total) {\n const offset = total > 1 ? (index - (total - 1) / 2) * 34 : 0\n return Math.round(cx - 15 + offset)\n })\n\n /** Y offset for fighters \u2014 positions image just above the cran circle. */\n Handlebars.registerHelper(\"fighterY\", function (cy, index, total) {\n return Math.round(cy - 50)\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { TEMPLATE_PARTIALS } from \"../config/constants.js\"\n\nexport async function preloadPartials() {\n return foundry.applications.handlebars.loadTemplates(TEMPLATE_PARTIALS)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Initiative determination system for Chroniques de l'\u00C9trange.\n *\n * PJ formula: Initiative = Prouesse + Premi\u00E8re action (comp\u00E9tence/ressource/magie)\n * PNJ formula: Initiative = Aptitude physique + Premi\u00E8re action (aptitude)\n *\n * Range 1-24 ; anti-initiative = 25 \u2212 initiative.\n * Combat order is ascending (low initiative acts first).\n */\n\nconst PC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-prompt.html\"\nconst NPC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-prompt-npc.html\"\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-result.html\"\n\n/** Skills, resources and magics available as \"premi\u00E8re action\" for a PC. */\nfunction buildPCOptions(sys) {\n const sk = sys.skills ?? {}\n const rs = sys.resources ?? {}\n const mg = sys.magics ?? {}\n return [\n { key: \"art\", label: game.i18n.localize(\"CDE.Art\"), value: sk.art?.value ?? 0 },\n { key: \"investigation\", label: game.i18n.localize(\"CDE.Investigation\"), value: sk.investigation?.value ?? 0 },\n { key: \"erudition\", label: game.i18n.localize(\"CDE.Erudition\"), value: sk.erudition?.value ?? 0 },\n { key: \"knavery\", label: game.i18n.localize(\"CDE.Knavery\"), value: sk.knavery?.value ?? 0 },\n { key: \"wordliness\", label: game.i18n.localize(\"CDE.Wordliness\"), value: sk.wordliness?.value ?? 0 },\n { key: \"prowess\", label: game.i18n.localize(\"CDE.Prowess\"), value: sk.prowess?.value ?? 0 },\n { key: \"sciences\", label: game.i18n.localize(\"CDE.Sciences\"), value: sk.sciences?.value ?? 0 },\n { key: \"technologies\", label: game.i18n.localize(\"CDE.Technologies\"), value: sk.technologies?.value ?? 0 },\n { key: \"kungfu\", label: game.i18n.localize(\"CDE.KungFu\"), value: sk.kungfu?.value ?? 0 },\n { key: \"rangedcombat\", label: game.i18n.localize(\"CDE.RangedCombat\"), value: sk.rangedcombat?.value ?? 0 },\n { key: \"supply\", label: game.i18n.localize(\"CDE.Supply\"), value: rs.supply?.value ?? 0 },\n { key: \"inquiry\", label: game.i18n.localize(\"CDE.Inquiry\"), value: rs.inquiry?.value ?? 0 },\n { key: \"influence\", label: game.i18n.localize(\"CDE.Influence\"), value: rs.influence?.value ?? 0 },\n { key: \"internalcinnabar\", label: game.i18n.localize(\"CDE.InternalCinnabar\"), value: mg.internalcinnabar?.value ?? 0 },\n { key: \"alchemy\", label: game.i18n.localize(\"CDE.Alchemy\"), value: mg.alchemy?.value ?? 0 },\n { key: \"masteryoftheway\", label: game.i18n.localize(\"CDE.MasteryOfTheWay\"), value: mg.masteryoftheway?.value ?? 0 },\n { key: \"exorcism\", label: game.i18n.localize(\"CDE.Exorcism\"), value: mg.exorcism?.value ?? 0 },\n { key: \"geomancy\", label: game.i18n.localize(\"CDE.Geomancy\"), value: mg.geomancy?.value ?? 0 },\n ]\n}\n\n/** Aptitudes available as \"premi\u00E8re action\" for an NPC. */\nfunction buildNPCOptions(sys) {\n const ap = sys.aptitudes ?? {}\n return [\n { key: \"physical\", label: game.i18n.localize(\"CDE.Physical\"), value: ap.physical?.value ?? 0 },\n { key: \"martial\", label: game.i18n.localize(\"CDE.Martial\"), value: ap.martial?.value ?? 0 },\n { key: \"mental\", label: game.i18n.localize(\"CDE.Mental\"), value: ap.mental?.value ?? 0 },\n { key: \"social\", label: game.i18n.localize(\"CDE.Social\"), value: ap.social?.value ?? 0 },\n { key: \"spiritual\", label: game.i18n.localize(\"CDE.Spiritual\"), value: ap.spiritual?.value ?? 0 },\n ]\n}\n\n/** Parse the dialog element and extract firstaction + modifier. */\nfunction readInitFields(dialog) {\n const root = dialog.element ?? dialog\n const selectedKey = root.querySelector(\"select[name='firstaction']\")?.value ?? \"\"\n const modifier = parseInt(root.querySelector(\"input[name='modifier']\")?.value ?? \"0\", 10) || 0\n return { selectedKey, modifier }\n}\n\n/** Post a styled initiative chat message. */\nasync function sendInitChatMessage({ actor, baseName, baseValue, actionName, actionValue, modifier, initiative, antiInitiative }) {\n const html = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, {\n actorName: actor.name,\n actorImg: actor.img,\n baseName,\n baseValue,\n actionName,\n actionValue,\n modifier,\n hasModifier: modifier !== 0,\n initiative,\n antiInitiative,\n })\n await ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor }),\n content: html,\n })\n}\n\n/**\n * Open the PC initiative dialog, compute initiative (Prouesse + Premi\u00E8re action + modificateur)\n * and update the actor, then post a chat card.\n */\nexport async function rollInitiativePC(actor) {\n const sys = actor.system\n const prowess = sys.skills?.prowess?.value ?? 0\n const options = buildPCOptions(sys)\n const baseName = game.i18n.localize(\"CDE.Prowess\")\n\n const content = await foundry.applications.handlebars.renderTemplate(PC_PROMPT_TEMPLATE, {\n prowessValue: prowess,\n options,\n modifier: 0,\n })\n\n const result = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.InitiativeRoll\") },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => readInitFields(dialog),\n },\n })\n if (!result) return\n\n const { selectedKey, modifier } = result\n const selected = options.find((o) => o.key === selectedKey) ?? options[0]\n const rawValue = prowess + selected.value + modifier\n const initiative = Math.max(1, Math.min(24, rawValue))\n const antiInit = 25 - initiative\n\n await actor.update({ \"system.initiative\": initiative })\n await sendInitChatMessage({\n actor,\n baseName,\n baseValue: prowess,\n actionName: selected.label,\n actionValue: selected.value,\n modifier,\n initiative,\n antiInitiative: antiInit,\n })\n}\n\n/**\n * Open the NPC initiative dialog, compute initiative (Aptitude physique + Premi\u00E8re action + modificateur)\n * and update the actor, then post a chat card.\n */\nexport async function rollInitiativeNPC(actor) {\n const sys = actor.system\n const physical = sys.aptitudes?.physical?.value ?? 0\n const options = buildNPCOptions(sys)\n const baseName = game.i18n.localize(\"CDE.Physical\")\n\n const content = await foundry.applications.handlebars.renderTemplate(NPC_PROMPT_TEMPLATE, {\n physicalValue: physical,\n options,\n modifier: 0,\n })\n\n const result = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.InitiativeRoll\") },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => readInitFields(dialog),\n },\n })\n if (!result) return\n\n const { selectedKey, modifier } = result\n const selected = options.find((o) => o.key === selectedKey) ?? options[0]\n const rawValue = physical + selected.value + modifier\n const initiative = Math.max(1, Math.min(24, rawValue))\n const antiInit = 25 - initiative\n\n await actor.update({ \"system.initiative\": initiative })\n await sendInitChatMessage({\n actor,\n baseName,\n baseValue: physical,\n actionName: selected.label,\n actionValue: selected.value,\n modifier,\n initiative,\n antiInitiative: antiInit,\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Loksyu / TinJi settings-based helpers.\n *\n * Data is stored as world settings instead of singleton Actor documents.\n */\n\nimport { SYSTEM_ID, WU_XING_CYCLE, ASPECT_FACES } from \"../../config/constants.js\"\n\n/** Read the current loksyu data object from world settings */\nexport function getLoksyuData() {\n return game.settings.get(SYSTEM_ID, \"loksyuData\") ?? {\n wood: {yin:0,yang:0}, fire: {yin:0,yang:0}, earth: {yin:0,yang:0}, metal: {yin:0,yang:0}, water: {yin:0,yang:0},\n }\n}\n\n/** Write the loksyu data object to world settings */\nexport async function setLoksyuData(data) {\n await game.settings.set(SYSTEM_ID, \"loksyuData\", data)\n Hooks.callAll(\"cde:loksyuUpdated\", data)\n}\n\n/** Read current TinJi value from world settings */\nexport function getTinjiValue() {\n return game.settings.get(SYSTEM_ID, \"tinjiData\") ?? 0\n}\n\n/** Write TinJi value to world settings */\nexport async function setTinjiValue(value) {\n await game.settings.set(SYSTEM_ID, \"tinjiData\", Math.max(0, value))\n Hooks.callAll(\"cde:tinjiUpdated\", Math.max(0, value))\n}\n\n/**\n * After a WuXing roll, add the loksyu faces (yin + yang) of the relevant\n * aspect to the loksyu settings data.\n *\n * @param {string} activeAspect - e.g. \"fire\"\n * @param {Object} faces - Die face counts { 0: n, 1: n, \u2026, 9: n }\n */\nexport async function updateLoksyuFromRoll(activeAspect, faces) {\n const cycle = WU_XING_CYCLE[activeAspect]\n if (!cycle) return\n\n const lokAspect = cycle[3]\n const [yinFace, yangFace] = ASPECT_FACES[lokAspect] ?? []\n if (yinFace === undefined) return\n\n const yinCount = faces[yinFace] ?? 0\n const yangCount = faces[yangFace] ?? 0\n if (yinCount === 0 && yangCount === 0) return\n\n const data = getLoksyuData()\n const current = data[lokAspect] ?? { yin: 0, yang: 0 }\n data[lokAspect] = {\n yin: (current.yin ?? 0) + yinCount,\n yang: (current.yang ?? 0) + yangCount,\n }\n await setLoksyuData(data)\n}\n\n/**\n * After a WuXing roll, add tinji faces to the TinJi settings.\n *\n * @param {number} count - Number of tinji faces rolled\n */\nexport async function updateTinjiFromRoll(count) {\n if (!count || count <= 0) return\n const current = getTinjiValue()\n await setTinjiValue(current + count)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Wu Xing rolling system for Chroniques de l'\u00C9trange.\n *\n * The Wu Xing cycle maps each aspect (by index 0-4) to die face groups:\n * - metal=0 : faces 3,8\n * - water=1 : faces 1,6\n * - earth=2 : faces 0/10,5\n * - fire=3 : faces 2,7\n * - wood=4 : faces 4,9\n *\n * For a given active aspect the five result categories are:\n * successes / auspicious / noxious / loksyu (yin face, yang face) / tinji\n * Each category is associated with one of the five aspects in Wu Xing cycle order.\n */\n\nimport { MAGICS, ASPECT_LABELS, ASPECT_ICONS, ASPECT_FACES, ASPECT_NAMES, WU_XING_CYCLE } from \"../config/constants.js\"\nimport { updateLoksyuFromRoll, updateTinjiFromRoll } from \"./apps/singletons.js\"\n\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html\"\nconst SKILL_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-skill-dice-prompt.html\"\nconst SKILL_SPECIAL_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-skill-special-dice-prompt.html\"\nconst MAGIC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-magic-dice-prompt.html\"\nconst WEAPON_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-weapon-dice-prompt.html\"\n\n/** Maps i18n element label \u2192 aspect name (for speciality default aspect lookup) */\nconst LABELELEMENT_TO_ASPECT = {\n \"CDE.Metal\": \"metal\",\n \"CDE.Water\": \"water\",\n \"CDE.Earth\": \"earth\",\n \"CDE.Fire\": \"fire\",\n \"CDE.Wood\": \"wood\",\n}\n\n/** Maps weapon range string \u2192 dice malus applied to the attack pool */\nconst RANGE_MALUS = {\n contact: 0,\n courte: 0,\n mediane: -1,\n longue: -2,\n extreme: -3,\n}\n\n/** Maps weapon type string \u2192 default skill key */\nconst WEAPON_TYPE_SKILL = {\n melee: \"kungfu\",\n thrown: \"rangedcombat\",\n ranged: \"rangedcombat\",\n firearm: \"rangedcombat\",\n}\n\n/** Maps weapon damageAspect name \u2192 ASPECT_NAMES index */\nconst WEAPON_ASPECT_INDEX = { metal: 0, eau: 1, water: 1, terre: 2, earth: 2, feu: 3, fire: 3, bois: 4, wood: 4 }\n\n/** Count how many times each die face appeared in the roll results */\nfunction countFaces(rollResults) {\n const counts = { 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 0:0 }\n for (const die of rollResults) {\n const face = die.result === 10 ? 0 : die.result\n counts[face]++\n }\n return counts\n}\n\n/**\n * Compute Wu Xing result categories from face counts and active aspect.\n * Returns { successesdice, auspiciousdice, noxiousdice, loksyudice, tinjidice, loksyurepartition }\n */\nfunction computeWuXingResults(faces, aspectName, bonusAuspicious = 0) {\n const cycle = WU_XING_CYCLE[aspectName]\n if (!cycle) return null\n\n const [succAspect, ausAspect, noxAspect, lokAspect, tinAspect] = cycle\n const [succYin, succYang] = ASPECT_FACES[succAspect]\n const [ausYin, ausYang] = ASPECT_FACES[ausAspect]\n const [noxYin, noxYang] = ASPECT_FACES[noxAspect]\n const [lokYin, lokYang] = ASPECT_FACES[lokAspect]\n const [tinYin, tinYang] = ASPECT_FACES[tinAspect]\n\n const yin = game.i18n.localize(\"CDE.Yin\")\n const yang = game.i18n.localize(\"CDE.Yang\")\n\n return {\n successesdice: faces[succYin] + faces[succYang],\n auspiciousdice: faces[ausYin] + faces[ausYang] + bonusAuspicious,\n noxiousdice: faces[noxYin] + faces[noxYang],\n loksyudice: faces[lokYin] + faces[lokYang],\n loksyurepartition: `[${yin}(${faces[lokYin]}) ${yang}(${faces[lokYang]})]`,\n tinjidice: faces[tinYin] + faces[tinYang],\n }\n}\n\n/** Read a named field from a dialog DOM element */\nfunction readField(dlg, name) {\n const el = dlg.querySelector(`[name=\"${name}\"]`)\n if (!el) return null\n return el.type === \"checkbox\" ? el.checked : el.value\n}\n\n/**\n * Open a DialogV2.prompt with the given template + data and return the resolved form values.\n * The callback receives the DialogV2 application instance; fields are read from its .element.\n * @returns {Promise|null>}\n */\nasync function showRollPrompt({ title, template, data, fields }) {\n const content = await foundry.applications.handlebars.renderTemplate(template, data)\n return foundry.applications.api.DialogV2.prompt({\n window: { title },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (event, button, dialog) => {\n // In AppV2, dialog is the application instance; .element is the root HTMLElement\n const root = dialog.element ?? dialog\n const result = {}\n for (const field of fields) {\n result[field] = readField(root, field)\n }\n return result\n },\n },\n })\n}\n\n/**\n * Open the skill roll prompt and return the user-confirmed parameters.\n * @param {object} params - Initial values\n * @returns {Promise}\n */\nasync function showSkillPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: params.isSpecial ? SKILL_SPECIAL_PROMPT_TEMPLATE : SKILL_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice,\n aspect: Number(params.aspect ?? 0),\n bonusmalus: params.bonusmalus ?? 0,\n woundmalus: params.woundmalus ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"aspect\", \"bonusmalus\", \"woundmalus\", \"bonusauspiciousdice\", \"typeofthrow\"],\n })\n}\n\n/**\n * Open the magic roll prompt and return the user-confirmed parameters.\n */\nasync function showMagicPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: MAGIC_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice ?? 0,\n aspectskill: Number(params.aspectskill ?? 0),\n bonusmalusskill: params.bonusmalusskill ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n aspectspeciality: Number(params.aspectspeciality ?? 0),\n rolldifficulty: params.rolldifficulty ?? 1,\n bonusmalusspeciality: params.bonusmalusspeciality ?? 0,\n heispend: params.heispend ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"aspectskill\", \"bonusmalusskill\", \"bonusauspiciousdice\",\n \"aspectspeciality\", \"rolldifficulty\", \"bonusmalusspeciality\",\n \"heispend\", \"typeofthrow\"],\n })\n}\n\n/**\n * Open the weapon attack roll prompt and return user-confirmed parameters.\n */\nasync function showWeaponPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: WEAPON_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice ?? 0,\n weaponName: params.weaponName ?? \"\",\n weaponTypeLabel: params.weaponTypeLabel ?? \"CDE.Weapon\",\n weaponAspectIcon: params.weaponAspectIcon ?? \"\",\n weaponAspectLabel: params.weaponAspectLabel ?? \"\",\n damageBase: params.damageBase ?? 1,\n weaponskill: params.weaponskill ?? \"kungfu\",\n aspect: Number(params.aspect ?? 0),\n effectiverange: params.effectiverange ?? \"contact\",\n bonusmalus: params.bonusmalus ?? 0,\n woundmalus: params.woundmalus ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"weaponskill\", \"aspect\", \"effectiverange\", \"bonusmalus\", \"woundmalus\",\n \"bonusauspiciousdice\", \"typeofthrow\"],\n })\n}\n\n/**\n * Build and send a single enriched ChatMessage containing both the roll\n * (for Dice So Nice) and the Wu Xing result card.\n */\nasync function sendResultMessage(actor, resultData, roll, rollMode) {\n const html = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, resultData)\n return ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor }),\n content: html,\n rolls: [roll],\n rollMode,\n flags: {\n \"fvtt-chroniques-de-l-etrange\": { rollResult: { ...resultData } },\n },\n })\n}\n\nconst ROLL_MODES = [\"roll\", \"gmroll\", \"blindroll\", \"selfroll\"]\n\n/**\n * Main entry point: roll dice for a given actor.\n *\n * @param {Actor} actor\n * @param {string} rollKey - e.g. \"prowess-skill\", \"fire-aspect\", \"alchemy-magic-elixirs\"\n */\nexport async function rollForActor(actor, rollKey) {\n const parts = rollKey.split(\"-\")\n const skillLibel = parts[0]\n const typeLibel = parts[1]\n const specialLibel = parts[2] ?? null\n\n const sys = actor.system\n const typeOfThrow = Number(sys.prefs?.typeofthrow?.choice ?? 0)\n\n let numberofdice = 0\n let title = \"\"\n let isSpecial = false\n let isMagic = false\n let isMagicSpecial = false\n let kfDefaultAspect = -1 // set in \"itemkungfu\" case, used when computing defaultAspect\n\n // ---- Determine dice count + title ----\n const MAGIC_I18N_KEYS = {\n internalcinnabar: \"CDE.InternalCinnabar\",\n alchemy: \"CDE.Alchemy\",\n masteryoftheway: \"CDE.MasteryOfTheWay\",\n exorcism: \"CDE.Exorcism\",\n geomancy: \"CDE.Geomancy\",\n }\n\n switch (typeLibel) {\n case \"aspect\":\n numberofdice = sys.aspect[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.aspect[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"aptitude\":\n // NPC aptitude roll \u2014 flat pool with WuXing prompt\n numberofdice = sys.aptitudes?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(`CDE.${skillLibel.charAt(0).toUpperCase() + skillLibel.slice(1)}`)\n break\n case \"skill\":\n numberofdice = sys.skills?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.skills?.[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"special\":\n numberofdice = sys.skills?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.skills?.[skillLibel]?.label ?? \"CDE.Roll\")\n title += ` [${game.i18n.localize(\"CDE.Speciality\")}]`\n isSpecial = true\n if (!sys.skills?.[skillLibel]?.specialities) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error2\"))\n return\n }\n break\n case \"resource\":\n numberofdice = sys.resources?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.resources?.[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"field\":\n numberofdice = sys.resources?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.resources?.[skillLibel]?.label ?? \"CDE.Roll\")\n title += ` [${game.i18n.localize(\"CDE.Field\")}]`\n isSpecial = true\n if (!sys.resources?.[skillLibel]?.specialities) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error4\"))\n return\n }\n break\n case \"magic\":\n numberofdice = sys.magics?.[skillLibel]?.value ?? 0\n isMagic = true\n title = game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? \"CDE.Magics\")\n break\n case \"magicspecial\":\n numberofdice = sys.magics?.[skillLibel]?.value ?? 0\n isMagicSpecial = true\n isMagic = true\n if (!sys.magics?.[skillLibel]?.speciality?.[specialLibel]?.check) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error6\"))\n return\n }\n title = `${game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? \"CDE.Magics\")} [${game.i18n.localize(MAGICS?.[skillLibel]?.speciality?.[specialLibel]?.label ?? \"\")}]`\n break\n case \"itemkungfu\": {\n // skillLibel = item._id \u2014 look up the kungfu item to find which skill + aspect to use\n const kfItem = actor.items.get(skillLibel)\n if (!kfItem) { ui.notifications.warn(game.i18n.localize(\"CDE.Error0\")); return }\n const kfSkill = kfItem.system.skill ?? \"kungfu\"\n numberofdice = sys.skills?.[kfSkill]?.value ?? 0\n title = `${kfItem.name} [${game.i18n.localize(sys.skills?.[kfSkill]?.label ?? \"CDE.KungFu\")}]`\n kfDefaultAspect = ASPECT_NAMES.indexOf(kfItem.system.aspect ?? \"metal\")\n if (kfDefaultAspect < 0) kfDefaultAspect = 0\n break\n }\n case \"itemweapon\": {\n // skillLibel = item._id \u2014 look up the weapon item to find type + aspect + damage\n const wpItem = actor.items.get(skillLibel)\n if (!wpItem) { ui.notifications.warn(game.i18n.localize(\"CDE.Error0\")); return }\n\n const wpType = wpItem.system.weaponType ?? \"melee\"\n const wpSkill = WEAPON_TYPE_SKILL[wpType] ?? \"kungfu\"\n numberofdice = sys.skills?.[wpSkill]?.value ?? 0\n\n const wpAspectRaw = wpItem.system.damageAspect ?? \"metal\"\n const wpAspectIdx = WEAPON_ASPECT_INDEX[wpAspectRaw] ?? 0\n const wpRange = wpItem.system.range ?? \"contact\"\n\n const WEAPON_TYPE_LABELS = {\n melee: \"CDE.WeaponMelee\",\n thrown: \"CDE.WeaponThrown\",\n ranged: \"CDE.WeaponRanged\",\n firearm: \"CDE.WeaponFirearm\",\n }\n\n // Show weapon-specific prompt\n const wParams = await showWeaponPrompt({\n title: `${wpItem.name} [${game.i18n.localize(sys.skills?.[wpSkill]?.label ?? \"CDE.WeaponRoll\")}]`,\n numberofdice,\n weaponName: wpItem.name,\n weaponTypeLabel: WEAPON_TYPE_LABELS[wpType] ?? \"CDE.Weapon\",\n weaponAspectIcon: ASPECT_ICONS[ASPECT_NAMES[wpAspectIdx]] ?? \"\",\n weaponAspectLabel: game.i18n.localize(ASPECT_LABELS[ASPECT_NAMES[wpAspectIdx]] ?? \"\"),\n damageBase: wpItem.system.damageBase ?? 1,\n weaponskill: wpSkill,\n aspect: wpAspectIdx,\n effectiverange: wpRange,\n bonusmalus: 0,\n woundmalus: 0,\n bonusauspiciousdice: 0,\n typeofthrow: typeOfThrow,\n })\n\n if (!wParams) return // cancelled\n\n // Resolve final pool from weapon prompt values\n const wpChosenSkill = wParams.weaponskill ?? wpSkill\n const wpSkillDice = sys.skills?.[wpChosenSkill]?.value ?? 0\n const wpAspFinal = Number(wParams.aspect ?? wpAspectIdx)\n const wpAspectDice = sys.aspect[ASPECT_NAMES[wpAspFinal]]?.value ?? 0\n const wpRangeMalus = RANGE_MALUS[wParams.effectiverange ?? \"contact\"] ?? 0\n const wpBonusMalus = Number(wParams.bonusmalus ?? 0)\n const wpWoundMalus = Number(wParams.woundmalus ?? 0)\n const wpBonusAusp = Number(wParams.bonusauspiciousdice ?? 0)\n const wpThrowMode = Number(wParams.typeofthrow ?? 0)\n const wpDamageBase = wpItem.system.damageBase ?? 1\n\n const wpTotalDice = wpSkillDice + wpAspectDice + wpRangeMalus + wpBonusMalus - wpWoundMalus\n if (wpTotalDice <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n const wpRoll = new Roll(`${wpTotalDice}d10`)\n await wpRoll.evaluate()\n\n const wpAspectName = ASPECT_NAMES[wpAspFinal] ?? \"metal\"\n const wpFaces = countFaces(wpRoll.dice[0]?.results ?? [])\n const wpResults = computeWuXingResults(wpFaces, wpAspectName, wpBonusAusp)\n if (!wpResults) return\n\n const wpModParts = []\n if (wpRangeMalus !== 0) wpModParts.push(`${wpRangeMalus} ${game.i18n.localize(\"CDE.RangePenalty\")}`)\n if (wpBonusMalus !== 0) wpModParts.push(`${wpBonusMalus > 0 ? \"+\" : \"\"}${wpBonusMalus} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (wpWoundMalus !== 0) wpModParts.push(`-${wpWoundMalus} ${game.i18n.localize(\"CDE.WoundMalus\")}`)\n if (wpBonusAusp !== 0) wpModParts.push(`+${wpBonusAusp} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n\n const wpMsg = await sendResultMessage(actor, {\n rollLabel: `${wpItem.name}`,\n aspectName: wpAspectName,\n aspectLabel: game.i18n.localize(ASPECT_LABELS[wpAspectName] ?? \"\"),\n aspectIcon: ASPECT_ICONS[wpAspectName] ?? \"\",\n totalDice: wpTotalDice,\n modifiersText: wpModParts.length ? wpModParts.join(\" \u00B7 \") : \"\",\n spellPower: null,\n rollDifficulty: null,\n actorName: actor.name ?? \"\",\n actorImg: actor.img ?? \"\",\n // weapon-specific\n weaponName: wpItem.name,\n damageBase: wpDamageBase,\n totalDamage: wpResults.successesdice * wpDamageBase,\n ...wpResults,\n aspect: wpAspectName,\n d1: wpFaces[1], d2: wpFaces[2], d3: wpFaces[3], d4: wpFaces[4], d5: wpFaces[5],\n d6: wpFaces[6], d7: wpFaces[7], d8: wpFaces[8], d9: wpFaces[9], d0: wpFaces[0],\n }, wpRoll, ROLL_MODES[wpThrowMode] ?? \"roll\")\n\n if (game.modules.get(\"dice-so-nice\")?.active && wpMsg?.id) {\n await game.dice3d.waitFor3DAnimationByMessageID(wpMsg.id)\n }\n // Auto-update Loksyu/TinJi singletons from weapon roll faces\n if ((wpResults.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wpAspectName, wpFaces)\n if ((wpResults.tinjidice ?? 0) > 0) await updateTinjiFromRoll(wpResults.tinjidice)\n return\n }\n default:\n ui.notifications.warn(`Unknown roll type: ${typeLibel}`)\n return\n }\n\n // For magic rolls the prompt allows adding HEI dice, so don't block early.\n // For itemkungfu, allow 0 base dice (user can add bonus dice in the prompt).\n if (numberofdice <= 0 && typeLibel !== \"aspect\" && typeLibel !== \"itemkungfu\" && !isMagic) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n // ---- Pre-compute default aspect for magic based on skill ----\n const MAGIC_ASPECTS = {\n internalcinnabar: 0, // metal\n alchemy: 1, // water\n masteryoftheway: 2, // earth\n exorcism: 3, // fire\n geomancy: 4, // wood\n }\n\n let defaultAspect = typeLibel === \"aspect\"\n ? [\"metal\",\"water\",\"earth\",\"fire\",\"wood\"].indexOf(skillLibel)\n : 0\n if (isMagic && MAGIC_ASPECTS[skillLibel] !== undefined) {\n defaultAspect = MAGIC_ASPECTS[skillLibel]\n }\n if (kfDefaultAspect >= 0) {\n defaultAspect = kfDefaultAspect\n }\n\n let defaultSpecialAspect = 0\n if (isMagicSpecial && specialLibel) {\n // Look up the speciality's element from the MAGICS config constant\n const specialCfg = MAGICS?.[skillLibel]?.speciality?.[specialLibel]\n const aspectName = LABELELEMENT_TO_ASPECT[specialCfg?.labelelement]\n if (aspectName) {\n defaultSpecialAspect = ASPECT_NAMES.indexOf(aspectName)\n }\n }\n\n // ---- Show roll prompt ----\n let params\n\n if (isMagic) {\n params = await showMagicPrompt({\n title,\n numberofdice,\n aspectskill: defaultAspect,\n bonusmalusskill: 0,\n bonusauspiciousdice: 0,\n aspectspeciality: defaultSpecialAspect,\n rolldifficulty: 1,\n bonusmalusspeciality: 0,\n heispend: 0,\n typeofthrow: typeOfThrow,\n })\n } else {\n params = await showSkillPrompt({\n title,\n numberofdice,\n aspect: defaultAspect,\n bonusmalus: 0,\n woundmalus: 0,\n bonusauspiciousdice: 0,\n typeofthrow: typeOfThrow,\n isSpecial,\n })\n }\n\n if (!params) return // cancelled\n\n // ---- Compute total dice and roll ----\n let aspectIndex, bonusMalus, bonusAuspicious, throwMode\n let spellAspectIndex = null // magic only: aspect of the speciality for Wu Xing\n let rollDifficulty = 1 // magic only: multiplier applied to successes\n\n if (isMagic) {\n const skillAspectIndex = Number(params.aspectskill ?? 0)\n spellAspectIndex = Number(params.aspectspeciality ?? skillAspectIndex)\n aspectIndex = skillAspectIndex // used only for skill dice pool\n bonusMalus = Number(params.bonusmalusskill ?? 0)\n bonusAuspicious = Number(params.bonusauspiciousdice ?? 0)\n rollDifficulty = Math.max(1, Number(params.rolldifficulty ?? 1))\n throwMode = Number(params.typeofthrow ?? 0)\n // magic: magic skill + aspect + bonuses + 1 (speciality base) + HEI spent\n const aspectDice = sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0\n const bonusSpec = Number(params.bonusmalusspeciality ?? 0)\n const heiDice = Number(params.heispend ?? 0)\n numberofdice = numberofdice + aspectDice + bonusMalus + 1 + bonusSpec + heiDice\n } else {\n aspectIndex = Number(params.aspect ?? 0)\n bonusMalus = Number(params.bonusmalus ?? 0)\n const woundMalus = Number(params.woundmalus ?? 0)\n bonusAuspicious = Number(params.bonusauspiciousdice ?? 0)\n throwMode = Number(params.typeofthrow ?? 0)\n\n const aspectDice = (typeLibel !== \"aspect\")\n ? (sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0)\n : 0\n\n numberofdice = numberofdice + aspectDice + bonusMalus - woundMalus\n if (isSpecial) numberofdice += 1 // +1d for speciality\n }\n\n if (numberofdice <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n // ---- Roll ----\n const roll = new Roll(`${numberofdice}d10`)\n await roll.evaluate()\n\n const rollModeKey = ROLL_MODES[throwMode] ?? \"roll\"\n\n // ---- Compute Wu Xing results ----\n // For magic rolls, the spell's aspect (aspectspeciality) governs the Wu Xing\n // cycle (which faces count as successes/auspicious/etc.), not the skill aspect.\n const wuXingAspectName = spellAspectIndex !== null\n ? ASPECT_NAMES[spellAspectIndex]\n : ASPECT_NAMES[aspectIndex]\n const allResults = roll.dice[0]?.results ?? []\n const faces = countFaces(allResults)\n const results = computeWuXingResults(faces, wuXingAspectName, bonusAuspicious)\n if (!results) return\n\n // For magic, successesdice \u00D7 rollDifficulty = spell power\n const spellPower = isMagic ? results.successesdice * rollDifficulty : null\n\n // ---- Build modifier summary text ----\n const modParts = []\n if (isMagic) {\n const bm = Number(params.bonusmalusskill ?? 0)\n const bs = Number(params.bonusmalusspeciality ?? 0)\n const hs = Number(params.heispend ?? 0)\n const ba = Number(params.bonusauspiciousdice ?? 0)\n if (bm !== 0) modParts.push(`${bm > 0 ? \"+\" : \"\"}${bm} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (bs !== 0) modParts.push(`${bs > 0 ? \"+\" : \"\"}${bs} ${game.i18n.localize(\"CDE.SpellBonus\")}`)\n if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n if (hs !== 0) modParts.push(`${hs} ${game.i18n.localize(\"CDE.HeiSpend\")}`)\n if (rollDifficulty !== 1) modParts.push(`\u00D7${rollDifficulty} ${game.i18n.localize(\"CDE.RollDifficulty\")}`)\n } else {\n const bm = Number(params.bonusmalus ?? 0)\n const wm = Number(params.woundmalus ?? 0)\n const ba = Number(params.bonusauspiciousdice ?? 0)\n if (bm !== 0) modParts.push(`${bm > 0 ? \"+\" : \"\"}${bm} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (wm !== 0) modParts.push(`-${wm} ${game.i18n.localize(\"CDE.WoundMalus\")}`)\n if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n }\n\n // ---- Send single enriched ChatMessage (roll + result card) ----\n const msg = await sendResultMessage(actor, {\n // Roll identity\n rollLabel: title,\n aspectName: wuXingAspectName,\n aspectLabel: game.i18n.localize(ASPECT_LABELS[wuXingAspectName] ?? \"\"),\n aspectIcon: ASPECT_ICONS[wuXingAspectName] ?? \"\",\n totalDice: numberofdice,\n modifiersText: modParts.length ? modParts.join(\" \u00B7 \") : \"\",\n // Spell power (magic only)\n spellPower,\n rollDifficulty: isMagic ? rollDifficulty : null,\n // Actor info\n actorName: actor.name ?? \"\",\n actorImg: actor.img ?? \"\",\n // Wu Xing results\n aspect: wuXingAspectName,\n ...results,\n // Die face counts\n d1: faces[1], d2: faces[2], d3: faces[3], d4: faces[4], d5: faces[5],\n d6: faces[6], d7: faces[7], d8: faces[8], d9: faces[9], d0: faces[0],\n }, roll, rollModeKey)\n\n // ---- Wait for Dice So Nice animation ----\n if (game.modules.get(\"dice-so-nice\")?.active && msg?.id) {\n await game.dice3d.waitFor3DAnimationByMessageID(msg.id)\n }\n\n // ---- Auto-update Loksyu / TinJi singletons ----\n if ((results.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wuXingAspectName, faces)\n if ((results.tinjidice ?? 0) > 0) await updateTinjiFromRoll(results.tinjidice)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst { HandlebarsApplicationMixin } = foundry.applications.api\n\nexport class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {\n static DEFAULT_OPTIONS = {\n classes: [\"fvtt-chroniques-de-l-etrange\", \"actor\"],\n position: { width: 920, height: 800 },\n window: { resizable: true },\n form: { submitOnChange: true },\n dragDrop: [{ dragSelector: \".item, [data-drag='true']\", dropSelector: null }],\n actions: {\n create: CDEBaseActorSheet.#onItemCreate,\n edit: CDEBaseActorSheet.#onItemEdit,\n delete: CDEBaseActorSheet.#onItemDelete,\n editImage: CDEBaseActorSheet.#onEditImage,\n },\n }\n\n tabGroups = { primary: \"description\" }\n\n get title() {\n return this.document.name\n }\n\n async _prepareContext() {\n const descriptionHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? \"\", { async: true })\n const cssClass = this.options.classes?.join(\" \") ?? \"\"\n return {\n actor: this.document,\n system: this.document.system,\n systemData: this.document.system,\n systemFields: this.document.system.schema.fields,\n items: this.document.items.contents,\n descriptionHTML,\n editable: this.isEditable,\n cssClass,\n }\n }\n\n // Restore the active tab after every render (including re-renders from submitOnChange).\n // AppV2 does NOT preserve tab state natively \u2014 we must re-apply it from this.tabGroups,\n // which is dynamically updated by changeTab() when the user clicks a tab.\n _onRender(context, options) {\n super._onRender?.(context, options)\n for (const [group, tab] of Object.entries(this.tabGroups)) {\n this.changeTab(tab, group, { force: true })\n }\n }\n\n static async #onItemCreate(event, target) {\n const type = target.dataset.type ?? \"item\"\n const cls = getDocumentClass(\"Item\")\n const labels = {\n item: \"CDE.ItemNew\",\n weapon: \"CDE.WeaponNew\",\n armor: \"CDE.ArmorNew\",\n sanhei: \"CDE.SanheiNew\",\n ingredient: \"CDE.IngredientNew\",\n kungfu: \"CDE.KFNew\",\n spell: \"CDE.SpellNew\",\n supernatural: \"CDE.SupernaturalNew\",\n }\n const name = game.i18n.localize(labels[type] ?? \"CDE.ItemNew\")\n const systemData = {}\n if (type === \"spell\" && target.dataset.discipline) {\n systemData.discipline = target.dataset.discipline\n }\n return cls.create({ name, type, system: systemData }, { parent: this.document })\n }\n\n static #onItemEdit(event, target) {\n const itemId = target.dataset.itemId ?? target.closest(\"[data-item-id]\")?.dataset.itemId\n const item = this.document.items.get(itemId)\n if (item) item.sheet.render(true)\n }\n\n static #onItemDelete(event, target) {\n const itemId = target.dataset.itemId ?? target.closest(\"[data-item-id]\")?.dataset.itemId\n const item = this.document.items.get(itemId)\n if (item) item.delete()\n }\n\n static async #onEditImage(event, target) {\n const attr = target.dataset.edit\n const current = foundry.utils.getProperty(this.document, attr)\n const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}\n const fp = new FilePicker({\n current,\n type: \"image\",\n redirectToRoot: img ? [img] : [],\n callback: (path) => this.document.update({ [attr]: path }),\n top: this.position.top + 40,\n left: this.position.left + 10,\n })\n return fp.browse()\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS, SUBTYPES } from \"../../../config/constants.js\"\nimport { rollInitiativePC } from \"../../initiative.js\"\nimport { rollForActor } from \"../../rolling.js\"\nimport { CDEBaseActorSheet } from \"./base.js\"\n\nexport class CDECharacterSheet extends CDEBaseActorSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"character\"],\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-character-sheet.html\" },\n }\n\n tabGroups = { primary: \"description\" }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n context.equipments = context.items.filter((item) => item.type === \"item\")\n context.weapons = context.items.filter((item) => item.type === \"weapon\")\n context.armors = context.items.filter((item) => item.type === \"armor\")\n context.sanheis = context.items.filter((item) => item.type === \"sanhei\")\n context.ingredients = context.items.filter((item) => item.type === \"ingredient\")\n context.spells = context.items.filter((item) => item.type === \"spell\")\n context.kungfus = context.items.filter((item) => item.type === \"kungfu\")\n context.CDE = { MAGICS, SUBTYPES }\n\n // Group spells by discipline key (matches MAGICS keys)\n const spellsByDiscipline = {}\n for (const spell of context.spells) {\n const disc = spell.system?.discipline ?? \"internalcinnabar\"\n if (!spellsByDiscipline[disc]) spellsByDiscipline[disc] = []\n spellsByDiscipline[disc].push(spell)\n }\n\n // Build magicsDisplay: only include the 5 relevant specialities per magic type + grimoire\n const systemMagics = context.systemData.magics ?? {}\n context.magicsDisplay = Object.fromEntries(\n Object.entries(MAGICS).map(([magicKey, magicDef]) => {\n const magicData = systemMagics[magicKey] ?? {}\n return [\n magicKey,\n {\n value: magicData.value ?? 0,\n visible: magicData.visible ?? false,\n speciality: Object.fromEntries(\n Object.keys(magicDef.speciality).map((specKey) => [\n specKey,\n { check: magicData.speciality?.[specKey]?.check ?? false },\n ])\n ),\n grimoire: spellsByDiscipline[magicKey] ?? [],\n },\n ]\n })\n )\n\n return context\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInitiativeControls()\n this.#bindPrefs()\n this.#bindRollButtons()\n this.#bindComponentRandomize()\n this.#bindDiagramZoom()\n }\n\n #bindInitiativeControls() {\n const buttons = this.element?.querySelectorAll(\".click-initiative\")\n if (!buttons?.length) return\n buttons.forEach((button) => {\n button.addEventListener(\"click\", async () => {\n const action = button.dataset.libelId\n let initiative = this.document.system.initiative ?? 1\n if (action === \"plus\") {\n initiative = initiative >= 24 ? 1 : initiative + 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"minus\") {\n initiative = initiative <= 1 ? 24 : initiative - 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"create\") {\n await rollInitiativePC(this.document)\n }\n })\n })\n }\n\n #bindPrefs() {\n const button = this.element?.querySelector(\".click-prefs\")\n if (!button) return\n button.addEventListener(\"click\", async () => {\n const current = this.document.system.prefs?.typeofthrow ?? { choice: \"0\", check: true }\n const html = `\n
\n
\n \n \n
\n
\n \n \n
\n
`\n const prefs = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.Preferences\") },\n content: html,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => {\n const root = dialog.element ?? dialog\n const choice = root.querySelector(\"select[name='choice']\")?.value ?? \"0\"\n const check = root.querySelector(\"input[name='check']\")?.checked ?? false\n return { choice, check }\n },\n },\n })\n if (prefs) {\n await this.document.update({\n \"system.prefs.typeofthrow.choice\": String(prefs.choice),\n \"system.prefs.typeofthrow.check\": !!prefs.check,\n })\n }\n })\n }\n\n #bindRollButtons() {\n const cells = this.element?.querySelectorAll(\"td.click[data-libel-id], td.click2[data-libel-id], .cde-roll-trigger[data-libel-id]\")\n if (!cells?.length) return\n cells.forEach((cell) => {\n cell.addEventListener(\"click\", (event) => {\n event.preventDefault()\n const rollKey = cell.dataset.libelId\n if (rollKey) rollForActor(this.document, rollKey)\n })\n })\n }\n\n #bindDiagramZoom() {\n const img = this.element?.querySelector(\"[data-action='zoom-diagram']\")\n if (!img) return\n img.addEventListener(\"click\", () => {\n new ImagePopout(img.src, {\n title: game.i18n.localize(\"CDE.NghangDiagramTitle\"),\n shareable: false,\n }).render(true)\n })\n }\n\n #bindComponentRandomize() {\n const btn = this.element?.querySelector(\"[data-action='randomize-component']\")\n if (!btn) return\n btn.addEventListener(\"click\", async () => {\n const roll = new Roll(\"1d10\")\n await roll.evaluate()\n const face = roll.total === 10 ? 0 : roll.total\n const COMPONENT_KEYS = { 1:\"one\", 2:\"two\", 3:\"three\", 4:\"four\", 5:\"five\",\n 6:\"six\", 7:\"seven\", 8:\"eight\", 9:\"nine\", 0:\"zero\" }\n const componentKey = COMPONENT_KEYS[face]\n const componentValue = this.document.system.component?.[componentKey]?.value ?? \"\"\n const label = componentValue\n ? `${componentValue}`\n : `${game.i18n.localize(\"CDE.Component\")}${face}`\n const content = `\n
\n ${game.i18n.localize(\"CDE.ChanceThrowResult\")}\n ${label}\n
`\n await ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor: this.document }),\n content,\n rolls: [roll],\n rollMode: game.settings.get(\"core\", \"rollMode\") ?? \"roll\",\n })\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { rollInitiativeNPC } from \"../../initiative.js\"\nimport { rollForActor } from \"../../rolling.js\"\nimport { CDEBaseActorSheet } from \"./base.js\"\n\nexport class CDENpcSheet extends CDEBaseActorSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"npc\"],\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-npc-sheet.html\" },\n }\n\n tabGroups = { primary: \"description\" }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n context.supernaturals = context.items.filter((item) => item.type === \"supernatural\")\n context.spells = context.items.filter((item) => item.type === \"spell\")\n context.kungfus = context.items.filter((item) => item.type === \"kungfu\")\n context.weapons = context.items.filter((item) => item.type === \"weapon\")\n context.armors = context.items.filter((item) => item.type === \"armor\")\n context.equipments = context.items.filter((item) => item.type === \"item\")\n return context\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInitiativeControls()\n this.#bindRollButtons()\n }\n\n #bindRollButtons() {\n const cells = this.element?.querySelectorAll(\".cde-roll-trigger[data-libel-id]\")\n if (!cells?.length) return\n cells.forEach((cell) => {\n cell.addEventListener(\"click\", (event) => {\n event.preventDefault()\n const rollKey = cell.dataset.libelId\n if (rollKey) rollForActor(this.document, rollKey)\n })\n })\n }\n\n #bindInitiativeControls() {\n const buttons = this.element?.querySelectorAll(\".click-initiative-npc\")\n if (!buttons?.length) return\n buttons.forEach((button) => {\n button.addEventListener(\"click\", async () => {\n const action = button.dataset.libelId\n let initiative = this.document.system.initiative ?? 1\n if (action === \"plus\") {\n initiative = initiative >= 24 ? 1 : initiative + 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"minus\") {\n initiative = initiative <= 1 ? 24 : initiative - 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"create\") {\n await rollInitiativeNPC(this.document)\n }\n })\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst { HandlebarsApplicationMixin } = foundry.applications.api\n\nexport class CDEBaseItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {\n static DEFAULT_OPTIONS = {\n classes: [\"fvtt-chroniques-de-l-etrange\", \"item\"],\n position: { width: 520, height: \"auto\" },\n window: { resizable: true },\n form: { submitOnChange: true },\n actions: {\n editImage: CDEBaseItemSheet.#onEditImage,\n },\n }\n\n tabGroups = { primary: \"details\" }\n\n get title() {\n return this.document.name\n }\n\n async _prepareContext() {\n const cssClass = this.options.classes?.join(\" \") ?? \"\"\n const enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? \"\", { async: true })\n const enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes ?? \"\", { async: true })\n return {\n item: this.document,\n system: this.document.system,\n systemData: this.document.system,\n systemFields: this.document.system.schema.fields,\n editable: this.isEditable,\n cssClass,\n enrichedDescription,\n enrichedNotes,\n descriptionHTML: enrichedDescription,\n notesHTML: enrichedNotes,\n }\n }\n\n // Restore the active tab after every render (including re-renders from submitOnChange).\n _onRender(context, options) {\n super._onRender?.(context, options)\n for (const [group, tab] of Object.entries(this.tabGroups)) {\n this.changeTab(tab, group, { force: true })\n }\n }\n\n static async #onEditImage(event, target) {\n const attr = target.dataset.edit\n const current = foundry.utils.getProperty(this.document, attr)\n const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}\n const fp = new FilePicker({\n current,\n type: \"image\",\n redirectToRoot: img ? [img] : [],\n callback: (path) => this.document.update({ [attr]: path }),\n top: this.position.top + 40,\n left: this.position.left + 10,\n })\n return fp.browse()\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEItemSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"equipment\"],\n position: { width: 560, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-item-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEKungfuSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"kungfu\"],\n position: { width: 720, height: 680 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-kungfu-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const techniques = this.document.system.techniques ?? {}\n const enrich = (value) => foundry.applications.ux.TextEditor.implementation.enrichHTML(value ?? \"\", { async: true })\n context.descriptionTechnique1HTML = await enrich(techniques.technique1?.technique)\n context.descriptionTechnique2HTML = await enrich(techniques.technique2?.technique)\n context.descriptionTechnique3HTML = await enrich(techniques.technique3?.technique)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESpellSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"spell\"],\n position: { width: 660, height: 680 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-spell-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n context.spellDescriptionHTML = await enrich(this.document.system.description)\n context.componentsDescriptionHTML = await enrich(this.document.system.components)\n context.effectsDescriptionHTML = await enrich(this.document.system.effects)\n context.examplesDescriptionHTML = await enrich(this.document.system.examples)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESupernaturalSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"supernatural\"],\n position: { width: 560, height: 520 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-supernatural-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n context.effectsHTML = await enrich(this.document.system.effects)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEWeaponSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"weapon\"],\n position: { width: 580, height: 520 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-weapon-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEArmorSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"armor\"],\n position: { width: 520, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-armor-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESanheiSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"sanhei\"],\n position: { width: 580, height: 620 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-sanhei-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n const props = this.document.system.properties\n context.prop1DescriptionHTML = await enrich(props.prop1.description)\n context.prop2DescriptionHTML = await enrich(props.prop2.description)\n context.prop3DescriptionHTML = await enrich(props.prop3.description)\n context.propFields = this.document.system.schema.fields.properties.fields\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEIngredientSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"ingredient\"],\n position: { width: 520, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-ingredient-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { getLoksyuData, setLoksyuData } from \"./singletons.js\"\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nexport class CDELoksyuApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-loksyu-app\",\n tag: \"div\",\n window: {\n title: \"CDE.Loksyu\",\n icon: \"fas fa-yin-yang\",\n resizable: false,\n },\n classes: [\"cde-app\", \"cde-loksyu-standalone\"],\n position: { width: 520, height: \"auto\" },\n actions: {\n resetElement: CDELoksyuApp.#onResetElement,\n resetAll: CDELoksyuApp.#onResetAll,\n zoomVisual: CDELoksyuApp.#onZoomVisual,\n },\n }\n\n static PARTS = {\n main: {\n template: `systems/${SYSTEM_ID}/templates/apps/cde-loksyu-app.html`,\n },\n }\n\n /** @type {Function|null} bound hook handler */\n _updateHook = null\n\n /** Singleton accessor \u2014 open or bring to front */\n static open() {\n const existing = Array.from(foundry.applications.instances.values()).find(\n (app) => app instanceof CDELoksyuApp\n )\n if (existing) { existing.bringToFront(); return existing }\n const app = new CDELoksyuApp()\n app.render(true)\n return app\n }\n\n async _prepareContext() {\n const sys = getLoksyuData()\n const ELEMENTS = [\n { key: \"wood\", nameKey: \"CDE.Wood\", qualKey: \"CDE.WoodQualities\", img: `systems/${SYSTEM_ID}/images/cde_bois.webp` },\n { key: \"fire\", nameKey: \"CDE.Fire\", qualKey: \"CDE.FireQualities\", img: `systems/${SYSTEM_ID}/images/cde_feu.webp` },\n { key: \"earth\", nameKey: \"CDE.Earth\", qualKey: \"CDE.EarthQualities\", img: `systems/${SYSTEM_ID}/images/cde_terre.webp` },\n { key: \"metal\", nameKey: \"CDE.Metal\", qualKey: \"CDE.MetalQualities\", img: `systems/${SYSTEM_ID}/images/cde_metal.webp` },\n { key: \"water\", nameKey: \"CDE.Water\", qualKey: \"CDE.WaterQualities\", img: `systems/${SYSTEM_ID}/images/cde_eau.webp` },\n ]\n\n return {\n canEdit: game.user.isGM,\n elements: ELEMENTS.map((el) => ({\n ...el,\n yang: sys[el.key]?.yang ?? 0,\n yin: sys[el.key]?.yin ?? 0,\n })),\n }\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInputs()\n\n this._updateHook = Hooks.on(\"cde:loksyuUpdated\", () => this.render())\n }\n\n _onClose(options) {\n if (this._updateHook !== null) {\n Hooks.off(\"cde:loksyuUpdated\", this._updateHook)\n this._updateHook = null\n }\n super._onClose(options)\n }\n\n #bindInputs() {\n const inputs = this.element?.querySelectorAll(\"input[data-field]\")\n if (!inputs?.length) return\n inputs.forEach((input) => {\n input.addEventListener(\"change\", async (ev) => {\n const field = ev.currentTarget.dataset.field\n const val = parseInt(ev.currentTarget.value, 10)\n if (!field || isNaN(val)) return\n // field is like \"wood.yin\" or \"fire.yang\"\n const [aspect, dim] = field.split(\".\")\n if (!aspect || !dim) return\n const data = getLoksyuData()\n if (!data[aspect]) data[aspect] = { yin: 0, yang: 0 }\n data[aspect][dim] = Math.max(0, val)\n await setLoksyuData(data)\n })\n })\n }\n\n static async #onResetElement(event, target) {\n const key = target.dataset.element\n if (!key) return\n const data = getLoksyuData()\n data[key] = { yin: 0, yang: 0 }\n await setLoksyuData(data)\n }\n\n static async #onResetAll(_event, _target) {\n const KEYS = [\"wood\", \"fire\", \"earth\", \"metal\", \"water\"]\n const data = getLoksyuData()\n for (const k of KEYS) data[k] = { yin: 0, yang: 0 }\n await setLoksyuData(data)\n }\n\n static #onZoomVisual(_event, target) {\n new ImagePopout(target.src, {\n title: game.i18n.localize(\"CDE.LoksyuDiagramTitle\"),\n shareable: false,\n }).render(true)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { getTinjiValue, setTinjiValue } from \"./singletons.js\"\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nexport class CDETinjiApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-tinji-app\",\n tag: \"div\",\n window: {\n title: \"CDE.TinJi2\",\n icon: \"fas fa-star\",\n resizable: false,\n },\n classes: [\"cde-app\", \"cde-tinji-standalone\"],\n position: { width: 380, height: \"auto\" },\n actions: {\n increment: CDETinjiApp.#onIncrement,\n decrement: CDETinjiApp.#onDecrement,\n reset: CDETinjiApp.#onReset,\n spend: CDETinjiApp.#onSpend,\n },\n }\n\n static PARTS = {\n main: {\n template: `systems/${SYSTEM_ID}/templates/apps/cde-tinji-app.html`,\n },\n }\n\n /** @type {Function|null} */\n _updateHook = null\n\n static open() {\n const existing = Array.from(foundry.applications.instances.values()).find(\n (app) => app instanceof CDETinjiApp\n )\n if (existing) { existing.bringToFront(); return existing }\n const app = new CDETinjiApp()\n app.render(true)\n return app\n }\n\n async _prepareContext() {\n return {\n canEdit: game.user.isGM,\n value: getTinjiValue(),\n }\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindDirectInput()\n this._updateHook = Hooks.on(\"cde:tinjiUpdated\", () => this.render())\n }\n\n _onClose(options) {\n if (this._updateHook !== null) {\n Hooks.off(\"cde:tinjiUpdated\", this._updateHook)\n this._updateHook = null\n }\n super._onClose(options)\n }\n\n #bindDirectInput() {\n const input = this.element?.querySelector(\"input.cde-tinji-direct\")\n if (!input) return\n input.addEventListener(\"change\", async (ev) => {\n const val = parseInt(ev.currentTarget.value, 10)\n if (!isNaN(val)) await setTinjiValue(val)\n })\n }\n\n static async #onIncrement() {\n await setTinjiValue(getTinjiValue() + 1)\n }\n\n static async #onDecrement() {\n const current = getTinjiValue()\n if (current <= 0) return\n await setTinjiValue(current - 1)\n }\n\n static async #onReset() {\n await setTinjiValue(0)\n }\n\n static async #onSpend() {\n const current = getTinjiValue()\n if (current <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.TinjiEmpty\"))\n return\n }\n await setTinjiValue(current - 1)\n ChatMessage.create({\n user: game.user.id,\n content: `
\n \n ${game.i18n.localize(\"CDE.TinJi2\")}\n ${game.i18n.format(\"CDE.TinjiSpent\", { name: game.user.name })}\n (${current - 1} ${game.i18n.localize(\"CDE.TinjiRemaining\")})\n
`,\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { rollInitiativePC, rollInitiativeNPC } from \"../ui/initiative.js\"\nimport { ACTOR_TYPES } from \"../config/constants.js\"\n\n/**\n * Custom Combat document for Chroniques de l'\u00C9trange.\n *\n * The initiative wheel has 24 crans (positions). The character with the\n * highest initiative acts first (furthest counter-clockwise from reference).\n * After each action, their position advances clockwise by the action's cran cost\n * (initiative decreases, wrapping from 1 \u2192 24).\n *\n * Sort order: descending by initiative (highest acts first).\n */\nexport class CDECombat extends Combat {\n\n /**\n * Override rollInitiative to open the PC or NPC initiative dialog\n * for each selected combatant, then sync the result to the Combatant document.\n */\n async rollInitiative(ids, options = {}) {\n const combatantIds = typeof ids === \"string\" ? [ids] : ids\n for (const id of combatantIds) {\n const combatant = this.combatants.get(id)\n if (!combatant) continue\n const actor = combatant.actor\n if (!actor) continue\n\n if (actor.type === ACTOR_TYPES.character) {\n await rollInitiativePC(actor)\n } else {\n await rollInitiativeNPC(actor)\n }\n // combatant.initiative is synced by the updateActor hook in system.js\n // (triggered by actor.update inside rollInitiativePC/NPC)\n }\n return this\n }\n\n /**\n * Sort combatants: highest initiative first (furthest counter-clockwise = acts first).\n * Ties: PCs before NPCs; among PCs, by name; among NPCs, by name.\n * Calls super.setupTurns() first to ensure this.current is properly initialized.\n */\n setupTurns() {\n super.setupTurns()\n this.turns = this.turns.slice().sort((a, b) => {\n const ia = a.initiative ?? 0\n const ib = b.initiative ?? 0\n if (ia !== ib) return ib - ia // descending \u2014 highest acts first\n\n // Tie-break: PCs before NPCs\n const aIsPC = a.actor?.type === ACTOR_TYPES.character ? 1 : 0\n const bIsPC = b.actor?.type === ACTOR_TYPES.character ? 1 : 0\n if (aIsPC !== bIsPC) return bIsPC - aIsPC\n\n return (a.name ?? \"\").localeCompare(b.name ?? \"\")\n })\n return this.turns\n }\n}\n\n/**\n * Advance a combatant's wheel position by the given action cran cost.\n * Position wraps: after reaching 1, it continues from 24.\n *\n * @param {Combatant} combatant\n * @param {number} cranCost\n */\nexport async function advanceCombatantPosition(combatant, cranCost) {\n const current = combatant.initiative ?? combatant.actor?.system?.initiative ?? 1\n const newValue = ((current - cranCost - 1 + 48) % 24) + 1\n // Update combatant only; the updateCombatant hook in system.js syncs actor.initiative.\n await combatant.update({ initiative: newValue })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { advanceCombatantPosition } from \"../../documents/combat.js\"\n\nconst WHEEL_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html\"\n\n/**\n * Action costs for common combat actions (in crans).\n * Listed in order from cheapest to most expensive.\n */\nexport const ACTION_COSTS = [\n { key: \"draw\", label: \"CDE.ActionCostDraw\", cost: 1 },\n { key: \"changestyle\", label: \"CDE.ActionCostChangeStyle\", cost: 1 },\n { key: \"defense\", label: \"CDE.ActionCostDefense\", cost: 1 },\n { key: \"aim\", label: \"CDE.ActionCostAim\", cost: 2 },\n { key: \"help\", label: \"CDE.ActionCostHelp\", cost: 2 },\n { key: \"defally\", label: \"CDE.ActionCostDefendAlly\", cost: 2 },\n { key: \"move\", label: \"CDE.ActionCostMove\", cost: 2 },\n { key: \"attack\", label: \"CDE.ActionCostAttack\", cost: 3 },\n { key: \"delay\", label: \"CDE.ActionCostDelay\", cost: 6 },\n]\n\n/**\n * Wu Xing color segments for the 24-cran wheel.\n * 6 colors \u00D7 4 crans = 24. Each colour covers crans [start..start+3].\n * An effect lasting 6 crans returns to the same colour.\n */\nconst WHEEL_SEGMENTS = [\n { label: \"M\u00E9tal\", color: \"#b8c4cc\", textColor: \"#1a1a1a\", crans: [1, 2, 3, 4] },\n { label: \"Eau\", color: \"#3a7bd5\", textColor: \"#ffffff\", crans: [5, 6, 7, 8] },\n { label: \"Terre\", color: \"#c8a84b\", textColor: \"#1a1a1a\", crans: [9, 10, 11, 12] },\n { label: \"Feu\", color: \"#d94f3d\", textColor: \"#ffffff\", crans: [13, 14, 15, 16] },\n { label: \"Bois\", color: \"#4a9b5a\", textColor: \"#ffffff\", crans: [17, 18, 19, 20] },\n { label: \"Rep\u00E8re\", color: \"#1a1a2e\", textColor: \"#aaaaaa\", crans: [21, 22, 23, 24] },\n]\n\n/** Return the segment data for a given cran (1\u201324). */\nfunction segmentForCran(cran) {\n return WHEEL_SEGMENTS.find(s => s.crans.includes(cran)) ?? WHEEL_SEGMENTS[0]\n}\n\n/**\n * Roue d'Initiative \u2014 visual initiative wheel for CDE combat.\n *\n * Shows all combatants in the current combat scene on a 24-cran wheel.\n * Provides action-cost buttons to advance a combatant's position.\n *\n * Singleton: open via CDEWheelApp.open().\n */\nexport class CDEWheelApp extends foundry.applications.api.ApplicationV2 {\n static DEFAULT_OPTIONS = {\n id: \"cde-wheel-app\",\n classes: [\"cde-wheel-app\"],\n tag: \"div\",\n window: {\n title: \"CDE.InitiativeWheel\",\n icon: \"fas fa-circle-notch\",\n resizable: true,\n },\n position: { width: 820, height: 620 },\n actions: {\n advanceCran: CDEWheelApp.#advanceCran,\n setSurprised: CDEWheelApp.#setSurprised,\n rollInitiative: CDEWheelApp.#rollInitiative,\n },\n }\n\n /** @type {CDEWheelApp|null} */\n static #instance = null\n\n /** Open (or bring to front) the singleton instance. */\n static open() {\n if (!CDEWheelApp.#instance || CDEWheelApp.#instance.rendered === false) {\n CDEWheelApp.#instance = new CDEWheelApp()\n CDEWheelApp.#instance.render(true)\n } else {\n CDEWheelApp.#instance.bringToFront()\n }\n return CDEWheelApp.#instance\n }\n\n /** Currently selected combatant id (for action panel). */\n #selectedId = null\n\n async _prepareContext(options) {\n const combat = game.combat\n const combatants = combat ? [...combat.combatants.values()] : []\n const sorted = [...combatants].sort((a, b) => (b.initiative ?? 0) - (a.initiative ?? 0))\n const cranData = this.#buildCranData(combatants)\n const selected = this.#selectedId\n ? combatants.find(c => c.id === this.#selectedId)\n : null\n const actionCosts = ACTION_COSTS.map(a => ({\n ...a,\n label: game.i18n.localize(a.label),\n }))\n\n return {\n hasCombat: !!combat,\n combatants: sorted.map(c => ({\n id: c.id,\n name: c.name,\n img: c.token?.texture?.src ?? c.actor?.img ?? \"icons/svg/mystery-man.svg\",\n initiative: c.initiative ?? \"\u2014\",\n segment: segmentForCran(c.initiative ?? 1),\n isActive: combat?.current?.combatantId === c.id,\n isSelected: c.id === this.#selectedId,\n hasInitiative: c.initiative != null,\n })),\n cranData,\n selected,\n selectedName: selected?.name ?? null,\n actionCosts,\n }\n }\n\n async _renderHTML(context, options) {\n return foundry.applications.handlebars.renderTemplate(WHEEL_TEMPLATE, context)\n }\n\n _replaceHTML(result, content, options) {\n content.innerHTML = result\n this.#bindEvents(content)\n }\n\n /** Build per-cran data for the SVG wheel. */\n #buildCranData(combatants) {\n const data = []\n for (let cran = 1; cran <= 24; cran++) {\n const segment = segmentForCran(cran)\n const fighters = combatants.filter(c => Math.round(c.initiative) === cran)\n data.push({ cran, segment, fighters })\n }\n return data\n }\n\n /** Bind click events for combatant selection. */\n #bindEvents(content) {\n content.querySelectorAll(\"[data-select-combatant]\").forEach(el => {\n el.addEventListener(\"click\", () => {\n this.#selectedId = el.dataset.selectCombatant\n this.render()\n })\n })\n }\n\n /** Action: advance selected combatant by given cran cost. */\n static async #advanceCran(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const cost = parseInt(element.dataset.cost, 10)\n if (!cost || isNaN(cost)) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n await advanceCombatantPosition(combatant, cost)\n }\n\n /** Action: set selected combatant to surprised (position 1 = reference). */\n static async #setSurprised(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n // Update combatant only \u2014 updateCombatant hook in system.js syncs actor\n await combatant.update({ initiative: 1 })\n }\n\n /** Action: open the initiative dialog for the selected combatant. */\n static async #rollInitiative(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n await game.combat.rollInitiative([app.#selectedId])\n }\n\n /** Re-render when combat state changes. */\n static registerHooks() {\n const refresh = () => {\n if (CDEWheelApp.#instance?.rendered) CDEWheelApp.#instance.render()\n }\n Hooks.on(\"updateCombat\", refresh)\n Hooks.on(\"updateCombatant\", refresh)\n Hooks.on(\"createCombatant\", refresh)\n Hooks.on(\"deleteCombatant\", refresh)\n Hooks.on(\"updateActor\", (_actor, diff) => {\n if (foundry.utils.hasProperty(diff, \"system.initiative\")) refresh()\n })\n Hooks.on(\"deleteCombat\", () => {\n if (CDEWheelApp.#instance?.rendered) CDEWheelApp.#instance.render()\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Post-roll interactive action buttons injected into dice result chat messages.\n * Allows players to pull dice from the Loksyu (as Successes or d\u00E9s-fastes)\n * and allows the GM to spend Tin Ji to intervene.\n *\n * After a draw, the originating roll result message is updated in-place\n * with the new counts, without creating noise.\n */\n\nimport { getLoksyuData, setLoksyuData, getTinjiValue, setTinjiValue } from \"./apps/singletons.js\"\nimport { SYSTEM_ID, WU_XING_CYCLE, ASPECT_LABELS, ASPECT_ICONS } from \"../config/constants.js\"\n\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html\"\n\n/**\n * Inject or refresh post-roll action buttons in the given chat message HTML element.\n * Called from renderChatMessageHTML hook.\n * @param {ChatMessage} message\n * @param {HTMLElement} html - the chat message HTML element (li.chat-message)\n */\nexport function injectRollActions(message, html) {\n const rollCard = html.querySelector(\".cde-roll-result\")\n if (!rollCard) return\n const aspect = rollCard.dataset.aspect\n if (!aspect || !WU_XING_CYCLE[aspect]) return\n refreshRollActions(rollCard, aspect, message)\n}\n\n/**\n * Re-render the action buttons section based on current Loksyu / TinJi state.\n */\nfunction refreshRollActions(rollCard, aspect, message) {\n rollCard.querySelector(\".cde-roll-actions\")?.remove()\n\n const cycle = WU_XING_CYCLE[aspect]\n const fasteAspect = cycle[1]\n\n const loksyu = getLoksyuData()\n const tinji = getTinjiValue()\n\n const successAvail = (loksyu[aspect]?.yin ?? 0) + (loksyu[aspect]?.yang ?? 0)\n const fasteAvail = (loksyu[fasteAspect]?.yin ?? 0) + (loksyu[fasteAspect]?.yang ?? 0)\n const isGM = game.user.isGM\n\n const hasSomething = successAvail > 0 || fasteAvail > 0 || (isGM && tinji > 0)\n if (!hasSomething) return\n\n const aspLabel = game.i18n.localize(ASPECT_LABELS[aspect])\n const fasteLabel = game.i18n.localize(ASPECT_LABELS[fasteAspect])\n\n let btns = \"\"\n\n if (successAvail > 0) {\n btns += ``\n }\n\n if (fasteAvail > 0) {\n btns += ``\n }\n\n if (isGM && tinji > 0) {\n btns += ``\n }\n\n const wrapper = document.createElement(\"div\")\n wrapper.className = \"cde-roll-actions\"\n wrapper.innerHTML = `\n
\n \n ${game.i18n.localize(\"CDE.PostRollActions\")}\n
\n
${btns}
\n `\n rollCard.appendChild(wrapper)\n\n wrapper.addEventListener(\"click\", async ev => {\n const btn = ev.target.closest(\"[data-action]\")\n if (!btn || btn.disabled) return\n const action = btn.dataset.action\n if (action === \"loksyu-success\") {\n await _drawFromLoksyu(message, aspect, \"success\", aspLabel)\n } else if (action === \"loksyu-faste\") {\n await _drawFromLoksyu(message, fasteAspect, \"faste\", fasteLabel)\n } else if (action === \"tinji\") {\n await _spendTinjiPostRoll()\n }\n // Buttons will be re-injected automatically via renderChatMessageHTML\n // after message.update(). For tinji (no message update), refresh manually.\n if (action === \"tinji\") refreshRollActions(rollCard, aspect, message)\n })\n}\n\n/**\n * Pull one die from a given Loksyu aspect slot, update Loksyu settings,\n * and update the originating roll-result message in-place.\n *\n * @param {ChatMessage} message - the roll result chat message to update\n * @param {string} aspect - which Loksyu aspect slot to draw from\n * @param {\"success\"|\"faste\"} type\n * @param {string} aspectLabel - localised aspect name for the notification\n */\nasync function _drawFromLoksyu(message, aspect, type, aspectLabel) {\n const data = getLoksyuData()\n const entry = data[aspect] ?? { yin: 0, yang: 0 }\n const total = entry.yin + entry.yang\n if (total <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.LoksyuEmpty\"))\n return\n }\n\n // Remove 1 die (prefer yang first)\n if (entry.yang > 0) entry.yang--\n else entry.yin--\n data[aspect] = entry\n await setLoksyuData(data)\n\n // Update the roll-result message in-place if it has stored flags\n const flags = message?.flags?.[SYSTEM_ID]\n if (flags?.rollResult && message.isOwner) {\n const updated = foundry.utils.deepClone(flags.rollResult)\n if (type === \"success\") {\n updated.successesdice = (updated.successesdice ?? 0) + 1\n updated.loksyuBonusSuc = (updated.loksyuBonusSuc ?? 0) + 1\n // Recalculate weapon damage if applicable\n if (updated.damageBase) updated.totalDamage = updated.successesdice * updated.damageBase\n } else {\n updated.auspiciousdice = (updated.auspiciousdice ?? 0) + 1\n updated.loksyuBonusFaste = (updated.loksyuBonusFaste ?? 0) + 1\n }\n const newHtml = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, updated)\n await message.update({\n content: newHtml,\n [`flags.${SYSTEM_ID}.rollResult`]: updated,\n })\n // renderChatMessageHTML hook fires automatically \u2192 buttons re-injected\n }\n\n const remain = entry.yin + entry.yang\n const typeLabel = type === \"success\"\n ? game.i18n.localize(\"CDE.Successes\")\n : game.i18n.localize(\"CDE.AuspiciousDie\")\n\n ChatMessage.create({\n user: game.user.id,\n content: `
\n
\n \"${aspectLabel}\"/\n ${game.user.name}\n ${game.i18n.localize(\"CDE.LoksyuDrawsA\")}\n ${typeLabel}\n ${game.i18n.localize(\"CDE.LoksyuFromAspect\")} ${aspectLabel}\n
\n
\n \n ${game.i18n.localize(\"CDE.Loksyu\")} ${aspectLabel} : \n ${remain} ${game.i18n.localize(\"CDE.LoksyuRemaining\")}\n
\n
`,\n })\n}\n\n/**\n * Spend 1 Tin Ji point (GM only) and post a notification.\n */\nasync function _spendTinjiPostRoll() {\n if (!game.user.isGM) return\n const current = getTinjiValue()\n if (current <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.TinjiEmpty\"))\n return\n }\n await setTinjiValue(current - 1)\n ChatMessage.create({\n user: game.user.id,\n content: `
\n \u5929\n \n ${game.user.name} ${game.i18n.localize(\"CDE.TinjiSpent\").replace(\"{name}\", game.user.name)}\n \n (${current - 1} ${game.i18n.localize(\"CDE.TinjiRemaining\")})\n
`,\n })\n}\n\n/**\n * Refresh all visible roll-result buttons when Loksyu or TinJi settings change.\n * Wired up via Hooks.on(\"updateSetting\", ...) in system.js.\n */\nexport function refreshAllRollActions() {\n document.querySelectorAll(\".chat-message .cde-roll-result[data-aspect]\").forEach(card => {\n const aspect = card.dataset.aspect\n if (!aspect || !WU_XING_CYCLE[aspect]) return\n // Find the ChatMessage document from the ancestor element's data-message-id\n const msgEl = card.closest(\"[data-message-id]\")\n const msgId = msgEl?.dataset?.messageId\n const message = msgId ? game.messages.get(msgId) : null\n refreshRollActions(card, aspect, message)\n })\n}\n\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nconst HELP_JOURNAL_UUID = `Compendium.${SYSTEM_ID}.cde-help.JournalEntry.CDEGuideMain0001`\n\n/** Post a styled welcome chat message. Called once per session by the GM. */\nexport async function showWelcomeMessage() {\n const logo = `systems/${SYSTEM_ID}/images/logo_jeu.webp`\n const content = `\n
\n \"Les\n

Les Chroniques de l'\u00C9trange

\n

\n Un jeu de r\u00F4le \u00E9dit\u00E9 par\n Antre-Monde \u00C9ditions\n

\n

\n Syst\u00E8me FoundryVTT r\u00E9alis\u00E9 par\n LeRatierBretonnien\n

\n \n
`\n\n await ChatMessage.create({\n content,\n speaker: { alias: \"Les Chroniques de l'\u00C9trange\" },\n flags: { [SYSTEM_ID]: { welcome: true } },\n })\n}\n\n/** Attach the help-open click handler to a welcome chat message HTML node. */\nexport function injectWelcomeActions(_message, html) {\n const el = html instanceof HTMLElement ? html : (html[0] ?? html)\n const btn = el?.querySelector?.(\"[data-action='open-cde-help']\")\n if (!btn) return\n\n btn.addEventListener(\"click\", async () => {\n try {\n const doc = await fromUuid(HELP_JOURNAL_UUID)\n doc?.sheet?.render(true)\n } catch {\n // Pack not yet loaded \u2014 open the compendium browser as fallback\n game.packs.get(`${SYSTEM_ID}.cde-help`)?.render(true)\n }\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { ACTOR_TYPES, ITEM_TYPES, MAGICS, SUBTYPES, SYSTEM_ID } from \"./config/constants.js\"\nimport { registerSettings, migrateIfNeeded, loadWelcomeSceneIfNeeded } from \"./config/settings.js\"\nimport { preLocalizeConfig } from \"./config/localize.js\"\nimport { configureRuntime } from \"./config/runtime.js\"\nimport { CharacterDataModel, NpcDataModel } from \"./data/actors/index.js\"\nimport { EquipmentDataModel, KungfuDataModel, SpellDataModel, SupernaturalDataModel, WeaponDataModel, ArmorDataModel, SanheiDataModel, IngredientDataModel } from \"./data/items/index.js\"\nimport { CDEMessage } from \"./documents/chat-message.js\"\nimport { CDEActor } from \"./documents/actor.js\"\nimport { CDEItem } from \"./documents/item.js\"\nimport { registerDice } from \"./ui/dice.js\"\nimport { registerHandlebarsHelpers } from \"./ui/helpers.js\"\nimport { preloadPartials } from \"./ui/templates.js\"\nimport { CDECharacterSheet, CDENpcSheet } from \"./ui/sheets/actors/index.js\"\nimport { CDEItemSheet, CDEKungfuSheet, CDESpellSheet, CDESupernaturalSheet, CDEWeaponSheet, CDEArmorSheet, CDESanheiSheet, CDEIngredientSheet } from \"./ui/sheets/items/index.js\"\nimport { CDELoksyuApp } from \"./ui/apps/loksyu-app.js\"\nimport { CDETinjiApp } from \"./ui/apps/tinji-app.js\"\nimport { CDEWheelApp } from \"./ui/apps/wheel-app.js\"\nimport { injectRollActions, refreshAllRollActions } from \"./ui/roll-actions.js\"\nimport { CDECombat } from \"./documents/combat.js\"\nimport { showWelcomeMessage, injectWelcomeActions } from \"./ui/apps/welcome.js\"\n\nHooks.once(\"i18nInit\", preLocalizeConfig)\n\nHooks.once(\"init\", async () => {\n console.info(`CHRONIQUESDELETRANGE | Initializing ${SYSTEM_ID}`)\n\n registerSettings()\n\n game.system.CONST = { MAGICS, SUBTYPES }\n\n // Expose standalone apps globally for macros\n game.cde = { CDELoksyuApp, CDETinjiApp, CDEWheelApp }\n\n CONFIG.Combat.documentClass = CDECombat\n\n CONFIG.Actor.dataModels = {\n [ACTOR_TYPES.character]: CharacterDataModel,\n [ACTOR_TYPES.npc]: NpcDataModel,\n }\n CONFIG.Item.dataModels = {\n [ITEM_TYPES.item]: EquipmentDataModel,\n [ITEM_TYPES.kungfu]: KungfuDataModel,\n [ITEM_TYPES.spell]: SpellDataModel,\n [ITEM_TYPES.supernatural]: SupernaturalDataModel,\n [ITEM_TYPES.weapon]: WeaponDataModel,\n [ITEM_TYPES.armor]: ArmorDataModel,\n [ITEM_TYPES.sanhei]: SanheiDataModel,\n [ITEM_TYPES.ingredient]: IngredientDataModel,\n }\n\n CONFIG.Actor.documentClass = CDEActor\n CONFIG.Item.documentClass = CDEItem\n CONFIG.ChatMessage.documentClass = CDEMessage\n\n configureRuntime()\n\n foundry.applications.apps.DocumentSheetConfig.unregisterSheet(Actor, \"core\", foundry.appv1.sheets.ActorSheet)\n foundry.applications.apps.DocumentSheetConfig.unregisterSheet(Item, \"core\", foundry.appv1.sheets.ItemSheet)\n\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, SYSTEM_ID, CDECharacterSheet, {\n types: [ACTOR_TYPES.character],\n makeDefault: true,\n label: \"CDE Character Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, SYSTEM_ID, CDENpcSheet, {\n types: [ACTOR_TYPES.npc],\n makeDefault: true,\n label: \"CDE NPC Sheet (V2)\",\n })\n\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEItemSheet, {\n types: [ITEM_TYPES.item],\n makeDefault: true,\n label: \"CDE Item Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEKungfuSheet, {\n types: [ITEM_TYPES.kungfu],\n makeDefault: true,\n label: \"CDE KungFu Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESpellSheet, {\n types: [ITEM_TYPES.spell],\n makeDefault: true,\n label: \"CDE Spell Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESupernaturalSheet, {\n types: [ITEM_TYPES.supernatural],\n makeDefault: true,\n label: \"CDE Supernatural Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEWeaponSheet, {\n types: [ITEM_TYPES.weapon],\n makeDefault: true,\n label: \"CDE Weapon Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEArmorSheet, {\n types: [ITEM_TYPES.armor],\n makeDefault: true,\n label: \"CDE Armor Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESanheiSheet, {\n types: [ITEM_TYPES.sanhei],\n makeDefault: true,\n label: \"CDE Sanhei Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEIngredientSheet, {\n types: [ITEM_TYPES.ingredient],\n makeDefault: true,\n label: \"CDE Ingredient Sheet (V2)\",\n })\n\n await preloadPartials()\n registerHandlebarsHelpers()\n registerDice()\n\n console.info(`CHRONIQUESDELETRANGE | Initialized`)\n})\n\nHooks.once(\"ready\", async () => {\n await migrateIfNeeded()\n await loadWelcomeSceneIfNeeded()\n CDEWheelApp.registerHooks()\n if (game.user.isGM) showWelcomeMessage()\n})\n\n/** Add Loksyu + Tin Ji quick-access buttons to the chat panel (FoundryVTT v13) */\nHooks.on(\"renderChatLog\", (_app, html) => {\n const el = html instanceof HTMLElement ? html : (html[0] ?? html)\n if (!el?.querySelector) return\n\n // Avoid double-injection on re-renders\n if (el.querySelector(\".cde-chat-app-buttons\")) return\n\n const wrapper = document.createElement(\"div\")\n wrapper.classList.add(\"cde-chat-app-buttons\")\n wrapper.innerHTML = `\n \n \n \n `\n\n // Use event delegation to avoid being swallowed by Foundry's own handlers\n wrapper.addEventListener(\"click\", (ev) => {\n if (ev.target.closest(\".cde-chat-btn--loksyu\")) CDELoksyuApp.open()\n if (ev.target.closest(\".cde-chat-btn--tinji\")) CDETinjiApp.open()\n if (ev.target.closest(\".cde-chat-btn--wheel\")) CDEWheelApp.open()\n })\n\n // Insert before the chat form \u2014 works on v12 and v13\n const anchor = el.querySelector(\".chat-form\")\n ?? el.querySelector(\".chat-message-form\")\n ?? el.querySelector(\"form\")\n if (anchor) anchor.parentElement.insertBefore(wrapper, anchor)\n else el.appendChild(wrapper)\n})\n\n/** Inject Loksyu / TinJi action buttons into roll-result chat messages */\nHooks.on(\"renderChatMessageHTML\", (message, html) => {\n injectRollActions(message, html)\n if (message.flags?.[SYSTEM_ID]?.welcome) injectWelcomeActions(message, html)\n})\n\n/** Refresh all visible roll-result buttons whenever Loksyu or TinJi settings change */\nHooks.on(\"updateSetting\", setting => {\n if (!setting.key) return\n if (setting.key.includes(\"loksyuData\") || setting.key.includes(\"tinjiData\")) {\n refreshAllRollActions()\n }\n})\n\n/**\n * When an actor's initiative changes (via +/- buttons on the sheet),\n * sync the corresponding combatant in the active combat.\n */\nHooks.on(\"updateActor\", (actor, diff) => {\n if (!foundry.utils.hasProperty(diff, \"system.initiative\")) return\n if (!game.combat) return\n const initiative = actor.system.initiative\n const combatant = game.combat.combatants.find(c => c.actor?.id === actor.id)\n if (combatant && combatant.initiative !== initiative) {\n combatant.update({ initiative }).catch(() => {})\n }\n})\n\n/**\n * When a combatant's initiative changes (via wheel action buttons),\n * sync the actor's system.initiative to match.\n * Uses setTimeout to defer until after Foundry's update chain resolves,\n * avoiding concurrent #recordPreviousState errors on the combat document.\n */\nHooks.on(\"updateCombatant\", (combatant, diff) => {\n if (!(\"initiative\" in diff)) return\n const initiative = combatant.initiative\n if (initiative == null) return\n setTimeout(() => {\n const actor = combatant.actor\n if (actor && actor.system?.initiative !== initiative) {\n actor.update({ \"system.initiative\": initiative }).catch(() => {})\n }\n }, 0)\n})\n"], + "mappings": "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", "names": ["RESULT_TEMPLATE", "HandlebarsApplicationMixin", "app", "app", "RESULT_TEMPLATE"] } diff --git a/images/banners/actor-banner.webp b/images/banners/actor-banner.webp new file mode 100644 index 0000000..9942295 Binary files /dev/null and b/images/banners/actor-banner.webp differ diff --git a/images/banners/item-banner.webp b/images/banners/item-banner.webp new file mode 100644 index 0000000..ae41bdd Binary files /dev/null and b/images/banners/item-banner.webp differ diff --git a/images/banners/journalentry-banner.webp b/images/banners/journalentry-banner.webp new file mode 100644 index 0000000..d50bbe5 Binary files /dev/null and b/images/banners/journalentry-banner.webp differ diff --git a/images/banners/scene-banner.webp b/images/banners/scene-banner.webp new file mode 100644 index 0000000..3b6b055 Binary files /dev/null and b/images/banners/scene-banner.webp differ diff --git a/images/ui/character-sheet-items.png b/images/ui/character-sheet-items.png new file mode 100644 index 0000000..bd45efe Binary files /dev/null and b/images/ui/character-sheet-items.png differ diff --git a/images/ui/character-sheet-kungfu.png b/images/ui/character-sheet-kungfu.png new file mode 100644 index 0000000..6484dca Binary files /dev/null and b/images/ui/character-sheet-kungfu.png differ diff --git a/images/ui/character-sheet-magics.png b/images/ui/character-sheet-magics.png new file mode 100644 index 0000000..bb96c60 Binary files /dev/null and b/images/ui/character-sheet-magics.png differ diff --git a/images/ui/character-sheet-nghang.png b/images/ui/character-sheet-nghang.png new file mode 100644 index 0000000..7216406 Binary files /dev/null and b/images/ui/character-sheet-nghang.png differ diff --git a/images/ui/character-sheet-skills.png b/images/ui/character-sheet-skills.png new file mode 100644 index 0000000..cb0a78c Binary files /dev/null and b/images/ui/character-sheet-skills.png differ diff --git a/images/ui/character-sheet-treasures.png b/images/ui/character-sheet-treasures.png new file mode 100644 index 0000000..b78454b Binary files /dev/null and b/images/ui/character-sheet-treasures.png differ diff --git a/images/ui/initiative-wheel.png b/images/ui/initiative-wheel.png new file mode 100644 index 0000000..a61b2de Binary files /dev/null and b/images/ui/initiative-wheel.png differ diff --git a/images/ui/loksyu-app.png b/images/ui/loksyu-app.png new file mode 100644 index 0000000..f509cb4 Binary files /dev/null and b/images/ui/loksyu-app.png differ diff --git a/images/ui/migration-dialog.png b/images/ui/migration-dialog.png new file mode 100644 index 0000000..9f3815b Binary files /dev/null and b/images/ui/migration-dialog.png differ diff --git a/images/ui/npc-sheet.png b/images/ui/npc-sheet.png new file mode 100644 index 0000000..64ff4e0 Binary files /dev/null and b/images/ui/npc-sheet.png differ diff --git a/images/ui/roll-dialog.png b/images/ui/roll-dialog.png new file mode 100644 index 0000000..b814a34 Binary files /dev/null and b/images/ui/roll-dialog.png differ diff --git a/images/ui/roll-result-chat.png b/images/ui/roll-result-chat.png new file mode 100644 index 0000000..f2b9db7 Binary files /dev/null and b/images/ui/roll-result-chat.png differ diff --git a/lang/fr-cde.json b/lang/fr-cde.json index 9dddcd6..675ce9a 100644 --- a/lang/fr-cde.json +++ b/lang/fr-cde.json @@ -432,5 +432,6 @@ "CDE.TotalDamage": "Dommages", "CDE.WeaponRoll": "Jet d'arme", "CDE.RangePenalty": "Pénalité de portée", - "CDE.SuccessTimesDamage": "succès × dégâts de base" + "CDE.SuccessTimesDamage": "succès × dégâts de base", + "CDE.WelcomeOpenHelp": "Ouvrir l'aide en ligne" } diff --git a/packs-src/cde-help/guide-systeme-cde.json b/packs-src/cde-help/guide-systeme-cde.json new file mode 100644 index 0000000..82bc9c7 --- /dev/null +++ b/packs-src/cde-help/guide-systeme-cde.json @@ -0,0 +1,293 @@ +{ + "_id": "CDEGuideMain0001", + "_key": "!journal!CDEGuideMain0001", + "name": "Guide du Système CDE", + "pages": [ + { + "_id": "CDEHelpP01Intro", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP01Intro", + "name": "Bienvenue dans CDE", + "type": "text", + "text": { + "content": "\n

Bienvenue dans les Chroniques de l'Étrange

\n

Ce guide vous présente l'interface du système FoundryVTT pour Chroniques de l'Étrange (CDE), jeu de rôle d'enquête et d'action surnaturelle dans le Hong Kong contemporain, édité par Antre-Monde Éditions.

\n

Structure du système

\n
    \n
  • Fiches de personnage (Fat Si) — Héros joueurs avec cinq aspects Wu Xing, compétences, Trois Trésors et équipement.
  • \n
  • Fiches de PNJ — Créatures, dieux, fantômes et humains à l'usage du MJ.
  • \n
  • Compendiums — Arts martiaux, sortilèges, équipements, PNJs, capacités surnaturelles, ingrédients, San Hei.
  • \n
  • Outils de MJ — Roue d'initiative, compteurs Loksyu/Tin Ji, outil de migration.
  • \n
\n

Naviguez dans ce journal via les onglets de page pour découvrir chaque aspect du système.

\n", + "format": 1, + "markdown": "" + }, + "sort": 100000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP02WuXin", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP02WuXin", + "name": "Le Cycle Wu Xing", + "type": "text", + "text": { + "content": "\n

Le Cycle Wu Xing (五行)

\n

Le Wu Xing est le cœur du système de résolution. Cinq aspects — Métal (㊎), Eau (㊌), Terre (㊏), Feu (㊋) et Bois (㊍) — définissent les capacités d'un personnage.

\n

Faces des d10 et résultats

\n

Chaque aspect est associé à deux faces du d10. Lors d'un jet, vous déclarez l'aspect utilisé avant de lancer vos dés. Chaque dé donne un résultat :

\n
    \n
  • Succès — avancez vers votre objectif.
  • \n
  • Dés-fastes (吉) — résultats favorables supplémentaires.
  • \n
  • Dés-néfastes (凶) — complications.
  • \n
  • Loksyu (落穗) — alimentent le compteur mondial de chance collective.
  • \n
  • Tin Ji (天機) — alimentent le compteur de destin.
  • \n
\n

Correspondances

\n\n\n\n\n\n\n\n\n\n
AspectFaces d10Caractère
㊎ Métal1 & 6Agressif, passionné, combatif
㊌ Eau2 & 7Souple, appliqué, adaptable
㊏ Terre3 & 8Obstiné, résilient, endurant
㊋ Feu4 & 9Chaleureux, créatif, empathique
㊍ Bois5 & 10Intuitif, observateur, instinctif
\n

La valeur d'un aspect (de 1 à 5) détermine le nombre de dés que vous lancez.

\n", + "format": 1, + "markdown": "" + }, + "sort": 200000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP03Sheet", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP03Sheet", + "name": "La Fiche de Personnage", + "type": "text", + "text": { + "content": "\n

La Fiche de Personnage (Fat Si)

\n
\"Fiche
Onglet Ng Hang : les cinq aspects Wu Xing
\n

La fiche de personnage se décompose en sept onglets :

\n
    \n
  1. Description — Biographie, concept, gardien céleste.
  2. \n
  3. Ng Hang — Les cinq aspects Wu Xing (valeur 1–5). Cliquez sur l'image du dé pour lancer.
  4. \n
  5. Compétences — Les compétences générales et ressources.
  6. \n
  7. Trois Trésors — Hei-Yang, Hei-Yin et les niveaux de dés.
  8. \n
  9. Magies — Les cinq écoles de magie et leurs sortilèges.
  10. \n
  11. Kung Fu — Arts martiaux possédés.
  12. \n
  13. Équipement — Objets portés.
  14. \n
\n

En-tête de fiche

\n

En haut de la fiche se trouvent le concept du personnage, son gardien céleste (aspect dominant) et la zone d'initiative avec les boutons ±.

\n
\"Fiche
Onglet Compétences : compétences et ressources
\n", + "format": 1, + "markdown": "" + }, + "sort": 300000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP04Treas", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP04Treas", + "name": "Les Trois Trésors", + "type": "text", + "text": { + "content": "\n

Les Trois Trésors (三寶)

\n
\"Fiche
Onglet Trois Trésors : Hei-Yang, Hei-Yin et niveaux de dés
\n

Les Trois Trésors représentent les réserves d'énergie vitale du personnage :

\n

Hei-Yang (陽氣) et Hei-Yin (陰氣)

\n

Ce sont les deux jauges de vitalité. Le Hei-Yang représente l'énergie active, le Hei-Yin l'énergie passive. Ensemble, ils forment le token attribute visible sur la carte.

\n

Niveaux de dés

\n

Les niveaux de dés (d4 → d6 → d8 → d10 → d12) reflètent la progression du personnage dans un aspect. Chaque niveau de dé confère un bonus ou un avantage supplémentaire.

\n

Blessures

\n

Les blessures s'accumulent et imposent des malus croissants :

\n
    \n
  • Blessé : −1 dé à tous les jets
  • \n
  • Gravement blessé : −2 dés
  • \n
  • État critique : −3 dés
  • \n
\n", + "format": 1, + "markdown": "" + }, + "sort": 400000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP05Magic", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP05Magic", + "name": "Magie", + "type": "text", + "text": { + "content": "\n

Magie

\n
\"Fiche
Onglet Magies : les cinq écoles et leurs sortilèges
\n

CDE dispose de cinq écoles de magie, chacune divisée en cinq spécialités :

\n
    \n
  • Cinabre Interne (内丹) — magie du souffle et du corps.
  • \n
  • Alchimie (外丹) — préparations, potions et talismans matériels.
  • \n
  • Maîtrise du Tao (道術) — maîtrise des principes cosmiques.
  • \n
  • Exorcisme (驅魔) — combat contre les entités surnaturelles.
  • \n
  • Géomancie (風水) — magie des lieux et de l'environnement.
  • \n
\n

Utiliser un sortilège

\n
    \n
  1. Cliquez sur l'icône dé du sort dans l'onglet Magies.
  2. \n
  3. Un dialog apparaît avec l'aspect associé, le coût en Hei et le nombre de dés.
  4. \n
  5. Validez pour effectuer le jet.
  6. \n
\n

Les sortilèges sont importés depuis le compendium Sortilèges et glissés sur la fiche.

\n", + "format": 1, + "markdown": "" + }, + "sort": 500000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP06KungF", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP06KungF", + "name": "Arts Martiaux", + "type": "text", + "text": { + "content": "\n

Arts Martiaux (武術)

\n
\"Fiche
Onglet Kung Fu : arts martiaux possédés
\n

Les arts martiaux représentent les techniques de combat du personnage. Chaque art martial possède :

\n
    \n
  • Un mode d'activation : passif, action d'attaque, réaction, etc.
  • \n
  • Une description des effets en jeu.
  • \n
\n

Importer un art martial

\n

Ouvrez le compendium Arts Martiaux et faites glisser une technique sur la fiche du personnage. Elle apparaît alors dans l'onglet Kung Fu.

\n

Types d'activation

\n\n\n\n\n\n\n\n\n\n
TypeDéclencheur
Passif (dés)Toujours actif
Action d'attaqueLors d'une attaque
Action de défenseLors d'une défense
RéactionEn réponse à un événement
Dégâts infligésQuand vous blessez
\n", + "format": 1, + "markdown": "" + }, + "sort": 600000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP07Items", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP07Items", + "name": "Équipement & Inventaire", + "type": "text", + "text": { + "content": "\n

Équipement & Inventaire

\n
\"Fiche
Onglet Équipement : objets portés
\n

L'onglet Équipement liste tout ce que porte le personnage. Les objets sont classés en plusieurs catégories :

\n
    \n
  • Armes — avec dégâts, distance et type.
  • \n
  • Protections — armures et protections spirituelles.
  • \n
  • San Hei (三氣) — objets magiques à charges.
  • \n
  • Ingrédients — matériaux pour l'alchimie.
  • \n
  • Équipement générique — tout autre objet.
  • \n
\n

Ajouter un objet

\n

Faites glisser un objet depuis un compendium (Armes, Protections, San Hei, Ingrédients, Équipements) ou créez-en un avec le bouton Créer correspondant.

\n

Cliquez sur l'image d'un objet pour ouvrir sa fiche détaillée.

\n", + "format": 1, + "markdown": "" + }, + "sort": 700000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP08NPCSH", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP08NPCSH", + "name": "Les PNJ", + "type": "text", + "text": { + "content": "\n

Les Personnages Non-Joueurs (PNJ)

\n
\"Fiche
Fiche PNJ : type, nuisance, menace et aptitudes
\n

Les PNJ ont une fiche simplifiée par rapport aux personnages joueurs.

\n

Caractéristiques

\n
    \n
  • Type de créature : Mortel, Démon, Esprit, Esprit animal, Fantôme, Jiugwaai, Dieu/Divinité.
  • \n
  • Capacité de nuisance : Figurant, Sbire, Adversaire, Allié, Boss, Divinité.
  • \n
  • Niveau de menace : Profane → Apprenti → Initié → Accompli → Renommé.
  • \n
\n

Aptitudes

\n

Les PNJ ont quatre aptitudes (Physique, Martiale, Mentale, Sociale) avec une spécialité optionnelle chacune.

\n

Capacités surnaturelles

\n

Les PNJ peuvent avoir des capacités importées depuis le compendium Capacités Surnaturelles.

\n", + "format": 1, + "markdown": "" + }, + "sort": 800000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP09Initi", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP09Initi", + "name": "Initiative & Combat", + "type": "text", + "text": { + "content": "\n

Initiative & Combat

\n
\"Roue
La Roue d'Initiative : 24 crans, couleurs Wu Xing
\n

La Roue d'Initiative

\n

La roue est un cercle de 24 crans numérotés. L'initiative de chaque personnage est calculée comme suit :

\n
    \n
  • Personnage joueur : Prouesse + valeur de compétence de la première action.
  • \n
  • PNJ : Aptitude physique + aptitude de la première action.
  • \n
\n

Les crans sont colorés selon le cycle Wu Xing (4 crans par couleur, 6 couleurs). Un effet qui dure 6 crans court jusqu'au prochain cran de la même couleur.

\n

Ordre d'action

\n

Les personnages agissent du numéro le plus élevé au plus bas. Après chaque action, le jeton avance dans le sens horaire du coût de l'action :

\n\n\n\n\n\n\n\n\n
ActionCoût (crans)
Défense1
Déplacement2
Attaque3
Retarder6
\n

Accès à la roue

\n

Ouvrez la roue depuis la barre latérale du chat (icône roue) ou via la console : game.cde.CDEWheelApp.open().

\n", + "format": 1, + "markdown": "" + }, + "sort": 900000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + }, + { + "_id": "CDEHelpP10Extra", + "_key": "!journal.pages!CDEGuideMain0001.CDEHelpP10Extra", + "name": "Loksyu, Tin Ji & Migration", + "type": "text", + "text": { + "content": "\n

Loksyu, Tin Ji & Outils de MJ

\n

Loksyu (落穗) et Tin Ji (天機)

\n
\"Application
Application Loksyu : compteurs Yin/Yang et Tin Ji
\n

Ces deux compteurs sont partagés entre tous les joueurs et le MJ :

\n
    \n
  • Loksyu — Se divise en Yin et Yang. Les jets de dés alimentent ces compteurs selon les résultats. Les joueurs peuvent puiser dans le Loksyu pour améliorer leurs jets.
  • \n
  • Tin Ji — Le compteur de destin. Peut être dépensé pour des effets exceptionnels.
  • \n
\n

Accédez via la barre du chat ou : game.cde.CDELoksyuApp.open()

\n

Migration de l'ancien système

\n
\"Outil
Outil de migration : importation depuis l'ancien système
\n

Si vous possédez des fiches de personnage créées dans l'ancien système CDE (non maintenu), l'outil de migration les convertit automatiquement :

\n
    \n
  1. Ouvrez Paramètres de la partie → Paramètres du système → Importer des personnages.
  2. \n
  3. Glissez les fichiers JSON des anciens personnages dans la zone de dépôt.
  4. \n
  5. Vérifiez l'aperçu et cliquez Importer.
  6. \n
\n

Les personnages migrés apparaissent dans la liste des Acteurs.

\n", + "format": 1, + "markdown": "" + }, + "sort": 1000000, + "title": { + "show": true, + "level": 1 + }, + "image": { + "caption": "" + }, + "video": { + "controls": true, + "volume": 0.5 + }, + "src": null, + "flags": {}, + "ownership": { + "default": -1 + } + } + ], + "sort": 0, + "ownership": { + "default": 0 + }, + "flags": {}, + "folder": null +} \ No newline at end of file diff --git a/packs/cde-armors/000010.ldb b/packs/cde-armors/000010.ldb deleted file mode 100644 index 16a4d2d..0000000 Binary files a/packs/cde-armors/000010.ldb and /dev/null differ diff --git a/packs/cde-armors/000013.log b/packs/cde-armors/000037.log similarity index 100% rename from packs/cde-armors/000013.log rename to packs/cde-armors/000037.log diff --git a/packs/cde-armors/CURRENT b/packs/cde-armors/CURRENT index 5b54010..29a53d8 100644 --- a/packs/cde-armors/CURRENT +++ b/packs/cde-armors/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000035 diff --git a/packs/cde-armors/LOG b/packs/cde-armors/LOG index 1bdd401..b7deb52 100644 --- a/packs/cde-armors/LOG +++ b/packs/cde-armors/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.523223 7fed92ffd6c0 Recovering log #8 -2026/04/29-22:22:16.534198 7fed92ffd6c0 Delete type=3 #6 -2026/04/29-22:22:16.534274 7fed92ffd6c0 Delete type=0 #8 -2026/04/29-22:25:51.987639 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.987684 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.993719 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:51.993848 7feb10fff6c0 Manual compaction at level-0 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end) -2026/04/29-22:25:51.993888 7feb10fff6c0 Manual compaction at level-1 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.366106 7fe44efef6c0 Recovering log #33 +2026/05/06-22:32:13.376874 7fe44efef6c0 Delete type=3 #31 +2026/05/06-22:32:13.376974 7fe44efef6c0 Delete type=0 #33 +2026/05/06-22:37:23.617629 7fe44cfeb6c0 Level-0 table #38: started +2026/05/06-22:37:23.617668 7fe44cfeb6c0 Level-0 table #38: 0 bytes OK +2026/05/06-22:37:23.624147 7fe44cfeb6c0 Delete type=0 #36 +2026/05/06-22:37:23.643567 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-armors/LOG.old b/packs/cde-armors/LOG.old index 87c6a74..e69de29 100644 --- a/packs/cde-armors/LOG.old +++ b/packs/cde-armors/LOG.old @@ -1,15 +0,0 @@ -2026/04/27-20:01:11.390845 7fed927fc6c0 Recovering log #4 -2026/04/27-20:01:11.400505 7fed927fc6c0 Delete type=3 #2 -2026/04/27-20:01:11.400599 7fed927fc6c0 Delete type=0 #4 -2026/04/27-22:04:19.362803 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.365860 7feb10fff6c0 Level-0 table #9: 1386 bytes OK -2026/04/27-22:04:19.371899 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.393316 7feb10fff6c0 Manual compaction at level-0 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.414834 7feb10fff6c0 Manual compaction at level-1 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at '!items!cXaQG1TBE0jzrbNt' @ 8 : 1 -2026/04/27-22:04:19.414848 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.418022 7feb10fff6c0 Generated table #10@1: 4 keys, 1386 bytes -2026/04/27-22:04:19.418047 7feb10fff6c0 Compacted 1@1 + 1@2 files => 1386 bytes -2026/04/27-22:04:19.424351 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.424476 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.424608 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.434505 7feb10fff6c0 Manual compaction at level-1 from '!items!cXaQG1TBE0jzrbNt' @ 8 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end) diff --git a/packs/cde-armors/MANIFEST-000011 b/packs/cde-armors/MANIFEST-000011 deleted file mode 100644 index 871e2e2..0000000 Binary files a/packs/cde-armors/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-armors/MANIFEST-000035 b/packs/cde-armors/MANIFEST-000035 new file mode 100644 index 0000000..fb55ffc Binary files /dev/null and b/packs/cde-armors/MANIFEST-000035 differ diff --git a/packs/cde-ingredients/000013.log b/packs/cde-armors/lost/000017.log similarity index 100% rename from packs/cde-ingredients/000013.log rename to packs/cde-armors/lost/000017.log diff --git a/packs/cde-help/000010.ldb b/packs/cde-help/000010.ldb new file mode 100644 index 0000000..fcdc2e6 Binary files /dev/null and b/packs/cde-help/000010.ldb differ diff --git a/packs/cde-items/000013.log b/packs/cde-help/000025.log similarity index 100% rename from packs/cde-items/000013.log rename to packs/cde-help/000025.log diff --git a/packs/cde-help/CURRENT b/packs/cde-help/CURRENT new file mode 100644 index 0000000..7fbb623 --- /dev/null +++ b/packs/cde-help/CURRENT @@ -0,0 +1 @@ +MANIFEST-000023 diff --git a/packs/cde-kungfus/000013.log b/packs/cde-help/LOCK similarity index 100% rename from packs/cde-kungfus/000013.log rename to packs/cde-help/LOCK diff --git a/packs/cde-help/LOG b/packs/cde-help/LOG new file mode 100644 index 0000000..503bd70 --- /dev/null +++ b/packs/cde-help/LOG @@ -0,0 +1,8 @@ +2026/05/06-22:32:13.427495 7fe44efef6c0 Recovering log #21 +2026/05/06-22:32:13.437731 7fe44efef6c0 Delete type=3 #19 +2026/05/06-22:32:13.437796 7fe44efef6c0 Delete type=0 #21 +2026/05/06-22:37:23.643733 7fe44cfeb6c0 Level-0 table #26: started +2026/05/06-22:37:23.643771 7fe44cfeb6c0 Level-0 table #26: 0 bytes OK +2026/05/06-22:37:23.650510 7fe44cfeb6c0 Delete type=0 #24 +2026/05/06-22:37:23.669664 7fe44cfeb6c0 Manual compaction at level-0 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.x83SZpLrbEi96PVQ' @ 0 : 0; will stop at (end) +2026/05/06-22:37:23.669706 7fe44cfeb6c0 Manual compaction at level-1 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.x83SZpLrbEi96PVQ' @ 0 : 0; will stop at (end) diff --git a/packs/cde-help/LOG.old b/packs/cde-help/LOG.old new file mode 100644 index 0000000..83fc92d --- /dev/null +++ b/packs/cde-help/LOG.old @@ -0,0 +1,8 @@ +2026/05/06-22:24:45.849795 7fe44efef6c0 Recovering log #17 +2026/05/06-22:24:45.867206 7fe44efef6c0 Delete type=3 #15 +2026/05/06-22:24:45.867306 7fe44efef6c0 Delete type=0 #17 +2026/05/06-22:30:22.773890 7fe44cfeb6c0 Level-0 table #22: started +2026/05/06-22:30:22.773918 7fe44cfeb6c0 Level-0 table #22: 0 bytes OK +2026/05/06-22:30:22.780047 7fe44cfeb6c0 Delete type=0 #20 +2026/05/06-22:30:22.798899 7fe44cfeb6c0 Manual compaction at level-0 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.x83SZpLrbEi96PVQ' @ 0 : 0; will stop at (end) +2026/05/06-22:30:22.798944 7fe44cfeb6c0 Manual compaction at level-1 from '!journal!CDEGuideMain0001' @ 72057594037927935 : 1 .. '!journal.pages!CDEGuideMain0001.x83SZpLrbEi96PVQ' @ 0 : 0; will stop at (end) diff --git a/packs/cde-help/MANIFEST-000023 b/packs/cde-help/MANIFEST-000023 new file mode 100644 index 0000000..5ac41c9 Binary files /dev/null and b/packs/cde-help/MANIFEST-000023 differ diff --git a/packs/cde-ingredients/000010.ldb b/packs/cde-ingredients/000010.ldb deleted file mode 100644 index e66820a..0000000 Binary files a/packs/cde-ingredients/000010.ldb and /dev/null differ diff --git a/packs/cde-npcs/000013.log b/packs/cde-ingredients/000037.log similarity index 100% rename from packs/cde-npcs/000013.log rename to packs/cde-ingredients/000037.log diff --git a/packs/cde-ingredients/CURRENT b/packs/cde-ingredients/CURRENT index 5b54010..29a53d8 100644 --- a/packs/cde-ingredients/CURRENT +++ b/packs/cde-ingredients/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000035 diff --git a/packs/cde-ingredients/LOG b/packs/cde-ingredients/LOG index 1108653..3ac6a47 100644 --- a/packs/cde-ingredients/LOG +++ b/packs/cde-ingredients/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.548077 7fed937fe6c0 Recovering log #8 -2026/04/29-22:22:16.558399 7fed937fe6c0 Delete type=3 #6 -2026/04/29-22:22:16.558484 7fed937fe6c0 Delete type=0 #8 -2026/04/29-22:25:51.968077 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.968115 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.974151 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:51.993811 7feb10fff6c0 Manual compaction at level-0 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end) -2026/04/29-22:25:51.993859 7feb10fff6c0 Manual compaction at level-1 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.390543 7fe44efef6c0 Recovering log #33 +2026/05/06-22:32:13.400800 7fe44efef6c0 Delete type=3 #31 +2026/05/06-22:32:13.400881 7fe44efef6c0 Delete type=0 #33 +2026/05/06-22:37:23.636590 7fe44cfeb6c0 Level-0 table #38: started +2026/05/06-22:37:23.636613 7fe44cfeb6c0 Level-0 table #38: 0 bytes OK +2026/05/06-22:37:23.643393 7fe44cfeb6c0 Delete type=0 #36 +2026/05/06-22:37:23.643628 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-ingredients/LOG.old b/packs/cde-ingredients/LOG.old index 22e4637..0b3b7d5 100644 --- a/packs/cde-ingredients/LOG.old +++ b/packs/cde-ingredients/LOG.old @@ -1,15 +1,7 @@ -2026/04/27-20:01:11.418750 7fed93fff6c0 Recovering log #4 -2026/04/27-20:01:11.428738 7fed93fff6c0 Delete type=3 #2 -2026/04/27-20:01:11.428793 7fed93fff6c0 Delete type=0 #4 -2026/04/27-22:04:19.624820 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.629114 7feb10fff6c0 Level-0 table #9: 8881 bytes OK -2026/04/27-22:04:19.636111 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.657606 7feb10fff6c0 Manual compaction at level-0 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.668457 7feb10fff6c0 Manual compaction at level-1 from '!items!0NDBw1YB54q3hLH0' @ 72057594037927935 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at '!items!ykekdZlirabRobEF' @ 108 : 1 -2026/04/27-22:04:19.668467 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.672553 7feb10fff6c0 Generated table #10@1: 54 keys, 8881 bytes -2026/04/27-22:04:19.672595 7feb10fff6c0 Compacted 1@1 + 1@2 files => 8881 bytes -2026/04/27-22:04:19.678837 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.678963 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.679140 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.691620 7feb10fff6c0 Manual compaction at level-1 from '!items!ykekdZlirabRobEF' @ 108 : 1 .. '!items!ykekdZlirabRobEF' @ 0 : 0; will stop at (end) +2026/05/06-22:24:45.793005 7fe44efef6c0 Recovering log #29 +2026/05/06-22:24:45.808875 7fe44efef6c0 Delete type=3 #27 +2026/05/06-22:24:45.808947 7fe44efef6c0 Delete type=0 #29 +2026/05/06-22:30:22.754997 7fe44cfeb6c0 Level-0 table #34: started +2026/05/06-22:30:22.755020 7fe44cfeb6c0 Level-0 table #34: 0 bytes OK +2026/05/06-22:30:22.760743 7fe44cfeb6c0 Delete type=0 #32 +2026/05/06-22:30:22.773745 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-ingredients/MANIFEST-000011 b/packs/cde-ingredients/MANIFEST-000011 deleted file mode 100644 index ed27acd..0000000 Binary files a/packs/cde-ingredients/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-ingredients/MANIFEST-000035 b/packs/cde-ingredients/MANIFEST-000035 new file mode 100644 index 0000000..fb55ffc Binary files /dev/null and b/packs/cde-ingredients/MANIFEST-000035 differ diff --git a/packs/cde-sanhei/000013.log b/packs/cde-ingredients/lost/000017.log similarity index 100% rename from packs/cde-sanhei/000013.log rename to packs/cde-ingredients/lost/000017.log diff --git a/packs/cde-items/000010.ldb b/packs/cde-items/000010.ldb deleted file mode 100644 index a356c2a..0000000 Binary files a/packs/cde-items/000010.ldb and /dev/null differ diff --git a/packs/cde-spells/000013.log b/packs/cde-items/000037.log similarity index 100% rename from packs/cde-spells/000013.log rename to packs/cde-items/000037.log diff --git a/packs/cde-items/CURRENT b/packs/cde-items/CURRENT index 5b54010..29a53d8 100644 --- a/packs/cde-items/CURRENT +++ b/packs/cde-items/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000035 diff --git a/packs/cde-items/LOG b/packs/cde-items/LOG index c2b3447..e78bb80 100644 --- a/packs/cde-items/LOG +++ b/packs/cde-items/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.560906 7fed92ffd6c0 Recovering log #8 -2026/04/29-22:22:16.571505 7fed92ffd6c0 Delete type=3 #6 -2026/04/29-22:22:16.571579 7fed92ffd6c0 Delete type=0 #8 -2026/04/29-22:25:51.974229 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.974252 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.980405 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:51.993825 7feb10fff6c0 Manual compaction at level-0 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end) -2026/04/29-22:25:51.993878 7feb10fff6c0 Manual compaction at level-1 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.402637 7fe44e7ee6c0 Recovering log #33 +2026/05/06-22:32:13.413187 7fe44e7ee6c0 Delete type=3 #31 +2026/05/06-22:32:13.413261 7fe44e7ee6c0 Delete type=0 #33 +2026/05/06-22:37:23.630418 7fe44cfeb6c0 Level-0 table #38: started +2026/05/06-22:37:23.630444 7fe44cfeb6c0 Level-0 table #38: 0 bytes OK +2026/05/06-22:37:23.636504 7fe44cfeb6c0 Delete type=0 #36 +2026/05/06-22:37:23.643610 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-items/LOG.old b/packs/cde-items/LOG.old index a79e20d..62af190 100644 --- a/packs/cde-items/LOG.old +++ b/packs/cde-items/LOG.old @@ -1,15 +1,7 @@ -2026/04/27-20:01:11.433002 7fed92ffd6c0 Recovering log #4 -2026/04/27-20:01:11.442974 7fed92ffd6c0 Delete type=3 #2 -2026/04/27-20:01:11.443041 7fed92ffd6c0 Delete type=0 #4 -2026/04/27-22:04:19.348217 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.355163 7feb10fff6c0 Level-0 table #9: 595 bytes OK -2026/04/27-22:04:19.362679 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.393301 7feb10fff6c0 Manual compaction at level-0 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.393355 7feb10fff6c0 Manual compaction at level-1 from '!items!HKq5ANSGiBIdcnki' @ 72057594037927935 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at '!items!HKq5ANSGiBIdcnki' @ 2 : 1 -2026/04/27-22:04:19.393364 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.396559 7feb10fff6c0 Generated table #10@1: 1 keys, 595 bytes -2026/04/27-22:04:19.396573 7feb10fff6c0 Compacted 1@1 + 1@2 files => 595 bytes -2026/04/27-22:04:19.402962 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.403060 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.403166 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.434477 7feb10fff6c0 Manual compaction at level-1 from '!items!HKq5ANSGiBIdcnki' @ 2 : 1 .. '!items!HKq5ANSGiBIdcnki' @ 0 : 0; will stop at (end) +2026/05/06-22:24:45.812009 7fe44dfed6c0 Recovering log #29 +2026/05/06-22:24:45.827425 7fe44dfed6c0 Delete type=3 #27 +2026/05/06-22:24:45.827509 7fe44dfed6c0 Delete type=0 #29 +2026/05/06-22:30:22.760828 7fe44cfeb6c0 Level-0 table #34: started +2026/05/06-22:30:22.760852 7fe44cfeb6c0 Level-0 table #34: 0 bytes OK +2026/05/06-22:30:22.766828 7fe44cfeb6c0 Delete type=0 #32 +2026/05/06-22:30:22.773753 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-items/MANIFEST-000011 b/packs/cde-items/MANIFEST-000011 deleted file mode 100644 index 547465d..0000000 Binary files a/packs/cde-items/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-items/MANIFEST-000035 b/packs/cde-items/MANIFEST-000035 new file mode 100644 index 0000000..fb55ffc Binary files /dev/null and b/packs/cde-items/MANIFEST-000035 differ diff --git a/packs/cde-supernaturals/000013.log b/packs/cde-items/lost/000017.log similarity index 100% rename from packs/cde-supernaturals/000013.log rename to packs/cde-items/lost/000017.log diff --git a/packs/cde-kungfus/000010.ldb b/packs/cde-kungfus/000010.ldb deleted file mode 100644 index 4d0b0a4..0000000 Binary files a/packs/cde-kungfus/000010.ldb and /dev/null differ diff --git a/packs/cde-weapons/000013.log b/packs/cde-kungfus/000037.log similarity index 100% rename from packs/cde-weapons/000013.log rename to packs/cde-kungfus/000037.log diff --git a/packs/cde-kungfus/CURRENT b/packs/cde-kungfus/CURRENT index 5b54010..29a53d8 100644 --- a/packs/cde-kungfus/CURRENT +++ b/packs/cde-kungfus/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000035 diff --git a/packs/cde-kungfus/LOG b/packs/cde-kungfus/LOG index b20d6c8..bc83665 100644 --- a/packs/cde-kungfus/LOG +++ b/packs/cde-kungfus/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.473404 7fed937fe6c0 Recovering log #8 -2026/04/29-22:22:16.483362 7fed937fe6c0 Delete type=3 #6 -2026/04/29-22:22:16.483437 7fed937fe6c0 Delete type=0 #8 -2026/04/29-22:25:51.954962 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.955023 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.961800 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:51.967898 7feb10fff6c0 Manual compaction at level-0 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end) -2026/04/29-22:25:51.967957 7feb10fff6c0 Manual compaction at level-1 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.317725 7fe44efef6c0 Recovering log #33 +2026/05/06-22:32:13.328138 7fe44efef6c0 Delete type=3 #31 +2026/05/06-22:32:13.328231 7fe44efef6c0 Delete type=0 #33 +2026/05/06-22:37:23.590888 7fe44cfeb6c0 Level-0 table #38: started +2026/05/06-22:37:23.590952 7fe44cfeb6c0 Level-0 table #38: 0 bytes OK +2026/05/06-22:37:23.597751 7fe44cfeb6c0 Delete type=0 #36 +2026/05/06-22:37:23.617391 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-kungfus/LOG.old b/packs/cde-kungfus/LOG.old index 9ab236c..2ed69ac 100644 --- a/packs/cde-kungfus/LOG.old +++ b/packs/cde-kungfus/LOG.old @@ -1,15 +1,7 @@ -2026/04/27-20:01:11.327150 7fed93fff6c0 Recovering log #4 -2026/04/27-20:01:11.338223 7fed93fff6c0 Delete type=3 #2 -2026/04/27-20:01:11.338311 7fed93fff6c0 Delete type=0 #4 -2026/04/27-22:04:19.636280 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.639967 7feb10fff6c0 Level-0 table #9: 34454 bytes OK -2026/04/27-22:04:19.646926 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.657623 7feb10fff6c0 Manual compaction at level-0 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.679254 7feb10fff6c0 Manual compaction at level-1 from '!items!2nKXEHLG0fXtSOdy' @ 72057594037927935 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at '!items!tlIc1bmIAbQeUwj7' @ 40 : 1 -2026/04/27-22:04:19.679269 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.684098 7feb10fff6c0 Generated table #10@1: 20 keys, 34454 bytes -2026/04/27-22:04:19.684137 7feb10fff6c0 Compacted 1@1 + 1@2 files => 34454 bytes -2026/04/27-22:04:19.691170 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.691333 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.691497 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.691633 7feb10fff6c0 Manual compaction at level-1 from '!items!tlIc1bmIAbQeUwj7' @ 40 : 1 .. '!items!tlIc1bmIAbQeUwj7' @ 0 : 0; will stop at (end) +2026/05/06-22:24:45.678133 7fe44d7ec6c0 Recovering log #29 +2026/05/06-22:24:45.699614 7fe44d7ec6c0 Delete type=3 #27 +2026/05/06-22:24:45.699668 7fe44d7ec6c0 Delete type=0 #29 +2026/05/06-22:30:22.729240 7fe44cfeb6c0 Level-0 table #34: started +2026/05/06-22:30:22.729273 7fe44cfeb6c0 Level-0 table #34: 0 bytes OK +2026/05/06-22:30:22.735324 7fe44cfeb6c0 Delete type=0 #32 +2026/05/06-22:30:22.748747 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-kungfus/MANIFEST-000011 b/packs/cde-kungfus/MANIFEST-000011 deleted file mode 100644 index 3188472..0000000 Binary files a/packs/cde-kungfus/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-kungfus/MANIFEST-000035 b/packs/cde-kungfus/MANIFEST-000035 new file mode 100644 index 0000000..fb55ffc Binary files /dev/null and b/packs/cde-kungfus/MANIFEST-000035 differ diff --git a/packs/cde-kungfus/lost/000017.log b/packs/cde-kungfus/lost/000017.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-npcs/000010.ldb b/packs/cde-npcs/000010.ldb deleted file mode 100644 index 09a4322..0000000 Binary files a/packs/cde-npcs/000010.ldb and /dev/null differ diff --git a/packs/cde-npcs/000025.ldb b/packs/cde-npcs/000025.ldb new file mode 100644 index 0000000..70c5795 Binary files /dev/null and b/packs/cde-npcs/000025.ldb differ diff --git a/packs/cde-npcs/000040.log b/packs/cde-npcs/000040.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-npcs/CURRENT b/packs/cde-npcs/CURRENT index 5b54010..59611b0 100644 --- a/packs/cde-npcs/CURRENT +++ b/packs/cde-npcs/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000038 diff --git a/packs/cde-npcs/LOG b/packs/cde-npcs/LOG index e706f78..146db9e 100644 --- a/packs/cde-npcs/LOG +++ b/packs/cde-npcs/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.573593 7fed93fff6c0 Recovering log #8 -2026/04/29-22:22:16.583105 7fed93fff6c0 Delete type=3 #6 -2026/04/29-22:22:16.583178 7fed93fff6c0 Delete type=0 #8 -2026/04/29-22:25:51.993997 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.994029 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.999825 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:52.019571 7feb10fff6c0 Manual compaction at level-0 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end) -2026/04/29-22:25:52.019629 7feb10fff6c0 Manual compaction at level-1 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.415167 7fe44efef6c0 Recovering log #36 +2026/05/06-22:32:13.424997 7fe44efef6c0 Delete type=3 #34 +2026/05/06-22:32:13.425065 7fe44efef6c0 Delete type=0 #36 +2026/05/06-22:37:23.794167 7fe44cfeb6c0 Level-0 table #41: started +2026/05/06-22:37:23.794211 7fe44cfeb6c0 Level-0 table #41: 0 bytes OK +2026/05/06-22:37:23.800534 7fe44cfeb6c0 Delete type=0 #39 +2026/05/06-22:37:23.800731 7fe44cfeb6c0 Manual compaction at level-0 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end) diff --git a/packs/cde-npcs/LOG.old b/packs/cde-npcs/LOG.old index 47c0861..5968ff3 100644 --- a/packs/cde-npcs/LOG.old +++ b/packs/cde-npcs/LOG.old @@ -1,15 +1,7 @@ -2026/04/27-20:01:11.445769 7fed937fe6c0 Recovering log #4 -2026/04/27-20:01:11.456194 7fed937fe6c0 Delete type=3 #2 -2026/04/27-20:01:11.456260 7fed937fe6c0 Delete type=0 #4 -2026/04/27-22:04:19.567804 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.572524 7feb10fff6c0 Level-0 table #9: 50410 bytes OK -2026/04/27-22:04:19.579249 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.579507 7feb10fff6c0 Manual compaction at level-0 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.589759 7feb10fff6c0 Manual compaction at level-1 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at '!actors!zVpmacwoWEG8YTCQ' @ 98 : 1 -2026/04/27-22:04:19.589777 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.594306 7feb10fff6c0 Generated table #10@1: 49 keys, 50410 bytes -2026/04/27-22:04:19.594339 7feb10fff6c0 Compacted 1@1 + 1@2 files => 50410 bytes -2026/04/27-22:04:19.600590 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.600711 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.600847 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.614717 7feb10fff6c0 Manual compaction at level-1 from '!actors!zVpmacwoWEG8YTCQ' @ 98 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end) +2026/05/06-22:24:45.830634 7fe44efef6c0 Recovering log #32 +2026/05/06-22:24:45.846170 7fe44efef6c0 Delete type=3 #30 +2026/05/06-22:24:45.846232 7fe44efef6c0 Delete type=0 #32 +2026/05/06-22:30:22.780170 7fe44cfeb6c0 Level-0 table #37: started +2026/05/06-22:30:22.780198 7fe44cfeb6c0 Level-0 table #37: 0 bytes OK +2026/05/06-22:30:22.786085 7fe44cfeb6c0 Delete type=0 #35 +2026/05/06-22:30:22.798917 7fe44cfeb6c0 Manual compaction at level-0 from '!actors!4ZjFZ1HoJV9mJStt' @ 72057594037927935 : 1 .. '!actors!zVpmacwoWEG8YTCQ' @ 0 : 0; will stop at (end) diff --git a/packs/cde-npcs/MANIFEST-000011 b/packs/cde-npcs/MANIFEST-000011 deleted file mode 100644 index 42ac261..0000000 Binary files a/packs/cde-npcs/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-npcs/MANIFEST-000038 b/packs/cde-npcs/MANIFEST-000038 new file mode 100644 index 0000000..d946fe9 Binary files /dev/null and b/packs/cde-npcs/MANIFEST-000038 differ diff --git a/packs/cde-npcs/lost/000017.log b/packs/cde-npcs/lost/000017.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-sanhei/000010.ldb b/packs/cde-sanhei/000010.ldb deleted file mode 100644 index c62409d..0000000 Binary files a/packs/cde-sanhei/000010.ldb and /dev/null differ diff --git a/packs/cde-sanhei/000037.log b/packs/cde-sanhei/000037.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-sanhei/CURRENT b/packs/cde-sanhei/CURRENT index 5b54010..29a53d8 100644 --- a/packs/cde-sanhei/CURRENT +++ b/packs/cde-sanhei/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000035 diff --git a/packs/cde-sanhei/LOG b/packs/cde-sanhei/LOG index f51d186..b9b9fce 100644 --- a/packs/cde-sanhei/LOG +++ b/packs/cde-sanhei/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.536279 7fed927fc6c0 Recovering log #8 -2026/04/29-22:22:16.545991 7fed927fc6c0 Delete type=3 #6 -2026/04/29-22:22:16.546048 7fed927fc6c0 Delete type=0 #8 -2026/04/29-22:25:51.980549 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.980578 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.987409 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:51.993836 7feb10fff6c0 Manual compaction at level-0 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end) -2026/04/29-22:25:51.993869 7feb10fff6c0 Manual compaction at level-1 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.378942 7fe44dfed6c0 Recovering log #33 +2026/05/06-22:32:13.388592 7fe44dfed6c0 Delete type=3 #31 +2026/05/06-22:32:13.388647 7fe44dfed6c0 Delete type=0 #33 +2026/05/06-22:37:23.624309 7fe44cfeb6c0 Level-0 table #38: started +2026/05/06-22:37:23.624349 7fe44cfeb6c0 Level-0 table #38: 0 bytes OK +2026/05/06-22:37:23.630330 7fe44cfeb6c0 Delete type=0 #36 +2026/05/06-22:37:23.643593 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-sanhei/LOG.old b/packs/cde-sanhei/LOG.old index f5f42d2..5e0278a 100644 --- a/packs/cde-sanhei/LOG.old +++ b/packs/cde-sanhei/LOG.old @@ -1,15 +1,7 @@ -2026/04/27-20:01:11.404989 7fed937fe6c0 Recovering log #4 -2026/04/27-20:01:11.415714 7fed937fe6c0 Delete type=3 #2 -2026/04/27-20:01:11.415769 7fed937fe6c0 Delete type=0 #4 -2026/04/27-22:04:19.600959 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.606292 7feb10fff6c0 Level-0 table #9: 4932 bytes OK -2026/04/27-22:04:19.614475 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.624799 7feb10fff6c0 Manual compaction at level-0 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.647175 7feb10fff6c0 Manual compaction at level-1 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at '!items!qzfAEhmvVxEMzm0k' @ 10 : 1 -2026/04/27-22:04:19.647190 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.651146 7feb10fff6c0 Generated table #10@1: 5 keys, 4932 bytes -2026/04/27-22:04:19.651182 7feb10fff6c0 Compacted 1@1 + 1@2 files => 4932 bytes -2026/04/27-22:04:19.657147 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.657307 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.657500 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.668439 7feb10fff6c0 Manual compaction at level-1 from '!items!qzfAEhmvVxEMzm0k' @ 10 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end) +2026/05/06-22:24:45.774814 7fe44e7ee6c0 Recovering log #29 +2026/05/06-22:24:45.790576 7fe44e7ee6c0 Delete type=3 #27 +2026/05/06-22:24:45.790660 7fe44e7ee6c0 Delete type=0 #29 +2026/05/06-22:30:22.748887 7fe44cfeb6c0 Level-0 table #34: started +2026/05/06-22:30:22.748914 7fe44cfeb6c0 Level-0 table #34: 0 bytes OK +2026/05/06-22:30:22.754926 7fe44cfeb6c0 Delete type=0 #32 +2026/05/06-22:30:22.773735 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-sanhei/MANIFEST-000011 b/packs/cde-sanhei/MANIFEST-000011 deleted file mode 100644 index 62fceda..0000000 Binary files a/packs/cde-sanhei/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-sanhei/MANIFEST-000035 b/packs/cde-sanhei/MANIFEST-000035 new file mode 100644 index 0000000..fb55ffc Binary files /dev/null and b/packs/cde-sanhei/MANIFEST-000035 differ diff --git a/packs/cde-sanhei/lost/000017.log b/packs/cde-sanhei/lost/000017.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-scenes/000005.ldb b/packs/cde-scenes/000005.ldb new file mode 100644 index 0000000..f208e18 Binary files /dev/null and b/packs/cde-scenes/000005.ldb differ diff --git a/packs/cde-scenes/000012.log b/packs/cde-scenes/000012.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-scenes/CURRENT b/packs/cde-scenes/CURRENT new file mode 100644 index 0000000..3051f81 --- /dev/null +++ b/packs/cde-scenes/CURRENT @@ -0,0 +1 @@ +MANIFEST-000010 diff --git a/packs/cde-scenes/LOCK b/packs/cde-scenes/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-scenes/LOG b/packs/cde-scenes/LOG new file mode 100644 index 0000000..19a5167 --- /dev/null +++ b/packs/cde-scenes/LOG @@ -0,0 +1,8 @@ +2026/05/06-22:32:13.440388 7fe44dfed6c0 Recovering log #8 +2026/05/06-22:32:13.451363 7fe44dfed6c0 Delete type=3 #6 +2026/05/06-22:32:13.451431 7fe44dfed6c0 Delete type=0 #8 +2026/05/06-22:37:23.650643 7fe44cfeb6c0 Level-0 table #13: started +2026/05/06-22:37:23.650683 7fe44cfeb6c0 Level-0 table #13: 0 bytes OK +2026/05/06-22:37:23.656717 7fe44cfeb6c0 Delete type=0 #11 +2026/05/06-22:37:23.669680 7fe44cfeb6c0 Manual compaction at level-0 from '!scenes!2C6gyZpvPxWlsVZi' @ 72057594037927935 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at (end) +2026/05/06-22:37:23.669713 7fe44cfeb6c0 Manual compaction at level-1 from '!scenes!2C6gyZpvPxWlsVZi' @ 72057594037927935 : 1 .. '!scenes.levels!olYe9bhuXwRWQ8j7.defaultLevel0000' @ 0 : 0; will stop at (end) diff --git a/packs/cde-scenes/LOG.old b/packs/cde-scenes/LOG.old new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-scenes/MANIFEST-000010 b/packs/cde-scenes/MANIFEST-000010 new file mode 100644 index 0000000..09d8e71 Binary files /dev/null and b/packs/cde-scenes/MANIFEST-000010 differ diff --git a/packs/cde-spells/000010.ldb b/packs/cde-spells/000010.ldb deleted file mode 100644 index d73f4e6..0000000 Binary files a/packs/cde-spells/000010.ldb and /dev/null differ diff --git a/packs/cde-spells/000037.log b/packs/cde-spells/000037.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-spells/CURRENT b/packs/cde-spells/CURRENT index 5b54010..29a53d8 100644 --- a/packs/cde-spells/CURRENT +++ b/packs/cde-spells/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000035 diff --git a/packs/cde-spells/LOG b/packs/cde-spells/LOG index ad320ff..e411feb 100644 --- a/packs/cde-spells/LOG +++ b/packs/cde-spells/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.485811 7fed92ffd6c0 Recovering log #8 -2026/04/29-22:22:16.496078 7fed92ffd6c0 Delete type=3 #6 -2026/04/29-22:22:16.496151 7fed92ffd6c0 Delete type=0 #8 -2026/04/29-22:25:51.961881 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.961902 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.967729 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:51.967910 7feb10fff6c0 Manual compaction at level-0 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end) -2026/04/29-22:25:51.967946 7feb10fff6c0 Manual compaction at level-1 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.330276 7fe44e7ee6c0 Recovering log #33 +2026/05/06-22:32:13.340631 7fe44e7ee6c0 Delete type=3 #31 +2026/05/06-22:32:13.340713 7fe44e7ee6c0 Delete type=0 #33 +2026/05/06-22:37:23.611067 7fe44cfeb6c0 Level-0 table #38: started +2026/05/06-22:37:23.611087 7fe44cfeb6c0 Level-0 table #38: 0 bytes OK +2026/05/06-22:37:23.617233 7fe44cfeb6c0 Delete type=0 #36 +2026/05/06-22:37:23.617453 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-spells/LOG.old b/packs/cde-spells/LOG.old index 6ea90d2..884e051 100644 --- a/packs/cde-spells/LOG.old +++ b/packs/cde-spells/LOG.old @@ -1,15 +1,7 @@ -2026/04/27-20:01:11.343717 7fed927fc6c0 Recovering log #4 -2026/04/27-20:01:11.353301 7fed927fc6c0 Delete type=3 #2 -2026/04/27-20:01:11.353373 7fed927fc6c0 Delete type=0 #4 -2026/04/27-22:04:19.372038 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.376931 7feb10fff6c0 Level-0 table #9: 124022 bytes OK -2026/04/27-22:04:19.383704 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.393329 7feb10fff6c0 Manual compaction at level-0 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.403238 7feb10fff6c0 Manual compaction at level-1 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at '!items!yVN7PZw35iIaBl0H' @ 50 : 1 -2026/04/27-22:04:19.403249 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.408494 7feb10fff6c0 Generated table #10@1: 25 keys, 124022 bytes -2026/04/27-22:04:19.408531 7feb10fff6c0 Compacted 1@1 + 1@2 files => 124022 bytes -2026/04/27-22:04:19.414410 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.414523 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.414716 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.434492 7feb10fff6c0 Manual compaction at level-1 from '!items!yVN7PZw35iIaBl0H' @ 50 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end) +2026/05/06-22:24:45.701526 7fe44e7ee6c0 Recovering log #29 +2026/05/06-22:24:45.717202 7fe44e7ee6c0 Delete type=3 #27 +2026/05/06-22:24:45.717295 7fe44e7ee6c0 Delete type=0 #29 +2026/05/06-22:30:22.722936 7fe44cfeb6c0 Level-0 table #34: started +2026/05/06-22:30:22.723007 7fe44cfeb6c0 Level-0 table #34: 0 bytes OK +2026/05/06-22:30:22.729144 7fe44cfeb6c0 Delete type=0 #32 +2026/05/06-22:30:22.748723 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-spells/MANIFEST-000011 b/packs/cde-spells/MANIFEST-000011 deleted file mode 100644 index 9de39d5..0000000 Binary files a/packs/cde-spells/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-spells/MANIFEST-000035 b/packs/cde-spells/MANIFEST-000035 new file mode 100644 index 0000000..fb55ffc Binary files /dev/null and b/packs/cde-spells/MANIFEST-000035 differ diff --git a/packs/cde-spells/lost/000017.log b/packs/cde-spells/lost/000017.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-supernaturals/000010.ldb b/packs/cde-supernaturals/000010.ldb deleted file mode 100644 index 5b06df9..0000000 Binary files a/packs/cde-supernaturals/000010.ldb and /dev/null differ diff --git a/packs/cde-supernaturals/000037.log b/packs/cde-supernaturals/000037.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-supernaturals/CURRENT b/packs/cde-supernaturals/CURRENT index 5b54010..29a53d8 100644 --- a/packs/cde-supernaturals/CURRENT +++ b/packs/cde-supernaturals/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000035 diff --git a/packs/cde-supernaturals/LOG b/packs/cde-supernaturals/LOG index ecb7dc2..e292a07 100644 --- a/packs/cde-supernaturals/LOG +++ b/packs/cde-supernaturals/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.498793 7fed927fc6c0 Recovering log #8 -2026/04/29-22:22:16.509236 7fed927fc6c0 Delete type=3 #6 -2026/04/29-22:22:16.509309 7fed927fc6c0 Delete type=0 #8 -2026/04/29-22:25:51.948721 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.948762 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.954716 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:51.967884 7feb10fff6c0 Manual compaction at level-0 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end) -2026/04/29-22:25:51.967934 7feb10fff6c0 Manual compaction at level-1 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.342531 7fe44efef6c0 Recovering log #33 +2026/05/06-22:32:13.352219 7fe44efef6c0 Delete type=3 #31 +2026/05/06-22:32:13.352311 7fe44efef6c0 Delete type=0 #33 +2026/05/06-22:37:23.597833 7fe44cfeb6c0 Level-0 table #38: started +2026/05/06-22:37:23.597852 7fe44cfeb6c0 Level-0 table #38: 0 bytes OK +2026/05/06-22:37:23.604282 7fe44cfeb6c0 Delete type=0 #36 +2026/05/06-22:37:23.617415 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-supernaturals/LOG.old b/packs/cde-supernaturals/LOG.old index a09672b..4d316f9 100644 --- a/packs/cde-supernaturals/LOG.old +++ b/packs/cde-supernaturals/LOG.old @@ -1,15 +1,7 @@ -2026/04/27-20:01:11.363742 7fed937fe6c0 Recovering log #4 -2026/04/27-20:01:11.374069 7fed937fe6c0 Delete type=3 #2 -2026/04/27-20:01:11.374139 7fed937fe6c0 Delete type=0 #4 -2026/04/27-22:04:19.383837 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.387155 7feb10fff6c0 Level-0 table #9: 8786 bytes OK -2026/04/27-22:04:19.393117 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.393340 7feb10fff6c0 Manual compaction at level-0 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.424676 7feb10fff6c0 Manual compaction at level-1 from '!items!APN91pQL0NBfZsG7' @ 72057594037927935 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at '!items!xxZKGqDVxAfr140W' @ 32 : 1 -2026/04/27-22:04:19.424688 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.428328 7feb10fff6c0 Generated table #10@1: 16 keys, 8786 bytes -2026/04/27-22:04:19.428349 7feb10fff6c0 Compacted 1@1 + 1@2 files => 8786 bytes -2026/04/27-22:04:19.434197 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.434290 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.434410 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.434517 7feb10fff6c0 Manual compaction at level-1 from '!items!xxZKGqDVxAfr140W' @ 32 : 1 .. '!items!xxZKGqDVxAfr140W' @ 0 : 0; will stop at (end) +2026/05/06-22:24:45.719300 7fe44efef6c0 Recovering log #29 +2026/05/06-22:24:45.734462 7fe44efef6c0 Delete type=3 #27 +2026/05/06-22:24:45.734527 7fe44efef6c0 Delete type=0 #29 +2026/05/06-22:30:22.735434 7fe44cfeb6c0 Level-0 table #34: started +2026/05/06-22:30:22.735464 7fe44cfeb6c0 Level-0 table #34: 0 bytes OK +2026/05/06-22:30:22.741423 7fe44cfeb6c0 Delete type=0 #32 +2026/05/06-22:30:22.748759 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-supernaturals/MANIFEST-000011 b/packs/cde-supernaturals/MANIFEST-000011 deleted file mode 100644 index ac166f9..0000000 Binary files a/packs/cde-supernaturals/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-supernaturals/MANIFEST-000035 b/packs/cde-supernaturals/MANIFEST-000035 new file mode 100644 index 0000000..fb55ffc Binary files /dev/null and b/packs/cde-supernaturals/MANIFEST-000035 differ diff --git a/packs/cde-supernaturals/lost/000017.log b/packs/cde-supernaturals/lost/000017.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-weapons/000010.ldb b/packs/cde-weapons/000010.ldb deleted file mode 100644 index a8ae084..0000000 Binary files a/packs/cde-weapons/000010.ldb and /dev/null differ diff --git a/packs/cde-weapons/000037.log b/packs/cde-weapons/000037.log new file mode 100644 index 0000000..e69de29 diff --git a/packs/cde-weapons/CURRENT b/packs/cde-weapons/CURRENT index 5b54010..29a53d8 100644 --- a/packs/cde-weapons/CURRENT +++ b/packs/cde-weapons/CURRENT @@ -1 +1 @@ -MANIFEST-000011 +MANIFEST-000035 diff --git a/packs/cde-weapons/LOG b/packs/cde-weapons/LOG index aaf545f..0e20291 100644 --- a/packs/cde-weapons/LOG +++ b/packs/cde-weapons/LOG @@ -1,8 +1,7 @@ -2026/04/29-22:22:16.511423 7fed937fe6c0 Recovering log #8 -2026/04/29-22:22:16.521178 7fed937fe6c0 Delete type=3 #6 -2026/04/29-22:22:16.521274 7fed937fe6c0 Delete type=0 #8 -2026/04/29-22:25:51.942659 7feb10fff6c0 Level-0 table #14: started -2026/04/29-22:25:51.942707 7feb10fff6c0 Level-0 table #14: 0 bytes OK -2026/04/29-22:25:51.948612 7feb10fff6c0 Delete type=0 #12 -2026/04/29-22:25:51.967864 7feb10fff6c0 Manual compaction at level-0 from '!items!2IYbyCPF9LJojzsj' @ 72057594037927935 : 1 .. '!items!uOpWyMGK3oiUJ1Sl' @ 0 : 0; will stop at (end) -2026/04/29-22:25:51.967921 7feb10fff6c0 Manual compaction at level-1 from '!items!2IYbyCPF9LJojzsj' @ 72057594037927935 : 1 .. '!items!uOpWyMGK3oiUJ1Sl' @ 0 : 0; will stop at (end) +2026/05/06-22:32:13.354217 7fe44dfed6c0 Recovering log #33 +2026/05/06-22:32:13.363990 7fe44dfed6c0 Delete type=3 #31 +2026/05/06-22:32:13.364058 7fe44dfed6c0 Delete type=0 #33 +2026/05/06-22:37:23.604413 7fe44cfeb6c0 Level-0 table #38: started +2026/05/06-22:37:23.604439 7fe44cfeb6c0 Level-0 table #38: 0 bytes OK +2026/05/06-22:37:23.610984 7fe44cfeb6c0 Delete type=0 #36 +2026/05/06-22:37:23.617436 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-weapons/LOG.old b/packs/cde-weapons/LOG.old index df6abad..f5e56de 100644 --- a/packs/cde-weapons/LOG.old +++ b/packs/cde-weapons/LOG.old @@ -1,15 +1,7 @@ -2026/04/27-20:01:11.377813 7fed93fff6c0 Recovering log #4 -2026/04/27-20:01:11.387818 7fed93fff6c0 Delete type=3 #2 -2026/04/27-20:01:11.387923 7fed93fff6c0 Delete type=0 #4 -2026/04/27-22:04:19.614736 7feb10fff6c0 Level-0 table #9: started -2026/04/27-22:04:19.618218 7feb10fff6c0 Level-0 table #9: 4526 bytes OK -2026/04/27-22:04:19.624621 7feb10fff6c0 Delete type=0 #7 -2026/04/27-22:04:19.647145 7feb10fff6c0 Manual compaction at level-0 from '!items!2IYbyCPF9LJojzsj' @ 72057594037927935 : 1 .. '!items!uOpWyMGK3oiUJ1Sl' @ 0 : 0; will stop at (end) -2026/04/27-22:04:19.657646 7feb10fff6c0 Manual compaction at level-1 from '!items!2IYbyCPF9LJojzsj' @ 72057594037927935 : 1 .. '!items!uOpWyMGK3oiUJ1Sl' @ 0 : 0; will stop at '!items!uOpWyMGK3oiUJ1Sl' @ 30 : 1 -2026/04/27-22:04:19.657657 7feb10fff6c0 Compacting 1@1 + 1@2 files -2026/04/27-22:04:19.660952 7feb10fff6c0 Generated table #10@1: 15 keys, 4526 bytes -2026/04/27-22:04:19.660988 7feb10fff6c0 Compacted 1@1 + 1@2 files => 4526 bytes -2026/04/27-22:04:19.668099 7feb10fff6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/04/27-22:04:19.668233 7feb10fff6c0 Delete type=2 #5 -2026/04/27-22:04:19.668365 7feb10fff6c0 Delete type=2 #9 -2026/04/27-22:04:19.691602 7feb10fff6c0 Manual compaction at level-1 from '!items!uOpWyMGK3oiUJ1Sl' @ 30 : 1 .. '!items!uOpWyMGK3oiUJ1Sl' @ 0 : 0; will stop at (end) +2026/05/06-22:24:45.736657 7fe44e7ee6c0 Recovering log #29 +2026/05/06-22:24:45.755278 7fe44e7ee6c0 Delete type=3 #27 +2026/05/06-22:24:45.755345 7fe44e7ee6c0 Delete type=0 #29 +2026/05/06-22:30:22.741586 7fe44cfeb6c0 Level-0 table #34: started +2026/05/06-22:30:22.741613 7fe44cfeb6c0 Level-0 table #34: 0 bytes OK +2026/05/06-22:30:22.748498 7fe44cfeb6c0 Delete type=0 #32 +2026/05/06-22:30:22.748771 7fe44cfeb6c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end) diff --git a/packs/cde-weapons/MANIFEST-000011 b/packs/cde-weapons/MANIFEST-000011 deleted file mode 100644 index 8193019..0000000 Binary files a/packs/cde-weapons/MANIFEST-000011 and /dev/null differ diff --git a/packs/cde-weapons/MANIFEST-000035 b/packs/cde-weapons/MANIFEST-000035 new file mode 100644 index 0000000..fb55ffc Binary files /dev/null and b/packs/cde-weapons/MANIFEST-000035 differ diff --git a/packs/cde-weapons/lost/000017.log b/packs/cde-weapons/lost/000017.log new file mode 100644 index 0000000..e69de29 diff --git a/src/config/settings.js b/src/config/settings.js index 686f9c7..25b718a 100644 --- a/src/config/settings.js +++ b/src/config/settings.js @@ -47,6 +47,13 @@ export function registerSettings() { type: Number, default: 0, }) + + game.settings.register(SYSTEM_ID, "welcomeSceneLoaded", { + scope: "world", + config: false, + type: Boolean, + default: false, + }) } /** @@ -56,3 +63,36 @@ export function registerSettings() { export async function migrateIfNeeded() { // No migrations required yet. } + +/** + * On first startup, import the "Accueil" scene from the cde-scenes compendium + * into the world and activate it. Only runs once (tracked via the + * `welcomeSceneLoaded` setting). GM-only. + */ +export async function loadWelcomeSceneIfNeeded() { + if (!game.user.isGM) return + if (game.settings.get(SYSTEM_ID, "welcomeSceneLoaded")) return + + try { + const pack = game.packs.get(`${SYSTEM_ID}.cde-scenes`) + if (!pack) return + + const index = await pack.getIndex() + const entry = index.find(e => e.name === "Accueil") + if (!entry) return + + // Check if the scene already exists in the world (e.g. manually imported) + const existing = game.scenes.find(s => s.name === "Accueil") + let scene = existing + + if (!scene) { + const doc = await pack.getDocument(entry._id) + ;[scene] = await Scene.createDocuments([doc.toObject()]) + } + + await game.settings.set(SYSTEM_ID, "welcomeSceneLoaded", true) + await scene.activate() + } catch (err) { + console.error("CHRONIQUESDELETRANGE | loadWelcomeSceneIfNeeded failed:", err) + } +} diff --git a/src/system.js b/src/system.js index d06d7f0..87fc1e6 100644 --- a/src/system.js +++ b/src/system.js @@ -12,7 +12,7 @@ */ import { ACTOR_TYPES, ITEM_TYPES, MAGICS, SUBTYPES, SYSTEM_ID } from "./config/constants.js" -import { registerSettings, migrateIfNeeded } from "./config/settings.js" +import { registerSettings, migrateIfNeeded, loadWelcomeSceneIfNeeded } from "./config/settings.js" import { preLocalizeConfig } from "./config/localize.js" import { configureRuntime } from "./config/runtime.js" import { CharacterDataModel, NpcDataModel } from "./data/actors/index.js" @@ -30,6 +30,7 @@ import { CDETinjiApp } from "./ui/apps/tinji-app.js" import { CDEWheelApp } from "./ui/apps/wheel-app.js" import { injectRollActions, refreshAllRollActions } from "./ui/roll-actions.js" import { CDECombat } from "./documents/combat.js" +import { showWelcomeMessage, injectWelcomeActions } from "./ui/apps/welcome.js" Hooks.once("i18nInit", preLocalizeConfig) @@ -130,7 +131,9 @@ Hooks.once("init", async () => { Hooks.once("ready", async () => { await migrateIfNeeded() + await loadWelcomeSceneIfNeeded() CDEWheelApp.registerHooks() + if (game.user.isGM) showWelcomeMessage() }) /** Add Loksyu + Tin Ji quick-access buttons to the chat panel (FoundryVTT v13) */ @@ -173,6 +176,7 @@ Hooks.on("renderChatLog", (_app, html) => { /** Inject Loksyu / TinJi action buttons into roll-result chat messages */ Hooks.on("renderChatMessageHTML", (message, html) => { injectRollActions(message, html) + if (message.flags?.[SYSTEM_ID]?.welcome) injectWelcomeActions(message, html) }) /** Refresh all visible roll-result buttons whenever Loksyu or TinJi settings change */ diff --git a/src/ui/apps/index.js b/src/ui/apps/index.js index 3be1cb8..0f62fce 100644 --- a/src/ui/apps/index.js +++ b/src/ui/apps/index.js @@ -16,3 +16,4 @@ export { CDETinjiApp } from "./tinji-app.js" export { updateLoksyuFromRoll, updateTinjiFromRoll } from "./singletons.js" export { CDEWheelApp } from "./wheel-app.js" export { CDEMigrationApp } from "./migration-app.js" +export { showWelcomeMessage, injectWelcomeActions } from "./welcome.js" diff --git a/src/ui/apps/welcome.js b/src/ui/apps/welcome.js new file mode 100644 index 0000000..a0cdcf5 --- /dev/null +++ b/src/ui/apps/welcome.js @@ -0,0 +1,61 @@ +/** + * Chroniques de l'Étrange — Système FoundryVTT + * + * Chroniques de l'Étrange est un jeu de rôle édité par Antre-Monde Éditions. + * Ce système FoundryVTT est une implémentation indépendante et n'est pas + * affilié à Antre-Monde Éditions, + * mais a été réalisé avec l'autorisation d'Antre-Monde Éditions. + * + * @author LeRatierBretonnien + * @copyright 2024–2026 LeRatierBretonnien + * @license CC BY-NC-SA 4.0 – https://creativecommons.org/licenses/by-nc-sa/4.0/ + */ + +import { SYSTEM_ID } from "../../config/constants.js" + +const HELP_JOURNAL_UUID = `Compendium.${SYSTEM_ID}.cde-help.JournalEntry.CDEGuideMain0001` + +/** Post a styled welcome chat message. Called once per session by the GM. */ +export async function showWelcomeMessage() { + const logo = `systems/${SYSTEM_ID}/images/logo_jeu.webp` + const content = ` +
+ +

Les Chroniques de l'Étrange

+ + + +
` + + await ChatMessage.create({ + content, + speaker: { alias: "Les Chroniques de l'Étrange" }, + flags: { [SYSTEM_ID]: { welcome: true } }, + }) +} + +/** Attach the help-open click handler to a welcome chat message HTML node. */ +export function injectWelcomeActions(_message, html) { + const el = html instanceof HTMLElement ? html : (html[0] ?? html) + const btn = el?.querySelector?.("[data-action='open-cde-help']") + if (!btn) return + + btn.addEventListener("click", async () => { + try { + const doc = await fromUuid(HELP_JOURNAL_UUID) + doc?.sheet?.render(true) + } catch { + // Pack not yet loaded — open the compendium browser as fallback + game.packs.get(`${SYSTEM_ID}.cde-help`)?.render(true) + } + }) +} diff --git a/system.json b/system.json index d99243d..b87750b 100644 --- a/system.json +++ b/system.json @@ -125,6 +125,30 @@ "PLAYER": "NONE", "ASSISTANT": "OWNER" } + }, + { + "name": "cde-help", + "label": "Aide en ligne", + "type": "JournalEntry", + "path": "packs/cde-help", + "system": "fvtt-chroniques-de-l-etrange", + "flags": {}, + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "cde-scenes", + "label": "Scènes", + "type": "Scene", + "path": "packs/cde-scenes", + "system": "fvtt-chroniques-de-l-etrange", + "flags": {}, + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } } ], "languages": [