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
|
@@ -161,6 +161,12 @@ function lengthSquaredVec3(a) {
|
|
|
161
161
|
function lengthVec3(a) {
|
|
162
162
|
return Math.sqrt(lengthSquaredVec3(a));
|
|
163
163
|
}
|
|
164
|
+
function distance(a, b) {
|
|
165
|
+
return lengthVec3(subtractVec3(a, b));
|
|
166
|
+
}
|
|
167
|
+
function vec3Equals(a, b) {
|
|
168
|
+
return a.x === b.x && a.y === b.y && a.z === b.z;
|
|
169
|
+
}
|
|
164
170
|
function normalizeVec3(a) {
|
|
165
171
|
const len = lengthVec3(a);
|
|
166
172
|
return len === 0 ? a : scaleVec3(a, 1 / len);
|
|
@@ -746,9 +752,13 @@ var Entity = class {
|
|
|
746
752
|
this.velocity = copyVec3();
|
|
747
753
|
this.avelocity = copyVec3();
|
|
748
754
|
this.angles = copyVec3();
|
|
755
|
+
this.pos1 = copyVec3();
|
|
756
|
+
this.pos2 = copyVec3();
|
|
749
757
|
this.viewheight = 0;
|
|
750
758
|
this.mins = copyVec3();
|
|
751
759
|
this.maxs = copyVec3();
|
|
760
|
+
this.absmin = copyVec3();
|
|
761
|
+
this.absmax = copyVec3();
|
|
752
762
|
this.size = copyVec3();
|
|
753
763
|
this.mass = 0;
|
|
754
764
|
this.gravity = 1;
|
|
@@ -770,6 +780,8 @@ var Entity = class {
|
|
|
770
780
|
this.wait = 0;
|
|
771
781
|
this.delay = 0;
|
|
772
782
|
this.timestamp = 0;
|
|
783
|
+
this.lip = 0;
|
|
784
|
+
this.state = 0;
|
|
773
785
|
this.sounds = 0;
|
|
774
786
|
this.noise_index = 0;
|
|
775
787
|
this.fly_sound_debounce_time = 0;
|
|
@@ -820,9 +832,13 @@ var Entity = class {
|
|
|
820
832
|
this.velocity = copyVec3();
|
|
821
833
|
this.avelocity = copyVec3();
|
|
822
834
|
this.angles = copyVec3();
|
|
835
|
+
this.pos1 = copyVec3();
|
|
836
|
+
this.pos2 = copyVec3();
|
|
823
837
|
this.viewheight = 0;
|
|
824
838
|
this.mins = copyVec3();
|
|
825
839
|
this.maxs = copyVec3();
|
|
840
|
+
this.absmin = copyVec3();
|
|
841
|
+
this.absmax = copyVec3();
|
|
826
842
|
this.size = copyVec3();
|
|
827
843
|
this.mass = 0;
|
|
828
844
|
this.gravity = 1;
|
|
@@ -844,6 +860,8 @@ var Entity = class {
|
|
|
844
860
|
this.wait = 0;
|
|
845
861
|
this.delay = 0;
|
|
846
862
|
this.timestamp = 0;
|
|
863
|
+
this.lip = 0;
|
|
864
|
+
this.state = 0;
|
|
847
865
|
this.sounds = 0;
|
|
848
866
|
this.noise_index = 0;
|
|
849
867
|
this.fly_sound_debounce_time = 0;
|
|
@@ -865,6 +883,7 @@ var Entity = class {
|
|
|
865
883
|
this.think = void 0;
|
|
866
884
|
this.touch = void 0;
|
|
867
885
|
this.use = void 0;
|
|
886
|
+
this.blocked = void 0;
|
|
868
887
|
this.pain = void 0;
|
|
869
888
|
this.die = void 0;
|
|
870
889
|
this.activator = null;
|
|
@@ -895,9 +914,13 @@ var ENTITY_FIELD_METADATA = [
|
|
|
895
914
|
{ name: "velocity", type: "vec3", save: true },
|
|
896
915
|
{ name: "avelocity", type: "vec3", save: true },
|
|
897
916
|
{ name: "angles", type: "vec3", save: true },
|
|
917
|
+
{ name: "pos1", type: "vec3", save: true },
|
|
918
|
+
{ name: "pos2", type: "vec3", save: true },
|
|
898
919
|
{ name: "viewheight", type: "int", save: true },
|
|
899
920
|
{ name: "mins", type: "vec3", save: true },
|
|
900
921
|
{ name: "maxs", type: "vec3", save: true },
|
|
922
|
+
{ name: "absmin", type: "vec3", save: true },
|
|
923
|
+
{ name: "absmax", type: "vec3", save: true },
|
|
901
924
|
{ name: "size", type: "vec3", save: true },
|
|
902
925
|
{ name: "mass", type: "int", save: true },
|
|
903
926
|
{ name: "gravity", type: "float", save: true },
|
|
@@ -918,6 +941,8 @@ var ENTITY_FIELD_METADATA = [
|
|
|
918
941
|
{ name: "wait", type: "float", save: true },
|
|
919
942
|
{ name: "delay", type: "float", save: true },
|
|
920
943
|
{ name: "timestamp", type: "float", save: true },
|
|
944
|
+
{ name: "lip", type: "int", save: true },
|
|
945
|
+
{ name: "state", type: "int", save: true },
|
|
921
946
|
{ name: "sounds", type: "int", save: true },
|
|
922
947
|
{ name: "noise_index", type: "int", save: true },
|
|
923
948
|
{ name: "fly_sound_debounce_time", type: "float", save: true },
|
|
@@ -942,6 +967,7 @@ var ENTITY_FIELD_METADATA = [
|
|
|
942
967
|
{ name: "think", type: "callback", save: false },
|
|
943
968
|
{ name: "touch", type: "callback", save: false },
|
|
944
969
|
{ name: "use", type: "callback", save: false },
|
|
970
|
+
{ name: "blocked", type: "callback", save: false },
|
|
945
971
|
{ name: "pain", type: "callback", save: false },
|
|
946
972
|
{ name: "die", type: "callback", save: false }
|
|
947
973
|
];
|
|
@@ -975,6 +1001,108 @@ function runProjectileMovement(ent, imports, frametime) {
|
|
|
975
1001
|
const traceResult = imports.trace(ent.origin, ent.mins, ent.maxs, end, ent, ent.clipmask);
|
|
976
1002
|
ent.origin = traceResult.endpos;
|
|
977
1003
|
}
|
|
1004
|
+
function testEntityPosition(ent, imports) {
|
|
1005
|
+
const trace = imports.trace(ent.origin, ent.mins, ent.maxs, ent.origin, ent, ent.clipmask);
|
|
1006
|
+
if (trace.startsolid || trace.allsolid) {
|
|
1007
|
+
return false;
|
|
1008
|
+
}
|
|
1009
|
+
return true;
|
|
1010
|
+
}
|
|
1011
|
+
function runPush(pusher, system, imports, frametime) {
|
|
1012
|
+
const move = {
|
|
1013
|
+
x: pusher.velocity.x * frametime,
|
|
1014
|
+
y: pusher.velocity.y * frametime,
|
|
1015
|
+
z: pusher.velocity.z * frametime
|
|
1016
|
+
};
|
|
1017
|
+
const amove = {
|
|
1018
|
+
x: pusher.avelocity.x * frametime,
|
|
1019
|
+
y: pusher.avelocity.y * frametime,
|
|
1020
|
+
z: pusher.avelocity.z * frametime
|
|
1021
|
+
};
|
|
1022
|
+
const mins = {
|
|
1023
|
+
x: Math.min(pusher.absmin.x, pusher.absmin.x + move.x) - 2,
|
|
1024
|
+
// Expand slightly? Quake2 does 'mins - move - 2' logic implicitly via box check
|
|
1025
|
+
y: Math.min(pusher.absmin.y, pusher.absmin.y + move.y) - 2,
|
|
1026
|
+
z: Math.min(pusher.absmin.z, pusher.absmin.z + move.z) - 2
|
|
1027
|
+
};
|
|
1028
|
+
const maxs = {
|
|
1029
|
+
x: Math.max(pusher.absmax.x, pusher.absmax.x + move.x) + 2,
|
|
1030
|
+
y: Math.max(pusher.absmax.y, pusher.absmax.y + move.y) + 2,
|
|
1031
|
+
z: Math.max(pusher.absmax.z, pusher.absmax.z + move.z) + 2
|
|
1032
|
+
};
|
|
1033
|
+
const pushed = [];
|
|
1034
|
+
pushed.push({
|
|
1035
|
+
ent: pusher,
|
|
1036
|
+
origin: { ...pusher.origin },
|
|
1037
|
+
angles: { ...pusher.angles },
|
|
1038
|
+
ground: pusher.groundentity
|
|
1039
|
+
});
|
|
1040
|
+
pusher.origin = {
|
|
1041
|
+
x: pusher.origin.x + move.x,
|
|
1042
|
+
y: pusher.origin.y + move.y,
|
|
1043
|
+
z: pusher.origin.z + move.z
|
|
1044
|
+
};
|
|
1045
|
+
pusher.angles = {
|
|
1046
|
+
x: pusher.angles.x + amove.x,
|
|
1047
|
+
y: pusher.angles.y + amove.y,
|
|
1048
|
+
z: pusher.angles.z + amove.z
|
|
1049
|
+
};
|
|
1050
|
+
imports.linkentity(pusher);
|
|
1051
|
+
if (!testEntityPosition(pusher, imports)) {
|
|
1052
|
+
pusher.origin = pushed[0].origin;
|
|
1053
|
+
pusher.angles = pushed[0].angles;
|
|
1054
|
+
imports.linkentity(pusher);
|
|
1055
|
+
return false;
|
|
1056
|
+
}
|
|
1057
|
+
const candidates = [];
|
|
1058
|
+
system.forEachEntity((check) => {
|
|
1059
|
+
if (check === pusher) return;
|
|
1060
|
+
if (check.solid === 0 /* Not */ || check.solid === 1 /* Trigger */) return;
|
|
1061
|
+
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) {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
candidates.push(check);
|
|
1065
|
+
});
|
|
1066
|
+
for (const ent of candidates) {
|
|
1067
|
+
let moveEntity = false;
|
|
1068
|
+
if (ent.groundentity === pusher) {
|
|
1069
|
+
moveEntity = true;
|
|
1070
|
+
} else {
|
|
1071
|
+
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) {
|
|
1072
|
+
moveEntity = true;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
if (moveEntity) {
|
|
1076
|
+
pushed.push({
|
|
1077
|
+
ent,
|
|
1078
|
+
origin: { ...ent.origin },
|
|
1079
|
+
angles: { ...ent.angles },
|
|
1080
|
+
ground: ent.groundentity
|
|
1081
|
+
});
|
|
1082
|
+
ent.origin = {
|
|
1083
|
+
x: ent.origin.x + move.x,
|
|
1084
|
+
y: ent.origin.y + move.y,
|
|
1085
|
+
z: ent.origin.z + move.z
|
|
1086
|
+
};
|
|
1087
|
+
imports.linkentity(ent);
|
|
1088
|
+
if (!testEntityPosition(ent, imports)) {
|
|
1089
|
+
if (pusher.blocked) {
|
|
1090
|
+
pusher.blocked(pusher, ent);
|
|
1091
|
+
}
|
|
1092
|
+
if (ent.solid !== 0 /* Not */ && (!ent.health || ent.health > 0)) {
|
|
1093
|
+
for (let i = pushed.length - 1; i >= 0; i--) {
|
|
1094
|
+
const p = pushed[i];
|
|
1095
|
+
p.ent.origin = p.origin;
|
|
1096
|
+
p.ent.angles = p.angles;
|
|
1097
|
+
p.ent.groundentity = p.ground, imports.linkentity(p.ent);
|
|
1098
|
+
}
|
|
1099
|
+
return false;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
return true;
|
|
1105
|
+
}
|
|
978
1106
|
|
|
979
1107
|
// src/entities/pool.ts
|
|
980
1108
|
var MAX_EDICTS = 2048;
|
|
@@ -1189,7 +1317,7 @@ var ThinkScheduler = class {
|
|
|
1189
1317
|
this.schedule(entity, entry.time);
|
|
1190
1318
|
}
|
|
1191
1319
|
}
|
|
1192
|
-
runDueThinks(currentTimeSeconds) {
|
|
1320
|
+
runDueThinks(currentTimeSeconds, context) {
|
|
1193
1321
|
while (this.queue.length > 0) {
|
|
1194
1322
|
const next = this.queue[0];
|
|
1195
1323
|
if (next.time > currentTimeSeconds) {
|
|
@@ -1206,7 +1334,7 @@ var ThinkScheduler = class {
|
|
|
1206
1334
|
if (entity.nextthink !== time) {
|
|
1207
1335
|
continue;
|
|
1208
1336
|
}
|
|
1209
|
-
entity.think(entity);
|
|
1337
|
+
entity.think(entity, context);
|
|
1210
1338
|
}
|
|
1211
1339
|
}
|
|
1212
1340
|
};
|
|
@@ -1279,7 +1407,19 @@ var EntitySystem = class {
|
|
|
1279
1407
|
contents: 0,
|
|
1280
1408
|
ent: null
|
|
1281
1409
|
}),
|
|
1282
|
-
pointcontents: () => 0
|
|
1410
|
+
pointcontents: () => 0,
|
|
1411
|
+
linkentity: (ent) => {
|
|
1412
|
+
ent.absmin = {
|
|
1413
|
+
x: ent.origin.x + ent.mins.x,
|
|
1414
|
+
y: ent.origin.y + ent.mins.y,
|
|
1415
|
+
z: ent.origin.z + ent.mins.z
|
|
1416
|
+
};
|
|
1417
|
+
ent.absmax = {
|
|
1418
|
+
x: ent.origin.x + ent.maxs.x,
|
|
1419
|
+
y: ent.origin.y + ent.maxs.y,
|
|
1420
|
+
z: ent.origin.z + ent.maxs.z
|
|
1421
|
+
};
|
|
1422
|
+
}
|
|
1283
1423
|
};
|
|
1284
1424
|
this.gravity = gravity || { x: 0, y: 0, z: 0 };
|
|
1285
1425
|
this.callbackToName = /* @__PURE__ */ new Map();
|
|
@@ -1329,6 +1469,9 @@ var EntitySystem = class {
|
|
|
1329
1469
|
sound(entity, channel, sound, volume, attenuation, timeofs) {
|
|
1330
1470
|
this.engine.sound?.(entity, channel, sound, volume, attenuation, timeofs);
|
|
1331
1471
|
}
|
|
1472
|
+
modelIndex(model) {
|
|
1473
|
+
return this.engine.modelIndex?.(model) || 0;
|
|
1474
|
+
}
|
|
1332
1475
|
scheduleThink(entity, nextThinkSeconds) {
|
|
1333
1476
|
this.thinkScheduler.schedule(entity, nextThinkSeconds);
|
|
1334
1477
|
}
|
|
@@ -1357,6 +1500,18 @@ var EntitySystem = class {
|
|
|
1357
1500
|
}
|
|
1358
1501
|
return Array.from(matches).filter((entity) => entity.inUse && !entity.freePending);
|
|
1359
1502
|
}
|
|
1503
|
+
findByRadius(origin, radius) {
|
|
1504
|
+
const matches = [];
|
|
1505
|
+
for (const entity of this.pool) {
|
|
1506
|
+
if (entity.inUse && !entity.freePending) {
|
|
1507
|
+
const distance2 = lengthVec3(subtractVec3(origin, entity.origin));
|
|
1508
|
+
if (distance2 <= radius) {
|
|
1509
|
+
matches.push(entity);
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
return matches;
|
|
1514
|
+
}
|
|
1360
1515
|
pickTarget(targetname) {
|
|
1361
1516
|
if (!targetname) {
|
|
1362
1517
|
return null;
|
|
@@ -1405,7 +1560,7 @@ var EntitySystem = class {
|
|
|
1405
1560
|
this.useTargetsImmediate(entity, activator ?? entity);
|
|
1406
1561
|
}
|
|
1407
1562
|
runFrame() {
|
|
1408
|
-
this.thinkScheduler.runDueThinks(this.currentTimeSeconds);
|
|
1563
|
+
this.thinkScheduler.runDueThinks(this.currentTimeSeconds, this);
|
|
1409
1564
|
for (const ent of this.pool) {
|
|
1410
1565
|
if (!ent.inUse || ent.freePending) {
|
|
1411
1566
|
continue;
|
|
@@ -1425,6 +1580,9 @@ var EntitySystem = class {
|
|
|
1425
1580
|
runProjectileMovement(ent, this.imports, frametime);
|
|
1426
1581
|
ent.timestamp = this.currentTimeSeconds;
|
|
1427
1582
|
break;
|
|
1583
|
+
case 2 /* Push */:
|
|
1584
|
+
runPush(ent, this, this.imports, frametime);
|
|
1585
|
+
break;
|
|
1428
1586
|
}
|
|
1429
1587
|
}
|
|
1430
1588
|
this.runTouches();
|
|
@@ -2993,6 +3151,112 @@ function registerItemSpawns(game, registry) {
|
|
|
2993
3151
|
}
|
|
2994
3152
|
}
|
|
2995
3153
|
|
|
3154
|
+
// src/entities/funcs.ts
|
|
3155
|
+
function door_blocked(self, other) {
|
|
3156
|
+
if (other && other.takedamage) {
|
|
3157
|
+
const damage = self.dmg || 2;
|
|
3158
|
+
other.health -= damage;
|
|
3159
|
+
}
|
|
3160
|
+
if (self.state === 1 /* Opening */) {
|
|
3161
|
+
self.state = 3 /* Closing */;
|
|
3162
|
+
self.think = door_go_down;
|
|
3163
|
+
} else if (self.state === 3 /* Closing */) {
|
|
3164
|
+
self.state = 1 /* Opening */;
|
|
3165
|
+
self.think = door_go_up;
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
function door_go_down(door, context) {
|
|
3169
|
+
if (vec3Equals(door.origin, door.pos1)) {
|
|
3170
|
+
door.state = 2 /* Closed */;
|
|
3171
|
+
door.velocity = { x: 0, y: 0, z: 0 };
|
|
3172
|
+
return;
|
|
3173
|
+
}
|
|
3174
|
+
const move = distance(door.origin, door.pos1);
|
|
3175
|
+
const speed = Math.min(door.speed, move);
|
|
3176
|
+
door.velocity = {
|
|
3177
|
+
x: (door.pos1.x - door.origin.x) / distance(door.pos1, door.origin) * door.speed,
|
|
3178
|
+
y: (door.pos1.y - door.origin.y) / distance(door.pos1, door.origin) * door.speed,
|
|
3179
|
+
z: (door.pos1.z - door.origin.z) / distance(door.pos1, door.origin) * door.speed
|
|
3180
|
+
};
|
|
3181
|
+
if (move <= door.speed * 0.1) {
|
|
3182
|
+
door.velocity = {
|
|
3183
|
+
x: (door.pos1.x - door.origin.x) / 0.1,
|
|
3184
|
+
y: (door.pos1.y - door.origin.y) / 0.1,
|
|
3185
|
+
z: (door.pos1.z - door.origin.z) / 0.1
|
|
3186
|
+
};
|
|
3187
|
+
}
|
|
3188
|
+
context?.scheduleThink(door, context.timeSeconds + 0.1);
|
|
3189
|
+
}
|
|
3190
|
+
function door_go_up(door, context) {
|
|
3191
|
+
if (vec3Equals(door.origin, door.pos2)) {
|
|
3192
|
+
door.state = 0 /* Open */;
|
|
3193
|
+
door.velocity = { x: 0, y: 0, z: 0 };
|
|
3194
|
+
context?.scheduleThink(door, context.timeSeconds + door.wait);
|
|
3195
|
+
door.think = door_go_down;
|
|
3196
|
+
return;
|
|
3197
|
+
}
|
|
3198
|
+
const move = distance(door.origin, door.pos2);
|
|
3199
|
+
door.velocity = {
|
|
3200
|
+
x: (door.pos2.x - door.origin.x) / distance(door.pos2, door.origin) * door.speed,
|
|
3201
|
+
y: (door.pos2.y - door.origin.y) / distance(door.pos2, door.origin) * door.speed,
|
|
3202
|
+
z: (door.pos2.z - door.origin.z) / distance(door.pos2, door.origin) * door.speed
|
|
3203
|
+
};
|
|
3204
|
+
if (move <= door.speed * 0.1) {
|
|
3205
|
+
door.velocity = {
|
|
3206
|
+
x: (door.pos2.x - door.origin.x) / 0.1,
|
|
3207
|
+
y: (door.pos2.y - door.origin.y) / 0.1,
|
|
3208
|
+
z: (door.pos2.z - door.origin.z) / 0.1
|
|
3209
|
+
};
|
|
3210
|
+
}
|
|
3211
|
+
context?.scheduleThink(door, context.timeSeconds + 0.1);
|
|
3212
|
+
}
|
|
3213
|
+
var func_door = (entity, context) => {
|
|
3214
|
+
entity.movedir = setMovedir(entity.angles);
|
|
3215
|
+
if (!entity.speed) {
|
|
3216
|
+
entity.speed = 100;
|
|
3217
|
+
}
|
|
3218
|
+
if (!entity.wait) {
|
|
3219
|
+
entity.wait = 3;
|
|
3220
|
+
}
|
|
3221
|
+
if (!entity.lip) {
|
|
3222
|
+
entity.lip = 8;
|
|
3223
|
+
}
|
|
3224
|
+
if (!entity.dmg) {
|
|
3225
|
+
entity.dmg = 2;
|
|
3226
|
+
}
|
|
3227
|
+
if (!entity.health) {
|
|
3228
|
+
entity.health = 0;
|
|
3229
|
+
}
|
|
3230
|
+
entity.solid = 3 /* Bsp */;
|
|
3231
|
+
entity.movetype = 2 /* Push */;
|
|
3232
|
+
entity.blocked = door_blocked;
|
|
3233
|
+
entity.state = 2 /* Closed */;
|
|
3234
|
+
entity.pos1 = { ...entity.origin };
|
|
3235
|
+
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);
|
|
3236
|
+
entity.pos2 = {
|
|
3237
|
+
x: entity.pos1.x + entity.movedir.x * move,
|
|
3238
|
+
y: entity.pos1.y + entity.movedir.y * move,
|
|
3239
|
+
z: entity.pos1.z + entity.movedir.z * move
|
|
3240
|
+
};
|
|
3241
|
+
entity.use = (self) => {
|
|
3242
|
+
if (self.state !== 2 /* Closed */) return;
|
|
3243
|
+
self.state = 1 /* Opening */;
|
|
3244
|
+
self.think = door_go_up;
|
|
3245
|
+
context.entities.scheduleThink(self, context.entities.timeSeconds + 0.1);
|
|
3246
|
+
};
|
|
3247
|
+
};
|
|
3248
|
+
var func_button = (entity, context) => {
|
|
3249
|
+
entity.solid = 3 /* Bsp */;
|
|
3250
|
+
entity.movetype = 2 /* Push */;
|
|
3251
|
+
entity.use = (self) => {
|
|
3252
|
+
context.entities.useTargets(self, self);
|
|
3253
|
+
};
|
|
3254
|
+
};
|
|
3255
|
+
function registerFuncSpawns(registry) {
|
|
3256
|
+
registry.register("func_door", func_door);
|
|
3257
|
+
registry.register("func_button", func_button);
|
|
3258
|
+
}
|
|
3259
|
+
|
|
2996
3260
|
// src/entities/spawn.ts
|
|
2997
3261
|
var FIELD_LOOKUP = new Map(
|
|
2998
3262
|
ENTITY_FIELD_METADATA.map((field) => [field.name, field])
|
|
@@ -3204,6 +3468,7 @@ function registerDefaultSpawns(game, registry) {
|
|
|
3204
3468
|
registerTargetSpawns(registry);
|
|
3205
3469
|
registerMiscSpawns(registry);
|
|
3206
3470
|
registerItemSpawns(game, registry);
|
|
3471
|
+
registerFuncSpawns(registry);
|
|
3207
3472
|
}
|
|
3208
3473
|
function createDefaultSpawnRegistry(game) {
|
|
3209
3474
|
const registry = new SpawnRegistry();
|
|
@@ -3395,19 +3660,19 @@ var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
|
|
|
3395
3660
|
})(TraceMask || {});
|
|
3396
3661
|
|
|
3397
3662
|
// src/ai/movement.ts
|
|
3398
|
-
function yawVector(yawDegrees,
|
|
3399
|
-
if (
|
|
3663
|
+
function yawVector(yawDegrees, distance2) {
|
|
3664
|
+
if (distance2 === 0) {
|
|
3400
3665
|
return { x: 0, y: 0, z: 0 };
|
|
3401
3666
|
}
|
|
3402
3667
|
const radians = degToRad(yawDegrees);
|
|
3403
3668
|
return {
|
|
3404
|
-
x: Math.cos(radians) *
|
|
3405
|
-
y: Math.sin(radians) *
|
|
3669
|
+
x: Math.cos(radians) * distance2,
|
|
3670
|
+
y: Math.sin(radians) * distance2,
|
|
3406
3671
|
z: 0
|
|
3407
3672
|
};
|
|
3408
3673
|
}
|
|
3409
|
-
function walkMove(self, yawDegrees,
|
|
3410
|
-
const delta = yawVector(yawDegrees,
|
|
3674
|
+
function walkMove(self, yawDegrees, distance2) {
|
|
3675
|
+
const delta = yawVector(yawDegrees, distance2);
|
|
3411
3676
|
const origin = self.origin;
|
|
3412
3677
|
origin.x += delta.x;
|
|
3413
3678
|
origin.y += delta.y;
|
|
@@ -3440,8 +3705,8 @@ function facingIdeal(self) {
|
|
|
3440
3705
|
}
|
|
3441
3706
|
return !(delta > 45 && delta < 315);
|
|
3442
3707
|
}
|
|
3443
|
-
function ai_move(self,
|
|
3444
|
-
walkMove(self, self.angles.y,
|
|
3708
|
+
function ai_move(self, distance2) {
|
|
3709
|
+
walkMove(self, self.angles.y, distance2);
|
|
3445
3710
|
}
|
|
3446
3711
|
function setIdealYawTowards(self, target) {
|
|
3447
3712
|
if (!target) return;
|
|
@@ -3455,40 +3720,40 @@ function setIdealYawTowards(self, target) {
|
|
|
3455
3720
|
function ai_stand(self, deltaSeconds) {
|
|
3456
3721
|
changeYaw(self, deltaSeconds);
|
|
3457
3722
|
}
|
|
3458
|
-
function ai_walk(self,
|
|
3723
|
+
function ai_walk(self, distance2, deltaSeconds) {
|
|
3459
3724
|
setIdealYawTowards(self, self.goalentity);
|
|
3460
3725
|
changeYaw(self, deltaSeconds);
|
|
3461
|
-
if (
|
|
3462
|
-
walkMove(self, self.angles.y,
|
|
3726
|
+
if (distance2 !== 0) {
|
|
3727
|
+
walkMove(self, self.angles.y, distance2);
|
|
3463
3728
|
}
|
|
3464
3729
|
}
|
|
3465
|
-
function ai_turn(self,
|
|
3466
|
-
if (
|
|
3467
|
-
walkMove(self, self.angles.y,
|
|
3730
|
+
function ai_turn(self, distance2, deltaSeconds) {
|
|
3731
|
+
if (distance2 !== 0) {
|
|
3732
|
+
walkMove(self, self.angles.y, distance2);
|
|
3468
3733
|
}
|
|
3469
3734
|
changeYaw(self, deltaSeconds);
|
|
3470
3735
|
}
|
|
3471
|
-
function ai_run(self,
|
|
3736
|
+
function ai_run(self, distance2, deltaSeconds) {
|
|
3472
3737
|
setIdealYawTowards(self, self.enemy ?? self.goalentity);
|
|
3473
3738
|
changeYaw(self, deltaSeconds);
|
|
3474
|
-
if (
|
|
3475
|
-
walkMove(self, self.angles.y,
|
|
3739
|
+
if (distance2 !== 0) {
|
|
3740
|
+
walkMove(self, self.angles.y, distance2);
|
|
3476
3741
|
}
|
|
3477
3742
|
}
|
|
3478
|
-
function ai_face(self, enemy,
|
|
3743
|
+
function ai_face(self, enemy, distance2, deltaSeconds) {
|
|
3479
3744
|
if (enemy) {
|
|
3480
3745
|
setIdealYawTowards(self, enemy);
|
|
3481
3746
|
}
|
|
3482
3747
|
changeYaw(self, deltaSeconds);
|
|
3483
|
-
if (
|
|
3484
|
-
walkMove(self, self.angles.y,
|
|
3748
|
+
if (distance2 !== 0) {
|
|
3749
|
+
walkMove(self, self.angles.y, distance2);
|
|
3485
3750
|
}
|
|
3486
3751
|
}
|
|
3487
|
-
function ai_charge(self,
|
|
3752
|
+
function ai_charge(self, distance2, deltaSeconds) {
|
|
3488
3753
|
setIdealYawTowards(self, self.enemy);
|
|
3489
3754
|
changeYaw(self, deltaSeconds);
|
|
3490
|
-
if (
|
|
3491
|
-
walkMove(self, self.angles.y,
|
|
3755
|
+
if (distance2 !== 0) {
|
|
3756
|
+
walkMove(self, self.angles.y, distance2);
|
|
3492
3757
|
}
|
|
3493
3758
|
}
|
|
3494
3759
|
|
|
@@ -3520,14 +3785,14 @@ function rangeTo(self, other) {
|
|
|
3520
3785
|
const distanceSquared = distanceBetweenBoxesSquared(a.mins, a.maxs, b.mins, b.maxs);
|
|
3521
3786
|
return Math.sqrt(distanceSquared);
|
|
3522
3787
|
}
|
|
3523
|
-
function classifyRange(
|
|
3524
|
-
if (
|
|
3788
|
+
function classifyRange(distance2) {
|
|
3789
|
+
if (distance2 <= RANGE_MELEE) {
|
|
3525
3790
|
return "melee" /* Melee */;
|
|
3526
3791
|
}
|
|
3527
|
-
if (
|
|
3792
|
+
if (distance2 <= RANGE_NEAR) {
|
|
3528
3793
|
return "near" /* Near */;
|
|
3529
3794
|
}
|
|
3530
|
-
if (
|
|
3795
|
+
if (distance2 <= RANGE_MID) {
|
|
3531
3796
|
return "mid" /* Mid */;
|
|
3532
3797
|
}
|
|
3533
3798
|
return "far" /* Far */;
|
|
@@ -3607,8 +3872,8 @@ function foundTarget(self, level, options) {
|
|
|
3607
3872
|
self.monsterinfo.run?.(self);
|
|
3608
3873
|
}
|
|
3609
3874
|
function classifyClientVisibility(self, other, level, trace) {
|
|
3610
|
-
const
|
|
3611
|
-
const range = classifyRange(
|
|
3875
|
+
const distance2 = rangeTo(self, other);
|
|
3876
|
+
const range = classifyRange(distance2);
|
|
3612
3877
|
if (range === "far" /* Far */) return false;
|
|
3613
3878
|
if (other.light_level <= 5) return false;
|
|
3614
3879
|
if (!visible(self, other, trace, { throughGlass: false })) return false;
|
|
@@ -4495,11 +4760,11 @@ function T_RadiusDamage(entities, inflictor, attacker, damage, ignore, radius, d
|
|
|
4495
4760
|
}
|
|
4496
4761
|
const entCenter = ent.mins && ent.maxs ? closestPointToBox(inflictorCenter, addVec3(ent.origin, ent.mins), addVec3(ent.origin, ent.maxs)) : targetCenter(ent);
|
|
4497
4762
|
const toTarget = subtractVec3(inflictorCenter, entCenter);
|
|
4498
|
-
const
|
|
4499
|
-
if (radius > 0 &&
|
|
4763
|
+
const distance2 = lengthVec3(toTarget);
|
|
4764
|
+
if (radius > 0 && distance2 > radius) {
|
|
4500
4765
|
continue;
|
|
4501
4766
|
}
|
|
4502
|
-
const points = damage - 0.5 *
|
|
4767
|
+
const points = damage - 0.5 * distance2;
|
|
4503
4768
|
if (points <= 0) {
|
|
4504
4769
|
continue;
|
|
4505
4770
|
}
|
|
@@ -4923,11 +5188,23 @@ function getWeaponState(playerStates, weaponId) {
|
|
|
4923
5188
|
|
|
4924
5189
|
// src/index.ts
|
|
4925
5190
|
var ZERO_VEC32 = { x: 0, y: 0, z: 0 };
|
|
4926
|
-
function createGame(
|
|
5191
|
+
function createGame({ trace, pointcontents }, engine, options) {
|
|
4927
5192
|
const gravity = options.gravity;
|
|
4928
5193
|
const levelClock = new LevelClock();
|
|
4929
5194
|
const frameLoop = new GameFrameLoop();
|
|
4930
|
-
const
|
|
5195
|
+
const linkentity = (ent) => {
|
|
5196
|
+
ent.absmin = {
|
|
5197
|
+
x: ent.origin.x + ent.mins.x,
|
|
5198
|
+
y: ent.origin.y + ent.mins.y,
|
|
5199
|
+
z: ent.origin.z + ent.mins.z
|
|
5200
|
+
};
|
|
5201
|
+
ent.absmax = {
|
|
5202
|
+
x: ent.origin.x + ent.maxs.x,
|
|
5203
|
+
y: ent.origin.y + ent.maxs.y,
|
|
5204
|
+
z: ent.origin.z + ent.maxs.z
|
|
5205
|
+
};
|
|
5206
|
+
};
|
|
5207
|
+
const entities = new EntitySystem(engine, { trace, pointcontents, linkentity }, gravity);
|
|
4931
5208
|
frameLoop.addStage("prep", (context) => {
|
|
4932
5209
|
levelClock.tick(context);
|
|
4933
5210
|
entities.beginFrame(levelClock.current.timeSeconds);
|
|
@@ -5005,7 +5282,7 @@ function createGame(imports, engine, options) {
|
|
|
5005
5282
|
};
|
|
5006
5283
|
const playerState = { origin: player.origin, velocity: player.velocity, onGround: false, waterLevel: 0, mins: player.mins, maxs: player.maxs, damageAlpha: 0, damageIndicators: [], viewAngles: player.angles };
|
|
5007
5284
|
const traceAdapter = (start, end) => {
|
|
5008
|
-
const result =
|
|
5285
|
+
const result = trace(start, player.mins, player.maxs, end, player, 268435457);
|
|
5009
5286
|
return {
|
|
5010
5287
|
fraction: result.fraction,
|
|
5011
5288
|
endpos: result.endpos,
|
|
@@ -5014,7 +5291,7 @@ function createGame(imports, engine, options) {
|
|
|
5014
5291
|
planeNormal: result.plane?.normal
|
|
5015
5292
|
};
|
|
5016
5293
|
};
|
|
5017
|
-
const pointContentsAdapter = (point) =>
|
|
5294
|
+
const pointContentsAdapter = (point) => pointcontents(point);
|
|
5018
5295
|
const newState = applyPmove(playerState, pcmd, traceAdapter, pointContentsAdapter);
|
|
5019
5296
|
player.origin = newState.origin;
|
|
5020
5297
|
player.velocity = newState.velocity;
|
|
@@ -5028,6 +5305,7 @@ function createGame(imports, engine, options) {
|
|
|
5028
5305
|
centerprintf(entity, message) {
|
|
5029
5306
|
engine.centerprintf?.(entity, message);
|
|
5030
5307
|
},
|
|
5308
|
+
trace,
|
|
5031
5309
|
get time() {
|
|
5032
5310
|
return levelClock.current.timeSeconds;
|
|
5033
5311
|
}
|