1681-engine 0.5.9 → 0.6.0
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/CHANGELOG.md +92 -1
- package/README.md +15 -6
- package/dist/1681-engine.js +588 -465
- package/dist/ai/behaviorTree.js +198 -0
- package/dist/ai/buildTree.js +54 -0
- package/dist/ambient/life/Birds.js +73 -0
- package/dist/ambient/life/Butterflies.js +43 -0
- package/dist/ambient/life/ChimneySmoke.js +50 -0
- package/dist/ambient/life/Drift.js +75 -0
- package/dist/ambient/life/Fireflies.js +52 -0
- package/dist/ambient/life/lifeMotion.js +49 -0
- package/dist/assets/AssetLoader.js +115 -70
- package/dist/assets/Prepainter.js +61 -0
- package/dist/assets/workerPainter.js +39 -0
- package/dist/audio/spatial.js +118 -0
- package/dist/cjs/electron/electronLike.d.ts +55 -0
- package/dist/cjs/electron/electronLike.js +7 -0
- package/dist/cjs/electron/index.d.ts +14 -0
- package/dist/cjs/electron/index.js +20 -0
- package/dist/cjs/electron/lockdown.d.ts +33 -0
- package/dist/cjs/electron/lockdown.js +69 -0
- package/dist/cjs/electron/lockdownRules.d.ts +28 -0
- package/dist/cjs/electron/lockdownRules.js +61 -0
- package/dist/cjs/electron/sessionStore.d.ts +40 -0
- package/dist/cjs/electron/sessionStore.js +77 -0
- package/dist/cjs/electron/shellId.d.ts +22 -0
- package/dist/cjs/electron/shellId.js +31 -0
- package/dist/cjs/electron/webFiles.d.ts +13 -0
- package/dist/cjs/electron/webFiles.js +52 -0
- package/dist/cjs/electron/webPatcher.d.ts +83 -0
- package/dist/cjs/electron/webPatcher.js +223 -0
- package/dist/cjs/electron/webPointers.d.ts +19 -0
- package/dist/cjs/electron/webPointers.js +35 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/updates/index.d.ts +8 -0
- package/dist/cjs/updates/index.js +21 -0
- package/dist/cjs/updates/manifest.d.ts +73 -0
- package/dist/cjs/updates/manifest.js +67 -0
- package/dist/cjs/updates/pickUpdate.d.ts +42 -0
- package/dist/cjs/updates/pickUpdate.js +52 -0
- package/dist/cjs/updates/webPlan.d.ts +20 -0
- package/dist/cjs/updates/webPlan.js +34 -0
- package/dist/dialogue/DialogueRunner.js +173 -0
- package/dist/dialogue/expr.js +137 -0
- package/dist/dialogue/validateDialogue.js +52 -0
- package/dist/ecs/prefab.js +94 -0
- package/dist/electron/lockdown.js +31 -0
- package/dist/electron/lockdownRules.js +42 -0
- package/dist/electron/sessionStore.js +48 -0
- package/dist/electron/shellId.js +18 -0
- package/dist/electron/webFiles.js +36 -0
- package/dist/electron/webPatcher.js +153 -0
- package/dist/electron/webPointers.js +25 -0
- package/dist/electron.js +19 -0
- package/dist/input/Actions.js +58 -27
- package/dist/input/InputCapture.js +98 -0
- package/dist/input/Keymap.js +32 -26
- package/dist/input/haptics.js +50 -0
- package/dist/input/inputTape.js +68 -0
- package/dist/mobile/backButton.js +40 -0
- package/dist/mobile/capacitor.js +48 -0
- package/dist/mobile/screen.js +31 -0
- package/dist/mobile.js +12 -0
- package/dist/nav/flowField.js +58 -0
- package/dist/nav/steering.js +77 -0
- package/dist/net/ApiClient.js +96 -0
- package/dist/net/InterpolationBuffer.js +30 -23
- package/dist/net/LagCompensator.js +100 -0
- package/dist/net/Room.js +122 -43
- package/dist/net/RoomHost.js +13 -4
- package/dist/net/SpatialHash.js +66 -0
- package/dist/pixel/lifeArt.js +83 -0
- package/dist/pixel.js +63 -58
- package/dist/react/ConfirmButton.js +24 -0
- package/dist/react/baseCss.js +1 -0
- package/dist/react/labels.js +7 -6
- package/dist/react/useJsonSelector.js +13 -0
- package/dist/react.js +73 -68
- package/dist/tilemap/TilemapView.js +57 -32
- package/dist/tilemap/autotile.js +103 -0
- package/dist/tilemap/collision.js +29 -18
- package/dist/tilemap/ldtk.js +21 -0
- package/dist/tilemap/ldtkParse.js +191 -0
- package/dist/types/ai/behaviorTree.d.ts +133 -0
- package/dist/types/ai/behaviorTree.d.ts.map +1 -0
- package/dist/types/ai/buildTree.d.ts +55 -0
- package/dist/types/ai/buildTree.d.ts.map +1 -0
- package/dist/types/ambient/life/Birds.d.ts +50 -0
- package/dist/types/ambient/life/Birds.d.ts.map +1 -0
- package/dist/types/ambient/life/Butterflies.d.ts +32 -0
- package/dist/types/ambient/life/Butterflies.d.ts.map +1 -0
- package/dist/types/ambient/life/ChimneySmoke.d.ts +37 -0
- package/dist/types/ambient/life/ChimneySmoke.d.ts.map +1 -0
- package/dist/types/ambient/life/Drift.d.ts +58 -0
- package/dist/types/ambient/life/Drift.d.ts.map +1 -0
- package/dist/types/ambient/life/Fireflies.d.ts +43 -0
- package/dist/types/ambient/life/Fireflies.d.ts.map +1 -0
- package/dist/types/ambient/life/lifeMotion.d.ts +63 -0
- package/dist/types/ambient/life/lifeMotion.d.ts.map +1 -0
- package/dist/types/assets/AssetLoader.d.ts +20 -0
- package/dist/types/assets/AssetLoader.d.ts.map +1 -1
- package/dist/types/assets/Prepainter.d.ts +64 -0
- package/dist/types/assets/Prepainter.d.ts.map +1 -0
- package/dist/types/assets/workerPainter.d.ts +21 -0
- package/dist/types/assets/workerPainter.d.ts.map +1 -0
- package/dist/types/audio/spatial.d.ts +107 -0
- package/dist/types/audio/spatial.d.ts.map +1 -0
- package/dist/types/dialogue/DialogueRunner.d.ts +78 -0
- package/dist/types/dialogue/DialogueRunner.d.ts.map +1 -0
- package/dist/types/dialogue/expr.d.ts +12 -0
- package/dist/types/dialogue/expr.d.ts.map +1 -0
- package/dist/types/dialogue/script.d.ts +78 -0
- package/dist/types/dialogue/script.d.ts.map +1 -0
- package/dist/types/dialogue/validateDialogue.d.ts +21 -0
- package/dist/types/dialogue/validateDialogue.d.ts.map +1 -0
- package/dist/types/ecs/prefab.d.ts +84 -0
- package/dist/types/ecs/prefab.d.ts.map +1 -0
- package/dist/types/electron/electronLike.d.ts +56 -0
- package/dist/types/electron/electronLike.d.ts.map +1 -0
- package/dist/types/electron/index.d.ts +15 -0
- package/dist/types/electron/index.d.ts.map +1 -0
- package/dist/types/electron/lockdown.d.ts +34 -0
- package/dist/types/electron/lockdown.d.ts.map +1 -0
- package/dist/types/electron/lockdownRules.d.ts +29 -0
- package/dist/types/electron/lockdownRules.d.ts.map +1 -0
- package/dist/types/electron/sessionStore.d.ts +41 -0
- package/dist/types/electron/sessionStore.d.ts.map +1 -0
- package/dist/types/electron/shellId.d.ts +23 -0
- package/dist/types/electron/shellId.d.ts.map +1 -0
- package/dist/types/electron/webFiles.d.ts +14 -0
- package/dist/types/electron/webFiles.d.ts.map +1 -0
- package/dist/types/electron/webPatcher.d.ts +84 -0
- package/dist/types/electron/webPatcher.d.ts.map +1 -0
- package/dist/types/electron/webPointers.d.ts +20 -0
- package/dist/types/electron/webPointers.d.ts.map +1 -0
- package/dist/types/index.d.ts +30 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/input/Actions.d.ts +14 -0
- package/dist/types/input/Actions.d.ts.map +1 -1
- package/dist/types/input/InputCapture.d.ts +53 -0
- package/dist/types/input/InputCapture.d.ts.map +1 -0
- package/dist/types/input/Keymap.d.ts +12 -6
- package/dist/types/input/Keymap.d.ts.map +1 -1
- package/dist/types/input/haptics.d.ts +42 -0
- package/dist/types/input/haptics.d.ts.map +1 -0
- package/dist/types/input/inputTape.d.ts +66 -0
- package/dist/types/input/inputTape.d.ts.map +1 -0
- package/dist/types/mobile/backButton.d.ts +30 -0
- package/dist/types/mobile/backButton.d.ts.map +1 -0
- package/dist/types/mobile/capacitor.d.ts +62 -0
- package/dist/types/mobile/capacitor.d.ts.map +1 -0
- package/dist/types/mobile/index.d.ts +4 -0
- package/dist/types/mobile/index.d.ts.map +1 -0
- package/dist/types/mobile/screen.d.ts +27 -0
- package/dist/types/mobile/screen.d.ts.map +1 -0
- package/dist/types/nav/flowField.d.ts +31 -0
- package/dist/types/nav/flowField.d.ts.map +1 -0
- package/dist/types/nav/steering.d.ts +47 -0
- package/dist/types/nav/steering.d.ts.map +1 -0
- package/dist/types/net/ApiClient.d.ts +74 -0
- package/dist/types/net/ApiClient.d.ts.map +1 -0
- package/dist/types/net/InterpolationBuffer.d.ts +5 -0
- package/dist/types/net/InterpolationBuffer.d.ts.map +1 -1
- package/dist/types/net/LagCompensator.d.ts +70 -0
- package/dist/types/net/LagCompensator.d.ts.map +1 -0
- package/dist/types/net/Room.d.ts +72 -3
- package/dist/types/net/Room.d.ts.map +1 -1
- package/dist/types/net/RoomHost.d.ts +8 -3
- package/dist/types/net/RoomHost.d.ts.map +1 -1
- package/dist/types/net/SpatialHash.d.ts +25 -0
- package/dist/types/net/SpatialHash.d.ts.map +1 -0
- package/dist/types/pixel/index.d.ts +1 -0
- package/dist/types/pixel/index.d.ts.map +1 -1
- package/dist/types/pixel/lifeArt.d.ts +63 -0
- package/dist/types/pixel/lifeArt.d.ts.map +1 -0
- package/dist/types/react/ConfirmButton.d.ts +26 -0
- package/dist/types/react/ConfirmButton.d.ts.map +1 -0
- package/dist/types/react/baseCss.d.ts +1 -1
- package/dist/types/react/baseCss.d.ts.map +1 -1
- package/dist/types/react/index.d.ts +2 -0
- package/dist/types/react/index.d.ts.map +1 -1
- package/dist/types/react/labels.d.ts +2 -0
- package/dist/types/react/labels.d.ts.map +1 -1
- package/dist/types/react/useJsonSelector.d.ts +13 -0
- package/dist/types/react/useJsonSelector.d.ts.map +1 -0
- package/dist/types/tilemap/TilemapView.d.ts +17 -0
- package/dist/types/tilemap/TilemapView.d.ts.map +1 -1
- package/dist/types/tilemap/autotile.d.ts +95 -0
- package/dist/types/tilemap/autotile.d.ts.map +1 -0
- package/dist/types/tilemap/collision.d.ts +8 -0
- package/dist/types/tilemap/collision.d.ts.map +1 -1
- package/dist/types/tilemap/ldtk.d.ts +97 -0
- package/dist/types/tilemap/ldtk.d.ts.map +1 -0
- package/dist/types/tilemap/ldtkParse.d.ts +26 -0
- package/dist/types/tilemap/ldtkParse.d.ts.map +1 -0
- package/dist/types/ui/ScrollView.d.ts.map +1 -1
- package/dist/types/updates/index.d.ts +9 -0
- package/dist/types/updates/index.d.ts.map +1 -0
- package/dist/types/updates/manifest.d.ts +74 -0
- package/dist/types/updates/manifest.d.ts.map +1 -0
- package/dist/types/updates/pickUpdate.d.ts +43 -0
- package/dist/types/updates/pickUpdate.d.ts.map +1 -0
- package/dist/types/updates/webPlan.d.ts +21 -0
- package/dist/types/updates/webPlan.d.ts.map +1 -0
- package/dist/ui/ScrollView.js +10 -8
- package/dist/updates/manifest.js +35 -0
- package/dist/updates/pickUpdate.js +27 -0
- package/dist/updates/webPlan.js +14 -0
- package/dist/updates.js +15 -0
- package/package.json +35 -3
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
class r {
|
|
2
|
+
constructor(t, e) {
|
|
3
|
+
this.meta = e, this.untap = t.tap((s) => this.capture(s));
|
|
4
|
+
}
|
|
5
|
+
meta;
|
|
6
|
+
order = [];
|
|
7
|
+
index = /* @__PURE__ */ new Map();
|
|
8
|
+
last = /* @__PURE__ */ new Map();
|
|
9
|
+
changes = [];
|
|
10
|
+
steps = 0;
|
|
11
|
+
untap;
|
|
12
|
+
stopped = null;
|
|
13
|
+
/** Steps recorded so far. */
|
|
14
|
+
get length() {
|
|
15
|
+
return this.steps;
|
|
16
|
+
}
|
|
17
|
+
/** Stops recording and returns the tape (the same one on every later call). */
|
|
18
|
+
stop() {
|
|
19
|
+
return this.stopped ? this.stopped : (this.untap(), this.stopped = { version: 1, actions: [...this.order], steps: this.steps, changes: this.changes.map((t) => [...t]) }, this.meta && (this.stopped.meta = structuredClone(this.meta)), this.stopped);
|
|
20
|
+
}
|
|
21
|
+
capture(t) {
|
|
22
|
+
const e = this.steps++;
|
|
23
|
+
for (const [s, i] of t) this.note(e, s, i);
|
|
24
|
+
for (const [s, i] of this.last) i !== 0 && !t.has(s) && this.note(e, s, 0);
|
|
25
|
+
}
|
|
26
|
+
note(t, e, s) {
|
|
27
|
+
if ((this.last.get(e) ?? 0) === s) return;
|
|
28
|
+
let i = this.index.get(e);
|
|
29
|
+
i === void 0 && (i = this.order.length, this.order.push(e), this.index.set(e, i)), this.last.set(e, s), this.changes.push([t, i, s]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
class h {
|
|
33
|
+
constructor(t) {
|
|
34
|
+
if (this.tape = t, !(t?.version === 1 && Array.isArray(t.actions) && Number.isInteger(t.steps) && Array.isArray(t.changes) && t.changes.every((s, i) => Array.isArray(s) && s.length === 3 && s.every(Number.isFinite) && s[1] >= 0 && s[1] < t.actions.length && (i === 0 || s[0] >= t.changes[i - 1][0])))) throw new Error("InputPlayer: not an input tape (version 1)");
|
|
35
|
+
}
|
|
36
|
+
tape;
|
|
37
|
+
step = 0;
|
|
38
|
+
next = 0;
|
|
39
|
+
values = /* @__PURE__ */ new Map();
|
|
40
|
+
/** Steps played so far. */
|
|
41
|
+
get position() {
|
|
42
|
+
return this.step;
|
|
43
|
+
}
|
|
44
|
+
get done() {
|
|
45
|
+
return this.step >= this.tape.steps;
|
|
46
|
+
}
|
|
47
|
+
/** The next step's values, or null once the tape is over. */
|
|
48
|
+
read() {
|
|
49
|
+
if (this.done) return null;
|
|
50
|
+
const t = this.tape.changes;
|
|
51
|
+
for (; this.next < t.length && t[this.next][0] === this.step; ) {
|
|
52
|
+
const [, e, s] = t[this.next++], i = this.tape.actions[e];
|
|
53
|
+
s === 0 ? this.values.delete(i) : this.values.set(i, s);
|
|
54
|
+
}
|
|
55
|
+
return this.step++, this.values;
|
|
56
|
+
}
|
|
57
|
+
/** Drives `actions` from the tape until it ends; `onEnd` is called on the poll that finds it over. */
|
|
58
|
+
playInto(t, e) {
|
|
59
|
+
t.replay(() => {
|
|
60
|
+
const s = this.read();
|
|
61
|
+
return s === null && e?.(), s;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
h as InputPlayer,
|
|
67
|
+
r as InputRecorder
|
|
68
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class r {
|
|
2
|
+
constructor(t = () => {
|
|
3
|
+
}) {
|
|
4
|
+
this.onRoot = t;
|
|
5
|
+
}
|
|
6
|
+
onRoot;
|
|
7
|
+
handlers = [];
|
|
8
|
+
/** Puts `handler` on top; the returned function takes it off (from anywhere in the stack). */
|
|
9
|
+
push(t) {
|
|
10
|
+
return this.handlers.push(t), () => {
|
|
11
|
+
const s = this.handlers.lastIndexOf(t);
|
|
12
|
+
s >= 0 && this.handlers.splice(s, 1);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
get size() {
|
|
16
|
+
return this.handlers.length;
|
|
17
|
+
}
|
|
18
|
+
/** A back press: offered from the top down; `onRoot` when none uses it. True when a handler used it. */
|
|
19
|
+
press() {
|
|
20
|
+
for (let t = this.handlers.length - 1; t >= 0; t--)
|
|
21
|
+
if (this.handlers[t]()) return !0;
|
|
22
|
+
return this.onRoot(), !1;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function h(n) {
|
|
26
|
+
const t = n.withinMs ?? 2e3, s = n.now ?? (() => Date.now());
|
|
27
|
+
let e = -1 / 0;
|
|
28
|
+
return () => {
|
|
29
|
+
const i = s();
|
|
30
|
+
if (i - e <= t) {
|
|
31
|
+
e = -1 / 0, n.exit();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
e = i, n.notify();
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
r as BackStack,
|
|
39
|
+
h as doubleBackToExit
|
|
40
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
async function i(e, n) {
|
|
2
|
+
const t = await e.addListener("backButton", () => {
|
|
3
|
+
n.press();
|
|
4
|
+
});
|
|
5
|
+
return () => {
|
|
6
|
+
t.remove();
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
async function s(e) {
|
|
10
|
+
if (!e?.getInfo) return 1 / 0;
|
|
11
|
+
try {
|
|
12
|
+
const n = parseInt((await e.getInfo()).build, 10);
|
|
13
|
+
return Number.isFinite(n) ? n : 0;
|
|
14
|
+
} catch {
|
|
15
|
+
return 1 / 0;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function u(e) {
|
|
19
|
+
if (!/^[a-zA-Z][\w]*(\.[a-zA-Z][\w]*)+$/.test(e.appId))
|
|
20
|
+
throw new Error(`capacitorConfig: appId must be reverse-domain, like com.example.game (got '${e.appId}')`);
|
|
21
|
+
const n = e.backgroundColor ?? "#000000", t = e.debug ?? !1, a = {
|
|
22
|
+
appId: e.appId,
|
|
23
|
+
appName: e.appName,
|
|
24
|
+
webDir: e.webDir ?? "dist",
|
|
25
|
+
backgroundColor: n,
|
|
26
|
+
server: { androidScheme: "https", cleartext: !1 },
|
|
27
|
+
android: { backgroundColor: n, allowMixedContent: !1, captureInput: !0, webContentsDebuggingEnabled: t },
|
|
28
|
+
ios: { backgroundColor: n, contentInset: "never", scrollEnabled: !1, webContentsDebuggingEnabled: t },
|
|
29
|
+
plugins: {
|
|
30
|
+
SplashScreen: { launchAutoHide: !1, backgroundColor: n, showSpinner: !1 },
|
|
31
|
+
CapacitorUpdater: { autoUpdate: !1 }
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
return c(a, e.extra ?? {});
|
|
35
|
+
}
|
|
36
|
+
function c(e, n) {
|
|
37
|
+
const t = { ...e };
|
|
38
|
+
for (const [a, r] of Object.entries(n)) {
|
|
39
|
+
const o = t[a];
|
|
40
|
+
t[a] = r && typeof r == "object" && !Array.isArray(r) && o && typeof o == "object" && !Array.isArray(o) ? c(o, r) : r;
|
|
41
|
+
}
|
|
42
|
+
return t;
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
u as capacitorConfig,
|
|
46
|
+
i as installBackButton,
|
|
47
|
+
s as nativeBuildOf
|
|
48
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function r(n = globalThis.document) {
|
|
2
|
+
if (!n?.body) return { top: 0, right: 0, bottom: 0, left: 0 };
|
|
3
|
+
const t = n.createElement("div");
|
|
4
|
+
t.style.cssText = "position:fixed;visibility:hidden;pointer-events:none;padding-top:env(safe-area-inset-top,0px);padding-right:env(safe-area-inset-right,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px)", n.body.appendChild(t);
|
|
5
|
+
const e = getComputedStyle(t), i = (o) => parseFloat(o) || 0, a = { top: i(e.paddingTop), right: i(e.paddingRight), bottom: i(e.paddingBottom), left: i(e.paddingLeft) };
|
|
6
|
+
return t.remove(), a;
|
|
7
|
+
}
|
|
8
|
+
async function l(n = globalThis.navigator?.wakeLock, t = globalThis.document) {
|
|
9
|
+
if (!n) return () => {
|
|
10
|
+
};
|
|
11
|
+
let e = null, i = !1;
|
|
12
|
+
const a = async () => {
|
|
13
|
+
try {
|
|
14
|
+
const s = await n.request("screen");
|
|
15
|
+
if (i) return void s.release();
|
|
16
|
+
e = s, s.addEventListener?.("release", () => {
|
|
17
|
+
e === s && (e = null);
|
|
18
|
+
});
|
|
19
|
+
} catch {
|
|
20
|
+
}
|
|
21
|
+
}, o = () => {
|
|
22
|
+
t?.visibilityState === "visible" && !e && a();
|
|
23
|
+
};
|
|
24
|
+
return await a(), t?.addEventListener("visibilitychange", o), () => {
|
|
25
|
+
i = !0, t?.removeEventListener("visibilitychange", o), e?.release(), e = null;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
l as keepScreenOn,
|
|
30
|
+
r as safeAreaInsets
|
|
31
|
+
};
|
package/dist/mobile.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BackStack as t, doubleBackToExit as a } from "./mobile/backButton.js";
|
|
2
|
+
import { capacitorConfig as c, installBackButton as n, nativeBuildOf as f } from "./mobile/capacitor.js";
|
|
3
|
+
import { keepScreenOn as k, safeAreaInsets as p } from "./mobile/screen.js";
|
|
4
|
+
export {
|
|
5
|
+
t as BackStack,
|
|
6
|
+
c as capacitorConfig,
|
|
7
|
+
a as doubleBackToExit,
|
|
8
|
+
n as installBackButton,
|
|
9
|
+
k as keepScreenOn,
|
|
10
|
+
f as nativeBuildOf,
|
|
11
|
+
p as safeAreaInsets
|
|
12
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { MinHeap as C } from "./MinHeap.js";
|
|
2
|
+
import { isOpen as g, NAV_STEPS as S, canStep as E } from "./navGrid.js";
|
|
3
|
+
function M(o, s, w = {}) {
|
|
4
|
+
const { cost: r, endOnly: l, maxCost: h = 1 / 0 } = w, i = o.width, e = i * o.height, u = new Float32Array(e).fill(1 / 0), x = new Int8Array(e).fill(-1), A = new Uint8Array(e), y = new C(), d = new Uint8Array(e);
|
|
5
|
+
for (const n of s) {
|
|
6
|
+
if (!g(o, n.x, n.y)) continue;
|
|
7
|
+
const t = n.y * i + n.x;
|
|
8
|
+
d[t] = 1, u[t] = 0, y.push(t, 0);
|
|
9
|
+
}
|
|
10
|
+
const k = (n, t) => d[t * i + n] === 1;
|
|
11
|
+
for (; y.size > 0; ) {
|
|
12
|
+
const n = y.pop();
|
|
13
|
+
if (A[n]) continue;
|
|
14
|
+
A[n] = 1;
|
|
15
|
+
const t = n % i, f = n / i | 0;
|
|
16
|
+
if (!(!d[n] && l?.(t, f)))
|
|
17
|
+
for (let c = 0; c < S.length; c++) {
|
|
18
|
+
const [T, U, z] = S[c], I = t - T, F = f - U;
|
|
19
|
+
if (!g(o, I, F) || !E(o, I, F, T, U, l, k)) continue;
|
|
20
|
+
const p = F * i + I;
|
|
21
|
+
if (A[p]) continue;
|
|
22
|
+
const a = u[n] + z + (r ? r(t, f) : 0);
|
|
23
|
+
a >= u[p] || a > h || (u[p] = a, x[p] = c, y.push(p, a));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const O = (n, t) => n >= 0 && t >= 0 && n < i && t < o.height;
|
|
27
|
+
return {
|
|
28
|
+
width: i,
|
|
29
|
+
height: o.height,
|
|
30
|
+
costs: u,
|
|
31
|
+
steps: x,
|
|
32
|
+
stepAt(n, t) {
|
|
33
|
+
if (!O(n, t)) return null;
|
|
34
|
+
const f = x[t * i + n];
|
|
35
|
+
if (f < 0) return null;
|
|
36
|
+
const c = S[f];
|
|
37
|
+
return [c[0], c[1]];
|
|
38
|
+
},
|
|
39
|
+
costAt(n, t) {
|
|
40
|
+
return O(n, t) ? u[t * i + n] : 1 / 0;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function N(o, s, w = o.width * o.height) {
|
|
45
|
+
if (o.costAt(s.x, s.y) === 1 / 0) return null;
|
|
46
|
+
const r = [{ x: s.x, y: s.y }];
|
|
47
|
+
let l = s.x, h = s.y;
|
|
48
|
+
for (let i = 0; i < w; i++) {
|
|
49
|
+
const e = o.stepAt(l, h);
|
|
50
|
+
if (!e) return r;
|
|
51
|
+
l += e[0], h += e[1], r.push({ x: l, y: h });
|
|
52
|
+
}
|
|
53
|
+
return r;
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
M as flowField,
|
|
57
|
+
N as followField
|
|
58
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const M = () => ({ x: 0, y: 0 });
|
|
2
|
+
function h(o, x, t, y) {
|
|
3
|
+
const n = Math.hypot(o, x);
|
|
4
|
+
return n === 0 ? { x: -y.vx, y: -y.vy } : { x: o / n * t - y.vx, y: x / n * t - y.vy };
|
|
5
|
+
}
|
|
6
|
+
function b(o, x, t, y) {
|
|
7
|
+
return h(x - o.x, t - o.y, y, o);
|
|
8
|
+
}
|
|
9
|
+
function I(o, x, t, y, n = 1 / 0) {
|
|
10
|
+
const r = o.x - x, f = o.y - t;
|
|
11
|
+
return r * r + f * f > n * n ? M() : h(r, f, y, o);
|
|
12
|
+
}
|
|
13
|
+
function w(o, x, t, y, n) {
|
|
14
|
+
const r = x - o.x, f = t - o.y, c = Math.hypot(r, f), v = c < n ? y * (c / n) : y;
|
|
15
|
+
return h(r, f, v, o);
|
|
16
|
+
}
|
|
17
|
+
function A(o, x, t, y) {
|
|
18
|
+
let n = 0, r = 0;
|
|
19
|
+
for (const f of x) {
|
|
20
|
+
if (f === o) continue;
|
|
21
|
+
let c = o.x - f.x, v = o.y - f.y, i = Math.hypot(c, v);
|
|
22
|
+
if (i >= t) continue;
|
|
23
|
+
i === 0 ? (c = o.vx - f.vx || 1, v = o.vy - f.vy, i = Math.hypot(c, v), c /= i, v /= i, i = 0) : (c /= i, v /= i);
|
|
24
|
+
const s = (1 - i / t) * y;
|
|
25
|
+
n += c * s, r += v * s;
|
|
26
|
+
}
|
|
27
|
+
return { x: n, y: r };
|
|
28
|
+
}
|
|
29
|
+
function k(o, x, t) {
|
|
30
|
+
let y = 0, n = 0, r = 0;
|
|
31
|
+
for (const f of x)
|
|
32
|
+
f === o || (f.x - o.x) ** 2 + (f.y - o.y) ** 2 > t * t || (y += f.vx, n += f.vy, r++);
|
|
33
|
+
return r === 0 ? M() : { x: y / r - o.vx, y: n / r - o.vy };
|
|
34
|
+
}
|
|
35
|
+
function E(o, x, t, y) {
|
|
36
|
+
let n = 0, r = 0, f = 0;
|
|
37
|
+
for (const c of x)
|
|
38
|
+
c === o || (c.x - o.x) ** 2 + (c.y - o.y) ** 2 > t * t || (n += c.x, r += c.y, f++);
|
|
39
|
+
return f === 0 ? M() : b(o, n / f, r / f, y);
|
|
40
|
+
}
|
|
41
|
+
function O(o, x, t, y) {
|
|
42
|
+
const n = Math.floor(o.x / t), r = Math.floor(o.y / t), f = x.stepAt(n, r);
|
|
43
|
+
if (f) return h(f[0], f[1], y, o);
|
|
44
|
+
if (x.costAt(n, r) === 0) return { x: -o.vx, y: -o.vy };
|
|
45
|
+
let c = 1 / 0, v = 0, i = 0;
|
|
46
|
+
for (let s = 1; s <= 2 && c === 1 / 0; s++)
|
|
47
|
+
for (let u = -s; u <= s; u++)
|
|
48
|
+
for (let l = -s; l <= s; l++) {
|
|
49
|
+
if (Math.max(Math.abs(l), Math.abs(u)) !== s) continue;
|
|
50
|
+
const p = x.costAt(n + l, r + u);
|
|
51
|
+
p < c && (c = p, v = l, i = u);
|
|
52
|
+
}
|
|
53
|
+
return c === 1 / 0 ? { x: -o.vx, y: -o.vy } : b(o, (n + v + 0.5) * t, (r + i + 0.5) * t, y);
|
|
54
|
+
}
|
|
55
|
+
function Z(o, ...x) {
|
|
56
|
+
let t = 0, y = 0;
|
|
57
|
+
for (const [r, f] of x)
|
|
58
|
+
t += r.x * f, y += r.y * f;
|
|
59
|
+
const n = Math.hypot(t, y);
|
|
60
|
+
return n > o && (t = t / n * o, y = y / n * o), { x: t, y };
|
|
61
|
+
}
|
|
62
|
+
function j(o, x, t, y) {
|
|
63
|
+
o.vx += x.x * y, o.vy += x.y * y;
|
|
64
|
+
const n = Math.hypot(o.vx, o.vy);
|
|
65
|
+
n > t && (o.vx = o.vx / n * t, o.vy = o.vy / n * t), o.x += o.vx * y, o.y += o.vy * y;
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
k as alignment,
|
|
69
|
+
j as applySteering,
|
|
70
|
+
w as arrive,
|
|
71
|
+
E as cohesion,
|
|
72
|
+
Z as combineSteering,
|
|
73
|
+
I as flee,
|
|
74
|
+
O as followFlow,
|
|
75
|
+
b as seek,
|
|
76
|
+
A as separation
|
|
77
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { timeoutSignal as p } from "../platform/timeoutSignal.js";
|
|
2
|
+
class g extends Error {
|
|
3
|
+
constructor(t, e, r, n, u) {
|
|
4
|
+
super(r), this.status = t, this.code = e, this.details = n, this.body = u, this.name = "ApiError";
|
|
5
|
+
}
|
|
6
|
+
status;
|
|
7
|
+
code;
|
|
8
|
+
details;
|
|
9
|
+
body;
|
|
10
|
+
}
|
|
11
|
+
function y(i) {
|
|
12
|
+
if (!i || typeof i != "object") return {};
|
|
13
|
+
const t = i;
|
|
14
|
+
return {
|
|
15
|
+
code: typeof t.code == "string" ? t.code : void 0,
|
|
16
|
+
message: typeof t.message == "string" ? t.message : void 0,
|
|
17
|
+
details: t.details && typeof t.details == "object" ? t.details : void 0
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function v(i) {
|
|
21
|
+
const t = AbortSignal.any;
|
|
22
|
+
if (typeof t == "function") return t.call(AbortSignal, [...i]);
|
|
23
|
+
const e = new AbortController();
|
|
24
|
+
for (const r of i) {
|
|
25
|
+
if (r.aborted) {
|
|
26
|
+
e.abort(r.reason);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
r.addEventListener("abort", () => e.abort(r.reason), { once: !0 });
|
|
30
|
+
}
|
|
31
|
+
return e.signal;
|
|
32
|
+
}
|
|
33
|
+
class E {
|
|
34
|
+
constructor(t) {
|
|
35
|
+
this.options = t;
|
|
36
|
+
}
|
|
37
|
+
options;
|
|
38
|
+
token = null;
|
|
39
|
+
/** A new access token for a 401 (`RefreshResult`); unset, a 401 is simply thrown. */
|
|
40
|
+
refresher = null;
|
|
41
|
+
/** Called when a 401 ends the session: no refresher, a refused refresh, or a retry refused again. */
|
|
42
|
+
onUnauthorized = null;
|
|
43
|
+
get accessToken() {
|
|
44
|
+
return this.token;
|
|
45
|
+
}
|
|
46
|
+
setToken(t) {
|
|
47
|
+
this.token = t;
|
|
48
|
+
}
|
|
49
|
+
/** Sends a request and returns its parsed JSON body (undefined for an empty or unreadable one). */
|
|
50
|
+
async request(t, e, r, n = {}, u = !1) {
|
|
51
|
+
const o = this.options, l = { Accept: "application/json", ...o.headers?.(), ...n.headers };
|
|
52
|
+
r !== void 0 && (l["Content-Type"] = "application/json");
|
|
53
|
+
const f = this.token;
|
|
54
|
+
f && (l.Authorization = `Bearer ${f}`);
|
|
55
|
+
const w = p(n.timeoutMs ?? o.timeoutMs ?? 1e4), b = n.signal ? v([w, n.signal]) : w;
|
|
56
|
+
let s, h;
|
|
57
|
+
try {
|
|
58
|
+
const a = typeof o.baseUrl == "function" ? o.baseUrl(e) : o.baseUrl;
|
|
59
|
+
s = await (o.fetch ?? fetch)(a + e, {
|
|
60
|
+
method: t,
|
|
61
|
+
headers: l,
|
|
62
|
+
body: r !== void 0 ? JSON.stringify(r) : void 0,
|
|
63
|
+
signal: b
|
|
64
|
+
}), h = s.status === 204 ? "" : await s.text();
|
|
65
|
+
} catch (a) {
|
|
66
|
+
throw n.signal?.aborted ? new g(0, "ABORTED", "Aborted.") : (console.warn("[api] network error", t, e, a), this.networkError());
|
|
67
|
+
}
|
|
68
|
+
let c;
|
|
69
|
+
if (h)
|
|
70
|
+
try {
|
|
71
|
+
c = JSON.parse(h);
|
|
72
|
+
} catch {
|
|
73
|
+
c = void 0;
|
|
74
|
+
}
|
|
75
|
+
if (s.ok) return c;
|
|
76
|
+
const d = (o.describe ?? y)(c, s.status), k = new g(s.status, d.code ?? `HTTP_${s.status}`, d.message ?? `HTTP ${s.status}`, d.details, c);
|
|
77
|
+
if (o.onError?.(k), o.onStatus?.[s.status]?.(k), s.status === 401 && this.token && !u && !o.noRefresh?.(e)) {
|
|
78
|
+
if (f !== this.token) return this.request(t, e, r, n, !0);
|
|
79
|
+
if (this.refresher) {
|
|
80
|
+
const a = await this.refresher().catch(() => null);
|
|
81
|
+
if (a !== null && a !== "refused")
|
|
82
|
+
return this.token = a, this.request(t, e, r, n, !0);
|
|
83
|
+
if (a === null) throw this.networkError();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
throw s.status === 401 && this.token && this.onUnauthorized?.(), k;
|
|
87
|
+
}
|
|
88
|
+
networkError() {
|
|
89
|
+
const t = this.options.networkMessage;
|
|
90
|
+
return new g(0, "NETWORK", typeof t == "function" ? t() : t ?? "Cannot reach the server.");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
E as ApiClient,
|
|
95
|
+
g as ApiError
|
|
96
|
+
};
|
|
@@ -1,55 +1,62 @@
|
|
|
1
1
|
class x {
|
|
2
|
-
constructor(
|
|
3
|
-
this.delayMs =
|
|
2
|
+
constructor(e = 100, a = 120, t = 30) {
|
|
3
|
+
this.delayMs = e, this.maxExtrapolateMs = a, this.keep = t;
|
|
4
4
|
}
|
|
5
5
|
delayMs;
|
|
6
6
|
maxExtrapolateMs;
|
|
7
7
|
keep;
|
|
8
8
|
samples = /* @__PURE__ */ new Map();
|
|
9
9
|
/** Records every body of a snapshot taken at `time`. */
|
|
10
|
-
push(
|
|
11
|
-
for (const [t, n,
|
|
10
|
+
push(e, a) {
|
|
11
|
+
for (const [t, n, r, h, m, p, c] of a) {
|
|
12
12
|
let i = this.samples.get(t);
|
|
13
13
|
i || (i = [], this.samples.set(t, i));
|
|
14
14
|
const l = i[i.length - 1];
|
|
15
|
-
l &&
|
|
15
|
+
l && e <= l.time || (i.push({ time: e, x: n, y: r, aim: h, anim: m, hp: p, flags: c }), i.length > this.keep && i.splice(0, i.length - this.keep));
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* The server time bodies are drawn at when it is `now` (`serverNow()`): what a shot should carry, so a server with
|
|
20
|
+
* lag compensation judges it against the picture the player aimed at.
|
|
21
|
+
*/
|
|
22
|
+
viewTime(e) {
|
|
23
|
+
return e - this.delayMs;
|
|
24
|
+
}
|
|
18
25
|
/** Forgets a body (it left view). */
|
|
19
|
-
remove(
|
|
20
|
-
this.samples.delete(
|
|
26
|
+
remove(e) {
|
|
27
|
+
this.samples.delete(e);
|
|
21
28
|
}
|
|
22
|
-
has(
|
|
23
|
-
return this.samples.has(
|
|
29
|
+
has(e) {
|
|
30
|
+
return this.samples.has(e);
|
|
24
31
|
}
|
|
25
32
|
ids() {
|
|
26
33
|
return this.samples.keys();
|
|
27
34
|
}
|
|
28
35
|
/** Where body `id` should be drawn at server time `now`, or null if nothing is known of it. */
|
|
29
|
-
sample(
|
|
30
|
-
const t = this.samples.get(
|
|
36
|
+
sample(e, a) {
|
|
37
|
+
const t = this.samples.get(e);
|
|
31
38
|
if (!t || t.length === 0) return null;
|
|
32
|
-
const n = a - this.delayMs,
|
|
33
|
-
if (n <=
|
|
39
|
+
const n = a - this.delayMs, r = t[0];
|
|
40
|
+
if (n <= r.time || t.length === 1) return g(r);
|
|
34
41
|
for (let i = t.length - 1; i > 0; i--) {
|
|
35
|
-
const l = t[i - 1],
|
|
36
|
-
if (n >= l.time && n <=
|
|
37
|
-
const u =
|
|
38
|
-
return f(l,
|
|
42
|
+
const l = t[i - 1], o = t[i];
|
|
43
|
+
if (n >= l.time && n <= o.time) {
|
|
44
|
+
const u = o.time === l.time ? 1 : (n - l.time) / (o.time - l.time);
|
|
45
|
+
return f(l, o, u);
|
|
39
46
|
}
|
|
40
47
|
}
|
|
41
48
|
const h = t[t.length - 2], m = t[t.length - 1], p = Math.min(n - m.time, this.maxExtrapolateMs), c = m.time === h.time ? 1 : 1 + p / (m.time - h.time);
|
|
42
49
|
return f(h, m, c);
|
|
43
50
|
}
|
|
44
51
|
}
|
|
45
|
-
function g(
|
|
46
|
-
return { x:
|
|
52
|
+
function g(s) {
|
|
53
|
+
return { x: s.x, y: s.y, aim: s.aim, anim: s.anim, hp: s.hp, flags: s.flags };
|
|
47
54
|
}
|
|
48
|
-
function f(
|
|
49
|
-
let t =
|
|
55
|
+
function f(s, e, a) {
|
|
56
|
+
let t = e.aim - s.aim;
|
|
50
57
|
t > Math.PI && (t -= Math.PI * 2), t < -Math.PI && (t += Math.PI * 2);
|
|
51
|
-
const n = a < 1 ?
|
|
52
|
-
return { x:
|
|
58
|
+
const n = a < 1 ? s : e;
|
|
59
|
+
return { x: s.x + (e.x - s.x) * a, y: s.y + (e.y - s.y) * a, aim: s.aim + t * a, anim: n.anim, hp: n.hp, flags: n.flags };
|
|
53
60
|
}
|
|
54
61
|
export {
|
|
55
62
|
x as InterpolationBuffer
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
class k {
|
|
2
|
+
/** `keepMs`: how much history is kept; at least the longest rewind allowed plus a snapshot interval. */
|
|
3
|
+
constructor(s = 1e3) {
|
|
4
|
+
this.keepMs = s;
|
|
5
|
+
}
|
|
6
|
+
keepMs;
|
|
7
|
+
frames = [];
|
|
8
|
+
/** The latest recorded time, or -Infinity before any. */
|
|
9
|
+
get newest() {
|
|
10
|
+
return this.frames.length ? this.frames[this.frames.length - 1].time : -1 / 0;
|
|
11
|
+
}
|
|
12
|
+
get oldest() {
|
|
13
|
+
return this.frames.length ? this.frames[0].time : -1 / 0;
|
|
14
|
+
}
|
|
15
|
+
/** Records every body's position at `time`. A time not after the last one recorded replaces that frame. */
|
|
16
|
+
record(s, t) {
|
|
17
|
+
const e = /* @__PURE__ */ new Map();
|
|
18
|
+
for (const r of t) e.set(r.id, [r.x, r.y]);
|
|
19
|
+
const n = this.frames[this.frames.length - 1];
|
|
20
|
+
n && s <= n.time ? n.pos = e : this.frames.push({ time: s, pos: e });
|
|
21
|
+
const o = s - this.keepMs;
|
|
22
|
+
for (; this.frames.length > 2 && this.frames[1].time <= o; ) this.frames.shift();
|
|
23
|
+
}
|
|
24
|
+
/** Forgets a body everywhere in the history (it left the game, not just the view). */
|
|
25
|
+
forget(s) {
|
|
26
|
+
for (const t of this.frames) t.pos.delete(s);
|
|
27
|
+
}
|
|
28
|
+
clear() {
|
|
29
|
+
this.frames.length = 0;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A time a client claims it saw, kept within `[now - maxRewindMs, now]`: the window a rewind is honoured in. A
|
|
33
|
+
* claim that is not a finite number is taken as `now` (no rewind).
|
|
34
|
+
*/
|
|
35
|
+
static clampTime(s, t, e) {
|
|
36
|
+
return typeof s != "number" || !Number.isFinite(s) ? t : Math.min(t, Math.max(t - e, s));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Where body `id` was at `time`, blended between the frames around it as `InterpolationBuffer` blends; null when
|
|
40
|
+
* the history has no frame of it. Before the oldest frame it is where it was then; after the newest, where it is.
|
|
41
|
+
*/
|
|
42
|
+
at(s, t) {
|
|
43
|
+
const e = this.around(t);
|
|
44
|
+
return e ? b(e[0], e[1], e[2], s) : null;
|
|
45
|
+
}
|
|
46
|
+
/** Every body in the history at `time`. */
|
|
47
|
+
all(s) {
|
|
48
|
+
const t = this.around(s);
|
|
49
|
+
if (!t) return [];
|
|
50
|
+
const [e, n, o] = t, r = /* @__PURE__ */ new Set([...e.pos.keys(), ...n.pos.keys()]), i = [];
|
|
51
|
+
for (const a of r) {
|
|
52
|
+
const h = b(e, n, o, a);
|
|
53
|
+
i.push({ id: a, x: h.x, y: h.y });
|
|
54
|
+
}
|
|
55
|
+
return i;
|
|
56
|
+
}
|
|
57
|
+
/** The bodies whose centre was within `radius` of (x, y) at `time`, nearest first; `except` (the shooter) left out. */
|
|
58
|
+
near(s, t, e, n, o) {
|
|
59
|
+
return this.all(s).filter((i) => i.id !== o && (i.x - t) ** 2 + (i.y - e) ** 2 <= n * n).sort((i, a) => (i.x - t) ** 2 + (i.y - e) ** 2 - ((a.x - t) ** 2 + (a.y - e) ** 2));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A hitscan at `time`: the bodies a ray from (x, y) along (dx, dy) passed within `radius` of, before `range` px, in
|
|
63
|
+
* the order it met them. `except` (the shooter) is left out. Walls are the game's to check against the first hit.
|
|
64
|
+
*/
|
|
65
|
+
alongRay(s, t, e, n, o, r, i, a) {
|
|
66
|
+
const h = Math.hypot(n, o);
|
|
67
|
+
if (h === 0) return [];
|
|
68
|
+
const u = n / h, m = o / h, p = [];
|
|
69
|
+
for (const f of this.all(s)) {
|
|
70
|
+
if (f.id === a) continue;
|
|
71
|
+
const c = (f.x - t) * u + (f.y - e) * m, g = t + u * c - f.x, y = e + m * c - f.y, x = g * g + y * y;
|
|
72
|
+
if (x > i * i) continue;
|
|
73
|
+
const M = c - Math.sqrt(i * i - x);
|
|
74
|
+
c < -i || M > r || p.push({ id: f.id, x: f.x, y: f.y, along: Math.max(0, M) });
|
|
75
|
+
}
|
|
76
|
+
return p.sort((f, c) => f.along - c.along);
|
|
77
|
+
}
|
|
78
|
+
/** The two frames around `time` and how far between them it is (0 at the first, 1 at the second). */
|
|
79
|
+
around(s) {
|
|
80
|
+
const t = this.frames;
|
|
81
|
+
if (t.length === 0) return null;
|
|
82
|
+
if (s <= t[0].time) return [t[0], t[0], 0];
|
|
83
|
+
const e = t[t.length - 1];
|
|
84
|
+
if (s >= e.time) return [e, e, 0];
|
|
85
|
+
for (let n = t.length - 1; n > 0; n--) {
|
|
86
|
+
const o = t[n - 1], r = t[n];
|
|
87
|
+
if (s >= o.time && s <= r.time) return [o, r, r.time === o.time ? 1 : (s - o.time) / (r.time - o.time)];
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function b(l, s, t, e) {
|
|
93
|
+
const n = l.pos.get(e), o = s.pos.get(e);
|
|
94
|
+
if (n && o) return { x: n[0] + (o[0] - n[0]) * t, y: n[1] + (o[1] - n[1]) * t };
|
|
95
|
+
const r = n ?? o;
|
|
96
|
+
return r ? { x: r[0], y: r[1] } : null;
|
|
97
|
+
}
|
|
98
|
+
export {
|
|
99
|
+
k as LagCompensator
|
|
100
|
+
};
|