Refactor des fiches de creatures
This commit is contained in:
120
dist/system.js
vendored
120
dist/system.js
vendored
@@ -740,6 +740,11 @@ function registerHandlebarsHelpers() {
|
||||
Handlebars.registerHelper("getElementIcon", function(aspect) {
|
||||
const 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",
|
||||
// legacy French keys
|
||||
eau: "/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp",
|
||||
terre: "/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp",
|
||||
feu: "/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp",
|
||||
@@ -825,7 +830,7 @@ function buildNPCOptions(sys) {
|
||||
function readInitFields(dialog) {
|
||||
const root = dialog.element ?? dialog;
|
||||
const selectedKey = root.querySelector("select[name='firstaction']")?.value ?? "";
|
||||
const modifier = parseInt(root.querySelector("input[name='modifier']")?.value ?? 0) || 0;
|
||||
const modifier = parseInt(root.querySelector("input[name='modifier']")?.value ?? "0", 10) || 0;
|
||||
return { selectedKey, modifier };
|
||||
}
|
||||
async function sendInitChatMessage({ actor, baseName, baseValue, actionName, actionValue, modifier, initiative, antiInitiative }) {
|
||||
@@ -1139,6 +1144,10 @@ async function rollForActor(actor, rollKey) {
|
||||
numberofdice = sys.aspect[skillLibel]?.value ?? 0;
|
||||
title = game.i18n.localize(sys.aspect[skillLibel]?.label ?? "CDE.Roll");
|
||||
break;
|
||||
case "aptitude":
|
||||
numberofdice = sys.aptitudes?.[skillLibel]?.value ?? 0;
|
||||
title = game.i18n.localize(`CDE.${skillLibel.charAt(0).toUpperCase() + skillLibel.slice(1)}`);
|
||||
break;
|
||||
case "skill":
|
||||
numberofdice = sys.skills[skillLibel]?.value ?? 0;
|
||||
title = game.i18n.localize(sys.skills[skillLibel]?.label ?? "CDE.Roll");
|
||||
@@ -1180,7 +1189,7 @@ async function rollForActor(actor, rollKey) {
|
||||
ui.notifications.warn(game.i18n.localize("CDE.Error6"));
|
||||
return;
|
||||
}
|
||||
title = `${game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? "CDE.Magics")} [${game.i18n.localize(game.system.CONST?.MAGICS?.[skillLibel]?.speciality?.[specialLibel]?.label ?? "")}]`;
|
||||
title = `${game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? "CDE.Magics")} [${game.i18n.localize(MAGICS?.[skillLibel]?.speciality?.[specialLibel]?.label ?? "")}]`;
|
||||
break;
|
||||
case "itemkungfu": {
|
||||
const kfItem = actor.items.get(skillLibel);
|
||||
@@ -1318,7 +1327,7 @@ async function rollForActor(actor, rollKey) {
|
||||
}
|
||||
let defaultSpecialAspect = 0;
|
||||
if (isMagicSpecial && specialLibel) {
|
||||
const specialCfg = game.system.CONST?.MAGICS?.[skillLibel]?.speciality?.[specialLibel];
|
||||
const specialCfg = MAGICS?.[skillLibel]?.speciality?.[specialLibel];
|
||||
const aspectName = LABELELEMENT_TO_ASPECT[specialCfg?.labelelement];
|
||||
if (aspectName) {
|
||||
defaultSpecialAspect = ASPECT_NAMES.indexOf(aspectName);
|
||||
@@ -1454,7 +1463,8 @@ var CDEBaseActorSheet = class _CDEBaseActorSheet extends HandlebarsApplicationMi
|
||||
actions: {
|
||||
create: _CDEBaseActorSheet.#onItemCreate,
|
||||
edit: _CDEBaseActorSheet.#onItemEdit,
|
||||
delete: _CDEBaseActorSheet.#onItemDelete
|
||||
delete: _CDEBaseActorSheet.#onItemDelete,
|
||||
editImage: _CDEBaseActorSheet.#onEditImage
|
||||
}
|
||||
};
|
||||
tabGroups = { primary: "description" };
|
||||
@@ -1462,7 +1472,7 @@ var CDEBaseActorSheet = class _CDEBaseActorSheet extends HandlebarsApplicationMi
|
||||
return this.document.name;
|
||||
}
|
||||
async _prepareContext() {
|
||||
const descriptionHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? "", { async: true });
|
||||
const descriptionHTML = await TextEditor.enrichHTML(this.document.system.description ?? "", { async: true });
|
||||
const cssClass = this.options.classes?.join(" ") ?? "";
|
||||
return {
|
||||
actor: this.document,
|
||||
@@ -1514,6 +1524,20 @@ var CDEBaseActorSheet = class _CDEBaseActorSheet extends HandlebarsApplicationMi
|
||||
const item = this.document.items.get(itemId);
|
||||
if (item) item.delete();
|
||||
}
|
||||
static async #onEditImage(event, target) {
|
||||
const attr = target.dataset.edit;
|
||||
const current = foundry.utils.getProperty(this.document, attr);
|
||||
const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {};
|
||||
const fp = new FilePicker({
|
||||
current,
|
||||
type: "image",
|
||||
redirectToRoot: img ? [img] : [],
|
||||
callback: (path) => this.document.update({ [attr]: path }),
|
||||
top: this.position.top + 40,
|
||||
left: this.position.left + 10
|
||||
});
|
||||
return fp.browse();
|
||||
}
|
||||
};
|
||||
|
||||
// src/ui/sheets/actors/character.js
|
||||
@@ -1564,7 +1588,7 @@ var CDECharacterSheet = class extends CDEBaseActorSheet {
|
||||
return context;
|
||||
}
|
||||
_onRender(context, options) {
|
||||
super._onRender?.(context, options);
|
||||
super._onRender(context, options);
|
||||
this.#bindInitiativeControls();
|
||||
this.#bindPrefs();
|
||||
this.#bindRollButtons();
|
||||
@@ -1602,7 +1626,7 @@ var CDECharacterSheet = class extends CDEBaseActorSheet {
|
||||
<form class="flexcol">
|
||||
<div class="form-group">
|
||||
<label>${game.i18n.localize("CDE.ThrowType")}</label>
|
||||
<select name="choice" value="${current.choice}">
|
||||
<select name="choice">
|
||||
<option value="0"${current.choice === "0" ? " selected" : ""}>0</option>
|
||||
<option value="1"${current.choice === "1" ? " selected" : ""}>1</option>
|
||||
<option value="2"${current.choice === "2" ? " selected" : ""}>2</option>
|
||||
@@ -1614,14 +1638,18 @@ var CDECharacterSheet = class extends CDEBaseActorSheet {
|
||||
<input type="checkbox" name="check" ${current.check ? "checked" : ""}/>
|
||||
</div>
|
||||
</form>`;
|
||||
const prefs = await Dialog.prompt({
|
||||
title: game.i18n.localize("CDE.Preferences"),
|
||||
const prefs = await foundry.applications.api.DialogV2.prompt({
|
||||
window: { title: game.i18n.localize("CDE.Preferences") },
|
||||
content: html,
|
||||
label: game.i18n.localize("CDE.Validate"),
|
||||
callback: (dlg) => {
|
||||
const choice = dlg.querySelector("select[name='choice']")?.value ?? "0";
|
||||
const check = dlg.querySelector("input[name='check']")?.checked ?? false;
|
||||
return { choice, check };
|
||||
rejectClose: false,
|
||||
ok: {
|
||||
label: game.i18n.localize("CDE.Validate"),
|
||||
callback: (_ev, _btn, dialog) => {
|
||||
const root = dialog.element ?? dialog;
|
||||
const choice = root.querySelector("select[name='choice']")?.value ?? "0";
|
||||
const check = root.querySelector("input[name='check']")?.checked ?? false;
|
||||
return { choice, check };
|
||||
}
|
||||
}
|
||||
});
|
||||
if (prefs) {
|
||||
@@ -1675,7 +1703,7 @@ var CDECharacterSheet = class extends CDEBaseActorSheet {
|
||||
speaker: ChatMessage.getSpeaker({ actor: this.document }),
|
||||
content,
|
||||
rolls: [roll],
|
||||
rollMode: "roll"
|
||||
rollMode: game.settings.get("core", "rollMode") ?? "roll"
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1695,12 +1723,26 @@ var CDENpcSheet = class extends CDEBaseActorSheet {
|
||||
context.supernaturals = context.items.filter((item) => item.type === "supernatural");
|
||||
context.spells = context.items.filter((item) => item.type === "spell");
|
||||
context.kungfus = context.items.filter((item) => item.type === "kungfu");
|
||||
context.weapons = context.items.filter((item) => item.type === "weapon");
|
||||
context.armors = context.items.filter((item) => item.type === "armor");
|
||||
context.equipments = context.items.filter((item) => item.type === "item");
|
||||
return context;
|
||||
}
|
||||
_onRender(context, options) {
|
||||
super._onRender?.(context, options);
|
||||
super._onRender(context, options);
|
||||
this.#bindInitiativeControls();
|
||||
this.#bindRollButtons();
|
||||
}
|
||||
#bindRollButtons() {
|
||||
const cells = this.element?.querySelectorAll(".cde-roll-trigger[data-libel-id]");
|
||||
if (!cells?.length) return;
|
||||
cells.forEach((cell) => {
|
||||
cell.addEventListener("click", (event) => {
|
||||
event.preventDefault();
|
||||
const rollKey = cell.dataset.libelId;
|
||||
if (rollKey) rollForActor(this.document, rollKey);
|
||||
});
|
||||
});
|
||||
}
|
||||
#bindInitiativeControls() {
|
||||
const buttons = this.element?.querySelectorAll(".click-initiative-npc");
|
||||
@@ -1751,13 +1793,15 @@ var CDELoksyuSheet = class extends CDEBaseActorSheet {
|
||||
|
||||
// src/ui/sheets/items/base.js
|
||||
var { HandlebarsApplicationMixin: HandlebarsApplicationMixin2 } = foundry.applications.api;
|
||||
var CDEBaseItemSheet = class extends HandlebarsApplicationMixin2(foundry.applications.sheets.ItemSheetV2) {
|
||||
var CDEBaseItemSheet = class _CDEBaseItemSheet extends HandlebarsApplicationMixin2(foundry.applications.sheets.ItemSheetV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["fvtt-chroniques-de-l-etrange", "item"],
|
||||
position: { width: 520, height: "auto" },
|
||||
window: { resizable: true },
|
||||
form: { submitOnChange: true },
|
||||
actions: {}
|
||||
actions: {
|
||||
editImage: _CDEBaseItemSheet.#onEditImage
|
||||
}
|
||||
};
|
||||
tabGroups = { primary: "details" };
|
||||
get title() {
|
||||
@@ -1765,8 +1809,8 @@ var CDEBaseItemSheet = class extends HandlebarsApplicationMixin2(foundry.applica
|
||||
}
|
||||
async _prepareContext() {
|
||||
const cssClass = this.options.classes?.join(" ") ?? "";
|
||||
const enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? "", { async: true });
|
||||
const enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes ?? "", { async: true });
|
||||
const enrichedDescription = await TextEditor.enrichHTML(this.document.system.description ?? "", { async: true });
|
||||
const enrichedNotes = await TextEditor.enrichHTML(this.document.system.notes ?? "", { async: true });
|
||||
return {
|
||||
item: this.document,
|
||||
system: this.document.system,
|
||||
@@ -1787,6 +1831,20 @@ var CDEBaseItemSheet = class extends HandlebarsApplicationMixin2(foundry.applica
|
||||
this.changeTab(tab, group, { force: true });
|
||||
}
|
||||
}
|
||||
static async #onEditImage(event, target) {
|
||||
const attr = target.dataset.edit;
|
||||
const current = foundry.utils.getProperty(this.document, attr);
|
||||
const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {};
|
||||
const fp = new FilePicker({
|
||||
current,
|
||||
type: "image",
|
||||
redirectToRoot: img ? [img] : [],
|
||||
callback: (path) => this.document.update({ [attr]: path }),
|
||||
top: this.position.top + 40,
|
||||
left: this.position.left + 10
|
||||
});
|
||||
return fp.browse();
|
||||
}
|
||||
};
|
||||
|
||||
// src/ui/sheets/items/item.js
|
||||
@@ -1923,7 +1981,7 @@ function registerSettings() {
|
||||
});
|
||||
}
|
||||
async function migrateIfNeeded() {
|
||||
const current = game.system.version ?? MIGRATION_VERSION;
|
||||
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 });
|
||||
@@ -1939,7 +1997,7 @@ async function migrateActors() {
|
||||
for (const actor of game.actors.contents) {
|
||||
const updateData = migrateActorData(actor);
|
||||
if (Object.keys(updateData).length > 0) {
|
||||
updates.push(actor.update(updateData, { enforceTypes: false }));
|
||||
updates.push(actor.update(updateData));
|
||||
}
|
||||
}
|
||||
await Promise.all(updates);
|
||||
@@ -1951,7 +2009,7 @@ async function migrateCompendiumActors() {
|
||||
for (const actor of content) {
|
||||
const updateData = migrateActorData(actor);
|
||||
if (Object.keys(updateData).length > 0) {
|
||||
await actor.update(updateData, { pack: pack.collection, enforceTypes: false });
|
||||
await actor.update(updateData, { pack: pack.collection });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1961,7 +2019,7 @@ async function migrateItems() {
|
||||
for (const item of game.items.contents) {
|
||||
const updateData = migrateItemData(item);
|
||||
if (Object.keys(updateData).length > 0) {
|
||||
updates.push(item.update(updateData, { enforceTypes: false }));
|
||||
updates.push(item.update(updateData));
|
||||
}
|
||||
}
|
||||
await Promise.all(updates);
|
||||
@@ -1973,7 +2031,7 @@ async function migrateCompendiumItems() {
|
||||
for (const item of content) {
|
||||
const updateData = migrateItemData(item);
|
||||
if (Object.keys(updateData).length > 0) {
|
||||
await item.update(updateData, { pack: pack.collection, enforceTypes: false });
|
||||
await item.update(updateData, { pack: pack.collection });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2012,6 +2070,13 @@ function migrateActorData(actor) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2110,9 +2175,6 @@ Hooks.once("init", async () => {
|
||||
console.info(`CHRONIQUESDELETRANGE | Initialized`);
|
||||
});
|
||||
Hooks.once("ready", async () => {
|
||||
if (!game.modules.get("lib-wrapper")?.active && game.user.isGM) {
|
||||
ui.notifications.error("System fvtt-chroniques-de-l-etrange requires the 'libWrapper' module. Please install and activate it.");
|
||||
}
|
||||
await migrateIfNeeded();
|
||||
});
|
||||
function injectCompendiumLink(html) {
|
||||
@@ -2138,7 +2200,7 @@ function injectCompendiumLink(html) {
|
||||
</section>
|
||||
`;
|
||||
section.querySelector("button[data-action='open-cde-link']")?.addEventListener("click", () => {
|
||||
window.open("https://antre-monde.com/les-chroniques-de-letrengae/", "_blank");
|
||||
window.open("https://antre-monde.com/les-chroniques-de-letrange/", "_blank");
|
||||
});
|
||||
header.parentNode.insertBefore(section, header);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user