stewbeet 2.2.5__tar.gz → 2.2.7__tar.gz

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 stewbeet might be problematic. Click here for more details.

Files changed (242) hide show
  1. {stewbeet-2.2.5 → stewbeet-2.2.7}/PKG-INFO +1 -1
  2. {stewbeet-2.2.5 → stewbeet-2.2.7}/pyproject.toml +1 -1
  3. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/definitions_helper/completion.py +1 -3
  4. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/custom_paintings/__init__.py +16 -11
  5. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/custom_blocks/__init__.py +215 -16
  6. stewbeet-2.2.7/stewbeet/plugins/finalyze/custom_blocks_ticking/__init__.py +67 -0
  7. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/image_utils.py +1 -1
  8. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/resource_pack/item_models/object.py +93 -24
  9. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/verify_definitions/__init__.py +58 -3
  10. stewbeet-2.2.5/stewbeet/plugins/finalyze/custom_blocks_ticking/__init__.py +0 -92
  11. {stewbeet-2.2.5 → stewbeet-2.2.7}/.gitignore +0 -0
  12. {stewbeet-2.2.5 → stewbeet-2.2.7}/LICENSE +0 -0
  13. {stewbeet-2.2.5 → stewbeet-2.2.7}/README.md +0 -0
  14. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/__init__.py +0 -0
  15. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/__main__.py +0 -0
  16. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/all.py +0 -0
  17. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/cli.py +0 -0
  18. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/continuous_delivery/__init__.py +0 -0
  19. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/continuous_delivery/cd_utils.py +0 -0
  20. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/continuous_delivery/github.py +0 -0
  21. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/continuous_delivery/modrinth.py +0 -0
  22. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/continuous_delivery/pmc.py +0 -0
  23. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/continuous_delivery/smithed.py +0 -0
  24. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/__init__.py +0 -0
  25. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/balancing.py +0 -0
  26. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/batteries.py +0 -0
  27. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/cables.py +0 -0
  28. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant.json +0 -0
  29. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_d.json +0 -0
  30. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_de.json +0 -0
  31. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dew.json +0 -0
  32. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dn.json +0 -0
  33. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dne.json +0 -0
  34. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnew.json +0 -0
  35. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dns.json +0 -0
  36. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnse.json +0 -0
  37. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnsew.json +0 -0
  38. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnsw.json +0 -0
  39. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnw.json +0 -0
  40. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ds.json +0 -0
  41. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dse.json +0 -0
  42. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dsew.json +0 -0
  43. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dsw.json +0 -0
  44. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dw.json +0 -0
  45. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_e.json +0 -0
  46. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ew.json +0 -0
  47. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_n.json +0 -0
  48. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ne.json +0 -0
  49. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_new.json +0 -0
  50. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ns.json +0 -0
  51. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nse.json +0 -0
  52. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nsew.json +0 -0
  53. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nsw.json +0 -0
  54. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nw.json +0 -0
  55. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_s.json +0 -0
  56. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_se.json +0 -0
  57. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_sew.json +0 -0
  58. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_sw.json +0 -0
  59. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_u.json +0 -0
  60. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ud.json +0 -0
  61. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ude.json +0 -0
  62. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udew.json +0 -0
  63. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udn.json +0 -0
  64. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udne.json +0 -0
  65. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnew.json +0 -0
  66. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udns.json +0 -0
  67. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnse.json +0 -0
  68. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnsew.json +0 -0
  69. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnsw.json +0 -0
  70. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnw.json +0 -0
  71. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uds.json +0 -0
  72. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udse.json +0 -0
  73. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udsew.json +0 -0
  74. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udsw.json +0 -0
  75. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udw.json +0 -0
  76. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ue.json +0 -0
  77. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uew.json +0 -0
  78. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_un.json +0 -0
  79. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_une.json +0 -0
  80. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unew.json +0 -0
  81. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uns.json +0 -0
  82. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unse.json +0 -0
  83. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unsew.json +0 -0
  84. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unsw.json +0 -0
  85. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unw.json +0 -0
  86. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_us.json +0 -0
  87. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_use.json +0 -0
  88. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_usew.json +0 -0
  89. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_usw.json +0 -0
  90. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uw.json +0 -0
  91. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_cable_models/variant_w.json +0 -0
  92. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/energy_lib_calls.py +0 -0
  93. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/gui.py +0 -0
  94. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/item_cable_models/cable.bbmodel +0 -0
  95. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/item_cable_models/cable_base.json +0 -0
  96. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/py.typed +0 -0
  97. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/servo_mechanism_models/base_block.json +0 -0
  98. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/servo_mechanism_models/base_item.json +0 -0
  99. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_block.json +0 -0
  100. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_connected.json +0 -0
  101. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_item.json +0 -0
  102. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_block.json +0 -0
  103. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_connected.json +0 -0
  104. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_item.json +0 -0
  105. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/contrib/simplenergy/wrench.py +0 -0
  106. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/__init__.py +0 -0
  107. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/__memory__.py +0 -0
  108. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/constants.py +0 -0
  109. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/definitions_helper/__init__.py +0 -0
  110. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/definitions_helper/equipments.py +0 -0
  111. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/definitions_helper/materials.py +0 -0
  112. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/definitions_helper/records.py +0 -0
  113. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/definitions_helper/simplenergy.py +0 -0
  114. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/definitions_helper/smart_ore_generation.py +0 -0
  115. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/definitions_helper/text.py +0 -0
  116. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/ingredients.py +0 -0
  117. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/utils/io.py +0 -0
  118. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/core/utils/sounds.py +0 -0
  119. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/__init__.py +0 -0
  120. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/bookshelf.py +0 -0
  121. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/bookshelf_config.json +0 -0
  122. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Bitwise.zip +0 -0
  123. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Block.zip +0 -0
  124. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Color.zip +0 -0
  125. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Dump.zip +0 -0
  126. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Environment.zip +0 -0
  127. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Generation.zip +0 -0
  128. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Health.zip +0 -0
  129. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Hitbox.zip +0 -0
  130. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Id.zip +0 -0
  131. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Interaction.zip +0 -0
  132. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Link.zip +0 -0
  133. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Log.zip +0 -0
  134. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Math.zip +0 -0
  135. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Move.zip +0 -0
  136. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Position.zip +0 -0
  137. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Random.zip +0 -0
  138. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Raycast.zip +0 -0
  139. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Schedule.zip +0 -0
  140. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Sidebar.zip +0 -0
  141. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Spline.zip +0 -0
  142. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf String.zip +0 -0
  143. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Time.zip +0 -0
  144. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Tree.zip +0 -0
  145. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Vector.zip +0 -0
  146. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf View.zip +0 -0
  147. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Bookshelf Xp.zip +0 -0
  148. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Common Signals.zip +0 -0
  149. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Furnace NBT Recipes.zip +0 -0
  150. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/ItemIO.zip +0 -0
  151. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/SmartOreGeneration.zip +0 -0
  152. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Smithed Crafter.zip +0 -0
  153. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/datapack/Smithed Custom Block.zip +0 -0
  154. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/dependencies/resource_pack/Smithed Crafter.zip +0 -0
  155. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/archive/__init__.py +0 -0
  156. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/auto/headers/__init__.py +0 -0
  157. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/auto/headers/context_analyzer.py +0 -0
  158. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/auto/headers/execution_parser.py +0 -0
  159. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/auto/headers/function_analyzer.py +0 -0
  160. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/auto/headers/object.py +0 -0
  161. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/auto/lang_file/__init__.py +0 -0
  162. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/auto/lang_file/utils.py +0 -0
  163. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/compatibilities/neo_enchant/__init__.py +0 -0
  164. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/compatibilities/simpledrawer/__init__.py +0 -0
  165. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/compute_sha1/__init__.py +0 -0
  166. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/copy_to_destination/__init__.py +0 -0
  167. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/custom_recipes/__init__.py +0 -0
  168. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/custom_recipes/furnace.py +0 -0
  169. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/custom_recipes/pulverizer.py +0 -0
  170. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/custom_recipes/smithed.py +0 -0
  171. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/custom_recipes/vanilla.py +0 -0
  172. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/loading/__init__.py +0 -0
  173. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/loot_tables/__init__.py +0 -0
  174. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/sorters/__init__.py +0 -0
  175. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/sorters/constants.py +0 -0
  176. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/sorters/extend_datapack.py +0 -0
  177. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/sorters/match.py +0 -0
  178. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/sorters/mod.mcdoc +0 -0
  179. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/sorters/quick_sort.py +0 -0
  180. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/datapack/sorters/selection_sort.py +0 -0
  181. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/finalyze/basic_datapack_structure/__init__.py +0 -0
  182. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/finalyze/check_unused_textures/__init__.py +0 -0
  183. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/finalyze/dependencies/__init__.py +0 -0
  184. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/finalyze/last_final/__init__.py +0 -0
  185. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/__init__.py +0 -0
  186. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/furnace.png +0 -0
  187. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/heavy_workbench.png +0 -0
  188. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/invisible_item.png +0 -0
  189. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/invisible_item_release.png +0 -0
  190. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/minecraft_font.ttf +0 -0
  191. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/mining.png +0 -0
  192. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/none.png +0 -0
  193. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/none_release.png +0 -0
  194. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/pulverizing.png +0 -0
  195. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/shaped_2x2.png +0 -0
  196. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/shaped_3x3.png +0 -0
  197. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/simple_case_no_border.png +0 -0
  198. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/stonecutting.png +0 -0
  199. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/wiki_information.png +0 -0
  200. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft.png +0 -0
  201. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft_template.png +0 -0
  202. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/wiki_mining_template.png +0 -0
  203. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/assets/wiki_result_of_craft.png +0 -0
  204. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/book_components.py +0 -0
  205. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/book_optimizer.py +0 -0
  206. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/craft_content.py +0 -0
  207. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/iso_renders.py +0 -0
  208. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/main.py +0 -0
  209. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/other_utils.py +0 -0
  210. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/page_font.py +0 -0
  211. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/shared_import.py +0 -0
  212. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/showcase_image.py +0 -0
  213. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/.gitignore +0 -0
  214. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/_README.md +0 -0
  215. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/furnace.png +0 -0
  216. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/heavy_workbench.png +0 -0
  217. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/invisible_item.png +0 -0
  218. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/invisible_item_release.png +0 -0
  219. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/minecraft_font.ttf +0 -0
  220. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/mining.png +0 -0
  221. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/none.png +0 -0
  222. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/none_release.png +0 -0
  223. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/pulverizing.png +0 -0
  224. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/shaped_2x2.png +0 -0
  225. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/shaped_3x3.png +0 -0
  226. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/simple_case_no_border.png +0 -0
  227. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/stonecutting.png +0 -0
  228. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/wiki_information.png +0 -0
  229. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/wiki_ingredient_of_craft.png +0 -0
  230. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/wiki_ingredient_of_craft_template.png +0 -0
  231. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/wiki_mining_template.png +0 -0
  232. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/templates/wiki_result_of_craft.png +0 -0
  233. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/ingame_manual/text_components.py +0 -0
  234. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/initialize/__init__.py +0 -0
  235. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/initialize/source_lore_font.py +0 -0
  236. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/merge_smithed_weld/__init__.py +0 -0
  237. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/merge_smithed_weld/weld.py +0 -0
  238. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/resource_pack/check_power_of_2/__init__.py +0 -0
  239. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/resource_pack/item_models/__init__.py +0 -0
  240. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/plugins/resource_pack/sounds/__init__.py +0 -0
  241. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/py.typed +0 -0
  242. {stewbeet-2.2.5 → stewbeet-2.2.7}/stewbeet/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stewbeet
