dfpyre 0.5.0__py3-none-any.whl → 0.6.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/items.py +72 -29
- dfpyre/pyre.py +93 -19
- dfpyre/scriptgen.py +144 -0
- {dfpyre-0.5.0.dist-info → dfpyre-0.6.0.dist-info}/LICENSE +1 -1
- {dfpyre-0.5.0.dist-info → dfpyre-0.6.0.dist-info}/METADATA +32 -4
- dfpyre-0.6.0.dist-info/RECORD +10 -0
- dfpyre-0.5.0.dist-info/RECORD +0 -9
- {dfpyre-0.5.0.dist-info → dfpyre-0.6.0.dist-info}/WHEEL +0 -0
dfpyre/items.py
CHANGED
|
@@ -3,15 +3,24 @@ Contains class definitions for code items.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from enum import Enum
|
|
6
|
-
|
|
6
|
+
import re
|
|
7
|
+
from typing import Literal, Dict, Any
|
|
7
8
|
from dfpyre.style import is_ampersand_coded, ampersand_to_minimessage
|
|
8
9
|
from mcitemlib.itemlib import Item as NbtItem
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
NUMBER_REGEX = r'-?\d*\.?\d+'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class PyreException(Exception):
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
11
19
|
def _add_slot(d: Dict, slot: int|None):
|
|
12
20
|
if slot is not None:
|
|
13
21
|
d['slot'] = slot
|
|
14
22
|
|
|
23
|
+
|
|
15
24
|
class item(NbtItem):
|
|
16
25
|
"""
|
|
17
26
|
Represents a Minecraft item.
|
|
@@ -62,7 +71,7 @@ class num:
|
|
|
62
71
|
"""
|
|
63
72
|
type = 'num'
|
|
64
73
|
|
|
65
|
-
def __init__(self, num: int|float):
|
|
74
|
+
def __init__(self, num: int|float|str):
|
|
66
75
|
self.value = num
|
|
67
76
|
|
|
68
77
|
def format(self, slot: int|None):
|
|
@@ -140,34 +149,11 @@ class particle:
|
|
|
140
149
|
Represents a DiamondFire particle object.
|
|
141
150
|
"""
|
|
142
151
|
type = 'part'
|
|
143
|
-
def __init__(self,
|
|
144
|
-
|
|
145
|
-
self.name = name
|
|
146
|
-
self.amount = amount
|
|
147
|
-
self.horizontal = horizontal
|
|
148
|
-
self.vertical = vertical
|
|
149
|
-
self.x = x
|
|
150
|
-
self.y = y
|
|
151
|
-
self.z = z
|
|
152
|
-
self.motionVariation = motionVariation
|
|
152
|
+
def __init__(self, particle_data: dict):
|
|
153
|
+
self.particle_data = particle_data
|
|
153
154
|
|
|
154
155
|
def format(self, slot: int|None):
|
|
155
|
-
formatted_dict = {"item": {"id": self.type,
|
|
156
|
-
"data": {
|
|
157
|
-
"particle": self.name,
|
|
158
|
-
"cluster": {
|
|
159
|
-
"amount": self.amount,
|
|
160
|
-
"horizontal": self.horizontal,
|
|
161
|
-
"vertical": self.vertical
|
|
162
|
-
},
|
|
163
|
-
"data": {
|
|
164
|
-
"x": self.x,
|
|
165
|
-
"y": self.y,
|
|
166
|
-
"z": self.z,
|
|
167
|
-
"motionVariation": self.motionVariation
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}}
|
|
156
|
+
formatted_dict = {"item": {"id": self.type, "data": self.particle_data}}
|
|
171
157
|
_add_slot(formatted_dict, slot)
|
|
172
158
|
return formatted_dict
|
|
173
159
|
|
|
@@ -276,4 +262,61 @@ class parameter:
|
|
|
276
262
|
if self.default_value is not None and not self.plural and self.optional:
|
|
277
263
|
formatted_dict['item']['data']['default_value'] = self.default_value.format(None)['item']
|
|
278
264
|
|
|
279
|
-
return formatted_dict
|
|
265
|
+
return formatted_dict
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _some_or(value: Any, none_value: Any):
|
|
269
|
+
"""
|
|
270
|
+
Returns `none_value` if `value` is None, otherwise returns `value`.
|
|
271
|
+
"""
|
|
272
|
+
if value is None:
|
|
273
|
+
return none_value
|
|
274
|
+
return value
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def item_from_dict(item_dict: Dict) -> object:
|
|
278
|
+
item_id = item_dict['id']
|
|
279
|
+
item_data = item_dict['data']
|
|
280
|
+
|
|
281
|
+
if item_id == 'item':
|
|
282
|
+
return item.from_nbt(item_data['item'])
|
|
283
|
+
elif item_id == 'txt':
|
|
284
|
+
return string(item_data['name'])
|
|
285
|
+
elif item_id == 'comp':
|
|
286
|
+
return text(item_data['name'])
|
|
287
|
+
elif item_id == 'num':
|
|
288
|
+
num_value = item_data['name']
|
|
289
|
+
if re.match(NUMBER_REGEX, num_value):
|
|
290
|
+
num_value = float(item_data['name'])
|
|
291
|
+
if num_value % 1 == 0:
|
|
292
|
+
num_value = int(num_value)
|
|
293
|
+
return num(num_value)
|
|
294
|
+
return num(num_value)
|
|
295
|
+
elif item_id == 'loc':
|
|
296
|
+
item_loc = item_data['loc']
|
|
297
|
+
return loc(item_loc['x'], item_loc['y'], item_loc['z'], item_loc['pitch'], item_loc['yaw'])
|
|
298
|
+
elif item_id == 'var':
|
|
299
|
+
return var(item_data['name'], item_data['scope'])
|
|
300
|
+
elif item_id == 'snd':
|
|
301
|
+
return sound(item_data['sound'], item_data['pitch'], item_data['vol'])
|
|
302
|
+
elif item_id == 'part':
|
|
303
|
+
return particle(item_data)
|
|
304
|
+
elif item_id == 'pot':
|
|
305
|
+
return potion(item_data['pot'], item_data['dur'], item_data['amp'])
|
|
306
|
+
elif item_id == 'g_val':
|
|
307
|
+
return gamevalue(item_data['type'], item_data['target'])
|
|
308
|
+
elif item_id == 'vec':
|
|
309
|
+
return vector(item_data['x'], item_data['y'], item_data['z'])
|
|
310
|
+
elif item_id == 'pn_el':
|
|
311
|
+
description = _some_or(item_data.get('description'), '')
|
|
312
|
+
note = _some_or(item_data.get('note'), '')
|
|
313
|
+
param_type = ParameterType(PARAMETER_TYPE_LOOKUP.index(item_data['type']))
|
|
314
|
+
if item_data['optional']:
|
|
315
|
+
param = parameter(item_data['name'], param_type, item_data['plural'], True, description, note, item_from_dict(item_data['default_value']))
|
|
316
|
+
else:
|
|
317
|
+
param = parameter(item_data['name'], param_type, item_data['plural'], False, description, note)
|
|
318
|
+
return param
|
|
319
|
+
elif item_id == 'bl_tag':
|
|
320
|
+
return
|
|
321
|
+
else:
|
|
322
|
+
raise PyreException(f'Unrecognized item id `{item_id}`')
|
dfpyre/pyre.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
A package for externally creating code templates for the DiamondFire Minecraft server.
|
|
3
3
|
|
|
4
4
|
By Amp
|
|
5
|
-
2/24/2024
|
|
6
5
|
"""
|
|
7
6
|
|
|
8
7
|
import base64
|
|
@@ -13,8 +12,10 @@ from difflib import get_close_matches
|
|
|
13
12
|
import datetime
|
|
14
13
|
from typing import Tuple, List, Dict
|
|
15
14
|
from enum import Enum
|
|
15
|
+
import socket
|
|
16
16
|
from mcitemlib.itemlib import Item as NbtItem
|
|
17
17
|
from dfpyre.items import *
|
|
18
|
+
from dfpyre.scriptgen import generate_script, GeneratorFlags
|
|
18
19
|
|
|
19
20
|
COL_WARN = '\x1b[33m'
|
|
20
21
|
COL_RESET = '\x1b[0m'
|
|
@@ -25,6 +26,7 @@ CODEBLOCK_DATA_PATH = os.path.join(os.path.dirname(__file__), 'data/data.json')
|
|
|
25
26
|
|
|
26
27
|
VARIABLE_TYPES = {'txt', 'comp', 'num', 'item', 'loc', 'var', 'snd', 'part', 'pot', 'g_val', 'vec', 'pn_el'}
|
|
27
28
|
TEMPLATE_STARTERS = {'event', 'entity_event', 'func', 'process'}
|
|
29
|
+
SINGLE_NAME_CODEBLOCKS = {'func', 'process', 'call_func', 'start_process', 'else'}
|
|
28
30
|
|
|
29
31
|
TARGETS = ['Selection', 'Default', 'Killer', 'Damager', 'Shooter', 'Victim', 'AllPlayers', 'Projectile', 'AllEntities', 'AllMobs', 'LastEntity']
|
|
30
32
|
TARGET_CODEBLOCKS = {'player_action', 'entity_action', 'if_player', 'if_entity'}
|
|
@@ -60,6 +62,15 @@ class CodeBlock:
|
|
|
60
62
|
self.args = args
|
|
61
63
|
self.target = target
|
|
62
64
|
self.data = data
|
|
65
|
+
|
|
66
|
+
def __repr__(self) -> str:
|
|
67
|
+
if self.name in SINGLE_NAME_CODEBLOCKS:
|
|
68
|
+
if self.name == 'else':
|
|
69
|
+
return 'CodeBlock(else)'
|
|
70
|
+
return f'CodeBlock({self.name}, {self.data["data"]})'
|
|
71
|
+
elif 'block' in self.data:
|
|
72
|
+
return f'CodeBlock({self.data["block"]}, {self.name})'
|
|
73
|
+
return f'CodeBlock(bracket, {self.data["type"]}, {self.data["direct"]})'
|
|
63
74
|
|
|
64
75
|
|
|
65
76
|
def _warn(message):
|
|
@@ -108,7 +119,7 @@ def _convert_data_types(args):
|
|
|
108
119
|
if type(value) in {int, float}:
|
|
109
120
|
converted_args.append(num(value))
|
|
110
121
|
elif type(value) is str:
|
|
111
|
-
if value[0] == VAR_SHORTHAND_CHAR and value[1] in VAR_SCOPES:
|
|
122
|
+
if len(value) > 2 and value[0] == VAR_SHORTHAND_CHAR and value[1] in VAR_SCOPES:
|
|
112
123
|
var_object = var(value[2:], VAR_SCOPES[value[1]])
|
|
113
124
|
converted_args.append(var_object)
|
|
114
125
|
else:
|
|
@@ -157,12 +168,12 @@ def _build_block(codeblock: CodeBlock, include_tags: bool):
|
|
|
157
168
|
"""
|
|
158
169
|
Builds a properly formatted block from a CodeBlock object.
|
|
159
170
|
"""
|
|
160
|
-
|
|
171
|
+
built_block = codeblock.data.copy()
|
|
161
172
|
codeblock_type = codeblock.data.get('block')
|
|
162
173
|
|
|
163
174
|
# add target if necessary ('Selection' is the default when 'target' is blank)
|
|
164
175
|
if codeblock_type in TARGET_CODEBLOCKS and codeblock.target != DEFAULT_TARGET:
|
|
165
|
-
|
|
176
|
+
built_block['target'] = codeblock.target.get_string_value()
|
|
166
177
|
|
|
167
178
|
# add items into args
|
|
168
179
|
final_args = [arg.format(slot) for slot, arg in enumerate(codeblock.args) if arg.type in VARIABLE_TYPES]
|
|
@@ -177,16 +188,20 @@ def _build_block(codeblock: CodeBlock, include_tags: bool):
|
|
|
177
188
|
final_args = final_args[:(27-len(tags))] # trim list if over 27 elements
|
|
178
189
|
final_args.extend(tags) # add tags to end
|
|
179
190
|
|
|
180
|
-
|
|
181
|
-
return
|
|
191
|
+
built_block['args'] = {'items': final_args}
|
|
192
|
+
return built_block
|
|
182
193
|
|
|
183
194
|
|
|
184
|
-
def _df_encode(
|
|
195
|
+
def _df_encode(json_string: str) -> str:
|
|
185
196
|
"""
|
|
186
197
|
Encodes a stringified json.
|
|
187
198
|
"""
|
|
188
|
-
|
|
189
|
-
return base64.b64encode(
|
|
199
|
+
encoded_string = gzip.compress(json_string.encode('utf-8'))
|
|
200
|
+
return base64.b64encode(encoded_string).decode('utf-8')
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def _df_decode(encoded_string: str) -> str:
|
|
204
|
+
return gzip.decompress(base64.b64decode(encoded_string)).decode('utf-8')
|
|
190
205
|
|
|
191
206
|
|
|
192
207
|
def _get_template_item(template_code: str, name: str, author: str) -> NbtItem:
|
|
@@ -211,15 +226,58 @@ def _get_template_item(template_code: str, name: str, author: str) -> NbtItem:
|
|
|
211
226
|
return template_item
|
|
212
227
|
|
|
213
228
|
|
|
229
|
+
# TODO:
|
|
230
|
+
# - add inserting codeblocks at any index
|
|
214
231
|
class DFTemplate:
|
|
215
232
|
"""
|
|
216
233
|
Represents a DiamondFire code template.
|
|
217
234
|
"""
|
|
218
235
|
def __init__(self, name: str=None, author: str='pyre'):
|
|
219
236
|
self.codeblocks: List[CodeBlock] = []
|
|
220
|
-
self.
|
|
237
|
+
self.bracket_stack: list[str] = []
|
|
221
238
|
self.name = name
|
|
222
239
|
self.author = author
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def __repr__(self) -> str:
|
|
243
|
+
return f'DFTemplate(name: {self.name}, author: {self.author}, codeblocks: {len(self.codeblocks)})'
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
@staticmethod
|
|
247
|
+
def from_code(template_code: str):
|
|
248
|
+
"""
|
|
249
|
+
Create a template object from an existing template code.
|
|
250
|
+
"""
|
|
251
|
+
template_dict = json.loads(_df_decode(template_code))
|
|
252
|
+
template = DFTemplate()
|
|
253
|
+
for block_dict in template_dict['blocks']:
|
|
254
|
+
if 'args' in block_dict:
|
|
255
|
+
args = []
|
|
256
|
+
for item_dict in block_dict['args']['items']:
|
|
257
|
+
parsed_item = item_from_dict(item_dict['item'])
|
|
258
|
+
if parsed_item is not None:
|
|
259
|
+
args.append(parsed_item)
|
|
260
|
+
target = Target(TARGETS.index(block_dict['target'])) if 'target' in block_dict else DEFAULT_TARGET
|
|
261
|
+
|
|
262
|
+
codeblock_name = 'bracket'
|
|
263
|
+
if 'block' in block_dict and block_dict['block'] in SINGLE_NAME_CODEBLOCKS:
|
|
264
|
+
codeblock_name = block_dict['block']
|
|
265
|
+
elif 'action' in block_dict:
|
|
266
|
+
codeblock_name = block_dict['action']
|
|
267
|
+
codeblock = CodeBlock(codeblock_name, args, target, block_dict)
|
|
268
|
+
template.codeblocks.append(codeblock)
|
|
269
|
+
|
|
270
|
+
return template
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@staticmethod
|
|
274
|
+
def receive_from_recode():
|
|
275
|
+
print('Waiting for item to be sent...')
|
|
276
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
277
|
+
s.connect(('localhost', 31372))
|
|
278
|
+
received = s.recv(8192)
|
|
279
|
+
print(received)
|
|
280
|
+
s.close()
|
|
223
281
|
|
|
224
282
|
|
|
225
283
|
def _set_template_name(self, first_block):
|
|
@@ -237,7 +295,7 @@ class DFTemplate:
|
|
|
237
295
|
"""
|
|
238
296
|
Build this template.
|
|
239
297
|
|
|
240
|
-
:param bool
|
|
298
|
+
:param bool include_tags: If True, include item tags in code blocks. Otherwise omit them.
|
|
241
299
|
:return: String containing encoded template data.
|
|
242
300
|
"""
|
|
243
301
|
template_dict_blocks = [_build_block(codeblock, include_tags) for codeblock in self.codeblocks]
|
|
@@ -262,7 +320,7 @@ class DFTemplate:
|
|
|
262
320
|
"""
|
|
263
321
|
templateCode = self.build(includeTags)
|
|
264
322
|
templateItem = _get_template_item(templateCode, self.name, self.author)
|
|
265
|
-
return templateItem.send_to_minecraft(method)
|
|
323
|
+
return templateItem.send_to_minecraft(method, 'pyre')
|
|
266
324
|
|
|
267
325
|
|
|
268
326
|
def clear(self):
|
|
@@ -273,9 +331,9 @@ class DFTemplate:
|
|
|
273
331
|
|
|
274
332
|
|
|
275
333
|
def _openbracket(self, btype: Literal['norm', 'repeat']='norm'):
|
|
276
|
-
bracket = CodeBlock('
|
|
334
|
+
bracket = CodeBlock('bracket', data={'id': 'bracket', 'direct': 'open', 'type': btype})
|
|
277
335
|
self.codeblocks.append(bracket)
|
|
278
|
-
self.
|
|
336
|
+
self.bracket_stack.append(btype)
|
|
279
337
|
|
|
280
338
|
|
|
281
339
|
# command methods
|
|
@@ -291,12 +349,13 @@ class DFTemplate:
|
|
|
291
349
|
|
|
292
350
|
def function(self, name: str, *args):
|
|
293
351
|
args = _convert_data_types(args)
|
|
294
|
-
cmd = CodeBlock('
|
|
352
|
+
cmd = CodeBlock('func', args, data={'id': 'block', 'block': 'func', 'data': name})
|
|
295
353
|
self.codeblocks.append(cmd)
|
|
296
354
|
|
|
297
355
|
|
|
298
|
-
def process(self, name: str):
|
|
299
|
-
|
|
356
|
+
def process(self, name: str, *args):
|
|
357
|
+
args = _convert_data_types(args)
|
|
358
|
+
cmd = CodeBlock('process', args, data={'id': 'block', 'block': 'process', 'data': name})
|
|
300
359
|
self.codeblocks.append(cmd)
|
|
301
360
|
|
|
302
361
|
|
|
@@ -383,7 +442,7 @@ class DFTemplate:
|
|
|
383
442
|
|
|
384
443
|
def bracket(self, *args):
|
|
385
444
|
args = _convert_data_types(args)
|
|
386
|
-
cmd = CodeBlock('
|
|
445
|
+
cmd = CodeBlock('bracket', data={'id': 'bracket', 'direct': 'close', 'type': self.bracket_stack.pop()})
|
|
387
446
|
self.codeblocks.append(cmd)
|
|
388
447
|
|
|
389
448
|
|
|
@@ -402,4 +461,19 @@ class DFTemplate:
|
|
|
402
461
|
def set_variable(self, name: str, *args):
|
|
403
462
|
args = _convert_data_types(args)
|
|
404
463
|
cmd = CodeBlock(name, args, data={'id': 'block', 'block': 'set_var', 'action': name})
|
|
405
|
-
self.codeblocks.append(cmd)
|
|
464
|
+
self.codeblocks.append(cmd)
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def generate_script(self, output_path: str, indent_size: int=4, literal_shorthand: bool=True, var_shorthand: bool=False):
|
|
468
|
+
"""
|
|
469
|
+
Generate an equivalent python script for this template.
|
|
470
|
+
|
|
471
|
+
:param str output_path: The file path to write the script to.
|
|
472
|
+
:param int indent_size: The multiple of spaces to add when indenting lines.
|
|
473
|
+
:param bool literal_shorthand: If True, `text` and `num` items will be written as strings and ints respectively.
|
|
474
|
+
:param bool var_shorthand: If True, all variables will be written using variable shorthand.
|
|
475
|
+
"""
|
|
476
|
+
flags = GeneratorFlags(indent_size, literal_shorthand, var_shorthand)
|
|
477
|
+
with open(output_path, 'w') as f:
|
|
478
|
+
f.write(generate_script(self, flags))
|
|
479
|
+
|
dfpyre/scriptgen.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import re
|
|
3
|
+
from dfpyre.items import *
|
|
4
|
+
|
|
5
|
+
SCRIPT_START = '''from dfpyre import *
|
|
6
|
+
t = DFTemplate()
|
|
7
|
+
'''
|
|
8
|
+
|
|
9
|
+
TEMPLATE_METHOD_LOOKUP = {
|
|
10
|
+
'event': 'player_event',
|
|
11
|
+
'entity_event': 'entity_event',
|
|
12
|
+
'func': 'function',
|
|
13
|
+
'process': 'process',
|
|
14
|
+
'call_func': 'call_function',
|
|
15
|
+
'start_process': 'start_process',
|
|
16
|
+
'player_action': 'player_action',
|
|
17
|
+
'game_action': 'game_action',
|
|
18
|
+
'entity_action': 'entity_action',
|
|
19
|
+
'if_player': 'if_player',
|
|
20
|
+
'if_var': 'if_variable',
|
|
21
|
+
'if_game': 'if_game',
|
|
22
|
+
'if_entity': 'if_entity',
|
|
23
|
+
'else': 'else_',
|
|
24
|
+
'repeat': 'repeat',
|
|
25
|
+
'control': 'control',
|
|
26
|
+
'select_obj': 'select_object',
|
|
27
|
+
'set_var': 'set_variable'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
TARGET_CODEBLOCKS = {'player_action', 'entity_action', 'if_player', 'if_entity'}
|
|
31
|
+
SINGLE_NAME_CODEBLOCKS = {'func', 'process', 'call_func', 'start_process'}
|
|
32
|
+
VAR_SCOPES = {'unsaved': 'g', 'saved': 's', 'local': 'l', 'line': 'i'}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclasses.dataclass
|
|
36
|
+
class GeneratorFlags:
|
|
37
|
+
indent_size: int
|
|
38
|
+
literal_shorthand: bool
|
|
39
|
+
var_shorthand: bool
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def argument_item_to_string(flags: GeneratorFlags, arg_item: object) -> str:
|
|
43
|
+
class_name = arg_item.__class__.__name__
|
|
44
|
+
if isinstance(arg_item, item):
|
|
45
|
+
return f'{class_name}.from_nbt("""{arg_item.get_nbt()}""")'
|
|
46
|
+
|
|
47
|
+
if isinstance(arg_item, string):
|
|
48
|
+
return f'{class_name}("{arg_item.value}")'
|
|
49
|
+
|
|
50
|
+
if isinstance(arg_item, text):
|
|
51
|
+
if flags.literal_shorthand:
|
|
52
|
+
return f'"{arg_item.value}"'
|
|
53
|
+
return f'{class_name}("{arg_item.value}")'
|
|
54
|
+
|
|
55
|
+
if isinstance(arg_item, num):
|
|
56
|
+
if not re.match(NUMBER_REGEX, str(arg_item.value)):
|
|
57
|
+
return f'{class_name}("{arg_item.value}")'
|
|
58
|
+
if flags.literal_shorthand:
|
|
59
|
+
return str(arg_item.value)
|
|
60
|
+
return f'{class_name}({arg_item.value})'
|
|
61
|
+
|
|
62
|
+
if isinstance(arg_item, loc):
|
|
63
|
+
loc_components = [arg_item.x, arg_item.y, arg_item.z]
|
|
64
|
+
if arg_item.pitch != 0:
|
|
65
|
+
loc_components.append(arg_item.pitch)
|
|
66
|
+
if arg_item.yaw != 0:
|
|
67
|
+
loc_components.append(arg_item.yaw)
|
|
68
|
+
return f'{class_name}({", ".join(str(c) for c in loc_components)})'
|
|
69
|
+
|
|
70
|
+
if isinstance(arg_item, var):
|
|
71
|
+
if flags.var_shorthand:
|
|
72
|
+
return f'"${VAR_SCOPES[arg_item.scope]}{arg_item.name}"'
|
|
73
|
+
if arg_item.scope == 'unsaved':
|
|
74
|
+
return f'{class_name}("{arg_item.name}")'
|
|
75
|
+
return f'{class_name}("{arg_item.name}", "{arg_item.scope}")'
|
|
76
|
+
|
|
77
|
+
if isinstance(arg_item, sound):
|
|
78
|
+
return f'{class_name}("{arg_item.name}", {arg_item.pitch}, {arg_item.vol})'
|
|
79
|
+
|
|
80
|
+
if isinstance(arg_item, particle):
|
|
81
|
+
return f'{class_name}({arg_item.particle_data})'
|
|
82
|
+
|
|
83
|
+
if isinstance(arg_item, potion):
|
|
84
|
+
return f'{class_name}("{arg_item.name}", {arg_item.dur}, {arg_item.amp})'
|
|
85
|
+
|
|
86
|
+
if isinstance(arg_item, gamevalue):
|
|
87
|
+
return f'{class_name}("{arg_item.name}", "{arg_item.target}")'
|
|
88
|
+
|
|
89
|
+
if isinstance(arg_item, parameter):
|
|
90
|
+
param_type_class_name = arg_item.param_type.__class__.__name__
|
|
91
|
+
param_args = [f'"{arg_item.name}"', f'{param_type_class_name}.{arg_item.param_type.name}']
|
|
92
|
+
if arg_item.plural:
|
|
93
|
+
param_args.append('plural=True')
|
|
94
|
+
if arg_item.optional:
|
|
95
|
+
param_args.append('optional=True')
|
|
96
|
+
if arg_item.default_value is not None:
|
|
97
|
+
param_args.append(f'default_value={argument_item_to_string(arg_item.default_value)}')
|
|
98
|
+
if arg_item.description:
|
|
99
|
+
param_args.append(f'description="{arg_item.description}"')
|
|
100
|
+
if arg_item.note:
|
|
101
|
+
param_args.append(f'note="{arg_item.note}"')
|
|
102
|
+
return f'{class_name}({", ".join(param_args)})'
|
|
103
|
+
|
|
104
|
+
if isinstance(arg_item, vector):
|
|
105
|
+
return f'{class_name}({arg_item.x}, {arg_item.y}, {arg_item.z})'
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def add_script_line(flags: GeneratorFlags, script_lines: list[str], indent_level: int, line: str, add_comma: bool=True):
|
|
109
|
+
added_line = ' '*flags.indent_size*indent_level + line
|
|
110
|
+
if add_comma and indent_level > 0:
|
|
111
|
+
added_line += ','
|
|
112
|
+
script_lines.append(added_line)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def generate_script(template, flags: GeneratorFlags) -> str:
|
|
116
|
+
indent_level = 0
|
|
117
|
+
script_lines = []
|
|
118
|
+
for codeblock in template.codeblocks:
|
|
119
|
+
if codeblock.name == 'bracket':
|
|
120
|
+
if codeblock.data['direct'] == 'open':
|
|
121
|
+
add_script_line(flags, script_lines, indent_level, 't.bracket(', False)
|
|
122
|
+
indent_level += 1
|
|
123
|
+
elif codeblock.data['direct'] == 'close':
|
|
124
|
+
indent_level -= 1
|
|
125
|
+
add_script_line(flags, script_lines, indent_level, ')')
|
|
126
|
+
continue
|
|
127
|
+
if codeblock.name == 'else':
|
|
128
|
+
add_script_line(flags, script_lines, indent_level, 't.else_()')
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
method_name = TEMPLATE_METHOD_LOOKUP[codeblock.data['block']]
|
|
132
|
+
method_args = [f'"{codeblock.name}"']
|
|
133
|
+
if codeblock.name in SINGLE_NAME_CODEBLOCKS:
|
|
134
|
+
method_args[0] = f'"{codeblock.data["data"]}"'
|
|
135
|
+
|
|
136
|
+
codeblock_args = [argument_item_to_string(flags, i) for i in codeblock.args]
|
|
137
|
+
if codeblock_args:
|
|
138
|
+
method_args.extend(codeblock_args)
|
|
139
|
+
if method_name in TARGET_CODEBLOCKS:
|
|
140
|
+
method_args.append(f'target=Target.{codeblock.target.name}')
|
|
141
|
+
|
|
142
|
+
line = f't.{method_name}({", ".join(method_args)})'
|
|
143
|
+
add_script_line(flags, script_lines, indent_level, line)
|
|
144
|
+
return SCRIPT_START + '\n'.join(script_lines)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dfpyre
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: A package for external creation of code templates for the DiamondFire Minecraft server.
|
|
5
5
|
Home-page: https://github.com/Amp63/pyre
|
|
6
6
|
License: MIT
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Requires-Dist: mcitemlib (>=0.
|
|
15
|
+
Requires-Dist: mcitemlib (>=0.2.4,<0.3.0)
|
|
16
16
|
Project-URL: Repository, https://github.com/Amp63/pyre
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
|
|
@@ -70,6 +70,8 @@ pip install dfpyre
|
|
|
70
70
|
|
|
71
71
|
## Extras
|
|
72
72
|
|
|
73
|
+
- [Importing from Code](#importing-from-code)
|
|
74
|
+
- [Script Generation](#script-generation)
|
|
73
75
|
- [Method List](#method-list)
|
|
74
76
|
|
|
75
77
|
___
|
|
@@ -279,7 +281,7 @@ t.player_action('PlaySound', sound('Grass Place'))
|
|
|
279
281
|
Represents a diamondfire particle item:
|
|
280
282
|
|
|
281
283
|
```py
|
|
282
|
-
particle(
|
|
284
|
+
particle({'particle':'Cloud','cluster':{'amount':1,'horizontal':0.0,'vertical':0.0},'data':{'x':1.0,'y':0.0,'z':0.0,'motionVariation':100}})
|
|
283
285
|
```
|
|
284
286
|
|
|
285
287
|
Example:
|
|
@@ -289,7 +291,8 @@ Example:
|
|
|
289
291
|
from dfpyre import *
|
|
290
292
|
t = DFTemplate()
|
|
291
293
|
t.player_event('Join')
|
|
292
|
-
|
|
294
|
+
part = particle({'particle':'Cloud','cluster':{'amount':1,'horizontal':0.0,'vertical':0.0},'data':{'x':1.0,'y':0.0,'z':0.0,'motionVariation':100}})
|
|
295
|
+
t.player_action('Particle', part, loc(5, 50, 5))
|
|
293
296
|
```
|
|
294
297
|
|
|
295
298
|
Currently, the particle object does not support colors.
|
|
@@ -441,6 +444,31 @@ t = DFTemplate()
|
|
|
441
444
|
t.player_event('Join')
|
|
442
445
|
t.call_function('doStuff')
|
|
443
446
|
```
|
|
447
|
+
|
|
448
|
+
### Importing from Code
|
|
449
|
+
|
|
450
|
+
You can import existing templates from their built code using the `from_code` method:
|
|
451
|
+
|
|
452
|
+
```py
|
|
453
|
+
from dfpyre import *
|
|
454
|
+
template_code = 'H4sIAGVyIGYC/3WOMQ7CMAxFz4LnDsw5AhITI6qQSaw2IrGrxkJCVe5eh3boAJP9n/Kfs8AziX8VcPcFYgC3Zej26YDexGoZvUZhAxeJ3PI8WMtKSrnV+1q7P4op4Yfmx244qG7E4Uql4EA/jNv2Jc3qJU/2KqBiY4yZjI6UkpzAjkNJouDO1X7S1xUDaGUl2QAAAA=='
|
|
455
|
+
|
|
456
|
+
t = DFTemplate.from_code(template_code)
|
|
457
|
+
# add onto the template from here
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
### Script Generation
|
|
462
|
+
|
|
463
|
+
You can also generate an equivalent python script for a template from a template object:
|
|
464
|
+
|
|
465
|
+
```py
|
|
466
|
+
from dfpyre import *
|
|
467
|
+
template_code = 'H4sIAGVyIGYC/3WOMQ7CMAxFz4LnDsw5AhITI6qQSaw2IrGrxkJCVe5eh3boAJP9n/Kfs8AziX8VcPcFYgC3Zej26YDexGoZvUZhAxeJ3PI8WMtKSrnV+1q7P4op4Yfmx244qG7E4Uql4EA/jNv2Jc3qJU/2KqBiY4yZjI6UkpzAjkNJouDO1X7S1xUDaGUl2QAAAA=='
|
|
468
|
+
|
|
469
|
+
t = DFTemplate.from_code(template_code)
|
|
470
|
+
t.generate_script('my_template.py') # generated python script will be written to my_template.py
|
|
471
|
+
```
|
|
444
472
|
|
|
445
473
|
### Method List
|
|
446
474
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
dfpyre/__init__.py,sha256=apPsSxJ1Tztfl71MoORoSmDfX7LyKLYlLwOGeLQUitw,25
|
|
2
|
+
dfpyre/data/data.json,sha256=M4EHXKkh7Cx7y3BQ6c3csvmNmSqP2oE4txLI9MZcDDA,30347
|
|
3
|
+
dfpyre/items.py,sha256=t9KsvhPOEe36_E7CNdgxNmEKtOF6nMvNZURyYFiXJb4,9215
|
|
4
|
+
dfpyre/pyre.py,sha256=wn75bzj4dteAMtOELuV7Q0Xe46FBcFbdzHlcc7yRnU4,16970
|
|
5
|
+
dfpyre/scriptgen.py,sha256=OS9VfFSTjIaxa28FqMxfIQ0bdfIJsI0ZqJo3UhHTYJ4,5450
|
|
6
|
+
dfpyre/style.py,sha256=mLW1CFvvi8_9fk8JaH10I5S4WI0YBdQIXHtI3G_4sR8,980
|
|
7
|
+
dfpyre-0.6.0.dist-info/LICENSE,sha256=_vuDskB0ja2c-Fgm7Gt8Q8cO9NsLNpZAVyvmZwX7E6o,1060
|
|
8
|
+
dfpyre-0.6.0.dist-info/METADATA,sha256=c0t4TVbXxz_KB-kYtz7MjJP_4kqIU463b156zMJJKD8,11344
|
|
9
|
+
dfpyre-0.6.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
10
|
+
dfpyre-0.6.0.dist-info/RECORD,,
|
dfpyre-0.5.0.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
dfpyre/__init__.py,sha256=apPsSxJ1Tztfl71MoORoSmDfX7LyKLYlLwOGeLQUitw,25
|
|
2
|
-
dfpyre/data/data.json,sha256=M4EHXKkh7Cx7y3BQ6c3csvmNmSqP2oE4txLI9MZcDDA,30347
|
|
3
|
-
dfpyre/items.py,sha256=L2e9b9BZQrI7AIBw46puENReDQRlWgHnw7T9NBG1Vcs,7688
|
|
4
|
-
dfpyre/pyre.py,sha256=5UryjtwsNRxl6mGknsKm8iM2DP49-B-tqwkr9LdoRJ8,13805
|
|
5
|
-
dfpyre/style.py,sha256=mLW1CFvvi8_9fk8JaH10I5S4WI0YBdQIXHtI3G_4sR8,980
|
|
6
|
-
dfpyre-0.5.0.dist-info/LICENSE,sha256=atkly29RNUY2evLoPyurzCJeQnhP-VCAD-JZEbq3mno,1060
|
|
7
|
-
dfpyre-0.5.0.dist-info/METADATA,sha256=RpuPps-V4FruPh1p0L7wroEDwZfC5lP6ITgl14334Cs,10142
|
|
8
|
-
dfpyre-0.5.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
9
|
-
dfpyre-0.5.0.dist-info/RECORD,,
|
|
File without changes
|