amulet-core 2.0a8__cp311-cp311-win_amd64.whl → 2.0.1.0.1297307203.19.43.34808.0a0__cp311-cp311-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/core/__init__.py +36 -0
- amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
- amulet/core/_amulet_core.cp311-win_amd64.pyd +0 -0
- amulet/core/_amulet_core.pyi +7 -0
- amulet/{_version.py → core/_version.py} +3 -3
- amulet/core/amulet_core.dll +0 -0
- amulet/core/amulet_core.lib +0 -0
- amulet/core/amulet_coreConfig.cmake +18 -0
- amulet/{biome.pyi → core/biome/__init__.pyi} +3 -3
- amulet/core/biome/biome.hpp +53 -0
- amulet/{block.pyi → core/block/__init__.pyi} +25 -26
- amulet/core/block/block.hpp +156 -0
- amulet/{block_entity.pyi → core/block_entity/__init__.pyi} +7 -7
- amulet/core/block_entity/block_entity.hpp +84 -0
- amulet/{errors.py → core/chunk/__init__.pyi} +37 -33
- amulet/core/chunk/chunk.hpp +126 -0
- amulet/core/chunk/component/__init__.pyi +18 -0
- amulet/core/chunk/component/biome_3d_component.hpp +96 -0
- amulet/core/chunk/component/block_component.hpp +101 -0
- amulet/core/chunk/component/block_component.pyi +28 -0
- amulet/core/chunk/component/block_entity_component.hpp +119 -0
- amulet/core/chunk/component/section_array_map.hpp +129 -0
- amulet/{chunk_components.pyi → core/chunk/component/section_array_map.pyi} +4 -24
- amulet/core/dll.hpp +21 -0
- amulet/core/entity/__init__.pyi +105 -0
- amulet/core/entity/entity.hpp +100 -0
- amulet/{palette → core/palette}/__init__.pyi +2 -2
- amulet/core/palette/biome_palette.hpp +65 -0
- amulet/{palette → core/palette}/biome_palette.pyi +8 -8
- amulet/core/palette/block_palette.hpp +71 -0
- amulet/{palette → core/palette}/block_palette.pyi +12 -10
- amulet/core/selection/__init__.pyi +8 -0
- amulet/core/selection/box.hpp +86 -0
- amulet/core/selection/box.pyi +215 -0
- amulet/core/selection/group.hpp +80 -0
- amulet/core/selection/group.pyi +213 -0
- amulet/{version.pyi → core/version/__init__.pyi} +58 -10
- amulet/core/version/version.hpp +204 -0
- {amulet_core-2.0a8.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/METADATA +25 -20
- amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info/RECORD +45 -0
- {amulet_core-2.0a8.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/WHEEL +1 -1
- amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info/entry_points.txt +2 -0
- amulet/__init__.cp311-win_amd64.pyd +0 -0
- amulet/__init__.py.cpp +0 -45
- amulet/__init__.pyi +0 -30
- amulet/__pyinstaller/hook-amulet.py +0 -4
- amulet/_init.py +0 -26
- amulet/biome.cpp +0 -36
- amulet/biome.hpp +0 -43
- amulet/biome.py.cpp +0 -122
- amulet/block.cpp +0 -435
- amulet/block.hpp +0 -119
- amulet/block.py.cpp +0 -377
- amulet/block_entity.cpp +0 -12
- amulet/block_entity.hpp +0 -56
- amulet/block_entity.py.cpp +0 -115
- amulet/chunk.cpp +0 -16
- amulet/chunk.hpp +0 -100
- amulet/chunk.py.cpp +0 -80
- amulet/chunk.pyi +0 -28
- amulet/chunk_components/biome_3d_component.cpp +0 -5
- amulet/chunk_components/biome_3d_component.hpp +0 -79
- amulet/chunk_components/block_component.cpp +0 -41
- amulet/chunk_components/block_component.hpp +0 -88
- amulet/chunk_components/block_entity_component.cpp +0 -5
- amulet/chunk_components/block_entity_component.hpp +0 -147
- amulet/chunk_components/section_array_map.cpp +0 -129
- amulet/chunk_components/section_array_map.hpp +0 -147
- amulet/collections/eq.py.hpp +0 -37
- amulet/collections/hash.py.hpp +0 -27
- amulet/collections/holder.py.hpp +0 -37
- amulet/collections/iterator.py.hpp +0 -80
- amulet/collections/mapping.py.hpp +0 -199
- amulet/collections/mutable_mapping.py.hpp +0 -226
- amulet/collections/sequence.py.hpp +0 -163
- amulet/collections.pyi +0 -40
- amulet/data_types.py +0 -29
- amulet/entity.py +0 -182
- amulet/game/__init__.py +0 -7
- amulet/game/_game.py +0 -152
- amulet/game/_universal/__init__.py +0 -1
- amulet/game/_universal/_biome.py +0 -17
- amulet/game/_universal/_block.py +0 -47
- amulet/game/_universal/_version.py +0 -68
- amulet/game/abc/__init__.py +0 -22
- amulet/game/abc/_block_specification.py +0 -150
- amulet/game/abc/biome.py +0 -213
- amulet/game/abc/block.py +0 -331
- amulet/game/abc/game_version_container.py +0 -25
- amulet/game/abc/json_interface.py +0 -27
- amulet/game/abc/version.py +0 -44
- amulet/game/bedrock/__init__.py +0 -1
- amulet/game/bedrock/_biome.py +0 -35
- amulet/game/bedrock/_block.py +0 -42
- amulet/game/bedrock/_version.py +0 -165
- amulet/game/java/__init__.py +0 -2
- amulet/game/java/_biome.py +0 -35
- amulet/game/java/_block.py +0 -60
- amulet/game/java/_version.py +0 -176
- amulet/game/translate/__init__.py +0 -12
- amulet/game/translate/_functions/__init__.py +0 -15
- amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
- amulet/game/translate/_functions/_code_functions/_text.py +0 -553
- amulet/game/translate/_functions/_code_functions/banner_pattern.py +0 -67
- amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +0 -152
- amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +0 -88
- amulet/game/translate/_functions/_code_functions/bedrock_sign.py +0 -152
- amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +0 -16
- amulet/game/translate/_functions/_code_functions/custom_name.py +0 -146
- amulet/game/translate/_functions/_frozen.py +0 -66
- amulet/game/translate/_functions/_state.py +0 -54
- amulet/game/translate/_functions/_typing.py +0 -98
- amulet/game/translate/_functions/abc.py +0 -123
- amulet/game/translate/_functions/carry_nbt.py +0 -160
- amulet/game/translate/_functions/carry_properties.py +0 -80
- amulet/game/translate/_functions/code.py +0 -143
- amulet/game/translate/_functions/map_block_name.py +0 -66
- amulet/game/translate/_functions/map_nbt.py +0 -111
- amulet/game/translate/_functions/map_properties.py +0 -93
- amulet/game/translate/_functions/multiblock.py +0 -112
- amulet/game/translate/_functions/new_block.py +0 -42
- amulet/game/translate/_functions/new_entity.py +0 -43
- amulet/game/translate/_functions/new_nbt.py +0 -206
- amulet/game/translate/_functions/new_properties.py +0 -64
- amulet/game/translate/_functions/sequence.py +0 -51
- amulet/game/translate/_functions/walk_input_nbt.py +0 -331
- amulet/game/translate/_translator.py +0 -433
- amulet/img/__init__.py +0 -10
- amulet/img/missing_no.png +0 -0
- amulet/img/missing_pack.png +0 -0
- amulet/img/missing_world.png +0 -0
- amulet/io/binary_reader.hpp +0 -45
- amulet/io/binary_writer.hpp +0 -30
- amulet/item.py +0 -75
- amulet/level/__init__.pyi +0 -23
- amulet/level/_load.py +0 -100
- amulet/level/abc/__init__.py +0 -12
- amulet/level/abc/_chunk_handle.py +0 -358
- amulet/level/abc/_dimension.py +0 -86
- amulet/level/abc/_history/__init__.py +0 -1
- amulet/level/abc/_history/_cache.py +0 -224
- amulet/level/abc/_history/_history_manager.py +0 -291
- amulet/level/abc/_level/__init__.py +0 -5
- amulet/level/abc/_level/_compactable_level.py +0 -10
- amulet/level/abc/_level/_creatable_level.py +0 -28
- amulet/level/abc/_level/_disk_level.py +0 -17
- amulet/level/abc/_level/_level.py +0 -449
- amulet/level/abc/_level/_loadable_level.py +0 -42
- amulet/level/abc/_player_storage.py +0 -7
- amulet/level/abc/_raw_level.py +0 -187
- amulet/level/abc/_registry.py +0 -40
- amulet/level/java/__init__.pyi +0 -16
- amulet/level/java/_chunk_handle.py +0 -17
- amulet/level/java/_dimension.py +0 -20
- amulet/level/java/_level.py +0 -184
- amulet/level/java/_raw/__init__.pyi +0 -15
- amulet/level/java/_raw/_chunk.pyi +0 -23
- amulet/level/java/_raw/_constant.py +0 -9
- amulet/level/java/_raw/_data_pack/__init__.py +0 -2
- amulet/level/java/_raw/_data_pack/data_pack.py +0 -241
- amulet/level/java/_raw/_data_pack/data_pack_manager.py +0 -77
- amulet/level/java/_raw/_dimension.py +0 -86
- amulet/level/java/_raw/_level.py +0 -507
- amulet/level/java/_raw/_typing.py +0 -3
- amulet/level/java/_raw/java_chunk_decode.cpp +0 -531
- amulet/level/java/_raw/java_chunk_decode.hpp +0 -23
- amulet/level/java/_raw/java_chunk_encode.cpp +0 -25
- amulet/level/java/_raw/java_chunk_encode.hpp +0 -23
- amulet/level/java/anvil/__init__.py +0 -2
- amulet/level/java/anvil/_dimension.py +0 -170
- amulet/level/java/anvil/_region.py +0 -421
- amulet/level/java/anvil/_sector_manager.py +0 -223
- amulet/level/java/chunk.pyi +0 -81
- amulet/level/java/chunk_/_chunk.py +0 -260
- amulet/level/java/chunk_/components/inhabited_time.py +0 -12
- amulet/level/java/chunk_/components/last_update.py +0 -12
- amulet/level/java/chunk_/components/legacy_version.py +0 -12
- amulet/level/java/chunk_/components/light_populated.py +0 -12
- amulet/level/java/chunk_/components/named_height_2d.py +0 -37
- amulet/level/java/chunk_/components/status.py +0 -11
- amulet/level/java/chunk_/components/terrain_populated.py +0 -12
- amulet/level/java/chunk_components/data_version_component.cpp +0 -32
- amulet/level/java/chunk_components/data_version_component.hpp +0 -31
- amulet/level/java/chunk_components/java_raw_chunk_component.cpp +0 -56
- amulet/level/java/chunk_components/java_raw_chunk_component.hpp +0 -45
- amulet/level/java/chunk_components.pyi +0 -22
- amulet/level/java/java_chunk.cpp +0 -170
- amulet/level/java/java_chunk.hpp +0 -141
- amulet/level/java/long_array.hpp +0 -175
- amulet/level/java/long_array.pyi +0 -39
- amulet/level/temporary_level/__init__.py +0 -1
- amulet/level/temporary_level/_level.py +0 -16
- amulet/mesh/__init__.py +0 -0
- amulet/mesh/block/__init__.pyi +0 -301
- amulet/mesh/block/_cube.py +0 -198
- amulet/mesh/block/_missing_block.py +0 -20
- amulet/mesh/block/block_mesh.cpp +0 -107
- amulet/mesh/block/block_mesh.hpp +0 -207
- amulet/mesh/util.py +0 -17
- amulet/palette/biome_palette.hpp +0 -85
- amulet/palette/block_palette.cpp +0 -32
- amulet/palette/block_palette.hpp +0 -93
- amulet/player.py +0 -62
- amulet/pybind11/collections.hpp +0 -118
- amulet/pybind11/numpy.hpp +0 -26
- amulet/pybind11/py_module.hpp +0 -34
- amulet/pybind11/type_hints.hpp +0 -51
- amulet/pybind11/types.hpp +0 -25
- amulet/pybind11/typing.hpp +0 -7
- amulet/resource_pack/__init__.py +0 -63
- amulet/resource_pack/abc/__init__.py +0 -2
- amulet/resource_pack/abc/resource_pack.py +0 -38
- amulet/resource_pack/abc/resource_pack_manager.py +0 -85
- amulet/resource_pack/java/__init__.py +0 -2
- amulet/resource_pack/java/download_resources.py +0 -212
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
- amulet/resource_pack/java/resource_pack.py +0 -44
- amulet/resource_pack/java/resource_pack_manager.py +0 -563
- amulet/resource_pack/unknown_resource_pack.py +0 -10
- amulet/selection/__init__.py +0 -2
- amulet/selection/abstract_selection.py +0 -342
- amulet/selection/box.py +0 -852
- amulet/selection/group.py +0 -481
- amulet/utils/__init__.pyi +0 -23
- amulet/utils/call_spec/__init__.py +0 -24
- amulet/utils/call_spec/_call_spec.py +0 -257
- amulet/utils/cast.py +0 -10
- amulet/utils/comment_json.py +0 -188
- amulet/utils/format_utils.py +0 -41
- amulet/utils/generator.py +0 -18
- amulet/utils/matrix.py +0 -243
- amulet/utils/numpy.hpp +0 -36
- amulet/utils/numpy.pyi +0 -11
- amulet/utils/numpy_helpers.py +0 -19
- amulet/utils/shareable_lock.py +0 -335
- amulet/utils/signal/__init__.py +0 -10
- amulet/utils/signal/_signal.py +0 -228
- amulet/utils/task_manager.py +0 -235
- amulet/utils/typed_property.py +0 -111
- amulet/utils/weakref.py +0 -70
- amulet/utils/world_utils.py +0 -102
- amulet/version.cpp +0 -136
- amulet/version.hpp +0 -142
- amulet/version.py.cpp +0 -281
- amulet_core-2.0a8.dist-info/RECORD +0 -241
- amulet_core-2.0a8.dist-info/entry_points.txt +0 -2
- /amulet/{__pyinstaller → core/__pyinstaller}/__init__.py +0 -0
- /amulet/{py.typed → core/py.typed} +0 -0
- {amulet_core-2.0a8.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/top_level.txt +0 -0
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Self, Any
|
|
4
|
-
from collections.abc import Mapping
|
|
5
|
-
|
|
6
|
-
from .abc import (
|
|
7
|
-
AbstractBaseTranslationFunction,
|
|
8
|
-
translation_function_from_json,
|
|
9
|
-
Data,
|
|
10
|
-
follow_nbt_path,
|
|
11
|
-
)
|
|
12
|
-
from amulet.game.abc import JSONCompatible, JSONDict
|
|
13
|
-
from ._frozen import FrozenMapping
|
|
14
|
-
from ._state import SrcData, StateData, DstData
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class MapNBT(AbstractBaseTranslationFunction):
|
|
18
|
-
# Class variables
|
|
19
|
-
Name = "map_nbt"
|
|
20
|
-
_instances = {}
|
|
21
|
-
|
|
22
|
-
# Instance variables
|
|
23
|
-
_cases: FrozenMapping[
|
|
24
|
-
str,
|
|
25
|
-
AbstractBaseTranslationFunction,
|
|
26
|
-
]
|
|
27
|
-
_default: AbstractBaseTranslationFunction | None
|
|
28
|
-
|
|
29
|
-
def __init__(
|
|
30
|
-
self,
|
|
31
|
-
cases: Mapping[
|
|
32
|
-
str,
|
|
33
|
-
AbstractBaseTranslationFunction,
|
|
34
|
-
],
|
|
35
|
-
default: AbstractBaseTranslationFunction | None,
|
|
36
|
-
) -> None:
|
|
37
|
-
super().__init__()
|
|
38
|
-
self._cases = FrozenMapping[
|
|
39
|
-
str,
|
|
40
|
-
AbstractBaseTranslationFunction,
|
|
41
|
-
](cases)
|
|
42
|
-
assert all(
|
|
43
|
-
isinstance(
|
|
44
|
-
key,
|
|
45
|
-
str,
|
|
46
|
-
)
|
|
47
|
-
and isinstance(value, AbstractBaseTranslationFunction)
|
|
48
|
-
for key, value in self._cases.items()
|
|
49
|
-
)
|
|
50
|
-
assert default is None or isinstance(default, AbstractBaseTranslationFunction)
|
|
51
|
-
self._default = default
|
|
52
|
-
|
|
53
|
-
def __reduce__(self) -> Any:
|
|
54
|
-
return MapNBT, (self._cases, self._default)
|
|
55
|
-
|
|
56
|
-
def _data(self) -> Data:
|
|
57
|
-
return self._cases, self._default
|
|
58
|
-
|
|
59
|
-
@classmethod
|
|
60
|
-
def from_json(cls, data: JSONCompatible) -> Self:
|
|
61
|
-
assert isinstance(data, dict)
|
|
62
|
-
assert data.get("function") == "map_nbt"
|
|
63
|
-
options = data["options"]
|
|
64
|
-
assert isinstance(options, dict)
|
|
65
|
-
cases = options.get("cases", {})
|
|
66
|
-
assert isinstance(cases, dict)
|
|
67
|
-
raw_default = options.get("default", None)
|
|
68
|
-
if raw_default is None:
|
|
69
|
-
default = None
|
|
70
|
-
else:
|
|
71
|
-
assert isinstance(raw_default, list)
|
|
72
|
-
default = translation_function_from_json(raw_default)
|
|
73
|
-
return cls(
|
|
74
|
-
{
|
|
75
|
-
key: translation_function_from_json(value)
|
|
76
|
-
for key, value in cases.items()
|
|
77
|
-
},
|
|
78
|
-
default,
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
def to_json(self) -> JSONDict:
|
|
82
|
-
options: JSONDict = {}
|
|
83
|
-
if self._cases:
|
|
84
|
-
options["cases"] = {
|
|
85
|
-
key: value.to_json() for key, value in self._cases.items()
|
|
86
|
-
}
|
|
87
|
-
if self._default:
|
|
88
|
-
options["default"] = self._default.to_json()
|
|
89
|
-
return {"function": "map_nbt", "options": options}
|
|
90
|
-
|
|
91
|
-
def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
|
|
92
|
-
dst.cacheable = False
|
|
93
|
-
if src.nbt is None:
|
|
94
|
-
dst.extra_needed = True
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
if state.nbt_path is None:
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
run_default = True
|
|
101
|
-
|
|
102
|
-
if self._cases:
|
|
103
|
-
nbt = follow_nbt_path(src.nbt, state.nbt_path)
|
|
104
|
-
if nbt is not None:
|
|
105
|
-
nbt_hash = nbt.to_snbt()
|
|
106
|
-
if nbt_hash in self._cases:
|
|
107
|
-
self._cases[nbt_hash].run(src, state, dst)
|
|
108
|
-
run_default = False
|
|
109
|
-
|
|
110
|
-
if run_default and self._default is not None:
|
|
111
|
-
self._default.run(src, state, dst)
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Self, Any
|
|
4
|
-
from collections.abc import Mapping
|
|
5
|
-
|
|
6
|
-
from amulet.block import PropertyValueType, Block
|
|
7
|
-
from .abc import (
|
|
8
|
-
AbstractBaseTranslationFunction,
|
|
9
|
-
immutable_from_snbt,
|
|
10
|
-
translation_function_from_json,
|
|
11
|
-
Data,
|
|
12
|
-
)
|
|
13
|
-
from amulet.game.abc import JSONCompatible, JSONDict
|
|
14
|
-
from ._frozen import FrozenMapping
|
|
15
|
-
from ._state import SrcData, StateData, DstData
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class MapProperties(AbstractBaseTranslationFunction):
|
|
19
|
-
# Class variables
|
|
20
|
-
Name = "map_properties"
|
|
21
|
-
_instances = {}
|
|
22
|
-
|
|
23
|
-
# Instance variables
|
|
24
|
-
_properties: FrozenMapping[
|
|
25
|
-
str, FrozenMapping[PropertyValueType, AbstractBaseTranslationFunction]
|
|
26
|
-
]
|
|
27
|
-
|
|
28
|
-
def __init__(
|
|
29
|
-
self,
|
|
30
|
-
properties: Mapping[
|
|
31
|
-
str, Mapping[PropertyValueType, AbstractBaseTranslationFunction]
|
|
32
|
-
],
|
|
33
|
-
) -> None:
|
|
34
|
-
super().__init__()
|
|
35
|
-
hashable_properties = {}
|
|
36
|
-
|
|
37
|
-
for prop, data in properties.items():
|
|
38
|
-
assert isinstance(prop, str)
|
|
39
|
-
hashable_data = FrozenMapping[
|
|
40
|
-
PropertyValueType, AbstractBaseTranslationFunction
|
|
41
|
-
](data)
|
|
42
|
-
for val, func in hashable_data.items():
|
|
43
|
-
assert isinstance(val, PropertyValueType)
|
|
44
|
-
assert isinstance(func, AbstractBaseTranslationFunction)
|
|
45
|
-
hashable_properties[prop] = hashable_data
|
|
46
|
-
|
|
47
|
-
self._properties = FrozenMapping[
|
|
48
|
-
str, FrozenMapping[PropertyValueType, AbstractBaseTranslationFunction]
|
|
49
|
-
](hashable_properties)
|
|
50
|
-
|
|
51
|
-
def __reduce__(self) -> Any:
|
|
52
|
-
return MapProperties, (self._properties,)
|
|
53
|
-
|
|
54
|
-
def _data(self) -> Data:
|
|
55
|
-
return self._properties
|
|
56
|
-
|
|
57
|
-
@classmethod
|
|
58
|
-
def from_json(cls, data: JSONCompatible) -> Self:
|
|
59
|
-
assert isinstance(data, dict)
|
|
60
|
-
assert data.get("function") == "map_properties"
|
|
61
|
-
options = data["options"]
|
|
62
|
-
assert isinstance(options, dict)
|
|
63
|
-
properties = {}
|
|
64
|
-
for property_name, mapping in options.items():
|
|
65
|
-
assert isinstance(property_name, str)
|
|
66
|
-
assert isinstance(mapping, dict)
|
|
67
|
-
values = {}
|
|
68
|
-
for snbt, func in mapping.items():
|
|
69
|
-
assert isinstance(snbt, str)
|
|
70
|
-
assert isinstance(func, dict | list)
|
|
71
|
-
values[immutable_from_snbt(snbt)] = translation_function_from_json(func)
|
|
72
|
-
properties[property_name] = values
|
|
73
|
-
return cls(properties)
|
|
74
|
-
|
|
75
|
-
def to_json(self) -> JSONDict:
|
|
76
|
-
return {
|
|
77
|
-
"function": "map_properties",
|
|
78
|
-
"options": {
|
|
79
|
-
property_name: {
|
|
80
|
-
nbt.to_snbt(): func.to_json() for nbt, func in mapping.items()
|
|
81
|
-
}
|
|
82
|
-
for property_name, mapping in self._properties.items()
|
|
83
|
-
},
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
|
|
87
|
-
block = src.block
|
|
88
|
-
assert isinstance(block, Block)
|
|
89
|
-
src_properties = block.properties
|
|
90
|
-
for key, options in self._properties.items():
|
|
91
|
-
val = src_properties.get(key)
|
|
92
|
-
if val is not None and val in options:
|
|
93
|
-
options[val].run(src, state, dst)
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Sequence, Self, Any
|
|
4
|
-
|
|
5
|
-
from amulet.data_types import BlockCoordinates
|
|
6
|
-
from amulet.errors import ChunkLoadError
|
|
7
|
-
from .abc import (
|
|
8
|
-
AbstractBaseTranslationFunction,
|
|
9
|
-
Data,
|
|
10
|
-
translation_function_from_json,
|
|
11
|
-
)
|
|
12
|
-
from amulet.game.abc import JSONCompatible, JSONDict
|
|
13
|
-
from ._state import SrcData, SrcDataExtra, StateData, DstData
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class MultiBlock(AbstractBaseTranslationFunction):
|
|
17
|
-
# Class variables
|
|
18
|
-
Name = "multiblock"
|
|
19
|
-
_instances = {}
|
|
20
|
-
|
|
21
|
-
_blocks: tuple[tuple[BlockCoordinates, AbstractBaseTranslationFunction], ...]
|
|
22
|
-
|
|
23
|
-
def __init__(
|
|
24
|
-
self, blocks: Sequence[tuple[BlockCoordinates, AbstractBaseTranslationFunction]]
|
|
25
|
-
) -> None:
|
|
26
|
-
super().__init__()
|
|
27
|
-
self._blocks = tuple[
|
|
28
|
-
tuple[BlockCoordinates, AbstractBaseTranslationFunction], ...
|
|
29
|
-
](blocks)
|
|
30
|
-
for coords, func in self._blocks:
|
|
31
|
-
if (
|
|
32
|
-
not isinstance(coords, tuple)
|
|
33
|
-
and len(coords) == 3
|
|
34
|
-
and all(isinstance(v, int) for v in coords)
|
|
35
|
-
):
|
|
36
|
-
raise TypeError
|
|
37
|
-
assert isinstance(func, AbstractBaseTranslationFunction)
|
|
38
|
-
|
|
39
|
-
def __reduce__(self) -> Any:
|
|
40
|
-
return MultiBlock, (self._blocks,)
|
|
41
|
-
|
|
42
|
-
def _data(self) -> Data:
|
|
43
|
-
return self._blocks
|
|
44
|
-
|
|
45
|
-
@classmethod
|
|
46
|
-
def from_json(cls, data: JSONCompatible) -> Self:
|
|
47
|
-
assert isinstance(data, dict)
|
|
48
|
-
assert data.get("function") == "multiblock"
|
|
49
|
-
options = data["options"]
|
|
50
|
-
assert isinstance(options, list)
|
|
51
|
-
blocks: list[tuple[BlockCoordinates, AbstractBaseTranslationFunction]] = []
|
|
52
|
-
for block in options:
|
|
53
|
-
assert isinstance(block, dict)
|
|
54
|
-
raw_coords = block["coords"]
|
|
55
|
-
assert isinstance(raw_coords, list)
|
|
56
|
-
x = raw_coords[0]
|
|
57
|
-
y = raw_coords[1]
|
|
58
|
-
z = raw_coords[2]
|
|
59
|
-
assert isinstance(x, int)
|
|
60
|
-
assert isinstance(y, int)
|
|
61
|
-
assert isinstance(z, int)
|
|
62
|
-
coords = (x, y, z)
|
|
63
|
-
function = translation_function_from_json(block["functions"])
|
|
64
|
-
blocks.append((coords, function))
|
|
65
|
-
return cls(blocks)
|
|
66
|
-
|
|
67
|
-
def to_json(self) -> JSONDict:
|
|
68
|
-
return {
|
|
69
|
-
"function": "multiblock",
|
|
70
|
-
"options": [
|
|
71
|
-
{"coords": list(coords), "functions": func.to_json()}
|
|
72
|
-
for coords, func in self._blocks
|
|
73
|
-
],
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
|
|
77
|
-
dst.cacheable = False
|
|
78
|
-
if src.extra is None:
|
|
79
|
-
dst.extra_needed = True
|
|
80
|
-
return
|
|
81
|
-
|
|
82
|
-
for (dx, dy, dz), func in self._blocks:
|
|
83
|
-
rx, ry, rz = state.relative_location
|
|
84
|
-
new_relative_location = (
|
|
85
|
-
rx + dx,
|
|
86
|
-
ry + dy,
|
|
87
|
-
rz + dz,
|
|
88
|
-
)
|
|
89
|
-
try:
|
|
90
|
-
new_block, new_block_entity = src.extra.get_block_callback(
|
|
91
|
-
new_relative_location
|
|
92
|
-
)
|
|
93
|
-
except ChunkLoadError:
|
|
94
|
-
continue
|
|
95
|
-
else:
|
|
96
|
-
ax, ay, az = src.extra.absolute_coordinates
|
|
97
|
-
new_absolute_location = (
|
|
98
|
-
ax + dx,
|
|
99
|
-
ay + dy,
|
|
100
|
-
az + dz,
|
|
101
|
-
)
|
|
102
|
-
# src is now the block at the new location
|
|
103
|
-
new_src = SrcData(
|
|
104
|
-
new_block,
|
|
105
|
-
None if new_block_entity is None else new_block_entity.nbt,
|
|
106
|
-
SrcDataExtra(
|
|
107
|
-
new_absolute_location,
|
|
108
|
-
src.extra.get_block_callback,
|
|
109
|
-
),
|
|
110
|
-
)
|
|
111
|
-
new_state = StateData(new_relative_location)
|
|
112
|
-
func.run(new_src, new_state, dst)
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Self, Any
|
|
4
|
-
from amulet.block import Block
|
|
5
|
-
from .abc import AbstractBaseTranslationFunction, Data
|
|
6
|
-
from amulet.game.abc import JSONCompatible, JSONDict
|
|
7
|
-
from ._state import SrcData, StateData, DstData
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class NewBlock(AbstractBaseTranslationFunction):
|
|
11
|
-
# Class variables
|
|
12
|
-
Name = "new_block"
|
|
13
|
-
_instances = {}
|
|
14
|
-
|
|
15
|
-
# Instance variables
|
|
16
|
-
_block: tuple[str, str]
|
|
17
|
-
|
|
18
|
-
def __init__(self, namespace: str, base_name: str) -> None:
|
|
19
|
-
super().__init__()
|
|
20
|
-
self._block = (namespace, base_name)
|
|
21
|
-
|
|
22
|
-
def __reduce__(self) -> Any:
|
|
23
|
-
return NewBlock, (self._block[0], self._block[1])
|
|
24
|
-
|
|
25
|
-
def _data(self) -> Data:
|
|
26
|
-
return self._block
|
|
27
|
-
|
|
28
|
-
@classmethod
|
|
29
|
-
def from_json(cls, data: JSONCompatible) -> Self:
|
|
30
|
-
assert isinstance(data, dict)
|
|
31
|
-
assert data.get("function") == "new_block"
|
|
32
|
-
block = data["options"]
|
|
33
|
-
assert isinstance(block, str)
|
|
34
|
-
namespace, base_name = block.split(":", 1)
|
|
35
|
-
return cls(namespace, base_name)
|
|
36
|
-
|
|
37
|
-
def to_json(self) -> JSONDict:
|
|
38
|
-
return {"function": "new_block", "options": ":".join(self._block)}
|
|
39
|
-
|
|
40
|
-
def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
|
|
41
|
-
dst.cls = Block
|
|
42
|
-
dst.resource_id = self._block
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Self, Any
|
|
4
|
-
|
|
5
|
-
from amulet.entity import Entity
|
|
6
|
-
from .abc import AbstractBaseTranslationFunction, Data
|
|
7
|
-
from amulet.game.abc import JSONCompatible, JSONDict
|
|
8
|
-
from ._state import SrcData, StateData, DstData
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class NewEntity(AbstractBaseTranslationFunction):
|
|
12
|
-
# Class variables
|
|
13
|
-
Name = "new_entity"
|
|
14
|
-
_instances = {}
|
|
15
|
-
|
|
16
|
-
# Instance variables
|
|
17
|
-
_entity: tuple[str, str]
|
|
18
|
-
|
|
19
|
-
def __init__(self, namespace: str, base_name: str) -> None:
|
|
20
|
-
super().__init__()
|
|
21
|
-
self._entity = (namespace, base_name)
|
|
22
|
-
|
|
23
|
-
def __reduce__(self) -> Any:
|
|
24
|
-
return NewEntity, (self._entity,)
|
|
25
|
-
|
|
26
|
-
def _data(self) -> Data:
|
|
27
|
-
return self._entity
|
|
28
|
-
|
|
29
|
-
@classmethod
|
|
30
|
-
def from_json(cls, data: JSONCompatible) -> Self:
|
|
31
|
-
assert isinstance(data, dict)
|
|
32
|
-
assert data.get("function") == "new_entity"
|
|
33
|
-
entity = data["options"]
|
|
34
|
-
assert isinstance(entity, str)
|
|
35
|
-
namespace, base_name = entity.split(":", 1)
|
|
36
|
-
return cls(namespace, base_name)
|
|
37
|
-
|
|
38
|
-
def to_json(self) -> JSONDict:
|
|
39
|
-
return {"function": "new_entity", "options": ":".join(self._entity)}
|
|
40
|
-
|
|
41
|
-
def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
|
|
42
|
-
dst.cls = Entity
|
|
43
|
-
dst.resource_id = self._entity
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import (
|
|
4
|
-
Sequence,
|
|
5
|
-
Self,
|
|
6
|
-
Any,
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
from amulet_nbt import (
|
|
10
|
-
ListTag,
|
|
11
|
-
CompoundTag,
|
|
12
|
-
read_snbt,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
from .abc import (
|
|
16
|
-
AbstractBaseTranslationFunction,
|
|
17
|
-
Data,
|
|
18
|
-
)
|
|
19
|
-
from amulet.game.abc import JSONCompatible, JSONDict
|
|
20
|
-
from ._typing import (
|
|
21
|
-
NBTTagT,
|
|
22
|
-
NBTTagClasses,
|
|
23
|
-
NBTClsToStr,
|
|
24
|
-
StrToNBTCls,
|
|
25
|
-
NBTPath,
|
|
26
|
-
NBTPathElement,
|
|
27
|
-
)
|
|
28
|
-
from ._state import SrcData, StateData, DstData
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class NewNBTItem(AbstractBaseTranslationFunction):
|
|
32
|
-
# Class variables
|
|
33
|
-
Name = "_new_nbt"
|
|
34
|
-
_instances = {}
|
|
35
|
-
|
|
36
|
-
# Instance variables
|
|
37
|
-
_key: str | int
|
|
38
|
-
_value: NBTTagT
|
|
39
|
-
_snbt: str
|
|
40
|
-
_outer_name: str
|
|
41
|
-
_outer_type: type[CompoundTag] | type[ListTag]
|
|
42
|
-
_path: NBTPath | None
|
|
43
|
-
|
|
44
|
-
def __init__(
|
|
45
|
-
self,
|
|
46
|
-
key: str | int,
|
|
47
|
-
value: NBTTagT,
|
|
48
|
-
outer_name: str = "",
|
|
49
|
-
outer_type: type[CompoundTag] | type[ListTag] = CompoundTag,
|
|
50
|
-
path: (
|
|
51
|
-
Sequence[tuple[str | int, type[CompoundTag] | type[ListTag]]] | None
|
|
52
|
-
) = None,
|
|
53
|
-
) -> None:
|
|
54
|
-
super().__init__()
|
|
55
|
-
assert isinstance(outer_name, str)
|
|
56
|
-
self._outer_name = outer_name
|
|
57
|
-
|
|
58
|
-
assert outer_type in NBTClsToStr
|
|
59
|
-
self._outer_type = outer_type
|
|
60
|
-
last_cls = outer_type
|
|
61
|
-
|
|
62
|
-
if path is None:
|
|
63
|
-
self._path = None
|
|
64
|
-
else:
|
|
65
|
-
path_l = list(path)
|
|
66
|
-
for i, (path_key, nbt_cls) in enumerate(path_l):
|
|
67
|
-
assert nbt_cls is CompoundTag or nbt_cls is ListTag
|
|
68
|
-
assert (last_cls is CompoundTag and isinstance(path_key, str)) or (
|
|
69
|
-
last_cls is ListTag and isinstance(path_key, int)
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
path_l[i] = (path_key, nbt_cls)
|
|
73
|
-
last_cls = nbt_cls
|
|
74
|
-
self._path = tuple[NBTPathElement, ...](path_l)
|
|
75
|
-
|
|
76
|
-
assert isinstance(key, (str, int))
|
|
77
|
-
if self._path is not None:
|
|
78
|
-
if last_cls is CompoundTag:
|
|
79
|
-
assert isinstance(key, str)
|
|
80
|
-
elif last_cls is ListTag:
|
|
81
|
-
assert isinstance(key, int)
|
|
82
|
-
self._key = key
|
|
83
|
-
|
|
84
|
-
assert isinstance(value, NBTTagClasses)
|
|
85
|
-
self._snbt = value.to_snbt()
|
|
86
|
-
self._value = value
|
|
87
|
-
|
|
88
|
-
def __reduce__(self) -> Any:
|
|
89
|
-
return NewNBTItem, (
|
|
90
|
-
self._key,
|
|
91
|
-
self._value,
|
|
92
|
-
self._outer_name,
|
|
93
|
-
self._outer_type,
|
|
94
|
-
self._path,
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
def _data(self) -> Data:
|
|
98
|
-
return (
|
|
99
|
-
self._outer_name,
|
|
100
|
-
self._outer_type,
|
|
101
|
-
self._path,
|
|
102
|
-
self._key,
|
|
103
|
-
self._snbt,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
@classmethod
|
|
107
|
-
def from_json(cls, data: JSONCompatible) -> Self:
|
|
108
|
-
assert isinstance(data, dict)
|
|
109
|
-
|
|
110
|
-
key = data["key"]
|
|
111
|
-
assert isinstance(key, str | int)
|
|
112
|
-
raw_value = data["value"]
|
|
113
|
-
assert isinstance(raw_value, str)
|
|
114
|
-
outer_name = data.get("outer_name", "")
|
|
115
|
-
assert isinstance(outer_name, str)
|
|
116
|
-
outer_type = data.get("outer_type", "compound")
|
|
117
|
-
assert isinstance(outer_type, str)
|
|
118
|
-
raw_path = data.get("path", None)
|
|
119
|
-
if raw_path is None:
|
|
120
|
-
path = None
|
|
121
|
-
else:
|
|
122
|
-
assert isinstance(raw_path, list)
|
|
123
|
-
path = []
|
|
124
|
-
for item in raw_path:
|
|
125
|
-
assert isinstance(item, list) and len(item) == 2
|
|
126
|
-
cls_key, cls_name = item
|
|
127
|
-
assert isinstance(cls_key, str | int)
|
|
128
|
-
assert isinstance(cls_name, str)
|
|
129
|
-
path.append((cls_key, StrToNBTCls[cls_name]))
|
|
130
|
-
|
|
131
|
-
return cls(
|
|
132
|
-
key,
|
|
133
|
-
read_snbt(raw_value),
|
|
134
|
-
outer_name,
|
|
135
|
-
StrToNBTCls[outer_type],
|
|
136
|
-
path,
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
def to_json(self) -> JSONDict:
|
|
140
|
-
options: JSONDict = {}
|
|
141
|
-
if self._outer_name:
|
|
142
|
-
options["outer_name"] = self._outer_name
|
|
143
|
-
if self._outer_type is not CompoundTag:
|
|
144
|
-
options["outer_type"] = NBTClsToStr[self._outer_type]
|
|
145
|
-
if self._path is not None:
|
|
146
|
-
options["path"] = [[key, NBTClsToStr[value]] for key, value in self._path]
|
|
147
|
-
options["key"] = self._key
|
|
148
|
-
options["value"] = self._value.to_snbt()
|
|
149
|
-
return options
|
|
150
|
-
|
|
151
|
-
def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
|
|
152
|
-
path: NBTPath
|
|
153
|
-
if self._path is None:
|
|
154
|
-
walked_path = state.nbt_path
|
|
155
|
-
if walked_path is None:
|
|
156
|
-
# If not used within walk_input_nbt then default to the root
|
|
157
|
-
path = ()
|
|
158
|
-
else:
|
|
159
|
-
# If used within walk_input_nbt default to
|
|
160
|
-
path = walked_path[2]
|
|
161
|
-
else:
|
|
162
|
-
# If path is defined then use that
|
|
163
|
-
path = self._path
|
|
164
|
-
|
|
165
|
-
dst.nbt.append(
|
|
166
|
-
(self._outer_name, self._outer_type, path, self._key, self._value)
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
class NewNBT(AbstractBaseTranslationFunction):
|
|
171
|
-
# Class variables
|
|
172
|
-
Name = "new_nbt"
|
|
173
|
-
_instances = {}
|
|
174
|
-
|
|
175
|
-
# Instance variables
|
|
176
|
-
_new_nbt: tuple[NewNBTItem, ...]
|
|
177
|
-
|
|
178
|
-
def __init__(self, *new_nbt: NewNBTItem) -> None:
|
|
179
|
-
super().__init__()
|
|
180
|
-
self._new_nbt = tuple(new_nbt)
|
|
181
|
-
if not all(isinstance(nbt, NewNBTItem) for nbt in self._new_nbt):
|
|
182
|
-
raise TypeError
|
|
183
|
-
|
|
184
|
-
def __reduce__(self) -> Any:
|
|
185
|
-
return NewNBT, (*self._new_nbt,)
|
|
186
|
-
|
|
187
|
-
def _data(self) -> Data:
|
|
188
|
-
return self._new_nbt
|
|
189
|
-
|
|
190
|
-
@classmethod
|
|
191
|
-
def from_json(cls, data: JSONCompatible) -> Self:
|
|
192
|
-
assert isinstance(data, dict)
|
|
193
|
-
assert data.get("function") == "new_nbt"
|
|
194
|
-
options = data["options"]
|
|
195
|
-
assert isinstance(options, list)
|
|
196
|
-
return cls(*(NewNBTItem.from_json(opt) for opt in options))
|
|
197
|
-
|
|
198
|
-
def to_json(self) -> JSONDict:
|
|
199
|
-
return {
|
|
200
|
-
"function": "new_nbt",
|
|
201
|
-
"options": [opt.to_json() for opt in self._new_nbt],
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
|
|
205
|
-
for item in self._new_nbt:
|
|
206
|
-
item.run(src, state, dst)
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Self, Any
|
|
4
|
-
from collections.abc import Mapping
|
|
5
|
-
|
|
6
|
-
from amulet.block import PropertyValueType
|
|
7
|
-
from .abc import (
|
|
8
|
-
AbstractBaseTranslationFunction,
|
|
9
|
-
immutable_from_snbt,
|
|
10
|
-
Data,
|
|
11
|
-
)
|
|
12
|
-
from amulet.game.abc import JSONCompatible, JSONDict
|
|
13
|
-
from ._frozen import FrozenMapping
|
|
14
|
-
from ._state import SrcData, StateData, DstData
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class NewProperties(AbstractBaseTranslationFunction):
|
|
18
|
-
# Class variables
|
|
19
|
-
Name = "new_properties"
|
|
20
|
-
_instances = {}
|
|
21
|
-
|
|
22
|
-
# Instance variables
|
|
23
|
-
_properties: FrozenMapping[str, PropertyValueType]
|
|
24
|
-
|
|
25
|
-
def __init__(self, properties: Mapping[str, PropertyValueType]) -> None:
|
|
26
|
-
super().__init__()
|
|
27
|
-
self._properties = FrozenMapping[str, PropertyValueType](properties)
|
|
28
|
-
if not all(isinstance(key, str) for key in self._properties.keys()):
|
|
29
|
-
raise TypeError
|
|
30
|
-
if not all(
|
|
31
|
-
isinstance(value, PropertyValueType) for value in self._properties.values()
|
|
32
|
-
):
|
|
33
|
-
raise TypeError
|
|
34
|
-
|
|
35
|
-
def __reduce__(self) -> Any:
|
|
36
|
-
return NewProperties, (self._properties,)
|
|
37
|
-
|
|
38
|
-
def _data(self) -> Data:
|
|
39
|
-
return self._properties
|
|
40
|
-
|
|
41
|
-
@classmethod
|
|
42
|
-
def from_json(cls, data: JSONCompatible) -> Self:
|
|
43
|
-
assert isinstance(data, dict)
|
|
44
|
-
assert data.get("function") == "new_properties"
|
|
45
|
-
options = data["options"]
|
|
46
|
-
assert isinstance(options, dict)
|
|
47
|
-
properties = {}
|
|
48
|
-
for property_name, snbt in options.items():
|
|
49
|
-
assert isinstance(property_name, str)
|
|
50
|
-
assert isinstance(snbt, str)
|
|
51
|
-
properties[property_name] = immutable_from_snbt(snbt)
|
|
52
|
-
return cls(properties)
|
|
53
|
-
|
|
54
|
-
def to_json(self) -> JSONDict:
|
|
55
|
-
return {
|
|
56
|
-
"function": "new_properties",
|
|
57
|
-
"options": {
|
|
58
|
-
property_name: tag.to_snbt()
|
|
59
|
-
for property_name, tag in self._properties.items()
|
|
60
|
-
},
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
|
|
64
|
-
dst.properties.update(self._properties)
|