quake2ts 0.0.219 → 0.0.221

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.
@@ -1945,9 +1945,18 @@ var AIFlags = /* @__PURE__ */ ((AIFlags2) => {
1945
1945
  AIFlags2[AIFlags2["CombatPoint"] = 4096] = "CombatPoint";
1946
1946
  AIFlags2[AIFlags2["Medic"] = 8192] = "Medic";
1947
1947
  AIFlags2[AIFlags2["Resurrecting"] = 16384] = "Resurrecting";
1948
+ AIFlags2[AIFlags2["ManualSteering"] = 32768] = "ManualSteering";
1948
1949
  AIFlags2[AIFlags2["Pathing"] = 1073741824] = "Pathing";
1949
1950
  return AIFlags2;
1950
1951
  })(AIFlags || {});
1952
+ var AttackState = /* @__PURE__ */ ((AttackState2) => {
1953
+ AttackState2[AttackState2["Straight"] = 0] = "Straight";
1954
+ AttackState2[AttackState2["Sliding"] = 1] = "Sliding";
1955
+ AttackState2[AttackState2["Melee"] = 2] = "Melee";
1956
+ AttackState2[AttackState2["Missile"] = 3] = "Missile";
1957
+ AttackState2[AttackState2["Blind"] = 4] = "Blind";
1958
+ return AttackState2;
1959
+ })(AttackState || {});
1951
1960
  var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
1952
1961
  TraceMask2[TraceMask2["Opaque"] = 1] = "Opaque";
1953
1962
  TraceMask2[TraceMask2["Window"] = 2] = "Window";
@@ -2241,7 +2250,9 @@ function ai_turn(self, distance2, deltaSeconds) {
2241
2250
  if (distance2 !== 0) {
2242
2251
  walkMove(self, self.angles.y, distance2);
2243
2252
  }
2244
- changeYaw(self, deltaSeconds);
2253
+ if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
2254
+ changeYaw(self, deltaSeconds);
2255
+ }
2245
2256
  }
