feat: implémentation complète du système Célestopol 1922 pour FoundryVTT v13
- DataModels (character, npc, anomaly, aspect, attribute, equipment) - ApplicationV2 sheets (character 5 tabs, npc 3 tabs, 4 item sheets) - DialogV2 pour les jets de dés avec phase de lune - Templates Handlebars complets (fiches PJ/PNJ, items, jet, chat) - Styles LESS → CSS compilé (thème vert foncé / orange CopaseticNF) - i18n fr.json complet (clés CELESTOPOL.*) - Point d'entrée fvtt-celestopol.mjs avec hooks init/ready - Assets : polices CopaseticNF, images UI, icônes items - Mise à jour copilot-instructions.md avec l'architecture réelle Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
98
module/models/items.mjs
Normal file
98
module/models/items.mjs
Normal file
@@ -0,0 +1,98 @@
|
||||
import { SYSTEM } from "../config/system.mjs"
|
||||
|
||||
/** Schéma partagé pour les bonus/malus par compétence (utilisé dans anomaly/aspect/attribute). */
|
||||
function skillScoresSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const reqInt = { required: true, nullable: false, integer: true }
|
||||
const scoreField = () => new fields.SchemaField({
|
||||
bonus: new fields.NumberField({ ...reqInt, initial: 0 }),
|
||||
malus: new fields.NumberField({ ...reqInt, initial: 0 }),
|
||||
})
|
||||
|
||||
const statGroup = (statId) => {
|
||||
const skills = SYSTEM.SKILLS[statId]
|
||||
const schema = {}
|
||||
for (const key of Object.keys(skills)) {
|
||||
schema[key] = scoreField()
|
||||
}
|
||||
return new fields.SchemaField(schema)
|
||||
}
|
||||
|
||||
return new fields.SchemaField({
|
||||
ame: statGroup("ame"),
|
||||
corps: statGroup("corps"),
|
||||
coeur: statGroup("coeur"),
|
||||
esprit: statGroup("esprit"),
|
||||
})
|
||||
}
|
||||
|
||||
export class CelestopolAnomaly extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const reqInt = { required: true, nullable: false, integer: true }
|
||||
return {
|
||||
subtype: new fields.StringField({ required: true, nullable: false, initial: "none",
|
||||
choices: Object.keys(SYSTEM.ANOMALY_TYPES) }),
|
||||
value: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 8 }),
|
||||
reference: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
scores: skillScoresSchema(),
|
||||
description: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
technique: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
narratif: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
notes: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class CelestopolAspect extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const reqInt = { required: true, nullable: false, integer: true }
|
||||
return {
|
||||
value: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 8 }),
|
||||
reference: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
scores: skillScoresSchema(),
|
||||
description: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
technique: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
narratif: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
notes: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class CelestopolAttribute extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const reqInt = { required: true, nullable: false, integer: true }
|
||||
return {
|
||||
value: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 8 }),
|
||||
reference: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
scores: skillScoresSchema(),
|
||||
description: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
technique: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
narratif: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
notes: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class CelestopolEquipment extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields
|
||||
const reqInt = { required: true, nullable: false, integer: true }
|
||||
return {
|
||||
subtype: new fields.StringField({ required: true, nullable: false, initial: "autre",
|
||||
choices: Object.keys(SYSTEM.EQUIPMENT_TYPES) }),
|
||||
reference: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
quantity: new fields.NumberField({ ...reqInt, initial: 1, min: 0 }),
|
||||
weight: new fields.NumberField({ required: true, nullable: false, initial: 0, min: 0 }),
|
||||
damage: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
range: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
speed: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
protection: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
crew: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||||
description:new fields.HTMLField({ required: true, textSearch: true }),
|
||||
notes: new fields.HTMLField({ required: true, textSearch: true }),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user