stewbeet 2.1.8__tar.gz → 2.2.1__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 (241) hide show
  1. {stewbeet-2.1.8 → stewbeet-2.2.1}/PKG-INFO +1 -1
  2. {stewbeet-2.1.8 → stewbeet-2.2.1}/pyproject.toml +1 -1
  3. stewbeet-2.2.1/stewbeet/continuous_delivery/cd_utils.py +47 -0
  4. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/constants.py +49 -5
  5. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/definitions_helper/equipments.py +12 -2
  6. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/definitions_helper/materials.py +55 -49
  7. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/ingredients.py +15 -0
  8. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/custom_recipes/smithed.py +4 -1
  9. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/custom_recipes/vanilla.py +125 -4
  10. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/custom_blocks/__init__.py +3 -1
  11. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/finalyze/dependencies/__init__.py +11 -4
  12. stewbeet-2.2.1/stewbeet/plugins/ingame_manual/assets/mining.png +0 -0
  13. stewbeet-2.2.1/stewbeet/plugins/ingame_manual/assets/stonecutting.png +0 -0
  14. stewbeet-2.2.1/stewbeet/plugins/ingame_manual/assets/wiki_mining_template.png +0 -0
  15. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/book_components.py +8 -7
  16. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/craft_content.py +106 -9
  17. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/image_utils.py +13 -8
  18. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/main.py +198 -42
  19. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/other_utils.py +7 -11
  20. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/page_font.py +5 -2
  21. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/shared_import.py +19 -13
  22. stewbeet-2.2.1/stewbeet/plugins/ingame_manual/templates/mining.png +0 -0
  23. stewbeet-2.2.1/stewbeet/plugins/ingame_manual/templates/stonecutting.png +0 -0
  24. stewbeet-2.2.1/stewbeet/plugins/ingame_manual/templates/wiki_mining_template.png +0 -0
  25. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/initialize/__init__.py +10 -15
  26. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/verify_definitions/__init__.py +1 -1
  27. stewbeet-2.1.8/stewbeet/continuous_delivery/cd_utils.py +0 -29
  28. stewbeet-2.1.8/stewbeet/plugins/ingame_manual/templates/_README.md +0 -5
  29. {stewbeet-2.1.8 → stewbeet-2.2.1}/.gitignore +0 -0
  30. {stewbeet-2.1.8 → stewbeet-2.2.1}/LICENSE +0 -0
  31. {stewbeet-2.1.8 → stewbeet-2.2.1}/README.md +0 -0
  32. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/__init__.py +0 -0
  33. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/__main__.py +0 -0
  34. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/all.py +0 -0
  35. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/cli.py +0 -0
  36. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/continuous_delivery/__init__.py +0 -0
  37. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/continuous_delivery/github.py +0 -0
  38. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/continuous_delivery/modrinth.py +0 -0
  39. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/continuous_delivery/pmc.py +0 -0
  40. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/continuous_delivery/smithed.py +0 -0
  41. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/__init__.py +0 -0
  42. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/balancing.py +0 -0
  43. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/batteries.py +0 -0
  44. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/cables.py +0 -0
  45. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant.json +0 -0
  46. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_d.json +0 -0
  47. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_de.json +0 -0
  48. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dew.json +0 -0
  49. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dn.json +0 -0
  50. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dne.json +0 -0
  51. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnew.json +0 -0
  52. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dns.json +0 -0
  53. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnse.json +0 -0
  54. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnsew.json +0 -0
  55. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnsw.json +0 -0
  56. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnw.json +0 -0
  57. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ds.json +0 -0
  58. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dse.json +0 -0
  59. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dsew.json +0 -0
  60. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dsw.json +0 -0
  61. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dw.json +0 -0
  62. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_e.json +0 -0
  63. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ew.json +0 -0
  64. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_n.json +0 -0
  65. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ne.json +0 -0
  66. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_new.json +0 -0
  67. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ns.json +0 -0
  68. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nse.json +0 -0
  69. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nsew.json +0 -0
  70. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nsw.json +0 -0
  71. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nw.json +0 -0
  72. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_s.json +0 -0
  73. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_se.json +0 -0
  74. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_sew.json +0 -0
  75. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_sw.json +0 -0
  76. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_u.json +0 -0
  77. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ud.json +0 -0
  78. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ude.json +0 -0
  79. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udew.json +0 -0
  80. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udn.json +0 -0
  81. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udne.json +0 -0
  82. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnew.json +0 -0
  83. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udns.json +0 -0
  84. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnse.json +0 -0
  85. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnsew.json +0 -0
  86. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnsw.json +0 -0
  87. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnw.json +0 -0
  88. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uds.json +0 -0
  89. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udse.json +0 -0
  90. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udsew.json +0 -0
  91. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udsw.json +0 -0
  92. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udw.json +0 -0
  93. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ue.json +0 -0
  94. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uew.json +0 -0
  95. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_un.json +0 -0
  96. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_une.json +0 -0
  97. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unew.json +0 -0
  98. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uns.json +0 -0
  99. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unse.json +0 -0
  100. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unsew.json +0 -0
  101. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unsw.json +0 -0
  102. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unw.json +0 -0
  103. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_us.json +0 -0
  104. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_use.json +0 -0
  105. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_usew.json +0 -0
  106. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_usw.json +0 -0
  107. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uw.json +0 -0
  108. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_cable_models/variant_w.json +0 -0
  109. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/energy_lib_calls.py +0 -0
  110. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/gui.py +0 -0
  111. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/item_cable_models/cable.bbmodel +0 -0
  112. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/item_cable_models/cable_base.json +0 -0
  113. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/py.typed +0 -0
  114. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/servo_mechanism_models/base_block.json +0 -0
  115. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/servo_mechanism_models/base_item.json +0 -0
  116. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_block.json +0 -0
  117. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_connected.json +0 -0
  118. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_item.json +0 -0
  119. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_block.json +0 -0
  120. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_connected.json +0 -0
  121. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_item.json +0 -0
  122. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/contrib/simplenergy/wrench.py +0 -0
  123. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/__init__.py +0 -0
  124. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/__memory__.py +0 -0
  125. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/definitions_helper/__init__.py +0 -0
  126. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/definitions_helper/completion.py +0 -0
  127. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/definitions_helper/records.py +0 -0
  128. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/definitions_helper/simplenergy.py +0 -0
  129. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/definitions_helper/smart_ore_generation.py +0 -0
  130. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/definitions_helper/text.py +0 -0
  131. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/utils/io.py +0 -0
  132. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/core/utils/sounds.py +0 -0
  133. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/__init__.py +0 -0
  134. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/bookshelf.py +0 -0
  135. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/bookshelf_config.json +0 -0
  136. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Bitwise.zip +0 -0
  137. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Block.zip +0 -0
  138. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Color.zip +0 -0
  139. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Dump.zip +0 -0
  140. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Environment.zip +0 -0
  141. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Generation.zip +0 -0
  142. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Health.zip +0 -0
  143. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Hitbox.zip +0 -0
  144. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Id.zip +0 -0
  145. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Interaction.zip +0 -0
  146. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Link.zip +0 -0
  147. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Log.zip +0 -0
  148. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Math.zip +0 -0
  149. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Move.zip +0 -0
  150. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Position.zip +0 -0
  151. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Random.zip +0 -0
  152. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Raycast.zip +0 -0
  153. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Schedule.zip +0 -0
  154. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Sidebar.zip +0 -0
  155. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Spline.zip +0 -0
  156. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf String.zip +0 -0
  157. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Time.zip +0 -0
  158. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Tree.zip +0 -0
  159. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Vector.zip +0 -0
  160. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf View.zip +0 -0
  161. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Bookshelf Xp.zip +0 -0
  162. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Common Signals.zip +0 -0
  163. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Furnace NBT Recipes.zip +0 -0
  164. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/ItemIO.zip +0 -0
  165. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/SmartOreGeneration.zip +0 -0
  166. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Smithed Crafter.zip +0 -0
  167. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/datapack/Smithed Custom Block.zip +0 -0
  168. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/dependencies/resource_pack/Smithed Crafter.zip +0 -0
  169. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/archive/__init__.py +0 -0
  170. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/auto/headers/__init__.py +0 -0
  171. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/auto/headers/context_analyzer.py +0 -0
  172. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/auto/headers/execution_parser.py +0 -0
  173. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/auto/headers/function_analyzer.py +0 -0
  174. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/auto/headers/object.py +0 -0
  175. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/auto/lang_file/__init__.py +0 -0
  176. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/auto/lang_file/utils.py +0 -0
  177. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/compatibilities/neo_enchant/__init__.py +0 -0
  178. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/compatibilities/simpledrawer/__init__.py +0 -0
  179. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/compute_sha1/__init__.py +0 -0
  180. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/copy_to_destination/__init__.py +0 -0
  181. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/custom_recipes/__init__.py +0 -0
  182. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/custom_recipes/furnace.py +0 -0
  183. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/custom_recipes/pulverizer.py +0 -0
  184. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/loading/__init__.py +0 -0
  185. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/loot_tables/__init__.py +0 -0
  186. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/sorters/__init__.py +0 -0
  187. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/sorters/constants.py +0 -0
  188. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/sorters/extend_datapack.py +0 -0
  189. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/sorters/match.py +0 -0
  190. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/sorters/mod.mcdoc +0 -0
  191. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/sorters/quick_sort.py +0 -0
  192. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/datapack/sorters/selection_sort.py +0 -0
  193. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/finalyze/basic_datapack_structure/__init__.py +0 -0
  194. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/finalyze/check_unused_textures/__init__.py +0 -0
  195. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/finalyze/custom_blocks_ticking/__init__.py +0 -0
  196. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/finalyze/last_final/__init__.py +0 -0
  197. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/__init__.py +0 -0
  198. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/furnace.png +0 -0
  199. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/heavy_workbench.png +0 -0
  200. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/invisible_item.png +0 -0
  201. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/invisible_item_release.png +0 -0
  202. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/minecraft_font.ttf +0 -0
  203. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/none.png +0 -0
  204. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/none_release.png +0 -0
  205. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/pulverizing.png +0 -0
  206. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/shaped_2x2.png +0 -0
  207. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/shaped_3x3.png +0 -0
  208. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/simple_case_no_border.png +0 -0
  209. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/wiki_information.png +0 -0
  210. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft.png +0 -0
  211. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft_template.png +0 -0
  212. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/assets/wiki_result_of_craft.png +0 -0
  213. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/book_optimizer.py +0 -0
  214. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/iso_renders.py +0 -0
  215. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/showcase_image.py +0 -0
  216. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/.gitignore +0 -0
  217. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/furnace.png +0 -0
  218. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/heavy_workbench.png +0 -0
  219. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/invisible_item.png +0 -0
  220. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/invisible_item_release.png +0 -0
  221. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/minecraft_font.ttf +0 -0
  222. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/none.png +0 -0
  223. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/none_release.png +0 -0
  224. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/pulverizing.png +0 -0
  225. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/shaped_2x2.png +0 -0
  226. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/shaped_3x3.png +0 -0
  227. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/simple_case_no_border.png +0 -0
  228. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/wiki_information.png +0 -0
  229. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/wiki_ingredient_of_craft.png +0 -0
  230. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/wiki_ingredient_of_craft_template.png +0 -0
  231. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/templates/wiki_result_of_craft.png +0 -0
  232. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/ingame_manual/text_components.py +0 -0
  233. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/initialize/source_lore_font.py +0 -0
  234. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/merge_smithed_weld/__init__.py +0 -0
  235. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/merge_smithed_weld/weld.py +0 -0
  236. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/resource_pack/check_power_of_2/__init__.py +0 -0
  237. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/resource_pack/item_models/__init__.py +0 -0
  238. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/resource_pack/item_models/object.py +0 -0
  239. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/plugins/resource_pack/sounds/__init__.py +0 -0
  240. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/py.typed +0 -0
  241. {stewbeet-2.1.8 → stewbeet-2.2.1}/stewbeet/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stewbeet
