pixospritz-core 0.10.1 → 1.0.1

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 (157) hide show
  1. package/README.md +36 -286
  2. package/dist/bundle.js +13 -3
  3. package/dist/bundle.js.map +1 -1
  4. package/dist/style.css +1 -0
  5. package/package.json +43 -44
  6. package/src/components/WebGLView.jsx +318 -0
  7. package/src/css/pixos.css +372 -0
  8. package/src/engine/actions/animate.js +41 -0
  9. package/src/engine/actions/changezone.js +135 -0
  10. package/src/engine/actions/chat.js +109 -0
  11. package/src/engine/actions/dialogue.js +90 -0
  12. package/src/engine/actions/face.js +22 -0
  13. package/src/engine/actions/greeting.js +28 -0
  14. package/src/engine/actions/interact.js +86 -0
  15. package/src/engine/actions/move.js +67 -0
  16. package/src/engine/actions/patrol.js +109 -0
  17. package/src/engine/actions/prompt.js +185 -0
  18. package/src/engine/actions/script.js +42 -0
  19. package/src/engine/core/audio/AudioSystem.js +543 -0
  20. package/src/engine/core/cutscene/PxcPlayer.js +956 -0
  21. package/src/engine/core/cutscene/manager.js +243 -0
  22. package/src/engine/core/database/index.js +75 -0
  23. package/src/engine/core/debug/index.js +371 -0
  24. package/src/engine/core/hud/index.js +765 -0
  25. package/src/engine/core/index.js +540 -0
  26. package/src/engine/core/input/gamepad/Controller.js +71 -0
  27. package/src/engine/core/input/gamepad/ControllerButtons.js +231 -0
  28. package/src/engine/core/input/gamepad/ControllerStick.js +173 -0
  29. package/src/engine/core/input/gamepad/index.js +592 -0
  30. package/src/engine/core/input/keyboard.js +196 -0
  31. package/src/engine/core/input/manager.js +485 -0
  32. package/src/engine/core/input/mouse.js +203 -0
  33. package/src/engine/core/input/touch.js +175 -0
  34. package/src/engine/core/mode/manager.js +199 -0
  35. package/src/engine/core/net/manager.js +535 -0
  36. package/src/engine/core/queue/action.js +83 -0
  37. package/src/engine/core/queue/event.js +82 -0
  38. package/src/engine/core/queue/index.js +44 -0
  39. package/src/engine/core/queue/loadable.js +33 -0
  40. package/src/engine/core/render/CameraEffects.js +494 -0
  41. package/src/engine/core/render/FrustumCuller.js +417 -0
  42. package/src/engine/core/render/LODManager.js +285 -0
  43. package/src/engine/core/render/ParticleManager.js +529 -0
  44. package/src/engine/core/render/TextureAtlas.js +465 -0
  45. package/src/engine/core/render/camera.js +338 -0
  46. package/src/engine/core/render/light.js +197 -0
  47. package/src/engine/core/render/manager.js +1079 -0
  48. package/src/engine/core/render/shaders.js +110 -0
  49. package/src/engine/core/render/skybox.js +342 -0
  50. package/src/engine/core/resource/manager.js +133 -0
  51. package/src/engine/core/resource/object.js +611 -0
  52. package/src/engine/core/resource/texture.js +103 -0
  53. package/src/engine/core/resource/tileset.js +177 -0
  54. package/src/engine/core/scene/avatar.js +215 -0
  55. package/src/engine/core/scene/speech.js +138 -0
  56. package/src/engine/core/scene/sprite.js +702 -0
  57. package/src/engine/core/scene/spritz.js +189 -0
  58. package/src/engine/core/scene/world.js +681 -0
  59. package/src/engine/core/scene/zone.js +1167 -0
  60. package/src/engine/core/store/index.js +110 -0
  61. package/src/engine/dynamic/animatedSprite.js +64 -0
  62. package/src/engine/dynamic/animatedTile.js +98 -0
  63. package/src/engine/dynamic/avatar.js +110 -0
  64. package/src/engine/dynamic/map.js +174 -0
  65. package/src/engine/dynamic/sprite.js +255 -0
  66. package/src/engine/dynamic/spritz.js +119 -0
  67. package/src/engine/events/EventSystem.js +609 -0
  68. package/src/engine/events/camera.js +142 -0
  69. package/src/engine/events/chat.js +75 -0
  70. package/src/engine/events/menu.js +186 -0
  71. package/src/engine/scripting/CallbackManager.js +514 -0
  72. package/src/engine/scripting/PixoScriptInterpreter.js +81 -0
  73. package/src/engine/scripting/PixoScriptLibrary.js +704 -0
  74. package/src/engine/shaders/effects/index.js +450 -0
  75. package/src/engine/shaders/fs.js +222 -0
  76. package/src/engine/shaders/particles/fs.js +41 -0
  77. package/src/engine/shaders/particles/vs.js +61 -0
  78. package/src/engine/shaders/picker/fs.js +34 -0
  79. package/src/engine/shaders/picker/init.js +62 -0
  80. package/src/engine/shaders/picker/vs.js +42 -0
  81. package/src/engine/shaders/pxsl/README.md +250 -0
  82. package/src/engine/shaders/pxsl/index.js +25 -0
  83. package/src/engine/shaders/pxsl/library.js +608 -0
  84. package/src/engine/shaders/pxsl/manager.js +338 -0
  85. package/src/engine/shaders/pxsl/specification.js +363 -0
  86. package/src/engine/shaders/pxsl/transpiler.js +753 -0
  87. package/src/engine/shaders/skybox/cosmic/fs.js +147 -0
  88. package/src/engine/shaders/skybox/cosmic/vs.js +23 -0
  89. package/src/engine/shaders/skybox/matrix/fs.js +127 -0
  90. package/src/engine/shaders/skybox/matrix/vs.js +23 -0
  91. package/src/engine/shaders/skybox/morning/fs.js +109 -0
  92. package/src/engine/shaders/skybox/morning/vs.js +23 -0
  93. package/src/engine/shaders/skybox/neon/fs.js +119 -0
  94. package/src/engine/shaders/skybox/neon/vs.js +23 -0
  95. package/src/engine/shaders/skybox/sky/fs.js +114 -0
  96. package/src/engine/shaders/skybox/sky/vs.js +23 -0
  97. package/src/engine/shaders/skybox/sunset/fs.js +101 -0
  98. package/src/engine/shaders/skybox/sunset/vs.js +23 -0
  99. package/src/engine/shaders/transition/blur/fs.js +42 -0
  100. package/src/engine/shaders/transition/blur/vs.js +26 -0
  101. package/src/engine/shaders/transition/cross/fs.js +36 -0
  102. package/src/engine/shaders/transition/cross/vs.js +26 -0
  103. package/src/engine/shaders/transition/crossBlur/fs.js +41 -0
  104. package/src/engine/shaders/transition/crossBlur/vs.js +25 -0
  105. package/src/engine/shaders/transition/dissolve/fs.js +78 -0
  106. package/src/engine/shaders/transition/dissolve/vs.js +24 -0
  107. package/src/engine/shaders/transition/fade/fs.js +31 -0
  108. package/src/engine/shaders/transition/fade/vs.js +27 -0
  109. package/src/engine/shaders/transition/iris/fs.js +52 -0
  110. package/src/engine/shaders/transition/iris/vs.js +24 -0
  111. package/src/engine/shaders/transition/pixelate/fs.js +44 -0
  112. package/src/engine/shaders/transition/pixelate/vs.js +24 -0
  113. package/src/engine/shaders/transition/slide/fs.js +53 -0
  114. package/src/engine/shaders/transition/slide/vs.js +24 -0
  115. package/src/engine/shaders/transition/swirl/fs.js +39 -0
  116. package/src/engine/shaders/transition/swirl/vs.js +26 -0
  117. package/src/engine/shaders/transition/wipe/fs.js +50 -0
  118. package/src/engine/shaders/transition/wipe/vs.js +24 -0
  119. package/src/engine/shaders/vs.js +60 -0
  120. package/src/engine/utils/CameraController.js +506 -0
  121. package/src/engine/utils/ObjHelper.js +551 -0
  122. package/src/engine/utils/debug-logger.js +110 -0
  123. package/src/engine/utils/enums.js +305 -0
  124. package/src/engine/utils/generator.js +156 -0
  125. package/src/engine/utils/index.js +21 -0
  126. package/src/engine/utils/loaders/ActionLoader.js +77 -0
  127. package/src/engine/utils/loaders/AudioLoader.js +157 -0
  128. package/src/engine/utils/loaders/EventLoader.js +66 -0
  129. package/src/engine/utils/loaders/ObjectLoader.js +67 -0
  130. package/src/engine/utils/loaders/SpriteLoader.js +77 -0
  131. package/src/engine/utils/loaders/TilesetLoader.js +103 -0
  132. package/src/engine/utils/loaders/index.js +21 -0
  133. package/src/engine/utils/math/matrix4.js +367 -0
  134. package/src/engine/utils/math/vector.js +458 -0
  135. package/src/engine/utils/obj/_old_js/index.js +46 -0
  136. package/src/engine/utils/obj/_old_js/layout.js +308 -0
  137. package/src/engine/utils/obj/_old_js/material.js +711 -0
  138. package/src/engine/utils/obj/_old_js/mesh.js +761 -0
  139. package/src/engine/utils/obj/_old_js/utils.js +647 -0
  140. package/src/engine/utils/obj/index.js +24 -0
  141. package/src/engine/utils/obj/js/index.js +277 -0
  142. package/src/engine/utils/obj/js/loader.js +232 -0
  143. package/src/engine/utils/obj/layout.js +246 -0
  144. package/src/engine/utils/obj/material.js +665 -0
  145. package/src/engine/utils/obj/mesh.js +657 -0
  146. package/src/engine/utils/obj/ts/index.ts +72 -0
  147. package/src/engine/utils/obj/ts/layout.ts +265 -0
  148. package/src/engine/utils/obj/ts/material.ts +760 -0
  149. package/src/engine/utils/obj/ts/mesh.ts +785 -0
  150. package/src/engine/utils/obj/ts/utils.ts +501 -0
  151. package/src/engine/utils/obj/utils.js +428 -0
  152. package/src/engine/utils/resources.js +18 -0
  153. package/src/index.jsx +55 -0
  154. package/src/spritz/player.js +18 -0
  155. package/src/spritz/readme.md +18 -0
  156. package/LICENSE +0 -437
  157. package/dist/bundle.js.LICENSE.txt +0 -31
