IMplémentation de la ajorité des remarques de Nepherius
This commit is contained in:
@@ -6,7 +6,10 @@ export default class CelestopolNPC extends foundry.abstract.TypeDataModel {
|
||||
const reqInt = { required: true, nullable: false, integer: true }
|
||||
const schema = {}
|
||||
|
||||
schema.concept = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.npcType = new fields.StringField({ required: true, nullable: false, initial: "standard",
|
||||
choices: Object.keys(SYSTEM.NPC_TYPES) })
|
||||
schema.concept = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.faction = new fields.StringField({ required: true, nullable: false, initial: "" })
|
||||
schema.initiative = new fields.NumberField({ ...reqInt, initial: 0, min: 0 })
|
||||
|
||||
schema.anomaly = new fields.SchemaField({
|
||||
@@ -15,43 +18,27 @@ export default class CelestopolNPC extends foundry.abstract.TypeDataModel {
|
||||
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 }),
|
||||
// PNJs : 4 domaines uniquement (pas de sous-compétences)
|
||||
const domainField = (statId) => 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 }),
|
||||
})
|
||||
|
||||
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"),
|
||||
ame: domainField("ame"),
|
||||
corps: domainField("corps"),
|
||||
coeur: domainField("coeur"),
|
||||
esprit: domainField("esprit"),
|
||||
})
|
||||
|
||||
schema.blessures = new fields.SchemaField({
|
||||
lvl: new fields.NumberField({ ...reqInt, initial: 0, min: 0, max: 8 }),
|
||||
})
|
||||
|
||||
schema.prefs = new fields.SchemaField({
|
||||
rollMoonDie: new fields.BooleanField({ required: true, initial: false }),
|
||||
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 })
|
||||
schema.histoire = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.descriptionPhysique = new fields.HTMLField({ required: true, textSearch: true })
|
||||
schema.notes = new fields.HTMLField({ required: true, textSearch: true })
|
||||
|
||||
return schema
|
||||
}
|
||||
@@ -61,11 +48,12 @@ export default class CelestopolNPC extends foundry.abstract.TypeDataModel {
|
||||
prepareDerivedData() {
|
||||
super.prepareDerivedData()
|
||||
const malus = this.getWoundMalus()
|
||||
// Initiative PNJ : valeur du Domaine Corps
|
||||
// Initiative PNJ : valeur du Domaine Corps (avec malus blessures)
|
||||
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)
|
||||
}
|
||||
this.armorMalus = this.getArmorMalus()
|
||||
}
|
||||
|
||||
getWoundMalus() {
|
||||
@@ -73,22 +61,43 @@ export default class CelestopolNPC extends foundry.abstract.TypeDataModel {
|
||||
return SYSTEM.WOUND_LEVELS[lvl]?.malus ?? 0
|
||||
}
|
||||
|
||||
async roll(statId, skillId) {
|
||||
/** Somme des malus des armures équipées (valeur négative ou 0). */
|
||||
getArmorMalus() {
|
||||
const armures = this.parent?.itemTypes?.armure ?? []
|
||||
return armures
|
||||
.filter(a => a.system.equipped)
|
||||
.reduce((sum, a) => sum + (a.system.malus ? -Math.abs(a.system.malus) : 0), 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Lance un jet sur un domaine (Âme/Corps/Cœur/Esprit).
|
||||
* Le label affiché tient compte du type de PNJ (standard vs antagoniste).
|
||||
*/
|
||||
async roll(statId) {
|
||||
const { CelestopolRoll } = await import("../documents/roll.mjs")
|
||||
const skill = this.stats[statId][skillId]
|
||||
if (!skill) return null
|
||||
const statData = this.stats[statId]
|
||||
if (!statData) return null
|
||||
|
||||
const isAntagoniste = this.npcType === "antagoniste"
|
||||
const skillLabel = isAntagoniste
|
||||
? SYSTEM.ANTAGONISTE_STATS[statId]?.label
|
||||
: SYSTEM.STATS[statId]?.label
|
||||
|
||||
return CelestopolRoll.prompt({
|
||||
actorId: this.parent.id,
|
||||
actorName: this.parent.name,
|
||||
actorImage: this.parent.img,
|
||||
statId,
|
||||
skillId,
|
||||
skillLabel: skill.label,
|
||||
skillValue: skill.value,
|
||||
skillLabel,
|
||||
skillValue: statData.res,
|
||||
woundMalus: this.getWoundMalus(),
|
||||
difficulty: this.prefs.difficulty,
|
||||
rollMoonDie: this.prefs.rollMoonDie ?? false,
|
||||
armorMalus: this.getArmorMalus(),
|
||||
woundLevel: this.blessures.lvl,
|
||||
})
|
||||
}
|
||||
|
||||
/** Alias pour compatibilité avec le handler _onRoll (clic sans skillId). */
|
||||
async rollResistance(statId) {
|
||||
return this.roll(statId)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user