286 lines
15 KiB
JavaScript
286 lines
15 KiB
JavaScript
/**
|
||
* Célestopol 1922 — Système FoundryVTT
|
||
*
|
||
* Célestopol 1922 est un jeu de rôle édité par Antre-Monde Éditions.
|
||
* Ce système FoundryVTT est une implémentation indépendante et n'est pas
|
||
* affilié à Antre-Monde Éditions,
|
||
* mais a été réalisé avec l'autorisation d'Antre-Monde Éditions.
|
||
*
|
||
* @author LeRatierBretonnien
|
||
* @copyright 2025–2026 LeRatierBretonnien
|
||
* @license CC BY-NC-SA 4.0 – https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||
*/
|
||
|
||
export const SYSTEM_ID = "fvtt-celestopol"
|
||
|
||
export const ASCII = `
|
||
░█▀▀░█▀▀░█░░░█▀▀░█▀▀░▀█▀░█▀█░█▀█░█▀█░█░░
|
||
░█░░░█▀▀░█░░░█▀▀░▀▀█░░█░░█░█░█▀▀░█░█░█░░
|
||
░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀▀▀░▀░░░▀▀▀░▀▀▀
|
||
░░░░░░░░░░░░░░░░░░1922░░░░░░░░░░░░░░░░░░░
|
||
`
|
||
|
||
/** Les 4 attributs principaux (stats). Chacun a une résistance (res) et 4 domaines. */
|
||
export const STATS = {
|
||
ame: { id: "ame", label: "CELESTOPOL.Stat.ame" },
|
||
corps: { id: "corps", label: "CELESTOPOL.Stat.corps" },
|
||
coeur: { id: "coeur", label: "CELESTOPOL.Stat.coeur" },
|
||
esprit: { id: "esprit", label: "CELESTOPOL.Stat.esprit" },
|
||
}
|
||
|
||
/** Domaines groupées par attribut. */
|
||
export const SKILLS = {
|
||
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", 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", 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", 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 },
|
||
},
|
||
}
|
||
|
||
/** Liste plate de tous les domaines (utile pour les DataModels d'items). */
|
||
export const ALL_SKILLS = Object.values(SKILLS).flatMap(group => Object.values(group))
|
||
|
||
/** Types d'anomalies (pouvoirs paranormaux). */
|
||
export const ANOMALY_TYPES = {
|
||
none: { id: "none", label: "CELESTOPOL.Anomaly.none" },
|
||
entropie: { id: "entropie", label: "CELESTOPOL.Anomaly.entropie" },
|
||
communicationaveclesmorts:{ id: "communicationaveclesmorts",label: "CELESTOPOL.Anomaly.communicationaveclesmorts" },
|
||
illusion: { id: "illusion", label: "CELESTOPOL.Anomaly.illusion" },
|
||
suggestion: { id: "suggestion", label: "CELESTOPOL.Anomaly.suggestion" },
|
||
tarotdivinatoire: { id: "tarotdivinatoire", label: "CELESTOPOL.Anomaly.tarotdivinatoire" },
|
||
telekinesie: { id: "telekinesie", label: "CELESTOPOL.Anomaly.telekinesie" },
|
||
telepathie: { id: "telepathie", label: "CELESTOPOL.Anomaly.telepathie" },
|
||
voyageastral: { id: "voyageastral", label: "CELESTOPOL.Anomaly.voyageastral" },
|
||
}
|
||
|
||
/**
|
||
* Définitions des anomalies : compétences applicables pour l'usage Technique.
|
||
* "lune" est une clé spéciale désignant le dé de lune (Entropie).
|
||
* Les autres clés correspondent aux identifiants de domaine dans SKILLS.
|
||
*/
|
||
export const ANOMALY_DEFINITIONS = {
|
||
none: { technicalSkills: [] },
|
||
entropie: { technicalSkills: ["lune"] },
|
||
communicationaveclesmorts:{ technicalSkills: ["instruction", "mtechnologique", "raisonnement", "traitement"] },
|
||
telekinesie: { technicalSkills: ["echauffouree", "effacement", "mobilite", "prouesse"] },
|
||
telepathie: { technicalSkills: ["appreciation", "attraction", "echauffouree", "faveur"] },
|
||
tarotdivinatoire: { technicalSkills: ["appreciation", "arts", "inspiration", "traque"] },
|
||
illusion: { technicalSkills: ["coercition", "echauffouree", "effacement", "traque"] },
|
||
suggestion: { technicalSkills: ["artifice", "attraction", "coercition", "faveur"] },
|
||
voyageastral: { technicalSkills: ["appreciation", "mtechnologique", "traitement", "traque"] },
|
||
}
|
||
|
||
/** Factions du monde de Célestopol. */
|
||
export const FACTIONS = {
|
||
pinkerton: { id: "pinkerton", label: "CELESTOPOL.Faction.pinkerton" },
|
||
police: { id: "police", label: "CELESTOPOL.Faction.police" },
|
||
okhrana: { id: "okhrana", label: "CELESTOPOL.Faction.okhrana" },
|
||
lunanovatek: { id: "lunanovatek", label: "CELESTOPOL.Faction.lunanovatek" },
|
||
oto: { id: "oto", label: "CELESTOPOL.Faction.oto" },
|
||
syndicats: { id: "syndicats", label: "CELESTOPOL.Faction.syndicats" },
|
||
vorovskoymir:{ id: "vorovskoymir",label: "CELESTOPOL.Faction.vorovskoymir" },
|
||
cour: { id: "cour", label: "CELESTOPOL.Faction.cour" },
|
||
}
|
||
|
||
/** Aspects de faction mobilisables au niveau du groupe. */
|
||
export const FACTION_ASPECTS = {
|
||
bonnesadresses: { id: "bonnesadresses", label: "CELESTOPOL.FactionAspect.bonnesadresses" },
|
||
contrebande: { id: "contrebande", label: "CELESTOPOL.FactionAspect.contrebande" },
|
||
corruption: { id: "corruption", label: "CELESTOPOL.FactionAspect.corruption" },
|
||
diversion: { id: "diversion", label: "CELESTOPOL.FactionAspect.diversion" },
|
||
falsification: { id: "falsification", label: "CELESTOPOL.FactionAspect.falsification" },
|
||
passedroit: { id: "passedroit", label: "CELESTOPOL.FactionAspect.passedroit" },
|
||
renforts: { id: "renforts", label: "CELESTOPOL.FactionAspect.renforts" },
|
||
renseignements: { id: "renseignements", label: "CELESTOPOL.FactionAspect.renseignements" },
|
||
ressources: { id: "ressources", label: "CELESTOPOL.FactionAspect.ressources" },
|
||
surveillance: { id: "surveillance", label: "CELESTOPOL.FactionAspect.surveillance" },
|
||
}
|
||
|
||
/** Tableau p.111 : aspects de faction disponibles selon l'organisation. */
|
||
export const FACTION_ASPECTS_BY_FACTION = {
|
||
police: [
|
||
"diversion", "passedroit", "renforts", "renseignements", "ressources", "surveillance",
|
||
],
|
||
vorovskoymir: [
|
||
"bonnesadresses", "contrebande", "corruption", "diversion", "falsification",
|
||
"renforts", "renseignements", "ressources", "surveillance",
|
||
],
|
||
okhrana: [
|
||
"corruption", "diversion", "falsification", "passedroit", "renforts",
|
||
"renseignements", "ressources",
|
||
],
|
||
oto: [
|
||
"contrebande", "corruption", "falsification", "renseignements", "surveillance",
|
||
],
|
||
syndicats: [
|
||
"bonnesadresses", "contrebande", "corruption", "falsification", "renseignements", "surveillance",
|
||
],
|
||
pinkerton: [
|
||
"bonnesadresses", "diversion", "falsification", "renforts",
|
||
"renseignements", "ressources", "surveillance",
|
||
],
|
||
cour: [
|
||
"bonnesadresses", "contrebande", "diversion", "renforts", "renseignements", "surveillance",
|
||
],
|
||
lunanovatek: [
|
||
"contrebande", "corruption", "falsification", "renforts",
|
||
"renseignements", "ressources", "surveillance",
|
||
],
|
||
}
|
||
|
||
/** Niveaux de blessures avec leur malus associé. */
|
||
export const WOUND_LEVELS = [
|
||
{ id: 0, label: "CELESTOPOL.Wound.none", malus: 0, duration: "" },
|
||
{ id: 1, label: "CELESTOPOL.Wound.anodin", malus: 0, duration: "CELESTOPOL.Wound.duration1min" },
|
||
{ id: 2, label: "CELESTOPOL.Wound.negligeable", malus: 0, duration: "CELESTOPOL.Wound.duration1min" },
|
||
{ id: 3, label: "CELESTOPOL.Wound.derisoire", malus: -1, duration: "CELESTOPOL.Wound.duration10min" },
|
||
{ id: 4, label: "CELESTOPOL.Wound.superficiel", malus: -1, duration: "CELESTOPOL.Wound.duration10min" },
|
||
{ id: 5, label: "CELESTOPOL.Wound.leger", malus: -2, duration: "CELESTOPOL.Wound.duration30min" },
|
||
{ id: 6, label: "CELESTOPOL.Wound.modere", malus: -2, duration: "CELESTOPOL.Wound.duration30min" },
|
||
{ id: 7, label: "CELESTOPOL.Wound.grave", malus: -3, duration: "CELESTOPOL.Wound.duration1jour" },
|
||
{ id: 8, label: "CELESTOPOL.Wound.dramatique", malus: -999, duration: "" },
|
||
]
|
||
|
||
/** Seuils de difficulté pour les jets de dés. */
|
||
export const DIFFICULTY_CHOICES = {
|
||
unknown: { id: "unknown", label: "CELESTOPOL.Difficulty.unknown", value: 0 },
|
||
facile: { id: "facile", label: "CELESTOPOL.Difficulty.facile", value: 5 },
|
||
normal: { id: "normal", label: "CELESTOPOL.Difficulty.normal", value: 7 },
|
||
difficile:{ id: "difficile", label: "CELESTOPOL.Difficulty.difficile", value: 9 },
|
||
ardu: { id: "ardu", label: "CELESTOPOL.Difficulty.ardu", value: 11 },
|
||
extreme: { id: "extreme", label: "CELESTOPOL.Difficulty.extreme", value: 13 },
|
||
}
|
||
|
||
/** Modificateurs contextuels (difficulté narrative) pour les jets. */
|
||
export const CONTEXT_MODIFIER_CHOICES = [
|
||
{ id: "evident", label: "CELESTOPOL.Modifier.evident", value: "auto" },
|
||
{ id: "malaise", label: "CELESTOPOL.Modifier.malaise", value: 0 },
|
||
{ id: "difficile", label: "CELESTOPOL.Modifier.difficile", value: -2 },
|
||
{ id: "tres", label: "CELESTOPOL.Modifier.tres", value: -4 },
|
||
{ id: "extreme", label: "CELESTOPOL.Modifier.extreme", value: -6 },
|
||
{ id: "incroyable", label: "CELESTOPOL.Modifier.incroyable", value: -8 },
|
||
]
|
||
|
||
/** Phases de la lune (dé de lune d8). Index 1-8 = résultat du dé. */
|
||
export const MOON_DIE_FACES = [
|
||
null, // index 0 non utilisé
|
||
{ phase: "nouvellelune", label: "CELESTOPOL.Moon.nouvellelune", result: "triomphe", symbol: "🌑" },
|
||
{ phase: "premiercroissant", label: "CELESTOPOL.Moon.premiercroissant", result: "triomphe", symbol: "🌒" },
|
||
{ phase: "premierquartier", label: "CELESTOPOL.Moon.premierquartier", result: "brio", symbol: "🌓" },
|
||
{ phase: "lunegibbeuse", label: "CELESTOPOL.Moon.lunegibbeuse", result: "brio", symbol: "🌔" },
|
||
{ phase: "lunevoutee", label: "CELESTOPOL.Moon.lunevoutee", result: "contrecoup", symbol: "🌕" },
|
||
{ phase: "dernierquartier", label: "CELESTOPOL.Moon.dernierquartier", result: "contrecoup", symbol: "🌖" },
|
||
{ phase: "derniercroissant", label: "CELESTOPOL.Moon.derniercroissant", result: "catastrophe", symbol: "🌗" },
|
||
{ phase: "pleinelune", label: "CELESTOPOL.Moon.pleinelune", result: "catastrophe", symbol: "🌘" },
|
||
]
|
||
|
||
/** Types de résultats narratifs du dé de Lune. */
|
||
export const MOON_RESULT_TYPES = {
|
||
triomphe: { id: "triomphe", label: "CELESTOPOL.Moon.triomphe", desc: "CELESTOPOL.Moon.triompheFull", cssClass: "moon-triomphe" },
|
||
brio: { id: "brio", label: "CELESTOPOL.Moon.brio", desc: "CELESTOPOL.Moon.brioFull", cssClass: "moon-brio" },
|
||
contrecoup: { id: "contrecoup", label: "CELESTOPOL.Moon.contrecoup", desc: "CELESTOPOL.Moon.contrecoupFull", cssClass: "moon-contrecoup" },
|
||
catastrophe: { id: "catastrophe", label: "CELESTOPOL.Moon.catastrophe", desc: "CELESTOPOL.Moon.catastropheFull", cssClass: "moon-catastrophe" },
|
||
}
|
||
|
||
/** Types d'équipements. */
|
||
export const EQUIPMENT_TYPES = {
|
||
autre: { id: "autre", label: "CELESTOPOL.Equipment.autre" },
|
||
arme: { id: "arme", label: "CELESTOPOL.Equipment.arme" },
|
||
protection:{ id: "protection",label: "CELESTOPOL.Equipment.protection" },
|
||
vehicule: { id: "vehicule", label: "CELESTOPOL.Equipment.vehicule" },
|
||
}
|
||
|
||
/** Types d'armes (mêlée / distance). */
|
||
export const WEAPON_COMBAT_TYPES = {
|
||
melee: { id: "melee", label: "CELESTOPOL.Weapon.typeMelee" },
|
||
distance: { id: "distance", label: "CELESTOPOL.Weapon.typeDistance" },
|
||
}
|
||
|
||
/** Niveaux de dégâts des armes (règles p. ?). */
|
||
export const WEAPON_DAMAGE_TYPES = {
|
||
"0": { id: "0", label: "CELESTOPOL.Weapon.degats0", hint: "CELESTOPOL.Weapon.degats0Hint" },
|
||
"1": { id: "1", label: "CELESTOPOL.Weapon.degats1", hint: "CELESTOPOL.Weapon.degats1Hint" },
|
||
"2": { id: "2", label: "CELESTOPOL.Weapon.degats2", hint: "CELESTOPOL.Weapon.degats2Hint" },
|
||
"X": { id: "X", label: "CELESTOPOL.Weapon.degatsX", hint: "CELESTOPOL.Weapon.degatsXHint" },
|
||
}
|
||
|
||
/** Portées des armes. */
|
||
export const WEAPON_RANGE_TYPES = {
|
||
contact: { id: "contact", label: "CELESTOPOL.Weapon.rangeContact" },
|
||
courte: { id: "courte", label: "CELESTOPOL.Weapon.rangeCourte" },
|
||
longue: { id: "longue", label: "CELESTOPOL.Weapon.rangeLongue" },
|
||
}
|
||
|
||
/** Types de PNJ : standard (domaines classiques) ou antagoniste (Emprise/Péril/Menace/Danger). */
|
||
export const NPC_TYPES = {
|
||
standard: { id: "standard", label: "CELESTOPOL.NPC.typeStandard" },
|
||
antagoniste: { id: "antagoniste", label: "CELESTOPOL.NPC.typeAntagoniste" },
|
||
}
|
||
|
||
/**
|
||
* Labels alternatifs des domaines pour les Antagonistes.
|
||
* Le domaine ame ↔ Emprise, corps ↔ Péril, coeur ↔ Menace, esprit ↔ Danger.
|
||
*/
|
||
export const ANTAGONISTE_STATS = {
|
||
ame: { id: "ame", label: "CELESTOPOL.NPC.emprise" },
|
||
corps: { id: "corps", label: "CELESTOPOL.NPC.peril" },
|
||
coeur: { id: "coeur", label: "CELESTOPOL.NPC.menace" },
|
||
esprit: { id: "esprit", label: "CELESTOPOL.NPC.danger" },
|
||
}
|
||
|
||
/**
|
||
* Modificateurs de tir à distance (LdB p.XX).
|
||
* Affiché dans le dialogue de jet uniquement pour les armes de type "distance".
|
||
*/
|
||
export const RANGED_MODIFIERS = [
|
||
{ id: "none", value: 0, label: "CELESTOPOL.Combat.rangedModNone" },
|
||
{ id: "aim", value: +2, label: "CELESTOPOL.Combat.rangedModAim" },
|
||
{ id: "moving", value: -2, label: "CELESTOPOL.Combat.rangedModMoving" },
|
||
{ id: "engaged", value: -4, label: "CELESTOPOL.Combat.rangedModEngaged" },
|
||
{ id: "longRange", value: -4, label: "CELESTOPOL.Combat.rangedModLongRange" },
|
||
]
|
||
|
||
export const SYSTEM = {
|
||
id: SYSTEM_ID,
|
||
ASCII,
|
||
STATS,
|
||
SKILLS,
|
||
ALL_SKILLS,
|
||
ANOMALY_TYPES,
|
||
ANOMALY_DEFINITIONS,
|
||
FACTIONS,
|
||
FACTION_ASPECTS,
|
||
FACTION_ASPECTS_BY_FACTION,
|
||
NPC_TYPES,
|
||
ANTAGONISTE_STATS,
|
||
WOUND_LEVELS,
|
||
DIFFICULTY_CHOICES,
|
||
CONTEXT_MODIFIER_CHOICES,
|
||
MOON_DIE_FACES,
|
||
MOON_RESULT_TYPES,
|
||
EQUIPMENT_TYPES,
|
||
WEAPON_DAMAGE_TYPES,
|
||
WEAPON_RANGE_TYPES,
|
||
WEAPON_COMBAT_TYPES,
|
||
RANGED_MODIFIERS,
|
||
}
|