feat(combat): skills system
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user