quake2ts 0.0.472 → 0.0.475

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +16 -16
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  5. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  6. package/packages/engine/dist/types/render/lightCulling.d.ts +17 -0
  7. package/packages/engine/dist/types/render/lightCulling.d.ts.map +1 -0
  8. package/packages/engine/dist/types/render/renderer.d.ts.map +1 -1
  9. package/packages/game/dist/browser/index.global.js +4 -4
  10. package/packages/game/dist/browser/index.global.js.map +1 -1
  11. package/packages/game/dist/cjs/index.cjs +143 -1
  12. package/packages/game/dist/cjs/index.cjs.map +1 -1
  13. package/packages/game/dist/esm/index.js +143 -1
  14. package/packages/game/dist/esm/index.js.map +1 -1
  15. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  16. package/packages/game/dist/types/entities/index.d.ts +1 -1
  17. package/packages/game/dist/types/entities/index.d.ts.map +1 -1
  18. package/packages/game/dist/types/entities/spawn.d.ts +2 -0
  19. package/packages/game/dist/types/entities/spawn.d.ts.map +1 -1
  20. package/packages/game/dist/types/index.d.ts +7 -1
  21. package/packages/game/dist/types/index.d.ts.map +1 -1
  22. package/packages/game/dist/types/mod.d.ts +26 -0
  23. package/packages/game/dist/types/mod.d.ts.map +1 -0
  24. package/packages/game/dist/types/save/adapter.d.ts +24 -0
  25. package/packages/game/dist/types/save/adapter.d.ts.map +1 -0
  26. package/packages/game/dist/types/save/tests/adapter.test.d.ts +2 -0
  27. package/packages/game/dist/types/save/tests/adapter.test.d.ts.map +1 -0
@@ -24594,9 +24594,15 @@ var SpawnRegistry = class {
24594
24594
  register(classname, spawn) {
24595
24595
  this.registry.set(classname, spawn);
24596
24596
  }
24597
+ unregister(classname) {
24598
+ this.registry.delete(classname);
24599
+ }
24597
24600
  get(classname) {
24598
24601
  return this.registry.get(classname);
24599
24602
  }
24603
+ keys() {
24604
+ return this.registry.keys();
24605
+ }
24600
24606
  };
