Compare commits

...

31 Commits

Author SHA1 Message Date
ctan 4b4e6f2726 fix(rules): stabilize a dying creature when healed
PF1e (CRB, Stable Characters and Recovery): any healing that cures a
dying creature of even 1 point makes it stable. _apply_heal_effect and
_channel_heal now set stabilized_hp when the healed hp stays negative,
so the creature stops losing 1 hp per round.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 10:35:44 +02:00
ctan e8cca954d0 docs(rules): document out-of-scope limitations
Record the three limitations deliberately left out of the L1-L10 conformance pass in the README: no surprise round (the combatant model has no awareness field), one_round casting clamped to a full-round action (no pending-cast state across turns), and Tiny/Diminutive/Fine reach and co-occupancy abstracted to the 5-ft grid.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 10:02:45 +02:00
ctan 1363bb7f06 fix(rules): consume the current turn's swift for an in-turn immediate
PF1e (SRD Immediate Actions): "Using an immediate action on your turn is the same as using a swift action and counts as your swift action for that turn." The engine now tracks the acting combatant (_turn_actor); an immediate fired during its OWN turn sets swift_used_this_turn instead of immediate_used, so swift actions later in the turn's sequence are dropped (downgraded:immediate_swift) and no second immediate fires that round, while the next turn's swift stays free. Off-turn immediates keep consuming the next swift. The off-turn consumption test was retargeted to a true off-turn event and an in-turn test added; README updated (Actions immediates + budget classification).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 10:00:25 +02:00
ctan dde6bc1f5d fix(rules): restrict nauseated creatures to a single move action
PF1e (SRD Conditions, nauseated): "The only action such a character can take is a single move actions per turn." _NAUSEA_MOVE_KINDS now holds only genuine move actions (move, stand_up, retrieve_weapon, repair_weapon): the 5-foot step and dropping prone are free actions and are dropped by the nauseated filter. The pinned filter test was retargeted; README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 09:44:53 +02:00
ctan 49aa79d612 fix(rules): restrict maneuvers to targets within one size category
PF1e (SRD Trip / Bull Rush / Overrun): "You can only [affect] an opponent who is no more than one size category larger than you." _execute_maneuver now rejects trip, bull_rush and overrun against a target two or more size categories larger: no roll, no provoked AoO, logged rejection. A _SIZE_ORDER ranking (Fine..Colossal, unknown -> Medium) backs the check; other maneuvers keep no size cap. README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 09:40:50 +02:00
ctan 1b60cd049b fix(rules): apply maneuver failure consequences
PF1e (SRD Trip): "If your attack fails by 10 or more, you are knocked prone instead" - a trip whose total lands at CMD-10 or below now knocks the attacker prone (1 round). PF1e (SRD Overrun): "If your overrun attempt fails, you stop in the space directly in front of the opponent, or the nearest open space in front of the creature" - a failed overrun from beyond adjacency walks the attacker to the free approach cell nearest the target; an already-adjacent attacker stays put. README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 09:34:57 +02:00
ctan 346e300eab fix(rules): scale the bull rush push distance with the margin
PF1e (SRD Bull Rush): "your target is pushed back 5 feet. For every 5 by which your attack exceeds your opponent's CMD you can push the target back an additional 5 feet." _bull_rush_push (and the explicit-direction branch) now walk 1 + margin//5 cells, stopping at the first obstacle; a natural-20 auto-success below CMD floors the margin at 0 (base push only). README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 09:27:03 +02:00
ctan 2f00d76ecc fix(rules): allow movement through friendly squares
PF1e (SRD Movement, Position and Distance): "You can move through a square occupied by a friendly character, unless you are charging." The move and run descents now route their Dijkstra cost field and greedy steps over hostile-only blocking (_blocked_hostile), so allies' squares are passable; a friendly square may only be entered when a free cell descends from it and the path tail is trimmed, so movement never ENDS on an occupied cell. Charge, withdraw, the auto 5-foot step and the Observation cost fields keep full blocking (documented). Corridor tests added; the Combat Reflexes multi-AoO transcript is unchanged. README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 09:18:29 +02:00
ctan faa8a72a86 fix(rules): let a natural 20 auto-succeed on escape
PF1e (SRD Combat Maneuvers): "Rolling a natural 20 while attempting a combat maneuver is always a success (except when attempting to escape from bonds)" - escaping a grapple is a combat maneuver, not bonds. _maneuver_escape now auto-succeeds on a natural 20 below CMD (the natural 1 auto-failure is unchanged). README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 08:58:11 +02:00
ctan c96579a485 fix(rules): forbid a diagonal 5-foot step past a corner
PF1e (SRD Measuring Distance): "You can't move diagonally past a corner (even by taking a 5-foot step)." _step5_to now rejects a diagonal destination whose two flanking squares are not both passable, reusing Grid.diagonal_allowed - the same corner rule the regular movement already applies. README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 08:54:36 +02:00
ctan 98b61c6cf8 fix(rules): add AC bonuses and flat-footed Dexterity to CMD
PF1e (SRD Combat Maneuver Defense): "A creature can also add any circumstance, deflection, dodge, insight, luck, morale, profane, and sacred bonuses to AC to its CMD [...] A flat-footed creature does not add its Dexterity bonus to its CMD." _maneuver_cmd now sums the target's eligible AC bonus modifiers (plus the dodge/circumstance runtime bonuses from total defense, fight defensively and aid another) and drops the Dexterity bonus (keeping any penalty) while the target denies its Dexterity to AC. README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 08:49:46 +02:00
ctan 47010c6e00 fix(rules): use Dexterity for the CMB of Tiny and smaller creatures
PF1e (SRD Combat Maneuvers): "Creatures that are size Tiny or smaller use their Dexterity modifier in place of their Strength modifier to determine their CMB." _maneuver_cmb now swaps Str for Dex when the size is Tiny, Diminutive or Fine. True 0-reach and co-occupancy for Tiny-or-smaller stay unmodelled (5-ft grid abstraction), documented in the README.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-12 08:44:44 +02:00
ctan 9d583a04c0 fix(rules): only total concealment blocks sneak attack
PF1e (CRB rogue Sneak Attack): "A rogue cannot sneak attack while
striking a creature with total concealment." _sneak_attack_dice now gates
on miss_chance >= 50 instead of any concealment > 0, so a blurred (20%)
target can still be sneak attacked while a displaced (50%) one cannot. The
test that pinned the old any-concealment denial was retargeted to total
concealment and a partial-concealment case added; README updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 23:41:06 +02:00
ctan a2825e73cc fix(rules): apply the power attack penalty to melee touch attacks
PF1e (CRB Power Attack): "take a -1 penalty on all melee attack rolls ...
The bonus damage does not apply to touch attacks." A melee touch (kind
"touch", no range increment) is a melee attack, so _power_attack_amt now
rides its attack and confirmation rolls; the +2X/+3X damage bonus stays
gated on kind == "melee". Ranged attacks and rays are unaffected. The
test that pinned the old melee-weapon-only simplification was rewritten to
lock the corrected behavior; README and abilities.py updated.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 23:35:07 +02:00
ctan 8a8b813889 fix(rules): pick the best target square for melee cover
PF1e (CRB Cover, Big Creatures and Cover): when making a melee attack
against a multi-square creature you can pick any of the squares it
occupies to determine cover. has_cover_cells/cover_bonus_cells now
aggregate the target side by the MINIMUM over target cells for melee and
keep the maximum (any line to any corner) for ranged; the attacker-side
minimum is unchanged. 1x1 geometry is bit-identical; no data case changes
today, locked by a unit test (Large target: melee 0, ranged +4).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 23:29:59 +02:00
ctan 843cbf881c fix(rules): suppress attacks of opportunity through cover or total concealment
PF1e (CRB Cover): "You can't execute an attack of opportunity against an
opponent with cover relative to you"; (CRB Concealment): the same holds
against total concealment. _resolve_aoo now checks terrain cover
(cover_bonus_cells, melee line) and miss_chance >= 50 before striking,
logs the suppression and leaves the per-round budget unspent. Partial
concealment (blurred 20%) and normal attacks are unaffected.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 23:23:11 +02:00
ctan be2a755d17 fix(rules): stop damage reduction from eating energy damage
PF1e (CRB Damage Reduction): "Damage reduction does not negate ...
energy damage dealt along with an attack." _resolve_hit_damage now
splits the post-crit total and applies DR only to the non-energy share
(physical dice + flat bonuses + precision dice); energy components are
reduced solely by the per-component energy resistance/immunity step.
DR-bypass semantics (multi-component "and" requires every component)
are unchanged. Pure-physical weapons keep bit-identical arithmetic and
the golden transcripts are untouched.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 23:17:34 +02:00
ctan 1862c22b7b fix(rules): apply maneuver AoO damage as a penalty to the maneuver
PF1e (CRB Combat Maneuvers): "If you are hit by the target, you take the
damage normally and apply that amount as a penalty to the attack roll to
perform the maneuver." Capture the provoked AoO's damage in
_execute_maneuver and subtract it from the check total (floored at 0;
natural 20 still succeeds, natural 1 still fails; dropping below 0 hp
still forfeits). Escape and the Improved-feat exemption are untouched.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 23:11:57 +02:00
ctan 74bfeb5414 fix(rules): allow one movement opportunity per opponent per round
PF1e (CRB Attacks of Opportunity): moving out of more than one square
threatened by the same opponent in the same round counts as one
opportunity for that opponent. Track per-round movement provocation in
_move_aoo_provoked (cleared with _aoo_used at round start); the stand-up
trigger passes movement=False and still provokes. Ranged, casting and
maneuver triggers are untouched.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 23:08:11 +02:00
ctan 5568e0f8af fix(rules): knock prone only on a 5-point overrun margin
PF1e CRB 'Overrun': 'If your maneuver is successful, you move through
the target's space. If your attack exceeds your opponent's CMD by 5 or
more, ... the target is knocked prone.' The engine knocked the target
prone on ANY success. A plain success (margin 0-4) now only moves the
attacker through; prone requires total - CMD >= 5 (_OVERRUN_PRONE_MARGIN).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 22:22:57 +02:00
ctan b453b19be2 fix(rules): stop a run from crossing difficult terrain
PF1e CRB 'Movement, Position and Distance - Difficult Terrain': 'You
can't run or charge across difficult terrain.' The run action reused the
move machinery (_descend_path), so it crossed rubble at 2x cost within
the 4x budget. The descent now takes an avoid_difficult option that
refuses every step whose footprint would touch a cell with move cost > 1
(the same rejection charge applies in _charge_path_clear); the run
moves up to the obstacle and stops there (deterministic, documented).
Move and charge behavior are unchanged.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 22:16:54 +02:00
ctan 4d89305881 fix(rules): distinguish natural reach from reach weapons
PF1e CRB 'Big and Little Creatures in Combat': a creature's natural
reach is a disk (a Large creature still threatens and strikes adjacent
squares), while a reach weapon doubles the wielder's natural reach but
'can't strike at their natural reach or less' (a ring whose dead zone is
the natural reach). The engine keyed the ring off reach_ft > 5, so
reach-10 natural attacks (giant belostomatid bite/claw, mounted
hooves) wrongly got a 5-ft dead zone.

