amulet-core 1.9.19__py3-none-any.whl → 1.9.20__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (198) hide show
  1. amulet/__init__.py +27 -27
  2. amulet/__pyinstaller/__init__.py +2 -2
  3. amulet/__pyinstaller/hook-amulet.py +4 -4
  4. amulet/_version.py +21 -21
  5. amulet/api/__init__.py +2 -2
  6. amulet/api/abstract_base_entity.py +128 -128
  7. amulet/api/block.py +630 -630
  8. amulet/api/block_entity.py +71 -71
  9. amulet/api/cache.py +107 -107
  10. amulet/api/chunk/__init__.py +6 -6
  11. amulet/api/chunk/biomes.py +207 -207
  12. amulet/api/chunk/block_entity_dict.py +175 -175
  13. amulet/api/chunk/blocks.py +46 -46
  14. amulet/api/chunk/chunk.py +389 -389
  15. amulet/api/chunk/entity_list.py +75 -75
  16. amulet/api/chunk/status.py +167 -167
  17. amulet/api/data_types/__init__.py +4 -4
  18. amulet/api/data_types/generic_types.py +4 -4
  19. amulet/api/data_types/operation_types.py +16 -16
  20. amulet/api/data_types/world_types.py +49 -49
  21. amulet/api/data_types/wrapper_types.py +71 -71
  22. amulet/api/entity.py +74 -74
  23. amulet/api/errors.py +119 -119
  24. amulet/api/history/__init__.py +36 -36
  25. amulet/api/history/base/__init__.py +3 -3
  26. amulet/api/history/base/base_history.py +26 -26
  27. amulet/api/history/base/history_manager.py +63 -63
  28. amulet/api/history/base/revision_manager.py +73 -73
  29. amulet/api/history/changeable.py +15 -15
  30. amulet/api/history/data_types.py +7 -7
  31. amulet/api/history/history_manager/__init__.py +3 -3
  32. amulet/api/history/history_manager/container.py +102 -102
  33. amulet/api/history/history_manager/database.py +279 -279
  34. amulet/api/history/history_manager/meta.py +93 -93
  35. amulet/api/history/history_manager/object.py +116 -116
  36. amulet/api/history/revision_manager/__init__.py +2 -2
  37. amulet/api/history/revision_manager/disk.py +33 -33
  38. amulet/api/history/revision_manager/ram.py +12 -12
  39. amulet/api/item.py +75 -75
  40. amulet/api/level/__init__.py +4 -4
  41. amulet/api/level/base_level/__init__.py +1 -1
  42. amulet/api/level/base_level/base_level.py +1035 -1026
  43. amulet/api/level/base_level/chunk_manager.py +227 -227
  44. amulet/api/level/base_level/clone.py +389 -389
  45. amulet/api/level/base_level/player_manager.py +101 -101
  46. amulet/api/level/immutable_structure/__init__.py +1 -1
  47. amulet/api/level/immutable_structure/immutable_structure.py +94 -94
  48. amulet/api/level/immutable_structure/void_format_wrapper.py +117 -117
  49. amulet/api/level/structure.py +22 -22
  50. amulet/api/level/world.py +19 -19
  51. amulet/api/partial_3d_array/__init__.py +2 -2
  52. amulet/api/partial_3d_array/base_partial_3d_array.py +263 -263
  53. amulet/api/partial_3d_array/bounded_partial_3d_array.py +528 -528
  54. amulet/api/partial_3d_array/data_types.py +15 -15
  55. amulet/api/partial_3d_array/unbounded_partial_3d_array.py +229 -229
  56. amulet/api/partial_3d_array/util.py +152 -152
  57. amulet/api/player.py +65 -65
  58. amulet/api/registry/__init__.py +2 -2
  59. amulet/api/registry/base_registry.py +34 -34
  60. amulet/api/registry/biome_manager.py +153 -153
  61. amulet/api/registry/block_manager.py +156 -156
  62. amulet/api/selection/__init__.py +2 -2
  63. amulet/api/selection/abstract_selection.py +315 -315
  64. amulet/api/selection/box.py +805 -805
  65. amulet/api/selection/group.py +488 -488
  66. amulet/api/structure.py +37 -37
  67. amulet/api/wrapper/__init__.py +8 -8
  68. amulet/api/wrapper/chunk/interface.py +441 -441
  69. amulet/api/wrapper/chunk/translator.py +567 -567
  70. amulet/api/wrapper/format_wrapper.py +772 -772
  71. amulet/api/wrapper/structure_format_wrapper.py +116 -116
  72. amulet/api/wrapper/world_format_wrapper.py +63 -63
  73. amulet/level/__init__.py +1 -1
  74. amulet/level/formats/anvil_forge_world.py +40 -40
  75. amulet/level/formats/anvil_world/__init__.py +3 -3
  76. amulet/level/formats/anvil_world/_sector_manager.py +291 -384
  77. amulet/level/formats/anvil_world/data_pack/__init__.py +2 -2
  78. amulet/level/formats/anvil_world/data_pack/data_pack.py +224 -224
  79. amulet/level/formats/anvil_world/data_pack/data_pack_manager.py +77 -77
  80. amulet/level/formats/anvil_world/dimension.py +177 -177
  81. amulet/level/formats/anvil_world/format.py +769 -769
  82. amulet/level/formats/anvil_world/region.py +384 -384
  83. amulet/level/formats/construction/__init__.py +3 -3
  84. amulet/level/formats/construction/format_wrapper.py +515 -515
  85. amulet/level/formats/construction/interface.py +134 -134
  86. amulet/level/formats/construction/section.py +60 -60
  87. amulet/level/formats/construction/util.py +165 -165
  88. amulet/level/formats/leveldb_world/__init__.py +3 -3
  89. amulet/level/formats/leveldb_world/chunk.py +33 -33
  90. amulet/level/formats/leveldb_world/dimension.py +385 -419
  91. amulet/level/formats/leveldb_world/format.py +659 -641
  92. amulet/level/formats/leveldb_world/interface/chunk/__init__.py +36 -36
  93. amulet/level/formats/leveldb_world/interface/chunk/base_leveldb_interface.py +836 -836
  94. amulet/level/formats/leveldb_world/interface/chunk/generate_interface.py +31 -31
  95. amulet/level/formats/leveldb_world/interface/chunk/leveldb_0.py +30 -30
  96. amulet/level/formats/leveldb_world/interface/chunk/leveldb_1.py +12 -12
  97. amulet/level/formats/leveldb_world/interface/chunk/leveldb_10.py +12 -12
  98. amulet/level/formats/leveldb_world/interface/chunk/leveldb_11.py +12 -12
  99. amulet/level/formats/leveldb_world/interface/chunk/leveldb_12.py +12 -12
  100. amulet/level/formats/leveldb_world/interface/chunk/leveldb_13.py +12 -12
  101. amulet/level/formats/leveldb_world/interface/chunk/leveldb_14.py +12 -12
  102. amulet/level/formats/leveldb_world/interface/chunk/leveldb_15.py +12 -12
  103. amulet/level/formats/leveldb_world/interface/chunk/leveldb_16.py +12 -12
  104. amulet/level/formats/leveldb_world/interface/chunk/leveldb_17.py +12 -12
  105. amulet/level/formats/leveldb_world/interface/chunk/leveldb_18.py +12 -12
  106. amulet/level/formats/leveldb_world/interface/chunk/leveldb_19.py +12 -12
  107. amulet/level/formats/leveldb_world/interface/chunk/leveldb_2.py +12 -12
  108. amulet/level/formats/leveldb_world/interface/chunk/leveldb_20.py +12 -12
  109. amulet/level/formats/leveldb_world/interface/chunk/leveldb_21.py +12 -12
  110. amulet/level/formats/leveldb_world/interface/chunk/leveldb_22.py +12 -12
  111. amulet/level/formats/leveldb_world/interface/chunk/leveldb_23.py +10 -10
  112. amulet/level/formats/leveldb_world/interface/chunk/leveldb_24.py +10 -10
  113. amulet/level/formats/leveldb_world/interface/chunk/leveldb_25.py +24 -24
  114. amulet/level/formats/leveldb_world/interface/chunk/leveldb_26.py +10 -10
  115. amulet/level/formats/leveldb_world/interface/chunk/leveldb_27.py +10 -10
  116. amulet/level/formats/leveldb_world/interface/chunk/leveldb_28.py +10 -10
  117. amulet/level/formats/leveldb_world/interface/chunk/leveldb_29.py +33 -33
  118. amulet/level/formats/leveldb_world/interface/chunk/leveldb_3.py +57 -57
  119. amulet/level/formats/leveldb_world/interface/chunk/leveldb_30.py +10 -10
  120. amulet/level/formats/leveldb_world/interface/chunk/leveldb_31.py +10 -10
  121. amulet/level/formats/leveldb_world/interface/chunk/leveldb_32.py +10 -10
  122. amulet/level/formats/leveldb_world/interface/chunk/leveldb_33.py +10 -10
  123. amulet/level/formats/leveldb_world/interface/chunk/leveldb_34.py +10 -10
  124. amulet/level/formats/leveldb_world/interface/chunk/leveldb_35.py +10 -10
  125. amulet/level/formats/leveldb_world/interface/chunk/leveldb_36.py +10 -10
  126. amulet/level/formats/leveldb_world/interface/chunk/leveldb_37.py +10 -10
  127. amulet/level/formats/leveldb_world/interface/chunk/leveldb_38.py +10 -10
  128. amulet/level/formats/leveldb_world/interface/chunk/leveldb_39.py +12 -12
  129. amulet/level/formats/leveldb_world/interface/chunk/leveldb_4.py +12 -12
  130. amulet/level/formats/leveldb_world/interface/chunk/leveldb_40.py +16 -16
  131. amulet/level/formats/leveldb_world/interface/chunk/leveldb_5.py +12 -12
  132. amulet/level/formats/leveldb_world/interface/chunk/leveldb_6.py +12 -12
  133. amulet/level/formats/leveldb_world/interface/chunk/leveldb_7.py +12 -12
  134. amulet/level/formats/leveldb_world/interface/chunk/leveldb_8.py +180 -180
  135. amulet/level/formats/leveldb_world/interface/chunk/leveldb_9.py +18 -18
  136. amulet/level/formats/leveldb_world/interface/chunk/leveldb_chunk_versions.py +79 -79
  137. amulet/level/formats/mcstructure/__init__.py +3 -3
  138. amulet/level/formats/mcstructure/chunk.py +50 -50
  139. amulet/level/formats/mcstructure/format_wrapper.py +408 -408
  140. amulet/level/formats/mcstructure/interface.py +175 -175
  141. amulet/level/formats/schematic/__init__.py +3 -3
  142. amulet/level/formats/schematic/chunk.py +55 -55
  143. amulet/level/formats/schematic/data_types.py +4 -4
  144. amulet/level/formats/schematic/format_wrapper.py +373 -373
  145. amulet/level/formats/schematic/interface.py +142 -142
  146. amulet/level/formats/sponge_schem/__init__.py +4 -4
  147. amulet/level/formats/sponge_schem/chunk.py +62 -62
  148. amulet/level/formats/sponge_schem/format_wrapper.py +463 -463
  149. amulet/level/formats/sponge_schem/interface.py +118 -118
  150. amulet/level/formats/sponge_schem/varint/__init__.py +1 -1
  151. amulet/level/formats/sponge_schem/varint/varint.py +87 -87
  152. amulet/level/interfaces/chunk/anvil/anvil_0.py +72 -72
  153. amulet/level/interfaces/chunk/anvil/anvil_1444.py +336 -336
  154. amulet/level/interfaces/chunk/anvil/anvil_1466.py +94 -94
  155. amulet/level/interfaces/chunk/anvil/anvil_1467.py +37 -37
  156. amulet/level/interfaces/chunk/anvil/anvil_1484.py +20 -20
  157. amulet/level/interfaces/chunk/anvil/anvil_1503.py +20 -20
  158. amulet/level/interfaces/chunk/anvil/anvil_1519.py +34 -34
  159. amulet/level/interfaces/chunk/anvil/anvil_1901.py +20 -20
  160. amulet/level/interfaces/chunk/anvil/anvil_1908.py +20 -20
  161. amulet/level/interfaces/chunk/anvil/anvil_1912.py +21 -21
  162. amulet/level/interfaces/chunk/anvil/anvil_1934.py +20 -20
  163. amulet/level/interfaces/chunk/anvil/anvil_2203.py +69 -69
  164. amulet/level/interfaces/chunk/anvil/anvil_2529.py +19 -19
  165. amulet/level/interfaces/chunk/anvil/anvil_2681.py +76 -76
  166. amulet/level/interfaces/chunk/anvil/anvil_2709.py +19 -19
  167. amulet/level/interfaces/chunk/anvil/anvil_2844.py +267 -267
  168. amulet/level/interfaces/chunk/anvil/anvil_3463.py +19 -19
  169. amulet/level/interfaces/chunk/anvil/anvil_na.py +607 -607
  170. amulet/level/interfaces/chunk/anvil/base_anvil_interface.py +326 -326
  171. amulet/level/load.py +59 -59
  172. amulet/level/loader.py +95 -95
  173. amulet/level/translators/chunk/bedrock/__init__.py +267 -267
  174. amulet/level/translators/chunk/bedrock/bedrock_nbt_blockstate_translator.py +46 -46
  175. amulet/level/translators/chunk/bedrock/bedrock_numerical_translator.py +39 -39
  176. amulet/level/translators/chunk/bedrock/bedrock_psudo_numerical_translator.py +37 -37
  177. amulet/level/translators/chunk/java/java_1_18_translator.py +40 -40
  178. amulet/level/translators/chunk/java/java_blockstate_translator.py +94 -94
  179. amulet/level/translators/chunk/java/java_numerical_translator.py +62 -62
  180. amulet/libs/leveldb/__init__.py +7 -7
  181. amulet/operations/__init__.py +5 -5
  182. amulet/operations/clone.py +18 -18
  183. amulet/operations/delete_chunk.py +32 -32
  184. amulet/operations/fill.py +30 -30
  185. amulet/operations/paste.py +65 -65
  186. amulet/operations/replace.py +58 -58
  187. amulet/utils/__init__.py +14 -14
  188. amulet/utils/format_utils.py +41 -41
  189. amulet/utils/generator.py +15 -15
  190. amulet/utils/matrix.py +243 -243
  191. amulet/utils/numpy_helpers.py +46 -46
  192. amulet/utils/world_utils.py +349 -349
  193. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/METADATA +97 -97
  194. amulet_core-1.9.20.dist-info/RECORD +208 -0
  195. amulet_core-1.9.19.dist-info/RECORD +0 -208
  196. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/WHEEL +0 -0
  197. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/entry_points.txt +0 -0
  198. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/top_level.txt +0 -0
@@ -1,175 +1,175 @@
1
- from collections import UserDict
2
- from typing import Iterable, KeysView, ValuesView, ItemsView
3
- import numpy
4
-
5
- from amulet.api.data_types import BlockCoordinates
6
- from amulet.api.block_entity import BlockEntity
7
-
8
-
9
- class BlockEntityDict(UserDict):
10
- """
11
- A custom implementation of the dictionary class.
12
-
13
- It can only store :class:`BlockEntity` instances under the absolute coordinate of the block entity ``Tuple[int, int, int]``
14
- """
15
-
16
- InputType = Iterable[BlockEntity]
17
-
18
- def __init__(self, block_entities: InputType = ()):
19
- super().__init__()
20
- for block_entity in block_entities:
21
- self._assert_val(block_entity)
22
- self.data[block_entity.location] = block_entity
23
-
24
- def _assert_key(self, key):
25
- assert self._check_key(
26
- key
27
- ), f"Key must be in the format Tuple[int, int, int]. Got: {key}"
28
-
29
- @staticmethod
30
- def _check_key(key) -> bool:
31
- return (
32
- isinstance(key, tuple)
33
- and len(key) == 3
34
- and all(isinstance(a, (int, numpy.integer)) for a in key)
35
- )
36
-
37
- def _assert_val(self, value):
38
- assert self._check_val(value), f"Val must be a BlockEntity. Got: {value}"
39
-
40
- @staticmethod
41
- def _check_val(value) -> bool:
42
- return isinstance(value, BlockEntity)
43
-
44
- def __repr__(self) -> str:
45
- super_repr = (
46
- "".join(f"\n\t{key}:{val}" for key, val in self.data.items()) + "\n"
47
- )
48
- return f"BlockEntityDict({super_repr})"
49
-
50
- def clear(self) -> None:
51
- """Remove all block entities from the chunk."""
52
- self.data.clear()
53
-
54
- def keys(self) -> KeysView[BlockCoordinates]:
55
- """The location of every block entity in the chunk. Absolute coordinates."""
56
- return self.data.keys()
57
-
58
- def __iter__(self) -> Iterable[BlockEntity]:
59
- """
60
- An iterable of all the :class:`BlockEntity` objects.
61
- """
62
- yield from self.data.values()
63
-
64
- def values(self) -> ValuesView[BlockEntity]:
65
- """
66
- An iterable of all the :class:`BlockEntity` objects.
67
- """
68
- return self.data.values()
69
-
70
- def items(self) -> ItemsView[BlockCoordinates, BlockEntity]:
71
- """
72
- An iterable of all the locations and :class:`BlockEntity` objects.
73
- """
74
- return self.data.items()
75
-
76
- def copy(self) -> "BlockEntityDict":
77
- """
78
- Create a shallow copy of the block entity container.
79
- """
80
- return BlockEntityDict(self.values())
81
-
82
- def insert(self, block_entity: BlockEntity):
83
- """
84
- Insert the given :class:`BlockEntity` into the chunk at the location :attr:`BlockEntity.location`
85
-
86
- If a block entity already exists at this location it will be overwritten.
87
-
88
- :param block_entity: The block entity to add to the chunk.
89
- """
90
- self._assert_val(block_entity)
91
- self.data[block_entity.location] = block_entity
92
-
93
- def pop(self, coordinate: BlockCoordinates) -> BlockEntity:
94
- """
95
- Remove and return the :class:`BlockEntity` at ``coordinate``.
96
-
97
- :param coordinate: The coordinate to remove the block entity from.
98
- :return: The block entity at the specified coordinate.
99
- :raises:
100
- KeyError if there is no BlockEntity at the given coordinate.
101
- """
102
- self._assert_key(coordinate)
103
- if coordinate in self.data:
104
- return self.data.pop(coordinate)
105
- raise KeyError
106
-
107
- def __delitem__(self, coordinate: BlockCoordinates):
108
- """
109
- Remove the :class:`BlockEntity` at ``coordinate``.
110
-
111
- :param coordinate: The coordinate to remove the block entity from.
112
- """
113
- self._assert_key(coordinate)
114
- super().__delitem__(coordinate)
115
-
116
- def _check_block_entity(
117
- self, coordinate: BlockCoordinates, block_entity: BlockEntity
118
- ) -> BlockEntity:
119
- self._assert_key(coordinate)
120
- self._assert_val(block_entity)
121
- if coordinate != block_entity.location:
122
- block_entity = block_entity.new_at_location(*coordinate)
123
- return block_entity
124
-
125
- def __getitem__(self, coordinate: BlockCoordinates) -> BlockEntity:
126
- """
127
- Get the :class:`BlockEntity` at ``coordinate``.
128
-
129
- >>> block_entity = chunk.block_entities[(x, y, z)]
130
-
131
- :param coordinate: The coordinate to find the block entity at.
132
- :return: The block entity at the specified coordinate.
133
- :raises:
134
- KeyError if there is no BlockEntity at the given coordinate.
135
- """
136
- self._assert_key(coordinate)
137
- return super().__getitem__(coordinate)
138
-
139
- def __setitem__(self, coordinate: BlockCoordinates, block_entity: BlockEntity):
140
- """
141
- Set the :class:`BlockEntity` at ``coordinate``.
142
-
143
- >>> chunk.block_entities[(x, y, z)] = block_entity
144
-
145
- :param coordinate: The coordinate to set the block entity at.
146
- :param block_entity: The block entity to set at the specified coordinate.
147
- """
148
- self.data[coordinate] = self._check_block_entity(coordinate, block_entity)
149
-
150
- def setdefault(
151
- self, coordinate: BlockCoordinates, block_entity: BlockEntity
152
- ) -> BlockEntity:
153
- """
154
- Set the block entity at the given coordinate if there is not a block entity present.
155
-
156
- :param coordinate: The coordinate to set the block entity at.
157
- :param block_entity: The block entity to set at the specified coordinate if one is not present.
158
- """
159
- block_entity = self._check_block_entity(coordinate, block_entity)
160
- return self.data.setdefault(coordinate, block_entity)
161
-
162
- def popitem(self):
163
- raise NotImplementedError
164
-
165
- def update(self, block_entities: InputType):
166
- """
167
- Add the sequence of :class:`BlockEntity` instances to the chunk at the location :attr:`BlockEntity.location`
168
-
169
- If multiple block entities have the same coordinate only the last one will remain.
170
-
171
- :param block_entities: A sequence of :class:`BlockEntity` objects to add to the chunk.
172
- """
173
- for block_entity in block_entities:
174
- self._assert_val(block_entity)
175
- self.data[block_entity.location] = block_entity
1
+ from collections import UserDict
2
+ from typing import Iterable, KeysView, ValuesView, ItemsView
3
+ import numpy
4
+
5
+ from amulet.api.data_types import BlockCoordinates
6
+ from amulet.api.block_entity import BlockEntity
7
+
8
+
9
+ class BlockEntityDict(UserDict):
10
+ """
11
+ A custom implementation of the dictionary class.
12
+
13
+ It can only store :class:`BlockEntity` instances under the absolute coordinate of the block entity ``Tuple[int, int, int]``
14
+ """
15
+
16
+ InputType = Iterable[BlockEntity]
17
+
18
+ def __init__(self, block_entities: InputType = ()):
19
+ super().__init__()
20
+ for block_entity in block_entities:
21
+ self._assert_val(block_entity)
22
+ self.data[block_entity.location] = block_entity
23
+
24
+ def _assert_key(self, key):
25
+ assert self._check_key(
26
+ key
27
+ ), f"Key must be in the format Tuple[int, int, int]. Got: {key}"
28
+
29
+ @staticmethod
30
+ def _check_key(key) -> bool:
31
+ return (
32
+ isinstance(key, tuple)
33
+ and len(key) == 3
34
+ and all(isinstance(a, (int, numpy.integer)) for a in key)
35
+ )
36
+
37
+ def _assert_val(self, value):
38
+ assert self._check_val(value), f"Val must be a BlockEntity. Got: {value}"
39
+
40
+ @staticmethod
41
+ def _check_val(value) -> bool:
42
+ return isinstance(value, BlockEntity)
43
+
44
+ def __repr__(self) -> str:
45
+ super_repr = (
46
+ "".join(f"\n\t{key}:{val}" for key, val in self.data.items()) + "\n"
47
+ )
48
+ return f"BlockEntityDict({super_repr})"
49
+
50
+ def clear(self) -> None:
51
+ """Remove all block entities from the chunk."""
52
+ self.data.clear()
53
+
54
+ def keys(self) -> KeysView[BlockCoordinates]:
55
+ """The location of every block entity in the chunk. Absolute coordinates."""
56
+ return self.data.keys()
57
+
58
+ def __iter__(self) -> Iterable[BlockEntity]:
59
+ """
60
+ An iterable of all the :class:`BlockEntity` objects.
61
+ """
62
+ yield from self.data.values()
63
+
64
+ def values(self) -> ValuesView[BlockEntity]:
65
+ """
66
+ An iterable of all the :class:`BlockEntity` objects.
67
+ """
68
+ return self.data.values()
69
+
70
+ def items(self) -> ItemsView[BlockCoordinates, BlockEntity]:
71
+ """
72
+ An iterable of all the locations and :class:`BlockEntity` objects.
73
+ """
74
+ return self.data.items()
75
+
76
+ def copy(self) -> "BlockEntityDict":
77
+ """
78
+ Create a shallow copy of the block entity container.
79
+ """
80
+ return BlockEntityDict(self.values())
81
+
82
+ def insert(self, block_entity: BlockEntity):
83
+ """
84
+ Insert the given :class:`BlockEntity` into the chunk at the location :attr:`BlockEntity.location`
85
+
86
+ If a block entity already exists at this location it will be overwritten.
87
+
88
+ :param block_entity: The block entity to add to the chunk.
89
+ """
90
+ self._assert_val(block_entity)
91
+ self.data[block_entity.location] = block_entity
92
+
93
+ def pop(self, coordinate: BlockCoordinates) -> BlockEntity:
94
+ """
95
+ Remove and return the :class:`BlockEntity` at ``coordinate``.
96
+
97
+ :param coordinate: The coordinate to remove the block entity from.
98
+ :return: The block entity at the specified coordinate.
99
+ :raises:
100
+ KeyError if there is no BlockEntity at the given coordinate.
101
+ """
102
+ self._assert_key(coordinate)
103
+ if coordinate in self.data:
104
+ return self.data.pop(coordinate)
105
+ raise KeyError
106
+
107
+ def __delitem__(self, coordinate: BlockCoordinates):
108
+ """
109
+ Remove the :class:`BlockEntity` at ``coordinate``.
110
+
111
+ :param coordinate: The coordinate to remove the block entity from.
112
+ """
113
+ self._assert_key(coordinate)
114
+ super().__delitem__(coordinate)
115
+
116
+ def _check_block_entity(
117
+ self, coordinate: BlockCoordinates, block_entity: BlockEntity
118
+ ) -> BlockEntity:
119
+ self._assert_key(coordinate)
120
+ self._assert_val(block_entity)
121
+ if coordinate != block_entity.location:
122
+ block_entity = block_entity.new_at_location(*coordinate)
123
+ return block_entity
124
+
125
+ def __getitem__(self, coordinate: BlockCoordinates) -> BlockEntity:
126
+ """
127
+ Get the :class:`BlockEntity` at ``coordinate``.
128
+
129
+ >>> block_entity = chunk.block_entities[(x, y, z)]
130
+
131
+ :param coordinate: The coordinate to find the block entity at.
132
+ :return: The block entity at the specified coordinate.
133
+ :raises:
134
+ KeyError if there is no BlockEntity at the given coordinate.
135
+ """
136
+ self._assert_key(coordinate)
137
+ return super().__getitem__(coordinate)
138
+
139
+ def __setitem__(self, coordinate: BlockCoordinates, block_entity: BlockEntity):
140
+ """
141
+ Set the :class:`BlockEntity` at ``coordinate``.
142
+
143
+ >>> chunk.block_entities[(x, y, z)] = block_entity
144
+
145
+ :param coordinate: The coordinate to set the block entity at.
146
+ :param block_entity: The block entity to set at the specified coordinate.
147
+ """
148
+ self.data[coordinate] = self._check_block_entity(coordinate, block_entity)
149
+
150
+ def setdefault(
151
+ self, coordinate: BlockCoordinates, block_entity: BlockEntity
152
+ ) -> BlockEntity:
153
+ """
154
+ Set the block entity at the given coordinate if there is not a block entity present.
155
+
156
+ :param coordinate: The coordinate to set the block entity at.
157
+ :param block_entity: The block entity to set at the specified coordinate if one is not present.
158
+ """
159
+ block_entity = self._check_block_entity(coordinate, block_entity)
160
+ return self.data.setdefault(coordinate, block_entity)
161
+
162
+ def popitem(self):
163
+ raise NotImplementedError
164
+
165
+ def update(self, block_entities: InputType):
166
+ """
167
+ Add the sequence of :class:`BlockEntity` instances to the chunk at the location :attr:`BlockEntity.location`
168
+
169
+ If multiple block entities have the same coordinate only the last one will remain.
170
+
171
+ :param block_entities: A sequence of :class:`BlockEntity` objects to add to the chunk.
172
+ """
173
+ for block_entity in block_entities:
174
+ self._assert_val(block_entity)
175
+ self.data[block_entity.location] = block_entity
@@ -1,46 +1,46 @@
1
- import numpy
2
- from typing import Iterable, Optional, Union, Dict
3
- from copy import deepcopy
4
-
5
- from amulet.api.partial_3d_array import UnboundedPartial3DArray
6
-
7
-
8
- class Blocks(UnboundedPartial3DArray):
9
- def __init__(
10
- self,
11
- input_array: Optional[Union[Dict[int, numpy.ndarray], "Blocks"]] = None,
12
- ):
13
- if input_array is None:
14
- input_array = {}
15
- if isinstance(input_array, Blocks):
16
- input_array: dict = deepcopy(input_array._sections)
17
- if not isinstance(input_array, dict):
18
- raise Exception(f"Input array must be Blocks or dict, got {input_array}")
19
- super().__init__(numpy.uint32, 0, (16, 16, 16), (0, 16), sections=input_array)
20
-
21
- @property
22
- def sub_chunks(self) -> Iterable[int]:
23
- """An iterable of the sub-chunk indexes that exist"""
24
- return self.sections
25
-
26
- def has_sub_chunk(self, cy: int) -> bool:
27
- """Check if the array for a given sub-chunk exists.
28
- :param cy: The section y index
29
- :return: True if the array exists, False otherwise
30
- """
31
- return self.has_section(cy)
32
-
33
- def get_sub_chunk(self, cy: int) -> numpy.ndarray:
34
- """Get the section ndarray for a given section index.
35
- :param cy: The section y index
36
- :return: Numpy array for this section
37
- """
38
- return self.get_section(cy)
39
-
40
- def add_sub_chunk(self, cy: int, sub_chunk: numpy.ndarray):
41
- """Add a sub-chunk. Overwrite if already exists
42
- :param cy: The section y index
43
- :param sub_chunk: The Numpy array to add at this location
44
- :return:
45
- """
46
- self.add_section(cy, sub_chunk)
1
+ import numpy
2
+ from typing import Iterable, Optional, Union, Dict
3
+ from copy import deepcopy
4
+
5
+ from amulet.api.partial_3d_array import UnboundedPartial3DArray
6
+
7
+
8
+ class Blocks(UnboundedPartial3DArray):
9
+ def __init__(
10
+ self,
11
+ input_array: Optional[Union[Dict[int, numpy.ndarray], "Blocks"]] = None,
12
+ ):
13
+ if input_array is None:
14
+ input_array = {}
15
+ if isinstance(input_array, Blocks):
16
+ input_array: dict = deepcopy(input_array._sections)
17
+ if not isinstance(input_array, dict):
18
+ raise Exception(f"Input array must be Blocks or dict, got {input_array}")
19
+ super().__init__(numpy.uint32, 0, (16, 16, 16), (0, 16), sections=input_array)
20
+
21
+ @property
22
+ def sub_chunks(self) -> Iterable[int]:
23
+ """An iterable of the sub-chunk indexes that exist"""
24
+ return self.sections
25
+
26
+ def has_sub_chunk(self, cy: int) -> bool:
27
+ """Check if the array for a given sub-chunk exists.
28
+ :param cy: The section y index
29
+ :return: True if the array exists, False otherwise
30
+ """
31
+ return self.has_section(cy)
32
+
33
+ def get_sub_chunk(self, cy: int) -> numpy.ndarray:
34
+ """Get the section ndarray for a given section index.
35
+ :param cy: The section y index
36
+ :return: Numpy array for this section
37
+ """
38
+ return self.get_section(cy)
39
+
40
+ def add_sub_chunk(self, cy: int, sub_chunk: numpy.ndarray):
41
+ """Add a sub-chunk. Overwrite if already exists
42
+ :param cy: The section y index
43
+ :param sub_chunk: The Numpy array to add at this location
44
+ :return:
45
+ """
46
+ self.add_section(cy, sub_chunk)