pylitematic 0.0.3__tar.gz → 0.0.4__tar.gz
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-0.0.3 → pylitematic-0.0.4}/PKG-INFO +4 -1
- {pylitematic-0.0.3 → pylitematic-0.0.4}/pyproject.toml +4 -1
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/__init__.py +2 -2
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/block_property.py +13 -13
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/block_state.py +8 -8
- pylitematic-0.0.4/src/pylitematic/geometry.py +171 -0
- pylitematic-0.0.4/src/pylitematic/region.py +485 -0
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/resource_location.py +6 -6
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/schematic.py +11 -8
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/test.py +11 -10
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/PKG-INFO +4 -1
- {pylitematic-0.0.3 → pylitematic-0.0.4}/tests/test_schematic.py +2 -2
- pylitematic-0.0.3/src/pylitematic/geometry.py +0 -207
- pylitematic-0.0.3/src/pylitematic/region.py +0 -335
- {pylitematic-0.0.3 → pylitematic-0.0.4}/README.md +0 -0
- {pylitematic-0.0.3 → pylitematic-0.0.4}/setup.cfg +0 -0
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/SOURCES.txt +0 -0
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/dependency_links.txt +0 -0
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/requires.txt +0 -0
- {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/top_level.txt +0 -0
- {pylitematic-0.0.3 → pylitematic-0.0.4}/tests/test_block_property.py +0 -0
- {pylitematic-0.0.3 → pylitematic-0.0.4}/tests/test_resource_location.py +0 -0
@@ -1,13 +1,16 @@
|
|
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
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "pylitematic"
|
7
|
-
version = "0.0.
|
7
|
+
version = "0.0.4"
|
8
8
|
description = "Load, modify, and save Litematica schematics"
|
9
9
|
authors = [
|
10
10
|
{ name="Boscawinks", email="bosca.winks@gmx.de" }
|
@@ -19,7 +19,10 @@ readme = "README.md"
|
|
19
19
|
requires-python = ">=3.10.12"
|
20
20
|
license = { text = "GPL-3.0-only" }
|
21
21
|
classifiers = [
|
22
|
+
"Development Status :: 2 - Pre-Alpha",
|
22
23
|
"Programming Language :: Python :: 3",
|
24
|
+
"Operating System :: OS Independent",
|
25
|
+
"Topic :: Utilities"
|
23
26
|
]
|
24
27
|
|
25
28
|
[project.optional-dependencies]
|
@@ -1,7 +1,7 @@
|
|
1
|
-
__version__ = "0.0.
|
1
|
+
__version__ = "0.0.4"
|
2
2
|
|
3
3
|
from .block_state import BlockState
|
4
|
-
from .geometry import BlockPosition, Size3D
|
4
|
+
from .geometry import BlockPosition, Direction, Size3D
|
5
5
|
from .region import Region
|
6
6
|
from .resource_location import BlockId
|
7
7
|
from .schematic import Schematic
|
@@ -94,10 +94,10 @@ class Properties(dict):
|
|
94
94
|
def to_string(self) -> str:
|
95
95
|
return str(self)
|
96
96
|
|
97
|
-
@
|
98
|
-
def from_string(string: str) -> Properties:
|
97
|
+
@classmethod
|
98
|
+
def from_string(cls, string: str) -> Properties:
|
99
99
|
if string in ("", "[]"):
|
100
|
-
return
|
100
|
+
return cls()
|
101
101
|
|
102
102
|
if not (string.startswith("[") and string.endswith("]")):
|
103
103
|
raise ValueError(f"Invalid properties string {string!r}")
|
@@ -113,18 +113,18 @@ class Properties(dict):
|
|
113
113
|
ValueError(f"Duplicate property name {name!r}")
|
114
114
|
props[name] = PropertyValue.from_string(string=val_str).get()
|
115
115
|
|
116
|
-
return
|
116
|
+
return cls(props)
|
117
117
|
|
118
118
|
def to_nbt(self) -> nbtlib.Compound:
|
119
119
|
return nbtlib.Compound(
|
120
120
|
{name: value.to_nbt() for name, value in sorted(super().items())})
|
121
121
|
|
122
|
-
@
|
123
|
-
def from_nbt(nbt: nbtlib.Compound) -> Properties:
|
122
|
+
@classmethod
|
123
|
+
def from_nbt(cls, nbt: nbtlib.Compound) -> Properties:
|
124
124
|
props = {}
|
125
125
|
for name, value in nbt.items():
|
126
126
|
props[name] = PropertyValue.from_nbt(nbt=value).get()
|
127
|
-
return
|
127
|
+
return cls(props)
|
128
128
|
|
129
129
|
|
130
130
|
class PropertyValue(ABC):
|
@@ -204,20 +204,20 @@ class PropertyValue(ABC):
|
|
204
204
|
def to_string(self) -> str:
|
205
205
|
return str(self)
|
206
206
|
|
207
|
-
@
|
208
|
-
def from_string(string: str) -> PropertyValue:
|
207
|
+
@classmethod
|
208
|
+
def from_string(cls, string: str) -> PropertyValue:
|
209
209
|
try:
|
210
210
|
value = json.loads(string)
|
211
211
|
except json.JSONDecodeError:
|
212
212
|
value = string
|
213
|
-
return
|
213
|
+
return cls.value_factory(value)
|
214
214
|
|
215
215
|
def to_nbt(self) -> nbtlib.String:
|
216
216
|
return nbtlib.String(self)
|
217
217
|
|
218
|
-
@
|
219
|
-
def from_nbt(nbt: nbtlib.String) -> PropertyValue:
|
220
|
-
return
|
218
|
+
@classmethod
|
219
|
+
def from_nbt(cls, nbt: nbtlib.String) -> PropertyValue:
|
220
|
+
return cls.from_string(str(nbt))
|
221
221
|
|
222
222
|
|
223
223
|
class BooleanValue(PropertyValue):
|
@@ -74,15 +74,15 @@ class BlockState:
|
|
74
74
|
def to_string(self) -> str:
|
75
75
|
return str(self)
|
76
76
|
|
77
|
-
@
|
78
|
-
def from_string(string: str) -> BlockState:
|
77
|
+
@classmethod
|
78
|
+
def from_string(cls, string: str) -> BlockState:
|
79
79
|
idx = string.find("[") # basic parsing to separate block:id[name=value]
|
80
80
|
if idx == -1:
|
81
81
|
id, props = string, ""
|
82
82
|
else:
|
83
83
|
id, props = string[:idx], string[idx:]
|
84
84
|
|
85
|
-
state =
|
85
|
+
state = cls(id)
|
86
86
|
state._props = Properties.from_string(props)
|
87
87
|
return state
|
88
88
|
|
@@ -93,19 +93,19 @@ class BlockState:
|
|
93
93
|
nbt["Properties"] = self._props.to_nbt()
|
94
94
|
return nbt
|
95
95
|
|
96
|
-
@
|
97
|
-
def from_nbt(nbt: Compound) -> BlockState:
|
98
|
-
state =
|
96
|
+
@classmethod
|
97
|
+
def from_nbt(cls, nbt: Compound) -> BlockState:
|
98
|
+
state = cls(str(nbt["Name"]))
|
99
99
|
state._props = Properties.from_nbt(nbt.get("Properties", Compound()))
|
100
100
|
return state
|
101
101
|
|
102
102
|
def with_id(self, id: str) -> BlockState:
|
103
|
-
state =
|
103
|
+
state = type(self)(id)
|
104
104
|
state._props = deepcopy(self._props)
|
105
105
|
return state
|
106
106
|
|
107
107
|
def with_props(self, **props: Any) -> BlockState:
|
108
|
-
state =
|
108
|
+
state = type(self)(self.id)
|
109
109
|
new_props = deepcopy(self._props)
|
110
110
|
for name, value in props.items():
|
111
111
|
if value is None:
|
@@ -0,0 +1,171 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from dataclasses import dataclass
|
4
|
+
import enum
|
5
|
+
import nbtlib
|
6
|
+
import numpy as np
|
7
|
+
from typing import Iterator
|
8
|
+
|
9
|
+
|
10
|
+
@dataclass(frozen=True)
|
11
|
+
class Vec3i:
|
12
|
+
_a: int
|
13
|
+
_b: int
|
14
|
+
_c: int
|
15
|
+
|
16
|
+
def __post_init__(self) -> None:
|
17
|
+
object.__setattr__(self, "_a", int(self._a))
|
18
|
+
object.__setattr__(self, "_b", int(self._b))
|
19
|
+
object.__setattr__(self, "_c", int(self._c))
|
20
|
+
|
21
|
+
def __getitem__(self, index: int) -> int:
|
22
|
+
return tuple(self)[index]
|
23
|
+
|
24
|
+
def __str__(self) -> str:
|
25
|
+
return str(list(self))
|
26
|
+
|
27
|
+
def __repr__(self) -> str:
|
28
|
+
return (
|
29
|
+
f"{type(self).__name__}(a={self._a}, b={self._b}, c={self._c})")
|
30
|
+
|
31
|
+
def __len__(self) -> int:
|
32
|
+
return 3
|
33
|
+
|
34
|
+
def __iter__(self) -> Iterator[int]:
|
35
|
+
return iter((self._a, self._b, self._c))
|
36
|
+
|
37
|
+
def __neg__(self) -> Vec3i:
|
38
|
+
return type(self)(*(-i for i in self))
|
39
|
+
|
40
|
+
def __abs__(self) -> Vec3i:
|
41
|
+
return type(self)(*(abs(i) for i in self))
|
42
|
+
|
43
|
+
def __array__(self, dtype: type | None = None, copy: bool = True):
|
44
|
+
arr = np.array(tuple(self), dtype=dtype)
|
45
|
+
return arr.copy() if copy else arr
|
46
|
+
|
47
|
+
def __add__(self, other) -> Vec3i:
|
48
|
+
return type(self)(*(np.array(self) + other))
|
49
|
+
|
50
|
+
def __radd__(self, other) -> Vec3i:
|
51
|
+
return self.__add__(other)
|
52
|
+
|
53
|
+
def __sub__(self, other) -> Vec3i:
|
54
|
+
return self.__add__(-other)
|
55
|
+
|
56
|
+
def __rsub__(self, other) -> Vec3i:
|
57
|
+
return -self.__sub__(other)
|
58
|
+
|
59
|
+
def __mul__(self, other) -> Vec3i:
|
60
|
+
return type(self)(*(np.array(self) * other))
|
61
|
+
|
62
|
+
def __rmul__(self, other) -> Vec3i:
|
63
|
+
return self.__mul__(other)
|
64
|
+
|
65
|
+
def __floordiv__(self, other) -> Vec3i:
|
66
|
+
return type(self)(*(np.array(self) // other))
|
67
|
+
|
68
|
+
def __rfloordiv__(self, other) -> Vec3i:
|
69
|
+
return type(self)(*(other // np.array(self)))
|
70
|
+
|
71
|
+
def __truediv__(self, other) -> Vec3i:
|
72
|
+
return self.__floordiv__(other)
|
73
|
+
|
74
|
+
def __rtruediv__(self, other) -> Vec3i:
|
75
|
+
return self.__rfloordiv__(other)
|
76
|
+
|
77
|
+
def __mod__(self, other) -> Vec3i:
|
78
|
+
return type(self)(*(np.array(self) % other))
|
79
|
+
|
80
|
+
def __rmod__(self, other) -> Vec3i:
|
81
|
+
return type(self)(*(other % np.array(self)))
|
82
|
+
|
83
|
+
def __eq__(self, other):
|
84
|
+
return np.array(self) == other
|
85
|
+
|
86
|
+
def __ne__(self, other):
|
87
|
+
return np.invert(self.__eq__(other))
|
88
|
+
|
89
|
+
def __lt__(self, other):
|
90
|
+
return np.array(self) < other
|
91
|
+
|
92
|
+
def __le__(self, other):
|
93
|
+
return np.array(self) <= other
|
94
|
+
|
95
|
+
def __gt__(self, other):
|
96
|
+
return np.array(self) > other
|
97
|
+
|
98
|
+
def __ge__(self, other):
|
99
|
+
return np.array(self) >= other
|
100
|
+
|
101
|
+
def to_nbt(self) -> nbtlib.Compound:
|
102
|
+
return nbtlib.Compound({
|
103
|
+
"x": nbtlib.Int(self._a),
|
104
|
+
"y": nbtlib.Int(self._b),
|
105
|
+
"z": nbtlib.Int(self._c),
|
106
|
+
})
|
107
|
+
|
108
|
+
@classmethod
|
109
|
+
def from_nbt(cls, nbt: nbtlib.Compound) -> Vec3i:
|
110
|
+
return cls(int(nbt["x"]), int(nbt["y"]), int(nbt["z"]))
|
111
|
+
|
112
|
+
|
113
|
+
@dataclass(frozen=True)
|
114
|
+
class BlockPosition(Vec3i):
|
115
|
+
|
116
|
+
@property
|
117
|
+
def x(self) -> int:
|
118
|
+
return self._a
|
119
|
+
|
120
|
+
@property
|
121
|
+
def y(self) -> int:
|
122
|
+
return self._b
|
123
|
+
|
124
|
+
@property
|
125
|
+
def z(self) -> int:
|
126
|
+
return self._c
|
127
|
+
|
128
|
+
def __repr__(self) -> str:
|
129
|
+
return f"{type(self).__name__}(x={self.x}, y={self.y}, z={self.z})"
|
130
|
+
|
131
|
+
|
132
|
+
class Direction(BlockPosition, enum.Enum):
|
133
|
+
NORTH = 0, 0, -1
|
134
|
+
SOUTH = 0, 0, 1
|
135
|
+
WEST = -1, 0, 0
|
136
|
+
EAST = 1, 0, 0
|
137
|
+
UP = 0, 1, 0
|
138
|
+
DOWN = 0, -1, 0
|
139
|
+
|
140
|
+
|
141
|
+
@dataclass(frozen=True)
|
142
|
+
class Size3D(Vec3i):
|
143
|
+
|
144
|
+
@property
|
145
|
+
def width(self) -> int:
|
146
|
+
return self._a
|
147
|
+
|
148
|
+
@property
|
149
|
+
def height(self) -> int:
|
150
|
+
return self._b
|
151
|
+
|
152
|
+
@property
|
153
|
+
def length(self) -> int:
|
154
|
+
return self._c
|
155
|
+
|
156
|
+
def __repr__(self) -> str:
|
157
|
+
return (
|
158
|
+
f"{type(self).__name__}("
|
159
|
+
f"width={self.width}, height={self.height}, length={self.length})")
|
160
|
+
|
161
|
+
@property
|
162
|
+
def volume(self) -> int:
|
163
|
+
return abs(self.width * self.height * self.length)
|
164
|
+
|
165
|
+
@property
|
166
|
+
def limit(self) -> BlockPosition:
|
167
|
+
return BlockPosition(*(self - self.sign))
|
168
|
+
|
169
|
+
@property
|
170
|
+
def sign(self) -> BlockPosition:
|
171
|
+
return BlockPosition(*np.sign(self))
|