quake2ts 0.0.543 → 0.0.544

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 (27) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +17 -17
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/cjs/index.cjs +264 -6
  5. package/packages/client/dist/cjs/index.cjs.map +1 -1
  6. package/packages/client/dist/esm/index.js +264 -6
  7. package/packages/client/dist/esm/index.js.map +1 -1
  8. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  9. package/packages/client/dist/types/effects-system.d.ts +1 -1
  10. package/packages/client/dist/types/effects-system.d.ts.map +1 -1
  11. package/packages/engine/dist/browser/index.global.js +15 -15
  12. package/packages/engine/dist/browser/index.global.js.map +1 -1
  13. package/packages/engine/dist/cjs/index.cjs +388 -46
  14. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  15. package/packages/engine/dist/esm/index.js +384 -46
  16. package/packages/engine/dist/esm/index.js.map +1 -1
  17. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  18. package/packages/engine/dist/types/assets/visibilityAnalyzer.d.ts +17 -0
  19. package/packages/engine/dist/types/assets/visibilityAnalyzer.d.ts.map +1 -0
  20. package/packages/engine/dist/types/demo/parser.d.ts.map +1 -1
  21. package/packages/engine/dist/types/demo/writer.d.ts +13 -12
  22. package/packages/engine/dist/types/demo/writer.d.ts.map +1 -1
  23. package/packages/engine/dist/types/index.d.ts +1 -1
  24. package/packages/engine/dist/types/index.d.ts.map +1 -1
  25. package/packages/engine/dist/types/render/particleSystem.d.ts +16 -0
  26. package/packages/engine/dist/types/render/particleSystem.d.ts.map +1 -1
  27. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
@@ -3986,6 +3986,137 @@ function spawnSteam(context) {
3986
3986
  });
3987
3987
  }
3988
3988
  }
