quake2ts 0.0.402 → 0.0.405
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 +383 -11
- package/packages/client/dist/cjs/index.cjs.map +1 -1
- package/packages/client/dist/esm/index.js +382 -11
- package/packages/client/dist/esm/index.js.map +1 -1
- package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/client/dist/types/demo/camera.d.ts +16 -0
- package/packages/client/dist/types/demo/camera.d.ts.map +1 -0
- package/packages/client/dist/types/index.d.ts +7 -1
- package/packages/client/dist/types/index.d.ts.map +1 -1
- package/packages/engine/dist/browser/index.global.js +16 -16
- package/packages/engine/dist/browser/index.global.js.map +1 -1
- package/packages/engine/dist/cjs/index.cjs +274 -2
- package/packages/engine/dist/cjs/index.cjs.map +1 -1
- package/packages/engine/dist/esm/index.js +274 -2
- package/packages/engine/dist/esm/index.js.map +1 -1
- package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/engine/dist/types/commands.d.ts +3 -0
- package/packages/engine/dist/types/commands.d.ts.map +1 -1
- package/packages/engine/dist/types/cvars.d.ts +11 -0
- package/packages/engine/dist/types/cvars.d.ts.map +1 -1
- package/packages/engine/dist/types/demo/analysis.d.ts +33 -0
- package/packages/engine/dist/types/demo/analysis.d.ts.map +1 -1
- package/packages/engine/dist/types/demo/analyzer.d.ts +28 -0
- package/packages/engine/dist/types/demo/analyzer.d.ts.map +1 -0
- package/packages/engine/dist/types/demo/playback.d.ts +16 -1
- package/packages/engine/dist/types/demo/playback.d.ts.map +1 -1
- package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
|
@@ -23,6 +23,7 @@ __export(index_exports, {
|
|
|
23
23
|
ClientConfigStrings: () => ClientConfigStrings,
|
|
24
24
|
ClientMode: () => ClientMode,
|
|
25
25
|
ClientPrediction: () => import_cgame5.ClientPrediction,
|
|
26
|
+
DemoCameraMode: () => DemoCameraMode,
|
|
26
27
|
GameSession: () => GameSession,
|
|
27
28
|
InputAction: () => InputAction,
|
|
28
29
|
InputBindings: () => InputBindings,
|
|
@@ -1855,6 +1856,9 @@ var CommandRegistry = class {
|
|
|
1855
1856
|
this.commands.set(name, command);
|
|
1856
1857
|
return command;
|
|
1857
1858
|
}
|
|
1859
|
+
registerCommand(name, callback) {
|
|
1860
|
+
this.register(name, callback);
|
|
1861
|
+
}
|
|
1858
1862
|
get(name) {
|
|
1859
1863
|
return this.commands.get(name);
|
|
1860
1864
|
}
|
|
@@ -1870,10 +1874,33 @@ var CommandRegistry = class {
|
|
|
1870
1874
|
command.execute(args);
|
|
1871
1875
|
return true;
|
|
1872
1876
|
}
|
|
1877
|
+
this.onConsoleOutput?.(`Unknown command "${name}"`);
|
|
1873
1878
|
return false;
|
|
1874
1879
|
}
|
|
1880
|
+
executeCommand(cmd) {
|
|
1881
|
+
this.execute(cmd);
|
|
1882
|
+
}
|
|
1875
1883
|
tokenize(text) {
|
|
1876
|
-
|
|
1884
|
+
const args = [];
|
|
1885
|
+
let currentArg = "";
|
|
1886
|
+
let inQuote = false;
|
|
1887
|
+
for (let i = 0; i < text.length; i++) {
|
|
1888
|
+
const char = text[i];
|
|
1889
|
+
if (char === '"') {
|
|
1890
|
+
inQuote = !inQuote;
|
|
1891
|
+
} else if (char === " " && !inQuote) {
|
|
1892
|
+
if (currentArg.length > 0) {
|
|
1893
|
+
args.push(currentArg);
|
|
1894
|
+
currentArg = "";
|
|
1895
|
+
}
|
|
1896
|
+
} else {
|
|
1897
|
+
currentArg += char;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
if (currentArg.length > 0) {
|
|
1901
|
+
args.push(currentArg);
|
|
1902
|
+
}
|
|
1903
|
+
return args;
|
|
1877
1904
|
}
|
|
1878
1905
|
list() {
|
|
1879
1906
|
return [...this.commands.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -2958,13 +2985,21 @@ var CvarRegistry = class {
|
|
|
2958
2985
|
if (existing) {
|
|
2959
2986
|
return existing;
|
|
2960
2987
|
}
|
|
2961
|
-
const
|
|
2988
|
+
const originalOnChange = def.onChange;
|
|
2989
|
+
const wrappedOnChange = (cvar2, prev) => {
|
|
2990
|
+
originalOnChange?.(cvar2, prev);
|
|
2991
|
+
this.onCvarChange?.(cvar2.name, cvar2.string);
|
|
2992
|
+
};
|
|
2993
|
+
const cvar = new Cvar({ ...def, onChange: wrappedOnChange });
|
|
2962
2994
|
this.cvars.set(def.name, cvar);
|
|
2963
2995
|
return cvar;
|
|
2964
2996
|
}
|
|
2965
2997
|
get(name) {
|
|
2966
2998
|
return this.cvars.get(name);
|
|
2967
2999
|
}
|
|
3000
|
+
getCvar(name) {
|
|
3001
|
+
return this.get(name);
|
|
3002
|
+
}
|
|
2968
3003
|
setValue(name, value) {
|
|
2969
3004
|
const cvar = this.get(name);
|
|
2970
3005
|
if (!cvar) {
|
|
@@ -2973,6 +3008,9 @@ var CvarRegistry = class {
|
|
|
2973
3008
|
cvar.set(value);
|
|
2974
3009
|
return cvar;
|
|
2975
3010
|
}
|
|
3011
|
+
setCvar(name, value) {
|
|
3012
|
+
this.setValue(name, value);
|
|
3013
|
+
}
|
|
2976
3014
|
resetAll() {
|
|
2977
3015
|
for (const cvar of this.cvars.values()) {
|
|
2978
3016
|
cvar.reset();
|
|
@@ -2988,6 +3026,15 @@ var CvarRegistry = class {
|
|
|
2988
3026
|
list() {
|
|
2989
3027
|
return [...this.cvars.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
2990
3028
|
}
|
|
3029
|
+
listCvars() {
|
|
3030
|
+
return this.list().map((cvar) => ({
|
|
3031
|
+
name: cvar.name,
|
|
3032
|
+
value: cvar.string,
|
|
3033
|
+
defaultValue: cvar.defaultValue,
|
|
3034
|
+
flags: cvar.flags,
|
|
3035
|
+
description: cvar.description
|
|
3036
|
+
}));
|
|
3037
|
+
}
|
|
2991
3038
|
};
|
|
2992
3039
|
var EngineHost = class {
|
|
2993
3040
|
constructor(game, client, options = {}) {
|
|
@@ -8796,6 +8843,162 @@ var NetworkMessageParser = class _NetworkMessageParser {
|
|
|
8796
8843
|
}
|
|
8797
8844
|
}
|
|
8798
8845
|
};
|
|
8846
|
+
var DemoAnalyzer = class {
|
|
8847
|
+
constructor(buffer) {
|
|
8848
|
+
this.events = [];
|
|
8849
|
+
this.summary = {
|
|
8850
|
+
totalKills: 0,
|
|
8851
|
+
totalDeaths: 0,
|
|
8852
|
+
damageDealt: 0,
|
|
8853
|
+
damageReceived: 0,
|
|
8854
|
+
weaponUsage: /* @__PURE__ */ new Map()
|
|
8855
|
+
};
|
|
8856
|
+
this.header = null;
|
|
8857
|
+
this.configStrings = /* @__PURE__ */ new Map();
|
|
8858
|
+
this.serverInfo = {};
|
|
8859
|
+
this.statistics = null;
|
|
8860
|
+
this.playerStats = /* @__PURE__ */ new Map();
|
|
8861
|
+
this.weaponStats = /* @__PURE__ */ new Map();
|
|
8862
|
+
this.buffer = buffer;
|
|
8863
|
+
}
|
|
8864
|
+
analyze() {
|
|
8865
|
+
const reader = new DemoReader(this.buffer);
|
|
8866
|
+
let currentFrameIndex = -1;
|
|
8867
|
+
let currentTime = 0;
|
|
8868
|
+
let frameDuration = 0.1;
|
|
8869
|
+
let protocolVersion = 0;
|
|
8870
|
+
const handler = {
|
|
8871
|
+
onServerData: (protocol, serverCount, attractLoop, gameDir, playerNum, levelName, tickRate, demoType) => {
|
|
8872
|
+
protocolVersion = protocol;
|
|
8873
|
+
this.header = {
|
|
8874
|
+
protocolVersion: protocol,
|
|
8875
|
+
gameDir,
|
|
8876
|
+
levelName,
|
|
8877
|
+
playerNum,
|
|
8878
|
+
serverCount,
|
|
8879
|
+
spawnCount: serverCount,
|
|
8880
|
+
// Mapping generic arg
|
|
8881
|
+
tickRate,
|
|
8882
|
+
demoType
|
|
8883
|
+
};
|
|
8884
|
+
if (tickRate && tickRate > 0) {
|
|
8885
|
+
frameDuration = 1 / tickRate;
|
|
8886
|
+
}
|
|
8887
|
+
},
|
|
8888
|
+
onConfigString: (index, str3) => {
|
|
8889
|
+
this.configStrings.set(index, str3);
|
|
8890
|
+
if (index === 0) {
|
|
8891
|
+
this.parseServerInfo(str3);
|
|
8892
|
+
}
|
|
8893
|
+
},
|
|
8894
|
+
onSpawnBaseline: (entity) => {
|
|
8895
|
+
},
|
|
8896
|
+
onFrame: (frame) => {
|
|
8897
|
+
},
|
|
8898
|
+
onPrint: (level, msg) => {
|
|
8899
|
+
if (msg.includes("died") || msg.includes("killed")) {
|
|
8900
|
+
this.summary.totalDeaths++;
|
|
8901
|
+
this.recordEvent({
|
|
8902
|
+
type: 4,
|
|
8903
|
+
frame: currentFrameIndex,
|
|
8904
|
+
time: currentTime,
|
|
8905
|
+
description: msg.trim()
|
|
8906
|
+
});
|
|
8907
|
+
}
|
|
8908
|
+
},
|
|
8909
|
+
onCenterPrint: () => {
|
|
8910
|
+
},
|
|
8911
|
+
onStuffText: () => {
|
|
8912
|
+
},
|
|
8913
|
+
onSound: () => {
|
|
8914
|
+
},
|
|
8915
|
+
onTempEntity: () => {
|
|
8916
|
+
},
|
|
8917
|
+
onLayout: () => {
|
|
8918
|
+
},
|
|
8919
|
+
onInventory: () => {
|
|
8920
|
+
},
|
|
8921
|
+
onMuzzleFlash: (ent, weapon) => {
|
|
8922
|
+
this.handleWeaponFire(ent, weapon, currentFrameIndex, currentTime);
|
|
8923
|
+
},
|
|
8924
|
+
onMuzzleFlash2: (ent, weapon) => {
|
|
8925
|
+
this.handleWeaponFire(ent, weapon, currentFrameIndex, currentTime);
|
|
8926
|
+
},
|
|
8927
|
+
onMuzzleFlash3: (ent, weapon) => {
|
|
8928
|
+
this.handleWeaponFire(ent, weapon, currentFrameIndex, currentTime);
|
|
8929
|
+
},
|
|
8930
|
+
onDisconnect: () => {
|
|
8931
|
+
},
|
|
8932
|
+
onReconnect: () => {
|
|
8933
|
+
},
|
|
8934
|
+
onDownload: () => {
|
|
8935
|
+
},
|
|
8936
|
+
// Rerelease specific
|
|
8937
|
+
onDamage: (indicators) => {
|
|
8938
|
+
for (const ind of indicators) {
|
|
8939
|
+
this.recordEvent({
|
|
8940
|
+
type: 2,
|
|
8941
|
+
frame: currentFrameIndex,
|
|
8942
|
+
time: currentTime,
|
|
8943
|
+
value: ind.damage,
|
|
8944
|
+
position: ind.dir,
|
|
8945
|
+
description: `Took ${ind.damage} damage`
|
|
8946
|
+
});
|
|
8947
|
+
this.summary.damageReceived += ind.damage;
|
|
8948
|
+
}
|
|
8949
|
+
}
|
|
8950
|
+
};
|
|
8951
|
+
while (reader.hasMore()) {
|
|
8952
|
+
const block = reader.readNextBlock();
|
|
8953
|
+
if (!block) break;
|
|
8954
|
+
currentFrameIndex++;
|
|
8955
|
+
currentTime = currentFrameIndex * frameDuration;
|
|
8956
|
+
const parser = new NetworkMessageParser(block.data, handler);
|
|
8957
|
+
parser.setProtocolVersion(protocolVersion);
|
|
8958
|
+
parser.parseMessage();
|
|
8959
|
+
protocolVersion = parser.getProtocolVersion();
|
|
8960
|
+
}
|
|
8961
|
+
this.statistics = {
|
|
8962
|
+
duration: currentTime,
|
|
8963
|
+
frameCount: currentFrameIndex + 1,
|
|
8964
|
+
averageFps: (currentFrameIndex + 1) / (currentTime || 1),
|
|
8965
|
+
mapName: this.header?.levelName || "unknown",
|
|
8966
|
+
playerCount: 1
|
|
8967
|
+
// Default to 1 for SP/client demo
|
|
8968
|
+
};
|
|
8969
|
+
return {
|
|
8970
|
+
events: this.events,
|
|
8971
|
+
summary: this.summary,
|
|
8972
|
+
header: this.header,
|
|
8973
|
+
configStrings: this.configStrings,
|
|
8974
|
+
serverInfo: this.serverInfo,
|
|
8975
|
+
statistics: this.statistics
|
|
8976
|
+
};
|
|
8977
|
+
}
|
|
8978
|
+
handleWeaponFire(ent, weapon, frame, time) {
|
|
8979
|
+
this.recordEvent({
|
|
8980
|
+
type: 0,
|
|
8981
|
+
frame,
|
|
8982
|
+
time,
|
|
8983
|
+
entityId: ent,
|
|
8984
|
+
value: weapon,
|
|
8985
|
+
description: `Weapon ${weapon} fired by ${ent}`
|
|
8986
|
+
});
|
|
8987
|
+
const count = this.summary.weaponUsage.get(weapon) || 0;
|
|
8988
|
+
this.summary.weaponUsage.set(weapon, count + 1);
|
|
8989
|
+
}
|
|
8990
|
+
recordEvent(event) {
|
|
8991
|
+
this.events.push(event);
|
|
8992
|
+
}
|
|
8993
|
+
parseServerInfo(str3) {
|
|
8994
|
+
const parts = str3.split("\\");
|
|
8995
|
+
for (let i = 1; i < parts.length; i += 2) {
|
|
8996
|
+
if (i + 1 < parts.length) {
|
|
8997
|
+
this.serverInfo[parts[i]] = parts[i + 1];
|
|
8998
|
+
}
|
|
8999
|
+
}
|
|
9000
|
+
}
|
|
9001
|
+
};
|
|
8799
9002
|
var PlaybackState = /* @__PURE__ */ ((PlaybackState22) => {
|
|
8800
9003
|
PlaybackState22[PlaybackState22["Stopped"] = 0] = "Stopped";
|
|
8801
9004
|
PlaybackState22[PlaybackState22["Playing"] = 1] = "Playing";
|
|
@@ -8806,6 +9009,7 @@ var PlaybackState = /* @__PURE__ */ ((PlaybackState22) => {
|
|
|
8806
9009
|
var DemoPlaybackController = class {
|
|
8807
9010
|
constructor() {
|
|
8808
9011
|
this.reader = null;
|
|
9012
|
+
this.buffer = null;
|
|
8809
9013
|
this.state = 0;
|
|
8810
9014
|
this.playbackSpeed = 1;
|
|
8811
9015
|
this.currentProtocolVersion = 0;
|
|
@@ -8815,6 +9019,12 @@ var DemoPlaybackController = class {
|
|
|
8815
9019
|
this.frameDuration = 100;
|
|
8816
9020
|
this.snapshotInterval = 100;
|
|
8817
9021
|
this.snapshots = /* @__PURE__ */ new Map();
|
|
9022
|
+
this.cachedEvents = null;
|
|
9023
|
+
this.cachedSummary = null;
|
|
9024
|
+
this.cachedHeader = null;
|
|
9025
|
+
this.cachedConfigStrings = null;
|
|
9026
|
+
this.cachedServerInfo = null;
|
|
9027
|
+
this.cachedStatistics = null;
|
|
8818
9028
|
}
|
|
8819
9029
|
setHandler(handler) {
|
|
8820
9030
|
this.handler = handler;
|
|
@@ -8823,6 +9033,7 @@ var DemoPlaybackController = class {
|
|
|
8823
9033
|
this.callbacks = callbacks;
|
|
8824
9034
|
}
|
|
8825
9035
|
loadDemo(buffer) {
|
|
9036
|
+
this.buffer = buffer;
|
|
8826
9037
|
this.reader = new DemoReader(buffer);
|
|
8827
9038
|
this.transitionState(
|
|
8828
9039
|
0
|
|
@@ -8833,6 +9044,12 @@ var DemoPlaybackController = class {
|
|
|
8833
9044
|
this.currentFrameIndex = -1;
|
|
8834
9045
|
this.snapshots.clear();
|
|
8835
9046
|
this.lastFrameData = null;
|
|
9047
|
+
this.cachedEvents = null;
|
|
9048
|
+
this.cachedSummary = null;
|
|
9049
|
+
this.cachedHeader = null;
|
|
9050
|
+
this.cachedConfigStrings = null;
|
|
9051
|
+
this.cachedServerInfo = null;
|
|
9052
|
+
this.cachedStatistics = null;
|
|
8836
9053
|
}
|
|
8837
9054
|
play() {
|
|
8838
9055
|
if (this.reader && this.state !== 1) {
|
|
@@ -9160,6 +9377,57 @@ var DemoPlaybackController = class {
|
|
|
9160
9377
|
this.seek(originalFrame);
|
|
9161
9378
|
return trajectory;
|
|
9162
9379
|
}
|
|
9380
|
+
// 3.2.3 Event Log Extraction & 3.3 Metadata
|
|
9381
|
+
getDemoEvents() {
|
|
9382
|
+
this.ensureAnalysis();
|
|
9383
|
+
return this.cachedEvents || [];
|
|
9384
|
+
}
|
|
9385
|
+
filterEvents(type, entityId) {
|
|
9386
|
+
const events = this.getDemoEvents();
|
|
9387
|
+
return events.filter((e) => {
|
|
9388
|
+
if (e.type !== type) return false;
|
|
9389
|
+
if (entityId !== void 0 && e.entityId !== entityId) return false;
|
|
9390
|
+
return true;
|
|
9391
|
+
});
|
|
9392
|
+
}
|
|
9393
|
+
getEventSummary() {
|
|
9394
|
+
this.ensureAnalysis();
|
|
9395
|
+
return this.cachedSummary || {
|
|
9396
|
+
totalKills: 0,
|
|
9397
|
+
totalDeaths: 0,
|
|
9398
|
+
damageDealt: 0,
|
|
9399
|
+
damageReceived: 0,
|
|
9400
|
+
weaponUsage: /* @__PURE__ */ new Map()
|
|
9401
|
+
};
|
|
9402
|
+
}
|
|
9403
|
+
getDemoHeader() {
|
|
9404
|
+
this.ensureAnalysis();
|
|
9405
|
+
return this.cachedHeader;
|
|
9406
|
+
}
|
|
9407
|
+
getDemoConfigStrings() {
|
|
9408
|
+
this.ensureAnalysis();
|
|
9409
|
+
return this.cachedConfigStrings || /* @__PURE__ */ new Map();
|
|
9410
|
+
}
|
|
9411
|
+
getDemoServerInfo() {
|
|
9412
|
+
this.ensureAnalysis();
|
|
9413
|
+
return this.cachedServerInfo || {};
|
|
9414
|
+
}
|
|
9415
|
+
getDemoStatistics() {
|
|
9416
|
+
this.ensureAnalysis();
|
|
9417
|
+
return this.cachedStatistics;
|
|
9418
|
+
}
|
|
9419
|
+
ensureAnalysis() {
|
|
9420
|
+
if (!this.cachedEvents && this.buffer) {
|
|
9421
|
+
const analyzer = new DemoAnalyzer(this.buffer);
|
|
9422
|
+
const result = analyzer.analyze();
|
|
9423
|
+
this.cachedEvents = result.events;
|
|
9424
|
+
this.cachedSummary = result.summary;
|
|
9425
|
+
this.cachedHeader = result.header;
|
|
9426
|
+
this.cachedConfigStrings = result.configStrings;
|
|
9427
|
+
this.cachedServerInfo = result.serverInfo;
|
|
9428
|
+
this.cachedStatistics = result.statistics;
|
|
9429
|
+
}
|
|
9430
|
+
}
|
|
9163
9431
|
};
|
|
9164
9432
|
var DemoRecorder = class {
|
|
9165
9433
|
// -1 means start of demo
|
|
@@ -9239,12 +9507,56 @@ var __export3 = (target, all) => {
|
|
|
9239
9507
|
};
|
|
9240
9508
|
var ZERO_VEC3 = { x: 0, y: 0, z: 0 };
|
|
9241
9509
|
var DEG_TO_RAD2 = Math.PI / 180;
|
|
9510
|
+
var PITCH = 0;
|
|
9511
|
+
var YAW = 1;
|
|
9512
|
+
var ROLL = 2;
|
|
9242
9513
|
var DEG2RAD_FACTOR2 = Math.PI / 180;
|
|
9243
9514
|
var RAD2DEG_FACTOR2 = 180 / Math.PI;
|
|
9515
|
+
function axisComponent(vec, axis) {
|
|
9516
|
+
switch (axis) {
|
|
9517
|
+
case PITCH:
|
|
9518
|
+
return vec.x;
|
|
9519
|
+
case YAW:
|
|
9520
|
+
return vec.y;
|
|
9521
|
+
case ROLL:
|
|
9522
|
+
default:
|
|
9523
|
+
return vec.z;
|
|
9524
|
+
}
|
|
9525
|
+
}
|
|
9526
|
+
function degToRad(degrees) {
|
|
9527
|
+
return degrees * DEG2RAD_FACTOR2;
|
|
9528
|
+
}
|
|
9244
9529
|
function angleMod(angle2) {
|
|
9245
9530
|
const value = angle2 % 360;
|
|
9246
9531
|
return value < 0 ? 360 + value : value;
|
|
9247
9532
|
}
|
|
9533
|
+
function angleVectors(angles) {
|
|
9534
|
+
const yaw = degToRad(axisComponent(angles, YAW));
|
|
9535
|
+
const pitch = degToRad(axisComponent(angles, PITCH));
|
|
9536
|
+
const roll = degToRad(axisComponent(angles, ROLL));
|
|
9537
|
+
const sy = Math.sin(yaw);
|
|
9538
|
+
const cy = Math.cos(yaw);
|
|
9539
|
+
const sp = Math.sin(pitch);
|
|
9540
|
+
const cp = Math.cos(pitch);
|
|
9541
|
+
const sr = Math.sin(roll);
|
|
9542
|
+
const cr = Math.cos(roll);
|
|
9543
|
+
const forward = {
|
|
9544
|
+
x: cp * cy,
|
|
9545
|
+
y: cp * sy,
|
|
9546
|
+
z: -sp
|
|
9547
|
+
};
|
|
9548
|
+
const right = {
|
|
9549
|
+
x: -sr * sp * cy - cr * -sy,
|
|
9550
|
+
y: -sr * sp * sy - cr * cy,
|
|
9551
|
+
z: -sr * cp
|
|
9552
|
+
};
|
|
9553
|
+
const up = {
|
|
9554
|
+
x: cr * sp * cy - sr * -sy,
|
|
9555
|
+
y: cr * sp * sy - sr * cy,
|
|
9556
|
+
z: cr * cp
|
|
9557
|
+
};
|
|
9558
|
+
return { forward, right, up };
|
|
9559
|
+
}
|
|
9248
9560
|
var ANORMS2 = [
|
|
9249
9561
|
[-0.525731, 0, 0.850651],
|
|
9250
9562
|
[-0.442863, 0.238856, 0.864188],
|
|
@@ -13230,6 +13542,15 @@ var DemoControls = class {
|
|
|
13230
13542
|
}
|
|
13231
13543
|
};
|
|
13232
13544
|
|
|
13545
|
+
// src/demo/camera.ts
|
|
13546
|
+
var DemoCameraMode = /* @__PURE__ */ ((DemoCameraMode2) => {
|
|
13547
|
+
DemoCameraMode2[DemoCameraMode2["FirstPerson"] = 0] = "FirstPerson";
|
|
13548
|
+
DemoCameraMode2[DemoCameraMode2["ThirdPerson"] = 1] = "ThirdPerson";
|
|
13549
|
+
DemoCameraMode2[DemoCameraMode2["Free"] = 2] = "Free";
|
|
13550
|
+
DemoCameraMode2[DemoCameraMode2["Follow"] = 3] = "Follow";
|
|
13551
|
+
return DemoCameraMode2;
|
|
13552
|
+
})(DemoCameraMode || {});
|
|
13553
|
+
|
|
13233
13554
|
// src/effects.ts
|
|
13234
13555
|
function addDLight(dlights, origin, color, intensity, minLight = 0, die = 0) {
|
|
13235
13556
|
dlights.push({
|
|
@@ -13924,6 +14245,14 @@ function createClient(imports) {
|
|
|
13924
14245
|
let isDemoPlaying = false;
|
|
13925
14246
|
let currentDemoName = null;
|
|
13926
14247
|
let clientMode = 0 /* Normal */;
|
|
14248
|
+
const demoCameraState = {
|
|
14249
|
+
mode: 0 /* FirstPerson */,
|
|
14250
|
+
thirdPersonDistance: 80,
|
|
14251
|
+
thirdPersonOffset: { x: 0, y: 0, z: 0 },
|
|
14252
|
+
freeCameraOrigin: { x: 0, y: 0, z: 0 },
|
|
14253
|
+
freeCameraAngles: { x: 0, y: 0, z: 0 },
|
|
14254
|
+
followEntityId: -1
|
|
14255
|
+
};
|
|
13927
14256
|
const menuSystem = new MenuSystem();
|
|
13928
14257
|
const loadingScreen = new LoadingScreen();
|
|
13929
14258
|
const errorDialog = new ErrorDialog();
|
|
@@ -14138,6 +14467,8 @@ function createClient(imports) {
|
|
|
14138
14467
|
},
|
|
14139
14468
|
handleInput(key, down) {
|
|
14140
14469
|
if (isDemoPlaying) {
|
|
14470
|
+
if (demoCameraState.mode === 2 /* Free */) {
|
|
14471
|
+
}
|
|
14141
14472
|
if (demoControls.handleInput(key, down)) {
|
|
14142
14473
|
return true;
|
|
14143
14474
|
}
|
|
@@ -14223,18 +14554,42 @@ function createClient(imports) {
|
|
|
14223
14554
|
lastRenderTime = now;
|
|
14224
14555
|
demoPlayback.update(dt);
|
|
14225
14556
|
lastRendered = demoHandler.getPredictionState(demoPlayback.getCurrentTime());
|
|
14226
|
-
const frameDuration = 100;
|
|
14227
14557
|
renderEntities = demoHandler.getRenderableEntities(1, configStrings);
|
|
14228
14558
|
if (demoHandler.latestFrame && demoHandler.latestFrame.packetEntities) {
|
|
14229
14559
|
currentPacketEntities = demoHandler.latestFrame.packetEntities.entities;
|
|
14230
14560
|
}
|
|
14231
14561
|
if (lastRendered) {
|
|
14232
14562
|
const demoCamera = demoHandler.getDemoCamera(1);
|
|
14233
|
-
if (
|
|
14234
|
-
|
|
14235
|
-
|
|
14236
|
-
|
|
14237
|
-
|
|
14563
|
+
if (demoCameraState.mode === 0 /* FirstPerson */) {
|
|
14564
|
+
if (demoCamera) {
|
|
14565
|
+
lastRendered.origin = demoCamera.origin;
|
|
14566
|
+
lastRendered.viewAngles = demoCamera.angles;
|
|
14567
|
+
if (demoCamera.fov) {
|
|
14568
|
+
lastRendered.fov = demoCamera.fov;
|
|
14569
|
+
}
|
|
14570
|
+
}
|
|
14571
|
+
} else if (demoCameraState.mode === 1 /* ThirdPerson */) {
|
|
14572
|
+
if (demoCamera) {
|
|
14573
|
+
const vectors = angleVectors(demoCamera.angles);
|
|
14574
|
+
const forward = vectors.forward;
|
|
14575
|
+
const dist2 = demoCameraState.thirdPersonDistance;
|
|
14576
|
+
const camOrigin = { ...demoCamera.origin };
|
|
14577
|
+
camOrigin.x -= forward.x * dist2;
|
|
14578
|
+
camOrigin.y -= forward.y * dist2;
|
|
14579
|
+
camOrigin.z -= forward.z * dist2;
|
|
14580
|
+
lastRendered.origin = camOrigin;
|
|
14581
|
+
lastRendered.viewAngles = demoCamera.angles;
|
|
14582
|
+
}
|
|
14583
|
+
} else if (demoCameraState.mode === 2 /* Free */) {
|
|
14584
|
+
lastRendered.origin = demoCameraState.freeCameraOrigin;
|
|
14585
|
+
lastRendered.viewAngles = demoCameraState.freeCameraAngles;
|
|
14586
|
+
} else if (demoCameraState.mode === 3 /* Follow */) {
|
|
14587
|
+
if (demoCameraState.followEntityId !== -1) {
|
|
14588
|
+
const ent = renderEntities.find((e) => e.id === demoCameraState.followEntityId);
|
|
14589
|
+
if (ent) {
|
|
14590
|
+
const mat = ent.transform;
|
|
14591
|
+
lastRendered.origin = { x: mat[12], y: mat[13], z: mat[14] };
|
|
14592
|
+
}
|
|
14238
14593
|
}
|
|
14239
14594
|
}
|
|
14240
14595
|
}
|
|
@@ -14274,8 +14629,10 @@ function createClient(imports) {
|
|
|
14274
14629
|
const { origin, viewAngles } = lastRendered;
|
|
14275
14630
|
camera = new Camera();
|
|
14276
14631
|
camera.position = vec3_exports.fromValues(origin.x, origin.y, origin.z);
|
|
14277
|
-
|
|
14278
|
-
|
|
14632
|
+
if (!isDemoPlaying || demoCameraState.mode === 0 /* FirstPerson */) {
|
|
14633
|
+
const viewOffset = lastView?.offset ?? { x: 0, y: 0, z: 0 };
|
|
14634
|
+
vec3_exports.add(camera.position, camera.position, [viewOffset.x, viewOffset.y, viewOffset.z]);
|
|
14635
|
+
}
|
|
14279
14636
|
const effectAngles = lastView?.angles ?? { x: 0, y: 0, z: 0 };
|
|
14280
14637
|
camera.angles = vec3_exports.fromValues(viewAngles.x + effectAngles.x, viewAngles.y + effectAngles.y, viewAngles.z + effectAngles.z);
|
|
14281
14638
|
if (isDemoPlaying && lastRendered.fov) {
|
|
@@ -14508,7 +14865,21 @@ function createClient(imports) {
|
|
|
14508
14865
|
},
|
|
14509
14866
|
demoHandler,
|
|
14510
14867
|
multiplayer,
|
|
14511
|
-
configStrings
|
|
14868
|
+
configStrings,
|
|
14869
|
+
// Demo Camera API
|
|
14870
|
+
setDemoCameraMode(mode) {
|
|
14871
|
+
demoCameraState.mode = mode;
|
|
14872
|
+
},
|
|
14873
|
+
setDemoThirdPersonDistance(dist2) {
|
|
14874
|
+
demoCameraState.thirdPersonDistance = dist2;
|
|
14875
|
+
},
|
|
14876
|
+
setDemoThirdPersonOffset(offset) {
|
|
14877
|
+
demoCameraState.thirdPersonOffset = offset;
|
|
14878
|
+
},
|
|
14879
|
+
setDemoFreeCamera(origin, angles) {
|
|
14880
|
+
demoCameraState.freeCameraOrigin = origin;
|
|
14881
|
+
demoCameraState.freeCameraAngles = angles;
|
|
14882
|
+
}
|
|
14512
14883
|
};
|
|
14513
14884
|
return clientExports;
|
|
14514
14885
|
}
|
|
@@ -14517,6 +14888,7 @@ function createClient(imports) {
|
|
|
14517
14888
|
ClientConfigStrings,
|
|
14518
14889
|
ClientMode,
|
|
14519
14890
|
ClientPrediction,
|
|
14891
|
+
DemoCameraMode,
|
|
14520
14892
|
GameSession,
|
|
14521
14893
|
InputAction,
|
|
14522
14894
|
InputBindings,
|