Date: 2024/05/26 08:11:25 UTC-07:00
Type: Denizen Script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
ui_gui_events_handler_world:
type: world
debug: true
subtasks:
injecter:
- stop if:!<context.inventory.script.exists>
- define SCRIPT <context.inventory.script>
- define SCRIPT_NAME <[SCRIPT].name>
- stop if:!<server.has_flag[CACHE.UI.GUI.EVENTS.<[SCRIPT_NAME]>.<[EVENT]>]>
- define HANDLERS_MAP <server.flag[CACHE.UI.GUI.EVENTS.<[SCRIPT_NAME]>.<[EVENT]>]>
- define HANDLERS <[HANDLERS_MAP.ON].if_null[<list>]>
- foreach <[HANDLERS]> as:HANDLER:
- inject <script> path:subtasks.handlers.<[EVENT]>
- wait 1t
- define HANDLERS <[HANDLERS_MAP.AFTER].if_null[<list>]>
- foreach <[HANDLERS]> as:HANDLER:
- inject <script> path:subtasks.handlers.<[EVENT]>
handlers:
open:
- inject <[SCRIPT]> path:subtasks.events.<[HANDLER.LINE]>
close:
- inject <[SCRIPT]> path:subtasks.events.<[HANDLER.LINE]>
click:
- if <[HANDLER.CLICK_TYPE].exists> && <context.click> != <[HANDLER.CLICK_TYPE]>:
- foreach next
- if <[HANDLER.ITEM_MATCHER].exists> && !<context.item.advanced_matches[<[HANDLER.ITEM_MATCHER]>]>:
- foreach next
- inject <[SCRIPT]> path:subtasks.events.<[HANDLER.LINE]>
drag:
- if <[HANDLER.ITEM_MATCHER].exists> && !<context.item.advanced_matches[<[HANDLER.ITEM_MATCHER]>]>:
- foreach next
- inject <[SCRIPT]> path:subtasks.events.<[HANDLER.LINE]>
events:
after script reload:
- run ui_gui_refresh_events_cache
on player clicks in inventory:
- define EVENT click
- inject <script> path:subtasks.injecter
on player drags in inventory:
- define EVENT drag
- inject <script> path:subtasks.injecter
on player opens inventory:
- define EVENT open
- inject <script> path:subtasks.injecter
on player closes inventory:
- define EVENT close
- inject <script> path:subtasks.injecter
ui_gui_refresh_events_cache:
type: task
debug: false
subtasks:
handle_script:
- define EVENT_LINES <[SCRIPT].data_key[subtasks.events].keys>
- define SCRIPT_NAME <[SCRIPT].name>
- foreach <[EVENT_LINES]> as:LINE:
- define HANDLER <[LINE].proc[parse_gui_event_line]>
- if <[HANDLER]> == null:
- debug error "Event line '<[LINE]>' for script '<[SCRIPT_NAME]>' has been skipped."
- foreach next
# The flag format is:
# EVENTS.my_script_name.click.on:<list[<map>]>
# EVENTS.my_script_name.drag.after:<list[<map>]>
# etc. to facilitate lookup during event handling.
- flag server CACHE.UI.GUI.EVENTS.<[SCRIPT_NAME]>.<[HANDLER.EVENT]>.<[HANDLER.TIMING]>:->:<[HANDLER]>
script:
- flag server CACHE.UI.GUI:!
- foreach <util.scripts> as:SCRIPT:
- if <[SCRIPT].container_type> != inventory:
- foreach next
- if !<[SCRIPT].data_key[gui].is_truthy>:
- foreach next
- if !<[SCRIPT].data_key[subtasks.events].exists>:
- foreach next
- inject <script> path:subtasks.handle_script
parse_gui_event_line:
type: procedure
debug: false
definitions: LINE
description: Parses an event handler line into a map of its components.
data:
click_types:
# https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/inventory/ClickType.html
- CONTROL_DROP
- CREATIVE
- DOUBLE_CLICK
- DROP
- LEFT
- MIDDLE
- NUMBER_KEY
- RIGHT
- SHIFT_LEFT
- SHIFT_RIGHT
- SWAP_OFFHAND
- UNKNOWN
- WINDOW_BORDER_LEFT
- WINDOW_BORDER_RIGHT
aliases:
open: open
close: close
click: click
clicked: click
drag: drag
dragged: drag
subtasks:
open:
- debug error "'<[LINE]>' provides arguments, but 'open' does not accept any."
- determine null
close:
- debug error "'<[LINE]>' provides arguments, but 'close' does not accept any."
- determine null
click:
- define CLICK_TYPES <script.data_key[data.click_types]>
- if <[PARTS].size> == 1:
- define PART <[PARTS].first>
- if <[PART]> in <[CLICK_TYPES]>:
- define HANDLER.CLICK_TYPE <[PART]>
- else:
- define HANDLER.ITEM_MATCHER <[PART]>
- else if <[PARTS].size> == 2:
- if <[PARTS].first> in <[CLICK_TYPES]>:
- define HANDLER.CLICK_TYPE <[PARTS].first>
- define HANDLER.ITEM_MATCHER <[PARTS].get[2]>
- else if <[PARTS].get[2]> in <[CLICK_TYPES]>:
- define HANDLER.CLICK_TYPE <[PARTS].get[2]>
- define HANDLER.ITEM_MATCHER <[PARTS].first>
- else:
- debug error "'<[LINE]>' event handler does not contain a valid click type."
- determine null
- else:
- debug error "'<[LINE]>' event handler contains too many arguments."
- determine null
drag:
- if <[PARTS].size> == 1:
- define HANDLER.ITEM_MATCHER <[PARTS].first>
- else:
- debug error "'<[LINE]>' event handler contains too many arguments."
- determine null
script:
- define PARTS <[LINE].split>
# The first part must always be `on` or `after`
- if <[PARTS].first> == on:
- define TIMING on
- else if <[PARTS].first> == after:
- define TIMING after
- else:
- debug error "'<[LINE]>': all event handlers must start with 'on' or 'after'."
- determine null
# All events end with the event type, but might be conjugated differently
# I.e. `on click` or `on item clicked`
- define ALIAS <[PARTS].last>
- define EVENT <script.data_key[data.aliases.<[ALIAS]>].if_null[null]>
- if <[EVENT]> == null:
- debug error "'<[LINE]>' did not match any known event name."
- determine null
- definemap HANDLER:
LINE: <[LINE]>
TIMING: <[TIMING]>
EVENT: <[EVENT]>
# The remaining parts are the handler details
- define PARTS <[PARTS].get[2].to[-2]>
- if <[PARTS].is_truthy>:
- inject <script> path:subtasks.<[EVENT]>
- determine <[HANDLER]>