diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2015-03-16 16:53:05 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2015-03-16 16:53:05 -0400 |
commit | 0d30e9b57229905f78e7bd60fe5d3cde72851f28 (patch) | |
tree | 4ca2abff9fb1933685f570e97a8b9e88a976c95f /tools/mapedit/src/map.cpp | |
parent | 36536297aac5c07e3d5fb96abed74570fc7615e9 (diff) | |
download | therapy-0d30e9b57229905f78e7bd60fe5d3cde72851f28.tar.gz therapy-0d30e9b57229905f78e7bd60fe5d3cde72851f28.tar.bz2 therapy-0d30e9b57229905f78e7bd60fe5d3cde72851f28.zip |
Rewrote map editor so a single file contains all maps
Maps are viewed in a tree control on the left. They can be dragged and dropped. Maps are bolded when they are dirty. Saving saves expansion status and order of maps in tree.
Diffstat (limited to 'tools/mapedit/src/map.cpp')
-rw-r--r-- | tools/mapedit/src/map.cpp | 289 |
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 | ||
7 | Map::Map() | 4 | Map::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 | ||
12 | Map::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 | |||
90 | Map::Map(const Map& map) | 9 | Map::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 | ||
103 | Map::Map(Map&& map) : Map() | 24 | Map::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" | 54 | int Map::getID() const |
55 | { | ||
56 | return id; | ||
57 | } | ||
132 | 58 | ||
133 | void Map::save(std::string name) | 59 | std::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); | 64 | int 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 | 69 | const 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++) | 74 | std::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()); | 84 | std::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 | ||
206 | bool Map::hasUnsavedChanges() const | 94 | wxTreeItemId Map::getTreeItemId() const |
207 | { | 95 | { |
208 | return dirty; | 96 | return treeItemId; |
209 | } | 97 | } |
210 | 98 | ||
211 | void Map::setTileAt(int x, int y, int tile) | 99 | std::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 | ||
217 | int Map::getTileAt(int x, int y) const | 111 | bool Map::getExpanded() const |
218 | { | 112 | { |
219 | return mapdata[x+y*MAP_WIDTH]; | 113 | return expanded; |
220 | } | 114 | } |
221 | 115 | ||
222 | std::string Map::getTitle() const | 116 | void 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 | ||
227 | void Map::setTitle(std::string title) | 126 | void 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 | ||
233 | const std::list<std::shared_ptr<MapObjectEntry>>& Map::getObjects() const | 136 | void 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 | ||
238 | void Map::addObject(std::shared_ptr<MapObjectEntry>& obj) | 147 | void 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 | ||
244 | void Map::removeObject(std::shared_ptr<MapObjectEntry>& obj) | 157 | void 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 | ||
250 | bool Map::getDirty() const | 167 | void 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 | ||
255 | void Map::setDirty(bool dirty) | 177 | void 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 | |||
187 | void Map::setTreeItemId(wxTreeItemId id) | ||
188 | { | ||
189 | this->treeItemId = id; | ||
190 | } | ||
191 | |||
192 | void Map::addChild(int id) | ||
193 | { | ||
194 | children.push_back(id); | ||
195 | } | ||
196 | |||
197 | void Map::setExpanded(bool exp) | ||
198 | { | ||
199 | expanded = exp; | ||
200 | } | ||