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 = 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)); }