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
|
@@ -1821,6 +1821,9 @@ var CommandRegistry = class {
|
|
|
1821
1821
|
this.commands.set(name, command);
|
|
1822
1822
|
return command;
|
|
1823
1823
|
}
|
|
1824
|
+
registerCommand(name, callback) {
|
|
1825
|
+
this.register(name, callback);
|
|
1826
|
+
}
|
|
1824
1827
|
get(name) {
|
|
1825
1828
|
return this.commands.get(name);
|
|
1826
1829
|
}
|
|
@@ -1836,10 +1839,33 @@ var CommandRegistry = class {
|
|
|
1836
1839
|
command.execute(args);
|
|
1837
1840
|
return true;
|
|
1838
1841
|
}
|
|
1842
|
+
this.onConsoleOutput?.(`Unknown command "${name}"`);
|
|
1839
1843
|
return false;
|
|
1840
1844
|
}
|
|
1845
|
+
executeCommand(cmd) {
|
|
1846
|
+
this.execute(cmd);
|
|
1847
|
+
}
|
|
1841
1848
|
tokenize(text) {
|
|
1842
|
-
|
|
1849
|
+
const args = [];
|
|
1850
|
+
let currentArg = "";
|
|
1851
|
+
let inQuote = false;
|
|
1852
|
+
for (let i = 0; i < text.length; i++) {
|
|
1853
|
+
const char = text[i];
|
|
1854
|
+
if (char === '"') {
|
|
1855
|
+
inQuote = !inQuote;
|
|
1856
|
+
} else if (char === " " && !inQuote) {
|
|
1857
|
+
if (currentArg.length > 0) {
|
|
1858
|
+
args.push(currentArg);
|
|
1859
|
+
currentArg = "";
|
|
1860
|
+
}
|
|
1861
|
+
} else {
|
|
1862
|
+
currentArg += char;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
if (currentArg.length > 0) {
|
|
1866
|
+
args.push(currentArg);
|
|
1867
|
+
}
|
|
1868
|
+
return args;
|
|
1843
1869
|
}
|
|
1844
1870
|
list() {
|
|
1845
1871
|
return [...this.commands.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -2924,13 +2950,21 @@ var CvarRegistry = class {
|
|
|
2924
2950
|
if (existing) {
|
|
2925
2951
|
return existing;
|
|
2926
2952
|
}
|
|
2927
|
-
const
|
|
2953
|
+
const originalOnChange = def.onChange;
|
|
2954
|
+
const wrappedOnChange = (cvar2, prev) => {
|
|
2955
|
+
originalOnChange?.(cvar2, prev);
|
|
2956
|
+
this.onCvarChange?.(cvar2.name, cvar2.string);
|
|
2957
|
+
};
|
|
2958
|
+
const cvar = new Cvar({ ...def, onChange: wrappedOnChange });
|
|
2928
2959
|
this.cvars.set(def.name, cvar);
|
|
2929
2960
|
return cvar;
|
|
2930
2961
|
}
|
|
2931
2962
|
get(name) {
|
|
2932
2963
|
return this.cvars.get(name);
|
|
2933
2964
|
}
|
|
2965
|
+
getCvar(name) {
|
|
2966
|
+
return this.get(name);
|
|
2967
|
+
}
|
|
2934
2968
|
setValue(name, value) {
|
|
2935
2969
|
const cvar = this.get(name);
|
|
2936
2970
|
if (!cvar) {
|
|
@@ -2939,6 +2973,9 @@ var CvarRegistry = class {
|
|
|
2939
2973
|
cvar.set(value);
|
|
2940
2974
|
return cvar;
|
|
2941
2975
|
}
|
|
2976
|
+
setCvar(name, value) {
|
|
2977
|
+
this.setValue(name, value);
|
|
2978
|
+
}
|
|
2942
2979
|
resetAll() {
|
|
2943
2980
|
for (const cvar of this.cvars.values()) {
|
|
2944
2981
|
cvar.reset();
|
|
@@ -2954,6 +2991,15 @@ var CvarRegistry = class {
|
|
|
2954
2991
|
list() {
|
|
2955
2992
|
return [...this.cvars.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
2956
2993
|
}
|
|
2994
|
+
listCvars() {
|
|
2995
|
+
return this.list().map((cvar) => ({
|
|
2996
|
+
name: cvar.name,
|
|
2997
|
+
value: cvar.string,
|
|
2998
|
+
defaultValue: cvar.defaultValue,
|
|
2999
|
+
flags: cvar.flags,
|
|
3000
|
+
description: cvar.description
|
|
3001
|
+
}));
|
|
3002
|
+
}
|
|
2957
3003
|
};
|
|
2958
3004
|
var EngineHost = class {
|
|
2959
3005
|
constructor(game, client, options = {}) {
|
|
@@ -8762,6 +8808,162 @@ var NetworkMessageParser = class _NetworkMessageParser {
|
|
|
8762
8808
|
}
|
|
8763
8809
|
}
|
|
8764
8810
|
};
|
|
8811
|
+
var DemoAnalyzer = class {
|
|
8812
|
+
constructor(buffer) {
|
|
8813
|
+
this.events = [];
|
|
8814
|
+
this.summary = {
|
|
8815
|
+
totalKills: 0,
|
|
8816
|
+
totalDeaths: 0,
|
|
8817
|
+
damageDealt: 0,
|
|
8818
|
+
damageReceived: 0,
|
|
8819
|
+
weaponUsage: /* @__PURE__ */ new Map()
|
|
8820
|
+
};
|
|
8821
|
+
this.header = null;
|
|
8822
|
+
this.configStrings = /* @__PURE__ */ new Map();
|
|
8823
|
+
this.serverInfo = {};
|
|
8824
|
+
this.statistics = null;
|
|
8825
|
+
this.playerStats = /* @__PURE__ */ new Map();
|
|
8826
|
+
this.weaponStats = /* @__PURE__ */ new Map();
|
|
8827
|
+
this.buffer = buffer;
|
|
8828
|
+
}
|
|
8829
|
+
analyze() {
|
|
8830
|
+
const reader = new DemoReader(this.buffer);
|
|
8831
|
+
let currentFrameIndex = -1;
|
|
8832
|
+
let currentTime = 0;
|
|
8833
|
+
let frameDuration = 0.1;
|
|
8834
|
+
let protocolVersion = 0;
|
|
8835
|
+
const handler = {
|
|
8836
|
+
onServerData: (protocol, serverCount, attractLoop, gameDir, playerNum, levelName, tickRate, demoType) => {
|
|
8837
|
+
protocolVersion = protocol;
|
|
8838
|
+
this.header = {
|
|
8839
|
+
protocolVersion: protocol,
|
|
8840
|
+
gameDir,
|
|
8841
|
+
levelName,
|
|
8842
|
+
playerNum,
|
|
8843
|
+
serverCount,
|
|
8844
|
+
spawnCount: serverCount,
|
|
8845
|
+
// Mapping generic arg
|
|
8846
|
+
tickRate,
|
|
8847
|
+
demoType
|
|
8848
|
+
};
|
|
8849
|
+
if (tickRate && tickRate > 0) {
|
|
8850
|
+
frameDuration = 1 / tickRate;
|
|
8851
|
+
}
|
|
8852
|
+
},
|
|
8853
|
+
onConfigString: (index, str3) => {
|
|
8854
|
+
this.configStrings.set(index, str3);
|
|
8855
|
+
if (index === 0) {
|
|
8856
|
+
this.parseServerInfo(str3);
|
|
8857
|
+
}
|
|
8858
|
+
},
|
|
8859
|
+
onSpawnBaseline: (entity) => {
|
|
8860
|
+
},
|
|
8861
|
+
onFrame: (frame) => {
|
|
8862
|
+
},
|
|
8863
|
+
onPrint: (level, msg) => {
|
|
8864
|
+
if (msg.includes("died") || msg.includes("killed")) {
|
|
8865
|
+
this.summary.totalDeaths++;
|
|
8866
|
+
this.recordEvent({
|
|
8867
|
+
type: 4,
|
|
8868
|
+
frame: currentFrameIndex,
|
|
8869
|
+
time: currentTime,
|
|
8870
|
+
description: msg.trim()
|
|
8871
|
+
});
|
|
8872
|
+
}
|
|
8873
|
+
},
|
|
8874
|
+
onCenterPrint: () => {
|
|
8875
|
+
},
|
|
8876
|
+
onStuffText: () => {
|
|
8877
|
+
},
|
|
8878
|
+
onSound: () => {
|
|
8879
|
+
},
|
|
8880
|
+
onTempEntity: () => {
|
|
8881
|
+
},
|
|
8882
|
+
onLayout: () => {
|
|
8883
|
+
},
|
|
8884
|
+
onInventory: () => {
|
|
8885
|
+
},
|
|
8886
|
+
onMuzzleFlash: (ent, weapon) => {
|
|
8887
|
+
this.handleWeaponFire(ent, weapon, currentFrameIndex, currentTime);
|
|
8888
|
+
},
|
|
8889
|
+
onMuzzleFlash2: (ent, weapon) => {
|
|
8890
|
+
this.handleWeaponFire(ent, weapon, currentFrameIndex, currentTime);
|
|
8891
|
+
},
|
|
8892
|
+
onMuzzleFlash3: (ent, weapon) => {
|
|
8893
|
+
this.handleWeaponFire(ent, weapon, currentFrameIndex, currentTime);
|
|
8894
|
+
},
|
|
8895
|
+
onDisconnect: () => {
|
|
8896
|
+
},
|
|
8897
|
+
onReconnect: () => {
|
|
8898
|
+
},
|
|
8899
|
+
onDownload: () => {
|
|
8900
|
+
},
|
|
8901
|
+
// Rerelease specific
|
|
8902
|
+
onDamage: (indicators) => {
|
|
8903
|
+
for (const ind of indicators) {
|
|
8904
|
+
this.recordEvent({
|
|
8905
|
+
type: 2,
|
|
8906
|
+
frame: currentFrameIndex,
|
|
8907
|
+
time: currentTime,
|
|
8908
|
+
value: ind.damage,
|
|
8909
|
+
position: ind.dir,
|
|
8910
|
+
description: `Took ${ind.damage} damage`
|
|
8911
|
+
});
|
|
8912
|
+
this.summary.damageReceived += ind.damage;
|
|
8913
|
+
}
|
|
8914
|
+
}
|
|
8915
|
+
};
|
|
8916
|
+
while (reader.hasMore()) {
|
|
8917
|
+
const block = reader.readNextBlock();
|
|
8918
|
+
if (!block) break;
|
|
8919
|
+
currentFrameIndex++;
|
|
8920
|
+
currentTime = currentFrameIndex * frameDuration;
|
|
8921
|
+
const parser = new NetworkMessageParser(block.data, handler);
|
|
8922
|
+
parser.setProtocolVersion(protocolVersion);
|
|
8923
|
+
parser.parseMessage();
|
|
8924
|
+
protocolVersion = parser.getProtocolVersion();
|
|
8925
|
+
}
|
|
8926
|
+
this.statistics = {
|
|
8927
|
+
duration: currentTime,
|
|
8928
|
+
frameCount: currentFrameIndex + 1,
|
|
8929
|
+
averageFps: (currentFrameIndex + 1) / (currentTime || 1),
|
|
8930
|
+
mapName: this.header?.levelName || "unknown",
|
|
8931
|
+
playerCount: 1
|
|
8932
|
+
// Default to 1 for SP/client demo
|
|
8933
|
+
};
|
|
8934
|
+
return {
|
|
8935
|
+
events: this.events,
|
|
8936
|
+
summary: this.summary,
|
|
8937
|
+
header: this.header,
|
|
8938
|
+
configStrings: this.configStrings,
|
|
8939
|
+
serverInfo: this.serverInfo,
|
|
8940
|
+
statistics: this.statistics
|
|
8941
|
+
};
|
|
8942
|
+
}
|
|
8943
|
+
handleWeaponFire(ent, weapon, frame, time) {
|
|
8944
|
+
this.recordEvent({
|
|
8945
|
+
type: 0,
|
|
8946
|
+
frame,
|
|
8947
|
+
time,
|
|
8948
|
+
entityId: ent,
|
|
8949
|
+
value: weapon,
|
|
8950
|
+
description: `Weapon ${weapon} fired by ${ent}`
|
|
8951
|
+
});
|
|
8952
|
+
const count = this.summary.weaponUsage.get(weapon) || 0;
|
|
8953
|
+
this.summary.weaponUsage.set(weapon, count + 1);
|
|
8954
|
+
}
|
|
8955
|
+
recordEvent(event) {
|
|
8956
|
+
this.events.push(event);
|
|
8957
|
+
}
|
|
8958
|
+
parseServerInfo(str3) {
|
|
8959
|
+
const parts = str3.split("\\");
|
|
8960
|
+
for (let i = 1; i < parts.length; i += 2) {
|
|
8961
|
+
if (i + 1 < parts.length) {
|
|
8962
|
+
this.serverInfo[parts[i]] = parts[i + 1];
|
|
8963
|
+
}
|
|
8964
|
+
}
|
|
8965
|
+
}
|
|
8966
|
+
};
|
|
8765
8967
|
var PlaybackState = /* @__PURE__ */ ((PlaybackState22) => {
|
|
8766
8968
|
PlaybackState22[PlaybackState22["Stopped"] = 0] = "Stopped";
|
|
8767
8969
|
PlaybackState22[PlaybackState22["Playing"] = 1] = "Playing";
|
|
@@ -8772,6 +8974,7 @@ var PlaybackState = /* @__PURE__ */ ((PlaybackState22) => {
|
|
|
8772
8974
|
var DemoPlaybackController = class {
|
|
8773
8975
|
constructor() {
|
|
8774
8976
|
this.reader = null;
|
|
8977
|
+
this.buffer = null;
|
|
8775
8978
|
this.state = 0;
|
|
8776
8979
|
this.playbackSpeed = 1;
|
|
8777
8980
|
this.currentProtocolVersion = 0;
|
|
@@ -8781,6 +8984,12 @@ var DemoPlaybackController = class {
|
|
|
8781
8984
|
this.frameDuration = 100;
|
|
8782
8985
|
this.snapshotInterval = 100;
|
|
8783
8986
|
this.snapshots = /* @__PURE__ */ new Map();
|
|
8987
|
+
this.cachedEvents = null;
|
|
8988
|
+
this.cachedSummary = null;
|
|
8989
|
+
this.cachedHeader = null;
|
|
8990
|
+
this.cachedConfigStrings = null;
|
|
8991
|
+
this.cachedServerInfo = null;
|
|
8992
|
+
this.cachedStatistics = null;
|
|
8784
8993
|
}
|
|
8785
8994
|
setHandler(handler) {
|
|
8786
8995
|
this.handler = handler;
|
|
@@ -8789,6 +8998,7 @@ var DemoPlaybackController = class {
|
|
|
8789
8998
|
this.callbacks = callbacks;
|
|
8790
8999
|
}
|
|
8791
9000
|
loadDemo(buffer) {
|
|
9001
|
+
this.buffer = buffer;
|
|
8792
9002
|
this.reader = new DemoReader(buffer);
|
|
8793
9003
|
this.transitionState(
|
|
8794
9004
|
0
|
|
@@ -8799,6 +9009,12 @@ var DemoPlaybackController = class {
|
|
|
8799
9009
|
this.currentFrameIndex = -1;
|
|
8800
9010
|
this.snapshots.clear();
|
|
8801
9011
|
this.lastFrameData = null;
|
|
9012
|
+
this.cachedEvents = null;
|
|
9013
|
+
this.cachedSummary = null;
|
|
9014
|
+
this.cachedHeader = null;
|
|
9015
|
+
this.cachedConfigStrings = null;
|
|
9016
|
+
this.cachedServerInfo = null;
|
|
9017
|
+
this.cachedStatistics = null;
|
|
8802
9018
|
}
|
|
8803
9019
|
play() {
|
|
8804
9020
|
if (this.reader && this.state !== 1) {
|
|
@@ -9126,6 +9342,57 @@ var DemoPlaybackController = class {
|
|
|
9126
9342
|
this.seek(originalFrame);
|
|
9127
9343
|
return trajectory;
|
|
9128
9344
|
}
|
|
9345
|
+
// 3.2.3 Event Log Extraction & 3.3 Metadata
|
|
9346
|
+
getDemoEvents() {
|
|
9347
|
+
this.ensureAnalysis();
|
|
9348
|
+
return this.cachedEvents || [];
|
|
9349
|
+
}
|
|
9350
|
+
filterEvents(type, entityId) {
|
|
9351
|
+
const events = this.getDemoEvents();
|
|
9352
|
+
return events.filter((e) => {
|
|
9353
|
+
if (e.type !== type) return false;
|
|
9354
|
+
if (entityId !== void 0 && e.entityId !== entityId) return false;
|
|
9355
|
+
return true;
|
|
9356
|
+
});
|
|
9357
|
+
}
|
|
9358
|
+
getEventSummary() {
|
|
9359
|
+
this.ensureAnalysis();
|
|
9360
|
+
return this.cachedSummary || {
|
|
9361
|
+
totalKills: 0,
|
|
9362
|
+
totalDeaths: 0,
|
|
9363
|
+
damageDealt: 0,
|
|
9364
|
+
damageReceived: 0,
|
|
9365
|
+
weaponUsage: /* @__PURE__ */ new Map()
|
|
9366
|
+
};
|
|
9367
|
+
}
|
|
9368
|
+
getDemoHeader() {
|
|
9369
|
+
this.ensureAnalysis();
|
|
9370
|
+
return this.cachedHeader;
|
|
9371
|
+
}
|
|
9372
|
+
getDemoConfigStrings() {
|
|
9373
|
+
this.ensureAnalysis();
|
|
9374
|
+
return this.cachedConfigStrings || /* @__PURE__ */ new Map();
|
|
9375
|
+
}
|
|
9376
|
+
getDemoServerInfo() {
|
|
9377
|
+
this.ensureAnalysis();
|
|
9378
|
+
return this.cachedServerInfo || {};
|
|
9379
|
+
}
|
|
9380
|
+
getDemoStatistics() {
|
|
9381
|
+
this.ensureAnalysis();
|
|
9382
|
+
return this.cachedStatistics;
|
|
9383
|
+
}
|
|
9384
|
+
ensureAnalysis() {
|
|
9385
|
+
if (!this.cachedEvents && this.buffer) {
|
|
9386
|
+
const analyzer = new DemoAnalyzer(this.buffer);
|
|
9387
|
+
const result = analyzer.analyze();
|
|
9388
|
+
this.cachedEvents = result.events;
|
|
9389
|
+
this.cachedSummary = result.summary;
|
|
9390
|
+
this.cachedHeader = result.header;
|
|
9391
|
+
this.cachedConfigStrings = result.configStrings;
|
|
9392
|
+
this.cachedServerInfo = result.serverInfo;
|
|
9393
|
+
this.cachedStatistics = result.statistics;
|
|
9394
|
+
}
|
|
9395
|
+
}
|
|
9129
9396
|
};
|
|
9130
9397
|
var DemoRecorder = class {
|
|
9131
9398
|
// -1 means start of demo
|
|
@@ -9205,12 +9472,56 @@ var __export3 = (target, all) => {
|
|
|
9205
9472
|
};
|
|
9206
9473
|
var ZERO_VEC3 = { x: 0, y: 0, z: 0 };
|
|
9207
9474
|
var DEG_TO_RAD2 = Math.PI / 180;
|
|
9475
|
+
var PITCH = 0;
|
|
9476
|
+
var YAW = 1;
|
|
9477
|
+
var ROLL = 2;
|
|
9208
9478
|
var DEG2RAD_FACTOR2 = Math.PI / 180;
|
|
9209
9479
|
var RAD2DEG_FACTOR2 = 180 / Math.PI;
|
|
9480
|
+
function axisComponent(vec, axis) {
|
|
9481
|
+
switch (axis) {
|
|
9482
|
+
case PITCH:
|
|
9483
|
+
return vec.x;
|
|
9484
|
+
case YAW:
|
|
9485
|
+
return vec.y;
|
|
9486
|
+
case ROLL:
|
|
9487
|
+
default:
|
|
9488
|
+
return vec.z;
|
|
9489
|
+
}
|
|
9490
|
+
}
|
|
9491
|
+
function degToRad(degrees) {
|
|
9492
|
+
return degrees * DEG2RAD_FACTOR2;
|
|
9493
|
+
}
|
|
9210
9494
|
function angleMod(angle2) {
|
|
9211
9495
|
const value = angle2 % 360;
|
|
9212
9496
|
return value < 0 ? 360 + value : value;
|
|
9213
9497
|
}
|
|
9498
|
+
function angleVectors(angles) {
|
|
9499
|
+
const yaw = degToRad(axisComponent(angles, YAW));
|
|
9500
|
+
const pitch = degToRad(axisComponent(angles, PITCH));
|
|
9501
|
+
const roll = degToRad(axisComponent(angles, ROLL));
|
|
9502
|
+
const sy = Math.sin(yaw);
|
|
9503
|
+
const cy = Math.cos(yaw);
|
|
9504
|
+
const sp = Math.sin(pitch);
|
|
9505
|
+
const cp = Math.cos(pitch);
|
|
9506
|
+
const sr = Math.sin(roll);
|
|
9507
|
+
const cr = Math.cos(roll);
|
|
9508
|
+
const forward = {
|
|
9509
|
+
x: cp * cy,
|
|
9510
|
+
y: cp * sy,
|
|
9511
|
+
z: -sp
|
|
9512
|
+
};
|
|
9513
|
+
const right = {
|
|
9514
|
+
x: -sr * sp * cy - cr * -sy,
|
|
9515
|
+
y: -sr * sp * sy - cr * cy,
|
|
9516
|
+
z: -sr * cp
|
|
9517
|
+
};
|
|
9518
|
+
const up = {
|
|
9519
|
+
x: cr * sp * cy - sr * -sy,
|
|
9520
|
+
y: cr * sp * sy - sr * cy,
|
|
9521
|
+
z: cr * cp
|
|
9522
|
+
};
|
|
9523
|
+
return { forward, right, up };
|
|
9524
|
+
}
|
|
9214
9525
|
var ANORMS2 = [
|
|
9215
9526
|
[-0.525731, 0, 0.850651],
|
|
9216
9527
|
[-0.442863, 0.238856, 0.864188],
|
|
@@ -13196,6 +13507,15 @@ var DemoControls = class {
|
|
|
13196
13507
|
}
|
|
13197
13508
|
};
|
|
13198
13509
|
|
|
13510
|
+
// src/demo/camera.ts
|
|
13511
|
+
var DemoCameraMode = /* @__PURE__ */ ((DemoCameraMode2) => {
|
|
13512
|
+
DemoCameraMode2[DemoCameraMode2["FirstPerson"] = 0] = "FirstPerson";
|
|
13513
|
+
DemoCameraMode2[DemoCameraMode2["ThirdPerson"] = 1] = "ThirdPerson";
|
|
13514
|
+
DemoCameraMode2[DemoCameraMode2["Free"] = 2] = "Free";
|
|
13515
|
+
DemoCameraMode2[DemoCameraMode2["Follow"] = 3] = "Follow";
|
|
13516
|
+
return DemoCameraMode2;
|
|
13517
|
+
})(DemoCameraMode || {});
|
|
13518
|
+
|
|
13199
13519
|
// src/effects.ts
|
|
13200
13520
|
function addDLight(dlights, origin, color, intensity, minLight = 0, die = 0) {
|
|
13201
13521
|
dlights.push({
|
|
@@ -13893,6 +14213,14 @@ function createClient(imports) {
|
|
|
13893
14213
|
let isDemoPlaying = false;
|
|
13894
14214
|
let currentDemoName = null;
|
|
13895
14215
|
let clientMode = 0 /* Normal */;
|
|
14216
|
+
const demoCameraState = {
|
|
14217
|
+
mode: 0 /* FirstPerson */,
|
|
14218
|
+
thirdPersonDistance: 80,
|
|
14219
|
+
thirdPersonOffset: { x: 0, y: 0, z: 0 },
|
|
14220
|
+
freeCameraOrigin: { x: 0, y: 0, z: 0 },
|
|
14221
|
+
freeCameraAngles: { x: 0, y: 0, z: 0 },
|
|
14222
|
+
followEntityId: -1
|
|
14223
|
+
};
|
|
13896
14224
|
const menuSystem = new MenuSystem();
|
|
13897
14225
|
const loadingScreen = new LoadingScreen();
|
|
13898
14226
|
const errorDialog = new ErrorDialog();
|
|
@@ -14107,6 +14435,8 @@ function createClient(imports) {
|
|
|
14107
14435
|
},
|
|
14108
14436
|
handleInput(key, down) {
|
|
14109
14437
|
if (isDemoPlaying) {
|
|
14438
|
+
if (demoCameraState.mode === 2 /* Free */) {
|
|
14439
|
+
}
|
|
14110
14440
|
if (demoControls.handleInput(key, down)) {
|
|
14111
14441
|
return true;
|
|
14112
14442
|
}
|
|
@@ -14192,18 +14522,42 @@ function createClient(imports) {
|
|
|
14192
14522
|
lastRenderTime = now;
|
|
14193
14523
|
demoPlayback.update(dt);
|
|
14194
14524
|
lastRendered = demoHandler.getPredictionState(demoPlayback.getCurrentTime());
|
|
14195
|
-
const frameDuration = 100;
|
|
14196
14525
|
renderEntities = demoHandler.getRenderableEntities(1, configStrings);
|
|
14197
14526
|
if (demoHandler.latestFrame && demoHandler.latestFrame.packetEntities) {
|
|
14198
14527
|
currentPacketEntities = demoHandler.latestFrame.packetEntities.entities;
|
|
14199
14528
|
}
|
|
14200
14529
|
if (lastRendered) {
|
|
14201
14530
|
const demoCamera = demoHandler.getDemoCamera(1);
|
|
14202
|
-
if (
|
|
14203
|
-
|
|
14204
|
-
|
|
14205
|
-
|
|
14206
|
-
|
|
14531
|
+
if (demoCameraState.mode === 0 /* FirstPerson */) {
|
|
14532
|
+
if (demoCamera) {
|
|
14533
|
+
lastRendered.origin = demoCamera.origin;
|
|
14534
|
+
lastRendered.viewAngles = demoCamera.angles;
|
|
14535
|
+
if (demoCamera.fov) {
|
|
14536
|
+
lastRendered.fov = demoCamera.fov;
|
|
14537
|
+
}
|
|
14538
|
+
}
|
|
14539
|
+
} else if (demoCameraState.mode === 1 /* ThirdPerson */) {
|
|
14540
|
+
if (demoCamera) {
|
|
14541
|
+
const vectors = angleVectors(demoCamera.angles);
|
|
14542
|
+
const forward = vectors.forward;
|
|
14543
|
+
const dist2 = demoCameraState.thirdPersonDistance;
|
|
14544
|
+
const camOrigin = { ...demoCamera.origin };
|
|
14545
|
+
camOrigin.x -= forward.x * dist2;
|
|
14546
|
+
camOrigin.y -= forward.y * dist2;
|
|
14547
|
+
camOrigin.z -= forward.z * dist2;
|
|
14548
|
+
lastRendered.origin = camOrigin;
|
|
14549
|
+
lastRendered.viewAngles = demoCamera.angles;
|
|
14550
|
+
}
|
|
14551
|
+
} else if (demoCameraState.mode === 2 /* Free */) {
|
|
14552
|
+
lastRendered.origin = demoCameraState.freeCameraOrigin;
|
|
14553
|
+
lastRendered.viewAngles = demoCameraState.freeCameraAngles;
|
|
14554
|
+
} else if (demoCameraState.mode === 3 /* Follow */) {
|
|
14555
|
+
if (demoCameraState.followEntityId !== -1) {
|
|
14556
|
+
const ent = renderEntities.find((e) => e.id === demoCameraState.followEntityId);
|
|
14557
|
+
if (ent) {
|
|
14558
|
+
const mat = ent.transform;
|
|
14559
|
+
lastRendered.origin = { x: mat[12], y: mat[13], z: mat[14] };
|
|
14560
|
+
}
|
|
14207
14561
|
}
|
|
14208
14562
|
}
|
|
14209
14563
|
}
|
|
@@ -14243,8 +14597,10 @@ function createClient(imports) {
|
|
|
14243
14597
|
const { origin, viewAngles } = lastRendered;
|
|
14244
14598
|
camera = new Camera();
|
|
14245
14599
|
camera.position = vec3_exports.fromValues(origin.x, origin.y, origin.z);
|
|
14246
|
-
|
|
14247
|
-
|
|
14600
|
+
if (!isDemoPlaying || demoCameraState.mode === 0 /* FirstPerson */) {
|
|
14601
|
+
const viewOffset = lastView?.offset ?? { x: 0, y: 0, z: 0 };
|
|
14602
|
+
vec3_exports.add(camera.position, camera.position, [viewOffset.x, viewOffset.y, viewOffset.z]);
|
|
14603
|
+
}
|
|
14248
14604
|
const effectAngles = lastView?.angles ?? { x: 0, y: 0, z: 0 };
|
|
14249
14605
|
camera.angles = vec3_exports.fromValues(viewAngles.x + effectAngles.x, viewAngles.y + effectAngles.y, viewAngles.z + effectAngles.z);
|
|
14250
14606
|
if (isDemoPlaying && lastRendered.fov) {
|
|
@@ -14477,7 +14833,21 @@ function createClient(imports) {
|
|
|
14477
14833
|
},
|
|
14478
14834
|
demoHandler,
|
|
14479
14835
|
multiplayer,
|
|
14480
|
-
configStrings
|
|
14836
|
+
configStrings,
|
|
14837
|
+
// Demo Camera API
|
|
14838
|
+
setDemoCameraMode(mode) {
|
|
14839
|
+
demoCameraState.mode = mode;
|
|
14840
|
+
},
|
|
14841
|
+
setDemoThirdPersonDistance(dist2) {
|
|
14842
|
+
demoCameraState.thirdPersonDistance = dist2;
|
|
14843
|
+
},
|
|
14844
|
+
setDemoThirdPersonOffset(offset) {
|
|
14845
|
+
demoCameraState.thirdPersonOffset = offset;
|
|
14846
|
+
},
|
|
14847
|
+
setDemoFreeCamera(origin, angles) {
|
|
14848
|
+
demoCameraState.freeCameraOrigin = origin;
|
|
14849
|
+
demoCameraState.freeCameraAngles = angles;
|
|
14850
|
+
}
|
|
14481
14851
|
};
|
|
14482
14852
|
return clientExports;
|
|
14483
14853
|
}
|
|
@@ -14485,6 +14855,7 @@ export {
|
|
|
14485
14855
|
ClientConfigStrings,
|
|
14486
14856
|
ClientMode,
|
|
14487
14857
|
ClientPrediction3 as ClientPrediction,
|
|
14858
|
+
DemoCameraMode,
|
|
14488
14859
|
GameSession,
|
|
14489
14860
|
InputAction,
|
|
14490
14861
|
InputBindings,
|