import type { CharacterCombatAnimationEvent } from "../game/combatAnimation"; import type { ActiveCast, MobCombatState } from "../game/combatStore"; import type { DamageSchool } from "../game/combatAuras"; import type { InventoryItem } from "../game/lootTypes"; import type { PartyMember } from "../game/partyStore"; import type { OnlineGroupActivity, OnlineGroupCharacter } from "./onlineGroupTypes"; import type { PartyRole } from "../game/partyRoles"; import type { DungeonEncounterSnapshot } from "../game/dungeonEncounterTypes"; export type OnlineSessionVector = readonly [number, number, number]; export interface OnlineSessionPlayer { readonly accountId: string; readonly username: string; readonly character: OnlineGroupCharacter | null; readonly role: PartyRole | null; readonly position: OnlineSessionVector; readonly yaw: number; readonly grounded: boolean; readonly health: number; readonly maxHealth: number; readonly resource: number; readonly maxResource: number; readonly resourceName: string; readonly selectedTargetId: string | null; readonly activeCast: ActiveCast | null; readonly animationEvent: CharacterCombatAnimationEvent | null; readonly equipment: readonly InventoryItem[]; readonly updatedAt: number; } export interface OnlineMobTransform { readonly position: OnlineSessionVector; readonly yaw: number; } export interface OnlineSharedWorld { /** Identifies the package that owns encounter snapshots and prevents cross-dungeon hydration. */ readonly dungeonId?: string; readonly encounters?: readonly DungeonEncounterSnapshot[]; readonly mobs: Readonly>; readonly mobTransforms: Readonly>; readonly partyMembers: readonly PartyMember[]; readonly partyPositions: Readonly>; readonly partyRuntime: { readonly command: string; readonly activeMobId: string | null; readonly objectiveBossId: string | null; readonly memberTargetIds: Readonly>; }; readonly wailing: Readonly> | null; readonly manastorm: Readonly> | null; readonly publishedAt?: number; readonly publishedBy?: string; } export type OnlineRelayEventKind = "damage" | "healing" | "resurrection" | "loot" | "portal" | "interact" | "party-teleport"; export interface OnlineRelayEventInput { readonly clientEventId: string; readonly kind: OnlineRelayEventKind; readonly sourceActorId: string; readonly targetActorId: string; readonly abilityId?: string | null; readonly school?: DamageSchool | null; readonly rawAmount?: number; readonly effectiveAmount?: number; readonly critical?: boolean; readonly occurredAt?: number; readonly position?: OnlineSessionVector; } export interface OnlineRelayEvent extends OnlineRelayEventInput { readonly id: number; readonly sourceAccountId: string; readonly createdAt: number; } export interface OnlineSessionSnapshot { readonly activity: OnlineGroupActivity; readonly groupId: string; readonly leaderAccountId: string; readonly localAccountId: string; readonly authority: boolean; readonly revision: number; readonly serverTime: number; readonly players: readonly OnlineSessionPlayer[]; readonly world: OnlineSharedWorld | null; readonly events: readonly OnlineRelayEvent[]; readonly latestEventId: number; } export interface OnlinePresenceInput { readonly position: OnlineSessionVector; readonly yaw: number; readonly grounded: boolean; readonly health: number; readonly maxHealth: number; readonly resource: number; readonly maxResource: number; readonly resourceName: string; readonly selectedTargetId: string | null; readonly activeCast: ActiveCast | null; readonly animationEvent: CharacterCombatAnimationEvent | null; readonly equipment: readonly InventoryItem[]; } export interface OnlineSessionSyncInput { readonly afterEventId: number; readonly presence: OnlinePresenceInput; readonly world?: OnlineSharedWorld; readonly events?: readonly OnlineRelayEventInput[]; }