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.

Files changed (210) hide show
  1. amulet/__init__.cp312-win_amd64.pyd +0 -0
  2. amulet/__init__.pyi +30 -0
  3. amulet/__pyinstaller/__init__.py +2 -0
  4. amulet/__pyinstaller/hook-amulet.py +4 -0
  5. amulet/_init.py +28 -0
  6. amulet/_version.py +21 -0
  7. amulet/biome.cpp +36 -0
  8. amulet/biome.hpp +43 -0
  9. amulet/biome.pyi +77 -0
  10. amulet/block.cpp +435 -0
  11. amulet/block.hpp +119 -0
  12. amulet/block.pyi +273 -0
  13. amulet/block_entity.cpp +12 -0
  14. amulet/block_entity.hpp +56 -0
  15. amulet/block_entity.pyi +80 -0
  16. amulet/chunk.cpp +16 -0
  17. amulet/chunk.hpp +99 -0
  18. amulet/chunk.pyi +30 -0
  19. amulet/chunk_/components/biome.py +155 -0
  20. amulet/chunk_/components/block_entity.py +117 -0
  21. amulet/chunk_/components/entity.py +64 -0
  22. amulet/chunk_/components/height_2d.py +16 -0
  23. amulet/chunk_components.pyi +95 -0
  24. amulet/collections.pyi +37 -0
  25. amulet/data_types.py +29 -0
  26. amulet/entity.py +180 -0
  27. amulet/errors.py +63 -0
  28. amulet/game/__init__.py +7 -0
  29. amulet/game/_game.py +152 -0
  30. amulet/game/_universal/__init__.py +1 -0
  31. amulet/game/_universal/_biome.py +17 -0
  32. amulet/game/_universal/_block.py +47 -0
  33. amulet/game/_universal/_version.py +68 -0
  34. amulet/game/abc/__init__.py +22 -0
  35. amulet/game/abc/_block_specification.py +150 -0
  36. amulet/game/abc/biome.py +213 -0
  37. amulet/game/abc/block.py +331 -0
  38. amulet/game/abc/game_version_container.py +25 -0
  39. amulet/game/abc/json_interface.py +27 -0
  40. amulet/game/abc/version.py +44 -0
  41. amulet/game/bedrock/__init__.py +1 -0
  42. amulet/game/bedrock/_biome.py +35 -0
  43. amulet/game/bedrock/_block.py +42 -0
  44. amulet/game/bedrock/_version.py +165 -0
  45. amulet/game/java/__init__.py +2 -0
  46. amulet/game/java/_biome.py +35 -0
  47. amulet/game/java/_block.py +60 -0
  48. amulet/game/java/_version.py +176 -0
  49. amulet/game/translate/__init__.py +12 -0
  50. amulet/game/translate/_functions/__init__.py +15 -0
  51. amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
  52. amulet/game/translate/_functions/_code_functions/_text.py +553 -0
  53. amulet/game/translate/_functions/_code_functions/banner_pattern.py +67 -0
  54. amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +152 -0
  55. amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +88 -0
  56. amulet/game/translate/_functions/_code_functions/bedrock_sign.py +152 -0
  57. amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +16 -0
  58. amulet/game/translate/_functions/_code_functions/custom_name.py +146 -0
  59. amulet/game/translate/_functions/_frozen.py +66 -0
  60. amulet/game/translate/_functions/_state.py +54 -0
  61. amulet/game/translate/_functions/_typing.py +98 -0
  62. amulet/game/translate/_functions/abc.py +116 -0
  63. amulet/game/translate/_functions/carry_nbt.py +160 -0
  64. amulet/game/translate/_functions/carry_properties.py +80 -0
  65. amulet/game/translate/_functions/code.py +143 -0
  66. amulet/game/translate/_functions/map_block_name.py +66 -0
  67. amulet/game/translate/_functions/map_nbt.py +111 -0
  68. amulet/game/translate/_functions/map_properties.py +93 -0
  69. amulet/game/translate/_functions/multiblock.py +112 -0
  70. amulet/game/translate/_functions/new_block.py +42 -0
  71. amulet/game/translate/_functions/new_entity.py +43 -0
  72. amulet/game/translate/_functions/new_nbt.py +206 -0
  73. amulet/game/translate/_functions/new_properties.py +64 -0
  74. amulet/game/translate/_functions/sequence.py +51 -0
  75. amulet/game/translate/_functions/walk_input_nbt.py +331 -0
  76. amulet/game/translate/_translator.py +433 -0
  77. amulet/item.py +75 -0
  78. amulet/level/__init__.pyi +27 -0
  79. amulet/level/_load.py +100 -0
  80. amulet/level/abc/__init__.py +12 -0
  81. amulet/level/abc/_chunk_handle.py +335 -0
  82. amulet/level/abc/_dimension.py +86 -0
  83. amulet/level/abc/_history/__init__.py +1 -0
  84. amulet/level/abc/_history/_cache.py +224 -0
  85. amulet/level/abc/_history/_history_manager.py +291 -0
  86. amulet/level/abc/_level/__init__.py +5 -0
  87. amulet/level/abc/_level/_compactable_level.py +10 -0
  88. amulet/level/abc/_level/_creatable_level.py +29 -0
  89. amulet/level/abc/_level/_disk_level.py +17 -0
  90. amulet/level/abc/_level/_level.py +453 -0
  91. amulet/level/abc/_level/_loadable_level.py +42 -0
  92. amulet/level/abc/_player_storage.py +7 -0
  93. amulet/level/abc/_raw_level.py +187 -0
  94. amulet/level/abc/_registry.py +40 -0
  95. amulet/level/bedrock/__init__.py +2 -0
  96. amulet/level/bedrock/_chunk_handle.py +19 -0
  97. amulet/level/bedrock/_dimension.py +22 -0
  98. amulet/level/bedrock/_level.py +187 -0
  99. amulet/level/bedrock/_raw/__init__.py +5 -0
  100. amulet/level/bedrock/_raw/_actor_counter.py +53 -0
  101. amulet/level/bedrock/_raw/_chunk.py +54 -0
  102. amulet/level/bedrock/_raw/_chunk_decode.py +668 -0
  103. amulet/level/bedrock/_raw/_chunk_encode.py +602 -0
  104. amulet/level/bedrock/_raw/_constant.py +9 -0
  105. amulet/level/bedrock/_raw/_dimension.py +343 -0
  106. amulet/level/bedrock/_raw/_level.py +463 -0
  107. amulet/level/bedrock/_raw/_level_dat.py +90 -0
  108. amulet/level/bedrock/_raw/_typing.py +6 -0
  109. amulet/level/bedrock/_raw/leveldb_chunk_versions.py +83 -0
  110. amulet/level/bedrock/chunk/__init__.py +1 -0
  111. amulet/level/bedrock/chunk/_chunk.py +126 -0
  112. amulet/level/bedrock/chunk/components/__init__.py +0 -0
  113. amulet/level/bedrock/chunk/components/chunk_version.py +12 -0
  114. amulet/level/bedrock/chunk/components/finalised_state.py +13 -0
  115. amulet/level/bedrock/chunk/components/raw_chunk.py +15 -0
  116. amulet/level/construction/__init__.py +0 -0
  117. amulet/level/java/__init__.pyi +21 -0
  118. amulet/level/java/_chunk_handle.py +17 -0
  119. amulet/level/java/_chunk_handle.pyi +15 -0
  120. amulet/level/java/_dimension.py +20 -0
  121. amulet/level/java/_dimension.pyi +13 -0
  122. amulet/level/java/_level.py +184 -0
  123. amulet/level/java/_level.pyi +120 -0
  124. amulet/level/java/_raw/__init__.pyi +19 -0
  125. amulet/level/java/_raw/_chunk.pyi +23 -0
  126. amulet/level/java/_raw/_chunk_decode.py +561 -0
  127. amulet/level/java/_raw/_chunk_encode.py +463 -0
  128. amulet/level/java/_raw/_constant.py +9 -0
  129. amulet/level/java/_raw/_constant.pyi +20 -0
  130. amulet/level/java/_raw/_data_pack/__init__.py +2 -0
  131. amulet/level/java/_raw/_data_pack/__init__.pyi +8 -0
  132. amulet/level/java/_raw/_data_pack/data_pack.py +241 -0
  133. amulet/level/java/_raw/_data_pack/data_pack.pyi +197 -0
  134. amulet/level/java/_raw/_data_pack/data_pack_manager.py +77 -0
  135. amulet/level/java/_raw/_data_pack/data_pack_manager.pyi +75 -0
  136. amulet/level/java/_raw/_dimension.py +86 -0
  137. amulet/level/java/_raw/_dimension.pyi +72 -0
  138. amulet/level/java/_raw/_level.py +507 -0
  139. amulet/level/java/_raw/_level.pyi +238 -0
  140. amulet/level/java/_raw/_typing.py +3 -0
  141. amulet/level/java/_raw/_typing.pyi +5 -0
  142. amulet/level/java/anvil/__init__.py +2 -0
  143. amulet/level/java/anvil/__init__.pyi +11 -0
  144. amulet/level/java/anvil/_dimension.py +170 -0
  145. amulet/level/java/anvil/_dimension.pyi +109 -0
  146. amulet/level/java/anvil/_region.py +421 -0
  147. amulet/level/java/anvil/_region.pyi +197 -0
  148. amulet/level/java/anvil/_sector_manager.py +223 -0
  149. amulet/level/java/anvil/_sector_manager.pyi +142 -0
  150. amulet/level/java/chunk.pyi +81 -0
  151. amulet/level/java/chunk_/_chunk.py +260 -0
  152. amulet/level/java/chunk_/components/inhabited_time.py +12 -0
  153. amulet/level/java/chunk_/components/last_update.py +12 -0
  154. amulet/level/java/chunk_/components/legacy_version.py +12 -0
  155. amulet/level/java/chunk_/components/light_populated.py +12 -0
  156. amulet/level/java/chunk_/components/named_height_2d.py +37 -0
  157. amulet/level/java/chunk_/components/status.py +11 -0
  158. amulet/level/java/chunk_/components/terrain_populated.py +12 -0
  159. amulet/level/java/chunk_components.pyi +22 -0
  160. amulet/level/java/long_array.pyi +38 -0
  161. amulet/level/java_forge/__init__.py +0 -0
  162. amulet/level/mcstructure/__init__.py +0 -0
  163. amulet/level/nbt/__init__.py +0 -0
  164. amulet/level/schematic/__init__.py +0 -0
  165. amulet/level/sponge_schematic/__init__.py +0 -0
  166. amulet/level/temporary_level/__init__.py +1 -0
  167. amulet/level/temporary_level/_level.py +16 -0
  168. amulet/palette/__init__.pyi +8 -0
  169. amulet/palette/biome_palette.pyi +45 -0
  170. amulet/palette/block_palette.pyi +45 -0
  171. amulet/player.py +64 -0
  172. amulet/py.typed +0 -0
  173. amulet/selection/__init__.py +2 -0
  174. amulet/selection/abstract_selection.py +342 -0
  175. amulet/selection/box.py +852 -0
  176. amulet/selection/group.py +481 -0
  177. amulet/utils/__init__.pyi +28 -0
  178. amulet/utils/call_spec/__init__.py +24 -0
  179. amulet/utils/call_spec/__init__.pyi +53 -0
  180. amulet/utils/call_spec/_call_spec.py +262 -0
  181. amulet/utils/call_spec/_call_spec.pyi +272 -0
  182. amulet/utils/format_utils.py +41 -0
  183. amulet/utils/generator.py +18 -0
  184. amulet/utils/matrix.py +243 -0
  185. amulet/utils/matrix.pyi +177 -0
  186. amulet/utils/numpy.pyi +11 -0
  187. amulet/utils/numpy_helpers.py +19 -0
  188. amulet/utils/shareable_lock.py +335 -0
  189. amulet/utils/shareable_lock.pyi +190 -0
  190. amulet/utils/signal/__init__.py +10 -0
  191. amulet/utils/signal/__init__.pyi +25 -0
  192. amulet/utils/signal/_signal.py +228 -0
  193. amulet/utils/signal/_signal.pyi +84 -0
  194. amulet/utils/task_manager.py +235 -0
  195. amulet/utils/task_manager.pyi +168 -0
  196. amulet/utils/typed_property.py +111 -0
  197. amulet/utils/typing.py +4 -0
  198. amulet/utils/typing.pyi +6 -0
  199. amulet/utils/weakref.py +70 -0
  200. amulet/utils/weakref.pyi +50 -0
  201. amulet/utils/world_utils.py +102 -0
  202. amulet/utils/world_utils.pyi +109 -0
  203. amulet/version.cpp +136 -0
  204. amulet/version.hpp +142 -0
  205. amulet/version.pyi +94 -0
  206. amulet_core-2.0a3.dist-info/METADATA +103 -0
  207. amulet_core-2.0a3.dist-info/RECORD +210 -0
  208. amulet_core-2.0a3.dist-info/WHEEL +5 -0
  209. amulet_core-2.0a3.dist-info/entry_points.txt +2 -0
  210. amulet_core-2.0a3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,51 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Self, Any
