Split The code is public; the app answers only to the crew.
A resumed match comes back on the map it was played on: `restoreWorld` reads the save, not a default #170
Check · Review · Land · Live done — Landed and live in production.
scout/cs:scout/161-a-resumed-match-comes-back-on-the-map-it → main 1 commit fork
2 files
changed +11
−3
src/client/world.test.ts +9
| @@ -693,6 +693,15 @@ test("a restored round leaves bot money alone", () => { | ||
| 693 | 693 | for (const p of restored.players) if (p.bot) expect(p.money).toBe(5000); |
| 694 | 694 | }); |
| 695 | 695 | |
| 696 | test("restoreWorld builds on the map the snapshot was played on, not the default", () => { | |
| 697 | const world = createWorld(SHORT, "me", "ct", 5, 401, "normal", MAPS.de_cinder); | |
| 698 | const saved = snapshot(world, crypto.randomUUID()); | |
| 699 | const restored = restoreWorld(saved); | |
| 700 | expect(restored).not.toBeNull(); | |
| 701 | if (restored === null) return; | |
| 702 | expect(restored.map.name).toBe("de_cinder"); | |
| 703 | }); | |
| 704 | ||
| 696 | 705 | test("a snapshot whose player count does not match the team size is refused before it can build half a world", () => { |
| 697 | 706 | const world = createWorld(SHORT, "me", "ct", 5, 501); |
| 698 | 707 | const saved = snapshot(world, crypto.randomUUID()); |
src/client/world.ts +2 −3
| @@ -14,7 +14,7 @@ import { | ||
| 14 | 14 | blastDamage, GRENADE, step as stepGrenade, thrown, type Grenade, |
| 15 | 15 | } from "./grenades.ts"; |
| 16 | 16 | import { pose, remember, rememberPos, type Pose } from "./interpolate.ts"; |
| 17 | import { DE_FORGE, siteAt, type MapDef } from "./map.ts"; | |
| 17 | import { DE_FORGE, MAPS, siteAt, type MapDef } from "./map.ts"; | |
| 18 | 18 | export { DEFAULT_MAP, MAP_NAMES, mapFor } from "./map.ts"; |
| 19 | 19 | import { angleVectors, angleDelta, clamp, dist, dist2d, normalize, rng, sub, type Vec3 } from "./math.ts"; |
| 20 | 20 | import * as rules from "./match.ts"; |
| @@ -333,13 +333,12 @@ const RESTORE_TEAM_SIZE = 5; | ||
| 333 | 333 | export function restoreWorld( |
| 334 | 334 | save: Saved, |
| 335 | 335 | difficulty: Difficulty = DEFAULT_DIFFICULTY, |
| 336 | map: MapDef = DE_FORGE, | |
| 337 | 336 | ): World | null { |
| 338 | 337 | if (save.players.length !== RESTORE_TEAM_SIZE * 2) return null; |
| 339 | 338 | if (save.score.t >= save.rules.winScore || save.score.ct >= save.rules.winScore) return null; |
| 340 | 339 | const pastHalf = save.round > rules.halfTime(save.rules); |
| 341 | 340 | const startTeam = pastHalf ? rules.other(save.playerTeam) : save.playerTeam; |
| 342 | const world = buildWorld(save.rules, save.name, startTeam, RESTORE_TEAM_SIZE, save.seed, difficulty, map); | |
| 341 | const world = buildWorld(save.rules, save.name, startTeam, RESTORE_TEAM_SIZE, save.seed, difficulty, MAPS[save.map]); | |
| 343 | 342 | world.match.round = save.round; |
| 344 | 343 | world.match.score = { ...save.score }; |
| 345 | 344 | world.match.losses = { ...save.losses }; |
new above
offline