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
+19
View File
@@ -19,6 +19,12 @@
<strong>{{localize "VERMINE.ranges"}}:</strong>
{{ weapon.system.min_range }} / {{ weapon.system.max_range }}
</span>
{{#if effectiveRange}}
<span class="weapon-detail">
<strong>{{localize "VERMINE.effective_range"}}:</strong>
{{ effectiveRange }} m
</span>
{{/if}}
<span class="weapon-detail">
<strong>{{localize "VERMINE.ammo"}}:</strong>
{{ weapon.system.ammo }}
@@ -29,6 +35,13 @@
<h4 class="combat-mode-label">{{#ife mode "ranged"}}{{localize 'VERMINE.attack_ranged'}}{{else}}{{localize 'VERMINE.attack_contact'}}{{/ife}}</h4>
{{#if lourdMalus}}
<p class="traits-reminder"><i class="fas fa-weight-hanging"></i> {{ localize 'VERMINE.lourd_malus_note' malus=lourdMalus }}</p>
{{/if}}
{{#if mobilityNote}}
<p class="traits-reminder"><i class="fas fa-shoe-prints"></i> {{ mobilityNote }}</p>
{{/if}}
<div class="dice-pool">
<!-- ATTACKER POOL -->
@@ -90,6 +103,12 @@
<span class="label">{{localize 'VERMINE.consume_ammo'}}</span>
</label>
{{/if}}
{{#if hasRafale}}
<label class="flexrow bonus-item">
<input type="checkbox" data-roll="true" name="rafale" id="rafale" value="1" />
<span class="label">{{ localize 'VERMINE.rafale_check' rafaleValue=rafaleValue }}</span>
</label>
{{/if}}
<div class="flexcol handicap-section">
<label class="label" for="handicap">{{localize 'VERMINE.handicap'}}</label>
<select class="info-value" data-roll="true" data-dtype="String" type="number"
+27 -2
View File
@@ -236,7 +236,7 @@
<!-- TOOLS -->
<div class="flexrow bonus-item full-width">
<label class="label">{{localize 'VERMINE.tooling'}} (+1D)</label>
<label class="label">{{localize 'VERMINE.tooling'}} (+1D / +2D)</label>
<div class="item-list grid grid-4col">
<label>
<input
@@ -258,12 +258,37 @@
id="usingTools"
value="{{item.name}}"
/>
<i>{{item.name}}</i>
<i>{{item.name}}{{#if item.system.traits.pratique}} <em class="tool-bonus">+2D</em>{{/if}}{{#if item.system.traits.ponctuel}} <em class="tool-ponctuel">P{{item.system.traits.ponctuel.value}}</em>{{/if}}</i>
</label>
{{/each}}
</div>
</div>
<!-- INTIMIDANT -->
{{#if hasIntimidant}}
<div class="flexrow bonus-item full-width">
<input type="checkbox" data-roll="true" name="intimidant" id="intimidant" value="1" />
<label class="label" for="intimidant">{{ localize 'VERMINE.intimidant_check' intimidantName=intimidantName }}</label>
</div>
{{/if}}
<!-- TEMPORARY MALUS -->
<div class="flexrow bonus-item full-width">
<label class="label" for="temporary-malus">{{localize 'VERMINE.temporary_malus'}}</label>
<input
type="number"
data-roll="true"
class="numeric-entry"
style="text-align: center;"
name="temporary-malus"
id="temporary-malus"
min="0"
max="5"
value="0"
/>
<span>D</span>
</div>
<!-- TOTEMS -->
{{#ifgt @root.actor.system.adaptation.totems.human.value 0}}
{{#ifgt @root.actor.system.adaptation.totems.adapted.value 0}}