4
+ from collections.abc import Sequence
5
+
6
+ from .abc import (
7
+ AbstractBaseTranslationFunction,
8
+ translation_function_from_json,
9
+ Data,
10
+ )
11
+ from amulet.game.abc import JSONCompatible, JSONList
12
+ from ._state import SrcData, StateData, DstData
13
+
14
+
15
+ class TranslationFunctionSequence(AbstractBaseTranslationFunction):
16
+ # Class variables
17
+ Name = "sequence"
18
+ _instances = {}
19
+
20
+ # Instance variables
21
+ _functions: tuple[AbstractBaseTranslationFunction, ...]
22
+
23
+ def __init__(self, functions: Sequence[AbstractBaseTranslationFunction]) -> None:
24
+ super().__init__()
25
+ self._functions = tuple(functions)
26
+ if not all(
27
+ isinstance(inst, AbstractBaseTranslationFunction)
28
+ for inst in self._functions
29
+ ):
30
+ raise TypeError
31
+
32
+ def __reduce__(self) -> Any:
33
+ return TranslationFunctionSequence, (self._functions,)
34
+
35
+ def _data(self) -> Data:
36
+ return self._functions
37
+
38
+ @classmethod
39
+ def from_json(cls, data: JSONCompatible) -> Self:
40
+ assert isinstance(data, Sequence)
41
+ return cls([translation_function_from_json(func) for func in data])
42
+
43
+ def to_json(self) -> JSONList:
44
+ return [func.to_json() for func in self._functions]
45
+
46
+ def __bool__(self) -> bool:
47
+ return bool(self._functions)
48
+
49
+ def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
50
+ for func in self._functions:
51
+ func.run(src, state, dst)
@@ -0,0 +1,331 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Self, TypeVar, cast, Any
4
+ from collections.abc import Mapping, Sequence, Iterable
5
+ import logging
6
+
7
+ from amulet_nbt import (
8
+ AbstractBaseArrayTag,
9
+ ByteTag,
10
+ ShortTag,
11
+ IntTag,
12
+ LongTag,
13
+ FloatTag,
14
+ DoubleTag,
15
+ ByteArrayTag,
16
+ StringTag,
17
+ ListTag,
18
+ CompoundTag,
19
+ IntArrayTag,
20
+ LongArrayTag,
21
+ )
22
+
23
+ from .abc import (
24
+ AbstractBaseTranslationFunction,
25
+ Data,
26
+ translation_function_from_json,
27
+ follow_nbt_path,
28
+ )
29
+ from amulet.game.abc import JSONCompatible, JSONDict
30
+ from ._typing import NBTClsToStr, StrToNBTCls, NBTPath, NBTPathElement, NBTTagClsT
31
+ from ._frozen import FrozenMapping
32
+ from ._state import SrcData, StateData, DstData
33
+
34
+ log = logging.getLogger(__name__)
35
+
36
+
37
+ NBTLookUp = [
38
+ None,
39
+ ByteTag,
40
+ ShortTag,
41
+ IntTag,
42
+ LongTag,
43
+ FloatTag,
44
+ DoubleTag,
45
+ ByteArrayTag,
46
+ StringTag,
47
+ ListTag,
48
+ CompoundTag,
49
+ IntArrayTag,
50
+ LongArrayTag,
51
+ ]
52
+
53
+
54
+ KeyT = TypeVar("KeyT", str, int)
55
+
56
+
57
+ class WalkInputNBTOptions(AbstractBaseTranslationFunction):
58
+ # Class variables
59
+ Name = "_walk_input_nbt"
60
+ _instances = {}
61
+
62
+ # Instance variables
63
+ _nbt_cls: type[CompoundTag] | type[ListTag]
64
+ _self_default: AbstractBaseTranslationFunction | None
65
+ _functions: AbstractBaseTranslationFunction | None
66
+ _keys: FrozenMapping[str, WalkInputNBTOptions] | None
67
+ _index: FrozenMapping[int, WalkInputNBTOptions] | None
68
+ _nested_default: AbstractBaseTranslationFunction | None
69
+
70
+ def __init__(
71
+ self,
72
+ nbt_cls: type[CompoundTag] | type[ListTag],
73
+ self_default: AbstractBaseTranslationFunction | None = None,
74
+ functions: AbstractBaseTranslationFunction | None = None,
75
+ keys: Mapping[str, WalkInputNBTOptions] | None = None,
76
+ index: Mapping[int, WalkInputNBTOptions] | None = None,
77
+ nested_default: AbstractBaseTranslationFunction | None = None,
78
+ ) -> None:
79
+ super().__init__()
80
+ self._nbt_cls = nbt_cls
81
+ self._self_default = self_default
82
+ self._functions = functions
83
+ self._keys = (
84
+ None if keys is None else FrozenMapping[str, WalkInputNBTOptions](keys)
85
+ )
86
+ self._index = (
87
+ None if index is None else FrozenMapping[int, WalkInputNBTOptions](index)
88
+ )
89
+ self._nested_default = nested_default
90
+
91
+ def __reduce__(self) -> Any:
92
+ return WalkInputNBTOptions, (
93
+ self._nbt_cls,
94
+ self._self_default,
95
+ self._functions,
96
+ self._keys,
97
+ self._index,
98
+ self._nested_default,
99
+ )
100
+
101
+ def _data(self) -> Data:
102
+ return (
103
+ self._nbt_cls,
104
+ self._self_default,
105
+ self._functions,
106
+ self._keys,
107
+ self._index,
108
+ self._nested_default,
109
+ )
110
+
111
+ @classmethod
112
+ def from_json(cls, data: JSONCompatible) -> Self:
113
+ assert isinstance(data, dict)
114
+ nbt_type = data["type"]
115
+ assert isinstance(nbt_type, str)
116
+ if "keys" in data:
117
+ raw_keys = data["keys"]
118
+ assert isinstance(raw_keys, dict)
119
+ keys = {
120
+ key: WalkInputNBTOptions.from_json(value)
121
+ for key, value in raw_keys.items()
122
+ }
123
+ else:
124
+ keys = None
125
+ if "index" in data:
126
+ raw_index = data["index"]
127
+ assert isinstance(raw_index, dict)
128
+ index = {
129
+ int(key): WalkInputNBTOptions.from_json(value)
130
+ for key, value in raw_index.items()
131
+ }
132
+ else:
133
+ index = None
134
+ return cls(
135
+ StrToNBTCls[nbt_type],
136
+ (
137
+ translation_function_from_json(data["self_default"])
138
+ if "self_default" in data
139
+ else None
140
+ ),
141
+ (
142
+ translation_function_from_json(data["functions"])
143
+ if "functions" in data
144
+ else None
145
+ ),
146
+ keys,
147
+ index,
148
+ (
149
+ translation_function_from_json(data["nested_default"])
150
+ if "nested_default" in data
151
+ else None
152
+ ),
153
+ )
154
+
155
+ def to_json(self) -> JSONDict:
156
+ options: JSONDict = {
157
+ "type": NBTClsToStr[self._nbt_cls],
158
+ }
159
+ if self._self_default is not None:
160
+ options["self_default"] = self._self_default.to_json()
161
+ if self._functions is not None:
162
+ options["functions"] = self._functions.to_json()
163
+ if self._keys is not None:
164
+ options["keys"] = {
165
+ key: value.to_json() for key, value in self._keys.items()
166
+ }
167
+ if self._index is not None:
168
+ options["index"] = {
169
+ str(key): value.to_json() for key, value in self._index.items()
170
+ }
171
+ if self._nested_default is not None:
172
+ options["nested_default"] = self._nested_default.to_json()
173
+ return options
174
+
175
+ def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
176
+ if self._functions is not None:
177
+ self._functions.run(src, state, dst)
178
+
179
+ nbt = src.nbt
180
+ if nbt is None:
181
+ raise RuntimeError
182
+ nbt_path_or_none = state.nbt_path
183
+ if nbt_path_or_none is None:
184
+ raise RuntimeError
185
+ else:
186
+ nbt_path = nbt_path_or_none
187
+
188
+ tag_or_none = follow_nbt_path(nbt, nbt_path)
189
+
190
+ nbt_cls = self._nbt_cls
191
+ if tag_or_none is None:
192
+ pass
193
+ elif isinstance(tag_or_none, nbt_cls):
194
+ tag = tag_or_none
195
+
196
+ def run(
197
+ keys: Iterable[KeyT],
198
+ lut: Mapping[KeyT, WalkInputNBTOptions] | None,
199
+ nested_dtype: NBTTagClsT | None,
200
+ ) -> None:
201
+ for key in keys:
202
+ if lut is not None and key in lut:
203
+ lut[key].run(src, StateData(), dst)
204
+ elif self._nested_default is not None:
205
+ outer_name, outer_type, path = nbt_path
206
+ new_type: NBTTagClsT
207
+ if nested_dtype is None:
208
+ new_type = tag.__class__
209
+ else:
210
+ new_type = nested_dtype
211
+ new_path: NBTPath = path + (
212
+ (
213
+ key,
214
+ new_type,
215
+ ),
216
+ )
217
+ self._nested_default.run(
218
+ src,
219
+ StateData(
220
+ state.relative_location,
221
+ (
222
+ outer_name,
223
+ outer_type,
224
+ new_path,
225
+ ),
226
+ ),
227
+ dst,
228
+ )
229
+
230
+ if isinstance(tag, CompoundTag):
231
+ run(
232
+ [key for key in tag.keys() if isinstance(key, str)],
233
+ self._keys,
234
+ None,
235
+ )
236
+ elif isinstance(tag, ListTag):
237
+ dtype = NBTLookUp[tag.element_tag_id]
238
+ assert dtype is not None
239
+ run(range(len(tag)), self._index, dtype)
240
+ elif isinstance(tag, AbstractBaseArrayTag):
241
+ nested_dtype_: NBTTagClsT
242
+ if isinstance(tag, ByteArrayTag):
243
+ nested_dtype_ = ByteTag
244
+ elif isinstance(tag, IntArrayTag):
245
+ nested_dtype_ = IntTag
246
+ elif isinstance(tag, LongArrayTag):
247
+ nested_dtype_ = LongTag
248
+ else:
249
+ raise TypeError
250
+ run(range(len(tag)), self._index, nested_dtype_)
251
+ else:
252
+ return
253
+
254
+ elif self._self_default is not None:
255
+ self._self_default.run(src, state, dst)
256
+
257
+
258
+ class WalkInputNBT(AbstractBaseTranslationFunction):
259
+ # Class variables
260
+ Name = "walk_input_nbt"
261
+ _instances = {}
262
+
263
+ # Instance variables
264
+ _walk_nbt: WalkInputNBTOptions
265
+ _path: NBTPath | None
266
+
267
+ def __init__(
268
+ self,
269
+ walk_nbt: WalkInputNBTOptions,
270
+ path: Sequence[NBTPathElement] | None = None,
271
+ ) -> None:
272
+ super().__init__()
273
+ self._walk_nbt = walk_nbt
274
+ self._path = None if path is None else tuple(path)
275
+
276
+ def __reduce__(self) -> Any:
277
+ return WalkInputNBT, (self._walk_nbt, self._path)
278
+
279
+ def _data(self) -> Data:
280
+ return self._walk_nbt, self._path
281
+
282
+ @classmethod
283
+ def from_json(cls, data: JSONCompatible) -> Self:
284
+ assert isinstance(data, dict)
285
+ assert data.get("function") == "walk_input_nbt"
286
+ raw_path = data.get("path", None)
287
+ if raw_path is None:
288
+ path = None
289
+ elif isinstance(raw_path, list):
290
+ path = []
291
+ for item in raw_path:
292
+ assert isinstance(item, list) and len(item) == 2
293
+ key, cls_name = item
294
+ assert isinstance(key, str | int)
295
+ assert isinstance(cls_name, str)
296
+ path.append((key, StrToNBTCls[cls_name]))
297
+ else:
298
+ raise TypeError
299
+ return cls(
300
+ WalkInputNBTOptions.from_json(data["options"]),
301
+ path,
302
+ )
303
+
304
+ def to_json(self) -> JSONDict:
305
+ data: JSONDict = {
306
+ "function": "walk_input_nbt",
307
+ "options": self._walk_nbt.to_json(),
308
+ }
309
+ if self._path is not None:
310
+ data["path"] = [[key, NBTClsToStr[cls]] for key, cls in self._path]
311
+ return data
312
+
313
+ def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
314
+ dst.cacheable = False
315
+ nbt = src.nbt
316
+ if nbt is None:
317
+ dst.extra_needed = True
318
+ return
319
+
320
+ if self._path is None:
321
+ new_state = state
322
+ else:
323
+ path = ("", CompoundTag, self._path)
324
+ # verify that the data exists at the path
325
+ tag = follow_nbt_path(nbt, path)
326
+ if not isinstance(tag, self._path[-1][1]):
327
+ log.error(f"Tag at path {path} does not exist or has the wrong type.")
328
+ return
329
+ new_state = StateData(state.relative_location, path)
330
+
331
+ self._walk_nbt.run(src, new_state, dst)