3
- Version: 2.2.5
3
+ Version: 2.2.7
4
4
  Summary: Beet Framework made to help generating advanced Minecraft datapack contents
5
5
  Project-URL: Homepage, https://github.com/Stoupy51/stewbeet
6
6
  Project-URL: Issues, https://github.com/Stoupy51/stewbeet/issues
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "stewbeet"
8
- version = "2.2.5"
8
+ version = "2.2.7"
9
9
  description = "Beet Framework made to help generating advanced Minecraft datapack contents"
10
10
  readme = "README.md"
11
11
  license = "MIT"
@@ -12,7 +12,7 @@ from ..__memory__ import Mem
12
12
 
13
13
 
14
14
  # Add item model component
15
- def add_item_model_component(black_list: list[str] | None = None, ignore_paintings: bool = True) -> None:
15
+ def add_item_model_component(black_list: list[str] | None = None) -> None:
16
16
  """ Add an item model component to all items in the definitions.
17
17
 
18
18
  Args:
@@ -24,8 +24,6 @@ def add_item_model_component(black_list: list[str] | None = None, ignore_paintin
24
24
  for item, data in Mem.definitions.items():
25
25
  if item in black_list or data.get("item_model", None) is not None:
26
26
  continue
27
- if ignore_paintings and data.get("painting_data", None) is not None:
28
- continue
29
27
  data["item_model"] = f"{Mem.ctx.project_id}:{item}"
30
28
  return
31
29
 
@@ -53,23 +53,28 @@ def beet_default(ctx: Context) -> None:
53
53
  ordered_painting_data = {"asset_id": f"{ns}:{item}"}
54
54
  ordered_painting_data.update(painting_data)
55
55
  ordered_painting_data.pop("not_placeable", None)
56
+ ordered_painting_data.pop("texture", None)
56
57
 
57
58
  # Create the painting definition
58
59
  Mem.ctx.data[ns].painting_variants[item] = set_json_encoder(PaintingVariant(ordered_painting_data))
59
60
 
60
61
  ## Resource pack
61
62
  # Get the texture path
62
- matching_textures: list[str] = [
63
- relative_path(f"{root}/{file}")
64
- for root, _, files in os.walk(textures_folder)
65
- for file in files if file == f"{item}.png"
66
- ]
67
- if not matching_textures:
68
- error(f"No texture found for painting '{item}' in the textures folder '{textures_folder}'. Expected a file named '{item}.png'.")
69
- continue
70
- elif len(matching_textures) > 1:
71
- warning(f"Multiple textures found for painting '{item}' in the textures folder '{textures_folder}'. Using the first one found: '{matching_textures[0]}'.")
72
- src: str = matching_textures[0]
63
+ if "texture" in painting_data:
64
+ texture: str = painting_data["texture"]
65
+ src: str = relative_path(f"{textures_folder}/{texture}.png")
66
+ else:
67
+ matching_textures: list[str] = [
68
+ relative_path(f"{root}/{file}")
69
+ for root, _, files in os.walk(textures_folder)
70
+ for file in files if file == f"{item}.png"
71
+ ]
72
+ if not matching_textures:
73
+ error(f"No texture found for painting '{item}' in the textures folder '{textures_folder}'. Expected a file named '{item}.png'.")
74
+ continue
75
+ elif len(matching_textures) > 1:
76
+ warning(f"Multiple textures found for painting '{item}' in the textures folder '{textures_folder}'. Using the first one found: '{matching_textures[0]}'.")
77
+ src: str = matching_textures[0]
73
78
  dst: str = f"painting/{item}"
74
79
 
75
80
  # Check if the texture is not already registered
@@ -1,10 +1,13 @@
1
1
 
2
2
  # Imports
3
- from beet import Advancement, BlockTag, Context, EntityTypeTag, Predicate
3
+ import os
4
+ from pathlib import Path
5
+
6
+ from beet import Advancement, BlockTag, Context, EntityTypeTag, LootTable, Predicate
4
7
  from beet.core.utils import JsonDict
5
8
  from stouputils.decorators import measure_time
6
- from stouputils.io import super_json_dump
7
- from stouputils.print import debug, progress
9
+ from stouputils.io import clean_path, relative_path, super_json_dump
10
+ from stouputils.print import debug, error, progress
8
11
 
9
12
  from ....core.__memory__ import Mem
10
13
  from ....core.constants import (
@@ -13,13 +16,14 @@ from ....core.constants import (
13
16
  CUSTOM_BLOCK_HEAD,
14
17
  CUSTOM_BLOCK_HEAD_CUBE_RADIUS,
15
18
  CUSTOM_BLOCK_VANILLA,
19
+ GROWING_SEED,
16
20
  NO_SILK_TOUCH_DROP,
17
21
  OFFICIAL_LIBS,
18
22
  VANILLA_BLOCK,
19
23
  VANILLA_BLOCK_FOR_ORES,
20
24
  official_lib_used,
21
25
  )
22
- from ....core.utils.io import set_json_encoder, write_function, write_function_tag, write_versioned_function
26
+ from ....core.utils.io import set_json_encoder, write_function, write_function_tag, write_load_file, write_versioned_function
23
27
 
24
28
 
25
29
  # Main entry point
@@ -34,10 +38,18 @@ def beet_default(ctx: Context):
34
38
  # Set up memory context
35
39
  if Mem.ctx is None: # pyright: ignore[reportUnnecessaryComparison]
36
40
  Mem.ctx = ctx
41
+ ns: str = ctx.project_id
42
+ textures_folder: str = relative_path(ctx.meta.get("stewbeet", {}).get("textures_folder", ""))
37
43
 
38
44
  # Assertions
39
45
  assert ctx.project_id, "Project ID is not set. Please set it in the project configuration."
40
- ns: str = ctx.project_id
46
+ assert textures_folder != "", "Textures folder path not found in 'ctx.meta.stewbeet.textures_folder'. Please set a directory path in project configuration."
47
+
48
+ # Textures
49
+ source_textures: dict[str, str] = {
50
+ clean_path(str(p)).split("/")[-1]: relative_path(str(p))
51
+ for p in Path(textures_folder).rglob("*.png")
52
+ }
41
53
 
42
54
  # Stop if not custom block
43
55
  if not any(data.get(VANILLA_BLOCK) for data in Mem.definitions.values()):
@@ -72,6 +84,7 @@ execute if score #rotation {ns}.data matches 0 if predicate {ns}:facing/west run
72
84
  # For each custom block,
73
85
  unique_blocks: set[str] = set()
74
86
  custom_block_entities: set[str] = set()
87
+ has_growing_seed: bool = False
75
88
  for item, data in Mem.definitions.items():
76
89
  item: str
77
90
  data: JsonDict
@@ -125,7 +138,25 @@ execute if score #rotation {ns}.data matches 0 if predicate {ns}:facing/west run
125
138
  advancement revoke @s only {ns}:custom_block_alternative/{item}
126
139
 
127
140
  # Execute the place function as and at the new placed item frame
128
- execute as @e[type=item_frame,tag={ns}.new,tag={ns}.{item}] at @s run function {ns}:custom_blocks/{item}/place_main
141
+ tag @s add {ns}.to_refund
142
+ execute as @e[type=item_frame,tag={ns}.new,tag={ns}.{item}] at @s run function {ns}:custom_blocks/{item}/place_check
143
+ tag @s remove {ns}.to_refund
144
+ """)
145
+
146
+ # Make place check function
147
+ write_function(f"{ns}:custom_blocks/{item}/place_check", f"""
148
+ # Check if there is air block at the position
149
+ execute if block ~ ~ ~ air run return run function {ns}:custom_blocks/{item}/place_main
150
+
151
+ # If not air, give back the item to the player
152
+ tag @e[type=item] add {ns}.temp
153
+ execute as @p[tag={ns}.to_refund] at @s run loot spawn ~ ~ ~ loot {ns}:i/{item}
154
+ data merge entity @n[type=item,tag=!{ns}.temp] {{PickupDelay:0s,Motion:[0.0d,0.0d,0.0d]}}
155
+ data modify entity @n[type=item,tag=!{ns}.temp] Owner set from entity @p[tag={ns}.to_refund] UUID
156
+ tag @n[type=item] remove {ns}.temp
157
+
158
+ # And kill the item frame
159
+ kill @s
129
160
  """)
