rwmap 2.0.0__tar.gz → 3.1.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rwmap
3
- Version: 2.0.0
3
+ Version: 3.1.4
4
4
  Summary: 一个精简的铁锈战争TMX地图操作工具
5
5
  Author: KEND
6
6
  License-Expression: GPL-3.0-or-later
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "rwmap"
7
- version = "2.0.0"
7
+ version = "3.1.4"
8
8
  description = "一个精简的铁锈战争TMX地图操作工具"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -5,16 +5,8 @@ from .properties import Property
5
5
  from .tiles import Tile, Tileset
6
6
  from .templates import Template, template
7
7
 
8
- from .rw import *
9
-
10
8
 
11
9
  __all__ = [
12
10
  "Property", "Shape", "Object", "ObjectGroup", "Layer", "Tile", "Tileset", "Map",
13
11
  "Template", "template",
14
- "unit", "UnitSpec",
15
- "Trigger", "TriggerLayer", "RwMap",
16
- "map_info", "team_info", "unit_detect", "unit_add", "unit_remove",
17
- "map_text", "point", "move", "rotate", "change_credits",
18
- "basic", "objective", "camera_start", "fall", "set_team", "ai_allow_full_use",
19
- "unit_info",
20
12
  ]
@@ -36,6 +36,9 @@ class Layer:
36
36
  self.properties = properties or []
37
37
  self.data = data[:] if data is not None else [0] * (width * height)
38
38
 
39
+ def property(self, name: str) -> Property | None:
40
+ return next((prop for prop in self.properties if prop.name == name), None)
41
+
39
42
  def get_tile(self, key: Tuple[int, int]) -> int:
40
43
  x, y = key
41
44
  if not (0 <= x < self.width and 0 <= y < self.height):
@@ -1,5 +1,5 @@
1
1
  import xml.etree.ElementTree as ET
2
- from typing import List, Dict, Optional
2
+ from typing import List, Optional
3
3
  import os
4
4
 
5
5
  from .properties import Property
@@ -8,6 +8,7 @@ from .objects import ObjectGroup
8
8
  from .layers import Layer
9
9
 
10
10
 
11
+
11
12
  class Map:
12
13
 
13
14
  def __init__(self, path: Optional[str] = None):
@@ -22,8 +23,8 @@ class Map:
22
23
  self.nextobjectid: int = 1
23
24
  self.properties: List[Property] = []
24
25
  self.tilesets: List[Tileset] = []
25
- self.layers: Dict[str, Layer] = {}
26
- self.objectgroups: Dict[str, ObjectGroup] = {}
26
+ self.layers: List[Layer] = []
27
+ self.objectgroups: List[ObjectGroup] = []
27
28
  if path and os.path.exists(path):
28
29
  self.load(path)
29
30
 
@@ -44,14 +45,14 @@ class Map:
44
45
  for prop_elem in props_elem.findall("property"):
45
46
  self.properties.append(Property.from_xml(prop_elem))
46
47
  self.tilesets = [Tileset.from_xml(ts_elem) for ts_elem in root.findall("tileset")]
47
- self.layers = {}
48
+ self.layers = []
48
49
  for layer_elem in root.findall("layer"):
49
50
  layer = Layer.from_xml(layer_elem)
50
- self.layers[layer.name] = layer
51
- self.objectgroups = {}
51
+ self.layers.append(layer)
52
+ self.objectgroups = []
52
53
  for og_elem in root.findall("objectgroup"):
53
54
  og = ObjectGroup.from_xml(og_elem)
54
- self.objectgroups[og.name] = og
55
+ self.objectgroups.append(og)
55
56
  return self
56
57
 
57
58
  def save(self, path: Optional[str] = None, encoding: str = "utf-8", indent: Optional[int] = None) -> None:
@@ -74,30 +75,24 @@ class Map:
74
75
  prop.to_xml(props_elem)
75
76
  for ts in self.tilesets:
76
77
  root.append(ts.to_xml())
77
- for layer in self.layers.values():
78
+ for layer in self.layers:
78
79
  root.append(layer.to_xml())
79
- for og in self.objectgroups.values():
80
+ for og in self.objectgroups:
80
81
  root.append(og.to_xml())
