Release Healer Man 0.1.21

This commit is contained in:
phenom committed 2026-09-08 10:40:26 -04:00
1 parent 699fc858c9
commit f6f2375145
210 files changed
+976039 -6247

No files matched your search

+165
View File
@@ -0,0 +1,165 @@
import type { Vector3Tuple } from "./dungeonTypes";
export const DUNGEON_ENCOUNTER_SNAPSHOT_SCHEMA_VERSION = 1;
export type DungeonEncounterResetScope = "boss-wipe" | "checkpoint" | "dungeon";
export type DungeonEncounterValue = string | number | boolean;
export interface DungeonEncounterFacts {
readonly registeredEntityIds?: readonly string[];
readonly deadEntityIds?: readonly string[];
}
export type DungeonEncounterEvent =
| {
readonly kind: "tick";
readonly now: number;
readonly facts?: DungeonEncounterFacts;
}
| {
readonly kind: "signal";
readonly now: number;
readonly signalId: string;
readonly sourceEntityId?: string;
}
| { readonly kind: "entity-engaged"; readonly now: number; readonly entityId: string }
| { readonly kind: "entity-death"; readonly now: number; readonly entityId: string }
| {
readonly kind: "entity-health";
readonly now: number;
readonly entityId: string;
readonly healthPercent: number;
}
| {
readonly kind: "interact";
readonly now: number;
readonly objectId: string;
readonly actorId?: string;
};
export type DungeonEncounterTrigger =
| { readonly kind: "tick" }
| { readonly kind: "signal"; readonly signalId: string }
| { readonly kind: "entity-engaged"; readonly entityId: string }
| { readonly kind: "entity-death"; readonly entityId: string }
| {
readonly kind: "entity-health";
readonly entityId: string;
readonly atOrBelowPercent: number;
}
| { readonly kind: "interact"; readonly objectId: string }
| { readonly kind: "elapsed"; readonly afterMs: number }
| {
readonly kind: "entities-dead";
readonly entityIds: readonly string[];
/** A source-authored safety timeout prevents an encounter from soft locking. */
readonly timeoutMs?: number;
};
export type DungeonEncounterGuard =
| { readonly kind: "phase"; readonly phases: readonly string[] }
| { readonly kind: "flag"; readonly flagId: string; readonly equals: boolean }
| {
readonly kind: "counter";
readonly counterId: string;
readonly comparison: "equal" | "at-least" | "at-most";
readonly value: number;
}
| { readonly kind: "objective-complete"; readonly objectiveId: string; readonly equals: boolean }
| { readonly kind: "spawn-group-active"; readonly spawnGroupId: string; readonly equals: boolean }
| { readonly kind: "world-object-state"; readonly objectId: string; readonly states: readonly string[] };
export type DungeonEncounterActionPersistence = "attempt" | "checkpoint" | "run";
interface DungeonEncounterActionBase {
/** Stable, encounter-local id used to make rule execution idempotent. */
readonly id: string;
readonly persistence?: DungeonEncounterActionPersistence;
}
export type DungeonEncounterAction =
| (DungeonEncounterActionBase & { readonly kind: "set-phase"; readonly phase: string })
| (DungeonEncounterActionBase & { readonly kind: "set-flag"; readonly flagId: string; readonly value: boolean })
| (DungeonEncounterActionBase & { readonly kind: "set-counter"; readonly counterId: string; readonly value: number })
| (DungeonEncounterActionBase & { readonly kind: "increment-counter"; readonly counterId: string; readonly amount?: number })
| (DungeonEncounterActionBase & { readonly kind: "start-timer"; readonly timerId: string; readonly durationMs: number })
| (DungeonEncounterActionBase & { readonly kind: "clear-timer"; readonly timerId: string })
| (DungeonEncounterActionBase & { readonly kind: "activate-spawn-group"; readonly spawnGroupId: string })
| (DungeonEncounterActionBase & { readonly kind: "deactivate-spawn-group"; readonly spawnGroupId: string })
| (DungeonEncounterActionBase & { readonly kind: "set-world-object-state"; readonly objectId: string; readonly state: string })
| (DungeonEncounterActionBase & { readonly kind: "set-transition-active"; readonly transitionId: string; readonly active: boolean })
| (DungeonEncounterActionBase & { readonly kind: "complete-objective"; readonly objectiveId: string })
| (DungeonEncounterActionBase & { readonly kind: "set-checkpoint"; readonly checkpointId: string })
| (DungeonEncounterActionBase & { readonly kind: "teleport-party"; readonly destination: Vector3Tuple })
| (DungeonEncounterActionBase & { readonly kind: "grant-loot"; readonly lootTableId: string })
| (DungeonEncounterActionBase & { readonly kind: "emit-signal"; readonly signalId: string });
export interface DungeonEncounterRule {
readonly id: string;
readonly trigger: DungeonEncounterTrigger;
readonly guards?: readonly DungeonEncounterGuard[];
readonly actions: readonly DungeonEncounterAction[];
/** Defaults to true. Repeatable rules must remain safe when evaluated again. */
readonly once?: boolean;
readonly priority?: number;
}
export interface DungeonEncounterInitialState {
readonly flags?: Readonly<Record<string, boolean>>;
readonly counters?: Readonly<Record<string, number>>;
readonly worldObjectStates?: Readonly<Record<string, string>>;
readonly transitionStates?: Readonly<Record<string, boolean>>;
}
export interface DungeonEncounterResetPolicy {
readonly bossWipePhase?: string;
readonly checkpointPhase?: string;
}
export interface DungeonEncounterDefinition {
readonly id: string;
readonly dungeonId: string;
readonly initialPhase: string;
readonly initialState?: DungeonEncounterInitialState;
readonly resetPolicy?: DungeonEncounterResetPolicy;
readonly rules: readonly DungeonEncounterRule[];
}
/** JSON-safe source of truth; renderer objects and callbacks never enter this state. */
export interface DungeonEncounterSnapshot {
readonly schemaVersion: typeof DUNGEON_ENCOUNTER_SNAPSHOT_SCHEMA_VERSION;
readonly encounterId: string;
readonly phase: string;
readonly phaseStartedAt: number;
readonly flags: Readonly<Record<string, boolean>>;
readonly counters: Readonly<Record<string, number>>;
readonly timers: Readonly<Record<string, number>>;
readonly worldObjectStates: Readonly<Record<string, string>>;
readonly transitionStates: Readonly<Record<string, boolean>>;
readonly activeSpawnGroupIds: readonly string[];
readonly completedObjectiveIds: readonly string[];
readonly consumedActionIds: readonly string[];
readonly checkpointId: string | null;
readonly revision: number;
}
export type DungeonEncounterEffect =
| { readonly kind: "spawn-group"; readonly actionId: string; readonly spawnGroupId: string }
| { readonly kind: "despawn-group"; readonly actionId: string; readonly spawnGroupId: string }
| { readonly kind: "world-object-state"; readonly actionId: string; readonly objectId: string; readonly state: string }
| { readonly kind: "transition-state"; readonly actionId: string; readonly transitionId: string; readonly active: boolean }
| { readonly kind: "party-teleport"; readonly actionId: string; readonly destination: Vector3Tuple }
| { readonly kind: "loot-grant"; readonly actionId: string; readonly lootTableId: string }
| { readonly kind: "signal"; readonly actionId: string; readonly signalId: string };
export interface DungeonEncounterReduction {
readonly snapshot: DungeonEncounterSnapshot;
readonly effects: readonly DungeonEncounterEffect[];
readonly firedRuleIds: readonly string[];
}
export interface DungeonEncounterEffectEnvelope {
readonly dungeonId: string;
readonly encounterId: string;
readonly effect: DungeonEncounterEffect;
}