@rpgjs/client 5.0.0-beta.10 → 5.0.0-beta.11

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.
Files changed (118) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/Game/ProjectileManager.d.ts +89 -0
  3. package/dist/Game/ProjectileManager.js +179 -0
  4. package/dist/Game/ProjectileManager.js.map +1 -0
  5. package/dist/Game/ProjectileManager.spec.d.ts +1 -0
  6. package/dist/RpgClient.d.ts +53 -13
  7. package/dist/RpgClientEngine.d.ts +25 -4
  8. package/dist/RpgClientEngine.js +197 -48
  9. package/dist/RpgClientEngine.js.map +1 -1
  10. package/dist/components/animations/hit.ce.js.map +1 -1
  11. package/dist/components/character.ce.js +32 -30
  12. package/dist/components/character.ce.js.map +1 -1
  13. package/dist/components/dynamics/bar.ce.js +4 -3
  14. package/dist/components/dynamics/bar.ce.js.map +1 -1
  15. package/dist/components/dynamics/image.ce.js +2 -1
  16. package/dist/components/dynamics/image.ce.js.map +1 -1
  17. package/dist/components/dynamics/shape.ce.js +3 -2
  18. package/dist/components/dynamics/shape.ce.js.map +1 -1
  19. package/dist/components/dynamics/text.ce.js +9 -8
  20. package/dist/components/dynamics/text.ce.js.map +1 -1
  21. package/dist/components/gui/dialogbox/index.ce.js +3 -2
  22. package/dist/components/gui/dialogbox/index.ce.js.map +1 -1
  23. package/dist/components/gui/gameover.ce.js +3 -2
  24. package/dist/components/gui/gameover.ce.js.map +1 -1
  25. package/dist/components/gui/hud/hud.ce.js.map +1 -1
  26. package/dist/components/gui/menu/equip-menu.ce.js +2 -1
  27. package/dist/components/gui/menu/equip-menu.ce.js.map +1 -1
  28. package/dist/components/gui/menu/exit-menu.ce.js +2 -1
  29. package/dist/components/gui/menu/exit-menu.ce.js.map +1 -1
  30. package/dist/components/gui/menu/items-menu.ce.js +3 -2
  31. package/dist/components/gui/menu/items-menu.ce.js.map +1 -1
  32. package/dist/components/gui/menu/main-menu.ce.js +3 -2
  33. package/dist/components/gui/menu/main-menu.ce.js.map +1 -1
  34. package/dist/components/gui/menu/options-menu.ce.js.map +1 -1
  35. package/dist/components/gui/menu/skills-menu.ce.js.map +1 -1
  36. package/dist/components/gui/mobile/mobile.ce.js.map +1 -1
  37. package/dist/components/gui/notification/notification.ce.js.map +1 -1
  38. package/dist/components/gui/save-load.ce.js +2 -1
  39. package/dist/components/gui/save-load.ce.js.map +1 -1
  40. package/dist/components/gui/shop/shop.ce.js +3 -2
  41. package/dist/components/gui/shop/shop.ce.js.map +1 -1
  42. package/dist/components/gui/title-screen.ce.js +3 -2
  43. package/dist/components/gui/title-screen.ce.js.map +1 -1
  44. package/dist/components/index.d.ts +2 -1
  45. package/dist/components/index.js +1 -0
  46. package/dist/components/player-components.ce.js +11 -10
  47. package/dist/components/player-components.ce.js.map +1 -1
  48. package/dist/components/prebuilt/hp-bar.ce.js +4 -3
  49. package/dist/components/prebuilt/hp-bar.ce.js.map +1 -1
  50. package/dist/components/prebuilt/light-halo.ce.js +2 -1
  51. package/dist/components/prebuilt/light-halo.ce.js.map +1 -1
  52. package/dist/components/scenes/canvas.ce.js +12 -4
  53. package/dist/components/scenes/canvas.ce.js.map +1 -1
  54. package/dist/components/scenes/draw-map.ce.js +6 -3
  55. package/dist/components/scenes/draw-map.ce.js.map +1 -1
  56. package/dist/components/scenes/event-layer.ce.js.map +1 -1
  57. package/dist/index.d.ts +3 -0
  58. package/dist/index.js +9 -5
  59. package/dist/module.js +11 -0
  60. package/dist/module.js.map +1 -1
  61. package/dist/services/actionInput.d.ts +12 -0
  62. package/dist/services/actionInput.js +27 -0
  63. package/dist/services/actionInput.js.map +1 -0
  64. package/dist/services/actionInput.spec.d.ts +1 -0
  65. package/dist/services/mmorpg-connection.d.ts +5 -0
  66. package/dist/services/mmorpg-connection.js +50 -0
  67. package/dist/services/mmorpg-connection.js.map +1 -0
  68. package/dist/services/mmorpg-connection.spec.d.ts +1 -0
  69. package/dist/services/mmorpg.d.ts +10 -4
  70. package/dist/services/mmorpg.js +48 -30
  71. package/dist/services/mmorpg.js.map +1 -1
  72. package/dist/services/pointerContext.d.ts +11 -0
  73. package/dist/services/pointerContext.js +48 -0
  74. package/dist/services/pointerContext.js.map +1 -0
  75. package/dist/services/pointerContext.spec.d.ts +1 -0
  76. package/dist/services/standalone-message.d.ts +1 -0
  77. package/dist/services/standalone-message.js +9 -0
  78. package/dist/services/standalone-message.js.map +1 -0
  79. package/dist/services/standalone.js +3 -2
  80. package/dist/services/standalone.js.map +1 -1
  81. package/dist/services/standalone.spec.d.ts +1 -0
  82. package/package.json +7 -7
  83. package/src/Game/ProjectileManager.spec.ts +338 -0
  84. package/src/Game/ProjectileManager.ts +324 -0
  85. package/src/RpgClient.ts +62 -15
  86. package/src/RpgClientEngine.ts +287 -65
  87. package/src/components/character.ce +34 -32
  88. package/src/components/dynamics/bar.ce +4 -3
  89. package/src/components/dynamics/image.ce +2 -1
  90. package/src/components/dynamics/shape.ce +3 -2
  91. package/src/components/dynamics/text.ce +9 -8
  92. package/src/components/gui/dialogbox/index.ce +3 -2
  93. package/src/components/gui/gameover.ce +2 -1
  94. package/src/components/gui/menu/equip-menu.ce +2 -1
  95. package/src/components/gui/menu/exit-menu.ce +2 -1
  96. package/src/components/gui/menu/items-menu.ce +3 -2
  97. package/src/components/gui/menu/main-menu.ce +2 -1
  98. package/src/components/gui/save-load.ce +2 -1
  99. package/src/components/gui/shop/shop.ce +3 -2
  100. package/src/components/gui/title-screen.ce +2 -1
  101. package/src/components/index.ts +2 -1
  102. package/src/components/player-components.ce +11 -10
  103. package/src/components/prebuilt/hp-bar.ce +4 -3
  104. package/src/components/prebuilt/light-halo.ce +2 -2
  105. package/src/components/scenes/canvas.ce +10 -2
  106. package/src/components/scenes/draw-map.ce +17 -3
  107. package/src/index.ts +3 -0
  108. package/src/module.ts +13 -0
  109. package/src/services/actionInput.spec.ts +101 -0
  110. package/src/services/actionInput.ts +53 -0
  111. package/src/services/mmorpg-connection.spec.ts +99 -0
  112. package/src/services/mmorpg-connection.ts +69 -0
  113. package/src/services/mmorpg.ts +60 -34
  114. package/src/services/pointerContext.spec.ts +36 -0
  115. package/src/services/pointerContext.ts +84 -0
  116. package/src/services/standalone-message.ts +7 -0
  117. package/src/services/standalone.spec.ts +34 -0
  118. package/src/services/standalone.ts +3 -2
