stewbeet 3.4.3__tar.gz → 3.4.4__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.
Files changed (297) hide show
  1. {stewbeet-3.4.3 → stewbeet-3.4.4}/PKG-INFO +1 -1
  2. {stewbeet-3.4.3 → stewbeet-3.4.4}/pyproject.toml +1 -1
  3. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/__memory__.py +9 -0
  4. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/__memory__.pyi +1 -0
  5. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/check_unused_textures/__init__.py +9 -0
  6. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/api.py +2 -0
  7. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/dialog.py +12 -2
  8. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/glyphs.py +8 -0
  9. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/images.py +18 -0
  10. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/manual.py +1 -0
  11. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/manual_emit.py +36 -3
  12. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/base.py +19 -2
  13. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/item_page.py +8 -0
  14. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/texture_page.py +14 -3
  15. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/renderer.py +34 -0
  16. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/initialize/__init__.py +1 -0
  17. {stewbeet-3.4.3 → stewbeet-3.4.4}/LICENSE +0 -0
  18. {stewbeet-3.4.3 → stewbeet-3.4.4}/README.md +0 -0
  19. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/__init__.py +0 -0
  20. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/__init__.pyi +0 -0
  21. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/__main__.py +0 -0
  22. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/all/__init__.py +0 -0
  23. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/all/__init__.pyi +0 -0
  24. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/all/silent.py +0 -0
  25. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/all/silent.pyi +0 -0
  26. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/cli.py +0 -0
  27. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/cli.pyi +0 -0
  28. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/__init__.py +0 -0
  29. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/__init__.pyi +0 -0
  30. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/cd_utils.py +0 -0
  31. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/cd_utils.pyi +0 -0
  32. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/github.py +0 -0
  33. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/github.pyi +0 -0
  34. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/modrinth.py +0 -0
  35. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/modrinth.pyi +0 -0
  36. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/pmc.py +0 -0
  37. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/pmc.pyi +0 -0
  38. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/smithed.py +0 -0
  39. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/continuous_delivery/smithed.pyi +0 -0
  40. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/__init__.py +0 -0
  41. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/balancing.py +0 -0
  42. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/batteries.py +0 -0
  43. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/cables.py +0 -0
  44. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant.json +0 -0
  45. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_d.json +0 -0
  46. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_de.json +0 -0
  47. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dew.json +0 -0
  48. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dn.json +0 -0
  49. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dne.json +0 -0
  50. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnew.json +0 -0
  51. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dns.json +0 -0
  52. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnse.json +0 -0
  53. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnsew.json +0 -0
  54. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnsw.json +0 -0
  55. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dnw.json +0 -0
  56. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ds.json +0 -0
  57. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dse.json +0 -0
  58. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dsew.json +0 -0
  59. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dsw.json +0 -0
  60. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_dw.json +0 -0
  61. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_e.json +0 -0
  62. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ew.json +0 -0
  63. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_n.json +0 -0
  64. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ne.json +0 -0
  65. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_new.json +0 -0
  66. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ns.json +0 -0
  67. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nse.json +0 -0
  68. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nsew.json +0 -0
  69. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nsw.json +0 -0
  70. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_nw.json +0 -0
  71. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_s.json +0 -0
  72. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_se.json +0 -0
  73. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_sew.json +0 -0
  74. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_sw.json +0 -0
  75. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_u.json +0 -0
  76. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ud.json +0 -0
  77. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ude.json +0 -0
  78. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udew.json +0 -0
  79. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udn.json +0 -0
  80. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udne.json +0 -0
  81. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnew.json +0 -0
  82. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udns.json +0 -0
  83. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnse.json +0 -0
  84. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnsew.json +0 -0
  85. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnsw.json +0 -0
  86. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udnw.json +0 -0
  87. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uds.json +0 -0
  88. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udse.json +0 -0
  89. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udsew.json +0 -0
  90. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udsw.json +0 -0
  91. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_udw.json +0 -0
  92. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_ue.json +0 -0
  93. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uew.json +0 -0
  94. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_un.json +0 -0
  95. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_une.json +0 -0
  96. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unew.json +0 -0
  97. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uns.json +0 -0
  98. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unse.json +0 -0
  99. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unsew.json +0 -0
  100. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unsw.json +0 -0
  101. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_unw.json +0 -0
  102. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_us.json +0 -0
  103. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_use.json +0 -0
  104. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_usew.json +0 -0
  105. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_usw.json +0 -0
  106. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_uw.json +0 -0
  107. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_cable_models/variant_w.json +0 -0
  108. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/energy_lib_calls.py +0 -0
  109. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/gui.py +0 -0
  110. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/item_cable_models/cable.bbmodel +0 -0
  111. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/item_cable_models/cable_base.json +0 -0
  112. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/py.typed +0 -0
  113. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/servo_mechanism_models/base_block.json +0 -0
  114. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/servo_mechanism_models/base_item.json +0 -0
  115. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_block.json +0 -0
  116. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_connected.json +0 -0
  117. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/servo_mechanism_models/extract_item.json +0 -0
  118. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_block.json +0 -0
  119. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_connected.json +0 -0
  120. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/servo_mechanism_models/insert_item.json +0 -0
  121. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/contrib/simplenergy/wrench.py +0 -0
  122. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/__init__.py +0 -0
  123. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/__init__.pyi +0 -0
  124. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/_recipe_list.py +0 -0
  125. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/_utils.py +0 -0
  126. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/block.py +0 -0
  127. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/external_item.py +0 -0
  128. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/ingredients.py +0 -0
  129. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/item.py +0 -0
  130. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/painting.py +0 -0
  131. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/recipe.py +0 -0
  132. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/cls/wiki_button.py +0 -0
  133. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/constants.py +0 -0
  134. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/constants.pyi +0 -0
  135. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/__init__.py +0 -0
  136. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/__init__.pyi +0 -0
  137. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/completion.py +0 -0
  138. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/completion.pyi +0 -0
  139. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/equipments.py +0 -0
  140. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/equipments.pyi +0 -0
  141. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/materials.py +0 -0
  142. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/materials.pyi +0 -0
  143. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/records.py +0 -0
  144. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/records.pyi +0 -0
  145. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/simplenergy.py +0 -0
  146. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/simplenergy.pyi +0 -0
  147. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/smart_ore_generation.py +0 -0
  148. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/smart_ore_generation.pyi +0 -0
  149. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/text.py +0 -0
  150. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/definitions_helper/text.pyi +0 -0
  151. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/dump.py +0 -0
  152. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/dump.pyi +0 -0
  153. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/migrate.py +0 -0
  154. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/migrate.pyi +0 -0
  155. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/template.py +0 -0
  156. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/template.pyi +0 -0
  157. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/utils/equation.py +0 -0
  158. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/utils/io.py +0 -0
  159. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/utils/loot_table.py +0 -0
  160. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/utils/sounds.py +0 -0
  161. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/core/utils/text_component.py +0 -0
  162. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/dependencies/__init__.py +0 -0
  163. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/dependencies/__init__.pyi +0 -0
  164. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/dependencies/download_manager.py +0 -0
  165. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/dependencies/download_manager.pyi +0 -0
  166. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/dependencies/official_libs.py +0 -0
  167. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/dependencies/official_libs.pyi +0 -0
  168. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/archive/__init__.py +0 -0
  169. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/archive/silent.py +0 -0
  170. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/__init__.py +0 -0
  171. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/context_analyzer.py +0 -0
  172. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/execution_parser.py +0 -0
  173. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/function_analyzer.py +0 -0
  174. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/macro_analyzer.py +0 -0
  175. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/macro_parser.py +0 -0
  176. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/object.py +0 -0
  177. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/silent.py +0 -0
  178. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/headers/type_inference.py +0 -0
  179. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/lang_file/__init__.py +0 -0
  180. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/lang_file/silent.py +0 -0
  181. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/lang_file/utils.py +0 -0
  182. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/scoreboard_constants/__init__.py +0 -0
  183. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/auto/scoreboard_constants/silent.py +0 -0
  184. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/compatibilities/neo_enchant/__init__.py +0 -0
  185. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/compatibilities/neo_enchant/silent.py +0 -0
  186. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/compatibilities/simpledrawer/__init__.py +0 -0
  187. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/compatibilities/simpledrawer/silent.py +0 -0
  188. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/compute_sha1/__init__.py +0 -0
  189. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/compute_sha1/silent.py +0 -0
  190. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/copy_to_destination/__init__.py +0 -0
  191. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/copy_to_destination/silent.py +0 -0
  192. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_paintings/__init__.py +0 -0
  193. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_paintings/silent.py +0 -0
  194. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_recipes/__init__.py +0 -0
  195. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_recipes/awakened_forge.py +0 -0
  196. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_recipes/furnace.py +0 -0
  197. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_recipes/pulverizer.py +0 -0
  198. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_recipes/silent.py +0 -0
  199. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_recipes/smithed.py +0 -0
  200. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/custom_recipes/vanilla.py +0 -0
  201. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/custom_blocks/__init__.py +0 -0
  202. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/custom_blocks/silent.py +0 -0
  203. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/loading/__init__.py +0 -0
  204. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/loading/silent.py +0 -0
  205. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/loot_tables/__init__.py +0 -0
  206. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/loot_tables/silent.py +0 -0
  207. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/sorters/__init__.py +0 -0
  208. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/sorters/constants.py +0 -0
  209. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/sorters/extend_datapack.py +0 -0
  210. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/sorters/match.py +0 -0
  211. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/sorters/mod.mcdoc +0 -0
  212. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/sorters/quick_sort.py +0 -0
  213. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/sorters/selection_sort.py +0 -0
  214. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/datapack/sorters/silent.py +0 -0
  215. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/basic_datapack_structure/__init__.py +0 -0
  216. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/basic_datapack_structure/silent.py +0 -0
  217. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/check_unused_textures/silent.py +0 -0
  218. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/custom_blocks_ticking/__init__.py +0 -0
  219. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/custom_blocks_ticking/silent.py +0 -0
  220. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/dependencies/__init__.py +0 -0
  221. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/dependencies/silent.py +0 -0
  222. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/last_final/__init__.py +0 -0
  223. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/last_final/silent.py +0 -0
  224. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/unload/__init__.py +0 -0
  225. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/finalyze/unload/silent.py +0 -0
  226. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/__init__.py +0 -0
  227. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/awakened_forge_1.png +0 -0
  228. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/awakened_forge_2.png +0 -0
  229. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/awakened_forge_3x3.png +0 -0
  230. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/awakened_forge_3x4.png +0 -0
  231. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/book.png +0 -0
  232. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/furnace.png +0 -0
  233. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/heavy_workbench.png +0 -0
  234. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/home.png +0 -0
  235. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/invisible_item.png +0 -0
  236. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/invisible_item_release.png +0 -0
  237. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/minecraft_font.ttf +0 -0
  238. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/mining.png +0 -0
  239. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/none.png +0 -0
  240. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/none_release.png +0 -0
  241. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/pulverizing.png +0 -0
  242. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/shaped_2x2.png +0 -0
  243. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/shaped_3x3.png +0 -0
  244. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/simple_case_no_border.png +0 -0
  245. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/stonecutting.png +0 -0
  246. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/wiki_growing_seed.png +0 -0
  247. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/wiki_information.png +0 -0
  248. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft.png +0 -0
  249. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft_template.png +0 -0
  250. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/wiki_mining_template.png +0 -0
  251. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/assets/wiki_result_of_craft.png +0 -0
  252. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/button_layout.py +0 -0
  253. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/config.py +0 -0
  254. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/iso_renders.py +0 -0
  255. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/optimizer.py +0 -0
  256. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/__init__.py +0 -0
  257. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/browser_page.py +0 -0
  258. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/button_layout.py +0 -0
  259. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/category_page.py +0 -0
  260. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/custom_page.py +0 -0
  261. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/intro_page.py +0 -0
  262. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/pages/raw_page.py +0 -0
  263. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/paths.py +0 -0
  264. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/__init__.py +0 -0
  265. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/buttons.py +0 -0
  266. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/collection.py +0 -0
  267. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/components.py +0 -0
  268. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/hovers.py +0 -0
  269. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/registry.py +0 -0
  270. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/types/__init__.py +0 -0
  271. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/types/awakened_forge.py +0 -0
  272. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/types/furnace.py +0 -0
  273. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/types/linear.py +0 -0
  274. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/types/shaped.py +0 -0
  275. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/recipes/types/smithing.py +0 -0
  276. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/refs.py +0 -0
  277. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/showcase.py +0 -0
  278. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/ingame_manual/special.py +0 -0
  279. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/initialize/silent.py +0 -0
  280. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/initialize/source_lore_font.py +0 -0
  281. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/merge_smithed_weld/__init__.py +0 -0
  282. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/merge_smithed_weld/silent.py +0 -0
  283. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/merge_smithed_weld/weld.py +0 -0
  284. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/resource_pack/check_power_of_2/__init__.py +0 -0
  285. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/resource_pack/check_power_of_2/silent.py +0 -0
  286. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/resource_pack/item_models/__init__.py +0 -0
  287. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/resource_pack/item_models/object.py +0 -0
  288. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/resource_pack/item_models/silent.py +0 -0
  289. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/resource_pack/sounds/__init__.py +0 -0
  290. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/resource_pack/sounds/silent.py +0 -0
  291. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/verify_definitions/__init__.py +0 -0
  292. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/plugins/verify_definitions/silent.py +0 -0
  293. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/py.typed +0 -0
  294. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/silent.py +0 -0
  295. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/silent.pyi +0 -0
  296. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/utils.py +0 -0
  297. {stewbeet-3.4.3 → stewbeet-3.4.4}/stewbeet/utils.pyi +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stewbeet
