quake2ts 0.0.506 → 0.0.507

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.
@@ -2183,6 +2183,10 @@ function pickupPowerup(client, item, time) {
2183
2183
  powerupId = PowerupId.DoubleDamage;
2184
2184
  icon = "p_double";
2185
2185
  break;
2186
+ case "item_invisibility":
2187
+ powerupId = PowerupId.Invisibility;
2188
+ icon = "p_invisibility";
2189
+ break;
2186
2190
  }
2187
2191
  if (powerupId) {
2188
2192
  const expiresAt = inventory.powerups.get(powerupId);
@@ -2198,6 +2202,9 @@ function pickupPowerup(client, item, time) {
2198
2202
  client.enviro_time = newExpiresAt / 1e3;
2199
2203
  } else if (powerupId === PowerupId.Rebreather) {
2200
2204
  client.breather_time = newExpiresAt / 1e3;
2205
+ } else if (powerupId === PowerupId.Invisibility) {
2206
+ client.invisible_time = newExpiresAt / 1e3;
2207
+ client.invisibility_fade_time = newExpiresAt / 1e3 - 3;
2201
2208
  }
2202
2209
  setPickup(inventory, icon, time);
2203
2210
  return true;
@@ -2952,6 +2959,20 @@ function visible(self, other, trace, options) {
2952
2959
  if ((other.flags & FL_NOVISIBLE) !== 0) {
2953
2960
  return false;
2954
2961
  }
2962
+ if (other.client && options?.timeSeconds !== void 0) {
2963
+ if (other.client.invisible_time && other.client.invisible_time > options.timeSeconds) {
2964
+ if (other.client.invisibility_fade_time && options.timeSeconds < other.client.invisibility_fade_time) {
2965
+ return false;
2966
+ }
2967
+ if (options.random) {
2968
+ if (other.alpha !== void 0) {
2969
+ if (options.random() > other.alpha) {
2970
+ return false;
2971
+ }
2972
+ }
2973
+ }
2974
+ }
2975
+ }
2955
2976
  const start = { x: self.origin.x, y: self.origin.y, z: self.origin.z + self.viewheight };
2956
2977
  const end = { x: other.origin.x, y: other.origin.y, z: other.origin.z + other.viewheight };
2957
2978
  const mask = options?.throughGlass ? 1 /* Opaque */ : 1 /* Opaque */ | 2 /* Window */;
@@ -3156,13 +3177,13 @@ function foundTarget(self, level, context, options) {
3156
3177
  self.monsterinfo.pausetime = 0;
3157
3178
  self.monsterinfo.run?.(self, context);
3158
3179
  }
3159
- function classifyClientVisibility(self, other, level, trace) {
3180
+ function classifyClientVisibility(self, other, level, trace, random5) {
3160
3181
  const distance4 = rangeTo(self, other);
3161
3182
  const range = classifyRange(distance4);
3162
3183
  if (range === "far" /* Far */) return false;
3163
3184
  if (other.light_level <= 5) return false;
3164
3185
  if ((self.monsterinfo.aiflags & 1048576 /* ThirdEye */) === 0) {
3165
- if (!visible(self, other, trace, { throughGlass: false })) return false;
3186
+ if (!visible(self, other, trace, { throughGlass: false, timeSeconds: level.timeSeconds, random: random5 })) return false;
3166
3187
  }
3167
3188
  if (range === "near" /* Near */) {
3168
3189
  return level.timeSeconds <= other.show_hostile || infront(self, other);
@@ -3187,15 +3208,15 @@ function AI_GetSightClient(self, context, trace) {
3187
3208
  if ((self.monsterinfo.aiflags & 1048576 /* ThirdEye */) !== 0) {
3188
3209
  return ent;
3189
3210
  }
3190
- if (visible(self, ent, trace, { throughGlass: false })) {
3211
+ if (visible(self, ent, trace, { throughGlass: false, timeSeconds: context.timeSeconds, random: () => context.rng.frandom() })) {
3191
3212
  return ent;
3192
3213
  }
3193
3214
  }
3194
3215
  return null;
3195
3216
  }
3196
- function updateSoundChase(self, client, level, hearability, trace) {
3217
+ function updateSoundChase(self, client, level, hearability, trace, context) {
3197
3218
  if ((self.spawnflags & SPAWNFLAG_MONSTER_AMBUSH) !== 0) {
3198
- if (!visible(self, client, trace)) return false;
3219
+ if (!visible(self, client, trace, { timeSeconds: level.timeSeconds, random: () => context.rng.frandom() })) return false;
3199
3220
  } else if (hearability.canHear && !hearability.canHear(self, client)) {
3200
3221
  return false;
3201
3222
  }
@@ -3255,12 +3276,12 @@ function findTarget(self, level, context, trace, hearability = {}) {
3255
3276
  return false;
3256
3277
  }
3257
3278
  if (!heardit) {
3258
- if (!classifyClientVisibility(self, candidate, level, trace)) {
3279
+ if (!classifyClientVisibility(self, candidate, level, trace, () => context.rng.frandom())) {
3259
3280
  return false;
3260
3281
  }
3261
3282
  self.monsterinfo.aiflags &= ~4 /* SoundTarget */;
3262
3283
  self.enemy = candidate;
3263
- } else if (!updateSoundChase(self, candidate, level, hearability, trace)) {
3284
+ } else if (!updateSoundChase(self, candidate, level, hearability, trace, context)) {
3264
3285
  return false;
3265
3286
  }
3266
3287
  foundTarget(self, level, context);
@@ -3282,8 +3303,8 @@ function findCover(self, context) {
3282
3303
  for (const spot of spots) {
3283
3304
  if (spot.owner) continue;
3284
3305
  if (spot.targetname) continue;
3285
- if (!visible(self, spot, context.trace, { throughGlass: false })) continue;
3286
- if (visible(spot, self.enemy, context.trace, { throughGlass: false })) continue;
3306
+ if (!visible(self, spot, context.trace, { throughGlass: false, timeSeconds: context.timeSeconds, random: () => context.rng.frandom() })) continue;
3307
+ if (visible(spot, self.enemy, context.trace, { throughGlass: false, timeSeconds: context.timeSeconds, random: () => context.rng.frandom() })) continue;
3287
3308
  self.goalentity = spot;
3288
3309
  self.movetarget = spot;
3289
3310
  setIdealYawTowards(self, spot);
@@ -3445,13 +3466,13 @@ function ai_run(self, dist, context) {
3445
3466
  setIdealYawTowards2(self, self.enemy ?? self.goalentity);
3446
3467
  }
3447
3468
  changeYaw(self, MONSTER_TICK);
3448
- if (self.enemy && self.enemy.inUse && visible(self, self.enemy, context.trace, { throughGlass: false })) {
3469
+ if (self.enemy && self.enemy.inUse && visible(self, self.enemy, context.trace, { throughGlass: false, timeSeconds: context.timeSeconds, random: () => context.rng.frandom() })) {
3449
3470
  self.monsterinfo.blind_fire_target = addVec3(self.enemy.origin, scaleVec3(self.enemy.velocity, -0.1));
3450
3471
  }
3451
3472
  if (ai_checkattack(self, dist, context)) {
3452
3473
  return;
3453
3474
  }
3454
- const enemy_vis = self.enemy && visible(self, self.enemy, context.trace, { throughGlass: false });
3475
+ const enemy_vis = self.enemy && visible(self, self.enemy, context.trace, { throughGlass: false, timeSeconds: context.timeSeconds, random: () => context.rng.frandom() });
3455
3476
  if (!enemy_vis && self.monsterinfo.attack_state === 1 /* Sliding */) {
3456
3477
  self.monsterinfo.attack_state = 0 /* Straight */;
3457
3478
  }
@@ -10481,6 +10502,12 @@ var POWERUP_ITEMS = {
10481
10502
  id: "item_enviro",
10482
10503
  name: "Enviro Suit",
10483
10504
  timer: 30
10505
+ },
10506
+ "item_invisibility": {
10507
+ type: "powerup",
10508
+ id: "item_invisibility",
10509
+ name: "Invisibility",
10510
+ timer: 30
10484
10511
  }
10485
10512
  };
10486
10513
  var POWER_ARMOR_ITEMS = {