130
161
 
131
162
  # If the block is a custom block with a block id,
@@ -173,8 +204,13 @@ execute as @e[type=item_frame,tag={ns}.new,tag={ns}.{item}] at @s run function {
173
204
  scoreboard players add #total_custom_blocks {ns}.data 1
174
205
  scoreboard players add #total_vanilla_{block_id.replace('minecraft:','')} {ns}.data 1
175
206
  scoreboard players add #total_{item} {ns}.data 1
207
+ {f"scoreboard players add #total_growing_seeds {ns}.data 1" if GROWING_SEED in data else ""}
176
208
  """
177
209
 
210
+ # If CUSTOM_BLOCK_ALTERNATIVE, we need to kill the old item frame
211
+ if data.get("id") == CUSTOM_BLOCK_ALTERNATIVE:
212
+ content += "kill @s[type=item_frame]\n"
213
+
178
214
  # Write the file
179
215
  write_function(f"{path}/place_main", content)
180
216
 
@@ -192,6 +228,7 @@ tag @s add smithed.block
192
228
  tag @s add {ns}.custom_block
193
229
  tag @s add {ns}.{item}
194
230
  tag @s add {ns}.vanilla.{block_id}
231
+ {f"tag @s add {ns}.growing_seed" if GROWING_SEED in data else ""}
195
232
 
196
233
  # Add a custom name
197
234
  data merge entity @s {custom_name}
@@ -237,6 +274,7 @@ execute as @n[tag={ns}.new] at @s run function {ns}:custom_blocks/{item}/place_s
237
274
  scoreboard players add #total_custom_blocks {ns}.data 1
238
275
  scoreboard players add #total_vanilla_item_frame {ns}.data 1
239
276
  scoreboard players add #total_{item} {ns}.data 1
277
+ {f"scoreboard players add #total_growing_seeds {ns}.data 1" if GROWING_SEED in data else ""}
240
278
 
241
279
  # Replace the placing sound
242
280
  playsound minecraft:block.stone.place block @a[distance=..5]
@@ -262,6 +300,7 @@ tag @s add smithed.block
262
300
  tag @s add {ns}.custom_block
263
301
  tag @s add {ns}.{item}
264
302
  tag @s add {ns}.vanilla.minecraft_item_frame
303
+ {f"tag @s add {ns}.growing_seed" if GROWING_SEED in data else ""}
265
304
 
266
305
  # Add a custom name
267
306
  data merge entity @s {custom_name}
@@ -274,9 +313,108 @@ execute store result entity @s Facing byte 1 run scoreboard players get #item_fr
274
313
  execute at @s run tp @s ^ ^ ^0.1
275
314
  """)