3
- Version: 2.1.8
3
+ Version: 2.2.1
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.1.8"
8
+ version = "2.2.1"
9
9
  description = "Beet Framework made to help generating advanced Minecraft datapack contents"
10
10
  readme = "README.md"
11
11
  license = "MIT"
@@ -0,0 +1,47 @@
1
+
2
+ # Imports
3
+ import os
4
+
5
+ from stouputils.continuous_delivery.cd_utils import load_credentials # type: ignore # noqa: F401
6
+
7
+ from ..core.constants import LATEST_MC_VERSION
8
+ from ..utils import ProjectConfig, get_project_config
9
+
10
+
11
+ # Function that replace the "~" by the user's home directory
12
+ def replace_tilde(path: str) -> str:
13
+ return path.replace("~", os.path.expanduser("~"))
14
+
15
+ # Supported versions
16
+ def get_supported_versions(version: str | None = None) -> list[str]:
17
+ """ Get the supported versions for a given version of Minecraft
18
+
19
+ Args:
20
+ version (str): Version of Minecraft
21
+ Returns:
22
+ list[str]: List of supported versions, ex: ["1.21.3", "1.21.2"]
23
+ """
24
+ # If version is None, get it from the project config, otherwise use the default version
25
+ if version is None:
26
+ try:
27
+ config: ProjectConfig = get_project_config()
28
+ version = config.minecraft or LATEST_MC_VERSION
29
+ except AssertionError:
30
+ version = LATEST_MC_VERSION
31
+
32
+ # Some versions are considered the same for compatibility purposes
33
+ sames: list[list[str]] = [
34
+ ["1.21", "1.21", "1.21.1"],
35
+ ["1.21.2", "1.21.3"],
36
+ ["1.21.6", "1.21.7", "1.21.8"],
37
+ ["1.21.9", "1.21.10"],
38
+ ]
39
+
40
+ # Find the matching list of versions
41
+ for s in sames:
42
+ if version in s:
43
+ return s
44
+
45
+ # If no match, return the version itself in a list
46
+ return [version]
47
+
@@ -2,13 +2,55 @@
2
2
  # ruff: noqa: E501, RUF012
