t2-demo-parser 1.0.2 → 2.0.0

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 (39) hide show
  1. package/README.md +201 -87
  2. package/dist/DataBlockParsers.d.ts.map +1 -1
  3. package/dist/DataBlockParsers.js +51 -42
  4. package/dist/DataBlockParsers.js.map +1 -1
  5. package/dist/DataBlockParsers.test.js +32 -0
  6. package/dist/DataBlockParsers.test.js.map +1 -1
  7. package/dist/DemoParser.d.ts.map +1 -1
  8. package/dist/DemoParser.js +43 -8
  9. package/dist/DemoParser.js.map +1 -1
  10. package/dist/GhostManager.d.ts.map +1 -1
  11. package/dist/GhostManager.js +36 -68
  12. package/dist/GhostManager.js.map +1 -1
  13. package/dist/GhostStateAccumulator.d.ts +36 -0
  14. package/dist/GhostStateAccumulator.d.ts.map +1 -0
  15. package/dist/GhostStateAccumulator.js +124 -0
  16. package/dist/GhostStateAccumulator.js.map +1 -0
  17. package/dist/GhostStateAccumulator.test.d.ts +2 -0
  18. package/dist/GhostStateAccumulator.test.d.ts.map +1 -0
  19. package/dist/GhostStateAccumulator.test.js +201 -0
  20. package/dist/GhostStateAccumulator.test.js.map +1 -0
  21. package/dist/LiveParser.d.ts +39 -1
  22. package/dist/LiveParser.d.ts.map +1 -1
  23. package/dist/LiveParser.js +43 -1
  24. package/dist/LiveParser.js.map +1 -1
  25. package/dist/PacketParser.d.ts +23 -2
  26. package/dist/PacketParser.d.ts.map +1 -1
  27. package/dist/PacketParser.js +62 -19
  28. package/dist/PacketParser.js.map +1 -1
  29. package/dist/dataBlockDataTypes.d.ts +22 -21
  30. package/dist/dataBlockDataTypes.d.ts.map +1 -1
  31. package/dist/dataBlockDataTypes.js.map +1 -1
  32. package/dist/index.d.ts +4 -3
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +3 -2
  35. package/dist/index.js.map +1 -1
  36. package/dist/types.d.ts +11 -0
  37. package/dist/types.d.ts.map +1 -1
  38. package/dist/types.js.map +1 -1
  39. package/package.json +1 -1
