Compare commits

..

7 Commits

113 changed files with 892 additions and 1689 deletions

View File

@@ -1,5 +1,5 @@
3.0.0
- Refonte complète vers DataModels (FoundryVTT V13) et Application V2
13.0.0
- Refonte complète en DataModels (FoundryVTT V13) et Application V2
- Suppression du code legacy (module/) — réécriture totale en src/
- Pipeline LESS (cde-theme.less → cde-theme.css) via lessc/esbuild
- DataModels pour acteurs : character, npc, tinji, loksyu
@@ -15,18 +15,3 @@
* .cde-neon-tabs avec underline néon animé
- Corrections AppV2 : DEFAULT_OPTIONS sans mergeObject, fix tabs display
- ID système : fvtt-chroniques-de-l-etrange
2.3.3
- Image monastère titre sans accentuations
2.3.2
- Correction CSS sur fiche de créature
2.3.1
- Thème de dés par défaut dans Dice-so-Nice!
2.3.0
- Ajout avatar dans Tchat
---
Bugs connus et non encore traités

View File

@@ -12,49 +12,12 @@ Vous pouvez retrouver le nom de leurs auteurs respectifs sur ce site.
version 1.2 ou toute version ultérieure publiée par la Free Software Foundation,
https://commons.wikimedia.org/wiki/File:Hong_Kong_18_Districts_Blank_Map.svg
- 'loksyu_roue_d_initiative.jpg' est une création originale de 'Darkwin'.
- L'organisation du reste des images provient du système produit par MysteryMan (merci à lui)
Code Author :
- Developed by LeRatierBretonnien
MUSIQUES / MUSICS: MODULE À PART À PARTIR DE LA v. 1.0.0
- Les musiques de Mathieu Verdier, composées spécialement pour les CdE,
à l'occasion du financement participatif de ce jeu de rôle,
sont librement téléchargeables sur le site d'Antre Monde Éditions :
https://antre-monde.com/les-chroniques-de-letrengae/
CODE / CODING:
- David R.D. 'Mystery Man From Outerspace' Bercovici
- Christophe 'Kristov / Qaw' Laudon (il a grandement collaboré !)
Avec l'aide précieuse de / with precious help from
(sur / on "La Fonderie" Discord - Many thanks to them!):
- LeRatierBretonnien
- Maxime
(et d'autres / and others)
COMPENDIUMS: MODULES À PART À PARTIR DE LA v. 1.0.0
Basés sur / based on:
Antre Monde Éditions' 'Les Chroniques de l'étrange' RPG books by:
- Romain 'Rom1' d'Huissier
- Cédric 'JTR the Hobbit' Lameire
Saisis par / Entered by:
David R.D. 'Mystery Man From Outerspace' Bercovici
MODULES: MODULES À PART À PARTIR DE LA v. 1.0.0
Les Compendiums sont téléchargeables depuis deux sources :
- Compendiums gratuits :
https://antre-monde.com/les-chroniques-de-letrengae/
- Compendiums payants :
https://preview.drivethrurpg.com/fr/publisher/15811/antre-monde-editions
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
Code LICENCE :
C BY-NC-SA 4.0
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
This license requires that reusers give credit to the creator. It allows reusers to distribute, remix, adapt, and build upon the material in any medium or format, for noncommercial purposes only. If others modify or adapt the material, they must license the modified material under identical terms.

View File

@@ -886,45 +886,135 @@ section.npc .cde-neon-tabs .item.active {
text-align: center;
padding: 10px 0;
}
.cde-supernatural-list .cde-supernatural-item {
background: rgba(16, 22, 34, 0.6);
border: 1px solid #1a2436;
border-radius: 4px;
margin-bottom: 6px;
padding: 6px;
list-style: none;
.cde-super-add-row {
display: flex;
justify-content: flex-end;
padding: 4px 0 8px;
}
.cde-supernatural-list .cde-supernatural-header {
.cde-super-add-btn {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 11px;
font-family: "Averia", sans-serif;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #7d94b8;
cursor: pointer;
padding: 4px 10px;
border-radius: 8px;
border: 1px solid #1a2436;
transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.cde-super-add-btn i {
font-size: 10px;
}
.cde-super-add-btn:hover {
color: #cc44ff;
border-color: #cc44ff;
background: rgba(204, 68, 255, 0.08);
}
.cde-super-card {
border: 1px solid #1a2436;
border-left: 3px solid #cc44ff;
border-radius: 8px;
background: rgba(16, 22, 34, 0.7);
margin-bottom: 10px;
overflow: hidden;
transition: box-shadow 0.15s;
}
.cde-super-card:hover {
box-shadow: 0 0 8px rgba(204, 68, 255, 0.2);
}
.cde-super-card:hover .cde-super-controls {
opacity: 1;
}
.cde-super-header {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
}
.cde-supernatural-list .cde-supernatural-header img {
.cde-super-img {
width: 28px;
height: 28px;
object-fit: contain;
border-radius: 4px;
flex-shrink: 0;
}
.cde-supernatural-list .cde-supernatural-info {
flex: 1 1 0;
.cde-super-info {
flex: 1;
display: flex;
align-items: center;
gap: 6px;
flex-direction: column;
gap: 3px;
min-width: 0;
}
.cde-supernatural-list .cde-supernatural-info .cde-supernatural-name {
font-size: 12px;
font-weight: 600;
.cde-super-name {
font-size: 14px;
font-weight: 700;
font-family: "Averia", sans-serif;
color: #e2e8f4;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.cde-supernatural-list .cde-supernatural-desc {
font-size: 10px;
color: #7d94b8;
margin-top: 4px;
padding-left: 36px;
line-height: 1.4;
.cde-super-meta {
display: flex;
align-items: center;
gap: 4px;
}
.cde-supernatural-list .cde-supernatural-desc p {
margin: 0;
.cde-super-controls {
display: flex;
align-items: center;
gap: 4px;
opacity: 0;
transition: opacity 0.12s;
flex-shrink: 0;
}
.cde-super-controls a {
display: flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
border-radius: 3px;
color: #7d94b8;
cursor: pointer;
transition: color 0.12s, background 0.12s;
}
.cde-super-controls a i {
font-size: 11px;
}
.cde-super-controls a:hover {
color: #e2e8f4;
background: rgba(38, 56, 83, 0.3);
}
.cde-super-desc {
padding: 6px 12px 8px 46px;
border-top: 1px solid rgba(26, 36, 54, 0.6);
background: rgba(16, 22, 34, 0.4);
font-size: 11px;
color: #7d94b8;
line-height: 1.5;
}
.cde-super-desc p {
margin: 0 0 4px;
}
.cde-super-desc p:last-child {
margin-bottom: 0;
}
.cde-super-desc em {
color: #e2e8f4;
}
.cde-super-desc strong {
color: #cc44ff;
}
.cde-super-empty {
padding: 16px;
text-align: center;
font-size: 12px;
color: #7d94b8;
font-style: italic;
}
.cde-npc-tracks {
margin-top: 12px;

353
dist/system.js vendored
View File

@@ -87,6 +87,36 @@ var MAGICS = {
}
}
};
var ASPECT_LABELS = {
metal: "CDE.Metal",
water: "CDE.Water",
earth: "CDE.Earth",
fire: "CDE.Fire",
wood: "CDE.Wood"
};
var ASPECT_ICONS = {
metal: "systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp",
water: "systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp",
earth: "systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp",
fire: "systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp",
wood: "systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp"
};
var ASPECT_FACES = {
metal: [3, 8],
water: [1, 6],
earth: [0, 5],
// 0 = face "10"
fire: [2, 7],
wood: [4, 9]
};
var ASPECT_NAMES = ["metal", "water", "earth", "fire", "wood"];
var WU_XING_CYCLE = {
wood: ["wood", "fire", "water", "earth", "metal"],
fire: ["fire", "earth", "wood", "metal", "water"],
earth: ["earth", "metal", "fire", "water", "wood"],
metal: ["metal", "water", "earth", "wood", "fire"],
water: ["water", "wood", "metal", "fire", "earth"]
};
var TEMPLATE_PARTIALS = [
"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-skills.html",
"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-magics.html",
@@ -103,6 +133,30 @@ var TEMPLATE_PARTIALS = [
"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-tinji-app.html"
];
// src/config/settings.js
function registerSettings() {
game.settings.register(SYSTEM_ID, "loksyuData", {
scope: "world",
config: false,
type: Object,
default: {
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 }
}
});
game.settings.register(SYSTEM_ID, "tinjiData", {
scope: "world",
config: false,
type: Number,
default: 0
});
}
async function migrateIfNeeded() {
}
// src/config/localize.js
function preLocalizeConfig() {
const localizeConfigObject = (obj, keys) => {
@@ -595,18 +649,6 @@ var CDEActor = class extends Actor {
// src/documents/item.js
var CDEItem = class extends Item {
get isWeapon() {
return this.system.subtype === "weapon";
}
get isArmor() {
return this.system.subtype === "armor";
}
get isSanhei() {
return this.system.subtype === "sanhei";
}
get isOther() {
return this.system.subtype === "other";
}
};
// src/ui/dice.js
@@ -894,23 +936,8 @@ async function rollInitiativeNPC(actor) {
}
// src/ui/apps/singletons.js
var SYSTEM_ID2 = "fvtt-chroniques-de-l-etrange";
var WU_XING_CYCLE = {
wood: ["wood", "fire", "water", "earth", "metal"],
fire: ["fire", "earth", "wood", "metal", "water"],
earth: ["earth", "metal", "fire", "water", "wood"],
metal: ["metal", "water", "earth", "wood", "fire"],
water: ["water", "wood", "metal", "fire", "earth"]
};
var ASPECT_FACES = {
metal: [3, 8],
water: [1, 6],
earth: [0, 5],
fire: [2, 7],
wood: [4, 9]
};
function getLoksyuData() {
return game.settings.get(SYSTEM_ID2, "loksyuData") ?? {
return game.settings.get(SYSTEM_ID, "loksyuData") ?? {
wood: { yin: 0, yang: 0 },
fire: { yin: 0, yang: 0 },
earth: { yin: 0, yang: 0 },
@@ -919,14 +946,14 @@ function getLoksyuData() {
};
}
async function setLoksyuData(data) {
await game.settings.set(SYSTEM_ID2, "loksyuData", data);
await game.settings.set(SYSTEM_ID, "loksyuData", data);
Hooks.callAll("cde:loksyuUpdated", data);
}
function getTinjiValue() {
return game.settings.get(SYSTEM_ID2, "tinjiData") ?? 0;
return game.settings.get(SYSTEM_ID, "tinjiData") ?? 0;
}
async function setTinjiValue(value) {
await game.settings.set(SYSTEM_ID2, "tinjiData", Math.max(0, value));
await game.settings.set(SYSTEM_ID, "tinjiData", Math.max(0, value));
Hooks.callAll("cde:tinjiUpdated", Math.max(0, value));
}
async function updateLoksyuFromRoll(activeAspect, faces) {
@@ -965,36 +992,6 @@ var LABELELEMENT_TO_ASPECT = {
"CDE.Fire": "fire",
"CDE.Wood": "wood"
};
var ASPECT_NAMES = ["metal", "water", "earth", "fire", "wood"];
var ASPECT_LABELS = {
metal: "CDE.Metal",
water: "CDE.Water",
earth: "CDE.Earth",
fire: "CDE.Fire",
wood: "CDE.Wood"
};
var ASPECT_ICONS = {
metal: "systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp",
water: "systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp",
earth: "systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp",
fire: "systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp",
wood: "systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp"
};
var ASPECT_FACES2 = {
metal: [3, 8],
water: [1, 6],
earth: [0, 5],
// 0 = face "10"
fire: [2, 7],
wood: [4, 9]
};
var WU_XING_CYCLE2 = {
wood: ["wood", "fire", "water", "earth", "metal"],
fire: ["fire", "earth", "wood", "metal", "water"],
earth: ["earth", "metal", "fire", "water", "wood"],
metal: ["metal", "water", "earth", "wood", "fire"],
water: ["water", "wood", "metal", "fire", "earth"]
};
var RANGE_MALUS = {
contact: 0,
courte: 0,
@@ -1018,14 +1015,14 @@ function countFaces(rollResults) {
return counts;
}
function computeWuXingResults(faces, aspectName, bonusAuspicious = 0) {
const cycle = WU_XING_CYCLE2[aspectName];
const cycle = WU_XING_CYCLE[aspectName];
if (!cycle) return null;
const [succAspect, ausAspect, noxAspect, lokAspect, tinAspect] = cycle;
const [succYin, succYang] = ASPECT_FACES2[succAspect];
const [ausYin, ausYang] = ASPECT_FACES2[ausAspect];
const [noxYin, noxYang] = ASPECT_FACES2[noxAspect];
const [lokYin, lokYang] = ASPECT_FACES2[lokAspect];
const [tinYin, tinYang] = ASPECT_FACES2[tinAspect];
const [succYin, succYang] = ASPECT_FACES[succAspect];
const [ausYin, ausYang] = ASPECT_FACES[ausAspect];
const [noxYin, noxYang] = ASPECT_FACES[noxAspect];
const [lokYin, lokYang] = ASPECT_FACES[lokAspect];
const [tinYin, tinYang] = ASPECT_FACES[tinAspect];
const yin = game.i18n.localize("CDE.Yin");
const yang = game.i18n.localize("CDE.Yang");
return {
@@ -1980,7 +1977,6 @@ var CDEIngredientSheet = class extends CDEBaseItemSheet {
};
// src/ui/apps/loksyu-app.js
var SYSTEM_ID3 = "fvtt-chroniques-de-l-etrange";
var CDELoksyuApp = class _CDELoksyuApp extends foundry.applications.api.HandlebarsApplicationMixin(
foundry.applications.api.ApplicationV2
) {
@@ -2001,7 +1997,7 @@ var CDELoksyuApp = class _CDELoksyuApp extends foundry.applications.api.Handleba
};
static PARTS = {
main: {
template: `systems/${SYSTEM_ID3}/templates/apps/cde-loksyu-app.html`
template: `systems/${SYSTEM_ID}/templates/apps/cde-loksyu-app.html`
}
};
/** @type {Function|null} bound hook handler */
@@ -2022,11 +2018,11 @@ var CDELoksyuApp = class _CDELoksyuApp extends foundry.applications.api.Handleba
async _prepareContext() {
const sys = getLoksyuData();
const ELEMENTS = [
{ key: "wood", nameKey: "CDE.Wood", qualKey: "CDE.WoodQualities", img: `systems/${SYSTEM_ID3}/images/cde_bois.webp` },
{ key: "fire", nameKey: "CDE.Fire", qualKey: "CDE.FireQualities", img: `systems/${SYSTEM_ID3}/images/cde_feu.webp` },
{ key: "earth", nameKey: "CDE.Earth", qualKey: "CDE.EarthQualities", img: `systems/${SYSTEM_ID3}/images/cde_terre.webp` },
{ key: "metal", nameKey: "CDE.Metal", qualKey: "CDE.MetalQualities", img: `systems/${SYSTEM_ID3}/images/cde_metal.webp` },
{ key: "water", nameKey: "CDE.Water", qualKey: "CDE.WaterQualities", img: `systems/${SYSTEM_ID3}/images/cde_eau.webp` }
{ key: "wood", nameKey: "CDE.Wood", qualKey: "CDE.WoodQualities", img: `systems/${SYSTEM_ID}/images/cde_bois.webp` },
{ key: "fire", nameKey: "CDE.Fire", qualKey: "CDE.FireQualities", img: `systems/${SYSTEM_ID}/images/cde_feu.webp` },
{ key: "earth", nameKey: "CDE.Earth", qualKey: "CDE.EarthQualities", img: `systems/${SYSTEM_ID}/images/cde_terre.webp` },
{ key: "metal", nameKey: "CDE.Metal", qualKey: "CDE.MetalQualities", img: `systems/${SYSTEM_ID}/images/cde_metal.webp` },
{ key: "water", nameKey: "CDE.Water", qualKey: "CDE.WaterQualities", img: `systems/${SYSTEM_ID}/images/cde_eau.webp` }
];
return {
canEdit: game.user.isGM,
@@ -2082,7 +2078,6 @@ var CDELoksyuApp = class _CDELoksyuApp extends foundry.applications.api.Handleba
};
// src/ui/apps/tinji-app.js
var SYSTEM_ID4 = "fvtt-chroniques-de-l-etrange";
var CDETinjiApp = class _CDETinjiApp extends foundry.applications.api.HandlebarsApplicationMixin(
foundry.applications.api.ApplicationV2
) {
@@ -2105,7 +2100,7 @@ var CDETinjiApp = class _CDETinjiApp extends foundry.applications.api.Handlebars
};
static PARTS = {
main: {
template: `systems/${SYSTEM_ID4}/templates/apps/cde-tinji-app.html`
template: `systems/${SYSTEM_ID}/templates/apps/cde-tinji-app.html`
}
};
/** @type {Function|null} */
@@ -2178,165 +2173,18 @@ var CDETinjiApp = class _CDETinjiApp extends foundry.applications.api.Handlebars
}
};
// src/migration.js
var MIGRATION_VERSION = "3.0.0";
function registerSettings() {
game.settings.register(SYSTEM_ID, "migrationVersion", {
name: "Migration version",
scope: "world",
config: false,
type: String,
default: "0.0.0"
});
game.settings.register(SYSTEM_ID, "loksyuData", {
name: "Loksyu Data",
scope: "world",
config: false,
type: Object,
default: { 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 } }
});
game.settings.register(SYSTEM_ID, "tinjiData", {
name: "TinJi Data",
scope: "world",
config: false,
type: Number,
default: 0
});
}
async function migrateIfNeeded() {
const current = MIGRATION_VERSION;
const stored = game.settings.get(SYSTEM_ID, "migrationVersion") ?? "0.0.0";
if (!foundry.utils.isNewerVersion(current, stored)) return;
ui.notifications.info(`CHRONIQUESDELETRANGE | Migration vers ${current} en cours...`, { permanent: true });
await migrateActors();
await migrateItems();
await migrateCompendiumActors();
await migrateCompendiumItems();
await game.settings.set(SYSTEM_ID, "migrationVersion", current);
ui.notifications.info(`CHRONIQUESDELETRANGE | Migration vers ${current} termin\xE9e.`);
}
async function migrateActors() {
const updates = [];
for (const actor of game.actors.contents) {
const updateData = migrateActorData(actor);
if (Object.keys(updateData).length > 0) {
updates.push(actor.update(updateData));
}
}
await Promise.all(updates);
}
async function migrateCompendiumActors() {
const packs = game.packs.filter((p) => p.documentName === "Actor" && p.metadata.system === SYSTEM_ID);
for (const pack of packs) {
const content = await pack.getDocuments();
for (const actor of content) {
const updateData = migrateActorData(actor);
if (Object.keys(updateData).length > 0) {
await actor.update(updateData, { pack: pack.collection });
}
}
}
}
async function migrateItems() {
const updates = [];
for (const item of game.items.contents) {
const updateData = migrateItemData(item);
if (Object.keys(updateData).length > 0) {
updates.push(item.update(updateData));
}
}
await Promise.all(updates);
}
async function migrateCompendiumItems() {
const packs = game.packs.filter((p) => p.documentName === "Item" && p.metadata.system === SYSTEM_ID);
for (const pack of packs) {
const content = await pack.getDocuments();
for (const item of content) {
const updateData = migrateItemData(item);
if (Object.keys(updateData).length > 0) {
await item.update(updateData, { pack: pack.collection });
}
}
}
}
function migrateActorData(actor) {
const updateData = {};
const system = actor.system ?? {};
const actorType = actor.type;
const legacyMagic = system.magics?.masteryofthway;
if (legacyMagic && !system.magics?.masteryoftheway) {
updateData["system.magics.masteryoftheway"] = legacyMagic;
updateData["system.magics.-=masteryofthway"] = null;
}
if ((actorType === "character" || actorType === "npc") && !system.prefs?.typeofthrow) {
const defaultCheck = actorType === "character";
updateData["system.prefs.typeofthrow"] = { check: defaultCheck, choice: "0" };
}
if (actorType === "npc") {
if (system.levelofthreat !== void 0 && system.threat === void 0) {
updateData["system.threat"] = system.levelofthreat;
updateData["system.-=levelofthreat"] = null;
}
if (system.powerofnuisance !== void 0 && system.nuisance === void 0) {
updateData["system.nuisance"] = system.powerofnuisance;
updateData["system.-=powerofnuisance"] = null;
}
}
if (actorType === "character" && typeof system.guardian === "string") {
const guardianNum = parseInt(system.guardian, 10);
if (!isNaN(guardianNum)) {
updateData["system.guardian"] = guardianNum;
}
}
return updateData;
}
function migrateItemData(item) {
const updateData = {};
const system = item.system ?? {};
if (item.type === "weapon") {
const ASPECT_FR_TO_EN = { eau: "water", terre: "earth", feu: "fire", bois: "wood" };
const normalized = ASPECT_FR_TO_EN[system.damageAspect];
if (normalized) {
updateData["system.damageAspect"] = normalized;
}
}
return updateData;
}
// src/ui/roll-actions.js
var SYSTEM_ID5 = "fvtt-chroniques-de-l-etrange";
var RESULT_TEMPLATE3 = "systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html";
var WU_XING_CYCLE3 = {
wood: ["wood", "fire", "water", "earth", "metal"],
fire: ["fire", "earth", "wood", "metal", "water"],
earth: ["earth", "metal", "fire", "water", "wood"],
metal: ["metal", "water", "earth", "wood", "fire"],
water: ["water", "wood", "metal", "fire", "earth"]
};
var ASPECT_LABELS2 = {
metal: "CDE.Metal",
water: "CDE.Water",
earth: "CDE.Earth",
fire: "CDE.Fire",
wood: "CDE.Wood"
};
var ASPECT_ICONS2 = {
metal: "systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp",
water: "systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp",
earth: "systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp",
fire: "systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp",
wood: "systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp"
};
function injectRollActions(message, html) {
const rollCard = html.querySelector(".cde-roll-result");
if (!rollCard) return;
const aspect = rollCard.dataset.aspect;
if (!aspect || !WU_XING_CYCLE3[aspect]) return;
if (!aspect || !WU_XING_CYCLE[aspect]) return;
refreshRollActions(rollCard, aspect, message);
}
function refreshRollActions(rollCard, aspect, message) {
rollCard.querySelector(".cde-roll-actions")?.remove();
const cycle = WU_XING_CYCLE3[aspect];
const cycle = WU_XING_CYCLE[aspect];
const fasteAspect = cycle[1];
const loksyu = getLoksyuData();
const tinji = getTinjiValue();
@@ -2345,19 +2193,19 @@ function refreshRollActions(rollCard, aspect, message) {
const isGM = game.user.isGM;
const hasSomething = successAvail > 0 || fasteAvail > 0 || isGM && tinji > 0;
if (!hasSomething) return;
const aspLabel = game.i18n.localize(ASPECT_LABELS2[aspect]);
const fasteLabel = game.i18n.localize(ASPECT_LABELS2[fasteAspect]);
const aspLabel = game.i18n.localize(ASPECT_LABELS[aspect]);
const fasteLabel = game.i18n.localize(ASPECT_LABELS[fasteAspect]);
let btns = "";
if (successAvail > 0) {
btns += `<button class="cde-roll-action-btn cde-roll-action--success" data-action="loksyu-success">
<img src="${ASPECT_ICONS2[aspect]}" class="cde-roll-action-icon" alt="${aspLabel}"/>
<img src="${ASPECT_ICONS[aspect]}" class="cde-roll-action-icon" alt="${aspLabel}"/>
<span class="cde-roll-action-label">+1 ${game.i18n.localize("CDE.Successes")}</span>
<span class="cde-roll-action-count">${successAvail}</span>
</button>`;
}
if (fasteAvail > 0) {
btns += `<button class="cde-roll-action-btn cde-roll-action--faste" data-action="loksyu-faste">
<img src="${ASPECT_ICONS2[fasteAspect]}" class="cde-roll-action-icon" alt="${fasteLabel}"/>
<img src="${ASPECT_ICONS[fasteAspect]}" class="cde-roll-action-icon" alt="${fasteLabel}"/>
<span class="cde-roll-action-label">+1 ${game.i18n.localize("CDE.AuspiciousDie")}</span>
<span class="cde-roll-action-count">${fasteAvail}</span>
</button>`;
@@ -2405,7 +2253,7 @@ async function _drawFromLoksyu(message, aspect, type, aspectLabel) {
else entry.yin--;
data[aspect] = entry;
await setLoksyuData(data);
const flags = message?.flags?.[SYSTEM_ID5];
const flags = message?.flags?.[SYSTEM_ID];
if (flags?.rollResult && message.isOwner) {
const updated = foundry.utils.deepClone(flags.rollResult);
if (type === "success") {
@@ -2419,7 +2267,7 @@ async function _drawFromLoksyu(message, aspect, type, aspectLabel) {
const newHtml = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE3, updated);
await message.update({
content: newHtml,
[`flags.${SYSTEM_ID5}.rollResult`]: updated
[`flags.${SYSTEM_ID}.rollResult`]: updated
});
}
const remain = entry.yin + entry.yang;
@@ -2428,7 +2276,7 @@ async function _drawFromLoksyu(message, aspect, type, aspectLabel) {
user: game.user.id,
content: `<div class="cde-loksyu-draw-msg">
<div class="cde-loksyu-draw-header">
<img src="${ASPECT_ICONS2[aspect]}" class="cde-loksyu-draw-aspect-icon" alt="${aspectLabel}"/>
<img src="${ASPECT_ICONS[aspect]}" class="cde-loksyu-draw-aspect-icon" alt="${aspectLabel}"/>
<span class="cde-loksyu-draw-user">${game.user.name}</span>
<span class="cde-loksyu-draw-action">${game.i18n.localize("CDE.LoksyuDrawsA")}</span>
<span class="cde-loksyu-draw-type">${typeLabel}</span>
@@ -2464,7 +2312,7 @@ async function _spendTinjiPostRoll() {
function refreshAllRollActions() {
document.querySelectorAll(".chat-message .cde-roll-result[data-aspect]").forEach((card) => {
const aspect = card.dataset.aspect;
if (!aspect || !WU_XING_CYCLE3[aspect]) return;
if (!aspect || !WU_XING_CYCLE[aspect]) return;
const msgEl = card.closest("[data-message-id]");
const msgId = msgEl?.dataset?.messageId;
const message = msgId ? game.messages.get(msgId) : null;
@@ -2552,7 +2400,6 @@ Hooks.once("init", async () => {
await preloadPartials();
registerHandlebarsHelpers();
registerDice();
Hooks.on("renderSettings", (_app, html) => injectCompendiumLink(html));
console.info(`CHRONIQUESDELETRANGE | Initialized`);
});
Hooks.once("ready", async () => {
@@ -2589,31 +2436,15 @@ Hooks.on("updateSetting", (setting) => {
refreshAllRollActions();
}
});
function injectCompendiumLink(html) {
const header = html[0]?.querySelector?.("h4.divider");
if (!header) return;
const section = document.createElement("section");
section.classList.add("settings", "flexcol");
section.innerHTML = `
<section class="links flexcol">
<img class="logo-info" src="systems/fvtt-chroniques-de-l-etrange/images/logo_jeu.webp" />
<h4 class="divider">&nbsp;Lien utile&nbsp;<i class="fa-light fa-up-right-from-square"></i>&nbsp;</h4>
</section>
<section class="settings flexcol">
<button type="button" data-action="open-cde-link">
<i class="fa fa-download"></i>&nbsp;Compendium pour Les CdE&nbsp;<i class="fa-light fa-up-right-from-square"></i>
</button>
<details>
<summary><small>Guide d'installation</small></summary>
<small style="text-align: center;">
<p>Rendez-vous sur le site de l'\xE9diteur, t\xE9l\xE9chargez les PDF contenant les liens vers les compendia, puis ajoutez leurs manifestes dans Foundry.</p>
</small>
</details>
</section>
`;
section.querySelector("button[data-action='open-cde-link']")?.addEventListener("click", () => {
window.open("https://antre-monde.com/les-chroniques-de-letrange/", "_blank");
});
header.parentNode.insertBefore(section, header);
}
/**
* 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.
*
* @author LeRatierBretonnien
* @copyright 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
//# sourceMappingURL=system.js.map

8
dist/system.js.map vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,76 +0,0 @@
{
"fvtt-chroniques-de-l-etrange": {
"system": "fvtt-chroniques-de-l-etrange",
"topology": "standard",
"quantity" : "quantity",
"aliases": {},
"sources": {
"Lampe torche": {
"name": "Lampe torche",
"type": "item",
"consumable": false,
"states": 2,
"light": [
{
"bright": 30, "dim": 300, "angle": 20, "color": "#c2fffb", "alpha": 0.5, "attenuation": 0.8
}
]
},
"怪 Lampe torche": {
"name": "怪 Lampe torche",
"type": "item",
"consumable": false,
"states": 2,
"light": [
{
"bright": 30, "dim": 300, "angle": 20, "color": "#c2fffb", "alpha": 0.5, "attenuation": 0.8
}
]
},
"Flashlight": {
"name": "Flashlight",
"type": "item",
"consumable": false,
"states": 2,
"light": [
{
"bright": 30, "dim": 300, "angle": 20, "color": "#c2fffb", "alpha": 0.5, "attenuation": 0.8
}
]
},
"怪 Flashlight": {
"name": "怪 Flashlight",
"type": "item",
"consumable": false,
"states": 2,
"light": [
{
"bright": 30, "dim": 300, "angle": 20, "color": "#c2fffb", "alpha": 0.5, "attenuation": 0.8
}
]
},
"Linterna eléctrica": {
"name": "Linterna eléctrica",
"type": "item",
"consumable": false,
"states": 2,
"light": [
{
"bright": 30, "dim": 300, "angle": 20, "color": "#c2fffb", "alpha": 0.5, "attenuation": 0.8
}
]
},
"怪 Linterna eléctrica": {
"name": "怪 Linterna eléctrica",
"type": "item",
"consumable": false,
"states": 2,
"light": [
{
"bright": 30, "dim": 300, "angle": 20, "color": "#c2fffb", "alpha": 0.5, "attenuation": 0.8
}
]
}
}
}
}

View File

@@ -1,385 +0,0 @@
{
"CDE.ItemCreate": "Create Equipment",
"CDE.ItemEdit": "Edit Equipment",
"CDE.ItemDelete": "Delete Equipment",
"CDE.ItemNew": "New Equipment",
"CDE.TypeOfItem": "Type of Equipment",
"CDE.Weapon": "Weapon",
"CDE.Armor": "Armor",
"CDE.Sanhei": "Sanhei",
"CDE.Other": "Other",
"CDE.ResourceMin": "Min",
"CDE.ResourceValue": "Value",
"CDE.ResourceMax": "Max",
"CDE.DefineTemplate": "Define as Template",
"CDE.UnsetTemplate": "Unset Template",
"CDE.NoTemplate": "No Template",
"CDE.NoSupernaturals": "No supernatural powers",
"CDE.NoSpells": "No spells",
"CDE.NoKungFu": "No martial arts",
"CDE.Quantity": "Quantity",
"CDE.Weight": "Weight",
"CDE.Damage": "Damage",
"CDE.Range": "Range",
"CDE.Masterized": "You have mastered this Technique",
"CDE.Create": "Create",
"CDE.New": "New",
"CDE.Name": "Name",
"CDE.PCName": "Character's Name",
"CDE.Concept": "Concept",
"CDE.CelestialGuardian": "Celestial Guardian",
"CDE.CelestialGuardian1": "White Tiger (Metal)",
"CDE.CelestialGuardian2": "Black Tortoise (Water)",
"CDE.CelestialGuardian3": "Yellow Kilin (Earth)",
"CDE.CelestialGuardian4": "Vermilion Bird (Fire)",
"CDE.CelestialGuardian5": "Azure Dragon (Wood)",
"CDE.Description": "Description",
"CDE.Description2": "Description",
"CDE.Attributes": "Attributes",
"CDE.Skills": "Skills",
"CDE.Magics": "Magics",
"CDE.Resources": "Resources",
"CDE.Treasures": "Three Treasures",
"CDE.NgHang": "Ng Hang",
"CDE.Items": "Equipment",
"CDE.KungFu": "Kung Fu",
"CDE.Spells": "Spells",
"CDE.ModernJapan": "Modern Japan",
"CDE.Die": "Click Here to Throw Dice For ",
"CDE.DieSP": "Click Here to Throw Dice For This Speciality: ",
"CDE.DieDM": "Click Here to Throw Dice For One Of These Fields",
"CDE.Debt": "Check If You Have Incurred a Debt For ",
"CDE.Specialities": "Specialities",
"CDE.Fields": "Fields",
"CDE.Art": "Art",
"CDE.Investigation": "Investigation",
"CDE.Erudition": "Erudition",
"CDE.Knavery": "Knavery",
"CDE.Wordliness": "Wordliness",
"CDE.Prowess": "Prowess",
"CDE.Sciences": "Sciences",
"CDE.Technologies": "Technologies",
"CDE.RangedCombat": "Ranged Combat",
"CDE.Supply": "Supply",
"CDE.Inquiry": "Inquiry",
"CDE.Influence": "Influence",
"CDE.Components2": "Components & Ingredients",
"CDE.Component": "Component #",
"CDE.ChanceThrow": "Selecting a Component at Random in a Hurry",
"CDE.TypesOfMagic": "Types of Magic",
"CDE.InternalCinnabar": "Internal Cinnabar",
"CDE.Alchemy": "Alchemy",
"CDE.MasteryOfTheWay": "Mastery of the Way",
"CDE.Exorcism": "Exorcism",
"CDE.Geomancy": "Geomancy",
"CDE.Metal": "㊎ Metal ",
"CDE.MetalQualities": " aggressive, passionate, combative, enthusiastic…",
"CDE.Water": "㊌ Water ",
"CDE.WaterQualities": " flexible, diligent, adaptable, disciplined…",
"CDE.Earth": "㊏ Earth ",
"CDE.EarthQualities": " stubborn, resilient, enduring, patient…",
"CDE.Fire": "㊋ Fire ",
"CDE.FireQualities": " warm, creative, empathetic, inspired…",
"CDE.Wood": "㊍ Wood ",
"CDE.WoodQualities": " intuitive, observant, open, instinctive…",
"CDE.PracticeSpecialty": "Check If You Practice This Speciality: ",
"CDE.Essence": "Essence",
"CDE.Mind": "Mind",
"CDE.Purification": "Purification",
"CDE.Manipulation": "Manipulation",
"CDE.Aura": "Aura",
"CDE.Acupuncture": "Acupuncture",
"CDE.Elixirs": "Elixirs",
"CDE.Poisons": "Poisons",
"CDE.Arsenal": "Arsenal",
"CDE.Potions": "Potions",
"CDE.Curse": "Curse",
"CDE.Transfiguration": "Transfiguration",
"CDE.Necromancy": "Necromancy",
"CDE.ClimateControl": "Climate Control",
"CDE.GoldenMagic": "Golden Magic",
"CDE.Invocation": "Invocation",
"CDE.Tracking": "Tracking",
"CDE.Protection": "Protection",
"CDE.Punishment": "Punishment",
"CDE.Domination": "Domination",
"CDE.Neutralization": "Neutralization",
"CDE.Divination": "Divination",
"CDE.EarthlyPrayer": "Earthly Prayer",
"CDE.HeavenlyPrayer": "Heavenly Prayer",
"CDE.Fungseoi": "Fungseoi",
"CDE.HEI": "HEI",
"CDE.Essence2": "(Essence)",
"CDE.YANG-YIN": "YANG ● YIN",
"CDE.Max-Present-Present-Max": "Max ● Present ● Present ● Max",
"CDE.SAN-ZING": "SAN ● ZING",
"CDE.MentalHealth-PhysicalHealth": "(Mental Health ● Physical Health)",
"CDE.Max-Present-Malus-Present-Max": "Max ● Present ● Malus ● Present ● Max",
"CDE.PTAO": "PTAO",
"CDE.Experience": "(Experience)",
"CDE.Total-Present": "Total ● Present",
"CDE.Present": "Present",
"CDE.Total": "Total",
"CDE.Max": "Max",
"CDE.Orientation": "Orientation",
"CDE.Aspect": "Aspect",
"CDE.Skill": "Skill",
"CDE.Speciality": "Speciality",
"CDE.Style": "Style",
"CDE.Field": "Field",
"CDE.Technique": "Technique",
"CDE.Activation": "Activation",
"CDE.KFCreate": "Create Martial Art",
"CDE.KFEdit": "Edit Martial Art",
"CDE.KFDelete": "Delete Martial Art",
"CDE.KFNew": "New Martial Art",
"CDE.SpecialityName": "Speciality Name",
"CDE.AssociatedElement": "Associated Element",
"CDE.HEI2": "Hei",
"CDE.RealizationTimeRitual": "Realization Time (Ritual)",
"CDE.RealizationTimeAccelerated": "Realization Time (Accelerated)",
"CDE.Data": "Data",
"CDE.Flashback": "Flashback",
"CDE.Components": "Components",
"CDE.Effects": "Effects",
"CDE.Examples": "Examples",
"CDE.SpellCreate": "Create Spell",
"CDE.SpellEdit": "Edit Spell",
"CDE.SpellDelete": "Delete Spell",
"CDE.SpellNew": "New Spell",
"CDE.SkillPromptName": "Skill Roll",
"CDE.Modifiers": "Modifiers",
"CDE.BonusMalus": "Bonus/Malus D",
"CDE.WoundMalus": "Wound Malus",
"CDE.HeiSpend": "HEI Spend",
"CDE.SpellBonus": "Spell Bonus",
"CDE.SpellPower": "Spell Power",
"CDE.BonusAuspiciousDice": "Bonus/Auspicious-Dice",
"CDE.MagicPromptName": "Magic Roll",
"CDE.OneMagicRoll": "1. Magic Roll",
"CDE.DoNotModify": "Do not Modify this Aspect",
"CDE.AspectSkill": "Aspect/Skill",
"CDE.TwoPowerOfSpell": "2. Power of Spell",
"CDE.AspectSpeciality": "Aspect/Speciality",
"CDE.RollDifficulty": "Roll Difficulty",
"CDE.TypeOfThrow": "Type of Throwing: Visible by…",
"CDE.Everybody": "Everybody",
"CDE.JustDMAndMe": "Just the DM and Me",
"CDE.DMOnly": "DM Only",
"CDE.MeOnly": "Me Only",
"CDE.AuspiciousDice": "Auspicious-Dice",
"CDE.AuspiciousDie": "Auspicious-Die",
"CDE.Validate": "Validate",
"CDE.Cancel": "Cancel",
"CDE.NPCName": "NPC's Name",
"CDE.TypeOfCreature": "Type of Creature",
"CDE.Threat": "Capacity of Threat",
"CDE.Profane": "Profane",
"CDE.Apprentice": "Apprentice",
"CDE.Initiate": "Initiate",
"CDE.Accomplished": "Accomplished",
"CDE.Renowned": "Renowned",
"CDE.Nuisance": "Level of Nuisance",
"CDE.Figurant": "Figurant",
"CDE.Minion": "Minion",
"CDE.Adversary": "Adversary",
"CDE.Ally": "Ally",
"CDE.Boss": "Boss",
"CDE.Divinity": "Divinity",
"CDE.Aptitudes": "Aptitudes",
"CDE.SuperNatural": "Supernatural Abilities",
"CDE.Physical": "● Physical",
"CDE.Martial": "● Martial",
"CDE.Mental": "● Mental",
"CDE.Social": "● Social",
"CDE.Spiritual": "● Spiritual",
"CDE.Vitality": "Vitality",
"CDE.Hei": "Hei",
"CDE.Notes": "Notes",
"CDE.SupernaturalCreate": "Create Supernatural Ability",
"CDE.SupernaturalEdit": "Edit Supernatural Ability",
"CDE.SupernaturalDelete": "Delete Supernatural Ability",
"CDE.SupernaturalNew": "New Supernatural Ability",
"CDE.LoksyuName": "Loksyu Name",
"CDE.Loksyu": "Loksyu",
"CDE.LoksyuNotFound": "No Loksyu actor found. The Game Master must create one.",
"CDE.MetalYang": "㊎ Yang Metal (3)",
"CDE.MetalYin": "㊎ Yin Metal (8)",
"CDE.WaterYang": "㊌ Yang Water (1)",
"CDE.WaterYin": "㊌ Yin Water (6)",
"CDE.EarthYang": "㊏Yang Earth (5)",
"CDE.EarthYin": "㊏Yin Earth (0)",
"CDE.FireYang": "㊋ Yang Fire (7)",
"CDE.FireYin": "㊋ Yin Fire (2)",
"CDE.WoodYang": "㊍ Yang Wood (9)",
"CDE.WoodYin": "㊍ Yin Wood (4)",
"CDE.Yin": "● Yin",
"CDE.Yang": "○ Yang",
"CDE.Successes": "Successes",
"CDE.Beneficial": "Auspicious-Dice",
"CDE.Noxious": "Noxious-Dice",
"CDE.TinJi": "Tin Ji:",
"CDE.Loksyu2": "Loksyu:",
"CDE.Results": "Results:",
"CDE.SpecialAspect": "Speciality Aspect",
"CDE.Randomize": "Randomize",
"CDE.RandomizeSentence": "# of the Component Selected at Random in a Hurry",
"CDE.Reference": "Reference",
"CDE.Error0": "Unable to proceed: total dice number to be thrown is less than 1.",
"CDE.Error1": "Unable to proceed: you don't possess this Skill.",
"CDE.Error2": "Unable to proceed: you don't possess any Speciality in this Skill.",
"CDE.Error3": "Unable to proceed: you don't possess this Resource.",
"CDE.Error4": "Unable to proceed: you don't possess any Field in this Resource.",
"CDE.Error5": "Unable to proceed: you don't possess this Magical Skill.",
"CDE.Error6": "Unable to proceed: you don't possess this Speciality in this Magical Skill.",
"CDE.Error10": "Unable to proceed: you've got 0 or less in this Aspect.",
"CDE.Error12": "Unable to proceed: you can't possess any Speciality in this Skill which score is less than 1.",
"CDE.Error14": "Unable to proceed: you can't possess any Field in this Resource which score is less than 1.",
"CDE.Error16": "Unable to proceed: you can't possess any Speciality in this Magical Skill which score is less than 1.",
"CDE.Preferences": "Preferences for this actor",
"CDE.TypeOfThrowCheck": "Always ask before making a throw",
"CDE.TypeOfThrow4ThisTime": "Type of Throwing for this time: Visible by…",
"CDE.TypeOfThrowTitle": "Modify Type of Throw?",
"CDE.CancelChanges": "Cancel Changes",
"CDE.NextTimeGoToTheSettings": "All these are parametrable in the Settings",
"CDE.OneDie": "Die",
"CDE.ManyDice": "Dice",
"CDE.HasCastASpell": "has cast a spell ",
"CDE.MsgMagic1": "The number of Hei points spent on the ",
"CDE.MsgMagic2": "speciality spell is ",
"CDE.MsgMagic3": ". The power to be invoked is ",
"CDE.MsgMagic4": ", if the spell is cast successfully.",
"CDE.TinJiName": "Tin Ji Name",
"CDE.TinJi2": "Tin Ji",
"CDE.TinjiNotFound": "No Tin Ji actor found. The Game Master must create one.",
"CDE.TinjiEmpty": "No Tin Ji dice remaining.",
"CDE.TinjiSpent": "{name} spends 1 Tin Ji die.",
"CDE.PostRollActions": "Draw from Loksyu / Spend Tin Ji",
"CDE.LoksyuDrawsA": "draws",
"CDE.LoksyuFromAspect": "from",
"CDE.LoksyuRemaining": "die/dice remaining",
"CDE.LoksyuEmpty": "The Loksyu has no dice remaining for this aspect.",
"CDE.TinjiRemaining": "remaining",
"CDE.SpendTinji": "Spend a die",
"CDE.Reset": "Reset",
"CDE.ResetAll": "Reset all",
"CDE.Decrement": "Decrease",
"CDE.Increment": "Increase",
"CDE.UpperCaseSuccesses": "SUCCESSES",
"CDE.UpperCaseAuspiciousDice": "AUSPICIOUS-DICE",
"CDE.UpperCaseNoxiousDice": "NOXIOUS-DICE",
"CDE.UpperCaseLoksyu": "LOKSYU",
"CDE.UpperCaseTinJi": "TIN JI",
"CDE.UpperCaseMetal": "METAL",
"CDE.UpperCaseWater": "WATER",
"CDE.UpperCaseEarth": "EARTH",
"CDE.UpperCaseFire": "FIRE",
"CDE.UpperCaseWood": "WOOD",
"CDE.Visible": "Visible Specialities",
"CDE.MartialArts": "Martial Arts",
"CDE.Initiative": "Initiative",
"CDE.TurnOrder": "Determining your Initiative",
"CDE.InitiativeSpeciality": "First action (Skill) you plan to perform",
"CDE.InitiativeNPCSpeciality": "First action (Aptitude) you plan to perform",
"CDE.DeterminateInitiative": "Determine Initiative: Prowess + first action",
"CDE.DeterminateNPCInitiative": "Determine Initiative: Physical Aptitude + first action",
"CDE.PlusInitiative": "More Initiative",
"CDE.MinusInitiative": "Less Initiative",
"TYPES": {
"Actor": {
"character": "Fat si",
"npc": "Creature",
"tinji": "Tin Ji",
"loksyu": "Loksyu"
},
"Item": {
"item": "Equipment",
"kungfu": "Martial Art",
"spell": "Spell",
"supernatural": "Supernatural Ability"
}
},
"CDE.WeaponCreate": "Create Weapon",
"CDE.ArmorCreate": "Create Armor",
"CDE.SanheiCreate": "Create San Hei",
"CDE.IngredientCreate": "Create Ingredient",
"CDE.WeaponNew": "New Weapon",
"CDE.ArmorNew": "New Armor",
"CDE.SanheiNew": "New San Hei",
"CDE.IngredientNew": "New Ingredient",
"CDE.ArmorType": "Armor",
"CDE.SanheiType": "San Hei",
"CDE.IngredientType": "Ingredient",
"CDE.ItemType": "Item",
"CDE.Weapons": "Weapons",
"CDE.Armors": "Armors",
"CDE.Sanheis": "San Hei",
"CDE.CreatureMortel": "Mortal",
"CDE.CreatureDemon": "Demon",
"CDE.CreatureEsprit": "Spirit",
"CDE.CreatureEspritAnimal": "Animal Spirit",
"CDE.CreatureFantome": "Ghost",
"CDE.CreatureJiugwaai": "Jiugwaai",
"CDE.CreatureDieu": "God / Divinity"
}

View File

@@ -1,340 +0,0 @@
{
"CDE.ItemCreate": "Crear un Equipo",
"CDE.ItemEdit": "Editar el Equipo",
"CDE.ItemDelete": "Borrar el Equipo",
"CDE.ItemNew": "Nuevo Equipo",
"CDE.TypeOfItem": "Tipo de Equipo",
"CDE.Weapon": "Arma",
"CDE.Armor": "Armor",
"CDE.Sanhei": "Sanhei",
"CDE.Other": "Otro",
"CDE.ResourceMin": "Min",
"CDE.ResourceValue": "Valor",
"CDE.ResourceMax": "Máx",
"CDE.DefineTemplate": " Establecer como Plantilla",
"CDE.UnsetTemplate": "Deactivar la Plantilla",
"CDE.NoTemplate": "Sin Plantilla",
"CDE.Quantity": "Cantidad",
"CDE.Weight": "Peso",
"CDE.Damage": "Daños",
"CDE.Range": "Alcance",
"CDE.Masterized": "Ha dominado esta técnica",
"CDE.Create": "Crear",
"CDE.New": "Nuevo",
"CDE.Name": "Nombre",
"CDE.PCName": "Nombre del Personaje",
"CDE.Concept": "Concepto",
"CDE.CelestialGuardian": "Guardián Celestial",
"CDE.CelestialGuardian1": "Tigre Blanco (Metal)",
"CDE.CelestialGuardian2": "Tortuga Negra (Agua)",
"CDE.CelestialGuardian3": "Kirin Amarillo (Tierra)",
"CDE.CelestialGuardian4": "Pájaro Escarlata (Fuego)",
"CDE.CelestialGuardian5": "Dragón Azul (Madera)",
"CDE.Description": "Descripción",
"CDE.Description2" : "Descripción",
"CDE.Attributes": "Atributos",
"CDE.Skills": "Habilidades",
"CDE.Magics": "Magias",
"CDE.Resources": "Recursos",
"CDE.Treasures": "Tres Tesoros",
"CDE.NgHang": "Ng Hang",
"CDE.Items": "Equipo",
"CDE.KungFu": "Kung Fu",
"CDE.Spells": "Hechizos",
"CDE.ModernJapan": "Japón contemporáneo",
"CDE.Die": "Haga clic aquí para tirar los dados para ",
"CDE.DieSP": "Haz clic aquí para tirar los dados para la especialidad ",
"CDE.DieDM": "Haga clic aquí para tirar los dados para una de estas áreas",
"CDE.Debt": "Marque esta casilla si ha contraído una deuda en ",
"CDE.Specialities": "Especialidades",
"CDE.Fields": "Áreas",
"CDE.Art": "Arte",
"CDE.Investigation": "Encuesta",
"CDE.Erudition": "Erudición",
"CDE.Knavery": "Engaño",
"CDE.Wordliness": "Mundanerías",
"CDE.Prowess": "Hazaña",
"CDE.Sciences": "Ciensas",
"CDE.Technologies": "Tecnologías",
"CDE.RangedCombat": "Combate a Distancia",
"CDE.Supply": "Suministro",
"CDE.Inquiry": "Información",
"CDE.Influence": "Influencia",
"CDE.Components2": "Componentes e Ingredientes",
"CDE.Component": "Componente #",
"CDE.ChanceThrow": "Eligir un ingrediente al azar y rápidamente",
"CDE.TypesOfMagic": "Tipos de Magia",
"CDE.InternalCinnabar": "Cinabrio Interno",
"CDE.Alchemy": "Alquimia",
"CDE.MasteryOfTheWay": "Dominio del Camino",
"CDE.Exorcism": "Exorcismo",
"CDE.Geomancy": "Geomancia",
"CDE.Metal": "㊎ Metal ",
"CDE.MetalQualities": " agresivo, apasionado, combativo, entusiasta…",
"CDE.Water": "㊌ Agua ",
"CDE.WaterQualities": " flexible, diligente, adaptable, disciplinado…",
"CDE.Earth": "㊏ Tierra ",
"CDE.EarthQualities": " terco, resistente, perdurable, paciente…",
"CDE.Fire": "㊋ Fuego ",
"CDE.FireQualities": " cálido, creativo, empático, inspirado…",
"CDE.Wood": "㊍ Madera ",
"CDE.WoodQualities": " intuitivo, observador, abierto, instintivo…",
"CDE.PracticeSpecialty": "Marque esta casilla si practica la especialidad ",
"CDE.Essence": "Esencia",
"CDE.Mind": "Mente",
"CDE.Purification": "Purificación",
"CDE.Manipulation": "Manejo",
"CDE.Aura": "Aura",
"CDE.Acupuncture": "Acupunctura",
"CDE.Elixirs": "Elixires",
"CDE.Poisons": "Venenos",
"CDE.Arsenal": "Arsenal",
"CDE.Potions": "Pociones",
"CDE.Curse": "Maldición",
"CDE.Transfiguration": "Transfiguración",
"CDE.Necromancy": "Nigromancia",
"CDE.ClimateControl": "Control Climatico",
"CDE.GoldenMagic": "Magia de Oro",
"CDE.Invocation": "Invocación",
"CDE.Tracking": "Seguimiento",
"CDE.Protection": "Protección",
"CDE.Punishment": "Castigo",
"CDE.Domination": "Dominación",
"CDE.Neutralization": "Neutralización",
"CDE.Divination": "Adivinación",
"CDE.EarthlyPrayer": "Oración Terrenal",
"CDE.HeavenlyPrayer": "Oración Celestial",
"CDE.Fungseoi": "Fungseoi",
"CDE.HEI": "HEI",
"CDE.Essence2": "(Esencia)",
"CDE.YANG-YIN": "YANG ● YIN",
"CDE.Max-Present-Present-Max": "Máx ● Actual ● Actual ● Máx",
"CDE.SAN-ZING": "SAN ● ZING",
"CDE.MentalHealth-PhysicalHealth": "(Salud Mental ● Salud Física)",
"CDE.Max-Present-Malus-Present-Max": "Máx ● Actual ● Malos ● Actual ● Máx",
"CDE.PTAO": "PTAO",
"CDE.Experience": "(Experiencia)",
"CDE.Total-Present": "Total ● Actual",
"CDE.Present": "Actual",
"CDE.Total": "Total",
"CDE.Max": "Máx",
"CDE.Orientation": "Orientación",
"CDE.Aspect": "Aspecto",
"CDE.Skill": "Habilidad",
"CDE.Speciality": "Especialidad",
"CDE.Field": "Área",
"CDE.Style": "Estilo",
"CDE.Technique": "Técnica",
"CDE.Activation": "Activación",
"CDE.KFCreate": "Crear un Arte Marcial",
"CDE.KFEdit": "Editar el Arte Marcial",
"CDE.KFDelete": "Borrar el Arte Marcial",
"CDE.KFNew": "Nuevo Arte Marcial",
"CDE.SpecialityName": "Nombre Especialidad",
"CDE.AssociatedElement": "Elemento Asociado",
"CDE.HEI2": "Hei",
"CDE.RealizationTimeRitual": "Tiempo de Realización (Ritual)",
"CDE.RealizationTimeAccelerated": "Tiempo de Realización (Acelerado)",
"CDE.Flashback": "Flashback",
"CDE.Data": "Data",
"CDE.Components": "Componentes",
"CDE.Effects": "Efectos",
"CDE.Examples": "Ejemplos",
"CDE.SpellCreate": "Crear un Hechizo",
"CDE.SpellEdit": "Editar el Hechizo",
"CDE.SpellDelete": "Borrar el Hechizo",
"CDE.SpellNew": "Nuevo Hechizo",
"CDE.SkillPromptName": "",
"CDE.BonusMalus": "D Bonos/Malos",
"CDE.BonusAuspiciousDice": "Bonos/Dados-buenos",
"CDE.MagicPromptName": "",
"CDE.OneMagicRoll": "1. Tirada Mágica",
"CDE.DoNotModify": "No cambie el Aspecto",
"CDE.AspectSkill": "Aspecto/Habilidad",
"CDE.TwoPowerOfSpell": "2. Poder de Hechizo",
"CDE.AspectSpeciality": "Aspecto/Especialidad",
"CDE.RollDifficulty": "Dificultad de la Tirada",
"CDE.TypeOfThrow": "Tipo de tirada: visible por…",
"CDE.Everybody": "Todo el mundo",
"CDE.JustDMAndMe": "Solo el DM y yo",
"CDE.DMOnly": "El DM solamente",
"CDE.MeOnly": "Yo solamente",
"CDE.AuspiciousDice": "Dados-buenos",
"CDE.AuspiciousDie": "Dada-bueno",
"CDE.Validate": "Validar",
"CDE.Cancel": "Anular",
"CDE.NPCName": "Nombre del NPC",
"CDE.TypeOfCreature": "Tipo de Criatura",
"CDE.Threat": "Nivel de Amenaza",
"CDE.Profane": "Profano",
"CDE.Apprentice": "Aprendiz",
"CDE.Initiate": "Iniciado",
"CDE.Accomplished": "Consumado",
"CDE.Renowned": "Renombrado",
"CDE.Nuisance": "Capacitad de Molesta",
"CDE.Figurant": "Extra",
"CDE.Minion": "Esbirro",
"CDE.Adversary": "Adversario",
"CDE.Ally": "Aliado",
"CDE.Boss": "Jefe",
"CDE.Divinity": "Deidad",
"CDE.Aptitudes": "Aptitudes",
"CDE.SuperNatural": "Habilidades Sobrenaturales",
"CDE.Physical": "● Física",
"CDE.Martial": "● Marcial",
"CDE.Mental": "● Mental",
"CDE.Social": "● Social",
"CDE.Spiritual": "● Espiritual",
"CDE.Vitality": "Vitalidad",
"CDE.Hei": "Hei",
"CDE.Notes": "Notas",
"CDE.SupernaturalCreate": "Crear una Habilidad Sobrenatural",
"CDE.SupernaturalEdit": "Editar la Habilidad Sobrenatural",
"CDE.SupernaturalDelete": "Borrar la Habilidad Sobrenatural",
"CDE.SupernaturalNew": "Nueva Habilidad Sobrenatural",
"CDE.LoksyuName": "Nombre del Loksyu",
"CDE.Loksyu": "Loksyu",
"CDE.MetalYang": "㊎ Metal Yang (3)",
"CDE.MetalYin": "㊎ Metal Yin (8)",
"CDE.WaterYang": "㊌ Agua Yang (1)",
"CDE.WaterYin": "㊌ Agua Yin (6)",
"CDE.EarthYang": "㊏ Tierra Yang (5)",
"CDE.EarthYin": "㊏ Tierra Yin (0)",
"CDE.FireYang": "㊋ Fuego Yang (7)",
"CDE.FireYin": "㊋ Fuego Yin (2)",
"CDE.WoodYang": "㊍ Madera Yang (9)",
"CDE.WoodYin": "㊍ Madera Yin (4)",
"CDE.Yin": "● Yin",
"CDE.Yang": "○ Yang",
"CDE.Successes": "Éxitos",
"CDE.Beneficial": "Dados-Buenos",
"CDE.Noxious": "Dados-Dañinos",
"CDE.TinJi": "Tin Ji:",
"CDE.Loksyu2": "Loksyu:",
"CDE.Results": "Resultados:",
"CDE.SpecialAspect": "Aspecto de Especialidad",
"CDE.Randomize": "Dibujo aleatorio",
"CDE.RandomizeSentence": "# del ingrediente eligido al azar y rápidamente",
"CDE.Reference": "Referencia",
"CDE.Error0": "No se puede continuar: el número total de dados que se van a lanzar es inferior a 1.",
"CDE.Error1": "No se puede continuar: no posee esta habilidad.",
"CDE.Error2": "No se puede continuar: no posee ninguna especialidad en esta habilidad.",
"CDE.Error3": "No se puede continuar: no posee este recurso.",
"CDE.Error4": "No se puede continuar: no posee ningún área en este recurso.",
"CDE.Error5": "No se puede continuar: no posee esta habilidad mágica.",
"CDE.Error6": "No se puede continuar: no posee esta especialidad en esta habilidad mágica.",
"CDE.Error10": "No se puede continuar: tienes 0 o menos en este aspecto.",
"CDE.Error12": "No se puede continuar: no puede poseer ninguna especialidad en esta habilidad cuya puntuación sea inferior a 1.",
"CDE.Error14": "No se puede continuar: no puede poseer ningún área en este recurso cuya puntuación sea inferior a 1.",
"CDE.Error16": "No se puede continuar: no puede poseer ninguna especialidad en esta habilidad mágica cuya puntuación sea inferior a 1.",
"CDE.Preferences": "Preferencias para este actor",
"CDE.TypeOfThrowCheck": "Preguntar siempre antes de realizar una tirada",
"CDE.TypeOfThrow4ThisTime": "Tipo de tirada por esta vez: visible por…",
"CDE.TypeOfThrowTitle": "¿Modificar el tipo de tirada?",
"CDE.CancelChanges": "Cancelar cambios",
"CDE.NextTimeGoToTheSettings": "Todos estos son configurables en la configuración.",
"CDE.OneDie": "dado",
"CDE.ManyDice": "dados",
"CDE.HasCastASpell": "ha lanzado un hechizo ",
"CDE.MsgMagic1": "El número de puntos Hei gastados en el hechizo especial ",
"CDE.MsgMagic2": "es ",
"CDE.MsgMagic3": ". El poder para invocar es ",
"CDE.MsgMagic4": ", si el hechizo se lanza con éxito.",
"CDE.TinJiName": "Nombre de la Tin Ji",
"CDE.TinJi2": "Tin Ji",
"CDE.UpperCaseSuccesses": "ÉXITOS",
"CDE.UpperCaseAuspiciousDice": "DADOS-BUENOS",
"CDE.UpperCaseNoxiousDice": "DADOS-DAÑINOS",
"CDE.UpperCaseLoksyu": "LOKSYU",
"CDE.UpperCaseTinJi": "TIN JI",
"CDE.UpperCaseMetal": "METAL",
"CDE.UpperCaseWater": "AGUA",
"CDE.UpperCaseEarth": "TIERRA",
"CDE.UpperCaseFire": "FUEGO",
"CDE.UpperCaseWood": "MADERA",
"CDE.Visible": "Especialidades visibles",
"CDE.MartialArts": "Artes Marciales",
"CDE.Initiative": "Iniciativa",
"CDE.TurnOrder": "Determinando su iniciativa",
"CDE.InitiativeSpeciality": "Primera acción (Habilidad) que planea realizar",
"CDE.InitiativeNPCSpeciality": "Primera acción (Aptitud) que planea realizar",
"CDE.DeterminateInitiative": "Determinar la iniciativa: Hazaña + primera acción",
"CDE.DeterminateNPCInitiative": "Determinar la iniciativa: Aptitud física + primera acción",
"CDE.PlusInitiative": "Más iniciativa",
"CDE.MinusInitiative": "Menos iniciativa",
"TYPES": {
"Actor": {
"character": "Fat si",
"npc": "Criatura",
"tinji": "Tin Ji",
"loksyu": "Loksyu"
},
"Item": {
"item": "Equipo",
"kungfu": "Arte marcial",
"spell": "Hechizo",
"supernatural": "Habilidad Sobrenatural"
}
}
}

View File

@@ -1,8 +1,8 @@
{
"name": "fvtt-chroniques-de-l-etrange",
"version": "3.0.0",
"description": "Refonte du système Chroniques de l'Étrange avec DataModels et Application V2.",
"main": "dist/system.js",
"version": "13.0.0",
"description": "Système Chroniques de l'Étrange avec DataModels et Application V2.",
"main": "src/system.js",
"scripts": {
"build:css": "lessc css/cde-theme.less css/cde-theme.css",
"build:js": "esbuild src/system.js --bundle --format=esm --target=es2022 --sourcemap --outfile=dist/system.js",
@@ -21,6 +21,7 @@
"type": "module",
"devDependencies": {
"esbuild": "^0.27.4",
"jscpd": "^4.0.8",
"less": "^4.2.0"
},
"dependencies": {

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000078

View File

@@ -1,3 +0,0 @@
2026/03/30-15:06:44.332250 7f4bdafee6c0 Recovering log #76
2026/03/30-15:06:44.345027 7f4bdafee6c0 Delete type=3 #74
2026/03/30-15:06:44.345091 7f4bdafee6c0 Delete type=0 #76

View File

@@ -1,7 +0,0 @@
2026/03/30-14:14:12.690902 7f4bdafee6c0 Recovering log #72
2026/03/30-14:14:12.745563 7f4bdafee6c0 Delete type=3 #70
2026/03/30-14:14:12.745612 7f4bdafee6c0 Delete type=0 #72
2026/03/30-15:06:34.607428 7f4bd8fea6c0 Level-0 table #77: started
2026/03/30-15:06:34.607461 7f4bd8fea6c0 Level-0 table #77: 0 bytes OK
2026/03/30-15:06:34.613785 7f4bd8fea6c0 Delete type=0 #75
2026/03/30-15:06:34.613973 7f4bd8fea6c0 Manual compaction at level-0 from '!journal!ZWBHiWW5QlUeseAX' @ 72057594037927935 : 1 .. '!journal.pages!ZWBHiWW5QlUeseAX.jtQXIqLfyet8Nlte' @ 0 : 0; will stop at (end)

View File

@@ -1 +0,0 @@
MANIFEST-000194

View File

@@ -1,3 +0,0 @@
2026/03/30-15:06:44.318696 7f4bd97eb6c0 Recovering log #192
2026/03/30-15:06:44.329241 7f4bd97eb6c0 Delete type=3 #190
2026/03/30-15:06:44.329288 7f4bd97eb6c0 Delete type=0 #192

View File

@@ -1,8 +0,0 @@
2026/03/30-14:14:12.605619 7f4bd9fec6c0 Recovering log #188
2026/03/30-14:14:12.686963 7f4bd9fec6c0 Delete type=3 #186
2026/03/30-14:14:12.687013 7f4bd9fec6c0 Delete type=0 #188
2026/03/30-15:06:34.620345 7f4bd8fea6c0 Level-0 table #193: started
2026/03/30-15:06:34.620377 7f4bd8fea6c0 Level-0 table #193: 0 bytes OK
2026/03/30-15:06:34.628129 7f4bd8fea6c0 Delete type=0 #191
2026/03/30-15:06:34.641660 7f4bd8fea6c0 Manual compaction at level-0 from '!journal!TniC3ok9W0hDYxJS' @ 72057594037927935 : 1 .. '!journal.pages!yZsG9QaBHT3cUfNd.AHcfBcO96nUCELxv' @ 0 : 0; will stop at (end)
2026/03/30-15:06:34.641692 7f4bd8fea6c0 Manual compaction at level-1 from '!journal!TniC3ok9W0hDYxJS' @ 72057594037927935 : 1 .. '!journal.pages!yZsG9QaBHT3cUfNd.AHcfBcO96nUCELxv' @ 0 : 0; will stop at (end)

View File

@@ -1 +0,0 @@
MANIFEST-000766

View File

@@ -1,3 +0,0 @@
2026/03/30-15:06:44.305642 7f4bda7ed6c0 Recovering log #764
2026/03/30-15:06:44.315212 7f4bda7ed6c0 Delete type=3 #762
2026/03/30-15:06:44.315294 7f4bda7ed6c0 Delete type=0 #764

View File

@@ -1,8 +0,0 @@
2026/03/30-14:14:12.515876 7f4bd97eb6c0 Recovering log #760
2026/03/30-14:14:12.589985 7f4bd97eb6c0 Delete type=3 #758
2026/03/30-14:14:12.590051 7f4bd97eb6c0 Delete type=0 #760
2026/03/30-15:06:34.600499 7f4bd8fea6c0 Level-0 table #765: started
2026/03/30-15:06:34.600616 7f4bd8fea6c0 Level-0 table #765: 0 bytes OK
2026/03/30-15:06:34.607256 7f4bd8fea6c0 Delete type=0 #763
2026/03/30-15:06:34.613958 7f4bd8fea6c0 Manual compaction at level-0 from '!journal!f6UhPlIUh2O0F36q' @ 72057594037927935 : 1 .. '!journal.pages!f6UhPlIUh2O0F36q.keqszrb6FAI7CVZx' @ 0 : 0; will stop at (end)
2026/03/30-15:06:34.614004 7f4bd8fea6c0 Manual compaction at level-1 from '!journal!f6UhPlIUh2O0F36q' @ 72057594037927935 : 1 .. '!journal.pages!f6UhPlIUh2O0F36q.keqszrb6FAI7CVZx' @ 0 : 0; will stop at (end)

View File

@@ -1 +0,0 @@
MANIFEST-004387

View File

@@ -1,3 +0,0 @@
2026/03/30-15:06:44.225449 7f4bd97eb6c0 Recovering log #4385
2026/03/30-15:06:44.236150 7f4bd97eb6c0 Delete type=3 #4383
2026/03/30-15:06:44.236230 7f4bd97eb6c0 Delete type=0 #4385

View File

@@ -1,7 +0,0 @@
2026/03/30-14:14:12.387545 7f4bda7ed6c0 Recovering log #4381
2026/03/30-14:14:12.435510 7f4bda7ed6c0 Delete type=3 #4379
2026/03/30-14:14:12.435579 7f4bda7ed6c0 Delete type=0 #4381
2026/03/30-15:06:34.685316 7f4bd8fea6c0 Level-0 table #4386: started
2026/03/30-15:06:34.685354 7f4bd8fea6c0 Level-0 table #4386: 0 bytes OK
2026/03/30-15:06:34.691827 7f4bd8fea6c0 Delete type=0 #4384
2026/03/30-15:06:34.709676 7f4bd8fea6c0 Manual compaction at level-0 from '!journal!0lxwWrzKsdTBQhH0' @ 72057594037927935 : 1 .. '!journal.pages!wgSyae4GTJDkmBOm.6Ql0lgquUCTrMyTZ' @ 0 : 0; will stop at (end)

View File

@@ -1 +0,0 @@
MANIFEST-000107

View File

@@ -1,3 +0,0 @@
2026/03/30-15:06:44.375576 7f4bd97eb6c0 Recovering log #105
2026/03/30-15:06:44.385281 7f4bd97eb6c0 Delete type=3 #103
2026/03/30-15:06:44.385352 7f4bd97eb6c0 Delete type=0 #105

View File

@@ -1,8 +0,0 @@
2026/03/30-14:14:12.872794 7f4bd9fec6c0 Recovering log #101
2026/03/30-14:14:12.920810 7f4bd9fec6c0 Delete type=3 #99
2026/03/30-14:14:12.920879 7f4bd9fec6c0 Delete type=0 #101
2026/03/30-15:06:34.717076 7f4bd8fea6c0 Level-0 table #106: started
2026/03/30-15:06:34.717223 7f4bd8fea6c0 Level-0 table #106: 0 bytes OK
2026/03/30-15:06:34.723514 7f4bd8fea6c0 Delete type=0 #104
2026/03/30-15:06:34.740972 7f4bd8fea6c0 Manual compaction at level-0 from '!tables!J9VdvrwkbyKxMAT7' @ 72057594037927935 : 1 .. '!tables.results!jGKjfCyk4ROSy9fU.zRzADzATtijaBdNX' @ 0 : 0; will stop at (end)
2026/03/30-15:06:34.741010 7f4bd8fea6c0 Manual compaction at level-1 from '!tables!J9VdvrwkbyKxMAT7' @ 72057594037927935 : 1 .. '!tables.results!jGKjfCyk4ROSy9fU.zRzADzATtijaBdNX' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000088

View File

View File

@@ -1,3 +0,0 @@
2026/03/30-15:06:44.362194 7f4bdafee6c0 Recovering log #86
2026/03/30-15:06:44.373140 7f4bdafee6c0 Delete type=3 #84
2026/03/30-15:06:44.373208 7f4bdafee6c0 Delete type=0 #86

View File

@@ -1,8 +0,0 @@
2026/03/30-14:14:12.812401 7f4bdafee6c0 Recovering log #82
2026/03/30-14:14:12.871063 7f4bdafee6c0 Delete type=3 #80
2026/03/30-14:14:12.871115 7f4bdafee6c0 Delete type=0 #82
2026/03/30-15:06:34.592601 7f4bd8fea6c0 Level-0 table #87: started
2026/03/30-15:06:34.592754 7f4bd8fea6c0 Level-0 table #87: 0 bytes OK
2026/03/30-15:06:34.600381 7f4bd8fea6c0 Delete type=0 #85
2026/03/30-15:06:34.613943 7f4bd8fea6c0 Manual compaction at level-0 from '!macros!apyHJT40enTKFUfX' @ 72057594037927935 : 1 .. '!macros!suexsLbORUfE9ptz' @ 0 : 0; will stop at (end)
2026/03/30-15:06:34.613995 7f4bd8fea6c0 Manual compaction at level-1 from '!macros!apyHJT40enTKFUfX' @ 72057594037927935 : 1 .. '!macros!suexsLbORUfE9ptz' @ 0 : 0; will stop at (end)

Binary file not shown.

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-000266

View File

View File

@@ -1,3 +0,0 @@
2026/03/30-15:06:44.348172 7f4bda7ed6c0 Recovering log #264
2026/03/30-15:06:44.358939 7f4bda7ed6c0 Delete type=3 #262
2026/03/30-15:06:44.358996 7f4bda7ed6c0 Delete type=0 #264

View File

@@ -1,8 +0,0 @@
2026/03/30-14:14:12.747731 7f4bda7ed6c0 Recovering log #260
2026/03/30-14:14:12.800943 7f4bda7ed6c0 Delete type=3 #258
2026/03/30-14:14:12.801033 7f4bda7ed6c0 Delete type=0 #260
2026/03/30-15:06:34.614167 7f4bd8fea6c0 Level-0 table #265: started
2026/03/30-15:06:34.614201 7f4bd8fea6c0 Level-0 table #265: 0 bytes OK
2026/03/30-15:06:34.620245 7f4bd8fea6c0 Delete type=0 #263
2026/03/30-15:06:34.641645 7f4bd8fea6c0 Manual compaction at level-0 from '!macros!Admg6zBHid4mfbJY' @ 72057594037927935 : 1 .. '!macros!wY3tga12higX7soz' @ 0 : 0; will stop at (end)
2026/03/30-15:06:34.641681 7f4bd8fea6c0 Manual compaction at level-1 from '!macros!Admg6zBHid4mfbJY' @ 72057594037927935 : 1 .. '!macros!wY3tga12higX7soz' @ 0 : 0; will stop at (end)

Binary file not shown.

View File

@@ -1 +0,0 @@
MANIFEST-001008

View File

@@ -1,3 +0,0 @@
2026/03/30-15:06:44.274432 7f4bdafee6c0 Recovering log #1006
2026/03/30-15:06:44.302845 7f4bdafee6c0 Delete type=3 #1004
2026/03/30-15:06:44.302897 7f4bdafee6c0 Delete type=0 #1006

View File

@@ -1,8 +0,0 @@
2026/03/30-14:14:12.447332 7f4bdafee6c0 Recovering log #1002
2026/03/30-14:14:12.506248 7f4bdafee6c0 Delete type=3 #1000
2026/03/30-14:14:12.506320 7f4bdafee6c0 Delete type=0 #1002
2026/03/30-15:06:34.585439 7f4bd8fea6c0 Level-0 table #1007: started
2026/03/30-15:06:34.585515 7f4bd8fea6c0 Level-0 table #1007: 0 bytes OK
2026/03/30-15:06:34.592340 7f4bd8fea6c0 Delete type=0 #1005
2026/03/30-15:06:34.613927 7f4bd8fea6c0 Manual compaction at level-0 from '!journal!OgzOugwIXfHtijaY' @ 72057594037927935 : 1 .. '!journal.pages!OgzOugwIXfHtijaY.OOev7kj2KoMOGoMD' @ 0 : 0; will stop at (end)
2026/03/30-15:06:34.613985 7f4bd8fea6c0 Manual compaction at level-1 from '!journal!OgzOugwIXfHtijaY' @ 72057594037927935 : 1 .. '!journal.pages!OgzOugwIXfHtijaY.OOev7kj2KoMOGoMD' @ 0 : 0; will stop at (end)

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export const SYSTEM_ID = "fvtt-chroniques-de-l-etrange"
export const ACTOR_TYPES = {
@@ -91,6 +104,49 @@ export const MAGICS = {
},
}
/** Map aspect name → i18n label key */
export const ASPECT_LABELS = {
metal: "CDE.Metal",
water: "CDE.Water",
earth: "CDE.Earth",
fire: "CDE.Fire",
wood: "CDE.Wood",
}
/** Map aspect name → image path */
export const ASPECT_ICONS = {
metal: "systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp",
water: "systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp",
earth: "systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp",
fire: "systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp",
wood: "systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp",
}
/** Map aspect name → die face pair [yin, yang] (face=10 stored as 0) */
export const ASPECT_FACES = {
metal: [3, 8],
water: [1, 6],
earth: [0, 5], // 0 = face "10"
fire: [2, 7],
wood: [4, 9],
}
/** Ordered aspect names by index (metal=0, water=1, earth=2, fire=3, wood=4) */
export const ASPECT_NAMES = ["metal", "water", "earth", "fire", "wood"]
/**
* Wu Xing generating/overcoming cycle.
* For each active aspect, the five result categories in order:
* [successes, auspicious, noxious, loksyu, tinji]
*/
export const WU_XING_CYCLE = {
wood: ["wood", "fire", "water", "earth", "metal"],
fire: ["fire", "earth", "wood", "metal", "water"],
earth: ["earth", "metal", "fire", "water", "wood"],
metal: ["metal", "water", "earth", "wood", "fire"],
water: ["water", "wood", "metal", "fire", "earth"],
}
export const TEMPLATE_PARTIALS = [
"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-skills.html",
"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-magics.html",

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
import { MAGICS, SUBTYPES } from "./constants.js"
export function preLocalizeConfig() {

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export function configureRuntime() {
CONFIG.Actor.compendiumBanner = "/systems/fvtt-chroniques-de-l-etrange/images/banners/actor-banner.webp"
CONFIG.Adventure.compendiumBanner = "/systems/fvtt-chroniques-de-l-etrange/images/banners/adventure-banner.webp"

48
src/config/settings.js Normal file
View File

@@ -0,0 +1,48 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
import { SYSTEM_ID } from "./constants.js"
/**
* Register all world/client settings for the system.
* Called during the "init" hook before sheets and data-models are set up.
*/
export function registerSettings() {
game.settings.register(SYSTEM_ID, "loksyuData", {
scope: "world",
config: false,
type: Object,
default: {
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 },
},
})
game.settings.register(SYSTEM_ID, "tinjiData", {
scope: "world",
config: false,
type: Number,
default: 0,
})
}
/**
* Run any pending data migrations on the "ready" hook.
* Reserved for future schema migrations.
*/
export async function migrateIfNeeded() {
// No migrations required yet.
}

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class CharacterDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,2 +1,15 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export { default as CharacterDataModel } from "./character.js"
export { default as NpcDataModel } from "./npc.js"

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class NpcDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class ArmorDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export { default as EquipmentDataModel } from "./item.js"
export { default as KungfuDataModel } from "./kungfu.js"
export { default as SpellDataModel } from "./spell.js"

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class IngredientDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class EquipmentDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class KungfuDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class SanheiDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class SpellDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class SupernaturalDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export default class WeaponDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
import { ACTOR_TYPES } from "../config/constants.js"
export class CDEActor extends Actor {

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export class CDEMessage extends ChatMessage {
async renderHTML({ canDelete, canClose = false, ...rest } = {}) {
const html = await super.renderHTML({ canDelete, canClose, ...rest })

View File

@@ -1,17 +1,15 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export class CDEItem extends Item {
get isWeapon() {
return this.system.subtype === "weapon"
}
get isArmor() {
return this.system.subtype === "armor"
}
get isSanhei() {
return this.system.subtype === "sanhei"
}
get isOther() {
return this.system.subtype === "other"
}
}

View File

@@ -1,146 +0,0 @@
import { SYSTEM_ID } from "./config/constants.js"
const MIGRATION_VERSION = "3.0.0"
export function registerSettings() {
game.settings.register(SYSTEM_ID, "migrationVersion", {
name: "Migration version",
scope: "world",
config: false,
type: String,
default: "0.0.0",
})
game.settings.register(SYSTEM_ID, "loksyuData", {
name: "Loksyu Data",
scope: "world",
config: false,
type: Object,
default: { 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} },
})
game.settings.register(SYSTEM_ID, "tinjiData", {
name: "TinJi Data",
scope: "world",
config: false,
type: Number,
default: 0,
})
}
export async function migrateIfNeeded() {
const current = MIGRATION_VERSION
const stored = game.settings.get(SYSTEM_ID, "migrationVersion") ?? "0.0.0"
if (!foundry.utils.isNewerVersion(current, stored)) return
ui.notifications.info(`CHRONIQUESDELETRANGE | Migration vers ${current} en cours...`, { permanent: true })
await migrateActors()
await migrateItems()
await migrateCompendiumActors()
await migrateCompendiumItems()
await game.settings.set(SYSTEM_ID, "migrationVersion", current)
ui.notifications.info(`CHRONIQUESDELETRANGE | Migration vers ${current} terminée.`)
}
async function migrateActors() {
const updates = []
for (const actor of game.actors.contents) {
const updateData = migrateActorData(actor)
if (Object.keys(updateData).length > 0) {
updates.push(actor.update(updateData))
}
}
await Promise.all(updates)
}
async function migrateCompendiumActors() {
const packs = game.packs.filter((p) => p.documentName === "Actor" && p.metadata.system === SYSTEM_ID)
for (const pack of packs) {
const content = await pack.getDocuments()
for (const actor of content) {
const updateData = migrateActorData(actor)
if (Object.keys(updateData).length > 0) {
await actor.update(updateData, { pack: pack.collection })
}
}
}
}
async function migrateItems() {
const updates = []
for (const item of game.items.contents) {
const updateData = migrateItemData(item)
if (Object.keys(updateData).length > 0) {
updates.push(item.update(updateData))
}
}
await Promise.all(updates)
}
async function migrateCompendiumItems() {
const packs = game.packs.filter((p) => p.documentName === "Item" && p.metadata.system === SYSTEM_ID)
for (const pack of packs) {
const content = await pack.getDocuments()
for (const item of content) {
const updateData = migrateItemData(item)
if (Object.keys(updateData).length > 0) {
await item.update(updateData, { pack: pack.collection })
}
}
}
}
function migrateActorData(actor) {
const updateData = {}
const system = actor.system ?? {}
const actorType = actor.type
// Fix legacy typo: masteryofthway -> masteryoftheway
const legacyMagic = system.magics?.masteryofthway
if (legacyMagic && !system.magics?.masteryoftheway) {
updateData["system.magics.masteryoftheway"] = legacyMagic
updateData["system.magics.-=masteryofthway"] = null
}
// Ensure prefs.typeofthrow exists on relevant actor types
if ((actorType === "character" || actorType === "npc") && !system.prefs?.typeofthrow) {
const defaultCheck = actorType === "character"
updateData["system.prefs.typeofthrow"] = { check: defaultCheck, choice: "0" }
}
// Migrate NPC field renames: levelofthreat → threat, powerofnuisance → nuisance
if (actorType === "npc") {
if (system.levelofthreat !== undefined && system.threat === undefined) {
updateData["system.threat"] = system.levelofthreat
updateData["system.-=levelofthreat"] = null
}
if (system.powerofnuisance !== undefined && system.nuisance === undefined) {
updateData["system.nuisance"] = system.powerofnuisance
updateData["system.-=powerofnuisance"] = null
}
}
// Migrate character guardian from string to number
if (actorType === "character" && typeof system.guardian === "string") {
const guardianNum = parseInt(system.guardian, 10)
if (!isNaN(guardianNum)) {
updateData["system.guardian"] = guardianNum
}
}
return updateData
}
function migrateItemData(item) {
const updateData = {}
const system = item.system ?? {}
// Normalize legacy French damageAspect values to English keys
if (item.type === "weapon") {
const ASPECT_FR_TO_EN = { eau: "water", terre: "earth", feu: "fire", bois: "wood" }
const normalized = ASPECT_FR_TO_EN[system.damageAspect]
if (normalized) {
updateData["system.damageAspect"] = normalized
}
}
return updateData
}

View File

@@ -1,4 +1,18 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
import { ACTOR_TYPES, ITEM_TYPES, MAGICS, SUBTYPES, SYSTEM_ID } from "./config/constants.js"
import { registerSettings, migrateIfNeeded } from "./config/settings.js"
import { preLocalizeConfig } from "./config/localize.js"
import { configureRuntime } from "./config/runtime.js"
import { CharacterDataModel, NpcDataModel } from "./data/actors/index.js"
@@ -13,7 +27,6 @@ import { CDECharacterSheet, CDENpcSheet } from "./ui/sheets/actors/index.js"
import { CDEItemSheet, CDEKungfuSheet, CDESpellSheet, CDESupernaturalSheet, CDEWeaponSheet, CDEArmorSheet, CDESanheiSheet, CDEIngredientSheet } from "./ui/sheets/items/index.js"
import { CDELoksyuApp } from "./ui/apps/loksyu-app.js"
import { CDETinjiApp } from "./ui/apps/tinji-app.js"
import { migrateIfNeeded, registerSettings } from "./migration.js"
import { injectRollActions, refreshAllRollActions } from "./ui/roll-actions.js"
Hooks.once("i18nInit", preLocalizeConfig)
@@ -107,7 +120,6 @@ Hooks.once("init", async () => {
await preloadPartials()
registerHandlebarsHelpers()
registerDice()
Hooks.on("renderSettings", (_app, html) => injectCompendiumLink(html))
console.info(`CHRONIQUESDELETRANGE | Initialized`)
})
@@ -138,7 +150,7 @@ Hooks.on("renderChatLog", (_app, html) => {
// Use event delegation to avoid being swallowed by Foundry's own handlers
wrapper.addEventListener("click", (ev) => {
if (ev.target.closest(".cde-chat-btn--loksyu")) CDELoksyuApp.open()
if (ev.target.closest(".cde-chat-btn--tinji")) CDETinjiApp.open()
if (ev.target.closest(".cde-chat-btn--tinji")) CDETinjiApp.open()
})
// Insert before the chat form — works on v12 and v13
@@ -161,33 +173,3 @@ Hooks.on("updateSetting", setting => {
refreshAllRollActions()
}
})
function injectCompendiumLink(html) {
const header = html[0]?.querySelector?.("h4.divider")
if (!header) return
const section = document.createElement("section")
section.classList.add("settings", "flexcol")
section.innerHTML = `
<section class="links flexcol">
<img class="logo-info" src="systems/fvtt-chroniques-de-l-etrange/images/logo_jeu.webp" />
<h4 class="divider">&nbsp;Lien utile&nbsp;<i class="fa-light fa-up-right-from-square"></i>&nbsp;</h4>
</section>
<section class="settings flexcol">
<button type="button" data-action="open-cde-link">
<i class="fa fa-download"></i>&nbsp;Compendium pour Les CdE&nbsp;<i class="fa-light fa-up-right-from-square"></i>
</button>
<details>
<summary><small>Guide d'installation</small></summary>
<small style="text-align: center;">
<p>Rendez-vous sur le site de l'éditeur, téléchargez les PDF contenant les liens vers les compendia, puis ajoutez leurs manifestes dans Foundry.</p>
</small>
</details>
</section>
`
section.querySelector("button[data-action='open-cde-link']")?.addEventListener("click", () => {
window.open("https://antre-monde.com/les-chroniques-de-letrange/", "_blank")
})
header.parentNode.insertBefore(section, header)
}

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export { CDELoksyuApp } from "./loksyu-app.js"
export { CDETinjiApp } from "./tinji-app.js"
export { getSingletonActor, updateLoksyuFromRoll, updateTinjiFromRoll } from "./singletons.js"
export { updateLoksyuFromRoll, updateTinjiFromRoll } from "./singletons.js"

View File

@@ -1,6 +1,18 @@
import { getLoksyuData, setLoksyuData } from "./singletons.js"
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
const SYSTEM_ID = "fvtt-chroniques-de-l-etrange"
import { getLoksyuData, setLoksyuData } from "./singletons.js"
import { SYSTEM_ID } from "../../config/constants.js"
export class CDELoksyuApp extends foundry.applications.api.HandlebarsApplicationMixin(
foundry.applications.api.ApplicationV2

View File

@@ -1,27 +1,23 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
/**
* Loksyu / TinJi settings-based helpers.
*
* Data is stored as world settings instead of singleton Actor documents.
*/
const SYSTEM_ID = "fvtt-chroniques-de-l-etrange"
/** Wu Xing generating cycle — [successes, auspicious, noxious, loksyu, tinji] */
const WU_XING_CYCLE = {
wood: ["wood", "fire", "water", "earth", "metal"],
fire: ["fire", "earth", "wood", "metal", "water"],
earth: ["earth", "metal", "fire", "water", "wood"],
metal: ["metal", "water", "earth", "wood", "fire"],
water: ["water", "wood", "metal", "fire", "earth"],
}
const ASPECT_FACES = {
metal: [3, 8],
water: [1, 6],
earth: [0, 5],
fire: [2, 7],
wood: [4, 9],
}
import { SYSTEM_ID, WU_XING_CYCLE, ASPECT_FACES } from "../../config/constants.js"
/** Read the current loksyu data object from world settings */
export function getLoksyuData() {

View File

@@ -1,6 +1,18 @@
import { getTinjiValue, setTinjiValue } from "./singletons.js"
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
const SYSTEM_ID = "fvtt-chroniques-de-l-etrange"
import { getTinjiValue, setTinjiValue } from "./singletons.js"
import { SYSTEM_ID } from "../../config/constants.js"
export class CDETinjiApp extends foundry.applications.api.HandlebarsApplicationMixin(
foundry.applications.api.ApplicationV2

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
const DIGIT_LABELS = [
"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-1.webp",
"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-2.webp",

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
import { MAGICS } from "../config/constants.js"
export function registerHandlebarsHelpers() {

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
/**
* Initiative determination system for Chroniques de l'Étrange.
*

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
/**
* Post-roll interactive action buttons injected into dice result chat messages.
* Allows players to pull dice from the Loksyu (as Successes or dés-fastes)
@@ -8,34 +21,10 @@
*/
import { getLoksyuData, setLoksyuData, getTinjiValue, setTinjiValue } from "./apps/singletons.js"
import { SYSTEM_ID, WU_XING_CYCLE, ASPECT_LABELS, ASPECT_ICONS } from "../config/constants.js"
const SYSTEM_ID = "fvtt-chroniques-de-l-etrange"
const RESULT_TEMPLATE = "systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html"
const WU_XING_CYCLE = {
wood: ["wood", "fire", "water", "earth", "metal"],
fire: ["fire", "earth", "wood", "metal", "water"],
earth: ["earth", "metal", "fire", "water", "wood"],
metal: ["metal", "water", "earth", "wood", "fire"],
water: ["water", "wood", "metal", "fire", "earth"],
}
const ASPECT_LABELS = {
metal: "CDE.Metal",
water: "CDE.Water",
earth: "CDE.Earth",
fire: "CDE.Fire",
wood: "CDE.Wood",
}
const ASPECT_ICONS = {
metal: "systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp",
water: "systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp",
earth: "systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp",
fire: "systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp",
wood: "systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp",
}
/**
* Inject or refresh post-roll action buttons in the given chat message HTML element.
* Called from renderChatMessageHTML hook.

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
/**
* Wu Xing rolling system for Chroniques de l'Étrange.
*
@@ -13,7 +26,7 @@
* Each category is associated with one of the five aspects in Wu Xing cycle order.
*/
import { MAGICS } from "../config/constants.js"
import { MAGICS, ASPECT_LABELS, ASPECT_ICONS, ASPECT_FACES, ASPECT_NAMES, WU_XING_CYCLE } from "../config/constants.js"
import { updateLoksyuFromRoll, updateTinjiFromRoll } from "./apps/singletons.js"
const RESULT_TEMPLATE = "systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html"
@@ -31,50 +44,6 @@ const LABELELEMENT_TO_ASPECT = {
"CDE.Wood": "wood",
}
/** Map aspect index → string name used in result template */
const ASPECT_NAMES = ["metal", "water", "earth", "fire", "wood"]
/** Map aspect name → i18n label key */
const ASPECT_LABELS = {
metal: "CDE.Metal",
water: "CDE.Water",
earth: "CDE.Earth",
fire: "CDE.Fire",
wood: "CDE.Wood",
}
/** Map aspect name → image path */
const ASPECT_ICONS = {
metal: "systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp",
water: "systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp",
earth: "systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp",
fire: "systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp",
wood: "systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp",
}
/** Map aspect index → die face pair [yin, yang] (face=10 stored as 0) */
const ASPECT_FACES = {
metal: [3, 8],
water: [1, 6],
earth: [0, 5], // 0 = face "10"
fire: [2, 7],
wood: [4, 9],
}
/**
* Wu Xing generating/overcoming cycle:
* wood → fire → earth → metal → water → wood (generating)
* For each active aspect, the five categories in order:
* [successes, auspicious, noxious, loksyu, tinji]
*/
const WU_XING_CYCLE = {
wood: ["wood", "fire", "water", "earth", "metal"],
fire: ["fire", "earth", "wood", "metal", "water"],
earth: ["earth", "metal", "fire", "water", "wood"],
metal: ["metal", "water", "earth", "wood", "fire"],
water: ["water", "wood", "metal", "fire", "earth"],
}
/** Maps weapon range string → dice malus applied to the attack pool */
const RANGE_MALUS = {
contact: 0,
@@ -171,7 +140,7 @@ async function showRollPrompt({ title, template, data, fields }) {
* @param {object} params - Initial values
* @returns {Promise<object|null>}
*/
export async function showSkillPrompt(params) {
async function showSkillPrompt(params) {
return showRollPrompt({
title: params.title,
template: params.isSpecial ? SKILL_SPECIAL_PROMPT_TEMPLATE : SKILL_PROMPT_TEMPLATE,
@@ -190,7 +159,7 @@ export async function showSkillPrompt(params) {
/**
* Open the magic roll prompt and return the user-confirmed parameters.
*/
export async function showMagicPrompt(params) {
async function showMagicPrompt(params) {
return showRollPrompt({
title: params.title,
template: MAGIC_PROMPT_TEMPLATE,
@@ -214,7 +183,7 @@ export async function showMagicPrompt(params) {
/**
* Open the weapon attack roll prompt and return user-confirmed parameters.
*/
export async function showWeaponPrompt(params) {
async function showWeaponPrompt(params) {
return showRollPrompt({
title: params.title,
template: WEAPON_PROMPT_TEMPLATE,

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
const { HandlebarsApplicationMixin } = foundry.applications.api
export class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {

View File

@@ -1,3 +1,16 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
import { MAGICS, SUBTYPES } from "../../../config/constants.js"
import { rollInitiativePC } from "../../initiative.js"
import { rollForActor } from "../../rolling.js"

View File

@@ -1,2 +1,15 @@
/**
* 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 20242026 LeRatierBretonnien
* @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
export { CDECharacterSheet } from "./character.js"
export { CDENpcSheet } from "./npc.js"

Some files were not shown because too many files have changed in this diff Show More