276
315
  pass
316
+
317
+ # If the block is a growing seed, make the update_seed_model function and call it in the place_secondary function
318
+ growing_seed: JsonDict = data.get(GROWING_SEED, {})
319
+ if growing_seed:
320
+ has_growing_seed = True
321
+ write_function(f"{ns}:custom_blocks/{item}/place_secondary", f"""
322
+ # Update seed model
323
+ scoreboard players add @s {ns}.growth_time 0
324
+ function {ns}:custom_blocks/{item}/update_seed_model
325
+ """)
326
+ # Get the number of growth stages
327
+ texture_basename: str = growing_seed.get("texture_basename", item)
328
+ starts: str = f"{texture_basename}_stage_"
329
+ num_stages: int = len({texture for texture in source_textures if os.path.basename(texture).startswith(starts)})
330
+ progress_stages: int = num_stages - 1 # Last stage is the full grown plant
331
+ growing_time: int = growing_seed["seconds"]
332
+
333
+ # Make the update function
334
+ content: str = ""
335
+ for stage in range(num_stages):
336
+ time_from: int = int(stage * growing_time / progress_stages)
337
+ time_to: int = int((stage + 1) * growing_time / progress_stages) - 1
338
+ time_to_str: str = str(time_to) if stage < progress_stages else ""
339
+ content += (
340
+ f"execute if score @s {ns}.growth_time matches {time_from}..{time_to_str} unless score @s {ns}.growth_stage matches {stage} run "
341
+ f"""function {ns}:custom_blocks/change_seed_stage {{stage:{stage}, model:"{ns}:seeds/{starts}{stage}"}}\n"""
342
+ )
343
+ write_function(f"{ns}:custom_blocks/{item}/update_seed_model", f"""
344
+ # Update growth stage based on growth_time
345
+ {content}
346
+ """)
347
+ # Optimisation: If total growing time is higher than 60*stages second, we will increment the growth_time score every minute
348
+ for (speed, secs) in [(60, "minute"), (5, "second_5"), (1, "second")]:
349
+ if growing_time > speed * progress_stages:
350
+ write_function(f"{ns}:custom_blocks/{item}/{secs}", f"""
351
+ # Increment growth time score by {speed} and update model
352
+ scoreboard players add @s {ns}.growth_time {speed}
353
+ function {ns}:custom_blocks/{item}/update_seed_model
354
+ """)
355
+ break
356
+ else:
357
+ error(f"Growing seed '{item}' has a growing time < to the number of stages ({growing_time} seconds). Please increase the growing time or reduce the number of stages.")
358
+
359
+ # Make the loot table for the seed
360
+ loot_table: str | list[JsonDict] = growing_seed.get("loots", [])
361
+ if not isinstance(loot_table, str):
362
+ ctx.data[ns].loot_tables[f"seeds/{item}"] = set_json_encoder(LootTable({
363
+ "type": "minecraft:block",
364
+ "pools": [
365
+ {
366
+ "rolls": pool.get("rolls", 1),
367
+ "bonus_rolls": 0,
368
+ "entries": [
369
+ {
370
+ # Vanilla item if "minecraft:" in id,
371
+ # Custom item if plain string
372
+ # Another loot table if ':' in id
373
+ "type": "minecraft:item" if "minecraft:" in pool["id"] else "minecraft:loot_table",
374
+ "name" if "minecraft:" in pool["id"] else "value": (f"{ns}:i/{pool["id"]}" if ":" not in pool["id"] else pool["id"]),
375
+ **({} if not pool.get("fortune") else {
376
+ "functions": [
377
+ {
378
+ "function": "minecraft:apply_bonus",
379
+ "enchantment": "minecraft:fortune",
380
+ "formula": "minecraft:binomial_with_bonus_count",
381
+ "parameters": pool["fortune"],
382
+ },
383
+ ]
384
+ })
385
+ }
386
+ ]
387
+ }
388
+ for pool in loot_table
389
+ ]
390
+ }), max_level=-1)
391
+ loot_table = f"{ns}:seeds/{item}"
392
+
393
+ # Make the is_fully_grown function that will be called on destroy
394
+ write_function(f"{ns}:custom_blocks/{item}/is_fully_grown", f"""
395
+ # If fully grown, drop the loot table and kill the current entity (item)
396
+ execute if score #growth_time {ns}.data matches {growing_time}.. as @p[gamemode=!spectator] run loot spawn ~ ~ ~ fish {loot_table} ~ ~ ~ mainhand
397
+ execute if score #growth_time {ns}.data matches {growing_time}.. run kill @s
398
+ """)
277
399
  pass
