Cap dying (4), doomed (3), wounded (3), and slowed (3) at their rule-defined maximums. The domain clamps values in setConditionValue and the condition picker disables the [+] button at the cap. Closes #31 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
535 lines
15 KiB
TypeScript
535 lines
15 KiB
TypeScript
export type ConditionId =
|
||
| "blinded"
|
||
| "charmed"
|
||
| "clumsy"
|
||
| "concealed"
|
||
| "confused"
|
||
| "controlled"
|
||
| "dazzled"
|
||
| "deafened"
|
||
| "doomed"
|
||
| "drained"
|
||
| "dying"
|
||
| "enfeebled"
|
||
| "exhaustion"
|
||
| "fascinated"
|
||
| "fatigued"
|
||
| "fleeing"
|
||
| "frightened"
|
||
| "grabbed"
|
||
| "grappled"
|
||
| "hidden"
|
||
| "immobilized"
|
||
| "incapacitated"
|
||
| "invisible"
|
||
| "off-guard"
|
||
| "paralyzed"
|
||
| "petrified"
|
||
| "poisoned"
|
||
| "prone"
|
||
| "quickened"
|
||
| "restrained"
|
||
| "sapped"
|
||
| "sickened"
|
||
| "slowed"
|
||
| "slowed-pf2e"
|
||
| "stunned"
|
||
| "stupefied"
|
||
| "unconscious"
|
||
| "undetected"
|
||
| "wounded";
|
||
|
||
export interface ConditionEntry {
|
||
readonly id: ConditionId;
|
||
readonly value?: number;
|
||
}
|
||
|
||
import type { RulesEdition } from "./rules-edition.js";
|
||
|
||
export interface ConditionDefinition {
|
||
readonly id: ConditionId;
|
||
readonly label: string;
|
||
readonly description: string;
|
||
readonly description5e: string;
|
||
readonly descriptionPf2e?: string;
|
||
readonly iconName: string;
|
||
readonly color: string;
|
||
/** When set, the condition only appears in these systems' pickers. */
|
||
readonly systems?: readonly RulesEdition[];
|
||
readonly valued?: boolean;
|
||
/** Rule-defined maximum value for PF2e valued conditions. */
|
||
readonly maxValue?: number;
|
||
}
|
||
|
||
export function getConditionDescription(
|
||
def: ConditionDefinition,
|
||
edition: RulesEdition,
|
||
): string {
|
||
if (edition === "pf2e" && def.descriptionPf2e) return def.descriptionPf2e;
|
||
return edition === "5e" ? def.description5e : def.description;
|
||
}
|
||
|
||
export const CONDITION_DEFINITIONS: readonly ConditionDefinition[] = [
|
||
// ── Shared conditions (D&D + PF2e) ──
|
||
{
|
||
id: "blinded",
|
||
label: "Blinded",
|
||
description:
|
||
"Can't see. Auto-fail sight checks. Attacks have Disadvantage; attacks against have Advantage.",
|
||
description5e:
|
||
"Can't see. Auto-fail sight checks. Attacks have Disadvantage; attacks against have Advantage.",
|
||
descriptionPf2e:
|
||
"Can't see. All terrain is difficult terrain. Auto-fail checks requiring sight. Immune to visual effects. Overrides dazzled.",
|
||
iconName: "EyeOff",
|
||
color: "neutral",
|
||
},
|
||
{
|
||
id: "charmed",
|
||
label: "Charmed",
|
||
description:
|
||
"Can't attack or target the charmer with harmful abilities. Charmer has Advantage on social checks.",
|
||
description5e:
|
||
"Can't attack or target the charmer with harmful abilities. Charmer has Advantage on social checks.",
|
||
iconName: "Heart",
|
||
color: "pink",
|
||
systems: ["5e", "5.5e"],
|
||
},
|
||
{
|
||
id: "deafened",
|
||
label: "Deafened",
|
||
description: "Can't hear. Auto-fail hearing checks.",
|
||
description5e: "Can't hear. Auto-fail hearing checks.",
|
||
descriptionPf2e:
|
||
"Can't hear. Auto-critically-fail hearing checks. –2 status penalty to Perception. Auditory actions require DC 5 flat check. Immune to auditory effects.",
|
||
iconName: "EarOff",
|
||
color: "neutral",
|
||
},
|
||
{
|
||
id: "exhaustion",
|
||
label: "Exhaustion",
|
||
description:
|
||
"D20 Tests reduced by 2 \u00D7 exhaustion level.\nSpeed reduced by 5 ft. \u00D7 level.\nLong rest removes 1 level.\nDeath at 6 levels.",
|
||
description5e:
|
||
"L1: Disadvantage on ability checks\nL2: Speed halved\nL3: Disadvantage on attacks and saves\nL4: HP max halved\nL5: Speed 0\nL6: Death\nLong rest removes 1 level.",
|
||
iconName: "BatteryLow",
|
||
color: "amber",
|
||
systems: ["5e", "5.5e"],
|
||
},
|
||
{
|
||
id: "frightened",
|
||
label: "Frightened",
|
||
description:
|
||
"Disadvantage on ability checks and attacks while source of fear is in line of sight. Can't willingly move closer to the source.",
|
||
description5e:
|
||
"Disadvantage on ability checks and attacks while source of fear is in line of sight. Can't willingly move closer to the source.",
|
||
descriptionPf2e:
|
||
"–X status penalty to all checks and DCs (X = value). Can't willingly approach the source.",
|
||
iconName: "Siren",
|
||
color: "orange",
|
||
valued: true,
|
||
},
|
||
{
|
||
id: "grappled",
|
||
label: "Grappled",
|
||
description:
|
||
"Speed 0. Disadvantage on attacks against targets other than the grappler. Grappler can drag you (extra movement cost). Ends if grappler is Incapacitated or you leave their reach.",
|
||
description5e:
|
||
"Speed 0. Ends if grappler is Incapacitated or moved out of reach.",
|
||
iconName: "Hand",
|
||
color: "neutral",
|
||
systems: ["5e", "5.5e"],
|
||
},
|
||
{
|
||
id: "incapacitated",
|
||
label: "Incapacitated",
|
||
description:
|
||
"Can't take Actions, Bonus Actions, or Reactions. Can't speak. Concentration is broken. Disadvantage on Initiative.",
|
||
description5e: "Can't take Actions or Reactions.",
|
||
iconName: "Ban",
|
||
color: "gray",
|
||
systems: ["5e", "5.5e"],
|
||
},
|
||
{
|
||
id: "invisible",
|
||
label: "Invisible",
|
||
description:
|
||
"Can't be seen. Advantage on Initiative. Not affected by effects requiring sight (unless caster sees you). Attacks have Advantage; attacks against have Disadvantage.",
|
||
description5e:
|
||
"Impossible to see without magic or special sense. Heavily Obscured. Attacks have Advantage; attacks against have Disadvantage.",
|
||
descriptionPf2e:
|
||
"Can't be seen except by special senses. Undetected to everyone. Can't be targeted except by effects that don't require sight.",
|
||
iconName: "Ghost",
|
||
color: "violet",
|
||
},
|
||
{
|
||
id: "paralyzed",
|
||
label: "Paralyzed",
|
||
description:
|
||
"Incapacitated. Can't move or speak. Auto-fail Str/Dex saves. Attacks against have Advantage. Hits within 5 ft. are critical.",
|
||
description5e:
|
||
"Incapacitated. Can't move or speak. Auto-fail Str/Dex saves. Attacks against have Advantage. Hits within 5 ft. are critical.",
|
||
descriptionPf2e:
|
||
"Can't act. Off-guard. Can only Recall Knowledge or use mental actions.",
|
||
iconName: "ZapOff",
|
||
color: "yellow",
|
||
},
|
||
{
|
||
id: "petrified",
|
||
label: "Petrified",
|
||
description:
|
||
"Turned to stone. Weight \u00D710. Incapacitated. Can't move or speak. Attacks against have Advantage. Auto-fail Str/Dex saves. Resistant to all damage. Immune to poison and disease.",
|
||
description5e:
|
||
"Turned to stone. Weight \u00D710. Incapacitated. Can't move or speak. Attacks against have Advantage. Auto-fail Str/Dex saves. Resistant to all damage. Immune to poison and disease.",
|
||
descriptionPf2e:
|
||
"Can't act. Can't sense anything. AC = 9. Hardness 8. Immune to most effects.",
|
||
iconName: "Gem",
|
||
color: "slate",
|
||
},
|
||
{
|
||
id: "poisoned",
|
||
label: "Poisoned",
|
||
description: "Disadvantage on attack rolls and ability checks.",
|
||
description5e: "Disadvantage on attack rolls and ability checks.",
|
||
iconName: "Droplet",
|
||
color: "green",
|
||
systems: ["5e", "5.5e"],
|
||
},
|
||
{
|
||
id: "prone",
|
||
label: "Prone",
|
||
description:
|
||
"Can only crawl (costs extra movement). Disadvantage on attacks. Attacks within 5 ft. have Advantage; ranged attacks have Disadvantage. Standing up costs half movement.",
|
||
description5e:
|
||
"Can only crawl (costs extra movement). Disadvantage on attacks. Attacks within 5 ft. have Advantage; ranged attacks have Disadvantage. Standing up costs half movement.",
|
||
descriptionPf2e:
|
||
"Off-guard. –2 circumstance penalty to attack rolls. Only movement is Crawl and Stand. +1 circumstance bonus to AC vs. ranged attacks, –2 vs. melee.",
|
||
iconName: "ArrowDown",
|
||
color: "neutral",
|
||
},
|
||
{
|
||
id: "restrained",
|
||
label: "Restrained",
|
||
description:
|
||
"Speed is 0. Attacks have Disadvantage. Attacks against have Advantage. Disadvantage on Dex saves.",
|
||
description5e:
|
||
"Speed is 0. Attacks have Disadvantage. Attacks against have Advantage. Disadvantage on Dex saves.",
|
||
descriptionPf2e:
|
||
"Off-guard. Immobilized. Can't use any actions with the attack trait except to attempt to Escape.",
|
||
iconName: "Link",
|
||
color: "neutral",
|
||
},
|
||
{
|
||
id: "sapped",
|
||
label: "Sapped",
|
||
description:
|
||
"Disadvantage on next attack roll before the start of your next turn. (Weapon Mastery: Sap)",
|
||
description5e: "",
|
||
iconName: "ShieldMinus",
|
||
color: "amber",
|
||
systems: ["5.5e"],
|
||
},
|
||
{
|
||
id: "slowed",
|
||
label: "Slowed",
|
||
description:
|
||
"Speed reduced by 10 ft. until the start of your next turn. (Weapon Mastery: Slow)",
|
||
description5e: "",
|
||
iconName: "Snail",
|
||
color: "sky",
|
||
systems: ["5.5e"],
|
||
},
|
||
{
|
||
id: "stunned",
|
||
label: "Stunned",
|
||
description:
|
||
"Incapacitated (can't act or speak). Auto-fail Str/Dex saves. Attacks against have Advantage.",
|
||
description5e:
|
||
"Incapacitated. Can't move. Can speak only falteringly. Auto-fail Str/Dex saves. Attacks against have Advantage.",
|
||
descriptionPf2e:
|
||
"Can't act. Lose X total actions across turns, then the condition ends. Overrides slowed.",
|
||
iconName: "Sparkles",
|
||
color: "yellow",
|
||
valued: true,
|
||
},
|
||
{
|
||
id: "unconscious",
|
||
label: "Unconscious",
|
||
description:
|
||
"Incapacitated. Speed 0. Can't move or speak. Unaware of surroundings. Drops held items, falls Prone. Auto-fail Str/Dex saves. Attacks against have Advantage. Hits within 5 ft. are critical.",
|
||
description5e:
|
||
"Incapacitated. Speed 0. Can't move or speak. Unaware of surroundings. Drops held items, falls Prone. Auto-fail Str/Dex saves. Attacks against have Advantage. Hits within 5 ft. are critical.",
|
||
descriptionPf2e:
|
||
"Can't act. Off-guard. Blinded. –4 status penalty to AC, Perception, and Reflex saves. Fall prone, drop items.",
|
||
iconName: "Moon",
|
||
color: "indigo",
|
||
},
|
||
// ── PF2e-only conditions ──
|
||
{
|
||
id: "clumsy",
|
||
label: "Clumsy",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"–X status penalty to Dex-based checks and DCs, including AC, Reflex saves, and ranged attack rolls.",
|
||
iconName: "Footprints",
|
||
color: "amber",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
},
|
||
{
|
||
id: "concealed",
|
||
label: "Concealed",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"DC 5 flat check for targeted attacks. Doesn't change which creatures can see you.",
|
||
iconName: "CloudFog",
|
||
color: "slate",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "confused",
|
||
label: "Confused",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Off-guard. Can't Delay, Ready, or use reactions. Must Strike or cast offensive cantrips at random targets. DC 11 flat check when damaged to end.",
|
||
iconName: "CircleHelp",
|
||
color: "pink",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "controlled",
|
||
label: "Controlled",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Another creature determines your actions. You gain no actions of your own.",
|
||
iconName: "Drama",
|
||
color: "pink",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "dazzled",
|
||
label: "Dazzled",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"All creatures and objects are concealed to you. DC 5 flat check for targeted attacks requiring sight.",
|
||
iconName: "Sun",
|
||
color: "yellow",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "doomed",
|
||
label: "Doomed",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Die at dying X (where X = 4 – doomed value instead of dying 4). Decreases by 1 on full night's rest.",
|
||
iconName: "Skull",
|
||
color: "red",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
maxValue: 3,
|
||
},
|
||
{
|
||
id: "drained",
|
||
label: "Drained",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"–X status penalty to Con-based checks and DCs. Lose X × level in max HP. Decreases by 1 on full night's rest.",
|
||
iconName: "Droplets",
|
||
color: "red",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
},
|
||
{
|
||
id: "dying",
|
||
label: "Dying",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Unconscious. Make recovery checks at start of turn. At dying 4 (or 4 – doomed), you die.",
|
||
iconName: "HeartPulse",
|
||
color: "red",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
maxValue: 4,
|
||
},
|
||
{
|
||
id: "enfeebled",
|
||
label: "Enfeebled",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"–X status penalty to Str-based rolls and DCs, including melee attack and damage rolls and Athletics checks.",
|
||
iconName: "TrendingDown",
|
||
color: "amber",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
},
|
||
{
|
||
id: "fascinated",
|
||
label: "Fascinated",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"–2 status penalty to Perception and skill checks. Can't use concentrate actions unless related to the fascination. Ends if hostile action is used against you or allies.",
|
||
iconName: "Eye",
|
||
color: "violet",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "fatigued",
|
||
label: "Fatigued",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"–1 status penalty to AC and saves. Can't use exploration activities while traveling. Recover after a full night's rest.",
|
||
iconName: "BatteryLow",
|
||
color: "amber",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "fleeing",
|
||
label: "Fleeing",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Must spend actions to move away from the source. Can't Delay or Ready.",
|
||
iconName: "PersonStanding",
|
||
color: "orange",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "grabbed",
|
||
label: "Grabbed",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Off-guard. Immobilized. Manipulate actions require DC 5 flat check or are wasted.",
|
||
iconName: "Hand",
|
||
color: "neutral",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "hidden",
|
||
label: "Hidden",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Known location but can't be seen. Off-guard to that creature. DC 11 flat check to target or miss.",
|
||
iconName: "EyeOff",
|
||
color: "slate",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "immobilized",
|
||
label: "Immobilized",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Can't use any action with the move trait to change position.",
|
||
iconName: "Anchor",
|
||
color: "neutral",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "off-guard",
|
||
label: "Off-Guard",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e: "–2 circumstance penalty to AC. (Formerly flat-footed.)",
|
||
iconName: "ShieldOff",
|
||
color: "amber",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "quickened",
|
||
label: "Quickened",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Gain 1 extra action at the start of your turn each round (limited uses specified by the effect).",
|
||
iconName: "Zap",
|
||
color: "green",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "sickened",
|
||
label: "Sickened",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"–X status penalty to all checks and DCs. Can't willingly ingest anything. Reduce by retching (Fortitude save).",
|
||
iconName: "Droplet",
|
||
color: "green",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
},
|
||
{
|
||
id: "slowed-pf2e",
|
||
label: "Slowed",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e: "Lose X actions at the start of your turn each round.",
|
||
iconName: "Snail",
|
||
color: "sky",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
maxValue: 3,
|
||
},
|
||
{
|
||
id: "stupefied",
|
||
label: "Stupefied",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"–X status penalty to Int/Wis/Cha-based checks and DCs, including spell attack rolls and spell DCs. DC 5 + X flat check to cast spells or lose the spell.",
|
||
iconName: "BrainCog",
|
||
color: "violet",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
},
|
||
{
|
||
id: "undetected",
|
||
label: "Undetected",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Location unknown. Must pick a square to target; DC 11 flat check. Attacker is off-guard against your attacks.",
|
||
iconName: "Ghost",
|
||
color: "violet",
|
||
systems: ["pf2e"],
|
||
},
|
||
{
|
||
id: "wounded",
|
||
label: "Wounded",
|
||
description: "",
|
||
description5e: "",
|
||
descriptionPf2e:
|
||
"Next time you gain dying, add wounded value to dying value. Wounded 1 when you recover from dying; increases if already wounded.",
|
||
iconName: "HeartCrack",
|
||
color: "red",
|
||
systems: ["pf2e"],
|
||
valued: true,
|
||
maxValue: 3,
|
||
},
|
||
] as const;
|
||
|
||
export const VALID_CONDITION_IDS: ReadonlySet<string> = new Set(
|
||
CONDITION_DEFINITIONS.map((d) => d.id),
|
||
);
|
||
|
||
export function getConditionsForEdition(
|
||
edition: RulesEdition,
|
||
): readonly ConditionDefinition[] {
|
||
return CONDITION_DEFINITIONS.filter(
|
||
(d) => d.systems === undefined || d.systems.includes(edition),
|
||
)
|
||
.slice()
|
||
.sort((a, b) => a.label.localeCompare(b.label));
|
||
}
|