@@ -1,11 +1,11 @@
1
1
  <Container x={smoothX} y={smoothY} zIndex={z} viewportFollow={shouldFollowCamera} controls onBeforeDestroy visible>
2
2
  @for (compConfig of normalizedComponentsBehind) {
3
3
  <Container>
4
- <compConfig.component object ...compConfig.props />
4
+ <compConfig.component object={sprite} ...compConfig.props />
5
5
  </Container>
6
6
  }
7
- <PlayerComponents object position="bottom" graphicBounds />
8
- <PlayerComponents object position="left" graphicBounds />
7
+ <PlayerComponents object={sprite} position="bottom" graphicBounds />
8
+ <PlayerComponents object={sprite} position="left" graphicBounds />
9
9
  <Particle emit={emitParticleTrigger} settings={particleSettings} zIndex={1000} name={particleName} />
10
10
  <Container>
11
11
  @for (graphicObj of graphicsSignals) {
@@ -21,18 +21,18 @@
21
21
  </Container>
22
22
  }
23
23
  </Container>
24
- <PlayerComponents object position="center" graphicBounds />
25
- <PlayerComponents object position="right" graphicBounds />
26
- <PlayerComponents object position="top" graphicBounds />
24
+ <PlayerComponents object={sprite} position="center" graphicBounds />
25
+ <PlayerComponents object={sprite} position="right" graphicBounds />
26
+ <PlayerComponents object={sprite} position="top" graphicBounds />
27
27
  @for (compConfig of normalizedComponentsInFront) {
28
28
  <Container dependencies={compConfig.dependencies}>
29
- <compConfig.component object ...compConfig.props />
29
+ <compConfig.component object={sprite} ...compConfig.props />
30
30
  </Container>
31
31
  }
