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
amulet/api/chunk/chunk.py
CHANGED
|
@@ -1,389 +1,389 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Union, Iterable, Dict
|
|
4
|
-
import time
|
|
5
|
-
import numpy
|
|
6
|
-
import pickle
|
|
7
|
-
|
|
8
|
-
from amulet.api.block import Block
|
|
9
|
-
from amulet.api.registry import BlockManager
|
|
10
|
-
from amulet.api.registry.biome_manager import BiomeManager
|
|
11
|
-
from amulet.api.chunk import (
|
|
12
|
-
Biomes,
|
|
13
|
-
BiomesShape,
|
|
14
|
-
Blocks,
|
|
15
|
-
Status,
|
|
16
|
-
BlockEntityDict,
|
|
17
|
-
EntityList,
|
|
18
|
-
)
|
|
19
|
-
from amulet.api.entity import Entity
|
|
20
|
-
from amulet.api.data_types import ChunkCoordinates, VersionIdentifierType
|
|
21
|
-
from amulet.api.history.changeable import Changeable
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class Chunk(Changeable):
|
|
25
|
-
"""
|
|
26
|
-
A class to represent a chunk that exists in a Minecraft world
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
def __init__(self, cx: int, cz: int):
|
|
30
|
-
"""
|
|
31
|
-
Construct an instance of :class:`Chunk` at the given coordinates.
|
|
32
|
-
|
|
33
|
-
:param cx: The x coordinate of the chunk (is not the same as block coordinates)
|
|
34
|
-
:param cz: The z coordinate of the chunk (is not the same as block coordinates)
|
|
35
|
-
"""
|
|
36
|
-
super().__init__()
|
|
37
|
-
self._cx, self._cz = cx, cz
|
|
38
|
-
self._changed_time = 0.0
|
|
39
|
-
|
|
40
|
-
self._blocks = None
|
|
41
|
-
self.__block_palette = BlockManager()
|
|
42
|
-
self.__biome_palette = BiomeManager()
|
|
43
|
-
self._biomes = None
|
|
44
|
-
self._entities = EntityList()
|
|
45
|
-
self._block_entities = BlockEntityDict()
|
|
46
|
-
self._status = Status()
|
|
47
|
-
self._misc = {} # all entries that are not important enough to get an attribute
|
|
48
|
-
|
|
49
|
-
# TODO: remove these variables. They are temporary until the translator supports entities
|
|
50
|
-
self._native_version: VersionIdentifierType = ("java", 0)
|
|
51
|
-
self._native_entities = EntityList()
|
|
52
|
-
|
|
53
|
-
def __repr__(self):
|
|
54
|
-
return f"Chunk({self.cx}, {self.cz}, {repr(self._blocks)}, {repr(self._entities)}, {repr(self._block_entities)})"
|
|
55
|
-
|
|
56
|
-
def pickle(self) -> bytes:
|
|
57
|
-
"""
|
|
58
|
-
Serialise the data in the chunk using pickle and return the resulting bytes.
|
|
59
|
-
|
|
60
|
-
:return: Pickled output.
|
|
61
|
-
"""
|
|
62
|
-
chunk_data = (
|
|
63
|
-
self._cx,
|
|
64
|
-
self._cz,
|
|
65
|
-
self._changed_time,
|
|
66
|
-
{sy: self.blocks.get_sub_chunk(sy) for sy in self.blocks.sub_chunks},
|
|
67
|
-
self.biomes.to_raw(),
|
|
68
|
-
self._entities.data,
|
|
69
|
-
tuple(self._block_entities.data.values()),
|
|
70
|
-
self._status.value,
|
|
71
|
-
self.misc,
|
|
72
|
-
self._native_entities,
|
|
73
|
-
self._native_version,
|
|
74
|
-
)
|
|
75
|
-
return pickle.dumps(chunk_data)
|
|
76
|
-
|
|
77
|
-
@classmethod
|
|
78
|
-
def unpickle(
|
|
79
|
-
cls,
|
|
80
|
-
pickled_bytes: bytes,
|
|
81
|
-
block_palette: BlockManager,
|
|
82
|
-
biome_palette: BiomeManager,
|
|
83
|
-
) -> Chunk:
|
|
84
|
-
"""
|
|
85
|
-
Deserialise the pickled input and unpack the data into an instance of :class:`Chunk`
|
|
86
|
-
|
|
87
|
-
:param pickled_bytes: The bytes returned from :func:`pickle`
|
|
88
|
-
:param block_palette: The instance of :class:`BlockManager` associated with the level.
|
|
89
|
-
:param biome_palette: The instance of :class:`BiomeManager` associated with the level.
|
|
90
|
-
:return: An instance of :class:`Chunk` containing the unpickled data.
|
|
91
|
-
"""
|
|
92
|
-
chunk_data = pickle.loads(pickled_bytes)
|
|
93
|
-
self = cls(*chunk_data[:2])
|
|
94
|
-
(
|
|
95
|
-
self.blocks,
|
|
96
|
-
biomes,
|
|
97
|
-
self.entities,
|
|
98
|
-
self.block_entities,
|
|
99
|
-
self.status,
|
|
100
|
-
self.misc,
|
|
101
|
-
self._native_entities,
|
|
102
|
-
self._native_version,
|
|
103
|
-
) = chunk_data[3:]
|
|
104
|
-
|
|
105
|
-
self._biomes = Biomes.from_raw(*biomes)
|
|
106
|
-
|
|
107
|
-
self._changed_time = chunk_data[2]
|
|
108
|
-
self._block_palette = block_palette
|
|
109
|
-
self._biome_palette = biome_palette
|
|
110
|
-
self.changed = False
|
|
111
|
-
return self
|
|
112
|
-
|
|
113
|
-
@property
|
|
114
|
-
def cx(self) -> int:
|
|
115
|
-
"""The chunk's x coordinate"""
|
|
116
|
-
return self._cx
|
|
117
|
-
|
|
118
|
-
@property
|
|
119
|
-
def cz(self) -> int:
|
|
120
|
-
"""The chunk's z coordinate"""
|
|
121
|
-
return self._cz
|
|
122
|
-
|
|
123
|
-
@property
|
|
124
|
-
def coordinates(self) -> ChunkCoordinates:
|
|
125
|
-
"""The chunk's x and z coordinates"""
|
|
126
|
-
return self._cx, self._cz
|
|
127
|
-
|
|
128
|
-
@property
|
|
129
|
-
def changed(self) -> bool:
|
|
130
|
-
"""
|
|
131
|
-
Has the chunk changed since the last undo point. Is used to track which chunks have changed.
|
|
132
|
-
|
|
133
|
-
>>> chunk = Chunk(0, 0)
|
|
134
|
-
>>> # Run this to notify that the chunk data has changed.
|
|
135
|
-
>>> chunk.changed = True
|
|
136
|
-
|
|
137
|
-
:setter: Set this to ``True`` if you have modified the chunk in any way.
|
|
138
|
-
:return: ``True`` if the chunk has been changed since the last undo point, ``False`` otherwise.
|
|
139
|
-
"""
|
|
140
|
-
return self._changed
|
|
141
|
-
|
|
142
|
-
@changed.setter
|
|
143
|
-
def changed(self, changed: bool):
|
|
144
|
-
assert isinstance(changed, bool), "Changed value must be a bool"
|
|
145
|
-
self._changed = changed
|
|
146
|
-
if changed:
|
|
147
|
-
self._changed_time = time.time()
|
|
148
|
-
|
|
149
|
-
@property
|
|
150
|
-
def changed_time(self) -> float:
|
|
151
|
-
"""
|
|
152
|
-
The last time the chunk was changed
|
|
153
|
-
|
|
154
|
-
Used to track if the chunk was changed since the last save snapshot and if the chunk model needs rebuilding.
|
|
155
|
-
"""
|
|
156
|
-
return self._changed_time
|
|
157
|
-
|
|
158
|
-
@property
|
|
159
|
-
def blocks(self) -> Blocks:
|
|
160
|
-
"""
|
|
161
|
-
The block array for the chunk.
|
|
162
|
-
|
|
163
|
-
This is a custom class that stores a numpy array per sub-chunk.
|
|
164
|
-
|
|
165
|
-
The values in the arrays are indexes into :attr:`block_palette`.
|
|
166
|
-
"""
|
|
167
|
-
if self._blocks is None:
|
|
168
|
-
self._blocks = Blocks()
|
|
169
|
-
return self._blocks
|
|
170
|
-
|
|
171
|
-
@blocks.setter
|
|
172
|
-
def blocks(self, value: Union[Dict[int, numpy.ndarray], Blocks, None]):
|
|
173
|
-
if isinstance(value, dict):
|
|
174
|
-
value: Dict[int, numpy.ndarray]
|
|
175
|
-
value = {k: v.astype(numpy.uint32) for k, v in value.items()}
|
|
176
|
-
self._blocks = Blocks(value)
|
|
177
|
-
|
|
178
|
-
def get_block(self, dx: int, y: int, dz: int) -> Block:
|
|
179
|
-
"""
|
|
180
|
-
Get the universal Block object at the given location within the chunk.
|
|
181
|
-
|
|
182
|
-
:param dx: The x coordinate within the chunk. 0-15 inclusive
|
|
183
|
-
:param y: The y coordinate within the chunk. This can be any integer.
|
|
184
|
-
:param dz: The z coordinate within the chunk. 0-15 inclusive
|
|
185
|
-
:return: The universal Block object representation of the block at that location
|
|
186
|
-
"""
|
|
187
|
-
return self.block_palette[self.blocks[dx, y, dz]]
|
|
188
|
-
|
|
189
|
-
def set_block(self, dx: int, y: int, dz: int, block: Block):
|
|
190
|
-
"""
|
|
191
|
-
Set the universal Block object at the given location within the chunk.
|
|
192
|
-
|
|
193
|
-
:param dx: The x coordinate within the chunk. 0-15 inclusive
|
|
194
|
-
:param y: The y coordinate within the chunk. This can be any integer.
|
|
195
|
-
:param dz: The z coordinate within the chunk. 0-15 inclusive
|
|
196
|
-
:param block: The universal Block object to set at the given location
|
|
197
|
-
"""
|
|
198
|
-
self.blocks[dx, y, dz] = self.block_palette.get_add_block(block)
|
|
199
|
-
|
|
200
|
-
@property
|
|
201
|
-
def _block_palette(self) -> BlockManager:
|
|
202
|
-
"""The block block_palette for the chunk.
|
|
203
|
-
Usually will refer to a global block block_palette."""
|
|
204
|
-
return self.__block_palette
|
|
205
|
-
|
|
206
|
-
@_block_palette.setter
|
|
207
|
-
def _block_palette(self, new_block_palette: BlockManager):
|
|
208
|
-
"""Change the block block_palette for the chunk.
|
|
209
|
-
This will change the block block_palette but leave the block array unchanged.
|
|
210
|
-
Only use this if you know what you are doing.
|
|
211
|
-
Designed for internal use. You probably want to use Chunk.block_palette"""
|
|
212
|
-
assert isinstance(new_block_palette, BlockManager)
|
|
213
|
-
self.__block_palette = new_block_palette
|
|
214
|
-
|
|
215
|
-
@property
|
|
216
|
-
def block_palette(self) -> BlockManager:
|
|
217
|
-
"""
|
|
218
|
-
The block block_palette for the chunk.
|
|
219
|
-
|
|
220
|
-
Usually will refer to the level's global block_palette.
|
|
221
|
-
"""
|
|
222
|
-
return self._block_palette
|
|
223
|
-
|
|
224
|
-
@block_palette.setter
|
|
225
|
-
def block_palette(self, new_block_palette: BlockManager):
|
|
226
|
-
"""
|
|
227
|
-
Change the block block_palette for the chunk.
|
|
228
|
-
|
|
229
|
-
This will copy over all block states from the old block_palette and remap the block indexes to use the new block_palette.
|
|
230
|
-
"""
|
|
231
|
-
assert isinstance(new_block_palette, BlockManager)
|
|
232
|
-
if new_block_palette is not self._block_palette:
|
|
233
|
-
# if current block block_palette and the new block block_palette are not the same object
|
|
234
|
-
if self._block_palette:
|
|
235
|
-
# if there are blocks in the current block block_palette remap the data
|
|
236
|
-
block_lut = numpy.array(
|
|
237
|
-
[
|
|
238
|
-
new_block_palette.get_add_block(block)
|
|
239
|
-
for block in self._block_palette.blocks
|
|
240
|
-
],
|
|
241
|
-
dtype=numpy.uint32,
|
|
242
|
-
)
|
|
243
|
-
for cy in self.blocks.sub_chunks:
|
|
244
|
-
self.blocks.add_sub_chunk(
|
|
245
|
-
cy, block_lut[self.blocks.get_sub_chunk(cy)]
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
self.__block_palette = new_block_palette
|
|
249
|
-
|
|
250
|
-
@property
|
|
251
|
-
def biomes(self) -> Biomes:
|
|
252
|
-
"""
|
|
253
|
-
The biome array for the chunk.
|
|
254
|
-
|
|
255
|
-
This is a custom class that stores numpy arrays. See the :class:`Biomes` documentation for more information.
|
|
256
|
-
|
|
257
|
-
The values in the arrays are indexes into :attr:`biome_palette`.
|
|
258
|
-
"""
|
|
259
|
-
if self._biomes is None:
|
|
260
|
-
self._biomes = Biomes()
|
|
261
|
-
return self._biomes
|
|
262
|
-
|
|
263
|
-
@biomes.setter
|
|
264
|
-
def biomes(self, value: Union[Biomes, Dict[int, numpy.ndarray]]):
|
|
265
|
-
self._biomes = Biomes(value)
|
|
266
|
-
|
|
267
|
-
@property
|
|
268
|
-
def _biome_palette(self) -> BiomeManager:
|
|
269
|
-
"""
|
|
270
|
-
The biome_palette for the chunk.
|
|
271
|
-
|
|
272
|
-
Usually will refer to a global biome_palette.
|
|
273
|
-
"""
|
|
274
|
-
return self.__biome_palette
|
|
275
|
-
|
|
276
|
-
@_biome_palette.setter
|
|
277
|
-
def _biome_palette(self, new_biome_palette: BiomeManager):
|
|
278
|
-
"""
|
|
279
|
-
Change the biome_palette for the chunk.
|
|
280
|
-
|
|
281
|
-
This will change the biome_palette but leave the biome array unchanged.
|
|
282
|
-
|
|
283
|
-
Only use this if you know what you are doing.
|
|
284
|
-
|
|
285
|
-
Designed for internal use. You probably want to use Chunk.biome_palette
|
|
286
|
-
"""
|
|
287
|
-
assert isinstance(new_biome_palette, BiomeManager)
|
|
288
|
-
self.__biome_palette = new_biome_palette
|
|
289
|
-
|
|
290
|
-
@property
|
|
291
|
-
def biome_palette(self) -> BiomeManager:
|
|
292
|
-
"""
|
|
293
|
-
The biome block_palette for the chunk.
|
|
294
|
-
|
|
295
|
-
Usually will refer to the level's global biome_palette.
|
|
296
|
-
"""
|
|
297
|
-
return self._biome_palette
|
|
298
|
-
|
|
299
|
-
@biome_palette.setter
|
|
300
|
-
def biome_palette(self, new_biome_palette: BiomeManager):
|
|
301
|
-
"""
|
|
302
|
-
Change the biome_palette for the chunk.
|
|
303
|
-
|
|
304
|
-
This will copy over all biome states from the old biome_palette and remap the biome indexes to use the new_biome_palette.
|
|
305
|
-
"""
|
|
306
|
-
assert isinstance(new_biome_palette, BiomeManager)
|
|
307
|
-
if new_biome_palette is not self._biome_palette:
|
|
308
|
-
# if current biome_palette and the new biome_palette are not the same object
|
|
309
|
-
if self._biome_palette:
|
|
310
|
-
# if there are biomes in the current biome_palette remap the data
|
|
311
|
-
biome_lut = numpy.array(
|
|
312
|
-
[
|
|
313
|
-
new_biome_palette.get_add_biome(biome)
|
|
314
|
-
for biome in self._biome_palette.biomes
|
|
315
|
-
],
|
|
316
|
-
dtype=numpy.uint32,
|
|
317
|
-
)
|
|
318
|
-
if self.biomes.dimension == BiomesShape.Shape2D:
|
|
319
|
-
self.biomes = biome_lut[self.biomes]
|
|
320
|
-
elif self.biomes.dimension == BiomesShape.Shape3D:
|
|
321
|
-
self.biomes = {
|
|
322
|
-
sy: biome_lut[self.biomes.get_section(sy)]
|
|
323
|
-
for sy in self.biomes.sections
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
self.__biome_palette = new_biome_palette
|
|
327
|
-
|
|
328
|
-
@property
|
|
329
|
-
def entities(self) -> EntityList:
|
|
330
|
-
"""
|
|
331
|
-
Property that returns the chunk's entity list. Setting this property replaces the chunk's entity list
|
|
332
|
-
|
|
333
|
-
:return: A list of all the entities contained in the chunk
|
|
334
|
-
"""
|
|
335
|
-
return self._entities
|
|
336
|
-
|
|
337
|
-
@entities.setter
|
|
338
|
-
def entities(self, value: Iterable[Entity]):
|
|
339
|
-
"""
|
|
340
|
-
:param value: The new entity list
|
|
341
|
-
:type value: list
|
|
342
|
-
:return:
|
|
343
|
-
"""
|
|
344
|
-
if self._entities != value:
|
|
345
|
-
self._entities = EntityList(value)
|
|
346
|
-
|
|
347
|
-
@property
|
|
348
|
-
def block_entities(self) -> BlockEntityDict:
|
|
349
|
-
"""
|
|
350
|
-
Property that returns the chunk's block entity list. Setting this property replaces the chunk's block entity list
|
|
351
|
-
|
|
352
|
-
:return: A list of all the block entities contained in the chunk
|
|
353
|
-
"""
|
|
354
|
-
return self._block_entities
|
|
355
|
-
|
|
356
|
-
@block_entities.setter
|
|
357
|
-
def block_entities(self, value: BlockEntityDict.InputType):
|
|
358
|
-
"""
|
|
359
|
-
:param value: The new block entity list
|
|
360
|
-
:type value: list
|
|
361
|
-
:return:
|
|
362
|
-
"""
|
|
363
|
-
if self._block_entities != value:
|
|
364
|
-
self._block_entities = BlockEntityDict(value)
|
|
365
|
-
|
|
366
|
-
@property
|
|
367
|
-
def status(self) -> Status:
|
|
368
|
-
"""
|
|
369
|
-
A class containing the chunk's generation status.
|
|
370
|
-
"""
|
|
371
|
-
return self._status
|
|
372
|
-
|
|
373
|
-
@status.setter
|
|
374
|
-
def status(self, value: Union[float, int, str]):
|
|
375
|
-
self._status.value = value
|
|
376
|
-
|
|
377
|
-
@property
|
|
378
|
-
def misc(self) -> dict:
|
|
379
|
-
"""
|
|
380
|
-
Extra data that exists in a chunk but does not have its own location.
|
|
381
|
-
|
|
382
|
-
Data in here is not guaranteed to exist and may get moved at a later date.
|
|
383
|
-
"""
|
|
384
|
-
return self._misc
|
|
385
|
-
|
|
386
|
-
@misc.setter
|
|
387
|
-
def misc(self, misc: dict):
|
|
388
|
-
assert isinstance(misc, dict), "misc must be a dictionary."
|
|
389
|
-
self._misc = misc
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Union, Iterable, Dict
|
|
4
|
+
import time
|
|
5
|
+
import numpy
|
|
6
|
+
import pickle
|
|
7
|
+
|
|
8
|
+
from amulet.api.block import Block
|
|
9
|
+
from amulet.api.registry import BlockManager
|
|
10
|
+
from amulet.api.registry.biome_manager import BiomeManager
|
|
11
|
+
from amulet.api.chunk import (
|
|
12
|
+
Biomes,
|
|
13
|
+
BiomesShape,
|
|
14
|
+
Blocks,
|
|
15
|
+
Status,
|
|
16
|
+
BlockEntityDict,
|
|
17
|
+
EntityList,
|
|
18
|
+
)
|
|
19
|
+
from amulet.api.entity import Entity
|
|
20
|
+
from amulet.api.data_types import ChunkCoordinates, VersionIdentifierType
|
|
21
|
+
from amulet.api.history.changeable import Changeable
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Chunk(Changeable):
|
|
25
|
+
"""
|
|
26
|
+
A class to represent a chunk that exists in a Minecraft world
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, cx: int, cz: int):
|
|
30
|
+
"""
|
|
31
|
+
Construct an instance of :class:`Chunk` at the given coordinates.
|
|
32
|
+
|
|
33
|
+
:param cx: The x coordinate of the chunk (is not the same as block coordinates)
|
|
34
|
+
:param cz: The z coordinate of the chunk (is not the same as block coordinates)
|
|
35
|
+
"""
|
|
36
|
+
super().__init__()
|
|
37
|
+
self._cx, self._cz = cx, cz
|
|
38
|
+
self._changed_time = 0.0
|
|
39
|
+
|
|
40
|
+
self._blocks = None
|
|
41
|
+
self.__block_palette = BlockManager()
|
|
42
|
+
self.__biome_palette = BiomeManager()
|
|
43
|
+
self._biomes = None
|
|
44
|
+
self._entities = EntityList()
|
|
45
|
+
self._block_entities = BlockEntityDict()
|
|
46
|
+
self._status = Status()
|
|
47
|
+
self._misc = {} # all entries that are not important enough to get an attribute
|
|
48
|
+
|
|
49
|
+
# TODO: remove these variables. They are temporary until the translator supports entities
|
|
50
|
+
self._native_version: VersionIdentifierType = ("java", 0)
|
|
51
|
+
self._native_entities = EntityList()
|
|
52
|
+
|
|
53
|
+
def __repr__(self):
|
|
54
|
+
return f"Chunk({self.cx}, {self.cz}, {repr(self._blocks)}, {repr(self._entities)}, {repr(self._block_entities)})"
|
|
55
|
+
|
|
56
|
+
def pickle(self) -> bytes:
|
|
57
|
+
"""
|
|
58
|
+
Serialise the data in the chunk using pickle and return the resulting bytes.
|
|
59
|
+
|
|
60
|
+
:return: Pickled output.
|
|
61
|
+
"""
|
|
62
|
+
chunk_data = (
|
|
63
|
+
self._cx,
|
|
64
|
+
self._cz,
|
|
65
|
+
self._changed_time,
|
|
66
|
+
{sy: self.blocks.get_sub_chunk(sy) for sy in self.blocks.sub_chunks},
|
|
67
|
+
self.biomes.to_raw(),
|
|
68
|
+
self._entities.data,
|
|
69
|
+
tuple(self._block_entities.data.values()),
|
|
70
|
+
self._status.value,
|
|
71
|
+
self.misc,
|
|
72
|
+
self._native_entities,
|
|
73
|
+
self._native_version,
|
|
74
|
+
)
|
|
75
|
+
return pickle.dumps(chunk_data)
|
|
76
|
+
|
|
77
|
+
@classmethod
|
|
78
|
+
def unpickle(
|
|
79
|
+
cls,
|
|
80
|
+
pickled_bytes: bytes,
|
|
81
|
+
block_palette: BlockManager,
|
|
82
|
+
biome_palette: BiomeManager,
|
|
83
|
+
) -> Chunk:
|
|
84
|
+
"""
|
|
85
|
+
Deserialise the pickled input and unpack the data into an instance of :class:`Chunk`
|
|
86
|
+
|
|
87
|
+
:param pickled_bytes: The bytes returned from :func:`pickle`
|
|
88
|
+
:param block_palette: The instance of :class:`BlockManager` associated with the level.
|
|
89
|
+
:param biome_palette: The instance of :class:`BiomeManager` associated with the level.
|
|
90
|
+
:return: An instance of :class:`Chunk` containing the unpickled data.
|
|
91
|
+
"""
|
|
92
|
+
chunk_data = pickle.loads(pickled_bytes)
|
|
93
|
+
self = cls(*chunk_data[:2])
|
|
94
|
+
(
|
|
95
|
+
self.blocks,
|
|
96
|
+
biomes,
|
|
97
|
+
self.entities,
|
|
98
|
+
self.block_entities,
|
|
99
|
+
self.status,
|
|
100
|
+
self.misc,
|
|
101
|
+
self._native_entities,
|
|
102
|
+
self._native_version,
|
|
103
|
+
) = chunk_data[3:]
|
|
104
|
+
|
|
105
|
+
self._biomes = Biomes.from_raw(*biomes)
|
|
106
|
+
|
|
107
|
+
self._changed_time = chunk_data[2]
|
|
108
|
+
self._block_palette = block_palette
|
|
109
|
+
self._biome_palette = biome_palette
|
|
110
|
+
self.changed = False
|
|
111
|
+
return self
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def cx(self) -> int:
|
|
115
|
+
"""The chunk's x coordinate"""
|
|
116
|
+
return self._cx
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def cz(self) -> int:
|
|
120
|
+
"""The chunk's z coordinate"""
|
|
121
|
+
return self._cz
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def coordinates(self) -> ChunkCoordinates:
|
|
125
|
+
"""The chunk's x and z coordinates"""
|
|
126
|
+
return self._cx, self._cz
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def changed(self) -> bool:
|
|
130
|
+
"""
|
|
131
|
+
Has the chunk changed since the last undo point. Is used to track which chunks have changed.
|
|
132
|
+
|
|
133
|
+
>>> chunk = Chunk(0, 0)
|
|
134
|
+
>>> # Run this to notify that the chunk data has changed.
|
|
135
|
+
>>> chunk.changed = True
|
|
136
|
+
|
|
137
|
+
:setter: Set this to ``True`` if you have modified the chunk in any way.
|
|
138
|
+
:return: ``True`` if the chunk has been changed since the last undo point, ``False`` otherwise.
|
|
139
|
+
"""
|
|
140
|
+
return self._changed
|
|
141
|
+
|
|
142
|
+
@changed.setter
|
|
143
|
+
def changed(self, changed: bool):
|
|
144
|
+
assert isinstance(changed, bool), "Changed value must be a bool"
|
|
145
|
+
self._changed = changed
|
|
146
|
+
if changed:
|
|
147
|
+
self._changed_time = time.time()
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def changed_time(self) -> float:
|
|
151
|
+
"""
|
|
152
|
+
The last time the chunk was changed
|
|
153
|
+
|
|
154
|
+
Used to track if the chunk was changed since the last save snapshot and if the chunk model needs rebuilding.
|
|
155
|
+
"""
|
|
156
|
+
return self._changed_time
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def blocks(self) -> Blocks:
|
|
160
|
+
"""
|
|
161
|
+
The block array for the chunk.
|
|
162
|
+
|
|
163
|
+
This is a custom class that stores a numpy array per sub-chunk.
|
|
164
|
+
|
|
165
|
+
The values in the arrays are indexes into :attr:`block_palette`.
|
|
166
|
+
"""
|
|
167
|
+
if self._blocks is None:
|
|
168
|
+
self._blocks = Blocks()
|
|
169
|
+
return self._blocks
|
|
170
|
+
|
|
171
|
+
@blocks.setter
|
|
172
|
+
def blocks(self, value: Union[Dict[int, numpy.ndarray], Blocks, None]):
|
|
173
|
+
if isinstance(value, dict):
|
|
174
|
+
value: Dict[int, numpy.ndarray]
|
|
175
|
+
value = {k: v.astype(numpy.uint32) for k, v in value.items()}
|
|
176
|
+
self._blocks = Blocks(value)
|
|
177
|
+
|
|
178
|
+
def get_block(self, dx: int, y: int, dz: int) -> Block:
|
|
179
|
+
"""
|
|
180
|
+
Get the universal Block object at the given location within the chunk.
|
|
181
|
+
|
|
182
|
+
:param dx: The x coordinate within the chunk. 0-15 inclusive
|
|
183
|
+
:param y: The y coordinate within the chunk. This can be any integer.
|
|
184
|
+
:param dz: The z coordinate within the chunk. 0-15 inclusive
|
|
185
|
+
:return: The universal Block object representation of the block at that location
|
|
186
|
+
"""
|
|
187
|
+
return self.block_palette[self.blocks[dx, y, dz]]
|
|
188
|
+
|
|
189
|
+
def set_block(self, dx: int, y: int, dz: int, block: Block):
|
|
190
|
+
"""
|
|
191
|
+
Set the universal Block object at the given location within the chunk.
|
|
192
|
+
|
|
193
|
+
:param dx: The x coordinate within the chunk. 0-15 inclusive
|
|
194
|
+
:param y: The y coordinate within the chunk. This can be any integer.
|
|
195
|
+
:param dz: The z coordinate within the chunk. 0-15 inclusive
|
|
196
|
+
:param block: The universal Block object to set at the given location
|
|
197
|
+
"""
|
|
198
|
+
self.blocks[dx, y, dz] = self.block_palette.get_add_block(block)
|
|
199
|
+
|
|
200
|
+
@property
|
|
201
|
+
def _block_palette(self) -> BlockManager:
|
|
202
|
+
"""The block block_palette for the chunk.
|
|
203
|
+
Usually will refer to a global block block_palette."""
|
|
204
|
+
return self.__block_palette
|
|
205
|
+
|
|
206
|
+
@_block_palette.setter
|
|
207
|
+
def _block_palette(self, new_block_palette: BlockManager):
|
|
208
|
+
"""Change the block block_palette for the chunk.
|
|
209
|
+
This will change the block block_palette but leave the block array unchanged.
|
|
210
|
+
Only use this if you know what you are doing.
|
|
211
|
+
Designed for internal use. You probably want to use Chunk.block_palette"""
|
|
212
|
+
assert isinstance(new_block_palette, BlockManager)
|
|
213
|
+
self.__block_palette = new_block_palette
|
|
214
|
+
|
|
215
|
+
@property
|
|
216
|
+
def block_palette(self) -> BlockManager:
|
|
217
|
+
"""
|
|
218
|
+
The block block_palette for the chunk.
|
|
219
|
+
|
|
220
|
+
Usually will refer to the level's global block_palette.
|
|
221
|
+
"""
|
|
222
|
+
return self._block_palette
|
|
223
|
+
|
|
224
|
+
@block_palette.setter
|
|
225
|
+
def block_palette(self, new_block_palette: BlockManager):
|
|
226
|
+
"""
|
|
227
|
+
Change the block block_palette for the chunk.
|
|
228
|
+
|
|
229
|
+
This will copy over all block states from the old block_palette and remap the block indexes to use the new block_palette.
|
|
230
|
+
"""
|
|
231
|
+
assert isinstance(new_block_palette, BlockManager)
|
|
232
|
+
if new_block_palette is not self._block_palette:
|
|
233
|
+
# if current block block_palette and the new block block_palette are not the same object
|
|
234
|
+
if self._block_palette:
|
|
235
|
+
# if there are blocks in the current block block_palette remap the data
|
|
236
|
+
block_lut = numpy.array(
|
|
237
|
+
[
|
|
238
|
+
new_block_palette.get_add_block(block)
|
|
239
|
+
for block in self._block_palette.blocks
|
|
240
|
+
],
|
|
241
|
+
dtype=numpy.uint32,
|
|
242
|
+
)
|
|
243
|
+
for cy in self.blocks.sub_chunks:
|
|
244
|
+
self.blocks.add_sub_chunk(
|
|
245
|
+
cy, block_lut[self.blocks.get_sub_chunk(cy)]
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
self.__block_palette = new_block_palette
|
|
249
|
+
|
|
250
|
+
@property
|
|
251
|
+
def biomes(self) -> Biomes:
|
|
252
|
+
"""
|
|
253
|
+
The biome array for the chunk.
|
|
254
|
+
|
|
255
|
+
This is a custom class that stores numpy arrays. See the :class:`Biomes` documentation for more information.
|
|
256
|
+
|
|
257
|
+
The values in the arrays are indexes into :attr:`biome_palette`.
|
|
258
|
+
"""
|
|
259
|
+
if self._biomes is None:
|
|
260
|
+
self._biomes = Biomes()
|
|
261
|
+
return self._biomes
|
|
262
|
+
|
|
263
|
+
@biomes.setter
|
|
264
|
+
def biomes(self, value: Union[Biomes, Dict[int, numpy.ndarray]]):
|
|
265
|
+
self._biomes = Biomes(value)
|
|
266
|
+
|
|
267
|
+
@property
|
|
268
|
+
def _biome_palette(self) -> BiomeManager:
|
|
269
|
+
"""
|
|
270
|
+
The biome_palette for the chunk.
|
|
271
|
+
|
|
272
|
+
Usually will refer to a global biome_palette.
|
|
273
|
+
"""
|
|
274
|
+
return self.__biome_palette
|
|
275
|
+
|
|
276
|
+
@_biome_palette.setter
|
|
277
|
+
def _biome_palette(self, new_biome_palette: BiomeManager):
|
|
278
|
+
"""
|
|
279
|
+
Change the biome_palette for the chunk.
|
|
280
|
+
|
|
281
|
+
This will change the biome_palette but leave the biome array unchanged.
|
|
282
|
+
|
|
283
|
+
Only use this if you know what you are doing.
|
|
284
|
+
|
|
285
|
+
Designed for internal use. You probably want to use Chunk.biome_palette
|
|
286
|
+
"""
|
|
287
|
+
assert isinstance(new_biome_palette, BiomeManager)
|
|
288
|
+
self.__biome_palette = new_biome_palette
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def biome_palette(self) -> BiomeManager:
|
|
292
|
+
"""
|
|
293
|
+
The biome block_palette for the chunk.
|
|
294
|
+
|
|
295
|
+
Usually will refer to the level's global biome_palette.
|
|
296
|
+
"""
|
|
297
|
+
return self._biome_palette
|
|
298
|
+
|
|
299
|
+
@biome_palette.setter
|
|
300
|
+
def biome_palette(self, new_biome_palette: BiomeManager):
|
|
301
|
+
"""
|
|
302
|
+
Change the biome_palette for the chunk.
|
|
303
|
+
|
|
304
|
+
This will copy over all biome states from the old biome_palette and remap the biome indexes to use the new_biome_palette.
|
|
305
|
+
"""
|
|
306
|
+
assert isinstance(new_biome_palette, BiomeManager)
|
|
307
|
+
if new_biome_palette is not self._biome_palette:
|
|
308
|
+
# if current biome_palette and the new biome_palette are not the same object
|
|
309
|
+
if self._biome_palette:
|
|
310
|
+
# if there are biomes in the current biome_palette remap the data
|
|
311
|
+
biome_lut = numpy.array(
|
|
312
|
+
[
|
|
313
|
+
new_biome_palette.get_add_biome(biome)
|
|
314
|
+
for biome in self._biome_palette.biomes
|
|
315
|
+
],
|
|
316
|
+
dtype=numpy.uint32,
|
|
317
|
+
)
|
|
318
|
+
if self.biomes.dimension == BiomesShape.Shape2D:
|
|
319
|
+
self.biomes = biome_lut[self.biomes]
|
|
320
|
+
elif self.biomes.dimension == BiomesShape.Shape3D:
|
|
321
|
+
self.biomes = {
|
|
322
|
+
sy: biome_lut[self.biomes.get_section(sy)]
|
|
323
|
+
for sy in self.biomes.sections
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
self.__biome_palette = new_biome_palette
|
|
327
|
+
|
|
328
|
+
@property
|
|
329
|
+
def entities(self) -> EntityList:
|
|
330
|
+
"""
|
|
331
|
+
Property that returns the chunk's entity list. Setting this property replaces the chunk's entity list
|
|
332
|
+
|
|
333
|
+
:return: A list of all the entities contained in the chunk
|
|
334
|
+
"""
|
|
335
|
+
return self._entities
|
|
336
|
+
|
|
337
|
+
@entities.setter
|
|
338
|
+
def entities(self, value: Iterable[Entity]):
|
|
339
|
+
"""
|
|
340
|
+
:param value: The new entity list
|
|
341
|
+
:type value: list
|
|
342
|
+
:return:
|
|
343
|
+
"""
|
|
344
|
+
if self._entities != value:
|
|
345
|
+
self._entities = EntityList(value)
|
|
346
|
+
|
|
347
|
+
@property
|
|
348
|
+
def block_entities(self) -> BlockEntityDict:
|
|
349
|
+
"""
|
|
350
|
+
Property that returns the chunk's block entity list. Setting this property replaces the chunk's block entity list
|
|
351
|
+
|
|
352
|
+
:return: A list of all the block entities contained in the chunk
|
|
353
|
+
"""
|
|
354
|
+
return self._block_entities
|
|
355
|
+
|
|
356
|
+
@block_entities.setter
|
|
357
|
+
def block_entities(self, value: BlockEntityDict.InputType):
|
|
358
|
+
"""
|
|
359
|
+
:param value: The new block entity list
|
|
360
|
+
:type value: list
|
|
361
|
+
:return:
|
|
362
|
+
"""
|
|
363
|
+
if self._block_entities != value:
|
|
364
|
+
self._block_entities = BlockEntityDict(value)
|
|
365
|
+
|
|
366
|
+
@property
|
|
367
|
+
def status(self) -> Status:
|
|
368
|
+
"""
|
|
369
|
+
A class containing the chunk's generation status.
|
|
370
|
+
"""
|
|
371
|
+
return self._status
|
|
372
|
+
|
|
373
|
+
@status.setter
|
|
374
|
+
def status(self, value: Union[float, int, str]):
|
|
375
|
+
self._status.value = value
|
|
376
|
+
|
|
377
|
+
@property
|
|
378
|
+
def misc(self) -> dict:
|
|
379
|
+
"""
|
|
380
|
+
Extra data that exists in a chunk but does not have its own location.
|
|
381
|
+
|
|
382
|
+
Data in here is not guaranteed to exist and may get moved at a later date.
|
|
383
|
+
"""
|
|
384
|
+
return self._misc
|
|
385
|
+
|
|
386
|
+
@misc.setter
|
|
387
|
+
def misc(self, misc: dict):
|
|
388
|
+
assert isinstance(misc, dict), "misc must be a dictionary."
|
|
389
|
+
self._misc = misc
|