Nombreuses corrections sur les fiches settlement/NPC

This commit is contained in:
2026-03-22 21:35:47 +01:00
parent ec291e9c60
commit b46c6d804c
51 changed files with 2892 additions and 227 deletions

View File

@@ -12,3 +12,6 @@ export { default as OathHammerOath } from "./oath.mjs"
export { default as OathHammerClass } from "./class.mjs"
export { default as OathHammerBuilding } from "./building.mjs"
export { default as OathHammerSettlement } from "./settlement.mjs"
export { default as OathHammerSkillNPC } from "./skillnpc.mjs"
export { default as OathHammerNpcAttack } from "./npcattack.mjs"
export { default as OathHammerRegiment } from "./regiment.mjs"

View File

@@ -31,7 +31,7 @@ export default class OathHammerCharacter extends foundry.abstract.TypeDataModel
// 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 }),
rank: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 6 }),
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" } }),

View File

@@ -9,16 +9,9 @@ export default class OathHammerNPC extends foundry.abstract.TypeDataModel {
schema.description = new fields.HTMLField({ required: true, textSearch: true })
schema.notes = 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()
// NPC (humanoid, needs light) vs Creature (monster, darkvision)
schema.subtype = new fields.StringField({
required: true, initial: "creature", choices: SYSTEM.NPC_SUBTYPES
})
schema.grit = new fields.SchemaField({
@@ -26,8 +19,15 @@ export default class OathHammerNPC extends foundry.abstract.TypeDataModel {
max: new fields.NumberField({ ...requiredInteger, initial: 2, min: 0 })
})
// Armor dice pool (value + color)
schema.armorDice = new fields.SchemaField({
value: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 20 }),
colorDiceType: new fields.StringField({ required: true, initial: "white", choices: SYSTEM.DICE_COLOR_TYPES })
})
schema.defense = new fields.SchemaField({
value: new fields.NumberField({ ...requiredInteger, initial: 10, min: 0 })
value: new fields.NumberField({ ...requiredInteger, initial: 10, min: 0 }),
colorDiceType: new fields.StringField({ required: true, initial: "white", choices: SYSTEM.DICE_COLOR_TYPES })
})
schema.movement = new fields.SchemaField({
@@ -37,7 +37,7 @@ export default class OathHammerNPC extends foundry.abstract.TypeDataModel {
schema.attackBonus = new fields.NumberField({ ...requiredInteger, initial: 0 })
schema.damageBonus = new fields.NumberField({ ...requiredInteger, initial: 0 })
schema.initiativeBonus = new fields.NumberField({ ...requiredInteger, initial: 0 })
schema.challengeRating = new fields.StringField({ required: true, nullable: false, initial: "1" })
schema.challengeRating = new fields.StringField({ required: true, nullable: false, initial: "1" })
return schema
}
@@ -46,6 +46,5 @@ export default class OathHammerNPC extends foundry.abstract.TypeDataModel {
prepareDerivedData() {
super.prepareDerivedData()
this.grit.max = this.attributes.might.rank + this.attributes.toughness.rank
}
}

View File

@@ -0,0 +1,42 @@
import { SYSTEM } from "../config/system.mjs"
export default class OathHammerNpcAttack 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 })
// Flat damage dice pool (no Might)
schema.damageDice = new fields.NumberField({
...requiredInteger, initial: 1, min: 0, max: 20
})
// Dice color: white (4+), red (3+), black (2+)
schema.colorDiceType = new fields.StringField({
required: true, initial: "white", choices: SYSTEM.DICE_COLOR_TYPES
})
// AP (Armor Penetration): penalty imposed on armor rolls
schema.ap = new fields.NumberField({
...requiredInteger, initial: 0, min: 0, max: 16
})
return schema
}
static LOCALIZATION_PREFIXES = ["OATHHAMMER.NpcAttack"]
get threshold() {
return this.colorDiceType === "black" ? 2 : this.colorDiceType === "red" ? 3 : 4
}
get colorEmoji() {
return this.colorDiceType === "black" ? "⬛" : this.colorDiceType === "red" ? "🔴" : "⬜"
}
get damageLabel() {
return `${this.colorEmoji} ${this.damageDice}d (${this.threshold}+)`
}
}

View File

