summary refs log tree commit diff stats
path: root/tools/mapedit/src/map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mapedit/src/map.cpp')
-rw-r--r--tools/mapedit/src/map.cpp289
1 files changed, 113 insertions, 176 deletions
diff --git a/tools/mapedit/src/map.cpp b/tools/mapedit/src/map.cpp index f9c07fc..32541e6 100644 --- a/tools/mapedit/src/map.cpp +++ b/tools/mapedit/src/map.cpp
@@ -1,106 +1,27 @@
1#include "map.h" 1#include "map.h"
2#include <libxml/parser.h>
3#include <libxml/xmlwriter.h>
4#include <sstream>
5#include "frame.h" 2#include "frame.h"
6 3
7Map::Map() 4Map::Map(int id, World* world) : id(id), world(world)
8{ 5{
9 mapdata = (int*) calloc(MAP_WIDTH * MAP_HEIGHT, sizeof(int)); 6 mapdata = (int*) calloc(MAP_WIDTH * MAP_HEIGHT, sizeof(int));
10} 7}
11 8
12Map::Map(std::string filename)
13{
14 xmlDocPtr doc = xmlParseFile(filename.c_str());
15 if (doc == nullptr)
16 {
17 throw MapLoadException(filename);
18 }
19
20 xmlNodePtr top = xmlDocGetRootElement(doc);
21 if (top == nullptr)
22 {
23 throw MapLoadException(filename);
24 }
25
26 if (xmlStrcmp(top->name, (const xmlChar*) "map-def"))
27 {
28 throw MapLoadException(filename);
29 }
30
31 for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next)
32 {
33 if (!xmlStrcmp(node->name, (const xmlChar*) "name"))
34 {
35 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
36 title = (char*) key;
37 xmlFree(key);
38 } else if (!xmlStrcmp(node->name, (const xmlChar*) "environment"))
39 {
40 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
41 mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int));
42 mapdata[0] = atoi(strtok((char*) key, ",\n"));
43 for (int i=1; i<(MAP_WIDTH*MAP_HEIGHT); i++)
44 {
45 mapdata[i] = atoi(strtok(NULL, ",\n"));
46 }
47 xmlFree(key);
48 } else if (!xmlStrcmp(node->name, (const xmlChar*) "leftmap"))
49 {
50 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
51 leftmap = (char*) key;
52 xmlFree(key);
53 } else if (!xmlStrcmp(node->name, (const xmlChar*) "rightmap"))
54 {
55 xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
56 rightmap = (char*) key;
57 xmlFree(key);
58 } else if (!xmlStrcmp(node->name, (const xmlChar*) "entities"))
59 {
60 for (xmlNodePtr entityNode = node->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next)
61 {
62 if (!xmlStrcmp(entityNode->name, (const xmlChar*) "entity"))
63 {
64 auto data = std::make_shared<MapObjectEntry>();
65
66 for (xmlNodePtr entityDataNode = entityNode->xmlChildrenNode; entityDataNode != NULL; entityDataNode = entityDataNode->next)
67 {
68 if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-type"))
69 {
70 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
71 data->object = MapObject::getAllObjects().at((char*) key).get();
72 xmlFree(key);
73 } else if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-position"))
74 {
75 xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1);
76 sscanf((char*) key, "%lf,%lf", &data->position.first, &data->position.second);
77 xmlFree(key);
78 }
79 }
80
81 objects.push_back(data);
82 }
83 }
84 }
85 }
86
87 xmlFreeDoc(doc);
88}
89
90Map::Map(const Map& map) 9Map::Map(const Map& map)
91{ 10{
92 mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int)); 11 mapdata = (int*) malloc(MAP_WIDTH*MAP_HEIGHT*sizeof(int));
93 memcpy(mapdata, map.mapdata, MAP_WIDTH*MAP_HEIGHT*sizeof(int)); 12 memcpy(mapdata, map.mapdata, MAP_WIDTH*MAP_HEIGHT*sizeof(int));
94 13
14 id = map.id;
95 title = map.title; 15 title = map.title;
96 leftmap = map.leftmap; 16 leftmap = map.leftmap;
97 rightmap = map.rightmap; 17 rightmap = map.rightmap;
98 dirty = map.dirty;
99 objects = map.objects; 18 objects = map.objects;
100 frame = map.frame; 19 world = map.world;
20 treeItemId = map.treeItemId;
21 children = map.children;
101} 22}
102 23
103Map::Map(Map&& map) : Map() 24Map::Map(Map&& map) : Map(-1, map.world)
104{ 25{
105 swap(*this, map); 26 swap(*this, map);
106} 27}
@@ -123,141 +44,157 @@ void swap(Map& first, Map& second)
123 std::swap(first.title, second.title); 44 std::swap(first.title, second.title);
124 std::swap(first.leftmap, second.leftmap); 45 std::swap(first.leftmap, second.leftmap);
125 std::swap(first.rightmap, second.rightmap); 46 std::swap(first.rightmap, second.rightmap);
126 std::swap(first.dirty, second.dirty);
127 std::swap(first.objects, second.objects); 47 std::swap(first.objects, second.objects);
128 std::swap(first.frame, second.frame); 48 std::swap(first.id, second.id);
49 std::swap(first.world, second.world);
50 std::swap(first.treeItemId, second.treeItemId);
51 std::swap(first.children, second.children);
129} 52}
130 53
131#define MY_ENCODING "ISO-8859-1" 54int Map::getID() const
55{
56 return id;
57}
132 58
133void Map::save(std::string name) 59std::string Map::getTitle() const
134{ 60{
135 if (!dirty) return; 61 return title;
136 62}
137 int rc;
138
139 xmlTextWriterPtr writer = xmlNewTextWriterFilename(name.c_str(), 0);
140 if (writer == NULL) throw MapWriteException(name);
141 63
142 rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL); 64int Map::getTileAt(int x, int y) const
143 if (rc < 0) throw MapWriteException(name); 65{
144 66 return mapdata[x+y*MAP_WIDTH];
145 rc = xmlTextWriterStartElement(writer, (xmlChar*) "map-def"); 67}
146 if (rc < 0) throw MapWriteException(name); 68
147 69const std::list<std::shared_ptr<MapObjectEntry>>& Map::getObjects() const
148 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "name", (xmlChar*) title.c_str()); 70{
149 if (rc < 0) throw MapWriteException(name); 71 return objects;
150 72}
151 std::ostringstream mapdata_out; 73
152 for (int y=0; y<MAP_HEIGHT; y++) 74std::shared_ptr<Map> Map::getLeftmap() const
75{
76 if (leftmap == -1)
153 { 77 {
154 for (int x=0; x<MAP_WIDTH; x++) 78 return std::shared_ptr<Map>();
155 { 79 } else {
156 mapdata_out << mapdata[x+y*MAP_WIDTH] << ","; 80 return world->getMap(leftmap);
157 }
158
159 mapdata_out << std::endl;
160 } 81 }
161 82}
162 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "environment", (xmlChar*) mapdata_out.str().c_str());
163 if (rc < 0) throw MapWriteException(name);
164
165 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "leftmap", (xmlChar*) leftmap.c_str());
166 if (rc < 0) throw MapWriteException(name);
167 83
168 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "rightmap", (xmlChar*) rightmap.c_str()); 84std::shared_ptr<Map> Map::getRightmap() const
169 if (rc < 0) throw MapWriteException(name); 85{
170 86 if (rightmap == -1)
171 rc = xmlTextWriterStartElement(writer, (xmlChar*) "entities");
172 if (rc < 0) throw MapWriteException(name);
173
174 for (auto object : objects)
175 { 87 {
176 rc = xmlTextWriterStartElement(writer, (xmlChar*) "entity"); 88 return std::shared_ptr<Map>();
177 if (rc < 0) throw MapWriteException(name); 89 } else {
178 90 return world->getMap(rightmap);
179 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "entity-type", (xmlChar*) object->object->getType().c_str());
180 if (rc < 0) throw MapWriteException(name);
181
182 std::ostringstream entpos_out;
183 entpos_out << object->position.first << "," << object->position.second;
184
185 rc = xmlTextWriterWriteElement(writer, (xmlChar*) "entity-position", (xmlChar*) entpos_out.str().c_str());
186 if (rc < 0) throw MapWriteException(name);
187
188 rc = xmlTextWriterEndElement(writer);
189 if (rc < 0) throw MapWriteException(name);
190 } 91 }
191
192 rc = xmlTextWriterEndElement(writer);
193 if (rc < 0) throw MapWriteException(name);
194
195 rc = xmlTextWriterEndElement(writer);
196 if (rc < 0) throw MapWriteException(name);
197
198 rc = xmlTextWriterEndDocument(writer);
199 if (rc < 0) throw MapWriteException(name);
200
201 xmlFreeTextWriter(writer);
202
203 setDirty(false);
204} 92}
205 93
206bool Map::hasUnsavedChanges() const 94wxTreeItemId Map::getTreeItemId() const
207{ 95{
208 return dirty; 96 return treeItemId;
209} 97}
210 98
211void Map::setTileAt(int x, int y, int tile) 99std::list<std::shared_ptr<Map>> Map::getChildren() const
212{ 100{
213 setDirty(true); 101 std::list<std::shared_ptr<Map>> ret;
214 mapdata[x+y*MAP_WIDTH] = tile; 102
103 for (auto id : children)
104 {
105 ret.push_back(world->getMap(id));
106 }
107
108 return ret;
215} 109}
216 110
217int Map::getTileAt(int x, int y) const 111bool Map::getExpanded() const
218{ 112{
219 return mapdata[x+y*MAP_WIDTH]; 113 return expanded;
220} 114}
221 115
222std::string Map::getTitle() const 116void Map::setTitle(std::string title, bool dirty)
223{ 117{
224 return title; 118 this->title = title;
119
120 if (dirty)
121 {
122 world->setDirty(true);
123 }
225} 124}
226 125
227void Map::setTitle(std::string title) 126void Map::setTileAt(int x, int y, int tile, bool dirty)
228{ 127{
229 setDirty(true); 128 mapdata[x+y*MAP_WIDTH] = tile;
230 this->title = title; 129
130 if (dirty)
131 {
132 world->setDirty(true);
133 }
231} 134}
232 135
233const std::list<std::shared_ptr<MapObjectEntry>>& Map::getObjects() const 136void Map::setMapdata(int* mapdata, bool dirty)
234{ 137{
235 return objects; 138 free(this->mapdata);
139 this->mapdata = mapdata;
140
141 if (dirty)
142 {
143 world->setDirty(true);
144 }
236} 145}
237 146
238void Map::addObject(std::shared_ptr<MapObjectEntry>& obj) 147void Map::addObject(std::shared_ptr<MapObjectEntry>& obj, bool dirty)
239{ 148{
240 setDirty(true);
241 objects.push_back(obj); 149 objects.push_back(obj);
150
151 if (dirty)
152 {
153 world->setDirty(true);
154 }
242} 155}
243 156
244void Map::removeObject(std::shared_ptr<MapObjectEntry>& obj) 157void Map::removeObject(std::shared_ptr<MapObjectEntry>& obj, bool dirty)
245{ 158{
246 setDirty(true);
247 objects.remove(obj); 159 objects.remove(obj);
160
161 if (dirty)
162 {
163 world->setDirty(true);
164 }
248} 165}
249 166
250bool Map::getDirty() const 167void Map::setLeftmap(int id, bool dirty)
251{ 168{
252 return dirty; 169 leftmap = id;
170
171 if (dirty)
172 {
173 world->setDirty(true);
174 }
253} 175}
254 176
255void Map::setDirty(bool dirty) 177void Map::setRightmap(int id, bool dirty)
256{ 178{
257 this->dirty = dirty; 179 rightmap = id;
258 180
259 if (frame != nullptr) 181 if (dirty)
260 { 182 {
261 frame->MapDirtyDidChange(dirty); 183 world->setDirty(true);
262 } 184 }
263} 185}
186
187void Map::setTreeItemId(wxTreeItemId id)
188{
189 this->treeItemId = id;
190}
191
192void Map::addChild(int id)
193{
194 children.push_back(id);
195}
196
197void Map::setExpanded(bool exp)
198{
199 expanded = exp;
200}