@almadar/std 1.0.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 (78) hide show
  1. package/LICENSE +72 -0
  2. package/dist/behaviors/action-affinity.d.ts +88 -0
  3. package/dist/behaviors/action-affinity.js +290 -0
  4. package/dist/behaviors/action-affinity.js.map +1 -0
  5. package/dist/behaviors/async.d.ts +20 -0
  6. package/dist/behaviors/async.js +542 -0
  7. package/dist/behaviors/async.js.map +1 -0
  8. package/dist/behaviors/data-management.d.ts +40 -0
  9. package/dist/behaviors/data-management.js +495 -0
  10. package/dist/behaviors/data-management.js.map +1 -0
  11. package/dist/behaviors/feedback.d.ts +18 -0
  12. package/dist/behaviors/feedback.js +307 -0
  13. package/dist/behaviors/feedback.js.map +1 -0
  14. package/dist/behaviors/game-core.d.ts +40 -0
  15. package/dist/behaviors/game-core.js +443 -0
  16. package/dist/behaviors/game-core.js.map +1 -0
  17. package/dist/behaviors/game-entity.d.ts +39 -0
  18. package/dist/behaviors/game-entity.js +643 -0
  19. package/dist/behaviors/game-entity.js.map +1 -0
  20. package/dist/behaviors/game-ui.d.ts +29 -0
  21. package/dist/behaviors/game-ui.js +493 -0
  22. package/dist/behaviors/game-ui.js.map +1 -0
  23. package/dist/behaviors/index.d.ts +11 -0
  24. package/dist/behaviors/index.js +4539 -0
  25. package/dist/behaviors/index.js.map +1 -0
  26. package/dist/behaviors/registry.d.ts +103 -0
  27. package/dist/behaviors/registry.js +4166 -0
  28. package/dist/behaviors/registry.js.map +1 -0
  29. package/dist/behaviors/types.d.ts +179 -0
  30. package/dist/behaviors/types.js +111 -0
  31. package/dist/behaviors/types.js.map +1 -0
  32. package/dist/behaviors/ui-interaction.d.ts +36 -0
  33. package/dist/behaviors/ui-interaction.js +1104 -0
  34. package/dist/behaviors/ui-interaction.js.map +1 -0
  35. package/dist/index.d.ts +195 -0
  36. package/dist/index.js +8209 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/modules/array.d.ts +28 -0
  39. package/dist/modules/array.js +556 -0
  40. package/dist/modules/array.js.map +1 -0
  41. package/dist/modules/async.d.ts +22 -0
  42. package/dist/modules/async.js +112 -0
  43. package/dist/modules/async.js.map +1 -0
  44. package/dist/modules/format.d.ts +21 -0
  45. package/dist/modules/format.js +129 -0
  46. package/dist/modules/format.js.map +1 -0
  47. package/dist/modules/index.d.ts +12 -0
  48. package/dist/modules/index.js +3131 -0
  49. package/dist/modules/index.js.map +1 -0
  50. package/dist/modules/math.d.ts +22 -0
  51. package/dist/modules/math.js +215 -0
  52. package/dist/modules/math.js.map +1 -0
  53. package/dist/modules/nn.d.ts +23 -0
  54. package/dist/modules/nn.js +189 -0
  55. package/dist/modules/nn.js.map +1 -0
  56. package/dist/modules/object.d.ts +22 -0
  57. package/dist/modules/object.js +257 -0
  58. package/dist/modules/object.js.map +1 -0
  59. package/dist/modules/str.d.ts +21 -0
  60. package/dist/modules/str.js +344 -0
  61. package/dist/modules/str.js.map +1 -0
  62. package/dist/modules/tensor.d.ts +23 -0
  63. package/dist/modules/tensor.js +427 -0
  64. package/dist/modules/tensor.js.map +1 -0
  65. package/dist/modules/time.d.ts +24 -0
  66. package/dist/modules/time.js +323 -0
  67. package/dist/modules/time.js.map +1 -0
  68. package/dist/modules/train.d.ts +23 -0
  69. package/dist/modules/train.js +308 -0
  70. package/dist/modules/train.js.map +1 -0
  71. package/dist/modules/validate.d.ts +23 -0
  72. package/dist/modules/validate.js +301 -0
  73. package/dist/modules/validate.js.map +1 -0
  74. package/dist/registry.d.ts +140 -0
  75. package/dist/registry.js +3240 -0
  76. package/dist/registry.js.map +1 -0
  77. package/dist/types-I95R8_FN.d.ts +91 -0
  78. package/package.json +59 -0
