Files
TheriapolisV3/Theriapolis.Core/Rules/Combat/AttackOption.cs
T
Christopher Wiebe b451f83174 Initial commit: Theriapolis baseline at port/godot branch point
Captures the pre-Godot-port state of the codebase. This is the rollback
anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md).
All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 20:40:51 -07:00

28 lines
1.3 KiB
C#

using Theriapolis.Core.Rules.Stats;
namespace Theriapolis.Core.Rules.Combat;
/// <summary>
/// One attack a combatant can attempt — a weapon, a natural attack, or an
/// NPC stat-block entry. Built once at combat-start; the resolver rolls
/// against it. Distinct from <see cref="AttackProfile"/>, which is the
/// per-attempt struct that bakes in attacker/defender/situation.
/// </summary>
public sealed record AttackOption
{
public string Name { get; init; } = "";
/// <summary>Total +N to add to the d20 attack roll.</summary>
public int ToHitBonus { get; init; }
public DamageRoll Damage { get; init; } = new(0, 0, 0, DamageType.Bludgeoning);
/// <summary>Reach in tactical tiles. 1 = 5 ft. melee; 2 = 10 ft. polearm or Large reach.</summary>
public int ReachTiles { get; init; } = 1;
/// <summary>Short-range tiles for ranged attacks (0 = melee-only).</summary>
public int RangeShortTiles { get; init; } = 0;
/// <summary>Long-range tiles (disadvantage past short, can't fire past long).</summary>
public int RangeLongTiles { get; init; } = 0;
/// <summary>Crit-range threshold (default 20; razored weapons crit on 19+).</summary>
public int CritOnNatural { get; init; } = 20;
public bool IsRanged => RangeShortTiles > 0;
}