2246
2257
  function ai_run(self, distance2, deltaSeconds, context) {
2247
2258
  if ((self.monsterinfo.aiflags & 1 /* StandGround */) !== 0) {
@@ -2250,7 +2261,9 @@ function ai_run(self, distance2, deltaSeconds, context) {
2250
2261
  }
2251
2262
  if (findTarget(self, context.targetAwareness, context, context.trace)) {
2252
2263
  }
2253
- setIdealYawTowards2(self, self.enemy ?? self.goalentity);
2264
+ if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
2265
+ setIdealYawTowards2(self, self.enemy ?? self.goalentity);
2266
+ }
2254
2267
  changeYaw(self, deltaSeconds);
2255
2268
  if (self.monsterinfo.checkattack && self.monsterinfo.checkattack(self, context)) {
2256
2269
  return;
@@ -2260,7 +2273,7 @@ function ai_run(self, distance2, deltaSeconds, context) {
2260
2273
  }
2261
2274
  }
2262
2275
  function ai_face(self, enemy, distance2, deltaSeconds) {
2263
- if (enemy) {
2276
+ if (enemy && (self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
2264
2277
  setIdealYawTowards2(self, enemy);
2265
2278
  }
2266
2279
  changeYaw(self, deltaSeconds);
@@ -2269,7 +2282,9 @@ function ai_face(self, enemy, distance2, deltaSeconds) {
2269
2282
  }
2270
2283
  }
2271
2284
  function ai_charge(self, distance2, deltaSeconds, context) {
2272
- setIdealYawTowards2(self, self.enemy);
2285
+ if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
2286
+ setIdealYawTowards2(self, self.enemy);
2287
+ }
2273
2288
  changeYaw(self, deltaSeconds);
2274
2289
  if (self.monsterinfo.checkattack && self.monsterinfo.checkattack(self, context)) {
2275
2290
  return;
@@ -11081,6 +11096,31 @@ function registerSupertankSpawns(registry) {
11081
11096
 
11082
11097
  // src/entities/monsters/tank.ts
11083
11098
  var MONSTER_TICK20 = 0.1;
11099
+ function M_AdjustBlindfireTarget(self, start, target, right, context) {
11100
+ const tr = context.trace(start, target, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
11101
+ if (!tr.startsolid && !tr.allsolid && tr.fraction >= 0.5) {
11102
+ return normalizeVec3(subtractVec3(target, start));
11103
+ }
11104
+ const leftTarget = addVec3(target, scaleVec3(right, -20));
11105
+ const trLeft = context.trace(start, leftTarget, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
11106
+ if (!trLeft.startsolid && !trLeft.allsolid && trLeft.fraction >= 0.5) {
11107
+ return normalizeVec3(subtractVec3(leftTarget, start));
11108
+ }
11109
+ const rightTarget = addVec3(target, scaleVec3(right, 20));
11110
+ const trRight = context.trace(start, rightTarget, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
11111
+ if (!trRight.startsolid && !trRight.allsolid && trRight.fraction >= 0.5) {
11112
+ return normalizeVec3(subtractVec3(rightTarget, start));
11113
+ }
11114
+ return null;
11115
+ }
11116
+ function tank_blind_check(self, context) {
11117
+ if (self.monsterinfo.aiflags & 32768 /* ManualSteering */) {
11118
+ if (self.monsterinfo.blind_fire_target) {
11119
+ const aim = subtractVec3(self.monsterinfo.blind_fire_target, self.origin);
11120
+ self.ideal_yaw = vectorToYaw(aim);
11121
+ }
11122
+ }
11123
+ }
11084
11124
  function monster_ai_stand20(self, dist, context) {
11085
11125
  ai_stand(self, MONSTER_TICK20, context);
11086
11126
  }
@@ -11127,8 +11167,60 @@ function classifyRange3(distance2) {
11127
11167
  if (distance2 <= 1e3) return "mid" /* Mid */;
11128
11168
  return "far" /* Far */;
11129
11169
  }
11170
+ function tank_checkattack(self, context) {
11171
+ if (!self.enemy) return false;
11172
+ const visibleEnemy = rangeTo(self, self.enemy) <= 1e3 && context.trace(self.origin, ZERO_VEC3, ZERO_VEC3, self.enemy.origin, self, MASK_SHOT).fraction === 1;
11173
+ if (visibleEnemy) {
11174
+ self.monsterinfo.blind_fire_target = addVec3(self.enemy.origin, scaleVec3(self.enemy.velocity, -0.1));
11175
+ self.monsterinfo.blind_fire_delay = 0;
11176
+ } else {
11177
+ if (self.monsterinfo.blindfire && (self.monsterinfo.blind_fire_delay || 0) <= 20) {
11178
+ if (self.attack_finished_time > context.timeSeconds) return false;
11179
+ if (context.timeSeconds < self.monsterinfo.trail_time + (self.monsterinfo.blind_fire_delay || 0)) {
11180
+ return false;
11181
+ }
11182
+ if (self.monsterinfo.blind_fire_target) {
11183
+ const tr = context.trace(self.origin, ZERO_VEC3, ZERO_VEC3, self.monsterinfo.blind_fire_target, self, 0);
11184
+ self.monsterinfo.attack_state = 4 /* Blind */;
11185
+ return true;
11186
+ }
11187
+ }
11188
+ return false;
11189
+ }
11190
+ const dist = rangeTo(self, self.enemy);
11191
+ if (self.attack_finished_time > context.timeSeconds) return false;
11192
+ let chance = 0;
11193
+ if (dist <= 150) chance = 0.4;
11194
+ else if (dist <= 500) chance = 0.25;
11195
+ else if (dist <= 1e3) chance = 0.06;
11196
+ else chance = 0;
11197
+ if (Math.random() < chance) {
11198
+ self.monsterinfo.attack_state = 3 /* Missile */;
11199
+ self.attack_finished_time = context.timeSeconds;
11200
+ return true;
11201
+ }
11202
+ return false;
11203
+ }
11130
11204
  function tank_attack(self) {
11131
11205
  if (!self.enemy) return;
11206
+ if (self.monsterinfo.attack_state === 4 /* Blind */) {
11207
+ let chance = 1;
11208
+ if ((self.monsterinfo.blind_fire_delay || 0) < 1) chance = 1;
11209
+ else if ((self.monsterinfo.blind_fire_delay || 0) < 7.5) chance = 0.4;
11210
+ else chance = 0.1;
11211
+ if (Math.random() > chance) return;
11212
+ self.monsterinfo.blind_fire_delay = (self.monsterinfo.blind_fire_delay || 0) + 5.2 + Math.random() * 3;
11213
+ if (!self.monsterinfo.blind_fire_target) return;
11214
+ self.monsterinfo.aiflags |= 32768 /* ManualSteering */;
11215
+ if (Math.random() < 0.5) {
11216
+ self.monsterinfo.current_move = attack_rocket_move3;
11217
+ } else {
11218
+ self.monsterinfo.current_move = attack_blaster_move;
11219
+ self.monsterinfo.nextframe = 69;
11220
+ }
11221
+ self.pain_debounce_time = self.timestamp + 5;
11222
+ return;
11223
+ }
11132
11224
  const dist = rangeTo(self, self.enemy);
11133
11225
  const range = classifyRange3(dist);
11134
11226
  if (range === "melee" /* Melee */ || range === "near" /* Near */) {
@@ -11154,7 +11246,18 @@ function tank_fire_blaster(self, context) {
11154
11246
  y: self.origin.y,
11155
11247
  z: self.origin.z + (self.viewheight || 0)
11156
11248
  };
11157
- const dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
11249
+ let dir;
11250
+ const blindfire = (self.monsterinfo.aiflags & 32768 /* ManualSteering */) !== 0;
11251
+ if (blindfire && self.monsterinfo.blind_fire_target) {
11252
+ const angles = self.angles;
11253
+ const { right } = angleVectors(angles);
11254
+ const target = self.monsterinfo.blind_fire_target;
11255
+ const adj = M_AdjustBlindfireTarget(self, start, target, right, context);
11256
+ if (!adj) return;
11257
+ dir = adj;
11258
+ } else {
11259
+ dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
11260
+ }
11158
11261
  const damage = 30;
11159
11262
  const speed = 1e3;
11160
11263
  monster_fire_blaster(self, start, dir, damage, speed, 0, 0, context, 1 /* BLASTER */);
@@ -11179,7 +11282,18 @@ function tank_fire_rocket(self, context) {
11179
11282
  z: self.origin.z + (self.viewheight || 0)
11180
11283
  // Firing from shoulder
11181
11284
  };
11182
- const dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
11285
+ let dir;
11286
+ const blindfire = (self.monsterinfo.aiflags & 32768 /* ManualSteering */) !== 0;
11287
+ if (blindfire && self.monsterinfo.blind_fire_target) {
11288
+ const angles = self.angles;
11289
+ const { right } = angleVectors(angles);
11290
+ const target = self.monsterinfo.blind_fire_target;
11291
+ const adj = M_AdjustBlindfireTarget(self, start, target, right, context);
11292
+ if (!adj) return;
11293
+ dir = adj;
11294
+ } else {
11295
+ dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
11296
+ }
11183
11297
  const damage = 50;
11184
11298
  const speed = 650;
11185
11299
  monster_fire_rocket(self, start, dir, damage, speed, 0, context);
@@ -11191,6 +11305,12 @@ function tank_dead(self) {
11191
11305
  self.monsterinfo.nextframe = death_move17.lastframe;
11192
11306
  self.nextthink = -1;
11193
11307
  }
11308
+ function tank_refire_rocket(self, context) {
11309
+ if (self.monsterinfo.aiflags & 32768 /* ManualSteering */) {
11310
+ self.monsterinfo.aiflags &= ~32768 /* ManualSteering */;
11311
+ }
11312
+ tank_run(self);
11313
+ }
11194
11314
  var stand_frames19 = Array.from({ length: 30 }, () => ({
11195
11315
  ai: monster_ai_stand20,
11196
11316
  dist: 0
@@ -11221,12 +11341,16 @@ run_move18 = {
11221
11341
  frames: run_frames17,
11222
11342
  endfunc: tank_run
11223
11343
  };
11224
- var attack_blaster_frames = Array.from({ length: 16 }, (_, i) => ({
11225
- ai: monster_ai_charge20,
11226
- dist: 0,
11227
- think: i > 5 && i < 12 ? tank_fire_blaster : null
11228
- // Rapid fire blaster
11229
- }));
11344
+ var attack_blaster_frames = Array.from({ length: 16 }, (_, i) => {
11345
+ let think = null;
11346
+ if (i === 7) think = tank_blind_check;
11347
+ else if (i > 5 && i < 12) think = tank_fire_blaster;
11348
+ return {
11349
+ ai: monster_ai_charge20,
11350
+ dist: 0,
11351
+ think
11352
+ };
11353
+ });
11230
11354
  attack_blaster_move = {
11231
11355
  firstframe: 62,
11232
11356
  lastframe: 77,
@@ -11244,17 +11368,21 @@ attack_machinegun_move = {
11244
11368
  frames: attack_machinegun_frames,
11245
11369
  endfunc: tank_run
11246
11370
  };
11247
- var attack_rocket_frames3 = Array.from({ length: 18 }, (_, i) => ({
11248
- ai: monster_ai_charge20,
11249
- dist: 0,
11250
- think: i === 8 ? tank_fire_rocket : i === 12 ? tank_fire_rocket : i === 16 ? tank_fire_rocket : null
11251
- // Burst of 3
11252
- }));
11371
+ var attack_rocket_frames3 = Array.from({ length: 18 }, (_, i) => {
11372
+ let think = null;
11373
+ if (i === 0) think = tank_blind_check;
11374
+ else if (i === 8 || i === 12 || i === 16) think = tank_fire_rocket;
11375
+ return {
11376
+ ai: monster_ai_charge20,
11377
+ dist: 0,
11378
+ think
11379
+ };
11380
+ });
11253
11381
  attack_rocket_move3 = {
11254
11382
  firstframe: 98,
11255
11383
  lastframe: 115,
11256
11384
  frames: attack_rocket_frames3,
11257
- endfunc: tank_run
11385
+ endfunc: tank_refire_rocket
11258
11386
  };
11259
11387
  var pain_frames11 = Array.from({ length: 6 }, () => ({
11260
11388
  ai: monster_ai_move20,
@@ -11314,6 +11442,8 @@ function SP_monster_tank(self, context) {
11314
11442
  self.monsterinfo.run = tank_run;
11315
11443
  self.monsterinfo.attack = tank_attack;
11316
11444
  self.monsterinfo.attack_machinegun = attack_machinegun_move;
11445
+ self.monsterinfo.checkattack = tank_checkattack;
11446
+ self.monsterinfo.blindfire = true;
11317
11447
  self.think = monster_think;
11318
11448
  tank_stand(self);
11319
11449
  self.nextthink = self.timestamp + MONSTER_TICK20;
@@ -13344,7 +13474,7 @@ var WEAPONS = {
13344
13474
  };
13345
13475
 
13346
13476
  // src/index.ts
13347
- var ZERO_VEC38 = { x: 0, y: 0, z: 0 };
13477
+ var ZERO_VEC37 = { x: 0, y: 0, z: 0 };
13348
13478
  function createGame(imports, engine, options) {
13349
13479
  const gravity = options.gravity;
13350
13480
  const deathmatch = options.deathmatch ?? false;
@@ -13411,8 +13541,8 @@ function createGame(imports, engine, options) {
13411
13541
  };
13412
13542
  entities.runFrame();
13413
13543
  });
13414
- let origin = { ...ZERO_VEC38 };
13415
- let velocity = { ...ZERO_VEC38 };
13544
+ let origin = { ...ZERO_VEC37 };
13545
+ let velocity = { ...ZERO_VEC37 };
13416
13546
  const calculateBlend = (player, time) => {
13417
13547
  const blend = [0, 0, 0, 0];
13418
13548
  if (!player || !player.client) return blend;
@@ -13495,9 +13625,9 @@ function createGame(imports, engine, options) {
13495
13625
  damageIndicators: [],
13496
13626
  // Stubs for new PlayerState fields
13497
13627
  stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
13498
- kick_angles: ZERO_VEC38,
13499
- gunoffset: ZERO_VEC38,
13500
- gunangles: ZERO_VEC38,
13628
+ kick_angles: ZERO_VEC37,
13629
+ gunoffset: ZERO_VEC37,
13630
+ gunangles: ZERO_VEC37,
13501
13631
  gunindex: 0
13502
13632
  }
13503
13633
  };
@@ -13505,8 +13635,8 @@ function createGame(imports, engine, options) {
13505
13635
  const resetState = (startTimeMs) => {
13506
13636
  frameLoop.reset(startTimeMs);
13507
13637
  levelClock.start(startTimeMs);
13508
- origin = { ...ZERO_VEC38 };
13509
- velocity = { ...ZERO_VEC38 };
13638
+ origin = { ...ZERO_VEC37 };
13639
+ velocity = { ...ZERO_VEC37 };
13510
13640
  entities.beginFrame(startTimeMs / 1e3);
13511
13641
  entities.runFrame();
13512
13642
  };
@@ -13534,9 +13664,9 @@ function createGame(imports, engine, options) {
13534
13664
  blend: [0, 0, 0, 0],
13535
13665
  // Stubs
13536
13666
  stats: populatePlayerStats(player, levelClock.current.timeSeconds),
13537
- kick_angles: ZERO_VEC38,
13538
- gunoffset: ZERO_VEC38,
13539
- gunangles: ZERO_VEC38,
13667
+ kick_angles: ZERO_VEC37,
13668
+ gunoffset: ZERO_VEC37,
13669
+ gunangles: ZERO_VEC37,
13540
13670
  gunindex: 0
13541
13671
  };
13542
13672
  const traceAdapter = (start, end) => {
@@ -13655,8 +13785,8 @@ function createGame(imports, engine, options) {
13655
13785
  rng,
13656
13786
  player: player?.client?.inventory
13657
13787
  });
13658
- origin = player ? { ...player.origin } : { ...ZERO_VEC38 };
13659
- velocity = player ? { ...player.velocity } : { ...ZERO_VEC38 };
13788
+ origin = player ? { ...player.origin } : { ...ZERO_VEC37 };
13789
+ velocity = player ? { ...player.velocity } : { ...ZERO_VEC37 };
13660
13790
  frameLoop.reset(save.level.timeSeconds * 1e3);
13661
13791
  }
13662
13792
  };
@@ -13672,6 +13802,7 @@ export {
13672
13802
  AmmoItemId,
13673
13803
  AmmoType,
13674
13804
  ArmorType,
13805
+ AttackState,
13675
13806
  CheckGround,
13676
13807
  DamageFlags,
13677
13808
  DamageMod,