quake2ts 0.0.266 → 0.0.269

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.
Files changed (32) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +13 -13
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/cjs/index.cjs +6 -6
  5. package/packages/client/dist/cjs/index.cjs.map +1 -1
  6. package/packages/client/dist/esm/index.js +6 -6
  7. package/packages/client/dist/esm/index.js.map +1 -1
  8. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  9. package/packages/engine/dist/browser/index.global.js.map +1 -1
  10. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  11. package/packages/engine/dist/esm/index.js.map +1 -1
  12. package/packages/game/dist/browser/index.global.js +3 -3
  13. package/packages/game/dist/browser/index.global.js.map +1 -1
  14. package/packages/game/dist/cjs/index.cjs +225 -16
  15. package/packages/game/dist/cjs/index.cjs.map +1 -1
  16. package/packages/game/dist/esm/index.js +225 -16
  17. package/packages/game/dist/esm/index.js.map +1 -1
  18. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  19. package/packages/game/dist/types/entities/system.d.ts +4 -0
  20. package/packages/game/dist/types/entities/system.d.ts.map +1 -1
  21. package/packages/game/dist/types/entities/targets.d.ts.map +1 -1
  22. package/packages/game/dist/types/save/rerelease.d.ts.map +1 -1
  23. package/packages/game/dist/types/save/save.d.ts.map +1 -1
  24. package/packages/shared/dist/browser/index.global.js +1 -1
  25. package/packages/shared/dist/browser/index.global.js.map +1 -1
  26. package/packages/shared/dist/cjs/index.cjs +36 -12
  27. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  28. package/packages/shared/dist/esm/index.js +36 -12
  29. package/packages/shared/dist/esm/index.js.map +1 -1
  30. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  31. package/packages/shared/dist/types/pmove/apply.d.ts.map +1 -1
  32. package/packages/shared/dist/types/pmove/pmove.d.ts.map +1 -1
@@ -512,12 +512,12 @@ function addReplayFrame(session, cmd, serverFrame, startTime) {
512
512
  timestamp: Date.now() - startTime
513
513
  });
514
514
  }
