feat(creature): ajustements manuels des valeurs calculées

Permet les disparités entre créatures de même Gabarit/Taille (ex. un
sanglier avec une Protection supérieure à celle d'un chien, un loup plus
vigoureux). Champ system.adjustments (9 stats) : valeur finale = base
dérivée + ajustement (jamais négative), persisté indépendamment des
niveaux. Section « Ajustements » éditable dans l'onglet Stats de la
fiche (mode édition).
This commit is contained in:
2026-08-09 20:33:35 +02:00
parent be43913ae3
commit d63eeda299
5 changed files with 127 additions and 0 deletions
+4
View File
@@ -143,6 +143,7 @@
"rerolls": "Rerolls",
"contact": "Contact",
"reaction": "Reaction",
"reaction_bonus": "Reaction bonus",
"pools": "Reserves",
"gear": "Gear",
"protection": "Protection",
@@ -390,6 +391,9 @@
"die_adapted": "adapted",
"die_successes": "successes",
"total": "Total",
"stat": "Stat",
"adjustment": "Adjustment",
"adjustments": "Adjustments",
"totem_dice": "Totem Dice",
"totem_hint": "Check to use totem dice (double success possible)",
"totem_neutral": "Neutral",
+4
View File
@@ -143,6 +143,7 @@
"rerolls": "Relances",
"contact": "Contact",
"reaction": "Réaction",
"reaction_bonus": "Bonus de Réaction",
"pools": "Réserves",
"gear": "Matériel",
"gear_hindrance": "Handicap Matériel",
@@ -371,6 +372,9 @@
"no_group": "Sans groupe",
"include_in_phase": "Inclure dans cette phase",
"total": "Total",
"stat": "Statistique",
"adjustment": "Ajustement",
"adjustments": "Ajustements",
"bonuses": "Bonus",
"handicap": "Handicap",
"score": "Score",
+27
View File
@@ -208,4 +208,31 @@
}
}
// ── Ajustements manuels des valeurs calculées ────────────────────────
.creature-adjustments {
width: 100%;
border-collapse: collapse;
margin-top: 4px;
th, td {
padding: 2px 8px;
border-bottom: 1px solid @color-border-dark-3;
font-size: @font-size-12;
text-align: left;
}
th { text-transform: uppercase; }
td:nth-child(2) {
width: 80px;
input {
width: 100%;
text-align: center;
}
}
td:nth-child(3) { text-align: center; }
}
}
+28
View File
@@ -65,6 +65,22 @@ export default class VermineCreatureData extends foundry.abstract.TypeDataModel
protection: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 1 })
}),
// Ajustements manuels des valeurs calculées : permettent les disparités
// entre créatures de même Gabarit/Taille (ex. un sanglier avec une
// Protection supérieure à celle d'un chien, un loup plus vigoureux).
// Base dérivée + ajustement = valeur finale (jamais négative).
adjustments: new fields.SchemaField({
attack: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
damage: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
vigor: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
reaction: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
reactionBonus: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
pools: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
gear: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
gearHindrance: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 }),
protection: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0 })
}),
// Équipement
equipment: equipmentSchema()
}
@@ -145,6 +161,18 @@ export default class VermineCreatureData extends foundry.abstract.TypeDataModel
// Protection
this.computed.protection = roleConfig.protection || 1
// Ajustements manuels (base + modificateur), plancher à 0.
const adj = this.adjustments ?? {}
this.computed.attack = Math.max(0, this.computed.attack + (adj.attack ?? 0))
this.computed.damage = Math.max(0, this.computed.damage + (adj.damage ?? 0))
this.computed.vigor = Math.max(0, this.computed.vigor + (adj.vigor ?? 0))
this.computed.reaction = Math.max(0, this.computed.reaction + (adj.reaction ?? 0))
this.computed.reactionBonus = Math.max(0, this.computed.reactionBonus + (adj.reactionBonus ?? 0))
this.computed.pools = Math.max(0, this.computed.pools + (adj.pools ?? 0))
this.computed.gear = Math.max(0, this.computed.gear + (adj.gear ?? 0))
this.computed.gearHindrance = Math.max(0, this.computed.gearHindrance + (adj.gearHindrance ?? 0))
this.computed.protection = Math.max(0, this.computed.protection + (adj.protection ?? 0))
}
/**
+64
View File
@@ -71,4 +71,68 @@
</ul>
</div>
</section>
{{!-- Ajustements manuels des valeurs calculées (disparités entre créatures
de même gabarit : base dérivée + modificateur = valeur finale) --}}
{{#if @root.isEditMode}}
<section class="mdb">
<h4 class="align-center">{{ localize 'VERMINE.adjustments' }}</h4>
<table class="creature-adjustments">
<thead>
<tr>
<th>{{ localize 'VERMINE.stat' }}</th>
<th>{{ localize 'VERMINE.adjustment' }}</th>
<th>{{ localize 'VERMINE.total' }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ localize 'VERMINE.total_attack' }}</td>
<td><input type="number" name="system.adjustments.attack" value="{{system.adjustments.attack}}" data-dtype="Number" /></td>
<td>{{ system.computed.attack }}D</td>
</tr>
<tr>
<td>{{ localize 'ADVERSITY.damage' }}</td>
<td><input type="number" name="system.adjustments.damage" value="{{system.adjustments.damage}}" data-dtype="Number" /></td>
<td>{{ system.computed.damage }}</td>
</tr>
<tr>
<td>{{ localize 'ADVERSITY.vigor' }}</td>
<td><input type="number" name="system.adjustments.vigor" value="{{system.adjustments.vigor}}" data-dtype="Number" /></td>
<td>{{ system.computed.vigor }}D</td>
</tr>
<tr>
<td>{{ localize 'ADVERSITY.reaction' }}</td>
<td><input type="number" name="system.adjustments.reaction" value="{{system.adjustments.reaction}}" data-dtype="Number" /></td>
<td>{{ system.computed.reaction }}D{{#ifgt system.computed.reactionBonus 0}}+{{system.computed.reactionBonus}}{{/ifgt}}</td>
</tr>
<tr>
<td>{{ localize 'ADVERSITY.reaction_bonus' }}</td>
<td><input type="number" name="system.adjustments.reactionBonus" value="{{system.adjustments.reactionBonus}}" data-dtype="Number" /></td>
<td>{{ system.computed.reactionBonus }}</td>
</tr>
<tr>
<td>{{ localize 'ADVERSITY.pools' }}</td>
<td><input type="number" name="system.adjustments.pools" value="{{system.adjustments.pools}}" data-dtype="Number" /></td>
<td>{{ system.computed.pools }}D</td>
</tr>
<tr>
<td>{{ localize 'ADVERSITY.gear' }}</td>
<td><input type="number" name="system.adjustments.gear" value="{{system.adjustments.gear}}" data-dtype="Number" /></td>
<td>{{ system.computed.gear }}</td>
</tr>
<tr>
<td>{{ localize 'ADVERSITY.gear_hindrance' }}</td>
<td><input type="number" name="system.adjustments.gearHindrance" value="{{system.adjustments.gearHindrance}}" data-dtype="Number" /></td>
<td>{{ system.computed.gearHindrance }}</td>
</tr>
<tr>
<td>{{ localize 'ADVERSITY.protection' }}</td>
<td><input type="number" name="system.adjustments.protection" value="{{system.adjustments.protection}}" data-dtype="Number" /></td>
<td>{{ system.computed.protection }}</td>
</tr>
</tbody>
</table>
</section>
{{/if}}
</div>