quake2ts 0.0.219 → 0.0.220

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.
@@ -27,6 +27,7 @@ __export(index_exports, {
27
27
  AmmoItemId: () => AmmoItemId,
28
28
  AmmoType: () => AmmoType,
29
29
  ArmorType: () => ArmorType,
30
+ AttackState: () => AttackState,
30
31
  CheckGround: () => CheckGround,
31
32
  DamageFlags: () => DamageFlags,
32
33
  DamageMod: () => DamageMod,
@@ -2111,9 +2112,18 @@ var AIFlags = /* @__PURE__ */ ((AIFlags2) => {
2111
2112
  AIFlags2[AIFlags2["CombatPoint"] = 4096] = "CombatPoint";
2112
2113
  AIFlags2[AIFlags2["Medic"] = 8192] = "Medic";
2113
2114
  AIFlags2[AIFlags2["Resurrecting"] = 16384] = "Resurrecting";
2115
+ AIFlags2[AIFlags2["ManualSteering"] = 32768] = "ManualSteering";
2114
2116
  AIFlags2[AIFlags2["Pathing"] = 1073741824] = "Pathing";
2115
2117
  return AIFlags2;
2116
2118
  })(AIFlags || {});
2119
+ var AttackState = /* @__PURE__ */ ((AttackState2) => {
2120
+ AttackState2[AttackState2["Straight"] = 0] = "Straight";
2121
+ AttackState2[AttackState2["Sliding"] = 1] = "Sliding";
2122
+ AttackState2[AttackState2["Melee"] = 2] = "Melee";
2123
+ AttackState2[AttackState2["Missile"] = 3] = "Missile";
2124
+ AttackState2[AttackState2["Blind"] = 4] = "Blind";
2125
+ return AttackState2;
2126
+ })(AttackState || {});
2117
2127
  var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
2118
2128
  TraceMask2[TraceMask2["Opaque"] = 1] = "Opaque";
2119
2129
  TraceMask2[TraceMask2["Window"] = 2] = "Window";
@@ -2407,7 +2417,9 @@ function ai_turn(self, distance2, deltaSeconds) {
2407
2417
  if (distance2 !== 0) {
2408
2418
  walkMove(self, self.angles.y, distance2);
2409
2419
  }
2410
- changeYaw(self, deltaSeconds);
2420
+ if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
2421
+ changeYaw(self, deltaSeconds);
2422
+ }
2411
2423
  }
2412
2424
  function ai_run(self, distance2, deltaSeconds, context) {
2413
2425
  if ((self.monsterinfo.aiflags & 1 /* StandGround */) !== 0) {
@@ -2416,7 +2428,9 @@ function ai_run(self, distance2, deltaSeconds, context) {
2416
2428
  }
2417
2429
  if (findTarget(self, context.targetAwareness, context, context.trace)) {
2418
2430
  }
2419
- setIdealYawTowards2(self, self.enemy ?? self.goalentity);
2431
+ if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
2432
+ setIdealYawTowards2(self, self.enemy ?? self.goalentity);
2433
+ }
2420
2434
  changeYaw(self, deltaSeconds);
2421
2435
  if (self.monsterinfo.checkattack && self.monsterinfo.checkattack(self, context)) {
2422
2436
  return;
@@ -2426,7 +2440,7 @@ function ai_run(self, distance2, deltaSeconds, context) {
2426
2440
  }
2427
2441
  }
2428
2442
  function ai_face(self, enemy, distance2, deltaSeconds) {
2429
- if (enemy) {
2443
+ if (enemy && (self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
2430
2444
  setIdealYawTowards2(self, enemy);
2431
2445
  }
2432
2446
  changeYaw(self, deltaSeconds);
@@ -2435,7 +2449,9 @@ function ai_face(self, enemy, distance2, deltaSeconds) {
2435
2449
  }
2436
2450
  }
2437
2451
  function ai_charge(self, distance2, deltaSeconds, context) {
2438
- setIdealYawTowards2(self, self.enemy);
2452
+ if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
2453
+ setIdealYawTowards2(self, self.enemy);
2454
+ }
2439
2455
  changeYaw(self, deltaSeconds);
2440
2456
  if (self.monsterinfo.checkattack && self.monsterinfo.checkattack(self, context)) {
2441
2457
  return;
@@ -11247,6 +11263,31 @@ function registerSupertankSpawns(registry) {
11247
11263
 
11248
11264
  // src/entities/monsters/tank.ts
11249
11265
  var MONSTER_TICK20 = 0.1;
11266
+ function M_AdjustBlindfireTarget(self, start, target, right, context) {
11267
+ const tr = context.trace(start, target, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
11268
+ if (!tr.startsolid && !tr.allsolid && tr.fraction >= 0.5) {
11269
+ return normalizeVec3(subtractVec3(target, start));
11270
+ }
11271
+ const leftTarget = addVec3(target, scaleVec3(right, -20));
11272
+ const trLeft = context.trace(start, leftTarget, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
11273
+ if (!trLeft.startsolid && !trLeft.allsolid && trLeft.fraction >= 0.5) {
11274
+ return normalizeVec3(subtractVec3(leftTarget, start));
11275
+ }
11276
+ const rightTarget = addVec3(target, scaleVec3(right, 20));
11277
+ const trRight = context.trace(start, rightTarget, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
11278
+ if (!trRight.startsolid && !trRight.allsolid && trRight.fraction >= 0.5) {
11279
+ return normalizeVec3(subtractVec3(rightTarget, start));
11280
+ }
11281
+ return null;
11282
+ }
11283
+ function tank_blind_check(self, context) {
11284
+ if (self.monsterinfo.aiflags & 32768 /* ManualSteering */) {
11285
+ if (self.monsterinfo.blind_fire_target) {
11286
+ const aim = subtractVec3(self.monsterinfo.blind_fire_target, self.origin);
11287
+ self.ideal_yaw = vectorToYaw(aim);
11288
+ }
11289
+ }
11290
+ }
11250
11291
  function monster_ai_stand20(self, dist, context) {
11251
11292
  ai_stand(self, MONSTER_TICK20, context);
11252
11293
  }
@@ -11293,8 +11334,60 @@ function classifyRange3(distance2) {
11293
11334
  if (distance2 <= 1e3) return "mid" /* Mid */;
11294
11335
  return "far" /* Far */;
11295
11336
  }
11337
+ function tank_checkattack(self, context) {
11338
+ if (!self.enemy) return false;
11339
+ const visibleEnemy = rangeTo(self, self.enemy) <= 1e3 && context.trace(self.origin, ZERO_VEC3, ZERO_VEC3, self.enemy.origin, self, MASK_SHOT).fraction === 1;
11340
+ if (visibleEnemy) {
11341
+ self.monsterinfo.blind_fire_target = addVec3(self.enemy.origin, scaleVec3(self.enemy.velocity, -0.1));
11342
+ self.monsterinfo.blind_fire_delay = 0;
11343
+ } else {
11344
+ if (self.monsterinfo.blindfire && (self.monsterinfo.blind_fire_delay || 0) <= 20) {
11345
+ if (self.attack_finished_time > context.timeSeconds) return false;
11346
+ if (context.timeSeconds < self.monsterinfo.trail_time + (self.monsterinfo.blind_fire_delay || 0)) {
11347
+ return false;
11348
+ }
11349
+ if (self.monsterinfo.blind_fire_target) {
11350
+ const tr = context.trace(self.origin, ZERO_VEC3, ZERO_VEC3, self.monsterinfo.blind_fire_target, self, 0);
11351
+ self.monsterinfo.attack_state = 4 /* Blind */;
11352
+ return true;
11353
+ }
11354
+ }
11355
+ return false;
11356
+ }
11357
+ const dist = rangeTo(self, self.enemy);
11358
+ if (self.attack_finished_time > context.timeSeconds) return false;
11359
+ let chance = 0;
11360
+ if (dist <= 150) chance = 0.4;
11361
+ else if (dist <= 500) chance = 0.25;
11362
+ else if (dist <= 1e3) chance = 0.06;
11363
+ else chance = 0;
11364
+ if (Math.random() < chance) {
11365
+ self.monsterinfo.attack_state = 3 /* Missile */;
11366
+ self.attack_finished_time = context.timeSeconds;
11367
+ return true;
11368
+ }
11369
+ return false;
11370
+ }
11296
11371
  function tank_attack(self) {
11297
11372
  if (!self.enemy) return;
11373
+ if (self.monsterinfo.attack_state === 4 /* Blind */) {
11374
+ let chance = 1;
11375
+ if ((self.monsterinfo.blind_fire_delay || 0) < 1) chance = 1;
11376
+ else if ((self.monsterinfo.blind_fire_delay || 0) < 7.5) chance = 0.4;
11377
+ else chance = 0.1;
11378
+ if (Math.random() > chance) return;
11379
+ self.monsterinfo.blind_fire_delay = (self.monsterinfo.blind_fire_delay || 0) + 5.2 + Math.random() * 3;
11380
+ if (!self.monsterinfo.blind_fire_target) return;
11381
+ self.monsterinfo.aiflags |= 32768 /* ManualSteering */;
11382
+ if (Math.random() < 0.5) {
11383
+ self.monsterinfo.current_move = attack_rocket_move3;
11384
+ } else {
11385
+ self.monsterinfo.current_move = attack_blaster_move;
11386
+ self.monsterinfo.nextframe = 69;
11387
+ }
11388
+ self.pain_debounce_time = self.timestamp + 5;
11389
+ return;
11390
+ }
11298
11391
  const dist = rangeTo(self, self.enemy);
11299
11392
  const range = classifyRange3(dist);
11300
11393
  if (range === "melee" /* Melee */ || range === "near" /* Near */) {
@@ -11320,7 +11413,18 @@ function tank_fire_blaster(self, context) {
11320
11413
  y: self.origin.y,
11321
11414
  z: self.origin.z + (self.viewheight || 0)
11322
11415
  };
11323
- const dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
11416
+ let dir;
11417
+ const blindfire = (self.monsterinfo.aiflags & 32768 /* ManualSteering */) !== 0;
11418
+ if (blindfire && self.monsterinfo.blind_fire_target) {
11419
+ const angles = self.angles;
11420
+ const { right } = angleVectors(angles);
11421
+ const target = self.monsterinfo.blind_fire_target;
11422
+ const adj = M_AdjustBlindfireTarget(self, start, target, right, context);
11423
+ if (!adj) return;
11424
+ dir = adj;
11425
+ } else {
11426
+ dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
11427
+ }
11324
11428
  const damage = 30;
11325
11429
  const speed = 1e3;
11326
11430
  monster_fire_blaster(self, start, dir, damage, speed, 0, 0, context, 1 /* BLASTER */);
@@ -11345,7 +11449,18 @@ function tank_fire_rocket(self, context) {
11345
11449
  z: self.origin.z + (self.viewheight || 0)
11346
11450
  // Firing from shoulder
11347
11451
  };
11348
- const dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
11452
+ let dir;
11453
+ const blindfire = (self.monsterinfo.aiflags & 32768 /* ManualSteering */) !== 0;
11454
+ if (blindfire && self.monsterinfo.blind_fire_target) {
11455
+ const angles = self.angles;
11456
+ const { right } = angleVectors(angles);
11457
+ const target = self.monsterinfo.blind_fire_target;
11458
+ const adj = M_AdjustBlindfireTarget(self, start, target, right, context);
11459
+ if (!adj) return;
11460
+ dir = adj;
11461
+ } else {
11462
+ dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
11463
+ }
11349
11464
  const damage = 50;
11350
11465
  const speed = 650;
11351
11466
  monster_fire_rocket(self, start, dir, damage, speed, 0, context);
@@ -11357,6 +11472,12 @@ function tank_dead(self) {
11357
11472
  self.monsterinfo.nextframe = death_move17.lastframe;
11358
11473
  self.nextthink = -1;
11359
11474
  }
11475
+ function tank_refire_rocket(self, context) {
11476
+ if (self.monsterinfo.aiflags & 32768 /* ManualSteering */) {
11477
+ self.monsterinfo.aiflags &= ~32768 /* ManualSteering */;
11478
+ }
11479
+ tank_run(self);
11480
+ }
11360
11481
  var stand_frames19 = Array.from({ length: 30 }, () => ({
11361
11482
  ai: monster_ai_stand20,
11362
11483
  dist: 0
@@ -11387,12 +11508,16 @@ run_move18 = {
11387
11508
  frames: run_frames17,
11388
11509
  endfunc: tank_run
11389
11510
  };
11390
- var attack_blaster_frames = Array.from({ length: 16 }, (_, i) => ({
11391
- ai: monster_ai_charge20,
11392
- dist: 0,
11393
- think: i > 5 && i < 12 ? tank_fire_blaster : null
11394
- // Rapid fire blaster
11395
- }));
11511
+ var attack_blaster_frames = Array.from({ length: 16 }, (_, i) => {
11512
+ let think = null;
11513
+ if (i === 7) think = tank_blind_check;
11514
+ else if (i > 5 && i < 12) think = tank_fire_blaster;
11515
+ return {
11516
+ ai: monster_ai_charge20,
11517
+ dist: 0,
11518
+ think
11519
+ };
11520
+ });
11396
11521
  attack_blaster_move = {
11397
11522
  firstframe: 62,
11398
11523
  lastframe: 77,
@@ -11410,17 +11535,21 @@ attack_machinegun_move = {
11410
11535
  frames: attack_machinegun_frames,
11411
11536
  endfunc: tank_run
11412
11537
  };
11413
- var attack_rocket_frames3 = Array.from({ length: 18 }, (_, i) => ({
11414
- ai: monster_ai_charge20,
11415
- dist: 0,
11416
- think: i === 8 ? tank_fire_rocket : i === 12 ? tank_fire_rocket : i === 16 ? tank_fire_rocket : null
11417
- // Burst of 3
11418
- }));
11538
+ var attack_rocket_frames3 = Array.from({ length: 18 }, (_, i) => {
11539
+ let think = null;
11540
+ if (i === 0) think = tank_blind_check;
11541
+ else if (i === 8 || i === 12 || i === 16) think = tank_fire_rocket;
11542
+ return {
11543
+ ai: monster_ai_charge20,
11544
+ dist: 0,
11545
+ think
11546
+ };
11547
+ });
11419
11548
  attack_rocket_move3 = {
11420
11549
  firstframe: 98,
11421
11550
  lastframe: 115,
11422
11551
  frames: attack_rocket_frames3,
11423
- endfunc: tank_run
11552
+ endfunc: tank_refire_rocket
11424
11553
  };
11425
11554
  var pain_frames11 = Array.from({ length: 6 }, () => ({
11426
11555
  ai: monster_ai_move20,
@@ -11480,6 +11609,8 @@ function SP_monster_tank(self, context) {
11480
11609
  self.monsterinfo.run = tank_run;
11481
11610
  self.monsterinfo.attack = tank_attack;
11482
11611
  self.monsterinfo.attack_machinegun = attack_machinegun_move;
11612
+ self.monsterinfo.checkattack = tank_checkattack;
11613
+ self.monsterinfo.blindfire = true;
11483
11614
  self.think = monster_think;
11484
11615
  tank_stand(self);
11485
11616
  self.nextthink = self.timestamp + MONSTER_TICK20;
@@ -13510,7 +13641,7 @@ var WEAPONS = {
13510
13641
  };
13511
13642
 
13512
13643
  // src/index.ts
13513
- var ZERO_VEC38 = { x: 0, y: 0, z: 0 };
13644
+ var ZERO_VEC37 = { x: 0, y: 0, z: 0 };
13514
13645
  function createGame(imports, engine, options) {
13515
13646
  const gravity = options.gravity;
13516
13647
  const deathmatch = options.deathmatch ?? false;
@@ -13577,8 +13708,8 @@ function createGame(imports, engine, options) {
13577
13708
  };
13578
13709
  entities.runFrame();
13579
13710
  });
13580
- let origin = { ...ZERO_VEC38 };
13581
- let velocity = { ...ZERO_VEC38 };
13711
+ let origin = { ...ZERO_VEC37 };
13712
+ let velocity = { ...ZERO_VEC37 };
13582
13713
  const calculateBlend = (player, time) => {
13583
13714
  const blend = [0, 0, 0, 0];
13584
13715
  if (!player || !player.client) return blend;
@@ -13661,9 +13792,9 @@ function createGame(imports, engine, options) {
13661
13792
  damageIndicators: [],
13662
13793
  // Stubs for new PlayerState fields
13663
13794
  stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
13664
- kick_angles: ZERO_VEC38,
13665
- gunoffset: ZERO_VEC38,
13666
- gunangles: ZERO_VEC38,
13795
+ kick_angles: ZERO_VEC37,
13796
+ gunoffset: ZERO_VEC37,
13797
+ gunangles: ZERO_VEC37,
13667
13798
  gunindex: 0
13668
13799
  }
13669
13800
  };
@@ -13671,8 +13802,8 @@ function createGame(imports, engine, options) {
13671
13802
  const resetState = (startTimeMs) => {
13672
13803
  frameLoop.reset(startTimeMs);
13673
13804
  levelClock.start(startTimeMs);
13674
- origin = { ...ZERO_VEC38 };
13675
- velocity = { ...ZERO_VEC38 };
13805
+ origin = { ...ZERO_VEC37 };
13806
+ velocity = { ...ZERO_VEC37 };
13676
13807
  entities.beginFrame(startTimeMs / 1e3);
13677
13808
  entities.runFrame();
13678
13809
  };
@@ -13700,9 +13831,9 @@ function createGame(imports, engine, options) {
13700
13831
  blend: [0, 0, 0, 0],
13701
13832
  // Stubs
13702
13833
  stats: populatePlayerStats(player, levelClock.current.timeSeconds),
13703
- kick_angles: ZERO_VEC38,
13704
- gunoffset: ZERO_VEC38,
13705
- gunangles: ZERO_VEC38,
13834
+ kick_angles: ZERO_VEC37,
13835
+ gunoffset: ZERO_VEC37,
13836
+ gunangles: ZERO_VEC37,
13706
13837
  gunindex: 0
13707
13838
  };
13708
13839
  const traceAdapter = (start, end) => {
@@ -13821,8 +13952,8 @@ function createGame(imports, engine, options) {
13821
13952
  rng,
13822
13953
  player: player?.client?.inventory
13823
13954
  });
13824
- origin = player ? { ...player.origin } : { ...ZERO_VEC38 };
13825
- velocity = player ? { ...player.velocity } : { ...ZERO_VEC38 };
13955
+ origin = player ? { ...player.origin } : { ...ZERO_VEC37 };
13956
+ velocity = player ? { ...player.velocity } : { ...ZERO_VEC37 };
13826
13957
  frameLoop.reset(save.level.timeSeconds * 1e3);
13827
13958
  }
13828
13959
  };
@@ -13839,6 +13970,7 @@ function createGame(imports, engine, options) {
13839
13970
  AmmoItemId,
13840
13971
  AmmoType,
13841
13972
  ArmorType,
13973
+ AttackState,
13842
13974
  CheckGround,
13843
13975
  DamageFlags,
13844
13976
  DamageMod,