import { SYSTEM } from "../config/system.mjs" export default class AwECharacter extends foundry.abstract.TypeDataModel { static defineSchema() { const fields = foundry.data.fields const requiredInteger = { required: true, nullable: false, integer: true } const schema = {} schema.description = new fields.HTMLField({ required: true, textSearch: true }) schema.notes = new fields.HTMLField({ required: true, textSearch: true }) // Identity schema.pronouns = new fields.StringField({ initial: "", required: false, nullable: true }) schema.specialization = new fields.StringField({ initial: "", required: false, nullable: true }) // Core stats schema.level = new fields.NumberField({ ...requiredInteger, initial: 1, min: 1, max: 10, choices: Object.fromEntries([1,2,3,4,5,6,7,8,9,10].map(v => [v, String(v)])) }) schema.stride = new fields.NumberField({ ...requiredInteger, initial: 5, min: 0 }) // Hit Points schema.hp = new fields.SchemaField({ value: new fields.NumberField({ ...requiredInteger, initial: 10, min: 0 }), max: new fields.NumberField({ ...requiredInteger, initial: 10, min: 0 }), temp: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) }) // Flow Points schema.flowPoints = new fields.SchemaField({ value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }), temp: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }) }) // Attributes: agility, fitness, awareness, influence // boostLevel: how many boosts applied (0-4) // mod = level + boostLevel (computed in prepareDerivedData) // dc = 10 + mod (computed) // bonus: manual +/- bonus const attributeField = () => new fields.SchemaField({ // boosts: permanent +1 increments from background, field, step5, and level 3/6/9 progression // max 7: 4 at creation + 3 from additional boosts at levels 3, 6, 9 boostLevel: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 7, choices: Object.fromEntries(Array.from({length: 8}, (_, i) => [i, String(i)])) }), bonus: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }) }) schema.attributes = new fields.SchemaField( Object.values(SYSTEM.ATTRIBUTES).reduce((obj, attr) => { obj[attr.id] = attributeField() return obj }, {}) ) // Condition penalty magnitudes (used when the respective condition is active) schema.inhibitedPenalty = new fields.NumberField({ required: true, nullable: false, integer: true, initial: 2, min: 0 }) schema.vulnerablePenalty = new fields.NumberField({ required: true, nullable: false, integer: true, initial: 2, min: 0 }) return schema } /** @override */ prepareDerivedData() { super.prepareDerivedData() const level = this.level for (const attrId of Object.keys(SYSTEM.ATTRIBUTES)) { const attr = this.attributes[attrId] attr.mod = level + attr.boostLevel + attr.bonus attr.dc = 10 + attr.mod const bonusPart = attr.bonus !== 0 ? ` + Bonus ${attr.bonus >= 0 ? '+' : ''}${attr.bonus}` : '' attr.modBreakdown = `Level ${level} + Boosts ${attr.boostLevel}${bonusPart} = ${attr.mod >= 0 ? '+' : ''}${attr.mod}` } } }