515
- var WaterLevel = /* @__PURE__ */ ((WaterLevel3) => {
516
- WaterLevel3[WaterLevel3["None"] = 0] = "None";
517
- WaterLevel3[WaterLevel3["Feet"] = 1] = "Feet";
518
- WaterLevel3[WaterLevel3["Waist"] = 2] = "Waist";
519
- WaterLevel3[WaterLevel3["Under"] = 3] = "Under";
520
- return WaterLevel3;
515
+ var WaterLevel = /* @__PURE__ */ ((WaterLevel4) => {
516
+ WaterLevel4[WaterLevel4["None"] = 0] = "None";
517
+ WaterLevel4[WaterLevel4["Feet"] = 1] = "Feet";
518
+ WaterLevel4[WaterLevel4["Waist"] = 2] = "Waist";
519
+ WaterLevel4[WaterLevel4["Under"] = 3] = "Under";
520
+ return WaterLevel4;
521
521
  })(WaterLevel || {});
522
522
  function applyPmoveFriction(params) {
523
523
  const {
@@ -594,12 +594,14 @@ function buildWaterWish(params) {
594
594
  let wishvel = {
595
595
  x: forward.x * cmd.forwardmove + right.x * cmd.sidemove,
596
596
  y: forward.y * cmd.forwardmove + right.y * cmd.sidemove,
597
- z: 0
597
+ z: forward.z * cmd.forwardmove + right.z * cmd.sidemove
598
598
  };
599
599
  if (cmd.upmove > 10) {
600
600
  wishvel = addVec3(wishvel, { x: 0, y: 0, z: cmd.upmove });
601
601
  } else if (cmd.upmove < -10) {
602
602
  wishvel = addVec3(wishvel, { x: 0, y: 0, z: cmd.upmove });
603
+ } else if (Math.abs(cmd.forwardmove) < 10 && Math.abs(cmd.sidemove) < 10) {
604
+ wishvel = addVec3(wishvel, { x: 0, y: 0, z: -60 });
603
605
  } else {
604
606
  wishvel = addVec3(wishvel, { x: 0, y: 0, z: 10 });
605
607
  }
@@ -987,6 +989,13 @@ var U_MODEL3 = 1 << 1;
987
989
  var U_MODEL4 = 1 << 2;
988
990
  var U_REMOVE = 32768;
989
991
  var FRAMETIME = 0.025;
992
+ var MASK_WATER2 = 33554432;
993
+ var WaterLevel3 = {
994
+ None: 0,
995
+ Feet: 1,
996
+ Waist: 2,
997
+ Under: 3
998
+ };
990
999
  var categorizePosition2 = (state, trace) => {
991
1000
  const point = { ...state.origin };
992
1001
  point.z -= 0.25;
@@ -998,12 +1007,26 @@ var categorizePosition2 = (state, trace) => {
998
1007
  };
999
1008
  var checkWater = (state, pointContents2) => {
1000
1009
  const point = { ...state.origin };
1001
- point.z += state.mins.z + 1;
1010
+ const { mins, maxs } = state;
1011
+ point.z = state.origin.z + mins.z + 1;
1002
1012
  const contents = pointContents2(point);
1003
- if (contents & 33554432) {
1004
- return { ...state, waterLevel: 1 };
1005
- }
1006
- return { ...state, waterLevel: 0 };
1013
+ if (!(contents & MASK_WATER2)) {
1014
+ return { ...state, waterLevel: WaterLevel3.None };
1015
+ }
1016
+ let waterLevel = WaterLevel3.Feet;
1017
+ const waist = state.origin.z + (mins.z + maxs.z) * 0.5;
1018
+ point.z = waist;
1019
+ const waistContents = pointContents2(point);
1020
+ if (waistContents & MASK_WATER2) {
1021
+ waterLevel = WaterLevel3.Waist;
1022
+ const head = state.origin.z + 22;
1023
+ point.z = head;
1024
+ const headContents = pointContents2(point);
1025
+ if (headContents & MASK_WATER2) {
1026
+ waterLevel = WaterLevel3.Under;
1027
+ }
1028
+ }
1029
+ return { ...state, waterLevel };
1007
1030
  };
1008
1031
  var applyPmove = (state, cmd, trace, pointContents2) => {
1009
1032
  let newState = { ...state };
@@ -1043,7 +1066,8 @@ var applyPmove = (state, cmd, trace, pointContents2) => {
1043
1066
  velocity: frictionedVelocity,
1044
1067
  wishdir: wish.wishdir,
1045
1068
  wishspeed: wish.wishspeed,
1046
- accel: onGround ? 10 : 1,
1069
+ // Water movement uses ground acceleration (10), not air acceleration (1)
1070
+ accel: onGround || waterLevel >= 2 ? 10 : 1,
1047
1071
  frametime: FRAMETIME
1048
1072
  });
1049
1073
  const traceResult = trace(origin, {
@@ -3112,6 +3136,9 @@ var EntitySystem = class {
3112
3136
  this.random = createRandomGenerator();
3113
3137
  this.currentTimeSeconds = 0;
3114
3138
  this.frameNumber = 0;
3139
+ // Persistent state for cross-level logic
3140
+ this.crossLevelFlags = 0;
3141
+ this.crossUnitFlags = 0;
3115
3142
  this.pool = new EntityPool(maxEntities);
3116
3143
  this.thinkScheduler = new ThinkScheduler();
3117
3144
  this.engine = engine;
@@ -3437,11 +3464,15 @@ var EntitySystem = class {
3437
3464
  sound2EntityIndex: this.targetAwareness.sound2Entity?.index ?? null,
3438
3465
  sound2EntityFrame: this.targetAwareness.sound2EntityFrame,
3439
3466
  sightClientIndex: this.targetAwareness.sightClient?.index ?? null
3440
- }
3467
+ },
3468
+ crossLevelFlags: this.crossLevelFlags,
3469
+ crossUnitFlags: this.crossUnitFlags
3441
3470
  };
3442
3471
  }
3443
3472
  restore(snapshot, callbackRegistry) {
3444
3473
  this.currentTimeSeconds = snapshot.timeSeconds;
3474
+ this.crossLevelFlags = snapshot.crossLevelFlags ?? 0;
3475
+ this.crossUnitFlags = snapshot.crossUnitFlags ?? 0;
3445
3476
  this.pool.restore(snapshot.pool);
3446
3477
  const indexToEntity = /* @__PURE__ */ new Map();
3447
3478
  for (const entity of this.pool) {
@@ -4434,6 +4465,131 @@ function useTargetBlaster(self, other, activator, context) {
4434
4465
  }
4435
4466
  context.entities.sound(self, 2, "weapons/laser2.wav", 1, ATTN_NORM, 0);
4436
4467
  }
4468
+ var TARGET_LASER_START_ON = 1;
4469
+ var TARGET_LASER_RED = 2;
4470
+ var TARGET_LASER_GREEN = 4;
4471
+ var TARGET_LASER_BLUE = 8;
4472
+ var TARGET_LASER_YELLOW = 16;
4473
+ var TARGET_LASER_ORANGE = 32;
4474
+ var TARGET_LASER_FAT = 64;
4475
+ function target_laser_think(self, context) {
4476
+ let count;
4477
+ if (self.spawnflags & 2147483648) {
4478
+ count = 8;
4479
+ } else {
4480
+ count = 4;
4481
+ }
4482
+ if (self.enemy) {
4483
+ const last_movedir = { ...self.movedir };
4484
+ const size = subtractVec3(self.enemy.maxs, self.enemy.mins);
4485
+ const centerOffset = scaleVec3(size, 0.5);
4486
+ const enemyCenter = addVec3(self.enemy.mins, centerOffset);
4487
+ const dir = subtractVec3(enemyCenter, self.origin);
4488
+ self.movedir = normalizeVec3(dir);
4489
+ if (Math.abs(self.movedir.x - last_movedir.x) > 1e-3 || Math.abs(self.movedir.y - last_movedir.y) > 1e-3 || Math.abs(self.movedir.z - last_movedir.z) > 1e-3) {
4490
+ self.spawnflags |= 2147483648;
4491
+ }
4492
+ }
4493
+ let ignore = self;
4494
+ let start = { ...self.origin };
4495
+ const end = addVec3(start, scaleVec3(self.movedir, 2048));
4496
+ let traceResult;
4497
+ while (true) {
4498
+ traceResult = context.entities.trace(start, end, ZERO_VEC3, ZERO_VEC3, ignore, CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_DEADMONSTER);
4499
+ if (!traceResult.ent) {
4500
+ break;
4501
+ }
4502
+ const trEnt = traceResult.ent;
4503
+ if (trEnt.takedamage && !(trEnt.flags & 2)) {
4504
+ T_Damage(trEnt, self, self.activator, self.movedir, traceResult.endpos, ZERO_VEC3, self.dmg, 1, 4 /* ENERGY */, 31 /* TARGET_LASER */, context.entities.timeSeconds);
4505
+ }
4506
+ if (!(trEnt.svflags & 1) && !trEnt.client) {
4507
+ if (self.spawnflags & 2147483648) {
4508
+ self.spawnflags &= ~2147483648;
4509
+ context.entities.multicast(traceResult.endpos, 1 /* Pvs */, ServerCommand.temp_entity, TempEntity.LASER_SPARKS, count, traceResult.endpos, traceResult.plane?.normal || ZERO_VEC3, self.skin);
4510
+ }
4511
+ break;
4512
+ }
4513
+ ignore = trEnt;
4514
+ start = { ...traceResult.endpos };
4515
+ }
4516
+ self.old_origin = { ...traceResult.endpos };
4517
+ self.nextthink = context.entities.timeSeconds + 0.1;
4518
+ }
4519
+ function target_laser_on(self, context) {
4520
+ if (!self.activator) {
4521
+ self.activator = self;
4522
+ }
4523
+ self.spawnflags |= 2147483649;
4524
+ self.svflags &= ~1 /* NoClient */;
4525
+ target_laser_think(self, context);
4526
+ }
4527
+ function target_laser_off(self) {
4528
+ self.spawnflags &= ~1;
4529
+ self.svflags |= 1 /* NoClient */;
4530
+ self.nextthink = 0;
4531
+ }
4532
+ function target_laser_use(self, other, activator, context) {
4533
+ self.activator = activator;
4534
+ if (self.spawnflags & 1) {
4535
+ target_laser_off(self);
4536
+ } else {
4537
+ target_laser_on(self, context);
4538
+ }
4539
+ }
4540
+ function target_laser_start(self, context) {
4541
+ self.movetype = 0 /* None */;
4542
+ self.solid = 0 /* Not */;
4543
+ self.renderfx |= 8 | 64;
4544
+ self.modelindex = 1;
4545
+ if (self.spawnflags & TARGET_LASER_FAT) {
4546
+ self.frame = 16;
4547
+ } else {
4548
+ self.frame = 4;
4549
+ }
4550
+ if (self.spawnflags & TARGET_LASER_RED) {
4551
+ self.skin = 4076007664;
4552
+ } else if (self.spawnflags & TARGET_LASER_GREEN) {
4553
+ self.skin = 3503411923;
4554
+ } else if (self.spawnflags & TARGET_LASER_BLUE) {
4555
+ self.skin = 4092850673;
4556
+ } else if (self.spawnflags & TARGET_LASER_YELLOW) {
4557
+ self.skin = 3705528031;
4558
+ } else if (self.spawnflags & TARGET_LASER_ORANGE) {
4559
+ self.skin = 3772900067;
4560
+ }
4561
+ if (!self.enemy) {
4562
+ if (self.target) {
4563
+ let found = null;
4564
+ context.entities.forEachEntity((ent) => {
4565
+ if (ent.targetname === self.target) {
4566
+ found = ent;
4567
+ }
4568
+ });
4569
+ if (found) {
4570
+ self.enemy = found;
4571
+ } else {
4572
+ context.warn(`${self.classname} at ${self.origin}: ${self.target} is a bad target`);
4573
+ self.movedir = setMovedir(self.angles);
4574
+ }
4575
+ } else {
4576
+ self.movedir = setMovedir(self.angles);
4577
+ }
4578
+ }
4579
+ self.use = (s, o, a) => target_laser_use(s, o, a || null, context);
4580
+ self.think = (s) => target_laser_think(s, context);
4581
+ if (!self.dmg) {
4582
+ self.dmg = 1;
4583
+ }
4584
+ self.absmin = addVec3(self.origin, { x: -8, y: -8, z: -8 });
4585
+ self.absmax = addVec3(self.origin, { x: 8, y: 8, z: 8 });
4586
+ context.entities.linkentity(self);
4587
+ if (self.spawnflags & TARGET_LASER_START_ON) {
4588
+ target_laser_on(self, context);
4589
+ } else {
4590
+ target_laser_off(self);
4591
+ }
4592
+ }
4437
4593
  function registerTargetSpawns(registry) {
4438
4594
  registry.register("target_temp_entity", (entity, context) => {
4439
4595
  entity.style = context.keyValues.style ? parseInt(context.keyValues.style) : 0;
@@ -4516,6 +4672,55 @@ function registerTargetSpawns(registry) {
4516
4672
  if (!entity.speed) entity.speed = 1e3;
4517
4673
  entity.svflags |= 1 /* NoClient */;
4518
4674
  });
4675
+ registry.register("target_laser", (entity, context) => {
4676
+ entity.think = (self) => target_laser_start(self, context);
4677
+ entity.think = (self) => target_laser_start(self, context);
4678
+ entity.nextthink = context.entities.timeSeconds + 1;
4679
+ });
4680
+ registry.register("target_crosslevel_trigger", (entity, context) => {
4681
+ entity.svflags |= 1 /* NoClient */;
4682
+ entity.use = (self) => {
4683
+ context.entities.crossLevelFlags |= self.spawnflags;
4684
+ context.free(self);
4685
+ };
4686
+ });
4687
+ registry.register("target_crosslevel_target", (entity, context) => {
4688
+ entity.svflags |= 1 /* NoClient */;
4689
+ if (!entity.delay) {
4690
+ entity.delay = 1;
4691
+ }
4692
+ const SFL_CROSS_TRIGGER_MASK = 4294967295;
4693
+ entity.think = (self) => {
4694
+ const flags = self.spawnflags & SFL_CROSS_TRIGGER_MASK;
4695
+ if ((context.entities.crossLevelFlags & flags) === flags) {
4696
+ context.entities.useTargets(self, self);
4697
+ context.free(self);
4698
+ }
4699
+ };
4700
+ context.entities.scheduleThink(entity, context.entities.timeSeconds + entity.delay);
4701
+ });
4702
+ registry.register("target_crossunit_trigger", (entity, context) => {
4703
+ entity.svflags |= 1 /* NoClient */;
4704
+ entity.use = (self) => {
4705
+ context.entities.crossUnitFlags |= self.spawnflags;
4706
+ context.free(self);
4707
+ };
4708
+ });
4709
+ registry.register("target_crossunit_target", (entity, context) => {
4710
+ entity.svflags |= 1 /* NoClient */;
4711
+ if (!entity.delay) {
4712
+ entity.delay = 1;
4713
+ }
4714
+ const SFL_CROSS_TRIGGER_MASK = 4294967295;
4715
+ entity.think = (self) => {
4716
+ const flags = self.spawnflags & SFL_CROSS_TRIGGER_MASK;
4717
+ if ((context.entities.crossUnitFlags & flags) === flags) {
4718
+ context.entities.useTargets(self, self);
4719
+ context.free(self);
4720
+ }
4721
+ };
4722
+ context.entities.scheduleThink(entity, context.entities.timeSeconds + entity.delay);
4723
+ });
4519
4724
  }
4520
4725
 
4521
4726
  // src/entities/triggers.ts
@@ -14579,7 +14784,9 @@ function parseEntitySnapshot(raw) {
14579
14784
  pool: parsePool(snapshot.pool),
14580
14785
  entities: parseEntities(snapshot.entities),
14581
14786
  thinks: parseThinkEntries(snapshot.thinks),
14582
- awareness: parseAwareness(snapshot.awareness)
14787
+ awareness: parseAwareness(snapshot.awareness),
14788
+ crossLevelFlags: ensureNumberOrDefault(snapshot.crossLevelFlags, "entities.crossLevelFlags", 0),
14789
+ crossUnitFlags: ensureNumberOrDefault(snapshot.crossUnitFlags, "entities.crossUnitFlags", 0)
14583
14790
  };
14584
14791
  }
14585
14792
  function parseCvars(raw) {
@@ -14940,7 +15147,9 @@ function buildEntitySnapshot(entities, levelTimeSeconds, capacityHint) {
14940
15147
  pool: { capacity, activeOrder, freeList, pendingFree: [] },
14941
15148
  entities: serialized,
14942
15149
  thinks: [],
14943
- awareness: dummyAwareness
15150
+ awareness: dummyAwareness,
15151
+ crossLevelFlags: 0,
15152
+ crossUnitFlags: 0
14944
15153
  };
14945
15154
  }
14946
15155
  function buildLevelState(level) {