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.
- amulet/__init__.py +27 -27
- amulet/__pyinstaller/__init__.py +2 -2
- amulet/__pyinstaller/hook-amulet.py +4 -4
- amulet/_version.py +21 -21
- amulet/api/__init__.py +2 -2
- amulet/api/abstract_base_entity.py +128 -128
- amulet/api/block.py +630 -630
- amulet/api/block_entity.py +71 -71
- amulet/api/cache.py +107 -107
- amulet/api/chunk/__init__.py +6 -6
- amulet/api/chunk/biomes.py +207 -207
- amulet/api/chunk/block_entity_dict.py +175 -175
- amulet/api/chunk/blocks.py +46 -46
- amulet/api/chunk/chunk.py +389 -389
- amulet/api/chunk/entity_list.py +75 -75
- amulet/api/chunk/status.py +167 -167
- amulet/api/data_types/__init__.py +4 -4
- amulet/api/data_types/generic_types.py +4 -4
- amulet/api/data_types/operation_types.py +16 -16
- amulet/api/data_types/world_types.py +49 -49
- amulet/api/data_types/wrapper_types.py +71 -71
- amulet/api/entity.py +74 -74
- amulet/api/errors.py +119 -119
- amulet/api/history/__init__.py +36 -36
- amulet/api/history/base/__init__.py +3 -3
- amulet/api/history/base/base_history.py +26 -26
- amulet/api/history/base/history_manager.py +63 -63
- amulet/api/history/base/revision_manager.py +73 -73
- amulet/api/history/changeable.py +15 -15
- amulet/api/history/data_types.py +7 -7
- amulet/api/history/history_manager/__init__.py +3 -3
- amulet/api/history/history_manager/container.py +102 -102
- amulet/api/history/history_manager/database.py +279 -279
- amulet/api/history/history_manager/meta.py +93 -93
- amulet/api/history/history_manager/object.py +116 -116
- amulet/api/history/revision_manager/__init__.py +2 -2
- amulet/api/history/revision_manager/disk.py +33 -33
- amulet/api/history/revision_manager/ram.py +12 -12
- amulet/api/item.py +75 -75
- amulet/api/level/__init__.py +4 -4
- amulet/api/level/base_level/__init__.py +1 -1
- amulet/api/level/base_level/base_level.py +1035 -1026
- amulet/api/level/base_level/chunk_manager.py +227 -227
- amulet/api/level/base_level/clone.py +389 -389
- amulet/api/level/base_level/player_manager.py +101 -101
- amulet/api/level/immutable_structure/__init__.py +1 -1
- amulet/api/level/immutable_structure/immutable_structure.py +94 -94
- amulet/api/level/immutable_structure/void_format_wrapper.py +117 -117
- amulet/api/level/structure.py +22 -22
- amulet/api/level/world.py +19 -19
- amulet/api/partial_3d_array/__init__.py +2 -2
- amulet/api/partial_3d_array/base_partial_3d_array.py +263 -263
- amulet/api/partial_3d_array/bounded_partial_3d_array.py +528 -528
- amulet/api/partial_3d_array/data_types.py +15 -15
- amulet/api/partial_3d_array/unbounded_partial_3d_array.py +229 -229
- amulet/api/partial_3d_array/util.py +152 -152
- amulet/api/player.py +65 -65
- amulet/api/registry/__init__.py +2 -2
- amulet/api/registry/base_registry.py +34 -34
- amulet/api/registry/biome_manager.py +153 -153
- amulet/api/registry/block_manager.py +156 -156
- amulet/api/selection/__init__.py +2 -2
- amulet/api/selection/abstract_selection.py +315 -315
- amulet/api/selection/box.py +805 -805
- amulet/api/selection/group.py +488 -488
- amulet/api/structure.py +37 -37
- amulet/api/wrapper/__init__.py +8 -8
- amulet/api/wrapper/chunk/interface.py +441 -441
- amulet/api/wrapper/chunk/translator.py +567 -567
- amulet/api/wrapper/format_wrapper.py +772 -772
- amulet/api/wrapper/structure_format_wrapper.py +116 -116
- amulet/api/wrapper/world_format_wrapper.py +63 -63
- amulet/level/__init__.py +1 -1
- amulet/level/formats/anvil_forge_world.py +40 -40
- amulet/level/formats/anvil_world/__init__.py +3 -3
- amulet/level/formats/anvil_world/_sector_manager.py +291 -384
- amulet/level/formats/anvil_world/data_pack/__init__.py +2 -2
- amulet/level/formats/anvil_world/data_pack/data_pack.py +224 -224
- amulet/level/formats/anvil_world/data_pack/data_pack_manager.py +77 -77
- amulet/level/formats/anvil_world/dimension.py +177 -177
- amulet/level/formats/anvil_world/format.py +769 -769
- amulet/level/formats/anvil_world/region.py +384 -384
- amulet/level/formats/construction/__init__.py +3 -3
- amulet/level/formats/construction/format_wrapper.py +515 -515
- amulet/level/formats/construction/interface.py +134 -134
- amulet/level/formats/construction/section.py +60 -60
- amulet/level/formats/construction/util.py +165 -165
- amulet/level/formats/leveldb_world/__init__.py +3 -3
- amulet/level/formats/leveldb_world/chunk.py +33 -33
- amulet/level/formats/leveldb_world/dimension.py +385 -419
- amulet/level/formats/leveldb_world/format.py +659 -641
- amulet/level/formats/leveldb_world/interface/chunk/__init__.py +36 -36
- amulet/level/formats/leveldb_world/interface/chunk/base_leveldb_interface.py +836 -836
- amulet/level/formats/leveldb_world/interface/chunk/generate_interface.py +31 -31
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_0.py +30 -30
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_1.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_10.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_11.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_12.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_13.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_14.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_15.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_16.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_17.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_18.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_19.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_2.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_20.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_21.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_22.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_23.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_24.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_25.py +24 -24
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_26.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_27.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_28.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_29.py +33 -33
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_3.py +57 -57
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_30.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_31.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_32.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_33.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_34.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_35.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_36.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_37.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_38.py +10 -10
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_39.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_4.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_40.py +16 -16
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_5.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_6.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_7.py +12 -12
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_8.py +180 -180
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_9.py +18 -18
- amulet/level/formats/leveldb_world/interface/chunk/leveldb_chunk_versions.py +79 -79
- amulet/level/formats/mcstructure/__init__.py +3 -3
- amulet/level/formats/mcstructure/chunk.py +50 -50
- amulet/level/formats/mcstructure/format_wrapper.py +408 -408
- amulet/level/formats/mcstructure/interface.py +175 -175
- amulet/level/formats/schematic/__init__.py +3 -3
- amulet/level/formats/schematic/chunk.py +55 -55
- amulet/level/formats/schematic/data_types.py +4 -4
- amulet/level/formats/schematic/format_wrapper.py +373 -373
- amulet/level/formats/schematic/interface.py +142 -142
- amulet/level/formats/sponge_schem/__init__.py +4 -4
- amulet/level/formats/sponge_schem/chunk.py +62 -62
- amulet/level/formats/sponge_schem/format_wrapper.py +463 -463
- amulet/level/formats/sponge_schem/interface.py +118 -118
- amulet/level/formats/sponge_schem/varint/__init__.py +1 -1
- amulet/level/formats/sponge_schem/varint/varint.py +87 -87
- amulet/level/interfaces/chunk/anvil/anvil_0.py +72 -72
- amulet/level/interfaces/chunk/anvil/anvil_1444.py +336 -336
- amulet/level/interfaces/chunk/anvil/anvil_1466.py +94 -94
- amulet/level/interfaces/chunk/anvil/anvil_1467.py +37 -37
- amulet/level/interfaces/chunk/anvil/anvil_1484.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1503.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1519.py +34 -34
- amulet/level/interfaces/chunk/anvil/anvil_1901.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1908.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_1912.py +21 -21
- amulet/level/interfaces/chunk/anvil/anvil_1934.py +20 -20
- amulet/level/interfaces/chunk/anvil/anvil_2203.py +69 -69
- amulet/level/interfaces/chunk/anvil/anvil_2529.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_2681.py +76 -76
- amulet/level/interfaces/chunk/anvil/anvil_2709.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_2844.py +267 -267
- amulet/level/interfaces/chunk/anvil/anvil_3463.py +19 -19
- amulet/level/interfaces/chunk/anvil/anvil_na.py +607 -607
- amulet/level/interfaces/chunk/anvil/base_anvil_interface.py +326 -326
- amulet/level/load.py +59 -59
- amulet/level/loader.py +95 -95
- amulet/level/translators/chunk/bedrock/__init__.py +267 -267
- amulet/level/translators/chunk/bedrock/bedrock_nbt_blockstate_translator.py +46 -46
- amulet/level/translators/chunk/bedrock/bedrock_numerical_translator.py +39 -39
- amulet/level/translators/chunk/bedrock/bedrock_psudo_numerical_translator.py +37 -37
- amulet/level/translators/chunk/java/java_1_18_translator.py +40 -40
- amulet/level/translators/chunk/java/java_blockstate_translator.py +94 -94
- amulet/level/translators/chunk/java/java_numerical_translator.py +62 -62
- amulet/libs/leveldb/__init__.py +7 -7
- amulet/operations/__init__.py +5 -5
- amulet/operations/clone.py +18 -18
- amulet/operations/delete_chunk.py +32 -32
- amulet/operations/fill.py +30 -30
- amulet/operations/paste.py +65 -65
- amulet/operations/replace.py +58 -58
- amulet/utils/__init__.py +14 -14
- amulet/utils/format_utils.py +41 -41
- amulet/utils/generator.py +15 -15
- amulet/utils/matrix.py +243 -243
- amulet/utils/numpy_helpers.py +46 -46
- amulet/utils/world_utils.py +349 -349
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/METADATA +97 -97
- amulet_core-1.9.20.dist-info/RECORD +208 -0
- amulet_core-1.9.19.dist-info/RECORD +0 -208
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/WHEEL +0 -0
- {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/entry_points.txt +0 -0
- {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
|
amulet/api/chunk/blocks.py
CHANGED
|
@@ -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)
|