dfpyre 0.6.3__py3-none-any.whl → 0.7.0__py3-none-any.whl
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.
Potentially problematic release.
This version of dfpyre might be problematic. Click here for more details.
- dfpyre/actiondump.py +72 -0
- dfpyre/data/actiondump_min.json +1 -0
- dfpyre/items.py +22 -8
- dfpyre/pyre.py +129 -159
- dfpyre/scriptgen.py +10 -2
- dfpyre/util.py +28 -0
- {dfpyre-0.6.3.dist-info → dfpyre-0.7.0.dist-info}/METADATA +16 -3
- dfpyre-0.7.0.dist-info/RECORD +12 -0
- dfpyre/data/data.json +0 -1
- dfpyre-0.6.3.dist-info/RECORD +0 -10
- {dfpyre-0.6.3.dist-info → dfpyre-0.7.0.dist-info}/LICENSE +0 -0
- {dfpyre-0.6.3.dist-info → dfpyre-0.7.0.dist-info}/WHEEL +0 -0
dfpyre/items.py
CHANGED
|
@@ -4,19 +4,28 @@ Contains class definitions for code items.
|
|
|
4
4
|
|
|
5
5
|
from enum import Enum
|
|
6
6
|
import re
|
|
7
|
-
from typing import Literal,
|
|
7
|
+
from typing import Literal, Any
|
|
8
8
|
from dfpyre.style import is_ampersand_coded, ampersand_to_minimessage
|
|
9
|
+
from dfpyre.util import PyreException, warn
|
|
9
10
|
from mcitemlib.itemlib import Item as NbtItem
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
NUMBER_REGEX = r'-?\d*\.?\d+'
|
|
14
|
+
VAR_SHORTHAND_CHAR = '$'
|
|
15
|
+
VAR_SCOPES = {'g': 'unsaved', 's': 'saved', 'l': 'local', 'i': 'line'}
|
|
13
16
|
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
def convert_argument(arg: Any):
|
|
19
|
+
if type(arg) in {int, float}:
|
|
20
|
+
return num(arg)
|
|
21
|
+
elif isinstance(arg, str):
|
|
22
|
+
if len(arg) > 2 and arg[0] == VAR_SHORTHAND_CHAR and arg[1] in VAR_SCOPES:
|
|
23
|
+
return var(arg[2:], VAR_SCOPES[arg[1]])
|
|
24
|
+
return text(arg)
|
|
25
|
+
return arg
|
|
17
26
|
|
|
18
27
|
|
|
19
|
-
def _add_slot(d:
|
|
28
|
+
def _add_slot(d: dict, slot: int|None):
|
|
20
29
|
if slot is not None:
|
|
21
30
|
d['slot'] = slot
|
|
22
31
|
|
|
@@ -274,7 +283,7 @@ class parameter:
|
|
|
274
283
|
self.optional = optional
|
|
275
284
|
self.description = description
|
|
276
285
|
self.note = note
|
|
277
|
-
self.default_value = default_value
|
|
286
|
+
self.default_value = convert_argument(default_value)
|
|
278
287
|
|
|
279
288
|
|
|
280
289
|
def format(self, slot: int):
|
|
@@ -292,8 +301,13 @@ class parameter:
|
|
|
292
301
|
formatted_dict['item']['data']['description'] = self.description
|
|
293
302
|
if self.note:
|
|
294
303
|
formatted_dict['item']['data']['note'] = self.note
|
|
295
|
-
if self.default_value is not None
|
|
296
|
-
|
|
304
|
+
if self.default_value is not None:
|
|
305
|
+
if not self.optional:
|
|
306
|
+
warn(f'For parameter "{self.name}": Default value cannot be set if optional is False.')
|
|
307
|
+
elif self.plural:
|
|
308
|
+
warn(f'For parameter "{self.name}": Default value cannot be set while plural is True.')
|
|
309
|
+
else:
|
|
310
|
+
formatted_dict['item']['data']['default_value'] = self.default_value.format(None)['item']
|
|
297
311
|
|
|
298
312
|
return formatted_dict
|
|
299
313
|
|
|
@@ -311,7 +325,7 @@ def _some_or(value: Any, none_value: Any):
|
|
|
311
325
|
return value
|
|
312
326
|
|
|
313
327
|
|
|
314
|
-
def item_from_dict(item_dict:
|
|
328
|
+
def item_from_dict(item_dict: dict) -> object:
|
|
315
329
|
item_id = item_dict['id']
|
|
316
330
|
item_data = item_dict['data']
|
|
317
331
|
|
dfpyre/pyre.py
CHANGED
|
@@ -4,25 +4,18 @@ A package for externally creating code templates for the DiamondFire Minecraft s
|
|
|
4
4
|
By Amp
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import base64
|
|
8
|
-
import gzip
|
|
9
7
|
import json
|
|
10
|
-
import os
|
|
11
8
|
from difflib import get_close_matches
|
|
12
9
|
import datetime
|
|
13
|
-
from typing import Tuple
|
|
10
|
+
from typing import Tuple
|
|
14
11
|
from enum import Enum
|
|
15
12
|
import socket
|
|
16
13
|
from mcitemlib.itemlib import Item as NbtItem
|
|
14
|
+
from dfpyre.util import *
|
|
17
15
|
from dfpyre.items import *
|
|
18
16
|
from dfpyre.scriptgen import generate_script, GeneratorFlags
|
|
17
|
+
from dfpyre.actiondump import CODEBLOCK_DATA, get_default_tags
|
|
19
18
|
|
|
20
|
-
COL_WARN = '\x1b[33m'
|
|
21
|
-
COL_RESET = '\x1b[0m'
|
|
22
|
-
COL_SUCCESS = '\x1b[32m'
|
|
23
|
-
COL_ERROR = '\x1b[31m'
|
|
24
|
-
|
|
25
|
-
CODEBLOCK_DATA_PATH = os.path.join(os.path.dirname(__file__), 'data/data.json')
|
|
26
19
|
|
|
27
20
|
VARIABLE_TYPES = {'txt', 'comp', 'num', 'item', 'loc', 'var', 'snd', 'part', 'pot', 'g_val', 'vec', 'pn_el'}
|
|
28
21
|
TEMPLATE_STARTERS = {'event', 'entity_event', 'func', 'process'}
|
|
@@ -31,9 +24,6 @@ SINGLE_NAME_CODEBLOCKS = {'func', 'process', 'call_func', 'start_process', 'else
|
|
|
31
24
|
TARGETS = ['Selection', 'Default', 'Killer', 'Damager', 'Shooter', 'Victim', 'AllPlayers', 'Projectile', 'AllEntities', 'AllMobs', 'LastEntity']
|
|
32
25
|
TARGET_CODEBLOCKS = {'player_action', 'entity_action', 'if_player', 'if_entity'}
|
|
33
26
|
|
|
34
|
-
VAR_SHORTHAND_CHAR = '$'
|
|
35
|
-
VAR_SCOPES = {'g': 'unsaved', 's': 'saved', 'l': 'local', 'i': 'line'}
|
|
36
|
-
|
|
37
27
|
CODECLIENT_URL = 'ws://localhost:31375'
|
|
38
28
|
|
|
39
29
|
|
|
@@ -57,54 +47,59 @@ DEFAULT_TARGET = Target.SELECTION
|
|
|
57
47
|
|
|
58
48
|
|
|
59
49
|
class CodeBlock:
|
|
60
|
-
def __init__(self, name: str, args: Tuple=(), target: Target=DEFAULT_TARGET, data:
|
|
50
|
+
def __init__(self, name: str, args: Tuple=(), target: Target=DEFAULT_TARGET, data: dict={}, tags: dict[str, str]={}):
|
|
61
51
|
self.name = name
|
|
62
52
|
self.args = args
|
|
63
53
|
self.target = target
|
|
64
54
|
self.data = data
|
|
55
|
+
self.tags = tags
|
|
65
56
|
|
|
66
57
|
def __repr__(self) -> str:
|
|
67
58
|
if self.name in SINGLE_NAME_CODEBLOCKS:
|
|
68
59
|
if self.name == 'else':
|
|
69
60
|
return 'CodeBlock(else)'
|
|
70
61
|
return f'CodeBlock({self.name}, {self.data["data"]})'
|
|
71
|
-
|
|
62
|
+
if 'block' in self.data:
|
|
72
63
|
return f'CodeBlock({self.data["block"]}, {self.name})'
|
|
73
64
|
return f'CodeBlock(bracket, {self.data["type"]}, {self.data["direct"]})'
|
|
74
65
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
def build(self, include_tags: bool=True) -> dict:
|
|
67
|
+
"""
|
|
68
|
+
Builds a properly formatted block from a CodeBlock object.
|
|
69
|
+
"""
|
|
70
|
+
built_block = self.data.copy()
|
|
71
|
+
codeblock_type = self.data.get('block')
|
|
72
|
+
|
|
73
|
+
# add target if necessary ('Selection' is the default when 'target' is blank)
|
|
74
|
+
if codeblock_type in TARGET_CODEBLOCKS and self.target != DEFAULT_TARGET:
|
|
75
|
+
built_block['target'] = self.target.get_string_value()
|
|
76
|
+
|
|
77
|
+
# add items into args
|
|
78
|
+
final_args = [arg.format(slot) for slot, arg in enumerate(self.args) if arg.type in VARIABLE_TYPES]
|
|
79
|
+
|
|
80
|
+
# check for unrecognized name, add tags
|
|
81
|
+
if codeblock_type is not None: # for brackets
|
|
82
|
+
if self.name not in CODEBLOCK_DATA[codeblock_type]:
|
|
83
|
+
_warn_unrecognized_name(codeblock_type, self.name)
|
|
84
|
+
elif include_tags:
|
|
85
|
+
tags = _get_codeblock_tags(codeblock_type, self.name, self.tags)
|
|
86
|
+
if len(final_args) + len(tags) > 27:
|
|
87
|
+
final_args = final_args[:(27-len(tags))] # trim list if over 27 elements
|
|
88
|
+
final_args.extend(tags) # add tags to end
|
|
89
|
+
|
|
90
|
+
# if final_args:
|
|
91
|
+
built_block['args'] = {'items': final_args}
|
|
92
|
+
return built_block
|
|
78
93
|
|
|
79
94
|
|
|
80
95
|
def _warn_unrecognized_name(codeblock_type: str, codeblock_name: str):
|
|
81
|
-
close = get_close_matches(codeblock_name,
|
|
96
|
+
close = get_close_matches(codeblock_name, CODEBLOCK_DATA[codeblock_type].keys())
|
|
82
97
|
if close:
|
|
83
|
-
|
|
98
|
+
warn(f'Code block name "{codeblock_name}" not recognized. Did you mean "{close[0]}"?')
|
|
84
99
|
else:
|
|
85
|
-
|
|
100
|
+
warn(f'Code block name "{codeblock_name}" not recognized. Try spell checking or retyping without spaces.')
|
|
86
101
|
|
|
87
102
|
|
|
88
|
-
def _load_codeblock_data() -> Tuple:
|
|
89
|
-
tag_data = {}
|
|
90
|
-
if os.path.exists(CODEBLOCK_DATA_PATH):
|
|
91
|
-
with open(CODEBLOCK_DATA_PATH, 'r') as f:
|
|
92
|
-
tag_data = json.load(f)
|
|
93
|
-
else:
|
|
94
|
-
_warn('data.json not found -- Item tags and error checking will not work.')
|
|
95
|
-
return ({}, set(), set())
|
|
96
|
-
|
|
97
|
-
del tag_data['meta']
|
|
98
|
-
|
|
99
|
-
all_names = [x for l in [d.keys() for d in tag_data.values()] for x in l] # flatten list
|
|
100
|
-
return (
|
|
101
|
-
tag_data,
|
|
102
|
-
set(tag_data['extras'].keys()),
|
|
103
|
-
set(all_names)
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
TAGDATA, TAGDATA_EXTRAS_KEYS, ALL_CODEBLOCK_NAMES = _load_codeblock_data()
|
|
107
|
-
|
|
108
103
|
def _add_inverted(data, inverted):
|
|
109
104
|
"""
|
|
110
105
|
If inverted is true, add 'inverted': 'NOT' to data.
|
|
@@ -113,36 +108,48 @@ def _add_inverted(data, inverted):
|
|
|
113
108
|
data['inverted'] = 'NOT'
|
|
114
109
|
|
|
115
110
|
|
|
116
|
-
def
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
111
|
+
def _convert_args(args):
|
|
112
|
+
return tuple(map(convert_argument, args))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _check_applied_tags(tags: list[dict], applied_tags: dict[str, str], codeblock_name: str) -> dict[str, str]:
|
|
116
|
+
if len(applied_tags) > 0 and len(tags) == 0:
|
|
117
|
+
warn(f'Action "{codeblock_name}" does not have any tags, but still received {len(applied_tags)}.')
|
|
118
|
+
return {}
|
|
119
|
+
valid_tags = {}
|
|
120
|
+
tags_formatted = {t['name']: t for t in tags}
|
|
121
|
+
for name, option in applied_tags.items():
|
|
122
|
+
if name not in tags_formatted:
|
|
123
|
+
tag_names_joined = '\n'.join(map(lambda s: ' - '+s, tags_formatted.keys()))
|
|
124
|
+
warn(f'Tag "{name}" does not exist for action "{codeblock_name}". Available tags:\n{tag_names_joined}')
|
|
125
|
+
elif option not in tags_formatted[name]['options']:
|
|
126
|
+
options_joined = '\n'.join(map(lambda s: ' - '+s, tags_formatted[name]['options']))
|
|
127
|
+
warn(f'Tag "{name}" does not have the option "{option}". Available tag options:\n{options_joined}')
|
|
127
128
|
else:
|
|
128
|
-
|
|
129
|
-
return
|
|
129
|
+
valid_tags[name] = option
|
|
130
|
+
return valid_tags
|
|
130
131
|
|
|
131
132
|
|
|
132
|
-
def _reformat_codeblock_tags(tags, codeblock_type: str, codeblock_name: str):
|
|
133
|
+
def _reformat_codeblock_tags(tags: list[dict], codeblock_type: str, codeblock_name: str, applied_tags: dict[str, str]):
|
|
133
134
|
"""
|
|
134
|
-
Turns
|
|
135
|
+
Turns tag objects into DiamondFire formatted tag items
|
|
135
136
|
"""
|
|
137
|
+
|
|
138
|
+
valid_applied_tags = _check_applied_tags(tags, applied_tags, codeblock_name)
|
|
136
139
|
reformatted_tags = []
|
|
137
140
|
for tag_item in tags:
|
|
138
|
-
|
|
141
|
+
tag_name = tag_item['name']
|
|
142
|
+
tag_option = tag_item['default']
|
|
143
|
+
if tag_name in valid_applied_tags:
|
|
144
|
+
tag_option = valid_applied_tags[tag_name]
|
|
145
|
+
|
|
139
146
|
new_tag_item = {
|
|
140
147
|
'item': {
|
|
141
148
|
'id': 'bl_tag',
|
|
142
149
|
'data': {
|
|
143
|
-
'option':
|
|
144
|
-
'tag':
|
|
145
|
-
'action':
|
|
150
|
+
'option': tag_option,
|
|
151
|
+
'tag': tag_name,
|
|
152
|
+
'action': codeblock_name,
|
|
146
153
|
'block': codeblock_type
|
|
147
154
|
}
|
|
148
155
|
},
|
|
@@ -152,57 +159,15 @@ def _reformat_codeblock_tags(tags, codeblock_type: str, codeblock_name: str):
|
|
|
152
159
|
return reformatted_tags
|
|
153
160
|
|
|
154
161
|
|
|
155
|
-
def _get_codeblock_tags(codeblock_type: str, codeblock_name: str):
|
|
162
|
+
def _get_codeblock_tags(codeblock_type: str, codeblock_name: str, applied_tags: dict[str, str]):
|
|
156
163
|
"""
|
|
157
164
|
Get tags for the specified codeblock type and name
|
|
158
165
|
"""
|
|
159
|
-
|
|
160
|
-
if
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return _reformat_codeblock_tags(tags, codeblock_type, codeblock_name)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
def _build_block(codeblock: CodeBlock, include_tags: bool):
|
|
168
|
-
"""
|
|
169
|
-
Builds a properly formatted block from a CodeBlock object.
|
|
170
|
-
"""
|
|
171
|
-
built_block = codeblock.data.copy()
|
|
172
|
-
codeblock_type = codeblock.data.get('block')
|
|
173
|
-
|
|
174
|
-
# add target if necessary ('Selection' is the default when 'target' is blank)
|
|
175
|
-
if codeblock_type in TARGET_CODEBLOCKS and codeblock.target != DEFAULT_TARGET:
|
|
176
|
-
built_block['target'] = codeblock.target.get_string_value()
|
|
177
|
-
|
|
178
|
-
# add items into args
|
|
179
|
-
final_args = [arg.format(slot) for slot, arg in enumerate(codeblock.args) if arg.type in VARIABLE_TYPES]
|
|
180
|
-
|
|
181
|
-
# check for unrecognized name, add tags
|
|
182
|
-
if codeblock_type is not None: # for brackets
|
|
183
|
-
if codeblock_type not in TAGDATA_EXTRAS_KEYS and codeblock.name not in ALL_CODEBLOCK_NAMES:
|
|
184
|
-
_warn_unrecognized_name(codeblock_type, codeblock.name)
|
|
185
|
-
elif include_tags:
|
|
186
|
-
tags = _get_codeblock_tags(codeblock_type, codeblock.name)
|
|
187
|
-
if len(final_args) + len(tags) > 27:
|
|
188
|
-
final_args = final_args[:(27-len(tags))] # trim list if over 27 elements
|
|
189
|
-
final_args.extend(tags) # add tags to end
|
|
190
|
-
|
|
191
|
-
if final_args:
|
|
192
|
-
built_block['args'] = {'items': final_args}
|
|
193
|
-
return built_block
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def _df_encode(json_string: str) -> str:
|
|
197
|
-
"""
|
|
198
|
-
Encodes a stringified json.
|
|
199
|
-
"""
|
|
200
|
-
encoded_string = gzip.compress(json_string.encode('utf-8'))
|
|
201
|
-
return base64.b64encode(encoded_string).decode('utf-8')
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def _df_decode(encoded_string: str) -> str:
|
|
205
|
-
return gzip.decompress(base64.b64decode(encoded_string)).decode('utf-8')
|
|
166
|
+
action_data = CODEBLOCK_DATA[codeblock_type][codeblock_name]
|
|
167
|
+
if 'deprecatedNote' in action_data:
|
|
168
|
+
warn(f'Action "{codeblock_name}" is deprecated: {action_data["deprecatedNote"]}')
|
|
169
|
+
tags = action_data['tags']
|
|
170
|
+
return _reformat_codeblock_tags(tags, codeblock_type, codeblock_name, applied_tags)
|
|
206
171
|
|
|
207
172
|
|
|
208
173
|
def _get_template_item(template_code: str, name: str, author: str) -> NbtItem:
|
|
@@ -232,7 +197,7 @@ class DFTemplate:
|
|
|
232
197
|
Represents a DiamondFire code template.
|
|
233
198
|
"""
|
|
234
199
|
def __init__(self, name: str=None, author: str='pyre'):
|
|
235
|
-
self.codeblocks:
|
|
200
|
+
self.codeblocks: list[CodeBlock] = []
|
|
236
201
|
self.bracket_stack: list[str] = []
|
|
237
202
|
self.name = name
|
|
238
203
|
self.author = author
|
|
@@ -247,12 +212,16 @@ class DFTemplate:
|
|
|
247
212
|
"""
|
|
248
213
|
Create a template object from an existing template code.
|
|
249
214
|
"""
|
|
250
|
-
template_dict = json.loads(
|
|
215
|
+
template_dict = json.loads(df_decode(template_code))
|
|
251
216
|
template = DFTemplate()
|
|
252
217
|
for block_dict in template_dict['blocks']:
|
|
218
|
+
block_tags = get_default_tags(block_dict.get('block'), block_dict.get('action'))
|
|
253
219
|
if 'args' in block_dict:
|
|
254
220
|
args = []
|
|
255
221
|
for item_dict in block_dict['args']['items']:
|
|
222
|
+
if item_dict['item'].get('id') == 'bl_tag':
|
|
223
|
+
tag_data = item_dict['item']['data']
|
|
224
|
+
block_tags[tag_data['tag']] = tag_data['option']
|
|
256
225
|
parsed_item = item_from_dict(item_dict['item'])
|
|
257
226
|
if parsed_item is not None:
|
|
258
227
|
args.append(parsed_item)
|
|
@@ -267,7 +236,7 @@ class DFTemplate:
|
|
|
267
236
|
if codeblock_name == 'bracket' or block_dict['block'] == 'else':
|
|
268
237
|
codeblock = CodeBlock(codeblock_name, data=block_dict)
|
|
269
238
|
else:
|
|
270
|
-
codeblock = CodeBlock(codeblock_name, args, target, block_dict)
|
|
239
|
+
codeblock = CodeBlock(codeblock_name, args, target, block_dict, tags=block_tags)
|
|
271
240
|
template.codeblocks.append(codeblock)
|
|
272
241
|
|
|
273
242
|
return template
|
|
@@ -301,16 +270,16 @@ class DFTemplate:
|
|
|
301
270
|
:param bool include_tags: If True, include item tags in code blocks. Otherwise omit them.
|
|
302
271
|
:return: String containing encoded template data.
|
|
303
272
|
"""
|
|
304
|
-
template_dict_blocks = [
|
|
273
|
+
template_dict_blocks = [codeblock.build(include_tags) for codeblock in self.codeblocks]
|
|
305
274
|
template_dict = {'blocks': template_dict_blocks}
|
|
306
275
|
first_block = template_dict_blocks[0]
|
|
307
276
|
if first_block['block'] not in TEMPLATE_STARTERS:
|
|
308
|
-
|
|
277
|
+
warn('Template does not start with an event, function, or process.')
|
|
309
278
|
|
|
310
279
|
self._set_template_name(first_block)
|
|
311
280
|
|
|
312
281
|
json_string = json.dumps(template_dict, separators=(',', ':'))
|
|
313
|
-
return
|
|
282
|
+
return df_encode(json_string)
|
|
314
283
|
|
|
315
284
|
|
|
316
285
|
def build_and_send(self, method: Literal['recode', 'codeclient'], include_tags: bool=True) -> int:
|
|
@@ -355,78 +324,79 @@ class DFTemplate:
|
|
|
355
324
|
self._add_codeblock(cmd, index)
|
|
356
325
|
|
|
357
326
|
|
|
358
|
-
def function(self, name: str, *args, index: int|None=None):
|
|
359
|
-
args =
|
|
360
|
-
cmd = CodeBlock('
|
|
327
|
+
def function(self, name: str, *args, tags: dict[str, str]={}, index: int|None=None):
|
|
328
|
+
args = _convert_args(args)
|
|
329
|
+
cmd = CodeBlock('dynamic', args, data={'id': 'block', 'block': 'func', 'data': name}, tags=tags)
|
|
361
330
|
self._add_codeblock(cmd, index)
|
|
362
331
|
|
|
363
332
|
|
|
364
|
-
def process(self, name: str, *args, index: int|None=None):
|
|
365
|
-
args =
|
|
366
|
-
cmd = CodeBlock('
|
|
333
|
+
def process(self, name: str, *args, tags: dict[str, str]={}, index: int|None=None):
|
|
334
|
+
args = _convert_args(args)
|
|
335
|
+
cmd = CodeBlock('dynamic', args, data={'id': 'block', 'block': 'process', 'data': name}, tags=tags)
|
|
367
336
|
self._add_codeblock(cmd, index)
|
|
368
337
|
|
|
369
338
|
|
|
370
339
|
def call_function(self, name: str, *args, index: int|None=None):
|
|
371
|
-
args =
|
|
372
|
-
cmd = CodeBlock('
|
|
340
|
+
args = _convert_args(args)
|
|
341
|
+
cmd = CodeBlock('dynamic', args, data={'id': 'block', 'block': 'call_func', 'data': name})
|
|
373
342
|
self._add_codeblock(cmd, index)
|
|
374
343
|
|
|
375
|
-
|
|
376
|
-
|
|
344
|
+
|
|
345
|
+
def start_process(self, name: str, tags: dict[str, str]={}, index: int|None=None):
|
|
346
|
+
cmd = CodeBlock('dynamic', data={'id': 'block', 'block': 'start_process', 'data': name}, tags=tags)
|
|
377
347
|
self._add_codeblock(cmd, index)
|
|
378
348
|
|
|
379
349
|
|
|
380
|
-
def player_action(self, name: str, *args, target: Target=DEFAULT_TARGET, index: int|None=None):
|
|
381
|
-
args =
|
|
382
|
-
cmd = CodeBlock(name, args, target=target, data={'id': 'block', 'block': 'player_action', 'action': name})
|
|
350
|
+
def player_action(self, name: str, *args, target: Target=DEFAULT_TARGET, tags: dict[str, str]={}, index: int|None=None):
|
|
351
|
+
args = _convert_args(args)
|
|
352
|
+
cmd = CodeBlock(name, args, target=target, data={'id': 'block', 'block': 'player_action', 'action': name}, tags=tags)
|
|
383
353
|
self._add_codeblock(cmd, index)
|
|
384
354
|
|
|
385
355
|
|
|
386
|
-
def game_action(self, name: str, *args, index: int|None=None):
|
|
387
|
-
args =
|
|
388
|
-
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'game_action', 'action': name})
|
|
356
|
+
def game_action(self, name: str, *args, tags: dict[str, str]={}, index: int|None=None):
|
|
357
|
+
args = _convert_args(args)
|
|
358
|
+
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'game_action', 'action': name}, tags=tags)
|
|
389
359
|
self._add_codeblock(cmd, index)
|
|
390
360
|
|
|
391
361
|
|
|
392
|
-
def entity_action(self, name: str, *args, target: Target=DEFAULT_TARGET, index: int|None=None):
|
|
393
|
-
args =
|
|
394
|
-
cmd = CodeBlock(name, args, target=target, data={'id': 'block', 'block': 'entity_action', 'action': name})
|
|
362
|
+
def entity_action(self, name: str, *args, target: Target=DEFAULT_TARGET, tags: dict[str, str]={}, index: int|None=None):
|
|
363
|
+
args = _convert_args(args)
|
|
364
|
+
cmd = CodeBlock(name, args, target=target, data={'id': 'block', 'block': 'entity_action', 'action': name}, tags=tags)
|
|
395
365
|
self._add_codeblock(cmd, index)
|
|
396
366
|
|
|
397
367
|
|
|
398
|
-
def if_player(self, name: str, *args, target: Target=DEFAULT_TARGET, inverted: bool=False, index: int|None=None):
|
|
399
|
-
args =
|
|
368
|
+
def if_player(self, name: str, *args, target: Target=DEFAULT_TARGET, tags: dict[str, str]={}, inverted: bool=False, index: int|None=None):
|
|
369
|
+
args = _convert_args(args)
|
|
400
370
|
data = {'id': 'block', 'block': 'if_player', 'action': name}
|
|
401
371
|
_add_inverted(data, inverted)
|
|
402
|
-
cmd = CodeBlock(name, args, target=target, data=data)
|
|
372
|
+
cmd = CodeBlock(name, args, target=target, data=data, tags=tags)
|
|
403
373
|
self._add_codeblock(cmd, index)
|
|
404
374
|
self._openbracket(index)
|
|
405
375
|
|
|
406
376
|
|
|
407
|
-
def if_variable(self, name: str, *args, inverted: bool=False, index: int|None=None):
|
|
408
|
-
args =
|
|
377
|
+
def if_variable(self, name: str, *args, tags: dict[str, str]={}, inverted: bool=False, index: int|None=None):
|
|
378
|
+
args = _convert_args(args)
|
|
409
379
|
data = {'id': 'block', 'block': 'if_var', 'action': name}
|
|
410
380
|
_add_inverted(data, inverted)
|
|
411
|
-
cmd = CodeBlock(name, args, data=data)
|
|
381
|
+
cmd = CodeBlock(name, args, data=data, tags=tags)
|
|
412
382
|
self._add_codeblock(cmd, index)
|
|
413
383
|
self._openbracket(index)
|
|
414
384
|
|
|
415
385
|
|
|
416
|
-
def if_game(self, name: str, *args, inverted: bool=False, index: int|None=None):
|
|
417
|
-
args =
|
|
386
|
+
def if_game(self, name: str, *args, tags: dict[str, str]={}, inverted: bool=False, index: int|None=None):
|
|
387
|
+
args = _convert_args(args)
|
|
418
388
|
data = {'id': 'block', 'block': 'if_game', 'action': name}
|
|
419
389
|
_add_inverted(data, inverted)
|
|
420
|
-
cmd = CodeBlock(name, args, data=data)
|
|
390
|
+
cmd = CodeBlock(name, args, data=data, tags=tags)
|
|
421
391
|
self._add_codeblock(cmd, index)
|
|
422
392
|
self._openbracket(index)
|
|
423
393
|
|
|
424
394
|
|
|
425
|
-
def if_entity(self, name: str, *args, target: Target=DEFAULT_TARGET, inverted: bool=False, index: int|None=None):
|
|
426
|
-
args =
|
|
395
|
+
def if_entity(self, name: str, *args, target: Target=DEFAULT_TARGET, tags: dict[str, str]={}, inverted: bool=False, index: int|None=None):
|
|
396
|
+
args = _convert_args(args)
|
|
427
397
|
data = {'id': 'block', 'block': 'if_entity', 'action': name}
|
|
428
398
|
_add_inverted(data, inverted)
|
|
429
|
-
cmd = CodeBlock(name, args, target=target, data=data)
|
|
399
|
+
cmd = CodeBlock(name, args, target=target, data=data, tags=tags)
|
|
430
400
|
self._add_codeblock(cmd, index)
|
|
431
401
|
self._openbracket(index)
|
|
432
402
|
|
|
@@ -437,37 +407,37 @@ class DFTemplate:
|
|
|
437
407
|
self._openbracket(index)
|
|
438
408
|
|
|
439
409
|
|
|
440
|
-
def repeat(self, name: str, *args, sub_action: str=None, index: int|None=None):
|
|
441
|
-
args =
|
|
410
|
+
def repeat(self, name: str, *args, tags: dict[str, str]={}, sub_action: str=None, index: int|None=None):
|
|
411
|
+
args = _convert_args(args)
|
|
442
412
|
data = {'id': 'block', 'block': 'repeat', 'action': name}
|
|
443
413
|
if sub_action is not None:
|
|
444
414
|
data['subAction'] = sub_action
|
|
445
|
-
cmd = CodeBlock(name, args, data=data)
|
|
415
|
+
cmd = CodeBlock(name, args, data=data, tags=tags)
|
|
446
416
|
self._add_codeblock(cmd, index)
|
|
447
417
|
self._openbracket(index, 'repeat')
|
|
448
418
|
|
|
449
419
|
|
|
450
420
|
def bracket(self, *args, index: int|None=None):
|
|
451
|
-
args =
|
|
421
|
+
args = _convert_args(args)
|
|
452
422
|
cmd = CodeBlock('bracket', data={'id': 'bracket', 'direct': 'close', 'type': self.bracket_stack.pop()})
|
|
453
423
|
self._add_codeblock(cmd, index)
|
|
454
424
|
|
|
455
425
|
|
|
456
|
-
def control(self, name: str, *args, index: int|None=None):
|
|
457
|
-
args =
|
|
458
|
-
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'control', 'action': name})
|
|
426
|
+
def control(self, name: str, *args, tags: dict[str, str]={}, index: int|None=None):
|
|
427
|
+
args = _convert_args(args)
|
|
428
|
+
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'control', 'action': name}, tags=tags)
|
|
459
429
|
self._add_codeblock(cmd, index)
|
|
460
430
|
|
|
461
431
|
|
|
462
|
-
def select_object(self, name: str, *args, index: int|None=None):
|
|
463
|
-
args =
|
|
464
|
-
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'select_obj', 'action': name})
|
|
432
|
+
def select_object(self, name: str, *args, tags: dict[str, str]={}, index: int|None=None):
|
|
433
|
+
args = _convert_args(args)
|
|
434
|
+
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'select_obj', 'action': name}, tags=tags)
|
|
465
435
|
self._add_codeblock(cmd, index)
|
|
466
436
|
|
|
467
437
|
|
|
468
|
-
def set_variable(self, name: str, *args, index: int|None=None):
|
|
469
|
-
args =
|
|
470
|
-
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'set_var', 'action': name})
|
|
438
|
+
def set_variable(self, name: str, *args, tags: dict[str, str]={}, index: int|None=None):
|
|
439
|
+
args = _convert_args(args)
|
|
440
|
+
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'set_var', 'action': name}, tags=tags)
|
|
471
441
|
self._add_codeblock(cmd, index)
|
|
472
442
|
|
|
473
443
|
|
|
@@ -481,6 +451,6 @@ class DFTemplate:
|
|
|
481
451
|
:param bool var_shorthand: If True, all variables will be written using variable shorthand.
|
|
482
452
|
"""
|
|
483
453
|
flags = GeneratorFlags(indent_size, literal_shorthand, var_shorthand)
|
|
484
|
-
with open(output_path, 'w') as f:
|
|
454
|
+
with open(output_path, 'w', encoding='utf-8') as f:
|
|
485
455
|
f.write(generate_script(self, flags))
|
|
486
456
|
|
dfpyre/scriptgen.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
import re
|
|
3
3
|
from dfpyre.items import *
|
|
4
|
+
from dfpyre.actiondump import get_default_tags
|
|
4
5
|
|
|
5
6
|
SCRIPT_START = '''from dfpyre import *
|
|
6
7
|
t = DFTemplate()
|
|
@@ -96,7 +97,7 @@ def argument_item_to_string(flags: GeneratorFlags, arg_item: object) -> str:
|
|
|
96
97
|
if arg_item.optional:
|
|
97
98
|
param_args.append('optional=True')
|
|
98
99
|
if arg_item.default_value is not None:
|
|
99
|
-
param_args.append(f'default_value={argument_item_to_string(arg_item.default_value)}')
|
|
100
|
+
param_args.append(f'default_value={argument_item_to_string(flags, arg_item.default_value)}')
|
|
100
101
|
if arg_item.description:
|
|
101
102
|
param_args.append(f'description="{arg_item.description}"')
|
|
102
103
|
if arg_item.note:
|
|
@@ -114,6 +115,7 @@ def add_script_line(flags: GeneratorFlags, script_lines: list[str], indent_level
|
|
|
114
115
|
script_lines.append(added_line)
|
|
115
116
|
|
|
116
117
|
|
|
118
|
+
# TODO: add tag values if not default
|
|
117
119
|
def generate_script(template, flags: GeneratorFlags) -> str:
|
|
118
120
|
indent_level = 0
|
|
119
121
|
script_lines = []
|
|
@@ -140,7 +142,13 @@ def generate_script(template, flags: GeneratorFlags) -> str:
|
|
|
140
142
|
method_args.extend(codeblock_args)
|
|
141
143
|
if method_name in TARGET_CODEBLOCKS and codeblock.target.name != 'SELECTION':
|
|
142
144
|
method_args.append(f'target=Target.{codeblock.target.name}')
|
|
145
|
+
if codeblock.tags:
|
|
146
|
+
print(codeblock.tags)
|
|
147
|
+
default_tags = get_default_tags(codeblock.data.get('block'), codeblock.name)
|
|
148
|
+
written_tags = {t: o for t, o in codeblock.tags.items() if default_tags[t] != o}
|
|
149
|
+
if written_tags:
|
|
150
|
+
method_args.append(f'tags={str(written_tags)}')
|
|
143
151
|
|
|
144
152
|
line = f't.{method_name}({", ".join(method_args)})'
|
|
145
153
|
add_script_line(flags, script_lines, indent_level, line)
|
|
146
|
-
return SCRIPT_START + '\n'.join(script_lines)
|
|
154
|
+
return SCRIPT_START + '\n'.join(script_lines)
|
dfpyre/util.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import gzip
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
COL_WARN = '\x1b[33m'
|
|
6
|
+
COL_RESET = '\x1b[0m'
|
|
7
|
+
COL_SUCCESS = '\x1b[32m'
|
|
8
|
+
COL_ERROR = '\x1b[31m'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PyreException(Exception):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def warn(message: str):
|
|
16
|
+
print(f'{COL_WARN}! WARNING ! {message}{COL_RESET}')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def df_encode(json_string: str) -> str:
|
|
20
|
+
"""
|
|
21
|
+
Encodes a stringified json.
|
|
22
|
+
"""
|
|
23
|
+
encoded_string = gzip.compress(json_string.encode('utf-8'))
|
|
24
|
+
return base64.b64encode(encoded_string).decode('utf-8')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def df_decode(encoded_string: str) -> str:
|
|
28
|
+
return gzip.decompress(base64.b64decode(encoded_string)).decode('utf-8')
|