feat(traits): tâche 0 + phases 2-4 — automatisation complète des Traits

Tâche 0 :
- item.mjs : champ equipped sur items génériques + toggle fiche
- nouveau module/system/traits.mjs (helpers partagés : equippedItems, lourdMalus, mobilityHandicap, feticheItem…)

Phase 2 — Combat :
- Lourd : malus cumulés auto (Vigueur < n) dans le dialogue + pool
- Rapide : handicap (n) pré-rempli dans la défense (character + PNJ) + note carte
- Rafale : case tir en rafale (+2 difficulté), +n réussites si réussi (bonusOnSuccess)
- Portée : portée effective n × Vigueur affichée
- Maniable/Mobilité : note de rappel (dialogue + carte)
- Incapacitant : bouton « Jet de Santé (n) » sur la carte d'échange
- getLabel() : libellés caractéristiques/compétences localisés

Phase 3 — Jets d'action :
- Ponctuel : annule jusqu'à n Handicaps, consommé au jet (Traits supprimé à 0)
- Pratique : outil sélectionné +2D au lieu de +1D
- Intimidant : case « Brandit » → -1D Psychologie ou Relance 1D
- Malus : champ « Malus temporaires » manuel déduit du pool
- Durée : note « n tours » sur la carte de jet d'arme
- roll() : transmission effectiveRange/mobilityHandicap/ponctuelUsed/intimidant (corrige l'affichage Portée/Mobilité)

Phase 4 — Acteur :
- Fétiche : +1D Effort ET Sang-Froid (max dérivé, config corrigé), alerte 2+ fétiches, action « Perdre le fétiche » (-2D, max -1D persistant feticheLoss)
- Zone : note + bouton « Appliquer aux cibles de la zone » (#onApplyZone)

CSS : styles LESS pour les nouvelles classes (fetiche-block, exchange-reminder/zone, traits-reminder, tool-bonus/ponctuel, duree-note)
i18n : 29 clés fr/en
TRAITS_PLAN.md : plan complet cochée
This commit is contained in:
2026-08-07 15:30:41 +02:00
parent 8dd5d02994
commit ef01651b1d
21 changed files with 770 additions and 63 deletions
+61 -6
View File
@@ -31,6 +31,12 @@
<strong>{{localize "VERMINE.ranges"}}:</strong>
{{param.weapon.system.min_range}} / {{param.weapon.system.max_range}}
</span>
{{#if param.effectiveRange}}
<span class="weapon-detail">
<strong>{{localize "VERMINE.effective_range"}}:</strong>
{{param.effectiveRange}} m
</span>
{{/if}}
<span class="weapon-detail">
<strong>{{localize "VERMINE.ammo"}}:</strong>
{{param.weapon.system.ammo}}
@@ -48,12 +54,21 @@
{{/each}}
</div>
{{/if}}
{{#if param.weapon.system.traits.duree}}
<div class="weapon-detail duree-note"><i class="fas fa-hourglass-half"></i> {{ localize 'VERMINE.duree_note' value=param.weapon.system.traits.duree.value }}</div>
{{/if}}
</div>
{{/if}}
{{#if param.attack}}
<div class="exchange-actions" data-exchange-id="{{param.attack.id}}">
<div class="exchange-header"><i class="fas fa-exchange-alt"></i> {{localize "VERMINE.exchange"}}</div>
{{#if param.attack.rapideHandicap}}
<div class="exchange-reminder"><i class="fas fa-bolt"></i> {{ localize 'VERMINE.rapide_note' handicap=param.attack.rapideHandicap }}</div>
{{/if}}
{{#if param.attack.zoneValue}}
<div class="exchange-reminder"><i class="fas fa-burst"></i> {{ localize 'VERMINE.zone_note' value=param.attack.zoneValue }}</div>
{{/if}}
{{#each param.attack.targets}}
<div class="exchange-target">
<span class="exchange-target-name"><i class="fas fa-bullseye"></i> {{this.name}}</span>
@@ -65,9 +80,15 @@
{{else}}
<span class="exchange-passive"><i class="fas fa-shield-virus"></i> {{localize "VERMINE.passive_defense"}}</span>
{{/if}}
{{#if @root.param.weapon.system.traits.incapacitant}}
<button type="button" class="exchange-incapacitant" data-target-id="{{this.id}}" data-target-uuid="{{this.uuid}}" data-value="{{@root.param.weapon.system.traits.incapacitant.value}}" title="{{localize 'VERMINE.incapacitant_roll'}}"><i class="fas fa-bolt"></i> {{localize "VERMINE.incapacitant_roll"}} ({{@root.param.weapon.system.traits.incapacitant.value}})</button>
{{/if}}
</div>
{{/each}}
<button type="button" class="exchange-resolve" data-exchange-id="{{param.attack.id}}"><i class="fas fa-balance-scale"></i> {{localize "VERMINE.resolve"}}</button>
{{#if param.attack.zoneValue}}
<button type="button" class="exchange-zone" data-exchange-id="{{param.attack.id}}"><i class="fas fa-burst"></i> {{ localize "VERMINE.zone_apply" }}</button>
{{/if}}
</div>
{{/if}}
@@ -87,12 +108,30 @@
<span class="context-value">+{{param.handicap}}</span>
</div>
{{/if}}
{{#if param.mobilityHandicap}}
<div class="context-item">
<span class="context-label">{{localize "VERMINE.mobility"}}</span>
<span class="context-value">{{ localize 'VERMINE.traits_mobility_note' handicap=param.mobilityHandicap }}</span>
</div>
{{/if}}
{{#if verdict.bonusSuccesses}}
<div class="context-item">
<span class="context-label">{{localize "VERMINE.auto_successes"}}</span>
<span class="context-value">+{{verdict.bonusSuccesses}}</span>
</div>
{{/if}}
{{#if param.intimidant}}
<div class="context-item">
<span class="context-label">{{localize "VERMINE.intimidant"}}</span>
<span class="context-value">{{#if param.intimidant.psychology}}{{localize "VERMINE.intimidant_psychology"}}{{else}}{{localize "VERMINE.intimidant_reroll"}}{{/if}}</span>
</div>
{{/if}}
{{#if param.ponctuelUsed}}
<div class="context-item">
<span class="context-label">{{localize "VERMINE.ponctuel"}}</span>
<span class="context-value">{{ localize 'VERMINE.ponctuel_used' value=param.ponctuelUsed }}</span>
</div>
{{/if}}
{{#if param.specialtyName}}
<div class="context-item">
<span class="context-label">{{localize "VERMINE.specialty"}}</span>
@@ -142,9 +181,15 @@
{{#if param.poolBreakdown.help}}
<span class="pool-item">{{localize "VERMINE.pool_help"}} +{{param.poolBreakdown.help}}D</span>
{{/if}}
{{#if param.poolBreakdown.tooling}}
<span class="pool-item">{{localize "VERMINE.pool_tooling"}} +{{param.poolBreakdown.tooling}}D</span>
{{/if}}
{{#if param.poolBreakdown.tooling}}
<span class="pool-item">{{localize "VERMINE.pool_tooling"}} +{{param.poolBreakdown.tooling}}D</span>
{{/if}}
{{#if param.poolBreakdown.tempMalus}}
<span class="pool-item pool-malus">{{localize "VERMINE.pool_temp_malus"}} -{{param.poolBreakdown.tempMalus}}D</span>
{{/if}}
{{#if param.poolBreakdown.psychology}}
<span class="pool-item pool-malus">{{localize "VERMINE.pool_psychology"}} -{{param.poolBreakdown.psychology}}D</span>
{{/if}}
{{#if param.poolBreakdown.group}}
<span class="pool-item">{{localize "VERMINE.pool_group"}} +{{param.poolBreakdown.group}}D</span>
{{/if}}
@@ -160,9 +205,19 @@
{{#if param.poolBreakdown.domainBonus}}
<span class="pool-item">{{#ifgt param.poolBreakdown.domainBonus 0}}{{localize "VERMINE.domain_bonus"}}{{else}}{{localize "VERMINE.domain_penalty"}}{{/ifgt}} {{param.poolBreakdown.domainBonus}}D</span>
{{/if}}
{{#if param.poolBreakdown.malus}}
<span class="pool-item pool-malus">{{localize "VERMINE.pool_malus"}} -{{param.poolBreakdown.malus}}D</span>
{{/if}}
{{#unless param.poolBreakdown.wound}}
{{#unless param.poolBreakdown.lourd}}
{{#if param.poolBreakdown.malus}}
<span class="pool-item pool-malus">{{localize "VERMINE.pool_malus"}} -{{param.poolBreakdown.malus}}D</span>
{{/if}}
{{/unless}}
{{/unless}}
{{#if param.poolBreakdown.wound}}
<span class="pool-item pool-malus">{{localize "VERMINE.pool_wound"}} -{{param.poolBreakdown.wound}}D</span>
{{/if}}
{{#if param.poolBreakdown.lourd}}
<span class="pool-item pool-malus">{{localize "VERMINE.pool_lourd"}} -{{param.poolBreakdown.lourd}}D</span>
{{/if}}
<span class="pool-item pool-total">{{localize "VERMINE.pool_total"}} {{param.poolBreakdown.total}}D</span>
</div>
</div>