@@ -0,0 +1,643 @@
1
+ // behaviors/game-entity.ts
2
+ var HEALTH_BEHAVIOR = {
3
+ name: "std/Health",
4
+ category: "game-entity",
5
+ description: "Entity health with damage, healing, invulnerability, and death",
6
+ suggestedFor: [
7
+ "Player characters",
8
+ "Enemies",
9
+ "Destructible objects",
10
+ "Bosses"
11
+ ],
12
+ dataEntities: [
13
+ {
14
+ name: "HealthState",
15
+ runtime: true,
16
+ fields: [
17
+ { name: "currentHealth", type: "number", default: 100 },
18
+ { name: "maxHealth", type: "number", default: 100 },
19
+ { name: "isInvulnerable", type: "boolean", default: false },
20
+ { name: "lastDamageTime", type: "number", default: 0 }
21
+ ]
22
+ }
23
+ ],
24
+ stateMachine: {
25
+ initial: "Alive",
26
+ states: [
27
+ { name: "Alive", isInitial: true },
28
+ { name: "Damaged" },
29
+ { name: "Invulnerable" },
30
+ { name: "Dead" }
31
+ ],
32
+ events: [
33
+ { key: "INIT" },
34
+ { key: "DAMAGE" },
35
+ { key: "HEAL" },
36
+ { key: "DIE" },
37
+ { key: "RESPAWN" },
38
+ { key: "INVULNERABILITY_END" }
39
+ ],
40
+ transitions: [
41
+ {
42
+ from: "*",
43
+ to: "Alive",
44
+ event: "INIT",
45
+ effects: [
46
+ ["set", "@entity.currentHealth", "@config.maxHealth"],
47
+ ["set", "@entity.maxHealth", "@config.maxHealth"],
48
+ ["set", "@entity.isInvulnerable", false],
49
+ ["render", "hud.health", "health-bar", {
50
+ current: "@entity.currentHealth",
51
+ max: "@entity.maxHealth"
52
+ }]
53
+ ]
54
+ },
55
+ {
56
+ from: "Alive",
57
+ to: "Damaged",
58
+ event: "DAMAGE",
59
+ guard: ["not", "@entity.isInvulnerable"],
60
+ effects: [
61
+ ["set", "@entity.currentHealth", ["math/max", 0, ["-", "@entity.currentHealth", "@payload.amount"]]],
62
+ ["set", "@entity.lastDamageTime", "@now"],
63
+ [
64
+ "if",
65
+ ["<=", "@entity.currentHealth", 0],
66
+ ["emit", "DIE"],
67
+ [
68
+ "do",
69
+ ["set", "@entity.isInvulnerable", true],
70
+ ["render", "entity.flash", "damage-flash", {}]
71
+ ]
72
+ ]
73
+ ]
74
+ },
75
+ {
76
+ from: ["Damaged", "Invulnerable"],
77
+ to: "Alive",
78
+ event: "INVULNERABILITY_END",
79
+ effects: [
80
+ ["set", "@entity.isInvulnerable", false]
81
+ ]
82
+ },
83
+ {
84
+ from: ["Alive", "Damaged", "Invulnerable"],
85
+ event: "HEAL",
86
+ effects: [
87
+ ["set", "@entity.currentHealth", ["math/min", "@entity.maxHealth", ["+", "@entity.currentHealth", "@payload.amount"]]],
88
+ ["render", "entity.effect", "heal-effect", {}]
89
+ ]
90
+ },
91
+ {
92
+ from: ["Alive", "Damaged", "Invulnerable"],
93
+ to: "Dead",
94
+ event: "DIE",
95
+ effects: [
96
+ ["set", "@entity.currentHealth", 0],
97
+ ["emit", "@config.onDeath", { entityId: "@entity.id" }],
98
+ ["render", "entity.sprite", "death-animation", {}]
99
+ ]
100
+ },
101
+ {
102
+ from: "Dead",
103
+ to: "Alive",
104
+ event: "RESPAWN",
105
+ effects: [
106
+ ["emit", "INIT"]
107
+ ]
108
+ }
109
+ ]
110
+ },
111
+ ticks: [
112
+ {
113
+ name: "InvulnerabilityTimer",
114
+ interval: "frame",
115
+ guard: ["and", "@entity.isInvulnerable", [">", ["-", "@now", "@entity.lastDamageTime"], "@config.invulnerabilityTime"]],
116
+ effects: [
117
+ ["emit", "INVULNERABILITY_END"]
118
+ ]
119
+ }
120
+ ],
121
+ configSchema: {
122
+ required: [
123
+ { name: "maxHealth", type: "number", description: "Maximum health points" }
124
+ ],
125
+ optional: [
126
+ { name: "invulnerabilityTime", type: "number", description: "Invulnerability duration after damage (ms)", default: 500 },
127
+ { name: "onDeath", type: "event", description: "Event to emit on death", default: "ENTITY_DIED" },
128
+ { name: "showHealthBar", type: "boolean", description: "Render health bar", default: true }
129
+ ]
130
+ }
131
+ };
132
+ var SCORE_BEHAVIOR = {
133
+ name: "std/Score",
134
+ category: "game-entity",
135
+ description: "Score tracking with points, combos, and multipliers",
136
+ suggestedFor: [
137
+ "Arcade games",
138
+ "Puzzle games",
139
+ "Platformers with collectibles",
140
+ "Competitive games"
141
+ ],
142
+ dataEntities: [
143
+ {
144
+ name: "ScoreState",
145
+ runtime: true,
146
+ singleton: true,
147
+ fields: [
148
+ { name: "currentScore", type: "number", default: 0 },
149
+ { name: "highScore", type: "number", default: 0 },
150
+ { name: "comboCount", type: "number", default: 0 },
151
+ { name: "multiplier", type: "number", default: 1 },
152
+ { name: "lastScoreTime", type: "number", default: 0 }
153
+ ]
154
+ }
155
+ ],
156
+ stateMachine: {
157
+ initial: "Active",
158
+ states: [
159
+ { name: "Active", isInitial: true }
160
+ ],
161
+ events: [
162
+ { key: "INIT" },
163
+ { key: "ADD_POINTS" },
164
+ { key: "COMBO_HIT" },
165
+ { key: "COMBO_BREAK" },
166
+ { key: "RESET" },
167
+ { key: "SAVE_HIGH_SCORE" }
168
+ ],
169
+ transitions: [
170
+ {
171
+ from: "*",
172
+ event: "INIT",
173
+ effects: [
174
+ ["set", "@entity.currentScore", 0],
175
+ ["set", "@entity.comboCount", 0],
176
+ ["set", "@entity.multiplier", 1],
177
+ ["render", "hud.score", "score-display", {
178
+ score: "@entity.currentScore",
179
+ highScore: "@entity.highScore",
180
+ combo: "@entity.comboCount",
181
+ multiplier: "@entity.multiplier"
182
+ }]
183
+ ]
184
+ },
185
+ {
186
+ event: "ADD_POINTS",
187
+ effects: [
188
+ ["set", "@entity.currentScore", ["+", "@entity.currentScore", ["*", "@payload.points", "@entity.multiplier"]]],
189
+ ["set", "@entity.lastScoreTime", "@now"],
190
+ ["render", "entity.effect", "score-popup", {
191
+ points: ["*", "@payload.points", "@entity.multiplier"],
192
+ position: "@payload.position"
193
+ }]
194
+ ]
195
+ },
196
+ {
197
+ event: "COMBO_HIT",
198
+ effects: [
199
+ ["set", "@entity.comboCount", ["+", "@entity.comboCount", 1]],
200
+ ["set", "@entity.multiplier", ["math/min", "@config.maxMultiplier", ["+", 1, ["/", "@entity.comboCount", 5]]]],
201
+ ["set", "@entity.lastScoreTime", "@now"]
202
+ ]
203
+ },
204
+ {
205
+ event: "COMBO_BREAK",
206
+ effects: [
207
+ ["set", "@entity.comboCount", 0],
208
+ ["set", "@entity.multiplier", 1]
209
+ ]
210
+ },
211
+ {
212
+ event: "RESET",
213
+ effects: [
214
+ [
215
+ "if",
216
+ [">", "@entity.currentScore", "@entity.highScore"],
217
+ ["set", "@entity.highScore", "@entity.currentScore"]
218
+ ],
219
+ ["emit", "INIT"]
220
+ ]
221
+ },
222
+ {
223
+ event: "SAVE_HIGH_SCORE",
224
+ guard: [">", "@entity.currentScore", "@entity.highScore"],
225
+ effects: [
226
+ ["set", "@entity.highScore", "@entity.currentScore"],
227
+ ["persist", "save", "HighScore", { score: "@entity.highScore" }]
228
+ ]
229
+ }
230
+ ]
231
+ },
232
+ ticks: [
233
+ {
234
+ name: "ComboTimeout",
235
+ interval: "frame",
236
+ guard: ["and", [">", "@entity.comboCount", 0], [">", ["-", "@now", "@entity.lastScoreTime"], "@config.comboTimeWindow"]],
237
+ effects: [
238
+ ["emit", "COMBO_BREAK"]
239
+ ]
240
+ }
241
+ ],
242
+ configSchema: {
243
+ required: [],
244
+ optional: [
245
+ { name: "comboTimeWindow", type: "number", description: "Time window for combos (ms)", default: 2e3 },
246
+ { name: "maxMultiplier", type: "number", description: "Maximum combo multiplier", default: 10 },
247
+ { name: "persistHighScore", type: "boolean", description: "Save high score to storage", default: true }
248
+ ]
249
+ }
250
+ };
251
+ var MOVEMENT_BEHAVIOR = {
252
+ name: "std/Movement",
253
+ category: "game-entity",
254
+ description: "Entity movement with speed and direction",
255
+ suggestedFor: [
256
+ "Player characters",
257
+ "NPCs",
258
+ "Enemies",
259
+ "Moving platforms"
260
+ ],
261
+ requiredFields: [
262
+ { name: "x", type: "number", description: "Entity X position" },
263
+ { name: "y", type: "number", description: "Entity Y position" }
264
+ ],
265
+ dataEntities: [
266
+ {
267
+ name: "MovementState",
268
+ runtime: true,
269
+ fields: [
270
+ { name: "direction", type: "number", default: 0 },
271
+ { name: "facingRight", type: "boolean", default: true },
272
+ { name: "canJump", type: "boolean", default: true }
273
+ ]
274
+ }
275
+ ],
276
+ stateMachine: {
277
+ initial: "Idle",
278
+ states: [
279
+ { name: "Idle", isInitial: true },
280
+ { name: "Moving" },
281
+ { name: "Jumping" },
282
+ { name: "Falling" }
283
+ ],
284
+ events: [
285
+ { key: "MOVE" },
286
+ { key: "STOP" },
287
+ { key: "JUMP" },
288
+ { key: "LAND" }
289
+ ],
290
+ transitions: [
291
+ {
292
+ from: "Idle",
293
+ to: "Moving",
294
+ event: "MOVE",
295
+ effects: [
296
+ ["set", "@entity.direction", "@payload.direction"],
297
+ [
298
+ "if",
299
+ [">", "@payload.direction", 0],
300
+ ["set", "@entity.facingRight", true]
301
+ ],
302
+ [
303
+ "if",
304
+ ["<", "@payload.direction", 0],
305
+ ["set", "@entity.facingRight", false]
306
+ ]
307
+ ]
308
+ },
309
+ {
310
+ from: "Moving",
311
+ event: "MOVE",
312
+ effects: [
313
+ ["set", "@entity.direction", "@payload.direction"],
314
+ [
315
+ "if",
316
+ [">", "@payload.direction", 0],
317
+ ["set", "@entity.facingRight", true]
318
+ ],
319
+ [
320
+ "if",
321
+ ["<", "@payload.direction", 0],
322
+ ["set", "@entity.facingRight", false]
323
+ ]
324
+ ]
325
+ },
326
+ {
327
+ from: "Moving",
328
+ to: "Idle",
329
+ event: "STOP",
330
+ effects: [
331
+ ["set", "@entity.direction", 0]
332
+ ]
333
+ },
334
+ {
335
+ from: ["Idle", "Moving"],
336
+ to: "Jumping",
337
+ event: "JUMP",
338
+ guard: "@entity.canJump",
339
+ effects: [
340
+ ["set", "@entity.canJump", false],
341
+ ["emit", "APPLY_FORCE", { fx: 0, fy: "@config.jumpForce" }]
342
+ ]
343
+ },
344
+ {
345
+ from: ["Jumping", "Falling"],
346
+ to: "Idle",
347
+ event: "LAND",
348
+ effects: [
349
+ ["set", "@entity.canJump", true],
350
+ [
351
+ "if",
352
+ ["!=", "@entity.direction", 0],
353
+ ["emit", "MOVE", { direction: "@entity.direction" }]
354
+ ]
355
+ ]
356
+ }
357
+ ]
358
+ },
359
+ ticks: [
360
+ {
361
+ name: "ApplyMovement",
362
+ interval: "frame",
363
+ guard: ["!=", "@entity.direction", 0],
364
+ effects: [
365
+ ["set", "@entity.x", ["+", "@entity.x", ["*", "@entity.direction", "@config.moveSpeed"]]]
366
+ ]
367
+ }
368
+ ],
369
+ configSchema: {
370
+ required: [],
371
+ optional: [
372
+ { name: "moveSpeed", type: "number", description: "Movement speed (pixels/frame)", default: 5 },
373
+ { name: "jumpForce", type: "number", description: "Jump velocity", default: -12 },
374
+ { name: "acceleration", type: "number", description: "Acceleration rate", default: 0.5 },
375
+ { name: "deceleration", type: "number", description: "Deceleration rate", default: 0.3 }
376
+ ]
377
+ }
378
+ };
379
+ var COMBAT_BEHAVIOR = {
380
+ name: "std/Combat",
381
+ category: "game-entity",
382
+ description: "Combat system with attacks, cooldowns, and hitboxes",
383
+ suggestedFor: [
384
+ "Fighting games",
385
+ "Action RPGs",
386
+ "Beat-em-ups",
387
+ "Boss encounters"
388
+ ],
389
+ dataEntities: [
390
+ {
391
+ name: "CombatState",
392
+ runtime: true,
393
+ fields: [
394
+ { name: "isAttacking", type: "boolean", default: false },
395
+ { name: "attackStartTime", type: "number", default: 0 },
396
+ { name: "hitEntities", type: "array", default: [] }
397
+ ]
398
+ }
399
+ ],
400
+ stateMachine: {
401
+ initial: "Ready",
402
+ states: [
403
+ { name: "Ready", isInitial: true },
404
+ { name: "Attacking" },
405
+ { name: "Cooldown" }
406
+ ],
407
+ events: [
408
+ { key: "ATTACK" },
409
+ { key: "ATTACK_END" },
410
+ { key: "HIT_CONNECT" },
411
+ { key: "COOLDOWN_END" }
412
+ ],
413
+ transitions: [
414
+ {
415
+ from: "Ready",
416
+ to: "Attacking",
417
+ event: "ATTACK",
418
+ effects: [
419
+ ["set", "@entity.isAttacking", true],
420
+ ["set", "@entity.attackStartTime", "@now"],
421
+ ["set", "@entity.hitEntities", []],
422
+ ["render", "entity.sprite", "attack-animation", {}],
423
+ ["render", "entity.hitbox", "hitbox", {
424
+ active: true,
425
+ offset: "@config.hitboxOffset",
426
+ size: "@config.hitboxSize"
427
+ }]
428
+ ]
429
+ },
430
+ {
431
+ from: "Attacking",
432
+ event: "HIT_CONNECT",
433
+ guard: ["not", ["array/includes", "@entity.hitEntities", "@payload.entityId"]],
434
+ effects: [
435
+ ["set", "@entity.hitEntities", ["array/append", "@entity.hitEntities", "@payload.entityId"]],
436
+ ["emit", "DAMAGE", { target: "@payload.entityId", amount: "@config.attackDamage" }],
437
+ ["render", "effect.impact", "hit-effect", { position: "@payload.position" }]
438
+ ]
439
+ },
440
+ {
441
+ from: "Attacking",
442
+ to: "Cooldown",
443
+ event: "ATTACK_END",
444
+ effects: [
445
+ ["set", "@entity.isAttacking", false],
446
+ ["render", "entity.hitbox", null]
447
+ ]
448
+ },
449
+ {
450
+ from: "Cooldown",
451
+ to: "Ready",
452
+ event: "COOLDOWN_END",
453
+ effects: []
454
+ }
455
+ ]
456
+ },
457
+ ticks: [
458
+ {
459
+ name: "AttackDuration",
460
+ interval: "frame",
461
+ guard: ["and", "@entity.isAttacking", [">", ["-", "@now", "@entity.attackStartTime"], "@config.attackDuration"]],
462
+ effects: [
463
+ ["emit", "ATTACK_END"]
464
+ ]
465
+ },
466
+ {
467
+ name: "CooldownTimer",
468
+ interval: "frame",
469
+ guard: ["and", ["=", "@state", "Cooldown"], [">", ["-", "@now", "@entity.attackStartTime"], ["+", "@config.attackDuration", "@config.cooldownDuration"]]],
470
+ effects: [
471
+ ["emit", "COOLDOWN_END"]
472
+ ]
473
+ }
474
+ ],
475
+ configSchema: {
476
+ required: [],
477
+ optional: [
478
+ { name: "attackDamage", type: "number", description: "Damage per attack", default: 10 },
479
+ { name: "attackDuration", type: "number", description: "Attack animation duration (ms)", default: 200 },
480
+ { name: "cooldownDuration", type: "number", description: "Cooldown between attacks (ms)", default: 300 },
481
+ { name: "hitboxOffset", type: "object", description: "Hitbox offset from entity", default: { x: 20, y: 0 } },
482
+ { name: "hitboxSize", type: "object", description: "Hitbox dimensions", default: { width: 30, height: 40 } }
483
+ ]
484
+ }
485
+ };
486
+ var INVENTORY_BEHAVIOR = {
487
+ name: "std/Inventory",
488
+ category: "game-entity",
489
+ description: "Item collection, storage, and usage",
490
+ suggestedFor: [
491
+ "RPGs",
492
+ "Adventure games",
493
+ "Survival games",
494
+ "Collectible-based games"
495
+ ],
496
+ dataEntities: [
497
+ {
498
+ name: "InventoryState",
499
+ runtime: true,
500
+ fields: [
501
+ { name: "items", type: "array", default: [] },
502
+ { name: "selectedSlot", type: "number", default: 0 },
503
+ { name: "isOpen", type: "boolean", default: false },
504
+ { name: "equipped", type: "object", default: {} }
505
+ ]
506
+ }
507
+ ],
508
+ stateMachine: {
509
+ initial: "Empty",
510
+ states: [
511
+ { name: "Empty", isInitial: true },
512
+ { name: "HasItems" },
513
+ { name: "Full" }
514
+ ],
515
+ events: [
516
+ { key: "COLLECT" },
517
+ { key: "USE" },
518
+ { key: "DROP" },
519
+ { key: "EQUIP" },
520
+ { key: "UNEQUIP" },
521
+ { key: "OPEN" },
522
+ { key: "CLOSE" },
523
+ { key: "INVENTORY_EMPTY" }
524
+ ],
525
+ transitions: [
526
+ {
527
+ from: ["Empty", "HasItems"],
528
+ to: "HasItems",
529
+ event: "COLLECT",
530
+ guard: ["<", ["array/len", "@entity.items"], "@config.maxSlots"],
531
+ effects: [
532
+ ["set", "@entity.items", ["array/append", "@entity.items", "@payload.item"]],
533
+ ["render", "effect.collect", "collect-effect", { item: "@payload.item" }],
534
+ ["notify", { type: "info", message: ["str/concat", "Collected ", "@payload.item.name"] }]
535
+ ]
536
+ },
537
+ {
538
+ from: "HasItems",
539
+ event: "USE",
540
+ effects: [
541
+ [
542
+ "let",
543
+ [["item", ["array/nth", "@entity.items", "@payload.slot"]]],
544
+ [
545
+ "if",
546
+ "@item.onUse",
547
+ ["emit", "@item.onUse", { item: "@item" }]
548
+ ],
549
+ [
550
+ "if",
551
+ "@item.consumable",
552
+ ["set", "@entity.items", ["array/filter", "@entity.items", ["fn", "i", "idx", ["!=", "@idx", "@payload.slot"]]]]
553
+ ]
554
+ ],
555
+ [
556
+ "if",
557
+ ["=", ["array/len", "@entity.items"], 0],
558
+ ["emit", "INVENTORY_EMPTY"]
559
+ ]
560
+ ]
561
+ },
562
+ {
563
+ from: "HasItems",
564
+ event: "DROP",
565
+ effects: [
566
+ [
567
+ "let",
568
+ [["item", ["array/nth", "@entity.items", "@payload.slot"]]],
569
+ ["set", "@entity.items", ["array/filter", "@entity.items", ["fn", "i", "idx", ["!=", "@idx", "@payload.slot"]]]],
570
+ ["emit", "ITEM_DROPPED", { item: "@item", position: { x: "@entity.x", y: "@entity.y" } }]
571
+ ],
572
+ [
573
+ "if",
574
+ ["=", ["array/len", "@entity.items"], 0],
575
+ ["emit", "INVENTORY_EMPTY"]
576
+ ]
577
+ ]
578
+ },
579
+ {
580
+ from: "HasItems",
581
+ to: "Empty",
582
+ event: "INVENTORY_EMPTY",
583
+ effects: []
584
+ },
585
+ {
586
+ event: "EQUIP",
587
+ effects: [
588
+ ["set", "@entity.equipped", ["object/set", "@entity.equipped", "@payload.slot", "@payload.item"]],
589
+ ["emit", "STATS_UPDATED", { equipped: "@entity.equipped" }]
590
+ ]
591
+ },
592
+ {
593
+ event: "UNEQUIP",
594
+ effects: [
595
+ ["set", "@entity.equipped", ["object/remove", "@entity.equipped", "@payload.slot"]],
596
+ ["emit", "STATS_UPDATED", { equipped: "@entity.equipped" }]
597
+ ]
598
+ },
599
+ {
600
+ event: "OPEN",
601
+ effects: [
602
+ ["set", "@entity.isOpen", true],
603
+ ["render", "overlay.inventory", "inventory-panel", {
604
+ items: "@entity.items",
605
+ selectedSlot: "@entity.selectedSlot",
606
+ equipped: "@entity.equipped",
607
+ maxSlots: "@config.maxSlots",
608
+ onUse: "USE",
609
+ onDrop: "DROP",
610
+ onEquip: "EQUIP",
611
+ onClose: "CLOSE"
612
+ }]
613
+ ]
614
+ },
615
+ {
616
+ event: "CLOSE",
617
+ effects: [
618
+ ["set", "@entity.isOpen", false],
619
+ ["render", "overlay.inventory", null]
620
+ ]
621
+ }
622
+ ]
623
+ },
624
+ configSchema: {
625
+ required: [],
626
+ optional: [
627
+ { name: "maxSlots", type: "number", description: "Maximum inventory slots", default: 20 },
628
+ { name: "stackable", type: "boolean", description: "Allow item stacking", default: true },
629
+ { name: "maxStack", type: "number", description: "Maximum stack size", default: 99 }
630
+ ]
631
+ }
632
+ };
633
+ var GAME_ENTITY_BEHAVIORS = [
634
+ HEALTH_BEHAVIOR,
635
+ SCORE_BEHAVIOR,
636
+ MOVEMENT_BEHAVIOR,
637
+ COMBAT_BEHAVIOR,
638
+ INVENTORY_BEHAVIOR
639
+ ];
640
+
641
+ export { COMBAT_BEHAVIOR, GAME_ENTITY_BEHAVIORS, HEALTH_BEHAVIOR, INVENTORY_BEHAVIOR, MOVEMENT_BEHAVIOR, SCORE_BEHAVIOR };
642
+ //# sourceMappingURL=game-entity.js.map
643
+ //# sourceMappingURL=game-entity.js.map