24601
24607
  function defaultWarn(message) {
24602
24608
  void message;
@@ -26290,6 +26296,106 @@ function populatePlayerStats(player, timeSeconds) {
26290
26296
  // src/index.ts
26291
26297
  init_esm();
26292
26298
 
26299
+ // src/save/adapter.ts
26300
+ function createSerializedGameState(context) {
26301
+ const { entitySystem, levelClock, random: random5 } = context;
26302
+ const player = entitySystem.find((e) => e.classname === "player");
26303
+ const sysSnapshot = entitySystem.createSnapshot();
26304
+ const playerState = {
26305
+ origin: player ? { ...player.origin } : { x: 0, y: 0, z: 0 },
26306
+ velocity: player ? { ...player.velocity } : { x: 0, y: 0, z: 0 },
26307
+ viewAngles: player ? { ...player.angles } : { x: 0, y: 0, z: 0 },
26308
+ onGround: player ? player.groundentity !== null : false,
26309
+ waterLevel: player ? player.waterlevel : 0,
26310
+ mins: player ? { ...player.mins } : { x: -16, y: -16, z: -24 },
26311
+ maxs: player ? { ...player.maxs } : { x: 16, y: 16, z: 32 },
26312
+ damageAlpha: player?.client?.damage_alpha ?? 0,
26313
+ damageIndicators: [],
26314
+ // Transient
26315
+ blend: [0, 0, 0, 0],
26316
+ // Transient
26317
+ stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
26318
+ kick_angles: player?.client?.kick_angles ?? { x: 0, y: 0, z: 0 },
26319
+ kick_origin: player?.client?.kick_origin ?? { x: 0, y: 0, z: 0 },
26320
+ gunoffset: { x: 0, y: 0, z: 0 },
26321
+ gunangles: { x: 0, y: 0, z: 0 },
26322
+ gunindex: 0,
26323
+ // Q2 Network Compatibility
26324
+ pm_type: player?.client?.pm_type ?? 0,
26325
+ pm_time: player?.client?.pm_time ?? 0,
26326
+ pm_flags: player?.client?.pm_flags ?? 0,
26327
+ gun_frame: player?.client?.gun_frame ?? 0,
26328
+ rdflags: player?.client?.rdflags ?? 0,
26329
+ fov: player?.client?.fov ?? 90,
26330
+ renderfx: player?.renderfx ?? 0
26331
+ };
26332
+ return {
26333
+ mapName: entitySystem.level.mapname || "unknown",
26334
+ playerState,
26335
+ entities: sysSnapshot.entities,
26336
+ levelState: sysSnapshot.level,
26337
+ time: levelClock.current.timeSeconds,
26338
+ playerInventory: player?.client?.inventory ? serializePlayerInventory(player.client.inventory) : void 0,
26339
+ rngState: random5?.getState(),
26340
+ _internalSnapshot: sysSnapshot
26341
+ };
26342
+ }
26343
+ function applySerializedGameState(state, context) {
26344
+ const { entitySystem, levelClock, random: random5 } = context;
26345
+ levelClock.restore({
26346
+ frameNumber: 0,
26347
+ // Unknown in this format, reset to 0
26348
+ timeSeconds: state.time,
26349
+ previousTimeSeconds: state.time,
26350
+ deltaSeconds: 0
26351
+ });
26352
+ if (random5 && state.rngState) {
26353
+ random5.setState(state.rngState);
26354
+ }
26355
+ if (state._internalSnapshot) {
26356
+ entitySystem.restore(state._internalSnapshot);
26357
+ } else {
26358
+ console.warn("Restoring from partial SerializedGameState. Thinks and Pool state may be lost.");
26359
+ const partialSnapshot = {
26360
+ timeSeconds: state.time,
26361
+ pool: {
26362
+ capacity: state.entities.length + 32,
26363
+ // Estimate
26364
+ activeOrder: state.entities.map((e) => e.index),
26365
+ // Naive
26366
+ freeList: [],
26367
+ // Assume none
26368
+ pendingFree: []
26369
+ },
26370
+ entities: state.entities,
26371
+ thinks: [],
26372
+ // LOST
26373
+ awareness: {
26374
+ frameNumber: 0,
26375
+ sightEntityIndex: null,
26376
+ sightEntityFrame: 0,
26377
+ soundEntityIndex: null,
26378
+ soundEntityFrame: 0,
26379
+ sound2EntityIndex: null,
26380
+ sound2EntityFrame: 0,
26381
+ sightClientIndex: null
26382
+ },
26383
+ crossLevelFlags: 0,
26384
+ crossUnitFlags: 0,
26385
+ level: state.levelState
26386
+ };
26387
+ entitySystem.restore(partialSnapshot);
26388
+ }
26389
+ const player = entitySystem.find((e) => e.classname === "player");
26390
+ if (player && state.playerInventory) {
26391
+ const inventory = deserializePlayerInventory(state.playerInventory);
26392
+ player.client = player.client || {};
26393
+ if (player.client) {
26394
+ player.client.inventory = inventory;
26395
+ }
26396
+ }
26397
+ }
26398
+
26293
26399
  // src/combat/weapon.ts
26294
26400
  var WeaponType = /* @__PURE__ */ ((WeaponType2) => {
26295
26401
  WeaponType2[WeaponType2["BLASTER"] = 0] = "BLASTER";
@@ -26593,6 +26699,7 @@ function createGame(imports, engine, options) {
26593
26699
  entities.beginFrame(startTimeMs / 1e3);
26594
26700
  entities.runFrame();
26595
26701
  };
26702
+ const spawnRegistry = new SpawnRegistry();
26596
26703
  const runPlayerMove = (player, command) => {
26597
26704
  const pcmd = {
26598
26705
  forwardmove: command.forwardmove,
@@ -26652,6 +26759,18 @@ function createGame(imports, engine, options) {
26652
26759
  }
26653
26760
  };
26654
26761
  const gameExports = {
26762
+ // CustomEntityRegistration implementation
26763
+ registerEntitySpawn(classname, spawnFunc) {
26764
+ spawnRegistry.register(classname, (entity, context) => {
26765
+ spawnFunc(entity);
26766
+ });
26767
+ },
26768
+ unregisterEntitySpawn(classname) {
26769
+ spawnRegistry.unregister(classname);
26770
+ },
26771
+ getCustomEntities() {
26772
+ return Array.from(spawnRegistry.keys());
26773
+ },
26655
26774
  init(startTimeMs) {
26656
26775
  resetState(startTimeMs);
26657
26776
  return snapshot(0);
@@ -26821,9 +26940,32 @@ function createGame(imports, engine, options) {
26821
26940
  velocity = player ? { ...player.velocity } : { ...ZERO_VEC312 };
26822
26941
  }
26823
26942
  frameLoop.reset(save.level.timeSeconds * 1e3);
26943
+ },
26944
+ serialize() {
26945
+ return createSerializedGameState({
26946
+ entitySystem: entities,
26947
+ levelClock,
26948
+ random: rng
26949
+ });
26950
+ },
26951
+ loadState(state) {
26952
+ applySerializedGameState(state, {
26953
+ entitySystem: entities,
26954
+ levelClock,
26955
+ random: rng
26956
+ });
26957
+ const player = entities.find((e) => e.classname === "player");
26958
+ if (player) {
26959
+ origin = { ...player.origin };
26960
+ velocity = { ...player.velocity };
26961
+ } else {
26962
+ origin = { ...ZERO_VEC312 };
26963
+ velocity = { ...ZERO_VEC312 };
26964
+ }
26965
+ frameLoop.reset(state.time * 1e3);
26824
26966
  }
26825
26967
  };
26826
- const spawnRegistry = createDefaultSpawnRegistry(gameExports);
26968
+ registerDefaultSpawns(spawnRegistry, gameExports);
26827
26969
  entities.setSpawnRegistry(spawnRegistry);
26828
26970
  entities._game = gameExports;
26829
26971
  return gameExports;