3
3
  # Imports
4
4
  from beet.core.utils import JsonDict
5
+ from beet.library import base
5
6
 
6
7
  from ..dependencies.bookshelf import BOOKSHELF_MODULES
7
8
 
8
- # Minecraft version constants
9
- MINECRAFT_VERSION: str = "1.21.8" # Text used when loading the datapack to warn the user when the data version is not right
10
- DATA_VERSION: int = 4435 # Depending on MC version, given by /data get entity @p DataVersion to check if the datapack is not running in an older version of MC
11
-
9
+ # Minecraft version specific constants
10
+ MORE_DATA_PACK_FORMATS: dict[tuple[int, ...], int] = {
11
+ (1, 21): 48,
12
+ (1, 21, 0): 48,
13
+ (1, 21, 1): 48,
14
+ (1, 21, 2): 57,
15
+ (1, 21, 3): 57,
16
+ (1, 21, 4): 61,
17
+ (1, 21, 5): 71,
18
+ (1, 21, 6): 80,
19
+ (1, 21, 7): 81,
20
+ (1, 21, 8): 81,
21
+ (1, 21, 9): 88,
22
+ (1, 21, 10): 88,
23
+ }
24
+ MORE_ASSETS_PACK_FORMATS: dict[tuple[int, ...], int] = {
25
+ (1, 21): 34,
26
+ (1, 21, 0): 34,
27
+ (1, 21, 1): 34,
28
+ (1, 21, 2): 42,
29
+ (1, 21, 3): 42,
30
+ (1, 21, 4): 46,
31
+ (1, 21, 5): 55,
32
+ (1, 21, 6): 63,
33
+ (1, 21, 7): 64,
34
+ (1, 21, 8): 64,
35
+ (1, 21, 9): 69,
36
+ (1, 21, 10): 69,
37
+ }
38
+ MORE_DATA_VERSIONS: dict[tuple[int, ...], int] = {
39
+ (1, 21): 3953,
40
+ (1, 21, 0): 3953,
41
+ (1, 21, 1): 3955,
42
+ (1, 21, 2): 4080,
43
+ (1, 21, 3): 4082,
44
+ (1, 21, 4): 4189,
45
+ (1, 21, 5): 4325,
46
+ (1, 21, 6): 4435,
47
+ (1, 21, 7): 4438,
48
+ (1, 21, 8): 4440,
49
+ (1, 21, 9): 4554,
50
+ (1, 21, 10): 4556,
51
+ }
52
+ LATEST_MC_VERSION: str = ".".join(str(x) for x in list(MORE_DATA_VERSIONS.keys())[-1])
53
+ base.LATEST_MINECRAFT_VERSION = LATEST_MC_VERSION
12
54
 
13
55
  # Databases
14
56
  CATEGORY: str = "category" # Key for the category, used for recipes and the manual, ex: CATEGORY:"material" or CATEGORY:"equipment"