AttackSpec gains reach_weapon (parsed from the combatant JSON); the
disk-vs-ring rule is centralized in _melee_reach_zone_cells and applied
consistently to weapon selection, melee usability, threatened squares
and charge end placement. Esha's Lance is the only reach weapon in the
shipped data; Large natural attackers keep the default (disk).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 22:06:46 +02:00
ctan 4f6b076a49 fix(rules): exempt retrieve and repair weapon from the disabled hit-point cost
PF1e (CRB, Disabled): a disabled creature can take move actions without further injuring itself. retrieve_weapon and repair_weapon are budget-classified move actions (_ACTION_ECONOMY_MOVE_KINDS) but were absent from _DISABLED_MOVE_KINDS, so a creature at 0 hp paid 1 hp to draw or mend a weapon. Added both kinds to the exempt set.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 21:22:03 +02:00
ctan fa01ed74c5 fix(rules): stop delay from double-processing the turn start
A freshly-delayed combatant is re-inserted into the round order and _take_turn runs a second time in the same round. That second pass re-ran _decrement_durations and _turn_gate, double-ticking bleed, double-decrementing buff/condition durations and re-firing the fear aura. The start-of-turn block is now skipped when delayed_this_round is already set at entry (cleared at round start, set only by a delay action); the delayed turn still gets its policy call, budget and execution.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 21:15:14 +02:00
ctan 1b5cac234e fix(rules): tick bleed and auto-fail stabilization for a dying creature
PF1e (CRB, Stable Characters and Recovery): characters taking continuous damage such as bleed automatically fail all Constitution checks made to stabilize, losing 1 hp per round in addition to the continuous damage. _process_dying never applied bleed (only _turn_gate, reached by active creatures did), so a bleeding dying creature lost 0 hp per round. It now ticks bleed_damage at the start of the dying turn and auto-fails the check (no d20 consumed), then evaluates death.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 21:06:10 +02:00
ctan 32c09df264 fix(rules): keep swift and free actions for staggered combatants
PF1e (CRB, Staggered): a staggered creature takes a single move OR standard action but can still take free, swift, and immediate actions. _staggered_filter returned only the first non-full-round action, so a disabled combatant with a queued swift bonus (deed/inspire_courage) lost its standard action. It now keeps every swift and free action plus the first move-or-standard, preserving the full_attack -> single attack downgrade.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 20:59:19 +02:00
ctan 529999da69 fix(rules): correct the inspire courage bonus type and saves
PF1e CRB (Bardic Performance - Inspire Courage): the attack/weapon-damage
bonus is a COMPETENCE bonus (not morale), so it stacks with morale sources
like Heroism; the performance also grants a +1 MORALE bonus on saving throws
against charm and fear effects, implemented as two descriptor-conditional
will modifiers (fear / mind_affecting) that dedupe via morale stacking.
Simplifications (documented): flat +1 (no scaling per four bard levels) and
mind_affecting stands in for the missing charm descriptor.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 20:35:01 +02:00
ctan 0fefb9cdd2 fix(rules): apply the -2 spell combat penalty to melee attacks
PF1e CRB (Magus Spell Combat): as a full-round action the magus casts a
standard-action spell and makes all his melee attacks at -2. The penalty is
threaded through the full-attack chain (_execute_attack -> _full_attack ->
_full_attack_weapon -> _attack/_resolve_swing -> resolve_attack bonus_override)
so it applies to every attack roll and crit confirmation. Simplification: the
arcane pool cost is still not modeled.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 20:30:19 +02:00
ctan e321c67779 fix(rules): allow a Will save to halve channeled energy damage
PF1e CRB (Channel Energy): creatures damaged by channeled energy get a Will
save (DC 10 + half the channeler's level + her Charisma modifier) for half
damage (floor). Harm mode only; heal mode unchanged. Charisma is used RAW
even for casters whose spellcasting ability differs (channeling is a
Charisma class feature).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 20:24:51 +02:00
ctan 6f784d3369 fix(rules): require a ranged touch attack for ray spells
PF1e CRB (Magic - Ranged Touch Attacks): spells delivered by ray require a
ranged touch attack (BAB + Dex vs touch AC, no range increment) to hit a
hostile target; a miss wastes the slot. SpellSpec gains requires_ranged_touch,
set on the 8 SRD-confirmed rays (Ray of Frost, Ray of Enfeeblement, Scorching
Ray, Acid Arrow, Acid Splash, Disrupt Undead, Shard of Chaos, Spear of Purity).
Magic Missile and area spells are unaffected. Simplification (documented): no
size modifier / Weapon Finesse on the roll.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-09-11 20:19:03 +02:00
ctan 24af1687ab fix(spells): backfill casting times for all imported spells 2026-09-11 15:01:42 +02:00
137 changed files with 2778 additions and 335 deletions
+254 -68
View File
@@ -269,7 +269,13 @@ jusqu'à 10 incréments, une arme `touch` jusqu'à 5 (jet/firearm), au-delà ell
n'est pas sélectionnable. `damage_bonus` et `dr` sont optionnels.
Le booléen `two_handed` (optionnel, défaut `false`) marque une arme tenue à
deux mains : Power Attack donne alors +3X (et non +2X) aux dégâts (conformance
B16). `spell_resistance` (entier), `resistances` (dict type → montant) et
B16). Le booléen `reach_weapon` (optionnel, défaut `false`) marque une arme
dotée de la qualité « reach » du CRB (lance, glaive, longspear, etc.) : elle
double l'allonge naturelle du porteur mais ne frappe pas à cette allonge
naturelle ou moins — anneau avec dead zone (conformance R1, voir « Mêlée »).
Le `reach_ft` d'une attaque naturelle (morsure, sabots) n'est **pas** une arme
à allonge : il encode l'allonge naturelle de la créature, qui reste un disque.
`spell_resistance` (entier), `resistances` (dict type → montant) et
`immunities` (liste de types) sont optionnels.
Deux monstres d'exemple sont fournis : gobelin et orc.
@@ -319,7 +325,12 @@ Règles modélisées :
ramenant à `hp ≥ 0` réinitialise la stabilisation pour toute chute future.
La mort survient quand les pv négatifs atteignent le score de CON
(`hp ≤ -CON`) — conformance P2 : la règle du −10 de D&D 3.5 n'existe pas
en PF1e et n'est plus modélisée.
en PF1e et n'est plus modélisée. Une créature mourante qui subit des dégâts
continus (saignement) perd ses dégâts de saignement au début de son tour,
puis **échoue automatiquement** son jet de stabilisation (aucun d20 jeté) et
perd donc 1 pv de plus par tour en plus des dégâts continus (CRB « Stable
Characters and Recovery ») — elle meurt ainsi plus vite qu'une créature
mourante non saignante.
- Mort simplifiée des monstres (option `--simple-monster-death`, défaut
désactivé) : quand l'option est présente dans la commande, un **monstre**
meurt dès `hp ≤ 0` — ni bande d'invalidité à 0 pv, ni bande d'agonie entre
@@ -339,10 +350,15 @@ Règles modélisées :
- Invalide (conformance P2, CRB « Effects of Death ») : à `hp = 0`
exactement, une créature est **invalide** — elle reste active mais
**staggered** (une action de mouvement OU une action standard par tour, pas
d'action à round complet), se déplace à **moitié vitesse**, et achever une
d'action à round complet, mais les actions swift, libre et immédiate restent
permises — CRB « Staggered »), se déplace à **moitié vitesse**, et achever une
action non-mouvement (standard ou pénible) lui coûte **1 pv** à la fin de
cette action (pv → −1, agonie). Simplification documentée : si l'action
elle-même soigne la créature au-dessus de 0 pv, ce coût n'est pas appliqué.
cette action (pv → −1, agonie). Les actions de mouvement — dont
`retrieve_weapon` (sortir/récupérer une arme) et `repair_weapon` (raccommoder
une arme brisée), classées mouvement — ne risquent pas de blessure
supplémentaire et coûtent 0 pv (CRB « Disabled »). Simplification documentée :
si l'action elle-même soigne la créature au-dessus de 0 pv, ce coût n'est pas
appliqué.
- `hp < 0` = inactive (mourante ou morte) ; `hp = 0` = active mais invalide.
- Initiative : triée sur (total, modificateur, ordre de liste), sans re-jet.
- Économie d'action : un tour normal donne une action standard + une action de
@@ -351,7 +367,8 @@ Règles modélisées :
`default_policy` renvoie `(full_attack,)` si l'ennemi est en portée, `(charge,)`
si une ligne droite existe, `(5foot_step, full_attack)` si un seul pas
suffit à entrer en portée, ou `(move, attack)` sinon. Les actions immédiates
(hors-tour, consomment le prochain swift) sont modélisées via une politique
(hors-tour : prochain swift ; pendant son tour : swift du tour courant —
conformance L10) sont modélisées via une politique
de réaction opt-in (`reaction_policy`) — voir « Actions immédiates » ci-dessous.
**Application du budget (conformance X4)** : le moteur applique désormais le
budget d'action PF1e (CRB « Actions in Combat ») à TOUTE séquence renvoyée par
@@ -387,8 +404,9 @@ Règles modélisées :
`run` (round complet en RAW — il consacre le standard ET le mouvement, tout
en posant `moved_this_turn` et `running`) ;
**libre/conditionnel (hors budget)** = `wait`, `free`, `immediate` (hors-tour ;
il consomme le PROCHAIN swift via `immediate_used`, pas les compartiments du
tour courant), `5foot_step` (pas libre, exclusif avec tout autre mouvement via
il consomme le PROCHAIN swift via `immediate_used` ; pendant son propre tour,
il consomme le swift du tour courant via `swift_used_this_turn` — conformance
L10), `5foot_step` (pas libre, exclusif avec tout autre mouvement via
`moved_this_turn`), `drop_prone`, `activate_power_attack` et `fight_defensively`
(des déclarations de mode appliquées à l'attaque qui les suit, comme le
basculement Power Attack). Ordre de composition : le pré-filtre des temps
@@ -414,17 +432,20 @@ Règles modélisées :
`one_round` → **round complet par clamp** — approximation documentée : le
moteur ne tient pas d'incantation en cours entre les tours, le sort
d'1 round se résout au bout du tour courant au lieu du suivant ;
`long` (≥ 1 minute) → **jeté avant le filtre de budget**, rapporté comme
`long` (> 1 round : 3 rounds, 10 minutes, 1 heure — cast multi-round non
planifiable dans un tour) → **jeté avant le filtre de budget**, rapporté comme
`ActionResult(kind="cast_spell", ok=False, reason="downgraded:cast_time")`
(seule `default_policy` s'en préserve : `_choose_spell_action` ne sélectionne
jamais un sort à temps long). Le moteur résout le code via sa registry
(`_cast_time_of`, repli `standard` pour un nom inconnu) et le passe aux
filtres purs sous forme de résolveur `CastTimeResolver`. Seuls
`Summon Monster I/II` déclarent `"1 round"` dans `data/spells/` ; les autres
sorts exotiques (Bladed Dash, Silence…) restent au défaut `standard` — hors
du périmètre de ce paquet. Hors du périmètre (hook futur, commenté dans
filtres purs sous forme de résolveur `CastTimeResolver`. Les 107 sorts
importés de `data/spells/` déclarent tous leur `cast_time` (codes normalisés,
backfillés depuis le SRD) : 95 `standard`, 6 `one_round` (Enhance Water,
Silence, Sleep, Summon Instrument, Summon Monster I/II), 2 `immediate`
(Grasp, Saving Finale) et 4 `long` (Make Whole, Masterwork Transformation,
Mending, Restoration Lesser). Hors du périmètre (hook futur, commenté dans
`_cast_time_of`) : la métamagie d'incanteur spontané qui allonge le temps
d'incantation à un round complet sans don Quickened — le signature
d'incantation à un round complet sans don Quickened — la signature
`Callable[[Action], CastTime]` du résolveur l'accommodera sans changement.
- Retard (`Action(kind="delay")`, action standard) : le combattant renonce à
agir maintenant et agit plus tard dans le **même round** — en fin d'ordre si
@@ -433,7 +454,12 @@ Règles modélisées :
cible − 0,5 (ou au minimum des totaux − 0,5 sans cible) et **persiste aux
rounds suivants** ; le reste du tour est perdu, un second retard dans le même
round est rejeté (`already_delayed`), et le drapeau se réinitialise au début
de chaque round. `default_policy` ne choisit pas le retard (disponible via
de chaque round. Le tour réinséré plus tard dans le même round **ne rejoue
pas le début de tour** : la décrément des durées (buffs/conditions), les
dégâts continus (saignement), l'effet de terreur et les réinitialisations de
drapeaux par tour ne s'appliquent qu'une fois par round (le tour retardé garde
néanmoins son appel de politique, son budget et son exécution normaux).
`default_policy` ne choisit pas le retard (disponible via
une politique personnalisée).
- Préparation (`Action(kind="ready", ready_trigger=...)`, action standard) : le
combattant se prépare à agir quand un événement déclencheur survient. Le
@@ -547,16 +573,33 @@ Règles modélisées :
aucun jet n'est effectué. Sans `weapon_id`, la sélection automatique est
inchangée. `default_policy` ne choisit pas d'arme (disponible via une
politique personnalisée).
- Mêlée : allonge effective = max(allonge naturelle du gabarit (Small/Medium
5 ft, Large 10 ft, Huge 15 ft, Gargantuan 20 ft, Colossal 30 ft), `reach_ft`
de l'arme). Une arme à allonge (`reach_ft` > 5) menace l'anneau de cases à
distance égale à son allonge — les cases à 5 ft sont une « dead zone » où
elle ne frappe pas ; une arme sans allonge menace les cases adjacentes.
Mouvement : un déplacement parcourt jusqu'à la
vitesse du combattant en cases le long du plus court chemin réel (champ de
coût Dijkstra depuis la cible, diagonales 5-10-5), en s'arrêtant adjacent à
l'ennemi le plus proche — les combattants contournent les murs au lieu
d'osciller contre eux.
- Mêlée (conformance R1, CRB « Big and Little Creatures in Combat ») :
l'**allonge naturelle** du gabarit (Small/Medium 5 ft, Large 10 ft, Huge
15 ft, Gargantuan 20 ft, Colossal 30 ft) est un **disque** : la créature
frappe et menace toutes les cases jusqu'à son allonge, l'adjacence
comprise — une créature Large dont l'attaque naturelle a `reach_ft` 10
menace donc aussi les cases adjacentes (le `reach_ft` d'une attaque
naturelle EST son allonge naturelle). Une **arme à allonge**
(`reach_weapon: true` dans le JSON) est un **anneau** : elle double
l'allonge naturelle du porteur mais ne frappe pas à l'allonge naturelle ou
moins — la zone utilisable est `allonge naturelle < distance ≤ 2 ×
allonge naturelle`, la dead zone vaut donc 5 ft pour un porteur
Small/Medium et 10 ft pour un porteur Large. Une arme ordinaire sans
allonge menace les cases adjacentes (disque de 5 ft).
Mouvement : un déplacement parcourt jusqu'à la
vitesse du combattant en cases le long du plus court chemin réel (champ de
coût Dijkstra depuis la cible, diagonales 5-10-5), en s'arrêtant adjacent à
l'ennemi le plus proche — les combattants contournent les murs au lieu
d'osciller contre eux. Conformance L5 (SRD « Movement, Position and
Distance ») : « You can move through a square occupied by a friendly
character, unless you are charging » — `move` et `run` **traversent** les
cases des alliés (les ennemis bloquent toujours le chemin), mais ne
peuvent jamais **finir** sur une case occupée : entrer sur une case alliée
exige un prolongement libre (règle du « pass-through »), et la queue du
chemin est tronquée si le budget s'épuise sur une case alliée. La charge
reste bloquée par les créatures (ligne droite dégagée), comme la retraite
(limite documentée : le passage à travers les alliés n'est pas modélisé
pour `withdraw` et le pas de placement auto-dirigé).
Vitesse de déplacement (V4) : le budget de tout mouvement (déplacement,
charge 2×, retraite 2×, course 4×) est le **meilleur entre la vitesse au
sol (`speed_land_ft`) et la vitesse de vol (`speed_fly_ft`)** — une créature
@@ -603,9 +646,18 @@ Règles modélisées :
`reaction_policy(engine, state, event)` (défaut : aucune) ; sur événement
(`attack_resolved`, `movement_step`, `spell_cast`, `damage_taken`) une
réaction `Action(kind="immediate")` peut être exécutée hors tour — une par
événement — et consomme le prochain swift de l'état (immédiate pendant le
tour : exécutée, consomme aussi le prochain swift — simplification
documentée). Les actions préparées (`ready`) sont traitées sur ces mêmes
événement — et consomme le prochain swift de l'état (`immediate_used`).
Conformance L10 (SRD « Immediate Actions ») : « Using an immediate action
on your turn is the same as using a swift action and counts as your swift
action for that turn » — une immédiate déclenchée **pendant le tour** du
combattant consomme le swift du **tour courant** (`swift_used_this_turn`,
posé par le moteur sur l'acteur du tour) : tout swift encore présent dans
la séquence est retiré (`downgraded:immediate_swift`) et aucune seconde
immédiate ne part ce round ; le swift du tour **suivant** reste disponible
(contrairement à l'immédiate hors-tour). Simplification documentée :
l'interdiction RAW d'une seconde immédiate s'étend jusqu'au début du tour
suivant, le moteur la borne au round en cours.
Les actions préparées (`ready`) sont traitées sur ces mêmes
événements **avant** et indépendamment de la politique de réaction (voir
« Préparation » plus haut).
- Ligne d'effet : une cible entièrement derrière un terrain `blocks_los` ne
@@ -618,9 +670,14 @@ Règles modélisées :
attaques de mêlée ignorent les créatures). Conformance B20 (CRB « Cover »,
règle des coins) : c'est **l'attaquant qui choisit son meilleur coin** —
une créature multi-cases (Large +) ne subit que le couvert de SA meilleure
case occupée (minimum sur ses cases), pas le pire. Le côté cible reste
évalué par la règle RAW : toute ligne vers tout coin des cases de la cible
compte (maximum sur les coins de la cible).
case occupée (minimum sur ses cases), pas le pire. Côté cible : à distance,
toute ligne vers tout coin des cases de la cible compte (maximum sur les
coins de la cible) ; **en mêlée**, l'attaquant peut choisir n'importe
quelle case occupée par une créature multi-cases pour déterminer le couvert
(conformance A5 — CRB « Big Creatures and Cover » : « when making a melee
attack against such a creature, you can pick any of the squares it occupies
to determine if it has cover against you ») — le score est donc le minimum
sur les cases de la cible en mêlée, le maximum à distance.
- Flanquement : +2 au jet d'attaque de mêlée (toucher de mêlée inclus, voir
« Touch AC ») si un allié actif menace réellement la cible depuis la
bordure ou le coin opposé — conformance P2 : l'allié doit **menacer** une
@@ -629,17 +686,26 @@ Règles modélisées :
(étourdi/paralysé ne flanque pas). Les attaques à distance ignorent le
flanquement ; un allié désarmé ou à distance ne compte pas.
- Attaques d'opportunité : un combattant actif doté d'une arme de mêlée menace
les cases à distance de son allonge effective (les 8 cases adjacentes pour
une arme sans allonge ; l'anneau à son allonge pour une arme reach — la
dead zone de 5 ft n'est pas menacée). Deux déclencheurs sont modélisés : (1) quitter une
les cases de sa zone d'allonge (voir « Mêlée » : le disque de l'allonge
naturelle — les 8 cases adjacentes pour un Small/Medium sans allonge — ou
l'anneau d'une arme à allonge, dont la dead zone n'est pas menacée). Deux déclencheurs sont modélisés : (1) quitter une
case menacée — le mouvement est résolu pas à pas, et chaque ennemi qui menace
la case actuelle porte une AoO avant que le mouvant ne la quitte ; (2) tirer
la case actuelle porte une AoO avant que le mouvant ne la quitte ; sortir
de plusieurs cases menacées par le **même** adversaire dans le même round ne
compte qu'**une seule opportunity** pour lui (piste `_move_aoo_provoked`,
réinitialisée au début du round — conformance A1, CRB « Attacks of
Opportunity ») ; le relèvement (stand_up) est un déclencheur distinct et
provoque toujours ; (2) tirer
avec une arme à distance depuis une case menacée — chaque ennemi menaçant
porte une AoO avant chaque tir. Une AoO par combattant par round (piste
`_aoo_used`, réinitialisée au début du round) ; le budget restant est exposé
dans l'Observation via la clé `aoo_remaining` par combattant ; les AoO sont
toujours portées
(PF1e permet de les décliner, le simulateur ne le fait pas). Le pas de
(PF1e permet de les décliner, le simulateur ne le fait pas) — **sauf** si la
cible a un couvert ou une dissimulation totale par rapport à l'attaquant :
l'AoO est alors supprimée et non consommée (conformance A4, CRB « Cover » :
« You can't execute an attack of opportunity against an opponent with cover
relative to you » ; CRB « Concealment » : dissimulation totale). Le pas de
placement (5 ft) ne provoque jamais d'AoO (voir ci-dessous) ; la retraite ne
protège que la case de départ (voir ci-dessous).
- Charge : action à round complet. Le combattant se déplace en ligne droite
@@ -661,17 +727,28 @@ Règles modélisées :
s'arrête adjacent à la cible) ou vers une `destination` explicite (U5c), en
réutilisant exactement la mécanique de `move` (descente du champ de coût
Dijkstra, pas à pas avec provocation d'AoO — courir ne protège pas des
AoO). À l'achèvement, le combattant est `running` jusqu'au début de son
prochain tour : il **perd son bonus de Dextérité à la CA** (résolu par le
même chemin flat-footed/`denies_dex_to_ac` que les conditions). Une
`destination` hors budget 4× (ou invalide) est rejetée
AoO), **sauf que la course ne traverse pas le terrain difficile**
(conformance R2 — CRB « Movement, Position and Distance — Difficult
Terrain » : « You can't run or charge across difficult terrain ») : la
descente refuse tout pas dont le footprint toucherait une case de coût > 1
(mécanisme `avoid_difficult` de `_descend_path`, symétrique du refus de la
charge dans `_charge_path_clear`) ; le combattant **avance jusqu'à
l'obstacle et s'y arrête** (comportement déterministe, retenu plutôt que
le rejet de l'action). À l'achèvement, le combattant est `running` jusqu'au
début de son prochain tour : il **perd son bonus de Dextérité à la CA**
(résolu par le même chemin flat-footed/`denies_dex_to_ac` que les
conditions). Une `destination` hors budget 4× (ou invalide) est rejetée
(`unreachable_destination`) ; sans cible ni destination, rejet
(`missing_target`). `default_policy` ne choisit pas la course (disponible
via une politique personnalisée).
- Pas de placement (5-foot step) : action libre qui déplace le combattant d'une
case vers l'ennemi le plus proche sans provoquer d'AoO. Exclusivité mutuelle
avec tout autre mouvement (move, charge, retraite) dans le même tour —
tracked via `moved_this_turn`, réinitialisé au début du tour. `default_policy`
tracked via `moved_this_turn`, réinitialisé au début du tour. Conformance
L3 (SRD « Measuring Distance ») : « You can't move diagonally past a corner
(even by taking a 5-foot step) » — un pas diagonal dont les deux cases
adjacentes (flancs) ne sont pas toutes deux praticables est rejeté
(`unreachable_destination`), comme pour tout autre déplacement. `default_policy`
choisit `(5foot_step, full_attack)` quand un seul pas suffit à entrer en
portée.
- Distance : pénalité cumulative de −2 par incrément de portée complet au-delà
@@ -690,8 +767,11 @@ Règles modélisées :
ex. le contact paralysant du liche) n'en fait rien. Conformance P2 : le
contact de mêlée (touch sans incrément) est une **attaque de mêlée** — il
bénéficie du flanquement, de la hauteur (+1), du +4 contre une cible inerme
et peut porter une attaque sournoise ; Power Attack reste réservé aux armes
de mêlée (le contact n'en bénéficie pas).
et peut porter une attaque sournoise ; Power Attack (conformance A6 — CRB :
« a –1 penalty on all melee attack rolls… The bonus damage does not apply to
touch attacks ») s'applique à **la touche** du contact de mêlée (pénalité −X
au jet d'attaque et de confirmation) mais son bonus de dégâts reste réservé
aux armes de mêlée (le contact ne gagne pas le +2X/+3X).
- Jets de sauvegarde : `resolve_save(state, save_type, dc)` — fort/ref/will.
1 naturel = échec automatique, 20 naturel = succès automatique. Les
modificateurs d'effets (`StatModifier` avec `target` correspondant) sont
@@ -742,7 +822,20 @@ Règles modélisées :
`resolve_attack`) ; en cas d'échec le sort n'a aucun effet (l'emplacement
est brûlé). Simplifications documentées : Weapon Finesse et les autres
bonus situationnels de jet de contact ne sont pas modélisés. Une cible
volontaire (soi ou un allié du même camp) ne demande aucun jet. Un sort ciblé avec sauvegarde fait pleins dégâts
volontaire (soi ou un allié du même camp) ne demande aucun jet. Sorts à
contact à distance (CRB « Magic — Ranged Touch Attacks ») : un sort dont le
JSON déclare `requires_ranged_touch: true` (les rayons du SRD — Ray of
Frost, Ray of Enfeeblement, Scorching Ray, Acid Arrow, Acid Splash, Disrupt
Undead, Shard of Chaos, Spear of Purity) impose une attaque de contact à
distance contre une cible **hostile** (hors effet de zone) — d20 + BAB + mod
de **Dextérité** du lanceur contre la CA de contact de la cible (amputée du
modificateur de Dextérité si la cible perd son bonus de Dextérité, même
chemin que `resolve_attack`) ; la portée du sort est une valeur absolue, il
n'y a donc **pas** de pénalité par incrément de portée ; en cas d'échec le
sort n'a aucun effet (l'emplacement est brûlé). Simplifications documentées
(miroir du contact de mêlée) : le modificateur de taille et Weapon Finesse
ne sont pas modélisés. Magic Missile (touche automatiquement), les sorts de
zone et les sorts à sauvegarde simple ne sont pas concernés. Un sort ciblé avec sauvegarde fait pleins dégâts
sur un échec et **aucun dégât sur un succès** (la sauvegarde annule) ; le
demi-dégât sur sauvegarde réussie ne s'applique que là où l'effet le déclare
(`half_on_save: true` pour les rayons/lignes/cônes, `AreaEffect.save_for_half`
@@ -774,8 +867,14 @@ Règles modélisées :
1d6 tranchant + 1d6 feu contre résistance feu 5 ne perd que ses dés de feu, les
dés tranchants, les bonus plats et les dés de précision (attaque sournoise, non
typés) restent intacts ; l'immunité à un type annule uniquement les composantes
de ce type. Les types physiques (contondant/perforant/tranchant) restent sur le
chemin de la RD, appliquée au total comme avant. La résistance énergétique
de ce type. Les types physiques (contondant/perforant/tranchant) restent sur le
chemin de la RD, appliquée **uniquement à la part physique** du dégât (dés
physiques + bonus plats + précision) — conformance A3 (CRB « Damage
Reduction » : « Damage reduction does not negate … energy damage dealt along
with an attack ») : la RD ne mange plus la composante énergétique d'une
attaque mixée (ex. arme à feu infligeant des dégâts de feu contre RD 15) ;
les composantes énergétiques ne sont réduites que par résistance/immunité
énergétique. La résistance énergétique
s'applique à l'étape du dégât final (même étape que la RD), y compris aux dégâts
de sorts (un `DamageEffect` est une composante unique — comportement inchangé).
- Concealment (chance de rater) : les conditions `blurred` (20 %, sort flou),
@@ -784,7 +883,10 @@ Règles modélisées :
cible en porte une, après la touche et la confirmation de critique, le moteur
tire un d100 : si `d100 ≤ miss_chance`, l'attaque rate complètement (aucun
dégât, pas de critique, deed non consommé — journalisé « concealment »). Une
cible avec concealment ne peut pas être la victime d'une attaque sournoise.
cible avec concealment **total** (`miss_chance ≥ 50 %`) ne peut pas être la
victime d'une attaque sournoise ; une dissimulation partielle (flou 20 %) ne
bloque plus la sournoise (conformance A7 — CRB rogue « Sneak Attack » :
« cannot sneak attack while striking a creature with total concealment »).
Attaquant aveugle (V5a) : un attaquant portant `blinded` considère tous ses
adversaires comme ayant un concealment total — le même jet unique de d100 est
tiré avec `miss_chance = max(concealment de la cible, 50)` et journalisé
@@ -815,7 +917,9 @@ Règles modélisées :
attaque à distance à ≤ 30 ft). Les dés sont jetés avec le RNG du moteur et
ajoutés APRÈS le multiplicateur de critique (la précision n'est jamais
multipliée) et AVANT la RD et les résistances énergétiques ; jamais contre une
cible avec concealment. Conformance P2 : les morts-vivants (`undead`) et les
cible à dissimulation **totale** (`miss_chance ≥ 50 %` ; conformance A7 — une
dissimulation partielle comme le flou 20 % n'empêche plus la sournoise).
Conformance P2 : les morts-vivants (`undead`) et les
constructeurs (`construct`) sont immunisés aux dégâts de précision — la cible
ne peut pas être la victime d'une attaque sournoise ; les autres immunités RAW
(vase, plante) ne sont pas modélisées (pas de tels types dans le modèle).
@@ -838,10 +942,17 @@ Règles modélisées :
- 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
de mouvement (`move`, `5foot_step`, `stand_up`, `drop_prone`) et bloque toute
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`,
`repair_weapon`) survivent au filtre ; le pas de placement (`5foot_step`) et
se jeter à terre (`drop_prone`) sont des actions **libres**, non de
mouvement, et sont donc retirés ; le nauséeux bloque toute
attaque, manœuvre **et incantation** (CRB : un nauséeux ne peut ni attaquer,
ni incanter, ni se concentrer) ; `staggered` restreint à une action
simple (pas d'attaque à outrance) ; `cant_move` bloque le déplacement ;
ni incanter, ni se concentrer) ; `staggered` restreint à une action
simple (une action de mouvement OU standard, pas d'attaque à outrance ni
d'action à round complet, mais swift/libre/immédiate conservées) ;
`cant_move` bloque le déplacement ;
`denies_dex_to_ac` (flat-footed, paralysé, aveuglé…) fait perdre le bonus de Dextérité à
la CA (CA flat-footed) ; `miss_chance` (flou 20 %, déplacement 50 %, invisible
50 %) impose la
@@ -887,22 +998,64 @@ Règles modélisées :
(conformance P2). Conformance P2 : tenter une manœuvre (sauf `escape`)
**provoque une attaque d'opportunité** de la cible, résolue **avant** le jet
de CMB ; le don « Improved <Maneuver> » correspondant (Improved Trip, …)
annule cette provocation ; si l'AoO fait passer l'attaquant sous 0 pv, la
manœuvre est perdue. L'AoO de manœuvre consomme le budget d'AoO du round de
annule cette provocation ; les dégâts infligés par cette AoO sont appliqués
comme **pénalité au jet de manœuvre** (conformance A2 — CRB « Combat
Maneuvers » : « apply that amount as a penalty to the attack roll to perform
the maneuver », total planché à 0, 20 naturel réussit / 1 naturel échoue
toujours) ; si l'AoO fait passer l'attaquant sous 0 pv, la manœuvre est
perdue. L'AoO de manœuvre consomme le budget d'AoO du round de
la cible (Combat Reflexes inclus). Conformance B16 (CRB « Power Attack ») :
la pénalité −X de Power Attack actif s'applique **au jet de CMB** de la
manœuvre (X = BAB//4 + 1) — la pénalité couvre « les jets d'attaque de mêlée
et les jets de manœuvres de combat » ; l'escape par compétence n'est pas
pénalisé (un test de compétence n'est pas un jet de manœuvre).
trip → `prone` ; disarm → `disarmed` (−4 attaque) ; bull_rush → pousse la
cible (direction sélectionnable via `Action.direction`) ;
grapple → `grappled`/`pinned` ; escape → **une** sauvegarde (bonus statique de la
compétence `escape_artist` ou CMB, + un d20) contre CMD — une seule tentative,
sans boucle multi-tour. Un sunder endommage l'**arme**, pas les PV : `str_mod + 2`
la pénalité −X de Power Attack actif s'applique **au jet de CMB** de la
manœuvre (X = BAB//4 + 1) — la pénalité couvre « les jets d'attaque de mêlée
et les jets de manœuvres de combat » ; l'escape par compétence n'est pas
pénalisé (un test de compétence n'est pas un jet de manœuvre). Conformance
L1 (SRD « Combat Maneuvers ») : « Creatures that are size Tiny or smaller
use their Dexterity modifier in place of their Strength modifier to
determine their CMB » — Tiny/Diminutive/Fine calculent donc leur CMB avec
le modificateur de Dextérité à la place de celui de Force ; lacune
documentée : l'allonge nulle et la co-occupation des créatures Tiny et
plus petites ne sont pas modélisées (abstraction à la grille de 5 ft).
Conformance L2 (SRD « Combat Maneuver Defense ») : le CMD calculé ajoute
les bonus de CA des huit types autorisés (« A creature can also add any
circumstance, deflection, dodge, insight, luck, morale, profane, and
sacred bonuses to AC to its CMD » — bonus issus des buffs/conditions/
dons, défense totale et combat défensif inclus) et une créature au
contact pris de dos ne ajoute pas son bonus de Dextérité (« A flat-footed
creature does not add its Dexterity bonus to its CMD » — la pénalité de
Dextérité, qui n'est pas un bonus, reste appliquée).
(SRD « Trip » / « Bull Rush » / « Overrun ») : « You can only [affect] an
opponent who is no more than one size category larger than you » — conformance
L8 : trip, bull_rush et overrun contre une cible de **deux catégories de
taille ou plus au-dessus** de l'attaquant sont illégaux (tentative refusée,
journalisée `rejected (target too large)`, aucun jet, pas d'AoO provoquée) ;
les autres manœuvres (disarm, sunder, grapple…) n'ont pas de limite de taille.
trip → `prone` ; disarm → `disarmed` (−4 attaque) ; bull_rush → pousse la
cible (direction sélectionnable via `Action.direction`) ; conformance L6
(SRD « Bull Rush ») : la poussée vaut 5 ft plus « For every 5 by which
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` ; escape → **une** sauvegarde (bonus statique de la
compétence `escape_artist` ou CMB, + un d20) contre CMD — une seule tentative,
sans boucle multi-tour. Conformance L4 (SRD « Combat Maneuvers ») : le 20
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 →
`prone` 1 round + passage au travers si la case au-delà est libre ; dirty trick →
`Action(kind="repair_weapon")`. 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,
you move through the target's space and the target is knocked prone ») ;
un succès par 0–4 points ne fait que traverser, sans renverser ; conformance
L7 (SRD « Overrun ») : une tentative **échouée** arrête l'attaquant « in the
space directly in front of the opponent, or the nearest open space in front
of the creature » — l'attaquant non adjacent est déplacé sur la case libre
la plus proche de la cible sur la ligne d'approche (adjacent : immobile) ;
conformance L7 (SRD « Trip ») : un trip qui « fails by 10 or more » renverse
l'**attaquant** (`prone` 1 round, `total <= CMD - 10`) ; dirty trick →
condition choisie par `Action.trick_condition` (défaut `dazzled` 1 round ;
`blinded`/`deafened`/`entangled`/`nauseated` possibles) ; steal → l'arme de
mêlée de la cible est volée (exclue de `usable_attacks()`, récupérable via
@@ -933,11 +1086,25 @@ Règles modélisées :
si un allié est < 50 % de ses PV → soigne tous les êtres vivants à 30 ft ; sinon, si au
moins 2 morts-vivants ennemis sont groupés à 30 ft → les blesse en 2d6 ; le camp de la
cible n'est pas pris en compte — seul `creature_type` compte, `selective_channeling` non
modélisé), sortilège `evil_eye` (nairda), deed `up_close_and_deadly`
modélisé ; les créatures blessées obtiennent un jet de Volonté DD `10 +
demi-niveau du canaliseur + modificateur de Charisme` pour demi-dégâts
— CRB Channel Energy ; le mode soin n'accorde pas de sauvegarde), sortilège `evil_eye` (nairda), deed `up_close_and_deadly`
(tammara, action bonus +1d6 à ≤ 30 ft — consommé sur la première attaque
résolue : si elle est à distance ET à ≤ 30 ft, +1d6 s'ajoute aux dégâts ;
sinon le bonus est perdu ; le drapeau est réinitialisé dans tous les cas),
`inspire_courage` + `spell_combat` (misty)
`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
d'attaque et de confirmation ; simplification : le coût de pool arcanique
n'est pas modélisé) ; Inspire Courage (CRB Bardic Performance) : **+1
compétence** (competence) aux jets d'attaque et de dégâts — type qui se
cumule donc avec les sources de moral (Heroism) — et **+1 moral** aux jets
de sauvegarde contre les effets de charme et de peur, portée par deux
modificateurs conditionnés (`fear` / `mind_affecting`, dédupliqués par la
règle d'empilement du moral) ; simplifications documentées : la
progression (+1 par quatre niveaux) n'est pas modélisée (plat +1) et le
moteur n'ayant pas de descripteur « charme », `mind_affecting` en tient
lieu (surcouverture : les effets de compulsion comptent aussi))
— couvertes par `tests/test_class_abilities.py`.
- Le Liche (`data/monsters/lich.json`) : `creature_type: "undead"` (sensible à l'énergie
positive canalisée), aura de terreur (30 ft, Volonté DD 22 ou
@@ -1061,6 +1228,22 @@ Règles modélisées :
Non modélisé : la couche `markers` (points nommés de la carte) est validée à
la lecture mais non appliquée dans la résolution.
Limites hors périmètre (arrêtées lors de la conformance L1-L10, documentées
plutôt que bricolées) :
- **Pas de round de surprise** : le modèle de combattant n'a pas de champ de
perception/attention (conscience du combat), donc le SRD « Surprise » ne
peut pas être résolu — le combat démarre toujours au round 1 complet.
- **Incantation `one_round` bornée à un round complet** : le moteur ne tient
pas d'incantation en cours entre les tours ; un sort d'1 round se résout à
la fin du tour courant au lieu du suivant (approximation documentée dans
« Temps d'incantation »). L'incantation multi-round vraie (> 1 round) est
jetée du budget (`long`).
- **Gabarits Tiny/Diminutive/Fine abstraits à la grille de 5 ft** : leur
allonge nulle et la co-occupation de leurs cases (plusieurs créatures
minuscules sur une même case) ne sont pas modélisées ; seule la substitution
Dextérité/Force du CMB (conformance L1) tient compte de leur taille.
## Architecture
- `dice.py` — parseur de notation de dés (`2d4+1`) et lancer.
@@ -1109,7 +1292,9 @@ la lecture mais non appliquée dans la résolution.
- `abilities.py` — dons et capacités : `AbilitySpec` (dataclass avec
catégorie feat/class/racial/trait) et fabriques de dons (Weapon Focus ciblé
par arme, Toughness lié au niveau, Power Attack actif −X attaque / +2X
dégâts, X = BAB//4 + 1, mêlée uniquement, activé comme action libre via le
dégâts, X = BAB//4 + 1 — la pénalité −X vise toutes les attaques de mêlée
(contact de mêlée inclus, conformance A6), le bonus de dégâts uniquement les
armes de mêlée —, activé comme action libre via le
kind `activate_power_attack` qui pose `state.power_attack`). Conformance
B16 (CRB « Power Attack ») : le bonus de dégâts passe à **+3X (×1,5)** pour
une arme marquée `two_handed: true` dans le JSON de l'attaque (arme à deux
@@ -1124,7 +1309,8 @@ la lecture mais non appliquée dans la résolution.
(`loaders/combatant.py`) résout les noms de dons des fiches vers des
`AbilitySpec` réels ou des « no-op » tracés.
- `spells.py` — sorts : `SpellSpec` (dataclass avec niveau, école, portée,
sauvegarde, DC de base, temps d'incantation `cast_time`) et types d'effets
sauvegarde, DC de base, exigence de contact à distance `requires_ranged_touch`
(rayons), temps d'incantation `cast_time`) et types d'effets
(`DamageEffect`, `ConditionEffect`,
`HealEffect`, `BuffEffect`). Portées PF1e (personal, touch, close, medium,
long) calculées par `spell_range_ft`. Chargeur JSON (`load_spell`,
+1
View File
@@ -44,6 +44,7 @@
"crit_range": 20,
"crit_mult": 3,
"reach_ft": 10,
"reach_weapon": true,
"count": 1
},
{
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip that conjures duplicate ammunition: attacks with the affected ammunition do not expend it. No combat-mechanical effect in the engine (ammunition is not tracked)."
}
+2
View File
@@ -5,6 +5,8 @@
"range": "medium",
"save": "none",
"base_dc": 10,
"requires_ranged_touch": true,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+2
View File
@@ -5,6 +5,8 @@
"range": "close",
"save": "none",
"base_dc": 10,
"requires_ranged_touch": true,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+1
View File
@@ -5,6 +5,7 @@
"range": "long",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "buff",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "You create a sphere of air around your head (or a touched creature's) that lasts 10 min/level, allowing breathing underwater. No combat-mechanical effect in the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "Wards a area (20-ft radius, 20 ft high) against intrusion for 2 hours/level, alerting you mentally. No combat-mechanical effect in the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "Creates a permanent visible inscribed mark of your choosing on an object or surface, optionally invisible and keyed to you. Utility cantrip, no combat effect."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "fort",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "buff",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "buff",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "fort",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "fort",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "buff",
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "ref",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip that lets you understand the meaning of any spoken or written language you encounter for 1 min/level. Utility spell, no combat effect."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip (Create Alcohol, spelled as on the PC sheet) that transforms one liquid per level into an alcoholic drink of equal volume. Utility spell, no combat effect."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "Conjures 4 gallons of clean water per level in an open space or container. Utility spell, no combat effect."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "heal",
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "heal",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip that creates up to four flickering torch-like lights you move as desired (concentration, 1 min/level). Utility spell, no combat effect."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip that lets you reroll one attack roll, saving throw, or skill check made in the past round (once per casting). Not modeled by the engine's action flow, so it carries no mechanical effect."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "fort",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "You suppress the progression of one disease the subject carries for 1 hour/level, keeping it dormant. Utility spell, no combat-mechanical effect in the engine. Fortitude negates (harmless)."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "fort",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "You temporarily stave off incoming poison or eliminate one already in the subject's system for 1 hour/level. Utility spell, no combat-mechanical effect in the engine. Fortitude negates (harmless)."
}
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip that reveals whether a creature of the outsider (evil) subtype has been in the area within 10 minutes/HD, and hints at its nature. Utility spell, no combat effect."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip that detects magical auras in a 60-ft cone (2 rounds to identify strength and school). Utility spell, no combat effect."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip that determines whether a creature, object, or area is poisoned, venomous, or afflicted by acid. Utility spell, no combat effect."
}
+2
View File
@@ -5,6 +5,8 @@
"range": "close",
"save": "none",
"base_dc": 10,
"requires_ranged_touch": true,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "You draw upon divine power for 1 round/level: a +1 luck bonus on attack rolls and weapon damage per 4 caster levels. Simplified: the engine has no luck-bonus self-buff that preserves the pinned default-policy casting order, so no mechanical effect is applied."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "For 1 hour/level you gain DR 5/- against alcohol effects and cannot become drunk. The engine has no DR buff target, so no mechanical effect is applied."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "For 24 hours you tolerate comfortable extremes of heat and cold (from -50 to 140 degrees F) without ill effect. Environmental protection, no combat-mechanical effect in the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "one_round",
"effects": [],
"description": "You purify and bless 1 gallon/level of water (or one vial of holy/unholy water). Utility spell, no combat-mechanical effect in the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: the subject gains a +2 competence bonus on a single Diplomacy or Intimidate check, declared before the roll (duration 1 minute or until discharged). Will negates (harmless). Social skill effect only: the engine does not model skill-check modifiers, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "fort",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "The target's face becomes hideous: it gains a +4 circumstance bonus on Intimidate checks and, if it lacks one, a bite attack (1d6 for Medium) for 1 min/level. Fortitude negates (harmless). The skill bonus and the granted natural attack are not modeled by the engine, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "long",
"save": "ref",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "ref",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "immediate",
"effects": [],
"description": "A cantrip cast as an immediate action when you fail a Climb check and would fall: you immediately retry the Climb check at a -2 penalty (increasing by 2 per successive use in the same situation); on success you don't fall. Climbing is not modeled by the engine, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: the subject gains a +1 competence bonus on a single attack roll, saving throw, or skill check, declared before the roll (duration 1 minute or until discharged). Will negates (harmless). Single-roll discharge is not modeled by the engine, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "buff",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "The target becomes susceptible to a repeat use of your harmful hexes for 1 round/level, bypassing the once-per-day targeting limit. Will negates. No combat effect: the hex-reuse permission is outside the engine's model, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "As part of casting, you attempt a single Intimidate check to make the target act friendly; its memory of the threats is clouded, so its attitude does not worsen afterward. Will negates. Social effect only: no combat mechanics are modeled."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "Undead cannot perceive warded creatures (nonintelligent undead ignore them automatically; intelligent undead get a single Will save) until the subject attacks, channels energy, or touches undead. Duration 10 min/level. Saving throw entries here cover the harmless-target save; the undead-perception effect is not modeled by the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "ref",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "The target is afflicted with bad luck: on its next d20 roll (one per 5 caster levels, up to five) it must roll twice and take the less favorable result; duration 1 round/level. No saving throw; spell resistance applies. The forced worst-of-two reroll mechanic is not modeled by the engine, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "buff",
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: a touched object glows like a torch, shedding normal light in a 20-foot radius (plus dim light for 20 more feet) for 10 min/level. No combat effect; illumination is not modeled by the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "ref",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: a spectral hand lifts and moves one unattended nonmagical object weighing up to 5 lb. from up to 25 ft. away, as far as 15 feet per move action while you concentrate. No combat effect; object manipulation is not modeled by the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "long",
"effects": [],
"description": "Repairs 1d6 points of damage per caster level (maximum 5d6) to one object or construct creature (10-minute casting). Will negates (harmless, object). Object/construct repair is outside the engine's combat model, so the spell has no mechanical effects here."
}
@@ -5,6 +5,7 @@
"range": "touch",
"save": "none",
"base_dc": 10,
"cast_time": "long",
"effects": [],
"description": "After 1 hour of casting (plus masterwork-priced reagents), a non-masterwork weapon, armor, shield, tool, or skill kit becomes its masterwork equivalent. Item crafting is outside the engine's combat model, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "long",
"effects": [],
"description": "A cantrip: after 10 minutes, the spell repairs 1d4 hit points of damage to one object (up to 1 lb./level), removing the broken condition if restored to at least half HP. Will negates (harmless, object). Object repair is outside the engine's combat model, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: you whisper messages and receive replies with targeted creatures within range for 10 min/level; bystanders hear nothing without a DC 25 Perception check. Communication is not modeled by the engine, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: you swear an oath of secrecy - your voice, body language and gear are magically distorted, granting a +10 bonus on Disguise checks to conceal your identity (not to impersonate a specific person) for 10 min/level. Social skill effect only: the engine does not model skill-check modifiers, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: you open or close one unsecured object or portal weighing up to 30 lb. at up to 25 ft. away (fails if a bar or lock resists). Will negates (object). Object manipulation is not modeled by the engine, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "The subject gains a +4 enhancement bonus to Wisdom for 1 min/level, adding the usual benefit to Wisdom-based skills, Will saves and spell DCs. Will negates (harmless). Ability-score increases are not modeled by the engine, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: minor magical tricks for 1 hour - lift 1 lb. of material, color/clean/soil items in a 1-ft cube, chill/warm/flavor 1 lb. of nonliving material, or create crude trinkets. It can deal no damage and duplicates no other spell. No combat effect; the trivial manipulations are not modeled by the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A barrier wards the subject from evil for 1 min/level: +2 deflection bonus to AC and +2 resistance bonus on saves against attacks and effects created by evil creatures, renewed saves and suppression of mental control, and lawful summoned evil creatures cannot touch it. Will negates (harmless). The engine has no alignment system, so alignment-restricted bonuses cannot be modeled and the spell has no mechanical effects here."
}
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "Functions like protection from evil (+2 deflection to AC and +2 resistance on saves vs evil creatures, protection from mental control), except the 1 min/level duration is divided in 1-minute intervals among the touched creatures. Will negates (harmless). Alignment-restricted bonuses and duration-sharing are not modeled, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A barrier wards the subject from lawful creatures for 1 min/level: +2 deflection bonus to AC and +2 resistance bonus on saves against attacks and effects created by lawful creatures, plus renewed saves against mental control by lawful creatures. Will negates (harmless). The engine has no alignment system, so alignment-restricted bonuses cannot be modeled and the spell has no mechanical effects here."
}
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "Functions like protection from law (+2 deflection to AC and +2 resistance on saves vs lawful creatures, protection from mental control), except the 1 min/level duration is divided in 1-minute intervals among the touched creatures. Will negates (harmless). Alignment-restricted bonuses and duration-sharing are not modeled, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: cleanses 1 cu. ft./level of spoiled, rotten, diseased or poisoned food and water, making it pure and drinkable (no effect on creatures or magic potions). Will negates (object). Non-combat utility: the engine does not model objects, so the spell has no mechanical effects here."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: instantly rots 1 cu. ft./level of edible food and makes water and liquids brackish and undrinkable (can also spoil a single potion; no effect on creatures or unholy water). Will negates (object). Non-combat utility: the engine does not model objects, so the spell has no mechanical effects here."
}
+2
View File
@@ -5,6 +5,8 @@
"range": "close",
"save": "fort",
"base_dc": 10,
"requires_ranged_touch": true,
"cast_time": "standard",
"effects": [
{
"type": "condition",
+2
View File
@@ -5,6 +5,8 @@
"range": "close",
"save": "none",
"base_dc": 10,
"requires_ranged_touch": true,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: you can decipher magical inscriptions on objects that would otherwise be unintelligible, at one page per minute, and you can thereafter read that particular writing without the spell. Duration 10 min./level. No combat effect; reading magical writing is not modeled by the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: the subject gains a +1 resistance bonus on saving throws for 1 minute. Will negates (harmless). Simplified: the engine has no resistance bonus type and no self-buff encoding that preserves the pinned default-policy casting order, so no mechanical effect is applied."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "long",
"effects": [],
"description": "Casting time 3 rounds. Dispels any magical effects reducing one of the subject's ability scores or cures 1d4 points of temporary ability damage to one ability score, and eliminates any fatigue (improving exhausted to fatigued). Will negates (harmless). No combat effect encoded: the engine has no ability damage, fatigue-from-spell, or magical-effect-reduction state to restore."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "You ward a creature against attacks for 1 round/level: any opponent attempting to directly attack the warded creature must succeed on a Will save or be unable to follow through with that attack and cannot directly attack the subject for the duration. The subject cannot attack without ending the spell. Will negates. No combat effect encoded: the engine has no attack-refusal-by-save mechanic, so the protection cannot be represented."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "immediate",
"effects": [],
"description": "Immediate action, requires an active bardic performance: when a creature affected by your performance fails a saving throw, end the performance to let it immediately reroll the failed save and take the new result. Will negates (harmless). No combat effect encoded: conditional save rerolls tied to bardic performance are not modeled by the engine."
}
+2
View File
@@ -5,6 +5,8 @@
"range": "close",
"save": "none",
"base_dc": 10,
"requires_ranged_touch": true,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+2
View File
@@ -5,6 +5,8 @@
"range": "close",
"save": "will",
"base_dc": 10,
"requires_ranged_touch": true,
"cast_time": "standard",
"effects": [],
"description": "A dart-shaped projectile of chaotic energy (ranged touch attack): lawful creatures take 1d8 per two caster levels (max 5d8); lawful outsiders take 1d6 per caster level (max 10d6) and are slowed 1 round. A successful Will save halves the damage and negates the slow. Half damage to neutral creatures, no effect on chaotic ones. No combat effect encoded: the engine has no alignment, so the alignment-gated damage cannot be represented."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "buff",
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A shimmering magical field grants the target a +2 deflection bonus to AC (+1 per six caster levels, max +5) for 1 min./level. Will negates (harmless). Simplified: the engine has no self-buff encoding that preserves the pinned default-policy casting order, so no mechanical effect is applied."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "damage",
+1
View File
@@ -5,6 +5,7 @@
"range": "long",
"save": "will",
"base_dc": 10,
"cast_time": "one_round",
"effects": [],
"description": "Casting time 1 round. A 20-ft.-radius emanation centered on a creature, object, or point in space: all sound is stopped in the area, spells with verbal components cannot be cast, and creatures inside are immune to sonic and language-dependent effects. Duration 1 round/level. Will negates (object). No combat effect encoded: the engine has no verbal component or sound propagation model."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "will",
"base_dc": 10,
"cast_time": "one_round",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "fort",
"base_dc": 10,
"cast_time": "standard",
"effects": [
{
"type": "area",
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "fort",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: you create a tiny spark that ignites one unattended Fine flammable object within close range, in any weather (works as flint and steel but much faster). Fortitude negates (object). No combat effect: the spell targets objects, not creatures."
}
+2
View File
@@ -5,6 +5,8 @@
"range": "close",
"save": "will",
"base_dc": 10,
"requires_ranged_touch": true,
"cast_time": "standard",
"effects": [],
"description": "A spear of good energy (ranged touch attack): evil creatures take 1d8 per two caster levels (max 5d8); evil outsiders take 1d6 per caster level (max 10d6) and are blinded 1 round. A successful Will save halves the damage and negates the blind. Half damage to neutral creatures, no effect on good ones. No combat effect encoded: the engine has no alignment, so the alignment-gated damage cannot be represented."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "medium",
"save": "none",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A force weapon appears and attacks foes at a distance as you direct it (1d8 force damage +1 per three caster levels), using your base attack bonus plus Wisdom modifier, once per round on your turn for 1 round/level. No combat effect encoded: the engine has no autonomous floating-attack creature to summon, and the weapon's per-round attacks are not modeled."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "close",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "A cantrip: you touch a living creature with -1 or fewer hit points (up to close range) and stabilize it automatically, so it stops losing hit points until it takes more damage. Will negates (harmless). No combat effect encoded: the engine's dying/stabilization track is not exposed to the spell-effect system."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "You mentally monitor the relative position and general condition (unharmed, wounded, staggered, unconscious, dying, poisoned, and so on) of up to one creature per three caster levels for 1 hour/level. Will negates (harmless). No combat effect: out-of-combat scrying is not modeled by the engine."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "touch",
"save": "will",
"base_dc": 10,
"cast_time": "standard",
"effects": [],
"description": "You ward the target to slow the advancement of its corruption, granting a +2 circumstance bonus on saving throws against the advancement of that corruption for 1 day per 2 caster levels. Will negates (harmless). Simplified: the engine has no corruption track and no self-buff encoding that preserves the pinned default-policy casting order, so no mechanical effect is applied."
}
+1
View File
@@ -5,6 +5,7 @@
"range": "personal",
"save": "none",
"base_dc": 10,
"cast_time": "one_round",
"effects": [],
"description": "A cantrip (casting time 1 round): you summon one handheld musical instrument of your choice into your hands or at your feet; it plays only for you and disappears when the spell ends (1 min./level). No combat effect: summoned objects are not modeled by the engine."
}
+1 -1
View File
@@ -5,7 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "1 round",
"cast_time": "one_round",
"effects": [
{
"type": "summon",
+1 -1
View File
@@ -5,7 +5,7 @@
"range": "close",
"save": "none",
"base_dc": 10,
"cast_time": "1 round",
"cast_time": "one_round",
"effects": [
{
"type": "summon",

Some files were not shown because too many files have changed in this diff Show More