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.

Files changed (198) hide show
  1. amulet/__init__.py +27 -27
  2. amulet/__pyinstaller/__init__.py +2 -2
  3. amulet/__pyinstaller/hook-amulet.py +4 -4
  4. amulet/_version.py +21 -21
  5. amulet/api/__init__.py +2 -2
  6. amulet/api/abstract_base_entity.py +128 -128
  7. amulet/api/block.py +630 -630
  8. amulet/api/block_entity.py +71 -71
  9. amulet/api/cache.py +107 -107
  10. amulet/api/chunk/__init__.py +6 -6
  11. amulet/api/chunk/biomes.py +207 -207
  12. amulet/api/chunk/block_entity_dict.py +175 -175
  13. amulet/api/chunk/blocks.py +46 -46
  14. amulet/api/chunk/chunk.py +389 -389
  15. amulet/api/chunk/entity_list.py +75 -75
  16. amulet/api/chunk/status.py +167 -167
  17. amulet/api/data_types/__init__.py +4 -4
  18. amulet/api/data_types/generic_types.py +4 -4
  19. amulet/api/data_types/operation_types.py +16 -16
  20. amulet/api/data_types/world_types.py +49 -49
  21. amulet/api/data_types/wrapper_types.py +71 -71
  22. amulet/api/entity.py +74 -74
  23. amulet/api/errors.py +119 -119
  24. amulet/api/history/__init__.py +36 -36
  25. amulet/api/history/base/__init__.py +3 -3
  26. amulet/api/history/base/base_history.py +26 -26
  27. amulet/api/history/base/history_manager.py +63 -63
  28. amulet/api/history/base/revision_manager.py +73 -73
  29. amulet/api/history/changeable.py +15 -15
  30. amulet/api/history/data_types.py +7 -7
  31. amulet/api/history/history_manager/__init__.py +3 -3
  32. amulet/api/history/history_manager/container.py +102 -102
  33. amulet/api/history/history_manager/database.py +279 -279
  34. amulet/api/history/history_manager/meta.py +93 -93
  35. amulet/api/history/history_manager/object.py +116 -116
  36. amulet/api/history/revision_manager/__init__.py +2 -2
  37. amulet/api/history/revision_manager/disk.py +33 -33
  38. amulet/api/history/revision_manager/ram.py +12 -12
  39. amulet/api/item.py +75 -75
  40. amulet/api/level/__init__.py +4 -4
  41. amulet/api/level/base_level/__init__.py +1 -1
  42. amulet/api/level/base_level/base_level.py +1035 -1026
  43. amulet/api/level/base_level/chunk_manager.py +227 -227
  44. amulet/api/level/base_level/clone.py +389 -389
  45. amulet/api/level/base_level/player_manager.py +101 -101
  46. amulet/api/level/immutable_structure/__init__.py +1 -1
  47. amulet/api/level/immutable_structure/immutable_structure.py +94 -94
  48. amulet/api/level/immutable_structure/void_format_wrapper.py +117 -117
  49. amulet/api/level/structure.py +22 -22
  50. amulet/api/level/world.py +19 -19
  51. amulet/api/partial_3d_array/__init__.py +2 -2
  52. amulet/api/partial_3d_array/base_partial_3d_array.py +263 -263
  53. amulet/api/partial_3d_array/bounded_partial_3d_array.py +528 -528
  54. amulet/api/partial_3d_array/data_types.py +15 -15
  55. amulet/api/partial_3d_array/unbounded_partial_3d_array.py +229 -229
  56. amulet/api/partial_3d_array/util.py +152 -152
  57. amulet/api/player.py +65 -65
  58. amulet/api/registry/__init__.py +2 -2
  59. amulet/api/registry/base_registry.py +34 -34
  60. amulet/api/registry/biome_manager.py +153 -153
  61. amulet/api/registry/block_manager.py +156 -156
  62. amulet/api/selection/__init__.py +2 -2
  63. amulet/api/selection/abstract_selection.py +315 -315
  64. amulet/api/selection/box.py +805 -805
  65. amulet/api/selection/group.py +488 -488
  66. amulet/api/structure.py +37 -37
  67. amulet/api/wrapper/__init__.py +8 -8
  68. amulet/api/wrapper/chunk/interface.py +441 -441
  69. amulet/api/wrapper/chunk/translator.py +567 -567
  70. amulet/api/wrapper/format_wrapper.py +772 -772
  71. amulet/api/wrapper/structure_format_wrapper.py +116 -116
  72. amulet/api/wrapper/world_format_wrapper.py +63 -63
  73. amulet/level/__init__.py +1 -1
  74. amulet/level/formats/anvil_forge_world.py +40 -40
  75. amulet/level/formats/anvil_world/__init__.py +3 -3
  76. amulet/level/formats/anvil_world/_sector_manager.py +291 -384
  77. amulet/level/formats/anvil_world/data_pack/__init__.py +2 -2
  78. amulet/level/formats/anvil_world/data_pack/data_pack.py +224 -224
  79. amulet/level/formats/anvil_world/data_pack/data_pack_manager.py +77 -77
  80. amulet/level/formats/anvil_world/dimension.py +177 -177
  81. amulet/level/formats/anvil_world/format.py +769 -769
  82. amulet/level/formats/anvil_world/region.py +384 -384
  83. amulet/level/formats/construction/__init__.py +3 -3
  84. amulet/level/formats/construction/format_wrapper.py +515 -515
  85. amulet/level/formats/construction/interface.py +134 -134
  86. amulet/level/formats/construction/section.py +60 -60
  87. amulet/level/formats/construction/util.py +165 -165
  88. amulet/level/formats/leveldb_world/__init__.py +3 -3
  89. amulet/level/formats/leveldb_world/chunk.py +33 -33
  90. amulet/level/formats/leveldb_world/dimension.py +385 -419
  91. amulet/level/formats/leveldb_world/format.py +659 -641
  92. amulet/level/formats/leveldb_world/interface/chunk/__init__.py +36 -36
  93. amulet/level/formats/leveldb_world/interface/chunk/base_leveldb_interface.py +836 -836
  94. amulet/level/formats/leveldb_world/interface/chunk/generate_interface.py +31 -31
  95. amulet/level/formats/leveldb_world/interface/chunk/leveldb_0.py +30 -30
  96. amulet/level/formats/leveldb_world/interface/chunk/leveldb_1.py +12 -12
  97. amulet/level/formats/leveldb_world/interface/chunk/leveldb_10.py +12 -12
  98. amulet/level/formats/leveldb_world/interface/chunk/leveldb_11.py +12 -12
  99. amulet/level/formats/leveldb_world/interface/chunk/leveldb_12.py +12 -12
  100. amulet/level/formats/leveldb_world/interface/chunk/leveldb_13.py +12 -12
  101. amulet/level/formats/leveldb_world/interface/chunk/leveldb_14.py +12 -12
  102. amulet/level/formats/leveldb_world/interface/chunk/leveldb_15.py +12 -12
  103. amulet/level/formats/leveldb_world/interface/chunk/leveldb_16.py +12 -12
  104. amulet/level/formats/leveldb_world/interface/chunk/leveldb_17.py +12 -12
  105. amulet/level/formats/leveldb_world/interface/chunk/leveldb_18.py +12 -12
  106. amulet/level/formats/leveldb_world/interface/chunk/leveldb_19.py +12 -12
  107. amulet/level/formats/leveldb_world/interface/chunk/leveldb_2.py +12 -12
  108. amulet/level/formats/leveldb_world/interface/chunk/leveldb_20.py +12 -12
  109. amulet/level/formats/leveldb_world/interface/chunk/leveldb_21.py +12 -12
  110. amulet/level/formats/leveldb_world/interface/chunk/leveldb_22.py +12 -12
  111. amulet/level/formats/leveldb_world/interface/chunk/leveldb_23.py +10 -10
  112. amulet/level/formats/leveldb_world/interface/chunk/leveldb_24.py +10 -10
  113. amulet/level/formats/leveldb_world/interface/chunk/leveldb_25.py +24 -24
  114. amulet/level/formats/leveldb_world/interface/chunk/leveldb_26.py +10 -10
  115. amulet/level/formats/leveldb_world/interface/chunk/leveldb_27.py +10 -10
  116. amulet/level/formats/leveldb_world/interface/chunk/leveldb_28.py +10 -10
  117. amulet/level/formats/leveldb_world/interface/chunk/leveldb_29.py +33 -33
  118. amulet/level/formats/leveldb_world/interface/chunk/leveldb_3.py +57 -57
  119. amulet/level/formats/leveldb_world/interface/chunk/leveldb_30.py +10 -10
  120. amulet/level/formats/leveldb_world/interface/chunk/leveldb_31.py +10 -10
  121. amulet/level/formats/leveldb_world/interface/chunk/leveldb_32.py +10 -10
  122. amulet/level/formats/leveldb_world/interface/chunk/leveldb_33.py +10 -10
  123. amulet/level/formats/leveldb_world/interface/chunk/leveldb_34.py +10 -10
  124. amulet/level/formats/leveldb_world/interface/chunk/leveldb_35.py +10 -10
  125. amulet/level/formats/leveldb_world/interface/chunk/leveldb_36.py +10 -10
  126. amulet/level/formats/leveldb_world/interface/chunk/leveldb_37.py +10 -10
  127. amulet/level/formats/leveldb_world/interface/chunk/leveldb_38.py +10 -10
  128. amulet/level/formats/leveldb_world/interface/chunk/leveldb_39.py +12 -12
  129. amulet/level/formats/leveldb_world/interface/chunk/leveldb_4.py +12 -12
  130. amulet/level/formats/leveldb_world/interface/chunk/leveldb_40.py +16 -16
  131. amulet/level/formats/leveldb_world/interface/chunk/leveldb_5.py +12 -12
  132. amulet/level/formats/leveldb_world/interface/chunk/leveldb_6.py +12 -12
  133. amulet/level/formats/leveldb_world/interface/chunk/leveldb_7.py +12 -12
  134. amulet/level/formats/leveldb_world/interface/chunk/leveldb_8.py +180 -180
  135. amulet/level/formats/leveldb_world/interface/chunk/leveldb_9.py +18 -18
  136. amulet/level/formats/leveldb_world/interface/chunk/leveldb_chunk_versions.py +79 -79
  137. amulet/level/formats/mcstructure/__init__.py +3 -3
  138. amulet/level/formats/mcstructure/chunk.py +50 -50
  139. amulet/level/formats/mcstructure/format_wrapper.py +408 -408
  140. amulet/level/formats/mcstructure/interface.py +175 -175
  141. amulet/level/formats/schematic/__init__.py +3 -3
  142. amulet/level/formats/schematic/chunk.py +55 -55
  143. amulet/level/formats/schematic/data_types.py +4 -4
  144. amulet/level/formats/schematic/format_wrapper.py +373 -373
  145. amulet/level/formats/schematic/interface.py +142 -142
  146. amulet/level/formats/sponge_schem/__init__.py +4 -4
  147. amulet/level/formats/sponge_schem/chunk.py +62 -62
  148. amulet/level/formats/sponge_schem/format_wrapper.py +463 -463
  149. amulet/level/formats/sponge_schem/interface.py +118 -118
  150. amulet/level/formats/sponge_schem/varint/__init__.py +1 -1
  151. amulet/level/formats/sponge_schem/varint/varint.py +87 -87
  152. amulet/level/interfaces/chunk/anvil/anvil_0.py +72 -72
  153. amulet/level/interfaces/chunk/anvil/anvil_1444.py +336 -336
  154. amulet/level/interfaces/chunk/anvil/anvil_1466.py +94 -94
  155. amulet/level/interfaces/chunk/anvil/anvil_1467.py +37 -37
  156. amulet/level/interfaces/chunk/anvil/anvil_1484.py +20 -20
  157. amulet/level/interfaces/chunk/anvil/anvil_1503.py +20 -20
  158. amulet/level/interfaces/chunk/anvil/anvil_1519.py +34 -34
  159. amulet/level/interfaces/chunk/anvil/anvil_1901.py +20 -20
  160. amulet/level/interfaces/chunk/anvil/anvil_1908.py +20 -20
  161. amulet/level/interfaces/chunk/anvil/anvil_1912.py +21 -21
  162. amulet/level/interfaces/chunk/anvil/anvil_1934.py +20 -20
  163. amulet/level/interfaces/chunk/anvil/anvil_2203.py +69 -69
  164. amulet/level/interfaces/chunk/anvil/anvil_2529.py +19 -19
  165. amulet/level/interfaces/chunk/anvil/anvil_2681.py +76 -76
  166. amulet/level/interfaces/chunk/anvil/anvil_2709.py +19 -19
  167. amulet/level/interfaces/chunk/anvil/anvil_2844.py +267 -267
  168. amulet/level/interfaces/chunk/anvil/anvil_3463.py +19 -19
  169. amulet/level/interfaces/chunk/anvil/anvil_na.py +607 -607
  170. amulet/level/interfaces/chunk/anvil/base_anvil_interface.py +326 -326
  171. amulet/level/load.py +59 -59
  172. amulet/level/loader.py +95 -95
  173. amulet/level/translators/chunk/bedrock/__init__.py +267 -267
  174. amulet/level/translators/chunk/bedrock/bedrock_nbt_blockstate_translator.py +46 -46
  175. amulet/level/translators/chunk/bedrock/bedrock_numerical_translator.py +39 -39
  176. amulet/level/translators/chunk/bedrock/bedrock_psudo_numerical_translator.py +37 -37
  177. amulet/level/translators/chunk/java/java_1_18_translator.py +40 -40
  178. amulet/level/translators/chunk/java/java_blockstate_translator.py +94 -94
  179. amulet/level/translators/chunk/java/java_numerical_translator.py +62 -62
  180. amulet/libs/leveldb/__init__.py +7 -7
  181. amulet/operations/__init__.py +5 -5
  182. amulet/operations/clone.py +18 -18
  183. amulet/operations/delete_chunk.py +32 -32
  184. amulet/operations/fill.py +30 -30
  185. amulet/operations/paste.py +65 -65
  186. amulet/operations/replace.py +58 -58
  187. amulet/utils/__init__.py +14 -14
  188. amulet/utils/format_utils.py +41 -41
  189. amulet/utils/generator.py +15 -15
  190. amulet/utils/matrix.py +243 -243
  191. amulet/utils/numpy_helpers.py +46 -46
  192. amulet/utils/world_utils.py +349 -349
  193. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/METADATA +97 -97
  194. amulet_core-1.9.20.dist-info/RECORD +208 -0
  195. amulet_core-1.9.19.dist-info/RECORD +0 -208
  196. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/WHEEL +0 -0
  197. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/entry_points.txt +0 -0
  198. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/top_level.txt +0 -0