278
400
  pass
279
401
 
402
+ # Make the change_stage function for growing seeds and create scoreboard objectives
403
+ if has_growing_seed:
404
+ write_function(f"{ns}:custom_blocks/change_seed_stage", f"""
405
+ # Update the growth stage score
406
+ $scoreboard players set @s {ns}.growth_stage $(stage)
407
+
408
+ # Change the item model to the right stage
409
+ $execute if entity @s[type=item_display] run return run data modify entity @s item.components."minecraft:item_model" set value "$(model)"
410
+ $execute if entity @s[type=item_frame] run return run data modify entity @s Item.components."minecraft:item_model" set value "$(model)"
411
+ """)
412
+ write_load_file(f"""
413
+ # Create objectives for growing seeds
414
+ scoreboard objectives add {ns}.growth_time dummy
415
+ scoreboard objectives add {ns}.growth_stage dummy
416
+ """)
417
+
280
418
  # Link the custom block library to the datapack
281
419
  smithed_custom_blocks = [1 for data in Mem.definitions.values() if data.get("id") == CUSTOM_BLOCK_VANILLA]
282
420
  if smithed_custom_blocks:
@@ -307,7 +445,7 @@ execute at @s run tp @s ^ ^ ^0.1
307
445
 
308
446
  ## Destroy functions