81
82
  if indent is not None:
82
83
  ET.indent(root, space=" " * indent)
83
84
  tree = ET.ElementTree(root)
84
85
  tree.write(out_path, encoding=encoding, xml_declaration=True)
85
86
 
86
- def layer(self, name: str) -> Layer:
87
- if name not in self.layers:
88
- raise KeyError(f"Layer '{name}' not found")
89
- return self.layers[name]
87
+ def property(self, name: str) -> Property | None:
88
+ return next((prop for prop in self.properties if prop.name == name), None)
90
89
 
91
- def objectgroup(self, name: str) -> ObjectGroup:
92
- if name not in self.objectgroups:
93
- raise KeyError(f"ObjectGroup '{name}' not found")
94
- return self.objectgroups[name]
90
+ def layer(self, name: str) -> Layer | None:
91
+ return next((layer for layer in self.layers if layer.name == name), None)
95
92
 
96
- def add_objectgroup(self, group: ObjectGroup) -> None:
97
- self.objectgroups[group.name] = group
93
+ def objectgroup(self, name: str) -> ObjectGroup | None:
94
+ return next((og for og in self.objectgroups if og.name == name), None)
98
95
 
99
- def remove_objectgroup(self, name: str) -> None:
100
- self.objectgroups.pop(name, None)
101
96
 
102
97
  def get_tileset_by_gid(self, gid: int) -> Optional[Tileset]:
103
98
  for ts in self.tilesets:
@@ -134,5 +129,5 @@ class Map:
134
129
  m.tileheight = tile_size
135
130
  if layer_names:
136
131
  for name in layer_names:
137
- m.layers[name] = Layer(name, width, height)
132
+ m.layers.append(Layer(name, width, height))
138
133
  return m
@@ -51,17 +51,15 @@ class Object:
51
51
  self.text = text
52
52
  self.properties = properties or []
53
53
 
54
+ def property(self, name: str) -> Property | None:
55
+ return next((prop for prop in self.properties if prop.name == name), None)
56
+
54
57
  def set(self, **kwargs: Any) -> 'Object':
55
58
  for k, v in kwargs.items():
56
59
  self.properties = [p for p in self.properties if p.name != k]
57
60
  self.properties.append(Property(k, v))
58
61
  return self
59
62
 
60
- def add_property(self, name: str, value: Any, type: Optional[str] = None) -> 'Object':
61
- self.properties = [p for p in self.properties if p.name != name]
62
- self.properties.append(Property(name, value, type))
63
- return self
64
-
65
63
  def copy_xy_from(self, other: 'Object') -> 'Object':
66
64
  self.x = other.x
67
65
  self.y = other.y
@@ -178,6 +176,9 @@ class ObjectGroup:
178
176
  self.offsety = offsety
179
177
  self.properties = properties or []
180
178
 
179
+ def property(self, name: str) -> Property | None:
180
+ return next((prop for prop in self.properties if prop.name == name), None)
181
+
181
182
  def add(self, obj: Object) -> 'ObjectGroup':
182
183
  self.objects.append(obj)
183
184
  return self
@@ -1,5 +1,5 @@
1
1
  from .rwmaps import RwMap
2
- from .triggers import Trigger, TriggerLayer
2
+ from .triggers import Trigger
3
3
  from .units import UnitSpec, unit