@@ -1,32 +1,32 @@
1
- from amulet.api.selection import SelectionGroup
2
- from amulet.api.data_types import Dimension
3
- from amulet.api.chunk import Chunk
4
- from typing import TYPE_CHECKING
5
-
6
- if TYPE_CHECKING:
7
- from amulet.api.level import BaseLevel
8
-
9
-
10
- def delete_chunk(
11
- world: "BaseLevel",
12
- dimension: Dimension,
13
- source_box: SelectionGroup,
14
- load_original: bool = True,
15
- ):
16
- chunks = [
17
- (cx, cz)
18
- for (cx, cz) in source_box.chunk_locations()
19
- if world.has_chunk(cx, cz, dimension)
20
- ]
21
- iter_count = len(chunks)
22
- for count, (cx, cz) in enumerate(chunks):
23
- world.delete_chunk(cx, cz, dimension)
24
-
25
- if not load_original:
26
- # this part is kind of hacky.
27
- # Work out a propery API to do this.
28
- key = dimension, cx, cz
29
- if key not in world.chunks._history_database:
30
- world.chunks._register_original_entry(key, Chunk(cx, cz))
31
-
32
- yield (count + 1) / iter_count
1
+ from amulet.api.selection import SelectionGroup
2
+ from amulet.api.data_types import Dimension
3
+ from amulet.api.chunk import Chunk
4
+ from typing import TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from amulet.api.level import BaseLevel
8
+
9
+
10
+ def delete_chunk(
11
+ world: "BaseLevel",
12
+ dimension: Dimension,
13
+ source_box: SelectionGroup,
14
+ load_original: bool = True,
15
+ ):
16
+ chunks = [
17
+ (cx, cz)
18
+ for (cx, cz) in source_box.chunk_locations()
19
+ if world.has_chunk(cx, cz, dimension)
20
+ ]
21
+ iter_count = len(chunks)
22
+ for count, (cx, cz) in enumerate(chunks):
23
+ world.delete_chunk(cx, cz, dimension)
24
+
25
+ if not load_original:
26
+ # this part is kind of hacky.
27
+ # Work out a propery API to do this.
28
+ key = dimension, cx, cz
29
+ if key not in world.chunks._history_database:
30
+ world.chunks._register_original_entry(key, Chunk(cx, cz))
31
+
32
+ yield (count + 1) / iter_count
amulet/operations/fill.py CHANGED
@@ -1,30 +1,30 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
-
5
- from amulet.api.selection import SelectionGroup
6
- from amulet.api.block import Block
7
- from amulet.api.data_types import Dimension, OperationReturnType
8
-
9
- if TYPE_CHECKING:
10
- from amulet.api.level import BaseLevel
11
-
12
-
13
- def fill(
14
- world: "BaseLevel",
15
- dimension: Dimension,
16
- target_box: SelectionGroup,
17
- fill_block: Block,
18
- ) -> OperationReturnType:
19
- if not isinstance(fill_block, Block):
20
- raise Exception("Fill operation was not given a Block object")
21
- internal_id = world.block_palette.get_add_block(fill_block)
22
-
23
- iter_count = len(list(world.get_coord_box(dimension, target_box, True)))
24
- count = 0
25
-
26
- for chunk, slices, _ in world.get_chunk_slice_box(dimension, target_box, True):
27
- chunk.blocks[slices] = internal_id
28
- chunk.changed = True
29
- count += 1
30
- yield count / iter_count
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from amulet.api.selection import SelectionGroup
6
+ from amulet.api.block import Block
7
+ from amulet.api.data_types import Dimension, OperationReturnType
8
+
9
+ if TYPE_CHECKING:
10
+ from amulet.api.level import BaseLevel
11
+
12
+
13
+ def fill(
14
+ world: "BaseLevel",
15
+ dimension: Dimension,
16
+ target_box: SelectionGroup,
17
+ fill_block: Block,
18
+ ) -> OperationReturnType:
19
+ if not isinstance(fill_block, Block):
20
+ raise Exception("Fill operation was not given a Block object")
21
+ internal_id = world.block_palette.get_add_block(fill_block)
22
+
23
+ iter_count = len(list(world.get_coord_box(dimension, target_box, True)))
24
+ count = 0
25
+
26
+ for chunk, slices, _ in world.get_chunk_slice_box(dimension, target_box, True):
27
+ chunk.blocks[slices] = internal_id
28
+ chunk.changed = True
29
+ count += 1
30
+ yield count / iter_count
@@ -1,65 +1,65 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
-
5
- from amulet.api.data_types import Dimension, BlockCoordinates, FloatTriplet
6
- from amulet.api.block import Block, UniversalAirLikeBlocks
7
-
8
- if TYPE_CHECKING:
9
- from amulet.api.level import BaseLevel
10
-
11
-
12
- def paste(
13
- dst: "BaseLevel",
14
- dst_dimension: Dimension,
15
- src: "BaseLevel",
16
- src_dimension: Dimension,
17
- location: BlockCoordinates,
18
- scale: FloatTriplet,
19
- rotation: FloatTriplet,
20
- copy_air=True,
21
- copy_water=True,
22
- copy_lava=True,
23
- ):
24
- for _ in paste_iter(
25
- dst,
26
- dst_dimension,
27
- src,
28
- src_dimension,
29
- location,
30
- scale,
31
- rotation,
32
- copy_air,
33
- copy_water,
34
- copy_lava,
35
- ):
36
- pass
37
-
38
-
39
- def paste_iter(
40
- dst: "BaseLevel",
41
- dst_dimension: Dimension,
42
- src: "BaseLevel",
43
- src_dimension: Dimension,
44
- location: BlockCoordinates,
45
- scale: FloatTriplet,
46
- rotation: FloatTriplet,
47
- copy_air=True,
48
- copy_water=True,
49
- copy_lava=True,
50
- ):
51
- yield from dst.paste_iter(
52
- src,
53
- src_dimension,
54
- src.bounds(src_dimension),
55
- dst_dimension,
56
- location,
57
- scale,
58
- rotation,
59
- True,
60
- True,
61
- tuple(UniversalAirLikeBlocks) * bool(not copy_air)
62
- + (Block("universal_minecraft", "water"),) * bool(not copy_water)
63
- + (Block("universal_minecraft", "lava"),) * bool(not copy_lava),
64
- True,
65
- )
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from amulet.api.data_types import Dimension, BlockCoordinates, FloatTriplet
6
+ from amulet.api.block import Block, UniversalAirLikeBlocks
7
+
8
+ if TYPE_CHECKING:
9
+ from amulet.api.level import BaseLevel
10
+
11
+
12
+ def paste(
13
+ dst: "BaseLevel",
14
+ dst_dimension: Dimension,
15
+ src: "BaseLevel",
16
+ src_dimension: Dimension,
17
+ location: BlockCoordinates,
18
+ scale: FloatTriplet,
19
+ rotation: FloatTriplet,
20
+ copy_air=True,
21
+ copy_water=True,
22
+ copy_lava=True,
23
+ ):
24
+ for _ in paste_iter(
25
+ dst,
26
+ dst_dimension,
27
+ src,
28
+ src_dimension,
29
+ location,
30
+ scale,
31
+ rotation,
32
+ copy_air,
33
+ copy_water,
34
+ copy_lava,
35
+ ):
36
+ pass
37
+
38
+
39
+ def paste_iter(
40
+ dst: "BaseLevel",
41
+ dst_dimension: Dimension,
42
+ src: "BaseLevel",
43
+ src_dimension: Dimension,
44
+ location: BlockCoordinates,
45
+ scale: FloatTriplet,
46
+ rotation: FloatTriplet,
47
+ copy_air=True,
48
+ copy_water=True,
49
+ copy_lava=True,
50
+ ):
51
+ yield from dst.paste_iter(
52
+ src,
53
+ src_dimension,
54
+ src.bounds(src_dimension),
55
+ dst_dimension,
56
+ location,
57
+ scale,
58
+ rotation,
59
+ True,
60
+ True,
61
+ tuple(UniversalAirLikeBlocks) * bool(not copy_air)
62
+ + (Block("universal_minecraft", "water"),) * bool(not copy_water)
63
+ + (Block("universal_minecraft", "lava"),) * bool(not copy_lava),
64
+ True,
65
+ )
@@ -1,58 +1,58 @@
1
- from __future__ import annotations
2
-
3
- from typing import List, TYPE_CHECKING
4
- import logging
5
-
6
- from amulet.api.selection import SelectionGroup
7
- from amulet.api.block import Block
8
- from amulet.api.data_types import Dimension
9
-
10
- if TYPE_CHECKING:
11
- from amulet.api.level import BaseLevel
12
-
13
- log = logging.getLogger(__name__)
14
-
15
-
16
- def replace(
17
- world: "BaseLevel", dimension: Dimension, selection: SelectionGroup, options: dict
18
- ):
19
- original_blocks = options.get("original_blocks", None)
20
- if not isinstance(original_blocks, list) and all(
21
- isinstance(block, Block) for block in original_blocks
22
- ):
23
- log.error("Replace operation was not given a list of source Block objects")
24
- return
25
-
26
- replacement_blocks = options.get("replacement_blocks", None)
27
- if not isinstance(replacement_blocks, list) and all(
28
- isinstance(block, Block) for block in replacement_blocks
29
- ):
30
- log.error("Replace operation was not given a list of destination Block objects")
31
- return
32
- original_blocks: List[Block]
33
- replacement_blocks: List[Block]
34
-
35
- if len(original_blocks) != len(replacement_blocks):
36
- if len(replacement_blocks) == 1:
37
- replacement_blocks = replacement_blocks * len(original_blocks)
38
- else:
39
- log.error(
40
- "Replace operation must be given the same number of destination blocks as source blocks"
41
- )
42
-
43
- original_internal_ids = list(
44
- map(world.block_palette.get_add_block, original_blocks)
45
- )
46
- replacement_internal_ids = list(
47
- map(world.block_palette.get_add_block, replacement_blocks)
48
- )
49
-
50
- for chunk, slices, _ in world.get_chunk_slice_box(dimension, selection):
51
- old_blocks = chunk.blocks[slices]
52
- new_blocks = old_blocks.copy()
53
- for original_id, replacement_id in zip(
54
- original_internal_ids, replacement_internal_ids
55
- ):
56
- new_blocks[old_blocks == original_id] = replacement_id
57
- chunk.blocks[slices] = new_blocks
58
- chunk.changed = True
1
+ from __future__ import annotations
2
+
3
+ from typing import List, TYPE_CHECKING
4
+ import logging
5
+
6
+ from amulet.api.selection import SelectionGroup
7
+ from amulet.api.block import Block
8
+ from amulet.api.data_types import Dimension
9
+
10
+ if TYPE_CHECKING:
11
+ from amulet.api.level import BaseLevel
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+
16
+ def replace(
17
+ world: "BaseLevel", dimension: Dimension, selection: SelectionGroup, options: dict
18
+ ):
19
+ original_blocks = options.get("original_blocks", None)
20
+ if not isinstance(original_blocks, list) and all(
21
+ isinstance(block, Block) for block in original_blocks
22
+ ):
23
+ log.error("Replace operation was not given a list of source Block objects")
24
+ return
25
+
26
+ replacement_blocks = options.get("replacement_blocks", None)
27
+ if not isinstance(replacement_blocks, list) and all(
28
+ isinstance(block, Block) for block in replacement_blocks
29
+ ):
30
+ log.error("Replace operation was not given a list of destination Block objects")
31
+ return
32
+ original_blocks: List[Block]
33
+ replacement_blocks: List[Block]
34
+
35
+ if len(original_blocks) != len(replacement_blocks):
36
+ if len(replacement_blocks) == 1:
37
+ replacement_blocks = replacement_blocks * len(original_blocks)
38
+ else:
39
+ log.error(
40
+ "Replace operation must be given the same number of destination blocks as source blocks"
41
+ )
42
+
43
+ original_internal_ids = list(
44
+ map(world.block_palette.get_add_block, original_blocks)
45
+ )
46
+ replacement_internal_ids = list(
47
+ map(world.block_palette.get_add_block, replacement_blocks)
48
+ )
49
+
50
+ for chunk, slices, _ in world.get_chunk_slice_box(dimension, selection):
51
+ old_blocks = chunk.blocks[slices]
52
+ new_blocks = old_blocks.copy()
53
+ for original_id, replacement_id in zip(
54
+ original_internal_ids, replacement_internal_ids
55
+ ):
56
+ new_blocks[old_blocks == original_id] = replacement_id
57
+ chunk.blocks[slices] = new_blocks
58
+ chunk.changed = True
amulet/utils/__init__.py CHANGED
@@ -1,14 +1,14 @@
1
- from .world_utils import (
2
- SECTOR_BYTES,
3
- SECTOR_INTS,
4
- CHUNK_HEADER_SIZE,
5
- VERSION_GZIP,
6
- VERSION_DEFLATE,
7
- block_coords_to_chunk_coords,
8
- chunk_coords_to_region_coords,
9
- region_coords_to_chunk_coords,
10
- blocks_slice_to_chunk_slice,
11
- gunzip,
12
- from_nibble_array,
13
- )
14
- from .format_utils import *
1
+ from .world_utils import (
2
+ SECTOR_BYTES,
3
+ SECTOR_INTS,
4
+ CHUNK_HEADER_SIZE,
5
+ VERSION_GZIP,
6
+ VERSION_DEFLATE,
7
+ block_coords_to_chunk_coords,
8
+ chunk_coords_to_region_coords,
9
+ region_coords_to_chunk_coords,
10
+ blocks_slice_to_chunk_slice,
11
+ gunzip,
12
+ from_nibble_array,
13
+ )
14
+ from .format_utils import *
@@ -1,41 +1,41 @@
1
- from __future__ import annotations
2
-
3
- import os
4
- import warnings
5
-
6
- from amulet_nbt import load as load_nbt, NamedTag
7
-
8
-
9
- def check_all_exist(in_dir: str, *args: str) -> bool:
10
- """
11
- Check that all files exist in a parent directory
12
-
13
- :param in_dir: The parent directory
14
- :param args: file or folder names to look for
15
- :return: Boolean value indicating whether all were found
16
- """
17
-
18
- return all(os.path.exists(os.path.join(in_dir, child)) for child in args)
19
-
20
-
21
- def check_one_exists(in_dir: str, *args: str) -> bool:
22
- """
23
- Check that at least one file exists in a parent directory
24
-
25
- :param in_dir: The parent directory
26
- :param args: file or folder names to look for
27
- :return: Boolean value indicating whether at least one was found
28
- """
29
-
30
- return any(os.path.exists(os.path.join(in_dir, child)) for child in args)
31
-
32
-
33
- def load_leveldat(in_dir: str) -> NamedTag:
34
- """
35
- Load the root tag of the level.dat file in the directory
36
-
37
- :param in_dir: The world directory containing the level.dat file
38
- :return: The NBT root tag
39
- """
40
- warnings.warn("load_leveldat is depreciated.", DeprecationWarning)
41
- return load_nbt(os.path.join(in_dir, "level.dat"))
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import warnings
5
+
6
+ from amulet_nbt import load as load_nbt, NamedTag
7
+
8
+
9
+ def check_all_exist(in_dir: str, *args: str) -> bool:
10
+ """
11
+ Check that all files exist in a parent directory
12
+
13
+ :param in_dir: The parent directory
14
+ :param args: file or folder names to look for
15
+ :return: Boolean value indicating whether all were found
16
+ """
17
+
18
+ return all(os.path.exists(os.path.join(in_dir, child)) for child in args)
19
+
20
+
21
+ def check_one_exists(in_dir: str, *args: str) -> bool:
22
+ """
23
+ Check that at least one file exists in a parent directory
24
+
25
+ :param in_dir: The parent directory
26
+ :param args: file or folder names to look for
27
+ :return: Boolean value indicating whether at least one was found
28
+ """
29
+
30
+ return any(os.path.exists(os.path.join(in_dir, child)) for child in args)
31
+
32
+
33
+ def load_leveldat(in_dir: str) -> NamedTag:
34
+ """
35
+ Load the root tag of the level.dat file in the directory
36
+
37
+ :param in_dir: The world directory containing the level.dat file
38
+ :return: The NBT root tag
39
+ """
40
+ warnings.warn("load_leveldat is depreciated.", DeprecationWarning)
41
+ return load_nbt(os.path.join(in_dir, "level.dat"))
amulet/utils/generator.py CHANGED
@@ -1,15 +1,15 @@
1
- from typing import Generator
2
-
3
-
4
- def generator_unpacker(gen: Generator):
5
- """
6
- Unpack a generator and return the value returned by the generator.
7
-
8
- :param gen: The generator to unpack.
9
- :return: The value that was returned by the generator.
10
- """
11
- try:
12
- while True:
13
- next(gen)
14
- except StopIteration as e:
15
- return e.value
1
+ from typing import Generator
2
+
3
+
4
+ def generator_unpacker(gen: Generator):
5
+ """
6
+ Unpack a generator and return the value returned by the generator.
7
+
8
+ :param gen: The generator to unpack.
9
+ :return: The value that was returned by the generator.
10
+ """
11
+ try:
12
+ while True:
13
+ next(gen)
14
+ except StopIteration as e:
15
+ return e.value