309
447
  # For each unique block, if the vanilla block is missing, call the destroy function for the group
310
- content = "\n"
448
+ content = "# Check for missing vanilla blocks\n"
311
449
  for block_id in unique_blocks_sorted:
312
450
  score_check: str = f"score #total_vanilla_{block_id.replace('minecraft:','')} {ns}.data matches 1.."
313
451
  block_underscore = block_id.replace(":","_")
@@ -319,15 +457,34 @@ execute at @s run tp @s ^ ^ ^0.1
319
457
  if block_id != CUSTOM_BLOCK_ALTERNATIVE:
320
458
  content += (
321
459
  f"execute if {score_check} if entity @s[tag={ns}.vanilla.{block_underscore}] "
322
- f"unless block ~ ~ ~ {block_id} run function {ns}:custom_blocks/_groups/{block_underscore}\n"
460
+ f"unless block ~ ~ ~ {block_id} run return run function {ns}:custom_blocks/_groups/{block_underscore}\n"
323
461
  )
324
462
  else:
325
463
  content += (
326
464
  f"execute if {score_check} if entity @s[tag={ns}.vanilla.{block_underscore}] "
327
- f"unless items entity @s contents *[minecraft:custom_data~{{{ns}:{{item_frame_destroy:true}}}}] run function {ns}:custom_blocks/_groups/{block_underscore}\n"
465
+ f"unless items entity @s contents *[minecraft:custom_data~{{{ns}:{{item_frame_destroy:true}}}}] run return run function {ns}:custom_blocks/_groups/{block_underscore}\n"
328
466
  )
329
467
  write_function(f"{ns}:custom_blocks/destroy", content)
330
468
 
469
+ # If there are growing seeds, we need to check the block below to see if it's still valid
470
+ if has_growing_seed:
471
+ content = ""
472
+ for item, data in Mem.definitions.items():
473
+ growing_seed: JsonDict = data.get(GROWING_SEED, {})
474
+ if growing_seed:
475
+ planted_on: str = growing_seed.get("planted_on", "dirt")
476
+ content += (
477
+ f"execute if score #total_{item} {ns}.data matches 1.. if entity @s[tag={ns}.{item}] "
478
+ f"""unless block ~ ~-1 ~ {planted_on} run return run function {ns}:custom_blocks/no_block_below {{item:"{item}"}}\n"""
479
+ )
480
+ write_function(f"{ns}:custom_blocks/destroy_growing_seeds", content)
481
+ write_function(f"{ns}:custom_blocks/no_block_below", f"""
482
+ # Break the block we're at and call the destroy function
483
+ execute if entity @s[type=item_frame] run summon item ~ ~ ~ {{Item:{{id:"minecraft:item_frame",count:1,components:{{"minecraft:custom_data":{{"{ns}":{{"item_frame_destroy":true}}}}}}}}}}
484
+ execute if entity @s[type=item_display] run setblock ~ ~ ~ air destroy
485
+ $function {ns}:custom_blocks/$(item)/destroy
486
+ """)
487
+
331
488
  # For each unique block, make the group function
332
489
  for block_id in unique_blocks_sorted:
333
490
 
@@ -369,7 +526,6 @@ execute at @s run tp @s ^ ^ ^0.1
369
526
  for item, data in Mem.definitions.items():
370
527
  if data.get(VANILLA_BLOCK):
371
528
  vanilla_block: JsonDict = data[VANILLA_BLOCK]
372
- path = f"{ns}:custom_blocks/{item}"
373
529
  if vanilla_block.get("id"):
374
530
  block_id: str = vanilla_block["id"].split('[')[0].split('{')[0]
375
531
  elif vanilla_block.get("contents", False):
