feat(rules): sunder deals real weapon damage vs object hardness/hp; broken weapons usable at -2 with restricted crits

SRD Sunder + CRB 'Smashing an Object' / 'Conditions - Broken': weapons
carry Table 7-12 object stats (AttackSpec.hardness/hit_points/enhancement,
defaults by weapon class); a successful sunder deals the attacker's actual
physical weapon damage minus the target weapon's hardness, subtracted from
its hp. At <= half hp the weapon gains the broken condition - still usable
at -2 attack/damage, crits only on a natural 20 at x2. At <= 0 it is
destroyed (weapon_destroyed, unusable). The old flat str_mod+2 / durability
10 / synthetic 'disarmed' condition is gone. Firearm misfire carve-out kept
(broken firearms stay unusable until Quick Clear - misfire escalation not
modeled, documented).
This commit is contained in:
2026-09-20 15:43:45 +02:00
parent 544d870688
commit 74f5d64c43
6 changed files with 482 additions and 159 deletions
+32 -14
View File
@@ -1526,10 +1526,22 @@ Règles modélisées :
naturel réussit **toujours** à l'escape d'un grapple (« Rolling a natural
20 while attempting a combat maneuver is always a success (except when
attempting to escape from bonds) » — un grapple n'est pas un lien), le 1
naturel échoue toujours. Un sunder endommage l'**arme**, pas les PV : `str_mod + 2`
de dégâts à l'arme, qui se brise à 10 d'usure cumulée (`_WEAPON_DURABILITY`) →
`disarmed` ; une arme brisée est exclue de `usable_attacks()` et réparable via
`Action(kind="repair_weapon")`. overrun →
naturel échoue toujours. Un sunder endommage l'**arme** comme un OBJET, pas
les PV (SRD « Sunder » / CRB « Smashing an Object ») : les dégâts réels de
l'arme de l'attaquant (composantes physiques + bonus plat ; une arme brisée
frappe à −2), moins la **dureté** de l'arme cible, sont retranchés de ses
**points de vie d'objet**. Chaque arme porte donc dureté/pv d'objet
(`AttackSpec.hardness`/`hit_points`, défauts de la Table 7-12 par classe
d'arme : lame en acier 10/5 une main, 10/10 deux mains ; arme emmanchée
bois 5/5 et 5/10 ; arme de jet 5/5 ; `enhancement` ajoute +2 de dureté et
+10 pv par +1). À **pv ≤ moitié**, l'arme gagne la condition **brisée** :
elle reste **utilisable** à **−2 aux jets d'attaque et de dégâts**, ne
menace de critique que sur le **20 naturel** et ne fait que **×2** (CRB
« Broken »). À **pv ≤ 0**, l'arme est **détruite** (`weapon_destroyed`) :
excluante de `usable_attacks()`. Simplification documentée : l'option SRD
« réduire à 1 pv au lieu de détruire » n'est pas offerte (le moteur
détruit toujours). Une arme brisée (non détruite) est réparable via
`Action(kind="repair_weapon")` ; une arme détruite ne l'est pas. overrun →
passage au travers si la case au-delà est libre, et `prone` 1 round
**seulement si le jet dépasse le CMD de 5 ou plus** (conformance R3 — CRB
« Overrun » : « If your attack exceeds your opponent's CMD by 5 or more,
@@ -1640,12 +1652,17 @@ Règles modélisées :
RAW « as part of a move action to clear all firearms » n'est pas modélisée
(un seul firearm par deed), et Quick Clear ne répare que le broken issu
d'un misfire — le broken d'un sunder se répare via `repair_weapon`.
Le misfire lui-même (Ultimate Combat « Firearm Rules — Misfires » : « When
a firearm misfires, it gains the broken condition ») : une attaque d'arme à
feu (`firearm: true`) sur un **1 naturel** casse l'arme (`weapon_broken`,
journalisé « MISFIRE (broken) ») — valeur de misfire minimale 1 ; la
progression de la valeur de misfire et l'explosion des early firearms
re-cassées ne sont pas modélisées (une arme brisée ne peut plus tirer ici)),
Le misfire lui-même (Ultimate Combat « Firearm Rules — Misfires » : « When
a firearm misfires, it gains the broken condition ») : une attaque d'arme à
feu (`firearm: true`) sur un **1 naturel** casse l'arme (`weapon_broken`,
journalisé « MISFIRE (broken) ») — valeur de misfire minimale 1 ; la
progression de la valeur de misfire et l'explosion des early firearms
re-cassées ne sont pas modélisées. Interaction avec la règle « Broken » :
une arme de mêlée brisée reste utilisable à −2, mais une **arme à feu
brisée reste exclue** de `usable_attacks()` (le SRD la laisserait tirer à
−2 avec une valeur de misfire majorée de 4 — cette progression n'étant
pas modélisée, le moteur interdit prudemment de tirer avec un pistolet
enrayé jusqu'à Quick Clear ou `repair_weapon`),
`inspire_courage` + `spell_combat` (misty — Spell Combat : action de round
complet, incante un sort standard et porte toutes ses attaques de mêlée à
**−2** (CRB Magus, conformance — la pénalité s'applique à chaque jet
@@ -1685,7 +1702,7 @@ Règles modélisées :
state) -> tuple[Action, ...]`). Schéma enrichi (E1-E5) :
- Par combattant : id, side, pos, occupied_cells, hp/hp_max, active/dead,
dying/stabilized, conditions (noms + rounds_left), resources_left (+ `spell_slot_{level}`),
weapon_broken/weapon_stolen/weapon_dropped, grappled_with, moved_this_turn, power_attack,
weapon_broken/weapon_destroyed/weapon_stolen/weapon_dropped, grappled_with, moved_this_turn, power_attack,
name, level, size, natural_reach_ft (S4c : allonge naturelle du gabarit
en pieds — 0 pour Tiny/Diminutive/Fine, 5 pour Small/Medium, 10 pour
Large… ; l'allonge effective d'une attaque reste `max(allonge naturelle,
@@ -1702,7 +1719,7 @@ Règles modélisées :
fraîche), casting_ability ou None pour non-jeteur
(E3), abilities {str/dex/con/int/wis/cha: score brut} (Medium), skills
{nom: {rank, class_skill, armor_penalty}} uniquement rank > 0 (Medium),
metamagic_feats (tuple trié), weapon_damage {weapon_id: dégâts courants},
metamagic_feats (tuple trié), weapon_damage {weapon_id: dégâts cumulés au-delà de la dureté},
summon_duration (int ou None), immediate_used, deed_up_close_and_deadly
(flags actuels), active_buffs {source, rounds_left, mods: tuple de
{target, value, bonus_type}} (E5), speed_land_ft, speed_fly_ft,
@@ -1710,8 +1727,9 @@ Règles modélisées :
en pieds), ac {total,
touch, flat_footed}, saves {fort, ref, will}, cmb, cmd, attacks
(référentiel complet : id, name, kind, attack_bonus, damage, damage_bonus,
crit_range, crit_mult, reach_ft, range_increment_ft, count, firearm —
y compris les armes broken/stolen), features (noms des capacités),
crit_range, crit_mult, reach_ft, range_increment_ft, count, firearm,
hardness, hit_points (stats d'objet effectives, Table 7-12) —
y compris les armes broken/destroyed/stolen), features (noms des capacités),
feature_details (C4 : tuple de {name, category, source_detail, effects:
tuple de {target, value, bonus_type, condition, weapon_filter}}),
spells (résumés enrichis du registre : name, level, school, range_ft,