diff --git a/README.md b/README.md index 00e4113..54e0432 100644 --- a/README.md +++ b/README.md @@ -1218,7 +1218,7 @@ Règles modélisées : (`_expire_summons` décrémente puis retire). - Conditions effectives : 28 conditions prédéfinies (`conditions.py`). Leurs drapeaux comportementaux sont appliqués par le moteur : `cant_act` (étourdi, paralysé, dazed, - endormi, inerme, fasciné) annule le tour ; `cant_attack` (nauséeux) n'autorise qu'une unique action + endormi, inerme, fasciné) annule le tour ; `cant_attack` (nauséeux, épinglé) n'autorise qu'une unique action de mouvement — conformance L9 (SRD « Conditions — Nauseated ») : « The only action such a character can take is a single move actions per turn » — seuls les vraies actions de mouvement (`move`, `stand_up`, `retrieve_weapon`, @@ -1242,7 +1242,11 @@ Règles modélisées : désormais réellement aux compétences de Dexterity (Acrobaties, Escalade, Équilibre, Évasion, Vol, Équitation, Manipulation de corde, Discrétion, Natation, Désamorçage — conformance P2) —, −2 attaque/CA/Réflexes, sans - déplacement ni AoO. Épinglé : même −4 `dex_skills`. + déplacement ni AoO. Épinglé : même −4 `dex_skills`, et `cant_attack` — un + épinglé ne peut pas attaquer (SRD « Conditions — Pinned » : il « peut + seulement tenter de se libérer ») ; lacune documentée : le moteur ne pose + **jamais** `pinned` (pas de boucle de maintien du grapple), la condition + n'est atteignable que par injection directe. Aveuglé (conformance P2) : −2 CA, perte du bonus de Dextérité à la CA, −4 aux compétences de Dexterity (`dex_skills`) et **aucun malus plat d'attaque** — la pénalité RAW est la dissimulation totale (50 % d'échec, @@ -1271,7 +1275,9 @@ Règles modélisées : ennemi, une seule si en allonge ; sinon le tour est perdu, journalisé). Simplification documentée : la clause « si elle est blessée, riposte l'agresseur » est réduite à « attaque la créature la plus proche » ; le coup - de grâce n'est pas modélisé. + de grâce n'est pas modélisé. Une créature confuse ne fait **aucune** + attaque d'opportunité (`cant_aoo`) — simplification de la clause SRD « not + already devoted to attacking », le moteur n'ayant pas ce concept. - Manœuvres de combat : trip, disarm, bull_rush, sunder, grapple, escape, overrun, dirty trick, steal, reposition et drag sont modélisées, chacune comme une tentative unique (1d20 + CMB contre CMD) : le jet de manœuvre est @@ -1326,7 +1332,10 @@ Règles modélisées : your attack exceeds your opponent's CMD you can push the target back an additional 5 feet » — `1 + marge//5` cases, stoppées au premier obstacle (un 20 naturel sous le CMD ne donne que la poussée de base) ; - grapple → `grappled`/`pinned` ; conformance L8 (SRD « Grapple ») : « If + grapple → `grappled` uniquement (la boucle de maintien du grapple et + l'application de `pinned` sont hors périmètre du moteur — la définition + de la condition `pinned` est conforme au SRD, mais elle n'est jamais + posée par le moteur lui-même) ; conformance L8 (SRD « Grapple ») : « If you successfully grapple a creature that is not adjacent to you, move that creature to an adjacent open space (if no space is available, your grapple fails) » — une réussite à distance **tire la cible** sur la case diff --git a/src/pf1e_simulator/abilities.py b/src/pf1e_simulator/abilities.py index c120b1a..949be61 100644 --- a/src/pf1e_simulator/abilities.py +++ b/src/pf1e_simulator/abilities.py @@ -37,7 +37,10 @@ class AbilitySpec: # ── Passive combat feats ───────────────────────────────────────────────────── -# Weapon Focus: +1 attack with a specific weapon (untyped, CRB) +# Weapon Focus: +1 attack with the named weapon GROUP (untyped, CRB) — the +# filter matches a weapon name case-insensitively as a substring (the engine +# resolves it in CombatEngine._weapon_filter_matches), so "Pistol" covers +# sheets that name individual pistols (e.g. "... (pistolet, masterwork)"). def weapon_focus(weapon_name: str) -> AbilitySpec: return AbilitySpec( name=f"Weapon Focus ({weapon_name})", diff --git a/src/pf1e_simulator/combat.py b/src/pf1e_simulator/combat.py index 505aca7..76ec879 100644 --- a/src/pf1e_simulator/combat.py +++ b/src/pf1e_simulator/combat.py @@ -2571,8 +2571,10 @@ class CombatEngine: """Collect all StatModifiers for ``target`` from all sources. ``weapon_name`` filters out modifiers with a ``weapon_filter`` that - doesn't match (e.g. Weapon Focus (Pistol) only applies to "Pistol"). - Modifiers without a ``weapon_filter`` are always included. + doesn't match (e.g. Weapon Focus (Pistol) only applies to weapons + whose name contains "Pistol", case-insensitively — see + ``_weapon_filter_matches``). Modifiers without a ``weapon_filter`` + are always included. Modifiers whose ``condition`` is set are only included when the named runtime condition holds for ``state`` (evaluated via