3
- Version: 3.4.3
3
+ Version: 3.4.4
4
4
  Summary: Beet Framework made to help generating advanced Minecraft datapack contents
5
5
  Author: Stoupy51
6
6
  Author-email: Stoupy51 <stoupy51@gmail.com>
@@ -8,7 +8,7 @@ module-root = ""
8
8
 
9
9
  [project]
10
10
  name = "stewbeet"
11
- version = "3.4.3"
11
+ version = "3.4.4"
12
12
  description = "Beet Framework made to help generating advanced Minecraft datapack contents"
13
13
  readme = "README.md"
14
14
  license = "MIT"
@@ -14,6 +14,8 @@ if TYPE_CHECKING:
14
14
 
15
15
  # Shared variables among plugins
16
16
  class Mem:
17
+
18
+ # Public and should be used
17
19
  ctx: Context = None
18
20
  """ Global context object that holds the beet project configuration.
19
21
  This is set during plugins.initialize and used throughout the codebase. """
@@ -24,7 +26,14 @@ class Mem:
24
26
  external_definitions: dict[str, ExternalItem] = {}
25
27
  """ Secondary JsonDict for storing external items or blocks most likely for recipes. """
26
28
 
29
+
30
+ # Very internal,
27
31
  manual: Manual | None = None
