import { SYSTEM } from "../config/system.mjs" export default class CelestopolNPC extends foundry.abstract.TypeDataModel { static defineSchema() { const fields = foundry.data.fields const reqInt = { required: true, nullable: false, integer: true } const schema = {} schema.concept = new fields.StringField({ required: true, nullable: false, initial: "" }) schema.initiative = new fields.NumberField({ ...reqInt, initial: 0, min: 0 }) schema.anomaly = new fields.SchemaField({ type: 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 }), }) const skillField = (label) => new fields.SchemaField({ label: new fields.StringField({ required: true, initial: label }), value: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 8 }), }) const statField = (statId) => { const skills = SYSTEM.SKILLS[statId] const skillSchema = {} for (const [key, skill] of Object.entries(skills)) { skillSchema[key] = skillField(skill.label) } return new fields.SchemaField({ label: new fields.StringField({ required: true, initial: SYSTEM.STATS[statId].label }), res: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 8 }), actuel: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }), // res + wound malus ...skillSchema, }) } schema.stats = new fields.SchemaField({ ame: statField("ame"), corps: statField("corps"), coeur: statField("coeur"), esprit: statField("esprit"), }) const woundField = (idx) => new fields.SchemaField({ checked: new fields.BooleanField({ required: true, initial: false }), malus: new fields.NumberField({ ...reqInt, initial: SYSTEM.WOUND_LEVELS[idx]?.malus ?? 0 }), }) schema.blessures = new fields.SchemaField({ lvl: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 8 }), b1: woundField(1), b2: woundField(2), b3: woundField(3), b4: woundField(4), b5: woundField(5), b6: woundField(6), b7: woundField(7), b8: woundField(8), }) schema.prefs = new fields.SchemaField({ moonPhase: new fields.StringField({ required: true, nullable: false, initial: "none" }), difficulty: new fields.StringField({ required: true, nullable: false, initial: "normal" }), }) schema.description = new fields.HTMLField({ required: true, textSearch: true }) schema.notes = new fields.HTMLField({ required: true, textSearch: true }) return schema } static LOCALIZATION_PREFIXES = ["CELESTOPOL.NPC"] prepareDerivedData() { super.prepareDerivedData() const malus = this.getWoundMalus() this.initiative = Math.max(0, this.stats.corps.res + malus) for (const stat of Object.values(this.stats)) { stat.actuel = Math.max(0, stat.res + malus) } } getWoundMalus() { const lvl = Math.max(0, Math.min(8, this.blessures.lvl)) return SYSTEM.WOUND_LEVELS[lvl]?.malus ?? 0 } async roll(statId, skillId) { const { CelestopolRoll } = await import("../documents/roll.mjs") const skill = this.stats[statId][skillId] if (!skill) return null return CelestopolRoll.prompt({ actorId: this.parent.id, actorName: this.parent.name, actorImage: this.parent.img, statId, skillId, skillLabel: skill.label, skillValue: skill.value, woundMalus: this.getWoundMalus(), moonPhase: this.prefs.moonPhase, difficulty: this.prefs.difficulty, }) } }