namespace Theriapolis.Core.Rules.Stats; /// /// Body-size category from clades.md. Determines tactical-tile footprint, /// reach, equipment fit, and grappling rules. /// public enum SizeCategory : byte { Tiny = 0, // reserved; no Phase 5 species uses this Small = 1, // rabbit-folk, housecat-folk, ferret-folk Medium = 2, // fox-folk, deer-folk, sheep-folk, goat-folk, leopard-folk, badger-folk, hare-folk MediumLarge = 3, // wolf-folk, elk-folk, lion-folk, wolverine-folk, coyote-folk Large = 4, // brown bear-folk, polar bear-folk, moose-folk, bull-folk, bison-folk Huge = 5, // reserved; no Phase 5 species uses this } public static class SizeExtensions { /// Tactical-tile footprint per side (1 = 1×1, 2 = 2×2). public static int FootprintTiles(this SizeCategory s) => s switch { SizeCategory.Tiny => 1, SizeCategory.Small => 1, SizeCategory.Medium => 1, SizeCategory.MediumLarge => 1, // counts as Large for grappling/carrying only SizeCategory.Large => 2, SizeCategory.Huge => 3, _ => throw new ArgumentOutOfRangeException(nameof(s)), }; /// Default melee reach in tactical tiles (weapon-modifiable). public static int DefaultReachTiles(this SizeCategory s) => s switch { SizeCategory.Tiny => 1, SizeCategory.Small => 1, SizeCategory.Medium => 1, SizeCategory.MediumLarge => 1, SizeCategory.Large => 2, SizeCategory.Huge => 3, _ => throw new ArgumentOutOfRangeException(nameof(s)), }; /// Carrying-capacity multiplier per equipment.md (Small ½×, Large 2×). public static float CarryCapacityMult(this SizeCategory s) => s switch { SizeCategory.Tiny => 0.25f, SizeCategory.Small => 0.5f, SizeCategory.Medium => 1.0f, SizeCategory.MediumLarge => 1.0f, // Medium frame, Large for grappling SizeCategory.Large => 2.0f, SizeCategory.Huge => 4.0f, _ => throw new ArgumentOutOfRangeException(nameof(s)), }; /// Parses a snake_case JSON value (e.g. "medium_large") into a SizeCategory. public static SizeCategory FromJson(string? raw) => raw switch { "tiny" => SizeCategory.Tiny, "small" => SizeCategory.Small, "medium" => SizeCategory.Medium, "medium_large" => SizeCategory.MediumLarge, "large" => SizeCategory.Large, "huge" => SizeCategory.Huge, _ => throw new ArgumentException($"Unknown size category: '{raw}'"), }; }