Résistance: dérivation automatique depuis les seuils de spécialisation

- Ajout resThreshold par domaine dans SKILLS (config/system.mjs)
  ame: artifice=5, attraction=2, coercition=3, faveur=6
  corps: echauffouree=6, effacement=3, mobilite=2, prouesse=5
  coeur: appreciation=6, arts=2, inspiration=3, traque=5
  esprit: instruction=2, mtechnologique=6, raisonnement=5, traitement=3
- prepareDerivedData() calcule stats.{stat}.res = +2 par seuil atteint
- Template: résistance non-éditable (span uniquement, valeur dérivée)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-03-29 22:55:27 +02:00
parent 56620f31de
commit df2ed14f34
3 changed files with 28 additions and 21 deletions

View File

@@ -18,28 +18,28 @@ export const STATS = {
/** Domaines groupées par attribut. */
export const SKILLS = {
ame: {
artifice: { id: "artifice", label: "CELESTOPOL.Skill.artifice", stat: "ame" },
attraction: { id: "attraction", label: "CELESTOPOL.Skill.attraction", stat: "ame" },
coercition: { id: "coercition", label: "CELESTOPOL.Skill.coercition", stat: "ame" },
faveur: { id: "faveur", label: "CELESTOPOL.Skill.faveur", stat: "ame" },
artifice: { id: "artifice", label: "CELESTOPOL.Skill.artifice", stat: "ame", resThreshold: 5 },
attraction: { id: "attraction", label: "CELESTOPOL.Skill.attraction", stat: "ame", resThreshold: 2 },
coercition: { id: "coercition", label: "CELESTOPOL.Skill.coercition", stat: "ame", resThreshold: 3 },
faveur: { id: "faveur", label: "CELESTOPOL.Skill.faveur", stat: "ame", resThreshold: 6 },
},
corps: {
echauffouree: { id: "echauffouree", label: "CELESTOPOL.Skill.echauffouree", stat: "corps" },
effacement: { id: "effacement", label: "CELESTOPOL.Skill.effacement", stat: "corps" },
mobilite: { id: "mobilite", label: "CELESTOPOL.Skill.mobilite", stat: "corps" },
prouesse: { id: "prouesse", label: "CELESTOPOL.Skill.prouesse", stat: "corps" },
echauffouree: { id: "echauffouree", label: "CELESTOPOL.Skill.echauffouree", stat: "corps", resThreshold: 6 },
effacement: { id: "effacement", label: "CELESTOPOL.Skill.effacement", stat: "corps", resThreshold: 3 },
mobilite: { id: "mobilite", label: "CELESTOPOL.Skill.mobilite", stat: "corps", resThreshold: 2 },
prouesse: { id: "prouesse", label: "CELESTOPOL.Skill.prouesse", stat: "corps", resThreshold: 5 },
},
coeur: {
appreciation: { id: "appreciation", label: "CELESTOPOL.Skill.appreciation", stat: "coeur" },
arts: { id: "arts", label: "CELESTOPOL.Skill.arts", stat: "coeur" },
inspiration: { id: "inspiration", label: "CELESTOPOL.Skill.inspiration", stat: "coeur" },
traque: { id: "traque", label: "CELESTOPOL.Skill.traque", stat: "coeur" },
appreciation: { id: "appreciation", label: "CELESTOPOL.Skill.appreciation", stat: "coeur", resThreshold: 6 },
arts: { id: "arts", label: "CELESTOPOL.Skill.arts", stat: "coeur", resThreshold: 2 },
inspiration: { id: "inspiration", label: "CELESTOPOL.Skill.inspiration", stat: "coeur", resThreshold: 3 },
traque: { id: "traque", label: "CELESTOPOL.Skill.traque", stat: "coeur", resThreshold: 5 },
},
esprit: {
instruction: { id: "instruction", label: "CELESTOPOL.Skill.instruction", stat: "esprit" },
mtechnologique: { id: "mtechnologique", label: "CELESTOPOL.Skill.mtechnologique", stat: "esprit" },
raisonnement: { id: "raisonnement", label: "CELESTOPOL.Skill.raisonnement", stat: "esprit" },
traitement: { id: "traitement", label: "CELESTOPOL.Skill.traitement", stat: "esprit" },
instruction: { id: "instruction", label: "CELESTOPOL.Skill.instruction", stat: "esprit", resThreshold: 2 },
mtechnologique: { id: "mtechnologique", label: "CELESTOPOL.Skill.mtechnologique", stat: "esprit", resThreshold: 6 },
raisonnement: { id: "raisonnement", label: "CELESTOPOL.Skill.raisonnement", stat: "esprit", resThreshold: 5 },
traitement: { id: "traitement", label: "CELESTOPOL.Skill.traitement", stat: "esprit", resThreshold: 3 },
},
}

View File

@@ -164,6 +164,17 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel
}
}
// Calcul automatique de la Résistance par stat = +2 par domaine atteignant son seuil
for (const [statId, statData] of Object.entries(this.stats)) {
let res = 0
for (const [skillId, skill] of Object.entries(statData)) {
if (typeof skill !== "object" || !("value" in skill)) continue
const threshold = SYSTEM.SKILLS[statId]?.[skillId]?.resThreshold
if (threshold !== undefined && skill.value >= threshold) res += 2
}
statData.res = res
}
// Calcul automatique de la valeur de chaque faction = nombre de cases cochées
for (const faction of Object.values(this.factions)) {
if (typeof faction !== "object" || !("level1" in faction)) continue