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 typing import TYPE_CHECKING, Any, Tuple, Optional, List
|
|
2
|
-
import numpy
|
|
3
|
-
|
|
4
|
-
from amulet_nbt import IntTag, StringTag, CompoundTag
|
|
5
|
-
|
|
6
|
-
from amulet.api.wrapper import Interface, EntityIDType, EntityCoordType
|
|
7
|
-
from amulet.api.chunk import Chunk
|
|
8
|
-
from amulet.api.selection import SelectionBox
|
|
9
|
-
from amulet.api.data_types import (
|
|
10
|
-
AnyNDArray,
|
|
11
|
-
VersionNumberTuple,
|
|
12
|
-
VersionIdentifierType,
|
|
13
|
-
VersionNumberAny,
|
|
14
|
-
PlatformType,
|
|
15
|
-
)
|
|
16
|
-
from amulet.level.loader import Translators
|
|
17
|
-
from amulet.api.block import Block
|
|
18
|
-
from .chunk import MCStructureChunk
|
|
19
|
-
|
|
20
|
-
from amulet_nbt import NamedTag
|
|
21
|
-
|
|
22
|
-
if TYPE_CHECKING:
|
|
23
|
-
from amulet.api.wrapper import Translator
|
|
24
|
-
from PyMCTranslate import TranslationManager
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class MCStructureInterface(Interface):
|
|
28
|
-
_entity_id_type = EntityIDType.namespace_str_identifier
|
|
29
|
-
_entity_coord_type = EntityCoordType.Pos_list_float
|
|
30
|
-
_block_entity_id_type = EntityIDType.str_id
|
|
31
|
-
_block_entity_coord_type = EntityCoordType.xyz_int
|
|
32
|
-
|
|
33
|
-
def is_valid(self, key: Tuple) -> bool:
|
|
34
|
-
return True
|
|
35
|
-
|
|
36
|
-
def decode(
|
|
37
|
-
self, cx: int, cz: int, data: MCStructureChunk
|
|
38
|
-
) -> Tuple["Chunk", AnyNDArray]:
|
|
39
|
-
"""
|
|
40
|
-
Create an amulet.api.chunk.Chunk object from raw data given by the format
|
|
41
|
-
:param cx: chunk x coordinate
|
|
42
|
-
:param cz: chunk z coordinate
|
|
43
|
-
:param data: Raw chunk data provided by the format.
|
|
44
|
-
:return: Chunk object in version-specific format, along with the block_palette for that chunk.
|
|
45
|
-
"""
|
|
46
|
-
palette = numpy.empty(len(data.palette) + 1, dtype=object)
|
|
47
|
-
palette[0] = (
|
|
48
|
-
(
|
|
49
|
-
17563649,
|
|
50
|
-
Block(
|
|
51
|
-
namespace="minecraft",
|
|
52
|
-
base_name="air",
|
|
53
|
-
properties={"block_data": IntTag(0)},
|
|
54
|
-
),
|
|
55
|
-
),
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
for index, blocks in enumerate(data.palette):
|
|
59
|
-
block_layers: List[Tuple[Optional[int], Block]] = []
|
|
60
|
-
for block in blocks:
|
|
61
|
-
*namespace_, base_name = block["name"].py_str.split(":", 1)
|
|
62
|
-
namespace = namespace_[0] if namespace_ else "minecraft"
|
|
63
|
-
if "version" in block:
|
|
64
|
-
version: Optional[int] = block["version"].py_int
|
|
65
|
-
else:
|
|
66
|
-
version = None
|
|
67
|
-
|
|
68
|
-
if "states" in block: # 1.13 format
|
|
69
|
-
properties = block["states"].py_dict
|
|
70
|
-
if version is None:
|
|
71
|
-
version = 17694720 # 1, 14, 0, 0
|
|
72
|
-
else:
|
|
73
|
-
properties = {"block_data": IntTag(block["val"].py_int)}
|
|
74
|
-
block_layers.append(
|
|
75
|
-
(
|
|
76
|
-
version,
|
|
77
|
-
Block(
|
|
78
|
-
namespace=namespace,
|
|
79
|
-
base_name=base_name,
|
|
80
|
-
properties=properties,
|
|
81
|
-
),
|
|
82
|
-
)
|
|
83
|
-
)
|
|
84
|
-
palette[index + 1] = block_layers
|
|
85
|
-
|
|
86
|
-
chunk = Chunk(cx, cz)
|
|
87
|
-
box = data.selection.create_moved_box((cx * 16, 0, cz * 16), subtract=True)
|
|
88
|
-
chunk.blocks[box.slice] = data.blocks + 1
|
|
89
|
-
for tag in data.block_entities:
|
|
90
|
-
block_entity = self._decode_block_entity(
|
|
91
|
-
NamedTag(tag), self._block_entity_id_type, self._block_entity_coord_type
|
|
92
|
-
)
|
|
93
|
-
if block_entity is not None:
|
|
94
|
-
chunk.block_entities.insert(block_entity)
|
|
95
|
-
for tag in data.entities:
|
|
96
|
-
entity = self._decode_entity(
|
|
97
|
-
NamedTag(tag), self._block_entity_id_type, self._block_entity_coord_type
|
|
98
|
-
)
|
|
99
|
-
if entity is not None:
|
|
100
|
-
chunk.entities.append(entity)
|
|
101
|
-
|
|
102
|
-
return chunk, palette
|
|
103
|
-
|
|
104
|
-
def encode(
|
|
105
|
-
self,
|
|
106
|
-
chunk: "Chunk",
|
|
107
|
-
palette: AnyNDArray,
|
|
108
|
-
max_world_version: VersionIdentifierType,
|
|
109
|
-
box: SelectionBox,
|
|
110
|
-
) -> MCStructureChunk:
|
|
111
|
-
"""
|
|
112
|
-
Take a version-specific chunk and encode it to raw data for the format to store.
|
|
113
|
-
:param chunk: The already translated version-specfic chunk to encode.
|
|
114
|
-
:param palette: The block_palette the ids in the chunk correspond to.
|
|
115
|
-
:type palette: numpy.ndarray[Block]
|
|
116
|
-
:param max_world_version: The key to use to find the encoder.
|
|
117
|
-
:param box: The volume of the chunk to pack.
|
|
118
|
-
:return: Raw data to be stored by the Format.
|
|
119
|
-
"""
|
|
120
|
-
entities = []
|
|
121
|
-
for entity in chunk.entities:
|
|
122
|
-
if entity.location in box:
|
|
123
|
-
entities.append(
|
|
124
|
-
self._encode_entity(
|
|
125
|
-
entity, self._entity_id_type, self._entity_coord_type
|
|
126
|
-
).compound
|
|
127
|
-
)
|
|
128
|
-
block_entities = []
|
|
129
|
-
for block_entity in chunk.block_entities:
|
|
130
|
-
if block_entity.location in box:
|
|
131
|
-
block_entities.append(
|
|
132
|
-
self._encode_block_entity(
|
|
133
|
-
block_entity,
|
|
134
|
-
self._block_entity_id_type,
|
|
135
|
-
self._block_entity_coord_type,
|
|
136
|
-
).compound
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
slices = box.create_moved_box(
|
|
140
|
-
(chunk.cx * 16, 0, chunk.cz * 16), subtract=True
|
|
141
|
-
).slice
|
|
142
|
-
|
|
143
|
-
out_palette = numpy.empty(palette.shape, dtype=object)
|
|
144
|
-
for index, block_layers in enumerate(palette):
|
|
145
|
-
blocks_out = []
|
|
146
|
-
for version, block in block_layers:
|
|
147
|
-
block = CompoundTag(
|
|
148
|
-
{
|
|
149
|
-
"name": StringTag(f"{block.namespace}:{block.base_name}"),
|
|
150
|
-
"states": CompoundTag(block.properties),
|
|
151
|
-
}
|
|
152
|
-
)
|
|
153
|
-
if version:
|
|
154
|
-
block["version"] = IntTag(version)
|
|
155
|
-
blocks_out.append(block)
|
|
156
|
-
out_palette[index] = blocks_out
|
|
157
|
-
|
|
158
|
-
return MCStructureChunk(
|
|
159
|
-
box,
|
|
160
|
-
numpy.asarray(chunk.blocks[slices]),
|
|
161
|
-
out_palette,
|
|
162
|
-
block_entities,
|
|
163
|
-
entities,
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
def get_translator(
|
|
167
|
-
self,
|
|
168
|
-
max_world_version: Tuple[PlatformType, VersionNumberTuple],
|
|
169
|
-
data: Any = None,
|
|
170
|
-
translation_manager: "TranslationManager" = None,
|
|
171
|
-
) -> Tuple["Translator", VersionNumberAny]:
|
|
172
|
-
platform, version_number = max_world_version
|
|
173
|
-
if platform != "bedrock":
|
|
174
|
-
raise ValueError("Platform must be bedrock")
|
|
175
|
-
return Translators.get((platform, version_number)), version_number
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Tuple, Optional, List
|
|
2
|
+
import numpy
|
|
3
|
+
|
|
4
|
+
from amulet_nbt import IntTag, StringTag, CompoundTag
|
|
5
|
+
|
|
6
|
+
from amulet.api.wrapper import Interface, EntityIDType, EntityCoordType
|
|
7
|
+
from amulet.api.chunk import Chunk
|
|
8
|
+
from amulet.api.selection import SelectionBox
|
|
9
|
+
from amulet.api.data_types import (
|
|
10
|
+
AnyNDArray,
|
|
11
|
+
VersionNumberTuple,
|
|
12
|
+
VersionIdentifierType,
|
|
13
|
+
VersionNumberAny,
|
|
14
|
+
PlatformType,
|
|
15
|
+
)
|
|
16
|
+
from amulet.level.loader import Translators
|
|
17
|
+
from amulet.api.block import Block
|
|
18
|
+
from .chunk import MCStructureChunk
|
|
19
|
+
|
|
20
|
+
from amulet_nbt import NamedTag
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from amulet.api.wrapper import Translator
|
|
24
|
+
from PyMCTranslate import TranslationManager
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class MCStructureInterface(Interface):
|
|
28
|
+
_entity_id_type = EntityIDType.namespace_str_identifier
|
|
29
|
+
_entity_coord_type = EntityCoordType.Pos_list_float
|
|
30
|
+
_block_entity_id_type = EntityIDType.str_id
|
|
31
|
+
_block_entity_coord_type = EntityCoordType.xyz_int
|
|
32
|
+
|
|
33
|
+
def is_valid(self, key: Tuple) -> bool:
|
|
34
|
+
return True
|
|
35
|
+
|
|
36
|
+
def decode(
|
|
37
|
+
self, cx: int, cz: int, data: MCStructureChunk
|
|
38
|
+
) -> Tuple["Chunk", AnyNDArray]:
|
|
39
|
+
"""
|
|
40
|
+
Create an amulet.api.chunk.Chunk object from raw data given by the format
|
|
41
|
+
:param cx: chunk x coordinate
|
|
42
|
+
:param cz: chunk z coordinate
|
|
43
|
+
:param data: Raw chunk data provided by the format.
|
|
44
|
+
:return: Chunk object in version-specific format, along with the block_palette for that chunk.
|
|
45
|
+
"""
|
|
46
|
+
palette = numpy.empty(len(data.palette) + 1, dtype=object)
|
|
47
|
+
palette[0] = (
|
|
48
|
+
(
|
|
49
|
+
17563649,
|
|
50
|
+
Block(
|
|
51
|
+
namespace="minecraft",
|
|
52
|
+
base_name="air",
|
|
53
|
+
properties={"block_data": IntTag(0)},
|
|
54
|
+
),
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
for index, blocks in enumerate(data.palette):
|
|
59
|
+
block_layers: List[Tuple[Optional[int], Block]] = []
|
|
60
|
+
for block in blocks:
|
|
61
|
+
*namespace_, base_name = block["name"].py_str.split(":", 1)
|
|
62
|
+
namespace = namespace_[0] if namespace_ else "minecraft"
|
|
63
|
+
if "version" in block:
|
|
64
|
+
version: Optional[int] = block["version"].py_int
|
|
65
|
+
else:
|
|
66
|
+
version = None
|
|
67
|
+
|
|
68
|
+
if "states" in block: # 1.13 format
|
|
69
|
+
properties = block["states"].py_dict
|
|
70
|
+
if version is None:
|
|
71
|
+
version = 17694720 # 1, 14, 0, 0
|
|
72
|
+
else:
|
|
73
|
+
properties = {"block_data": IntTag(block["val"].py_int)}
|
|
74
|
+
block_layers.append(
|
|
75
|
+
(
|
|
76
|
+
version,
|
|
77
|
+
Block(
|
|
78
|
+
namespace=namespace,
|
|
79
|
+
base_name=base_name,
|
|
80
|
+
properties=properties,
|
|
81
|
+
),
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
palette[index + 1] = block_layers
|
|
85
|
+
|
|
86
|
+
chunk = Chunk(cx, cz)
|
|
87
|
+
box = data.selection.create_moved_box((cx * 16, 0, cz * 16), subtract=True)
|
|
88
|
+
chunk.blocks[box.slice] = data.blocks + 1
|
|
89
|
+
for tag in data.block_entities:
|
|
90
|
+
block_entity = self._decode_block_entity(
|
|
91
|
+
NamedTag(tag), self._block_entity_id_type, self._block_entity_coord_type
|
|
92
|
+
)
|
|
93
|
+
if block_entity is not None:
|
|
94
|
+
chunk.block_entities.insert(block_entity)
|
|
95
|
+
for tag in data.entities:
|
|
96
|
+
entity = self._decode_entity(
|
|
97
|
+
NamedTag(tag), self._block_entity_id_type, self._block_entity_coord_type
|
|
98
|
+
)
|
|
99
|
+
if entity is not None:
|
|
100
|
+
chunk.entities.append(entity)
|
|
101
|
+
|
|
102
|
+
return chunk, palette
|
|
103
|
+
|
|
104
|
+
def encode(
|
|
105
|
+
self,
|
|
106
|
+
chunk: "Chunk",
|
|
107
|
+
palette: AnyNDArray,
|
|
108
|
+
max_world_version: VersionIdentifierType,
|
|
109
|
+
box: SelectionBox,
|
|
110
|
+
) -> MCStructureChunk:
|
|
111
|
+
"""
|
|
112
|
+
Take a version-specific chunk and encode it to raw data for the format to store.
|
|
113
|
+
:param chunk: The already translated version-specfic chunk to encode.
|
|
114
|
+
:param palette: The block_palette the ids in the chunk correspond to.
|
|
115
|
+
:type palette: numpy.ndarray[Block]
|
|
116
|
+
:param max_world_version: The key to use to find the encoder.
|
|
117
|
+
:param box: The volume of the chunk to pack.
|
|
118
|
+
:return: Raw data to be stored by the Format.
|
|
119
|
+
"""
|
|
120
|
+
entities = []
|
|
121
|
+
for entity in chunk.entities:
|
|
122
|
+
if entity.location in box:
|
|
123
|
+
entities.append(
|
|
124
|
+
self._encode_entity(
|
|
125
|
+
entity, self._entity_id_type, self._entity_coord_type
|
|
126
|
+
).compound
|
|
127
|
+
)
|
|
128
|
+
block_entities = []
|
|
129
|
+
for block_entity in chunk.block_entities:
|
|
130
|
+
if block_entity.location in box:
|
|
131
|
+
block_entities.append(
|
|
132
|
+
self._encode_block_entity(
|
|
133
|
+
block_entity,
|
|
134
|
+
self._block_entity_id_type,
|
|
135
|
+
self._block_entity_coord_type,
|
|
136
|
+
).compound
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
slices = box.create_moved_box(
|
|
140
|
+
(chunk.cx * 16, 0, chunk.cz * 16), subtract=True
|
|
141
|
+
).slice
|
|
142
|
+
|
|
143
|
+
out_palette = numpy.empty(palette.shape, dtype=object)
|
|
144
|
+
for index, block_layers in enumerate(palette):
|
|
145
|
+
blocks_out = []
|
|
146
|
+
for version, block in block_layers:
|
|
147
|
+
block = CompoundTag(
|
|
148
|
+
{
|
|
149
|
+
"name": StringTag(f"{block.namespace}:{block.base_name}"),
|
|
150
|
+
"states": CompoundTag(block.properties),
|
|
151
|
+
}
|
|
152
|
+
)
|
|
153
|
+
if version:
|
|
154
|
+
block["version"] = IntTag(version)
|
|
155
|
+
blocks_out.append(block)
|
|
156
|
+
out_palette[index] = blocks_out
|
|
157
|
+
|
|
158
|
+
return MCStructureChunk(
|
|
159
|
+
box,
|
|
160
|
+
numpy.asarray(chunk.blocks[slices]),
|
|
161
|
+
out_palette,
|
|
162
|
+
block_entities,
|
|
163
|
+
entities,
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
def get_translator(
|
|
167
|
+
self,
|
|
168
|
+
max_world_version: Tuple[PlatformType, VersionNumberTuple],
|
|
169
|
+
data: Any = None,
|
|
170
|
+
translation_manager: "TranslationManager" = None,
|
|
171
|
+
) -> Tuple["Translator", VersionNumberAny]:
|
|
172
|
+
platform, version_number = max_world_version
|
|
173
|
+
if platform != "bedrock":
|
|
174
|
+
raise ValueError("Platform must be bedrock")
|
|
175
|
+
return Translators.get((platform, version_number)), version_number
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from .format_wrapper import SchematicFormatWrapper
|
|
2
|
-
|
|
3
|
-
export = SchematicFormatWrapper
|
|
1
|
+
from .format_wrapper import SchematicFormatWrapper
|
|
2
|
+
|
|
3
|
+
export = SchematicFormatWrapper
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import numpy
|
|
2
|
-
from typing import List
|
|
3
|
-
|
|
4
|
-
from amulet_nbt import CompoundTag
|
|
5
|
-
|
|
6
|
-
from amulet.api.selection import SelectionBox
|
|
7
|
-
from .data_types import BlockDataArrayType, BlockArrayType
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class SchematicChunk:
|
|
11
|
-
def __init__(
|
|
12
|
-
self,
|
|
13
|
-
selection: SelectionBox,
|
|
14
|
-
blocks: BlockArrayType,
|
|
15
|
-
data: BlockDataArrayType,
|
|
16
|
-
block_entities: List[CompoundTag],
|
|
17
|
-
entities: List[CompoundTag],
|
|
18
|
-
):
|
|
19
|
-
self.selection = selection
|
|
20
|
-
self.blocks = blocks
|
|
21
|
-
self.data = data
|
|
22
|
-
self.block_entities = block_entities
|
|
23
|
-
self.entities = entities
|
|
24
|
-
|
|
25
|
-
@property
|
|
26
|
-
def blocks(self) -> BlockArrayType:
|
|
27
|
-
return self._blocks
|
|
28
|
-
|
|
29
|
-
@blocks.setter
|
|
30
|
-
def blocks(self, blocks: BlockArrayType):
|
|
31
|
-
if not (
|
|
32
|
-
isinstance(blocks, numpy.ndarray)
|
|
33
|
-
and blocks.shape == self.selection.shape
|
|
34
|
-
and blocks.dtype == numpy.uint16
|
|
35
|
-
):
|
|
36
|
-
raise TypeError(
|
|
37
|
-
"SchematicChunk.blocks must be a uint16 numpy array with shape that matches selection"
|
|
38
|
-
)
|
|
39
|
-
self._blocks = blocks
|
|
40
|
-
|
|
41
|
-
@property
|
|
42
|
-
def data(self) -> BlockDataArrayType:
|
|
43
|
-
return self._data
|
|
44
|
-
|
|
45
|
-
@data.setter
|
|
46
|
-
def data(self, data: BlockDataArrayType):
|
|
47
|
-
if not (
|
|
48
|
-
isinstance(data, numpy.ndarray)
|
|
49
|
-
and data.shape == self.selection.shape
|
|
50
|
-
and data.dtype == numpy.uint8
|
|
51
|
-
):
|
|
52
|
-
raise TypeError(
|
|
53
|
-
"SchematicChunk.data must be a uint8 numpy array with shape that matches selection"
|
|
54
|
-
)
|
|
55
|
-
self._data = data
|
|
1
|
+
import numpy
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
from amulet_nbt import CompoundTag
|
|
5
|
+
|
|
6
|
+
from amulet.api.selection import SelectionBox
|
|
7
|
+
from .data_types import BlockDataArrayType, BlockArrayType
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SchematicChunk:
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
selection: SelectionBox,
|
|
14
|
+
blocks: BlockArrayType,
|
|
15
|
+
data: BlockDataArrayType,
|
|
16
|
+
block_entities: List[CompoundTag],
|
|
17
|
+
entities: List[CompoundTag],
|
|
18
|
+
):
|
|
19
|
+
self.selection = selection
|
|
20
|
+
self.blocks = blocks
|
|
21
|
+
self.data = data
|
|
22
|
+
self.block_entities = block_entities
|
|
23
|
+
self.entities = entities
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def blocks(self) -> BlockArrayType:
|
|
27
|
+
return self._blocks
|
|
28
|
+
|
|
29
|
+
@blocks.setter
|
|
30
|
+
def blocks(self, blocks: BlockArrayType):
|
|
31
|
+
if not (
|
|
32
|
+
isinstance(blocks, numpy.ndarray)
|
|
33
|
+
and blocks.shape == self.selection.shape
|
|
34
|
+
and blocks.dtype == numpy.uint16
|
|
35
|
+
):
|
|
36
|
+
raise TypeError(
|
|
37
|
+
"SchematicChunk.blocks must be a uint16 numpy array with shape that matches selection"
|
|
38
|
+
)
|
|
39
|
+
self._blocks = blocks
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def data(self) -> BlockDataArrayType:
|
|
43
|
+
return self._data
|
|
44
|
+
|
|
45
|
+
@data.setter
|
|
46
|
+
def data(self, data: BlockDataArrayType):
|
|
47
|
+
if not (
|
|
48
|
+
isinstance(data, numpy.ndarray)
|
|
49
|
+
and data.shape == self.selection.shape
|
|
50
|
+
and data.dtype == numpy.uint8
|
|
51
|
+
):
|
|
52
|
+
raise TypeError(
|
|
53
|
+
"SchematicChunk.data must be a uint8 numpy array with shape that matches selection"
|
|
54
|
+
)
|
|
55
|
+
self._data = data
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import numpy
|
|
2
|
-
|
|
3
|
-
BlockArrayType = numpy.ndarray # uint16 array
|
|
4
|
-
BlockDataArrayType = numpy.ndarray # uint8 array
|
|
1
|
+
import numpy
|
|
2
|
+
|
|
3
|
+
BlockArrayType = numpy.ndarray # uint16 array
|
|
4
|
+
BlockDataArrayType = numpy.ndarray # uint8 array
|