@@ -385,6 +541,9 @@ execute at @s run tp @s ^ ^ ^0.1
385
541
  # Replace the item with the custom one
386
542
  execute as @n[type=item,nbt={{Item:{item_nbt}}},distance=..1] run function {ns}:custom_blocks/{item}/replace_item
387
543
  """
544
+ # If growing seed, get the growth_time score
545
+ if GROWING_SEED in data:
546
+ content = content.replace("custom one", f"custom one\nscoreboard players operation #growth_time {ns}.data = @s {ns}.growth_time", 1)
388
547
 
389
548
  # Decrease count scores for stats and optimization
390
549
  content += f"""
@@ -395,20 +554,37 @@ scoreboard players remove #total_{item} {ns}.data 1
395
554
  """
396
555
 
397
556
  # Add the destroy function
398
- write_function(f"{path}/destroy", content + "\n# Kill the custom block entity\nkill @s\n")
557
+ write_function(f"{ns}:custom_blocks/{item}/destroy", content + "\n# Kill the custom block entity\nkill @s\n")
399
558
 
400
559
  # Replace item function
401
- if vanilla_block != VANILLA_BLOCK_FOR_ORES:
560
+ if not data.get(NO_SILK_TOUCH_DROP):
402
561
  content = f"""
562
+ # Replace the item with the custom one
403
563
  data modify entity @s Item.components set from storage {ns}:items all.{item}.components
404
564
  data modify entity @s Item.id set from storage {ns}:items all.{item}.id
405
565
  """
406
566
  else:
567
+ # If no VANILLA_BLOCK_FOR_ORES, check if the player has silk touch in mainhand
568
+ if data.get(VANILLA_BLOCK) != VANILLA_BLOCK_FOR_ORES:
569
+ write_function(f"{ns}:custom_blocks/{item}/destroy", f"""
570
+ # Check if the player has silk touch in mainhand
571
+ scoreboard players set #is_silk_touch {ns}.data 0
572
+ execute as @p[distance=..10,gamemode=!spectator] if data entity @s SelectedItem.components."minecraft:enchantments"."minecraft:silk_touch" run scoreboard players set #is_silk_touch {ns}.data 1
573
+
574
+ # If no item found, summon it
575
+ execute unless entity @n[type=item,nbt={{Item:{item_nbt}}},distance=..1] run loot spawn ~ ~ ~ loot {{pools:[{{entries:[{{type:"minecraft:item",name:"minecraft:glass"}}],rolls:1}}]}}
576
+ """, prepend=True)
577
+
578
+ # Handle no silk touch drop
407
579
  no_silk_touch_drop: str | JsonDict = data[NO_SILK_TOUCH_DROP]
408
580
  if isinstance(no_silk_touch_drop, dict):
409
581
  item_to_drop: str = no_silk_touch_drop["id"]
410
- item_count_min: int = no_silk_touch_drop["count"]["min"]
411
- item_count_max: int = no_silk_touch_drop["count"]["max"]
582
+ if isinstance(no_silk_touch_drop.get("count"), int):
583
+ item_count_min = no_silk_touch_drop["count"]
584
+ item_count_max = no_silk_touch_drop["count"]
585
+ else:
586
+ item_count_min = no_silk_touch_drop["count"]["min"]
587
+ item_count_max = no_silk_touch_drop["count"]["max"]
412
588
  else:
413
589
  item_to_drop: str = no_silk_touch_drop
414
590
  item_count_min: int = 1
@@ -436,11 +612,21 @@ execute if score #is_silk_touch {ns}.data matches 1 run data modify entity @s It
436
612
 
437
613
  # Else, no silk touch
438
614
  {silk_text}
439
-
615
+ """
616
+ if data.get(VANILLA_BLOCK) == VANILLA_BLOCK_FOR_ORES:
617
+ content += f"""
440
618
  # Get item count in every case
441
619
  execute store result entity @s Item.count byte 1 run scoreboard players get #item_count {ns}.data
442
620
  """
443
- write_function(f"{path}/replace_item", content)
621
+ # If growing seed, call the loot table function
622
+ if GROWING_SEED in data:
623
+ content += f"""
624
+ # Check if the seed is fully grown
625
+ function {ns}:custom_blocks/{item}/is_fully_grown
626
+ """
627
+
628
+ # Write the function
629
+ write_function(f"{ns}:custom_blocks/{item}/replace_item", content)
444
630
 
445
631
 
446
632
  # Write the used_vanilla_blocks tag, the predicate to check the blocks with the tag and an advanced one
@@ -501,6 +687,11 @@ execute if {score_check} as @e[type=#{ns}:custom_blocks,tag={ns}.custom_block,ta
501
687
  write_versioned_function("second_5", f"""
502
688
  # 5 seconds break detection (item display only)
503
689
  execute if {score_check} as @e[type=item_display,tag={ns}.custom_block,predicate=!{ns}:advanced_check_vanilla_blocks] at @s run function {ns}:custom_blocks/destroy
690
+ """)
691
+ if has_growing_seed:
692
+ write_versioned_function("second_5", f"""
693
+ # 5 seconds growing seed break detection (below block check)
694
+ execute if score #total_growing_seeds {ns}.data matches 1.. as @e[type=#{ns}:custom_blocks,tag={ns}.growing_seed] at @s run function {ns}:custom_blocks/destroy_growing_seeds
504
695
  """)
505
696
  # Write the entity type tag for custom blocks
506
697
  ctx.data[ns].entity_type_tags["custom_blocks"] = set_json_encoder(EntityTypeTag({"values": sorted(custom_block_entities)}))
@@ -558,6 +749,14 @@ execute as @n[type=item,nbt={{Item:{{id:"minecraft:item_frame"}}}},distance=..1]
558
749
  f'scoreboard players add #total_custom_blocks {ns}.data 0',
559
750
  prepend = True
560
751
  )
