feat: implémente 'Puiser dans ses ressources'
Règle : le joueur peut ignorer tous les malus actifs contre une case de Spleen. - roll.mjs : checkbox puiserRessources ; ignore woundMalus, modifier négatif et aspectMod négatif ; incrémente system.spleen.lvl +1 après le jet - roll-dialog.hbs : bloc rouge foncé visible si woundMalus < 0 ; preview mis à jour - chat-message.hbs : bandeau '💪 Ressources puisées' si utilisé - roll.less : .form-puiser-row, .used-info.used-puiser - lang/fr.json : Roll.puiser/puiserDesc/usedPuiser Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -148,7 +148,10 @@
|
|||||||
"fortune": "Utiliser la Fortune",
|
"fortune": "Utiliser la Fortune",
|
||||||
"fortuneBonus": "1d8 + 8 au lieu de 2d8",
|
"fortuneBonus": "1d8 + 8 au lieu de 2d8",
|
||||||
"fortuneFixed": "Bonus fixe Fortune",
|
"fortuneFixed": "Bonus fixe Fortune",
|
||||||
"usedFortune": "Fortune utilisée (1d8+8)"
|
"usedFortune": "Fortune utilisée (1d8+8)",
|
||||||
|
"puiser": "Puiser dans ses ressources",
|
||||||
|
"puiserDesc": "Ignore tous les malus — coche 1 case de Spleen",
|
||||||
|
"usedPuiser": "Ressources puisées — malus ignorés, +1 Spleen"
|
||||||
},
|
},
|
||||||
"Moon": {
|
"Moon": {
|
||||||
"none": "Aucune phase",
|
"none": "Aucune phase",
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export class CelestopolRoll extends Roll {
|
|||||||
skillValue,
|
skillValue,
|
||||||
woundMalus,
|
woundMalus,
|
||||||
woundLabel,
|
woundLabel,
|
||||||
|
hasMalus: woundMalus < 0,
|
||||||
difficultyChoices: SYSTEM.DIFFICULTY_CHOICES,
|
difficultyChoices: SYSTEM.DIFFICULTY_CHOICES,
|
||||||
defaultDifficulty: options.difficulty ?? "normal",
|
defaultDifficulty: options.difficulty ?? "normal",
|
||||||
destGaugeFull,
|
destGaugeFull,
|
||||||
@@ -101,11 +102,17 @@ export class CelestopolRoll extends Roll {
|
|||||||
const aspectMod = parseInt(rollContext.aspectModifier ?? 0) || 0
|
const aspectMod = parseInt(rollContext.aspectModifier ?? 0) || 0
|
||||||
const useDestin = destGaugeFull && (rollContext.useDestin === true || rollContext.useDestin === "true")
|
const useDestin = destGaugeFull && (rollContext.useDestin === true || rollContext.useDestin === "true")
|
||||||
const useFortune = fortuneValue > 0 && (rollContext.useFortune === true || rollContext.useFortune === "true")
|
const useFortune = fortuneValue > 0 && (rollContext.useFortune === true || rollContext.useFortune === "true")
|
||||||
|
const puiserRessources = rollContext.puiserRessources === true || rollContext.puiserRessources === "true"
|
||||||
const rollMoonDie = rollContext.rollMoonDie === true || rollContext.rollMoonDie === "true"
|
const rollMoonDie = rollContext.rollMoonDie === true || rollContext.rollMoonDie === "true"
|
||||||
|
|
||||||
|
// Puiser dans ses ressources → ignorer tous les malus
|
||||||
|
const effectiveWoundMalus = puiserRessources ? 0 : woundMalus
|
||||||
|
const effectiveModifier = puiserRessources ? Math.max(0, modifier) : modifier
|
||||||
|
const effectiveAspectMod = puiserRessources ? Math.max(0, aspectMod) : aspectMod
|
||||||
|
|
||||||
// Fortune : 1d8 + 8 ; Destin : 3d8 ; sinon : 2d8
|
// Fortune : 1d8 + 8 ; Destin : 3d8 ; sinon : 2d8
|
||||||
const nbDice = useDestin ? 3 : 2
|
const nbDice = useDestin ? 3 : 2
|
||||||
const totalModifier = skillValue + woundMalus + aspectMod + modifier
|
const totalModifier = skillValue + effectiveWoundMalus + effectiveAspectMod + effectiveModifier
|
||||||
const formula = useFortune
|
const formula = useFortune
|
||||||
? buildFormula(1, totalModifier + 8)
|
? buildFormula(1, totalModifier + 8)
|
||||||
: buildFormula(nbDice, totalModifier)
|
: buildFormula(nbDice, totalModifier)
|
||||||
@@ -125,10 +132,12 @@ export class CelestopolRoll extends Roll {
|
|||||||
...options,
|
...options,
|
||||||
difficulty,
|
difficulty,
|
||||||
difficultyValue: diffConfig.value,
|
difficultyValue: diffConfig.value,
|
||||||
modifier,
|
modifier: effectiveModifier,
|
||||||
aspectMod,
|
aspectMod: effectiveAspectMod,
|
||||||
|
woundMalus: effectiveWoundMalus,
|
||||||
useDestin,
|
useDestin,
|
||||||
useFortune,
|
useFortune,
|
||||||
|
puiserRessources,
|
||||||
nbDice: useFortune ? 1 : nbDice,
|
nbDice: useFortune ? 1 : nbDice,
|
||||||
formula,
|
formula,
|
||||||
rollMode: rollContext.visibility ?? "publicroll",
|
rollMode: rollContext.visibility ?? "publicroll",
|
||||||
@@ -165,6 +174,19 @@ export class CelestopolRoll extends Roll {
|
|||||||
await actor.update({ "system.attributs.fortune.value": Math.max(0, currentFortune - 1) })
|
await actor.update({ "system.attributs.fortune.value": Math.max(0, currentFortune - 1) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Puiser dans ses ressources → coche une case de spleen
|
||||||
|
if (puiserRessources && actor) {
|
||||||
|
const currentSpleen = actor.system.spleen.lvl ?? 0
|
||||||
|
if (currentSpleen < 8) {
|
||||||
|
const newLvl = currentSpleen + 1
|
||||||
|
const key = `s${newLvl}`
|
||||||
|
await actor.update({
|
||||||
|
"system.spleen.lvl": newLvl,
|
||||||
|
[`system.spleen.${key}.checked`]: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mémoriser les préférences sur l'acteur
|
// Mémoriser les préférences sur l'acteur
|
||||||
if (actor) {
|
if (actor) {
|
||||||
await actor.update({
|
await actor.update({
|
||||||
@@ -260,6 +282,7 @@ export class CelestopolRoll extends Roll {
|
|||||||
skillValue,
|
skillValue,
|
||||||
useDestin: this.options.useDestin ?? false,
|
useDestin: this.options.useDestin ?? false,
|
||||||
useFortune: this.options.useFortune ?? false,
|
useFortune: this.options.useFortune ?? false,
|
||||||
|
puiserRessources: this.options.puiserRessources ?? false,
|
||||||
nbDice: this.options.nbDice ?? diceResults.length,
|
nbDice: this.options.nbDice ?? diceResults.length,
|
||||||
woundMalus,
|
woundMalus,
|
||||||
woundLabel,
|
woundLabel,
|
||||||
|
|||||||
@@ -285,6 +285,78 @@
|
|||||||
|
|
||||||
.form-visibility label { color: #888; }
|
.form-visibility label { color: #888; }
|
||||||
|
|
||||||
|
// ── Ligne Puiser dans ses ressources ──
|
||||||
|
.form-puiser-row {
|
||||||
|
border: 1px solid rgba(139,62,72,0.4);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: rgba(107,30,40,0.06);
|
||||||
|
padding: 7px 10px;
|
||||||
|
|
||||||
|
.puiser-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 rgba(139,62,72,0.6);
|
||||||
|
border-radius: 2px;
|
||||||
|
background: white;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:checked {
|
||||||
|
background: var(--cel-accent, #6b1e28);
|
||||||
|
border-color: var(--cel-accent, #6b1e28);
|
||||||
|
&::after {
|
||||||
|
content: "✓";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 0.75em;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.puiser-icon { font-size: 1em; flex-shrink: 0; }
|
||||||
|
|
||||||
|
.puiser-text {
|
||||||
|
flex: 1;
|
||||||
|
.puiser-main {
|
||||||
|
font-family: var(--cel-font-title, "CopaseticNF", serif);
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: var(--cel-accent, #6b1e28);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.puiser-sub {
|
||||||
|
font-size: 0.7em;
|
||||||
|
color: #888;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.puiser-cost {
|
||||||
|
font-size: 0.8em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--cel-accent, #6b1e28);
|
||||||
|
background: rgba(107,30,40,0.1);
|
||||||
|
border: 1px solid rgba(139,62,72,0.35);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 1px 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Ligne Fortune ──
|
// ── Ligne Fortune ──
|
||||||
.form-fortune-row {
|
.form-fortune-row {
|
||||||
border: 1px solid rgba(12,76,12,0.4);
|
border: 1px solid rgba(12,76,12,0.4);
|
||||||
@@ -567,6 +639,13 @@
|
|||||||
.used-fortune { font-weight: bold; color: var(--cel-green, #0c4c0c); }
|
.used-fortune { font-weight: bold; color: var(--cel-green, #0c4c0c); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.used-info.used-puiser {
|
||||||
|
color: var(--cel-accent, #6b1e28);
|
||||||
|
background: rgba(107,30,40,0.08);
|
||||||
|
border-top-color: rgba(139,62,72,0.3);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
// ── Fortune fixe badge dans zone dés ──
|
// ── Fortune fixe badge dans zone dés ──
|
||||||
.fortune-fixed-badge {
|
.fortune-fixed-badge {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|||||||
@@ -84,6 +84,11 @@
|
|||||||
<span class="used-fortune">⚜ {{localize "CELESTOPOL.Roll.usedFortune"}}</span>
|
<span class="used-fortune">⚜ {{localize "CELESTOPOL.Roll.usedFortune"}}</span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{#if puiserRessources}}
|
||||||
|
<div class="used-info used-puiser">
|
||||||
|
<span>💪 {{localize "CELESTOPOL.Roll.usedPuiser"}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{!-- Résultat du Dé de la Lune (narratif) --}}
|
{{!-- Résultat du Dé de la Lune (narratif) --}}
|
||||||
{{#if hasMoonDie}}
|
{{#if hasMoonDie}}
|
||||||
|
|||||||
@@ -82,6 +82,21 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{!-- Puiser dans ses ressources — si malus de blessures --}}
|
||||||
|
{{#if hasMalus}}
|
||||||
|
<div class="form-puiser-row">
|
||||||
|
<label class="puiser-toggle" for="puiserRessources">
|
||||||
|
<input type="checkbox" id="puiserRessources" name="puiserRessources">
|
||||||
|
<span class="puiser-icon">💪</span>
|
||||||
|
<span class="puiser-text">
|
||||||
|
<span class="puiser-main">{{localize "CELESTOPOL.Roll.puiser"}}</span>
|
||||||
|
<span class="puiser-sub">{{localize "CELESTOPOL.Roll.puiserDesc"}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="puiser-cost">+1 <i class="fas fa-face-sad-tear"></i></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{!-- Fortune (1d8+8) — seulement si Fortune > 0 --}}
|
{{!-- Fortune (1d8+8) — seulement si Fortune > 0 --}}
|
||||||
{{#if fortuneValue}}
|
{{#if fortuneValue}}
|
||||||
<div class="form-fortune-row">
|
<div class="form-fortune-row">
|
||||||
@@ -130,8 +145,13 @@
|
|||||||
const aspectMod = parseInt(wrap.querySelector('#aspectModifier')?.value ?? 0) || 0;
|
const aspectMod = parseInt(wrap.querySelector('#aspectModifier')?.value ?? 0) || 0;
|
||||||
const useDestin = wrap.querySelector('#useDestin')?.checked;
|
const useDestin = wrap.querySelector('#useDestin')?.checked;
|
||||||
const useFortune = wrap.querySelector('#useFortune')?.checked;
|
const useFortune = wrap.querySelector('#useFortune')?.checked;
|
||||||
|
const puiser = wrap.querySelector('#puiserRessources')?.checked;
|
||||||
const ndice = useDestin ? 3 : 2;
|
const ndice = useDestin ? 3 : 2;
|
||||||
const totalMod = skillVal + woundMalus + modifier + aspectMod;
|
|
||||||
|
const effWound = puiser ? 0 : woundMalus;
|
||||||
|
const effMod = puiser ? Math.max(0, modifier) : modifier;
|
||||||
|
const effAspect = puiser ? Math.max(0, aspectMod) : aspectMod;
|
||||||
|
const totalMod = skillVal + effWound + effMod + effAspect;
|
||||||
|
|
||||||
let formula;
|
let formula;
|
||||||
if (useFortune) {
|
if (useFortune) {
|
||||||
@@ -147,7 +167,7 @@
|
|||||||
if (previewEl) previewEl.textContent = formula;
|
if (previewEl) previewEl.textContent = formula;
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap.querySelectorAll('#modifier, #aspectModifier, #useDestin, #useFortune').forEach(el => {
|
wrap.querySelectorAll('#modifier, #aspectModifier, #useDestin, #useFortune, #puiserRessources').forEach(el => {
|
||||||
el.addEventListener('change', update);
|
el.addEventListener('change', update);
|
||||||
el.addEventListener('input', update);
|
el.addEventListener('input', update);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user