quake2ts 0.0.473 → 0.0.476

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
@@ -24402,9 +24402,15 @@ var SpawnRegistry = class {
24402
24402
  register(classname, spawn) {
24403
24403
  this.registry.set(classname, spawn);
24404
24404
  }
24405
+ unregister(classname) {
24406
+ this.registry.delete(classname);
24407
+ }
24405
24408
  get(classname) {
24406
24409
  return this.registry.get(classname);
24407
24410
  }
24411
+ keys() {
24412
+ return this.registry.keys();
24413
+ }
24408
24414
  };
24409
24415
  function defaultWarn(message) {
24410
24416
  void message;
@@ -26098,6 +26104,106 @@ function populatePlayerStats(player, timeSeconds) {
26098
26104
  // src/index.ts
26099
26105
  init_esm();
26100
26106
 
26107
+ // src/save/adapter.ts
26108
+ function createSerializedGameState(context) {
26109
+ const { entitySystem, levelClock, random: random5 } = context;
26110
+ const player = entitySystem.find((e) => e.classname === "player");
26111
+ const sysSnapshot = entitySystem.createSnapshot();
26112
+ const playerState = {
26113
+ origin: player ? { ...player.origin } : { x: 0, y: 0, z: 0 },
26114
+ velocity: player ? { ...player.velocity } : { x: 0, y: 0, z: 0 },
26115
+ viewAngles: player ? { ...player.angles } : { x: 0, y: 0, z: 0 },
26116
+ onGround: player ? player.groundentity !== null : false,
26117
+ waterLevel: player ? player.waterlevel : 0,
26118
+ mins: player ? { ...player.mins } : { x: -16, y: -16, z: -24 },
26119
+ maxs: player ? { ...player.maxs } : { x: 16, y: 16, z: 32 },
26120
+ damageAlpha: player?.client?.damage_alpha ?? 0,
26121
+ damageIndicators: [],
26122
+ // Transient
26123
+ blend: [0, 0, 0, 0],
26124
+ // Transient
26125
+ stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
26126
+ kick_angles: player?.client?.kick_angles ?? { x: 0, y: 0, z: 0 },
26127
+ kick_origin: player?.client?.kick_origin ?? { x: 0, y: 0, z: 0 },
26128
+ gunoffset: { x: 0, y: 0, z: 0 },
26129
+ gunangles: { x: 0, y: 0, z: 0 },
26130
+ gunindex: 0,
26131
+ // Q2 Network Compatibility
26132
+ pm_type: player?.client?.pm_type ?? 0,
26133
+ pm_time: player?.client?.pm_time ?? 0,
26134
+ pm_flags: player?.client?.pm_flags ?? 0,
26135
+ gun_frame: player?.client?.gun_frame ?? 0,
26136
+ rdflags: player?.client?.rdflags ?? 0,
26137
+ fov: player?.client?.fov ?? 90,
26138
+ renderfx: player?.renderfx ?? 0
26139
+ };
26140
+ return {
26141
+ mapName: entitySystem.level.mapname || "unknown",
26142
+ playerState,
26143
+ entities: sysSnapshot.entities,
26144
+ levelState: sysSnapshot.level,
26145
+ time: levelClock.current.timeSeconds,
26146
+ playerInventory: player?.client?.inventory ? serializePlayerInventory(player.client.inventory) : void 0,
26147
+ rngState: random5?.getState(),
26148
+ _internalSnapshot: sysSnapshot
26149
+ };
26150
+ }
26151
+ function applySerializedGameState(state, context) {
26152
+ const { entitySystem, levelClock, random: random5 } = context;
26153
+ levelClock.restore({
26154
+ frameNumber: 0,
26155
+ // Unknown in this format, reset to 0
26156
+ timeSeconds: state.time,
26157
+ previousTimeSeconds: state.time,
26158
+ deltaSeconds: 0
26159
+ });
26160
+ if (random5 && state.rngState) {
26161
+ random5.setState(state.rngState);
26162
+ }
26163
+ if (state._internalSnapshot) {
26164
+ entitySystem.restore(state._internalSnapshot);
26165
+ } else {
26166
+ console.warn("Restoring from partial SerializedGameState. Thinks and Pool state may be lost.");
26167
+ const partialSnapshot = {
26168
+ timeSeconds: state.time,
26169
+ pool: {
26170
+ capacity: state.entities.length + 32,
26171
+ // Estimate
26172
+ activeOrder: state.entities.map((e) => e.index),
26173
+ // Naive
26174
+ freeList: [],
26175
+ // Assume none
26176
+ pendingFree: []
26177
+ },
26178
+ entities: state.entities,
26179
+ thinks: [],
26180
+ // LOST
26181
+ awareness: {
26182
+ frameNumber: 0,
26183
+ sightEntityIndex: null,
26184
+ sightEntityFrame: 0,
26185
+ soundEntityIndex: null,
26186
+ soundEntityFrame: 0,
26187
+ sound2EntityIndex: null,
26188
+ sound2EntityFrame: 0,
26189
+ sightClientIndex: null
26190
+ },
26191
+ crossLevelFlags: 0,
26192
+ crossUnitFlags: 0,
26193
+ level: state.levelState
26194
+ };
26195
+ entitySystem.restore(partialSnapshot);
26196
+ }
26197
+ const player = entitySystem.find((e) => e.classname === "player");
26198
+ if (player && state.playerInventory) {
26199
+ const inventory = deserializePlayerInventory(state.playerInventory);
26200
+ player.client = player.client || {};
26201
+ if (player.client) {
26202
+ player.client.inventory = inventory;
26203
+ }
26204
+ }
26205
+ }
26206
+
26101
26207
  // src/combat/weapon.ts
26102
26208
  var WeaponType = /* @__PURE__ */ ((WeaponType2) => {
26103
26209
  WeaponType2[WeaponType2["BLASTER"] = 0] = "BLASTER";
@@ -26401,6 +26507,7 @@ function createGame(imports, engine, options) {
26401
26507
  entities.beginFrame(startTimeMs / 1e3);
26402
26508
  entities.runFrame();
26403
26509
  };
26510
+ const spawnRegistry = new SpawnRegistry();
26404
26511
  const runPlayerMove = (player, command) => {
26405
26512
  const pcmd = {
26406
26513
  forwardmove: command.forwardmove,
@@ -26460,6 +26567,18 @@ function createGame(imports, engine, options) {
26460
26567
  }
26461
26568
  };
26462
26569
  const gameExports = {
26570
+ // CustomEntityRegistration implementation
26571
+ registerEntitySpawn(classname, spawnFunc) {
26572
+ spawnRegistry.register(classname, (entity, context) => {
26573
+ spawnFunc(entity);
26574
+ });
26575
+ },
26576
+ unregisterEntitySpawn(classname) {
26577
+ spawnRegistry.unregister(classname);
26578
+ },
26579
+ getCustomEntities() {
26580
+ return Array.from(spawnRegistry.keys());
26581
+ },
26463
26582
  init(startTimeMs) {
26464
26583
  resetState(startTimeMs);
26465
26584
  return snapshot(0);
@@ -26629,9 +26748,32 @@ function createGame(imports, engine, options) {
26629
26748
  velocity = player ? { ...player.velocity } : { ...ZERO_VEC312 };
26630
26749
  }
26631
26750
  frameLoop.reset(save.level.timeSeconds * 1e3);
26751
+ },
26752
+ serialize() {
26753
+ return createSerializedGameState({
26754
+ entitySystem: entities,
26755
+ levelClock,
26756
+ random: rng
26757
+ });
26758
+ },
26759
+ loadState(state) {
26760
+ applySerializedGameState(state, {
26761
+ entitySystem: entities,
26762
+ levelClock,
26763
+ random: rng
26764
+ });
26765
+ const player = entities.find((e) => e.classname === "player");
26766
+ if (player) {
26767
+ origin = { ...player.origin };
26768
+ velocity = { ...player.velocity };
26769
+ } else {
26770
+ origin = { ...ZERO_VEC312 };
26771
+ velocity = { ...ZERO_VEC312 };
26772
+ }
26773
+ frameLoop.reset(state.time * 1e3);
26632
26774
  }
26633
26775
  };
26634
- const spawnRegistry = createDefaultSpawnRegistry(gameExports);
26776
+ registerDefaultSpawns(spawnRegistry, gameExports);
26635
26777
  entities.setSpawnRegistry(spawnRegistry);
26636
26778
  entities._game = gameExports;
26637
26779
  return gameExports;