752
+ if has_growing_seed:
753
+ write_function(f"{ns}:_stats_custom_blocks",
754
+ f'tellraw @s [{{"text":"- Total growing seeds: ","color":"dark_aqua"}},{{"score":{{"name":"#total_growing_seeds","objective":"{ns}.data"}},"color":"aqua"}}]'
755
+ )
756
+ write_function(f"{ns}:_stats_custom_blocks",
757
+ f'scoreboard players add #total_growing_seeds {ns}.data 0',
758
+ prepend = True
759
+ )
561
760
 
562
761
 
563
762
 
@@ -0,0 +1,67 @@
1
+
2
+ # Imports
3
+ from beet import Context
4
+ from stouputils.decorators import measure_time
5
+ from stouputils.print import progress
6
+
7
+ from ....core.__memory__ import Mem
8
+ from ....core.utils.io import write_function, write_versioned_function
9
+
10
+
11
+ # Main entry point
12
+ @measure_time(progress, message="Execution time of 'stewbeet.plugins.finalyze.custom_blocks_ticking'")
13
+ def beet_default(ctx: Context):
14
+ """ Main entry point for the custom blocks ticking plugin.
15
+ This plugin sets up custom blocks ticks and second functions calls.
16
+
17
+ It will seek for "second.mcfunction", "tick.mcfunction", and more files in the custom_blocks folder
18
+ Then it will generate all functions to lead to the execution of these files by adding tags.
19
+
20
+ Args:
21
+ ctx (Context): The beet context.
22
+ """
23
+ if Mem.ctx is None: # pyright: ignore[reportUnnecessaryComparison]
24
+ Mem.ctx = ctx
25
+
26
+ # Get namespace
27
+ assert ctx.project_id, "Project ID is not set. Please set it in the project configuration."
28
+ ns: str = ctx.project_id
29
+
30
+ # Get ticks functions from the context
31
+ for ticking in ["tick", "tick_2", "second", "second_5", "minute"]:
32
+ custom_blocks_tick: list[str] = []
33
+
34
+ # Check for custom block functions in the data pack
35
+ for function_path in ctx.data.functions:
36
+ if function_path.startswith(f"{ns}:custom_blocks/") and "/" in function_path[len(f"{ns}:custom_blocks/"):]:
37
+
38
+ # Split the path to get custom block name and function type
39
+ parts = function_path[len(f"{ns}:custom_blocks/"):].split("/")
40
+ if len(parts) == 2:
41
+ custom_block, function_name = parts
42
+ if function_name == ticking:
43
+ custom_blocks_tick.append(custom_block)
44
+
45
+ # For each custom block, add tags when placed
46
+ for custom_block in custom_blocks_tick:
47
+ write_function(f"{ns}:custom_blocks/{custom_block}/place_secondary",
48
+ f"# Add tag for loop every {ticking}\ntag @s add {ns}.{ticking}\nscoreboard players add #{ticking}_entities {ns}.data 1\n")
49
+ write_function(f"{ns}:custom_blocks/{custom_block}/destroy",
50
+ f"# Decrease the number of entities with {ticking} tag\nscoreboard players remove #{ticking}_entities {ns}.data 1\n")
51
+
52
+ # Write ticking functions
53
+ if custom_blocks_tick:
54
+ score_check: str = f"score #{ticking}_entities {ns}.data matches 1.."
55
+ write_versioned_function(ticking, f"# Custom blocks {ticking} functions\nexecute if {score_check} as @e[tag={ns}.{ticking}] at @s run function {ns}:custom_blocks/{ticking}")
56
+
57
+ content = "\n".join(
58
+ f"execute if entity @s[tag={ns}.{custom_block}] run function {ns}:custom_blocks/{custom_block}/{ticking}"
59
+ for custom_block in custom_blocks_tick
60
+ )
61
+ write_function(f"{ns}:custom_blocks/{ticking}", content)
62
+
63
+ # Write in stats_custom_blocks
64
+ write_function(f"{ns}:_stats_custom_blocks", f'scoreboard players add #{ticking}_entities {ns}.data 0', prepend=True)
65
+ write_function(f"{ns}:_stats_custom_blocks",
66
+ f'tellraw @s [{{"text":"- \'{ticking}\' tag function: ","color":"green"}},{{"score":{{"name":"#{ticking}_entities","objective":"{ns}.data"}},"color":"dark_green"}}]')
67
+
@@ -111,7 +111,7 @@ def generate_high_res_font(item: str, item_image: Image.Image, count: int = 1) -
111
111
  str: The font to the generated texture
112
112
  """
113
113
  font = get_next_font()
114
- item = f"{item}_{count}" if isinstance(count, str) or count > 1 else item
114
+ item = f"{item}_{str(count).replace('-', '_')}" if isinstance(count, str) or count > 1 else item
115
115
 
116
116
  # Get output path
117
117
  path = f"{SharedMemory.cache_path}/font/high_res/{item}.png"