diff --git a/lang/fr.json b/lang/fr.json index 6371902..ccf59d5 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -122,7 +122,10 @@ "margin": "Marge", "above": "au-dessus du seuil", "below": "en dessous du seuil", - "destin": "Dépenser 1 Destin (+2 dés)", + "destin": "Dépenser 1 Destin", + "destinBonus": "+2 dés", + "destinAvailable": "disponible(s)", + "destinNone": "Aucun Destin disponible", "usedAspect": "Aspect utilisé", "usedDestin": "Destin dépensé", "criticalSuccessDesc": "Marge ≥ 5 — résultat exceptionnel !", @@ -130,7 +133,12 @@ "woundLevel": "Niveau de blessures", "diceBreakdown": "Détail du jet", "threshold": "Seuil", - "nbDiceBase": "Dés de base" + "nbDiceBase": "Dés de base", + "formula": "Formule", + "visibility": "Visibilité", + "visibilityPublic": "Public", + "visibilityGM": "MJ uniquement", + "visibilitySelf": "Secret (moi)" }, "Moon": { "none": "Aucune phase", diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index 6378309..1fb0b83 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -69,6 +69,7 @@ export class CelestopolRoll extends Roll { moonPhaseChoices, defaultDifficulty: options.difficulty ?? "normal", defaultMoonPhase: options.moonPhase ?? "none", + destActuel: options.destActuel ?? null, } const content = await foundry.applications.handlebars.renderTemplate( @@ -142,8 +143,18 @@ export class CelestopolRoll extends Roll { roll.computeResult() await roll.toMessage({}, { rollMode: rollData.rollMode }) - // Mémoriser les préférences sur l'acteur + // Déduire automatiquement 1 point de Destin si utilisé const actor = game.actors.get(options.actorId) + if (useDestin && actor && (options.destActuel ?? 1) > 0) { + const currentLvl = actor.system.destin?.lvl ?? 0 + const newLvl = Math.min(8, currentLvl + 1) + await actor.update({ + "system.destin.lvl": newLvl, + [`system.destin.d${newLvl}.checked`]: true, + }) + } + + // Mémoriser les préférences sur l'acteur if (actor) { await actor.update({ "system.prefs.moonPhase": moonPhase, diff --git a/module/models/character.mjs b/module/models/character.mjs index 550869a..017a368 100644 --- a/module/models/character.mjs +++ b/module/models/character.mjs @@ -177,18 +177,19 @@ export default class CelestopolCharacter extends foundry.abstract.TypeDataModel if (!skill) return null return CelestopolRoll.prompt({ - actorId: this.parent.id, - actorName: this.parent.name, - actorImage: this.parent.img, + actorId: this.parent.id, + actorName: this.parent.name, + actorImage: this.parent.img, statId, skillId, - statLabel: SYSTEM.STATS[statId]?.label, - skillLabel: skill.label, - skillValue: skill.value, - woundMalus: this.getWoundMalus(), - woundLevel: this.blessures.lvl, - moonPhase: this.prefs.moonPhase, - difficulty: this.prefs.difficulty, + statLabel: SYSTEM.STATS[statId]?.label, + skillLabel: skill.label, + skillValue: skill.value, + woundMalus: this.getWoundMalus(), + woundLevel: this.blessures.lvl, + moonPhase: this.prefs.moonPhase, + difficulty: this.prefs.difficulty, + destActuel: Math.max(0, 8 - (this.destin.lvl ?? 0)), }) } } diff --git a/styles/roll.less b/styles/roll.less index 111eaf8..371d298 100644 --- a/styles/roll.less +++ b/styles/roll.less @@ -1,8 +1,5 @@ // ─── Roll dialog ───────────────────────────────────────────────────────────── -// DialogV2 sets roll-dialog class on the .application element, not on the form. -// All dialog content lives in .application.roll-dialog .dialog-content - .application.roll-dialog .window-content { padding: 0 !important; } @@ -13,94 +10,97 @@ } .application.roll-dialog .roll-dialog-content { - padding: 10px 14px; + padding: 10px 14px 14px; font-family: var(--cel-font-body, "Palatino Linotype", serif); - min-width: 340px; + min-width: 360px; display: flex; flex-direction: column; gap: 0; - // ── Bloc infos acteur ── + // ── Bloc info acteur ── .roll-info-block { - background: var(--cel-green, #1b3828); + background: var(--cel-green, #0c4c0c); background-image: url("../assets/ui/fond_cadrille.jpg"); background-blend-mode: soft-light; - border-bottom: 2px solid var(--cel-orange, #c49a1a); + border-bottom: 2px solid var(--cel-orange, #e07b00); padding: 10px 14px 12px; - margin: -10px -14px 14px; + margin: -10px -14px 12px; text-align: center; .roll-actor { font-family: var(--cel-font-title, "CopaseticNF", serif); color: var(--cel-orange-light, #ddb84a); - font-size: 0.82em; - letter-spacing: 0.06em; - opacity: 0.85; + font-size: 0.78em; + letter-spacing: 0.07em; + text-transform: uppercase; + opacity: 0.9; } .roll-skill-line { font-family: var(--cel-font-title, "CopaseticNF", serif); - font-size: 1.2em; + font-size: 1.25em; color: var(--cel-cream, #f0e8d4); - margin-top: 1px; + margin-top: 2px; .stat-label { color: var(--cel-orange-light, #ddb84a); } - .sep { color: var(--cel-border, #7a5c20); margin: 0 4px; } + .sep { color: rgba(196,154,26,0.45); margin: 0 5px; } } .roll-dice-summary { margin-top: 8px; - padding: 5px 10px; - background: rgba(0,0,0,0.25); + padding: 5px 12px; + background: rgba(0,0,0,0.28); border-radius: 4px; .dice-breakdown { display: flex; align-items: baseline; justify-content: center; - gap: 5px; - font-size: 0.85em; + flex-wrap: wrap; + gap: 4px; + font-size: 0.82em; color: var(--cel-cream, #f0e8d4); .dval, .nb-dice { font-family: var(--cel-font-title, "CopaseticNF", serif); - font-size: 1.6em; - color: var(--cel-orange, #c49a1a); + font-size: 1.7em; + color: var(--cel-orange, #e07b00); font-weight: bold; line-height: 1; } - - .dlabel { font-size: 0.8em; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.8; } - .dminus { color: #e8a0a0; font-weight: bold; } - .deq { opacity: 0.6; } - .ddice { font-size: 1em; color: var(--cel-orange, #c49a1a); } + .dlabel { font-size: 0.78em; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.75; } + .dminus { color: #f0a0a0; font-weight: bold; } + .deq { opacity: 0.55; } + .ddice { color: var(--cel-orange, #e07b00); } } .wound-info { - font-size: 0.75em; - color: #e8a0a0; + font-size: 0.73em; + color: #f0a0a0; margin-top: 3px; } } } - // ── Phases de lune ── + // ── Phases de lune : grille 3 colonnes ── .moon-section { display: flex; flex-direction: column; - gap: 4px; - margin-bottom: 10px; + gap: 5px; + margin-bottom: 12px; .moon-section-label { - font-size: 0.75em; + font-size: 0.72em; text-transform: uppercase; - letter-spacing: 0.06em; - color: var(--cel-orange, #c49a1a); + letter-spacing: 0.07em; + color: var(--cel-orange, #e07b00); + border-bottom: 1px solid rgba(122,92,32,0.3); + padding-bottom: 3px; } .moon-phases { - display: flex; - flex-wrap: wrap; + display: grid; + grid-template-columns: repeat(3, 1fr); gap: 4px; .moon-option { @@ -108,106 +108,204 @@ flex-direction: column; align-items: center; cursor: pointer; - padding: 4px 5px; - border-radius: 3px; - border: 1px solid transparent; - flex: 1; - min-width: 52px; + padding: 5px 4px; + border-radius: 4px; + border: 1px solid rgba(122,92,32,0.25); transition: all 0.15s; + background: rgba(255,255,255,0.4); &:hover { background: rgba(196,154,26,0.12); border-color: var(--cel-border, #7a5c20); } + &.active { - background: rgba(27,56,40,0.15); - border-color: var(--cel-orange, #c49a1a); + background: linear-gradient(160deg, #f5ecd4, #e8d8a0); + border: 2px solid var(--cel-orange, #e07b00); + box-shadow: inset 0 0 6px rgba(196,154,26,0.3); } - .moon-symbol { font-size: 1.4em; line-height: 1; } - .moon-name { font-size: 0.6em; text-align: center; margin-top: 2px; color: #555; } - .moon-bonus { font-size: 0.7em; color: var(--cel-orange, #c49a1a); font-weight: bold; } + .moon-symbol { font-size: 1.5em; line-height: 1; } + .moon-name { font-size: 0.58em; text-align: center; margin-top: 2px; color: #444; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; } + .moon-bonus { font-size: 0.68em; color: var(--cel-orange, #e07b00); font-weight: bold; margin-top: 1px; } } } } - // ── Champs de formulaire ── - .form-group { + // ── Lignes de formulaire ── + .roll-form-rows { + display: flex; + flex-direction: column; + gap: 7px; + margin-bottom: 10px; + } + + .form-row-line { display: flex; align-items: center; gap: 8px; - margin-bottom: 8px; label { - flex: 0 0 130px; - font-size: 0.82em; + flex: 0 0 110px; + font-size: 0.78em; text-transform: uppercase; letter-spacing: 0.04em; - color: var(--cel-orange, #c49a1a); + color: var(--cel-border, #7a5c20); } select, input[type="number"] { flex: 1; - border: 1px solid var(--cel-border, #7a5c20); - border-radius: 2px; - padding: 3px 6px; - background: rgba(255,255,255,0.75); + border: 1px solid rgba(122,92,32,0.5); + border-radius: 3px; + padding: 3px 7px; + background: rgba(255,255,255,0.85); font-family: inherit; - } + font-size: 0.85em; + color: #333; - &.form-row label { flex: 0 0 130px; } + &:focus { outline: 1px solid var(--cel-orange, #e07b00); } + } } .form-two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; - margin-bottom: 8px; - .form-group { + .form-row-line { flex-direction: column; align-items: stretch; - margin-bottom: 0; + gap: 2px; label { flex: none; - margin-bottom: 2px; + text-align: left; + } + + input { width: 100%; box-sizing: border-box; } + } + } + + // ── Ligne Destin ── + .form-destin-row { + border: 1px solid var(--cel-orange, #e07b00); + border-radius: 4px; + background: rgba(196,154,26,0.08); + padding: 7px 10px; + + &.destin-disabled { + border-color: rgba(122,92,32,0.3); + background: rgba(0,0,0,0.04); + opacity: 0.7; + } + + .destin-toggle { + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; + width: 100%; + + input[type="checkbox"] { + width: 16px; + height: 16px; + flex-shrink: 0; + appearance: none; + -webkit-appearance: none; + border: 2px solid var(--cel-border, #7a5c20); + border-radius: 2px; + background: white; + cursor: pointer; + position: relative; + + &:checked { + background: var(--cel-orange, #e07b00); + border-color: var(--cel-orange, #e07b00); + &::after { + content: "✦"; + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + font-size: 0.65em; + color: white; + } + } + + &:disabled { opacity: 0.5; cursor: not-allowed; } + } + + .destin-icon { + font-size: 1.1em; + color: var(--cel-orange, #e07b00); + flex-shrink: 0; + } + + .destin-text { + flex: 1; + + .destin-main { + font-family: var(--cel-font-title, "CopaseticNF", serif); + font-size: 0.9em; + color: var(--cel-green, #0c4c0c); + display: block; + } + + .destin-bonus { + font-size: 0.72em; + color: var(--cel-border, #7a5c20); + font-style: italic; + } + } + + .destin-count { + font-size: 0.75em; + font-weight: bold; + color: var(--cel-green, #0c4c0c); + background: rgba(196,154,26,0.2); + border: 1px solid rgba(196,154,26,0.4); + border-radius: 10px; + padding: 1px 8px; + white-space: nowrap; + + &.no-destin { + color: #888; + background: rgba(0,0,0,0.05); + border-color: rgba(0,0,0,0.1); + } } } } - .form-destin { - margin-bottom: 10px; - - .destin-label { - display: flex; - align-items: center; - gap: 6px; - cursor: pointer; - color: var(--cel-orange, #c49a1a); - font-size: 0.85em; - white-space: nowrap; - flex-wrap: nowrap; - - input[type="checkbox"] { width: 14px; height: 14px; flex-shrink: 0; } - .destin-icon { font-size: 1em; flex-shrink: 0; } - } - } + .form-visibility label { color: #888; } // ── Prévisualisation ── .dice-preview { text-align: center; - margin-top: 4px; - padding: 8px; - background: rgba(27,56,40,0.08); - border-radius: 3px; - border: 1px solid var(--cel-green, #1b3828); + padding: 10px 8px; + background: linear-gradient(160deg, rgba(12,76,12,0.06), rgba(12,76,12,0.12)); + border-radius: 4px; + border: 1px solid rgba(12,76,12,0.2); + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + + .preview-label { + font-size: 0.7em; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--cel-border, #7a5c20); + opacity: 0.8; + } .preview-formula { font-family: var(--cel-font-title, "CopaseticNF", serif); - font-size: 1.4em; - color: var(--cel-orange, #c49a1a); + font-size: 1.6em; + color: var(--cel-orange, #e07b00); font-weight: bold; + letter-spacing: 0.04em; } } } @@ -225,19 +323,18 @@ display: flex; align-items: center; gap: 8px; - background-color: var(--cel-green, #1b3828); + background-color: var(--cel-green, #0c4c0c); background-image: url("../assets/ui/fond_cadrille.jpg"); background-blend-mode: soft-light; padding: 6px 8px; - border-bottom: 2px solid var(--cel-orange, #c49a1a); + border-bottom: 2px solid var(--cel-orange, #e07b00); .actor-img { width: 40px; height: 40px; object-fit: cover; - border: 1px solid var(--cel-orange, #c49a1a); + border: 1px solid var(--cel-orange, #e07b00); border-radius: 2px; - box-shadow: inset 0 0 4px rgba(196,154,26,0.3); flex-shrink: 0; } @@ -249,31 +346,28 @@ .actor-name { font-family: var(--cel-font-title, "CopaseticNF", serif); - color: var(--cel-orange, #c49a1a); + color: var(--cel-orange, #e07b00); font-weight: bold; letter-spacing: 0.05em; - font-size: 0.95em; + font-size: 0.92em; } .skill-info { color: var(--cel-cream, #f0e8d4); - font-size: 0.78em; + font-size: 0.77em; font-style: italic; .stat-lbl { color: var(--cel-orange-light, #ddb84a); } - .sep { margin: 0 2px; color: var(--cel-border, #7a5c20); } - } - .wound-info { - font-size: 0.72em; - color: #e8a0a0; + .sep { margin: 0 2px; opacity: 0.5; } } + .wound-info { font-size: 0.7em; color: #f0a0a0; } } .moon-badge { display: flex; flex-direction: column; align-items: center; - font-size: 0.75em; - .moon-sym { font-size: 1.3em; line-height: 1; } - .moon-bon { color: var(--cel-orange-light, #ddb84a); font-weight: bold; } + gap: 1px; + .moon-sym { font-size: 1.35em; line-height: 1; } + .moon-bon { font-size: 0.72em; color: var(--cel-orange-light, #ddb84a); font-weight: bold; } } } @@ -282,7 +376,7 @@ display: flex; flex-wrap: wrap; gap: 5px; - padding: 8px 10px 4px; + padding: 8px 10px 5px; background: var(--cel-cream, #f0e8d4); justify-content: center; @@ -290,23 +384,25 @@ display: inline-flex; align-items: center; justify-content: center; - width: 30px; - height: 30px; + width: 32px; + height: 32px; border: 2px solid var(--cel-border, #7a5c20); border-radius: 4px; background: white; font-weight: bold; - font-size: 1em; + font-size: 1.05em; font-family: var(--cel-font-title, "CopaseticNF", serif); - box-shadow: 1px 1px 2px rgba(0,0,0,0.15); + box-shadow: 1px 1px 2px rgba(0,0,0,0.12); + color: #222; &.max { - background: var(--cel-green, #1b3828); - color: var(--cel-orange, #c49a1a); - border-color: var(--cel-orange, #c49a1a); + background: var(--cel-green, #0c4c0c); + color: var(--cel-orange, #e07b00); + border-color: var(--cel-orange, #e07b00); + box-shadow: 0 0 5px rgba(224,123,0,0.3); } &.min { - background: #f9e8e8; + background: #fae8e8; color: #a03030; border-color: #c07070; } @@ -319,59 +415,66 @@ flex-wrap: wrap; align-items: baseline; justify-content: center; - gap: 3px; - padding: 4px 10px; + gap: 4px; + padding: 5px 10px 4px; background: var(--cel-cream, #f0e8d4); - font-size: 0.85em; + border-top: 1px solid rgba(122,92,32,0.2); + font-size: 0.83em; color: #555; - .fl-ndice { color: var(--cel-green, #1b3828); font-weight: bold; } - .fl-sum { font-weight: bold; } + .fl-label { color: #999; font-size: 0.88em; text-transform: uppercase; letter-spacing: 0.04em; margin-right: 2px; } + .fl-ndice { color: var(--cel-green, #0c4c0c); font-weight: bold; } + .fl-sum { font-weight: bold; color: #333; } .fl-total { font-family: var(--cel-font-title, "CopaseticNF", serif); - font-size: 1.4em; - color: var(--cel-orange, #c49a1a); + font-size: 1.5em; + color: var(--cel-orange, #e07b00); font-weight: bold; + line-height: 1; } .fl-moon { color: #666; } - .fl-mod { color: #444; } - .fl-asp { color: var(--cel-orange, #c49a1a); } + .fl-mod { color: #444; font-weight: bold; } + .fl-asp { color: var(--cel-orange, #e07b00); font-weight: bold; } .fl-sep { font-weight: bold; color: var(--cel-border, #7a5c20); margin: 0 2px; } - .fl-eq { color: #888; } - .fl-op { color: #888; } + .fl-eq { color: #aaa; } + .fl-op { color: #aaa; } } // ── Seuil et marge ── .threshold-line { display: flex; align-items: center; - justify-content: center; - gap: 5px; - padding: 4px 10px 6px; + justify-content: space-between; + padding: 5px 12px 6px; background: var(--cel-cream, #f0e8d4); - border-top: 1px solid rgba(122,92,32,0.25); + border-top: 1px solid rgba(122,92,32,0.2); font-size: 0.82em; - .vs-label { color: #888; text-transform: uppercase; font-size: 0.85em; } - .diff-label{ font-style: italic; color: var(--cel-green, #1b3828); } + .vs-wrap { + display: flex; + align-items: baseline; + gap: 5px; + } + .vs-label { color: #aaa; text-transform: uppercase; font-size: 0.8em; } + .diff-label{ font-style: italic; color: var(--cel-green, #0c4c0c); } .diff-val { color: #888; } .margin-badge { - margin-left: 6px; - padding: 1px 7px; - border-radius: 10px; + padding: 2px 10px; + border-radius: 12px; font-weight: bold; - font-size: 0.95em; + font-size: 1.05em; font-family: var(--cel-font-title, "CopaseticNF", serif); + letter-spacing: 0.05em; &.above { - background: var(--cel-green, #1b3828); - color: var(--cel-orange, #c49a1a); - border: 1px solid var(--cel-orange, #c49a1a); + background: var(--cel-green, #0c4c0c); + color: var(--cel-orange, #e07b00); + border: 1px solid var(--cel-orange, #e07b00); } &.below { background: var(--cel-accent, #6b1e28); - color: #e8c8c8; + color: #f0d0d0; border: 1px solid #8b3e48; } } @@ -380,11 +483,13 @@ // ── Destin utilisé ── .used-info { text-align: center; - font-size: 0.78em; - color: var(--cel-orange, #c49a1a); - padding: 2px 8px; - background: var(--cel-cream-dark, #e0d4b8); + font-size: 0.77em; + color: var(--cel-orange, #e07b00); + padding: 3px 8px; + background: rgba(196,154,26,0.1); border-top: 1px dashed var(--cel-border, #7a5c20); + + .used-destin { font-weight: bold; } } // ── Bandeau résultat ── @@ -392,50 +497,56 @@ display: flex; flex-direction: column; align-items: center; - padding: 6px 8px; + padding: 7px 8px; font-family: var(--cel-font-title, "CopaseticNF", serif); text-transform: uppercase; letter-spacing: 0.1em; + border-top: 2px solid rgba(0,0,0,0.1); - .result-icon { font-size: 0.9em; opacity: 0.8; } - .result-label { font-size: 1.15em; line-height: 1.2; } + .result-icon { + font-size: 0.85em; + opacity: 0.85; + letter-spacing: 0.15em; + } + .result-label { font-size: 1.2em; line-height: 1.2; } .result-desc { font-size: 0.65em; - letter-spacing: 0.12em; - margin-top: 1px; - opacity: 0.85; + letter-spacing: 0.08em; + margin-top: 2px; + opacity: 0.8; text-transform: none; font-style: italic; font-family: var(--cel-font-body, serif); } &.success { - background-color: var(--cel-green, #1b3828); + background-color: var(--cel-green, #0c4c0c); background-image: url("../assets/ui/fond_cadrille.jpg"); background-blend-mode: soft-light; - color: var(--cel-orange, #c49a1a); + color: var(--cel-orange, #e07b00); } &.critical-success { - background: linear-gradient(135deg, #1b3828, #2c5a3f); + background: linear-gradient(135deg, #0c4c0c 0%, #1a6e1a 50%, #0c4c0c 100%); background-image: url("../assets/ui/fond_cadrille.jpg"); background-blend-mode: soft-light; - color: var(--cel-orange-light, #ddb84a); - border-top: 2px solid var(--cel-orange, #c49a1a); - border-bottom: 2px solid var(--cel-orange, #c49a1a); - text-shadow: 0 0 8px rgba(196,154,26,0.5); + color: #ffd870; + border-top: 3px solid var(--cel-orange, #e07b00); + border-bottom: 3px solid var(--cel-orange, #e07b00); + text-shadow: 0 0 10px rgba(255,216,112,0.6); } &.failure { - background: var(--cel-accent, #6b1e28); - color: #e8c8c8; + background: #4a1520; + color: #f0c0c0; } &.critical-failure { - background: linear-gradient(135deg, #3d0f18, #6b1e28); - color: #f0c8c8; - border-top: 2px solid #8b3e48; - border-bottom: 2px solid #8b3e48; + background: linear-gradient(135deg, #3d0f18 0%, #5c1a25 50%, #3d0f18 100%); + color: #ffd0d0; + border-top: 3px solid #8b3e48; + border-bottom: 3px solid #8b3e48; } } } + diff --git a/templates/chat-message.hbs b/templates/chat-message.hbs index d48ad7f..04716af 100644 --- a/templates/chat-message.hbs +++ b/templates/chat-message.hbs @@ -11,9 +11,7 @@ {{#if statLabel}}{{statLabel}}{{/if}} {{skillLabel}} - {{#if woundLabel}} - ⚠ {{woundLabel}} - {{/if}} + {{#if woundLabel}}⚠ {{woundLabel}}{{/if}}
{{moonSymbol}} @@ -21,7 +19,7 @@
- {{!-- Dés --}} + {{!-- Zone dés --}}
{{#each diceResults as |die|}} {{die}} @@ -30,30 +28,33 @@ {{!-- Formule détaillée --}}
+ {{localize "CELESTOPOL.Roll.formula"}} : {{nbDice}}d6 = {{diceSum}} {{#if moonBonus}} - + - {{moonSymbol}} {{moonBonus}} + + + {{moonSymbol}}{{moonBonus}} {{/if}} {{#if modifier}} - {{#if (gt modifier 0)}}+{{else}}−{{/if}} + {{#if (gt modifier 0)}}+{{else}}−{{/if}} {{abs modifier}} {{/if}} {{#if aspectMod}} - {{#if (gt aspectMod 0)}}+{{else}}−{{/if}} - ✦ {{abs aspectMod}} + {{#if (gt aspectMod 0)}}+{{else}}−{{/if}} + ✦{{abs aspectMod}} {{/if}} - = + = {{total}}
{{!-- Seuil et marge --}}
- vs - {{difficultyLabel}} - ({{difficultyValue}}) + + vs + {{difficultyLabel}} + ({{difficultyValue}}) + {{#if margin}} {{#if marginAbove}}+{{/if}}{{margin}} @@ -61,26 +62,28 @@ {{/if}}
- {{!-- Infos bonus (Destin utilisé) --}} + {{!-- Infos bonus (Destin, Aspect) --}} {{#if useDestin}}
- ⭐ {{localize "CELESTOPOL.Roll.usedDestin"}} + ✦ {{localize "CELESTOPOL.Roll.usedDestin"}}
{{/if}} {{!-- Bandeau résultat --}}
{{#if isCriticalSuccess}} - + ✦✦ {{localize "CELESTOPOL.Roll.criticalSuccess"}} {{localize "CELESTOPOL.Roll.criticalSuccessDesc"}} {{else if isSuccess}} + {{localize "CELESTOPOL.Roll.success"}} {{else if isCriticalFailure}} - + ✖✖ {{localize "CELESTOPOL.Roll.criticalFailure"}} {{localize "CELESTOPOL.Roll.criticalFailureDesc"}} {{else if isFailure}} + {{localize "CELESTOPOL.Roll.failure"}} {{/if}}
diff --git a/templates/roll-dialog.hbs b/templates/roll-dialog.hbs index 0c376fe..19bceec 100644 --- a/templates/roll-dialog.hbs +++ b/templates/roll-dialog.hbs @@ -1,13 +1,12 @@
- {{!-- Info bloc : acteur + domaine --}} + {{!-- En-tête : acteur + domaine + dés de base --}}
{{actorName}}
{{#if statLabel}}{{localize statLabel}}{{/if}} {{localize skillLabel}}
-
{{skillValue}} @@ -26,12 +25,12 @@
- {{!-- Sélecteur Phase de Lune --}} + {{!-- Phases de lune : grille 3 × 3 --}}
{{#each moonPhaseChoices as |phase key|}} -
- {{!-- Seuil de difficulté --}} -
- - -
+
- {{!-- Modificateur & Aspect en ligne --}} -
-
- - + {{!-- Difficulté --}} +
+ +
-
- - + + {{!-- Modificateur & Aspect côte à côte --}} +
+
+ + +
+
+ + +
+ + {{!-- Destin --}} +
+ +
+ + {{!-- Visibilité --}} +
+ + +
+
- {{!-- Destin --}} -
- -
- - {{!-- Prévisualisation dynamique --}} -
+ {{!-- Prévisualisation formule --}} +
+ {{localize "CELESTOPOL.Roll.formula"}} {{nbDiceBase}}d6
@@ -91,27 +113,26 @@ const base = Math.max(1, skillVal + woundMalus); function update() { - const moonBonus = parseInt(wrap.querySelector('input[name="moonPhase"]:checked')?.closest('[data-moon]') - ?.dataset.moonBonus ?? 0); + const moonOpt = wrap.querySelector('input[name="moonPhase"]:checked')?.closest('[data-moon]'); + const moonBonus = parseInt(moonOpt?.dataset.moonBonus ?? 0) || 0; const modifier = parseInt(wrap.querySelector('#modifier')?.value ?? 0) || 0; const aspectMod = parseInt(wrap.querySelector('#aspectModifier')?.value ?? 0) || 0; const useDestin = wrap.querySelector('#useDestin')?.checked ? 2 : 0; const ndice = Math.max(1, base + useDestin); const totalMod = moonBonus + modifier + aspectMod; - const formula = totalMod !== 0 ? `${ndice}d6 + ${totalMod}` : `${ndice}d6`; - const previewEl = wrap.querySelector('#preview-formula'); - const ndiceEl = wrap.querySelector('#preview-ndice'); - if (previewEl) previewEl.textContent = formula; - if (ndiceEl) ndiceEl.textContent = ndice; + let formula = `${ndice}d6`; + if (totalMod > 0) formula += ` + ${totalMod}`; + if (totalMod < 0) formula += ` − ${Math.abs(totalMod)}`; + + const previewEl = wrap.querySelector('#preview-formula'); + const ndiceEl = wrap.querySelector('#preview-ndice'); + if (previewEl) previewEl.textContent = formula; + if (ndiceEl) ndiceEl.textContent = ndice; } - // Mettre à jour les classes actives des lunes + moon-bonus wrap.querySelectorAll('.moon-option').forEach(opt => { const input = opt.querySelector('input[type="radio"]'); - const key = opt.dataset.moon; - const bonusMap = { {{#each moonPhaseChoices}}"{{@key}}": {{#if bonus}}{{bonus}}{{else}}0{{/if}}, {{/each}} }; - opt.dataset.moonBonus = bonusMap[key] ?? 0; input.addEventListener('change', () => { wrap.querySelectorAll('.moon-option').forEach(o => o.classList.remove('active')); opt.classList.add('active'); @@ -121,7 +142,7 @@ wrap.querySelectorAll('#modifier, #aspectModifier, #useDestin').forEach(el => { el.addEventListener('change', update); - el.addEventListener('input', update); + el.addEventListener('input', update); }); update();