Add PF2e weak/elite creature adjustments with stat block toggle
Weak/Normal/Elite toggle in PF2e stat block header applies standard adjustments (level, AC, HP, saves, Perception, attacks, damage) to individual combatants. Adjusted stats are highlighted blue (elite) or red (weak). Persisted via creatureAdjustment field on Combatant. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,17 @@
|
||||
import type { Creature, CreatureId } from "@initiative/domain";
|
||||
import type {
|
||||
AnyCreature,
|
||||
Combatant,
|
||||
CombatantId,
|
||||
Creature,
|
||||
CreatureId,
|
||||
Pf2eCreature,
|
||||
} from "@initiative/domain";
|
||||
import { applyPf2eAdjustment } from "@initiative/domain";
|
||||
import { PanelRightClose, Pin, PinOff } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useBestiaryContext } from "../contexts/bestiary-context.js";
|
||||
import { useEncounterContext } from "../contexts/encounter-context.js";
|
||||
import { useSidePanelContext } from "../contexts/side-panel-context.js";
|
||||
import { useSwipeToDismiss } from "../hooks/use-swipe-to-dismiss.js";
|
||||
import { cn } from "../lib/utils.js";
|
||||
@@ -216,6 +225,7 @@ function MobileDrawer({
|
||||
function usePanelRole(panelRole: "browse" | "pinned") {
|
||||
const sidePanel = useSidePanelContext();
|
||||
const { getCreature } = useBestiaryContext();
|
||||
const { encounter, setCreatureAdjustment } = useEncounterContext();
|
||||
|
||||
const creatureId =
|
||||
panelRole === "browse"
|
||||
@@ -223,10 +233,18 @@ function usePanelRole(panelRole: "browse" | "pinned") {
|
||||
: sidePanel.pinnedCreatureId;
|
||||
const creature = creatureId ? (getCreature(creatureId) ?? null) : null;
|
||||
|
||||
const combatantId =
|
||||
panelRole === "browse" ? sidePanel.selectedCombatantId : null;
|
||||
const combatant = combatantId
|
||||
? (encounter.combatants.find((c) => c.id === combatantId) ?? null)
|
||||
: null;
|
||||
|
||||
const isBrowse = panelRole === "browse";
|
||||
return {
|
||||
creatureId,
|
||||
creature,
|
||||
combatant,
|
||||
setCreatureAdjustment,
|
||||
isCollapsed: isBrowse ? sidePanel.isRightPanelCollapsed : false,
|
||||
onToggleCollapse: isBrowse ? sidePanel.toggleCollapse : () => {},
|
||||
onDismiss: isBrowse ? sidePanel.dismissPanel : () => {},
|
||||
@@ -238,6 +256,33 @@ function usePanelRole(panelRole: "browse" | "pinned") {
|
||||
};
|
||||
}
|
||||
|
||||
function renderStatBlock(
|
||||
creature: AnyCreature,
|
||||
combatant: Combatant | null,
|
||||
setCreatureAdjustment: (
|
||||
id: CombatantId,
|
||||
adj: "weak" | "elite" | undefined,
|
||||
base: Pf2eCreature,
|
||||
) => void,
|
||||
) {
|
||||
if ("system" in creature && creature.system === "pf2e") {
|
||||
const baseCreature = creature;
|
||||
const adjusted = combatant?.creatureAdjustment
|
||||
? applyPf2eAdjustment(baseCreature, combatant.creatureAdjustment)
|
||||
: baseCreature;
|
||||
return (
|
||||
<Pf2eStatBlock
|
||||
creature={adjusted}
|
||||
adjustment={combatant?.creatureAdjustment}
|
||||
combatantId={combatant?.id}
|
||||
baseCreature={baseCreature}
|
||||
onSetAdjustment={setCreatureAdjustment}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <DndStatBlock creature={creature as Creature} />;
|
||||
}
|
||||
|
||||
export function StatBlockPanel({
|
||||
panelRole,
|
||||
side,
|
||||
@@ -245,6 +290,8 @@ export function StatBlockPanel({
|
||||
const {
|
||||
creatureId,
|
||||
creature,
|
||||
combatant,
|
||||
setCreatureAdjustment,
|
||||
isCollapsed,
|
||||
onToggleCollapse,
|
||||
onDismiss,
|
||||
@@ -316,10 +363,7 @@ export function StatBlockPanel({
|
||||
}
|
||||
|
||||
if (creature) {
|
||||
if ("system" in creature && creature.system === "pf2e") {
|
||||
return <Pf2eStatBlock creature={creature} />;
|
||||
}
|
||||
return <DndStatBlock creature={creature as Creature} />;
|
||||
return renderStatBlock(creature, combatant, setCreatureAdjustment);
|
||||
}
|
||||
|
||||
if (needsFetch && sourceCode) {
|
||||
|
||||
Reference in New Issue
Block a user