amulet-core 2.0a8__cp312-cp312-win_amd64.whl → 2.0.1.0.1297307203.19.43.34808.0a0__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of amulet-core might be problematic. Click here for more details.

Files changed (271) hide show
  1. amulet/core/__init__.py +36 -0
  2. amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
  3. amulet/core/_amulet_core.cp312-win_amd64.pyd +0 -0
  4. amulet/core/_amulet_core.pyi +7 -0
  5. amulet/{_version.py → core/_version.py} +3 -3
  6. amulet/core/amulet_core.dll +0 -0
  7. amulet/core/amulet_core.lib +0 -0
  8. amulet/core/amulet_coreConfig.cmake +18 -0
  9. amulet/{biome.pyi → core/biome/__init__.pyi} +3 -3
  10. amulet/core/biome/biome.hpp +53 -0
  11. amulet/{block.pyi → core/block/__init__.pyi} +25 -26
  12. amulet/core/block/block.hpp +156 -0
  13. amulet/{block_entity.pyi → core/block_entity/__init__.pyi} +7 -7
  14. amulet/core/block_entity/block_entity.hpp +84 -0
  15. amulet/{errors.py → core/chunk/__init__.pyi} +37 -33
  16. amulet/core/chunk/chunk.hpp +126 -0
  17. amulet/core/chunk/component/__init__.pyi +18 -0
  18. amulet/core/chunk/component/biome_3d_component.hpp +96 -0
  19. amulet/core/chunk/component/block_component.hpp +101 -0
  20. amulet/core/chunk/component/block_component.pyi +28 -0
  21. amulet/core/chunk/component/block_entity_component.hpp +119 -0
  22. amulet/core/chunk/component/section_array_map.hpp +129 -0
  23. amulet/{chunk_components.pyi → core/chunk/component/section_array_map.pyi} +4 -24
  24. amulet/core/dll.hpp +21 -0
  25. amulet/core/entity/__init__.pyi +105 -0
  26. amulet/core/entity/entity.hpp +100 -0
  27. amulet/{palette → core/palette}/__init__.pyi +2 -2
  28. amulet/core/palette/biome_palette.hpp +65 -0
  29. amulet/{palette → core/palette}/biome_palette.pyi +8 -8
  30. amulet/core/palette/block_palette.hpp +71 -0
  31. amulet/{palette → core/palette}/block_palette.pyi +12 -10
  32. amulet/core/selection/__init__.pyi +8 -0
  33. amulet/core/selection/box.hpp +86 -0
  34. amulet/core/selection/box.pyi +215 -0
  35. amulet/core/selection/group.hpp +80 -0
  36. amulet/core/selection/group.pyi +213 -0
  37. amulet/{version.pyi → core/version/__init__.pyi} +58 -10
  38. amulet/core/version/version.hpp +204 -0
  39. {amulet_core-2.0a8.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/METADATA +25 -20
  40. amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info/RECORD +45 -0
  41. {amulet_core-2.0a8.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/WHEEL +1 -1
  42. amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info/entry_points.txt +2 -0
  43. amulet/__init__.cp312-win_amd64.pyd +0 -0
  44. amulet/__init__.py.cpp +0 -45
  45. amulet/__init__.pyi +0 -30
  46. amulet/__pyinstaller/hook-amulet.py +0 -4
  47. amulet/_init.py +0 -26
  48. amulet/biome.cpp +0 -36
  49. amulet/biome.hpp +0 -43
  50. amulet/biome.py.cpp +0 -122
  51. amulet/block.cpp +0 -435
  52. amulet/block.hpp +0 -119
  53. amulet/block.py.cpp +0 -377
  54. amulet/block_entity.cpp +0 -12
  55. amulet/block_entity.hpp +0 -56
  56. amulet/block_entity.py.cpp +0 -115
  57. amulet/chunk.cpp +0 -16
  58. amulet/chunk.hpp +0 -100
  59. amulet/chunk.py.cpp +0 -80
  60. amulet/chunk.pyi +0 -28
  61. amulet/chunk_components/biome_3d_component.cpp +0 -5
  62. amulet/chunk_components/biome_3d_component.hpp +0 -79
  63. amulet/chunk_components/block_component.cpp +0 -41
  64. amulet/chunk_components/block_component.hpp +0 -88
  65. amulet/chunk_components/block_entity_component.cpp +0 -5
  66. amulet/chunk_components/block_entity_component.hpp +0 -147
  67. amulet/chunk_components/section_array_map.cpp +0 -129
  68. amulet/chunk_components/section_array_map.hpp +0 -147
  69. amulet/collections/eq.py.hpp +0 -37
  70. amulet/collections/hash.py.hpp +0 -27
  71. amulet/collections/holder.py.hpp +0 -37
  72. amulet/collections/iterator.py.hpp +0 -80
  73. amulet/collections/mapping.py.hpp +0 -199
  74. amulet/collections/mutable_mapping.py.hpp +0 -226
  75. amulet/collections/sequence.py.hpp +0 -163
  76. amulet/collections.pyi +0 -40
  77. amulet/data_types.py +0 -29
  78. amulet/entity.py +0 -182
  79. amulet/game/__init__.py +0 -7
  80. amulet/game/_game.py +0 -152
  81. amulet/game/_universal/__init__.py +0 -1
  82. amulet/game/_universal/_biome.py +0 -17
  83. amulet/game/_universal/_block.py +0 -47
  84. amulet/game/_universal/_version.py +0 -68
  85. amulet/game/abc/__init__.py +0 -22
  86. amulet/game/abc/_block_specification.py +0 -150
  87. amulet/game/abc/biome.py +0 -213
  88. amulet/game/abc/block.py +0 -331
  89. amulet/game/abc/game_version_container.py +0 -25
  90. amulet/game/abc/json_interface.py +0 -27
  91. amulet/game/abc/version.py +0 -44
  92. amulet/game/bedrock/__init__.py +0 -1
  93. amulet/game/bedrock/_biome.py +0 -35
  94. amulet/game/bedrock/_block.py +0 -42
  95. amulet/game/bedrock/_version.py +0 -165
  96. amulet/game/java/__init__.py +0 -2
  97. amulet/game/java/_biome.py +0 -35
  98. amulet/game/java/_block.py +0 -60
  99. amulet/game/java/_version.py +0 -176
  100. amulet/game/translate/__init__.py +0 -12
  101. amulet/game/translate/_functions/__init__.py +0 -15
  102. amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
  103. amulet/game/translate/_functions/_code_functions/_text.py +0 -553
  104. amulet/game/translate/_functions/_code_functions/banner_pattern.py +0 -67
  105. amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +0 -152
  106. amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +0 -88
  107. amulet/game/translate/_functions/_code_functions/bedrock_sign.py +0 -152
  108. amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +0 -16
  109. amulet/game/translate/_functions/_code_functions/custom_name.py +0 -146
  110. amulet/game/translate/_functions/_frozen.py +0 -66
  111. amulet/game/translate/_functions/_state.py +0 -54
  112. amulet/game/translate/_functions/_typing.py +0 -98
  113. amulet/game/translate/_functions/abc.py +0 -123
  114. amulet/game/translate/_functions/carry_nbt.py +0 -160
  115. amulet/game/translate/_functions/carry_properties.py +0 -80
  116. amulet/game/translate/_functions/code.py +0 -143
  117. amulet/game/translate/_functions/map_block_name.py +0 -66
  118. amulet/game/translate/_functions/map_nbt.py +0 -111
  119. amulet/game/translate/_functions/map_properties.py +0 -93
  120. amulet/game/translate/_functions/multiblock.py +0 -112
  121. amulet/game/translate/_functions/new_block.py +0 -42
  122. amulet/game/translate/_functions/new_entity.py +0 -43
  123. amulet/game/translate/_functions/new_nbt.py +0 -206
  124. amulet/game/translate/_functions/new_properties.py +0 -64
  125. amulet/game/translate/_functions/sequence.py +0 -51
  126. amulet/game/translate/_functions/walk_input_nbt.py +0 -331
  127. amulet/game/translate/_translator.py +0 -433
  128. amulet/img/__init__.py +0 -10
  129. amulet/img/missing_no.png +0 -0
  130. amulet/img/missing_pack.png +0 -0
  131. amulet/img/missing_world.png +0 -0
  132. amulet/io/binary_reader.hpp +0 -45
  133. amulet/io/binary_writer.hpp +0 -30
  134. amulet/item.py +0 -75
  135. amulet/level/__init__.pyi +0 -23
  136. amulet/level/_load.py +0 -100
  137. amulet/level/abc/__init__.py +0 -12
  138. amulet/level/abc/_chunk_handle.py +0 -358
  139. amulet/level/abc/_dimension.py +0 -86
  140. amulet/level/abc/_history/__init__.py +0 -1
  141. amulet/level/abc/_history/_cache.py +0 -224
  142. amulet/level/abc/_history/_history_manager.py +0 -291
  143. amulet/level/abc/_level/__init__.py +0 -5
  144. amulet/level/abc/_level/_compactable_level.py +0 -10
  145. amulet/level/abc/_level/_creatable_level.py +0 -28
  146. amulet/level/abc/_level/_disk_level.py +0 -17
  147. amulet/level/abc/_level/_level.py +0 -449
  148. amulet/level/abc/_level/_loadable_level.py +0 -42
  149. amulet/level/abc/_player_storage.py +0 -7
  150. amulet/level/abc/_raw_level.py +0 -187
  151. amulet/level/abc/_registry.py +0 -40
  152. amulet/level/java/__init__.pyi +0 -16
  153. amulet/level/java/_chunk_handle.py +0 -17
  154. amulet/level/java/_dimension.py +0 -20
  155. amulet/level/java/_level.py +0 -184
  156. amulet/level/java/_raw/__init__.pyi +0 -15
  157. amulet/level/java/_raw/_chunk.pyi +0 -23
  158. amulet/level/java/_raw/_constant.py +0 -9
  159. amulet/level/java/_raw/_data_pack/__init__.py +0 -2
  160. amulet/level/java/_raw/_data_pack/data_pack.py +0 -241
  161. amulet/level/java/_raw/_data_pack/data_pack_manager.py +0 -77
  162. amulet/level/java/_raw/_dimension.py +0 -86
  163. amulet/level/java/_raw/_level.py +0 -507
  164. amulet/level/java/_raw/_typing.py +0 -3
  165. amulet/level/java/_raw/java_chunk_decode.cpp +0 -531
  166. amulet/level/java/_raw/java_chunk_decode.hpp +0 -23
  167. amulet/level/java/_raw/java_chunk_encode.cpp +0 -25
  168. amulet/level/java/_raw/java_chunk_encode.hpp +0 -23
  169. amulet/level/java/anvil/__init__.py +0 -2
  170. amulet/level/java/anvil/_dimension.py +0 -170
  171. amulet/level/java/anvil/_region.py +0 -421
  172. amulet/level/java/anvil/_sector_manager.py +0 -223
  173. amulet/level/java/chunk.pyi +0 -81
  174. amulet/level/java/chunk_/_chunk.py +0 -260
  175. amulet/level/java/chunk_/components/inhabited_time.py +0 -12
  176. amulet/level/java/chunk_/components/last_update.py +0 -12
  177. amulet/level/java/chunk_/components/legacy_version.py +0 -12
  178. amulet/level/java/chunk_/components/light_populated.py +0 -12
  179. amulet/level/java/chunk_/components/named_height_2d.py +0 -37
  180. amulet/level/java/chunk_/components/status.py +0 -11
  181. amulet/level/java/chunk_/components/terrain_populated.py +0 -12
  182. amulet/level/java/chunk_components/data_version_component.cpp +0 -32
  183. amulet/level/java/chunk_components/data_version_component.hpp +0 -31
  184. amulet/level/java/chunk_components/java_raw_chunk_component.cpp +0 -56
  185. amulet/level/java/chunk_components/java_raw_chunk_component.hpp +0 -45
  186. amulet/level/java/chunk_components.pyi +0 -22
  187. amulet/level/java/java_chunk.cpp +0 -170
  188. amulet/level/java/java_chunk.hpp +0 -141
  189. amulet/level/java/long_array.hpp +0 -175
  190. amulet/level/java/long_array.pyi +0 -39
  191. amulet/level/temporary_level/__init__.py +0 -1
  192. amulet/level/temporary_level/_level.py +0 -16
  193. amulet/mesh/__init__.py +0 -0
  194. amulet/mesh/block/__init__.pyi +0 -301
  195. amulet/mesh/block/_cube.py +0 -198
  196. amulet/mesh/block/_missing_block.py +0 -20
  197. amulet/mesh/block/block_mesh.cpp +0 -107
  198. amulet/mesh/block/block_mesh.hpp +0 -207
  199. amulet/mesh/util.py +0 -17
  200. amulet/palette/biome_palette.hpp +0 -85
  201. amulet/palette/block_palette.cpp +0 -32
  202. amulet/palette/block_palette.hpp +0 -93
  203. amulet/player.py +0 -62
  204. amulet/pybind11/collections.hpp +0 -118
  205. amulet/pybind11/numpy.hpp +0 -26
  206. amulet/pybind11/py_module.hpp +0 -34
  207. amulet/pybind11/type_hints.hpp +0 -51
  208. amulet/pybind11/types.hpp +0 -25
  209. amulet/pybind11/typing.hpp +0 -7
  210. amulet/resource_pack/__init__.py +0 -63
  211. amulet/resource_pack/abc/__init__.py +0 -2
  212. amulet/resource_pack/abc/resource_pack.py +0 -38
  213. amulet/resource_pack/abc/resource_pack_manager.py +0 -85
  214. amulet/resource_pack/java/__init__.py +0 -2
  215. amulet/resource_pack/java/download_resources.py +0 -212
  216. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
  217. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
  218. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
  219. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
  220. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
  221. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
  222. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
  223. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
  224. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
  225. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
  226. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
  227. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
  228. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
  229. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
  230. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
  231. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
  232. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
  233. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
  234. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
  235. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
  236. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
  237. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
  238. amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
  239. amulet/resource_pack/java/resource_pack.py +0 -44
  240. amulet/resource_pack/java/resource_pack_manager.py +0 -563
  241. amulet/resource_pack/unknown_resource_pack.py +0 -10
  242. amulet/selection/__init__.py +0 -2
  243. amulet/selection/abstract_selection.py +0 -342
  244. amulet/selection/box.py +0 -852
  245. amulet/selection/group.py +0 -481
  246. amulet/utils/__init__.pyi +0 -23
  247. amulet/utils/call_spec/__init__.py +0 -24
  248. amulet/utils/call_spec/_call_spec.py +0 -257
  249. amulet/utils/cast.py +0 -10
  250. amulet/utils/comment_json.py +0 -188
  251. amulet/utils/format_utils.py +0 -41
  252. amulet/utils/generator.py +0 -18
  253. amulet/utils/matrix.py +0 -243
  254. amulet/utils/numpy.hpp +0 -36
  255. amulet/utils/numpy.pyi +0 -11
  256. amulet/utils/numpy_helpers.py +0 -19
  257. amulet/utils/shareable_lock.py +0 -335
  258. amulet/utils/signal/__init__.py +0 -10
  259. amulet/utils/signal/_signal.py +0 -228
  260. amulet/utils/task_manager.py +0 -235
  261. amulet/utils/typed_property.py +0 -111
  262. amulet/utils/weakref.py +0 -70
  263. amulet/utils/world_utils.py +0 -102
  264. amulet/version.cpp +0 -136
  265. amulet/version.hpp +0 -142
  266. amulet/version.py.cpp +0 -281
  267. amulet_core-2.0a8.dist-info/RECORD +0 -241
  268. amulet_core-2.0a8.dist-info/entry_points.txt +0 -2
  269. /amulet/{__pyinstaller → core/__pyinstaller}/__init__.py +0 -0
  270. /amulet/{py.typed → core/py.typed} +0 -0
  271. {amulet_core-2.0a8.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/top_level.txt +0 -0
@@ -1,563 +0,0 @@
1
- import os
2
- import json
3
- from typing import Union, Iterable, Iterator, Optional
4
- from PIL import Image
5
- import numpy
6
- import glob
7
- import itertools
8
- import logging
9
- import re
10
-
11
- from amulet_nbt import StringTag
12
-
13
- from amulet.utils.cast import dynamic_cast
14
- from amulet.block import Block, PropertyValueType
15
- from amulet.resource_pack import BaseResourcePackManager
16
- from amulet.resource_pack.java import JavaResourcePack
17
- from amulet.mesh.block import (
18
- BlockMesh,
19
- BlockMeshPart,
20
- Triangle,
21
- Vertex,
22
- FloatVec3,
23
- FloatVec2,
24
- BlockMeshTransparency,
25
- BlockMeshCullDirection,
26
- merge_block_meshes,
27
- FACE_KEYS,
28
- CUBE_FACE_LUT,
29
- UV_ROTATION_LUT,
30
- TRI_FACE,
31
- )
32
- from amulet.mesh.util import rotate_3d
33
-
34
- log = logging.getLogger(__name__)
35
-
36
-
37
- UselessImageGroups = {
38
- "colormap",
39
- "effect",
40
- "environment",
41
- "font",
42
- "gui",
43
- "map",
44
- "mob_effect",
45
- "particle",
46
- }
47
-
48
- _PropertiesPattern = re.compile(r"(?P<name>[a-zA-Z0-9_]+)=(?P<value>[a-zA-Z0-9_]+),?")
49
-
50
- CULL_DIRECTIONS = {
51
- None: BlockMeshCullDirection.CullNone,
52
- "down": BlockMeshCullDirection.CullDown,
53
- "up": BlockMeshCullDirection.CullUp,
54
- "north": BlockMeshCullDirection.CullNorth,
55
- "east": BlockMeshCullDirection.CullEast,
56
- "south": BlockMeshCullDirection.CullSouth,
57
- "west": BlockMeshCullDirection.CullWest,
58
- }
59
-
60
-
61
- def get_py_data(obj: PropertyValueType) -> str | bytes | int:
62
- if isinstance(obj, StringTag):
63
- return obj.py_str_or_bytes
64
- else:
65
- return obj.py_int
66
-
67
-
68
- class JavaResourcePackManager(BaseResourcePackManager[JavaResourcePack]):
69
- """A class to load and handle the data from the packs.
70
- Packs are given as a list with the later packs overwriting the earlier ones."""
71
-
72
- def __init__(
73
- self,
74
- resource_packs: Union[JavaResourcePack, Iterable[JavaResourcePack]],
75
- load: bool = True,
76
- ) -> None:
77
- super().__init__()
78
- self._blockstate_files: dict[tuple[str, str], dict] = {}
79
- self._textures: dict[tuple[str, str], str] = {}
80
- self._texture_is_transparent: dict[str, tuple[float, bool]] = {}
81
- self._model_files: dict[tuple[str, str], dict] = {}
82
- if isinstance(resource_packs, Iterable):
83
- self._packs = list(resource_packs)
84
- elif isinstance(resource_packs, JavaResourcePack):
85
- self._packs = [resource_packs]
86
- else:
87
- raise Exception(f"Invalid format {resource_packs}")
88
- if load:
89
- for _ in self.reload():
90
- pass
91
-
92
- def _unload(self) -> None:
93
- """Clear all loaded resources."""
94
- super()._unload()
95
- self._blockstate_files.clear()
96
- self._textures.clear()
97
- self._texture_is_transparent.clear()
98
- self._model_files.clear()
99
-
100
- def _load_iter(self) -> Iterator[float]:
101
- blockstate_file_paths: dict[tuple[str, str], str] = {}
102
- model_file_paths: dict[tuple[str, str], str] = {}
103
-
104
- transparency_cache_path = os.path.join(
105
- os.environ["CACHE_DIR"], "resource_packs", "java", "transparency_cache.json"
106
- )
107
- self._load_transparency_cache(transparency_cache_path)
108
-
109
- self._textures[("minecraft", "missing_no")] = self.missing_no
110
-
111
- pack_count = len(self._packs)
112
-
113
- for pack_index, pack in enumerate(self._packs):
114
- # pack_format=2 textures/blocks, textures/items - case sensitive
115
- # pack_format=3 textures/blocks, textures/items - lower case
116
- # pack_format=4 textures/block, textures/item
117
- # pack_format=5 model paths and texture paths are now optionally namespaced
118
-
119
- pack_progress = pack_index / pack_count
120
- yield pack_progress
121
-
122
- if pack.valid_pack and pack.pack_format >= 2:
123
- image_paths = glob.glob(
124
- os.path.join(
125
- glob.escape(pack.root_dir),
126
- "assets",
127
- "*", # namespace
128
- "textures",
129
- "**",
130
- "*.png",
131
- ),
132
- recursive=True,
133
- )
134
- image_count = len(image_paths)
135
- sub_progress = pack_progress
136
- for image_index, texture_path in enumerate(image_paths):
137
- _, namespace, _, *rel_path_list = os.path.normpath(
138
- os.path.relpath(texture_path, pack.root_dir)
139
- ).split(os.sep)
140
- if rel_path_list[0] not in UselessImageGroups:
141
- rel_path = "/".join(rel_path_list)[:-4]
142
- self._textures[(namespace, rel_path)] = texture_path
143
- if (
144
- os.stat(texture_path).st_mtime
145
- != self._texture_is_transparent.get(texture_path, [0])[0]
146
- ):
147
- im: Image.Image = Image.open(texture_path)
148
- if im.mode == "RGBA":
149
- alpha = numpy.array(im.getchannel("A").getdata())
150
- texture_is_transparent = bool(numpy.any(alpha != 255))
151
- else:
152
- texture_is_transparent = False
153
-
154
- self._texture_is_transparent[texture_path] = (
155
- os.stat(texture_path).st_mtime,
156
- texture_is_transparent,
157
- )
158
- yield sub_progress + image_index / (image_count * pack_count * 3)
159
-
160
- blockstate_paths = glob.glob(
161
- os.path.join(
162
- glob.escape(pack.root_dir),
163
- "assets",
164
- "*", # namespace
165
- "blockstates",
166
- "*.json",
167
- )
168
- )
169
- blockstate_count = len(blockstate_paths)
170
- sub_progress = pack_progress + 1 / (pack_count * 3)
171
- for blockstate_index, blockstate_path in enumerate(blockstate_paths):
172
- _, namespace, _, blockstate_file = os.path.normpath(
173
- os.path.relpath(blockstate_path, pack.root_dir)
174
- ).split(os.sep)
175
- blockstate_file_paths[(namespace, blockstate_file[:-5])] = (
176
- blockstate_path
177
- )
178
- yield sub_progress + (blockstate_index) / (
179
- blockstate_count * pack_count * 3
180
- )
181
-
182
- model_paths = glob.glob(
183
- os.path.join(
184
- glob.escape(pack.root_dir),
185
- "assets",
186
- "*", # namespace
187
- "models",
188
- "**",
189
- "*.json",
190
- ),
191
- recursive=True,
192
- )
193
- model_count = len(model_paths)
194
- sub_progress = pack_progress + 2 / (pack_count * 3)
195
- for model_index, model_path in enumerate(model_paths):
196
- _, namespace, _, *rel_path_list = os.path.normpath(
197
- os.path.relpath(model_path, pack.root_dir)
198
- ).split(os.sep)
199
- rel_path = "/".join(rel_path_list)[:-5]
200
- model_file_paths[(namespace, rel_path.replace(os.sep, "/"))] = (
201
- model_path
202
- )
203
- yield sub_progress + (model_index) / (model_count * pack_count * 3)
204
-
205
- os.makedirs(os.path.dirname(transparency_cache_path), exist_ok=True)
206
- with open(transparency_cache_path, "w") as f:
207
- json.dump(self._texture_is_transparent, f)
208
-
209
- for key, path in blockstate_file_paths.items():
210
- with open(path) as fi:
211
- try:
212
- self._blockstate_files[key] = json.load(fi)
213
- except json.JSONDecodeError:
214
- log.error(f"Failed to parse blockstate file {path}")
215
-
216
- for key, path in model_file_paths.items():
217
- with open(path) as fi:
218
- try:
219
- self._model_files[key] = json.load(fi)
220
- except json.JSONDecodeError:
221
- log.error(f"Failed to parse model file file {path}")
222
-
223
- @property
224
- def textures(self) -> tuple[str, ...]:
225
- """Returns a tuple of all the texture paths in the resource pack."""
226
- return tuple(self._textures.values())
227
-
228
- def get_texture_path(self, namespace: Optional[str], relative_path: str) -> str:
229
- """Get the absolute texture path from the namespace and relative path pair"""
230
- if namespace is None:
231
- return self.missing_no
232
- key = (namespace, relative_path)
233
- if key in self._textures:
234
- return self._textures[key]
235
- else:
236
- return self.missing_no
237
-
238
- @staticmethod
239
- def parse_state_val(val: Union[str, bool]) -> list:
240
- """Convert the json block state format into a consistent format."""
241
- if isinstance(val, str):
242
- return [StringTag(v) for v in val.split("|")]
243
- elif isinstance(val, bool):
244
- return [StringTag("true") if val else StringTag("false")]
245
- else:
246
- raise Exception(f"Could not parse state val {val}")
247
-
248
- def _get_model(self, block: Block) -> BlockMesh:
249
- """Find the model paths for a given block state and load them."""
250
- if (block.namespace, block.base_name) in self._blockstate_files:
251
- blockstate: dict = self._blockstate_files[
252
- (block.namespace, block.base_name)
253
- ]
254
- if "variants" in blockstate:
255
- for variant in blockstate["variants"]:
256
- if variant == "":
257
- try:
258
- return self._load_blockstate_model(
259
- blockstate["variants"][variant]
260
- )
261
- except Exception as e:
262
- log.exception(
263
- f"Failed to load block model {blockstate['variants'][variant]}\n{e}"
264
- )
265
- else:
266
- properties_match = _PropertiesPattern.finditer(f",{variant}")
267
- if all(
268
- get_py_data(
269
- block.properties.get(
270
- match.group("name"),
271
- StringTag(match.group("value")),
272
- )
273
- )
274
- == match.group("value")
275
- for match in properties_match
276
- ):
277
- try:
278
- return self._load_blockstate_model(
279
- blockstate["variants"][variant]
280
- )
281
- except Exception as e:
282
- log.exception(
283
- f"Failed to load block model {blockstate['variants'][variant]}\n{e}"
284
- )
285
-
286
- elif "multipart" in blockstate:
287
- models = []
288
-
289
- for case in blockstate["multipart"]:
290
- try:
291
- if "when" in case:
292
- if "OR" in case["when"]:
293
- if not any(
294
- all(
295
- block.properties.get(prop, None)
296
- in self.parse_state_val(val)
297
- for prop, val in prop_match.items()
298
- )
299
- for prop_match in case["when"]["OR"]
300
- ):
301
- continue
302
- elif "AND" in case["when"]:
303
- if not all(
304
- all(
305
- block.properties.get(prop, None)
306
- in self.parse_state_val(val)
307
- for prop, val in prop_match.items()
308
- )
309
- for prop_match in case["when"]["AND"]
310
- ):
311
- continue
312
- elif not all(
313
- block.properties.get(prop, None)
314
- in self.parse_state_val(val)
315
- for prop, val in case["when"].items()
316
- ):
317
- continue
318
-
319
- if "apply" in case:
320
- try:
321
- models.append(
322
- self._load_blockstate_model(case["apply"])
323
- )
324
-
325
- except Exception as e:
326
- log.exception(
327
- f"Failed to load block model {case['apply']}\n{e}"
328
- )
329
- except Exception as e:
330
- log.exception(f"Failed to parse block state for {block}\n{e}")
331
-
332
- return merge_block_meshes(models)
333
-
334
- return self.missing_block
335
-
336
- def _load_blockstate_model(
337
- self, blockstate_value: Union[dict, list[dict]]
338
- ) -> BlockMesh:
339
- """Load the model(s) associated with a block state and apply rotations if needed."""
340
- if isinstance(blockstate_value, list):
341
- blockstate_value = blockstate_value[0]
342
- if "model" not in blockstate_value:
343
- return self.missing_block
344
- model_path = blockstate_value["model"]
345
- rotx = int(blockstate_value.get("x", 0) // 90)
346
- roty = int(blockstate_value.get("y", 0) // 90)
347
- uvlock = blockstate_value.get("uvlock", False)
348
-
349
- model = self._load_block_model(model_path)
350
-
351
- # TODO: rotate model based on uv_lock
352
- return model.rotate(rotx, roty)
353
-
354
- def _load_block_model(self, model_path: str) -> BlockMesh:
355
- """Load the model file associated with the Block and convert to a BlockMesh."""
356
- # recursively load model files into one dictionary
357
- java_model = self._recursive_load_block_model(model_path)
358
-
359
- if java_model.get("textures", {}) and not java_model.get("elements"):
360
- return self.missing_block
361
-
362
- # set up some variables
363
- texture_paths: dict[str, int] = {}
364
- mesh_parts: list[tuple[list[Vertex], list[Triangle]] | None] = [
365
- None,
366
- None,
367
- None,
368
- None,
369
- None,
370
- None,
371
- None,
372
- ]
373
- transparency = BlockMeshTransparency.Partial
374
-
375
- for element in dynamic_cast(java_model.get("elements", []), list):
376
- # iterate through elements (one cube per element)
377
- element_faces = dynamic_cast(element.get("faces", {}), dict)
378
-
379
- opaque_face_count = 0
380
- if (
381
- transparency
382
- and "rotation" not in element
383
- and element.get("to", [16, 16, 16]) == [16, 16, 16]
384
- and element.get("from", [0, 0, 0]) == [0, 0, 0]
385
- and len(element_faces) >= 6
386
- ):
387
- # if the block is not yet defined as a solid block
388
- # and this element is a full size element
389
- # check if the texture is opaque
390
- transparency = BlockMeshTransparency.FullTranslucent
391
- check_faces = True
392
- else:
393
- check_faces = False
394
-
395
- # lower and upper box coordinates
396
- x1, y1, z1 = [v / 16.0 for v in element.get("from", [0, 0, 0])]
397
- x2, y2, z2 = [v / 16.0 for v in element.get("to", [16, 16, 16])]
398
-
399
- # vertex coordinates of the box
400
- box_coordinates = numpy.array(
401
- list(
402
- itertools.product(
403
- (min(x1, x2), max(x1, x2)),
404
- (min(y1, y2), max(y1, y2)),
405
- (min(z1, z2), max(z1, x2)),
406
- )
407
- )
408
- )
409
-
410
- for face_dir, face_data in element_faces.items():
411
- if face_dir not in CUBE_FACE_LUT:
412
- continue
413
-
414
- # get the cull direction. If there is an opaque block in this direction then cull this face
415
- cull_dir = face_data.get("cullface", None)
416
- if cull_dir not in FACE_KEYS:
417
- cull_dir = None
418
-
419
- # get the relative texture path for the texture used
420
- texture_relative_path = face_data.get("texture", None)
421
- while isinstance(
422
- texture_relative_path, str
423
- ) and texture_relative_path.startswith("#"):
424
- texture_relative_path = java_model["textures"].get(
425
- texture_relative_path[1:], None
426
- )
427
- texture_path_list = texture_relative_path.split(":", 1)
428
- if len(texture_path_list) == 2:
429
- namespace, texture_relative_path = texture_path_list
430
- else:
431
- namespace = "minecraft"
432
-
433
- texture_path = self.get_texture_path(namespace, texture_relative_path)
434
-
435
- if check_faces:
436
- if self._texture_is_transparent[texture_path][1]:
437
- check_faces = False
438
- else:
439
- opaque_face_count += 1
440
-
441
- # texture index for the face
442
- texture_index = texture_paths.setdefault(
443
- texture_path, len(texture_paths)
444
- )
445
-
446
- # get the uv values for each vertex
447
- texture_uv: tuple[float, float, float, float]
448
- if "uv" in face_data:
449
- uv = face_data["uv"]
450
- texture_uv = (
451
- uv[0] / 16.0,
452
- uv[1] / 16.0,
453
- uv[2] / 16.0,
454
- uv[3] / 16.0,
455
- )
456
- else:
457
- # TODO: get the uv based on box location if not defined
458
- texture_uv = (0.0, 0.0, 1.0, 1.0)
459
-
460
- texture_rotation = face_data.get("rotation", 0)
461
- uv_slice = (
462
- UV_ROTATION_LUT[2 * int(texture_rotation / 90) :]
463
- + UV_ROTATION_LUT[: 2 * int(texture_rotation / 90)]
464
- )
465
-
466
- # merge the vertex coordinates and texture coordinates
467
- face_verts = box_coordinates[CUBE_FACE_LUT[face_dir]]
468
- if "rotation" in element:
469
- rotation = element["rotation"]
470
- origin = [r / 16 for r in rotation.get("origin", [8, 8, 8])]
471
- angle = rotation.get("angle", 0)
472
- axis = rotation.get("axis", "x")
473
- angles = [0, 0, 0]
474
- if axis == "x":
475
- angles[0] = -angle
476
- elif axis == "y":
477
- angles[1] = -angle
478
- elif axis == "z":
479
- angles[2] = -angle
480
- face_verts = rotate_3d(face_verts, *angles, *origin)
481
-
482
- cull_direction = CULL_DIRECTIONS[cull_dir]
483
- part = mesh_parts[cull_direction]
484
- if part is None:
485
- mesh_parts[cull_direction] = part = ([], [])
486
- verts, tris = part
487
- vert_count = len(verts)
488
-
489
- if "tintindex" in face_data:
490
- # TODO: set this up for each supported block
491
- tint_vec = FloatVec3(0, 1, 0)
492
- else:
493
- tint_vec = FloatVec3(1, 1, 1)
494
-
495
- for i in range(4):
496
- x, y, z = face_verts[i]
497
- uvx = texture_uv[uv_slice[i * 2]]
498
- uvy = texture_uv[uv_slice[i * 2 + 1]]
499
- verts.append(
500
- Vertex(
501
- FloatVec3(x, y, z),
502
- FloatVec2(uvx, uvy),
503
- tint_vec,
504
- )
505
- )
506
-
507
- for a, b, c in TRI_FACE.reshape((2, 3)):
508
- tris.append(
509
- Triangle(
510
- a + vert_count,
511
- b + vert_count,
512
- c + vert_count,
513
- texture_index,
514
- )
515
- )
516
-
517
- if opaque_face_count == 6:
518
- transparency = BlockMeshTransparency.FullOpaque
519
-
520
- def create_part(
521
- part: tuple[list[Vertex], list[Triangle]] | None
522
- ) -> BlockMeshPart | None:
523
- return None if part is None else BlockMeshPart(*part)
524
-
525
- return BlockMesh(
526
- transparency,
527
- list(texture_paths),
528
- (
529
- create_part(mesh_parts[0]),
530
- create_part(mesh_parts[1]),
531
- create_part(mesh_parts[2]),
532
- create_part(mesh_parts[3]),
533
- create_part(mesh_parts[4]),
534
- create_part(mesh_parts[5]),
535
- create_part(mesh_parts[6]),
536
- ),
537
- )
538
-
539
- def _recursive_load_block_model(self, model_path: str) -> dict:
540
- """Load a model json file and recursively load and merge the parent entries into one json file."""
541
- model_path_list = model_path.split(":", 1)
542
- if len(model_path_list) == 2:
543
- namespace, model_path = model_path_list
544
- else:
545
- namespace = "minecraft"
546
- if (namespace, model_path) in self._model_files:
547
- model = self._model_files[(namespace, model_path)]
548
-
549
- if "parent" in model:
550
- parent_model = self._recursive_load_block_model(model["parent"])
551
- else:
552
- parent_model = {}
553
- if "textures" in model:
554
- if "textures" not in parent_model:
555
- parent_model["textures"] = {}
556
- for key, val in model["textures"].items():
557
- parent_model["textures"][key] = val
558
- if "elements" in model:
559
- parent_model["elements"] = model["elements"]
560
-
561
- return parent_model
562
-
563
- return {}
@@ -1,10 +0,0 @@
1
- from amulet.resource_pack.abc.resource_pack import BaseResourcePack
2
-
3
-
4
- class UnknownResourcePack(BaseResourcePack):
5
- def __repr__(self) -> str:
6
- return f"UnknownResourcePack({self._root_dir})"
7
-
8
- @staticmethod
9
- def is_valid(pack_path: str) -> bool:
10
- return True
@@ -1,2 +0,0 @@
1
- from .group import SelectionGroup
2
- from .box import SelectionBox