@@ -0,0 +1,305 @@
1
+ /* *\
2
+ ** ----------------------------------------------- **
3
+ ** Calliope - Pixos Game Engine **
4
+ ** ----------------------------------------------- **
5
+ ** Copyright (c) 2020-2025 - Kyle Derby MacInnis **
6
+ ** **
7
+ ** Any unauthorized distribution or transfer **
8
+ ** of this work is strictly prohibited. **
9
+ ** **
10
+ ** All Rights Reserved. **
11
+ ** ----------------------------------------------- **
12
+ \* */
13
+ import { Vector } from '@Engine/utils/math/vector.js';
14
+
15
+ // Mouse event enumeration
16
+ export const Mouse = {
17
+ DOWN: 1,
18
+ UP: 2,
19
+ MOVE: 3,
20
+ };
21
+
22
+ // Degrees to Radians
23
+ function degToRad(degrees) {
24
+ return (degrees * Math.PI) / 180;
25
+ }
26
+
27
+ // Directions enumeration & methods
28
+ export const Direction = {
29
+ None: 0, //0000
30
+ Right: 1, //0001
31
+ Up: 2, //0010
32
+ Left: 4, //0100
33
+ Down: 8, //1000
34
+ All: 15, //1111
35
+
36
+ fromOffset(dp) {
37
+ if (dp[0] > 0) return Direction.Right;
38
+ if (dp[0] < 0) return Direction.Left;
39
+ if (dp[1] > 0) return Direction.Down;
40
+ if (dp[1] < 0) return Direction.Up;
41
+ return 0;
42
+ },
43
+
44
+ toOffset(dir) {
45
+ switch (dir) {
46
+ case Direction.Right:
47
+ return [1, 0];
48
+ case Direction.Up:
49
+ return [0, -1];
50
+ case Direction.Left:
51
+ return [-1, 0];
52
+ case Direction.Down:
53
+ return [0, 1];
54
+ }
55
+ return [0, 0];
56
+ },
57
+
58
+ reverse(dir) {
59
+ switch (dir) {
60
+ case Direction.Right:
61
+ return Direction.Left;
62
+ case Direction.Up:
63
+ return Direction.Down;
64
+ case Direction.Left:
65
+ return Direction.Right;
66
+ case Direction.Down:
67
+ return Direction.Up;
68
+ }
69
+ return Direction.None;
70
+ },
71
+
72
+ rotate(dir, ccw = false) {
73
+ switch (dir) {
74
+ case Direction.Right:
75
+ return ccw ? Direction.Up : Direction.Down;
76
+ case Direction.Up:
77
+ return ccw ? Direction.Left : Direction.Right;
78
+ case Direction.Left:
79
+ return ccw ? Direction.Down : Direction.Up;
80
+ case Direction.Down:
81
+ return ccw ? Direction.Right : Direction.Left;
82
+ }
83
+ return Direction.None;
84
+ },
85
+
86
+ // determine which camera facing applies (seems to be working)
87
+ adjustCameraDirection(vec) {
88
+ switch (vec.z % 8) {
89
+ case 0:
90
+ return 'N';
91
+ case 1:
92
+ case -7:
93
+ return 'NW';
94
+ case 2:
95
+ case -6:
96
+ return 'W';
97
+ case 3:
98
+ case -5:
99
+ return 'SW';
100
+ case 4:
101
+ case -4:
102
+ return 'S';
103
+ case 5:
104
+ case -3:
105
+ return 'SE';
106
+ case 6:
107
+ case -2:
108
+ return 'E';
109
+ case 7:
110
+ case -1:
111
+ return 'NE';
112
+ }
113
+ },
114
+
115
+ // Get camera-relative movement direction
116
+ // Maps input directions (forward/backward/left/right) to world directions based on camera facing
117
+ // Forward always moves "into" the screen (away from camera), backward comes toward camera
118
+ // Left/right are perpendicular to the camera view
119
+ getCameraRelativeDirection(inputDir, cameraDir) {
120
+ const mappings = {
121
+ // Camera North: forward moves north (up in world), etc.
122
+ 'N': { forward: Direction.Up, backward: Direction.Down, left: Direction.Left, right: Direction.Right },
123
+ // Camera NE: forward moves up-right diagonally
124
+ 'NE': { forward: Direction.Up, backward: Direction.Down, left: Direction.Up, right: Direction.Down },
125
+ // Camera East: forward moves right, left moves up
126
+ 'E': { forward: Direction.Right, backward: Direction.Left, left: Direction.Up, right: Direction.Down },
127
+ // Camera SE: forward moves right-down diagonally
128
+ 'SE': { forward: Direction.Right, backward: Direction.Left, left: Direction.Up, right: Direction.Down },
129
+ // Camera South: inverted from North
130
+ 'S': { forward: Direction.Down, backward: Direction.Up, left: Direction.Right, right: Direction.Left },
131
+ // Camera SW: forward moves left-down diagonally
132
+ 'SW': { forward: Direction.Down, backward: Direction.Up, left: Direction.Right, right: Direction.Left },
133
+ // Camera West: forward moves left, right moves up
134
+ 'W': { forward: Direction.Left, backward: Direction.Right, left: Direction.Down, right: Direction.Up },
135
+ // Camera NW: forward moves up-left diagonally
136
+ 'NW': { forward: Direction.Left, backward: Direction.Right, left: Direction.Down, right: Direction.Up }
137
+ };
138
+
139
+ const mapping = mappings[cameraDir] || mappings['N'];
140
+ return mapping[inputDir] || Direction.None;
141
+ },
142
+
143
+ // sprite sequence facing (Needs work -- still not quite right)
144
+ spriteSequence(dir, camera = 'N') {
145
+ switch (camera) {
146
+ case 'N':
147
+ switch (dir) {
148
+ case Direction.Up:
149
+ return 'N';
150
+ case Direction.Right:
151
+ return 'E';
152
+ case Direction.Down:
153
+ return 'S';
154
+ case Direction.Left:
155
+ return 'W';
156
+ }
157
+ case 'E':
158
+ switch (dir) {
159
+ case Direction.Up:
160
+ return 'W';
161
+ case Direction.Right:
162
+ return 'N';
163
+ case Direction.Down:
164
+ return 'E';
165
+ case Direction.Left:
166
+ return 'S';
167
+ }
168
+ case 'S':
169
+ switch (dir) {
170
+ case Direction.Up:
171
+ return 'S';
172
+ case Direction.Right:
173
+ return 'W';
174
+ case Direction.Down:
175
+ return 'N';
176
+ case Direction.Left:
177
+ return 'E';
178
+ }
179
+ case 'W':
180
+ switch (dir) {
181
+ case Direction.Up:
182
+ return 'E';
183
+ case Direction.Right:
184
+ return 'S';
185
+ case Direction.Down:
186
+ return 'W';
187
+ case Direction.Left:
188
+ return 'N';
189
+ }
190
+ case 'NE':
191
+ switch (dir) {
192
+ case Direction.Up:
193
+ return 'NW';
194
+ case Direction.Right:
195
+ return 'SE';
196
+ case Direction.Down:
197
+ return 'NE';
198
+ case Direction.Left:
199
+ return 'SW';
200
+ }
201
+ case 'SE':
202
+ switch (dir) {
203
+ case Direction.Up:
204
+ return 'SW';
205
+ case Direction.Right:
206
+ return 'NW';
207
+ case Direction.Down:
208
+ return 'SE';
209
+ case Direction.Left:
210
+ return 'NE';
211
+ }
212
+ case 'SW':
213
+ switch (dir) {
214
+ case Direction.Up:
215
+ return 'NE';
216
+ case Direction.Right:
217
+ return 'SW';
218
+ case Direction.Down:
219
+ return 'NW';
220
+ case Direction.Left:
221
+ return 'SE';
222
+ }
223
+ case 'NW':
224
+ switch (dir) {
225
+ case Direction.Up:
226
+ return 'SE';
227
+ case Direction.Right:
228
+ return 'NE';
229
+ case Direction.Down:
230
+ return 'SW';
231
+ case Direction.Left:
232
+ return 'NW';
233
+ }
234
+ }
235
+
236
+ return 'S';
237
+ },
238
+
239
+ // adjust draw offset based on rotation position
240
+ drawOffset(vec, camera = 'N') {
241
+ // return vec;
242
+ // todo -- needs work
243
+ switch (camera) {
244
+ case 'NE':
245
+ return vec.cross(new Vector(Math.sin(degToRad(315)), 2 * Math.cos(degToRad(315)), 0));
246
+ case 'NW':
247
+ return vec.cross(new Vector(-2 * Math.sin(degToRad(315)), -Math.cos(degToRad(315)), 0));
248
+ case 'SE':
249
+ return vec.cross(new Vector(Math.sin(degToRad(225)), Math.cos(degToRad(225)), 0));
250
+ case 'SW':
251
+ return vec.cross(new Vector(Math.sin(degToRad(135)), Math.cos(degToRad(135)), 0));
252
+ case 'E':
253
+ return vec.cross(new Vector(Math.sin(degToRad(270)), Math.cos(degToRad(270)), 0));
254
+ case 'W':
255
+ return vec.cross(new Vector(Math.sin(degToRad(90)), Math.cos(degToRad(90)), 0));
256
+ case 'S':
257
+ return vec.cross(new Vector(Math.sin(degToRad(180)), Math.cos(degToRad(180)), 0));
258
+ case 'N':
259
+ return vec.cross(new Vector(Math.sin(degToRad(0)), Math.cos(degToRad(0)), 0));
260
+ default:
261
+ return vec;
262
+ }
263
+ },
264
+
265
+ // object sequence rotation (TODO)
266
+ objectSequence(dir) {
267
+ switch (dir) {
268
+ case Direction.Right:
269
+ return [0, 90, 0];
270
+ case Direction.Up:
271
+ return [0, 0, 0];
272
+ case Direction.Left:
273
+ return [0, -90, 0];
274
+ case Direction.Down:
275
+ return [0, 180, 0];
276
+ }
277
+ return [0, 0, 0];
278
+ },
279
+ };
280
+
281
+ export const isObject = (item) => {
282
+ return item && typeof item === 'object' && !Array.isArray(item);
283
+ };
284
+
285
+ export const mergeDeep = (target, ...sources) => {
286
+ if (!sources.length) return target;
287
+ const source = sources.shift();
288
+ if (isObject(target) && isObject(source)) {
289
+ for (const key in source) {
290
+ if (isObject(source[key])) {
291
+ if (!target[key])
292
+ Object.assign(target, {
293
+ [key]: {},
294
+ });
295
+ mergeDeep(target[key], source[key]);
296
+ } else {
297
+ Object.assign(target, {
298
+ [key]: source[key] && Array.isArray(source[key]) ? [].concat(target[key] ?? [], source[key]) : source[key],
299
+ });
300
+ }
301
+ }
302
+ }
303
+
304
+ return mergeDeep(target, ...sources);
305
+ };
@@ -0,0 +1,156 @@
1
+ /* *\
2
+ ** ----------------------------------------------- **
3
+ ** Calliope - Pixos Game Engine **
4
+ ** ----------------------------------------------- **
5
+ ** Copyright (c) 2020-2025 - Kyle Derby MacInnis **
6
+ ** **
7
+ ** Any unauthorized distribution or transfer **
8
+ ** of this work is strictly prohibited. **
9
+ ** **
10
+ ** All Rights Reserved. **
11
+ ** ----------------------------------------------- **
12
+ \* */
13
+
14
+ import { store } from 'react-recollect';
15
+
16
+ import { Vector } from '@Engine/utils/math/vector.js';
17
+ import { Direction } from '@Engine/utils/enums.js';
18
+
19
+ // Store Name
20
+ export const STORE_NAME = 'garden-tome';
21
+
22
+ // generate random map zone
23
+ export async function generateZone(self, gender, storeName, cyoa) {
24
+ // load current spritz or play welcome
25
+ let tome = self.engine.store.get(storeName);
26
+
27
+ if (!tome) {
28
+ // Initialize the garden
29
+ tome = {
30
+ gender: gender,
31
+ position: new Vector(...[8, 3, 0]),
32
+ selected: -2,
33
+ rain: true,
34
+ snow: false,
35
+ spritz: [],
36
+ sprites: [],
37
+ objects: [],
38
+ };
39
+
40
+ // Load CYOA config
41
+ Object.assign(tome, cyoa);
42
+
43
+ self.engine.store.add(storeName, tome);
44
+
45
+ // Generate a collection of spritz programmably
46
+ // and append them to the spritz collection.
47
+
48
+ // self.randomlyGenerateSprites();
49
+ // self.randomlySprites();
50
+ await self.playCutScene('welcome');
51
+ } else {
52
+ // load Sprites
53
+ await Promise.all(
54
+ tome.sprites
55
+ .filter((x) => {
56
+ // Determine whether to load sprite or not
57
+ // base on the tome settings and cyoa
58
+
59
+ return x.id == tome.selected;
60
+ })
61
+ .map(self.loadSprite.bind(self))
62
+ );
63
+
64
+ // Load Objects
65
+ await Promise.all(
66
+ tome.objects
67
+ .filter((x) => {
68
+ // Determine whether to load object or not
69
+ // base on the tome settings and cyoa
70
+
71
+ return x.id == tome.selected;
72
+ })
73
+ .map(self.loadObject.bind(self))
74
+ );
75
+
76
+ // Load NPCs for the zone
77
+ await Promise.all(
78
+ tome.npcs
79
+ .filter((x) => {
80
+ // Determine whether to load NPC and decide what
81
+ // dialogue is base on the tome settings and cyoa
82
+
83
+ return x.id == tome.selected;
84
+ })
85
+ .map(async (trigger) => {
86
+ // run trigger
87
+ })
88
+ );
89
+
90
+ // Apply any Triggers & Setup New Spritz if needed
91
+ await Promise.all(
92
+ tome.triggers
93
+ .filter((x) => {
94
+ // Determine whether to load trigger
95
+ // base on the tome settings and cyoa
96
+
97
+ return x.id == tome.selected;
98
+ })
99
+ .map(async (trigger) => {
100
+ // run trigger
101
+ })
102
+ );
103
+
104
+ // Finally - Play appropriate spritz
105
+ await Promise.all(
106
+ tome.spritz
107
+ .filter((x) => {
108
+ return x.id == tome.selected;
109
+ })
110
+ .map(async (spritz) => {
111
+ await self.playCutScene(spritz.id, tome.spritz);
112
+ })
113
+ );
114
+
115
+ // run custom spritz
116
+ let spritz = [
117
+ {
118
+ id: 'new-space' + Math.random(),
119
+ actions: [
120
+ // manual actions
121
+ // Scripted Dialogue Action Controls directly on sprites
122
+ {
123
+ sprite: 'avatar',
124
+ action: 'dialogue',
125
+ args: [
126
+ [
127
+ 'Welcome traveler... I see you are exploring. Good. Please continue to look',
128
+ 'You have travelled into the number ' + (store.pixos && store.pixos[storeName] ? store.pixos[storeName].selected : -2) + ' room',
129
+ ],
130
+ false,
131
+ { autoclose: true },
132
+ ],
133
+ scope: self, // scoped to the zone
134
+ },
135
+ ],
136
+ },
137
+ ];
138
+ await self.playCutScene(spritz[0].id, spritz);
139
+ }
140
+ }
141
+
142
+ // load avatar
143
+ export async function loadAvatar(zone, storeName) {
144
+ // randomly pick gender & store
145
+ let gender =
146
+ typeof store.pixos[storeName]?.gender !== 'undefined' ? store.pixos[storeName].gender : ['male', 'female'][Math.floor((2 * Math.random()) % 2)];
147
+ // Load avatar (Male or Female)
148
+ await zone.loadSprite.bind(self)({
149
+ id: 'avatar',
150
+ type: 'characters/' + gender,
151
+ gender: gender,
152
+ pos: typeof store.pixos[storeName]?.position !== 'undefined' ? store.pixos[storeName].position : new Vector(...[8, 8, zone.getHeight(8, 8)]),
153
+ facing: Direction.Down,
154
+ });
155
+ return gender;
156
+ }
@@ -0,0 +1,21 @@
1
+ import { Vector, Vector4 } from './math/vector.js';
2
+
3
+ /**
4
+ * Clamps a value between a minimum and maximum value.
5
+ * @param {number} value - The value to clamp.
6
+ * @param {number} min - The minimum allowed value.
7
+ * @param {number} max - The maximum allowed value.
8
+ * @returns {number} The clamped value.
9
+ */
10
+ export const clamp = (value, min, max) => {
11
+ return Math.max(min, Math.min(value, max));
12
+ };
13
+
14
+ /**
15
+ * Utility functions and common exports for the Pixos Game Engine.
16
+ */
17
+ export default {
18
+ Vector,
19
+ Vector4,
20
+ clamp,
21
+ };
@@ -0,0 +1,77 @@
1
+ /* *\
2
+ ** ----------------------------------------------- **
3
+ ** Calliope - Pixos Game Engine **
4
+ ** ----------------------------------------------- **
5
+ ** Copyright (c) 2020-2025 - Kyle Derby MacInnis **
6
+ ** **
7
+ ** Any unauthorized distribution or transfer **
8
+ ** of this work is strictly prohibited. **
9
+ ** **
10
+ ** All Rights Reserved. **
11
+ ** ----------------------------------------------- **
12
+ \* */
13
+
14
+ import { debug } from '../debug-logger.js';
15
+ import Action from '@Engine/core/queue/action.js';
16
+
17
+ // Helps Loads New Action Instance
18
+ export class ActionLoader {
19
+ constructor(engine, type, args, sprite, callback) {
20
+ this.engine = engine;
21
+ this.type = type;
22
+ this.args = args;
23
+ this.sprite = sprite;
24
+ this.callback = callback;
25
+ this.instances = {};
26
+ this.definitions = [];
27
+ this.assets = {};
28
+
29
+ let time = new Date().getTime();
30
+ let id = sprite.id + '-' + type + '-' + time;
31
+ return this.load(
32
+ type,
33
+ async function (action) {
34
+ await action.onLoad(args);
35
+ },
36
+ function (action) {
37
+ action.configure(type, sprite, id, time, args);
38
+ }
39
+ );
40
+ }
41
+ // Load Internal Action
42
+ async load(type) {
43
+ debug('Loader', 'Loading Action: ' + type);
44
+
45
+ let afterLoad = arguments[1];
46
+ let runConfigure = arguments[2];
47
+ if (!this.instances[type]) {
48
+ this.instances[type] = [];
49
+ }
50
+ debug('Loader', {afterLoad, runConfigure})
51
+ // New Instance (assigns properties loaded by type)
52
+ let instance = new Action(this.type, this.sprite, this.callback);
53
+ const actionModule = await import('../../actions/' + type + '.js');
54
+ Object.assign(instance, actionModule.default);
55
+ instance.templateLoaded = true;
56
+ debug('Loader', 'Notifying in Action: ' + type);
57
+
58
+ // Notify existing
59
+ await Promise.all(
60
+ this.instances[type].map(async function (instance) {
61
+ debug('Loader', {instance});
62
+ if (instance.afterLoad) await instance.afterLoad(instance.instance);
63
+ })
64
+ );
65
+ // construct
66
+ if (runConfigure) runConfigure(instance);
67
+ // load
68
+ if (afterLoad) {
69
+ if (instance.templateLoaded) afterLoad(instance);
70
+ else this.instances[type].push({ instance, afterLoad });
71
+ }
72
+
73
+ debug('Loader', 'Ending load Action: ' + type);
74
+
75
+ return instance;
76
+ }
77
+ }