135 lines
6.0 KiB
JavaScript
135 lines
6.0 KiB
JavaScript
|
||
export default class OathHammerCharacter extends foundry.abstract.TypeDataModel {
|
||
static defineSchema() {
|
||
const fields = foundry.data.fields
|
||
const requiredInteger = { required: true, nullable: false, integer: true }
|
||
const schema = {}
|
||
|
||
schema.background = new fields.HTMLField({ required: true, textSearch: true })
|
||
schema.description = new fields.HTMLField({ required: true, textSearch: true })
|
||
schema.notes = new fields.HTMLField({ required: true, textSearch: true })
|
||
|
||
// Lineage (simple fields on the actor — not an Item)
|
||
schema.lineage = new fields.SchemaField({
|
||
name: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||
traits: new fields.HTMLField({ required: true, textSearch: true }),
|
||
})
|
||
|
||
const attributeField = () => new fields.SchemaField({
|
||
rank: new fields.NumberField({ ...requiredInteger, initial: 1, min: 1, max: 4 })
|
||
})
|
||
schema.attributes = new fields.SchemaField({
|
||
might: attributeField(),
|
||
toughness: attributeField(),
|
||
agility: attributeField(),
|
||
willpower: attributeField(),
|
||
intelligence: attributeField(),
|
||
fate: attributeField()
|
||
})
|
||
|
||
// Skills: 26 skills each with a rank (0–4), a bonus/penalty modifier, and color dice.
|
||
// Total dice = attr rank + skill rank. Modifier = bonus (+) or penalty (-) dice.
|
||
// Color dice: type (white 4+, red 3+, black 2+) + count of colored dice in the pool.
|
||
const skillField = () => new fields.SchemaField({
|
||
rank: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 4 }),
|
||
modifier: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
|
||
colorDiceType: new fields.StringField({ required: true, nullable: false, initial: "white",
|
||
choices: { white: "OATHHAMMER.ColorDice.White", red: "OATHHAMMER.ColorDice.Red", black: "OATHHAMMER.ColorDice.Black" } }),
|
||
colorDice: new fields.NumberField({ ...requiredInteger, initial: 4, min: 0 }),
|
||
})
|
||
schema.skills = new fields.SchemaField({
|
||
academics: skillField(),
|
||
acrobatics: skillField(),
|
||
animalHandling:skillField(),
|
||
athletics: skillField(),
|
||
brewing: skillField(),
|
||
carpentry: skillField(),
|
||
defense: skillField(),
|
||
dexterity: skillField(),
|
||
diplomacy: skillField(),
|
||
discipline: skillField(),
|
||
fighting: skillField(),
|
||
folklore: skillField(),
|
||
fortune: skillField(),
|
||
heal: skillField(),
|
||
leadership: skillField(),
|
||
magic: skillField(),
|
||
masonry: skillField(),
|
||
orientation: skillField(),
|
||
perception: skillField(),
|
||
resilience: skillField(),
|
||
ride: skillField(),
|
||
shooting: skillField(),
|
||
smithing: skillField(),
|
||
stealth: skillField(),
|
||
survival: skillField(),
|
||
tracking: skillField(),
|
||
})
|
||
|
||
schema.grit = new fields.SchemaField({
|
||
value: new fields.NumberField({ ...requiredInteger, initial: 2, min: 0 }),
|
||
max: new fields.NumberField({ ...requiredInteger, initial: 2, min: 0 })
|
||
})
|
||
|
||
// Luck.max is derived from fate.rank; resets at session start.
|
||
schema.luck = new fields.SchemaField({
|
||
value: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 }),
|
||
max: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })
|
||
})
|
||
|
||
schema.arcaneStress = new fields.SchemaField({
|
||
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||
threshold: new fields.NumberField({ ...requiredInteger, initial: 10, min: 0 })
|
||
})
|
||
|
||
schema.miracleBlocked = new fields.BooleanField({ required: true, initial: false })
|
||
|
||
schema.movement = new fields.SchemaField({
|
||
base: new fields.NumberField({ ...requiredInteger, initial: 30, min: 0 }),
|
||
adjusted: new fields.NumberField({ ...requiredInteger, initial: 30, min: 0 })
|
||
})
|
||
|
||
schema.defense = new fields.SchemaField({
|
||
value: new fields.NumberField({ ...requiredInteger, initial: 10, min: 0 }),
|
||
armorRating: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||
bonus: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||
})
|
||
|
||
schema.experience = new fields.SchemaField({
|
||
current: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||
total: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||
level: new fields.NumberField({ ...requiredInteger, initial: 1, min: 1 })
|
||
})
|
||
|
||
schema.biodata = new fields.SchemaField({
|
||
age: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||
gender: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||
height: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||
weight: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||
eyes: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||
hair: new fields.StringField({ required: true, nullable: false, initial: "" }),
|
||
alignment: new fields.StringField({ required: true, nullable: false, initial: "" })
|
||
})
|
||
|
||
schema.currency = new fields.SchemaField({
|
||
gold: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||
silver: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 }),
|
||
copper: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
|
||
})
|
||
|
||
return schema
|
||
}
|
||
|
||
static LOCALIZATION_PREFIXES = ["OATHHAMMER.Character"]
|
||
|
||
prepareDerivedData() {
|
||
super.prepareDerivedData()
|
||
// Grit max = Resilience skill rank + Toughness attribute rank (rulebook p.5)
|
||
this.grit.max = this.skills.resilience.rank + this.attributes.toughness.rank
|
||
// Luck max = Fate rank; restores at session start
|
||
this.luck.max = this.attributes.fate.rank
|
||
// Defense score = 10 + Agility + Armor Rating + bonus
|
||
this.defense.value = 10 + this.attributes.agility.rank + this.defense.armorRating + this.defense.bonus
|
||
}
|
||
}
|