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/__init__.py +3 -3
- pylitematic/block_property.py +13 -79
- pylitematic/block_state.py +20 -13
- pylitematic/geometry.py +70 -92
- pylitematic/region.py +339 -182
- pylitematic/resource_location.py +10 -6
- pylitematic/schematic.py +18 -13
- pylitematic/test.py +69 -36
- {pylitematic-0.0.2.dist-info → pylitematic-0.0.4.dist-info}/METADATA +7 -1
- pylitematic-0.0.4.dist-info/RECORD +12 -0
- pylitematic-0.0.2.dist-info/RECORD +0 -12
- {pylitematic-0.0.2.dist-info → pylitematic-0.0.4.dist-info}/WHEEL +0 -0
- {pylitematic-0.0.2.dist-info → pylitematic-0.0.4.dist-info}/top_level.txt +0 -0
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.
|
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
|
-
|
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
|
-
@
|
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
|
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
|
-
@
|
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
|
-
|
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 =
|
253
|
+
schem = cls(
|
249
254
|
name=name,
|
250
255
|
author=author,
|
251
|
-
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,
|
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/
|
7
|
-
path = pathlib.Path("/mnt/d/minecraft/schematics/Litematica/test/
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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.
|
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,,
|
File without changes
|
File without changes
|