3989
+ function spawnRailTrail(context) {
3990
+ const { system, start, end } = context;
3991
+ const dx = end.x - start.x;
3992
+ const dy = end.y - start.y;
3993
+ const dz = end.z - start.z;
3994
+ const dist2 = Math.sqrt(dx * dx + dy * dy + dz * dz);
3995
+ if (dist2 < 1) return;
3996
+ const dir = { x: dx / dist2, y: dy / dist2, z: dz / dist2 };
3997
+ const step = 8;
3998
+ for (let d = 0; d < dist2; d += step) {
3999
+ const x = start.x + dir.x * d;
4000
+ const y = start.y + dir.y * d;
4001
+ const z = start.z + dir.z * d;
4002
+ system.spawn({
4003
+ position: { x, y, z },
4004
+ velocity: { x: 0, y: 0, z: 0 },
4005
+ // Static
4006
+ color: [0.4, 0.4, 1, 0.8],
4007
+ size: 2,
4008
+ lifetime: 0.6,
4009
+ blendMode: "additive",
4010
+ fade: true
4011
+ });
4012
+ const radius = 3;
4013
+ const theta = d * 0.5;
4014
+ system.spawn({
4015
+ position: {
4016
+ x: x + (system.rng.frandom() - 0.5) * 6,
4017
+ y: y + (system.rng.frandom() - 0.5) * 6,
4018
+ z: z + (system.rng.frandom() - 0.5) * 6
4019
+ },
4020
+ velocity: {
4021
+ x: (system.rng.frandom() - 0.5) * 10,
4022
+ y: (system.rng.frandom() - 0.5) * 10,
4023
+ z: (system.rng.frandom() - 0.5) * 10
4024
+ },
4025
+ color: [0.1, 0.1, 0.8, 0.6],
4026
+ size: 3,
4027
+ lifetime: 0.8 + system.rng.frandom() * 0.2,
4028
+ blendMode: "additive",
4029
+ fade: true
4030
+ });
4031
+ }
4032
+ }
4033
+ function spawnSparks(context) {
4034
+ const { system, origin, normal = { x: 0, y: 0, z: 1 }, count = 12, color = [1, 0.9, 0.2, 1] } = context;
4035
+ for (let i = 0; i < count; i++) {
4036
+ const speed = 100 + system.rng.frandom() * 200;
4037
+ const spread = 0.5;
4038
+ system.spawn({
4039
+ position: origin,
4040
+ velocity: {
4041
+ x: normal.x * speed + (system.rng.frandom() - 0.5) * 100 * spread,
4042
+ y: normal.y * speed + (system.rng.frandom() - 0.5) * 100 * spread,
4043
+ z: normal.z * speed + (system.rng.frandom() - 0.5) * 100 * spread
4044
+ },
4045
+ color,
4046
+ size: 1.5,
4047
+ lifetime: 0.3 + system.rng.frandom() * 0.2,
4048
+ gravity: 800,
4049
+ bounce: 0.5,
4050
+ damping: 1,
4051
+ blendMode: "additive",
4052
+ fade: true
4053
+ });
4054
+ }
4055
+ }
4056
+ function spawnBlasterImpact(context) {
4057
+ const { system, origin, normal = { x: 0, y: 0, z: 1 }, color = [1, 0.8, 0, 1] } = context;
4058
+ system.spawn({
4059
+ position: origin,
4060
+ velocity: { x: 0, y: 0, z: 0 },
4061
+ color,
4062
+ size: 8,
4063
+ lifetime: 0.2,
4064
+ blendMode: "additive",
4065
+ fade: true
4066
+ });
4067
+ for (let i = 0; i < 8; i++) {
4068
+ const speed = 150 + system.rng.frandom() * 150;
4069
+ system.spawn({
4070
+ position: origin,
4071
+ velocity: {
4072
+ x: normal.x * speed + (system.rng.frandom() - 0.5) * 120,
4073
+ y: normal.y * speed + (system.rng.frandom() - 0.5) * 120,
4074
+ z: normal.z * speed + (system.rng.frandom() - 0.5) * 120
4075
+ },
4076
+ color,
4077
+ size: 2,
4078
+ lifetime: 0.4 + system.rng.frandom() * 0.2,
4079
+ gravity: 400,
4080
+ blendMode: "additive",
4081
+ fade: true
4082
+ });
4083
+ }
4084
+ }
4085
+ function spawnBfgExplosion(context) {
4086
+ const { system, origin } = context;
4087
+ system.spawn({
4088
+ position: origin,
4089
+ velocity: { x: 0, y: 0, z: 0 },
4090
+ color: [0.2, 1, 0.2, 1],
4091
+ // Green
4092
+ size: 30,
4093
+ lifetime: 0.5,
4094
+ blendMode: "additive",
4095
+ fade: true
4096
+ });
4097
+ for (let i = 0; i < 60; i++) {
4098
+ const theta = system.rng.frandom() * Math.PI * 2;
4099
+ const phi = Math.acos(2 * system.rng.frandom() - 1);
4100
+ const speed = 300 + system.rng.frandom() * 400;
4101
+ const dir = {
4102
+ x: Math.sin(phi) * Math.cos(theta),
4103
+ y: Math.sin(phi) * Math.sin(theta),
4104
+ z: Math.cos(phi)
4105
+ };
4106
+ system.spawn({
4107
+ position: origin,
4108
+ velocity: { x: dir.x * speed, y: dir.y * speed, z: dir.z * speed },
4109
+ color: [0.2, 1, 0.2, 0.8],
4110
+ size: 4,
4111
+ lifetime: 1,
4112
+ gravity: 100,
4113
+ // Low gravity
4114
+ damping: 1,
4115
+ blendMode: "additive",
4116
+ fade: true
4117
+ });
4118
+ }
4119
+ }
3989
4120
  var DemoReader = class {
3990
4121
  constructor(buffer) {
3991
4122
  this.messageOffsets = [];
@@ -8651,6 +8782,32 @@ var BinaryStreamAdapter = class extends StreamingBuffer {
8651
8782
  throw new Error("peekBytes not implemented for BinaryStreamAdapter");
8652
8783
  }
8653
8784
  };
8785
+ var PROTO34_MAP = {
8786
+ 0: ServerCommand.bad,
8787
+ 1: ServerCommand.nop,
8788
+ 2: ServerCommand.disconnect,
8789
+ 3: ServerCommand.reconnect,
8790
+ 4: ServerCommand.download,
8791
+ 5: ServerCommand.frame,
8792
+ 6: ServerCommand.inventory,
8793
+ 7: ServerCommand.layout,
8794
+ 8: ServerCommand.muzzleflash,
8795
+ 9: ServerCommand.sound,
8796
+ 10: ServerCommand.print,
8797
+ 11: ServerCommand.stufftext,
8798
+ 12: ServerCommand.serverdata,
8799
+ 13: ServerCommand.configstring,
8800
+ 14: ServerCommand.spawnbaseline,
8801
+ 15: ServerCommand.centerprint,
8802
+ 16: ServerCommand.download,
8803
+ 17: ServerCommand.playerinfo,
8804
+ 18: ServerCommand.packetentities,
8805
+ 19: ServerCommand.deltapacketentities,
8806
+ 23: ServerCommand.temp_entity,
8807
+ // Wire 23 -> Enum 3 (TempEntity)
8808
+ 22: ServerCommand.muzzleflash2
8809
+ // Wire 22 -> Enum 2 (MuzzleFlash2)
8810
+ };
8654
8811
  var NetworkMessageParser = class _NetworkMessageParser {
8655
8812
  constructor(stream, handler, strictMode = false) {
8656
8813
  this.protocolVersion = 0;
@@ -8692,7 +8849,9 @@ var NetworkMessageParser = class _NetworkMessageParser {
8692
8849
  return ServerCommand.bad;
8693
8850
  }
8694
8851
  if (this.protocolVersion === 34) {
8695
- if (cmd <= ServerCommand.frame) return cmd;
8852
+ if (PROTO34_MAP[cmd] !== void 0) {
8853
+ return PROTO34_MAP[cmd];
8854
+ }
8696
8855
  return ServerCommand.bad;
8697
8856
  }
8698
8857
  return cmd;
@@ -9230,7 +9389,7 @@ var NetworkMessageParser = class _NetworkMessageParser {
9230
9389
  const playerState = this.parsePlayerState();
9231
9390
  let peCmd = this.stream.readByte();
9232
9391
  peCmd = this.translateCommand(peCmd);
9233
- if (peCmd !== ServerCommand.packetentities) {
9392
+ if (peCmd !== ServerCommand.packetentities && peCmd !== ServerCommand.deltapacketentities) {
9234
9393
  if (this.strictMode) throw new Error(`Expected svc_packetentities after svc_playerinfo, got ${peCmd}`);
9235
9394
  return;
9236
9395
  }
@@ -10431,6 +10590,47 @@ var DemoValidator = class {
10431
10590
  return { valid: true, version };
10432
10591
  }
10433
10592
  };
10593
+ var PROTO34_REVERSE_MAP = {
10594
+ [ServerCommand.bad]: 0,
10595
+ [ServerCommand.nop]: 1,
10596
+ [ServerCommand.disconnect]: 2,
10597
+ [ServerCommand.reconnect]: 3,
10598
+ // 4 is download? standard Q2 uses 4 for download sometimes, but let's stick to parser map (download=16).
10599
+ // Let's map download to 16.
10600
+ [ServerCommand.download]: 16,
10601
+ [ServerCommand.frame]: 5,
10602
+ [ServerCommand.inventory]: 6,
10603
+ [ServerCommand.layout]: 7,
10604
+ [ServerCommand.muzzleflash]: 8,
10605
+ [ServerCommand.sound]: 9,
10606
+ [ServerCommand.print]: 10,
10607
+ [ServerCommand.stufftext]: 11,
10608
+ [ServerCommand.serverdata]: 12,
10609
+ [ServerCommand.configstring]: 13,
10610
+ [ServerCommand.spawnbaseline]: 14,
10611
+ [ServerCommand.centerprint]: 15,
10612
+ // 16 is download
10613
+ [ServerCommand.playerinfo]: 17,
10614
+ [ServerCommand.packetentities]: 18,
10615
+ [ServerCommand.deltapacketentities]: 19,
10616
+ // Temp entity? Standard Q2 uses 9 for temp_entity?
10617
+ // But we mapped 9 to sound.
10618
+ // If we map temp_entity to 23 (arbitrary safe slot for internal tests) or assume standard Q2 layout:
10619
+ // Q2: svc_temp_entity = 9. svc_sound = 10.
10620
+ // My previous edit to parser.ts used 9->Sound, 10->Print.
10621
+ // I should check what I committed to `parser.ts` just now.
10622
+ // I committed: 9: Sound, 10: Print.
10623
+ // So Writer MUST MATCH Parser.
10624
+ // So if Parser says 9 is Sound, Writer must write Sound as 9.
10625
+ // But what about TempEntity?
10626
+ // Parser does NOT map any wire code to TempEntity in my recent edit (I commented out 23).
10627
+ // So TempEntity is currently broken for Protocol 34 unless I map it.
10628
+ // I will map TempEntity to 23 in both.
10629
+ [ServerCommand.temp_entity]: 23,
10630
+ // MuzzleFlash2?
10631
+ // I'll map it to 22 (arbitrary) just to have a value, or skip if unused.
10632
+ [ServerCommand.muzzleflash2]: 22
10633
+ };
10434
10634
  function applyEntityDelta(to, from) {
10435
10635
  const bits = from.bits;
10436
10636
  const bitsHigh = from.bitsHigh;
@@ -14937,7 +15137,7 @@ var ClientEffectSystem = class {
14937
15137
  this.playSound(null, entNum, soundName, volume, 1);
14938
15138
  }
14939
15139
  }
14940
- onTempEntity(type, pos, time, dir) {
15140
+ onTempEntity(type, pos, time, dir, pos2) {
14941
15141
  const particleSystem = this.engine.renderer?.particleSystem;
14942
15142
  switch (type) {
14943
15143
  case TempEntity2.GUNSHOT:
@@ -14993,10 +15193,9 @@ var ClientEffectSystem = class {
14993
15193
  this.addLight(void 0, pos, color, startRadius, 0, time + duration, speed);
14994
15194
  this.playSound(pos, 0, "weapons/bfg__x1b.wav", 1, 0.5);
14995
15195
  if (particleSystem) {
14996
- spawnExplosion({
15196
+ spawnBfgExplosion({
14997
15197
  system: particleSystem,
14998
15198
  origin: pos
14999
- // TODO: Make BFG explosion green/bigger
15000
15199
  });
15001
15200
  }
15002
15201
  }
@@ -15019,6 +15218,65 @@ var ClientEffectSystem = class {
15019
15218
  });
15020
15219
  }
15021
15220
  break;
15221
+ case TempEntity2.RAILTRAIL:
15222
+ if (particleSystem && pos2) {
15223
+ spawnRailTrail({
15224
+ system: particleSystem,
15225
+ start: pos,
15226
+ end: pos2
15227
+ });
15228
+ }
15229
+ break;
15230
+ case TempEntity2.BLASTER:
15231
+ if (particleSystem) {
15232
+ spawnBlasterImpact({
15233
+ system: particleSystem,
15234
+ origin: pos,
15235
+ color: [1, 1, 0, 1]
15236
+ // Yellow
15237
+ });
15238
+ }
15239
+ this.playSound(pos, 0, "weapons/lasthit.wav");
15240
+ break;
15241
+ case TempEntity2.BLUEHYPERBLASTER:
15242
+ if (particleSystem) {
15243
+ spawnBlasterImpact({
15244
+ system: particleSystem,
15245
+ origin: pos,
15246
+ color: [0, 0, 1, 1]
15247
+ // Blue
15248
+ });
15249
+ }
15250
+ this.playSound(pos, 0, "weapons/lasthit.wav");
15251
+ break;
15252
+ case TempEntity2.SPARKS:
15253
+ case TempEntity2.BULLET_SPARKS:
15254
+ case TempEntity2.WELDING_SPARKS:
15255
+ if (particleSystem) {
15256
+ spawnSparks({
15257
+ system: particleSystem,
15258
+ origin: pos,
15259
+ normal: dir || { x: 0, y: 0, z: 1 },
15260
+ count: 8,
15261
+ color: [1, 0.8, 0.2, 1]
15262
+ });
15263
+ }
15264
+ this.playSound(pos, 0, "world/spark1.wav");
15265
+ break;
15266
+ case TempEntity2.SHIELD_SPARKS:
15267
+ case TempEntity2.SCREEN_SPARKS:
15268
+ if (particleSystem) {
15269
+ spawnSparks({
15270
+ system: particleSystem,
15271
+ origin: pos,
15272
+ normal: dir || { x: 0, y: 0, z: 1 },
15273
+ count: 12,
15274
+ color: [0.5, 1, 0.5, 1]
15275
+ // Greenish for shield? Or classic spark color.
15276
+ });
15277
+ }
15278
+ this.playSound(pos, 0, "world/spark2.wav");
15279
+ break;
15022
15280
  }
15023
15281
  }
15024
15282
  };
@@ -16492,7 +16750,7 @@ function createClient(imports) {
16492
16750
  onTempEntity: (type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt) => {
16493
16751
  const time = demoPlayback.getCurrentTime() / 1e3;
16494
16752
  if (pos) {
16495
- effectSystem.onTempEntity(type, pos, time, dir);
16753
+ effectSystem.onTempEntity(type, pos, time, dir, pos2);
16496
16754
  }
16497
16755
  },
16498
16756
  onDamage: (indicators) => {