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.
Files changed (22) hide show
  1. {pylitematic-0.0.3 → pylitematic-0.0.4}/PKG-INFO +4 -1
  2. {pylitematic-0.0.3 → pylitematic-0.0.4}/pyproject.toml +4 -1
  3. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/__init__.py +2 -2
  4. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/block_property.py +13 -13
  5. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/block_state.py +8 -8
  6. pylitematic-0.0.4/src/pylitematic/geometry.py +171 -0
  7. pylitematic-0.0.4/src/pylitematic/region.py +485 -0
  8. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/resource_location.py +6 -6
  9. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/schematic.py +11 -8
  10. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic/test.py +11 -10
  11. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/PKG-INFO +4 -1
  12. {pylitematic-0.0.3 → pylitematic-0.0.4}/tests/test_schematic.py +2 -2
  13. pylitematic-0.0.3/src/pylitematic/geometry.py +0 -207
  14. pylitematic-0.0.3/src/pylitematic/region.py +0 -335
  15. {pylitematic-0.0.3 → pylitematic-0.0.4}/README.md +0 -0
  16. {pylitematic-0.0.3 → pylitematic-0.0.4}/setup.cfg +0 -0
  17. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/SOURCES.txt +0 -0
  18. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/dependency_links.txt +0 -0
  19. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/requires.txt +0 -0
  20. {pylitematic-0.0.3 → pylitematic-0.0.4}/src/pylitematic.egg-info/top_level.txt +0 -0
  21. {pylitematic-0.0.3 → pylitematic-0.0.4}/tests/test_block_property.py +0 -0
  22. {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
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.3"
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.3"
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
- @staticmethod
98
- def from_string(string: str) -> Properties:
97
+ @classmethod
98
+ def from_string(cls, string: str) -> Properties:
99
99
  if string in ("", "[]"):
100
- return Properties()
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 Properties(props)
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
- @staticmethod
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 Properties(props)
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
- @staticmethod
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 PropertyValue.value_factory(value)
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
- @staticmethod
219
- def from_nbt(nbt: nbtlib.String) -> PropertyValue:
220
- return PropertyValue.from_string(str(nbt))
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
- @staticmethod
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 = BlockState(id)
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
- @staticmethod
97
- def from_nbt(nbt: Compound) -> BlockState:
98
- state = BlockState(str(nbt["Name"]))
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 = BlockState(id)
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 = BlockState(self.id)
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))