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

Revision 335, 7.3 KB checked in by Kaydeth_parpg, 10 years ago (diff)

Ticket #120. Patch by beliar and Kaydeth. Added some new lines and indentation to the map editor so the saved file is more readable and looks more like it used to when it was created by hand. comments[s:trac, t:120]

  • 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 inst_id is not None and inst_id in loaders.data.objects:
138                for key in loaders.data.objects[inst_id]:
139                    if key not in attrib and loaders.data.objects[inst_id][key]:
140                        print key
141                        attrib[key] = str(loaders.data.objects[inst_id][key])
142                        print key, attrib[key]
143
144            # the local_loader loader sets object_type as type, we have to
145            # correct for that here but really we should fix that there
146            if attrib.get('type'):
147                attrib['object_type'] = attrib['type']
148                del attrib['type']
149
150            inst_element = Element('i', attrib)
151            inst_element.tail = "\n\t\t\t"
152            instances_element.append(inst_element)
153
154    def write_cameras(self):
155        """Write out the cameras specified in a map"""
156        cameras = self.engine.getView().getCameras()
157
158        for cam in cameras:
159            if cam.getLocationRef().getMap().getId() != self.map.getId(): continue
160            cell_dimensions = cam.getCellImageDimensions()
161            viewport = cam.getViewPort()
162
163            attrib = {
164                'id': cam.getId(),
165                'zoom': str(cam.getZoom()),
166                'tilt': str(cam.getTilt()),
167                'rotation': str(cam.getRotation()),
168                'ref_layer_id': cam.getLocation().getLayer().getId(),
169                'ref_cell_width': str(cell_dimensions.x),
170                'ref_cell_height': str(cell_dimensions.y),
171            }
172
173            if viewport != self.engine.getRenderBackend().getArea():
174                attrib['viewport'] = '%d,%d,%d,%d' % (viewport.x, viewport.y, viewport.w, viewport.h)
175               
176            camera_element = Element('camera', attrib)
177            camera_element.tail = "\n"
178            self.map_element.append(camera_element)
179
180    def pathing_val_to_str(self, val):
181        """Convert a pathing value to a string"""
182        if val == fife.CELL_EDGES_AND_DIAGONALS:
183            return "cell_edges_and_diagonals"
184        if val == fife.FREEFORM:
185            return "freeform"
186        return "cell_edges_only"
187
188def saveMapFile(path, engine, map, **kwargs):
189    """Saves a map"""
190    map.setResourceFile(path) #wtf is this
191    saver = Saver(path, engine)
192    saver.write_map(map, kwargs.get('importList'))
Note: See TracBrowser for help on using the repository browser.