quake2ts 0.0.485 → 0.0.486

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.
@@ -153,6 +153,7 @@ __export(index_exports, {
153
153
  getAmmoItemDefinition: () => getAmmoItemDefinition,
154
154
  getWeaponState: () => getWeaponState,
155
155
  giveAmmoItem: () => giveAmmoItem,
156
+ giveItem: () => giveItem,
156
157
  giveWeapon: () => giveWeapon,
157
158
  hasAnyDamageFlag: () => hasAnyDamageFlag,
158
159
  hasItem: () => hasItem,
@@ -2077,6 +2078,13 @@ var DamageFlags = /* @__PURE__ */ ((DamageFlags2) => {
2077
2078
  DamageFlags2[DamageFlags2["NO_DAMAGE_EFFECTS"] = 1024] = "NO_DAMAGE_EFFECTS";
2078
2079
  return DamageFlags2;
2079
2080
  })(DamageFlags || {});
2081
+ var EntityDamageFlags = /* @__PURE__ */ ((EntityDamageFlags2) => {
2082
+ EntityDamageFlags2[EntityDamageFlags2["GODMODE"] = 1] = "GODMODE";
2083
+ EntityDamageFlags2[EntityDamageFlags2["IMMORTAL"] = 2] = "IMMORTAL";
2084
+ EntityDamageFlags2[EntityDamageFlags2["NO_KNOCKBACK"] = 4] = "NO_KNOCKBACK";
2085
+ EntityDamageFlags2[EntityDamageFlags2["NO_DAMAGE_EFFECTS"] = 8] = "NO_DAMAGE_EFFECTS";
2086
+ return EntityDamageFlags2;
2087
+ })(EntityDamageFlags || {});
2080
2088
  function hasAnyDamageFlag(flags, mask) {
2081
2089
  return (flags & mask) !== 0;
2082
2090
  }
@@ -4063,13 +4071,6 @@ var MulticastType = /* @__PURE__ */ ((MulticastType2) => {
4063
4071
  })(MulticastType || {});
4064
4072
 
4065
4073
  // src/combat/damage.ts
4066
- var EntityDamageFlags = /* @__PURE__ */ ((EntityDamageFlags2) => {
4067
- EntityDamageFlags2[EntityDamageFlags2["GODMODE"] = 1] = "GODMODE";
4068
- EntityDamageFlags2[EntityDamageFlags2["IMMORTAL"] = 2] = "IMMORTAL";
4069
- EntityDamageFlags2[EntityDamageFlags2["NO_KNOCKBACK"] = 4] = "NO_KNOCKBACK";
4070
- EntityDamageFlags2[EntityDamageFlags2["NO_DAMAGE_EFFECTS"] = 8] = "NO_DAMAGE_EFFECTS";
4071
- return EntityDamageFlags2;
4072
- })(EntityDamageFlags || {});
4073
4074
  function getDamageModifier(attacker, time) {
4074
4075
  if (!attacker) {
4075
4076
  return 1;
@@ -4133,6 +4134,18 @@ function T_Damage(targ, inflictor, attacker, dir, point, normal, damage, knockba
4133
4134
  if (!targ.takedamage) {
4134
4135
  return null;
4135
4136
  }
4137
+ const client = targ.client;
4138
+ if (client && client.enviro_time && client.enviro_time > time) {
4139
+ if (mod === 18 /* SLIME */ || mod === 19 /* LAVA */) {
4140
+ return {
4141
+ take: 0,
4142
+ psave: 0,
4143
+ asave: 0,
4144
+ knocked: { x: 0, y: 0, z: 0 },
4145
+ killed: false
4146
+ };
4147
+ }
4148
+ }
4136
4149
  const modifier = getDamageModifier(attacker, time);
4137
4150
  const modifiedDamage = damage * modifier;
4138
4151
  const modifiedKnockback = knockback * modifier;
@@ -5314,8 +5327,14 @@ var EntitySystem = class {
5314
5327
  linkentity(ent) {
5315
5328
  this.imports.linkentity(ent);
5316
5329
  }
5317
- multicast(origin, type, event, ...args) {
5318
- this.imports.multicast(origin, type, event, ...args);
5330
+ link(ent) {
5331
+ this.linkentity(ent);
5332
+ }
5333
+ unlink(ent) {
5334
+ this.spatialGrid.remove(ent);
5335
+ }
5336
+ multicast(origin, type, ServerCommand6, ...args) {
5337
+ this.imports.multicast(origin, type, ServerCommand6, ...args);
5319
5338
  }
5320
5339
  unicast(ent, reliable, event, ...args) {
5321
5340
  this.imports.unicast(ent, reliable, event, ...args);
@@ -10291,6 +10310,64 @@ var FLAG_ITEMS = {
10291
10310
  }
10292
10311
  };
10293
10312
 
10313
+ // src/inventory/give.ts
10314
+ function giveItem(entity, classname) {
10315
+ if (!entity.client) return false;
10316
+ const client = entity.client;
10317
+ const inventory = client.inventory;
10318
+ const time = 0;
10319
+ const weapon = WEAPON_ITEMS[classname];
10320
+ if (weapon) {
10321
+ return pickupWeapon(inventory, weapon, time);
10322
+ }
10323
+ const isAmmo = Object.values(AmmoItemId).includes(classname);
10324
+ if (isAmmo) {
10325
+ const res = giveAmmoItem(inventory, classname);
10326
+ return res.pickedUp;
10327
+ }
10328
+ const healthItem = HEALTH_ITEMS[classname];
10329
+ if (healthItem) {
10330
+ if (canPickupHealth(inventory, entity.health, healthItem)) {
10331
+ const count = healthItem.amount;
10332
+ const max = healthItem.max;
10333
+ if (entity.health < max) {
10334
+ entity.health += count;
10335
+ if (entity.health > max) entity.health = max;
10336
+ return true;
10337
+ }
10338
+ if (classname === "item_health_mega") {
10339
+ if (entity.health < max) {
10340
+ entity.health += count;
10341
+ return true;
10342
+ }
10343
+ return false;
10344
+ }
10345
+ }
10346
+ return false;
10347
+ }
10348
+ const armorItem = ARMOR_ITEMS[classname];
10349
+ if (armorItem) {
10350
+ return pickupArmor(inventory, armorItem, time);
10351
+ }
10352
+ const powerupItem = POWERUP_ITEMS[classname];
10353
+ if (powerupItem) {
10354
+ return pickupPowerup(client, powerupItem, time);
10355
+ }
10356
+ const powerArmorItem = POWER_ARMOR_ITEMS[classname];
10357
+ if (powerArmorItem) {
10358
+ return pickupPowerArmor(inventory, powerArmorItem, time);
10359
+ }
10360
+ const keyItem = KEY_ITEMS[classname];
10361
+ if (keyItem) {
10362
+ return pickupKey(inventory, keyItem, time);
10363
+ }
10364
+ const flagItem = FLAG_ITEMS[classname];
10365
+ if (flagItem) {
10366
+ return pickupFlag(client, flagItem, time);
10367
+ }
10368
+ return false;
10369
+ }
10370
+
10294
10371
  // src/entities/items/common.ts
10295
10372
  function handleItemPickup(game, self, other, respawnTime = 30) {
10296
10373
  if (!game.deathmatch) {
@@ -26047,6 +26124,11 @@ function player_think(self, sys) {
26047
26124
  return;
26048
26125
  }
26049
26126
  const nowMs = sys.timeSeconds * 1e3;
26127
+ if (self.client.invincible_time && self.client.invincible_time > sys.timeSeconds) {
26128
+ self.flags = (self.flags || 0) | 1 /* GODMODE */;
26129
+ } else {
26130
+ self.flags = (self.flags || 0) & ~1 /* GODMODE */;
26131
+ }
26050
26132
  const quadTime = self.client.quad_time || 0;
26051
26133
  const doubleTime = self.client.double_time || 0;
26052
26134
  const soundTime = self.client.quadsound_time || 0;
@@ -26151,106 +26233,6 @@ function populatePlayerStats(player, timeSeconds) {
26151
26233
  return statArray;
26152
26234
  }
26153
26235
 
26154
- // src/save/adapter.ts
26155
- function createSerializedGameState(context) {
26156
- const { entitySystem, levelClock, random: random5 } = context;
26157
- const player = entitySystem.find((e) => e.classname === "player");
26158
- const sysSnapshot = entitySystem.createSnapshot();
26159
- const playerState = {
26160
- origin: player ? { ...player.origin } : { x: 0, y: 0, z: 0 },
26161
- velocity: player ? { ...player.velocity } : { x: 0, y: 0, z: 0 },
26162
- viewAngles: player ? { ...player.angles } : { x: 0, y: 0, z: 0 },
26163
- onGround: player ? player.groundentity !== null : false,
26164
- waterLevel: player ? player.waterlevel : 0,
26165
- mins: player ? { ...player.mins } : { x: -16, y: -16, z: -24 },
26166
- maxs: player ? { ...player.maxs } : { x: 16, y: 16, z: 32 },
26167
- damageAlpha: player?.client?.damage_alpha ?? 0,
26168
- damageIndicators: [],
26169
- // Transient
26170
- blend: [0, 0, 0, 0],
26171
- // Transient
26172
- stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
26173
- kick_angles: player?.client?.kick_angles ?? { x: 0, y: 0, z: 0 },
26174
- kick_origin: player?.client?.kick_origin ?? { x: 0, y: 0, z: 0 },
26175
- gunoffset: { x: 0, y: 0, z: 0 },
26176
- gunangles: { x: 0, y: 0, z: 0 },
26177
- gunindex: 0,
26178
- // Q2 Network Compatibility
26179
- pm_type: player?.client?.pm_type ?? 0,
26180
- pm_time: player?.client?.pm_time ?? 0,
26181
- pm_flags: player?.client?.pm_flags ?? 0,
26182
- gun_frame: player?.client?.gun_frame ?? 0,
26183
- rdflags: player?.client?.rdflags ?? 0,
26184
- fov: player?.client?.fov ?? 90,
26185
- renderfx: player?.renderfx ?? 0
26186
- };
26187
- return {
26188
- mapName: entitySystem.level.mapname || "unknown",
26189
- playerState,
26190
- entities: sysSnapshot.entities,
26191
- levelState: sysSnapshot.level,
26192
- time: levelClock.current.timeSeconds,
26193
- playerInventory: player?.client?.inventory ? serializePlayerInventory(player.client.inventory) : void 0,
26194
- rngState: random5?.getState(),
26195
- _internalSnapshot: sysSnapshot
26196
- };
26197
- }
26198
- function applySerializedGameState(state, context) {
26199
- const { entitySystem, levelClock, random: random5 } = context;
26200
- levelClock.restore({
26201
- frameNumber: 0,
26202
- // Unknown in this format, reset to 0
26203
- timeSeconds: state.time,
26204
- previousTimeSeconds: state.time,
26205
- deltaSeconds: 0
26206
- });
26207
- if (random5 && state.rngState) {
26208
- random5.setState(state.rngState);
26209
- }
26210
- if (state._internalSnapshot) {
26211
- entitySystem.restore(state._internalSnapshot);
26212
- } else {
26213
- console.warn("Restoring from partial SerializedGameState. Thinks and Pool state may be lost.");
26214
- const partialSnapshot = {
26215
- timeSeconds: state.time,
26216
- pool: {
26217
- capacity: state.entities.length + 32,
26218
- // Estimate
26219
- activeOrder: state.entities.map((e) => e.index),
26220
- // Naive
26221
- freeList: [],
26222
- // Assume none
26223
- pendingFree: []
26224
- },
26225
- entities: state.entities,
26226
- thinks: [],
26227
- // LOST
26228
- awareness: {
26229
- frameNumber: 0,
26230
- sightEntityIndex: null,
26231
- sightEntityFrame: 0,
26232
- soundEntityIndex: null,
26233
- soundEntityFrame: 0,
26234
- sound2EntityIndex: null,
26235
- sound2EntityFrame: 0,
26236
- sightClientIndex: null
26237
- },
26238
- crossLevelFlags: 0,
26239
- crossUnitFlags: 0,
26240
- level: state.levelState
26241
- };
26242
- entitySystem.restore(partialSnapshot);
26243
- }
26244
- const player = entitySystem.find((e) => e.classname === "player");
26245
- if (player && state.playerInventory) {
26246
- const inventory = deserializePlayerInventory(state.playerInventory);
26247
- player.client = player.client || {};
26248
- if (player.client) {
26249
- player.client.inventory = inventory;
26250
- }
26251
- }
26252
- }
26253
-
26254
26236
  // src/combat/weapon.ts
26255
26237
  var WeaponType = /* @__PURE__ */ ((WeaponType2) => {
26256
26238
  WeaponType2[WeaponType2["BLASTER"] = 0] = "BLASTER";
@@ -26358,6 +26340,106 @@ var WEAPONS = {
26358
26340
  }
26359
26341
  };
26360
26342
 
26343
+ // src/save/adapter.ts
26344
+ function createSerializedGameState(context) {
26345
+ const { entitySystem, levelClock, random: random5 } = context;
26346
+ const player = entitySystem.find((e) => e.classname === "player");
26347
+ const sysSnapshot = entitySystem.createSnapshot();
26348
+ const playerState = {
26349
+ origin: player ? { ...player.origin } : { x: 0, y: 0, z: 0 },
26350
+ velocity: player ? { ...player.velocity } : { x: 0, y: 0, z: 0 },
26351
+ viewAngles: player ? { ...player.angles } : { x: 0, y: 0, z: 0 },
26352
+ onGround: player ? player.groundentity !== null : false,
26353
+ waterLevel: player ? player.waterlevel : 0,
26354
+ mins: player ? { ...player.mins } : { x: -16, y: -16, z: -24 },
26355
+ maxs: player ? { ...player.maxs } : { x: 16, y: 16, z: 32 },
26356
+ damageAlpha: player?.client?.damage_alpha ?? 0,
26357
+ damageIndicators: [],
26358
+ // Transient
26359
+ blend: [0, 0, 0, 0],
26360
+ // Transient
26361
+ stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
26362
+ kick_angles: player?.client?.kick_angles ?? { x: 0, y: 0, z: 0 },
26363
+ kick_origin: player?.client?.kick_origin ?? { x: 0, y: 0, z: 0 },
26364
+ gunoffset: { x: 0, y: 0, z: 0 },
26365
+ gunangles: { x: 0, y: 0, z: 0 },
26366
+ gunindex: 0,
26367
+ // Q2 Network Compatibility
26368
+ pm_type: player?.client?.pm_type ?? 0,
26369
+ pm_time: player?.client?.pm_time ?? 0,
26370
+ pm_flags: player?.client?.pm_flags ?? 0,
26371
+ gun_frame: player?.client?.gun_frame ?? 0,
26372
+ rdflags: player?.client?.rdflags ?? 0,
26373
+ fov: player?.client?.fov ?? 90,
26374
+ renderfx: player?.renderfx ?? 0
26375
+ };
26376
+ return {
26377
+ mapName: entitySystem.level.mapname || "unknown",
26378
+ playerState,
26379
+ entities: sysSnapshot.entities,
26380
+ levelState: sysSnapshot.level,
26381
+ time: levelClock.current.timeSeconds,
26382
+ playerInventory: player?.client?.inventory ? serializePlayerInventory(player.client.inventory) : void 0,
26383
+ rngState: random5?.getState(),
26384
+ _internalSnapshot: sysSnapshot
26385
+ };
26386
+ }
26387
+ function applySerializedGameState(state, context) {
26388
+ const { entitySystem, levelClock, random: random5 } = context;
26389
+ levelClock.restore({
26390
+ frameNumber: 0,
26391
+ // Unknown in this format, reset to 0
26392
+ timeSeconds: state.time,
26393
+ previousTimeSeconds: state.time,
26394
+ deltaSeconds: 0
26395
+ });
26396
+ if (random5 && state.rngState) {
26397
+ random5.setState(state.rngState);
26398
+ }
26399
+ if (state._internalSnapshot) {
26400
+ entitySystem.restore(state._internalSnapshot);
26401
+ } else {
26402
+ console.warn("Restoring from partial SerializedGameState. Thinks and Pool state may be lost.");
26403
+ const partialSnapshot = {
26404
+ timeSeconds: state.time,
26405
+ pool: {
26406
+ capacity: state.entities.length + 32,
26407
+ // Estimate
26408
+ activeOrder: state.entities.map((e) => e.index),
26409
+ // Naive
26410
+ freeList: [],
26411
+ // Assume none
26412
+ pendingFree: []
26413
+ },
26414
+ entities: state.entities,
26415
+ thinks: [],
26416
+ // LOST
26417
+ awareness: {
26418
+ frameNumber: 0,
26419
+ sightEntityIndex: null,
26420
+ sightEntityFrame: 0,
26421
+ soundEntityIndex: null,
26422
+ soundEntityFrame: 0,
26423
+ sound2EntityIndex: null,
26424
+ sound2EntityFrame: 0,
26425
+ sightClientIndex: null
26426
+ },
26427
+ crossLevelFlags: 0,
26428
+ crossUnitFlags: 0,
26429
+ level: state.levelState
26430
+ };
26431
+ entitySystem.restore(partialSnapshot);
26432
+ }
26433
+ const player = entitySystem.find((e) => e.classname === "player");
26434
+ if (player && state.playerInventory) {
26435
+ const inventory = deserializePlayerInventory(state.playerInventory);
26436
+ player.client = player.client || {};
26437
+ if (player.client) {
26438
+ player.client.inventory = inventory;
26439
+ }
26440
+ }
26441
+ }
26442
+
26361
26443
  // src/index.ts
26362
26444
  var ZERO_VEC312 = { x: 0, y: 0, z: 0 };
26363
26445
  function createGame(imports, engine, options) {
@@ -26818,6 +26900,57 @@ function createGame(imports, engine, options) {
26818
26900
  velocity = { ...ZERO_VEC312 };
26819
26901
  }
26820
26902
  frameLoop.reset(state.time * 1e3);
26903
+ },
26904
+ setGodMode(enabled) {
26905
+ const player = entities.find((e) => e.classname === "player");
26906
+ if (player) {
26907
+ if (enabled) {
26908
+ player.flags |= 16 /* GodMode */;
26909
+ } else {
26910
+ player.flags &= ~16 /* GodMode */;
26911
+ }
26912
+ }
26913
+ },
26914
+ setNoclip(enabled) {
26915
+ const player = entities.find((e) => e.classname === "player");
26916
+ if (player) {
26917
+ if (enabled) {
26918
+ player.movetype = 1 /* Noclip */;
26919
+ } else {
26920
+ player.movetype = 4 /* Walk */;
26921
+ }
26922
+ }
26923
+ },
26924
+ setNotarget(enabled) {
26925
+ const player = entities.find((e) => e.classname === "player");
26926
+ if (player) {
26927
+ if (enabled) {
26928
+ player.flags |= 32 /* NoTarget */;
26929
+ } else {
26930
+ player.flags &= ~32 /* NoTarget */;
26931
+ }
26932
+ }
26933
+ },
26934
+ giveItem(itemClassname) {
26935
+ const player = entities.find((e) => e.classname === "player");
26936
+ if (player) {
26937
+ giveItem(player, itemClassname);
26938
+ }
26939
+ },
26940
+ damage(amount) {
26941
+ const player = entities.find((e) => e.classname === "player");
26942
+ if (player) {
26943
+ T_Damage(player, null, null, ZERO_VEC312, player.origin, ZERO_VEC312, amount, 0, 0 /* NONE */, 0 /* UNKNOWN */, levelClock.current.timeSeconds);
26944
+ }
26945
+ },
26946
+ teleport(origin2) {
26947
+ const player = entities.find((e) => e.classname === "player");
26948
+ if (player) {
26949
+ entities.unlink(player);
26950
+ player.origin = { ...origin2 };
26951
+ player.velocity = { ...ZERO_VEC312 };
26952
+ entities.link(player);
26953
+ }
26821
26954
  }
26822
26955
  };
26823
26956
  registerDefaultSpawns(spawnRegistry, gameExports);
@@ -26960,6 +27093,7 @@ function createGame(imports, engine, options) {
26960
27093
  getAmmoItemDefinition,
26961
27094
  getWeaponState,
26962
27095
  giveAmmoItem,
27096
+ giveItem,
26963
27097
  giveWeapon,
26964
27098
  hasAnyDamageFlag,
26965
27099
  hasItem,