minecraft-datapack-language 15.1.63__py3-none-any.whl → 15.1.65__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.
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '15.1.63'
32
- __version_tuple__ = version_tuple = (15, 1, 63)
31
+ __version__ = version = '15.1.65'
32
+ __version_tuple__ = version_tuple = (15, 1, 65)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -193,6 +193,9 @@ def _generate_load_function(scoreboard_commands: List[str], output_dir: Path, na
193
193
  """Generate the load function with scoreboard setup."""
194
194
  load_content = []
195
195
 
196
+ # Add armor stand setup for server-side operations
197
+ load_content.append("execute unless entity @e[type=armor_stand,tag=mdl_server,limit=1] run summon armor_stand ~ 320 ~ {Tags:[\"mdl_server\"],Invisible:1b,Marker:1b,NoGravity:1b,Invulnerable:1b}")
198
+
196
199
  # Add scoreboard objectives
197
200
  load_content.extend(scoreboard_commands)
198
201
 
@@ -213,15 +216,20 @@ def _process_say_command_with_variables(content: str, selector: str) -> str:
213
216
  """Process say command content with variable substitution, converting to tellraw with score components."""
214
217
  import re
215
218
 
219
+ # Clean up the content - remove quotes if present
220
+ content = content.strip()
221
+ if content.startswith('"') and content.endswith('"'):
222
+ content = content[1:-1] # Remove surrounding quotes
223
+
216
224
  # Find all variable references like $variable$ or $variable<selector>$
217
225
  var_pattern = r'\$([^$]+)\$'
218
226
  matches = re.findall(var_pattern, content)
219
227
 
220
228
  if not matches:
221
229
  # No variables, return simple tellraw
222
- return f'tellraw @a [{{"text":{content}}}]'
230
+ return f'tellraw @a [{{"text":"{content}"}}]'
223
231
 
224
- # Split content by variable references
232
+ # Split content by variable references while preserving the structure
225
233
  parts = re.split(var_pattern, content)
226
234
 
227
235
  # Build tellraw components
@@ -244,8 +252,8 @@ def _process_say_command_with_variables(content: str, selector: str) -> str:
244
252
  var_selector = var_parts[1][:-1] # Remove trailing >
245
253
  components.append(f'{{"score":{{"name":"{var_selector}","objective":"{base_var}"}}}}')
246
254
  else:
247
- # Simple variable: $variable$
248
- components.append(f'{{"score":{{"name":"{selector}","objective":"{var_name}"}}}}')
255
+ # Simple variable: $variable$ - use server armor stand
256
+ components.append(f'{{"score":{{"name":"@e[type=armor_stand,tag=mdl_server,limit=1]","objective":"{var_name}"}}}}')
249
257
 
250
258
  var_index += 1
251
259
 
@@ -274,6 +282,10 @@ def _process_statement(statement: Any, namespace: str, function_name: str, state
274
282
  # Convert to Minecraft tellraw format
275
283
  processed_command = _process_say_command_with_variables(content, selector)
276
284
  commands.append(processed_command)
285
+ elif command.startswith('tellraw @a '):
286
+ # Fix extra space in tellraw commands
287
+ fixed_command = command.replace('tellraw @ a ', 'tellraw @a ')
288
+ commands.append(fixed_command)
277
289
  else:
278
290
  # Process other commands normally
279
291
  processed_command = _process_variable_substitutions(command, selector)
@@ -285,26 +297,50 @@ def _process_statement(statement: Any, namespace: str, function_name: str, state
285
297
 
286
298
  # Handle different value types
287
299
  if isinstance(value, int):
288
- commands.append(f"scoreboard players set {var_name} {selector} {value}")
300
+ commands.append(f"scoreboard players set {selector} {var_name} {value}")
289
301
  elif isinstance(value, str) and value.startswith('$') and value.endswith('$'):
290
302
  # Variable reference
291
303
  ref_var = value[1:-1] # Remove $ symbols
292
- commands.append(f"scoreboard players operation {var_name} {selector} = {ref_var} {selector}")
304
+ commands.append(f"scoreboard players operation {selector} {var_name} = {selector} {ref_var}")
293
305
  elif hasattr(value, '__class__') and 'BinaryExpression' in str(value.__class__):
294
306
  # Handle complex expressions (BinaryExpression, etc.)
295
- # For now, add a placeholder command
296
- commands.append(f"# Complex assignment: {var_name} = {value}")
307
+ # Convert to proper Minecraft scoreboard commands
308
+ if hasattr(value, 'left') and hasattr(value, 'right') and hasattr(value, 'operator'):
309
+ left = value.left
310
+ right = value.right
311
+ operator = value.operator
312
+
313
+ # Handle different operators
314
+ if operator == 'PLUS':
315
+ if hasattr(left, 'name') and hasattr(right, 'value'):
316
+ # counter = counter + 1
317
+ commands.append(f"scoreboard players add {selector} {var_name} {right.value}")
318
+ else:
319
+ # Complex case - use operation
320
+ commands.append(f"# Complex addition: {var_name} = {left} + {right}")
321
+ elif operator == 'MINUS':
322
+ if hasattr(left, 'name') and hasattr(right, 'value'):
323
+ # health = health - 10
324
+ commands.append(f"scoreboard players remove {selector} {var_name} {right.value}")
325
+ else:
326
+ # Complex case - use operation
327
+ commands.append(f"# Complex subtraction: {var_name} = {left} - {right}")
328
+ else:
329
+ # Other operators - use operation
330
+ commands.append(f"# Complex operation: {var_name} = {left} {operator} {right}")
331
+ else:
332
+ commands.append(f"# Complex assignment: {var_name} = {value}")
297
333
  else:
298
334
  # Handle LiteralExpression and other value types
299
335
  try:
300
336
  if hasattr(value, 'value'):
301
337
  # LiteralExpression case
302
338
  num_value = int(value.value)
303
- commands.append(f"scoreboard players set {var_name} {selector} {num_value}")
339
+ commands.append(f"scoreboard players set {selector} {var_name} {num_value}")
304
340
  else:
305
341
  # Direct value case
306
342
  num_value = int(value)
307
- commands.append(f"scoreboard players set {var_name} {selector} {num_value}")
343
+ commands.append(f"scoreboard players set {selector} {var_name} {num_value}")
308
344
  except (ValueError, TypeError):
309
345
  # If we can't convert to int, add a placeholder
310
346
  commands.append(f"# Assignment: {var_name} = {value}")
@@ -328,7 +364,11 @@ def _process_statement(statement: Any, namespace: str, function_name: str, state
328
364
 
329
365
  # Write conditional function
330
366
  if if_commands:
331
- if_dir = Path(f"data/{namespace}/function")
367
+ # Use the output directory from build context
368
+ if hasattr(build_context, 'output_dir'):
369
+ if_dir = build_context.output_dir / "data" / namespace / "function"
370
+ else:
371
+ if_dir = Path(f"data/{namespace}/function")
332
372
  ensure_dir(str(if_dir))
333
373
  with open(if_dir / f"{if_func_name}.mcfunction", 'w', encoding='utf-8') as f:
334
374
  f.write('\n'.join(if_commands))
@@ -410,11 +450,17 @@ def _generate_function_file(ast: Dict[str, Any], output_dir: Path, namespace: st
410
450
 
411
451
  # Write function file
412
452
  if function_commands:
453
+ # Add armor stand setup to the beginning of each function
454
+ final_commands = []
455
+ final_commands.append("execute unless entity @e[type=armor_stand,tag=mdl_server,limit=1] run summon armor_stand ~ 320 ~ {Tags:[\"mdl_server\"],Invisible:1b,Marker:1b,NoGravity:1b,Invulnerable:1b}")
456
+ final_commands.append("")
457
+ final_commands.extend(function_commands)
458
+
413
459
  func_dir = output_dir / "data" / namespace / "function"
414
460
  ensure_dir(str(func_dir))
415
461
 
416
462
  with open(func_dir / f"{func_name}.mcfunction", 'w', encoding='utf-8') as f:
417
- f.write('\n'.join(function_commands))
463
+ f.write('\n'.join(final_commands))
418
464
 
419
465
  if verbose:
420
466
  print(f"Generated function: {namespace}:{func_name}")
@@ -442,6 +488,11 @@ def _generate_hook_files(ast: Dict[str, Any], output_dir: Path, namespace: str,
442
488
  if hook['hook_type'] == 'load':
443
489
  load_values.append(hook['function_name'])
444
490
 
491
+ # Add pack-specific load function if pack name is available
492
+ if 'pack' in ast and 'name' in ast['pack']:
493
+ pack_name = ast['pack']['name']
494
+ load_values.append(f"{pack_name}:load")
495
+
445
496
  load_tag_content = {
446
497
  "values": load_values
447
498
  }
@@ -540,7 +591,11 @@ def _process_while_loop_recursion(while_statement, namespace: str, function_name
540
591
 
541
592
  # Write loop body function
542
593
  if body_commands:
543
- func_dir = Path(f"data/{namespace}/function")
594
+ # Use the output directory from build context
595
+ if hasattr(build_context, 'output_dir'):
596
+ func_dir = build_context.output_dir / "data" / namespace / "function"
597
+ else:
598
+ func_dir = Path(f"data/{namespace}/function")
544
599
  ensure_dir(str(func_dir))
545
600
  with open(func_dir / f"{loop_body_func_name}.mcfunction", 'w', encoding='utf-8') as f:
546
601
  f.write('\n'.join(body_commands))
@@ -586,7 +641,11 @@ def _process_while_loop_schedule(while_statement, namespace: str, function_name:
586
641
 
587
642
  # Write loop body function
588
643
  if body_commands:
589
- func_dir = Path(f"data/{namespace}/function")
644
+ # Use the output directory from build context
645
+ if hasattr(build_context, 'output_dir'):
646
+ func_dir = build_context.output_dir / "data" / namespace / "function"
647
+ else:
648
+ func_dir = Path(f"data/{namespace}/function")
590
649
  ensure_dir(str(func_dir))
591
650
  with open(func_dir / f"{loop_body_func_name}.mcfunction", 'w', encoding='utf-8') as f:
592
651
  f.write('\n'.join(body_commands))
@@ -119,6 +119,24 @@ def _convert_condition_to_minecraft_syntax(condition: str, selector: str = "@s")
119
119
  # Remove extra whitespace and normalize
120
120
  condition = condition.strip()
121
121
 
122
+ # Handle variable substitution in conditions (e.g., "$value$ > 3")
123
+ import re
124
+ var_pattern = r'\$([^$]+)\$'
125
+
126
+ # Replace variable references with proper scoreboard syntax
127
+ def replace_var(match):
128
+ var_name = match.group(1)
129
+ # Remove scope selector if present
130
+ if '<' in var_name and var_name.endswith('>'):
131
+ var_parts = var_name.split('<', 1)
132
+ base_var = var_parts[0]
133
+ return f"@e[type=armor_stand,tag=mdl_server,limit=1] {base_var}"
134
+ else:
135
+ return f"@e[type=armor_stand,tag=mdl_server,limit=1] {var_name}"
136
+
137
+ # Apply variable substitution
138
+ condition = re.sub(var_pattern, replace_var)
139
+
122
140
  # Handle common patterns
123
141
  if '==' in condition:
124
142
  var1, var2 = condition.split('==', 1)
@@ -128,10 +146,10 @@ def _convert_condition_to_minecraft_syntax(condition: str, selector: str = "@s")
128
146
  # Check if var2 is a number
129
147
  try:
130
148
  value = int(var2)
131
- return f"score {var1} {selector} matches {value}"
149
+ return f"score {var1} matches {value}"
132
150
  except ValueError:
133
151
  # Both are variables, compare them
134
- return f"score {var1} {selector} = {var2} {selector}"
152
+ return f"score {var1} = {var2}"
135
153
 
136
154
  elif '!=' in condition:
137
155
  var1, var2 = condition.split('!=', 1)
@@ -140,9 +158,9 @@ def _convert_condition_to_minecraft_syntax(condition: str, selector: str = "@s")
140
158
 
141
159
  try:
142
160
  value = int(var2)
143
- return f"score {var1} {selector} matches ..{value-1} {value+1}.."
161
+ return f"score {var1} matches ..{value-1} {value+1}.."
144
162
  except ValueError:
145
- return f"score {var1} {selector} != {var2} {selector}"
163
+ return f"score {var1} != {var2}"
146
164
 
147
165
  elif '>' in condition:
148
166
  var1, var2 = condition.split('>', 1)
@@ -151,9 +169,9 @@ def _convert_condition_to_minecraft_syntax(condition: str, selector: str = "@s")
151
169
 
152
170
  try:
153
171
  value = int(var2)
154
- return f"score {var1} {selector} matches {value+1}.."
172
+ return f"score {var1} matches {value+1}.."
155
173
  except ValueError:
156
- return f"score {var1} {selector} > {var2} {selector}"
174
+ return f"score {var1} > {var2}"
157
175
 
158
176
  elif '<' in condition:
159
177
  var1, var2 = condition.split('<', 1)
@@ -162,9 +180,9 @@ def _convert_condition_to_minecraft_syntax(condition: str, selector: str = "@s")
162
180
 
163
181
  try:
164
182
  value = int(var2)
165
- return f"score {var1} {selector} matches ..{value-1}"
183
+ return f"score {var1} matches ..{value-1}"
166
184
  except ValueError:
167
- return f"score {var1} {selector} < {var2} {selector}"
185
+ return f"score {var1} < {var2}"
168
186
 
169
187
  elif '>=' in condition:
170
188
  var1, var2 = condition.split('>=', 1)
@@ -173,9 +191,9 @@ def _convert_condition_to_minecraft_syntax(condition: str, selector: str = "@s")
173
191
 
174
192
  try:
175
193
  value = int(var2)
176
- return f"score {var1} {selector} matches {value}.."
194
+ return f"score {var1} matches {value}.."
177
195
  except ValueError:
178
- return f"score {var1} {selector} >= {var2} {selector}"
196
+ return f"score {var1} >= {var2}"
179
197
 
180
198
  elif '<=' in condition:
181
199
  var1, var2 = condition.split('<=', 1)
@@ -184,12 +202,12 @@ def _convert_condition_to_minecraft_syntax(condition: str, selector: str = "@s")
184
202
 
185
203
  try:
186
204
  value = int(var2)
187
- return f"score {var1} {selector} matches ..{value}"
205
+ return f"score {var1} matches ..{value}"
188
206
  except ValueError:
189
- return f"score {var1} {selector} <= {var2} {selector}"
207
+ return f"score {var1} <= {var2}"
190
208
 
191
209
  # Default: treat as a variable that should be non-zero
192
- return f"score {condition} {selector} matches 1.."
210
+ return f"score {condition} matches 1.."
193
211
 
194
212
 
195
213
  def _find_mdl_files(directory: Path) -> List[Path]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: minecraft-datapack-language
3
- Version: 15.1.63
3
+ Version: 15.1.65
4
4
  Summary: Compile JavaScript-style MDL language or Python API into a Minecraft datapack (1.21+ ready). Features variables, control flow, error handling, and VS Code extension.
5
5
  Project-URL: Homepage, https://www.mcmdl.com
6
6
  Project-URL: Documentation, https://www.mcmdl.com/docs
@@ -1,12 +1,12 @@
1
1
  minecraft_datapack_language/__init__.py,sha256=i-qCchbe5b2Fshgc6yCU9mddOLs2UBt9SAcLqfUIrT0,606
2
- minecraft_datapack_language/_version.py,sha256=kT4vFfqTGE0yqzzOA5QjfjVNdwoR0e2Fdpe1CF8Ke6E,708
2
+ minecraft_datapack_language/_version.py,sha256=7XSJDjuzb6Ytmg80BCgGO_aHPtsA2iZo3CHgHS1KD24,708
3
3
  minecraft_datapack_language/ast_nodes.py,sha256=pgjI2Nlap3ixFPgWqGSkqncG9zB91h5BKgRjtcJqMew,2118
4
4
  minecraft_datapack_language/cli.py,sha256=p5A_tEEXugN2NhQFbbgfwi4FxbWYD91RWeKR_A3Vuec,6263
5
- minecraft_datapack_language/cli_build.py,sha256=_U8pYPpjcaaODb6wfyUUzdA1ki8MmF_6_MBdBxmrafY,36574
5
+ minecraft_datapack_language/cli_build.py,sha256=UwAGGnL7PyTnBZ9ArIrPcTx5-mysy_HGWA_f9-AjUak,39959
6
6
  minecraft_datapack_language/cli_check.py,sha256=bPq9gHsxQ1CIiftkrAtRCifWkVAyjp5c8Oay2NNQ1qs,6277
7
7
  minecraft_datapack_language/cli_help.py,sha256=jUTHUQBONAZKVTdQK9tNPXq4c_6xpsafNOvHDjkEldg,12243
8
8
  minecraft_datapack_language/cli_new.py,sha256=uaKH0VBC43XBt_Hztc35-BfC9bYlsDdLbAfe_42rrtI,8235
9
- minecraft_datapack_language/cli_utils.py,sha256=gLGe2nAn8pLiSJhn-DpNvMxo0th_Gj89I-oSeyPx4zU,9293
9
+ minecraft_datapack_language/cli_utils.py,sha256=OF64njFa_19qGJ-1EBMI8btMs8OUi-0wGoFAQo6525U,9775
10
10
  minecraft_datapack_language/dir_map.py,sha256=HmxFkuvWGkzHF8o_GFb4BpuMCRc6QMw8UbmcAI8JVdY,1788
11
11
  minecraft_datapack_language/expression_processor.py,sha256=GN6cuRNvgI8TrV6YnEHrA9P0X-ACTT7rCBh4WlOPjSI,20140
12
12
  minecraft_datapack_language/linter.py,sha256=7UqbygC5JPCGg-BSOq65NB2xEJBu_OUOYIIgmHItO2M,16567
@@ -16,9 +16,9 @@ minecraft_datapack_language/mdl_linter.py,sha256=z85xoAglENurCh30bR7kEHZ_JeMxcYa
16
16
  minecraft_datapack_language/mdl_parser_js.py,sha256=4VMWx6O7A10afTzjGnnwL_Sh52osIO84ObqHp8KoDZw,38677
17
17
  minecraft_datapack_language/pack.py,sha256=nYiXQ3jgJlDfc4m-65f7C2LFhDRioaUU_XVy6Na4SJI,34625
18
18
  minecraft_datapack_language/utils.py,sha256=Aq0HAGlXqj9BUTEjaEilpvzEW0EtZYYMMwOqG9db6dE,684
19
- minecraft_datapack_language-15.1.63.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
20
- minecraft_datapack_language-15.1.63.dist-info/METADATA,sha256=4V1-aPYtWcii4iq4tvsnPHLSIfzdJzku230oYucm_aY,35230
21
- minecraft_datapack_language-15.1.63.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- minecraft_datapack_language-15.1.63.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
23
- minecraft_datapack_language-15.1.63.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
24
- minecraft_datapack_language-15.1.63.dist-info/RECORD,,
19
+ minecraft_datapack_language-15.1.65.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
20
+ minecraft_datapack_language-15.1.65.dist-info/METADATA,sha256=r8kJIxQ6Z_eslXNyagKOtfz_Cq5vX_1f6U9Q33saoRw,35230
21
+ minecraft_datapack_language-15.1.65.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ minecraft_datapack_language-15.1.65.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
23
+ minecraft_datapack_language-15.1.65.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
24
+ minecraft_datapack_language-15.1.65.dist-info/RECORD,,