28
32
  """ The ingame_manual Manual handle, used to register pages/hooks during setup.
29
33
  Created lazily via stewbeet.get_manual(); reset after each build (for `beet watch`). """
30
34
 
35
+ used_textures: set[str] = set()
36
+ """ Source texture paths consumed by generators (e.g. manual book_texture / TexturePage
37
+ backgrounds) that get re-encoded under new names. The check_unused_textures plugin treats
38
+ them as used. Reset by plugins.initialize (for `beet watch`). """
39
+
@@ -8,3 +8,4 @@ class Mem:
8
8
  definitions: dict[str, Item]
9
9
  external_definitions: dict[str, ExternalItem]
10
10
  manual: Manual | None
11
+ used_textures: set[str]
@@ -8,6 +8,8 @@ import stouputils as stp
8
8
  from beet import Context, Texture
9
9
  from stouputils.typing import JsonDict
10
10
 
11
+ from ....core.__memory__ import Mem
12
+
11
13
 
12
14
  # Main entry point
13
15
  @stp.measure_time(message="Execution time of 'stewbeet.plugins.finalyze.check_unused_textures'")
@@ -29,8 +31,15 @@ def beet_default(ctx: Context) -> None:
29
31
  textures: set[str] = {stp.relative_path(str(p), textures_folder) for p in Path(textures_folder).rglob("*.png")}
