Fix formule de dés : 2d8 de base (règles Célestopol)
Correction majeure de la mécanique de jet selon les règles : - Formule : 2d8 + Spécialisation + modificateurs (blessures/aspect/manual) (vs. ancienne formule erronée : Nd6 pool variable) - Dé de la Lune : 1d8 narratif optionnel (résultat 1-8 → Triomphe / Brio / Contrecoup / Catastrophe) — pas un bonus numérique - Destin : disponible uniquement jauge pleine (lvl=8), donne 3d8, vide la jauge entière après usage - system.mjs : MOON_DIE_FACES (tableau 1-8) + MOON_RESULT_TYPES - roll.mjs : logique complète réécrite (2d8, lune séparée, destin reset) - character/npc.mjs : prefs.rollMoonDie + destGaugeFull - roll-dialog.hbs : sans grille lune, checkbox dé lune, destin conditionnel - chat-message.hbs : résultat dé lune narratif (phase + type + desc), dés .d8, suppression moonSymbol/moonBonus header - roll.less : .form-moon-row, .moon-die-result avec couleurs Triomphe/ Brio/Contrecoup/Catastrophe - lang/fr.json : Moon.triomphe/brio/contrecoup/catastrophe + Full descs, Roll.rollMoonDie/destGaugeFull/destGaugeEmpty/baseDice Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<div class="roll-dialog-content">
|
||||
|
||||
{{!-- En-tête : acteur + domaine + dés de base --}}
|
||||
{{!-- En-tête : acteur + domaine + formule de base --}}
|
||||
<div class="roll-info-block">
|
||||
<div class="roll-actor">{{actorName}}</div>
|
||||
<div class="roll-skill-line">
|
||||
@@ -9,15 +9,12 @@
|
||||
</div>
|
||||
<div class="roll-dice-summary">
|
||||
<div class="dice-breakdown">
|
||||
<span class="base-dice">2d8</span>
|
||||
<span class="plus-sign"> + </span>
|
||||
<span class="dval">{{skillValue}}</span>
|
||||
<span class="dlabel">{{localize "CELESTOPOL.Roll.nbDiceBase"}}</span>
|
||||
{{#if woundMalus}}
|
||||
<span class="dminus"> − {{abs woundMalus}}</span>
|
||||
<span class="dlabel">{{localize "CELESTOPOL.Roll.woundMalus"}}</span>
|
||||
{{/if}}
|
||||
<span class="deq"> = </span>
|
||||
<span class="nb-dice" id="preview-ndice">{{nbDiceBase}}</span>
|
||||
<span class="ddice">d6</span>
|
||||
</div>
|
||||
{{#if woundLabel}}
|
||||
<div class="wound-info">⚠ {{woundLabel}}</div>
|
||||
@@ -25,21 +22,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Phases de lune : grille 3 × 3 --}}
|
||||
<div class="moon-section">
|
||||
<div class="moon-section-label">{{localize "CELESTOPOL.Roll.moonPhase"}}</div>
|
||||
<div class="moon-phases" id="moon-phases">
|
||||
{{#each moonPhaseChoices as |phase key|}}
|
||||
<label class="moon-option {{#if (eq key ../defaultMoonPhase)}}active{{/if}}" data-moon="{{key}}" data-moon-bonus="{{#if phase.bonus}}{{phase.bonus}}{{else}}0{{/if}}" title="{{localize phase.label}}">
|
||||
<input type="radio" name="moonPhase" value="{{key}}" {{#if (eq key ../defaultMoonPhase)}}checked{{/if}} hidden>
|
||||
<span class="moon-symbol">{{phase.symbol}}</span>
|
||||
<span class="moon-name">{{localize phase.label}}</span>
|
||||
<span class="moon-bonus">{{#if phase.bonus}}+{{phase.bonus}}{{else}}+0{{/if}}</span>
|
||||
</label>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="roll-form-rows">
|
||||
|
||||
{{!-- Difficulté --}}
|
||||
@@ -66,19 +48,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- Destin --}}
|
||||
<div class="form-destin-row {{#unless destActuel}}destin-disabled{{/unless}}">
|
||||
{{!-- Dé de la Lune --}}
|
||||
<div class="form-moon-row">
|
||||
<label class="moon-toggle" for="rollMoonDie">
|
||||
<input type="checkbox" id="rollMoonDie" name="rollMoonDie" {{#if defaultRollMoonDie}}checked{{/if}}>
|
||||
<span class="moon-icon">🌑</span>
|
||||
<span class="moon-text">{{localize "CELESTOPOL.Roll.rollMoonDie"}}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{{!-- Destin (3d8) — seulement si jauge pleine --}}
|
||||
<div class="form-destin-row {{#unless destGaugeFull}}destin-disabled{{/unless}}">
|
||||
<label class="destin-toggle" for="useDestin">
|
||||
<input type="checkbox" id="useDestin" name="useDestin" {{#unless destActuel}}disabled{{/unless}}>
|
||||
<input type="checkbox" id="useDestin" name="useDestin" {{#unless destGaugeFull}}disabled{{/unless}}>
|
||||
<span class="destin-icon">✦</span>
|
||||
<span class="destin-text">
|
||||
<span class="destin-main">{{localize "CELESTOPOL.Roll.destin"}}</span>
|
||||
<span class="destin-bonus">{{localize "CELESTOPOL.Roll.destinBonus"}}</span>
|
||||
</span>
|
||||
{{#if destActuel}}
|
||||
<span class="destin-count">{{destActuel}} {{localize "CELESTOPOL.Roll.destinAvailable"}}</span>
|
||||
{{#if destGaugeFull}}
|
||||
<span class="destin-badge full">{{localize "CELESTOPOL.Roll.destGaugeFull"}}</span>
|
||||
{{else}}
|
||||
<span class="destin-count no-destin">{{localize "CELESTOPOL.Roll.destinNone"}}</span>
|
||||
<span class="destin-badge empty">{{localize "CELESTOPOL.Roll.destGaugeEmpty"}}</span>
|
||||
{{/if}}
|
||||
</label>
|
||||
</div>
|
||||
@@ -98,48 +89,34 @@
|
||||
{{!-- Prévisualisation formule --}}
|
||||
<div class="dice-preview">
|
||||
<span class="preview-label">{{localize "CELESTOPOL.Roll.formula"}}</span>
|
||||
<span class="preview-formula" id="preview-formula">{{nbDiceBase}}d6</span>
|
||||
<span class="preview-formula" id="preview-formula">2d8</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const wrap = document.querySelector('.roll-dialog-content');
|
||||
const wrap = document.querySelector('.roll-dialog-content');
|
||||
if (!wrap) return;
|
||||
|
||||
const skillVal = {{skillValue}};
|
||||
const woundMalus = {{woundMalus}};
|
||||
const base = Math.max(1, skillVal + woundMalus);
|
||||
|
||||
function update() {
|
||||
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 modifier = parseInt(wrap.querySelector('#modifier')?.value ?? 0) || 0;
|
||||
const aspectMod = parseInt(wrap.querySelector('#aspectModifier')?.value ?? 0) || 0;
|
||||
const useDestin = wrap.querySelector('#useDestin')?.checked;
|
||||
const ndice = useDestin ? 3 : 2;
|
||||
const totalMod = skillVal + woundMalus + modifier + aspectMod;
|
||||
|
||||
let formula = `${ndice}d6`;
|
||||
if (totalMod > 0) formula += ` + ${totalMod}`;
|
||||
if (totalMod < 0) formula += ` − ${Math.abs(totalMod)}`;
|
||||
let formula = `${ndice}d8`;
|
||||
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;
|
||||
}
|
||||
|
||||
wrap.querySelectorAll('.moon-option').forEach(opt => {
|
||||
const input = opt.querySelector('input[type="radio"]');
|
||||
input.addEventListener('change', () => {
|
||||
wrap.querySelectorAll('.moon-option').forEach(o => o.classList.remove('active'));
|
||||
opt.classList.add('active');
|
||||
update();
|
||||
});
|
||||
});
|
||||
|
||||
wrap.querySelectorAll('#modifier, #aspectModifier, #useDestin').forEach(el => {
|
||||
el.addEventListener('change', update);
|
||||
el.addEventListener('input', update);
|
||||
@@ -148,3 +125,4 @@
|
||||
update();
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user