quake2ts 0.0.182 → 0.0.184

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.
@@ -2845,6 +2845,12 @@ var EntitySystem = class {
2845
2845
  get rng() {
2846
2846
  return this.random;
2847
2847
  }
2848
+ setSpawnRegistry(registry) {
2849
+ this.spawnRegistry = registry;
2850
+ }
2851
+ getSpawnFunction(classname) {
2852
+ return this.spawnRegistry?.get(classname);
2853
+ }
2848
2854
  get trace() {
2849
2855
  return this.imports.trace;
2850
2856
  }
@@ -9074,18 +9080,79 @@ function medic_fire_blaster(self, context) {
9074
9080
  const forward = normalizeVec3(subtractVec3(self.enemy.origin, start));
9075
9081
  monster_fire_blaster(self, start, forward, 2, 1e3, 0, 0, context, 10 /* HYPERBLASTER */);
9076
9082
  }
9077
- function medic_heal(self, context) {
9083
+ function medic_cable_attack(self, context) {
9084
+ if (!self.enemy || self.enemy.deadflag !== 2 /* Dead */) {
9085
+ return;
9086
+ }
9087
+ const dist = rangeTo(self, self.enemy);
9088
+ if (dist > 400) {
9089
+ self.monsterinfo.current_move = run_move13;
9090
+ return;
9091
+ }
9092
+ const vectors = angleVectors(self.angles);
9093
+ const f = vectors.forward;
9094
+ const r = vectors.right;
9095
+ const u = vectors.up;
9096
+ const offset = { x: 24, y: 0, z: 6 };
9097
+ const start = addVec3(
9098
+ self.origin,
9099
+ addVec3(
9100
+ scaleVec3(f, offset.x),
9101
+ addVec3(scaleVec3(r, offset.y), scaleVec3(u, offset.z))
9102
+ )
9103
+ );
9104
+ const end = self.enemy.origin;
9105
+ context.multicast(self.origin, 1 /* Pvs */, ServerCommand.temp_entity, {
9106
+ te: TempEntity.MEDIC_CABLE_ATTACK,
9107
+ entId: self.index,
9108
+ targetId: self.enemy.index,
9109
+ // Assuming targetId for the beam target
9110
+ start,
9111
+ end
9112
+ });
9113
+ }
9114
+ function medic_hook_launch(self, context) {
9115
+ context.engine.sound?.(self, 0, "medic/medatck2.wav", 1, 1, 0);
9116
+ medic_cable_attack(self, context);
9117
+ }
9118
+ function medic_hook_retract(self, context) {
9078
9119
  if (!self.enemy || self.enemy.deadflag !== 2 /* Dead */) {
9079
9120
  return;
9080
9121
  }
9081
9122
  const ent = self.enemy;
9082
- ent.deadflag = 0 /* Alive */;
9083
- ent.health = ent.max_health;
9084
- ent.takedamage = true;
9085
- ent.solid = 2 /* BoundingBox */;
9086
- ent.nextthink = context.timeSeconds + 0.1;
9087
- if (ent.monsterinfo && ent.monsterinfo.stand) {
9088
- ent.monsterinfo.stand(ent, context);
9123
+ const spawnFunc = context.getSpawnFunction(ent.classname);
9124
+ if (rangeTo(self, ent) > 400) {
9125
+ self.enemy = null;
9126
+ return;
9127
+ }
9128
+ if (!spawnFunc) {
9129
+ ent.deadflag = 0 /* Alive */;
9130
+ ent.health = ent.max_health;
9131
+ ent.takedamage = true;
9132
+ ent.solid = 2 /* BoundingBox */;
9133
+ ent.nextthink = context.timeSeconds + 0.1;
9134
+ if (ent.monsterinfo && ent.monsterinfo.stand) {
9135
+ ent.monsterinfo.stand(ent, context);
9136
+ }
9137
+ } else {
9138
+ const spawnContext = {
9139
+ entities: context,
9140
+ keyValues: { classname: ent.classname },
9141
+ // Minimal keyvalues
9142
+ warn: (msg) => {
9143
+ },
9144
+ // Suppress warnings
9145
+ free: (e) => context.free(e)
9146
+ };
9147
+ const origin = { ...ent.origin };
9148
+ const angles = { ...ent.angles };
9149
+ spawnFunc(ent, spawnContext);
9150
+ ent.origin = origin;
9151
+ ent.angles = angles;
9152
+ context.linkentity(ent);
9153
+ ent.deadflag = 0 /* Alive */;
9154
+ ent.takedamage = true;
9155
+ context.finalizeSpawn(ent);
9089
9156
  }
9090
9157
  self.enemy = null;
9091
9158
  }
@@ -9108,6 +9175,7 @@ function medic_find_dead(self, context) {
9108
9175
  if (ent.deadflag !== 2 /* Dead */) return;
9109
9176
  if (!ent.monsterinfo) return;
9110
9177
  if (ent.classname === "monster_medic") return;
9178
+ if (ent.bad_medic === self) return;
9111
9179
  if (!visible(self, ent, traceWrapper)) return;
9112
9180
  const dist = rangeTo(self, ent);
9113
9181
  if (dist < bestDist) {
@@ -9169,15 +9237,22 @@ attack_hyper_move = {
9169
9237
  frames: attack_hyper_frames,
9170
9238
  endfunc: medic_run
9171
9239
  };
9172
- var attack_cable_frames = Array.from({ length: 10 }, (_, i) => ({
9173
- ai: monster_ai_charge15,
9174
- dist: 0,
9175
- think: i === 5 ? medic_heal : null
9176
- }));
9240
+ var attack_cable_frames = [
9241
+ { ai: monster_ai_charge15, dist: 0, think: medic_hook_launch },
9242
+ { ai: monster_ai_charge15, dist: 0, think: medic_cable_attack },
9243
+ { ai: monster_ai_charge15, dist: 0, think: medic_cable_attack },
9244
+ { ai: monster_ai_charge15, dist: 0, think: medic_cable_attack },
9245
+ { ai: monster_ai_charge15, dist: 0, think: medic_cable_attack },
9246
+ { ai: monster_ai_charge15, dist: 0, think: medic_cable_attack },
9247
+ { ai: monster_ai_charge15, dist: 0, think: medic_cable_attack },
9248
+ { ai: monster_ai_charge15, dist: 0, think: medic_cable_attack },
9249
+ { ai: monster_ai_charge15, dist: 0, think: medic_hook_retract }
9250
+ ];
9177
9251
  attack_cable_move = {
9178
9252
  firstframe: 106,
9179
- // Assume frames come after hyper attack
9180
- lastframe: 115,
9253
+ // FRAME_attack42 (starts at 0+30+40+20+16 = 106) ... wait, check original counts.
9254
+ // stand=30, walk=40, run=20, hyper=16. 30+40+20+16 = 106. Correct.
9255
+ lastframe: 114,
9181
9256
  frames: attack_cable_frames,
9182
9257
  endfunc: medic_run
9183
9258
  };
@@ -12870,7 +12945,7 @@ function createGame({ trace, pointcontents, multicast, unicast }, engine, option
12870
12945
  player.velocity = newState.velocity;
12871
12946
  player.angles = newState.viewAngles;
12872
12947
  };
12873
- return {
12948
+ const gameExports = {
12874
12949
  init(startTimeMs) {
12875
12950
  resetState(startTimeMs);
12876
12951
  return snapshot(0);
@@ -12964,6 +13039,9 @@ function createGame({ trace, pointcontents, multicast, unicast }, engine, option
12964
13039
  frameLoop.reset(save.level.timeSeconds * 1e3);
12965
13040
  }
12966
13041
  };
13042
+ const spawnRegistry = createDefaultSpawnRegistry(gameExports);
13043
+ entities.setSpawnRegistry(spawnRegistry);
13044
+ return gameExports;
12967
13045
  }
12968
13046
  export {
12969
13047
  AIFlags,