feat: fiche de Communauté (socle)
- acteur community (identité, géographie, histoire, objectifs, taille/effectif) - 4 Domaines x 2 jauges avec états (Crise/Bas/Stable/Opulent), moral, réserves - onglets Identité / Domaines / Ressources, édition ProseMirror (formInput) - header avec fond, totem, niveau, effectif ; icône par défaut - libellé du type via typeLabels (sans écraser TYPES.* du core)
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import VermineBaseActorSheet from "./base-actor-sheet.mjs"
|
||||
|
||||
export default class VermineCommunitySheetV2 extends VermineBaseActorSheet {
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["community"],
|
||||
position: { width: 760, height: 640 },
|
||||
window: { contentClasses: ["community-content"] },
|
||||
actions: {
|
||||
addObjective: VermineCommunitySheetV2.#onAddObjective,
|
||||
deleteObjective: VermineCommunitySheetV2.#onDeleteObjective
|
||||
}
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
main: { template: "systems/vermine2047/templates/actor/appv2/community-main.hbs", scrollable: [""] },
|
||||
tabs: { template: "templates/generic/tab-navigation.hbs" },
|
||||
identity: { template: "systems/vermine2047/templates/actor/appv2/community-identity.hbs", scrollable: [""] },
|
||||
domains: { template: "systems/vermine2047/templates/actor/appv2/community-domains.hbs", scrollable: [""] },
|
||||
resources: { template: "systems/vermine2047/templates/actor/appv2/community-resources.hbs", scrollable: [""] }
|
||||
}
|
||||
|
||||
tabGroups = { sheet: "identity" }
|
||||
|
||||
#getTabs() {
|
||||
const tabs = {
|
||||
identity: { id: "identity", group: "sheet", icon: "fas fa-info-circle", label: "COMMUNITY.tabs.identity" },
|
||||
domains: { id: "domains", group: "sheet", icon: "fas fa-chart-simple", label: "COMMUNITY.tabs.domains" },
|
||||
resources: { id: "resources", group: "sheet", icon: "fas fa-boxes-stacked", label: "COMMUNITY.tabs.resources" }
|
||||
}
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] === v.id
|
||||
v.cssClass = v.active ? "active" : ""
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
const context = await super._prepareContext()
|
||||
context.tabs = this.#getTabs()
|
||||
// Groupe de personnages rattaché
|
||||
context.resolvedGroup = null
|
||||
if (this.document.system.groupId) {
|
||||
const g = game.actors.get(this.document.system.groupId)
|
||||
if (g) context.resolvedGroup = { id: g.id, name: g.name }
|
||||
}
|
||||
// Enrichissement HTML des champs longs (même logique que la fiche PNJ)
|
||||
const enrich = async (path) => {
|
||||
const val = foundry.utils.getProperty(this.document.system, path)
|
||||
return val ? await foundry.applications.ux.TextEditor.implementation.enrichHTML(val, { async: true }) : ""
|
||||
}
|
||||
context.enrichedNotes = await enrich("identity.notes")
|
||||
context.enrichedLandmarks = await enrich("location.landmarks")
|
||||
context.enrichedTerritory = await enrich("location.territory")
|
||||
context.enrichedEvents = await enrich("history.events")
|
||||
context.enrichedRelations = await enrich("history.relations")
|
||||
return context
|
||||
}
|
||||
|
||||
async _preparePartContext(partId, context) {
|
||||
const doc = this.document
|
||||
switch (partId) {
|
||||
case "main": break
|
||||
case "identity":
|
||||
context.tab = context.tabs.identity
|
||||
context.ageOptions = Object.entries(CONFIG.VERMINE.communityAges).map(([key, label]) => ({ key, label: game.i18n.localize(label) }))
|
||||
break
|
||||
case "domains":
|
||||
context.tab = context.tabs.domains
|
||||
context.sizeOptions = CONFIG.VERMINE.communitySizeLevels
|
||||
context.sizeLabel = doc.system.size?.value ? game.i18n.localize(CONFIG.VERMINE.communitySizeLevels[doc.system.size.value]?.label ?? "") : ""
|
||||
context.sizeInfo = doc.system.size?.value ? CONFIG.VERMINE.communitySizeLevels[doc.system.size.value] : null
|
||||
// Préparer les 4 Domaines avec leurs 2 sections (jauges) et leur état
|
||||
context.domains = []
|
||||
for (const [dkey, dcfg] of Object.entries(CONFIG.VERMINE.communityDomains)) {
|
||||
const domain = doc.system.domains?.[dkey]
|
||||
context.domains.push({
|
||||
key: dkey,
|
||||
label: game.i18n.localize(dcfg.label),
|
||||
sections: Object.entries(dcfg.sections).map(([skey, label]) => {
|
||||
const gauge = domain?.[skey] ?? { value: 0 }
|
||||
const state = gauge.state || "crisis"
|
||||
return {
|
||||
domainKey: dkey,
|
||||
key: skey,
|
||||
label: game.i18n.localize(label),
|
||||
gauge,
|
||||
state,
|
||||
stateLabel: game.i18n.localize(CONFIG.VERMINE.communityGaugeStates[state]?.label ?? "COMMUNITY.states.crisis")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
break
|
||||
case "resources":
|
||||
context.tab = context.tabs.resources
|
||||
break
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
changeTab(tab, group, options = {}) {
|
||||
super.changeTab(tab, group, options)
|
||||
if (group === "sheet") {
|
||||
const main = this.element?.querySelector('[data-group="sheet"][data-tab="main"]')
|
||||
if (main) main.classList.add("active")
|
||||
}
|
||||
}
|
||||
|
||||
static #onDeleteObjective(event, target) {
|
||||
const index = parseInt(target.dataset.index)
|
||||
if (isNaN(index)) return
|
||||
const objectives = foundry.utils.duplicate(this.document.system.objectives || { major: "", minor: [] })
|
||||
objectives.minor.splice(index, 1)
|
||||
this.document.update({ "system.objectives": objectives })
|
||||
}
|
||||
|
||||
static #onAddObjective(event, target) {
|
||||
const objectives = foundry.utils.duplicate(this.document.system.objectives || { major: "", minor: [] })
|
||||
objectives.minor.push("")
|
||||
this.document.update({ "system.objectives": objectives })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user