32
32
  @for (attachedGui of attachedGuis) {
33
33
  @if (shouldDisplayAttachedGui) {
34
34
  <Container>
35
- <attachedGui.component ...attachedGui.data() dependencies={attachedGui.dependencies} object={object} onFinish={(data) => {
35
+ <attachedGui.component ...attachedGui.data() dependencies={attachedGui.dependencies} object={sprite} onFinish={(data) => {
36
36
  onAttachedGuiFinish(attachedGui, data)
37
37
  }} onInteraction={(name, data) => {
38
38
  onAttachedGuiInteraction(attachedGui, name, data)
@@ -56,8 +56,10 @@
56
56
  import PlayerComponents from "./player-components.ce";
57
57
  import { RpgGui } from "../Gui/Gui";
58
58
  import { getCanMoveValue } from "../utils/readPropValue";
59
+ import { getKeyboardControlBind, resolveKeyboardActionInput } from "../services/actionInput";
59
60
 
60
61
  const { object, id } = defineProps();
62
+ const sprite = object();
61
63
 
62
64
  const client = inject(RpgClientEngine);
63
65
  const hooks = inject(ModulesToken);
@@ -71,9 +73,9 @@
71
73
  const playerId = client.playerIdSignal();
72
74
  const currentPlayer = playerId ? client.sceneMap?.players?.()?.[playerId] : undefined;
73
75
  return readProp(id) === playerId
74
- || readProp(object?.id) === playerId
75
- || object === currentPlayer
76
- || object === client.sceneMap?.getCurrentPlayer?.();
76
+ || readProp(sprite?.id) === playerId
77
+ || sprite === currentPlayer
78
+ || sprite === client.sceneMap?.getCurrentPlayer?.();
77
79
  };
78
80
  const isMe = computed(isCurrentPlayer);
79
81
  const shadowsEnabled = computed(() => {
@@ -150,8 +152,8 @@
150
152
  // The computed will be created in the template when needed
151
153
  return {
152
154
  component: componentRef,
153
- props: typeof propsValue === 'function' ? propsValue(object) : propsValue || {},
154
- dependencies: dependenciesFn ? dependenciesFn(object) : []
155
+ props: typeof propsValue === 'function' ? propsValue(sprite) : propsValue || {},
156
+ dependencies: dependenciesFn ? dependenciesFn(sprite) : []
155
157
  };
156
158
  };
157
159
 
@@ -259,7 +261,7 @@
259
261
  isConnected,
260
262
  graphicsSignals,
261
263
  flashTrigger
262
- } = object;
264
+ } = sprite;
263
265
 
264
266
  /**
265
267
  * Flash configuration signals for dynamic options
@@ -304,11 +306,11 @@
304
306
 
305
307
  const particleSettings = client.particleSettings;
306
308
 
307
- const canControls = () => isMe() && getCanMoveValue(object)
309
+ const canControls = () => isMe() && getCanMoveValue(sprite)
308
310
  const keyboardControls = client.globalConfig.keyboardControls;
309
311
 
310
312
  const visible = computed(() => {
311
- if (object.isEvent()) {
313
+ if (sprite.isEvent()) {
312
314
  return true
313
315
  }
314
316
  return isConnected()
@@ -344,10 +346,10 @@
344
346
  },
345
347
  },
346
348
  action: {
347
- bind: keyboardControls.action,
349
+ bind: getKeyboardControlBind(keyboardControls.action),
348
350
  keyDown() {
349
351
  if (canControls()) {
350
- client.processAction({ action: 'action' })
352
+ client.processAction(resolveKeyboardActionInput(keyboardControls.action, client, sprite))
351
353
  }
352
354
  },
353
355
  },
@@ -373,7 +375,7 @@
373
375
  });
374
376
 
375
377
  const z = computed(() => {
376
- return object.y() + object.z()
378
+ return sprite.y() + sprite.z()
377
379
  });
378
380
 
379
381
  const realAnimationName = signal(animationName());
@@ -734,8 +736,8 @@
734
736
  let beforeRemovePromise = null;
735
737
  let beforeRemoveTransitionValue = null;
736
738
  const resolveRemoveContext = () => {
737
- if (!object._removeTransition) return null;
738
- const value = object._removeTransition();
739
+ if (!sprite._removeTransition) return null;
740
+ const value = sprite._removeTransition();
739
741
  if (!value || typeof value !== 'string') return null;
740
742
  try {
741
743
  const context = JSON.parse(value);
@@ -764,13 +766,13 @@
764
766
  }
765
767
  beforeRemoveTransitionValue = context.__transitionValue;
766
768
  beforeRemovePromise = withTimeout(
767
- lastValueFrom(hooks.callHooks("client-sprite-onBeforeRemove", object, context)),
769
+ lastValueFrom(hooks.callHooks("client-sprite-onBeforeRemove", sprite, context)),
768
770
  context.timeoutMs
769
771
  );
770
772
  return beforeRemovePromise;
771
773
  };
772
774
 
773
- const removeTransitionSubscription = object._removeTransition?.observable?.subscribe(() => {
775
+ const removeTransitionSubscription = sprite._removeTransition?.observable?.subscribe(() => {
774
776
  if (resolveRemoveContext()) {
775
777
  runBeforeRemove();
776
778
  }
@@ -786,10 +788,10 @@
786
788
  else if (!movementAnimations.includes(curr)) {
787
789
  realAnimationName.set(curr);
788
790
  }
789
- if (!isMoving && object.animationIsPlaying && object.animationIsPlaying()) {
791
+ if (!isMoving && sprite.animationIsPlaying && sprite.animationIsPlaying()) {
790
792
  if (movementAnimations.includes(curr)) {
791
- if (typeof object.resetAnimationState === 'function') {
792
- object.resetAnimationState();
793
+ if (typeof sprite.resetAnimationState === 'function') {
794
+ sprite.resetAnimationState();
793
795
  }
794
796
  }
795
797
  }
@@ -806,7 +808,7 @@
806
808
  * await onBeforeDestroy();
807
809
  */
808
810
  const waitForTemporaryAnimationEnd = (maxDuration = 1200) => {
809
- if (!object.animationIsPlaying || !object.animationIsPlaying()) {
811
+ if (!sprite.animationIsPlaying || !sprite.animationIsPlaying()) {
810
812
  return Promise.resolve();
811
813
  }
812
814
 
@@ -822,7 +824,7 @@
822
824
  resolve();
823
825
  };
824
826
  timeout = setTimeout(finish, maxDuration);
825
- subscription = object.animationIsPlaying.observable.subscribe((isPlaying) => {
827
+ subscription = sprite.animationIsPlaying.observable.subscribe((isPlaying) => {
826
828
  if (!isPlaying) finish();
827
829
  });
828
830
  if (finished) subscription.unsubscribe();
@@ -836,13 +838,13 @@
836
838
  animationMovementSubscription.unsubscribe();
837
839
  xSubscription.unsubscribe();
838
840
  ySubscription.unsubscribe();
839
- await lastValueFrom(hooks.callHooks("client-sprite-onDestroy", object))
840
- await lastValueFrom(hooks.callHooks("client-sceneMap-onRemoveSprite", client.sceneMap, object))
841
+ await lastValueFrom(hooks.callHooks("client-sprite-onDestroy", sprite))
842
+ await lastValueFrom(hooks.callHooks("client-sceneMap-onRemoveSprite", client.sceneMap, sprite))
841
843
  }
842
844
 
843
845
  mount((element) => {
844
- hooks.callHooks("client-sprite-onAdd", object).subscribe()
845
- hooks.callHooks("client-sceneMap-onAddSprite", client.sceneMap, object).subscribe()
846
+ hooks.callHooks("client-sprite-onAdd", sprite).subscribe()
847
+ hooks.callHooks("client-sceneMap-onAddSprite", client.sceneMap, sprite).subscribe()
846
848
  effect(() => {
847
849
  if (isCurrentPlayer()) {
848
850
  client.setKeyboardControls(element.directives.controls)
@@ -10,17 +10,18 @@ import { computed } from "canvasengine";
10
10
  import { resolveDynamicValue } from "./parse-value";
11
11
 
12
12
  const { object, current, max, style, text } = defineProps();
13
+ const sprite = object();
13
14
 
14
15
  const read = (prop, fallback) => prop ? prop() : fallback;
15
16
 
16
17
  const toNumber = (value, fallback = 0) => {
17
- const resolved = resolveDynamicValue(value, object);
18
+ const resolved = resolveDynamicValue(value, sprite);
18
19
  const num = typeof resolved === 'number' ? resolved : parseFloat(resolved);
19
20
  return Number.isFinite(num) ? num : fallback;
20
21
  };
21
22
 
22
23
  const toColor = (value, fallback) => {
23
- const resolved = resolveDynamicValue(value, object);
24
+ const resolved = resolveDynamicValue(value, sprite);
24
25
  if (typeof resolved === 'number') return resolved;
25
26
  if (typeof resolved === 'string' && resolved.startsWith('#')) {
26
27
  return parseInt(resolved.slice(1), 16);
@@ -57,7 +58,7 @@ const labelText = computed(() => {
57
58
  .replace(/\{\$max\}/g, String(maxValue()))
58
59
  .replace(/\{\$percent\}/g, String(Math.round(percent() * 100)));
59
60
 
60
- return String(resolveDynamicValue(value, object) ?? '');
61
+ return String(resolveDynamicValue(value, sprite) ?? '');
61
62
  });
62
63
  const labelSize = computed(() => toNumber(config().fontSize, 10));
63
64
  const hasLabel = computed(() => labelText().length > 0);
@@ -7,10 +7,11 @@ import { inject } from "../../core/inject";
7
7
  import { resolveDynamicValue } from "./parse-value";
8
8
 
9
9
  const { object, value } = defineProps();
10
+ const sprite = object();
10
11
  const client = inject(RpgClientEngine);
11
12
 
12
13
  const sheet = computed(() => {
13
- const id = resolveDynamicValue(value?.(), object);
14
+ const id = resolveDynamicValue(value?.(), sprite);
14
15
  if (!id) return null;
15
16
  return {
16
17
  definition: client.getSpriteSheet(id),
@@ -9,17 +9,18 @@ import { getShapeBox, translatePolygonPoints } from "./shape-utils";
9
9
 
10
10
  const props = defineProps();
11
11
  const { object } = props;
12
+ const sprite = object();
12
13
 
13
14
  const read = (prop, fallback) => prop ? prop() : fallback;
14
15
 
15
16
  const toNumber = (value, fallback = 0) => {
16
- const resolved = resolveDynamicValue(value, object);
17
+ const resolved = resolveDynamicValue(value, sprite);
17
18
  const num = typeof resolved === 'number' ? resolved : parseFloat(resolved);
18
19
  return Number.isFinite(num) ? num : fallback;
19
20
  };
20
21
 
21
22
  const toColor = (value, fallback) => {
22
- const resolved = resolveDynamicValue(value, object);
23
+ const resolved = resolveDynamicValue(value, sprite);
23
24
  if (typeof resolved === 'number') return resolved;
24
25
  if (typeof resolved === 'string' && resolved.startsWith('#')) {
25
26
  return parseInt(resolved.slice(1), 16);
@@ -5,11 +5,12 @@ import { computed } from "canvasengine";
5
5
  import { resolveDynamicValue } from "./parse-value";
6
6
 
7
7
  const { object, value, style } = defineProps();
8
+ const sprite = object();
8
9
 
9
10
  const read = (prop, fallback) => prop ? prop() : fallback;
10
11
 
11
12
  const parseNumericStyleValue = (value, object) => {
12
- value = resolveDynamicValue(value, object);
13
+ value = resolveDynamicValue(value, sprite);
13
14
  if (value === undefined || value === null) return undefined;
14
15
  if (typeof value === 'number') return value;
15
16
 
@@ -22,15 +23,15 @@ const getTextStyle = (style) => {
22
23
  const textStyle = {};
23
24
 
24
25
  if (style.fontStyle !== undefined) {
25
- textStyle.fontStyle = resolveDynamicValue(style.fontStyle, object);
26
+ textStyle.fontStyle = resolveDynamicValue(style.fontStyle, sprite);
26
27
  }
27
28
 
28
29
  if (style.fontWeight !== undefined) {
29
- textStyle.fontWeight = resolveDynamicValue(style.fontWeight, object);
30
+ textStyle.fontWeight = resolveDynamicValue(style.fontWeight, sprite);
30
31
  }
31
32
 
32
33
  if (style.stroke !== undefined) {
33
- textStyle.stroke = resolveDynamicValue(style.stroke, object);
34
+ textStyle.stroke = resolveDynamicValue(style.stroke, sprite);
34
35
  }
35
36
 
36
37
  if (style.opacity !== undefined) {
@@ -45,16 +46,16 @@ const getTextStyle = (style) => {
45
46
  }
46
47
 
47
48
  if (style.align !== undefined) {
48
- textStyle.align = resolveDynamicValue(style.align, object);
49
+ textStyle.align = resolveDynamicValue(style.align, sprite);
49
50
  }
50
51
 
51
52
  return textStyle;
52
53
  };
53
54
 
54
- const textValue = computed(() => String(resolveDynamicValue(read(value, ''), object) ?? ''));
55
+ const textValue = computed(() => String(resolveDynamicValue(read(value, ''), sprite) ?? ''));
55
56
  const textColor = computed(() => {
56
57
  const currentStyle = read(style, {});
57
- return currentStyle.fill !== undefined ? resolveDynamicValue(currentStyle.fill, object) : undefined;
58
+ return currentStyle.fill !== undefined ? resolveDynamicValue(currentStyle.fill, sprite) : undefined;
58
59
  });
59
60
  const textSize = computed(() => {
60
61
  const currentStyle = read(style, {});
@@ -62,7 +63,7 @@ const textSize = computed(() => {
62
63
  });
63
64
  const textFontFamily = computed(() => {
64
65
  const currentStyle = read(style, {});
65
- return currentStyle.fontFamily !== undefined ? resolveDynamicValue(currentStyle.fontFamily, object) : undefined;
66
+ return currentStyle.fontFamily !== undefined ? resolveDynamicValue(currentStyle.fontFamily, sprite) : undefined;
66
67
  });
67
68
  const textStyle = computed(() => getTextStyle(read(style, {})));
68
69
  </script>
@@ -53,6 +53,7 @@
53
53
  import { inject } from "../../../core/inject";
54
54
  import { RpgClientEngine } from "../../../RpgClientEngine";
55
55
  import { delay } from "@rpgjs/common";
56
+ import { getKeyboardControlBind } from "../../../services/actionInput";
56
57
 
57
58
  const engine = inject(RpgClientEngine);
58
59
  const currentPlayer = engine.scene.currentPlayer
@@ -172,7 +173,7 @@
172
173
  }
173
174
  },
174
175
  action: {
175
- bind: keyboardControls.action,
176
+ bind: getKeyboardControlBind(keyboardControls.action),
176
177
  keyDown() {
177
178
  if (isTyping()) {
178
179
  finishTyping();
@@ -189,7 +190,7 @@
189
190
 
190
191
  const dialogControls = signal({
191
192
  action: {
192
- bind: keyboardControls.action,
193
+ bind: getKeyboardControlBind(keyboardControls.action),
193
194
  keyDown() {
194
195
  if (isTyping()) {
195
196
  finishTyping();
@@ -31,6 +31,7 @@
31
31
  import { inject } from "../../core/inject";
32
32
  import { RpgClientEngine } from "../../RpgClientEngine";
33
33
  import { RpgGui } from "../../Gui/Gui";
34
+ import { getKeyboardControlBind } from "../../services/actionInput";
34
35
 
35
36
  const engine = inject(RpgClientEngine);
36
37
  const guiService = inject(RpgGui);
@@ -146,7 +147,7 @@
146
147
  }
147
148
  },
148
149
  action: {
149
- bind: keyboardControls.action,
150
+ bind: getKeyboardControlBind(keyboardControls.action),
150
151
  keyDown() {
151
152
  triggerSelect(selectedEntry());
152
153
  }
@@ -90,6 +90,7 @@
90
90
  import { signal, computed, createTabindexNavigator, effect } from "canvasengine";
91
91
  import { inject } from "../../../core/inject";
92
92
  import { RpgClientEngine } from "../../../RpgClientEngine";
93
+ import { getKeyboardControlBind } from "../../../services/actionInput";
93
94
 
94
95
  const engine = inject(RpgClientEngine);
95
96
  const keyboardControls = engine.globalConfig.keyboardControls;
@@ -380,7 +381,7 @@
380
381
  }
381
382
  },
382
383
  action: {
383
- bind: keyboardControls.action,
384
+ bind: getKeyboardControlBind(keyboardControls.action),
384
385
  keyDown() {
385
386
  if (!listEntries().length) return;
386
387
  commitSelection(selectedItem());
@@ -16,6 +16,7 @@
16
16
  import { signal } from "canvasengine";
17
17
  import { inject } from "../../../core/inject";
18
18
  import { RpgClientEngine } from "../../../RpgClientEngine";
19
+ import { getKeyboardControlBind } from "../../../services/actionInput";
19
20
 
20
21
  const engine = inject(RpgClientEngine);
21
22
  const keyboardControls = engine.globalConfig.keyboardControls;
@@ -23,7 +24,7 @@
23
24
 
24
25
  const controls = signal({
25
26
  action: {
26
- bind: keyboardControls.action,
27
+ bind: getKeyboardControlBind(keyboardControls.action),
27
28
  keyDown() {
28
29
  if (onConfirm) onConfirm();
29
30
  }
@@ -90,6 +90,7 @@
90
90
  import { inject } from "../../../core/inject";
91
91
  import { RpgClientEngine } from "../../../RpgClientEngine";
92
92
  import { delay } from "@rpgjs/common";
93
+ import { getKeyboardControlBind } from "../../../services/actionInput";
93
94
 
94
95
  const engine = inject(RpgClientEngine);
95
96
  const keyboardControls = engine.globalConfig.keyboardControls;
@@ -226,7 +227,7 @@
226
227
  }
227
228
  },
228
229
  action: {
229
- bind: keyboardControls.action,
230
+ bind: getKeyboardControlBind(keyboardControls.action),
230
231
  keyDown() {
231
232
  if (!confirmOpen()) return;
232
233
  confirmSelect(selectedConfirm())();
@@ -289,7 +290,7 @@
289
290
  }
290
291
  },
291
292
  action: {
292
- bind: keyboardControls.action,
293
+ bind: getKeyboardControlBind(keyboardControls.action),
293
294
  keyDown() {
294
295
  if (confirmOpen()) {
295
296
  confirmSelect(selectedConfirm())();
@@ -101,6 +101,7 @@
101
101
  import ExitMenu from "./exit-menu.ce";
102
102
  import { getEntityProp } from "../../../utils/getEntityProp";
103
103
  import { delay } from "@rpgjs/common";
104
+ import { getKeyboardControlBind } from "../../../services/actionInput";
104
105
 
105
106
  const engine = inject(RpgClientEngine);
106
107
  const currentPlayer = engine.scene.currentPlayer;
@@ -259,7 +260,7 @@
259
260
  }
260
261
  },
261
262
  action: {
262
- bind: keyboardControls.action,
263
+ bind: getKeyboardControlBind(keyboardControls.action),
263
264
  keyDown() {
264
265
  if (saveOverlay()) return;
265
266
  if (view() !== "menu") return;
@@ -40,6 +40,7 @@
40
40
  import { SaveClientService } from "../../services/save";
41
41
  import { PrebuiltGui } from "@rpgjs/common";
42
42
  import { RpgGui } from "../../Gui/Gui";
43
+ import { getKeyboardControlBind } from "../../services/actionInput";
43
44
 
44
45
  const engine = inject(RpgClientEngine);
45
46
  const saveClient = inject(SaveClientService);
@@ -185,7 +186,7 @@
185
186
  }
186
187
  },
187
188
  action: {
188
- bind: keyboardControls.action,
189
+ bind: getKeyboardControlBind(keyboardControls.action),
189
190
  keyDown() {
190
191
  triggerSelect(selectedSlot());
191
192
  }
@@ -180,6 +180,7 @@
180
180
  import { mount, signal, computed, createTabindexNavigator, effect } from "canvasengine";
181
181
  import { inject } from "../../../core/inject";
182
182
  import { RpgClientEngine } from "../../../RpgClientEngine";
183
+ import { getKeyboardControlBind } from "../../../services/actionInput";
183
184
 
184
185
  const engine = inject(RpgClientEngine)
185
186
  const currentPlayer = engine.scene.currentPlayer
@@ -387,7 +388,7 @@
387
388
  }
388
389
  },
389
390
  action: {
390
- bind: keyboardControls.action,
391
+ bind: getKeyboardControlBind(keyboardControls.action),
391
392
  keyDown() {
392
393
  const mode = selectedModeIndex() === 0 ? 'buy' : 'sell'
393
394
  tradeMode.set(mode)
@@ -433,7 +434,7 @@
433
434
  }
434
435
  },
435
436
  action: {
436
- bind: keyboardControls.action,
437
+ bind: getKeyboardControlBind(keyboardControls.action),
437
438
  keyDown() {
438
439
  if (quantityDialogOpen()) {
439
440
  const item = currentItem()
@@ -31,6 +31,7 @@
31
31
  import { inject } from "../../core/inject";
32
32
  import { RpgClientEngine } from "../../RpgClientEngine";
33
33
  import { RpgGui } from "../../Gui/Gui";
34
+ import { getKeyboardControlBind } from "../../services/actionInput";
34
35
 
35
36
  const engine = inject(RpgClientEngine);
36
37
  const guiService = inject(RpgGui);
@@ -150,7 +151,7 @@
150
151
  }
151
152
  },
152
153
  action: {
153
- bind: keyboardControls.action,
154
+ bind: getKeyboardControlBind(keyboardControls.action),
154
155
  keyDown() {
155
156
  if (guiService.isDisplaying(PrebuiltGui.Save)) return;
156
157
  triggerSelect(selectedEntry());
@@ -1,7 +1,8 @@
1
1
  import EventLayerComponent from "./scenes/event-layer.ce";
2
+ import SceneMap from "./scenes/draw-map.ce";
2
3
  import CharacterComponent from "./character.ce";
3
4
 
4
5
  // Prebuilt sprite components
5
6
  export { HpBar } from "./prebuilt";
6
7
 
7
- export { EventLayerComponent, CharacterComponent }
8
+ export { EventLayerComponent, SceneMap, CharacterComponent }
@@ -29,7 +29,7 @@
29
29
  justifyContent="center"
30
30
  alignItems="center"
31
31
  >
32
- <entry.component object ...entry.props />
32
+ <entry.component object={sprite} ...entry.props />
33
33
  </Container>
34
34
  }
35
35
  </Container>
@@ -54,6 +54,7 @@ const { object, position, graphicBounds } = defineProps({
54
54
  default: 'top'
55
55
  }
56
56
  });
57
+ const sprite = object();
57
58
 
58
59
  const client = inject(RpgClientEngine);
59
60
  const warnedComponents = new Set();
@@ -63,16 +64,16 @@ const readPosition = computed(() => position?.() ?? 'top');
63
64
  const componentSource = computed(() => {
64
65
  switch (readPosition()) {
65
66
  case 'bottom':
66
- return object.componentsBottom?.();
67
+ return sprite.componentsBottom?.();
67
68
  case 'center':
68
- return object.componentsCenter?.();
69
+ return sprite.componentsCenter?.();
69
70
  case 'left':
70
- return object.componentsLeft?.();
71
+ return sprite.componentsLeft?.();
71
72
  case 'right':
72
- return object.componentsRight?.();
73
+ return sprite.componentsRight?.();
73
74
  case 'top':
74
75
  default:
75
- return object.componentsTop?.();
76
+ return sprite.componentsTop?.();
76
77
  }
77
78
  });
78
79
 
@@ -98,16 +99,16 @@ const componentData = computed(() => {
98
99
 
99
100
  const layout = computed(() => componentData()?.layout ?? {});
100
101
  const rows = computed(() => componentData()?.components ?? []);
101
- const hitbox = object.hitbox;
102
+ const hitbox = sprite.hitbox;
102
103
 
103
104
  const toNumber = (value, fallback = 0) => {
104
- const resolved = resolveDynamicValue(value, object);
105
+ const resolved = resolveDynamicValue(value, sprite);
105
106
  const num = typeof resolved === 'number' ? resolved : parseFloat(resolved);
106
107
  return Number.isFinite(num) ? num : fallback;
107
108
  };
108
109
 
109
110
  const estimateTextWidth = (value, style = {}) => {
110
- const text = String(resolveDynamicValue(value ?? '', object) ?? '');
111
+ const text = String(resolveDynamicValue(value ?? '', sprite) ?? '');
111
112
  const fontSize = toNumber(style.fontSize, 12);
112
113
  return Math.max(1, Math.ceil(text.length * fontSize * 0.6));
113
114
  };
@@ -206,7 +207,7 @@ const renderedRows = computed(() => {
206
207
 
207
208
  entries.push({
208
209
  component,
209
- props: resolveDynamicProps(getComponentProps(definition), object),
210
+ props: resolveDynamicProps(getComponentProps(definition), sprite),
210
211
  width: cell.width,
211
212
  height: cell.height
212
213
  });
@@ -46,6 +46,7 @@
46
46
  import { computed, animatedSignal, effect } from "canvasengine";
47
47
 
48
48
  const { object } = defineProps();
49
+ const sprite = object();
49
50
 
50
51
  // ====================
51
52
  // Configuration
@@ -93,14 +94,14 @@ const highlightHeight = Math.floor(fillHeight / 2);
93
94
  // ====================
94
95
 
95
96
  /** Gets hitbox dimensions for positioning */
96
- const hitbox = object.hitbox;
97
+ const hitbox = sprite.hitbox;
97
98
 
98
99
  /**
99
100
  * Gets the current HP value from the player object
100
101
  * Uses hpSignal which is synchronized from the server
101
102
  */
102
103
  const currentHp = computed(() => {
103
- return object.hpSignal?.() ?? 0;
104
+ return sprite.hpSignal?.() ?? 0;
104
105
  });
105
106
 
106
107
  /**
@@ -108,7 +109,7 @@ const currentHp = computed(() => {
108
109
  * Reads from _param.maxHp which contains calculated stats
109
110
  */
110
111
  const maxHp = computed(() => {
111
- const params = object._param?.() ?? {};
112
+ const params = sprite._param?.() ?? {};
112
113
  return params.maxHp ?? 100;
113
114
  });
114
115
 
@@ -31,6 +31,7 @@ const {
31
31
  opacitySpeed,
32
32
  lightColor
33
33
  } = defineProps();
34
+ const sprite = object();
34
35
 
35
36
  // ====================
36
37
  // Props with default values
@@ -92,7 +93,7 @@ const currentOpacity = computed(() => {
92
93
  // Position calculations
93
94
  // ====================
94
95
 
95
- const hitbox = object.hitbox;
96
+ const hitbox = sprite.hitbox;
96
97
 
97
98
  const position = computed(() => ({
98
99
  x: hitbox().w / 2,
@@ -145,4 +146,3 @@ tick(() => {
145
146
  time.update(t => t + 1);
146
147
  });
147
148
  </script>
148
-