@sadhaka/loom-engine 0.10.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.
Files changed (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +344 -0
  3. package/dist/animation/animation-clip.d.ts +12 -0
  4. package/dist/animation/animation-clip.d.ts.map +1 -0
  5. package/dist/animation/animation-clip.js +85 -0
  6. package/dist/animation/animation-clip.js.map +1 -0
  7. package/dist/animation/animation-state-pool.d.ts +25 -0
  8. package/dist/animation/animation-state-pool.d.ts.map +1 -0
  9. package/dist/animation/animation-state-pool.js +113 -0
  10. package/dist/animation/animation-state-pool.js.map +1 -0
  11. package/dist/asset/sprite-sheet-loader.d.ts +41 -0
  12. package/dist/asset/sprite-sheet-loader.d.ts.map +1 -0
  13. package/dist/asset/sprite-sheet-loader.js +313 -0
  14. package/dist/asset/sprite-sheet-loader.js.map +1 -0
  15. package/dist/audio/audio-bus.d.ts +43 -0
  16. package/dist/audio/audio-bus.d.ts.map +1 -0
  17. package/dist/audio/audio-bus.js +258 -0
  18. package/dist/audio/audio-bus.js.map +1 -0
  19. package/dist/combat/mob-catalog.d.ts +29 -0
  20. package/dist/combat/mob-catalog.d.ts.map +1 -0
  21. package/dist/combat/mob-catalog.js +104 -0
  22. package/dist/combat/mob-catalog.js.map +1 -0
  23. package/dist/components/health.d.ts +28 -0
  24. package/dist/components/health.d.ts.map +1 -0
  25. package/dist/components/health.js +150 -0
  26. package/dist/components/health.js.map +1 -0
  27. package/dist/components/interactable.d.ts +30 -0
  28. package/dist/components/interactable.d.ts.map +1 -0
  29. package/dist/components/interactable.js +94 -0
  30. package/dist/components/interactable.js.map +1 -0
  31. package/dist/components/particle-emitter.d.ts +62 -0
  32. package/dist/components/particle-emitter.d.ts.map +1 -0
  33. package/dist/components/particle-emitter.js +193 -0
  34. package/dist/components/particle-emitter.js.map +1 -0
  35. package/dist/components/pursue.d.ts +23 -0
  36. package/dist/components/pursue.d.ts.map +1 -0
  37. package/dist/components/pursue.js +96 -0
  38. package/dist/components/pursue.js.map +1 -0
  39. package/dist/components/ranged-attack.d.ts +44 -0
  40. package/dist/components/ranged-attack.d.ts.map +1 -0
  41. package/dist/components/ranged-attack.js +120 -0
  42. package/dist/components/ranged-attack.js.map +1 -0
  43. package/dist/components/sprite.d.ts +27 -0
  44. package/dist/components/sprite.d.ts.map +1 -0
  45. package/dist/components/sprite.js +122 -0
  46. package/dist/components/sprite.js.map +1 -0
  47. package/dist/components/transform.d.ts +30 -0
  48. package/dist/components/transform.d.ts.map +1 -0
  49. package/dist/components/transform.js +150 -0
  50. package/dist/components/transform.js.map +1 -0
  51. package/dist/director/director-bridge.d.ts +22 -0
  52. package/dist/director/director-bridge.d.ts.map +1 -0
  53. package/dist/director/director-bridge.js +23 -0
  54. package/dist/director/director-bridge.js.map +1 -0
  55. package/dist/director/director-encounter-system.d.ts +21 -0
  56. package/dist/director/director-encounter-system.d.ts.map +1 -0
  57. package/dist/director/director-encounter-system.js +128 -0
  58. package/dist/director/director-encounter-system.js.map +1 -0
  59. package/dist/director/director-system.d.ts +19 -0
  60. package/dist/director/director-system.d.ts.map +1 -0
  61. package/dist/director/director-system.js +179 -0
  62. package/dist/director/director-system.js.map +1 -0
  63. package/dist/director/event-envelope.d.ts +144 -0
  64. package/dist/director/event-envelope.d.ts.map +1 -0
  65. package/dist/director/event-envelope.js +108 -0
  66. package/dist/director/event-envelope.js.map +1 -0
  67. package/dist/director/knot-context-resource.d.ts +25 -0
  68. package/dist/director/knot-context-resource.d.ts.map +1 -0
  69. package/dist/director/knot-context-resource.js +152 -0
  70. package/dist/director/knot-context-resource.js.map +1 -0
  71. package/dist/director/mock-director-bridge.d.ts +18 -0
  72. package/dist/director/mock-director-bridge.d.ts.map +1 -0
  73. package/dist/director/mock-director-bridge.js +75 -0
  74. package/dist/director/mock-director-bridge.js.map +1 -0
  75. package/dist/director/snapshot-recovery.d.ts +37 -0
  76. package/dist/director/snapshot-recovery.d.ts.map +1 -0
  77. package/dist/director/snapshot-recovery.js +180 -0
  78. package/dist/director/snapshot-recovery.js.map +1 -0
  79. package/dist/director/sse-director-bridge.d.ts +42 -0
  80. package/dist/director/sse-director-bridge.d.ts.map +1 -0
  81. package/dist/director/sse-director-bridge.js +280 -0
  82. package/dist/director/sse-director-bridge.js.map +1 -0
  83. package/dist/engine.d.ts +25 -0
  84. package/dist/engine.d.ts.map +1 -0
  85. package/dist/engine.js +166 -0
  86. package/dist/engine.js.map +1 -0
  87. package/dist/entity.d.ts +17 -0
  88. package/dist/entity.d.ts.map +1 -0
  89. package/dist/entity.js +77 -0
  90. package/dist/entity.js.map +1 -0
  91. package/dist/index.d.ts +85 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +64 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/input/input-manager.d.ts +91 -0
  96. package/dist/input/input-manager.d.ts.map +1 -0
  97. package/dist/input/input-manager.js +349 -0
  98. package/dist/input/input-manager.js.map +1 -0
  99. package/dist/input/tap-to-walk.d.ts +27 -0
  100. package/dist/input/tap-to-walk.d.ts.map +1 -0
  101. package/dist/input/tap-to-walk.js +118 -0
  102. package/dist/input/tap-to-walk.js.map +1 -0
  103. package/dist/input/virtual-dpad.d.ts +34 -0
  104. package/dist/input/virtual-dpad.d.ts.map +1 -0
  105. package/dist/input/virtual-dpad.js +267 -0
  106. package/dist/input/virtual-dpad.js.map +1 -0
  107. package/dist/renderer/camera.d.ts +26 -0
  108. package/dist/renderer/camera.d.ts.map +1 -0
  109. package/dist/renderer/camera.js +39 -0
  110. package/dist/renderer/camera.js.map +1 -0
  111. package/dist/renderer/canvas2d-device.d.ts +26 -0
  112. package/dist/renderer/canvas2d-device.d.ts.map +1 -0
  113. package/dist/renderer/canvas2d-device.js +252 -0
  114. package/dist/renderer/canvas2d-device.js.map +1 -0
  115. package/dist/renderer/graphics-device.d.ts +36 -0
  116. package/dist/renderer/graphics-device.d.ts.map +1 -0
  117. package/dist/renderer/graphics-device.js +12 -0
  118. package/dist/renderer/graphics-device.js.map +1 -0
  119. package/dist/renderer/iso-projection.d.ts +11 -0
  120. package/dist/renderer/iso-projection.d.ts.map +1 -0
  121. package/dist/renderer/iso-projection.js +59 -0
  122. package/dist/renderer/iso-projection.js.map +1 -0
  123. package/dist/resources.d.ts +28 -0
  124. package/dist/resources.d.ts.map +1 -0
  125. package/dist/resources.js +53 -0
  126. package/dist/resources.js.map +1 -0
  127. package/dist/system.d.ts +14 -0
  128. package/dist/system.d.ts.map +1 -0
  129. package/dist/system.js +25 -0
  130. package/dist/system.js.map +1 -0
  131. package/dist/systems/animation-system.d.ts +8 -0
  132. package/dist/systems/animation-system.d.ts.map +1 -0
  133. package/dist/systems/animation-system.js +77 -0
  134. package/dist/systems/animation-system.js.map +1 -0
  135. package/dist/systems/attack-system.d.ts +17 -0
  136. package/dist/systems/attack-system.d.ts.map +1 -0
  137. package/dist/systems/attack-system.js +94 -0
  138. package/dist/systems/attack-system.js.map +1 -0
  139. package/dist/systems/damage-system.d.ts +18 -0
  140. package/dist/systems/damage-system.d.ts.map +1 -0
  141. package/dist/systems/damage-system.js +77 -0
  142. package/dist/systems/damage-system.js.map +1 -0
  143. package/dist/systems/input-system.d.ts +7 -0
  144. package/dist/systems/input-system.d.ts.map +1 -0
  145. package/dist/systems/input-system.js +27 -0
  146. package/dist/systems/input-system.js.map +1 -0
  147. package/dist/systems/interaction-system.d.ts +23 -0
  148. package/dist/systems/interaction-system.d.ts.map +1 -0
  149. package/dist/systems/interaction-system.js +120 -0
  150. package/dist/systems/interaction-system.js.map +1 -0
  151. package/dist/systems/particle-emitter-system.d.ts +8 -0
  152. package/dist/systems/particle-emitter-system.d.ts.map +1 -0
  153. package/dist/systems/particle-emitter-system.js +161 -0
  154. package/dist/systems/particle-emitter-system.js.map +1 -0
  155. package/dist/systems/particle-render-system.d.ts +7 -0
  156. package/dist/systems/particle-render-system.d.ts.map +1 -0
  157. package/dist/systems/particle-render-system.js +53 -0
  158. package/dist/systems/particle-render-system.js.map +1 -0
  159. package/dist/systems/particle-simulation-system.d.ts +8 -0
  160. package/dist/systems/particle-simulation-system.d.ts.map +1 -0
  161. package/dist/systems/particle-simulation-system.js +45 -0
  162. package/dist/systems/particle-simulation-system.js.map +1 -0
  163. package/dist/systems/projectile-render-system.d.ts +7 -0
  164. package/dist/systems/projectile-render-system.d.ts.map +1 -0
  165. package/dist/systems/projectile-render-system.js +35 -0
  166. package/dist/systems/projectile-render-system.js.map +1 -0
  167. package/dist/systems/projectile-system.d.ts +7 -0
  168. package/dist/systems/projectile-system.d.ts.map +1 -0
  169. package/dist/systems/projectile-system.js +114 -0
  170. package/dist/systems/projectile-system.js.map +1 -0
  171. package/dist/systems/pursue-system.d.ts +7 -0
  172. package/dist/systems/pursue-system.d.ts.map +1 -0
  173. package/dist/systems/pursue-system.js +83 -0
  174. package/dist/systems/pursue-system.js.map +1 -0
  175. package/dist/systems/ranged-attack-system.d.ts +7 -0
  176. package/dist/systems/ranged-attack-system.d.ts.map +1 -0
  177. package/dist/systems/ranged-attack-system.js +98 -0
  178. package/dist/systems/ranged-attack-system.js.map +1 -0
  179. package/dist/systems/sprite-render-system.d.ts +9 -0
  180. package/dist/systems/sprite-render-system.d.ts.map +1 -0
  181. package/dist/systems/sprite-render-system.js +108 -0
  182. package/dist/systems/sprite-render-system.js.map +1 -0
  183. package/dist/systems/veil-budget-system.d.ts +7 -0
  184. package/dist/systems/veil-budget-system.d.ts.map +1 -0
  185. package/dist/systems/veil-budget-system.js +37 -0
  186. package/dist/systems/veil-budget-system.js.map +1 -0
  187. package/dist/util/color.d.ts +19 -0
  188. package/dist/util/color.d.ts.map +1 -0
  189. package/dist/util/color.js +45 -0
  190. package/dist/util/color.js.map +1 -0
  191. package/dist/util/math.d.ts +26 -0
  192. package/dist/util/math.d.ts.map +1 -0
  193. package/dist/util/math.js +47 -0
  194. package/dist/util/math.js.map +1 -0
  195. package/dist/util/typed-arrays.d.ts +7 -0
  196. package/dist/util/typed-arrays.d.ts.map +1 -0
  197. package/dist/util/typed-arrays.js +42 -0
  198. package/dist/util/typed-arrays.js.map +1 -0
  199. package/dist/vfx/particle-pool.d.ts +61 -0
  200. package/dist/vfx/particle-pool.d.ts.map +1 -0
  201. package/dist/vfx/particle-pool.js +204 -0
  202. package/dist/vfx/particle-pool.js.map +1 -0
  203. package/dist/vfx/projectile-pool.d.ts +56 -0
  204. package/dist/vfx/projectile-pool.d.ts.map +1 -0
  205. package/dist/vfx/projectile-pool.js +157 -0
  206. package/dist/vfx/projectile-pool.js.map +1 -0
  207. package/dist/world.d.ts +23 -0
  208. package/dist/world.d.ts.map +1 -0
  209. package/dist/world.js +101 -0
  210. package/dist/world.js.map +1 -0
  211. package/dist/zone/zone-catalog.d.ts +17 -0
  212. package/dist/zone/zone-catalog.d.ts.map +1 -0
  213. package/dist/zone/zone-catalog.js +116 -0
  214. package/dist/zone/zone-catalog.js.map +1 -0
  215. package/dist/zone/zone-state.d.ts +18 -0
  216. package/dist/zone/zone-state.d.ts.map +1 -0
  217. package/dist/zone/zone-state.js +52 -0
  218. package/dist/zone/zone-state.js.map +1 -0
  219. package/package.json +56 -0
@@ -0,0 +1,29 @@
1
+ import type { World } from '../world.js';
2
+ import type { ColorRGBA } from '../util/color.js';
3
+ import type { AtlasHandle } from '../renderer/graphics-device.js';
4
+ import type { EntityId } from '../entity.js';
5
+ export type MobArchetype = 'skel_warrior' | 'skel_archer' | 'skel_caster';
6
+ export interface MobCatalogEntry {
7
+ archetype: MobArchetype;
8
+ name: string;
9
+ hp: number;
10
+ speed: number;
11
+ stopDistance: number;
12
+ contactDamage: number;
13
+ contactCooldownMs: number;
14
+ tint: Readonly<ColorRGBA>;
15
+ ranged: {
16
+ range: number;
17
+ minRange: number;
18
+ cooldownMs: number;
19
+ damage: number;
20
+ projectileSpeed: number;
21
+ projectileLife: number;
22
+ projectileSize: number;
23
+ projectileColor: Readonly<ColorRGBA>;
24
+ homing: boolean;
25
+ } | null;
26
+ }
27
+ export declare const MOB_CATALOG: Record<MobArchetype, MobCatalogEntry>;
28
+ export declare function spawnMob(world: World, archetype: MobArchetype, x: number, y: number, target: EntityId, atlas: AtlasHandle, frame?: number): EntityId;
29
+ //# sourceMappingURL=mob-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mob-catalog.d.ts","sourceRoot":"","sources":["../../src/combat/mob-catalog.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAOzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,MAAM,YAAY,GAAG,cAAc,GAAG,aAAa,GAAG,aAAa,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,YAAY,CAAC;IAExB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IAEX,KAAK,EAAE,MAAM,CAAC;IAGd,YAAY,EAAE,MAAM,CAAC;IAErB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAE1B,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE1B,MAAM,EAAE;QACN,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,EAAE,OAAO,CAAC;KACjB,GAAG,IAAI,CAAC;CACV;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,eAAe,CAsD7D,CAAC;AAIF,wBAAgB,QAAQ,CACtB,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,YAAY,EACvB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,QAAQ,EAChB,KAAK,EAAE,WAAW,EAClB,KAAK,GAAE,MAAU,GAChB,QAAQ,CAsCV"}
@@ -0,0 +1,104 @@
1
+ // MobCatalog - data table of Survivor-style mob archetypes.
2
+ //
3
+ // Each entry describes an archetype's stats, AI behaviour, and
4
+ // rendering. Phase 7 deeper port: 3 baseline archetypes derived from
5
+ // the legacy Survivor (skel_warrior melee, skel_archer ranged,
6
+ // skel_caster homing) but rebuilt as engine-side configuration data
7
+ // rather than copying the legacy three.js sprite code.
8
+ //
9
+ // spawnMob(world, type, x, y, target, atlas) is the factory: it
10
+ // creates an entity and attaches the components implied by the
11
+ // catalog entry. The actual sprite atlas is passed in by the caller
12
+ // because asset registration is application-side; the catalog only
13
+ // describes WHICH frame + tint to use, not how to load the asset.
14
+ import { POOL_TRANSFORM, POOL_SPRITE } from '../world.js';
15
+ import { POOL_HEALTH } from '../components/health.js';
16
+ import { POOL_PURSUE } from '../components/pursue.js';
17
+ import { POOL_RANGED } from '../components/ranged-attack.js';
18
+ import { hexToRgba } from '../util/color.js';
19
+ export const MOB_CATALOG = {
20
+ skel_warrior: {
21
+ archetype: 'skel_warrior',
22
+ name: 'Skeleton Warrior',
23
+ hp: 50,
24
+ speed: 0.8,
25
+ stopDistance: 0.5,
26
+ contactDamage: 8,
27
+ contactCooldownMs: 1000,
28
+ tint: hexToRgba(0xffffff, 1), // bone-white default; demo colors via per-spawn override
29
+ ranged: null,
30
+ },
31
+ skel_archer: {
32
+ archetype: 'skel_archer',
33
+ name: 'Skeleton Archer',
34
+ hp: 35,
35
+ speed: 0.6,
36
+ stopDistance: 3.0, // hangs back at 3 tiles
37
+ contactDamage: 0,
38
+ contactCooldownMs: 1000,
39
+ tint: hexToRgba(0xfff0a0, 1), // pale yellow-bone
40
+ ranged: {
41
+ range: 4.0,
42
+ minRange: 1.0,
43
+ cooldownMs: 1500,
44
+ damage: 6,
45
+ projectileSpeed: 5.0,
46
+ projectileLife: 2.0,
47
+ projectileSize: 5,
48
+ projectileColor: hexToRgba(0xffeb88, 1), // pale-gold arrow
49
+ homing: false,
50
+ },
51
+ },
52
+ skel_caster: {
53
+ archetype: 'skel_caster',
54
+ name: 'Skeleton Caster',
55
+ hp: 30,
56
+ speed: 0.4,
57
+ stopDistance: 4.5, // stays far back
58
+ contactDamage: 0,
59
+ contactCooldownMs: 1000,
60
+ tint: hexToRgba(0xc88cff, 1), // violet-bone (sigil-orb hint)
61
+ ranged: {
62
+ range: 5.0,
63
+ minRange: 1.5,
64
+ cooldownMs: 2200,
65
+ damage: 12,
66
+ projectileSpeed: 3.0,
67
+ projectileLife: 4.0,
68
+ projectileSize: 6,
69
+ projectileColor: hexToRgba(0xb86eff, 1), // homing violet bolt
70
+ homing: true,
71
+ },
72
+ },
73
+ };
74
+ // Spawn a mob entity with all components attached per the catalog.
75
+ // Returns the new EntityId.
76
+ export function spawnMob(world, archetype, x, y, target, atlas, frame = 0) {
77
+ const cat = MOB_CATALOG[archetype];
78
+ const e = world.createEntity();
79
+ const transforms = world.requirePool(POOL_TRANSFORM);
80
+ const sprites = world.requirePool(POOL_SPRITE);
81
+ const health = world.requirePool(POOL_HEALTH);
82
+ const pursuit = world.requirePool(POOL_PURSUE);
83
+ transforms.attach(e, x, y, 0);
84
+ sprites.attach(e, atlas, frame, cat.tint);
85
+ health.attach(e, cat.hp);
86
+ pursuit.attach(e, target, cat.speed, cat.stopDistance, cat.contactDamage, cat.contactCooldownMs);
87
+ if (cat.ranged) {
88
+ const ranged = world.requirePool(POOL_RANGED);
89
+ ranged.attach(e, {
90
+ target,
91
+ range: cat.ranged.range,
92
+ minRange: cat.ranged.minRange,
93
+ cooldownMs: cat.ranged.cooldownMs,
94
+ damage: cat.ranged.damage,
95
+ projectileSpeed: cat.ranged.projectileSpeed,
96
+ projectileLife: cat.ranged.projectileLife,
97
+ projectileSize: cat.ranged.projectileSize,
98
+ projectileColor: cat.ranged.projectileColor,
99
+ homing: cat.ranged.homing,
100
+ });
101
+ }
102
+ return e;
103
+ }
104
+ //# sourceMappingURL=mob-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mob-catalog.js","sourceRoot":"","sources":["../../src/combat/mob-catalog.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,+DAA+D;AAC/D,qEAAqE;AACrE,+DAA+D;AAC/D,oEAAoE;AACpE,uDAAuD;AACvD,EAAE;AACF,gEAAgE;AAChE,+DAA+D;AAC/D,oEAAoE;AACpE,mEAAmE;AACnE,kEAAkE;AAGlE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,EAAc,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAc,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAoB,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAE/E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAmC7C,MAAM,CAAC,MAAM,WAAW,GAA0C;IAChE,YAAY,EAAE;QACZ,SAAS,EAAE,cAAc;QACzB,IAAI,EAAE,kBAAkB;QACxB,EAAE,EAAE,EAAE;QACN,KAAK,EAAE,GAAG;QACV,YAAY,EAAE,GAAG;QACjB,aAAa,EAAE,CAAC;QAChB,iBAAiB,EAAE,IAAI;QACvB,IAAI,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAK,yDAAyD;QAC1F,MAAM,EAAE,IAAI;KACb;IACD,WAAW,EAAE;QACX,SAAS,EAAE,aAAa;QACxB,IAAI,EAAE,iBAAiB;QACvB,EAAE,EAAE,EAAE;QACN,KAAK,EAAE,GAAG;QACV,YAAY,EAAE,GAAG,EAAiB,wBAAwB;QAC1D,aAAa,EAAE,CAAC;QAChB,iBAAiB,EAAE,IAAI;QACvB,IAAI,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAK,mBAAmB;QACpD,MAAM,EAAE;YACN,KAAK,EAAE,GAAG;YACV,QAAQ,EAAE,GAAG;YACb,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,CAAC;YACT,eAAe,EAAE,GAAG;YACpB,cAAc,EAAE,GAAG;YACnB,cAAc,EAAE,CAAC;YACjB,eAAe,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAI,kBAAkB;YAC7D,MAAM,EAAE,KAAK;SACd;KACF;IACD,WAAW,EAAE;QACX,SAAS,EAAE,aAAa;QACxB,IAAI,EAAE,iBAAiB;QACvB,EAAE,EAAE,EAAE;QACN,KAAK,EAAE,GAAG;QACV,YAAY,EAAE,GAAG,EAAiB,iBAAiB;QACnD,aAAa,EAAE,CAAC;QAChB,iBAAiB,EAAE,IAAI;QACvB,IAAI,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAK,+BAA+B;QAChE,MAAM,EAAE;YACN,KAAK,EAAE,GAAG;YACV,QAAQ,EAAE,GAAG;YACb,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,EAAE;YACV,eAAe,EAAE,GAAG;YACpB,cAAc,EAAE,GAAG;YACnB,cAAc,EAAE,CAAC;YACjB,eAAe,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAI,qBAAqB;YAChE,MAAM,EAAE,IAAI;SACb;KACF;CACF,CAAC;AAEF,mEAAmE;AACnE,4BAA4B;AAC5B,MAAM,UAAU,QAAQ,CACtB,KAAY,EACZ,SAAuB,EACvB,CAAS,EACT,CAAS,EACT,MAAgB,EAChB,KAAkB,EAClB,QAAgB,CAAC;IAEjB,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;IAE/B,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAgB,cAAc,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAa,WAAW,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAa,WAAW,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAa,WAAW,CAAC,CAAC;IAE3D,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9B,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACzB,OAAO,CAAC,MAAM,CACZ,CAAC,EACD,MAAM,EACN,GAAG,CAAC,KAAK,EACT,GAAG,CAAC,YAAY,EAChB,GAAG,CAAC,aAAa,EACjB,GAAG,CAAC,iBAAiB,CACtB,CAAC;IAEF,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAmB,WAAW,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;YACf,MAAM;YACN,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK;YACvB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;YAC7B,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU;YACjC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;YACzB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,eAAe;YAC3C,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,cAAc;YACzC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,cAAc;YACzC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,eAAe;YAC3C,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { type EntityId } from '../entity.js';
2
+ export declare const HEALTH_FLAG_ACTIVE: number;
3
+ export declare const HEALTH_FLAG_DEAD: number;
4
+ export declare const HEALTH_FLAG_INVULNERABLE: number;
5
+ export declare class HealthPool {
6
+ current: Float32Array;
7
+ max: Float32Array;
8
+ lastDamageMs: Float32Array;
9
+ flags: Uint8Array;
10
+ private capacity;
11
+ private highWaterMark;
12
+ constructor(initialCapacity?: number);
13
+ ensureCapacity(neededIndex: number): void;
14
+ attach(e: EntityId, maxHp: number): void;
15
+ detach(e: EntityId): void;
16
+ applyDamage(e: EntityId, amount: number, nowMs: number): number;
17
+ heal(e: EntityId, amount: number): number;
18
+ setInvulnerable(e: EntityId, invulnerable: boolean): void;
19
+ isAlive(e: EntityId): boolean;
20
+ isDead(e: EntityId): boolean;
21
+ isInvulnerable(e: EntityId): boolean;
22
+ getHp(e: EntityId): number;
23
+ getMaxHp(e: EntityId): number;
24
+ getHighWaterMark(): number;
25
+ getCapacity(): number;
26
+ }
27
+ export declare const POOL_HEALTH = "health";
28
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/components/health.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,cAAc,CAAC;AAG1D,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAGvC,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,qBAAa,UAAU;IAErB,OAAO,EAAE,YAAY,CAAC;IACtB,GAAG,EAAE,YAAY,CAAC;IAGlB,YAAY,EAAE,YAAY,CAAC;IAG3B,KAAK,EAAE,UAAU,CAAC;IAElB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;gBAEtB,eAAe,GAAE,MAAW;IAQxC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAUzC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAUxC,MAAM,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAQzB,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAsB/D,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM;IAczC,eAAe,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;IAOzD,OAAO,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAO7B,MAAM,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAM5B,cAAc,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAMpC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM;IAM1B,QAAQ,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM;IAM7B,gBAAgB,IAAI,MAAM;IAI1B,WAAW,IAAI,MAAM;CAGtB;AAED,eAAO,MAAM,WAAW,WAAW,CAAC"}
@@ -0,0 +1,150 @@
1
+ // HealthPool - per-entity health state.
2
+ //
3
+ // Companion to Transform + Sprite. Entities with Health are subject
4
+ // to DamageSystem ticking, AttackSystem damage application, and emit
5
+ // death events when HP drops to or below zero.
6
+ //
7
+ // Layout: hot data (current HP, max HP, last-damage timestamp) in
8
+ // Float32Arrays; flags in Uint8Array.
9
+ import { entityIndex } from '../entity.js';
10
+ import { growF32, growU8, nextPow2 } from '../util/typed-arrays.js';
11
+ export const HEALTH_FLAG_ACTIVE = 1 << 0;
12
+ export const HEALTH_FLAG_DEAD = 1 << 1;
13
+ // Entities marked invulnerable take 0 damage. Set / cleared by
14
+ // gameplay logic for i-frames after a hit, boss intro phases, etc.
15
+ export const HEALTH_FLAG_INVULNERABLE = 1 << 2;
16
+ export class HealthPool {
17
+ // Hot data
18
+ current;
19
+ max;
20
+ // Wall-clock ms timestamp of the last damage event. Useful for
21
+ // i-frame logic and damage-number display fade.
22
+ lastDamageMs;
23
+ // Cold data
24
+ flags;
25
+ capacity = 0;
26
+ highWaterMark = 0;
27
+ constructor(initialCapacity = 64) {
28
+ this.capacity = nextPow2(initialCapacity);
29
+ this.current = new Float32Array(this.capacity);
30
+ this.max = new Float32Array(this.capacity);
31
+ this.lastDamageMs = new Float32Array(this.capacity);
32
+ this.flags = new Uint8Array(this.capacity);
33
+ }
34
+ ensureCapacity(neededIndex) {
35
+ if (neededIndex < this.capacity)
36
+ return;
37
+ const next = nextPow2(neededIndex + 1);
38
+ this.current = growF32(this.current, next);
39
+ this.max = growF32(this.max, next);
40
+ this.lastDamageMs = growF32(this.lastDamageMs, next);
41
+ this.flags = growU8(this.flags, next);
42
+ this.capacity = next;
43
+ }
44
+ attach(e, maxHp) {
45
+ const i = entityIndex(e);
46
+ this.ensureCapacity(i);
47
+ this.current[i] = maxHp;
48
+ this.max[i] = maxHp;
49
+ this.lastDamageMs[i] = -1;
50
+ this.flags[i] = HEALTH_FLAG_ACTIVE;
51
+ if (i >= this.highWaterMark)
52
+ this.highWaterMark = i + 1;
53
+ }
54
+ detach(e) {
55
+ const i = entityIndex(e);
56
+ if (i >= this.capacity)
57
+ return;
58
+ this.flags[i] = 0;
59
+ }
60
+ // Apply damage. Returns the actual amount applied (0 if invulnerable
61
+ // or dead). Caller is responsible for spawning hit VFX, audio, etc.
62
+ applyDamage(e, amount, nowMs) {
63
+ const i = entityIndex(e);
64
+ if (i >= this.capacity)
65
+ return 0;
66
+ const f = this.flags[i] ?? 0;
67
+ if ((f & HEALTH_FLAG_ACTIVE) === 0)
68
+ return 0;
69
+ if ((f & HEALTH_FLAG_DEAD) !== 0)
70
+ return 0;
71
+ if ((f & HEALTH_FLAG_INVULNERABLE) !== 0)
72
+ return 0;
73
+ if (amount <= 0)
74
+ return 0;
75
+ const before = this.current[i] ?? 0;
76
+ const after = Math.max(0, before - amount);
77
+ this.current[i] = after;
78
+ this.lastDamageMs[i] = nowMs;
79
+ if (after <= 0) {
80
+ this.flags[i] = (f | HEALTH_FLAG_DEAD);
81
+ }
82
+ return before - after;
83
+ }
84
+ // Heal. Caps at max. Returns amount actually healed (0 if dead /
85
+ // already full). A dead entity stays dead even at heal > 0; a
86
+ // resurrection requires explicit setHealth + clear of DEAD flag.
87
+ heal(e, amount) {
88
+ const i = entityIndex(e);
89
+ if (i >= this.capacity)
90
+ return 0;
91
+ const f = this.flags[i] ?? 0;
92
+ if ((f & HEALTH_FLAG_ACTIVE) === 0)
93
+ return 0;
94
+ if ((f & HEALTH_FLAG_DEAD) !== 0)
95
+ return 0;
96
+ if (amount <= 0)
97
+ return 0;
98
+ const before = this.current[i] ?? 0;
99
+ const max = this.max[i] ?? 0;
100
+ const after = Math.min(max, before + amount);
101
+ this.current[i] = after;
102
+ return after - before;
103
+ }
104
+ setInvulnerable(e, invulnerable) {
105
+ const i = entityIndex(e);
106
+ if (i >= this.capacity)
107
+ return;
108
+ const f = this.flags[i] ?? 0;
109
+ this.flags[i] = invulnerable ? f | HEALTH_FLAG_INVULNERABLE : f & ~HEALTH_FLAG_INVULNERABLE;
110
+ }
111
+ isAlive(e) {
112
+ const i = entityIndex(e);
113
+ if (i >= this.capacity)
114
+ return false;
115
+ const f = this.flags[i] ?? 0;
116
+ return (f & HEALTH_FLAG_ACTIVE) !== 0 && (f & HEALTH_FLAG_DEAD) === 0;
117
+ }
118
+ isDead(e) {
119
+ const i = entityIndex(e);
120
+ if (i >= this.capacity)
121
+ return false;
122
+ return ((this.flags[i] ?? 0) & HEALTH_FLAG_DEAD) !== 0;
123
+ }
124
+ isInvulnerable(e) {
125
+ const i = entityIndex(e);
126
+ if (i >= this.capacity)
127
+ return false;
128
+ return ((this.flags[i] ?? 0) & HEALTH_FLAG_INVULNERABLE) !== 0;
129
+ }
130
+ getHp(e) {
131
+ const i = entityIndex(e);
132
+ if (i >= this.capacity)
133
+ return 0;
134
+ return this.current[i] ?? 0;
135
+ }
136
+ getMaxHp(e) {
137
+ const i = entityIndex(e);
138
+ if (i >= this.capacity)
139
+ return 0;
140
+ return this.max[i] ?? 0;
141
+ }
142
+ getHighWaterMark() {
143
+ return this.highWaterMark;
144
+ }
145
+ getCapacity() {
146
+ return this.capacity;
147
+ }
148
+ }
149
+ export const POOL_HEALTH = 'health';
150
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/components/health.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type EntityId } from '../entity.js';
2
+ export declare const INTERACTABLE_FLAG_ACTIVE: number;
3
+ export type InteractableKind = 'npc' | 'portal' | 'lore' | 'item';
4
+ export interface InteractableConfig {
5
+ kind: InteractableKind;
6
+ prompt: string;
7
+ payload: string;
8
+ radius: number;
9
+ }
10
+ export declare class InteractablePool {
11
+ radius: Float32Array;
12
+ kind: InteractableKind[];
13
+ prompt: string[];
14
+ payload: string[];
15
+ flags: Uint8Array;
16
+ private capacity;
17
+ private highWaterMark;
18
+ constructor(initialCapacity?: number);
19
+ ensureCapacity(neededIndex: number): void;
20
+ attach(e: EntityId, cfg: InteractableConfig): void;
21
+ detach(e: EntityId): void;
22
+ isActive(e: EntityId): boolean;
23
+ getPrompt(e: EntityId): string;
24
+ getKind(e: EntityId): InteractableKind;
25
+ getPayload(e: EntityId): string;
26
+ getHighWaterMark(): number;
27
+ getCapacity(): number;
28
+ }
29
+ export declare const POOL_INTERACTABLE = "interactable";
30
+ //# sourceMappingURL=interactable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactable.d.ts","sourceRoot":"","sources":["../../src/components/interactable.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,cAAc,CAAC;AAG1D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAC;IAGvB,MAAM,EAAE,MAAM,CAAC;IAIf,OAAO,EAAE,MAAM,CAAC;IAGhB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,gBAAgB;IAE3B,MAAM,EAAE,YAAY,CAAC;IAGrB,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,KAAK,EAAE,UAAU,CAAC;IAElB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;gBAEtB,eAAe,GAAE,MAAW;IASxC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAgBzC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAWlD,MAAM,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAMzB,QAAQ,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAM9B,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM;IAM9B,OAAO,CAAC,CAAC,EAAE,QAAQ,GAAG,gBAAgB;IAMtC,UAAU,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM;IAM/B,gBAAgB,IAAI,MAAM;IAC1B,WAAW,IAAI,MAAM;CACtB;AAED,eAAO,MAAM,iBAAiB,iBAAiB,CAAC"}
@@ -0,0 +1,94 @@
1
+ // InteractablePool - per-entity flag marking the entity as something
2
+ // the player can interact with (talk, examine, use, transition).
3
+ //
4
+ // NPCs, portal tiles, lore stones, treasure chests all get an
5
+ // InteractableComponent. The InteractionSystem detects player clicks
6
+ // or proximity-key-press and dispatches the configured action.
7
+ //
8
+ // Layout: kind (tag for routing), prompt (label shown when in range),
9
+ // payload (free-form data for the action handler). For Phase 8 v1
10
+ // the payload is just a string id that the demo's action handler
11
+ // switches on; future versions may extend to action functions.
12
+ import { entityIndex } from '../entity.js';
13
+ import { growF32, growU8, nextPow2 } from '../util/typed-arrays.js';
14
+ export const INTERACTABLE_FLAG_ACTIVE = 1 << 0;
15
+ export class InteractablePool {
16
+ // Hot
17
+ radius;
18
+ // Cold (per-entity strings)
19
+ kind;
20
+ prompt;
21
+ payload;
22
+ flags;
23
+ capacity = 0;
24
+ highWaterMark = 0;
25
+ constructor(initialCapacity = 32) {
26
+ this.capacity = nextPow2(initialCapacity);
27
+ this.radius = new Float32Array(this.capacity);
28
+ this.kind = new Array(this.capacity).fill('npc');
29
+ this.prompt = new Array(this.capacity).fill('');
30
+ this.payload = new Array(this.capacity).fill('');
31
+ this.flags = new Uint8Array(this.capacity);
32
+ }
33
+ ensureCapacity(neededIndex) {
34
+ if (neededIndex < this.capacity)
35
+ return;
36
+ const next = nextPow2(neededIndex + 1);
37
+ this.radius = growF32(this.radius, next);
38
+ this.kind.length = next;
39
+ this.prompt.length = next;
40
+ this.payload.length = next;
41
+ for (let i = this.capacity; i < next; i++) {
42
+ this.kind[i] = 'npc';
43
+ this.prompt[i] = '';
44
+ this.payload[i] = '';
45
+ }
46
+ this.flags = growU8(this.flags, next);
47
+ this.capacity = next;
48
+ }
49
+ attach(e, cfg) {
50
+ const i = entityIndex(e);
51
+ this.ensureCapacity(i);
52
+ this.radius[i] = cfg.radius;
53
+ this.kind[i] = cfg.kind;
54
+ this.prompt[i] = cfg.prompt;
55
+ this.payload[i] = cfg.payload;
56
+ this.flags[i] = INTERACTABLE_FLAG_ACTIVE;
57
+ if (i >= this.highWaterMark)
58
+ this.highWaterMark = i + 1;
59
+ }
60
+ detach(e) {
61
+ const i = entityIndex(e);
62
+ if (i >= this.capacity)
63
+ return;
64
+ this.flags[i] = 0;
65
+ }
66
+ isActive(e) {
67
+ const i = entityIndex(e);
68
+ if (i >= this.capacity)
69
+ return false;
70
+ return ((this.flags[i] ?? 0) & INTERACTABLE_FLAG_ACTIVE) !== 0;
71
+ }
72
+ getPrompt(e) {
73
+ const i = entityIndex(e);
74
+ if (i >= this.capacity)
75
+ return '';
76
+ return this.prompt[i] ?? '';
77
+ }
78
+ getKind(e) {
79
+ const i = entityIndex(e);
80
+ if (i >= this.capacity)
81
+ return 'npc';
82
+ return this.kind[i] ?? 'npc';
83
+ }
84
+ getPayload(e) {
85
+ const i = entityIndex(e);
86
+ if (i >= this.capacity)
87
+ return '';
88
+ return this.payload[i] ?? '';
89
+ }
90
+ getHighWaterMark() { return this.highWaterMark; }
91
+ getCapacity() { return this.capacity; }
92
+ }
93
+ export const POOL_INTERACTABLE = 'interactable';
94
+ //# sourceMappingURL=interactable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactable.js","sourceRoot":"","sources":["../../src/components/interactable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { type EntityId } from '../entity.js';
2
+ import type { ColorRGBA } from '../util/color.js';
3
+ export declare const EMITTER_FLAG_ACTIVE: number;
4
+ export declare const EMITTER_FLAG_ADDITIVE: number;
5
+ export interface EmitterConfig {
6
+ rate: number;
7
+ particleLife: number;
8
+ speedMin: number;
9
+ speedMax: number;
10
+ dirX: number;
11
+ dirY: number;
12
+ dirZ: number;
13
+ coneRadians: number;
14
+ ax: number;
15
+ ay: number;
16
+ az: number;
17
+ startSize: number;
18
+ endSize: number;
19
+ startColor: Readonly<ColorRGBA>;
20
+ endColor: Readonly<ColorRGBA>;
21
+ additive: boolean;
22
+ }
23
+ export declare class ParticleEmitterPool {
24
+ rate: Float32Array;
25
+ spawnCarry: Float32Array;
26
+ burstRemaining: Int32Array;
27
+ particleLife: Float32Array;
28
+ speedMin: Float32Array;
29
+ speedMax: Float32Array;
30
+ dirX: Float32Array;
31
+ dirY: Float32Array;
32
+ dirZ: Float32Array;
33
+ coneRadians: Float32Array;
34
+ ax: Float32Array;
35
+ ay: Float32Array;
36
+ az: Float32Array;
37
+ startSize: Float32Array;
38
+ endSize: Float32Array;
39
+ startR: Float32Array;
40
+ startG: Float32Array;
41
+ startB: Float32Array;
42
+ startA: Float32Array;
43
+ endR: Float32Array;
44
+ endG: Float32Array;
45
+ endB: Float32Array;
46
+ endA: Float32Array;
47
+ flags: Uint8Array;
48
+ private capacity;
49
+ private highWaterMark;
50
+ constructor(initialCapacity?: number);
51
+ private ensureCapacity;
52
+ attach(e: EntityId, cfg: EmitterConfig): void;
53
+ detach(e: EntityId): void;
54
+ setActive(e: EntityId, active: boolean): void;
55
+ setRate(e: EntityId, rate: number): void;
56
+ burst(e: EntityId, count: number): void;
57
+ isActive(e: EntityId): boolean;
58
+ isAdditive(e: EntityId): boolean;
59
+ getHighWaterMark(): number;
60
+ getCapacity(): number;
61
+ }
62
+ //# sourceMappingURL=particle-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"particle-emitter.d.ts","sourceRoot":"","sources":["../../src/components/particle-emitter.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,cAAc,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,mBAAmB,QAAS,CAAC;AAC1C,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAI5C,MAAM,WAAW,aAAa;IAI5B,IAAI,EAAE,MAAM,CAAC;IAEb,YAAY,EAAE,MAAM,CAAC;IAKrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IAEjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IAEb,WAAW,EAAE,MAAM,CAAC;IAEpB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IAEX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChC,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE9B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,mBAAmB;IAE9B,IAAI,EAAE,YAAY,CAAC;IAEnB,UAAU,EAAE,YAAY,CAAC;IAGzB,cAAc,EAAE,UAAU,CAAC;IAG3B,YAAY,EAAE,YAAY,CAAC;IAG3B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IAGvB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,WAAW,EAAE,YAAY,CAAC;IAG1B,EAAE,EAAE,YAAY,CAAC;IACjB,EAAE,EAAE,YAAY,CAAC;IACjB,EAAE,EAAE,YAAY,CAAC;IAGjB,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IAEnB,KAAK,EAAE,UAAU,CAAC;IAElB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,aAAa,CAAa;gBAEtB,eAAe,GAAE,MAAW;IA6BxC,OAAO,CAAC,cAAc;IAgCtB,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI;IAgC7C,MAAM,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI;IAQzB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAO7C,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IASxC,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAMvC,QAAQ,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAM9B,UAAU,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO;IAMhC,gBAAgB,IAAI,MAAM;IAI1B,WAAW,IAAI,MAAM;CAGtB"}