30
32
 
31
33
  # 2) For each texture, check if any of the ctx.assets.textures matches the texture filename.
34
+ # Textures consumed as source files by generators (e.g. manual book_texture / TexturePage
35
+ # backgrounds) are re-encoded under new names, so they never appear in ctx.assets.textures:
36
+ # they are recorded in Mem.used_textures and skipped here.
37
+ consumed: set[str] = {stp.clean_path(p) for p in Mem.used_textures}
32
38
  unused_paths: set[str] = set()
33
39
  for path in textures:
40
+ full_path: str = stp.clean_path(f"{textures_folder}/{path}")
41
+ if any(u == full_path or u.endswith("/" + path) for u in consumed):
42
+ continue
34
43
  # Get just the filename without extension for comparison
35
44
  filename_no_ext: str = os.path.splitext(os.path.basename(path))[0]
36
45
  no_extension_path: str = os.path.splitext(path)[0]
@@ -19,6 +19,7 @@ from .pages import (
19
19
  RawPage,
20
20
  TexturePage,
21
21
  )
22
+ from .paths import template_path
22
23
  from .recipes import CraftRenderer, WikiButtonRender, register_craft_renderer
23
24
  from .refs import PageRef
24
25
 
@@ -41,6 +42,7 @@ __all__ = [
41
42
  "WikiButtonRender",
42
43
  "get_manual",
43
44
  "register_craft_renderer",
45
+ "template_path",
44
46
  ]
45
47
 
46
48
 
@@ -132,10 +132,19 @@ class DialogEmitter:
132
132
  "click_event": {"action": "show_dialog", "dialog": next_dialog_id},
133
133
  "hover_event": {"action": "show_text", "value": [{"text": "Go to next page"}, f" ({next_index + 1})"]},
134
134
  }
135
- nav_contents: list[TextComponent] = [{"text": BOOK_FONT + NONE_FONT * 3, "font": f"{ns}:manual", "color": "white"}]
135
+ # Book background & home button: the page's own override glyphs if set, else the shared ones.
136
+ book_font: str = page_obj.book_font if page_obj is not None and page_obj.book_font else BOOK_FONT
137
+ home_font: str = page_obj.home_font if page_obj is not None and page_obj.home_font else HOME_FONT
138
+ nav_contents: list[TextComponent] = [{"text": book_font + NONE_FONT * 3, "font": f"{ns}:manual", "color": "white"}]
139
+ # No home button on the first page (it IS the home page) or when the page opts out.
140
+ hide_home: bool = page_index == 0 or (page_obj is not None and not page_obj.home_button)
136
141
  for row in range(2):