@@ -22,7 +64,8 @@ VANILLA_BLOCK_FOR_ORES: JsonDict = {"id":"minecraft:polished_deepslate", "apply_
22
64
  OVERRIDE_MODEL: str = "override_model" # Key to a dictionnary that will be used to override the whole model
23
65
  PULVERIZING: str = "simplenergy_pulverizing" # Value of a recipe type, used to generate dusts from ores (used by SimplEnergy)
24
66
  SMITHED_CRAFTER_COMMAND: str = "smithed_crafter_command" # Key to a command that will be used in a recipe in the Smithed Crafter library. If not present, the command will be defaulted to a loot table. Ex: {"result":...,SMITHED_CRAFTER_COMMAND: "function your_namespace:calls/smithed_crafter/do_something_else"}
25
- WIKI_COMPONENT: str = "wiki_components" # Key to a text component that will be used to generate the wiki button in the manual
67
+ GROWING_SEED: str = "staged_seed" # Key to a seed that has multiple growth stages, value needs to be a dict like {"texture_basename":"wheat","stages":8,"seconds":600,"planted_on":"stone","loots":[{"id":"minecraft:wheat_seeds","min_count":1,"max_count":3}]} where loots can be either this format or a loot table path "namespace:blocks/loot_table_name"
68
+ WIKI_COMPONENT: str = "wiki_components" # Key to a text component that will be used to generate the wiki button in the manual
26
69
  RESULT_OF_CRAFTING: str = "result_of_crafting" # Key to a list of recipes to craft the item, ex: "adamantium": {RESULT_OF_CRAFTING: [...]}
27
70
  USED_FOR_CRAFTING: str = "used_for_crafting" # Should not be used unless you are crafting a vanilla item (ex: iyc.chainmail -> chainmail armor)
28
71
  NOT_COMPONENTS: list[str] = [ # Keys that should not be considered as components. Used for recipes, loot tables, etc.
@@ -35,6 +78,7 @@ NOT_COMPONENTS: list[str] = [ # Keys that should not be considered as comp
35
78
  NO_SILK_TOUCH_DROP,
36
79
  OVERRIDE_MODEL,
37
80
  SMITHED_CRAFTER_COMMAND,
81
+ GROWING_SEED,
38
82
  ]
39
83
 
40
84
  # Technical constants
@@ -32,13 +32,15 @@ class DefaultOre(Enum):
32
32
  DIAMOND = "diamond"
33
33
  IRON = "iron"
34
34
  GOLD = "golden"
35
- CHAINMAIL = "stone" # stone tools
36
- LEATHER = "wooden" # wood tools
35
+ CHAINMAIL = "stone" # Stone tools
36
+ COPPER = "copper" # Copper added in 1.21.9
37
+ LEATHER = "wooden" # Wooden tools
37
38
 
38
39
  class VanillaEquipments(Enum):
39
40
  """ Default vanilla equipments values (durability, armor, armor_toughness, knockback_resistance, attack_damage, attack_speed) """
40
41
  HELMET = cast(dict[DefaultOre, dict[str, float]],
41
42
  { DefaultOre.LEATHER: {"durability": 55, "armor": 1},
43
+ DefaultOre.COPPER: {"durability": 121, "armor": 2},
42
44
  DefaultOre.CHAINMAIL: {"durability": 165, "armor": 2},
43
45
  DefaultOre.IRON: {"durability": 165, "armor": 2},
44
46
  DefaultOre.GOLD: {"durability": 77, "armor": 2},
@@ -47,6 +49,7 @@ class VanillaEquipments(Enum):
47
49
  })
48
50
  CHESTPLATE = cast(dict[DefaultOre, dict[str, float]],
49
51
  { DefaultOre.LEATHER: {"durability": 80, "armor": 3},
52
+ DefaultOre.COPPER: {"durability": 176, "armor": 4},
50
53
  DefaultOre.CHAINMAIL: {"durability": 240, "armor": 5},
51
54
  DefaultOre.IRON: {"durability": 240, "armor": 6},
52
55
  DefaultOre.GOLD: {"durability": 112, "armor": 5},
@@ -55,6 +58,7 @@ class VanillaEquipments(Enum):
55
58
  })
56
59
  LEGGINGS = cast(dict[DefaultOre, dict[str, float]],
57
60
  { DefaultOre.LEATHER: {"durability": 75, "armor": 2},
61
+ DefaultOre.COPPER: {"durability": 165, "armor": 3},
58
62
  DefaultOre.CHAINMAIL: {"durability": 225, "armor": 4},
59
63
  DefaultOre.IRON: {"durability": 225, "armor": 5},
60
64
  DefaultOre.GOLD: {"durability": 105, "armor": 3},
@@ -63,6 +67,7 @@ class VanillaEquipments(Enum):
63
67
  })
64
68
  BOOTS = cast(dict[DefaultOre, dict[str, float]],
65
69
  { DefaultOre.LEATHER: {"durability": 65, "armor": 1},
70
+ DefaultOre.COPPER: {"durability": 143, "armor": 1},
66
71
  DefaultOre.CHAINMAIL: {"durability": 195, "armor": 1},
67
72
  DefaultOre.IRON: {"durability": 195, "armor": 2},
68
73
  DefaultOre.GOLD: {"durability": 95, "armor": 1},
@@ -71,6 +76,7 @@ class VanillaEquipments(Enum):
71
76
  })
72
77
  SWORD = cast(dict[DefaultOre, dict[str, float]],
73
78
  { DefaultOre.LEATHER: {"durability": 59, "attack_damage": 4, "attack_speed": -2.40},
79
+ DefaultOre.COPPER: {"durability": 190, "attack_damage": 5, "attack_speed": -2.40},
74
80
  DefaultOre.CHAINMAIL: {"durability": 131, "attack_damage": 5, "attack_speed": -2.40},
75
81
  DefaultOre.IRON: {"durability": 250, "attack_damage": 6, "attack_speed": -2.40},
76
82
  DefaultOre.GOLD: {"durability": 32, "attack_damage": 4, "attack_speed": -2.40},
@@ -79,6 +85,7 @@ class VanillaEquipments(Enum):
79
85
  })
80
86
  PICKAXE = cast(dict[DefaultOre, dict[str, float]],
81
87
  { DefaultOre.LEATHER: {"durability": 59, "attack_damage": 2, "attack_speed": -2.8},
88
+ DefaultOre.COPPER: {"durability": 190, "attack_damage": 3, "attack_speed": -2.8},
82
89
  DefaultOre.CHAINMAIL: {"durability": 131, "attack_damage": 3, "attack_speed": -2.8},
83
90
  DefaultOre.IRON: {"durability": 250, "attack_damage": 4, "attack_speed": -2.8},
84
91
  DefaultOre.GOLD: {"durability": 32, "attack_damage": 2, "attack_speed": -2.8},
@@ -87,6 +94,7 @@ class VanillaEquipments(Enum):
87
94
  })
88
95
  AXE = cast(dict[DefaultOre, dict[str, float]],
89
96
  { DefaultOre.LEATHER: {"durability": 59, "attack_damage": 7, "attack_speed": -3.20},
97
+ DefaultOre.COPPER: {"durability": 190, "attack_damage": 9, "attack_speed": -3.20},
90
98
  DefaultOre.CHAINMAIL: {"durability": 131, "attack_damage": 9, "attack_speed": -3.20},
91
99
  DefaultOre.IRON: {"durability": 250, "attack_damage": 9, "attack_speed": -3.10},
92
100
  DefaultOre.GOLD: {"durability": 32, "attack_damage": 7, "attack_speed": -3.00},
@@ -95,6 +103,7 @@ class VanillaEquipments(Enum):
95
103
  })
96
104
  SHOVEL = cast(dict[DefaultOre, dict[str, float]],
97
105
  { DefaultOre.LEATHER: {"durability": 59, "attack_damage": 2.5, "attack_speed": -3.00},
106
+ DefaultOre.COPPER: {"durability": 190, "attack_damage": 3.5, "attack_speed": -3.00},
98
107
  DefaultOre.CHAINMAIL: {"durability": 131, "attack_damage": 3.5, "attack_speed": -3.00},
99
108
  DefaultOre.IRON: {"durability": 250, "attack_damage": 4.5, "attack_speed": -3.00},
100
109
  DefaultOre.GOLD: {"durability": 32, "attack_damage": 2.5, "attack_speed": -3.00},
@@ -103,6 +112,7 @@ class VanillaEquipments(Enum):
103
112
  })
104
113
  HOE = cast(dict[DefaultOre, dict[str, float]],
105
114
  { DefaultOre.LEATHER: {"durability": 59, "attack_damage": 1, "attack_speed": -3.00},
115
+ DefaultOre.COPPER: {"durability": 190, "attack_damage": 1, "attack_speed": -2.00},
106
116
  DefaultOre.CHAINMAIL: {"durability": 131, "attack_damage": 1, "attack_speed": -2.00},
107
117
  DefaultOre.IRON: {"durability": 250, "attack_damage": 1, "attack_speed": -1.00},
108
118
  DefaultOre.GOLD: {"durability": 32, "attack_damage": 1, "attack_speed": -3.00},
@@ -114,51 +114,57 @@ def generate_everything_about_this_material(
114
114
 
115
115
 
116
116
  ## Armor (helmet, chestplate, leggings, boots)
117
- for gear in ["helmet", "chestplate", "leggings", "boots"]:
118
- armor = material_base + "_" + gear
119
- if armor + ".png" not in textures:
120
- continue
121
- if armor not in Mem.definitions:
122
- Mem.definitions[armor] = {}
123
- Mem.definitions[armor]["id"] = f"minecraft:leather_{gear}" # Leather armor by default
124
- Mem.definitions[armor][CATEGORY] = "equipment" # Category
125
- Mem.definitions[armor]["custom_data"] = {"smithed":{}} # Smithed convention
126
- Mem.definitions[armor]["custom_data"]["smithed"]["dict"] = {"armor": {material_base: True, gear: True}}
127
- gear_config = {}
128
- if gear == "helmet":
129
- if not ignore_recipes:
130
- Mem.definitions[armor][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XXX","X X"],"ingredients":{"X": main_ingredient}}]
131
- if equipments_config:
132
- gear_config = VanillaEquipments.HELMET.value[equipments_config.equivalent_to]
133
- Mem.definitions[armor]["max_damage"] = int(gear_config["durability"] * durability_factor)
134
- if top_layer:
135
- Mem.definitions[armor]["equippable"] = {"slot":"head", "asset_id":f"{Mem.ctx.project_id}:{material_base}"}
136
- elif gear == "chestplate":
137
- if not ignore_recipes:
138
- Mem.definitions[armor][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["X X","XXX","XXX"],"ingredients":{"X": main_ingredient}}]
117
+ if equipments_config is not None:
118
+ for gear in ["helmet", "chestplate", "leggings", "boots"]:
119
+ armor = material_base + "_" + gear
120
+ if armor + ".png" not in textures:
121
+ continue
122
+ if armor not in Mem.definitions:
123
+ Mem.definitions[armor] = {}
124
+ equivalent_to: str = equipments_config.equivalent_to.value
125
+ if equivalent_to == "stone":
126
+ equivalent_to = "chainmail"
127
+ elif equivalent_to == "wooden":
128
+ equivalent_to = "leather"
129
+ Mem.definitions[armor]["id"] = f"minecraft:{equivalent_to}_{gear}"
130
+ Mem.definitions[armor][CATEGORY] = "equipment" # Category
131
+ Mem.definitions[armor]["custom_data"] = {"smithed":{}} # Smithed convention
132
+ Mem.definitions[armor]["custom_data"]["smithed"]["dict"] = {"armor": {material_base: True, gear: True}}
133
+ gear_config = {}
134
+ if gear == "helmet":
135
+ if not ignore_recipes:
136
+ Mem.definitions[armor][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XXX","X X"],"ingredients":{"X": main_ingredient},"manual_priority":0}]
137
+ if equipments_config:
138
+ gear_config = VanillaEquipments.HELMET.value[equipments_config.equivalent_to]
139
+ Mem.definitions[armor]["max_damage"] = int(gear_config["durability"] * durability_factor)
140
+ if top_layer:
141
+ Mem.definitions[armor]["equippable"] = {"slot":"head", "asset_id":f"{Mem.ctx.project_id}:{material_base}"}
142
+ elif gear == "chestplate":
143
+ if not ignore_recipes:
144
+ Mem.definitions[armor][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["X X","XXX","XXX"],"ingredients":{"X": main_ingredient},"manual_priority":0}]
145
+ if equipments_config:
146
+ gear_config = VanillaEquipments.CHESTPLATE.value[equipments_config.equivalent_to]
147
+ Mem.definitions[armor]["max_damage"] = int(gear_config["durability"] * durability_factor)
148
+ if top_layer:
149
+ Mem.definitions[armor]["equippable"] = {"slot":"chest", "asset_id":f"{Mem.ctx.project_id}:{material_base}"}
150
+ elif gear == "leggings":
151
+ if not ignore_recipes:
152
+ Mem.definitions[armor][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XXX","X X","X X"],"ingredients":{"X": main_ingredient},"manual_priority":0}]
153
+ if equipments_config:
154
+ gear_config = VanillaEquipments.LEGGINGS.value[equipments_config.equivalent_to]
155
+ Mem.definitions[armor]["max_damage"] = int(gear_config["durability"] * durability_factor)
156
+ if bottom_layer:
157
+ Mem.definitions[armor]["equippable"] = {"slot":"legs", "asset_id":f"{Mem.ctx.project_id}:{material_base}"}
158
+ elif gear == "boots":
159
+ if not ignore_recipes:
160
+ Mem.definitions[armor][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["X X","X X"],"ingredients":{"X": main_ingredient},"manual_priority":0}]
161
+ if equipments_config:
162
+ gear_config = VanillaEquipments.BOOTS.value[equipments_config.equivalent_to]
163
+ Mem.definitions[armor]["max_damage"] = int(gear_config["durability"] * durability_factor)
164
+ if bottom_layer:
165
+ Mem.definitions[armor]["equippable"] = {"slot":"feet", "asset_id":f"{Mem.ctx.project_id}:{material_base}"}
139
166
  if equipments_config:
140
- gear_config = VanillaEquipments.CHESTPLATE.value[equipments_config.equivalent_to]
141
- Mem.definitions[armor]["max_damage"] = int(gear_config["durability"] * durability_factor)
142
- if top_layer:
143
- Mem.definitions[armor]["equippable"] = {"slot":"chest", "asset_id":f"{Mem.ctx.project_id}:{material_base}"}
144
- elif gear == "leggings":
145
- if not ignore_recipes:
146
- Mem.definitions[armor][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XXX","X X","X X"],"ingredients":{"X": main_ingredient}}]
147
- if equipments_config:
148
- gear_config = VanillaEquipments.LEGGINGS.value[equipments_config.equivalent_to]
149
- Mem.definitions[armor]["max_damage"] = int(gear_config["durability"] * durability_factor)
150
- if bottom_layer:
151
- Mem.definitions[armor]["equippable"] = {"slot":"legs", "asset_id":f"{Mem.ctx.project_id}:{material_base}"}
152
- elif gear == "boots":
153
- if not ignore_recipes:
154
- Mem.definitions[armor][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["X X","X X"],"ingredients":{"X": main_ingredient}}]
155
- if equipments_config:
156
- gear_config = VanillaEquipments.BOOTS.value[equipments_config.equivalent_to]
157
- Mem.definitions[armor]["max_damage"] = int(gear_config["durability"] * durability_factor)
158
- if bottom_layer:
159
- Mem.definitions[armor]["equippable"] = {"slot":"feet", "asset_id":f"{Mem.ctx.project_id}:{material_base}"}
160
- if equipments_config:
161
- Mem.definitions[armor]["attribute_modifiers"] = format_attributes(equipments_config.get_armor_attributes(), SLOTS[gear], gear_config)
167
+ Mem.definitions[armor]["attribute_modifiers"] = format_attributes(equipments_config.get_armor_attributes(), SLOTS[gear], gear_config)
162
168
 
163
169
  # Tools (sword, pickaxe, axe, shovel, hoe)
164
170
  for gear in ["sword", "pickaxe", "axe", "shovel", "hoe"]:
@@ -179,31 +185,31 @@ def generate_everything_about_this_material(
179
185
  gear_config = VanillaEquipments.SWORD.value[equipments_config.equivalent_to]
180
186
  Mem.definitions[tool]["max_damage"] = int(gear_config["durability"] * durability_factor)
181
187
  if not ignore_recipes:
182
- Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["X","X","S"],"ingredients": tools_ingr}]
188
+ Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["X","X","S"],"ingredients": tools_ingr,"manual_priority":0}]
183
189
  elif gear == "pickaxe":
184
190
  if equipments_config:
185
191
  gear_config = VanillaEquipments.PICKAXE.value[equipments_config.equivalent_to]
186
192
  Mem.definitions[tool]["max_damage"] = int(gear_config["durability"] * durability_factor)
187
193
  if not ignore_recipes:
188
- Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XXX"," S "," S "],"ingredients": tools_ingr}]
194
+ Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XXX"," S "," S "],"ingredients": tools_ingr,"manual_priority":0}]
189
195
  elif gear == "axe":
190
196
  if equipments_config:
191
197
  gear_config = VanillaEquipments.AXE.value[equipments_config.equivalent_to]
192
198
  Mem.definitions[tool]["max_damage"] = int(gear_config["durability"] * durability_factor)
193
199
  if not ignore_recipes:
194
- Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XX","XS"," S"],"ingredients": tools_ingr}]
200
+ Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XX","XS"," S"],"ingredients": tools_ingr,"manual_priority":0}]
195
201
  elif gear == "shovel":
196
202
  if equipments_config:
197
203
  gear_config = VanillaEquipments.SHOVEL.value[equipments_config.equivalent_to]
198
204
  Mem.definitions[tool]["max_damage"] = int(gear_config["durability"] * durability_factor)
199
205
  if not ignore_recipes:
200
- Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["X","S","S"],"ingredients": tools_ingr}]
206
+ Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["X","S","S"],"ingredients": tools_ingr,"manual_priority":0}]
201
207
  elif gear == "hoe":
202
208
  if equipments_config:
203
209
  gear_config = VanillaEquipments.HOE.value[equipments_config.equivalent_to]
204
210
  Mem.definitions[tool]["max_damage"] = int(gear_config["durability"] * durability_factor)
205
211
  if not ignore_recipes:
206
- Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XX"," S"," S"],"ingredients": tools_ingr}]
212
+ Mem.definitions[tool][RESULT_OF_CRAFTING] = [{"type":"crafting_shaped","result_count":1,"category":"equipment","shape":["XX"," S"," S"],"ingredients": tools_ingr,"manual_priority":0}]
207
213
  if equipments_config:
208
214
  Mem.definitions[tool]["attribute_modifiers"] = format_attributes(equipments_config.get_tools_attributes(), SLOTS[gear], gear_config)
209
215
  if gear == "sword": # Remove the mining_efficiency attribute from swords
@@ -14,7 +14,16 @@ from .constants import NOT_COMPONENTS, PULVERIZING
14
14
  # Recipes constants
15
15
  FURNACES_RECIPES_TYPES: tuple[str, ...] = ("smelting", "blasting", "smoking", "campfire_cooking")
16
16
  CRAFTING_RECIPES_TYPES: tuple[str, ...] = ("crafting_shaped", "crafting_shapeless")
17
+ OTHER_RECIPES_TYPES: tuple[str, ...] = ("smithing_transform", "smithing_trim", "stonecutting")
18
+ UNUSED_RECIPES_TYPES: tuple[str, ...] = (
19
+ "crafting_decorated_pot", "crafting_special_armordye", "crafting_special_bannerduplicate",
20
+ "crafting_special_bookcloning", "crafting_special_firework_rocket", "crafting_special_firework_star",
21
+ "crafting_special_firework_star_fade", "crafting_special_mapcloning", "crafting_special_mapextending",
22
+ "crafting_special_repairitem", "crafting_special_shielddecoration", "crafting_special_tippedarrow",
23
+ "crafting_transmute",
24
+ )
17
25
  SPECIAL_RECIPES_TYPES: tuple[str, ...] = (PULVERIZING, )
26
+ ALL_RECIPES_TYPES: tuple[str, ...] = (*FURNACES_RECIPES_TYPES, *CRAFTING_RECIPES_TYPES, *OTHER_RECIPES_TYPES, *UNUSED_RECIPES_TYPES, *SPECIAL_RECIPES_TYPES)
18
27
 
19
28
  # Function mainly used for definitions generation
20
29
  @simple_cache
@@ -69,6 +78,8 @@ def ingr_to_id(ingredient: JsonDict, add_namespace: bool = True) -> str:
69
78
  Returns:
70
79
  str: The id of the ingredient, ex: "minecraft:stick" or "iyc:adamantium_ingot"
71
80
  """
81
+ if isinstance(ingredient, str):
82
+ ingredient = {"item": ingredient}
72
83
  if ingredient.get("item"):
73
84
  if not add_namespace:
74
85
  return ingredient["item"].split(":")[1]
@@ -103,6 +114,8 @@ def get_vanilla_item_id_from_ingredient(ingredient: JsonDict, add_namespace: boo
103
114
  Returns:
104
115
  str: The id of the vanilla item, ex: "minecraft:stick"
105
116
  """
117
+ if isinstance(ingredient, str):
118
+ ingredient = {"item": ingredient}
106
119
  ns, ingr_id = ingr_to_id(ingredient).split(":")
107
120
  if ns == Mem.ctx.project_id:
108
121
  if add_namespace:
@@ -132,6 +145,8 @@ def get_item_from_ingredient(ingredient: JsonDict) -> JsonDict:
132
145
  Returns:
133
146
  dict: The item data dict, ex: {"id": "minecraft:stick", "count": 1}
134
147
  """
148
+ if isinstance(ingredient, str):
149
+ ingredient = {"item": ingredient}
135
150
  ingr_id = ingr_to_id(ingredient)
136
151
  ns, id = ingr_id.split(":")
137
152
 
@@ -154,6 +154,9 @@ class SmithedRecipeHandler:
154
154
  crafts += list(data.get("used_for_crafting", []))
155
155
 
156
156
  for recipe in crafts:
157
+ if recipe.get("type") not in ["crafting_shapeless", "crafting_shaped"]:
158
+ continue
159
+
157
160
  # Get ingredients
158
161
  ingr = recipe.get("ingredients", {})
159
162
  if not ingr:
@@ -170,7 +173,7 @@ class SmithedRecipeHandler:
170
173
  ingr = [recipe.get("ingredient", {})]
171
174
 
172
175
  # If there is a component in the ingredients of shaped/shapeless, use smithed crafter
173
- if recipe.get("type") in ["crafting_shapeless", "crafting_shaped"] and any(i.get("components") for i in ingr):
176
+ if any(i.get("components") for i in ingr):
174
177
  if not official_lib_used("smithed.crafter"):
175
178
  debug("Found a crafting table recipe using custom item in ingredients, adding 'smithed.crafter' dependency")
176
179
 
@@ -7,19 +7,25 @@ from beet.core.utils import JsonDict
7
7
  from stouputils.decorators import simple_cache
8
8
 
9
9
  from ...core.__memory__ import Mem
10
- from ...core.ingredients import get_ingredients_from_recipe, get_item_from_ingredient, get_vanilla_item_id_from_ingredient, ingr_repr, item_to_id_ingr_repr
10
+ from ...core.ingredients import (
11
+ FURNACES_RECIPES_TYPES,
12
+ get_ingredients_from_recipe,
13
+ get_item_from_ingredient,
14
+ get_vanilla_item_id_from_ingredient,
15
+ ingr_repr,
16
+ item_to_id_ingr_repr,
17
+ )
11
18
  from ...core.utils.io import set_json_encoder, write_function
12
19
 
13
20
 
14
21
  class VanillaRecipeHandler:
15
22
  """ Handler for vanilla recipe generation.
16
23
 
17
- This class handles the generation of vanilla recipes (shapeless, shaped, furnace).
24
+ This class handles the generation of vanilla recipes (shapeless, shaped, furnace, ...).
18
25
  """
19
26
 
20
27
  def __init__(self) -> None:
21
28
  """ Initialize the handler. """
22
- self.SMELTING: list[str] = ["smelting", "blasting", "smoking"]
23
29
  self.vanilla_generated_recipes: list[tuple[str, str]] = []
24
30
 
25
31
  @classmethod
@@ -166,6 +172,86 @@ advancement revoke @s only {Mem.ctx.project_id}:unlock_recipes
166
172
  to_return["result"]["count"] = recipe["result_count"]
167
173
  return to_return
168
174
 
175
+ @simple_cache()
176
+ def vanilla_stonecutting_recipe(self, recipe: JsonDict, item: str) -> JsonDict:
177
+ """ Generate a vanilla stonecutting recipe.
178
+
179
+ Args:
180
+ recipe (Dict[str, Any]): The recipe data.
181
+ item (str): The item to generate the recipe for.
182
+
183
+ Returns:
184
+ Dict[str, Any]: The generated recipe.
185
+ """
186
+ result_ingr = ingr_repr(item, Mem.ctx.project_id) if not recipe.get("result") else recipe["result"]
187
+ ingredient_vanilla: str = get_vanilla_item_id_from_ingredient(recipe["ingredient"])
188
+
189
+ to_return: JsonDict = {
190
+ "type": "minecraft:" + recipe["type"],
191
+ "group": recipe.get("group"),
192
+ "ingredient": ingredient_vanilla,
193
+ "result": item_to_id_ingr_repr(get_item_from_ingredient(result_ingr)),
194
+ }
195
+
196
+ if not to_return["group"]:
197
+ del to_return["group"]
198
+
199
+ to_return["result"]["count"] = recipe["result_count"]
200
+ return to_return
201
+
202
+ @simple_cache()
203
+ def vanilla_smithing_transform_recipe(self, recipe: JsonDict, item: str) -> JsonDict:
204
+ """ Generate a vanilla smithing transform recipe.
205
+
206
+ Args:
207
+ recipe (Dict[str, Any]): The recipe data.
208
+ item (str): The item to generate the recipe for.
209
+
210
+ Returns:
211
+ Dict[str, Any]: The generated recipe.
212
+ """
213
+ result_ingr = ingr_repr(item, Mem.ctx.project_id) if not recipe.get("result") else recipe["result"]
214
+ base_vanilla: str = get_vanilla_item_id_from_ingredient(recipe["base"])
215
+ addition_vanilla: str = get_vanilla_item_id_from_ingredient(recipe["addition"])
216
+ template_vanilla: str = get_vanilla_item_id_from_ingredient(recipe["template"])
217
+
218
+ to_return: JsonDict = {
219
+ "type": "minecraft:" + recipe["type"],
220
+ "base": base_vanilla,
221
+ "addition": addition_vanilla,
222
+ "template": template_vanilla,
223
+ "result": item_to_id_ingr_repr(get_item_from_ingredient(result_ingr)),
224
+ }
225
+
226
+ to_return["result"]["count"] = recipe["result_count"]
227
+ return to_return
228
+
229
+ @simple_cache()
230
+ def vanilla_smithing_trim_recipe(self, recipe: JsonDict, item: str) -> JsonDict:
231
+ """ Generate a vanilla smithing trim recipe.
232
+
233
+ Args:
234
+ recipe (Dict[str, Any]): The recipe data.
235
+ item (str): The item to generate the recipe for.
236
+
237
+ Returns:
238
+ Dict[str, Any]: The generated recipe.
239
+ """
240
+ base_vanilla: str = get_vanilla_item_id_from_ingredient(recipe["base"])
241
+ addition_vanilla: str = get_vanilla_item_id_from_ingredient(recipe["addition"])
242
+ template_vanilla: str = get_vanilla_item_id_from_ingredient(recipe["template"])
243
+ pattern_vanilla: str = get_vanilla_item_id_from_ingredient(recipe["pattern"])
244
+
245
+ to_return: JsonDict = {
246
+ "type": "minecraft:" + recipe["type"],
247
+ "base": base_vanilla,
248
+ "addition": addition_vanilla,
249
+ "template": template_vanilla,
250
+ "pattern": pattern_vanilla,
251
+ }
252
+
253
+ return to_return
254
+
169
255
  def generate_recipes(self) -> None:
170
256
  """ Generate all vanilla recipes. """
171
257
  for item, data in Mem.definitions.items():
@@ -196,13 +282,48 @@ advancement revoke @s only {Mem.ctx.project_id}:unlock_recipes
196
282
  i += 1
197
283
  self.vanilla_generated_recipes.append((name, item))
198
284
 
199
- elif recipe["type"] in [*self.SMELTING, "campfire_cooking"]:
285
+ elif recipe["type"] in FURNACES_RECIPES_TYPES:
200
286
  if isinstance(ingr, dict) and cast(JsonDict, ingr).get("item"):
201
287
  r = self.vanilla_furnace_recipe(recipe, item)
202
288
  self.write_recipe_file(name, r)
203
289
  i += 1
204
290
  self.vanilla_generated_recipes.append((name, item))
205
291
 
292
+ elif recipe["type"] == "stonecutting":
293
+ if isinstance(ingr, dict) and cast(JsonDict, ingr).get("item"):
294
+ r = self.vanilla_stonecutting_recipe(recipe, item)
295
+ self.write_recipe_file(name, r)
296
+ i += 1
297
+ self.vanilla_generated_recipes.append((name, item))
298
+
299
+ elif recipe["type"] == "smithing_transform":
300
+ # Check if all required ingredients are present
301
+ base = recipe.get("base", {})
302
+ addition = recipe.get("addition", {})
303
+ template = recipe.get("template", {})
304
+ if (isinstance(base, dict) and cast(JsonDict, base).get("item") and
305
+ isinstance(addition, dict) and cast(JsonDict, addition).get("item") and
306
+ isinstance(template, dict) and cast(JsonDict, template).get("item")):
307
+ r = self.vanilla_smithing_transform_recipe(recipe, item)
308
+ self.write_recipe_file(name, r)
309
+ i += 1
310
+ self.vanilla_generated_recipes.append((name, item))
311
+
312
+ elif recipe["type"] == "smithing_trim":
313
+ # Check if all required ingredients are present
314
+ base = recipe.get("base", {})
315
+ addition = recipe.get("addition", {})
316
+ template = recipe.get("template", {})
317
+ pattern = recipe.get("pattern", {})
318
+ if (isinstance(base, dict) and cast(JsonDict, base).get("item") and
319
+ isinstance(addition, dict) and cast(JsonDict, addition).get("item") and
320
+ isinstance(template, dict) and cast(JsonDict, template).get("item") and
321
+ isinstance(pattern, dict) and cast(JsonDict, pattern).get("item")):
322
+ r = self.vanilla_smithing_trim_recipe(recipe, item)
323
+ self.write_recipe_file(name, r)
324
+ i += 1
325
+ self.vanilla_generated_recipes.append((name, item))
326
+
206
327
  def write_recipe_file(self, name: str, content: JsonDict) -> None:
207
328
  """ Write a recipe file.
208
329
 
@@ -139,7 +139,7 @@ execute as @e[type=item_frame,tag={ns}.new,tag={ns}.{item}] at @s run function {
139
139
 
140
140
  ## Place function
141
141
  content = ""
142
- if block["apply_facing"]:
142
+ if block.get("apply_facing") not in (False, "entity"):
143
143
  content += f"function {ns}:custom_blocks/get_rotation\n"
144
144
  content += "setblock ~ ~ ~ air\n"
145
145
  block_states = []
@@ -152,6 +152,8 @@ execute as @e[type=item_frame,tag={ns}.new,tag={ns}.{item}] at @s run function {
152
152
  else:
153
153
  content += f"execute if score #rotation {ns}.data matches {i+1} run setblock ~ ~ ~ {block_id}[facing={face}]{beautify_name}\n"
154
154
  else:
155
+ if block.get("apply_facing") == "entity":
156
+ content += f"function {ns}:custom_blocks/get_rotation\n"
155
157
  # Simple setblock
156
158
  content += "setblock ~ ~ ~ air\n"
157
159
  content += f"setblock ~ ~ ~ {block_id}{beautify_name}\n"