const fields = foundry.data.fields; export default class CreatureData extends foundry.abstract.TypeDataModel { static defineSchema() { return { life: new fields.SchemaField({ value: new fields.NumberField({ required: true, initial: 10, min: 0, integer: true }), max: new fields.NumberField({ required: true, initial: 10, min: 0, integer: true }) }), speed: new fields.NumberField({ required: true, initial: 6, min: 0, integer: true }), armor: new fields.NumberField({ required: true, initial: 0, min: 0, integer: true }), psi: new fields.NumberField({ required: true, initial: 0, min: 0, integer: true }), initiativeBonus: new fields.NumberField({ required: true, initial: 0, integer: true }), skills: new fields.ArrayField( new fields.SchemaField({ name: new fields.StringField({ required: true, blank: true, trim: true, initial: "" }), level: new fields.NumberField({ required: true, initial: 0, integer: true }), note: new fields.StringField({ required: false, blank: true, trim: true, initial: "" }) }) ), attacks: new fields.ArrayField( new fields.SchemaField({ name: new fields.StringField({ required: true, blank: true, trim: true, initial: "" }), damage: new fields.StringField({ required: true, blank: true, trim: true, initial: "1D" }), description: new fields.StringField({ required: false, blank: true, trim: true, initial: "" }) }) ), traits: new fields.ArrayField( new fields.SchemaField({ name: new fields.StringField({ required: true, blank: true, trim: true, initial: "" }), value: new fields.StringField({ required: false, blank: true, trim: true, initial: "" }), description: new fields.StringField({ required: false, blank: true, trim: true, initial: "" }) }) ), behavior: new fields.SchemaField({ type: new fields.StringField({ required: false, blank: true, trim: true, initial: "" }), subtype: new fields.StringField({ required: false, blank: true, trim: true, initial: "" }) }), biography: new fields.HTMLField({ required: false, blank: true, trim: true }), notes: new fields.HTMLField({ required: false, blank: true, trim: true }), }; } /** @override */ prepareDerivedData() { // Compute initiative bonus from Métabolisme traits let bonus = 0; for (const trait of this.traits) { const nameLower = trait.name.toLowerCase(); if (nameLower.includes("métabolisme rapide") || nameLower.includes("metabolisme rapide")) { const val = parseInt(trait.value); if (!isNaN(val)) bonus += val; } else if (nameLower.includes("métabolisme lent") || nameLower.includes("metabolisme lent")) { const val = parseInt(trait.value); if (!isNaN(val)) bonus -= val; } } this.initiativeBonus = bonus; // Compute armor from Armure trait if not set manually if (this.armor === 0) { for (const trait of this.traits) { if (trait.name.toLowerCase().startsWith("armure")) { const val = parseInt(trait.value); if (!isNaN(val)) { this.armor = val; break; } } } } // Compute PSI from Psionique trait if (this.psi === 0) { for (const trait of this.traits) { if (trait.name.toLowerCase().startsWith("psionique")) { const val = parseInt(trait.value); if (!isNaN(val)) { this.psi = val; break; } } } } } }