137
142
  nav_contents.append({"text": "\n" + NONE_FONT * 3, **prev_event})
138
- nav_contents.append({"text": (HOME_FONT if row == 0 else NONE_FONT), "font": f"{ns}:manual", "color": "white", **home_event})
143
+ if hide_home:
144
+ # Keep the spacing but drop the button
145
+ nav_contents.append({"text": NONE_FONT, "font": f"{ns}:manual", "color": "white"})
146
+ else:
147
+ nav_contents.append({"text": (home_font if row == 0 else NONE_FONT), "font": f"{ns}:manual", "color": "white", **home_event})
139
148
  nav_contents.append({"text": NONE_FONT * 3, **next_event})
140
149
 
141
150
  dialog: JsonDict = {
@@ -183,3 +192,4 @@ execute if items entity @s weapon.* *[custom_data~{{{ns}:{{manual:true}}}}] run
183
192
  "dialogs": dialog_ids,
184
193
  "exit_action": {"label": {"translate": "gui.back"}, "width": 200},
185
194
  }))
195
+
@@ -85,6 +85,14 @@ HOVER_EQUIVALENTS: dict[str, str] = {
85
85
  # First dynamically-allocated code point (high-res item icons, wiki result icons, page glyphs...)
86
86
  DEFAULT_NEXT_CRAFT_FONT: int = 0x8000
87
87
 
88
+ # Bitmap placement of the book background glyph (shared BOOK_FONT and per-page overrides)
89
+ BOOK_ASCENT: int = 25
90
+ BOOK_HEIGHT: int = 300
91
+
92
+ # Bitmap placement of the home button glyph (shared HOME_FONT and per-page overrides)
93
+ HOME_ASCENT: int = 8
94
+ HOME_HEIGHT: int = 20
95
+
88
96
  # Misc constants
89
97
  SQUARE_SIZE: int = 32
90
98
  FONT_FILE: str = "manual"
@@ -134,6 +134,8 @@ class GlyphImageBuilder:
134
134
  """ Cache for :meth:`get_border_color`. """
135
135
  _wiki_icons_generated: set[str] = field(default_factory=set[str])
136
136
  """ Wiki icon files already generated this build (skip re-encoding identical PNGs). """
137
+ _spacer_chars: dict[int, str] = field(default_factory=dict[int, str])
138
+ """ Invisible spacer glyph per pixel width (see :meth:`invisible_spacer`). """
137
139
 
138
140
  # --- helpers ---
139
141
  def get_border_color(self) -> tuple[int, int, int, int]:
@@ -290,6 +292,22 @@ class GlyphImageBuilder:
290
292
  return font
291
293
 
292
294
  # --- new texture-page helpers ---
295
+ def invisible_spacer(self, width_px: int) -> str:
296
+ """ Return an invisible glyph advancing exactly ``width_px`` pixels ("" if <= 0).
297
+
298
+ The square ``none`` texture rendered at height ``H`` advances ``H + 1`` pixels, so one
299
+ provider (ascent 0, height ``width_px - 1``) is registered per distinct width, then reused.
300
+ Used by :class:`~.pages.texture_page.TexturePage` left/right paddings.
301
+ """
302
+ if width_px <= 0:
303
+ return ""
304
+ char: str | None = self._spacer_chars.get(width_px)
305
+ if char is None:
306
+ char = self.glyphs.allocate()
307
+ self.glyphs.add_provider(char, f"{self.config.project_id}:font/none.png", ascent=0, height=width_px - 1)
308
+ self._spacer_chars[width_px] = char
309
+ return char
310
+
293
311
  def bake_text_onto(self, background: Image.Image, baked_texts: list[BakedText]) -> Image.Image:
294
312
  """ Draw a list of :class:`BakedText` onto a copy of ``background`` and return it. """
295
313
  out = background.convert("RGBA").copy()
@@ -459,6 +459,7 @@ class Manual:
459
459
  from .showcase import generate_showcase_images
460
460
 
461
461
  manual_emit.register_static_assets(self)
462
+ manual_emit.register_nav_overrides(self)
462
463
  manual_emit.write_font(self)
463
464
  manual_emit.copy_generated_textures(self)
464
465
  manual_emit.validate_providers(self)
@@ -11,6 +11,7 @@ from typing import TYPE_CHECKING
11
11
 
12
12
  import stouputils as stp
13
13
  from beet import Font, Texture
14
+ from PIL import Image
14
15
 
15
16
  from ...core.__memory__ import Mem
16
17
  from ...core.cls.item import Item
@@ -18,9 +19,13 @@ from .glyphs import (
18
19
  AWAKENED_3X3_FONT,
19
20
  AWAKENED_3X4_FONT,
20
21
  AWAKENED_FORGE_STRUCT_FONT,
22
+ BOOK_ASCENT,
21
23
  BOOK_FONT,
24
+ BOOK_HEIGHT,
22
25
  FURNACE_FONT,
26
+ HOME_ASCENT,
23
27
  HOME_FONT,
28
+ HOME_HEIGHT,
24
29
  HOVER_AWAKENED_3X3_FONT,
25
30
  HOVER_AWAKENED_3X4_FONT,
26
31
  HOVER_FURNACE_FONT,
@@ -46,7 +51,7 @@ from .glyphs import (
46
51
  WIKI_NONE_FONT,
47
52
  WIKI_RESULT_OF_CRAFT_FONT,
48
53
  )
49
- from .paths import TEMPLATES_PATH
54
+ from .paths import TEMPLATES_PATH, template_path
50
55
 
51
56
  if TYPE_CHECKING:
52
57
  from .manual import Manual
@@ -122,8 +127,36 @@ def register_static_assets(manual: Manual) -> None:
122
127
  if manual.has_forge_3x3 or manual.has_forge_3x4:
123
128
  add(AWAKENED_FORGE_STRUCT_FONT[0], f("awakened_forge_1"), 8, 56)
124
129
  add(AWAKENED_FORGE_STRUCT_FONT[1], f("awakened_forge_2"), 8, 56)
125
- add(BOOK_FONT, f("book"), 25, 300)
126
- add(HOME_FONT, f("home"), 8, 20) # same advance as NONE_FONT so the prev/next gap stays aligned
130
+ add(BOOK_FONT, f("book"), BOOK_ASCENT, BOOK_HEIGHT)
131
+ add(HOME_FONT, f("home"), HOME_ASCENT, HOME_HEIGHT) # same advance as NONE_FONT so the prev/next gap stays aligned
132
+
133
+
134
+ def load_page_texture(texture: str | Image.Image) -> Image.Image:
135
+ """ Open a per-page override texture. A string resolves as a project path first, then
136
+ against the templates dir (so a ``manual_overrides`` filename works); the source is marked
137
+ used because it gets re-encoded under a new name. """
138
+ if isinstance(texture, str):
139
+ source: str = texture if os.path.exists(texture) else template_path(texture)
140
+ Mem.used_textures.add(source)
141
+ return Image.open(source)
142
+ return texture
143
+
144
+
145
+ def register_nav_overrides(manual: Manual) -> None:
146
+ """ Register dedicated glyphs for every page overriding ``book_texture`` / ``home_texture``.
147
+
148
+ Each glyph replaces ``BOOK_FONT`` / ``HOME_FONT`` in that page's dialog navigation row, with
149
+ the same ascent/height as the shared provider so the layout stays put (a home texture should
150
+ keep the default's 16x16 proportions, since the glyph advance follows the image content).
151
+ """
152
+ for page in manual.pages:
153
+ glyph_suffix: str = page.anchor.replace(":", "_").replace(" ", "_").lower()
154
+ if page.book_texture is not None:
155
+ image = load_page_texture(page.book_texture)
156
+ page.book_font = manual.images.register_full_page_glyph(image.convert("RGBA"), f"book_{glyph_suffix}", ascent=BOOK_ASCENT, height=BOOK_HEIGHT)
157
+ if page.home_texture is not None:
158
+ image = load_page_texture(page.home_texture)
159
+ page.home_font = manual.images.register_full_page_glyph(image.convert("RGBA"), f"home_{glyph_suffix}", ascent=HOME_ASCENT, height=HOME_HEIGHT)
127
160
 
128
161
 
129
162
  def write_font(manual: Manual) -> None:
@@ -12,6 +12,7 @@ from dataclasses import dataclass, field
12
12
  from typing import TYPE_CHECKING
13
13
 
14
14
  from beet.core.utils import TextComponent
15
+ from PIL import Image
15
16
 
16
17
  from ..button_layout import ButtonLayout
17
18
 
@@ -29,11 +30,20 @@ class Page:
29
30
 
30
31
  Attributes:
31
32
  anchor (str): Stable identity used for ordering and deferred links (e.g. "intro",
32
- "category:Materials", "item:wrench"). Must be unique within a manual.
33
+ "category:Materials", "item:wrench"). Must be unique within a manual.
33
34
  title (str): Human-readable page title.
34
35
  item_id (str|None): If this page represents an item, its id (drives ``PageRef(item=...)``
35
- resolution and dialog atlas sprites).
36
+ resolution and dialog atlas sprites).
36
37
  button_layout (ButtonLayout|None): Per-page override of the manual-wide button layout.
38
+ book_texture (str|Image.Image|None): Per-page override of the book background ("book.png").
39
+ A path (project path, or a filename resolved against the templates dir so
40
+ ``manual_overrides`` files work) or a ready PIL image. None = shared book.
41
+ home_texture (str|Image.Image|None): Per-page override of the home button ("home.png"),
42
+ same accepted values as ``book_texture``. Keep the default's 16x16
43
+ proportions so the navigation row stays aligned. None = shared home.
44
+ home_button (bool): Whether this page shows the home button in its navigation row
45
+ (an invisible spacer keeps the prev/next layout when hidden).
46
+ The first page never shows it regardless of this flag.
37
47
  transformers (list): Developer hooks applied to the rendered content, in order.
38
48
 
39
49
  >>> page = Page(anchor="demo", transformers=[lambda content, manual: [*content, "!"]])
@@ -44,6 +54,13 @@ class Page:
44
54
  title: str = ""
45
55
  item_id: str | None = None
46
56
  button_layout: ButtonLayout | None = None
57
+ book_texture: str | Image.Image | None = None
58
+ book_font: str = field(default="", init=False, repr=False)
59
+ """ Glyph char registered for :attr:`book_texture` (set during emit, "" = shared BOOK_FONT). """
60
+ home_texture: str | Image.Image | None = None
61
+ home_font: str = field(default="", init=False, repr=False)
62
+ """ Glyph char registered for :attr:`home_texture` (set during emit, "" = shared HOME_FONT). """
63
+ home_button: bool = True
47
64
  transformers: list[Transformer] = field(default_factory=list[Transformer])
48
65
  optimize: bool = True
49
66
  """ Whether the optimizer may merge this page's components. Set False for pre-built
@@ -7,6 +7,8 @@ emitted as deferred :class:`~..refs.PageRef`.
7
7
  """
8
8
 
9
9
  # Imports
10
+ from __future__ import annotations
11
+
10
12
  import copy
11
13
  from dataclasses import dataclass, field
12
14
  from typing import TYPE_CHECKING, Any, cast
@@ -44,6 +46,9 @@ class ItemPage(Page):
44
46
  """ Every craft related to the item, gathered by :meth:`prepare`. """
45
47
  buttons: list[WikiButtonRender] = field(default_factory=list[WikiButtonRender])
46
48
  """ The wiki buttons rendered on the page (populated during :meth:`build`). """
49
+ extra_buttons: list[WikiButtonRender] = field(default_factory=list[WikiButtonRender])
50
+ """ Developer-added buttons appended after the automatic ones (e.g. another item's recipe
51
+ via ``manual.recipes.button_for_item(...)`` or a page link via ``manual.recipes.link_button(...)``). """
47
52
 
48
53
  @classmethod
49
54
  def for_item(cls, item_id: str, **kwargs: Any) -> ItemPage:
@@ -128,6 +133,9 @@ class ItemPage(Page):
128
133
  previous_result = current_result
129
134
  info_buttons.append(recipes.render_button(craft, name, idx))
130
135
 
136
+ # Developer-added buttons (cross-page recipe buttons, page links...)
137
+ info_buttons += self.extra_buttons
138
+
131
139
  # Combine with the page's button layout
132
140
  self.buttons = info_buttons
133
141
  layout = self.resolve_button_layout(manual)
@@ -14,6 +14,7 @@ from typing import TYPE_CHECKING
14
14
  from beet.core.utils import TextComponent
15
15
  from PIL import Image
16
16
 
17
+ from ....core.__memory__ import Mem
17
18
  from ..images import BakedText
18
19
  from .base import Page
19
20
 
@@ -29,26 +30,36 @@ class TexturePage(Page):
29
30
  background (str|Image.Image): Background image path, or a ready PIL image.
30
31
  baked_texts (list[BakedText]): Texts drawn onto the background with PIL.
31
32
  body (list[TextComponent]): Optional MC text shown under the texture.
32
- glyph_ascent / glyph_height (int): Bitmap placement of the page texture.
33
+ glyph_ascent / glyph_height (int): Bitmap placement of the page texture (size and Y offset).
34
+ left_padding / right_padding (int): Invisible pixels emitted before/after the texture glyph.
35
+ The dialog centers the line, so ``left_padding`` shifts the texture right
36
+ and ``right_padding`` shifts it left, each by half the padding.
33
37
  """
34
38
  background: str | Image.Image = ""
35
39
  baked_texts: list[BakedText] = field(default_factory=list[BakedText])
36
40
  body: list[TextComponent] = field(default_factory=list[TextComponent])
37
41
  glyph_ascent: int = 1
38
42
  glyph_height: int = 131
43
+ left_padding: int = 0
44
+ right_padding: int = 0
39
45
 
40
46
  def build(self, manual: Manual) -> list[TextComponent]:
41
47
  """ Composite the background + baked texts, register it as one glyph, append the body. """
42
48
  config = manual.config
43
- bg = Image.open(self.background) if isinstance(self.background, str) else self.background
49
+ if isinstance(self.background, str):
50
+ Mem.used_textures.add(self.background) # the file is re-encoded under a new name, mark the source as used
51
+ bg = Image.open(self.background)
52
+ else:
53
+ bg = self.background
44
54
  composited = manual.images.bake_text_onto(bg, self.baked_texts) if self.baked_texts else bg.convert("RGBA")
45
55
 
46
56
  glyph_name = self.anchor.replace(":", "_").replace(" ", "_").lower()
47
57
  page_font = manual.images.register_full_page_glyph(composited, glyph_name, ascent=self.glyph_ascent, height=self.glyph_height)
58
+ page_text: str = manual.images.invisible_spacer(self.left_padding) + page_font + manual.images.invisible_spacer(self.right_padding)
48
59
 
49
60
  # Neutral base (default font, no shadow) so the developer body keeps its own font; only the
50
61
  # page-texture glyph is drawn in the manual font. The title is shown by the dialog itself.
51
62
  content: list[TextComponent] = [{"text": "", "shadow_color": [0,0,0,0]}]
52
- content.append({"text": page_font + "\n", "font": config.font, "color": "white"})
63
+ content.append({"text": page_text + "\n", "font": config.font, "color": "white"})
53
64
  content += list(self.body)
54
65
  return content
@@ -184,6 +184,40 @@ class RecipeRenderer:
184
184
  button.target = PageRef(item=craft_ingredient)
185
185
  return button
186
186
 
187
+ # --- cross-page buttons (add another item's recipe/link to any page's extra_buttons) ---
188
+ def button_for_item(self, item_id: str, index: int = 0) -> WikiButtonRender | None:
189
+ """ Build the wiki button of another item's craft, linking to that item's page.
190
+
191
+ Use it to cross-link related pages, e.g. show the Starlight Infuser's recipe button on
192
+ the Stardust Pillar page. ``index`` selects which of the item's crafts to render (same
193
+ order as its own page). Returns None (with a warning) if the item has no such craft.
194
+ """
195
+ obj = self.manual.object_for(item_id)
196
+ if obj is None:
197
+ stp.warning(f"button_for_item: no item '{item_id}' in the definitions")
198
+ return None
199
+ page = self.manual.get_page_for_item(item_id)
200
+ crafts: list[JsonDict] = page.crafts if page is not None and page.crafts \
201
+ else self.collect_for_item(item_id, obj, self.manual.definitions_as_objects)
202
+ if not 0 <= index < len(crafts):
203
+ stp.warning(f"button_for_item: no craft at index {index} for '{item_id}' ({len(crafts)} available)")
204
+ return None
205
+ button = self.render_button(crafts[index], item_id, index)
206
+ if button.target is None: # crafts producing the item itself get no target on their own page
207
+ button.target = PageRef(item=item_id)
208
+ return button
209
+
210
+ def link_button(self, item_id: str, hover: TextComponent | None = None) -> WikiButtonRender:
211
+ """ Build a wiki button that simply links to another item's page (no recipe).
212
+
213
+ The icon shows the item in a wiki slot; ``hover`` defaults to its name plus a click hint.
214
+ """
215
+ ingr = Ingr(item_id)
216
+ glyph: str = self.images.wiki_result_icon(item_id, {"type": "page_link", "result": ingr})
217
+ if hover is None:
218
+ hover = [{"text": ingr.to_name(), "color": "yellow"}, {"text": "\nClick to open this page", "color": "gray"}]
219
+ return WikiButtonRender(glyph=glyph, hover=hover, target=PageRef(item=item_id), is_info=True)
220
+
187
221
  # --- growing seed info button (button-only pseudo, built from block metadata) ---
188
222
  def growing_seed_button(self, item_obj: Item) -> WikiButtonRender | None:
189
223
  """ Build an info button describing a block's :class:`GrowingSeed` drops, if any. """
@@ -31,6 +31,7 @@ def beet_default(ctx: Context, silent: bool = False) -> Generator[None]:
31
31
  Mem.ctx = ctx
32
32
  Mem.definitions = {}
33
33
  Mem.external_definitions = {}
34
+ Mem.used_textures = set()
34
35
 
35
36
  # Reset per-build module state so consecutive builds in one process (`stewbeet watch`) behave like fresh runs
36
37
  stp.clear_simple_caches()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes