Files
i-want-to-heal-mmo/src/game/types.ts
T
2026-07-11 00:12:57 -04:00

169 lines
3.7 KiB
TypeScript

export type MemberId = "aelia" | "brann" | "nia" | "orin" | "vale";
export type AbilityId = "mend" | "renew" | "shield" | "purify" | "radiance" | "barrier";
export type BossId = "bulldrome" | "vexa" | "cindermaw" | "ember-mantis-duelist";
export type GamePhase = "briefing" | "combat" | "victory" | "defeat";
export type BottomTab = "combat" | "map" | "pack";
export type PulseKind = AbilityId | "boss" | "debuff" | "charge" | "pounce" | "tether" | "venom" | "breath" | "skyfall" | "slash";
export type BossMotionMode =
| "holding"
| "telegraph"
| "charging"
| "returning"
| "stacking"
| "pouncing"
| "tethering"
| "venom_cast"
| "breath_telegraph"
| "breath_sweeping"
| "skyfall"
| "mantis_sidestep"
| "mantis_line_telegraph"
| "mantis_cross_telegraph"
| "mantis_recover";
export type WorldPosition = [number, number];
export type CircleHazardKind = "venom_pool" | "skyfall";
export interface CircleHazard {
id: string;
kind: CircleHazardKind;
center: WorldPosition;
radius: number;
activatesAt: number;
expiresAt: number;
damage: number;
tickInterval?: number;
nextDamageAt: Partial<Record<MemberId, number>>;
resolved: boolean;
hitIds: MemberId[];
}
export interface SlashLane {
id: string;
start: WorldPosition;
end: WorldPosition;
width: number;
damage: number;
}
export interface Debuff {
id: string;
name: string;
expiresAt: number;
nextTickAt: number;
tickDamage: number;
}
export interface PartyMember {
id: MemberId;
name: string;
className: string;
role: "Healer" | "Tank" | "Damage";
color: string;
maxHp: number;
hp: number;
absorb: number;
renewExpiresAt: number;
renewNextTickAt: number;
knockedUntil: number;
debuffs: Debuff[];
}
export interface BossState {
id: BossId;
name: string;
maxHp: number;
hp: number;
nextMeleeAt: number;
nextNovaAt: number;
nextBrandAt: number;
brandCount: number;
}
export interface BossMotionState {
bossId: BossId;
formationOffsetX: number;
mode: BossMotionMode;
position: WorldPosition;
chargeStart: WorldPosition;
chargeEnd: WorldPosition;
chargeTargetId: MemberId;
chargeHitIds: MemberId[];
phaseEndsAt: number;
nextChargeAt: number;
chargeCount: number;
chargesSincePounce: number;
pounceTargetId: MemberId;
pounceCenter: WorldPosition;
pounceCount: number;
nextMechanicAt: number;
mechanicCount: number;
phaseStartedAt: number;
mechanicHitIds: MemberId[];
mechanicNextDamageAt: Partial<Record<MemberId, number>>;
tetherIds: MemberId[];
tetherBreakDistance: number;
breathAngle: number;
breathStartAngle: number;
breathEndAngle: number;
hazards: CircleHazard[];
slashLanes: SlashLane[];
}
export interface AbilityDefinition {
id: AbilityId;
name: string;
shortName: string;
key: string;
gamepad: string;
cooldown: number;
castTime?: number;
mana: number;
icon: string;
description: string;
targeting: "enemy" | "ally" | "party";
color: string;
}
export interface ActiveCast {
abilityId: "mend";
targetId: MemberId;
startedAt: number;
completesAt: number;
}
export interface BarrierState {
center: WorldPosition;
expiresAt: number;
}
export interface ScenePulse {
id: number;
kind: PulseKind;
targetId?: MemberId;
}
export interface InventoryItem {
id: string;
name: string;
slot: string;
rarity: "Common" | "Uncommon" | "Rare";
icon: string;
stats: string[];
effect: string;
equipped: boolean;
}
export type HealerClassId = "priest" | "druid" | "shaman";
export interface HealerClassDefinition {
id: HealerClassId;
name: string;
specialization: string;
icon: string;
color: string;
resourceName: string;
description: string;
abilities: Record<AbilityId, AbilityDefinition>;
}