quake2ts 0.0.68 → 0.0.71
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 +1 -1
- package/packages/client/dist/browser/index.global.js +1 -1
- package/packages/client/dist/browser/index.global.js.map +1 -1
- package/packages/client/dist/cjs/index.cjs.map +1 -1
- package/packages/client/dist/esm/index.js.map +1 -1
- package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/engine/dist/browser/index.global.js +14 -14
- package/packages/engine/dist/browser/index.global.js.map +1 -1
- package/packages/engine/dist/cjs/index.cjs +84 -0
- package/packages/engine/dist/cjs/index.cjs.map +1 -1
- package/packages/engine/dist/esm/index.js +81 -0
- package/packages/engine/dist/esm/index.js.map +1 -1
- package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/engine/dist/types/assets/manager.d.ts +4 -1
- package/packages/engine/dist/types/assets/manager.d.ts.map +1 -1
- package/packages/engine/dist/types/assets/sprite.d.ts +23 -0
- package/packages/engine/dist/types/assets/sprite.d.ts.map +1 -0
- package/packages/engine/dist/types/index.d.ts +1 -0
- package/packages/engine/dist/types/index.d.ts.map +1 -1
- package/packages/game/dist/browser/index.global.js +1 -1
- package/packages/game/dist/browser/index.global.js.map +1 -1
- package/packages/game/dist/cjs/index.cjs +318 -40
- package/packages/game/dist/cjs/index.cjs.map +1 -1
- package/packages/game/dist/esm/index.js +318 -40
- package/packages/game/dist/esm/index.js.map +1 -1
- package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/types/combat/weapons/firing.d.ts.map +1 -1
- package/packages/game/dist/types/entities/entity.d.ts +9 -1
- package/packages/game/dist/types/entities/entity.d.ts.map +1 -1
- package/packages/game/dist/types/entities/funcs.d.ts +9 -0
- package/packages/game/dist/types/entities/funcs.d.ts.map +1 -0
- package/packages/game/dist/types/entities/projectiles.d.ts +2 -0
- package/packages/game/dist/types/entities/projectiles.d.ts.map +1 -1
- package/packages/game/dist/types/entities/spawn.d.ts.map +1 -1
- package/packages/game/dist/types/entities/system.d.ts +2 -0
- package/packages/game/dist/types/entities/system.d.ts.map +1 -1
- package/packages/game/dist/types/entities/thinkScheduler.d.ts +1 -1
- package/packages/game/dist/types/entities/thinkScheduler.d.ts.map +1 -1
- package/packages/game/dist/types/imports.d.ts +1 -0
- package/packages/game/dist/types/imports.d.ts.map +1 -1
- package/packages/game/dist/types/index.d.ts +4 -1
- package/packages/game/dist/types/index.d.ts.map +1 -1
- package/packages/game/dist/types/physics/movement.d.ts +2 -0
- package/packages/game/dist/types/physics/movement.d.ts.map +1 -1
- package/packages/shared/dist/browser/index.global.js +1 -1
- package/packages/shared/dist/browser/index.global.js.map +1 -1
- package/packages/shared/dist/cjs/index.cjs +18 -8
- package/packages/shared/dist/cjs/index.cjs.map +1 -1
- package/packages/shared/dist/esm/index.js +16 -8
- package/packages/shared/dist/esm/index.js.map +1 -1
- package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/shared/dist/types/math/vec3.d.ts +2 -0
- package/packages/shared/dist/types/math/vec3.d.ts.map +1 -1
- package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
|
@@ -20,6 +20,12 @@ function lengthSquaredVec3(a) {
|
|
|
20
20
|
function lengthVec3(a) {
|
|
21
21
|
return Math.sqrt(lengthSquaredVec3(a));
|
|
22
22
|
}
|
|
23
|
+
function distance(a, b) {
|
|
24
|
+
return lengthVec3(subtractVec3(a, b));
|
|
25
|
+
}
|
|
26
|
+
function vec3Equals(a, b) {
|
|
27
|
+
return a.x === b.x && a.y === b.y && a.z === b.z;
|
|
28
|
+
}
|
|
23
29
|
function normalizeVec3(a) {
|
|
24
30
|
const len = lengthVec3(a);
|
|
25
31
|
return len === 0 ? a : scaleVec3(a, 1 / len);
|
|
@@ -605,9 +611,13 @@ var Entity = class {
|
|
|
605
611
|
this.velocity = copyVec3();
|
|
606
612
|
this.avelocity = copyVec3();
|
|
607
613
|
this.angles = copyVec3();
|
|
614
|
+
this.pos1 = copyVec3();
|
|
615
|
+
this.pos2 = copyVec3();
|
|
608
616
|
this.viewheight = 0;
|
|
609
617
|
this.mins = copyVec3();
|
|
610
618
|
this.maxs = copyVec3();
|
|
619
|
+
this.absmin = copyVec3();
|
|
620
|
+
this.absmax = copyVec3();
|
|
611
621
|
this.size = copyVec3();
|
|
612
622
|
this.mass = 0;
|
|
613
623
|
this.gravity = 1;
|
|
@@ -629,6 +639,8 @@ var Entity = class {
|
|
|
629
639
|
this.wait = 0;
|
|
630
640
|
this.delay = 0;
|
|
631
641
|
this.timestamp = 0;
|
|
642
|
+
this.lip = 0;
|
|
643
|
+
this.state = 0;
|
|
632
644
|
this.sounds = 0;
|
|
633
645
|
this.noise_index = 0;
|
|
634
646
|
this.fly_sound_debounce_time = 0;
|
|
@@ -679,9 +691,13 @@ var Entity = class {
|
|
|
679
691
|
this.velocity = copyVec3();
|
|
680
692
|
this.avelocity = copyVec3();
|
|
681
693
|
this.angles = copyVec3();
|
|
694
|
+
this.pos1 = copyVec3();
|
|
695
|
+
this.pos2 = copyVec3();
|
|
682
696
|
this.viewheight = 0;
|
|
683
697
|
this.mins = copyVec3();
|
|
684
698
|
this.maxs = copyVec3();
|
|
699
|
+
this.absmin = copyVec3();
|
|
700
|
+
this.absmax = copyVec3();
|
|
685
701
|
this.size = copyVec3();
|
|
686
702
|
this.mass = 0;
|
|
687
703
|
this.gravity = 1;
|
|
@@ -703,6 +719,8 @@ var Entity = class {
|
|
|
703
719
|
this.wait = 0;
|
|
704
720
|
this.delay = 0;
|
|
705
721
|
this.timestamp = 0;
|
|
722
|
+
this.lip = 0;
|
|
723
|
+
this.state = 0;
|
|
706
724
|
this.sounds = 0;
|
|
707
725
|
this.noise_index = 0;
|
|
708
726
|
this.fly_sound_debounce_time = 0;
|
|
@@ -724,6 +742,7 @@ var Entity = class {
|
|
|
724
742
|
this.think = void 0;
|
|
725
743
|
this.touch = void 0;
|
|
726
744
|
this.use = void 0;
|
|
745
|
+
this.blocked = void 0;
|
|
727
746
|
this.pain = void 0;
|
|
728
747
|
this.die = void 0;
|
|
729
748
|
this.activator = null;
|
|
@@ -754,9 +773,13 @@ var ENTITY_FIELD_METADATA = [
|
|
|
754
773
|
{ name: "velocity", type: "vec3", save: true },
|
|
755
774
|
{ name: "avelocity", type: "vec3", save: true },
|
|
756
775
|
{ name: "angles", type: "vec3", save: true },
|
|
776
|
+
{ name: "pos1", type: "vec3", save: true },
|
|
777
|
+
{ name: "pos2", type: "vec3", save: true },
|
|
757
778
|
{ name: "viewheight", type: "int", save: true },
|
|
758
779
|
{ name: "mins", type: "vec3", save: true },
|
|
759
780
|
{ name: "maxs", type: "vec3", save: true },
|
|
781
|
+
{ name: "absmin", type: "vec3", save: true },
|
|
782
|
+
{ name: "absmax", type: "vec3", save: true },
|
|
760
783
|
{ name: "size", type: "vec3", save: true },
|
|
761
784
|
{ name: "mass", type: "int", save: true },
|
|
762
785
|
{ name: "gravity", type: "float", save: true },
|
|
@@ -777,6 +800,8 @@ var ENTITY_FIELD_METADATA = [
|
|
|
777
800
|
{ name: "wait", type: "float", save: true },
|
|
778
801
|
{ name: "delay", type: "float", save: true },
|
|
779
802
|
{ name: "timestamp", type: "float", save: true },
|
|
803
|
+
{ name: "lip", type: "int", save: true },
|
|
804
|
+
{ name: "state", type: "int", save: true },
|
|
780
805
|
{ name: "sounds", type: "int", save: true },
|
|
781
806
|
{ name: "noise_index", type: "int", save: true },
|
|
782
807
|
{ name: "fly_sound_debounce_time", type: "float", save: true },
|
|
@@ -801,6 +826,7 @@ var ENTITY_FIELD_METADATA = [
|
|
|
801
826
|
{ name: "think", type: "callback", save: false },
|
|
802
827
|
{ name: "touch", type: "callback", save: false },
|
|
803
828
|
{ name: "use", type: "callback", save: false },
|
|
829
|
+
{ name: "blocked", type: "callback", save: false },
|
|
804
830
|
{ name: "pain", type: "callback", save: false },
|
|
805
831
|
{ name: "die", type: "callback", save: false }
|
|
806
832
|
];
|
|
@@ -834,6 +860,108 @@ function runProjectileMovement(ent, imports, frametime) {
|
|
|
834
860
|
const traceResult = imports.trace(ent.origin, ent.mins, ent.maxs, end, ent, ent.clipmask);
|
|
835
861
|
ent.origin = traceResult.endpos;
|
|
836
862
|
}
|
|
863
|
+
function testEntityPosition(ent, imports) {
|
|
864
|
+
const trace = imports.trace(ent.origin, ent.mins, ent.maxs, ent.origin, ent, ent.clipmask);
|
|
865
|
+
if (trace.startsolid || trace.allsolid) {
|
|
866
|
+
return false;
|
|
867
|
+
}
|
|
868
|
+
return true;
|
|
869
|
+
}
|
|
870
|
+
function runPush(pusher, system, imports, frametime) {
|
|
871
|
+
const move = {
|
|
872
|
+
x: pusher.velocity.x * frametime,
|
|
873
|
+
y: pusher.velocity.y * frametime,
|
|
874
|
+
z: pusher.velocity.z * frametime
|
|
875
|
+
};
|
|
876
|
+
const amove = {
|
|
877
|
+
x: pusher.avelocity.x * frametime,
|
|
878
|
+
y: pusher.avelocity.y * frametime,
|
|
879
|
+
z: pusher.avelocity.z * frametime
|
|
880
|
+
};
|
|
881
|
+
const mins = {
|
|
882
|
+
x: Math.min(pusher.absmin.x, pusher.absmin.x + move.x) - 2,
|
|
883
|
+
// Expand slightly? Quake2 does 'mins - move - 2' logic implicitly via box check
|
|
884
|
+
y: Math.min(pusher.absmin.y, pusher.absmin.y + move.y) - 2,
|
|
885
|
+
z: Math.min(pusher.absmin.z, pusher.absmin.z + move.z) - 2
|
|
886
|
+
};
|
|
887
|
+
const maxs = {
|
|
888
|
+
x: Math.max(pusher.absmax.x, pusher.absmax.x + move.x) + 2,
|
|
889
|
+
y: Math.max(pusher.absmax.y, pusher.absmax.y + move.y) + 2,
|
|
890
|
+
z: Math.max(pusher.absmax.z, pusher.absmax.z + move.z) + 2
|
|
891
|
+
};
|
|
892
|
+
const pushed = [];
|
|
893
|
+
pushed.push({
|
|
894
|
+
ent: pusher,
|
|
895
|
+
origin: { ...pusher.origin },
|
|
896
|
+
angles: { ...pusher.angles },
|
|
897
|
+
ground: pusher.groundentity
|
|
898
|
+
});
|
|
899
|
+
pusher.origin = {
|
|
900
|
+
x: pusher.origin.x + move.x,
|
|
901
|
+
y: pusher.origin.y + move.y,
|
|
902
|
+
z: pusher.origin.z + move.z
|
|
903
|
+
};
|
|
904
|
+
pusher.angles = {
|
|
905
|
+
x: pusher.angles.x + amove.x,
|
|
906
|
+
y: pusher.angles.y + amove.y,
|
|
907
|
+
z: pusher.angles.z + amove.z
|
|
908
|
+
};
|
|
909
|
+
imports.linkentity(pusher);
|
|
910
|
+
if (!testEntityPosition(pusher, imports)) {
|
|
911
|
+
pusher.origin = pushed[0].origin;
|
|
912
|
+
pusher.angles = pushed[0].angles;
|
|
913
|
+
imports.linkentity(pusher);
|
|
914
|
+
return false;
|
|
915
|
+
}
|
|
916
|
+
const candidates = [];
|
|
917
|
+
system.forEachEntity((check) => {
|
|
918
|
+
if (check === pusher) return;
|
|
919
|
+
if (check.solid === 0 /* Not */ || check.solid === 1 /* Trigger */) return;
|
|
920
|
+
if (check.absmin.x >= maxs.x || check.absmax.x <= mins.x || check.absmin.y >= maxs.y || check.absmax.y <= mins.y || check.absmin.z >= maxs.z || check.absmax.z <= mins.z) {
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
candidates.push(check);
|
|
924
|
+
});
|
|
925
|
+
for (const ent of candidates) {
|
|
926
|
+
let moveEntity = false;
|
|
927
|
+
if (ent.groundentity === pusher) {
|
|
928
|
+
moveEntity = true;
|
|
929
|
+
} else {
|
|
930
|
+
if (ent.absmin.x < pusher.absmax.x && ent.absmax.x > pusher.absmin.x && ent.absmin.y < pusher.absmax.y && ent.absmax.y > pusher.absmin.y && ent.absmin.z < pusher.absmax.z && ent.absmax.z > pusher.absmin.z) {
|
|
931
|
+
moveEntity = true;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
if (moveEntity) {
|
|
935
|
+
pushed.push({
|
|
936
|
+
ent,
|
|
937
|
+
origin: { ...ent.origin },
|
|
938
|
+
angles: { ...ent.angles },
|
|
939
|
+
ground: ent.groundentity
|
|
940
|
+
});
|
|
941
|
+
ent.origin = {
|
|
942
|
+
x: ent.origin.x + move.x,
|
|
943
|
+
y: ent.origin.y + move.y,
|
|
944
|
+
z: ent.origin.z + move.z
|
|
945
|
+
};
|
|
946
|
+
imports.linkentity(ent);
|
|
947
|
+
if (!testEntityPosition(ent, imports)) {
|
|
948
|
+
if (pusher.blocked) {
|
|
949
|
+
pusher.blocked(pusher, ent);
|
|
950
|
+
}
|
|
951
|
+
if (ent.solid !== 0 /* Not */ && (!ent.health || ent.health > 0)) {
|
|
952
|
+
for (let i = pushed.length - 1; i >= 0; i--) {
|
|
953
|
+
const p = pushed[i];
|
|
954
|
+
p.ent.origin = p.origin;
|
|
955
|
+
p.ent.angles = p.angles;
|
|
956
|
+
p.ent.groundentity = p.ground, imports.linkentity(p.ent);
|
|
957
|
+
}
|
|
958
|
+
return false;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
return true;
|
|
964
|
+
}
|
|
837
965
|
|
|
838
966
|
// src/entities/pool.ts
|
|
839
967
|
var MAX_EDICTS = 2048;
|
|
@@ -1048,7 +1176,7 @@ var ThinkScheduler = class {
|
|
|
1048
1176
|
this.schedule(entity, entry.time);
|
|
1049
1177
|
}
|
|
1050
1178
|
}
|
|
1051
|
-
runDueThinks(currentTimeSeconds) {
|
|
1179
|
+
runDueThinks(currentTimeSeconds, context) {
|
|
1052
1180
|
while (this.queue.length > 0) {
|
|
1053
1181
|
const next = this.queue[0];
|
|
1054
1182
|
if (next.time > currentTimeSeconds) {
|
|
@@ -1065,7 +1193,7 @@ var ThinkScheduler = class {
|
|
|
1065
1193
|
if (entity.nextthink !== time) {
|
|
1066
1194
|
continue;
|
|
1067
1195
|
}
|
|
1068
|
-
entity.think(entity);
|
|
1196
|
+
entity.think(entity, context);
|
|
1069
1197
|
}
|
|
1070
1198
|
}
|
|
1071
1199
|
};
|
|
@@ -1138,7 +1266,19 @@ var EntitySystem = class {
|
|
|
1138
1266
|
contents: 0,
|
|
1139
1267
|
ent: null
|
|
1140
1268
|
}),
|
|
1141
|
-
pointcontents: () => 0
|
|
1269
|
+
pointcontents: () => 0,
|
|
1270
|
+
linkentity: (ent) => {
|
|
1271
|
+
ent.absmin = {
|
|
1272
|
+
x: ent.origin.x + ent.mins.x,
|
|
1273
|
+
y: ent.origin.y + ent.mins.y,
|
|
1274
|
+
z: ent.origin.z + ent.mins.z
|
|
1275
|
+
};
|
|
1276
|
+
ent.absmax = {
|
|
1277
|
+
x: ent.origin.x + ent.maxs.x,
|
|
1278
|
+
y: ent.origin.y + ent.maxs.y,
|
|
1279
|
+
z: ent.origin.z + ent.maxs.z
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1142
1282
|
};
|
|
1143
1283
|
this.gravity = gravity || { x: 0, y: 0, z: 0 };
|
|
1144
1284
|
this.callbackToName = /* @__PURE__ */ new Map();
|
|
@@ -1188,6 +1328,9 @@ var EntitySystem = class {
|
|
|
1188
1328
|
sound(entity, channel, sound, volume, attenuation, timeofs) {
|
|
1189
1329
|
this.engine.sound?.(entity, channel, sound, volume, attenuation, timeofs);
|
|
1190
1330
|
}
|
|
1331
|
+
modelIndex(model) {
|
|
1332
|
+
return this.engine.modelIndex?.(model) || 0;
|
|
1333
|
+
}
|
|
1191
1334
|
scheduleThink(entity, nextThinkSeconds) {
|
|
1192
1335
|
this.thinkScheduler.schedule(entity, nextThinkSeconds);
|
|
1193
1336
|
}
|
|
@@ -1216,6 +1359,18 @@ var EntitySystem = class {
|
|
|
1216
1359
|
}
|
|
1217
1360
|
return Array.from(matches).filter((entity) => entity.inUse && !entity.freePending);
|
|
1218
1361
|
}
|
|
1362
|
+
findByRadius(origin, radius) {
|
|
1363
|
+
const matches = [];
|
|
1364
|
+
for (const entity of this.pool) {
|
|
1365
|
+
if (entity.inUse && !entity.freePending) {
|
|
1366
|
+
const distance2 = lengthVec3(subtractVec3(origin, entity.origin));
|
|
1367
|
+
if (distance2 <= radius) {
|
|
1368
|
+
matches.push(entity);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
return matches;
|
|
1373
|
+
}
|
|
1219
1374
|
pickTarget(targetname) {
|
|
1220
1375
|
if (!targetname) {
|
|
1221
1376
|
return null;
|
|
@@ -1264,7 +1419,7 @@ var EntitySystem = class {
|
|
|
1264
1419
|
this.useTargetsImmediate(entity, activator ?? entity);
|
|
1265
1420
|
}
|
|
1266
1421
|
runFrame() {
|
|
1267
|
-
this.thinkScheduler.runDueThinks(this.currentTimeSeconds);
|
|
1422
|
+
this.thinkScheduler.runDueThinks(this.currentTimeSeconds, this);
|
|
1268
1423
|
for (const ent of this.pool) {
|
|
1269
1424
|
if (!ent.inUse || ent.freePending) {
|
|
1270
1425
|
continue;
|
|
@@ -1284,6 +1439,9 @@ var EntitySystem = class {
|
|
|
1284
1439
|
runProjectileMovement(ent, this.imports, frametime);
|
|
1285
1440
|
ent.timestamp = this.currentTimeSeconds;
|
|
1286
1441
|
break;
|
|
1442
|
+
case 2 /* Push */:
|
|
1443
|
+
runPush(ent, this, this.imports, frametime);
|
|
1444
|
+
break;
|
|
1287
1445
|
}
|
|
1288
1446
|
}
|
|
1289
1447
|
this.runTouches();
|
|
@@ -2852,6 +3010,112 @@ function registerItemSpawns(game, registry) {
|
|
|
2852
3010
|
}
|
|
2853
3011
|
}
|
|
2854
3012
|
|
|
3013
|
+
// src/entities/funcs.ts
|
|
3014
|
+
function door_blocked(self, other) {
|
|
3015
|
+
if (other && other.takedamage) {
|
|
3016
|
+
const damage = self.dmg || 2;
|
|
3017
|
+
other.health -= damage;
|
|
3018
|
+
}
|
|
3019
|
+
if (self.state === 1 /* Opening */) {
|
|
3020
|
+
self.state = 3 /* Closing */;
|
|
3021
|
+
self.think = door_go_down;
|
|
3022
|
+
} else if (self.state === 3 /* Closing */) {
|
|
3023
|
+
self.state = 1 /* Opening */;
|
|
3024
|
+
self.think = door_go_up;
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
3027
|
+
function door_go_down(door, context) {
|
|
3028
|
+
if (vec3Equals(door.origin, door.pos1)) {
|
|
3029
|
+
door.state = 2 /* Closed */;
|
|
3030
|
+
door.velocity = { x: 0, y: 0, z: 0 };
|
|
3031
|
+
return;
|
|
3032
|
+
}
|
|
3033
|
+
const move = distance(door.origin, door.pos1);
|
|
3034
|
+
const speed = Math.min(door.speed, move);
|
|
3035
|
+
door.velocity = {
|
|
3036
|
+
x: (door.pos1.x - door.origin.x) / distance(door.pos1, door.origin) * door.speed,
|
|
3037
|
+
y: (door.pos1.y - door.origin.y) / distance(door.pos1, door.origin) * door.speed,
|
|
3038
|
+
z: (door.pos1.z - door.origin.z) / distance(door.pos1, door.origin) * door.speed
|
|
3039
|
+
};
|
|
3040
|
+
if (move <= door.speed * 0.1) {
|
|
3041
|
+
door.velocity = {
|
|
3042
|
+
x: (door.pos1.x - door.origin.x) / 0.1,
|
|
3043
|
+
y: (door.pos1.y - door.origin.y) / 0.1,
|
|
3044
|
+
z: (door.pos1.z - door.origin.z) / 0.1
|
|
3045
|
+
};
|
|
3046
|
+
}
|
|
3047
|
+
context?.scheduleThink(door, context.timeSeconds + 0.1);
|
|
3048
|
+
}
|
|
3049
|
+
function door_go_up(door, context) {
|
|
3050
|
+
if (vec3Equals(door.origin, door.pos2)) {
|
|
3051
|
+
door.state = 0 /* Open */;
|
|
3052
|
+
door.velocity = { x: 0, y: 0, z: 0 };
|
|
3053
|
+
context?.scheduleThink(door, context.timeSeconds + door.wait);
|
|
3054
|
+
door.think = door_go_down;
|
|
3055
|
+
return;
|
|
3056
|
+
}
|
|
3057
|
+
const move = distance(door.origin, door.pos2);
|
|
3058
|
+
door.velocity = {
|
|
3059
|
+
x: (door.pos2.x - door.origin.x) / distance(door.pos2, door.origin) * door.speed,
|
|
3060
|
+
y: (door.pos2.y - door.origin.y) / distance(door.pos2, door.origin) * door.speed,
|
|
3061
|
+
z: (door.pos2.z - door.origin.z) / distance(door.pos2, door.origin) * door.speed
|
|
3062
|
+
};
|
|
3063
|
+
if (move <= door.speed * 0.1) {
|
|
3064
|
+
door.velocity = {
|
|
3065
|
+
x: (door.pos2.x - door.origin.x) / 0.1,
|
|
3066
|
+
y: (door.pos2.y - door.origin.y) / 0.1,
|
|
3067
|
+
z: (door.pos2.z - door.origin.z) / 0.1
|
|
3068
|
+
};
|
|
3069
|
+
}
|
|
3070
|
+
context?.scheduleThink(door, context.timeSeconds + 0.1);
|
|
3071
|
+
}
|
|
3072
|
+
var func_door = (entity, context) => {
|
|
3073
|
+
entity.movedir = setMovedir(entity.angles);
|
|
3074
|
+
if (!entity.speed) {
|
|
3075
|
+
entity.speed = 100;
|
|
3076
|
+
}
|
|
3077
|
+
if (!entity.wait) {
|
|
3078
|
+
entity.wait = 3;
|
|
3079
|
+
}
|
|
3080
|
+
if (!entity.lip) {
|
|
3081
|
+
entity.lip = 8;
|
|
3082
|
+
}
|
|
3083
|
+
if (!entity.dmg) {
|
|
3084
|
+
entity.dmg = 2;
|
|
3085
|
+
}
|
|
3086
|
+
if (!entity.health) {
|
|
3087
|
+
entity.health = 0;
|
|
3088
|
+
}
|
|
3089
|
+
entity.solid = 3 /* Bsp */;
|
|
3090
|
+
entity.movetype = 2 /* Push */;
|
|
3091
|
+
entity.blocked = door_blocked;
|
|
3092
|
+
entity.state = 2 /* Closed */;
|
|
3093
|
+
entity.pos1 = { ...entity.origin };
|
|
3094
|
+
const move = entity.movedir.x * (Math.abs(entity.maxs.x - entity.mins.x) - entity.lip) + entity.movedir.y * (Math.abs(entity.maxs.y - entity.mins.y) - entity.lip) + entity.movedir.z * (Math.abs(entity.maxs.z - entity.mins.z) - entity.lip);
|
|
3095
|
+
entity.pos2 = {
|
|
3096
|
+
x: entity.pos1.x + entity.movedir.x * move,
|
|
3097
|
+
y: entity.pos1.y + entity.movedir.y * move,
|
|
3098
|
+
z: entity.pos1.z + entity.movedir.z * move
|
|
3099
|
+
};
|
|
3100
|
+
entity.use = (self) => {
|
|
3101
|
+
if (self.state !== 2 /* Closed */) return;
|
|
3102
|
+
self.state = 1 /* Opening */;
|
|
3103
|
+
self.think = door_go_up;
|
|
3104
|
+
context.entities.scheduleThink(self, context.entities.timeSeconds + 0.1);
|
|
3105
|
+
};
|
|
3106
|
+
};
|
|
3107
|
+
var func_button = (entity, context) => {
|
|
3108
|
+
entity.solid = 3 /* Bsp */;
|
|
3109
|
+
entity.movetype = 2 /* Push */;
|
|
3110
|
+
entity.use = (self) => {
|
|
3111
|
+
context.entities.useTargets(self, self);
|
|
3112
|
+
};
|
|
3113
|
+
};
|
|
3114
|
+
function registerFuncSpawns(registry) {
|
|
3115
|
+
registry.register("func_door", func_door);
|
|
3116
|
+
registry.register("func_button", func_button);
|
|
3117
|
+
}
|
|
3118
|
+
|
|
2855
3119
|
// src/entities/spawn.ts
|
|
2856
3120
|
var FIELD_LOOKUP = new Map(
|
|
2857
3121
|
ENTITY_FIELD_METADATA.map((field) => [field.name, field])
|
|
@@ -3063,6 +3327,7 @@ function registerDefaultSpawns(game, registry) {
|
|
|
3063
3327
|
registerTargetSpawns(registry);
|
|
3064
3328
|
registerMiscSpawns(registry);
|
|
3065
3329
|
registerItemSpawns(game, registry);
|
|
3330
|
+
registerFuncSpawns(registry);
|
|
3066
3331
|
}
|
|
3067
3332
|
function createDefaultSpawnRegistry(game) {
|
|
3068
3333
|
const registry = new SpawnRegistry();
|
|
@@ -3254,19 +3519,19 @@ var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
|
|
|
3254
3519
|
})(TraceMask || {});
|
|
3255
3520
|
|
|
3256
3521
|
// src/ai/movement.ts
|
|
3257
|
-
function yawVector(yawDegrees,
|
|
3258
|
-
if (
|
|
3522
|
+
function yawVector(yawDegrees, distance2) {
|
|
3523
|
+
if (distance2 === 0) {
|
|
3259
3524
|
return { x: 0, y: 0, z: 0 };
|
|
3260
3525
|
}
|
|
3261
3526
|
const radians = degToRad(yawDegrees);
|
|
3262
3527
|
return {
|
|
3263
|
-
x: Math.cos(radians) *
|
|
3264
|
-
y: Math.sin(radians) *
|
|
3528
|
+
x: Math.cos(radians) * distance2,
|
|
3529
|
+
y: Math.sin(radians) * distance2,
|
|
3265
3530
|
z: 0
|
|
3266
3531
|
};
|
|
3267
3532
|
}
|
|
3268
|
-
function walkMove(self, yawDegrees,
|
|
3269
|
-
const delta = yawVector(yawDegrees,
|
|
3533
|
+
function walkMove(self, yawDegrees, distance2) {
|
|
3534
|
+
const delta = yawVector(yawDegrees, distance2);
|
|
3270
3535
|
const origin = self.origin;
|
|
3271
3536
|
origin.x += delta.x;
|
|
3272
3537
|
origin.y += delta.y;
|
|
@@ -3299,8 +3564,8 @@ function facingIdeal(self) {
|
|
|
3299
3564
|
}
|
|
3300
3565
|
return !(delta > 45 && delta < 315);
|
|
3301
3566
|
}
|
|
3302
|
-
function ai_move(self,
|
|
3303
|
-
walkMove(self, self.angles.y,
|
|
3567
|
+
function ai_move(self, distance2) {
|
|
3568
|
+
walkMove(self, self.angles.y, distance2);
|
|
3304
3569
|
}
|
|
3305
3570
|
function setIdealYawTowards(self, target) {
|
|
3306
3571
|
if (!target) return;
|
|
@@ -3314,40 +3579,40 @@ function setIdealYawTowards(self, target) {
|
|
|
3314
3579
|
function ai_stand(self, deltaSeconds) {
|
|
3315
3580
|
changeYaw(self, deltaSeconds);
|
|
3316
3581
|
}
|
|
3317
|
-
function ai_walk(self,
|
|
3582
|
+
function ai_walk(self, distance2, deltaSeconds) {
|
|
3318
3583
|
setIdealYawTowards(self, self.goalentity);
|
|
3319
3584
|
changeYaw(self, deltaSeconds);
|
|
3320
|
-
if (
|
|
3321
|
-
walkMove(self, self.angles.y,
|
|
3585
|
+
if (distance2 !== 0) {
|
|
3586
|
+
walkMove(self, self.angles.y, distance2);
|
|
3322
3587
|
}
|
|
3323
3588
|
}
|
|
3324
|
-
function ai_turn(self,
|
|
3325
|
-
if (
|
|
3326
|
-
walkMove(self, self.angles.y,
|
|
3589
|
+
function ai_turn(self, distance2, deltaSeconds) {
|
|
3590
|
+
if (distance2 !== 0) {
|
|
3591
|
+
walkMove(self, self.angles.y, distance2);
|
|
3327
3592
|
}
|
|
3328
3593
|
changeYaw(self, deltaSeconds);
|
|
3329
3594
|
}
|
|
3330
|
-
function ai_run(self,
|
|
3595
|
+
function ai_run(self, distance2, deltaSeconds) {
|
|
3331
3596
|
setIdealYawTowards(self, self.enemy ?? self.goalentity);
|
|
3332
3597
|
changeYaw(self, deltaSeconds);
|
|
3333
|
-
if (
|
|
3334
|
-
walkMove(self, self.angles.y,
|
|
3598
|
+
if (distance2 !== 0) {
|
|
3599
|
+
walkMove(self, self.angles.y, distance2);
|
|
3335
3600
|
}
|
|
3336
3601
|
}
|
|
3337
|
-
function ai_face(self, enemy,
|
|
3602
|
+
function ai_face(self, enemy, distance2, deltaSeconds) {
|
|
3338
3603
|
if (enemy) {
|
|
3339
3604
|
setIdealYawTowards(self, enemy);
|
|
3340
3605
|
}
|
|
3341
3606
|
changeYaw(self, deltaSeconds);
|
|
3342
|
-
if (
|
|
3343
|
-
walkMove(self, self.angles.y,
|
|
3607
|
+
if (distance2 !== 0) {
|
|
3608
|
+
walkMove(self, self.angles.y, distance2);
|
|
3344
3609
|
}
|
|
3345
3610
|
}
|
|
3346
|
-
function ai_charge(self,
|
|
3611
|
+
function ai_charge(self, distance2, deltaSeconds) {
|
|
3347
3612
|
setIdealYawTowards(self, self.enemy);
|
|
3348
3613
|
changeYaw(self, deltaSeconds);
|
|
3349
|
-
if (
|
|
3350
|
-
walkMove(self, self.angles.y,
|
|
3614
|
+
if (distance2 !== 0) {
|
|
3615
|
+
walkMove(self, self.angles.y, distance2);
|
|
3351
3616
|
}
|
|
3352
3617
|
}
|
|
3353
3618
|
|
|
@@ -3379,14 +3644,14 @@ function rangeTo(self, other) {
|
|
|
3379
3644
|
const distanceSquared = distanceBetweenBoxesSquared(a.mins, a.maxs, b.mins, b.maxs);
|
|
3380
3645
|
return Math.sqrt(distanceSquared);
|
|
3381
3646
|
}
|
|
3382
|
-
function classifyRange(
|
|
3383
|
-
if (
|
|
3647
|
+
function classifyRange(distance2) {
|
|
3648
|
+
if (distance2 <= RANGE_MELEE) {
|
|
3384
3649
|
return "melee" /* Melee */;
|
|
3385
3650
|
}
|
|
3386
|
-
if (
|
|
3651
|
+
if (distance2 <= RANGE_NEAR) {
|
|
3387
3652
|
return "near" /* Near */;
|
|
3388
3653
|
}
|
|
3389
|
-
if (
|
|
3654
|
+
if (distance2 <= RANGE_MID) {
|
|
3390
3655
|
return "mid" /* Mid */;
|
|
3391
3656
|
}
|
|
3392
3657
|
return "far" /* Far */;
|
|
@@ -3466,8 +3731,8 @@ function foundTarget(self, level, options) {
|
|
|
3466
3731
|
self.monsterinfo.run?.(self);
|
|
3467
3732
|
}
|
|
3468
3733
|
function classifyClientVisibility(self, other, level, trace) {
|
|
3469
|
-
const
|
|
3470
|
-
const range = classifyRange(
|
|
3734
|
+
const distance2 = rangeTo(self, other);
|
|
3735
|
+
const range = classifyRange(distance2);
|
|
3471
3736
|
if (range === "far" /* Far */) return false;
|
|
3472
3737
|
if (other.light_level <= 5) return false;
|
|
3473
3738
|
if (!visible(self, other, trace, { throughGlass: false })) return false;
|
|
@@ -4354,11 +4619,11 @@ function T_RadiusDamage(entities, inflictor, attacker, damage, ignore, radius, d
|
|
|
4354
4619
|
}
|
|
4355
4620
|
const entCenter = ent.mins && ent.maxs ? closestPointToBox(inflictorCenter, addVec3(ent.origin, ent.mins), addVec3(ent.origin, ent.maxs)) : targetCenter(ent);
|
|
4356
4621
|
const toTarget = subtractVec3(inflictorCenter, entCenter);
|
|
4357
|
-
const
|
|
4358
|
-
if (radius > 0 &&
|
|
4622
|
+
const distance2 = lengthVec3(toTarget);
|
|
4623
|
+
if (radius > 0 && distance2 > radius) {
|
|
4359
4624
|
continue;
|
|
4360
4625
|
}
|
|
4361
|
-
const points = damage - 0.5 *
|
|
4626
|
+
const points = damage - 0.5 * distance2;
|
|
4362
4627
|
if (points <= 0) {
|
|
4363
4628
|
continue;
|
|
4364
4629
|
}
|
|
@@ -4782,11 +5047,23 @@ function getWeaponState(playerStates, weaponId) {
|
|
|
4782
5047
|
|
|
4783
5048
|
// src/index.ts
|
|
4784
5049
|
var ZERO_VEC32 = { x: 0, y: 0, z: 0 };
|
|
4785
|
-
function createGame(
|
|
5050
|
+
function createGame({ trace, pointcontents }, engine, options) {
|
|
4786
5051
|
const gravity = options.gravity;
|
|
4787
5052
|
const levelClock = new LevelClock();
|
|
4788
5053
|
const frameLoop = new GameFrameLoop();
|
|
4789
|
-
const
|
|
5054
|
+
const linkentity = (ent) => {
|
|
5055
|
+
ent.absmin = {
|
|
5056
|
+
x: ent.origin.x + ent.mins.x,
|
|
5057
|
+
y: ent.origin.y + ent.mins.y,
|
|
5058
|
+
z: ent.origin.z + ent.mins.z
|
|
5059
|
+
};
|
|
5060
|
+
ent.absmax = {
|
|
5061
|
+
x: ent.origin.x + ent.maxs.x,
|
|
5062
|
+
y: ent.origin.y + ent.maxs.y,
|
|
5063
|
+
z: ent.origin.z + ent.maxs.z
|
|
5064
|
+
};
|
|
5065
|
+
};
|
|
5066
|
+
const entities = new EntitySystem(engine, { trace, pointcontents, linkentity }, gravity);
|
|
4790
5067
|
frameLoop.addStage("prep", (context) => {
|
|
4791
5068
|
levelClock.tick(context);
|
|
4792
5069
|
entities.beginFrame(levelClock.current.timeSeconds);
|
|
@@ -4864,7 +5141,7 @@ function createGame(imports, engine, options) {
|
|
|
4864
5141
|
};
|
|
4865
5142
|
const playerState = { origin: player.origin, velocity: player.velocity, onGround: false, waterLevel: 0, mins: player.mins, maxs: player.maxs, damageAlpha: 0, damageIndicators: [], viewAngles: player.angles };
|
|
4866
5143
|
const traceAdapter = (start, end) => {
|
|
4867
|
-
const result =
|
|
5144
|
+
const result = trace(start, player.mins, player.maxs, end, player, 268435457);
|
|
4868
5145
|
return {
|
|
4869
5146
|
fraction: result.fraction,
|
|
4870
5147
|
endpos: result.endpos,
|
|
@@ -4873,7 +5150,7 @@ function createGame(imports, engine, options) {
|
|
|
4873
5150
|
planeNormal: result.plane?.normal
|
|
4874
5151
|
};
|
|
4875
5152
|
};
|
|
4876
|
-
const pointContentsAdapter = (point) =>
|
|
5153
|
+
const pointContentsAdapter = (point) => pointcontents(point);
|
|
4877
5154
|
const newState = applyPmove(playerState, pcmd, traceAdapter, pointContentsAdapter);
|
|
4878
5155
|
player.origin = newState.origin;
|
|
4879
5156
|
player.velocity = newState.velocity;
|
|
@@ -4887,6 +5164,7 @@ function createGame(imports, engine, options) {
|
|
|
4887
5164
|
centerprintf(entity, message) {
|
|
4888
5165
|
engine.centerprintf?.(entity, message);
|
|
4889
5166
|
},
|
|
5167
|
+
trace,
|
|
4890
5168
|
get time() {
|
|
4891
5169
|
return levelClock.current.timeSeconds;
|
|
4892
5170
|
}
|