@almadar/std 16.152.0 → 16.154.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.
- package/behaviors/lolo/infra/atoms/std-data-erasure.lolo +5 -1
- package/behaviors/lolo/ui/core/atoms/std-browse.lolo +1 -0
- package/behaviors/lolo/ui/core/molecules/ui-emoji-picker.lolo +56 -0
- package/behaviors/lolo/ui/core/molecules/ui-popover.lolo +39 -0
- package/behaviors/lolo/ui/core/molecules/ui-table-view.lolo +11 -0
- package/behaviors/lolo/ui/game/atoms/ui-draw-sprite.lolo +2 -2
- package/behaviors/lolo/ui/game/molecules/std-crew-board-2d.lolo +4 -4
- package/behaviors/lolo/ui/game/molecules/std-dungeon-board-2d.lolo +6 -6
- package/behaviors/lolo/ui/game/molecules/std-tactics-board-2d.lolo +41 -9
- package/behaviors/lolo/ui/game/molecules/std-worldmap-board-2d.lolo +2 -2
- package/behaviors/lolo/ui/game/molecules/ui-canvas-2d.lolo +11 -1
- package/behaviors/lolo/ui/game/molecules/ui-canvas.lolo +10 -0
- package/behaviors/lolo/ui/game/organisms/ui-arena-board.lolo +2 -2
- package/behaviors/lolo/ui/game/organisms/ui-battle-board.lolo +110 -7
- package/behaviors/lolo/ui/game/organisms/ui-builder-board.lolo +5 -20
- package/behaviors/lolo/ui/game/organisms/ui-card-battler-board.lolo +2 -0
- package/behaviors/lolo/ui/game/organisms/ui-castle-board.lolo +3 -3
- package/behaviors/lolo/ui/game/organisms/ui-city-builder-board.lolo +9 -7
- package/behaviors/lolo/ui/game/organisms/ui-fishing-board.lolo +8 -8
- package/behaviors/lolo/ui/game/organisms/ui-grid-tactics-demo-board.lolo +2 -2
- package/behaviors/lolo/ui/game/organisms/ui-hex-strategy-board.lolo +5 -1
- package/behaviors/lolo/ui/game/organisms/ui-holiday-runner-board.lolo +1 -1
- package/behaviors/lolo/ui/game/organisms/ui-minigolf-board.lolo +22 -22
- package/behaviors/lolo/ui/game/organisms/ui-physics-sandbox-board.lolo +5 -5
- package/behaviors/lolo/ui/game/organisms/ui-pinball-board.lolo +7 -7
- package/behaviors/lolo/ui/game/organisms/ui-pirate-board.lolo +14 -14
- package/behaviors/lolo/ui/game/organisms/ui-platformer-board.lolo +4 -0
- package/behaviors/lolo/ui/game/organisms/ui-roguelike-board.lolo +5 -5
- package/behaviors/lolo/ui/game/organisms/ui-sokoban-board.lolo +5 -5
- package/behaviors/lolo/ui/game/organisms/ui-sports-board.lolo +10 -7
- package/behaviors/lolo/ui/game/organisms/ui-state-architect-board.lolo +4 -4
- package/behaviors/lolo/ui/game/organisms/ui-tactics-demo-2d.lolo +7 -3
- package/behaviors/lolo/ui/game/organisms/ui-tanks-board.lolo +5 -1
- package/behaviors/lolo/ui/game/organisms/ui-topdown-rts-board.lolo +5 -1
- package/behaviors/lolo/ui/game/organisms/ui-tower-defense-board.lolo +8 -8
- package/behaviors/lolo/ui/game/organisms/ui-uncontrolled-battle-board.lolo +5 -5
- package/behaviors/lolo/ui/game/organisms/ui-winter-ski-board.lolo +7 -7
- package/behaviors/lolo/ui/game/organisms/ui-world-map-board.lolo +3 -3
- package/behaviors/registry/factory-signatures.json +6211 -2181
- package/behaviors/registry/infra/atoms/std-approval-gate.orb +16 -8
- package/behaviors/registry/infra/atoms/std-cache-aside.orb +62 -31
- package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +32 -16
- package/behaviors/registry/infra/atoms/std-data-erasure.orb +17 -9
- package/behaviors/registry/infra/atoms/std-mod-queue.orb +16 -8
- package/behaviors/registry/infra/atoms/std-rate-limiter.orb +28 -14
- package/behaviors/registry/ml/molecules/std-escalating-decision.orb +10 -5
- package/behaviors/registry/ml/molecules/std-knowledge-tracing.orb +4 -2
- package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +2 -1
- package/behaviors/registry/ui/core/atoms/std-browse.orb +4 -0
- package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +2 -1
- package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +4 -2
- package/behaviors/registry/ui/core/atoms/std-esign-request.orb +6 -3
- package/behaviors/registry/ui/core/atoms/std-gallery.orb +18 -9
- package/behaviors/registry/ui/core/atoms/std-import.orb +4 -2
- package/behaviors/registry/ui/core/molecules/ui-emoji-picker.orb +214 -0
- package/behaviors/registry/ui/core/molecules/ui-popover.orb +112 -1
- package/behaviors/registry/ui/core/molecules/ui-table-view.orb +44 -0
- package/behaviors/registry/ui/game/atoms/std-arcade-flow.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-arcade-play.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-chase-ai.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-gather.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-gold.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-grid-tactics.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-hero-nav.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-market-flow.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-objective-flow.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-objective-reach.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-patience.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-production.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-round-flow.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-score.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-survival-flow.orb +1 -0
- package/behaviors/registry/ui/game/atoms/std-xp.orb +1 -0
- package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +2 -2
- package/behaviors/registry/ui/game/molecules/std-crew-board-2d.orb +10 -12
- package/behaviors/registry/ui/game/molecules/std-dungeon-board-2d.orb +15 -18
- package/behaviors/registry/ui/game/molecules/std-tactics-board-2d.orb +860 -138
- package/behaviors/registry/ui/game/molecules/std-worldmap-board-2d.orb +4 -54
- package/behaviors/registry/ui/game/molecules/ui-canvas-2d.orb +16 -1
- package/behaviors/registry/ui/game/molecules/ui-canvas.orb +14 -0
- package/behaviors/registry/ui/game/organisms/ui-arena-board.orb +5 -6
- package/behaviors/registry/ui/game/organisms/ui-battle-board.orb +86 -99
- package/behaviors/registry/ui/game/organisms/ui-builder-board.orb +21 -226
- package/behaviors/registry/ui/game/organisms/ui-card-battler-board.orb +42 -0
- package/behaviors/registry/ui/game/organisms/ui-castle-board.orb +30 -9
- package/behaviors/registry/ui/game/organisms/ui-city-builder-board.orb +49 -0
- package/behaviors/registry/ui/game/organisms/ui-fishing-board.orb +16 -16
- package/behaviors/registry/ui/game/organisms/ui-grid-tactics-demo-board.orb +5 -6
- package/behaviors/registry/ui/game/organisms/ui-hex-strategy-board.orb +30 -10
- package/behaviors/registry/ui/game/organisms/ui-holiday-runner-board.orb +2 -3
- package/behaviors/registry/ui/game/organisms/ui-minigolf-board.orb +55 -11
- package/behaviors/registry/ui/game/organisms/ui-physics-sandbox-board.orb +10 -10
- package/behaviors/registry/ui/game/organisms/ui-pinball-board.orb +8 -8
- package/behaviors/registry/ui/game/organisms/ui-pirate-board.orb +14 -0
- package/behaviors/registry/ui/game/organisms/ui-platformer-board.orb +72 -0
- package/behaviors/registry/ui/game/organisms/ui-roguelike-board.orb +10 -10
- package/behaviors/registry/ui/game/organisms/ui-sokoban-board.orb +10 -10
- package/behaviors/registry/ui/game/organisms/ui-sports-board.orb +60 -0
- package/behaviors/registry/ui/game/organisms/ui-state-architect-board.orb +8 -8
- package/behaviors/registry/ui/game/organisms/ui-tactics-demo-2d.orb +48 -28
- package/behaviors/registry/ui/game/organisms/ui-tanks-board.orb +30 -10
- package/behaviors/registry/ui/game/organisms/ui-topdown-rts-board.orb +31 -12
- package/behaviors/registry/ui/game/organisms/ui-tower-defense-board.orb +8 -0
- package/behaviors/registry/ui/game/organisms/ui-uncontrolled-battle-board.orb +5 -0
- package/behaviors/registry/ui/game/organisms/ui-winter-ski-board.orb +14 -14
- package/behaviors/registry/ui/game/organisms/ui-world-map-board.orb +8 -12
- package/dist/behaviors/behaviors-embeddings.json +384 -380
- package/dist/behaviors/behaviors-registry.json +594 -57
- package/dist/behaviors/exports-reader.js +3409 -3101
- package/dist/behaviors/functions/index.d.ts +596 -5
- package/dist/behaviors/functions/index.js +3389 -3102
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +3410 -3102
- package/dist/behaviors/knob-embeddings.json +1 -1
- package/dist/behaviors/query.js +3409 -3101
- package/dist/behaviors/registry/factory-signatures.json +6211 -2181
- package/dist/behaviors/registry/infra/atoms/std-approval-gate.orb +16 -8
- package/dist/behaviors/registry/infra/atoms/std-cache-aside.orb +62 -31
- package/dist/behaviors/registry/infra/atoms/std-circuit-breaker.orb +32 -16
- package/dist/behaviors/registry/infra/atoms/std-data-erasure.orb +17 -9
- package/dist/behaviors/registry/infra/atoms/std-mod-queue.orb +16 -8
- package/dist/behaviors/registry/infra/atoms/std-rate-limiter.orb +28 -14
- package/dist/behaviors/registry/ml/molecules/std-escalating-decision.orb +10 -5
- package/dist/behaviors/registry/ml/molecules/std-knowledge-tracing.orb +4 -2
- package/dist/behaviors/registry/ui/core/atoms/std-billable-hour.orb +2 -1
- package/dist/behaviors/registry/ui/core/atoms/std-browse.orb +4 -0
- package/dist/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +2 -1
- package/dist/behaviors/registry/ui/core/atoms/std-esign-flow.orb +4 -2
- package/dist/behaviors/registry/ui/core/atoms/std-esign-request.orb +6 -3
- package/dist/behaviors/registry/ui/core/atoms/std-gallery.orb +18 -9
- package/dist/behaviors/registry/ui/core/atoms/std-import.orb +4 -2
- package/dist/behaviors/registry/ui/core/molecules/ui-emoji-picker.orb +214 -0
- package/dist/behaviors/registry/ui/core/molecules/ui-popover.orb +112 -1
- package/dist/behaviors/registry/ui/core/molecules/ui-table-view.orb +44 -0
- package/dist/behaviors/registry/ui/game/atoms/std-arcade-flow.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-arcade-play.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-chase-ai.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-fx-particles.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-gather.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-gold.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-grid-tactics.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-hero-nav.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-market-flow.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-objective-flow.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-objective-reach.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-patience.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-production.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-round-flow.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-score.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-survival-flow.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/std-xp.orb +1 -0
- package/dist/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +2 -2
- package/dist/behaviors/registry/ui/game/molecules/std-crew-board-2d.orb +10 -12
- package/dist/behaviors/registry/ui/game/molecules/std-dungeon-board-2d.orb +15 -18
- package/dist/behaviors/registry/ui/game/molecules/std-tactics-board-2d.orb +860 -138
- package/dist/behaviors/registry/ui/game/molecules/std-worldmap-board-2d.orb +4 -54
- package/dist/behaviors/registry/ui/game/molecules/ui-canvas-2d.orb +16 -1
- package/dist/behaviors/registry/ui/game/molecules/ui-canvas.orb +14 -0
- package/dist/behaviors/registry/ui/game/organisms/ui-arena-board.orb +5 -6
- package/dist/behaviors/registry/ui/game/organisms/ui-battle-board.orb +86 -99
- package/dist/behaviors/registry/ui/game/organisms/ui-builder-board.orb +21 -226
- package/dist/behaviors/registry/ui/game/organisms/ui-card-battler-board.orb +42 -0
- package/dist/behaviors/registry/ui/game/organisms/ui-castle-board.orb +30 -9
- package/dist/behaviors/registry/ui/game/organisms/ui-city-builder-board.orb +49 -0
- package/dist/behaviors/registry/ui/game/organisms/ui-fishing-board.orb +16 -16
- package/dist/behaviors/registry/ui/game/organisms/ui-grid-tactics-demo-board.orb +5 -6
- package/dist/behaviors/registry/ui/game/organisms/ui-hex-strategy-board.orb +30 -10
- package/dist/behaviors/registry/ui/game/organisms/ui-holiday-runner-board.orb +2 -3
- package/dist/behaviors/registry/ui/game/organisms/ui-minigolf-board.orb +55 -11
- package/dist/behaviors/registry/ui/game/organisms/ui-physics-sandbox-board.orb +10 -10
- package/dist/behaviors/registry/ui/game/organisms/ui-pinball-board.orb +8 -8
- package/dist/behaviors/registry/ui/game/organisms/ui-pirate-board.orb +14 -0
- package/dist/behaviors/registry/ui/game/organisms/ui-platformer-board.orb +72 -0
- package/dist/behaviors/registry/ui/game/organisms/ui-roguelike-board.orb +10 -10
- package/dist/behaviors/registry/ui/game/organisms/ui-sokoban-board.orb +10 -10
- package/dist/behaviors/registry/ui/game/organisms/ui-sports-board.orb +60 -0
- package/dist/behaviors/registry/ui/game/organisms/ui-state-architect-board.orb +8 -8
- package/dist/behaviors/registry/ui/game/organisms/ui-tactics-demo-2d.orb +48 -28
- package/dist/behaviors/registry/ui/game/organisms/ui-tanks-board.orb +30 -10
- package/dist/behaviors/registry/ui/game/organisms/ui-topdown-rts-board.orb +31 -12
- package/dist/behaviors/registry/ui/game/organisms/ui-tower-defense-board.orb +8 -0
- package/dist/behaviors/registry/ui/game/organisms/ui-uncontrolled-battle-board.orb +5 -0
- package/dist/behaviors/registry/ui/game/organisms/ui-winter-ski-board.orb +14 -14
- package/dist/behaviors/registry/ui/game/organisms/ui-world-map-board.orb +8 -12
- package/dist/behaviors-embeddings.json +384 -380
- package/dist/behaviors-registry.json +594 -57
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3410 -3102
- package/dist/knob-embeddings.json +1 -1
- package/dist/registry/factory-signatures.json +6211 -2181
- package/package.json +2 -2
|
@@ -211,7 +211,11 @@ orbital DataErasureOrbital {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
state browsing {
|
|
214
|
-
|
|
214
|
+
;; Stays in `browsing`: this persist's result arms (ErasureSaved /
|
|
215
|
+
;; ErasureSaveFailed) are declared here. Leaving for `loading` landed the
|
|
216
|
+
;; save on a deaf state and wedged the panel on its spinner — the
|
|
217
|
+
;; ErasureSaved arm below is what moves to `loading` to re-fetch.
|
|
218
|
+
CANCEL_ERASURE -> browsing
|
|
215
219
|
(set @entity.id ?id)
|
|
216
220
|
(set @entity.status cancelled)
|
|
217
221
|
(persist update ErasureRequest @entity {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
app ui-emoji-picker "1.0.0"
|
|
2
|
+
"EmojiPicker — UI factory (1:1 with the @almadar/ui emoji-picker pattern)."
|
|
3
|
+
orbital EmojiPickerOrbital {
|
|
4
|
+
entity EmojiPickerItem [runtime] {
|
|
5
|
+
id : string!
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
trait EmojiPickerRender -> @rebindable EmojiPickerItem [interaction, instance] {
|
|
9
|
+
initial: idle
|
|
10
|
+
|
|
11
|
+
state idle {
|
|
12
|
+
INIT -> idle
|
|
13
|
+
(render-ui main {
|
|
14
|
+
pickEvent: @config.pickEvent
|
|
15
|
+
position: @config.position
|
|
16
|
+
triggerIcon: @config.triggerIcon
|
|
17
|
+
triggerLabel: @config.triggerLabel
|
|
18
|
+
className: @config.className
|
|
19
|
+
type: emoji-picker
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
emits {
|
|
24
|
+
@config.pickEvent -> external {
|
|
25
|
+
id : string
|
|
26
|
+
}
|
|
27
|
+
@description "Declarative event name — picking an emoji emits UI:{pickEvent} with { emoji } via eventBus"
|
|
28
|
+
@tier "essential"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
config {
|
|
32
|
+
pickEvent : string = "PICK"
|
|
33
|
+
@label "Pick Event"
|
|
34
|
+
@description "Declarative event name — picking an emoji emits UI:{pickEvent} with { emoji } via eventBus"
|
|
35
|
+
@tier "presentation"
|
|
36
|
+
position : "top" | "bottom" = top
|
|
37
|
+
@label "Position"
|
|
38
|
+
@description "Which side of the trigger the panel opens on"
|
|
39
|
+
@tier "presentation"
|
|
40
|
+
triggerIcon : icon
|
|
41
|
+
@label "Trigger Icon"
|
|
42
|
+
@description "Icon shown on the trigger button"
|
|
43
|
+
@tier "presentation"
|
|
44
|
+
triggerLabel : string = "Add emoji"
|
|
45
|
+
@label "Trigger Label"
|
|
46
|
+
@description "Accessible label for the trigger button"
|
|
47
|
+
@tier "presentation"
|
|
48
|
+
className : string
|
|
49
|
+
@label "Class Name"
|
|
50
|
+
@description "Additional CSS classes applied to the trigger button"
|
|
51
|
+
@tier "presentation"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
page "/emoji-picker" as EmojiPickerPage -> EmojiPickerRender
|
|
56
|
+
}
|
|
@@ -3,6 +3,7 @@ app ui-popover "1.0.0"
|
|
|
3
3
|
orbital PopoverOrbital {
|
|
4
4
|
entity PopoverItem [runtime] {
|
|
5
5
|
id : string!
|
|
6
|
+
open : boolean
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
trait PopoverRender -> @rebindable PopoverItem [interaction, instance] {
|
|
@@ -10,15 +11,45 @@ orbital PopoverOrbital {
|
|
|
10
11
|
|
|
11
12
|
state idle {
|
|
12
13
|
INIT -> idle
|
|
14
|
+
(set @entity.open @config.open)
|
|
13
15
|
(render-ui main {
|
|
14
16
|
content: @config.content
|
|
15
17
|
children: @config.children
|
|
16
18
|
position: @config.position
|
|
17
19
|
trigger: @config.trigger
|
|
18
20
|
showArrow: @config.showArrow
|
|
21
|
+
open: @entity.open
|
|
22
|
+
onOpenChange: @config.onOpenChange
|
|
19
23
|
className: @config.className
|
|
20
24
|
type: popover
|
|
21
25
|
})
|
|
26
|
+
OPEN_CHANGE -> idle
|
|
27
|
+
(set @entity.open ?open)
|
|
28
|
+
(render-ui main {
|
|
29
|
+
content: @config.content
|
|
30
|
+
children: @config.children
|
|
31
|
+
position: @config.position
|
|
32
|
+
trigger: @config.trigger
|
|
33
|
+
showArrow: @config.showArrow
|
|
34
|
+
open: @entity.open
|
|
35
|
+
onOpenChange: @config.onOpenChange
|
|
36
|
+
className: @config.className
|
|
37
|
+
type: popover
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
emits {
|
|
42
|
+
@config.onOpenChange -> external {
|
|
43
|
+
open : boolean
|
|
44
|
+
}
|
|
45
|
+
@description "Fired when the popover wants to change visibility (trigger click, outside click)"
|
|
46
|
+
@tier "essential"
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
listens {
|
|
50
|
+
OPEN_CHANGE {
|
|
51
|
+
open : boolean
|
|
52
|
+
}
|
|
22
53
|
}
|
|
23
54
|
|
|
24
55
|
config {
|
|
@@ -42,6 +73,14 @@ orbital PopoverOrbital {
|
|
|
42
73
|
@label "Show Arrow"
|
|
43
74
|
@description "Show arrow"
|
|
44
75
|
@tier "presentation"
|
|
76
|
+
open : boolean
|
|
77
|
+
@label "Open"
|
|
78
|
+
@description "Controlled open state. When set, the host owns visibility and the popover reports intent through onOpenChange instead of toggling itself."
|
|
79
|
+
@tier "presentation"
|
|
80
|
+
onOpenChange : string = "OPEN_CHANGE"
|
|
81
|
+
@label "On Open Change"
|
|
82
|
+
@description "Fired when the popover wants to change visibility (trigger click, outside click)"
|
|
83
|
+
@tier "presentation"
|
|
45
84
|
className : string
|
|
46
85
|
@label "Class Name"
|
|
47
86
|
@description "Additional CSS classes"
|
|
@@ -66,6 +66,7 @@ orbital TableViewOrbital {
|
|
|
66
66
|
fields: @config.fields
|
|
67
67
|
itemActions: @config.itemActions
|
|
68
68
|
maxInlineActions: @config.maxInlineActions
|
|
69
|
+
itemClickEvent: @config.itemClickEvent
|
|
69
70
|
selectable: @config.selectable
|
|
70
71
|
selectEvent: @config.selectEvent
|
|
71
72
|
selectedIds: @config.selectedIds
|
|
@@ -96,6 +97,7 @@ orbital TableViewOrbital {
|
|
|
96
97
|
fields: @config.fields
|
|
97
98
|
itemActions: @config.itemActions
|
|
98
99
|
maxInlineActions: @config.maxInlineActions
|
|
100
|
+
itemClickEvent: @config.itemClickEvent
|
|
99
101
|
selectable: @config.selectable
|
|
100
102
|
selectEvent: @config.selectEvent
|
|
101
103
|
selectedIds: @config.selectedIds
|
|
@@ -114,6 +116,11 @@ orbital TableViewOrbital {
|
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
emits {
|
|
119
|
+
@config.itemClickEvent -> external {
|
|
120
|
+
id : string
|
|
121
|
+
}
|
|
122
|
+
@description "When set, the whole row is clickable and emits UI:{itemClickEvent} with { id, row } (action-button clicks stopPropagation so they still win). Mirrors DataList's contract."
|
|
123
|
+
@tier "essential"
|
|
117
124
|
@config.selectEvent -> external {
|
|
118
125
|
id : string
|
|
119
126
|
}
|
|
@@ -184,6 +191,10 @@ orbital TableViewOrbital {
|
|
|
184
191
|
@label "Max Inline Actions"
|
|
185
192
|
@description "Max inline action buttons before the rest collapse into a '⋯' overflow menu. Omit = all inline."
|
|
186
193
|
@tier "presentation"
|
|
194
|
+
itemClickEvent : string = "ITEM_CLICK"
|
|
195
|
+
@label "Item Click Event"
|
|
196
|
+
@description "When set, the whole row is clickable and emits UI:{itemClickEvent} with { id, row } (action-button clicks stopPropagation so they still win). Mirrors DataList's contract."
|
|
197
|
+
@tier "presentation"
|
|
187
198
|
selectable : boolean = false
|
|
188
199
|
@label "Selectable"
|
|
189
200
|
@description "Render a leading checkbox column. Selection changes emit `selectEvent`."
|
|
@@ -61,11 +61,11 @@ orbital DrawSpriteOrbital {
|
|
|
61
61
|
@tier "presentation"
|
|
62
62
|
width : number
|
|
63
63
|
@label "Width"
|
|
64
|
-
@description "Draw width in world units (fractions of `projector.tileWidth`)
|
|
64
|
+
@description "Draw width in world units (fractions of `projector.tileWidth`). Omitted → one cell on tile grids (`flat`/`iso`/`hex`); native source px on `free`/`side`."
|
|
65
65
|
@tier "presentation"
|
|
66
66
|
height : number
|
|
67
67
|
@label "Height"
|
|
68
|
-
@description "Draw height in world units (fractions of `projector.tileWidth`)
|
|
68
|
+
@description "Draw height in world units (fractions of `projector.tileWidth`). Omitted → one cell on tile grids (`flat`/`iso`/`hex`); native source px on `free`/`side`."
|
|
69
69
|
@tier "presentation"
|
|
70
70
|
frame : json = {}
|
|
71
71
|
@label "Frame"
|
|
@@ -123,11 +123,11 @@ orbital CrewBoard2DOrbital {
|
|
|
123
123
|
hud: { type: stack, direction: horizontal, gap: md, justify: between, children: [ { type: game-hud, stats: [ { label: "Crew", value: @entity.crewCount, iconUrl: @config.crewIcon }, { label: "Oxygen", value: @entity.oxygen, iconUrl: @config.oxygenIcon } ] }, { type: stack, direction: horizontal, gap: xs, align: center, children: [ { type: typography, variant: caption, content: "Status" }, { type: badge, label: @entity.phase, variant: (if (== @entity.phase "movement") "info" "neutral") } ] }, { type: timer-display, value: @entity.oxygen, label: "O2" }, { type: button, action: CANCEL, label: "Cancel", iconAsset: @config.cancelIcon, variant: secondary } ] }
|
|
124
124
|
children: [ { type: canvas, camera: { zoom: (math/min 1 (/ 5 (+ 1 (math/max (array/max @entity.tiles "x") (array/max @entity.tiles "y"))))), pos: { x: (/ (+ (array/min @entity.tiles "x") (array/max @entity.tiles "x")) 2), y: (/ (+ (array/min @entity.tiles "y") (array/max @entity.tiles "y")) 2) } }, projection: @config.projection, showMinimap: @config.showMinimap, tileClickEvent: TILE_CLICK, unitClickEvent: UNIT_CLICK, children: [
|
|
125
125
|
{ type: draw-shape-layer, items: (array/map @entity.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#5c94fc", stroke: "rgba(255,255,255,0.35)", strokeWidth: 1 })) }
|
|
126
|
-
{ type: draw-sprite-layer, items: (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width:
|
|
126
|
+
{ type: draw-sprite-layer, items: (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width: 1, height: 1 })) }
|
|
127
127
|
{ type: draw-sprite-layer, items: (array/map @config.features (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f y) }, asset: (object/get @f assetUrl) })) }
|
|
128
128
|
{ type: draw-shape-layer, items: (array/map @entity.validMoves (fn m { type: draw-shape, shape: "cell", position: { x: (object/get @m x), y: (object/get @m z) }, fill: "rgba(74,222,128,0.4)" })) }
|
|
129
129
|
{ type: draw-shape-layer, items: (array/map (array/filter @entity.units (fn u (== (object/get @u id) @entity.selectedUnitId))) (fn u { type: draw-shape, shape: "ellipse", position: (object/get @u position), radiusX: 0.5, radiusY: 0.2, stroke: "rgba(0,200,255,0.8)", strokeWidth: 3 })) }
|
|
130
|
-
{ type: draw-sprite-layer, items: (array/map @entity.units (fn u { type: draw-sprite, position: (object/get @u position), asset: (if (object/get (object/get @u modelUrl) url) (object/get @u modelUrl) (object/get (object/get @config.assetManifest units) (object/get @u unitType))), id: (object/get @u id), anchor: "ground", width:
|
|
130
|
+
{ type: draw-sprite-layer, items: (array/map @entity.units (fn u { type: draw-sprite, position: (object/get @u position), asset: (if (object/get (object/get @u modelUrl) url) (object/get @u modelUrl) (object/get (object/get @config.assetManifest units) (object/get @u unitType))), id: (object/get @u id), anchor: "ground", width: 1, height: 1 })) }
|
|
131
131
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: 0.5, height: 0.12, fill: "rgba(0,0,0,0.6)" })) }
|
|
132
132
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: (* 0.5 (/ (object/get @u health) (object/get @u maxHealth))), height: 0.12, fill: "#22c55e" })) }
|
|
133
133
|
{ type: draw-text-layer, items: (array/map @entity.units (fn u { type: draw-text, text: (object/get @u name), position: (object/get @u position), offsetY: -0.85, color: "#ffffff" })) }
|
|
@@ -166,11 +166,11 @@ orbital CrewBoard2DOrbital {
|
|
|
166
166
|
hud: { type: stack, direction: horizontal, gap: md, justify: between, children: [ { type: game-hud, stats: [ { label: "Crew", value: @entity.crewCount, iconUrl: @config.crewIcon }, { label: "Oxygen", value: @entity.oxygen, iconUrl: @config.oxygenIcon } ] }, { type: stack, direction: horizontal, gap: xs, align: center, children: [ { type: typography, variant: caption, content: "Status" }, { type: badge, label: @entity.phase, variant: (if (== @entity.phase "movement") "info" "neutral") } ] }, { type: timer-display, value: @entity.oxygen, label: "O2" }, { type: button, action: CANCEL, label: "Cancel", iconAsset: @config.cancelIcon, variant: secondary } ] }
|
|
167
167
|
children: [ { type: canvas, camera: { zoom: (math/min 1 (/ 5 (+ 1 (math/max (array/max @entity.tiles "x") (array/max @entity.tiles "y"))))), pos: { x: (/ (+ (array/min @entity.tiles "x") (array/max @entity.tiles "x")) 2), y: (/ (+ (array/min @entity.tiles "y") (array/max @entity.tiles "y")) 2) } }, projection: @config.projection, showMinimap: @config.showMinimap, tileClickEvent: TILE_CLICK, unitClickEvent: UNIT_CLICK, children: [
|
|
168
168
|
{ type: draw-shape-layer, items: (array/map @entity.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#5c94fc", stroke: "rgba(255,255,255,0.35)", strokeWidth: 1 })) }
|
|
169
|
-
{ type: draw-sprite-layer, items: (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width:
|
|
169
|
+
{ type: draw-sprite-layer, items: (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width: 1, height: 1 })) }
|
|
170
170
|
{ type: draw-sprite-layer, items: (array/map @config.features (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f y) }, asset: (object/get @f assetUrl) })) }
|
|
171
171
|
{ type: draw-shape-layer, items: (array/map @entity.validMoves (fn m { type: draw-shape, shape: "cell", position: { x: (object/get @m x), y: (object/get @m z) }, fill: "rgba(74,222,128,0.4)" })) }
|
|
172
172
|
{ type: draw-shape-layer, items: (array/map (array/filter @entity.units (fn u (== (object/get @u id) @entity.selectedUnitId))) (fn u { type: draw-shape, shape: "ellipse", position: (object/get @u position), radiusX: 0.5, radiusY: 0.2, stroke: "rgba(0,200,255,0.8)", strokeWidth: 3 })) }
|
|
173
|
-
{ type: draw-sprite-layer, items: (array/map @entity.units (fn u { type: draw-sprite, position: (object/get @u position), asset: (if (object/get (object/get @u modelUrl) url) (object/get @u modelUrl) (object/get (object/get @config.assetManifest units) (object/get @u unitType))), id: (object/get @u id), anchor: "ground", width:
|
|
173
|
+
{ type: draw-sprite-layer, items: (array/map @entity.units (fn u { type: draw-sprite, position: (object/get @u position), asset: (if (object/get (object/get @u modelUrl) url) (object/get @u modelUrl) (object/get (object/get @config.assetManifest units) (object/get @u unitType))), id: (object/get @u id), anchor: "ground", width: 1, height: 1 })) }
|
|
174
174
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: 0.5, height: 0.12, fill: "rgba(0,0,0,0.6)" })) }
|
|
175
175
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: (* 0.5 (/ (object/get @u health) (object/get @u maxHealth))), height: 0.12, fill: "#22c55e" })) }
|
|
176
176
|
{ type: draw-text-layer, items: (array/map @entity.units (fn u { type: draw-text, text: (object/get @u name), position: (object/get @u position), offsetY: -0.85, color: "#ffffff" })) }
|
|
@@ -195,11 +195,11 @@ orbital DungeonBoard2DOrbital {
|
|
|
195
195
|
hud: { type: game-hud, stats: [ { label: "HP", value: @entity.hp, max: @entity.maxHp, format: "hearts" }, { label: "Score", value: (+ @entity.score @entity.combatScore) } ] }
|
|
196
196
|
controls: { type: control-grid, kind: "dpad", directionEvents: { up: "MOVE_UP", down: "MOVE_DOWN", left: "MOVE_LEFT", right: "MOVE_RIGHT" }, directionAssets: @config.directionAssets }
|
|
197
197
|
overlay: (if (!= @entity.result "none") { type: game-menu, title: "VICTORY", subtitle: "You found the chest!", options: [ { id: "again", label: "Play Again", event: "PLAY_AGAIN", variant: "primary" } ] } (if (!= @entity.combatResult "none") { type: game-menu, title: "DEFEAT", subtitle: "The dungeon claims another hero", options: [ { id: "again", label: "Play Again", event: "PLAY_AGAIN", variant: "primary" } ] } null))
|
|
198
|
-
children: [ { type: canvas, camera: { zoom: @config.scale }, projection: "flat", showMinimap: false, keyMap: { ArrowUp: "MOVE_UP", KeyW: "MOVE_UP", ArrowDown: "MOVE_DOWN", KeyS: "MOVE_DOWN", ArrowLeft: "MOVE_LEFT", KeyA: "MOVE_LEFT", ArrowRight: "MOVE_RIGHT", KeyD: "MOVE_RIGHT" }, children: [
|
|
198
|
+
children: [ { type: canvas, fit: true, camera: { zoom: @config.scale }, projection: "flat", showMinimap: false, keyMap: { ArrowUp: "MOVE_UP", KeyW: "MOVE_UP", ArrowDown: "MOVE_DOWN", KeyS: "MOVE_DOWN", ArrowLeft: "MOVE_LEFT", KeyA: "MOVE_LEFT", ArrowRight: "MOVE_RIGHT", KeyD: "MOVE_RIGHT" }, children: [
|
|
199
199
|
{ type: draw-shape-layer, items: (array/map @entity.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#5c94fc" })) }
|
|
200
|
-
{ type: draw-sprite-layer, items: (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width:
|
|
200
|
+
{ type: draw-sprite-layer, items: (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width: 1, height: 1 })) }
|
|
201
201
|
{ type: draw-sprite-layer, items: (array/map @entity.features (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f y) }, asset: (object/get @f sprite) })) }
|
|
202
|
-
{ type: draw-sprite-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-sprite, position: (object/get @u position), asset: (if (object/get (object/get @u sprite) url) (object/get @u sprite) (object/get (object/get @config.assetManifest units) (object/get @u unitType))), anchor: "ground", width:
|
|
202
|
+
{ type: draw-sprite-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-sprite, position: (object/get @u position), asset: (if (object/get (object/get @u sprite) url) (object/get @u sprite) (object/get (object/get @config.assetManifest units) (object/get @u unitType))), anchor: "ground", width: 1, height: 1 })) }
|
|
203
203
|
{ type: draw-shape-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: 0.5, height: 0.12, fill: "rgba(0,0,0,0.6)" })) }
|
|
204
204
|
{ type: draw-shape-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: (* 0.5 (/ (object/get @u health) (object/get @u maxHealth))), height: 0.12, fill: "#22c55e" })) }
|
|
205
205
|
{ type: draw-text-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-text, text: (object/get @u name), position: (object/get @u position), offsetY: -0.85, color: "#ffffff" })) }
|
|
@@ -261,11 +261,11 @@ orbital DungeonBoard2DOrbital {
|
|
|
261
261
|
hud: { type: game-hud, stats: [ { label: "HP", value: @entity.hp, max: @entity.maxHp, format: "hearts" }, { label: "Score", value: (+ @entity.score @entity.combatScore) } ] }
|
|
262
262
|
controls: { type: control-grid, kind: "dpad", directionEvents: { up: "MOVE_UP", down: "MOVE_DOWN", left: "MOVE_LEFT", right: "MOVE_RIGHT" }, directionAssets: @config.directionAssets }
|
|
263
263
|
overlay: (if (!= @entity.result "none") { type: game-menu, title: "VICTORY", subtitle: "You found the chest!", options: [ { id: "again", label: "Play Again", event: "PLAY_AGAIN", variant: "primary" } ] } (if (!= @entity.combatResult "none") { type: game-menu, title: "DEFEAT", subtitle: "The dungeon claims another hero", options: [ { id: "again", label: "Play Again", event: "PLAY_AGAIN", variant: "primary" } ] } null))
|
|
264
|
-
children: [ { type: canvas, camera: { zoom: @config.scale }, projection: "flat", showMinimap: false, keyMap: { ArrowUp: "MOVE_UP", KeyW: "MOVE_UP", ArrowDown: "MOVE_DOWN", KeyS: "MOVE_DOWN", ArrowLeft: "MOVE_LEFT", KeyA: "MOVE_LEFT", ArrowRight: "MOVE_RIGHT", KeyD: "MOVE_RIGHT" }, children: [
|
|
264
|
+
children: [ { type: canvas, fit: true, camera: { zoom: @config.scale }, projection: "flat", showMinimap: false, keyMap: { ArrowUp: "MOVE_UP", KeyW: "MOVE_UP", ArrowDown: "MOVE_DOWN", KeyS: "MOVE_DOWN", ArrowLeft: "MOVE_LEFT", KeyA: "MOVE_LEFT", ArrowRight: "MOVE_RIGHT", KeyD: "MOVE_RIGHT" }, children: [
|
|
265
265
|
{ type: draw-shape-layer, items: (array/map @entity.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#5c94fc" })) }
|
|
266
|
-
{ type: draw-sprite-layer, items: (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width:
|
|
266
|
+
{ type: draw-sprite-layer, items: (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width: 1, height: 1 })) }
|
|
267
267
|
{ type: draw-sprite-layer, items: (array/map @entity.features (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f y) }, asset: (object/get @f sprite) })) }
|
|
268
|
-
{ type: draw-sprite-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-sprite, position: (object/get @u position), asset: (if (object/get (object/get @u sprite) url) (object/get @u sprite) (object/get (object/get @config.assetManifest units) (object/get @u unitType))), anchor: "ground", width:
|
|
268
|
+
{ type: draw-sprite-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-sprite, position: (object/get @u position), asset: (if (object/get (object/get @u sprite) url) (object/get @u sprite) (object/get (object/get @config.assetManifest units) (object/get @u unitType))), anchor: "ground", width: 1, height: 1 })) }
|
|
269
269
|
{ type: draw-shape-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: 0.5, height: 0.12, fill: "rgba(0,0,0,0.6)" })) }
|
|
270
270
|
{ type: draw-shape-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: (* 0.5 (/ (object/get @u health) (object/get @u maxHealth))), height: 0.12, fill: "#22c55e" })) }
|
|
271
271
|
{ type: draw-text-layer, items: (array/map (array/concat @entity.units @entity.enemies) (fn u { type: draw-text, text: (object/get @u name), position: (object/get @u position), offsetY: -0.85, color: "#ffffff" })) }
|
|
@@ -5,6 +5,7 @@ orbital TacticsBoard2DOrbital {
|
|
|
5
5
|
uses Particles from "std/behaviors/std-fx-particles"
|
|
6
6
|
uses Round from "std/behaviors/std-round-flow"
|
|
7
7
|
uses Score from "std/behaviors/std-score"
|
|
8
|
+
uses AnimTick from "std/behaviors/std-anim-tick"
|
|
8
9
|
|
|
9
10
|
type Asset = {
|
|
10
11
|
url : asset
|
|
@@ -100,6 +101,13 @@ orbital TacticsBoard2DOrbital {
|
|
|
100
101
|
turn : number = 0
|
|
101
102
|
score : number = 0
|
|
102
103
|
scoreBaseline : number = 0
|
|
104
|
+
animCounter : number = 0
|
|
105
|
+
frameName : string = "0"
|
|
106
|
+
animUnitId : string = ""
|
|
107
|
+
animState : string = "idle"
|
|
108
|
+
animTicksLeft : number = 0
|
|
109
|
+
animAttackerId : string = ""
|
|
110
|
+
animAtkTicksLeft : number = 0
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
trait TacticsAuthority = Tactics.traits.GridTactics -> GameState {
|
|
@@ -133,6 +141,10 @@ orbital TacticsBoard2DOrbital {
|
|
|
133
141
|
config { running: true, pointsPerKill: 10, startScore: 0, initialEnemies: 0 }
|
|
134
142
|
}
|
|
135
143
|
|
|
144
|
+
trait AnimClock = AnimTick.traits.AnimTick -> GameState {
|
|
145
|
+
config { frames: [] }
|
|
146
|
+
}
|
|
147
|
+
|
|
136
148
|
trait PlayerIntent -> GameState [interaction, instance] {
|
|
137
149
|
initial: playing
|
|
138
150
|
|
|
@@ -149,23 +161,27 @@ orbital TacticsBoard2DOrbital {
|
|
|
149
161
|
hudBackgroundAsset: @config.hudBackgroundAsset
|
|
150
162
|
hud: { type: game-hud, stats: (array/concat [ { label: "Result", value: @entity.result }, { label: "Phase", value: @entity.uiPhase }, { label: "Turn", value: @entity.turn }, { label: "Score", value: @entity.score } ] @config.extraStats) }
|
|
151
163
|
addons: { type: stack, direction: vertical, gap: sm, children: (array/concat [ { type: button, action: END_TURN, label: "End Turn", variant: primary }, { type: button, action: CANCEL, label: "Cancel", variant: secondary } ] @config.extraAddons) }
|
|
152
|
-
children: [ { type: canvas,
|
|
164
|
+
children: [ { type: canvas, fit: true, camera: { pos: { x: (/ (+ (array/min @entity.tiles "x") (array/max @entity.tiles "x")) 2), y: (/ (+ (array/min @entity.tiles "y") (array/max @entity.tiles "y")) 2) } }, projection: @config.projection, showMinimap: @config.showMinimap, tileClickEvent: TILE_CLICK, unitClickEvent: UNIT_CLICK, children: [
|
|
153
165
|
{ type: draw-shape-layer, items: (array/map @entity.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#5c94fc", stroke: "rgba(255,255,255,0.35)", strokeWidth: 1 })) }
|
|
154
|
-
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width:
|
|
166
|
+
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width: 1, height: 1 })) (fn s (object/get (object/get @s asset) url))) }
|
|
155
167
|
{ type: draw-sprite-layer, items: (array/filter (array/map @config.features (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f y) }, asset: (object/get @f assetUrl) })) (fn s (object/get (object/get @s asset) url))) }
|
|
156
168
|
{ type: draw-shape-layer, items: (array/map @entity.validMoves (fn m { type: draw-shape, shape: "cell", position: { x: (object/get @m x), y: (object/get @m z) }, fill: "rgba(74,222,128,0.4)" })) }
|
|
157
169
|
{ type: draw-shape-layer, items: (array/map @entity.attackTargets (fn a { type: draw-shape, shape: "cell", position: { x: (object/get @a x), y: (object/get @a z) }, fill: "rgba(239,68,68,0.4)" })) }
|
|
158
170
|
{ type: draw-shape-layer, items: (array/map (array/filter @entity.units (fn u (== (object/get @u id) @entity.selectedUnitId))) (fn u { type: draw-shape, shape: "ellipse", position: (object/get @u position), radiusX: 0.5, radiusY: 0.2, stroke: "rgba(0,200,255,0.8)", strokeWidth: 3 })) }
|
|
159
|
-
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.units (fn u
|
|
171
|
+
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.units (fn u (let ((unitAsset (if (object/get (object/get @u modelUrl) url) (object/get @u modelUrl) (object/get (object/get @config.assetManifest units) (object/get @u unitType)))) (unitUrl (object/get @unitAsset url)) (unitAnim (if (<= (object/get @u health) 0) "death" (if (and (== (object/get @u id) @entity.animAttackerId) (> @entity.animAtkTicksLeft 0)) "attack" (if (== (object/get @u id) @entity.animUnitId) @entity.animState "idle"))))) { type: draw-sprite, position: (object/get @u position), asset: (if (and @unitUrl (str/includes @unitUrl ".svg")) (object/merge @unitAsset { url: (str/concat (array/nth (str/split @unitUrl ".svg") 0) (str/concat "." (str/concat @unitAnim (str/concat "-" (str/concat (if (== @unitAnim "walk") (% @entity.animCounter 2) (if (== @unitAnim "idle") (% (math/floor (/ @entity.animCounter 3)) 4) 0))) ".svg")))) }) @unitAsset), id: (object/get @u id), anchor: "ground", width: 0.5, height: 0.5 }))) (fn s (object/get (object/get @s asset) url))) }
|
|
160
172
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: 0.5, height: 0.12, fill: "rgba(0,0,0,0.6)" })) }
|
|
161
173
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: (* 0.5 (/ (object/get @u health) (object/get @u maxHealth))), height: 0.12, fill: "#22c55e" })) }
|
|
162
174
|
{ type: draw-text-layer, items: (array/map @entity.units (fn u { type: draw-text, text: (object/get @u name), position: (object/get @u position), offsetY: -0.85, color: "#ffffff" })) }
|
|
163
|
-
{ type: draw-text-layer, items: (array/map @entity.fx (fn f { type: draw-text, text: (object/get @f message), position: { x: (object/get @f x), y: (object/get @f
|
|
175
|
+
{ type: draw-text-layer, items: (array/map @entity.fx (fn f { type: draw-text, text: (object/get @f message), position: { x: (object/get @f x), y: (object/get @f z) }, color: "#ffe066" })) }
|
|
176
|
+
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.fx (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f z) }, asset: (object/get (object/get @config.assetManifest effects) (object/get @f type)), anchor: "center", width: 0.6, height: 0.6 })) (fn s (object/get (object/get @s asset) url))) }
|
|
177
|
+
{ type: draw-sprite-layer, items: (array/map (array/filter (array/flatten (array/map @entity.units (fn u (array/flatten (array/map [ ["idle", 4], ["walk", 2], ["attack", 1], ["hit", 1], ["death", 1] ] (fn st (array/map (array/range 0 (array/nth @st 1)) (fn i (if (and (object/get (object/get @u modelUrl) url) (str/includes (object/get (object/get @u modelUrl) url) ".svg")) (str/concat (array/nth (str/split (object/get (object/get @u modelUrl) url) ".svg") 0) (str/concat "." (str/concat (array/nth @st 0) (str/concat "-" (str/concat @i ".svg"))))) ""))))))))) (fn w (!= @w ""))) (fn warmUrl { type: draw-sprite, position: { x: 0, y: 0 }, asset: { url: @warmUrl }, opacity: 0, width: 0.5, height: 0.5 })) }
|
|
164
178
|
] } ]
|
|
165
179
|
})
|
|
166
180
|
|
|
167
181
|
UNIT_CLICK -> playing when (and (== @entity.uiPhase "action") (and (== (object/get (array/find @entity.units (fn u (== @u.id ?unitId))) team) "enemy") (<= (grid/manhattan-distance (object/get (array/find @entity.units (fn u (== @u.id @entity.selectedUnitId))) position) (object/get (array/find @entity.units (fn u (== @u.id ?unitId))) position)) 1)))
|
|
168
182
|
(emit ATTACK { targetId: ?unitId })
|
|
183
|
+
(set @entity.animAttackerId @entity.selectedUnitId)
|
|
184
|
+
(set @entity.animAtkTicksLeft 4)
|
|
169
185
|
(set @entity.selectedUnitId "")
|
|
170
186
|
(set @entity.validMoves [])
|
|
171
187
|
(set @entity.attackTargets [])
|
|
@@ -198,28 +214,44 @@ orbital TacticsBoard2DOrbital {
|
|
|
198
214
|
END_TURN -> playing when (== @entity.result "none")
|
|
199
215
|
(set @entity.turn (+ @entity.turn 1))
|
|
200
216
|
(emit AI_TURN { turn: @entity.turn })
|
|
217
|
+
|
|
218
|
+
MOVE -> playing
|
|
219
|
+
(set @entity.animUnitId ?unitId)
|
|
220
|
+
(set @entity.animState "walk")
|
|
221
|
+
(set @entity.animTicksLeft 6)
|
|
222
|
+
|
|
223
|
+
ATTACK -> playing
|
|
224
|
+
(set @entity.animUnitId ?targetId)
|
|
225
|
+
(set @entity.animState "hit")
|
|
226
|
+
(set @entity.animTicksLeft 4)
|
|
201
227
|
}
|
|
202
228
|
|
|
203
229
|
ticks {
|
|
204
230
|
renderTick every 100ms
|
|
231
|
+
(set @entity.animTicksLeft (if (> @entity.animTicksLeft 0) (- @entity.animTicksLeft 1) 0))
|
|
232
|
+
(set @entity.animAtkTicksLeft (if (> @entity.animAtkTicksLeft 0) (- @entity.animAtkTicksLeft 1) 0))
|
|
233
|
+
(set @entity.animState (if (== @entity.animTicksLeft 0) "idle" @entity.animState))
|
|
234
|
+
(set @entity.animUnitId (if (== @entity.animTicksLeft 0) "" @entity.animUnitId))
|
|
235
|
+
(set @entity.animAttackerId (if (== @entity.animAtkTicksLeft 0) "" @entity.animAttackerId))
|
|
205
236
|
(render-ui main {
|
|
206
237
|
type: game-shell
|
|
207
238
|
backgroundAsset: @config.backgroundAsset
|
|
208
239
|
hudBackgroundAsset: @config.hudBackgroundAsset
|
|
209
240
|
hud: { type: game-hud, stats: (array/concat [ { label: "Result", value: @entity.result }, { label: "Phase", value: @entity.uiPhase }, { label: "Turn", value: @entity.turn }, { label: "Score", value: @entity.score } ] @config.extraStats) }
|
|
210
241
|
addons: { type: stack, direction: vertical, gap: sm, children: (array/concat [ { type: button, action: END_TURN, label: "End Turn", variant: primary }, { type: button, action: CANCEL, label: "Cancel", variant: secondary } ] @config.extraAddons) }
|
|
211
|
-
children: [ { type: canvas,
|
|
242
|
+
children: [ { type: canvas, fit: true, camera: { pos: { x: (/ (+ (array/min @entity.tiles "x") (array/max @entity.tiles "x")) 2), y: (/ (+ (array/min @entity.tiles "y") (array/max @entity.tiles "y")) 2) } }, projection: @config.projection, showMinimap: @config.showMinimap, tileClickEvent: TILE_CLICK, unitClickEvent: UNIT_CLICK, children: [
|
|
212
243
|
{ type: draw-shape-layer, items: (array/map @entity.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#5c94fc", stroke: "rgba(255,255,255,0.35)", strokeWidth: 1 })) }
|
|
213
|
-
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width:
|
|
244
|
+
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width: 1, height: 1 })) (fn s (object/get (object/get @s asset) url))) }
|
|
214
245
|
{ type: draw-sprite-layer, items: (array/filter (array/map @config.features (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f y) }, asset: (object/get @f assetUrl) })) (fn s (object/get (object/get @s asset) url))) }
|
|
215
246
|
{ type: draw-shape-layer, items: (array/map @entity.validMoves (fn m { type: draw-shape, shape: "cell", position: { x: (object/get @m x), y: (object/get @m z) }, fill: "rgba(74,222,128,0.4)" })) }
|
|
216
247
|
{ type: draw-shape-layer, items: (array/map @entity.attackTargets (fn a { type: draw-shape, shape: "cell", position: { x: (object/get @a x), y: (object/get @a z) }, fill: "rgba(239,68,68,0.4)" })) }
|
|
217
248
|
{ type: draw-shape-layer, items: (array/map (array/filter @entity.units (fn u (== (object/get @u id) @entity.selectedUnitId))) (fn u { type: draw-shape, shape: "ellipse", position: (object/get @u position), radiusX: 0.5, radiusY: 0.2, stroke: "rgba(0,200,255,0.8)", strokeWidth: 3 })) }
|
|
218
|
-
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.units (fn u
|
|
249
|
+
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.units (fn u (let ((unitAsset (if (object/get (object/get @u modelUrl) url) (object/get @u modelUrl) (object/get (object/get @config.assetManifest units) (object/get @u unitType)))) (unitUrl (object/get @unitAsset url)) (unitAnim (if (<= (object/get @u health) 0) "death" (if (and (== (object/get @u id) @entity.animAttackerId) (> @entity.animAtkTicksLeft 0)) "attack" (if (== (object/get @u id) @entity.animUnitId) @entity.animState "idle"))))) { type: draw-sprite, position: (object/get @u position), asset: (if (and @unitUrl (str/includes @unitUrl ".svg")) (object/merge @unitAsset { url: (str/concat (array/nth (str/split @unitUrl ".svg") 0) (str/concat "." (str/concat @unitAnim (str/concat "-" (str/concat (if (== @unitAnim "walk") (% @entity.animCounter 2) (if (== @unitAnim "idle") (% (math/floor (/ @entity.animCounter 3)) 4) 0))) ".svg")))) }) @unitAsset), id: (object/get @u id), anchor: "ground", width: 0.5, height: 0.5 }))) (fn s (object/get (object/get @s asset) url))) }
|
|
219
250
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: 0.5, height: 0.12, fill: "rgba(0,0,0,0.6)" })) }
|
|
220
251
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), anchor: "ground", offsetX: -0.25, offsetY: -0.6, width: (* 0.5 (/ (object/get @u health) (object/get @u maxHealth))), height: 0.12, fill: "#22c55e" })) }
|
|
221
252
|
{ type: draw-text-layer, items: (array/map @entity.units (fn u { type: draw-text, text: (object/get @u name), position: (object/get @u position), offsetY: -0.85, color: "#ffffff" })) }
|
|
222
|
-
{ type: draw-text-layer, items: (array/map @entity.fx (fn f { type: draw-text, text: (object/get @f message), position: { x: (object/get @f x), y: (object/get @f
|
|
253
|
+
{ type: draw-text-layer, items: (array/map @entity.fx (fn f { type: draw-text, text: (object/get @f message), position: { x: (object/get @f x), y: (object/get @f z) }, color: "#ffe066" })) }
|
|
254
|
+
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.fx (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f z) }, asset: (object/get (object/get @config.assetManifest effects) (object/get @f type)), anchor: "center", width: 0.6, height: 0.6 })) (fn s (object/get (object/get @s asset) url))) }
|
|
223
255
|
] } ]
|
|
224
256
|
})
|
|
225
257
|
}
|
|
@@ -321,5 +353,5 @@ orbital TacticsBoard2DOrbital {
|
|
|
321
353
|
}
|
|
322
354
|
}
|
|
323
355
|
|
|
324
|
-
page "/tactics-board-2d" as TacticsBoard2DPage -> TacticsAuthority, FxDecay, RoundLogic, ScoreKeeper, PlayerIntent
|
|
356
|
+
page "/tactics-board-2d" as TacticsBoard2DPage -> TacticsAuthority, FxDecay, RoundLogic, ScoreKeeper, PlayerIntent, AnimClock
|
|
325
357
|
}
|
|
@@ -147,7 +147,7 @@ orbital WorldMapBoard2DOrbital {
|
|
|
147
147
|
hud: { type: stack, direction: horizontal, gap: md, justify: between, children: [ { type: game-hud, stats: (array/concat [ { label: "Region", value: @config.region, iconUrl: @config.regionIconAsset }, { label: "Turn", value: @entity.turn, iconUrl: @config.turnIconAsset }, { label: "Gold", value: @entity.gold, iconUrl: @config.goldIconAsset } ] @config.extraStats) }, { type: stack, direction: horizontal, gap: xs, align: center, children: [ { type: icon, name: map-pin }, { type: typography, variant: caption, content: "Waypoints" } ] } ] }
|
|
148
148
|
addons: { type: stack, direction: vertical, gap: sm, children: (array/concat [ { type: button, action: ADVANCE_TURN, label: "Pass Turn", iconAsset: @config.travelIconAsset, variant: primary } ] @config.extraAddons) }
|
|
149
149
|
overlay: (if (!= @entity.result "none") { type: game-menu, title: (if (== @entity.result "victory") "VICTORY" "DEFEAT"), subtitle: (if (== @entity.result "victory") "The realm is secured" "Your heroes have fallen"), options: [] } null)
|
|
150
|
-
children: [ { type: canvas,
|
|
150
|
+
children: [ { type: canvas, fit: true, camera: { pos: { x: (/ (+ (array/min @entity.tiles "x") (array/max @entity.tiles "x")) 2), y: (/ (+ (array/min @entity.tiles "y") (array/max @entity.tiles "y")) 2) } }, projection: "isometric", showMinimap: true, tileClickEvent: HERO_MOVE, unitClickEvent: HERO_SELECT, children: [
|
|
151
151
|
{ type: draw-shape-layer, items: (array/map @entity.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#5c94fc", stroke: "rgba(255,255,255,0.35)", strokeWidth: 1 })) }
|
|
152
152
|
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width: 0.5, height: 0.5 })) (fn s (object/get (object/get @s asset) url))) }
|
|
153
153
|
{ type: draw-sprite-layer, items: (array/map @config.features (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f y) }, asset: (object/get @f sprite) })) }
|
|
@@ -195,7 +195,7 @@ orbital WorldMapBoard2DOrbital {
|
|
|
195
195
|
hud: { type: stack, direction: horizontal, gap: md, justify: between, children: [ { type: game-hud, stats: (array/concat [ { label: "Region", value: @config.region, iconUrl: @config.regionIconAsset }, { label: "Turn", value: @entity.turn, iconUrl: @config.turnIconAsset }, { label: "Gold", value: @entity.gold, iconUrl: @config.goldIconAsset } ] @config.extraStats) }, { type: stack, direction: horizontal, gap: xs, align: center, children: [ { type: icon, name: map-pin }, { type: typography, variant: caption, content: "Waypoints" } ] } ] }
|
|
196
196
|
addons: { type: stack, direction: vertical, gap: sm, children: (array/concat [ { type: button, action: ADVANCE_TURN, label: "Pass Turn", iconAsset: @config.travelIconAsset, variant: primary } ] @config.extraAddons) }
|
|
197
197
|
overlay: (if (!= @entity.result "none") { type: game-menu, title: (if (== @entity.result "victory") "VICTORY" "DEFEAT"), subtitle: (if (== @entity.result "victory") "The realm is secured" "Your heroes have fallen"), options: [] } null)
|
|
198
|
-
children: [ { type: canvas,
|
|
198
|
+
children: [ { type: canvas, fit: true, camera: { pos: { x: (/ (+ (array/min @entity.tiles "x") (array/max @entity.tiles "x")) 2), y: (/ (+ (array/min @entity.tiles "y") (array/max @entity.tiles "y")) 2) } }, projection: "isometric", showMinimap: true, tileClickEvent: HERO_MOVE, unitClickEvent: HERO_SELECT, children: [
|
|
199
199
|
{ type: draw-shape-layer, items: (array/map @entity.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#5c94fc", stroke: "rgba(255,255,255,0.35)", strokeWidth: 1 })) }
|
|
200
200
|
{ type: draw-sprite-layer, items: (array/filter (array/map @entity.tiles (fn t { type: draw-sprite, position: { x: (object/get @t x), y: (object/get @t y) }, asset: (if (object/get (object/get @t terrainSprite) url) (object/get @t terrainSprite) (object/get (object/get @config.assetManifest terrains) (object/get @t terrain))), anchor: "center", width: 0.5, height: 0.5 })) (fn s (object/get (object/get @s asset) url))) }
|
|
201
201
|
{ type: draw-sprite-layer, items: (array/map @config.features (fn f { type: draw-sprite, position: { x: (object/get @f x), y: (object/get @f y) }, asset: (object/get @f sprite) })) }
|
|
@@ -42,6 +42,8 @@ orbital Canvas2dOrbital {
|
|
|
42
42
|
keyUpMap: @config.keyUpMap
|
|
43
43
|
camera: @config.camera
|
|
44
44
|
scale: @config.scale
|
|
45
|
+
tileWidth: @config.tileWidth
|
|
46
|
+
fit: @config.fit
|
|
45
47
|
showMinimap: @config.showMinimap
|
|
46
48
|
followTarget: @config.followTarget
|
|
47
49
|
cameraPos: @config.cameraPos
|
|
@@ -130,7 +132,15 @@ orbital Canvas2dOrbital {
|
|
|
130
132
|
@tier "presentation"
|
|
131
133
|
scale : number = 0.4
|
|
132
134
|
@label "Scale"
|
|
133
|
-
@description "Render scale (
|
|
135
|
+
@description "Render scale, legacy-squared semantics: on-screen cell ≈ `256 × scale²` px (the authored contract every board tuned its value for). Converted internally to the single camera zoom against the board's native tile width, so the cell pitch follows the asset while the on-screen size stays as authored. Ignored when `fit` is on; passed through raw for `free`/`side` (world-pixel-direct)."
|
|
136
|
+
@tier "presentation"
|
|
137
|
+
tileWidth : number
|
|
138
|
+
@label "Tile Width"
|
|
139
|
+
@description "Native tile/cell width in source px for this board's asset (e.g. 16 for Kenney tiny-dungeon, ~128 for iso blocks). The grid cell pitch follows the asset, so tile textures map 1:1 (crisp, no stretch). Defaults to the detected atlas tile width, else 256."
|
|
140
|
+
@tier "presentation"
|
|
141
|
+
fit : boolean = false
|
|
142
|
+
@label "Fit"
|
|
143
|
+
@description "Auto-fit the board's grid extent to the viewport (default false — boards render at their authored `scale` and overflow → pan). Opt in for whole-board-overview boards. User wheel/pinch zoom always wins after the initial fit."
|
|
134
144
|
@tier "presentation"
|
|
135
145
|
showMinimap : boolean = true
|
|
136
146
|
@label "Show Minimap"
|
|
@@ -19,6 +19,8 @@ orbital CanvasOrbital {
|
|
|
19
19
|
isLoading: @config.isLoading
|
|
20
20
|
unitScale: @config.unitScale
|
|
21
21
|
showMinimap: @config.showMinimap
|
|
22
|
+
fit: @config.fit
|
|
23
|
+
tileWidth: @config.tileWidth
|
|
22
24
|
backgroundImage: @config.backgroundImage
|
|
23
25
|
backgroundColor: @config.backgroundColor
|
|
24
26
|
worldWidth: @config.worldWidth
|
|
@@ -104,6 +106,14 @@ orbital CanvasOrbital {
|
|
|
104
106
|
@label "Show Minimap"
|
|
105
107
|
@description "Minimap overlay (2D)."
|
|
106
108
|
@tier "presentation"
|
|
109
|
+
fit : boolean
|
|
110
|
+
@label "Fit"
|
|
111
|
+
@description "Auto-fit the board's grid extent to the viewport (2D grid layouts; default false — boards render at their authored `camera.zoom` scale)."
|
|
112
|
+
@tier "presentation"
|
|
113
|
+
tileWidth : number
|
|
114
|
+
@label "Tile Width"
|
|
115
|
+
@description "Native tile/cell width in source px of the board's asset (2D grid layouts; defaults to the detected atlas tile width, else 256)."
|
|
116
|
+
@tier "presentation"
|
|
107
117
|
backgroundImage : asset
|
|
108
118
|
@label "Background Image"
|
|
109
119
|
@description "Backdrop image (2D iso/hex/flat/free/side)."
|
|
@@ -42,7 +42,7 @@ orbital ArenaBoardOrbital {
|
|
|
42
42
|
(render-ui main {
|
|
43
43
|
type: game-shell
|
|
44
44
|
hud: { type: game-hud, stats: [ { label: "Result", value: @entity.result } ] }
|
|
45
|
-
children: [ { type: canvas, projection: "flat", showMinimap: false, children: [
|
|
45
|
+
children: [ { type: canvas, fit: true, projection: "flat", showMinimap: false, children: [
|
|
46
46
|
{ type: draw-shape-layer, items: (array/map @config.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#4ade80", stroke: "rgba(0,0,0,0.2)" })) }
|
|
47
47
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "ellipse", position: (object/get @u position), radiusX: 0.4, radiusY: 0.4, fill: (if (== (object/get @u team) "player") "#3b82f6" "#ef4444") })) }
|
|
48
48
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), offsetY: -0.6, width: 0.8, height: 0.12, fill: "rgba(0,0,0,0.6)" })) }
|
|
@@ -57,7 +57,7 @@ orbital ArenaBoardOrbital {
|
|
|
57
57
|
(render-ui main {
|
|
58
58
|
type: game-shell
|
|
59
59
|
hud: { type: game-hud, stats: [ { label: "Result", value: @entity.result } ] }
|
|
60
|
-
children: [ { type: canvas, projection: "flat", showMinimap: false, children: [
|
|
60
|
+
children: [ { type: canvas, fit: true, projection: "flat", showMinimap: false, children: [
|
|
61
61
|
{ type: draw-shape-layer, items: (array/map @config.tiles (fn t { type: draw-shape, shape: "cell", position: { x: (object/get @t x), y: (object/get @t y) }, fill: "#4ade80", stroke: "rgba(0,0,0,0.2)" })) }
|
|
62
62
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "ellipse", position: (object/get @u position), radiusX: 0.4, radiusY: 0.4, fill: (if (== (object/get @u team) "player") "#3b82f6" "#ef4444") })) }
|
|
63
63
|
{ type: draw-shape-layer, items: (array/map @entity.units (fn u { type: draw-shape, shape: "rect", position: (object/get @u position), offsetY: -0.6, width: 0.8, height: 0.12, fill: "rgba(0,0,0,0.6)" })) }
|