quake2ts 0.0.496 → 0.0.498
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.
- package/package.json +1 -1
- package/packages/client/dist/browser/index.global.js +17 -16
- package/packages/client/dist/browser/index.global.js.map +1 -1
- package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/browser/index.global.js +5 -4
- package/packages/game/dist/browser/index.global.js.map +1 -1
- package/packages/game/dist/cjs/index.cjs +339 -35
- package/packages/game/dist/cjs/index.cjs.map +1 -1
- package/packages/game/dist/esm/index.js +339 -35
- package/packages/game/dist/esm/index.js.map +1 -1
- package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/types/entities/monsters/rogue/common.d.ts.map +1 -1
- package/packages/game/dist/types/entities/monsters/rogue/widow.d.ts.map +1 -1
- package/packages/game/dist/types/entities/player.d.ts.map +1 -1
- package/packages/game/dist/types/entities/playerStats.d.ts.map +1 -1
- package/packages/game/dist/types/entities/projectiles.d.ts +5 -0
- package/packages/game/dist/types/entities/projectiles.d.ts.map +1 -1
- package/packages/game/dist/types/entities/system.d.ts +1 -0
- package/packages/game/dist/types/entities/system.d.ts.map +1 -1
- package/packages/game/dist/types/entities/targets.d.ts.map +1 -1
- package/packages/game/dist/types/inventory/items.d.ts.map +1 -1
- package/packages/game/dist/types/inventory/playerInventory.d.ts +1 -0
- package/packages/game/dist/types/inventory/playerInventory.d.ts.map +1 -1
- package/packages/game/dist/types/modes/ctf/capture.d.ts.map +1 -1
- package/packages/game/dist/types/modes/ctf/grapple.d.ts +13 -0
- package/packages/game/dist/types/modes/ctf/grapple.d.ts.map +1 -0
- package/packages/game/dist/types/modes/ctf/pickup.d.ts.map +1 -1
- package/packages/game/dist/types/modes/ctf/scoreboard.d.ts +34 -0
- package/packages/game/dist/types/modes/ctf/scoreboard.d.ts.map +1 -0
|
@@ -611,36 +611,36 @@ var MAX_ITEMS = 256;
|
|
|
611
611
|
var MAX_GENERAL = MAX_CLIENTS * 2;
|
|
612
612
|
var MAX_SHADOW_LIGHTS = 256;
|
|
613
613
|
var MAX_WHEEL_ITEMS = 32;
|
|
614
|
-
var ConfigStringIndex = ((
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
return
|
|
614
|
+
var ConfigStringIndex = ((ConfigStringIndex22) => {
|
|
615
|
+
ConfigStringIndex22[ConfigStringIndex22["Name"] = 0] = "Name";
|
|
616
|
+
ConfigStringIndex22[ConfigStringIndex22["CdTrack"] = 1] = "CdTrack";
|
|
617
|
+
ConfigStringIndex22[ConfigStringIndex22["Sky"] = 2] = "Sky";
|
|
618
|
+
ConfigStringIndex22[ConfigStringIndex22["SkyAxis"] = 3] = "SkyAxis";
|
|
619
|
+
ConfigStringIndex22[ConfigStringIndex22["SkyRotate"] = 4] = "SkyRotate";
|
|
620
|
+
ConfigStringIndex22[ConfigStringIndex22["StatusBar"] = 5] = "StatusBar";
|
|
621
|
+
ConfigStringIndex22[ConfigStringIndex22["HealthBarName"] = 55] = "HealthBarName";
|
|
622
|
+
ConfigStringIndex22[ConfigStringIndex22["CONFIG_N64_PHYSICS"] = 56] = "CONFIG_N64_PHYSICS";
|
|
623
|
+
ConfigStringIndex22[ConfigStringIndex22["CONFIG_CTF_TEAMS"] = 57] = "CONFIG_CTF_TEAMS";
|
|
624
|
+
ConfigStringIndex22[ConfigStringIndex22["CONFIG_COOP_RESPAWN_STRING"] = 58] = "CONFIG_COOP_RESPAWN_STRING";
|
|
625
|
+
ConfigStringIndex22[ConfigStringIndex22["Story"] = 54] = "Story";
|
|
626
|
+
ConfigStringIndex22[ConfigStringIndex22["AirAccel"] = 59] = "AirAccel";
|
|
627
|
+
ConfigStringIndex22[ConfigStringIndex22["MaxClients"] = 60] = "MaxClients";
|
|
628
|
+
ConfigStringIndex22[ConfigStringIndex22["MapChecksum"] = 61] = "MapChecksum";
|
|
629
|
+
ConfigStringIndex22[ConfigStringIndex22["Models"] = 62] = "Models";
|
|
630
|
+
ConfigStringIndex22[ConfigStringIndex22["Sounds"] = 62 + MAX_MODELS] = "Sounds";
|
|
631
|
+
ConfigStringIndex22[ConfigStringIndex22["Images"] = ConfigStringIndex22.Sounds + MAX_SOUNDS] = "Images";
|
|
632
|
+
ConfigStringIndex22[ConfigStringIndex22["Lights"] = ConfigStringIndex22.Images + MAX_IMAGES] = "Lights";
|
|
633
|
+
ConfigStringIndex22[ConfigStringIndex22["ShadowLights"] = ConfigStringIndex22.Lights + MAX_LIGHTSTYLES] = "ShadowLights";
|
|
634
|
+
ConfigStringIndex22[ConfigStringIndex22["Items"] = ConfigStringIndex22.ShadowLights + MAX_SHADOW_LIGHTS] = "Items";
|
|
635
|
+
ConfigStringIndex22[ConfigStringIndex22["PlayerSkins"] = ConfigStringIndex22.Items + MAX_ITEMS] = "PlayerSkins";
|
|
636
|
+
ConfigStringIndex22[ConfigStringIndex22["General"] = ConfigStringIndex22.PlayerSkins + MAX_CLIENTS] = "General";
|
|
637
|
+
ConfigStringIndex22[ConfigStringIndex22["WheelWeapons"] = ConfigStringIndex22.General + MAX_GENERAL] = "WheelWeapons";
|
|
638
|
+
ConfigStringIndex22[ConfigStringIndex22["WheelAmmo"] = ConfigStringIndex22.WheelWeapons + MAX_WHEEL_ITEMS] = "WheelAmmo";
|
|
639
|
+
ConfigStringIndex22[ConfigStringIndex22["WheelPowerups"] = ConfigStringIndex22.WheelAmmo + MAX_WHEEL_ITEMS] = "WheelPowerups";
|
|
640
|
+
ConfigStringIndex22[ConfigStringIndex22["CdLoopCount"] = ConfigStringIndex22.WheelPowerups + MAX_WHEEL_ITEMS] = "CdLoopCount";
|
|
641
|
+
ConfigStringIndex22[ConfigStringIndex22["GameStyle"] = ConfigStringIndex22.CdLoopCount + 1] = "GameStyle";
|
|
642
|
+
ConfigStringIndex22[ConfigStringIndex22["MaxConfigStrings"] = ConfigStringIndex22.GameStyle + 1] = "MaxConfigStrings";
|
|
643
|
+
return ConfigStringIndex22;
|
|
644
644
|
})(ConfigStringIndex || {});
|
|
645
645
|
var MAX_CONFIGSTRINGS = ConfigStringIndex.MaxConfigStrings;
|
|
646
646
|
var replay_exports = {};
|
|
@@ -5127,6 +5127,9 @@ var EntitySystem = class {
|
|
|
5127
5127
|
soundIndex(sound) {
|
|
5128
5128
|
return this.engine.soundIndex?.(sound) || 0;
|
|
5129
5129
|
}
|
|
5130
|
+
configStringIndex(str) {
|
|
5131
|
+
return this.engine.configStringIndex?.(str) || 0;
|
|
5132
|
+
}
|
|
5130
5133
|
modelIndex(model) {
|
|
5131
5134
|
return this.engine.modelIndex?.(model) || 0;
|
|
5132
5135
|
}
|
|
@@ -5139,8 +5142,8 @@ var EntitySystem = class {
|
|
|
5139
5142
|
unlink(ent) {
|
|
5140
5143
|
this.spatialGrid.remove(ent);
|
|
5141
5144
|
}
|
|
5142
|
-
multicast(origin, type,
|
|
5143
|
-
this.imports.multicast(origin, type,
|
|
5145
|
+
multicast(origin, type, ServerCommand7, ...args) {
|
|
5146
|
+
this.imports.multicast(origin, type, ServerCommand7, ...args);
|
|
5144
5147
|
}
|
|
5145
5148
|
unicast(ent, reliable, event, ...args) {
|
|
5146
5149
|
this.imports.unicast(ent, reliable, event, ...args);
|
|
@@ -5881,6 +5884,19 @@ function createTrap(context, owner, start, dir, speed) {
|
|
|
5881
5884
|
// src/entities/projectiles.ts
|
|
5882
5885
|
var BFG_LASER_RADIUS = 256;
|
|
5883
5886
|
var BFG_LASER_RANGE = 2048;
|
|
5887
|
+
function createProjectile(sys, start, dir, speed, mod, damage, radiusDamage) {
|
|
5888
|
+
const proj = sys.spawn();
|
|
5889
|
+
proj.movetype = 8 /* FlyMissile */;
|
|
5890
|
+
proj.solid = 2 /* BoundingBox */;
|
|
5891
|
+
proj.origin = { ...start };
|
|
5892
|
+
proj.velocity = { x: dir.x * speed, y: dir.y * speed, z: dir.z * speed };
|
|
5893
|
+
proj.mins = { x: -4, y: -4, z: -4 };
|
|
5894
|
+
proj.maxs = { x: 4, y: 4, z: 4 };
|
|
5895
|
+
proj.angles = vectorToAngles(dir);
|
|
5896
|
+
proj.takedamage = false;
|
|
5897
|
+
sys.finalizeSpawn(proj);
|
|
5898
|
+
return proj;
|
|
5899
|
+
}
|
|
5884
5900
|
function createRocket(sys, owner, start, dir, damage, radiusDamage, speed, flashtype = 0) {
|
|
5885
5901
|
const rocket = sys.spawn();
|
|
5886
5902
|
rocket.classname = "rocket";
|
|
@@ -6993,8 +7009,10 @@ var SPEAKER_SPAWNFLAGS = {
|
|
|
6993
7009
|
LoopedOff: 1 << 1,
|
|
6994
7010
|
Reliable: 1 << 2
|
|
6995
7011
|
};
|
|
6996
|
-
function useChangeLevel(self) {
|
|
7012
|
+
function useChangeLevel(self, other, activator, context) {
|
|
6997
7013
|
if (self.map) {
|
|
7014
|
+
context.entities.imports.serverCommand(`changelevel ${self.map}
|
|
7015
|
+
`);
|
|
6998
7016
|
}
|
|
6999
7017
|
}
|
|
7000
7018
|
function targetSpeakerUse(self, other, activator, context) {
|
|
@@ -7454,13 +7472,14 @@ function registerTargetSpawns(registry) {
|
|
|
7454
7472
|
entities.useTargets(self, self.activator ?? null);
|
|
7455
7473
|
};
|
|
7456
7474
|
});
|
|
7457
|
-
registry.register("target_changelevel", (entity,
|
|
7475
|
+
registry.register("target_changelevel", (entity, context) => {
|
|
7476
|
+
const { keyValues, free } = context;
|
|
7458
7477
|
if (!keyValues.map) {
|
|
7459
7478
|
free(entity);
|
|
7460
7479
|
return;
|
|
7461
7480
|
}
|
|
7462
7481
|
entity.map = keyValues.map;
|
|
7463
|
-
entity.use = useChangeLevel;
|
|
7482
|
+
entity.use = (self, other, activator) => useChangeLevel(self, other, activator ?? null, context);
|
|
7464
7483
|
entity.solid = 1 /* Trigger */;
|
|
7465
7484
|
});
|
|
7466
7485
|
registry.register("target_spawner", (entity, context) => {
|
|
@@ -9920,6 +9939,95 @@ function Trap_Think(player, sys) {
|
|
|
9920
9939
|
);
|
|
9921
9940
|
}
|
|
9922
9941
|
|
|
9942
|
+
// src/modes/ctf/grapple.ts
|
|
9943
|
+
var GRAPPLE_SPEED = 1200;
|
|
9944
|
+
var GRAPPLE_PULL_SPEED = 800;
|
|
9945
|
+
var GRAPPLE_DAMAGE = 20;
|
|
9946
|
+
function Grapple_Think(player, sys) {
|
|
9947
|
+
if (player.client?.inventory.currentWeapon !== WeaponId.Grapple) {
|
|
9948
|
+
ResetGrapple(player, sys);
|
|
9949
|
+
}
|
|
9950
|
+
Weapon_Generic(
|
|
9951
|
+
player,
|
|
9952
|
+
0,
|
|
9953
|
+
10,
|
|
9954
|
+
// ready
|
|
9955
|
+
11,
|
|
9956
|
+
20,
|
|
9957
|
+
// fire
|
|
9958
|
+
[],
|
|
9959
|
+
// pause frames
|
|
9960
|
+
[11],
|
|
9961
|
+
// fire frames
|
|
9962
|
+
(ent) => fire_grapple(ent, sys),
|
|
9963
|
+
sys
|
|
9964
|
+
);
|
|
9965
|
+
if (player.client && !(player.client.buttons & 1)) {
|
|
9966
|
+
ResetGrapple(player, sys);
|
|
9967
|
+
}
|
|
9968
|
+
if (player.grapple && player.grapple.grappleState === "attached") {
|
|
9969
|
+
Grapple_Pull(player, player.grapple, sys);
|
|
9970
|
+
}
|
|
9971
|
+
}
|
|
9972
|
+
function fire_grapple(player, sys) {
|
|
9973
|
+
if (player.grapple) return;
|
|
9974
|
+
const angles = player.client.v_angle || player.angles;
|
|
9975
|
+
const vectors = angleVectors(angles);
|
|
9976
|
+
const forward = vectors.forward;
|
|
9977
|
+
const right = vectors.right;
|
|
9978
|
+
const up = vectors.up;
|
|
9979
|
+
const game = sys.game;
|
|
9980
|
+
const start = P_ProjectSource(game, player, { x: 8, y: 8, z: 8 }, forward, right, up);
|
|
9981
|
+
const dir = { ...forward };
|
|
9982
|
+
const grapple = createProjectile(sys, start, dir, GRAPPLE_SPEED, 57 /* GRAPPLE */, 0);
|
|
9983
|
+
grapple.classname = "grapple";
|
|
9984
|
+
grapple.owner = player;
|
|
9985
|
+
grapple.movetype = 8 /* FlyMissile */;
|
|
9986
|
+
grapple.solid = 2 /* BoundingBox */;
|
|
9987
|
+
grapple.mins = { x: -4, y: -4, z: -4 };
|
|
9988
|
+
grapple.maxs = { x: 4, y: 4, z: 4 };
|
|
9989
|
+
grapple.model = "models/weapons/grapple/hook/tris.md2";
|
|
9990
|
+
grapple.grappleState = "fly";
|
|
9991
|
+
grapple.touch = (self, other, plane, surface) => {
|
|
9992
|
+
if (!other) return;
|
|
9993
|
+
Grapple_Touch(self, other, plane, surface, sys);
|
|
9994
|
+
};
|
|
9995
|
+
player.grapple = grapple;
|
|
9996
|
+
sys.sound(player, 0, "weapons/grapple/throw.wav", 1, 1, 0);
|
|
9997
|
+
}
|
|
9998
|
+
function Grapple_Touch(self, other, plane, surface, sys) {
|
|
9999
|
+
if (other === self.owner) return;
|
|
10000
|
+
if (self.grappleState === "attached") return;
|
|
10001
|
+
if (other.takedamage) {
|
|
10002
|
+
T_Damage(other, self, self.owner, self.velocity, self.origin, ZERO_VEC3, GRAPPLE_DAMAGE, 0, 0, 57 /* GRAPPLE */, sys.timeSeconds, sys.multicast.bind(sys));
|
|
10003
|
+
sys.free(self);
|
|
10004
|
+
if (self.owner) self.owner.grapple = void 0;
|
|
10005
|
+
return;
|
|
10006
|
+
}
|
|
10007
|
+
if (other.solid === 3 /* Bsp */ || other.solid === 2 /* BoundingBox */) {
|
|
10008
|
+
self.velocity = { x: 0, y: 0, z: 0 };
|
|
10009
|
+
self.movetype = 0 /* None */;
|
|
10010
|
+
self.grappleState = "attached";
|
|
10011
|
+
sys.sound(self, 0, "weapons/grapple/hit.wav", 1, 1, 0);
|
|
10012
|
+
if (plane) {
|
|
10013
|
+
}
|
|
10014
|
+
}
|
|
10015
|
+
}
|
|
10016
|
+
function Grapple_Pull(player, grapple, sys) {
|
|
10017
|
+
const dir = subtractVec3(grapple.origin, player.origin);
|
|
10018
|
+
const dist = lengthVec3(dir);
|
|
10019
|
+
if (dist < 32) return;
|
|
10020
|
+
const normalizedDir = normalizeVec3(dir);
|
|
10021
|
+
const pull = scaleVec3(normalizedDir, GRAPPLE_PULL_SPEED);
|
|
10022
|
+
player.velocity = pull;
|
|
10023
|
+
}
|
|
10024
|
+
function ResetGrapple(player, sys) {
|
|
10025
|
+
if (player.grapple) {
|
|
10026
|
+
sys.free(player.grapple);
|
|
10027
|
+
player.grapple = void 0;
|
|
10028
|
+
}
|
|
10029
|
+
}
|
|
10030
|
+
|
|
9923
10031
|
// src/inventory/items.ts
|
|
9924
10032
|
var WEAPON_ITEMS = {
|
|
9925
10033
|
"weapon_blaster": {
|
|
@@ -10117,6 +10225,18 @@ var WEAPON_ITEMS = {
|
|
|
10117
10225
|
pickupAmmo: 5,
|
|
10118
10226
|
fireRate: 1,
|
|
10119
10227
|
think: Trap_Think
|
|
10228
|
+
},
|
|
10229
|
+
"weapon_grapple": {
|
|
10230
|
+
type: "weapon",
|
|
10231
|
+
id: "weapon_grapple",
|
|
10232
|
+
name: "Grapple",
|
|
10233
|
+
weaponId: WeaponId.Grapple,
|
|
10234
|
+
ammoType: null,
|
|
10235
|
+
// Grapple uses no ammo in standard Q2 CTF? Or maybe just internal timer.
|
|
10236
|
+
initialAmmo: 0,
|
|
10237
|
+
pickupAmmo: 0,
|
|
10238
|
+
fireRate: 0.5,
|
|
10239
|
+
think: Grapple_Think
|
|
10120
10240
|
}
|
|
10121
10241
|
};
|
|
10122
10242
|
var HEALTH_ITEMS = {
|
|
@@ -10518,6 +10638,34 @@ function setFlagState(flag, newState, context) {
|
|
|
10518
10638
|
flag.flagState = newState;
|
|
10519
10639
|
}
|
|
10520
10640
|
|
|
10641
|
+
// src/modes/ctf/scoreboard.ts
|
|
10642
|
+
var teamScores = {
|
|
10643
|
+
[1 /* RED */]: 0,
|
|
10644
|
+
[2 /* BLUE */]: 0
|
|
10645
|
+
};
|
|
10646
|
+
function addTeamScore(team, points) {
|
|
10647
|
+
if (team === 1 /* RED */ || team === 2 /* BLUE */) {
|
|
10648
|
+
teamScores[team] += points;
|
|
10649
|
+
}
|
|
10650
|
+
}
|
|
10651
|
+
function updateCtfScoreboard(ent, sys) {
|
|
10652
|
+
if (!ent.client || !ent.client.stats) return;
|
|
10653
|
+
const stats = ent.client.stats;
|
|
10654
|
+
stats[PlayerStat.STAT_CTF_TEAM1_PIC] = sys.configStringIndex ? sys.configStringIndex("pics/ctf_r.pcx") : 0;
|
|
10655
|
+
stats[PlayerStat.STAT_CTF_TEAM1_CAPS] = teamScores[1 /* RED */];
|
|
10656
|
+
stats[PlayerStat.STAT_CTF_TEAM2_PIC] = sys.configStringIndex ? sys.configStringIndex("pics/ctf_b.pcx") : 0;
|
|
10657
|
+
stats[PlayerStat.STAT_CTF_TEAM2_CAPS] = teamScores[2 /* BLUE */];
|
|
10658
|
+
const clientTeam = ent.client.ctfTeam;
|
|
10659
|
+
stats[PlayerStat.STAT_CTF_JOINED_TEAM1_PIC] = 0;
|
|
10660
|
+
stats[PlayerStat.STAT_CTF_JOINED_TEAM2_PIC] = 0;
|
|
10661
|
+
if (clientTeam === 1 /* RED */) {
|
|
10662
|
+
stats[PlayerStat.STAT_CTF_JOINED_TEAM1_PIC] = sys.configStringIndex ? sys.configStringIndex("pics/ctf_r.pcx") : 0;
|
|
10663
|
+
} else if (clientTeam === 2 /* BLUE */) {
|
|
10664
|
+
stats[PlayerStat.STAT_CTF_JOINED_TEAM2_PIC] = sys.configStringIndex ? sys.configStringIndex("pics/ctf_b.pcx") : 0;
|
|
10665
|
+
}
|
|
10666
|
+
stats[PlayerStat.STAT_CTF_TEAMINFO] = 1;
|
|
10667
|
+
}
|
|
10668
|
+
|
|
10521
10669
|
// src/modes/ctf/capture.ts
|
|
10522
10670
|
function checkCapture(flag, player, game, context) {
|
|
10523
10671
|
if (!player.client) return false;
|
|
@@ -10538,11 +10686,17 @@ function captureFlag(ownFlag, player, game, context) {
|
|
|
10538
10686
|
if (!player.client) return false;
|
|
10539
10687
|
const playerTeam = player.client.team || "red";
|
|
10540
10688
|
const enemyTeam = playerTeam === "red" ? "blue" : "red";
|
|
10689
|
+
const ctfStats = player.client.ctfStats;
|
|
10690
|
+
if (ctfStats) {
|
|
10691
|
+
ctfStats.captures++;
|
|
10692
|
+
}
|
|
10541
10693
|
if (player.client.score !== void 0) {
|
|
10542
10694
|
player.client.score += 5;
|
|
10543
10695
|
} else {
|
|
10544
10696
|
player.client.score = 5;
|
|
10545
10697
|
}
|
|
10698
|
+
const teamEnum = playerTeam === "red" ? 1 /* RED */ : 2 /* BLUE */;
|
|
10699
|
+
addTeamScore(teamEnum, 1);
|
|
10546
10700
|
game.sound?.(player, 0, "ctf/flagcap.wav", 1, 1, 0);
|
|
10547
10701
|
game.centerprintf?.(player, "You captured the flag!");
|
|
10548
10702
|
const enemyFlagKey = playerTeam === "red" ? "key_blue_flag" /* BlueFlag */ : "key_red_flag" /* RedFlag */;
|
|
@@ -12141,14 +12295,81 @@ var generic_stand_frames = Array.from({ length: 1 }, () => ({
|
|
|
12141
12295
|
ai: generic_ai_stand,
|
|
12142
12296
|
dist: 0
|
|
12143
12297
|
}));
|
|
12298
|
+
var generic_stand_move = {
|
|
12299
|
+
firstframe: 0,
|
|
12300
|
+
lastframe: 0,
|
|
12301
|
+
frames: generic_stand_frames,
|
|
12302
|
+
endfunc: (self) => {
|
|
12303
|
+
self.monsterinfo.current_move = generic_stand_move;
|
|
12304
|
+
}
|
|
12305
|
+
};
|
|
12144
12306
|
var generic_walk_frames = Array.from({ length: 1 }, () => ({
|
|
12145
12307
|
ai: generic_ai_walk,
|
|
12146
12308
|
dist: 5
|
|
12147
12309
|
}));
|
|
12310
|
+
var generic_walk_move = {
|
|
12311
|
+
firstframe: 0,
|
|
12312
|
+
lastframe: 0,
|
|
12313
|
+
frames: generic_walk_frames,
|
|
12314
|
+
endfunc: (self) => {
|
|
12315
|
+
self.monsterinfo.current_move = generic_walk_move;
|
|
12316
|
+
}
|
|
12317
|
+
};
|
|
12148
12318
|
var generic_run_frames = Array.from({ length: 1 }, () => ({
|
|
12149
12319
|
ai: generic_ai_run,
|
|
12150
12320
|
dist: 10
|
|
12151
12321
|
}));
|
|
12322
|
+
var generic_run_move = {
|
|
12323
|
+
firstframe: 0,
|
|
12324
|
+
lastframe: 0,
|
|
12325
|
+
frames: generic_run_frames,
|
|
12326
|
+
endfunc: (self) => {
|
|
12327
|
+
self.monsterinfo.current_move = generic_run_move;
|
|
12328
|
+
}
|
|
12329
|
+
};
|
|
12330
|
+
function createMonsterSpawn(config) {
|
|
12331
|
+
return function(self, context) {
|
|
12332
|
+
self.model = config.model;
|
|
12333
|
+
self.mins = config.mins || { x: -16, y: -16, z: -24 };
|
|
12334
|
+
self.maxs = config.maxs || { x: 16, y: 16, z: 32 };
|
|
12335
|
+
self.movetype = config.fly ? 5 /* Step */ : 5 /* Step */;
|
|
12336
|
+
self.solid = 2 /* BoundingBox */;
|
|
12337
|
+
self.health = config.health * context.health_multiplier;
|
|
12338
|
+
self.max_health = self.health;
|
|
12339
|
+
self.mass = config.mass;
|
|
12340
|
+
self.takedamage = true;
|
|
12341
|
+
self.pain = (self2, other, kick, damage) => {
|
|
12342
|
+
};
|
|
12343
|
+
self.die = (self2, inflictor, attacker, damage, point, mod = 0 /* UNKNOWN */) => {
|
|
12344
|
+
self2.deadflag = 2 /* Dead */;
|
|
12345
|
+
self2.solid = 0 /* Not */;
|
|
12346
|
+
if (self2.health < -40) {
|
|
12347
|
+
throwGibs(context.entities, self2.origin, damage, GIB_ORGANIC, mod);
|
|
12348
|
+
context.entities.free(self2);
|
|
12349
|
+
return;
|
|
12350
|
+
}
|
|
12351
|
+
self2.think = (self3) => {
|
|
12352
|
+
context.entities.free(self3);
|
|
12353
|
+
};
|
|
12354
|
+
self2.nextthink = context.entities.timeSeconds + 5;
|
|
12355
|
+
};
|
|
12356
|
+
self.monsterinfo.stand = (self2, context2) => {
|
|
12357
|
+
self2.monsterinfo.current_move = generic_stand_move;
|
|
12358
|
+
};
|
|
12359
|
+
self.monsterinfo.walk = (self2, context2) => {
|
|
12360
|
+
self2.monsterinfo.current_move = generic_walk_move;
|
|
12361
|
+
};
|
|
12362
|
+
self.monsterinfo.run = (self2, context2) => {
|
|
12363
|
+
self2.monsterinfo.current_move = generic_run_move;
|
|
12364
|
+
};
|
|
12365
|
+
self.monsterinfo.attack = (self2, context2) => {
|
|
12366
|
+
self2.monsterinfo.current_move = generic_run_move;
|
|
12367
|
+
};
|
|
12368
|
+
self.think = monster_think;
|
|
12369
|
+
self.monsterinfo.stand(self, context.entities);
|
|
12370
|
+
self.nextthink = self.timestamp + MONSTER_TICK2;
|
|
12371
|
+
};
|
|
12372
|
+
}
|
|
12152
12373
|
function M_SetAnimation(self, move, context) {
|
|
12153
12374
|
self.monsterinfo.current_move = move;
|
|
12154
12375
|
}
|
|
@@ -23873,6 +24094,39 @@ function registerShamblerSpawns(registry) {
|
|
|
23873
24094
|
registry.register("monster_shambler", SP_monster_shambler);
|
|
23874
24095
|
}
|
|
23875
24096
|
|
|
24097
|
+
// src/entities/monsters/rogue/common.ts
|
|
24098
|
+
var MAX_REINFORCEMENTS2 = 5;
|
|
24099
|
+
var INVERSE_LOG_SLOTS = Math.pow(2, MAX_REINFORCEMENTS2);
|
|
24100
|
+
function M_PickValidReinforcements(self, space, output) {
|
|
24101
|
+
output.length = 0;
|
|
24102
|
+
if (!self.monsterinfo.reinforcements) return;
|
|
24103
|
+
for (let i = 0; i < self.monsterinfo.reinforcements.length; i++) {
|
|
24104
|
+
if (self.monsterinfo.reinforcements[i].strength <= space) {
|
|
24105
|
+
output.push(i);
|
|
24106
|
+
}
|
|
24107
|
+
}
|
|
24108
|
+
}
|
|
24109
|
+
function M_PickReinforcements(self, rng, countRef, max_slots = 0) {
|
|
24110
|
+
const output = [];
|
|
24111
|
+
const chosen = new Array(MAX_REINFORCEMENTS2).fill(255);
|
|
24112
|
+
let num_chosen = 0;
|
|
24113
|
+
let num_slots = Math.max(1, Math.floor(Math.log2(rng.frandomRange(0, INVERSE_LOG_SLOTS))));
|
|
24114
|
+
let remaining = (self.monsterinfo.monster_slots || 0) - (self.monsterinfo.monster_used || 0);
|
|
24115
|
+
for (num_chosen = 0; num_chosen < num_slots; num_chosen++) {
|
|
24116
|
+
if (max_slots && num_chosen === max_slots || !remaining) {
|
|
24117
|
+
break;
|
|
24118
|
+
}
|
|
24119
|
+
M_PickValidReinforcements(self, remaining, output);
|
|
24120
|
+
if (output.length === 0) {
|
|
24121
|
+
break;
|
|
24122
|
+
}
|
|
24123
|
+
const randIndex = rng.irandomRange(0, output.length);
|
|
24124
|
+
chosen[num_chosen] = output[randIndex];
|
|
24125
|
+
remaining -= self.monsterinfo.reinforcements[chosen[num_chosen]].strength;
|
|
24126
|
+
}
|
|
24127
|
+
return { chosen, count: num_chosen };
|
|
24128
|
+
}
|
|
24129
|
+
|
|
23876
24130
|
// src/entities/monsters/rogue/widow.ts
|
|
23877
24131
|
var MODEL_SCALE3 = 1;
|
|
23878
24132
|
var RANGE_MELEE3 = 100;
|
|
@@ -23984,6 +24238,43 @@ function widow_kick(self, context) {
|
|
|
23984
24238
|
}
|
|
23985
24239
|
function widow_spawn_check(self, context) {
|
|
23986
24240
|
if (M_SlotsLeft(self) > 0) {
|
|
24241
|
+
const result = M_PickReinforcements(self, context.rng, 1);
|
|
24242
|
+
self.monsterinfo.chosen_reinforcements = result.chosen;
|
|
24243
|
+
if (result.count > 0) {
|
|
24244
|
+
const reinforcement = self.monsterinfo.reinforcements[self.monsterinfo.chosen_reinforcements[0]];
|
|
24245
|
+
WidowSpawn(self, context);
|
|
24246
|
+
}
|
|
24247
|
+
}
|
|
24248
|
+
}
|
|
24249
|
+
function WidowSpawn(self, context) {
|
|
24250
|
+
const { forward, right } = angleVectors(self.angles);
|
|
24251
|
+
const offset = { x: 50, y: 0, z: 0 };
|
|
24252
|
+
const start = M_ProjectFlashSource(self, offset, forward, right);
|
|
24253
|
+
if (!self.monsterinfo.chosen_reinforcements) {
|
|
24254
|
+
const result = M_PickReinforcements(self, context.rng, 1);
|
|
24255
|
+
self.monsterinfo.chosen_reinforcements = result.chosen;
|
|
24256
|
+
}
|
|
24257
|
+
if (self.monsterinfo.chosen_reinforcements && self.monsterinfo.chosen_reinforcements[0] !== 255) {
|
|
24258
|
+
const rIndex = self.monsterinfo.chosen_reinforcements[0];
|
|
24259
|
+
const reinforcement = self.monsterinfo.reinforcements[rIndex];
|
|
24260
|
+
const ent = context.spawn();
|
|
24261
|
+
ent.origin = { ...start };
|
|
24262
|
+
ent.angles = { ...self.angles };
|
|
24263
|
+
if (reinforcement.classname === "monster_stalker") {
|
|
24264
|
+
SP_monster_stalker(ent, { entities: context });
|
|
24265
|
+
} else if (reinforcement.classname === "monster_flyer") {
|
|
24266
|
+
SP_monster_flyer(ent, { entities: context });
|
|
24267
|
+
} else {
|
|
24268
|
+
createMonsterSpawn({
|
|
24269
|
+
model: "models/monsters/stalker/tris.md2",
|
|
24270
|
+
health: 100,
|
|
24271
|
+
mass: 100
|
|
24272
|
+
})(ent, { entities: context });
|
|
24273
|
+
}
|
|
24274
|
+
if (ent.inUse) {
|
|
24275
|
+
if (!self.monsterinfo.monster_used) self.monsterinfo.monster_used = 0;
|
|
24276
|
+
self.monsterinfo.monster_used += reinforcement.strength;
|
|
24277
|
+
}
|
|
23987
24278
|
}
|
|
23988
24279
|
}
|
|
23989
24280
|
var widow_frames_stand = Array(20).fill({ ai: widow_ai_stand, dist: 0 });
|
|
@@ -26172,6 +26463,9 @@ function player_think(self, sys) {
|
|
|
26172
26463
|
}
|
|
26173
26464
|
}
|
|
26174
26465
|
P_PlayerThink(self, sys);
|
|
26466
|
+
if (sys.deathmatch && (sys.configStringIndex ? sys.configStringIndex("pics/ctf_r.pcx") > 0 : true)) {
|
|
26467
|
+
updateCtfScoreboard(self, sys);
|
|
26468
|
+
}
|
|
26175
26469
|
self.nextthink = sys.timeSeconds + 0.1;
|
|
26176
26470
|
sys.scheduleThink(self, self.nextthink);
|
|
26177
26471
|
}
|
|
@@ -26239,6 +26533,16 @@ function populatePlayerStats(player, timeSeconds) {
|
|
|
26239
26533
|
const remainingSeconds = Math.ceil((bestTime - nowMs) / 1e3);
|
|
26240
26534
|
statArray[PlayerStat.STAT_TIMER] = remainingSeconds;
|
|
26241
26535
|
}
|
|
26536
|
+
if (player.client.score !== void 0) {
|
|
26537
|
+
statArray[PlayerStat.STAT_FRAGS] = player.client.score;
|
|
26538
|
+
}
|
|
26539
|
+
if (player.client.stats) {
|
|
26540
|
+
for (let i = 0; i < player.client.stats.length; i++) {
|
|
26541
|
+
if (player.client.stats[i] !== 0) {
|
|
26542
|
+
statArray[i] = player.client.stats[i];
|
|
26543
|
+
}
|
|
26544
|
+
}
|
|
26545
|
+
}
|
|
26242
26546
|
return statArray;
|
|
26243
26547
|
}
|
|
26244
26548
|
|