From 70a97796a3be3a9a404910e08b10f628ad730dda Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Fri, 7 Aug 2026 08:57:35 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20gestion=20de=20la=20Fiabilit=C3=A9=20du?= =?UTF-8?q?=20mat=C3=A9riel=20(test=20de=20Fiabilit=C3=A9=20+=20r=C3=A9par?= =?UTF-8?q?ations)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - module/system/reliability.mjs : VermineReliability - Test de Fiabilité : jet Xd10 (Mineurs 1D / Graves 3D / Critiques 5D), chaque dé >= Fiabilité inflige 1 Dommage ; réduit Fiabilité et dommages cumulés (panne/état/effet) ; destruction à 0 - Traits appliqués : Coque (absorbe n puis se perd), Cassant (+1 perte), Étanche (Dommages d'immersion ignorés si Fiabilité au max) - Réparations : classique (Précision + Artisanat/Mécanique/Technologie/ Armurerie vs Fiabilité d'origine + Handicap de panne, +1 Fiabilité/Réussite) et de fortune (Précision + Bricolage, panne réparée sans gain de Fiabilité) - ReliabilityDialog (test/réparation) + cartes de chat dédiées - Boutons Test de Fiabilité / Réparer sur les fiches d'items (weapon/defense/item) - i18n fr/en + styles des cartes et boutons --- lang/en.json | 26 ++ lang/fr.json | 26 ++ less/base.less | 161 ++++++++++++ .../applications/sheets/base-item-sheet.mjs | 16 +- module/system/dialogs/reliabilityDialog.mjs | 114 ++++++++ module/system/reliability.mjs | 246 ++++++++++++++++++ templates/dialogs/reliability-dialog.hbs | 53 ++++ templates/item/partials/physicalItems.hbs | 4 + templates/reliability-repair.hbs | 21 ++ templates/reliability-test.hbs | 22 ++ 10 files changed, 688 insertions(+), 1 deletion(-) create mode 100644 module/system/dialogs/reliabilityDialog.mjs create mode 100644 module/system/reliability.mjs create mode 100644 templates/dialogs/reliability-dialog.hbs create mode 100644 templates/reliability-repair.hbs create mode 100644 templates/reliability-test.hbs diff --git a/lang/en.json b/lang/en.json index 2be5a9b..0610193 100644 --- a/lang/en.json +++ b/lang/en.json @@ -211,6 +211,32 @@ "rarity_sm": "Rar.", "reliability": "Reliability", "reliability_sm": "Fiab.", + "reliability_test": "Reliability test", + "reliability_repair": "Repair", + "reliability_severity": "Damage severity", + "reliability_severity_mineurs": "Minor (1D)", + "reliability_severity_graves": "Grave (3D)", + "reliability_severity_critiques": "Critical (5D)", + "reliability_immersion": "Prolonged immersion", + "reliability_damages": "Damage taken", + "reliability_state": "State", + "reliability_destroyed": "OBJECT DESTROYED / UNUSABLE", + "reliability_repair_mode": "Repair type", + "reliability_repair_classic": "Classic", + "reliability_repair_fortune": "Field repair", + "reliability_skill": "Skill", + "reliability_run": "Roll", + "reliability_successes": "Successes", + "reliability_result": "Result", + "reliability_gained": "Reliability restored: +{gained}", + "reliability_fixed": "Breakdown fixed (object functional)", + "reliability_failed": "Failure — no reliability point restored", + "reliability_need_actor": "Repair impossible: the object must belong to an actor", + "reliability_already_destroyed": "Object already destroyed or unusable", + "reliability_coque_absorbed": "Hull absorbs {absorbed} damage(s), {remaining} left", + "reliability_coque_lost": "Hull: trait exhausted and lost", + "reliability_cassant": "Fragile: reliability losses increased by 1 point", + "reliability_etanche": "Watertight: immersion damage ignored", "wounds": { "name": "Wounds", "threshold": "Threshold", diff --git a/lang/fr.json b/lang/fr.json index 72de5b0..b65ca1c 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -292,6 +292,32 @@ "rarity_sm": "Rar.", "reliability": "Fiabilité", "reliability_sm": "Fiab.", + "reliability_test": "Test de Fiabilité", + "reliability_repair": "Réparer", + "reliability_severity": "Gravité des Dommages", + "reliability_severity_mineurs": "Mineurs (1D)", + "reliability_severity_graves": "Graves (3D)", + "reliability_severity_critiques": "Critiques (5D)", + "reliability_immersion": "Immersion prolongée", + "reliability_damages": "Dommages subis", + "reliability_state": "État", + "reliability_destroyed": "OBJET DÉTRUIT / INUTILISABLE", + "reliability_repair_mode": "Type de réparation", + "reliability_repair_classic": "Classique", + "reliability_repair_fortune": "De fortune", + "reliability_skill": "Compétence", + "reliability_run": "Lancer", + "reliability_successes": "Réussites", + "reliability_result": "Résultat", + "reliability_gained": "Fiabilité restaurée : +{gained}", + "reliability_fixed": "Panne réparée (objet fonctionnel)", + "reliability_failed": "Échec — aucun point de Fiabilité rendu", + "reliability_need_actor": "Réparation impossible : l'objet doit appartenir à un acteur", + "reliability_already_destroyed": "Objet déjà détruit ou inutilisable", + "reliability_coque_absorbed": "Coque absorbe {absorbed} Dommage(s), {remaining} restant(s)", + "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", "choose_ability": "Choisissez une caractéristique", "choose_skill": "Choisissez une compétence", "none": "Aucun", diff --git a/less/base.less b/less/base.less index 22f1ba7..294572e 100644 --- a/less/base.less +++ b/less/base.less @@ -1171,3 +1171,164 @@ ol.chat-log { } } } + +// ── Test de Fiabilité / Réparations ────────────────────────────────── +.vermine-reliability-message { + padding: 4px 10px 10px; + + .reliability-header { + align-items: center; + gap: 8px; + + img { + flex: 0 0 auto; + width: 36px; + height: 36px; + object-fit: cover; + border-radius: 3px; + border: 1px solid @color-border-dark-4; + } + + h3 { + font-family: "DistressBlack"; + text-transform: uppercase; + font-size: @font-size-13; + margin: 0; + border-bottom: none; + color: @theme-color-dark; + } + } + + .reliability-meta { + gap: 4px 12px; + margin: 4px 0 6px; + padding: 4px 8px; + background: rgba(0, 0, 0, 0.06); + border-radius: 3px; + + .reliability-meta-item { + font-family: "Roboto", sans-serif; + font-size: @font-size-11; + color: @color-text-dark-primary; + + strong { + text-transform: uppercase; + } + } + } + + .reliability-results { + gap: 6px; + margin: 6px 0; + + .reliability-die { + flex: none; + width: 34px; + height: 34px; + display: flex; + align-items: center; + justify-content: center; + font-family: "DistressBlack"; + font-size: @font-size-16; + border: 1px solid @color-border-dark-4; + border-radius: 50%; + background: rgba(0, 0, 0, 0.08); + color: @color-text-dark-primary; + + &.damage { + border-color: @color-hemolymph; + background: fade(@color-hemolymph, 15%); + color: @color-hemolymph; + font-weight: 900; + } + + &.success { + border-color: @color-acid-green; + background: fade(@color-acid-green, 15%); + color: @color-acid-green; + font-weight: 900; + } + } + } + + .reliability-summary { + gap: 4px 16px; + margin: 4px 0; + font-family: "Roboto", sans-serif; + font-size: @font-size-12; + color: @color-text-dark-primary; + + strong { + text-transform: uppercase; + } + } + + .reliability-note { + margin: 2px 0; + font-size: @font-size-11; + font-style: italic; + color: @color-text-dark-secondary; + } + + .reliability-destroyed { + margin: 6px 0 0; + padding: 4px 8px; + font-family: "DistressBlack"; + text-transform: uppercase; + font-size: @font-size-12; + text-align: center; + color: @color-hemolymph; + border: 1px solid @color-hemolymph; + border-radius: 3px; + background: fade(@color-hemolymph, 12%); + } +} + +.item .reliability-actions { + gap: 6px; + justify-content: center; + margin: 4px 0 8px; + + button { + font-family: "DistressBlack", sans-serif; + text-transform: uppercase; + font-size: @font-size-11; + padding: 3px 12px; + cursor: pointer; + color: @theme-color-dark; + background: fade(@color-hemolymph, 15%); + border: 1px solid @color-hemolymph; + border-radius: 3px; + .transition(); + + &:hover { + color: @theme-color-dark; + background: @color-hemolymph; + } + + i { + margin-right: 4px; + } + } +} + +.reliability-severities, +.reliability-modes { + gap: 8px; + + .reliability-option { + display: flex; + align-items: center; + gap: 4px; + cursor: pointer; + font-size: @font-size-12; + color: @color-text-dark-primary; + } +} + +.reliability-hint { + margin: 0; + font-size: @font-size-11; + font-style: italic; + color: @color-text-dark-secondary; +} diff --git a/module/applications/sheets/base-item-sheet.mjs b/module/applications/sheets/base-item-sheet.mjs index dea6170..af08644 100644 --- a/module/applications/sheets/base-item-sheet.mjs +++ b/module/applications/sheets/base-item-sheet.mjs @@ -25,7 +25,9 @@ export class VermineBaseItemSheet extends HandlebarsApplicationMixin(foundry.app editImage: VermineBaseItemSheet.#onEditImage, toggleSheet: VermineBaseItemSheet.#onToggleSheet, clickDamage: VermineBaseItemSheet.#onClickDamage, - openTraits: VermineBaseItemSheet.#onOpenTraits + openTraits: VermineBaseItemSheet.#onOpenTraits, + reliabilityTest: VermineBaseItemSheet.#onReliabilityTest, + reliabilityRepair: VermineBaseItemSheet.#onReliabilityRepair } } @@ -120,4 +122,16 @@ export class VermineBaseItemSheet extends HandlebarsApplicationMixin(foundry.app const { TraitSelector } = await import("../../system/applications.mjs") new TraitSelector(this.document).render(true) } + + static async #onReliabilityTest() { + const { ReliabilityDialog } = await import("../../system/dialogs/reliabilityDialog.mjs") + const dialog = new ReliabilityDialog({ 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" }) + await dialog.render(true) + } } diff --git a/module/system/dialogs/reliabilityDialog.mjs b/module/system/dialogs/reliabilityDialog.mjs new file mode 100644 index 0000000..f913142 --- /dev/null +++ b/module/system/dialogs/reliabilityDialog.mjs @@ -0,0 +1,114 @@ +import { VermineReliability } from '../reliability.mjs'; + +const { HandlebarsApplicationMixin } = foundry.applications.api; + +/** + * Dialogue de Test de Fiabilité / Réparation d'un item. + * Mode "test" : choix de la gravité des Dommages matériels (Mineurs/Graves/Critiques) + * + case Immersion (Trait Étanche). Mode "repair" : type de réparation + * (classique/de fortune) + compétence utilisée. + */ +export default class ReliabilityDialog extends HandlebarsApplicationMixin(foundry.applications.api.ApplicationV2) { + #item; + #mode; + + static DEFAULT_OPTIONS = { + classes: ['vermine-roll', 'reliability'], + tag: 'form', + window: { + icon: 'fas fa-tools', + resizable: false, + }, + position: { + width: 460, + height: 'auto', + }, + actions: { + run: ReliabilityDialog.#onRun, + cancel: ReliabilityDialog.#onCancel, + }, + }; + + static PARTS = { + main: { template: 'systems/vermine2047/templates/dialogs/reliability-dialog.hbs', scrollable: [''] }, + }; + + static async create({ item, mode = 'test' }) { + return new ReliabilityDialog({ item, mode }); + } + + constructor(options = {}) { + super(options); + this.#item = options.item; + this.#mode = options.mode ?? 'test'; + } + + get title() { + return game.i18n.localize(this.#mode === 'repair' ? 'VERMINE.reliability_repair' : 'VERMINE.reliability_test'); + } + + async _prepareContext() { + const hasEtanche = !!this.#item.system?.traits?.etanche; + const hasActor = !!this.#item.actor; + const severities = ['mineurs', 'graves', 'critiques'].map((key) => ({ + key, + label: game.i18n.localize(`VERMINE.reliability_severity_${key}`), + selected: key === 'graves', + })); + const skills = VermineReliability.REPAIR_SKILLS.map((key) => ({ + key, + label: game.i18n.localize(`SKILLS.${key}.name`), + })); + return { + mode: this.#mode, + isTest: this.#mode === 'test', + isRepair: this.#mode === 'repair', + hasEtanche, + hasActor, + severities, + skills, + }; + } + + _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') { + return { + severity: el.querySelector('input[name="severity"]:checked')?.value ?? 'graves', + immersion: !!el.querySelector('#reliability-immersion')?.checked, + }; + } + return { + mode: el.querySelector('input[name="repairMode"]:checked')?.value ?? 'classique', + skill: el.querySelector('#reliability-skill')?.value ?? 'technology', + }; + } + + static async #onRun() { + const options = this.#getOptions(); + if (this.#mode === 'test') { + await VermineReliability.test(this.#item, options); + } else { + await VermineReliability.repair(this.#item, options); + } + this.close(); + } + + static #onCancel() { + this.close(); + } +} diff --git a/module/system/reliability.mjs b/module/system/reliability.mjs new file mode 100644 index 0000000..34e3fae --- /dev/null +++ b/module/system/reliability.mjs @@ -0,0 +1,246 @@ +import { VermineUtils } from './roll.mjs'; + +/** + * Gestion de la Fiabilité du matériel (regles/regles_materiel.txt). + * + * Test de Fiabilité (Dommages matériels) : selon la gravité (Mineurs 1D, + * Graves 3D, Critiques 5D), on lance les dés sans Relance ni Réserve ; + * chaque dé >= Fiabilité inflige 1 Dommage (réduit la Fiabilité de 1). + * À 0, l'équipement est détruit ou inutilisable. + * + * Réparations : jet de Précision + Compétence contre la Fiabilité d'origine + * (classique) ou de Précision + Bricolage contre la Fiabilité actuelle + * (de fortune). Chaque Réussite rend 1 point de Fiabilité (classique) ; + * la réparation de fortune rend l'objet fonctionnel sans rendre de point. + */ +export class VermineReliability { + /** Gravités et nombre de dés de Dommages (p. 37). */ + static SEVERITIES = { mineurs: 1, graves: 3, critiques: 5 }; + + /** Handicap de réparation selon les Dommages subis (Mineure I, Grave II, Critique III). */ + static #PANNE_HANDICAP = { 1: 1, 2: 1, 3: 2, 4: 2, 5: 3 }; + + /** Compétences de réparation classique (regles_materiel p. 39). */ + static REPAIR_SKILLS = ['crafting', 'mecanical', 'technology', 'armory']; + + /** + * Handicap de la panne courante (0 si intact). + * @param {Item} item + * @returns {number} + */ + static panneHandicap(item) { + const value = parseInt(item.system?.damages?.value ?? 0, 10) || 0; + return this.#PANNE_HANDICAP[value] || 0; + } + + /** + * État courant dérivé des Dommages subis (tableau `damages.state`). + * @param {Item} item + * @returns {string} + */ + static panneState(item) { + const damages = item.system?.damages; + const idx = (parseInt(damages?.value ?? 0, 10) || 0) - 1; + return idx >= 0 ? damages.state?.[idx] ?? '' : ''; + } + + /** + * Test de Fiabilité : jet de Dommages matériels. + * @param {Item} item + * @param {Object} opts + * @param {string} opts.severity "mineurs" | "graves" | "critiques" + * @param {boolean} opts.immersion si vrai, le Trait Étanche peut annuler les Dommages + * @returns {Promise} Résultat (null si impossible) + */ + static async test(item, { severity = 'graves', immersion = false } = {}) { + if (!item) return null; + const diceCount = this.SEVERITIES[severity] ?? 3; + const current = parseInt(item.system?.reliability ?? 0, 10) || 0; + const traits = item.system?.traits ?? {}; + const damagesValue = parseInt(item.system?.damages?.value ?? 0, 10) || 0; + + if (current <= 0) { + ui.notifications.warn(game.i18n.localize('VERMINE.reliability_already_destroyed')); + return { destroyed: true, dommages: 0 }; + } + + // Jet des dés de Dommages (sans Relance ni Réserve) + const roll = new Roll(`${diceCount}d10`); + await roll.evaluate(); + await VermineUtils.showDiceSoNice(roll); + + const results = (roll.dice ?? []).flatMap((d) => (d.results ?? []).map((r) => r.result ?? 0)); + const traitsNotes = []; + + // Trait Étanche : ignore les Dommages d'immersion tant que la Fiabilité + // est à son maximum (objet sans Dommage cumulé). + let dommages = results.filter((r) => r >= current).length; + if (immersion && traits.etanche && damagesValue === 0) { + dommages = 0; + traitsNotes.push(game.i18n.localize('VERMINE.reliability_etanche')); + } + + // Trait Coque (n) : ignore les (n) premiers Dommages puis se perd. + let coqueValue = parseInt(traits.coque?.value ?? 0, 10) || 0; + const updates = {}; + if (coqueValue > 0 && dommages > 0) { + const absorbed = Math.min(coqueValue, dommages); + dommages -= absorbed; + coqueValue -= absorbed; + if (coqueValue > 0) { + updates['system.traits.coque.value'] = coqueValue; + traitsNotes.push(game.i18n.format('VERMINE.reliability_coque_absorbed', { absorbed, remaining: coqueValue })); + } else { + updates['system.traits.coque'] = null; + traitsNotes.push(game.i18n.localize('VERMINE.reliability_coque_lost')); + } + } + + // Trait Cassant : toutes les pertes de Fiabilité sont majorées d'1 point. + const cassant = !!traits.cassant; + if (cassant && dommages > 0) { + dommages += 1; + traitsNotes.push(game.i18n.localize('VERMINE.reliability_cassant')); + } + + const newReliability = Math.max(0, current - dommages); + const newDamagesValue = Math.min(5, damagesValue + dommages); + const destroyed = newReliability === 0; + + updates['system.reliability'] = newReliability; + updates['system.damages.value'] = destroyed ? 5 : newDamagesValue; + await item.update(updates); + + // État final affiché sur la carte. + let state = ''; + if (destroyed) { + state = game.i18n.localize('VERMINE.reliability_destroyed'); + } else if (newDamagesValue > 0) { + const idx = newDamagesValue - 1; + state = item.system.damages.state?.[idx] ?? ''; + } else { + state = ''; + } + + const content = await foundry.applications.handlebars.renderTemplate( + 'systems/vermine2047/templates/reliability-test.hbs', + { + item: { name: item.name, img: item.img }, + severityLabel: game.i18n.localize(`VERMINE.reliability_severity_${severity}`), + diceCount, + oldReliability: current, + newReliability, + dommages, + results: results.map((v) => ({ value: v, isDamage: v >= current })), + state, + destroyed, + traitsNotes, + }, + ); + + await ChatMessage.create({ + user: game.user?._id, + speaker: this.#getSpeaker(item), + content, + }); + + return { dommages, newReliability, destroyed }; + } + + /** + * Réparation classique ou de fortune. + * @param {Item} item + * @param {Object} opts + * @param {string} opts.mode "classique" | "fortune" + * @param {string} opts.skill Compétence de réparation classique (clé de skills) + * @returns {Promise} + */ + static async repair(item, { mode = 'classique', skill = 'technology' } = {}) { + const actor = item?.actor; + if (!item || !actor) { + ui.notifications.warn(game.i18n.localize('VERMINE.reliability_need_actor')); + return null; + } + + const current = parseInt(item.system?.reliability ?? 0, 10) || 0; + const damagesValue = parseInt(item.system?.damages?.value ?? 0, 10) || 0; + const handicap = this.panneHandicap(item); + + // Difficulté : Fiabilité d'origine (≈ actuelle + Dommages subis) pour la + // réparation classique ; Fiabilité actuelle pour la réparation de fortune. + const difficulty = mode === 'classique' ? Math.min(10, current + damagesValue) : current; + + const precision = parseInt(actor.system?.abilities?.precision?.value ?? 0, 10) || 0; + const skillValue = mode === 'fortune' + ? parseInt(actor.system?.skills?.diy?.value ?? 0, 10) || 0 + : parseInt(actor.system?.skills?.[skill]?.value ?? 0, 10) || 0; + const NoD = Math.max(0, precision + skillValue); + + const roll = new Roll(`${NoD}d10cs>=${difficulty}`); + await roll.evaluate(); + await VermineUtils.showDiceSoNice(roll); + + const results = (roll.dice ?? []).flatMap((d) => (d.results ?? []).map((r) => ({ + value: r.result ?? 0, + isSuccess: r.success, + }))); + const successes = roll._total ?? 0; + const required = 1 + handicap; + const success = successes >= required; + + let gained = 0; + let fortuneFixed = false; + let resultLabel = ''; + if (success) { + if (mode === 'classique') { + gained = successes; + resultLabel = game.i18n.format('VERMINE.reliability_gained', { gained }); + } else { + fortuneFixed = true; + resultLabel = game.i18n.localize('VERMINE.reliability_fixed'); + } + } else { + resultLabel = game.i18n.localize('VERMINE.reliability_failed'); + } + + const updates = {}; + if (mode === 'classique' && gained > 0) { + updates['system.reliability'] = Math.min(10, current + gained); + updates['system.damages.value'] = Math.max(0, damagesValue - gained); + } else if (mode === 'fortune' && fortuneFixed) { + updates['system.damages.value'] = 0; + } + if (Object.keys(updates).length) await item.update(updates); + + const skillLabel = mode === 'fortune' + ? game.i18n.localize('SKILLS.diy.name') + : game.i18n.localize(`SKILLS.${skill}.name`); + + const content = await foundry.applications.handlebars.renderTemplate( + 'systems/vermine2047/templates/reliability-repair.hbs', + { + item: { name: item.name, img: item.img }, + modeLabel: game.i18n.localize(mode === 'classique' ? 'VERMINE.reliability_repair_classic' : 'VERMINE.reliability_repair_fortune'), + skillLabel, + difficulty, + handicap, + results, + successes, + required, + resultLabel, + }, + ); + + await ChatMessage.create({ + user: game.user?._id, + speaker: this.#getSpeaker(item), + content, + }); + + return { success, gained, successes, required }; + } + + static #getSpeaker(item) { + return ChatMessage.getSpeaker({ actor: item?.actor ?? null }); + } +} diff --git a/templates/dialogs/reliability-dialog.hbs b/templates/dialogs/reliability-dialog.hbs new file mode 100644 index 0000000..e9ebae2 --- /dev/null +++ b/templates/dialogs/reliability-dialog.hbs @@ -0,0 +1,53 @@ +
+ {{#if isTest}} +
+ +
+ {{#each severities}} + + {{/each}} +
+
+ {{#if hasEtanche}} +
+ +
+ {{/if}} + {{else}} +
+ +
+ + +
+
+
+ + +
+ {{#unless hasActor}} +

{{ localize "VERMINE.reliability_need_actor" }}

+ {{/unless}} + {{/if}} + +
+ + +
+
diff --git a/templates/item/partials/physicalItems.hbs b/templates/item/partials/physicalItems.hbs index 96ba7dc..6f98550 100644 --- a/templates/item/partials/physicalItems.hbs +++ b/templates/item/partials/physicalItems.hbs @@ -38,6 +38,10 @@ +
+ + +

description

{{localize "VERMINE.sheet.description"}} diff --git a/templates/reliability-repair.hbs b/templates/reliability-repair.hbs new file mode 100644 index 0000000..163a06f --- /dev/null +++ b/templates/reliability-repair.hbs @@ -0,0 +1,21 @@ +
+
+ {{#if item.img}}{{item.name}}{{/if}} +

{{item.name}} — {{ localize "VERMINE.reliability_repair" }}

+
+
+ {{ localize "VERMINE.reliability_repair_mode" }}: {{modeLabel}} + {{ localize "VERMINE.reliability_skill" }}: {{skillLabel}} + {{ localize "VERMINE.difficulty" }}: {{difficulty}} + {{#if handicap}}{{ localize "VERMINE.handicap" }}: +{{handicap}}{{/if}} +
+
    + {{#each results}} +
  • {{this.value}}
  • + {{/each}} +
+
+ {{ localize "VERMINE.reliability_successes" }}: {{successes}} / {{required}} + {{ localize "VERMINE.reliability_result" }}: {{resultLabel}} +
+
diff --git a/templates/reliability-test.hbs b/templates/reliability-test.hbs new file mode 100644 index 0000000..c9756be --- /dev/null +++ b/templates/reliability-test.hbs @@ -0,0 +1,22 @@ +
+
+ {{#if item.img}}{{item.name}}{{/if}} +

{{item.name}} — {{ localize "VERMINE.reliability_test" }}

+
+
+ {{ localize "VERMINE.reliability_severity" }}: {{severityLabel}} + {{ localize "VERMINE.reliability" }}: {{oldReliability}} +
+
    + {{#each results}} +
  • {{this.value}}
  • + {{/each}} +
+
+ {{ localize "VERMINE.reliability_damages" }}: {{dommages}} + {{ localize "VERMINE.reliability" }}: {{oldReliability}} → {{newReliability}} + {{#if state}}{{ localize "VERMINE.reliability_state" }}: {{state}}{{/if}} +
+ {{#each traitsNotes}}

{{this}}

{{/each}} + {{#if destroyed}}

{{ localize "VERMINE.reliability_destroyed" }}

{{/if}} +