4
4
  from .factories import (
5
5
  map_info, team_info, unit_detect, unit_add, unit_remove,
@@ -10,7 +10,7 @@ from .factories import (
10
10
 
11
11
  __all__ = [
12
12
  "unit", "UnitSpec",
13
- "Trigger", "TriggerLayer", "RwMap",
13
+ "Trigger", "RwMap",
14
14
  "map_info", "team_info", "unit_detect", "unit_add", "unit_remove",
15
15
  "map_text", "point", "move", "rotate", "change_credits",
16
16
  "basic", "objective", "camera_start", "fall", "set_team", "ai_allow_full_use",
@@ -0,0 +1,77 @@
1
+ from typing import List, Optional, cast
2
+
3
+ from .triggers import Trigger
4
+ from ..objects import Object, ObjectGroup
5
+ from ..layers import Layer
6
+ from ..maps import Map
7
+
8
+
9
+ class RwMap(Map):
10
+
11
+ def __init__(self, path: Optional[str] = None) -> None:
12
+ super().__init__(path=path)
13
+
14
+ # ---------- 触发器图层 ----------
15
+ @property
16
+ def triggers(self) -> List[Trigger]:
17
+ og = self.objectgroup("Triggers")
18
+ if og is None:
19
+ # 自动创建空的 Triggers 图层并添加到地图
20
+ og = ObjectGroup(name="Triggers", objects=[])
21
+ self.objectgroups.append(og)
22
+ return cast(List[Trigger], og.objects)
23
+
24
+ @triggers.setter
25
+ def triggers(self, triggers: List[Trigger]) -> None:
26
+ og = self.objectgroup("Triggers")
27
+ if og is None:
28
+ og = ObjectGroup(
29
+ name="Triggers",
30
+ objects=cast(List[Object], triggers),
31
+ color=None,
32
+ opacity=1.0,
33
+ visible=True,
34
+ offsetx=0.0,
35
+ offsety=0.0,
36
+ properties=None,
37
+ )
38
+ self.objectgroups.append(og)
39
+ else:
40
+ og.objects = cast(List[Object], triggers)
41
+
42
+ @property
43
+ def ground(self) -> Optional[Layer]:
44
+ return self.layer("Ground")
45
+
46
+ @property
47
+ def items(self) -> Optional[Layer]:
48
+ return self.layer("Items")
49
+
50
+ @property
51
+ def units(self) -> Optional[Layer]:
52
+ return self.layer("Units")
53
+
54
+ @classmethod
55
+ def create_empty(
56
+ cls,
57
+ width: int = 256,
58
+ height: int = 256,
59
+ tile_size: int = 20,
60
+ layer_names: Optional[List[str]] = None,
61
+ ) -> "RwMap":
62
+ """创建一个空地图,包含指定的图层和默认的 Triggers 图层。"""
63
+ if layer_names is None:
64
+ layer_names = ["Ground", "Items", "Units", "Set"]
65
+
66
+ m = cls()
67
+ m.width = width
68
+ m.height = height
69
+ m.tilewidth = tile_size
70
+ m.tileheight = tile_size
71
+
72
+ for name in layer_names:
73
+ m.layers.append(Layer(name=name, width=width, height=height))
74
+
75
+ _ = m.triggers
76
+
77
+ return m
@@ -1,8 +1,7 @@
1
- import xml.etree.ElementTree as ET
2
1
  from typing import List, Optional, Union, Any
3
2
 
4
3
  from ..properties import Property
5
- from ..objects import Shape, Object, ObjectGroup
4
+ from ..objects import Shape, Object
6
5
  from .units import UnitSpec
7
6
 
8
7
 
@@ -65,52 +64,3 @@ class Trigger(Object):
65
64
 
66
65
  def all_to_activate(self, value: bool) -> 'Trigger':
67
66
  return self.set(allToActivate=value)
68
-
69
-
70
- class TriggerLayer(ObjectGroup):
71
-
72
- def __init__(
73
- self,
74
- triggers: Optional[List[Trigger]] = None,
75
- color: Optional[str] = None,
76
- opacity: float = 1.0,
77
- visible: bool = True,
78
- offsetx: float = 0.0,
79
- offsety: float = 0.0,
80
- properties: Optional[List[Property]] = None,
81
- ):
82
- super().__init__(
83
- name="Triggers",
84
- objects=triggers if triggers is not None else [],# type: ignore
85
- color=color,
86
- opacity=opacity,
87
- visible=visible,
88
- offsetx=offsetx,
89
- offsety=offsety,
90
- properties=properties,
91
- )
92
-
93
- def add(self, trigger: Trigger) -> 'TriggerLayer':# type: ignore
94
- super().add(trigger)
95
- return self
96
-
97
- def extend(self, triggers: List[Trigger]) -> 'TriggerLayer':# type: ignore
98
- super().extend(triggers)# type: ignore
99
- return self
100
-
101
- @property
102
- def triggers(self) -> List[Trigger]:
103
- return self.objects # type: ignore
104
-
105
- @classmethod
106
- def from_xml(cls, elem: ET.Element) -> 'TriggerLayer':
107
- og = ObjectGroup.from_xml(elem)
108
- return cls(
109
- triggers=og.objects, # type: ignore
110
- color=og.color,
111
- opacity=og.opacity,
112
- visible=og.visible,
113
- offsetx=og.offsetx,
114
- offsety=og.offsety,
115
- properties=og.properties,
116
- )
@@ -26,10 +26,8 @@ class Tile:
26
26
  self.image_height = image_height
27
27
  self.image_trans = image_trans
28
28
 
29
- def set_property(self, name: str, value: Any, type: Optional[str] = None) -> 'Tile':
30
- self.properties = [p for p in self.properties if p.name != name]
31
- self.properties.append(Property(name, value, type))
32
- return self
29
+ def property(self, name: str) -> Property | None:
30
+ return next((prop for prop in self.properties if prop.name == name), None)
33
31
 
34
32
  @classmethod
35
33
  def from_xml(cls, elem: ET.Element) -> 'Tile':
@@ -107,6 +105,9 @@ class Tileset:
107
105
  self.properties = properties or []
108
106
  self.tiles: Dict[int, Tile] = {}
109
107
 
108
+ def property(self, name: str) -> Property | None:
109
+ return next((prop for prop in self.properties if prop.name == name), None)
110
+
110
111
  def add_tile(self, tile: Tile) -> 'Tileset':
111
112
  self.tiles[tile.id] = tile
112
113
  return self
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rwmap
3
- Version: 2.0.0
3
+ Version: 3.1.4
4
4
  Summary: 一个精简的铁锈战争TMX地图操作工具
5
5
  Author: KEND
6
6
  License-Expression: GPL-3.0-or-later
@@ -1,77 +0,0 @@
1
- from typing import List, Optional
2
-
3
- from .triggers import TriggerLayer
4
- from ..layers import Layer
5
- from ..maps import Map
6
-
7
-
8
- class RwMap(Map):
9
-
10
- def __init__(self, path: Optional[str] = None):
11
- super().__init__(path)
12
- self._triggers: Optional[TriggerLayer] = None
13
- if "Triggers" in self.objectgroups:
14
- og = self.objectgroups["Triggers"]
15
- if isinstance(og, TriggerLayer):
16
- self._triggers = og
17
- else:
18
- self._triggers = TriggerLayer(
19
- triggers=og.objects, # type: ignore
20
- color=og.color,
21
- opacity=og.opacity,
22
- visible=og.visible,
23
- offsetx=og.offsetx,
24
- offsety=og.offsety,
25
- properties=og.properties,
26
- )
27
- self.objectgroups["Triggers"] = self._triggers
28
-
29
- @property
30
- def triggers(self) -> TriggerLayer:
31
- if self._triggers is None:
32
- self._triggers = TriggerLayer()
33
- self.objectgroups["Triggers"] = self._triggers
34
- return self._triggers
35
-
36
- @triggers.setter
37
- def triggers(self, layer: TriggerLayer) -> None:
38
- self._triggers = layer
39
- self.objectgroups["Triggers"] = layer
40
-
41
- @property
42
- def ground(self) -> Optional[Layer]:
43
- return self.layers.get("Ground")
44
-
45
- @property
46
- def items(self) -> Optional[Layer]:
47
- return self.layers.get("Items")
48
-
49
- @property
50
- def units(self) -> Optional[Layer]:
51
- return self.layers.get("Units")
52
-
53
- @property
54
- def set_layer(self) -> Optional[Layer]:
55
- return self.layers.get("Set")
56
-
57
- @classmethod
58
- def create_empty(
59
- cls,
60
- width: int = 256,
61
- height: int = 256,
62
- tile_size: int = 20,
63
- layer_names: Optional[List[str]] = None
64
- ) -> 'RwMap':
65
- if layer_names is None:
66
- layer_names = ["Ground", "Items", "Units", "Set"]
67
- m = cls()
68
- m.width = width
69
- m.height = height
70
- m.tilewidth = tile_size
71
- m.tileheight = tile_size
72
- for name in layer_names:
73
- m.layers[name] = Layer(name, width, height)
74
- _ = m.triggers # 触发自动创建
75
- return m
76
-
77
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes