quake2ts 0.0.598 → 0.0.600

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quake2ts",
3
- "version": "0.0.598",
3
+ "version": "0.0.600",
4
4
  "description": "Quake II re-release port to TypeScript with WebGL renderer - A complete game engine with physics, networking, and BSP rendering",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -110,8 +110,8 @@
110
110
  "tsx": "^4.20.6",
111
111
  "typescript": "^5.4.5",
112
112
  "vitest": "^1.5.3",
113
- "@quake2ts/tests": "^0.0.1",
114
- "@quake2ts/test-utils": "^0.0.1"
113
+ "@quake2ts/test-utils": "^0.0.1",
114
+ "@quake2ts/tests": "^0.0.1"
115
115
  },
116
116
  "dependencies": {
117
117
  "@wasm-audio-decoders/ogg-vorbis": "^0.1.20",
@@ -121,6 +121,7 @@ __export(index_exports, {
121
121
  createNetChanMock: () => createNetChanMock,
122
122
  createPacketMock: () => createPacketMock,
123
123
  createPhysicsTestContext: () => createPhysicsTestContext,
124
+ createPhysicsTestScenario: () => createPhysicsTestScenario,
124
125
  createPlayerEntityFactory: () => createPlayerEntityFactory,
125
126
  createPlayerStateFactory: () => createPlayerStateFactory,
126
127
  createPlaywrightTestClient: () => createPlaywrightTestClient,
@@ -156,7 +157,10 @@ __export(index_exports, {
156
157
  simulateBandwidthLimit: () => simulateBandwidthLimit,
157
158
  simulateCameraMovement: () => simulateCameraMovement,
158
159
  simulateFrames: () => simulateFrames,
160
+ simulateGravity: () => simulateGravity,
159
161
  simulateHandshake: () => simulateHandshake,
162
+ simulateJump: () => simulateJump,
163
+ simulateMovement: () => simulateMovement,
160
164
  simulateNetworkCondition: () => simulateNetworkCondition,
161
165
  simulatePlayerInput: () => simulatePlayerInput,
162
166
  simulatePlayerJoin: () => simulatePlayerJoin,
@@ -699,6 +703,8 @@ function createTestContext(options) {
699
703
  sightEntity: null,
700
704
  soundEntity: null
701
705
  },
706
+ warn: import_vitest2.vi.fn(),
707
+ // Added warn to entities as it is sometimes used there too, though typically on SpawnContext
702
708
  // Adding missing properties to satisfy EntitySystem interface partially or fully
703
709
  // We cast to unknown first anyway, but filling these in makes it safer for consumers
704
710
  skill: 1,
@@ -739,6 +745,112 @@ function createEntity() {
739
745
  return new import_game2.Entity(1);
740
746
  }
741
747
 
748
+ // src/game/helpers/physics.ts
749
+ var import_game3 = require("@quake2ts/game");
750
+ var import_shared5 = require("@quake2ts/shared");
751
+ function createPhysicsTestScenario(scenarioType, context) {
752
+ const walls = [];
753
+ const ground = context.entities.spawn();
754
+ ground.classname = "func_wall";
755
+ ground.solid = import_game3.Solid.Bsp;
756
+ ground.movetype = import_game3.MoveType.Push;
757
+ ground.origin = { x: 0, y: 0, z: -10 };
758
+ ground.mins = { x: -1e3, y: -1e3, z: -10 };
759
+ ground.maxs = { x: 1e3, y: 1e3, z: 0 };
760
+ context.entities.linkentity(ground);
761
+ const setupStairs = () => {
762
+ for (let i = 0; i < 5; i++) {
763
+ const step = context.entities.spawn();
764
+ step.classname = "func_wall";
765
+ step.solid = import_game3.Solid.Bsp;
766
+ step.origin = { x: 100 + i * 32, y: 0, z: i * 16 };
767
+ step.mins = { x: 0, y: -64, z: 0 };
768
+ step.maxs = { x: 32, y: 64, z: 16 };
769
+ context.entities.linkentity(step);
770
+ walls.push(step);
771
+ }
772
+ };
773
+ const setupLadder = () => {
774
+ const ladder = context.entities.spawn();
775
+ ladder.classname = "func_wall";
776
+ ladder.solid = import_game3.Solid.Bsp;
777
+ ladder.origin = { x: 100, y: 0, z: 0 };
778
+ ladder.mins = { x: 0, y: -32, z: 0 };
779
+ ladder.maxs = { x: 10, y: 32, z: 200 };
780
+ ladder.surfaceFlags = 1;
781
+ context.entities.linkentity(ladder);
782
+ walls.push(ladder);
783
+ };
784
+ const setupPlatform = () => {
785
+ const plat = context.entities.spawn();
786
+ plat.classname = "func_plat";
787
+ plat.solid = import_game3.Solid.Bsp;
788
+ plat.movetype = import_game3.MoveType.Push;
789
+ plat.origin = { x: 0, y: 0, z: 0 };
790
+ plat.mins = { x: -64, y: -64, z: 0 };
791
+ plat.maxs = { x: 64, y: 64, z: 10 };
792
+ context.entities.linkentity(plat);
793
+ walls.push(plat);
794
+ };
795
+ if (scenarioType === "stairs") setupStairs();
796
+ else if (scenarioType === "ladder") setupLadder();
797
+ else if (scenarioType === "platform") setupPlatform();
798
+ return {
799
+ ground,
800
+ walls,
801
+ setup: (ctx) => {
802
+ }
803
+ };
804
+ }
805
+ function simulateMovement(entity, destination, context) {
806
+ const dt = 0.1;
807
+ const delta = (0, import_shared5.subtractVec3)(destination, entity.origin);
808
+ const dist2 = (0, import_shared5.lengthVec3)(delta);
809
+ if (dist2 < 1e-3) {
810
+ return createTraceMock({ fraction: 1, endpos: destination });
811
+ }
812
+ const dir = (0, import_shared5.normalizeVec3)(delta);
813
+ entity.velocity = (0, import_shared5.scaleVec3)(dir, dist2 / dt);
814
+ const start = { ...entity.origin };
815
+ const end = destination;
816
+ const tr = context.entities.trace(start, entity.mins, entity.maxs, end, entity, entity.clipmask || 0);
817
+ if (!tr.startsolid && !tr.allsolid) {
818
+ if (tr.endpos) {
819
+ entity.origin = { ...tr.endpos };
820
+ } else {
821
+ entity.origin = { ...end };
822
+ }
823
+ context.entities.linkentity(entity);
824
+ }
825
+ return tr;
826
+ }
827
+ function simulateGravity(entity, deltaTime, context) {
828
+ const gravity = context.game.cvars?.gravity?.value ?? 800;
829
+ if (entity.groundentity || !entity.movetype) return;
830
+ entity.velocity = {
831
+ x: entity.velocity.x,
832
+ y: entity.velocity.y,
833
+ z: entity.velocity.z - gravity * deltaTime
834
+ };
835
+ const start = { ...entity.origin };
836
+ const end = { x: start.x, y: start.y, z: start.z - 0.25 };
837
+ const tr = context.entities.trace(start, entity.mins, entity.maxs, end, entity, entity.clipmask || 0);
838
+ if (tr.fraction < 1) {
839
+ entity.groundentity = tr.ent || context.entities.world;
840
+ entity.velocity = { ...entity.velocity, z: 0 };
841
+ if (tr.endpos) {
842
+ entity.origin = { ...entity.origin, z: tr.endpos.z };
843
+ }
844
+ } else {
845
+ entity.groundentity = null;
846
+ }
847
+ }
848
+ function simulateJump(entity, context) {
849
+ if (!entity.groundentity) return;
850
+ entity.groundentity = null;
851
+ entity.velocity = { ...entity.velocity, z: 270 };
852
+ }
853
+
742
854
  // src/game/mocks/ai.ts
743
855
  var import_vitest3 = require("vitest");
744
856
  function createMockAI(overrides = {}) {
@@ -782,11 +894,11 @@ function createMockMonsterMove(first, last, think, action) {
782
894
 
783
895
  // src/game/mocks/combat.ts
784
896
  var import_vitest4 = require("vitest");
785
- var import_game3 = require("@quake2ts/game");
897
+ var import_game4 = require("@quake2ts/game");
786
898
  function createMockDamageInfo(overrides = {}) {
787
899
  return {
788
900
  damage: 10,
789
- mod: import_game3.DamageMod.UNKNOWN,
901
+ mod: import_game4.DamageMod.UNKNOWN,
790
902
  knockback: 0,
791
903
  attacker: null,
792
904
  inflictor: null,
@@ -830,10 +942,10 @@ var mockMonsterAttacks = {
830
942
  };
831
943
 
832
944
  // src/game/mocks/items.ts
833
- var import_game4 = require("@quake2ts/game");
834
945
  var import_game5 = require("@quake2ts/game");
946
+ var import_game6 = require("@quake2ts/game");
835
947
  function createMockInventory(overrides = {}) {
836
- const defaultInventory = (0, import_game4.createPlayerInventory)();
948
+ const defaultInventory = (0, import_game5.createPlayerInventory)();
837
949
  const inventory = {
838
950
  ...defaultInventory,
839
951
  ...overrides
@@ -842,7 +954,7 @@ function createMockInventory(overrides = {}) {
842
954
  }
843
955
  function createMockItem(id, overrides = {}) {
844
956
  let base;
845
- base = import_game5.WEAPON_ITEMS[id] || import_game5.HEALTH_ITEMS[id] || import_game5.ARMOR_ITEMS[id] || import_game5.POWERUP_ITEMS[id] || import_game5.POWER_ARMOR_ITEMS[id] || import_game5.KEY_ITEMS[id] || import_game5.FLAG_ITEMS[id];
957
+ base = import_game6.WEAPON_ITEMS[id] || import_game6.HEALTH_ITEMS[id] || import_game6.ARMOR_ITEMS[id] || import_game6.POWERUP_ITEMS[id] || import_game6.POWER_ARMOR_ITEMS[id] || import_game6.KEY_ITEMS[id] || import_game6.FLAG_ITEMS[id];
846
958
  if (!base) {
847
959
  base = {
848
960
  id,
@@ -855,7 +967,7 @@ function createMockItem(id, overrides = {}) {
855
967
  };
856
968
  }
857
969
  function createMockWeaponItem(weaponId, overrides = {}) {
858
- const found = Object.values(import_game5.WEAPON_ITEMS).find((w) => w.weaponId === weaponId);
970
+ const found = Object.values(import_game6.WEAPON_ITEMS).find((w) => w.weaponId === weaponId);
859
971
  const base = found ? { ...found } : {
860
972
  type: "weapon",
861
973
  id: `weapon_${weaponId}`,
@@ -888,7 +1000,7 @@ function createMockArmorItem(amount, overrides = {}) {
888
1000
  };
889
1001
  }
890
1002
  function createMockAmmoItem(ammoItemId, overrides = {}) {
891
- const def = (0, import_game5.getAmmoItemDefinition)(ammoItemId);
1003
+ const def = (0, import_game6.getAmmoItemDefinition)(ammoItemId);
892
1004
  if (!def) {
893
1005
  throw new Error(`Unknown ammo item id: ${ammoItemId}`);
894
1006
  }
@@ -902,7 +1014,7 @@ function createMockAmmoItem(ammoItemId, overrides = {}) {
902
1014
  };
903
1015
  }
904
1016
  function createMockPowerupItem(id, duration, overrides = {}) {
905
- const found = import_game5.POWERUP_ITEMS[id];
1017
+ const found = import_game6.POWERUP_ITEMS[id];
906
1018
  const base = found ? { ...found } : {
907
1019
  type: "powerup",
908
1020
  id,
@@ -1103,12 +1215,12 @@ function createMockNetDriver(overrides) {
1103
1215
  }
1104
1216
 
1105
1217
  // src/server/mockTransport.ts
1106
- var import_shared5 = require("@quake2ts/shared");
1218
+ var import_shared6 = require("@quake2ts/shared");
1107
1219
  var MockNetworkTransport = class {
1108
1220
  constructor() {
1109
1221
  this.recordedPackets = [];
1110
1222
  this.sentPackets = [];
1111
- this.netchan = new import_shared5.NetChan();
1223
+ this.netchan = new import_shared6.NetChan();
1112
1224
  this.netchan.setup(1234, { type: "loopback", port: 0 });
1113
1225
  }
1114
1226
  reset() {
@@ -1143,7 +1255,7 @@ var MockNetworkTransport = class {
1143
1255
 
1144
1256
  // src/server/mocks/state.ts
1145
1257
  var import_server = require("@quake2ts/server");
1146
- var import_shared6 = require("@quake2ts/shared");
1258
+ var import_shared7 = require("@quake2ts/shared");
1147
1259
  var import_vitest7 = require("vitest");
1148
1260
  function createMockServerState(overrides) {
1149
1261
  return {
@@ -1155,8 +1267,8 @@ function createMockServerState(overrides) {
1155
1267
  frame: 0,
1156
1268
  name: "test_map",
1157
1269
  collisionModel: null,
1158
- configStrings: new Array(import_shared6.MAX_CONFIGSTRINGS).fill(""),
1159
- baselines: new Array(import_shared6.MAX_EDICTS).fill(null),
1270
+ configStrings: new Array(import_shared7.MAX_CONFIGSTRINGS).fill(""),
1271
+ baselines: new Array(import_shared7.MAX_EDICTS).fill(null),
1160
1272
  multicastBuf: new Uint8Array(0),
1161
1273
  ...overrides
1162
1274
  };
@@ -3429,6 +3541,7 @@ function createVisualTestScenario(sceneName) {
3429
3541
  createNetChanMock,
3430
3542
  createPacketMock,
3431
3543
  createPhysicsTestContext,
3544
+ createPhysicsTestScenario,
3432
3545
  createPlayerEntityFactory,
3433
3546
  createPlayerStateFactory,
3434
3547
  createPlaywrightTestClient,
@@ -3464,7 +3577,10 @@ function createVisualTestScenario(sceneName) {
3464
3577
  simulateBandwidthLimit,
3465
3578
  simulateCameraMovement,
3466
3579
  simulateFrames,
3580
+ simulateGravity,
3467
3581
  simulateHandshake,
3582
+ simulateJump,
3583
+ simulateMovement,
3468
3584
  simulateNetworkCondition,
3469
3585
  simulatePlayerInput,
3470
3586
  simulatePlayerJoin,