quake2ts 0.0.45 → 0.0.47
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/apps/viewer/dist/browser/index.global.js +1 -1
- package/apps/viewer/dist/browser/index.global.js.map +1 -1
- package/apps/viewer/dist/cjs/index.cjs +14 -3
- package/apps/viewer/dist/cjs/index.cjs.map +1 -1
- package/apps/viewer/dist/esm/index.js +14 -3
- package/apps/viewer/dist/esm/index.js.map +1 -1
- package/apps/viewer/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +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 +69 -10
- package/packages/engine/dist/browser/index.global.js.map +1 -1
- package/packages/engine/dist/cjs/index.cjs +781 -5
- package/packages/engine/dist/cjs/index.cjs.map +1 -1
- package/packages/engine/dist/esm/index.js +763 -5
- package/packages/engine/dist/esm/index.js.map +1 -1
- package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/engine/dist/types/index.d.ts +2 -0
- package/packages/engine/dist/types/index.d.ts.map +1 -1
- package/packages/engine/dist/types/render/md3Pipeline.d.ts +79 -0
- package/packages/engine/dist/types/render/md3Pipeline.d.ts.map +1 -0
- package/packages/engine/dist/types/render/particleSystem.d.ts +105 -0
- package/packages/engine/dist/types/render/particleSystem.d.ts.map +1 -0
- 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 +176 -3
- package/packages/game/dist/cjs/index.cjs.map +1 -1
- package/packages/game/dist/esm/index.js +172 -3
- package/packages/game/dist/esm/index.js.map +1 -1
- package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/types/ai/constants.d.ts +16 -0
- package/packages/game/dist/types/ai/constants.d.ts.map +1 -1
- package/packages/game/dist/types/ai/index.d.ts +1 -0
- package/packages/game/dist/types/ai/index.d.ts.map +1 -1
- package/packages/game/dist/types/ai/targeting.d.ts +25 -0
- package/packages/game/dist/types/ai/targeting.d.ts.map +1 -0
- package/packages/game/dist/types/entities/entity.d.ts +11 -0
- package/packages/game/dist/types/entities/entity.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 +65 -0
- package/packages/shared/dist/cjs/index.cjs.map +1 -1
- package/packages/shared/dist/esm/index.js +61 -0
- package/packages/shared/dist/esm/index.js.map +1 -1
- package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/shared/dist/types/index.d.ts +1 -0
- package/packages/shared/dist/types/index.d.ts.map +1 -1
- package/packages/shared/dist/types/math/mat4.d.ts +7 -0
- package/packages/shared/dist/types/math/mat4.d.ts.map +1 -0
- package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
|
@@ -408,7 +408,12 @@ var ZERO = { ...ZERO_VEC3 };
|
|
|
408
408
|
function copyVec3() {
|
|
409
409
|
return { ...ZERO };
|
|
410
410
|
}
|
|
411
|
-
var DEFAULT_MONSTER_INFO = Object.freeze({
|
|
411
|
+
var DEFAULT_MONSTER_INFO = Object.freeze({
|
|
412
|
+
aiflags: 0,
|
|
413
|
+
last_sighting: ZERO,
|
|
414
|
+
trail_time: 0,
|
|
415
|
+
pausetime: 0
|
|
416
|
+
});
|
|
412
417
|
var Entity = class {
|
|
413
418
|
constructor(index) {
|
|
414
419
|
this.inUse = false;
|
|
@@ -468,7 +473,9 @@ var Entity = class {
|
|
|
468
473
|
this.solid = 0 /* Not */;
|
|
469
474
|
this.flags = 0;
|
|
470
475
|
this.svflags = 0;
|
|
471
|
-
this.monsterinfo = { ...DEFAULT_MONSTER_INFO };
|
|
476
|
+
this.monsterinfo = { ...DEFAULT_MONSTER_INFO, last_sighting: copyVec3() };
|
|
477
|
+
this.show_hostile = 0;
|
|
478
|
+
this.light_level = 0;
|
|
472
479
|
this.index = index;
|
|
473
480
|
}
|
|
474
481
|
reset() {
|
|
@@ -542,7 +549,10 @@ var Entity = class {
|
|
|
542
549
|
this.solid = 0 /* Not */;
|
|
543
550
|
this.flags = 0;
|
|
544
551
|
this.svflags = 0;
|
|
545
|
-
this.monsterinfo = { ...DEFAULT_MONSTER_INFO };
|
|
552
|
+
this.monsterinfo = { ...DEFAULT_MONSTER_INFO, last_sighting: copyVec3() };
|
|
553
|
+
this.combattarget = void 0;
|
|
554
|
+
this.show_hostile = 0;
|
|
555
|
+
this.light_level = 0;
|
|
546
556
|
}
|
|
547
557
|
};
|
|
548
558
|
var ENTITY_FIELD_METADATA = [
|
|
@@ -2065,9 +2075,25 @@ var LevelClock = class {
|
|
|
2065
2075
|
var RANGE_MELEE = 20;
|
|
2066
2076
|
var RANGE_NEAR = 440;
|
|
2067
2077
|
var RANGE_MID = 940;
|
|
2078
|
+
var FL_NOTARGET = 1 << 5;
|
|
2068
2079
|
var FL_NOVISIBLE = 1 << 24;
|
|
2069
2080
|
var SPAWNFLAG_MONSTER_AMBUSH = 1 << 0;
|
|
2070
2081
|
var AIFlags = /* @__PURE__ */ ((AIFlags2) => {
|
|
2082
|
+
AIFlags2[AIFlags2["StandGround"] = 1] = "StandGround";
|
|
2083
|
+
AIFlags2[AIFlags2["TempStandGround"] = 2] = "TempStandGround";
|
|
2084
|
+
AIFlags2[AIFlags2["SoundTarget"] = 4] = "SoundTarget";
|
|
2085
|
+
AIFlags2[AIFlags2["LostSight"] = 8] = "LostSight";
|
|
2086
|
+
AIFlags2[AIFlags2["PursuitLastSeen"] = 16] = "PursuitLastSeen";
|
|
2087
|
+
AIFlags2[AIFlags2["PursueNext"] = 32] = "PursueNext";
|
|
2088
|
+
AIFlags2[AIFlags2["PursueTemp"] = 64] = "PursueTemp";
|
|
2089
|
+
AIFlags2[AIFlags2["HoldFrame"] = 128] = "HoldFrame";
|
|
2090
|
+
AIFlags2[AIFlags2["GoodGuy"] = 256] = "GoodGuy";
|
|
2091
|
+
AIFlags2[AIFlags2["Brutal"] = 512] = "Brutal";
|
|
2092
|
+
AIFlags2[AIFlags2["NoStep"] = 1024] = "NoStep";
|
|
2093
|
+
AIFlags2[AIFlags2["Ducked"] = 2048] = "Ducked";
|
|
2094
|
+
AIFlags2[AIFlags2["CombatPoint"] = 4096] = "CombatPoint";
|
|
2095
|
+
AIFlags2[AIFlags2["Medic"] = 8192] = "Medic";
|
|
2096
|
+
AIFlags2[AIFlags2["Resurrecting"] = 16384] = "Resurrecting";
|
|
2071
2097
|
AIFlags2[AIFlags2["Pathing"] = 1073741824] = "Pathing";
|
|
2072
2098
|
return AIFlags2;
|
|
2073
2099
|
})(AIFlags || {});
|
|
@@ -2235,6 +2261,145 @@ function visible(self, other, trace, options) {
|
|
|
2235
2261
|
return result.fraction === 1 || result.entity === other;
|
|
2236
2262
|
}
|
|
2237
2263
|
|
|
2264
|
+
// src/ai/targeting.ts
|
|
2265
|
+
function setIdealYawTowards2(self, other) {
|
|
2266
|
+
const delta = {
|
|
2267
|
+
x: other.origin.x - self.origin.x,
|
|
2268
|
+
y: other.origin.y - self.origin.y,
|
|
2269
|
+
z: other.origin.z - self.origin.z
|
|
2270
|
+
};
|
|
2271
|
+
self.ideal_yaw = vectorToYaw(delta);
|
|
2272
|
+
}
|
|
2273
|
+
function faceYawInstantly(self) {
|
|
2274
|
+
self.angles.y = angleMod(self.ideal_yaw);
|
|
2275
|
+
}
|
|
2276
|
+
function huntTarget(self, level) {
|
|
2277
|
+
if (!self.enemy) return;
|
|
2278
|
+
self.goalentity = self.enemy;
|
|
2279
|
+
setIdealYawTowards2(self, self.enemy);
|
|
2280
|
+
faceYawInstantly(self);
|
|
2281
|
+
if ((self.monsterinfo.aiflags & 1 /* StandGround */) !== 0) {
|
|
2282
|
+
self.monsterinfo.stand?.(self);
|
|
2283
|
+
} else {
|
|
2284
|
+
self.monsterinfo.run?.(self);
|
|
2285
|
+
self.attack_finished_time = level.timeSeconds + 1;
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
function foundTarget(self, level, options) {
|
|
2289
|
+
if (!self.enemy) return;
|
|
2290
|
+
if ((self.enemy.svflags & 8 /* Player */) !== 0) {
|
|
2291
|
+
level.sightEntity = self;
|
|
2292
|
+
level.sightEntityFrame = level.frameNumber;
|
|
2293
|
+
self.light_level = 128;
|
|
2294
|
+
}
|
|
2295
|
+
self.show_hostile = level.timeSeconds + 1;
|
|
2296
|
+
const lastSighting = self.monsterinfo.last_sighting;
|
|
2297
|
+
lastSighting.x = self.enemy.origin.x;
|
|
2298
|
+
lastSighting.y = self.enemy.origin.y;
|
|
2299
|
+
lastSighting.z = self.enemy.origin.z;
|
|
2300
|
+
self.trail_time = level.timeSeconds;
|
|
2301
|
+
self.monsterinfo.trail_time = level.timeSeconds;
|
|
2302
|
+
if (!self.combattarget) {
|
|
2303
|
+
huntTarget(self, level);
|
|
2304
|
+
return;
|
|
2305
|
+
}
|
|
2306
|
+
const pickTarget = options?.pickTarget;
|
|
2307
|
+
const movetarget = pickTarget?.(self.combattarget) ?? self.enemy;
|
|
2308
|
+
self.goalentity = movetarget;
|
|
2309
|
+
self.movetarget = movetarget;
|
|
2310
|
+
self.combattarget = void 0;
|
|
2311
|
+
self.monsterinfo.aiflags |= 4096 /* CombatPoint */;
|
|
2312
|
+
if (self.movetarget) {
|
|
2313
|
+
self.movetarget.targetname = void 0;
|
|
2314
|
+
}
|
|
2315
|
+
self.monsterinfo.pausetime = 0;
|
|
2316
|
+
self.monsterinfo.run?.(self);
|
|
2317
|
+
}
|
|
2318
|
+
function classifyClientVisibility(self, other, level) {
|
|
2319
|
+
const distance = rangeTo(self, other);
|
|
2320
|
+
const range = classifyRange(distance);
|
|
2321
|
+
const passthrough = (_start, _end, _ignore, _mask) => ({ fraction: 1, entity: other });
|
|
2322
|
+
if (range === "far" /* Far */) return false;
|
|
2323
|
+
if (other.light_level <= 5) return false;
|
|
2324
|
+
if (!visible(self, other, passthrough, { throughGlass: false })) return false;
|
|
2325
|
+
if (range === "near" /* Near */) {
|
|
2326
|
+
return level.timeSeconds <= other.show_hostile || infront(self, other);
|
|
2327
|
+
}
|
|
2328
|
+
if (range === "mid" /* Mid */) {
|
|
2329
|
+
return infront(self, other);
|
|
2330
|
+
}
|
|
2331
|
+
return true;
|
|
2332
|
+
}
|
|
2333
|
+
function updateSoundChase(self, client, level, hearability) {
|
|
2334
|
+
const passthrough = (_start, _end, _ignore, _mask) => ({ fraction: 1, entity: client });
|
|
2335
|
+
if ((self.spawnflags & SPAWNFLAG_MONSTER_AMBUSH) !== 0) {
|
|
2336
|
+
if (!visible(self, client, passthrough)) return false;
|
|
2337
|
+
} else if (hearability.canHear && !hearability.canHear(self, client)) {
|
|
2338
|
+
return false;
|
|
2339
|
+
}
|
|
2340
|
+
const delta = subtractVec3(client.origin, self.origin);
|
|
2341
|
+
if (lengthVec3(delta) > 1e3) return false;
|
|
2342
|
+
if (hearability.areasConnected && !hearability.areasConnected(self, client)) return false;
|
|
2343
|
+
self.ideal_yaw = vectorToYaw(delta);
|
|
2344
|
+
faceYawInstantly(self);
|
|
2345
|
+
self.monsterinfo.aiflags |= 4 /* SoundTarget */;
|
|
2346
|
+
self.enemy = client;
|
|
2347
|
+
return true;
|
|
2348
|
+
}
|
|
2349
|
+
function chooseCandidate(self, level) {
|
|
2350
|
+
if (level.sightEntity && level.sightEntityFrame >= level.frameNumber - 1 && (self.spawnflags & SPAWNFLAG_MONSTER_AMBUSH) === 0) {
|
|
2351
|
+
if (level.sightEntity.enemy !== self.enemy) {
|
|
2352
|
+
return { candidate: level.sightEntity, heardit: false };
|
|
2353
|
+
}
|
|
2354
|
+
return { candidate: null, heardit: false };
|
|
2355
|
+
}
|
|
2356
|
+
if (level.soundEntity && level.soundEntityFrame >= level.frameNumber - 1) {
|
|
2357
|
+
return { candidate: level.soundEntity, heardit: true };
|
|
2358
|
+
}
|
|
2359
|
+
if (!self.enemy && level.sound2Entity && level.sound2EntityFrame >= level.frameNumber - 1 && (self.spawnflags & SPAWNFLAG_MONSTER_AMBUSH) === 0) {
|
|
2360
|
+
return { candidate: level.sound2Entity, heardit: true };
|
|
2361
|
+
}
|
|
2362
|
+
if (level.sightClient) {
|
|
2363
|
+
return { candidate: level.sightClient, heardit: false };
|
|
2364
|
+
}
|
|
2365
|
+
return { candidate: null, heardit: false };
|
|
2366
|
+
}
|
|
2367
|
+
function rejectNotargetEntity(client) {
|
|
2368
|
+
if ((client.flags & FL_NOTARGET) !== 0) return true;
|
|
2369
|
+
if ((client.svflags & 4 /* Monster */) !== 0 && client.enemy) {
|
|
2370
|
+
return (client.enemy.flags & FL_NOTARGET) !== 0;
|
|
2371
|
+
}
|
|
2372
|
+
if (client.enemy && (client.enemy.flags & FL_NOTARGET) !== 0) return true;
|
|
2373
|
+
return false;
|
|
2374
|
+
}
|
|
2375
|
+
function findTarget(self, level, hearability = {}) {
|
|
2376
|
+
if ((self.monsterinfo.aiflags & 256 /* GoodGuy */) !== 0) {
|
|
2377
|
+
if (self.goalentity?.classname === "target_actor") {
|
|
2378
|
+
return false;
|
|
2379
|
+
}
|
|
2380
|
+
return false;
|
|
2381
|
+
}
|
|
2382
|
+
if ((self.monsterinfo.aiflags & 4096 /* CombatPoint */) !== 0) {
|
|
2383
|
+
return false;
|
|
2384
|
+
}
|
|
2385
|
+
const { candidate, heardit } = chooseCandidate(self, level);
|
|
2386
|
+
if (!candidate || !candidate.inUse) return false;
|
|
2387
|
+
if (candidate === self.enemy) return true;
|
|
2388
|
+
if (rejectNotargetEntity(candidate)) return false;
|
|
2389
|
+
if (!heardit) {
|
|
2390
|
+
if (!classifyClientVisibility(self, candidate, level)) return false;
|
|
2391
|
+
self.monsterinfo.aiflags &= ~4 /* SoundTarget */;
|
|
2392
|
+
self.enemy = candidate;
|
|
2393
|
+
} else if (!updateSoundChase(self, candidate, level, hearability)) {
|
|
2394
|
+
return false;
|
|
2395
|
+
}
|
|
2396
|
+
foundTarget(self, level);
|
|
2397
|
+
if ((self.monsterinfo.aiflags & 4 /* SoundTarget */) === 0) {
|
|
2398
|
+
self.monsterinfo.sight?.(self, self.enemy);
|
|
2399
|
+
}
|
|
2400
|
+
return true;
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2238
2403
|
// src/checksum.ts
|
|
2239
2404
|
var FNV_OFFSET_BASIS = 2166136261;
|
|
2240
2405
|
var FNV_PRIME = 16777619;
|
|
@@ -3697,6 +3862,7 @@ export {
|
|
|
3697
3862
|
EntityDamageFlags,
|
|
3698
3863
|
EntitySystem,
|
|
3699
3864
|
EnvironmentalFlags,
|
|
3865
|
+
FL_NOTARGET,
|
|
3700
3866
|
FL_NOVISIBLE,
|
|
3701
3867
|
KeyId,
|
|
3702
3868
|
MoveType,
|
|
@@ -3750,6 +3916,8 @@ export {
|
|
|
3750
3916
|
damageModName,
|
|
3751
3917
|
equipArmor,
|
|
3752
3918
|
facingIdeal,
|
|
3919
|
+
findTarget,
|
|
3920
|
+
foundTarget,
|
|
3753
3921
|
getAmmoItemDefinition,
|
|
3754
3922
|
giveAmmo,
|
|
3755
3923
|
giveAmmoItem,
|
|
@@ -3759,6 +3927,7 @@ export {
|
|
|
3759
3927
|
hasPowerup,
|
|
3760
3928
|
hasWeapon,
|
|
3761
3929
|
hashGameState,
|
|
3930
|
+
huntTarget,
|
|
3762
3931
|
infront,
|
|
3763
3932
|
isZeroVector,
|
|
3764
3933
|
killBox,
|