quake2ts 0.0.467 → 0.0.468
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 +16 -16
- package/packages/client/dist/browser/index.global.js.map +1 -1
- package/packages/client/dist/cjs/index.cjs +206 -3
- package/packages/client/dist/cjs/index.cjs.map +1 -1
- package/packages/client/dist/esm/index.js +205 -3
- package/packages/client/dist/esm/index.js.map +1 -1
- package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/client/dist/types/index.d.ts +13 -1
- package/packages/client/dist/types/index.d.ts.map +1 -1
- package/packages/client/dist/types/scoreboard.d.ts +31 -0
- package/packages/client/dist/types/scoreboard.d.ts.map +1 -0
- package/packages/client/dist/types/session.d.ts +15 -2
- package/packages/client/dist/types/session.d.ts.map +1 -1
|
@@ -14353,6 +14353,123 @@ var updateBlend = (state, ps, dt, damageIntensity = 0) => {
|
|
|
14353
14353
|
return [0, 0, 0, 0];
|
|
14354
14354
|
};
|
|
14355
14355
|
|
|
14356
|
+
// src/scoreboard.ts
|
|
14357
|
+
var ScoreboardManager = class {
|
|
14358
|
+
constructor(configStrings) {
|
|
14359
|
+
this.localPlayerId = -1;
|
|
14360
|
+
this.listeners = [];
|
|
14361
|
+
// Cache players to support stateful updates (e.g. scores)
|
|
14362
|
+
this.players = /* @__PURE__ */ new Map();
|
|
14363
|
+
this.configStrings = configStrings;
|
|
14364
|
+
this.refreshAll();
|
|
14365
|
+
}
|
|
14366
|
+
setLocalPlayerId(id) {
|
|
14367
|
+
this.localPlayerId = id;
|
|
14368
|
+
}
|
|
14369
|
+
addListener(listener) {
|
|
14370
|
+
this.listeners.push(listener);
|
|
14371
|
+
}
|
|
14372
|
+
removeListener(listener) {
|
|
14373
|
+
const index = this.listeners.indexOf(listener);
|
|
14374
|
+
if (index !== -1) {
|
|
14375
|
+
this.listeners.splice(index, 1);
|
|
14376
|
+
}
|
|
14377
|
+
}
|
|
14378
|
+
notifyUpdate() {
|
|
14379
|
+
const data = this.getScoreboard();
|
|
14380
|
+
for (const listener of this.listeners) {
|
|
14381
|
+
listener(data);
|
|
14382
|
+
}
|
|
14383
|
+
}
|
|
14384
|
+
refreshAll() {
|
|
14385
|
+
this.players.clear();
|
|
14386
|
+
for (let i = 0; i < MAX_CLIENTS2; i++) {
|
|
14387
|
+
const csIndex = ConfigStringIndex2.PlayerSkins + i;
|
|
14388
|
+
const str3 = this.configStrings.get(csIndex);
|
|
14389
|
+
if (str3 && str3.length > 0) {
|
|
14390
|
+
this.parseConfigString(csIndex, str3);
|
|
14391
|
+
}
|
|
14392
|
+
}
|
|
14393
|
+
}
|
|
14394
|
+
parseConfigString(index, str3) {
|
|
14395
|
+
if (index < ConfigStringIndex2.PlayerSkins || index >= ConfigStringIndex2.PlayerSkins + MAX_CLIENTS2) {
|
|
14396
|
+
return;
|
|
14397
|
+
}
|
|
14398
|
+
const id = index - ConfigStringIndex2.PlayerSkins;
|
|
14399
|
+
if (!str3 || str3.length === 0) {
|
|
14400
|
+
if (this.players.has(id)) {
|
|
14401
|
+
this.players.delete(id);
|
|
14402
|
+
}
|
|
14403
|
+
return;
|
|
14404
|
+
}
|
|
14405
|
+
const entry = this.parsePlayerConfigString(id, str3);
|
|
14406
|
+
if (entry) {
|
|
14407
|
+
const existing = this.players.get(id);
|
|
14408
|
+
if (existing) {
|
|
14409
|
+
entry.frags = existing.frags;
|
|
14410
|
+
entry.deaths = existing.deaths;
|
|
14411
|
+
entry.ping = existing.ping;
|
|
14412
|
+
}
|
|
14413
|
+
this.players.set(id, entry);
|
|
14414
|
+
}
|
|
14415
|
+
}
|
|
14416
|
+
getScoreboard() {
|
|
14417
|
+
const players = Array.from(this.players.values());
|
|
14418
|
+
players.sort((a, b) => b.frags - a.frags);
|
|
14419
|
+
const worldModel = this.configStrings.getModelName(1);
|
|
14420
|
+
let mapName = "unknown";
|
|
14421
|
+
if (worldModel) {
|
|
14422
|
+
const match = worldModel.match(/maps\/(.*)\.bsp/i);
|
|
14423
|
+
if (match) {
|
|
14424
|
+
mapName = match[1];
|
|
14425
|
+
} else {
|
|
14426
|
+
mapName = worldModel;
|
|
14427
|
+
}
|
|
14428
|
+
}
|
|
14429
|
+
return {
|
|
14430
|
+
players,
|
|
14431
|
+
mapName
|
|
14432
|
+
};
|
|
14433
|
+
}
|
|
14434
|
+
parsePlayerConfigString(id, str3) {
|
|
14435
|
+
const parts = str3.split("\\");
|
|
14436
|
+
const info = {};
|
|
14437
|
+
let startIndex = 0;
|
|
14438
|
+
if (parts.length > 0 && parts[0] === "") {
|
|
14439
|
+
startIndex = 1;
|
|
14440
|
+
}
|
|
14441
|
+
for (let i = startIndex; i < parts.length; i += 2) {
|
|
14442
|
+
if (i + 1 < parts.length) {
|
|
14443
|
+
const key = parts[i].toLowerCase();
|
|
14444
|
+
const value = parts[i + 1];
|
|
14445
|
+
info[key] = value;
|
|
14446
|
+
}
|
|
14447
|
+
}
|
|
14448
|
+
if (!info.name) {
|
|
14449
|
+
return null;
|
|
14450
|
+
}
|
|
14451
|
+
return {
|
|
14452
|
+
id,
|
|
14453
|
+
name: info.name,
|
|
14454
|
+
frags: 0,
|
|
14455
|
+
deaths: 0,
|
|
14456
|
+
ping: 0,
|
|
14457
|
+
skin: info.skin,
|
|
14458
|
+
model: info.model
|
|
14459
|
+
};
|
|
14460
|
+
}
|
|
14461
|
+
// Method to update scores explicitly
|
|
14462
|
+
updateScore(id, frags, deaths, ping) {
|
|
14463
|
+
const player = this.players.get(id);
|
|
14464
|
+
if (player) {
|
|
14465
|
+
player.frags = frags;
|
|
14466
|
+
player.deaths = deaths;
|
|
14467
|
+
player.ping = ping;
|
|
14468
|
+
this.notifyUpdate();
|
|
14469
|
+
}
|
|
14470
|
+
}
|
|
14471
|
+
};
|
|
14472
|
+
|
|
14356
14473
|
// src/input/bindings.ts
|
|
14357
14474
|
var DEFAULT_BINDINGS = [
|
|
14358
14475
|
{ code: "KeyW", command: "+forward" },
|
|
@@ -14883,6 +15000,7 @@ var GameSession = class {
|
|
|
14883
15000
|
this.currentMapName = "";
|
|
14884
15001
|
this.options = options;
|
|
14885
15002
|
this.engine = options.engine;
|
|
15003
|
+
this.inputController = new InputController();
|
|
14886
15004
|
}
|
|
14887
15005
|
startNewGame(mapName, skill = 1) {
|
|
14888
15006
|
if (this.host) {
|
|
@@ -14973,9 +15091,16 @@ var GameSession = class {
|
|
|
14973
15091
|
this.host = new EngineHost(this.game, clientProxy);
|
|
14974
15092
|
const clientImports = {
|
|
14975
15093
|
engine: this.engine,
|
|
14976
|
-
host: this.host
|
|
15094
|
+
host: this.host,
|
|
15095
|
+
inputController: this.inputController
|
|
14977
15096
|
};
|
|
14978
15097
|
this.client = createClient(clientImports);
|
|
15098
|
+
if (this._onInputCommand) {
|
|
15099
|
+
this.client.onInputCommand = this._onInputCommand;
|
|
15100
|
+
}
|
|
15101
|
+
if (this._onHudUpdate) {
|
|
15102
|
+
this.client.onHudUpdate = this._onHudUpdate;
|
|
15103
|
+
}
|
|
14979
15104
|
this.game.spawnWorld();
|
|
14980
15105
|
this.host.start();
|
|
14981
15106
|
if (this.engine.cmd) {
|
|
@@ -15069,9 +15194,16 @@ var GameSession = class {
|
|
|
15069
15194
|
this.host = new EngineHost(this.game, clientProxy);
|
|
15070
15195
|
const clientImports = {
|
|
15071
15196
|
engine: this.engine,
|
|
15072
|
-
host: this.host
|
|
15197
|
+
host: this.host,
|
|
15198
|
+
inputController: this.inputController
|
|
15073
15199
|
};
|
|
15074
15200
|
this.client = createClient(clientImports);
|
|
15201
|
+
if (this._onInputCommand) {
|
|
15202
|
+
this.client.onInputCommand = this._onInputCommand;
|
|
15203
|
+
}
|
|
15204
|
+
if (this._onHudUpdate) {
|
|
15205
|
+
this.client.onHudUpdate = this._onHudUpdate;
|
|
15206
|
+
}
|
|
15075
15207
|
if (this.engine.cmd) {
|
|
15076
15208
|
this.engine.cmd.executeText(`map ${mapName}`);
|
|
15077
15209
|
} else if (this.host.commands) {
|
|
@@ -15102,6 +15234,43 @@ var GameSession = class {
|
|
|
15102
15234
|
getHost() {
|
|
15103
15235
|
return this.host;
|
|
15104
15236
|
}
|
|
15237
|
+
bindInputSource(source) {
|
|
15238
|
+
this.inputController.bindInputSource(source);
|
|
15239
|
+
}
|
|
15240
|
+
setKeyBinding(action, keys) {
|
|
15241
|
+
this.inputController.setKeyBinding(action, keys);
|
|
15242
|
+
}
|
|
15243
|
+
getDefaultBindings() {
|
|
15244
|
+
return this.inputController.getDefaultBindings();
|
|
15245
|
+
}
|
|
15246
|
+
set onInputCommand(handler) {
|
|
15247
|
+
this._onInputCommand = handler;
|
|
15248
|
+
if (this.client) {
|
|
15249
|
+
this.client.onInputCommand = handler;
|
|
15250
|
+
}
|
|
15251
|
+
}
|
|
15252
|
+
get onInputCommand() {
|
|
15253
|
+
return this._onInputCommand;
|
|
15254
|
+
}
|
|
15255
|
+
// Section 4.2: HUD and UI Integration
|
|
15256
|
+
getHudData() {
|
|
15257
|
+
return this.client?.getHudData() ?? null;
|
|
15258
|
+
}
|
|
15259
|
+
getStatusBar() {
|
|
15260
|
+
return this.client?.getStatusBar() ?? null;
|
|
15261
|
+
}
|
|
15262
|
+
getCrosshairInfo() {
|
|
15263
|
+
return this.client?.getCrosshairInfo() ?? null;
|
|
15264
|
+
}
|
|
15265
|
+
set onHudUpdate(handler) {
|
|
15266
|
+
this._onHudUpdate = handler;
|
|
15267
|
+
if (this.client) {
|
|
15268
|
+
this.client.onHudUpdate = handler;
|
|
15269
|
+
}
|
|
15270
|
+
}
|
|
15271
|
+
get onHudUpdate() {
|
|
15272
|
+
return this._onHudUpdate;
|
|
15273
|
+
}
|
|
15105
15274
|
// Section 4.1.3: Game State Queries
|
|
15106
15275
|
getPlayerState() {
|
|
15107
15276
|
if (this.client && this.client.lastRendered) {
|
|
@@ -15204,6 +15373,12 @@ function createClient(imports) {
|
|
|
15204
15373
|
freeCameraAngles: { x: 0, y: 0, z: 0 },
|
|
15205
15374
|
followEntityId: -1
|
|
15206
15375
|
};
|
|
15376
|
+
const inputController = imports.inputController ?? new InputController();
|
|
15377
|
+
inputController.onInputCommand = (cmd) => {
|
|
15378
|
+
if (clientExports.onInputCommand) {
|
|
15379
|
+
clientExports.onInputCommand(cmd);
|
|
15380
|
+
}
|
|
15381
|
+
};
|
|
15207
15382
|
const inputState = {
|
|
15208
15383
|
forward: false,
|
|
15209
15384
|
backward: false,
|
|
@@ -15220,6 +15395,7 @@ function createClient(imports) {
|
|
|
15220
15395
|
let pauseMenuFactory;
|
|
15221
15396
|
let optionsFactory;
|
|
15222
15397
|
const configStrings = new ClientConfigStrings();
|
|
15398
|
+
const scoreboardManager = new ScoreboardManager(configStrings);
|
|
15223
15399
|
const blendState = createBlendState();
|
|
15224
15400
|
let currentBlend = [0, 0, 0, 0];
|
|
15225
15401
|
let pendingDamage = 0;
|
|
@@ -15274,6 +15450,10 @@ function createClient(imports) {
|
|
|
15274
15450
|
onConfigString: (index, str3) => {
|
|
15275
15451
|
configStrings.set(index, str3);
|
|
15276
15452
|
cg.ParseConfigString(index, str3);
|
|
15453
|
+
if (index >= ConfigStringIndex2.PlayerSkins && index < ConfigStringIndex2.PlayerSkins + MAX_CLIENTS2) {
|
|
15454
|
+
scoreboardManager.parseConfigString(index, str3);
|
|
15455
|
+
scoreboardManager.notifyUpdate();
|
|
15456
|
+
}
|
|
15277
15457
|
},
|
|
15278
15458
|
onServerData: (protocol, tickRate) => {
|
|
15279
15459
|
if (tickRate && tickRate > 0) {
|
|
@@ -15509,6 +15689,15 @@ function createClient(imports) {
|
|
|
15509
15689
|
menuSystem.pushMenu(pauseMenuFactory.createPauseMenu());
|
|
15510
15690
|
}
|
|
15511
15691
|
},
|
|
15692
|
+
bindInputSource(source) {
|
|
15693
|
+
inputController.bindInputSource(source);
|
|
15694
|
+
},
|
|
15695
|
+
setKeyBinding(action, keys) {
|
|
15696
|
+
inputController.setKeyBinding(action, keys);
|
|
15697
|
+
},
|
|
15698
|
+
getDefaultBindings() {
|
|
15699
|
+
return inputController.getDefaultBindings();
|
|
15700
|
+
},
|
|
15512
15701
|
createMainMenu(options, storage, saveCallback, loadCallback, deleteCallback) {
|
|
15513
15702
|
const saveLoadFactory = new SaveLoadMenuFactory(menuSystem, storage, saveCallback, loadCallback, deleteCallback);
|
|
15514
15703
|
let optsFactory = optionsFactory;
|
|
@@ -15676,7 +15865,10 @@ function createClient(imports) {
|
|
|
15676
15865
|
} else {
|
|
15677
15866
|
currentBlend = [0, 0, 0, 0];
|
|
15678
15867
|
}
|
|
15679
|
-
const command =
|
|
15868
|
+
const command = inputController.buildCommand(dtMs, now, demoHandler.latestServerFrame);
|
|
15869
|
+
if (!isDemoPlaying && !menuSystem.isActive()) {
|
|
15870
|
+
clientExports.predict(command);
|
|
15871
|
+
}
|
|
15680
15872
|
const timeSeconds = sample.nowMs / 1e3;
|
|
15681
15873
|
dlightManager.update(timeSeconds, dtMs / 1e3);
|
|
15682
15874
|
const dlights = [...dlightManager.getActiveLights()];
|
|
@@ -15977,8 +16169,17 @@ function createClient(imports) {
|
|
|
15977
16169
|
},
|
|
15978
16170
|
setDemoFollowEntity(entityId) {
|
|
15979
16171
|
demoCameraState.followEntityId = entityId;
|
|
16172
|
+
},
|
|
16173
|
+
// Scoreboard API
|
|
16174
|
+
getScoreboard() {
|
|
16175
|
+
return scoreboardManager.getScoreboard();
|
|
15980
16176
|
}
|
|
15981
16177
|
};
|
|
16178
|
+
scoreboardManager.addListener((data) => {
|
|
16179
|
+
if (clientExports.onScoreboardUpdate) {
|
|
16180
|
+
clientExports.onScoreboardUpdate(data);
|
|
16181
|
+
}
|
|
16182
|
+
});
|
|
15982
16183
|
return clientExports;
|
|
15983
16184
|
}
|
|
15984
16185
|
export {
|
|
@@ -15991,6 +16192,7 @@ export {
|
|
|
15991
16192
|
InputBindings,
|
|
15992
16193
|
InputCommandBuffer,
|
|
15993
16194
|
InputController,
|
|
16195
|
+
ScoreboardManager,
|
|
15994
16196
|
ViewEffects3 as ViewEffects,
|
|
15995
16197
|
createClient,
|
|
15996
16198
|
createDefaultBindings,
|