fix: aligner les jets et la boîte de dialogue avec les règles

This commit is contained in:
2026-08-01 21:33:38 +02:00
parent 6ce51ed8cf
commit c87b25fbaf
5 changed files with 24 additions and 82 deletions
+2 -5
View File
@@ -121,7 +121,8 @@ export default class RollDialog extends HandlebarsApplicationMixin(foundry.appli
const specChecked = this.#el.querySelector("#usingSpecialization")?.checked;
const helped = this.#el.querySelector("#helped")?.checked;
const tools = this.#el.querySelector("input[name='usingTools']:checked")?.value !== "0";
const bonuses = (specChecked ? 1 : 0) + (helped ? 1 : 0) + (tools ? 1 : 0);
const group = parseInt(this.#el.querySelector("#group")?.value, 10) || 0;
const bonuses = (specChecked ? 1 : 0) + (helped ? 1 : 0) + (tools ? 1 : 0) + group;
return (abilVal + sc + skillPool + bonuses) || 0;
}
@@ -212,10 +213,6 @@ export default class RollDialog extends HandlebarsApplicationMixin(foundry.appli
b += parseInt(this.#getSelfCtrl()?.value, 10) || 0;
const tools = this.#el.querySelector("input[name='usingTools']:checked");
if (tools && tools.value !== "0") b += 1;
const human = this.#el.querySelector("#human-totem");
if (human?.checked) b += parseInt(this.#actor?.system?.adaptation?.totems?.human?.value, 10) || 0;
const adapted = this.#el.querySelector("#adapted-totem");
if (adapted?.checked) b += parseInt(this.#actor?.system?.adaptation?.totems?.adapted?.value, 10) || 0;
if (this.hasSpecialtySelected()) b += 1;
return b;
}
+11
View File
@@ -388,4 +388,15 @@ export const registerHandlebarsHelpers = function () {
Handlebars.registerHelper("setVar", function (varName, varValue, options) {
options.data.root[varName] = varValue;
});
// assign local variables in the current context (used by roll-message.hbs)
Handlebars.registerHelper("set", function (options) {
const ctx = (this && typeof this === "object") ? this : options.contexts?.[0];
if ( ctx && typeof ctx === "object" ) {
for ( const [key, value] of Object.entries(options.hash) ) {
ctx[key] = value;
}
}
return "";
});
}
+5 -72
View File
@@ -49,22 +49,13 @@ export class VermineUtils {
totemBonus = this._calculateTotemDomainBonuses(skillCategory, actor);
}
// Apply auto-successes and auto-thresholds
let autoSuccesses = 0;
// Apply automatic successes from skill mastery
let adjustedDifficulty = difficulty;
if (skillLevel !== null && skillLevel !== undefined) {
autoSuccesses = this._calculateAutoSuccesses(skillLevel, hasSpecialty);
const autoThreshold = this._getAutoThreshold(skillLevel);
if (autoThreshold !== null) {
adjustedDifficulty = autoThreshold;
}
}
// Handle human totem
if (totems.human) {
NoD--;
const humanDifficulty = skillLevel !== null ? Math.max(adjustedDifficulty, difficulty) : adjustedDifficulty;
const humanDifficulty = adjustedDifficulty;
const humanFormula = `(1D10cs>=${humanDifficulty}[human_${safeUserName}]*2)`;
// Apply domain bonus/malus
@@ -78,7 +69,7 @@ export class VermineUtils {
// Handle adapted totem
if (totems.adapted) {
NoD--;
const adaptedDifficulty = skillLevel !== null ? Math.max(adjustedDifficulty, difficulty) : adjustedDifficulty;
const adaptedDifficulty = adjustedDifficulty;
const adaptedFormula = `(1D10cs>=${adaptedDifficulty}[adapted_${safeUserName}]*2)`;
// Apply domain bonus/malus
@@ -105,8 +96,8 @@ export class VermineUtils {
}
}
// Apply handicap (wounds/maluses reduce dice pool)
NoD = Math.max(1, NoD - handicap)
// Ensure the dice pool cannot go below zero
NoD = Math.max(0, NoD)
// Build base formula
const baseFormula = `${NoD}d10cs>=${adjustedDifficulty}[regular_${safeUserName}]`;
@@ -126,7 +117,6 @@ export class VermineUtils {
skillCategory: skillCategory,
skillLevel: skillLevel,
hasSpecialty: hasSpecialty,
autoSuccesses: autoSuccesses,
totemBonuses: { ...totemBonus },
baseNoD: NoD,
rerolls: Reroll,
@@ -205,63 +195,6 @@ export class VermineUtils {
return bonuses;
}
/**
* Calculates automatic successes based on skill mastery level.
* @param {number} skillLevel - Skill level (0-5)
* @param {boolean} [hasSpecialty=false] - Whether a specialty is used
* @returns {number} Number of automatic successes
*/
static _calculateAutoSuccesses(skillLevel, hasSpecialty = false) {
// According to Vermine2047 rules, automatic successes are based on mastery level:
// Level 0 (Incompetent): 0 automatic successes
// Level 1 (Beginner): 0 automatic successes
// Level 2 (Proficient): 1 automatic success if specialty is used
// Level 3 (Expert): 1 automatic success
// Level 4 (Master): 1 automatic success + 1 if specialty is used
// Level 5 (Legend): 2 automatic successes
if (!skillLevel) return 0;
let autoSuccesses = 0;
switch (skillLevel) {
case 2: // Compétent
if (hasSpecialty) autoSuccesses = 1;
break;
case 3: // Expert
autoSuccesses = 1;
break;
case 4: // Maître
autoSuccesses = 1;
if (hasSpecialty) autoSuccesses += 1;
break;
case 5: // Légende
autoSuccesses = 2;
break;
default:
autoSuccesses = 0;
}
return autoSuccesses;
}
/**
* Determines the automatic threshold if the skill is not mastered.
* @param {number} skillLevel - Skill level
* @returns {number|null} Automatic threshold or null if skill is mastered
*/
static _getAutoThreshold(skillLevel) {
// If the skill is not mastered (level 0 or 1), use a default threshold
// Level 0 (Incompetent): threshold = 9 (very hard)
// Level 1 (Beginner): threshold = 7 (hard)
// Level >= 2: null (use normal threshold)
if (skillLevel === 0) return 9; // Very hard
if (skillLevel === 1) return 7; // Hard
return null; // Utiliser le seuil normal
}
/**
* Handles reroll events on dice in chat messages.
* @param {Object} message - The chat message containing the reroll event
+4 -4
View File
@@ -280,7 +280,7 @@
class="totem-checkbox"
/>
<span class="totem-label">{{localize 'TOTEMS.human.name'}}</span>
<small>(+{{@root.actor.system.adaptation.totems.human.value}}D)</small>
<small>({{@root.actor.system.adaptation.totems.human.value}}D)</small>
</label>
<label class="totem-option">
<input
@@ -292,7 +292,7 @@
class="totem-checkbox"
/>
<span class="totem-label">{{localize 'TOTEMS.adapted.name'}}</span>
<small>(+{{@root.actor.system.adaptation.totems.adapted.value}}D)</small>
<small>({{@root.actor.system.adaptation.totems.adapted.value}}D)</small>
</label>
</div>
<small class="totem-hint">{{localize 'VERMINE.totem_hint'}}</small>
@@ -309,7 +309,7 @@
value="1"
/>
<span class="totem-label">{{localize 'TOTEMS.human.name'}}</span>
<small>(+{{@root.actor.system.adaptation.totems.human.value}}D)</small>
<small>({{@root.actor.system.adaptation.totems.human.value}}D)</small>
</label>
</div>
{{/ifgt}}
@@ -326,7 +326,7 @@
value="1"
/>
<span class="totem-label">{{localize 'TOTEMS.adapted.name'}}</span>
<small>(+{{@root.actor.system.adaptation.totems.adapted.value}}D)</small>
<small>({{@root.actor.system.adaptation.totems.adapted.value}}D)</small>
</label>
</div>
{{/ifgt}}
+2 -1
View File
@@ -6,6 +6,7 @@
<span id="difficulty">{{param.difficulty}}</span>
</div>
<div class="reroll-fromroll">
<h4>{{localize "VERMINE.rerolls_possible"}} : <span id="allowed_reroll">{{param.Reroll}}</span></h4>
<div class="reroll flexrow">
@@ -56,7 +57,7 @@
</div>
<div class="flexcol">
<h4>{{localize "VERMINE.success_required"}}:</h4>
<span id="required">{{param.handicap}}</span>
<span id="required">{{math_add 1 param.handicap}}</span>
</div>
</div>
</div>