@@ -0,0 +1,57 @@
import { SYSTEM } from "../config/system.mjs"
export default class OathHammerRegiment extends foundry.abstract.TypeDataModel {
static defineSchema() {
const { fields } = foundry.data
const requiredInteger = { required: true, nullable: false, integer: true }
const schema = {}
schema.description = new fields.HTMLField({ required: false, nullable: true, initial: "" })
schema.notes = new fields.StringField({ required: false, nullable: true, initial: "" })
schema.grit = new fields.SchemaField({
max: new fields.NumberField({ ...requiredInteger, initial: 20, min: 0, max: 200 }),
})
schema.armorDice = new fields.SchemaField({
value: new fields.NumberField({ ...requiredInteger, initial: 1, min: 0, max: 20 }),
colorDiceType: new fields.StringField({ required: true, nullable: false, initial: "white", choices: SYSTEM.DICE_COLOR_TYPES }),
})
schema.movement = new fields.NumberField({ ...requiredInteger, initial: 60, min: 0, max: 500 })
// Embedded skill rows: [{name, value, colorDiceType}]
schema.skills = new fields.ArrayField(new fields.SchemaField({
name: new fields.StringField({ required: true, nullable: false, initial: "" }),
value: new fields.NumberField({ ...requiredInteger, initial: 2, min: 0, max: 6 }),
colorDiceType: new fields.StringField({ required: true, nullable: false, initial: "white", choices: SYSTEM.DICE_COLOR_TYPES }),
}))
// Embedded attack rows: [{name, damageDice, colorDiceType, ap, special}]
schema.attacks = new fields.ArrayField(new fields.SchemaField({
name: new fields.StringField({ required: true, nullable: false, initial: "" }),
damageDice: new fields.NumberField({ ...requiredInteger, initial: 6, min: 0, max: 20 }),
colorDiceType: new fields.StringField({ required: true, nullable: false, initial: "white", choices: SYSTEM.DICE_COLOR_TYPES }),
ap: new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 6 }),
special: new fields.StringField({ required: false, nullable: true, initial: "" }),
}))
// Embedded trait rows: [{name, description}]
schema.traits = new fields.ArrayField(new fields.SchemaField({
name: new fields.StringField({ required: true, nullable: false, initial: "" }),
description: new fields.StringField({ required: false, nullable: true, initial: "" }),
}))
return schema
}
static LOCALIZATION_PREFIXES = ["OATHHAMMER.Regiment"]
get colorEmoji() {
return { white: "⬜", red: "🔴", black: "⬛" }[this.armorDice.colorDiceType] ?? "⬜"
}
get armorLabel() {
return `${this.colorEmoji} ${this.armorDice.value}d`
}
}

View File

@@ -0,0 +1,36 @@
import { SYSTEM } from "../config/system.mjs"
export default class OathHammerSkillNPC extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields
const schema = {}
schema.description = new fields.HTMLField({ required: true, textSearch: true })
// Total dice pool for this skill (attribute + skill ranks combined)
schema.dicePool = new fields.NumberField({
required: true, nullable: false, integer: true, initial: 1, min: 0, max: 20
})
// Dice color: white (4+), red (3+), black (2+)
schema.colorDiceType = new fields.StringField({
required: true, initial: "white", choices: SYSTEM.DICE_COLOR_TYPES
})
// Optional reference to a system skill key (e.g. "fighting", "perception")
// Used for display/tooltip only — does not restrict the roll.
schema.skillRef = new fields.StringField({ required: false, nullable: true, initial: null })
return schema
}
static LOCALIZATION_PREFIXES = ["OATHHAMMER.SkillNPC"]
get threshold() {
return this.colorDiceType === "black" ? 2 : this.colorDiceType === "red" ? 3 : 4
}
get colorEmoji() {
return this.colorDiceType === "black" ? "⬛" : this.colorDiceType === "red" ? "🔴" : "⬜"
}
}

View File

@@ -57,7 +57,12 @@ export default class OathHammerWeapon extends foundry.abstract.TypeDataModel {
// Enchantment description (displayed when isMagic is true)
schema.magicEffect = new fields.HTMLField({ required: false, textSearch: true })
// Class/lineage restriction, e.g. "Dwarves only" (empty = no restriction)
schema.classRestriction = new fields.StringField({ required: true, nullable: false, initial: "" })
schema.classRestriction = new fields.StringField({ required: false, nullable: true, initial: null, choices: SYSTEM.CLASS_RESTRICTION_CHOICES })
// Override which skill (and its linked attribute) is used for attack rolls.
// Null / "" = auto-detect (fighting for melee, shooting for ranged).
// Use this for abilities like Magic Bolt that roll Magic+Willpower instead.
schema.skillOverride = new fields.StringField({ required: false, nullable: true, initial: null })
return schema
}