source: trunk/game/editor/savers.py @ 415

Revision 367, 7.3 KB checked in by orlandov, 10 years ago (diff)

Ticket #135 - patch by or1andov. Do not write out gfx, xpos and ypos attributes when map editor saves. fixes[s:trac, t:135]

  • Property svn:eol-style set to native
Line 
1#!python
2
3# This file is part of PARPG.
4# PARPG is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# PARPG is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
16
17import fife
18import loaders
19from serializers import root_subfile
20
21from xml.etree.ElementTree import Element, SubElement, tostring
22
23class Saver(object):
24    """Serialize a FIFE map object to an XML file"""
25
26    def __init__(self, filepath, engine):
27        self.filepath = filepath
28        self.engine = engine
29        self.namespace = ''
30
31    def write_map(self, map, import_list):
32        """Write the specified map to an XML file"""
33
34        self.map = map
35        attrib = {
36            'id': map.getId(),
37            'format': "1.0"
38        }
39        self.map_element = Element('map', attrib)
40        self.map_element.text = "\n\t"
41        self.map_element.tail = "\n"
42        # serialize FIFE details
43        self.write_imports(import_list)
44        self.write_layers()
45        self.write_cameras()
46
47        # add newlines to the elements
48#        for subElement in self.map_element:
49#            subElement.tail = "\n"
50        # finally write out the XML file
51        file(self.filepath, 'w').write(
52            """<?xml version="1.0" encoding="ascii"?>\n%s"""
53                % (tostring(self.map_element),))
54
55    def write_imports(self, import_list):
56        """Serialize imports"""
57        map = self.map
58        for import_dir in import_list:
59            self.write_importdir(
60                root_subfile(map.getResourceFile(), import_dir))
61
62        imports = []
63        for layer in map.getLayers():
64            for instance in layer.getInstances():
65                file = instance.getObject().getResourceFile()
66                if (file in imports): continue
67                if self.have_superdir(file, import_list): continue
68                imports.append(file)
69                self.write_import(
70                    root_subfile(map.getResourceFile(), file))
71
72    def have_superdir(self, file, import_list):
73        """Returns true, if file is in directories given in import_list"""
74        for dir in import_list:
75            have = True
76            # TODO use os.path.split here
77            for test in zip(dir.split(os.path.sep), file.split(os.path.sep)):
78                if test[0] != test[1]: have = False
79            if have: return True
80
81        return False
82
83    def write_import(self, filename):
84        """Write an import filename"""
85        import_element = Element('import', { 'file': filename })
86        import_element.tail = "\n\t"
87        self.map_element.append(import_element)
88
89    def write_import_dir(import_dir):
90        """Write an import dir"""
91        import_dir_element = Element('import', { 'dir': import_dir })
92        import_dir_element.tail = "\n"
93        self.map_element.append(import_dir_element)
94
95    def write_layers(self):
96        """Write a layer"""
97        for layer in self.map.getLayers():
98            cellgrid = layer.getCellGrid()
99            attrib = {
100                'id': layer.getId(),
101                'grid_type': cellgrid.getType(),
102                'x_scale': str(cellgrid.getXScale()),
103                'y_scale': str(cellgrid.getYScale()),
104                'rotation': str(cellgrid.getRotation()),
105                'x_offset': str(cellgrid.getXShift()),
106                'y_offset': str(cellgrid.getYShift()),
107                'pathing': self.pathing_val_to_str(layer.getPathingStrategy()),
108                'transparency': str(layer.getLayerTransparency()),
109            }
110            layer_element = SubElement(self.map_element, 'layer', attrib)
111            layer_element.text = "\n\t\t"
112            layer_element.tail = "\n\n\t"
113            self.write_instances(layer_element, layer)
114
115    def write_instances(self, layer_element, layer):
116        """Write out the instances in a layer"""
117        instances_element = SubElement(layer_element, 'instances')
118        instances_element.text = "\n\t\t\t"
119        instances_element.tail = "\n\t"
120        for inst in layer.getInstances():
121            position = inst.getLocationRef().getExactLayerCoordinates()
122            attrib = {
123                'o': inst.getObject().getId(),
124                'x': str(position.x),
125                'y': str(position.y),
126                'z': str(position.z),
127                'r': str(inst.getRotation()),
128            }
129            namespace = inst.getObject().getNamespace()
130            if namespace != self.namespace:
131                attrib['ns'] = inst.getObject().getNamespace()
132                self.namespace = namespace
133            inst_id = inst.getId()
134            if inst_id:
135                attrib['id'] = inst_id
136
137            # if the object has an instance id, write out saved attributes
138            if inst_id is not None and inst_id in loaders.data.objects:
139                skip_keys = ['gfx', 'xpos', 'ypos']
140                for key in loaders.data.objects[inst_id]:
141                    # set value if we haven't written the key out yet and key
142                    # has a value in our attr stash (loaders.data.objects)
143                    if key in skip_keys or key in attrib \
144                        or key not in loaders.data.objects[inst_id]:
145                        continue
146
147                    attrib[key] = str(loaders.data.objects[inst_id][key])
148
149            # the local_loader loader sets object_type as type, we have to
150            # correct for that here but really we should fix that there
151            if attrib.get('type'):
152                attrib['object_type'] = attrib['type']
153                del attrib['type']
154
155            inst_element = Element('i', attrib)
156            inst_element.tail = "\n\t\t\t"
157            instances_element.append(inst_element)
158
159    def write_cameras(self):
160        """Write out the cameras specified in a map"""
161        cameras = self.engine.getView().getCameras()
162
163        for cam in cameras:
164            if cam.getLocationRef().getMap().getId() != self.map.getId(): continue
165            cell_dimensions = cam.getCellImageDimensions()
166
167            attrib = {
168                'id': cam.getId(),
169                'zoom': str(cam.getZoom()),
170                'tilt': str(cam.getTilt()),
171                'rotation': str(cam.getRotation()),
172                'ref_layer_id': cam.getLocation().getLayer().getId(),
173                'ref_cell_width': str(cell_dimensions.x),
174                'ref_cell_height': str(cell_dimensions.y),
175            }
176
177            camera_element = Element('camera', attrib)
178            camera_element.tail = "\n"
179            self.map_element.append(camera_element)
180
181    def pathing_val_to_str(self, val):
182        """Convert a pathing value to a string"""
183        if val == fife.CELL_EDGES_AND_DIAGONALS:
184            return "cell_edges_and_diagonals"
185        if val == fife.FREEFORM:
186            return "freeform"
187        return "cell_edges_only"
188
189def saveMapFile(path, engine, map, **kwargs):
190    """Saves a map"""
191    map.setResourceFile(path) #wtf is this
192    saver = Saver(path, engine)
193    saver.write_map(map, kwargs.get('importList'))
Note: See TracBrowser for help on using the repository browser.