feat(combat): skills system

This commit is contained in:
2026-09-04 22:55:41 +02:00
parent 223e10b88e
commit 842d5aee7e
4 changed files with 233 additions and 1 deletions
+34
View File
@@ -81,6 +81,7 @@ from typing import TYPE_CHECKING
from pf1e_simulator.conditions import CONDITIONS_BY_NAME
from pf1e_simulator.effects import ActiveBuff, ActiveCondition, StatModifier, resolve_modifiers
from pf1e_simulator.models import PREDEFINED_SKILLS
from pf1e_simulator.spells import (
BuffEffect,
ConditionEffect,
@@ -561,6 +562,39 @@ class CombatEngine:
success = roll != _NATURAL_ONE and (roll == _NATURAL_TWENTY or total >= dc)
return SaveResult(success=success, roll=roll, total=total, dc=dc)
def resolve_skill(
self, state: CombatantState, skill: str, dc: int
) -> SaveResult:
"""Roll a skill check against ``dc``.
"""
skill_spec = PREDEFINED_SKILLS.get(skill)
if skill_spec is None:
msg = f"Unknown skill: {skill}"
raise ValueError(msg)
roll = self._rng.d20()
skill_rank = state.combatant.skills.get(skill, None)
rank = skill_rank.rank if skill_rank else 0
# Class skill bonus
class_bonus = 3 if skill_rank and skill_rank.class_skill else 0
# Armor check penalty
armor_penalty = skill_rank.armor_penalty if skill_rank else 0
if armor_penalty and skill_spec.armor_check_penalty:
armor_penalty = -abs(armor_penalty)
else:
armor_penalty = 0
# Ability modifier
ability_name = skill_spec.ability
ability_score = getattr(state.combatant.abilities, f"{ability_name}_score")
ability_mod = (ability_score - 10) // 2
# Effect/condition modifiers
mod_bonus = resolve_modifiers(self._stat_modifiers(state, skill))
total = roll + rank + class_bonus + ability_mod + armor_penalty + mod_bonus
# Natural 1/20 are not auto-fail/success for skills
success = total >= dc
return SaveResult(success=success, roll=roll, total=total, dc=dc)
def _roll_initiative(self) -> list[CombatantState]:
rolls: dict[str, tuple[int, int]] = {}
for state in self._states: