amulet-core 2.0a3__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.
- amulet/__init__.cp312-win_amd64.pyd +0 -0
- amulet/__init__.pyi +30 -0
- amulet/__pyinstaller/__init__.py +2 -0
- amulet/__pyinstaller/hook-amulet.py +4 -0
- amulet/_init.py +28 -0
- amulet/_version.py +21 -0
- amulet/biome.cpp +36 -0
- amulet/biome.hpp +43 -0
- amulet/biome.pyi +77 -0
- amulet/block.cpp +435 -0
- amulet/block.hpp +119 -0
- amulet/block.pyi +273 -0
- amulet/block_entity.cpp +12 -0
- amulet/block_entity.hpp +56 -0
- amulet/block_entity.pyi +80 -0
- amulet/chunk.cpp +16 -0
- amulet/chunk.hpp +99 -0
- amulet/chunk.pyi +30 -0
- amulet/chunk_/components/biome.py +155 -0
- amulet/chunk_/components/block_entity.py +117 -0
- amulet/chunk_/components/entity.py +64 -0
- amulet/chunk_/components/height_2d.py +16 -0
- amulet/chunk_components.pyi +95 -0
- amulet/collections.pyi +37 -0
- amulet/data_types.py +29 -0
- amulet/entity.py +180 -0
- amulet/errors.py +63 -0
- amulet/game/__init__.py +7 -0
- amulet/game/_game.py +152 -0
- amulet/game/_universal/__init__.py +1 -0
- amulet/game/_universal/_biome.py +17 -0
- amulet/game/_universal/_block.py +47 -0
- amulet/game/_universal/_version.py +68 -0
- amulet/game/abc/__init__.py +22 -0
- amulet/game/abc/_block_specification.py +150 -0
- amulet/game/abc/biome.py +213 -0
- amulet/game/abc/block.py +331 -0
- amulet/game/abc/game_version_container.py +25 -0
- amulet/game/abc/json_interface.py +27 -0
- amulet/game/abc/version.py +44 -0
- amulet/game/bedrock/__init__.py +1 -0
- amulet/game/bedrock/_biome.py +35 -0
- amulet/game/bedrock/_block.py +42 -0
- amulet/game/bedrock/_version.py +165 -0
- amulet/game/java/__init__.py +2 -0
- amulet/game/java/_biome.py +35 -0
- amulet/game/java/_block.py +60 -0
- amulet/game/java/_version.py +176 -0
- amulet/game/translate/__init__.py +12 -0
- amulet/game/translate/_functions/__init__.py +15 -0
- amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
- amulet/game/translate/_functions/_code_functions/_text.py +553 -0
- amulet/game/translate/_functions/_code_functions/banner_pattern.py +67 -0
- amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +152 -0
- amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +88 -0
- amulet/game/translate/_functions/_code_functions/bedrock_sign.py +152 -0
- amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +16 -0
- amulet/game/translate/_functions/_code_functions/custom_name.py +146 -0
- amulet/game/translate/_functions/_frozen.py +66 -0
- amulet/game/translate/_functions/_state.py +54 -0
- amulet/game/translate/_functions/_typing.py +98 -0
- amulet/game/translate/_functions/abc.py +116 -0
- amulet/game/translate/_functions/carry_nbt.py +160 -0
- amulet/game/translate/_functions/carry_properties.py +80 -0
- amulet/game/translate/_functions/code.py +143 -0
- amulet/game/translate/_functions/map_block_name.py +66 -0
- amulet/game/translate/_functions/map_nbt.py +111 -0
- amulet/game/translate/_functions/map_properties.py +93 -0
- amulet/game/translate/_functions/multiblock.py +112 -0
- amulet/game/translate/_functions/new_block.py +42 -0
- amulet/game/translate/_functions/new_entity.py +43 -0
- amulet/game/translate/_functions/new_nbt.py +206 -0
- amulet/game/translate/_functions/new_properties.py +64 -0
- amulet/game/translate/_functions/sequence.py +51 -0
- amulet/game/translate/_functions/walk_input_nbt.py +331 -0
- amulet/game/translate/_translator.py +433 -0
- amulet/item.py +75 -0
- amulet/level/__init__.pyi +27 -0
- amulet/level/_load.py +100 -0
- amulet/level/abc/__init__.py +12 -0
- amulet/level/abc/_chunk_handle.py +335 -0
- amulet/level/abc/_dimension.py +86 -0
- amulet/level/abc/_history/__init__.py +1 -0
- amulet/level/abc/_history/_cache.py +224 -0
- amulet/level/abc/_history/_history_manager.py +291 -0
- amulet/level/abc/_level/__init__.py +5 -0
- amulet/level/abc/_level/_compactable_level.py +10 -0
- amulet/level/abc/_level/_creatable_level.py +29 -0
- amulet/level/abc/_level/_disk_level.py +17 -0
- amulet/level/abc/_level/_level.py +453 -0
- amulet/level/abc/_level/_loadable_level.py +42 -0
- amulet/level/abc/_player_storage.py +7 -0
- amulet/level/abc/_raw_level.py +187 -0
- amulet/level/abc/_registry.py +40 -0
- amulet/level/bedrock/__init__.py +2 -0
- amulet/level/bedrock/_chunk_handle.py +19 -0
- amulet/level/bedrock/_dimension.py +22 -0
- amulet/level/bedrock/_level.py +187 -0
- amulet/level/bedrock/_raw/__init__.py +5 -0
- amulet/level/bedrock/_raw/_actor_counter.py +53 -0
- amulet/level/bedrock/_raw/_chunk.py +54 -0
- amulet/level/bedrock/_raw/_chunk_decode.py +668 -0
- amulet/level/bedrock/_raw/_chunk_encode.py +602 -0
- amulet/level/bedrock/_raw/_constant.py +9 -0
- amulet/level/bedrock/_raw/_dimension.py +343 -0
- amulet/level/bedrock/_raw/_level.py +463 -0
- amulet/level/bedrock/_raw/_level_dat.py +90 -0
- amulet/level/bedrock/_raw/_typing.py +6 -0
- amulet/level/bedrock/_raw/leveldb_chunk_versions.py +83 -0
- amulet/level/bedrock/chunk/__init__.py +1 -0
- amulet/level/bedrock/chunk/_chunk.py +126 -0
- amulet/level/bedrock/chunk/components/__init__.py +0 -0
- amulet/level/bedrock/chunk/components/chunk_version.py +12 -0
- amulet/level/bedrock/chunk/components/finalised_state.py +13 -0
- amulet/level/bedrock/chunk/components/raw_chunk.py +15 -0
- amulet/level/construction/__init__.py +0 -0
- amulet/level/java/__init__.pyi +21 -0
- amulet/level/java/_chunk_handle.py +17 -0
- amulet/level/java/_chunk_handle.pyi +15 -0
- amulet/level/java/_dimension.py +20 -0
- amulet/level/java/_dimension.pyi +13 -0
- amulet/level/java/_level.py +184 -0
- amulet/level/java/_level.pyi +120 -0
- amulet/level/java/_raw/__init__.pyi +19 -0
- amulet/level/java/_raw/_chunk.pyi +23 -0
- amulet/level/java/_raw/_chunk_decode.py +561 -0
- amulet/level/java/_raw/_chunk_encode.py +463 -0
- amulet/level/java/_raw/_constant.py +9 -0
- amulet/level/java/_raw/_constant.pyi +20 -0
- amulet/level/java/_raw/_data_pack/__init__.py +2 -0
- amulet/level/java/_raw/_data_pack/__init__.pyi +8 -0
- amulet/level/java/_raw/_data_pack/data_pack.py +241 -0
- amulet/level/java/_raw/_data_pack/data_pack.pyi +197 -0
- amulet/level/java/_raw/_data_pack/data_pack_manager.py +77 -0
- amulet/level/java/_raw/_data_pack/data_pack_manager.pyi +75 -0
- amulet/level/java/_raw/_dimension.py +86 -0
- amulet/level/java/_raw/_dimension.pyi +72 -0
- amulet/level/java/_raw/_level.py +507 -0
- amulet/level/java/_raw/_level.pyi +238 -0
- amulet/level/java/_raw/_typing.py +3 -0
- amulet/level/java/_raw/_typing.pyi +5 -0
- amulet/level/java/anvil/__init__.py +2 -0
- amulet/level/java/anvil/__init__.pyi +11 -0
- amulet/level/java/anvil/_dimension.py +170 -0
- amulet/level/java/anvil/_dimension.pyi +109 -0
- amulet/level/java/anvil/_region.py +421 -0
- amulet/level/java/anvil/_region.pyi +197 -0
- amulet/level/java/anvil/_sector_manager.py +223 -0
- amulet/level/java/anvil/_sector_manager.pyi +142 -0
- amulet/level/java/chunk.pyi +81 -0
- amulet/level/java/chunk_/_chunk.py +260 -0
- amulet/level/java/chunk_/components/inhabited_time.py +12 -0
- amulet/level/java/chunk_/components/last_update.py +12 -0
- amulet/level/java/chunk_/components/legacy_version.py +12 -0
- amulet/level/java/chunk_/components/light_populated.py +12 -0
- amulet/level/java/chunk_/components/named_height_2d.py +37 -0
- amulet/level/java/chunk_/components/status.py +11 -0
- amulet/level/java/chunk_/components/terrain_populated.py +12 -0
- amulet/level/java/chunk_components.pyi +22 -0
- amulet/level/java/long_array.pyi +38 -0
- amulet/level/java_forge/__init__.py +0 -0
- amulet/level/mcstructure/__init__.py +0 -0
- amulet/level/nbt/__init__.py +0 -0
- amulet/level/schematic/__init__.py +0 -0
- amulet/level/sponge_schematic/__init__.py +0 -0
- amulet/level/temporary_level/__init__.py +1 -0
- amulet/level/temporary_level/_level.py +16 -0
- amulet/palette/__init__.pyi +8 -0
- amulet/palette/biome_palette.pyi +45 -0
- amulet/palette/block_palette.pyi +45 -0
- amulet/player.py +64 -0
- amulet/py.typed +0 -0
- amulet/selection/__init__.py +2 -0
- amulet/selection/abstract_selection.py +342 -0
- amulet/selection/box.py +852 -0
- amulet/selection/group.py +481 -0
- amulet/utils/__init__.pyi +28 -0
- amulet/utils/call_spec/__init__.py +24 -0
- amulet/utils/call_spec/__init__.pyi +53 -0
- amulet/utils/call_spec/_call_spec.py +262 -0
- amulet/utils/call_spec/_call_spec.pyi +272 -0
- amulet/utils/format_utils.py +41 -0
- amulet/utils/generator.py +18 -0
- amulet/utils/matrix.py +243 -0
- amulet/utils/matrix.pyi +177 -0
- amulet/utils/numpy.pyi +11 -0
- amulet/utils/numpy_helpers.py +19 -0
- amulet/utils/shareable_lock.py +335 -0
- amulet/utils/shareable_lock.pyi +190 -0
- amulet/utils/signal/__init__.py +10 -0
- amulet/utils/signal/__init__.pyi +25 -0
- amulet/utils/signal/_signal.py +228 -0
- amulet/utils/signal/_signal.pyi +84 -0
- amulet/utils/task_manager.py +235 -0
- amulet/utils/task_manager.pyi +168 -0
- amulet/utils/typed_property.py +111 -0
- amulet/utils/typing.py +4 -0
- amulet/utils/typing.pyi +6 -0
- amulet/utils/weakref.py +70 -0
- amulet/utils/weakref.pyi +50 -0
- amulet/utils/world_utils.py +102 -0
- amulet/utils/world_utils.pyi +109 -0
- amulet/version.cpp +136 -0
- amulet/version.hpp +142 -0
- amulet/version.pyi +94 -0
- amulet_core-2.0a3.dist-info/METADATA +103 -0
- amulet_core-2.0a3.dist-info/RECORD +210 -0
- amulet_core-2.0a3.dist-info/WHEEL +5 -0
- amulet_core-2.0a3.dist-info/entry_points.txt +2 -0
- amulet_core-2.0a3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING, Callable
|
|
3
|
+
|
|
4
|
+
import numpy
|
|
5
|
+
from amulet_nbt import (
|
|
6
|
+
NamedTag,
|
|
7
|
+
ByteTag,
|
|
8
|
+
ShortTag,
|
|
9
|
+
IntTag,
|
|
10
|
+
LongTag,
|
|
11
|
+
FloatTag,
|
|
12
|
+
DoubleTag,
|
|
13
|
+
StringTag,
|
|
14
|
+
CompoundTag,
|
|
15
|
+
ListTag,
|
|
16
|
+
ByteArrayTag,
|
|
17
|
+
IntArrayTag,
|
|
18
|
+
LongArrayTag,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from amulet.game import get_game_version
|
|
22
|
+
from amulet.game.java import Waterloggable
|
|
23
|
+
from amulet.block import Block, BlockStack, PropertyValueType
|
|
24
|
+
from amulet.biome import Biome
|
|
25
|
+
from amulet.block_entity import BlockEntity
|
|
26
|
+
from amulet.entity import Entity
|
|
27
|
+
from amulet.version import VersionNumber, VersionRange
|
|
28
|
+
from amulet.palette import BlockPalette
|
|
29
|
+
from amulet.chunk import ComponentDataMapping
|
|
30
|
+
from amulet.chunk.components.height_2d import Height2DComponent
|
|
31
|
+
from amulet.chunk.components.sub_chunk_array import SubChunkArrayContainer
|
|
32
|
+
from amulet.chunk.components.biome import (
|
|
33
|
+
Biome2DComponent,
|
|
34
|
+
Biome2DComponentData,
|
|
35
|
+
Biome3DComponent,
|
|
36
|
+
Biome3DComponentData,
|
|
37
|
+
)
|
|
38
|
+
from amulet.chunk.components.block import BlockComponent, BlockComponentData
|
|
39
|
+
from amulet.chunk.components.block_entity import (
|
|
40
|
+
BlockEntityComponent,
|
|
41
|
+
BlockEntityComponentData,
|
|
42
|
+
)
|
|
43
|
+
from amulet.chunk.components.entity import EntityComponent, EntityComponentData
|
|
44
|
+
|
|
45
|
+
from amulet.utils.world_utils import decode_long_array, from_nibble_array
|
|
46
|
+
from amulet.utils.numpy import unique_inverse
|
|
47
|
+
|
|
48
|
+
from amulet.level.java.anvil import RawChunkType
|
|
49
|
+
from amulet.level.java.chunk import (
|
|
50
|
+
JavaChunk,
|
|
51
|
+
JavaChunkNA,
|
|
52
|
+
JavaChunk0,
|
|
53
|
+
JavaChunk1444,
|
|
54
|
+
JavaChunk1466,
|
|
55
|
+
JavaChunk2203,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
from amulet.level.java.chunk.components.raw_chunk import RawChunkComponent
|
|
59
|
+
from amulet.level.java.chunk.components.data_version import DataVersionComponent
|
|
60
|
+
from amulet.level.java.chunk.components.legacy_version import LegacyVersionComponent
|
|
61
|
+
from amulet.level.java.chunk.components.status import StatusComponent
|
|
62
|
+
from amulet.level.java.chunk.components.light_populated import LightPopulatedComponent
|
|
63
|
+
from amulet.level.java.chunk.components.terrain_populated import (
|
|
64
|
+
TerrainPopulatedComponent,
|
|
65
|
+
)
|
|
66
|
+
from amulet.level.java.chunk.components.named_height_2d import (
|
|
67
|
+
NamedHeight2DComponent,
|
|
68
|
+
NamedHeight2DData,
|
|
69
|
+
)
|
|
70
|
+
from amulet.level.java.chunk.components.last_update import LastUpdateComponent
|
|
71
|
+
from amulet.level.java.chunk.components.inhabited_time import InhabitedTimeComponent
|
|
72
|
+
|
|
73
|
+
if TYPE_CHECKING:
|
|
74
|
+
from ._level import JavaRawLevel
|
|
75
|
+
from ._dimension import JavaRawDimension
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def raw_to_native(
|
|
79
|
+
raw_level: JavaRawLevel,
|
|
80
|
+
dimension: JavaRawDimension,
|
|
81
|
+
raw_chunk: RawChunkType,
|
|
82
|
+
cx: int,
|
|
83
|
+
cz: int,
|
|
84
|
+
) -> JavaChunk:
|
|
85
|
+
floor_y = dimension.bounds().min_y
|
|
86
|
+
ceil_y = dimension.bounds().max_y
|
|
87
|
+
height_y = ceil_y - floor_y
|
|
88
|
+
|
|
89
|
+
# Init the chunk components
|
|
90
|
+
chunk_components: ComponentDataMapping = {} # type: ignore
|
|
91
|
+
# Raw chunk data
|
|
92
|
+
chunk_components[RawChunkComponent] = raw_chunk
|
|
93
|
+
|
|
94
|
+
# Get the region object
|
|
95
|
+
region = raw_chunk.get("region", NamedTag()).compound
|
|
96
|
+
# Get the level object. This may not exist.
|
|
97
|
+
level = region.get_compound("Level", CompoundTag())
|
|
98
|
+
|
|
99
|
+
# Pull out the data version
|
|
100
|
+
chunk_components[DataVersionComponent] = data_version = region.pop_int(
|
|
101
|
+
"DataVersion", IntTag(-1)
|
|
102
|
+
).py_int
|
|
103
|
+
version = VersionNumber(data_version)
|
|
104
|
+
version_range = VersionRange("java", version, version)
|
|
105
|
+
game_version = get_game_version("java", version)
|
|
106
|
+
|
|
107
|
+
# Get the chunk class
|
|
108
|
+
chunk_class: type[JavaChunk]
|
|
109
|
+
if data_version >= 2203:
|
|
110
|
+
chunk_class = JavaChunk2203
|
|
111
|
+
elif data_version >= 1466:
|
|
112
|
+
chunk_class = JavaChunk1466
|
|
113
|
+
elif data_version >= 1444:
|
|
114
|
+
chunk_class = JavaChunk1444
|
|
115
|
+
elif data_version >= 0:
|
|
116
|
+
chunk_class = JavaChunk0
|
|
117
|
+
else:
|
|
118
|
+
chunk_class = JavaChunkNA
|
|
119
|
+
|
|
120
|
+
if data_version == -1:
|
|
121
|
+
chunk_components[LegacyVersionComponent] = level.pop_byte(
|
|
122
|
+
"V", ByteTag(1)
|
|
123
|
+
).py_int
|
|
124
|
+
|
|
125
|
+
# Chunk x and y pos
|
|
126
|
+
if data_version >= 2844:
|
|
127
|
+
assert region.pop_int("xPos") == IntTag(cx)
|
|
128
|
+
floor_cy = region.pop_int("yPos", IntTag(0)).py_int << 4
|
|
129
|
+
assert region.pop_int("zPos") == IntTag(cz)
|
|
130
|
+
else:
|
|
131
|
+
assert level.pop_int("xPos") == IntTag(cx)
|
|
132
|
+
floor_cy = 0
|
|
133
|
+
assert level.pop_int("zPos") == IntTag(cz)
|
|
134
|
+
|
|
135
|
+
# LastUpdate and InhabitedTime
|
|
136
|
+
if data_version >= 2844:
|
|
137
|
+
chunk_components[LastUpdateComponent] = region.pop_long(
|
|
138
|
+
"LastUpdate", LongTag(0)
|
|
139
|
+
).py_int
|
|
140
|
+
chunk_components[InhabitedTimeComponent] = region.pop_long(
|
|
141
|
+
"InhabitedTime", LongTag(0)
|
|
142
|
+
).py_int
|
|
143
|
+
else:
|
|
144
|
+
chunk_components[LastUpdateComponent] = level.pop_long(
|
|
145
|
+
"LastUpdate", LongTag(0)
|
|
146
|
+
).py_int
|
|
147
|
+
chunk_components[InhabitedTimeComponent] = level.pop_long(
|
|
148
|
+
"InhabitedTime", LongTag(0)
|
|
149
|
+
).py_int
|
|
150
|
+
|
|
151
|
+
# Status
|
|
152
|
+
if data_version >= 1444:
|
|
153
|
+
if data_version >= 2844:
|
|
154
|
+
status = region.pop_string("Status")
|
|
155
|
+
else:
|
|
156
|
+
status = level.pop_string("Status")
|
|
157
|
+
|
|
158
|
+
if status is not None:
|
|
159
|
+
chunk_components[StatusComponent] = status.py_str
|
|
160
|
+
elif data_version >= 3454:
|
|
161
|
+
chunk_components[StatusComponent] = "minecraft:full"
|
|
162
|
+
elif data_version >= 1912:
|
|
163
|
+
chunk_components[StatusComponent] = "full"
|
|
164
|
+
else:
|
|
165
|
+
chunk_components[StatusComponent] = "postprocessed"
|
|
166
|
+
else:
|
|
167
|
+
chunk_components[TerrainPopulatedComponent] = bool(
|
|
168
|
+
level.pop_byte("TerrainPopulated", ByteTag(1))
|
|
169
|
+
)
|
|
170
|
+
chunk_components[LightPopulatedComponent] = bool(
|
|
171
|
+
level.pop_byte("LightPopulated", ByteTag(1))
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Height map
|
|
175
|
+
if data_version >= 1466:
|
|
176
|
+
# CompoundTag of named heightmaps
|
|
177
|
+
if data_version >= 2844:
|
|
178
|
+
heights = region.pop_compound("HeightMaps", CompoundTag())
|
|
179
|
+
else:
|
|
180
|
+
heights = level.pop_compound("HeightMaps", CompoundTag())
|
|
181
|
+
arrays: dict[str, numpy.ndarray] = {}
|
|
182
|
+
for key, value in heights.items():
|
|
183
|
+
if isinstance(key, str) and isinstance(value, LongArrayTag):
|
|
184
|
+
arrays[key] = decode_long_array(
|
|
185
|
+
value.np_array,
|
|
186
|
+
256,
|
|
187
|
+
height_y.bit_length(),
|
|
188
|
+
dense=data_version <= 2529,
|
|
189
|
+
).reshape((16, 16)) + (floor_cy << 4)
|
|
190
|
+
chunk_components[NamedHeight2DComponent] = NamedHeight2DData((16, 16), arrays)
|
|
191
|
+
else:
|
|
192
|
+
# Single heightmap
|
|
193
|
+
height = level.pop_int_array("HeightMap")
|
|
194
|
+
if isinstance(height, IntArrayTag) and len(height) == 256:
|
|
195
|
+
chunk_components[Height2DComponent] = height.np_array.astype(
|
|
196
|
+
numpy.int64
|
|
197
|
+
).reshape((16, 16))
|
|
198
|
+
else:
|
|
199
|
+
chunk_components[Height2DComponent] = numpy.zeros((16, 16), numpy.int64)
|
|
200
|
+
|
|
201
|
+
if data_version >= 2844:
|
|
202
|
+
# region.sections[]
|
|
203
|
+
sections = region.get_list("sections", ListTag())
|
|
204
|
+
else:
|
|
205
|
+
# region.Level.sections[]
|
|
206
|
+
sections = level.get_list("sections", ListTag())
|
|
207
|
+
sections_map = {}
|
|
208
|
+
for section in sections:
|
|
209
|
+
assert isinstance(section, CompoundTag)
|
|
210
|
+
sections_map[section.get_byte("Y", ByteTag(0)).py_int] = section
|
|
211
|
+
|
|
212
|
+
# biomes
|
|
213
|
+
default_biome = dimension.default_biome()
|
|
214
|
+
if not version_range.contains(default_biome.platform, default_biome.version):
|
|
215
|
+
default_biome = get_game_version(
|
|
216
|
+
default_biome.platform, default_biome.version
|
|
217
|
+
).biome.translate("java", version, default_biome)
|
|
218
|
+
if data_version >= 2836:
|
|
219
|
+
# if data_version >= 2844:
|
|
220
|
+
# # region.sections[].biomes
|
|
221
|
+
# else:
|
|
222
|
+
# # region.Level.sections[].biomes
|
|
223
|
+
chunk_components[Biome3DComponent] = biome_data_3d = Biome3DComponentData(
|
|
224
|
+
version_range, (4, 4, 4), default_biome
|
|
225
|
+
)
|
|
226
|
+
for cy, section in sections_map.items():
|
|
227
|
+
biomes_structure = section.get_compound("biomes")
|
|
228
|
+
if biomes_structure is None:
|
|
229
|
+
continue
|
|
230
|
+
palette_tag = biomes_structure.get_list("palette", raise_errors=True)
|
|
231
|
+
lut = []
|
|
232
|
+
for biome_name in palette_tag:
|
|
233
|
+
assert isinstance(biome_name, StringTag)
|
|
234
|
+
namespace, base_name = biome_name.py_str.split(":", 1)
|
|
235
|
+
lut.append(
|
|
236
|
+
biome_data_3d.palette.biome_to_index(
|
|
237
|
+
Biome("java", version, namespace, base_name)
|
|
238
|
+
)
|
|
239
|
+
)
|
|
240
|
+
data = biomes_structure.get_long_array("data")
|
|
241
|
+
if data is None:
|
|
242
|
+
biome_data_3d.sections[cy] = numpy.full((4, 4, 4), lut[0], numpy.uint32)
|
|
243
|
+
else:
|
|
244
|
+
biome_data_3d.sections[cy] = numpy.array(lut, numpy.uint32)[
|
|
245
|
+
numpy.transpose(
|
|
246
|
+
decode_long_array(
|
|
247
|
+
data.np_array,
|
|
248
|
+
4**3,
|
|
249
|
+
max(1, (len(lut) - 1).bit_length()),
|
|
250
|
+
dense=data_version <= 2529,
|
|
251
|
+
)
|
|
252
|
+
.astype(numpy.uint32)
|
|
253
|
+
.reshape((4, 4, 4)),
|
|
254
|
+
(2, 0, 1),
|
|
255
|
+
)
|
|
256
|
+
]
|
|
257
|
+
elif data_version >= 2203:
|
|
258
|
+
# region.Level.Biomes (4x64x4 IntArrayTag[1024])
|
|
259
|
+
biomes_3d = level.pop_int_array("Biomes")
|
|
260
|
+
chunk_components[Biome3DComponent] = biome_data_3d = Biome3DComponentData(
|
|
261
|
+
version_range, (4, 4, 4), default_biome
|
|
262
|
+
)
|
|
263
|
+
if biomes_3d is not None:
|
|
264
|
+
arr: numpy.ndarray = biomes_3d.np_array
|
|
265
|
+
assert len(arr) % 64 == 0
|
|
266
|
+
numerical_ids, arr = numpy.unique(arr, return_inverse=True)
|
|
267
|
+
arr = numpy.transpose(
|
|
268
|
+
arr.astype(numpy.uint32).reshape((-1, 4, 4)),
|
|
269
|
+
(2, 0, 1),
|
|
270
|
+
) # YZX -> XYZ
|
|
271
|
+
lut = []
|
|
272
|
+
for numerical_id in numerical_ids:
|
|
273
|
+
try:
|
|
274
|
+
(
|
|
275
|
+
namespace,
|
|
276
|
+
base_name,
|
|
277
|
+
) = raw_level.biome_id_override.numerical_id_to_namespace_id(
|
|
278
|
+
numerical_id
|
|
279
|
+
)
|
|
280
|
+
except KeyError:
|
|
281
|
+
namespace, base_name = (
|
|
282
|
+
game_version.biome.numerical_id_to_namespace_id(numerical_id)
|
|
283
|
+
)
|
|
284
|
+
biome = Biome("java", version, namespace, base_name)
|
|
285
|
+
runtime_id = biome_data_3d.palette.biome_to_index(biome)
|
|
286
|
+
lut.append(runtime_id)
|
|
287
|
+
arr = numpy.array(lut, dtype=numpy.uint32)[arr]
|
|
288
|
+
for sy, sub_arr in enumerate(
|
|
289
|
+
numpy.split(
|
|
290
|
+
arr,
|
|
291
|
+
arr.shape[1] // 4,
|
|
292
|
+
1,
|
|
293
|
+
)
|
|
294
|
+
):
|
|
295
|
+
biome_data_3d.sections[sy + floor_cy] = sub_arr
|
|
296
|
+
else:
|
|
297
|
+
biomes_2d: ByteArrayTag | IntArrayTag | None
|
|
298
|
+
if data_version >= 1467:
|
|
299
|
+
# region.Level.Biomes (16x16 IntArrayTag[256])
|
|
300
|
+
biomes_2d = level.pop_int_array("Biomes")
|
|
301
|
+
else:
|
|
302
|
+
# region.Level.Biomes (16x16 ByteArrayTag[256])
|
|
303
|
+
biomes_2d = level.pop_byte_array("Biomes")
|
|
304
|
+
chunk_components[Biome2DComponent] = biome_data_2d = Biome2DComponentData(
|
|
305
|
+
version_range, (16, 16), default_biome
|
|
306
|
+
)
|
|
307
|
+
if biomes_2d is not None and len(biomes_2d) == 256:
|
|
308
|
+
_decode_2d_biomes(
|
|
309
|
+
biome_data_2d,
|
|
310
|
+
version,
|
|
311
|
+
biomes_2d.np_array,
|
|
312
|
+
raw_level.biome_id_override.numerical_id_to_namespace_id,
|
|
313
|
+
game_version.biome.numerical_id_to_namespace_id,
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
# blocks
|
|
317
|
+
blocks: list[Block] = []
|
|
318
|
+
for block in dimension.default_block():
|
|
319
|
+
if version_range.contains(block.platform, block.version):
|
|
320
|
+
blocks.append(block)
|
|
321
|
+
else:
|
|
322
|
+
block_ = get_game_version(block.platform, block.version).block.translate(
|
|
323
|
+
"java", version, block
|
|
324
|
+
)[0]
|
|
325
|
+
if isinstance(block_, Block):
|
|
326
|
+
blocks.append(block_)
|
|
327
|
+
chunk_components[BlockComponent] = block_component_data = BlockComponentData(
|
|
328
|
+
version_range, (16, 16, 16), BlockStack(*blocks)
|
|
329
|
+
)
|
|
330
|
+
block_palette: BlockPalette = block_component_data.palette
|
|
331
|
+
block_sections: SubChunkArrayContainer = block_component_data.sections
|
|
332
|
+
|
|
333
|
+
if data_version >= 1444:
|
|
334
|
+
# if data_version >= 2844:
|
|
335
|
+
# # region.sections[].block_states.data
|
|
336
|
+
# # region.sections[].block_states.palette
|
|
337
|
+
# elif data_version >= 2836:
|
|
338
|
+
# # region.Level.Sections[].block_states.data
|
|
339
|
+
# # region.Level.Sections[].block_states.palette
|
|
340
|
+
# else:
|
|
341
|
+
# # region.Level.Sections[].BlockStates
|
|
342
|
+
# # region.Level.Sections[].Palette
|
|
343
|
+
|
|
344
|
+
_water_block: Block | None = None
|
|
345
|
+
|
|
346
|
+
def get_water() -> Block:
|
|
347
|
+
nonlocal _water_block
|
|
348
|
+
if _water_block is None:
|
|
349
|
+
_block, _, _ = get_game_version(
|
|
350
|
+
"java", VersionNumber(1, 20, 5)
|
|
351
|
+
).block.translate(
|
|
352
|
+
"java",
|
|
353
|
+
version,
|
|
354
|
+
Block(
|
|
355
|
+
"java",
|
|
356
|
+
VersionNumber(1, 20, 5),
|
|
357
|
+
"minecraft",
|
|
358
|
+
"water",
|
|
359
|
+
{"level": StringTag("0")},
|
|
360
|
+
),
|
|
361
|
+
)
|
|
362
|
+
if not isinstance(_block, Block):
|
|
363
|
+
raise RuntimeError
|
|
364
|
+
_water_block = _block
|
|
365
|
+
return _water_block
|
|
366
|
+
|
|
367
|
+
for cy, section in sections_map.items():
|
|
368
|
+
if data_version >= 2836:
|
|
369
|
+
block_states_tag = section.pop_compound("block_states", CompoundTag())
|
|
370
|
+
palette_tag = block_states_tag.pop_list("palette")
|
|
371
|
+
data_tag = block_states_tag.pop_long_array("data")
|
|
372
|
+
else:
|
|
373
|
+
palette_tag = section.pop_list("Palette")
|
|
374
|
+
data_tag = section.pop_long_array("BlockStates")
|
|
375
|
+
if palette_tag is None:
|
|
376
|
+
continue
|
|
377
|
+
lut = []
|
|
378
|
+
for block_tag in palette_tag:
|
|
379
|
+
assert isinstance(block_tag, CompoundTag)
|
|
380
|
+
namespace, base_name = block_tag.get_string(
|
|
381
|
+
"Name", raise_errors=True
|
|
382
|
+
).py_str.split(":", 1)
|
|
383
|
+
properties = {
|
|
384
|
+
k: v
|
|
385
|
+
for k, v in block_tag.get_compound(
|
|
386
|
+
"Properties", CompoundTag({})
|
|
387
|
+
).items()
|
|
388
|
+
if isinstance(k, str) and isinstance(v, PropertyValueType)
|
|
389
|
+
}
|
|
390
|
+
blocks = []
|
|
391
|
+
waterloggable = game_version.block.waterloggable(namespace, base_name)
|
|
392
|
+
if waterloggable == Waterloggable.Yes:
|
|
393
|
+
# waterlogged property
|
|
394
|
+
if properties.get("waterlogged") == StringTag("true"):
|
|
395
|
+
del properties["waterlogged"]
|
|
396
|
+
blocks.append(get_water())
|
|
397
|
+
elif waterloggable == Waterloggable.Always:
|
|
398
|
+
blocks.append(get_water())
|
|
399
|
+
blocks.insert(
|
|
400
|
+
0, Block("java", version, namespace, base_name, properties)
|
|
401
|
+
)
|
|
402
|
+
lut.append(block_palette.block_stack_to_index(BlockStack(*blocks)))
|
|
403
|
+
|
|
404
|
+
if data_tag is None:
|
|
405
|
+
arr = numpy.zeros((16, 16, 16), numpy.uint32)
|
|
406
|
+
else:
|
|
407
|
+
decoded = decode_long_array(
|
|
408
|
+
data_tag.np_array,
|
|
409
|
+
16**3,
|
|
410
|
+
max(4, (len(palette_tag) - 1).bit_length()),
|
|
411
|
+
dense=data_version <= 2529,
|
|
412
|
+
).astype(numpy.uint32)
|
|
413
|
+
arr = numpy.transpose(decoded.reshape((16, 16, 16)), (2, 0, 1))
|
|
414
|
+
block_sections[cy] = numpy.array(lut, dtype=numpy.uint32)[arr]
|
|
415
|
+
else:
|
|
416
|
+
# region.Level.Sections[].Blocks
|
|
417
|
+
# region.Level.Sections[].Add
|
|
418
|
+
# region.Level.Sections[].Data
|
|
419
|
+
get_block_namespace_override = (
|
|
420
|
+
raw_level.biome_id_override.numerical_id_to_namespace_id
|
|
421
|
+
)
|
|
422
|
+
get_block_namespace_game = game_version.biome.numerical_id_to_namespace_id
|
|
423
|
+
for cy, section in sections_map.items():
|
|
424
|
+
block_tag = section.pop_byte_array("Blocks")
|
|
425
|
+
data_tag = section.pop_byte_array("Data")
|
|
426
|
+
if block_tag is None or data_tag is None:
|
|
427
|
+
continue
|
|
428
|
+
section_blocks = numpy.asarray(block_tag, dtype=numpy.uint16)
|
|
429
|
+
section_data = from_nibble_array(numpy.asarray(data_tag, dtype=numpy.uint8))
|
|
430
|
+
|
|
431
|
+
# add_tag = section.pop_byte_array("Add")
|
|
432
|
+
# if add_tag is not None:
|
|
433
|
+
# add_blocks = from_nibble_array(numpy.asarray(add_tag, dtype=numpy.uint8)).astype(numpy.uint16)
|
|
434
|
+
# section_blocks |= add_blocks << 8
|
|
435
|
+
# # TODO: fix this
|
|
436
|
+
|
|
437
|
+
section_palette, section_array = unique_inverse(
|
|
438
|
+
(section_blocks << 4) + section_data
|
|
439
|
+
)
|
|
440
|
+
section_array = numpy.transpose(
|
|
441
|
+
section_array.reshape((16, 16, 16)), (2, 0, 1)
|
|
442
|
+
) # YZX -> XYZ
|
|
443
|
+
section_block_ids = section_palette >> 4
|
|
444
|
+
section_block_datas = section_palette & 15
|
|
445
|
+
lut = []
|
|
446
|
+
for block_id, block_data in zip(section_block_ids, section_block_datas):
|
|
447
|
+
try:
|
|
448
|
+
namespace, base_name = get_block_namespace_override(block_id)
|
|
449
|
+
except KeyError:
|
|
450
|
+
try:
|
|
451
|
+
namespace, base_name = get_block_namespace_game(block_id)
|
|
452
|
+
except KeyError:
|
|
453
|
+
namespace = "numerical"
|
|
454
|
+
base_name = str(block_id)
|
|
455
|
+
lut.append(
|
|
456
|
+
block_palette.block_stack_to_index(
|
|
457
|
+
BlockStack(
|
|
458
|
+
Block(
|
|
459
|
+
"java",
|
|
460
|
+
version,
|
|
461
|
+
namespace,
|
|
462
|
+
base_name,
|
|
463
|
+
{"block_data": IntTag(block_data)},
|
|
464
|
+
)
|
|
465
|
+
)
|
|
466
|
+
)
|
|
467
|
+
)
|
|
468
|
+
block_sections[cy] = numpy.array(lut, dtype=numpy.uint32)[section_array]
|
|
469
|
+
|
|
470
|
+
# block entities
|
|
471
|
+
if data_version >= 2844:
|
|
472
|
+
# region.block_entities
|
|
473
|
+
block_entities = region.pop_list("block_entities", ListTag())
|
|
474
|
+
else:
|
|
475
|
+
# region.Level.TileEntities
|
|
476
|
+
block_entities = level.pop_list("TileEntities", ListTag())
|
|
477
|
+
chunk_components[BlockEntityComponent] = block_entity_component = (
|
|
478
|
+
BlockEntityComponentData(version_range)
|
|
479
|
+
)
|
|
480
|
+
for tag in block_entities:
|
|
481
|
+
if not isinstance(tag, CompoundTag):
|
|
482
|
+
continue
|
|
483
|
+
|
|
484
|
+
entity_id = tag.pop_string("id", raise_errors=True)
|
|
485
|
+
namespace, base_name = entity_id.py_str.split(":", 1)
|
|
486
|
+
x_int = tag.pop_int("x", raise_errors=True).py_int
|
|
487
|
+
y_int = tag.pop_int("y", raise_errors=True).py_int
|
|
488
|
+
z_int = tag.pop_int("z", raise_errors=True).py_int
|
|
489
|
+
|
|
490
|
+
block_entity_component[(x_int, y_int, z_int)] = BlockEntity(
|
|
491
|
+
"java", version, namespace, base_name, NamedTag(tag)
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
# entities
|
|
495
|
+
entities = ListTag[CompoundTag]()
|
|
496
|
+
if data_version >= 2681:
|
|
497
|
+
# It seems like the inline version can exist at the same time as the external format.
|
|
498
|
+
# entities.Entities
|
|
499
|
+
entity_layer = raw_chunk.get("entities", NamedTag()).compound
|
|
500
|
+
assert (
|
|
501
|
+
entity_layer.get_int("DataVersion", IntTag(data_version)).py_int
|
|
502
|
+
== data_version
|
|
503
|
+
), "data version mismatch."
|
|
504
|
+
entities.extend(entity_layer.pop_list("Entities", ListTag()))
|
|
505
|
+
if data_version >= 2844:
|
|
506
|
+
# region.entities
|
|
507
|
+
entities.extend(region.pop_list("entities", ListTag()))
|
|
508
|
+
else:
|
|
509
|
+
# region.Level.Entities
|
|
510
|
+
entities.extend(level.pop_list("Entities", ListTag()))
|
|
511
|
+
chunk_components[EntityComponent] = entity_component = EntityComponentData(
|
|
512
|
+
version_range
|
|
513
|
+
)
|
|
514
|
+
for tag in entities:
|
|
515
|
+
if not isinstance(tag, CompoundTag):
|
|
516
|
+
continue
|
|
517
|
+
|
|
518
|
+
entity_id = tag.pop_string("id", raise_errors=True)
|
|
519
|
+
namespace, base_name = entity_id.py_str.split(":", 1)
|
|
520
|
+
pos = tag.pop_list("Pos", raise_errors=True)
|
|
521
|
+
x_float = pos.get_double(0).py_float
|
|
522
|
+
y_float = pos.get_double(1).py_float
|
|
523
|
+
z_float = pos.get_double(2).py_float
|
|
524
|
+
entity_component.add(
|
|
525
|
+
Entity(
|
|
526
|
+
"java",
|
|
527
|
+
version,
|
|
528
|
+
namespace,
|
|
529
|
+
base_name,
|
|
530
|
+
x_float,
|
|
531
|
+
y_float,
|
|
532
|
+
z_float,
|
|
533
|
+
NamedTag(tag),
|
|
534
|
+
)
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
return chunk_class.from_component_data(chunk_components)
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
def _decode_2d_biomes(
|
|
541
|
+
biome_data_2d: Biome2DComponentData,
|
|
542
|
+
version: VersionNumber,
|
|
543
|
+
arr: numpy.ndarray,
|
|
544
|
+
numerical_id_to_namespace_id_override: Callable[[int], tuple[str, str]],
|
|
545
|
+
numerical_id_to_namespace_id: Callable[[int], tuple[str, str]],
|
|
546
|
+
) -> None:
|
|
547
|
+
numerical_ids, arr = numpy.unique(arr, return_inverse=True)
|
|
548
|
+
arr = arr.reshape(16, 16).T.astype(numpy.uint32)
|
|
549
|
+
lut = []
|
|
550
|
+
for numerical_id in numerical_ids:
|
|
551
|
+
try:
|
|
552
|
+
(
|
|
553
|
+
namespace,
|
|
554
|
+
base_name,
|
|
555
|
+
) = numerical_id_to_namespace_id_override(numerical_id)
|
|
556
|
+
except KeyError:
|
|
557
|
+
namespace, base_name = numerical_id_to_namespace_id(numerical_id)
|
|
558
|
+
biome = Biome("java", version, namespace, base_name)
|
|
559
|
+
runtime_id = biome_data_2d.palette.biome_to_index(biome)
|
|
560
|
+
lut.append(runtime_id)
|
|
561
|
+
biome_data_2d.array[:, :] = numpy.array(lut, dtype=numpy.uint32)[arr]
|