pylitematic 0.0.2__py3-none-any.whl → 0.0.4__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.
pylitematic/schematic.py CHANGED
@@ -8,8 +8,8 @@ import time
8
8
  import twos
9
9
  from typing import Iterator
10
10
 
11
- from .geometry import BlockPosition, Size3D
12
- from .region import Region
11
+ from pylitematic.geometry import BlockPosition, Size3D
12
+ from pylitematic.region import Region
13
13
 
14
14
 
15
15
  DEFAULT_VERSION_MAJOR: int = 7
@@ -70,6 +70,7 @@ class Schematic:
70
70
  self._created_at = round(time.time() * 1000)
71
71
  self._modified_at = self._created_at
72
72
 
73
+ # TODO: use packaging.version.Version
73
74
  self.version_major = version_major
74
75
  self.version_minor = version_minor
75
76
  self.mc_version = mc_version
@@ -104,10 +105,11 @@ class Schematic:
104
105
 
105
106
  @property
106
107
  def bounds(self) -> tuple[BlockPosition, BlockPosition]:
108
+ # TODO: make cached and update on region add / remove
107
109
  lowers = []
108
110
  uppers = []
109
111
  for reg in self._regions.values():
110
- lower, upper = reg.global_bounds
112
+ lower, upper = reg.world.bounds
111
113
  lowers.append(lower)
112
114
  uppers.append(upper)
