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 +3 -3
- package/packages/test-utils/dist/index.cjs +129 -13
- package/packages/test-utils/dist/index.cjs.map +1 -1
- package/packages/test-utils/dist/index.d.cts +28 -2
- package/packages/test-utils/dist/index.d.ts +28 -2
- package/packages/test-utils/dist/index.js +112 -0
- package/packages/test-utils/dist/index.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quake2ts",
|
|
3
|
-
"version": "0.0.
|
|
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/
|
|
114
|
-
"@quake2ts/
|
|
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
|
|
897
|
+
var import_game4 = require("@quake2ts/game");
|
|
786
898
|
function createMockDamageInfo(overrides = {}) {
|
|
787
899
|
return {
|
|
788
900
|
damage: 10,
|
|
789
|
-
mod:
|
|
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,
|
|
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 =
|
|
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(
|
|
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,
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
1159
|
-
baselines: new Array(
|
|
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,
|