103 lines
3.4 KiB
TypeScript
103 lines
3.4 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
import type { OnlineSessionPlayer } from "../app/onlineSessionTypes";
|
|
import { useCombatStore } from "./combatStore";
|
|
import { clearMobRuntimeRegistry, registerMobRuntime } from "./mobRuntimeRegistry";
|
|
import {
|
|
configureOnlineSessionRuntime,
|
|
onlinePlayerActorId,
|
|
} from "./onlineSessionRuntime";
|
|
import {
|
|
clearPartyRuntimeRegistry,
|
|
registerPartyRuntimePosition,
|
|
} from "./partyRuntimeRegistry";
|
|
import { usePartyStore } from "./partyStore";
|
|
|
|
function remotePlayer(health = 1): OnlineSessionPlayer {
|
|
return {
|
|
accountId: "remote",
|
|
username: "Remote",
|
|
character: {
|
|
id: "remote-character",
|
|
name: "Bulwarka",
|
|
classId: "warrior",
|
|
categoryId: "wow",
|
|
raceId: "human",
|
|
gender: "female",
|
|
level: 20,
|
|
},
|
|
role: "tank",
|
|
position: [8, 0, 0],
|
|
yaw: 0,
|
|
grounded: true,
|
|
health,
|
|
maxHealth: 1_000,
|
|
resource: 0,
|
|
maxResource: 100,
|
|
resourceName: "Rage",
|
|
selectedTargetId: null,
|
|
activeCast: null,
|
|
animationEvent: null,
|
|
equipment: [],
|
|
updatedAt: 1,
|
|
};
|
|
}
|
|
|
|
beforeEach(() => {
|
|
clearMobRuntimeRegistry();
|
|
clearPartyRuntimeRegistry();
|
|
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 20 });
|
|
useCombatStore.getState().resetEncounter();
|
|
usePartyStore.setState({ members: [], selectedMemberId: null, selfSelected: false });
|
|
});
|
|
|
|
afterEach(() => {
|
|
configureOnlineSessionRuntime({ active: false, authority: true, localAccountId: null });
|
|
clearMobRuntimeRegistry();
|
|
clearPartyRuntimeRegistry();
|
|
});
|
|
|
|
describe("shared online combat actors", () => {
|
|
it("casts a normal player heal on a remote online player", () => {
|
|
const player = remotePlayer();
|
|
const actorId = onlinePlayerActorId(player.accountId);
|
|
configureOnlineSessionRuntime({
|
|
active: true,
|
|
authority: true,
|
|
localAccountId: "local",
|
|
players: [player],
|
|
});
|
|
registerPartyRuntimePosition(actorId, player.position);
|
|
useCombatStore.getState().synchronizeActors();
|
|
expect(useCombatStore.getState().selectFriendlyActor(actorId)).toBe(true);
|
|
expect(useCombatStore.getState().castAbility("wow335-priest-lesser-heal", [0, 0, 0], 1_000).ok).toBe(true);
|
|
const completion = useCombatStore.getState().activeCast?.completesAt ?? 1_000;
|
|
useCombatStore.getState().tick(0.1, completion);
|
|
expect(useCombatStore.getState().actors[actorId]?.health).toBeGreaterThan(1);
|
|
expect(useCombatStore.getState().combatEvents).toContainEqual(
|
|
expect.objectContaining({ kind: "healing", targetActorId: actorId }),
|
|
);
|
|
});
|
|
|
|
it("lets the leader's enemies acquire a nearby remote player", () => {
|
|
const player = { ...remotePlayer(1_000), position: [1, 0, 0] as const };
|
|
const actorId = onlinePlayerActorId(player.accountId);
|
|
configureOnlineSessionRuntime({
|
|
active: true,
|
|
authority: true,
|
|
localAccountId: "local",
|
|
players: [player],
|
|
});
|
|
registerPartyRuntimePosition(actorId, player.position);
|
|
registerMobRuntime("shared-enemy", [0, 0, 0]);
|
|
useCombatStore.getState().setPlayerPosition([100, 0, 100]);
|
|
useCombatStore.getState().registerMob("shared-enemy", {
|
|
name: "Shared enemy",
|
|
maxHealth: 100,
|
|
aggroRange: 5,
|
|
leashRange: 20,
|
|
});
|
|
expect(useCombatStore.getState().engageNearbyMobs(1_000)).toBe(1);
|
|
expect(useCombatStore.getState().mobs["shared-enemy"].targetActorId).toBe(actorId);
|
|
});
|
|
});
|