@rpgjs/client 5.0.0-beta.12 → 5.0.0-beta.14
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 +18 -0
- package/dist/Game/Object.d.ts +2 -0
- package/dist/Game/Object.js +20 -6
- package/dist/Game/Object.js.map +1 -1
- package/dist/Gui/Gui.d.ts +3 -2
- package/dist/Gui/Gui.js +18 -6
- package/dist/Gui/Gui.js.map +1 -1
- package/dist/RpgClient.d.ts +21 -1
- package/dist/RpgClientEngine.d.ts +20 -2
- package/dist/RpgClientEngine.js +182 -17
- package/dist/RpgClientEngine.js.map +1 -1
- package/dist/components/character.ce.js +84 -9
- package/dist/components/character.ce.js.map +1 -1
- package/dist/components/gui/dialogbox/index.ce.js +27 -12
- package/dist/components/gui/dialogbox/index.ce.js.map +1 -1
- package/dist/components/gui/gameover.ce.js +4 -3
- package/dist/components/gui/gameover.ce.js.map +1 -1
- package/dist/components/gui/menu/equip-menu.ce.js +9 -8
- package/dist/components/gui/menu/equip-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/exit-menu.ce.js +7 -5
- package/dist/components/gui/menu/exit-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/items-menu.ce.js +8 -7
- package/dist/components/gui/menu/items-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/main-menu.ce.js +12 -11
- package/dist/components/gui/menu/main-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/options-menu.ce.js +7 -5
- package/dist/components/gui/menu/options-menu.ce.js.map +1 -1
- package/dist/components/gui/menu/skills-menu.ce.js +4 -2
- package/dist/components/gui/menu/skills-menu.ce.js.map +1 -1
- package/dist/components/gui/notification/notification.ce.js +4 -1
- package/dist/components/gui/notification/notification.ce.js.map +1 -1
- package/dist/components/gui/save-load.ce.js +10 -9
- package/dist/components/gui/save-load.ce.js.map +1 -1
- package/dist/components/gui/shop/shop.ce.js +17 -16
- package/dist/components/gui/shop/shop.ce.js.map +1 -1
- package/dist/components/gui/title-screen.ce.js +4 -3
- package/dist/components/gui/title-screen.ce.js.map +1 -1
- package/dist/components/interaction-components.ce.js +20 -0
- package/dist/components/interaction-components.ce.js.map +1 -0
- package/dist/components/scenes/canvas.ce.js +66 -33
- package/dist/components/scenes/canvas.ce.js.map +1 -1
- package/dist/components/scenes/draw-map.ce.js +18 -13
- package/dist/components/scenes/draw-map.ce.js.map +1 -1
- package/dist/components/scenes/event-layer.ce.js +42 -3
- package/dist/components/scenes/event-layer.ce.js.map +1 -1
- package/dist/i18n.d.ts +55 -0
- package/dist/i18n.js +60 -0
- package/dist/i18n.js.map +1 -0
- package/dist/i18n.spec.d.ts +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -1
- package/dist/module.js +23 -3
- package/dist/module.js.map +1 -1
- package/dist/services/interactions.d.ts +159 -0
- package/dist/services/interactions.js +460 -0
- package/dist/services/interactions.js.map +1 -0
- package/dist/services/interactions.spec.d.ts +1 -0
- package/dist/services/keyboardControls.d.ts +1 -0
- package/dist/services/keyboardControls.js +1 -0
- package/dist/services/keyboardControls.js.map +1 -1
- package/dist/services/loadMap.d.ts +3 -0
- package/dist/services/loadMap.js.map +1 -1
- package/package.json +4 -4
- package/src/Game/Object.spec.ts +14 -1
- package/src/Game/Object.ts +34 -10
- package/src/Gui/Gui.spec.ts +67 -0
- package/src/Gui/Gui.ts +24 -7
- package/src/RpgClient.ts +28 -1
- package/src/RpgClientEngine.ts +254 -29
- package/src/components/character.ce +92 -9
- package/src/components/gui/dialogbox/index.ce +35 -14
- package/src/components/gui/gameover.ce +4 -3
- package/src/components/gui/menu/equip-menu.ce +9 -8
- package/src/components/gui/menu/exit-menu.ce +4 -3
- package/src/components/gui/menu/items-menu.ce +8 -7
- package/src/components/gui/menu/main-menu.ce +12 -11
- package/src/components/gui/menu/options-menu.ce +4 -3
- package/src/components/gui/menu/skills-menu.ce +2 -1
- package/src/components/gui/notification/notification.ce +7 -1
- package/src/components/gui/save-load.ce +11 -10
- package/src/components/gui/shop/shop.ce +17 -16
- package/src/components/gui/title-screen.ce +4 -3
- package/src/components/interaction-components.ce +23 -0
- package/src/components/scenes/canvas.ce +68 -31
- package/src/components/scenes/draw-map.ce +16 -5
- package/src/components/scenes/event-layer.ce +54 -2
- package/src/i18n.spec.ts +39 -0
- package/src/i18n.ts +59 -0
- package/src/index.ts +2 -0
- package/src/module.ts +32 -10
- package/src/services/interactions.spec.ts +175 -0
- package/src/services/interactions.ts +722 -0
- package/src/services/keyboardControls.ts +2 -1
- package/src/services/loadMap.ts +3 -1
package/dist/RpgClientEngine.js
CHANGED
|
@@ -23,12 +23,68 @@ import { normalizeRoomMapId } from "./utils/mapId.js";
|
|
|
23
23
|
import { ProjectileManager } from "./Game/ProjectileManager.js";
|
|
24
24
|
import { ClientVisualRegistry } from "./Game/ClientVisuals.js";
|
|
25
25
|
import { createClientPointerContext } from "./services/pointerContext.js";
|
|
26
|
+
import { RpgClientInteractions } from "./services/interactions.js";
|
|
26
27
|
import { EventComponentResolverRegistry } from "./Game/EventComponentResolver.js";
|
|
28
|
+
import { RpgClientBuiltinI18n } from "./i18n.js";
|
|
27
29
|
import { Howl, bootstrapCanvas, signal, trigger } from "canvasengine";
|
|
28
|
-
import { Direction, ModulesToken, PredictionController, Vector2, normalizeLightingState } from "@rpgjs/common";
|
|
30
|
+
import { Direction, ModulesToken, PredictionController, Vector2, getOrCreateI18nService, normalizeLightingState } from "@rpgjs/common";
|
|
29
31
|
import { BehaviorSubject, combineLatest, filter, lastValueFrom, switchMap, take } from "rxjs";
|
|
30
32
|
import * as PIXI from "pixi.js";
|
|
31
33
|
//#region src/RpgClientEngine.ts
|
|
34
|
+
var DEFAULT_DASH_ADDITIONAL_SPEED = 8;
|
|
35
|
+
var DEFAULT_DASH_DURATION_MS = 180;
|
|
36
|
+
var DEFAULT_DASH_COOLDOWN_MS = 450;
|
|
37
|
+
var isDashInput = (input) => typeof input === "object" && input !== null && input.type === "dash";
|
|
38
|
+
var isMoveInput = (input) => typeof input === "object" && input !== null && input.type === "move";
|
|
39
|
+
var resolveMoveDirection = (input) => {
|
|
40
|
+
if (isMoveInput(input)) return input.direction;
|
|
41
|
+
if (typeof input === "string" || typeof input === "number") return input;
|
|
42
|
+
};
|
|
43
|
+
var directionToVector = (direction) => {
|
|
44
|
+
switch (direction) {
|
|
45
|
+
case Direction.Left: return {
|
|
46
|
+
x: -1,
|
|
47
|
+
y: 0
|
|
48
|
+
};
|
|
49
|
+
case Direction.Right: return {
|
|
50
|
+
x: 1,
|
|
51
|
+
y: 0
|
|
52
|
+
};
|
|
53
|
+
case Direction.Up: return {
|
|
54
|
+
x: 0,
|
|
55
|
+
y: -1
|
|
56
|
+
};
|
|
57
|
+
case Direction.Down:
|
|
58
|
+
default: return {
|
|
59
|
+
x: 0,
|
|
60
|
+
y: 1
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var vectorToDirection = (direction) => {
|
|
65
|
+
if (Math.abs(direction.x) > Math.abs(direction.y)) return direction.x < 0 ? Direction.Left : Direction.Right;
|
|
66
|
+
return direction.y < 0 ? Direction.Up : Direction.Down;
|
|
67
|
+
};
|
|
68
|
+
var normalizeDashInput = (input, fallbackDirection) => {
|
|
69
|
+
const rawDirection = input.direction ?? directionToVector(fallbackDirection);
|
|
70
|
+
const rawX = Number(rawDirection?.x ?? 0);
|
|
71
|
+
const rawY = Number(rawDirection?.y ?? 0);
|
|
72
|
+
const magnitude = Math.hypot(rawX, rawY);
|
|
73
|
+
if (!Number.isFinite(magnitude) || magnitude <= 0) return null;
|
|
74
|
+
const additionalSpeed = typeof input.additionalSpeed === "number" && Number.isFinite(input.additionalSpeed) ? Math.max(0, Math.min(input.additionalSpeed, 64)) : DEFAULT_DASH_ADDITIONAL_SPEED;
|
|
75
|
+
const duration = typeof input.duration === "number" && Number.isFinite(input.duration) ? Math.max(1, Math.min(input.duration, 1e3)) : DEFAULT_DASH_DURATION_MS;
|
|
76
|
+
const cooldown = typeof input.cooldown === "number" && Number.isFinite(input.cooldown) ? Math.max(0, Math.min(input.cooldown, 5e3)) : DEFAULT_DASH_COOLDOWN_MS;
|
|
77
|
+
return {
|
|
78
|
+
type: "dash",
|
|
79
|
+
direction: {
|
|
80
|
+
x: rawX / magnitude,
|
|
81
|
+
y: rawY / magnitude
|
|
82
|
+
},
|
|
83
|
+
additionalSpeed,
|
|
84
|
+
duration,
|
|
85
|
+
cooldown
|
|
86
|
+
};
|
|
87
|
+
};
|
|
32
88
|
var RpgClientEngine = class {
|
|
33
89
|
constructor(context) {
|
|
34
90
|
this.context = context;
|
|
@@ -37,10 +93,12 @@ var RpgClientEngine = class {
|
|
|
37
93
|
this.width = signal("100%");
|
|
38
94
|
this.height = signal("100%");
|
|
39
95
|
this.spritesheets = /* @__PURE__ */ new Map();
|
|
96
|
+
this.spritesheetPromises = /* @__PURE__ */ new Map();
|
|
40
97
|
this.sounds = /* @__PURE__ */ new Map();
|
|
41
98
|
this.componentAnimations = [];
|
|
42
99
|
this.clientVisuals = new ClientVisualRegistry();
|
|
43
100
|
this.pointer = createClientPointerContext();
|
|
101
|
+
this.interactions = new RpgClientInteractions(this);
|
|
44
102
|
this.particleSettings = { emitters: [] };
|
|
45
103
|
this.playerIdSignal = signal(null);
|
|
46
104
|
this.spriteComponentsBehind = signal([]);
|
|
@@ -58,6 +116,7 @@ var RpgClientEngine = class {
|
|
|
58
116
|
this.lastClientPhysicsStepAt = 0;
|
|
59
117
|
this.frameOffset = 0;
|
|
60
118
|
this.latestServerTickAt = 0;
|
|
119
|
+
this.dashLockedUntil = 0;
|
|
61
120
|
this.rtt = 0;
|
|
62
121
|
this.pingInterval = null;
|
|
63
122
|
this.PING_INTERVAL_MS = 5e3;
|
|
@@ -80,6 +139,8 @@ var RpgClientEngine = class {
|
|
|
80
139
|
this.guiService = inject(RpgGui);
|
|
81
140
|
this.loadMapService = inject(LoadMapToken);
|
|
82
141
|
this.hooks = inject(ModulesToken);
|
|
142
|
+
this.i18nService = getOrCreateI18nService(context);
|
|
143
|
+
this.i18nService.addMessages(RpgClientBuiltinI18n, "rpgjs-client", 0);
|
|
83
144
|
this.projectiles = new ProjectileManager(this.hooks, (projectile) => this.predictProjectileImpact(projectile));
|
|
84
145
|
this.globalConfig = inject(GlobalConfigToken);
|
|
85
146
|
if (!this.globalConfig) this.globalConfig = {};
|
|
@@ -103,6 +164,21 @@ var RpgClientEngine = class {
|
|
|
103
164
|
this.predictionEnabled = this.globalConfig?.prediction?.enabled !== false;
|
|
104
165
|
this.initializePredictionController();
|
|
105
166
|
}
|
|
167
|
+
setLocale(locale) {
|
|
168
|
+
this.locale = locale;
|
|
169
|
+
}
|
|
170
|
+
getLocale() {
|
|
171
|
+
return this.locale || this.i18nService.defaultLocale;
|
|
172
|
+
}
|
|
173
|
+
t(key, params) {
|
|
174
|
+
return this.i18nService.t(key, params, this.getLocale());
|
|
175
|
+
}
|
|
176
|
+
i18n() {
|
|
177
|
+
return {
|
|
178
|
+
locale: this.getLocale(),
|
|
179
|
+
t: (key, params) => this.t(key, params)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
106
182
|
/**
|
|
107
183
|
* Assigns a CanvasEngine KeyboardControls instance to the dependency injection context
|
|
108
184
|
*
|
|
@@ -167,7 +243,6 @@ var RpgClientEngine = class {
|
|
|
167
243
|
this.renderer = app.renderer;
|
|
168
244
|
this.setupPointerTracking();
|
|
169
245
|
this.tick = canvasElement?.propObservables?.context["tick"].observable;
|
|
170
|
-
this.flushPendingSyncPackets();
|
|
171
246
|
const inputCheckSubscription = this.tick.subscribe(() => {
|
|
172
247
|
if (Date.now() - this.lastInputTime > 100) {
|
|
173
248
|
const player = this.getCurrentPlayer();
|
|
@@ -178,6 +253,7 @@ var RpgClientEngine = class {
|
|
|
178
253
|
this.tickSubscriptions.push(inputCheckSubscription);
|
|
179
254
|
this.hooks.callHooks("client-spritesheets-load", this).subscribe();
|
|
180
255
|
this.hooks.callHooks("client-spritesheetResolver-load", this).subscribe();
|
|
256
|
+
this.flushPendingSyncPackets();
|
|
181
257
|
this.hooks.callHooks("client-sounds-load", this).subscribe();
|
|
182
258
|
this.hooks.callHooks("client-soundResolver-load", this).subscribe();
|
|
183
259
|
RpgSound.init(this);
|
|
@@ -187,6 +263,7 @@ var RpgClientEngine = class {
|
|
|
187
263
|
this.hooks.callHooks("client-componentAnimations-load", this).subscribe();
|
|
188
264
|
this.hooks.callHooks("client-clientVisuals-load", this).subscribe();
|
|
189
265
|
this.hooks.callHooks("client-projectiles-load", this).subscribe();
|
|
266
|
+
this.hooks.callHooks("client-interactions-load", this).subscribe();
|
|
190
267
|
this.hooks.callHooks("client-sprite-load", this).subscribe();
|
|
191
268
|
await lastValueFrom(this.hooks.callHooks("client-engine-onStart", this));
|
|
192
269
|
this.resizeHandler = () => {
|
|
@@ -218,7 +295,7 @@ var RpgClientEngine = class {
|
|
|
218
295
|
const canvas = renderer?.canvas ?? renderer?.view ?? this.canvasApp?.canvas;
|
|
219
296
|
if (!canvas || typeof canvas.addEventListener !== "function") return;
|
|
220
297
|
this.pointerCanvas = canvas;
|
|
221
|
-
|
|
298
|
+
const updatePointer = (event) => {
|
|
222
299
|
const rect = canvas.getBoundingClientRect();
|
|
223
300
|
const screen = {
|
|
224
301
|
x: event.clientX - rect.left,
|
|
@@ -241,11 +318,59 @@ var RpgClientEngine = class {
|
|
|
241
318
|
}
|
|
242
319
|
this.pointer.update(screen, world);
|
|
243
320
|
};
|
|
321
|
+
this.pointerMoveHandler = (event) => {
|
|
322
|
+
updatePointer(event);
|
|
323
|
+
this.interactions.handlePointerMove(event);
|
|
324
|
+
};
|
|
325
|
+
this.pointerUpHandler = (event) => {
|
|
326
|
+
updatePointer(event);
|
|
327
|
+
this.interactions.handlePointerUp(event);
|
|
328
|
+
};
|
|
329
|
+
this.pointerCancelHandler = (event) => {
|
|
330
|
+
updatePointer(event);
|
|
331
|
+
this.interactions.cancelDrag(event);
|
|
332
|
+
};
|
|
244
333
|
canvas.addEventListener("pointermove", this.pointerMoveHandler);
|
|
245
334
|
canvas.addEventListener("pointerdown", this.pointerMoveHandler);
|
|
335
|
+
canvas.addEventListener("pointerup", this.pointerUpHandler);
|
|
336
|
+
canvas.addEventListener("pointercancel", this.pointerCancelHandler);
|
|
337
|
+
canvas.addEventListener("pointerleave", this.pointerCancelHandler);
|
|
338
|
+
}
|
|
339
|
+
updatePointerFromInteractionEvent(event) {
|
|
340
|
+
const global = event?.global ?? event?.data?.global;
|
|
341
|
+
if (!global) {
|
|
342
|
+
this.pointer.updateFromEvent(event);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const screen = {
|
|
346
|
+
x: Number(global.x),
|
|
347
|
+
y: Number(global.y)
|
|
348
|
+
};
|
|
349
|
+
if (!Number.isFinite(screen.x) || !Number.isFinite(screen.y)) {
|
|
350
|
+
this.pointer.updateFromEvent(event);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const viewport = this.findViewportInstance();
|
|
354
|
+
if (viewport && typeof viewport.toWorld === "function") {
|
|
355
|
+
const point = viewport.toWorld(screen.x, screen.y);
|
|
356
|
+
this.pointer.update(screen, {
|
|
357
|
+
x: Number(point.x),
|
|
358
|
+
y: Number(point.y)
|
|
359
|
+
});
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
this.pointer.update(screen);
|
|
246
363
|
}
|
|
247
364
|
findViewportInstance() {
|
|
248
|
-
|
|
365
|
+
const find = (node) => {
|
|
366
|
+
if (!node) return void 0;
|
|
367
|
+
if (typeof node?.toWorld === "function" || node?.constructor?.name === "Viewport") return node;
|
|
368
|
+
for (const child of node.children ?? []) {
|
|
369
|
+
const viewport = find(child);
|
|
370
|
+
if (viewport) return viewport;
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
return find(this.canvasApp?.stage);
|
|
249
374
|
}
|
|
250
375
|
prepareSyncPayload(data) {
|
|
251
376
|
const payload = { ...data ?? {} };
|
|
@@ -569,6 +694,8 @@ var RpgClientEngine = class {
|
|
|
569
694
|
throw error;
|
|
570
695
|
}
|
|
571
696
|
const res = await this.loadMapService.load(mapId);
|
|
697
|
+
const loadedLighting = typeof res?.lighting !== "undefined" ? res.lighting : res?.data?.lighting;
|
|
698
|
+
if (typeof loadedLighting !== "undefined") this.sceneMap.lightingState.set(normalizeLightingState(loadedLighting));
|
|
572
699
|
this.sceneMap.data.set(res);
|
|
573
700
|
if (this.playerIdSignal()) this.playerIdReceived$.next(true);
|
|
574
701
|
const players = this.sceneMap.players();
|
|
@@ -637,12 +764,20 @@ var RpgClientEngine = class {
|
|
|
637
764
|
getSpriteSheet(id) {
|
|
638
765
|
if (this.spritesheets.has(id)) return this.spritesheets.get(id);
|
|
639
766
|
if (this.spritesheetResolver) {
|
|
767
|
+
if (this.spritesheetPromises.has(id)) return this.spritesheetPromises.get(id);
|
|
640
768
|
const result = this.spritesheetResolver(id);
|
|
641
|
-
if (result instanceof Promise)
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
769
|
+
if (result instanceof Promise) {
|
|
770
|
+
const promise = result.then((spritesheet) => {
|
|
771
|
+
if (spritesheet) this.spritesheets.set(id, spritesheet);
|
|
772
|
+
this.spritesheetPromises.delete(id);
|
|
773
|
+
return spritesheet;
|
|
774
|
+
}).catch((error) => {
|
|
775
|
+
this.spritesheetPromises.delete(id);
|
|
776
|
+
throw error;
|
|
777
|
+
});
|
|
778
|
+
this.spritesheetPromises.set(id, promise);
|
|
779
|
+
return promise;
|
|
780
|
+
} else {
|
|
646
781
|
if (result) this.spritesheets.set(id, result);
|
|
647
782
|
return result;
|
|
648
783
|
}
|
|
@@ -1163,10 +1298,17 @@ var RpgClientEngine = class {
|
|
|
1163
1298
|
return;
|
|
1164
1299
|
}
|
|
1165
1300
|
const timestamp = Date.now();
|
|
1301
|
+
const movementInput = isDashInput(input) ? normalizeDashInput(input, currentPlayer?.direction?.()) : input;
|
|
1302
|
+
if (!movementInput) return;
|
|
1303
|
+
if (isDashInput(movementInput)) {
|
|
1304
|
+
const cooldown = movementInput.cooldown ?? DEFAULT_DASH_COOLDOWN_MS;
|
|
1305
|
+
if (timestamp < this.dashLockedUntil) return;
|
|
1306
|
+
this.dashLockedUntil = timestamp + cooldown;
|
|
1307
|
+
}
|
|
1166
1308
|
let frame;
|
|
1167
1309
|
let tick;
|
|
1168
1310
|
if (this.predictionEnabled && this.prediction) {
|
|
1169
|
-
const meta = this.prediction.recordInput(
|
|
1311
|
+
const meta = this.prediction.recordInput(movementInput, timestamp);
|
|
1170
1312
|
frame = meta.frame;
|
|
1171
1313
|
tick = meta.tick;
|
|
1172
1314
|
} else {
|
|
@@ -1175,20 +1317,25 @@ var RpgClientEngine = class {
|
|
|
1175
1317
|
}
|
|
1176
1318
|
this.inputFrameCounter = frame;
|
|
1177
1319
|
this.hooks.callHooks("client-engine-onInput", this, {
|
|
1178
|
-
input,
|
|
1320
|
+
input: movementInput,
|
|
1179
1321
|
playerId: this.playerId
|
|
1180
1322
|
}).subscribe();
|
|
1181
1323
|
const bodyReady = this.ensureCurrentPlayerBody();
|
|
1182
1324
|
if (currentPlayer && bodyReady) {
|
|
1183
|
-
|
|
1184
|
-
this.sceneMap.moveBody(currentPlayer, input);
|
|
1325
|
+
this.applyPredictedMovementInput(currentPlayer, movementInput);
|
|
1185
1326
|
if (this.predictionEnabled && this.prediction) {
|
|
1186
1327
|
this.pendingPredictionFrames.push(frame);
|
|
1187
1328
|
if (this.pendingPredictionFrames.length > 240) this.pendingPredictionFrames = this.pendingPredictionFrames.slice(-240);
|
|
1188
1329
|
}
|
|
1189
1330
|
}
|
|
1190
|
-
this.emitMovePacket(
|
|
1191
|
-
this.lastInputTime = Date.now();
|
|
1331
|
+
this.emitMovePacket(movementInput, frame, tick, timestamp, true);
|
|
1332
|
+
this.lastInputTime = isDashInput(movementInput) ? Date.now() + (movementInput.duration ?? DEFAULT_DASH_DURATION_MS) : Date.now();
|
|
1333
|
+
}
|
|
1334
|
+
async processDash(input = {}) {
|
|
1335
|
+
const currentPlayer = this.sceneMap.getCurrentPlayer();
|
|
1336
|
+
const dashInput = normalizeDashInput(input, typeof currentPlayer?.direction === "function" ? currentPlayer.direction() : currentPlayer?.direction);
|
|
1337
|
+
if (!dashInput) return;
|
|
1338
|
+
await this.processInput({ input: dashInput });
|
|
1192
1339
|
}
|
|
1193
1340
|
processAction(action, data) {
|
|
1194
1341
|
if (this.stopProcessingInput) return;
|
|
@@ -1297,7 +1444,7 @@ var RpgClientEngine = class {
|
|
|
1297
1444
|
input: entry.direction,
|
|
1298
1445
|
x: state.x,
|
|
1299
1446
|
y: state.y,
|
|
1300
|
-
direction: state.direction ?? entry.direction
|
|
1447
|
+
direction: state.direction ?? resolveMoveDirection(entry.direction)
|
|
1301
1448
|
});
|
|
1302
1449
|
}
|
|
1303
1450
|
if (trajectory.length > this.MAX_MOVE_TRAJECTORY_POINTS) return trajectory.slice(-this.MAX_MOVE_TRAJECTORY_POINTS);
|
|
@@ -1332,6 +1479,17 @@ var RpgClientEngine = class {
|
|
|
1332
1479
|
if (now - this.lastMovePathSentAt < this.MOVE_PATH_RESEND_INTERVAL_MS) return;
|
|
1333
1480
|
this.emitMovePacket(latest.direction, latest.frame, latest.tick, now, false);
|
|
1334
1481
|
}
|
|
1482
|
+
applyPredictedMovementInput(player, input) {
|
|
1483
|
+
if (isDashInput(input)) {
|
|
1484
|
+
const direction = vectorToDirection(input.direction);
|
|
1485
|
+
player.changeDirection(direction);
|
|
1486
|
+
return Boolean(this.sceneMap.dashBody?.(player, input));
|
|
1487
|
+
}
|
|
1488
|
+
const direction = resolveMoveDirection(input);
|
|
1489
|
+
if (!direction) return false;
|
|
1490
|
+
player.changeDirection(direction);
|
|
1491
|
+
return Boolean(this.sceneMap.moveBody?.(player, direction));
|
|
1492
|
+
}
|
|
1335
1493
|
getLocalPlayerState() {
|
|
1336
1494
|
const currentPlayer = this.sceneMap?.getCurrentPlayer();
|
|
1337
1495
|
if (!currentPlayer) return {
|
|
@@ -1557,7 +1715,7 @@ var RpgClientEngine = class {
|
|
|
1557
1715
|
const replayInputs = pendingInputs.slice(-600);
|
|
1558
1716
|
for (const entry of replayInputs) {
|
|
1559
1717
|
if (!entry?.direction) continue;
|
|
1560
|
-
this.
|
|
1718
|
+
this.applyPredictedMovementInput(player, entry.direction);
|
|
1561
1719
|
this.sceneMap.stepPredictionTick();
|
|
1562
1720
|
this.prediction?.attachPredictedState(entry.frame, this.getLocalPlayerState());
|
|
1563
1721
|
}
|
|
@@ -1626,7 +1784,14 @@ var RpgClientEngine = class {
|
|
|
1626
1784
|
if (this.pointerMoveHandler && this.pointerCanvas) {
|
|
1627
1785
|
this.pointerCanvas.removeEventListener("pointermove", this.pointerMoveHandler);
|
|
1628
1786
|
this.pointerCanvas.removeEventListener("pointerdown", this.pointerMoveHandler);
|
|
1787
|
+
if (this.pointerUpHandler) this.pointerCanvas.removeEventListener("pointerup", this.pointerUpHandler);
|
|
1788
|
+
if (this.pointerCancelHandler) {
|
|
1789
|
+
this.pointerCanvas.removeEventListener("pointercancel", this.pointerCancelHandler);
|
|
1790
|
+
this.pointerCanvas.removeEventListener("pointerleave", this.pointerCancelHandler);
|
|
1791
|
+
}
|
|
1629
1792
|
this.pointerMoveHandler = void 0;
|
|
1793
|
+
this.pointerUpHandler = void 0;
|
|
1794
|
+
this.pointerCancelHandler = void 0;
|
|
1630
1795
|
this.pointerCanvas = void 0;
|
|
1631
1796
|
}
|
|
1632
1797
|
const rendererStillExists = this.renderer && typeof this.renderer.destroy === "function";
|