diff --git a/lang/en.json b/lang/en.json index b67510c..3fddad7 100644 --- a/lang/en.json +++ b/lang/en.json @@ -237,6 +237,14 @@ "reliability_coque_lost": "Hull: trait exhausted and lost", "reliability_cassant": "Fragile: reliability losses increased by 1 point", "reliability_etanche": "Watertight: immersion damage ignored", + "reliability_fortune_skill_bonus": "+1D — the character has the required skill ({skill})", + "reliability_fortune_skill_missing": "Required skill ({skill}) not mastered: rarity Handicap +{rarity}", + "reliability_fortune_hint": "Field repair: +1D if the character has the required skill, otherwise the rarity Handicap of that skill applies.", + "damages_state_1": "Damaged", + "damages_state_2": "Damaged", + "damages_state_3": "Faulty", + "damages_state_4": "Faulty", + "damages_state_5": "Out of service", "wounds": { "name": "Wounds", "threshold": "Threshold", diff --git a/lang/fr.json b/lang/fr.json index 6704da9..1069213 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -318,6 +318,14 @@ "reliability_coque_lost": "Coque : Trait épuisé et perdu", "reliability_cassant": "Cassant : pertes de Fiabilité majorées d'1 point", "reliability_etanche": "Étanche : Dommages d'immersion ignorés", + "reliability_fortune_skill_bonus": "+1D — le personnage possède la Compétence requise ({skill})", + "reliability_fortune_skill_missing": "Compétence requise ({skill}) non maîtrisée : Handicap de Rareté +{rarity}", + "reliability_fortune_hint": "Réparation de fortune : +1D si le personnage possède la Compétence requise, sinon Handicap de Rareté de cette Compétence.", + "damages_state_1": "Endommagé", + "damages_state_2": "Endommagé", + "damages_state_3": "Défectueux", + "damages_state_4": "Défectueux", + "damages_state_5": "Hors d'usage", "choose_ability": "Choisissez une caractéristique", "choose_skill": "Choisissez une compétence", "none": "Aucun", diff --git a/module/applications/sheets/base-item-sheet.mjs b/module/applications/sheets/base-item-sheet.mjs index af08644..91cc630 100644 --- a/module/applications/sheets/base-item-sheet.mjs +++ b/module/applications/sheets/base-item-sheet.mjs @@ -125,13 +125,13 @@ export class VermineBaseItemSheet extends HandlebarsApplicationMixin(foundry.app static async #onReliabilityTest() { const { ReliabilityDialog } = await import("../../system/dialogs/reliabilityDialog.mjs") - const dialog = new ReliabilityDialog({ item: this.document, mode: "test" }) + const dialog = await ReliabilityDialog.create({ item: this.document, mode: "test" }) await dialog.render(true) } static async #onReliabilityRepair() { const { ReliabilityDialog } = await import("../../system/dialogs/reliabilityDialog.mjs") - const dialog = new ReliabilityDialog({ item: this.document, mode: "repair" }) + const dialog = await ReliabilityDialog.create({ item: this.document, mode: "repair" }) await dialog.render(true) } } diff --git a/module/models/_shared.mjs b/module/models/_shared.mjs index 8c8c01b..fc638cb 100644 --- a/module/models/_shared.mjs +++ b/module/models/_shared.mjs @@ -253,7 +253,7 @@ export function baseItemSchema() { return { description: new fields.HTMLField({ required: true, initial: "", textSearch: true }), rarity: raritySchema(), - reliability: new fields.NumberField({ ...reqInt, initial: 3, min: 1, max: 10 }), + reliability: new fields.NumberField({ ...reqInt, initial: 3, min: 0, max: 10 }), handicap: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }), quantity: new fields.NumberField({ ...reqInt, initial: 1, min: 1 }), weight: new fields.NumberField({ ...reqInt, initial: 0, min: 0 }), diff --git a/module/system/dialogs/reliabilityDialog.mjs b/module/system/dialogs/reliabilityDialog.mjs index f913142..69b04f5 100644 --- a/module/system/dialogs/reliabilityDialog.mjs +++ b/module/system/dialogs/reliabilityDialog.mjs @@ -50,6 +50,8 @@ export default class ReliabilityDialog extends HandlebarsApplicationMixin(foundr async _prepareContext() { const hasEtanche = !!this.#item.system?.traits?.etanche; const hasActor = !!this.#item.actor; + const storedSkill = (this.#item.system?.needSkill?.value && this.#item.system?.needSkill?.skill) + || this.#item.system?.skill || ''; const severities = ['mineurs', 'graves', 'critiques'].map((key) => ({ key, label: game.i18n.localize(`VERMINE.reliability_severity_${key}`), @@ -58,6 +60,7 @@ export default class ReliabilityDialog extends HandlebarsApplicationMixin(foundr const skills = VermineReliability.REPAIR_SKILLS.map((key) => ({ key, label: game.i18n.localize(`SKILLS.${key}.name`), + selected: key === storedSkill && VermineReliability.REPAIR_SKILLS.includes(storedSkill), })); return { mode: this.#mode, @@ -70,20 +73,6 @@ export default class ReliabilityDialog extends HandlebarsApplicationMixin(foundr }; } - _onRender(context, options) { - super._onRender(context, options); - if (this.#mode !== 'repair') return; - const select = this.element.querySelector('#reliability-skill'); - const radios = this.element.querySelectorAll('input[name="repairMode"]'); - if (!select || !radios.length) return; - const refresh = () => { - const fortune = this.element.querySelector('input[name="repairMode"]:checked')?.value === 'fortune'; - select.closest('.form-group')?.classList.toggle('hidden', fortune); - }; - radios.forEach((r) => r.addEventListener('change', refresh)); - refresh(); - } - #getOptions() { const el = this.element; if (this.#mode === 'test') { diff --git a/module/system/reliability.mjs b/module/system/reliability.mjs index 34e3fae..3a7efa1 100644 --- a/module/system/reliability.mjs +++ b/module/system/reliability.mjs @@ -40,8 +40,9 @@ export class VermineReliability { */ static panneState(item) { const damages = item.system?.damages; - const idx = (parseInt(damages?.value ?? 0, 10) || 0) - 1; - return idx >= 0 ? damages.state?.[idx] ?? '' : ''; + const value = parseInt(damages?.value ?? 0, 10) || 0; + if (value <= 0 || !damages?.state?.[value - 1]) return ''; + return game.i18n.localize(`VERMINE.damages_state_${value}`); } /** @@ -108,7 +109,7 @@ export class VermineReliability { const destroyed = newReliability === 0; updates['system.reliability'] = newReliability; - updates['system.damages.value'] = destroyed ? 5 : newDamagesValue; + updates['system.damages.value'] = newDamagesValue; await item.update(updates); // État final affiché sur la carte. @@ -116,12 +117,17 @@ export class VermineReliability { if (destroyed) { state = game.i18n.localize('VERMINE.reliability_destroyed'); } else if (newDamagesValue > 0) { - const idx = newDamagesValue - 1; - state = item.system.damages.state?.[idx] ?? ''; + state = game.i18n.localize(`VERMINE.damages_state_${newDamagesValue}`); } else { state = ''; } + // Ne marque comme Dommage que les dés réellement comptés (après + // absorption Étanche/Coque) : les dés absorbés restent affichés mais + // sans le style "damage". + const candidates = results.map((v, i) => ({ v, i })).filter((o) => o.v >= current); + const damageIdx = new Set(candidates.slice(0, Math.max(0, dommages)).map((o) => o.i)); + const content = await foundry.applications.handlebars.renderTemplate( 'systems/vermine2047/templates/reliability-test.hbs', { @@ -131,7 +137,7 @@ export class VermineReliability { oldReliability: current, newReliability, dommages, - results: results.map((v) => ({ value: v, isDamage: v >= current })), + results: results.map((v, i) => ({ value: v, isDamage: damageIdx.has(i) })), state, destroyed, traitsNotes, @@ -176,7 +182,23 @@ export class VermineReliability { : parseInt(actor.system?.skills?.[skill]?.value ?? 0, 10) || 0; const NoD = Math.max(0, precision + skillValue); - const roll = new Roll(`${NoD}d10cs>=${difficulty}`); + // Réparation de fortune (p. 39) : si le personnage possède la Compétence + // requise, +1D sur le jet ; sinon, Handicap de Rareté de cette Compétence + // (le Bonus de Bricolage s'applique dans les deux cas). + const skillRarity = parseInt(actor.system?.skills?.[skill]?.rarity ?? 0, 10) || 0; + const hasSkill = (parseInt(actor.system?.skills?.[skill]?.value ?? 0, 10) || 0) > 0; + const fortuneBonus = mode === 'fortune' && hasSkill ? 1 : 0; + const fortuneHandicap = mode === 'fortune' && !hasSkill ? skillRarity : 0; + let fortuneNote = ''; + if (mode === 'fortune') { + if (hasSkill) { + fortuneNote = game.i18n.format('VERMINE.reliability_fortune_skill_bonus', { skill: game.i18n.localize(`SKILLS.${skill}.name`) }); + } else if (skillRarity > 0) { + fortuneNote = game.i18n.format('VERMINE.reliability_fortune_skill_missing', { skill: game.i18n.localize(`SKILLS.${skill}.name`), rarity: skillRarity }); + } + } + + const roll = new Roll(`${NoD + fortuneBonus}d10cs>=${difficulty}`); await roll.evaluate(); await VermineUtils.showDiceSoNice(roll); @@ -185,7 +207,7 @@ export class VermineReliability { isSuccess: r.success, }))); const successes = roll._total ?? 0; - const required = 1 + handicap; + const required = 1 + handicap + fortuneHandicap; const success = successes >= required; let gained = 0; @@ -228,6 +250,7 @@ export class VermineReliability { successes, required, resultLabel, + fortuneNote, }, ); diff --git a/templates/dialogs/reliability-dialog.hbs b/templates/dialogs/reliability-dialog.hbs index 1e77b19..6bdf44c 100644 --- a/templates/dialogs/reliability-dialog.hbs +++ b/templates/dialogs/reliability-dialog.hbs @@ -37,10 +37,11 @@ +
{{ localize "VERMINE.reliability_fortune_hint" }}
{{#unless hasActor}}{{ localize "VERMINE.reliability_need_actor" }}
{{/unless}} diff --git a/templates/reliability-repair.hbs b/templates/reliability-repair.hbs index 163a06f..2e0a58c 100644 --- a/templates/reliability-repair.hbs +++ b/templates/reliability-repair.hbs @@ -18,4 +18,5 @@ {{ localize "VERMINE.reliability_successes" }}: {{successes}} / {{required}} {{ localize "VERMINE.reliability_result" }}: {{resultLabel}} + {{#if fortuneNote}}{{fortuneNote}}
{{/if}}