@@ -433,17 +433,8 @@ function wheeledVehicleReadPacketData(bs, conn) {
433
433
  const result = vehicleReadPacketData(bs, conn);
434
434
  result.braking = bs.readFlag();
435
435
  // wheelCount × 3 F32 (avel, Dy, Dx per wheel)
436
- // Use ghost wheel count cache (populated during ghost creates)
437
- let wheelCount = 4;
438
- const ghostIdx = conn.currentGhostIndex;
439
- if (ghostIdx !== undefined) {
440
- const cached = ghostWheelCountCache.get(ghostIdx);
441
- if (cached !== undefined) {
442
- wheelCount = cached;
443
- }
444
- }
445
436
  const wheels = [];
446
- for (let i = 0; i < wheelCount; i++) {
437
+ for (let i = 0; i < WheeledVehicleWheelCount; i++) {
447
438
  wheels.push({
448
439
  avel: bs.readF32(),
449
440
  dy: bs.readF32(),
@@ -649,7 +640,11 @@ function bombProjectileUnpackUpdate(bs, _isInitial, _conn) {
649
640
  }
650
641
  if (bs.readFlag()) {
651
642
  result.explodePoint = { x: bs.readF32(), y: bs.readF32(), z: bs.readF32() };
652
- result.explodeNormal = { x: bs.readF32(), y: bs.readF32(), z: bs.readF32() };
643
+ result.explodeNormal = {
644
+ x: bs.readF32(),
645
+ y: bs.readF32(),
646
+ z: bs.readF32(),
647
+ };
653
648
  }
654
649
  if (bs.readFlag()) {
655
650
  result.sourceObject = bs.readInt(11); // nextPow2(0x401) -> 11 bits
@@ -713,8 +708,16 @@ function seekerUnpackUpdate(bs, isInitial, conn) {
713
708
  const isExplosion = bs.readFlag();
714
709
  if (isExplosion) {
715
710
  // FUN_00639370: explode(position, normal) — SeekerProjectile detonation.
716
- result.explodePosition = { x: bs.readF32(), y: bs.readF32(), z: bs.readF32() };
717
- result.explodeNormal = { x: bs.readF32(), y: bs.readF32(), z: bs.readF32() };
711
+ result.explodePosition = {
712
+ x: bs.readF32(),
713
+ y: bs.readF32(),
714
+ z: bs.readF32(),
715
+ };
716
+ result.explodeNormal = {
717
+ x: bs.readF32(),
718
+ y: bs.readF32(),
719
+ z: bs.readF32(),
720
+ };
718
721
  return result;
719
722
  }
720
723
  result.position = { x: bs.readF32(), y: bs.readF32(), z: bs.readF32() };
@@ -1163,7 +1166,12 @@ function sunUnpackUpdate(bs, _isInitial, _conn) {
1163
1166
  }
1164
1167
  result.direction = { x: values[0], y: values[1], z: values[2] };
1165
1168
  result.color = { r: values[3], g: values[4], b: values[5], a: values[6] };
1166
- result.ambient = { r: values[7], g: values[8], b: values[9], a: values[10] };
1169
+ result.ambient = {
1170
+ r: values[7],
1171
+ g: values[8],
1172
+ b: values[9],
1173
+ a: values[10],
1174
+ };
1167
1175
  // Remaining 8 values are additional light properties in build 25034
1168
1176
  result.extraLightProps = values.slice(11);
1169
1177
  }
@@ -1189,7 +1197,11 @@ function skyUnpackUpdate(bs, _isInitial, _conn) {
1189
1197
  // bool fields are read via Stream::read(1) in the binary (byte-sized bool)
1190
1198
  result.useSkyTextures = bs.readBool();
1191
1199
  result.renderBottomTexture = bs.readBool();
1192
- result.skySolidColor = { r: bs.readF32(), g: bs.readF32(), b: bs.readF32() };
1200
+ result.skySolidColor = {
1201
+ r: bs.readF32(),
1202
+ g: bs.readF32(),
1203
+ b: bs.readF32(),
1204
+ };
1193
1205
  result.windEffectPrecipitation = bs.readBool();
1194
1206
  const fogVolumes = [];
1195
1207
  for (let i = 0; i < fogVolumeCount; i++) {
@@ -1505,26 +1517,15 @@ function shockLanceProjectileUnpackUpdate(bs, isInitial, conn) {
1505
1517
  // WheeledVehicle ghost parser
1506
1518
  // ============================================================
1507
1519
  /**
1508
- * Determine wheel count from a WheeledVehicleData shape name.
1509
- * In standard Tribes 2, the only WheeledVehicle is the MPB/Jericho (6 wheels).
1510
- * Wildcat and Beowulf are HoverVehicleData, NOT WheeledVehicleData.
1511
- * wheelCount is computed at runtime from shape ground#/spring# node pairs.
1512
- * Falls back to 6 (the only standard WheeledVehicle) if shape unknown.
1520
+ * In standard Tribes 2, the only WheeledVehicleData is the MPB/Jericho
1521
+ * (vehicle_land_mpbase.dts: Ground0-5 + Spring0-5), so the wheel section
1522
+ * is always 6 entries. Wildcat and Beowulf are HoverVehicleData, NOT
1523
+ * WheeledVehicleData. The engine computes the count at runtime from the
1524
+ * shape's ground#/spring# node pairs; deriving it here from state
1525
+ * accumulated in earlier packets (e.g. the create's dataBlockId) would
1526
+ * desync parsers seeded mid-stream, which never parse the create.
1513
1527
  */
1514
- function getWheelCountFromShape(shapeName) {
1515
- if (!shapeName)
1516
- return 6;
1517
- const lower = shapeName.toLowerCase();
1518
- // MPB (vehicle_land_mpbase.dts) has 6 wheels: Ground0-5 + Spring0-5
1519
- if (lower.includes("mpb") || lower.includes("mpbase"))
1520
- return 6;
1521
- // Default to 6 for unknown shapes (standard T2 only has the MPB)
1522
- return 6;
1523
- }
1524
- /** Cache of dataBlockId → wheelCount for WheeledVehicle ghosts. */
1525
- const wheelCountCache = new Map();
1526
- /** Cache of ghostIndex → wheelCount for WheeledVehicle updates (where dbId is absent). */
1527
- const ghostWheelCountCache = new Map();
1528
+ const WheeledVehicleWheelCount = 6;
1528
1529
  function wheeledVehicleUnpackUpdate(bs, isInitial, conn) {
1529
1530
  const result = vehicleUnpackUpdate(bs, isInitial, conn);
1530
1531
  // Always read braking/wheels. Binary (FUN_00615a70) checks
@@ -1534,41 +1535,8 @@ function wheeledVehicleUnpackUpdate(bs, isInitial, conn) {
1534
1535
  {
1535
1536
  result.braking = bs.readFlag();
1536
1537
  if (bs.readFlag()) {
1537
- // Determine wheel count from the DataBlock's shape name.
1538
- // On creates, dataBlockId is available (DataBlockMask set).
1539
- // On updates, use ghost-index cache populated during create.
1540
- let wheelCount = 4;
1541
- const dbId = result.dataBlockId;
1542
- const ghostIdx = conn.currentGhostIndex;
1543
- if (dbId !== undefined) {
1544
- const cached = wheelCountCache.get(dbId);
1545
- if (cached !== undefined) {
1546
- wheelCount = cached;
1547
- }
1548
- else if (conn.getDataBlockData) {
1549
- const dbData = conn.getDataBlockData(dbId);
1550
- if (dbData) {
1551
- const shapeName = dbData.shapeName;
1552
- if (typeof shapeName === "string") {
1553
- wheelCount = getWheelCountFromShape(shapeName);
1554
- }
1555
- wheelCountCache.set(dbId, wheelCount);
1556
- }
1557
- }
1558
- // Cache by ghost index for future updates
1559
- if (ghostIdx !== undefined) {
1560
- ghostWheelCountCache.set(ghostIdx, wheelCount);
1561
- }
1562
- }
1563
- else if (ghostIdx !== undefined) {
1564
- // UPDATE: look up by ghost index
1565
- const cached = ghostWheelCountCache.get(ghostIdx);
1566
- if (cached !== undefined) {
1567
- wheelCount = cached;
1568
- }
1569
- }
1570
1538
  const wheels = [];
1571
- for (let i = 0; i < wheelCount; i++) {
1539
+ for (let i = 0; i < WheeledVehicleWheelCount; i++) {
1572
1540
  wheels.push({
1573
1541
  avel: bs.readF32(),
1574
1542
  dy: bs.readF32(),