113
115
  return (
@@ -142,10 +144,11 @@ class Schematic:
142
144
 
143
145
  def add_region(self, name: str, region: Region) -> None:
144
146
  self._regions[name] = region
145
- self._update()
147
+ # TODO: re-calculate bounding box
146
148
 
147
149
  def remove_region(self, name: str) -> Region:
148
150
  return self._regions.pop(name)
151
+ # TODO: re-calculate bounding box
149
152
 
150
153
  @property
151
154
  def created_at(self) -> datetime:
@@ -159,15 +162,14 @@ class Schematic:
159
162
  file = nbtlib.File(self.to_nbt())
160
163
  file.save(path, gzipped=True, byteorder="big")
161
164
 
162
- @staticmethod
163
- def load(path: pathlib.Path | str) -> Schematic:
165
+ @classmethod
166
+ def load(cls, path: pathlib.Path | str) -> Schematic:
164
167
  if isinstance(path, str):
165
168
  path = pathlib.Path(path)
166
169
  nbt = nbtlib.File.load(path.expanduser(), True)
167
- return Schematic.from_nbt(nbt)
170
+ return cls.from_nbt(nbt)
168
171
 
169
172
  def to_nbt(self) -> nbtlib.Compound:
170
- # self._update()
171
173
  nbt = nbtlib.Compound()
172
174
 
173
175
  # meta data
@@ -203,8 +205,8 @@ class Schematic:
203
205
 
204
206
  return nbt
205
207
 
206
- @staticmethod
207
- def from_nbt(nbt: nbtlib.Compound) -> Schematic:
208
+ @classmethod
209
+ def from_nbt(cls, nbt: nbtlib.Compound) -> Schematic:
208
210
  # meta data
209
211
  try:
210
212
  meta = nbt["Metadata"]
@@ -214,7 +216,10 @@ class Schematic:
214
216
 
215
217
  name = meta["Name"].unpack()
216
218
  author = meta["Author"].unpack()
217
- description = meta["Description"].unpack()
219
+ try:
220
+ desc = meta["Description"].unpack()
221
+ except KeyError:
222
+ desc = ""
218
223
 
219
224
  preview = meta.get("PreviewImageData")
220
225
  if preview is not None:
@@ -245,10 +250,10 @@ class Schematic:
245
250
 
246
251
  mc_version = nbt.get("MinecraftDataVersion")
247
252
 
248
- schem = Schematic(
253
+ schem = cls(
249
254
  name=name,
250
255
  author=author,
251
- description=description,
256
+ description=desc,
252
257
  regions=regions,
253
258
  preview=preview,
254
259
  version_major=major,
pylitematic/test.py CHANGED
@@ -1,39 +1,72 @@
1
1
  import numpy as np
2
2
  import pathlib
3
- from pylitematic import BlockPosition, BlockState, ResourceLocation, Schematic
3
+ from pylitematic import BlockPosition, BlockId, BlockState, Region, Schematic, Size3D
4
4
 
5
- path = pathlib.Path("/mnt/d/minecraft/schematics/Litematica/test/subs.litematic")
6
- path = pathlib.Path("/mnt/d/minecraft/schematics/Litematica/test/creeper_test.litematic")
7
- path = pathlib.Path("/mnt/d/minecraft/schematics/Litematica/test/regions.litematic")
8
- stone = BlockState.from_string("minecraft:stone")
9
- dirt = BlockState.from_string("minecraft:dirt")
10
- s = Schematic.load(path)
11
- print(f"{s.volume=} {s.size=} {s.bounds=}")
12
- for name, reg in s.regions():
13
- print(name)
14
- print(f"\t{reg.shape=} {reg.volume=} {reg.block_count=}")
15
- print(f"\t{reg.origin=!s} {reg.limit=!s}")
16
- print(f"\t{reg.start=!s} {reg.end=!s}")
17
- print(f"\t{reg.lower=!s} {reg.upper=!s} {reg.size=}")
18
- # print(f"\t{reg[..., 1, 0]}")
19
- # print(f"\t{reg[:][1][0]}")
20
- # print(f"\t{reg[BlockPosition(0, 1, 0)]}")
21
- # reg[1,1,1] = BlockState.from_string("minecraft:stone")
22
- # print("lol: ", reg[reg.end])
23
- reg[0,:,0] = BlockState("minecraft:obsidian")
24
- reg[0,:,0] = [dirt, stone, dirt]
25
- # print(reg[...,0])
26
- # print(reg[np.array([BlockPosition(0, 0, 0), BlockPosition(1, 1, 1)])])
27
- # print(f"\t{reg[:]}")
28
- # for pos, state in reg.blocks(exclude_air=True):
29
- # print(pos, state)
30
- # for pos, state in reg.blocks((BlockState("oak_log", axis="x"), BlockState("spruce_log", axis="z")), ignore_props=True):
31
- for pos, state in reg.blocks(exclude=BlockState("air")):
32
- print(pos, reg._to_internal(pos), state)
33
- for pos, state in reg.blocks(include=BlockState("air")):
34
- reg[pos] = BlockState("minecraft:netherrack")
35
- print(BlockState("oak_log", axis="x") in reg)
36
- print(BlockPosition(1, 1, 0) in reg)
37
- print(ResourceLocation("birch_log") in reg)
38
- # print(reg[0,:,2])
39
- s.save("/mnt/d/minecraft/schematics/Litematica/test/aaa.litematic")
5
+ # path = pathlib.Path("/mnt/d/minecraft/schematics/Litematica/test/subs.litematic")
6
+ # path = pathlib.Path("/mnt/d/minecraft/schematics/Litematica/test/regions.litematic")
7
+ # path = pathlib.Path("/mnt/d/minecraft/schematics/Litematica/test/creeper_test.litematic")
8
+ # stone = BlockState.from_string("minecraft:stone")
9
+ # dirt = BlockState.from_string("minecraft:dirt")
10
+ # s = Schematic.load(path)
11
+ # print(f"{s.volume=} {s.size=} {s.bounds=}")
12
+ # for name, reg in s.regions():
13
+ # print(name)
14
+ # print(f"\t{reg.shape=} {reg.volume=} {reg.block_count=}")
15
+ # print(f"\t{reg.origin=!s} {reg.limit=!s}")
16
+ # print(f"\t{reg.start=!s} {reg.end=!s}")
17
+ # print(f"\t{reg.lower=!s} {reg.upper=!s} {reg.size=}")
18
+ # # print(f"\t{reg[..., 1, 0]}")
19
+ # # print(f"\t{reg[:][1][0]}")
20
+ # # print(f"\t{reg[BlockPosition(0, 1, 0)]}")
21
+ # # reg[1,1,1] = BlockState.from_string("minecraft:stone")
22
+ # # print("lol: ", reg[reg.end])
23
+ # # reg[0,:,0] = BlockState("minecraft:obsidian")
24
+ # # reg[0,:,0] = [dirt, stone, dirt]
25
+ # # print(reg[...,0])
26
+ # # print(reg[np.array([BlockPosition(0, 0, 0), BlockPosition(1, 1, 1)])])
27
+ # # print(f"\t{reg[:]}")
28
+ # # for pos, state in reg.blocks(exclude_air=True):
29
+ # # print(pos, state)
30
+ # # for pos, state in reg.blocks((BlockState("oak_log", axis="x"), BlockState("spruce_log", axis="z")), ignore_props=True):
31
+ # # reg[...,-1] = stone
32
+ # for pos, state in reg.blocks(exclude=BlockState("air")):
33
+ # print(f"\t{pos} {reg._to_internal(pos)}: {state}")
34
+ # for pos, state in reg.blocks(include=BlockState("lime_wool")):
35
+ # reg[pos] = BlockState("minecraft:blue_wool")
36
+ # for pos, state in reg.blocks(include=BlockState("tripwire"), ignore_props=True):
37
+ # reg[pos] = BlockState("minecraft:glass")
38
+ # # print(BlockState("oak_log", axis="x") in reg)
39
+ # # print(BlockPosition(1, 1, 0) in reg)
40
+ # # print(ResourceLocation("birch_log") in reg)
41
+ # # print(reg[0,:,2])
42
+ # s.save("/mnt/d/minecraft/schematics/Litematica/test/aaa.litematic")
43
+
44
+ air = BlockState("air")
45
+ stone = BlockState("stone")
46
+ dirt = BlockState("dirt")
47
+ grass = BlockState("grass_block")
48
+ cobble = BlockState("cobblestone")
49
+ mossy_cobble = BlockState("mossy_cobblestone")
50
+ snow = BlockState("snow_block")
51
+ pumpkin = BlockState("carved_pumpkin", facing="west")
52
+
53
+ ground = Region(size=Size3D(16, 9, 16), origin=BlockPosition(0, 0, 0))
54
+ ground.local[:,:5,:] = stone
55
+ ground.local[:,5:8,:] = dirt
56
+ ground.local[:,8:,:] = grass
57
+
58
+ boulder = Region(size=(4, 4, 4), origin=ground.origin+[6, ground.height, 6])
59
+ boulder[:] = mossy_cobble
60
+ boulder.numpy[:,-2:,:] = cobble
61
+
62
+ # snow_man = Region(size=(1, 3, 1), origin=boulder.origin+[1, boulder.height, 1])
63
+ snow_man = Region(size=(1, -3, 1), origin=boulder.origin+[1, boulder.upper.y+3, 1])
64
+ snow_man[...] = snow
65
+ # snow_man.numpy[:,:2,:] = [[[snow], [snow]]]
66
+ snow_man[0,snow_man.upper.y,0] = pumpkin
67
+
68
+ schem = Schematic(name="a_scene", author="Boscawinks", description="A simple scene")
69
+ schem.add_region("ground", ground)
70
+ schem.add_region("boulder", boulder)
71
+ schem.add_region("snow_man", snow_man)
72
+ schem.save(f"/mnt/d/minecraft/schematics/Litematica/test/{schem.name}.litematic")
@@ -1,18 +1,24 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pylitematic
3
- Version: 0.0.2
3
+ Version: 0.0.4
4
4
  Summary: Load, modify, and save Litematica schematics
5
5
  Author-email: Boscawinks <bosca.winks@gmx.de>
6
6
  License: GPL-3.0-only
7
7
  Project-URL: Homepage, https://github.com/boscawinks/pylitematic
8
8
  Project-URL: Repository, https://github.com/boscawinks/pylitematic
9
9
  Project-URL: Issues, https://github.com/boscawinks/pylitematic/issues
10
+ Classifier: Development Status :: 2 - Pre-Alpha
10
11
  Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Topic :: Utilities
11
14
  Requires-Python: >=3.10.12
12
15
  Description-Content-Type: text/markdown
13
16
  Requires-Dist: bitpacking>=0.1.0
14
17
  Requires-Dist: nbtlib>=2.0.4
15
18
  Requires-Dist: numpy>=2.2.6
19
+ Requires-Dist: twos>=0.0.1
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest; extra == "dev"
16
22
 
17
23
  # pylitematic
18
24
 
@@ -0,0 +1,12 @@
1
+ pylitematic/__init__.py,sha256=Cu9tl3jcE6c1VPcMFkrNq5ddWhGZFd7OT_lhItHBdsI,213
2
+ pylitematic/block_property.py,sha256=HGxDSngEr-tcwuZPGn6ohHQQ65OL4MaTP9ytDAvuSCw,7714
3
+ pylitematic/block_state.py,sha256=PuwE3b7zf8Gw-wV3DOXYYwfvLrUJmkj0H_XC7yGMKdw,3540
4
+ pylitematic/geometry.py,sha256=x_rjJ0gO7uhUJqEg9es8nzD-p3rCiSM9vpdwF7JukAM,4194
5
+ pylitematic/region.py,sha256=iMX95qkd-OAWP8GUyi-_DBYgtphy8djgLb5lRR_Ssu8,15150
6
+ pylitematic/resource_location.py,sha256=bqw3Oh9Bx-oWZdm-Qj_FoqpNOh3gc6DPvKqCm6DIDSo,2168
7
+ pylitematic/schematic.py,sha256=nKH5EjU2ZvuJzjyO84kmKrcKI0jqmNfzq1UXNIroKYQ,8090
8
+ pylitematic/test.py,sha256=weexc1mKqC7f2Uayd3KuXLsXBOvMCmLGqZrekyeVEiI,3284
9
+ pylitematic-0.0.4.dist-info/METADATA,sha256=pKIVzFpc22EELK8IyPmlM2UB5999l_SGozXuZucRRDQ,1159
10
+ pylitematic-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ pylitematic-0.0.4.dist-info/top_level.txt,sha256=sYUxm6O7Dh5TzuP-kPFe2FHJWUuwHFO69vN2VBiEG4A,12
12
+ pylitematic-0.0.4.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- pylitematic/__init__.py,sha256=ycco-z7gJlUnBUJuJRo9qzu5pSzXSZLPkqOVLy8OsEI,211
2
- pylitematic/block_property.py,sha256=eV9YbMcuttX-WPdbqN6dMmhb4jK_8_zRv33wNaVd8_o,9887
3
- pylitematic/block_state.py,sha256=hC8ptOTR6XKokn-m2Nlxpi44AvL-vwlgive3KQ4VtUg,3328
4
- pylitematic/geometry.py,sha256=n4Kk413FFhWHFgRRRQCYB2UdDBnbUMqwCEBP85YK1vI,5009
5
- pylitematic/region.py,sha256=15elHo9Li_nw7_VeM9GP92mcK0cYuJtONKnDyj_SnxY,10918
6
- pylitematic/resource_location.py,sha256=kVv9-4WVu_Ak24Um05bucKG-mcXymnylwHMha-ORLoo,2143
7
- pylitematic/schematic.py,sha256=Zc85oT6jdHVdQtAgcZbj9qFXXXWow1GfKXc1TV10CqQ,7879
8
- pylitematic/test.py,sha256=6IrD4t3f7puWIkgsZVfy-epDgKWFQIOGMizQFF7O7u0,1886
9
- pylitematic-0.0.2.dist-info/METADATA,sha256=f0AzgTmhaCPTVVjpnoovf_q_2vG9x_KToOT4kh7bQDM,948
10
- pylitematic-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- pylitematic-0.0.2.dist-info/top_level.txt,sha256=sYUxm6O7Dh5TzuP-kPFe2FHJWUuwHFO69vN2VBiEG4A,12
12
- pylitematic-0.0.2.dist-info/RECORD,,