Import initial du système

This commit is contained in:
2026-03-28 08:44:19 +01:00
parent 068fca00e5
commit f7a01900ac
105 changed files with 7362 additions and 2090 deletions
+14 -8
View File
@@ -3,7 +3,7 @@ const { HandlebarsApplicationMixin } = foundry.applications.api
export class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
static DEFAULT_OPTIONS = {
classes: ["fvtt-chroniques-de-l-etrange", "actor"],
position: { width: 920, height: "auto" },
position: { width: 920, height: 800 },
window: { resizable: true },
form: { submitOnChange: true },
dragDrop: [{ dragSelector: ".item, [data-drag='true']", dropSelector: null }],
@@ -16,6 +16,10 @@ export class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applic
tabGroups = { primary: "description" }
get title() {
return this.document.name
}
async _prepareContext() {
const descriptionHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? "", { async: true })
const cssClass = this.options.classes?.join(" ") ?? ""
@@ -23,6 +27,7 @@ export class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applic
actor: this.document,
system: this.document.system,
systemData: this.document.system,
systemFields: this.document.system.schema.fields,
items: this.document.items.contents,
descriptionHTML,
editable: this.isEditable,
@@ -30,14 +35,11 @@ export class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applic
}
}
async _onFirstRender(context, options) {
await super._onFirstRender(context, options)
for (const [group, tab] of Object.entries(this.tabGroups)) {
this.changeTab(tab, group, { force: true })
}
}
// Restore the active tab after every render (including re-renders from submitOnChange).
// AppV2 does NOT preserve tab state natively — we must re-apply it from this.tabGroups,
// which is dynamically updated by changeTab() when the user clicks a tab.
_onRender(context, options) {
super._onRender?.(context, options)
for (const [group, tab] of Object.entries(this.tabGroups)) {
this.changeTab(tab, group, { force: true })
}
@@ -48,6 +50,10 @@ export class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applic
const cls = getDocumentClass("Item")
const labels = {
item: "CDE.ItemNew",
weapon: "CDE.WeaponNew",
armor: "CDE.ArmorNew",
sanhei: "CDE.SanheiNew",
ingredient: "CDE.IngredientNew",
kungfu: "CDE.KFNew",
spell: "CDE.SpellNew",
supernatural: "CDE.SupernaturalNew",
+20 -20
View File
@@ -1,4 +1,6 @@
import { MAGICS, SUBTYPES } from "../../../config/constants.js"
import { rollInitiativePC } from "../../initiative.js"
import { rollForActor } from "../../rolling.js"
import { CDEBaseActorSheet } from "./base.js"
export class CDECharacterSheet extends CDEBaseActorSheet {
@@ -15,6 +17,10 @@ export class CDECharacterSheet extends CDEBaseActorSheet {
async _prepareContext() {
const context = await super._prepareContext()
context.equipments = context.items.filter((item) => item.type === "item")
context.weapons = context.items.filter((item) => item.type === "weapon")
context.armors = context.items.filter((item) => item.type === "armor")
context.sanheis = context.items.filter((item) => item.type === "sanhei")
context.ingredients = context.items.filter((item) => item.type === "ingredient")
context.spells = context.items.filter((item) => item.type === "spell")
context.kungfus = context.items.filter((item) => item.type === "kungfu")
context.CDE = { MAGICS, SUBTYPES }
@@ -25,6 +31,7 @@ export class CDECharacterSheet extends CDEBaseActorSheet {
super._onRender?.(context, options)
this.#bindInitiativeControls()
this.#bindPrefs()
this.#bindRollButtons()
}
#bindInitiativeControls() {
@@ -45,26 +52,7 @@ export class CDECharacterSheet extends CDEBaseActorSheet {
return
}
if (action === "create") {
const html = `
<form class="flexcol">
<div class="form-group">
<label>${game.i18n.localize("CDE.TurnOrder")}</label>
<input type="number" name="initiative" value="${initiative}" min="1" max="24" />
</div>
</form>`
const value = await Dialog.prompt({
title: game.i18n.localize("CDE.TurnOrder"),
content: html,
label: game.i18n.localize("CDE.Validate"),
callback: (dlg) => {
const input = dlg.querySelector("input[name='initiative']")
return Number(input?.value ?? initiative)
},
})
if (Number.isFinite(value)) {
const sanitized = foundry.utils.clamp(Number(value), 1, 24)
await this.document.update({ "system.initiative": sanitized })
}
await rollInitiativePC(this.document)
}
})
})
@@ -109,4 +97,16 @@ export class CDECharacterSheet extends CDEBaseActorSheet {
}
})
}
#bindRollButtons() {
const cells = this.element?.querySelectorAll("td.click[data-libel-id], td.click2[data-libel-id], .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)
})
})
}
}
+2 -17
View File
@@ -1,3 +1,4 @@
import { rollInitiativeNPC } from "../../initiative.js"
import { CDEBaseActorSheet } from "./base.js"
export class CDENpcSheet extends CDEBaseActorSheet {
@@ -43,23 +44,7 @@ export class CDENpcSheet extends CDEBaseActorSheet {
return
}
if (action === "create") {
const html = `
<form class="flexcol">
<div class="form-group">
<label>${game.i18n.localize("CDE.TurnOrder")}</label>
<input type="number" name="initiative" value="${initiative}" min="1" max="24" />
</div>
</form>`
const value = await Dialog.prompt({
title: game.i18n.localize("CDE.TurnOrder"),
content: html,
label: game.i18n.localize("CDE.Validate"),
callback: (dlg) => Number(dlg.querySelector("input[name='initiative']")?.value ?? initiative),
})
if (Number.isFinite(value)) {
const sanitized = foundry.utils.clamp(Number(value), 1, 24)
await this.document.update({ "system.initiative": sanitized })
}
await rollInitiativeNPC(this.document)
}
})
})
+12
View File
@@ -0,0 +1,12 @@
import { CDEBaseItemSheet } from "./base.js"
export class CDEArmorSheet extends CDEBaseItemSheet {
static DEFAULT_OPTIONS = {
classes: ["armor"],
position: { width: 520, height: 460 },
}
static PARTS = {
main: { template: "systems/fvtt-chroniques-de-l-etrange/templates/item/cde-armor-sheet.html" },
}
}
+8 -8
View File
@@ -9,7 +9,11 @@ export class CDEBaseItemSheet extends HandlebarsApplicationMixin(foundry.applica
actions: {},
}
tabGroups = { primary: "description" }
tabGroups = { primary: "details" }
get title() {
return this.document.name
}
async _prepareContext() {
const cssClass = this.options.classes?.join(" ") ?? ""
@@ -19,6 +23,7 @@ export class CDEBaseItemSheet extends HandlebarsApplicationMixin(foundry.applica
item: this.document,
system: this.document.system,
systemData: this.document.system,
systemFields: this.document.system.schema.fields,
editable: this.isEditable,
cssClass,
enrichedDescription,
@@ -28,14 +33,9 @@ export class CDEBaseItemSheet extends HandlebarsApplicationMixin(foundry.applica
}
}
async _onFirstRender(context, options) {
await super._onFirstRender(context, options)
for (const [group, tab] of Object.entries(this.tabGroups)) {
this.changeTab(tab, group, { force: true })
}
}
// Restore the active tab after every render (including re-renders from submitOnChange).
_onRender(context, options) {
super._onRender?.(context, options)
for (const [group, tab] of Object.entries(this.tabGroups)) {
this.changeTab(tab, group, { force: true })
}
+4
View File
@@ -3,3 +3,7 @@ export { CDEItemSheet } from "./item.js"
export { CDEKungfuSheet } from "./kungfu.js"
export { CDESpellSheet } from "./spell.js"
export { CDESupernaturalSheet } from "./supernatural.js"
export { CDEWeaponSheet } from "./weapon.js"
export { CDEArmorSheet } from "./armor.js"
export { CDESanheiSheet } from "./sanhei.js"
export { CDEIngredientSheet } from "./ingredient.js"
+12
View File
@@ -0,0 +1,12 @@
import { CDEBaseItemSheet } from "./base.js"
export class CDEIngredientSheet extends CDEBaseItemSheet {
static DEFAULT_OPTIONS = {
classes: ["ingredient"],
position: { width: 520, height: 460 },
}
static PARTS = {
main: { template: "systems/fvtt-chroniques-de-l-etrange/templates/item/cde-ingredient-sheet.html" },
}
}
+1 -12
View File
@@ -1,23 +1,12 @@
import { SUBTYPES } from "../../../config/constants.js"
import { CDEBaseItemSheet } from "./base.js"
export class CDEItemSheet extends CDEBaseItemSheet {
static DEFAULT_OPTIONS = {
classes: ["equipment"],
position: { width: 620, height: 580 },
position: { width: 560, height: 460 },
}
static PARTS = {
main: { template: "systems/fvtt-chroniques-de-l-etrange/templates/item/cde-item-sheet.html" },
}
async _prepareContext() {
const context = await super._prepareContext()
context.subtypes = SUBTYPES
context.isWeapon = this.document.isWeapon
context.isArmor = this.document.isArmor
context.isSanhei = this.document.isSanhei
context.isOther = this.document.isOther
return context
}
}
+23
View File
@@ -0,0 +1,23 @@
import { CDEBaseItemSheet } from "./base.js"
export class CDESanheiSheet extends CDEBaseItemSheet {
static DEFAULT_OPTIONS = {
classes: ["sanhei"],
position: { width: 580, height: 620 },
}
static PARTS = {
main: { template: "systems/fvtt-chroniques-de-l-etrange/templates/item/cde-sanhei-sheet.html" },
}
async _prepareContext() {
const context = await super._prepareContext()
const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? "", { async: true })
const props = this.document.system.properties
context.prop1DescriptionHTML = await enrich(props.prop1.description)
context.prop2DescriptionHTML = await enrich(props.prop2.description)
context.prop3DescriptionHTML = await enrich(props.prop3.description)
context.propFields = this.document.system.schema.fields.properties.fields
return context
}
}
+7
View File
@@ -9,4 +9,11 @@ export class CDESupernaturalSheet extends CDEBaseItemSheet {
static PARTS = {
main: { template: "systems/fvtt-chroniques-de-l-etrange/templates/item/cde-supernatural-sheet.html" },
}
async _prepareContext() {
const context = await super._prepareContext()
const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? "", { async: true })
context.effectsHTML = await enrich(this.document.system.effects)
return context
}
}
+12
View File
@@ -0,0 +1,12 @@
import { CDEBaseItemSheet } from "./base.js"
export class CDEWeaponSheet extends CDEBaseItemSheet {
static DEFAULT_OPTIONS = {
classes: ["weapon"],
position: { width: 580, height: 520 },
}
static PARTS = {
main: { template: "systems/fvtt-chroniques-de-l-etrange/templates/item/cde-weapon-sheet.html" },
}
}