diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2015-03-19 11:42:54 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2015-03-19 11:42:54 -0400 |
commit | 281bdf956a646fd8c9944e9a44f867c984792216 (patch) | |
tree | ba0297d2125ac22d22c873e012a8f0604e9e3a86 /tools/mapedit/src/object.cpp | |
parent | 103587c2d5f9deb20e549a86cdf5023b429cc6a1 (diff) | |
download | therapy-281bdf956a646fd8c9944e9a44f867c984792216.tar.gz therapy-281bdf956a646fd8c9944e9a44f867c984792216.tar.bz2 therapy-281bdf956a646fd8c9944e9a44f867c984792216.zip |
Map editor can now edit properties for objects (breaks main game build)
Diffstat (limited to 'tools/mapedit/src/object.cpp')
-rw-r--r-- | tools/mapedit/src/object.cpp | 304 |
1 files changed, 254 insertions, 50 deletions
diff --git a/tools/mapedit/src/object.cpp b/tools/mapedit/src/object.cpp index a783691..8ed29af 100644 --- a/tools/mapedit/src/object.cpp +++ b/tools/mapedit/src/object.cpp | |||
@@ -2,29 +2,130 @@ | |||
2 | #include <dirent.h> | 2 | #include <dirent.h> |
3 | #include <libxml/parser.h> | 3 | #include <libxml/parser.h> |
4 | #include <memory> | 4 | #include <memory> |
5 | #include "world.h" | ||
5 | 6 | ||
6 | static std::map<std::string, std::shared_ptr<MapObject>> allObjects; | 7 | static std::map<std::string, MapObject> allObjects; |
7 | static bool objsInit = false; | 8 | static bool objsInit = false; |
8 | 9 | ||
9 | const std::map<std::string, std::shared_ptr<MapObject>> MapObject::getAllObjects() | 10 | const std::map<std::string, MapObject>& MapObject::getAllObjects() |
10 | { | 11 | { |
11 | if (!objsInit) | 12 | if (!objsInit) |
12 | { | 13 | { |
13 | DIR* dir = opendir("entities/"); | 14 | try |
14 | if (dir != NULL) | ||
15 | { | 15 | { |
16 | struct dirent* ent; | 16 | xmlDocPtr doc = xmlParseFile("res/entities.xml"); |
17 | while ((ent = readdir(dir)) != NULL) | 17 | if (doc == nullptr) |
18 | { | 18 | { |
19 | std::string path = ent->d_name; | 19 | throw MapObjectLoadException("can't open file"); |
20 | if ((path.length() >= 4) && (path.substr(path.length() - 4, 4) == ".xml")) | 20 | } |
21 | |||
22 | xmlNodePtr top = xmlDocGetRootElement(doc); | ||
23 | if (top == nullptr) | ||
24 | { | ||
25 | throw MapObjectLoadException("missing root element"); | ||
26 | } | ||
27 | |||
28 | if (xmlStrcmp(top->name, (const xmlChar*) "entities")) | ||
29 | { | ||
30 | throw MapObjectLoadException("root element is not entities"); | ||
31 | } | ||
32 | |||
33 | for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next) | ||
34 | { | ||
35 | if (!xmlStrcmp(node->name, (const xmlChar*) "entity")) | ||
21 | { | 36 | { |
22 | std::string name = path.substr(0, path.length() - 4); | 37 | xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id"); |
23 | auto obj = std::make_shared<MapObject>(name.c_str()); | 38 | if (idKey == 0) throw MapObjectLoadException("entity missing id"); |
24 | 39 | std::string theID = (char*) idKey; | |
25 | allObjects[name] = obj; | 40 | xmlFree(idKey); |
41 | |||
42 | allObjects.emplace(theID, theID); | ||
43 | MapObject& mapObject = allObjects.at(theID); | ||
44 | |||
45 | xmlChar* nameKey = xmlGetProp(node, (xmlChar*) "name"); | ||
46 | if (nameKey == 0) throw MapObjectLoadException("entity missing name"); | ||
47 | mapObject.name = (char*) nameKey; | ||
48 | xmlFree(nameKey); | ||
49 | |||
50 | xmlChar* spriteKey = xmlGetProp(node, (xmlChar*) "sprite"); | ||
51 | if (spriteKey == 0) throw MapObjectLoadException("entity missing sprite"); | ||
52 | mapObject.sprite = wxImage((char*) spriteKey); | ||
53 | xmlFree(spriteKey); | ||
54 | |||
55 | xmlChar* widthKey = xmlGetProp(node, (xmlChar*) "width"); | ||
56 | if (widthKey == 0) throw MapObjectLoadException("entity missing width"); | ||
57 | mapObject.width = atoi((char*) widthKey); | ||
58 | xmlFree(widthKey); | ||
59 | |||
60 | xmlChar* heightKey = xmlGetProp(node, (xmlChar*) "height"); | ||
61 | if (heightKey == 0) throw MapObjectLoadException("entity missing height"); | ||
62 | mapObject.height = atoi((char*) heightKey); | ||
63 | xmlFree(heightKey); | ||
64 | |||
65 | for (xmlNodePtr entityNode = node->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next) | ||
66 | { | ||
67 | if (!xmlStrcmp(entityNode->name, (const xmlChar*) "input")) | ||
68 | { | ||
69 | xmlChar* key = xmlGetProp(entityNode, (xmlChar*) "id"); | ||
70 | if (key == 0) throw MapObjectLoadException("input missing id"); | ||
71 | std::string inputID = (char*) key; | ||
72 | xmlFree(key); | ||
73 | |||
74 | Input& input = mapObject.inputs[inputID]; | ||
75 | |||
76 | key = xmlGetProp(entityNode, (xmlChar*) "name"); | ||
77 | if (key == 0) throw MapObjectLoadException("input missing name"); | ||
78 | input.name = (char*) key; | ||
79 | xmlFree(key); | ||
80 | |||
81 | key = xmlGetProp(entityNode, (xmlChar*) "type"); | ||
82 | if (key == 0) throw MapObjectLoadException("input missing type"); | ||
83 | std::string inputType = (char*) key; | ||
84 | xmlFree(key); | ||
85 | |||
86 | if (inputType == "choice") | ||
87 | { | ||
88 | input.type = Input::Type::Choice; | ||
89 | |||
90 | for (xmlNodePtr choiceNode = entityNode->xmlChildrenNode; choiceNode != NULL; choiceNode = choiceNode->next) | ||
91 | { | ||
92 | if (!xmlStrcmp(choiceNode->name, (xmlChar*) "value")) | ||
93 | { | ||
94 | key = xmlGetProp(choiceNode, (xmlChar*) "id"); | ||
95 | if (key == 0) throw MapObjectLoadException("input value missing id"); | ||
96 | int valueId = atoi((char*) key); | ||
97 | xmlFree(key); | ||
98 | |||
99 | key = xmlNodeGetContent(choiceNode); | ||
100 | if (key == 0) throw MapObjectLoadException("input value missing content"); | ||
101 | std::string choiceText = (char*) key; | ||
102 | xmlFree(key); | ||
103 | |||
104 | input.choices[valueId] = choiceText; | ||
105 | } | ||
106 | } | ||
107 | } else if (inputType == "slider") | ||
108 | { | ||
109 | input.type = Input::Type::Slider; | ||
110 | |||
111 | key = xmlGetProp(entityNode, (xmlChar*) "minvalue"); | ||
112 | if (key == 0) throw MapObjectLoadException("integer input missing minvalue"); | ||
113 | input.minvalue = atoi((char*) key); | ||
114 | xmlFree(key); | ||
115 | |||
116 | key = xmlGetProp(entityNode, (xmlChar*) "maxvalue"); | ||
117 | if (key == 0) throw MapObjectLoadException("integer input missing maxvalue"); | ||
118 | input.maxvalue = atoi((char*) key); | ||
119 | xmlFree(key); | ||
120 | } | ||
121 | } | ||
122 | } | ||
26 | } | 123 | } |
27 | } | 124 | } |
125 | } catch (std::exception& ex) | ||
126 | { | ||
127 | wxMessageBox(ex.what(), "Error loading objects", wxOK | wxCENTRE | wxICON_ERROR); | ||
128 | exit(3); | ||
28 | } | 129 | } |
29 | 130 | ||
30 | objsInit = true; | 131 | objsInit = true; |
@@ -33,67 +134,170 @@ const std::map<std::string, std::shared_ptr<MapObject>> MapObject::getAllObjects | |||
33 | return allObjects; | 134 | return allObjects; |
34 | } | 135 | } |
35 | 136 | ||
36 | MapObject::MapObject(const char* filename) | 137 | MapObject::MapObject(std::string id) : id(id) |
37 | { | 138 | { |
38 | type = filename; | ||
39 | 139 | ||
40 | xmlDocPtr doc = xmlParseFile(("entities/" + std::string(filename) + ".xml").c_str()); | 140 | } |
41 | if (doc == nullptr) throw MapObjectLoadException(filename); | ||
42 | 141 | ||
43 | xmlNodePtr top = xmlDocGetRootElement(doc); | 142 | std::string MapObject::getID() const |
44 | if (top == nullptr) throw MapObjectLoadException(filename); | 143 | { |
144 | return id; | ||
145 | } | ||
45 | 146 | ||
46 | if (xmlStrcmp(top->name, (const xmlChar*) "entity-def")) | 147 | std::string MapObject::getName() const |
47 | { | 148 | { |
48 | throw MapObjectLoadException(filename); | 149 | return name; |
49 | } | 150 | } |
151 | |||
152 | wxBitmap MapObject::getSprite() const | ||
153 | { | ||
154 | return sprite; | ||
155 | } | ||
156 | |||
157 | int MapObject::getWidth() const | ||
158 | { | ||
159 | return width; | ||
160 | } | ||
161 | |||
162 | int MapObject::getHeight() const | ||
163 | { | ||
164 | return height; | ||
165 | } | ||
166 | |||
167 | const std::map<std::string, MapObject::Input>& MapObject::getInputs() const | ||
168 | { | ||
169 | return inputs; | ||
170 | } | ||
171 | |||
172 | const MapObject::Input& MapObject::getInput(std::string id) const | ||
173 | { | ||
174 | return inputs.at(id); | ||
175 | } | ||
176 | |||
177 | bool MapObject::operator==(const MapObject& other) const | ||
178 | { | ||
179 | return id == other.id; | ||
180 | } | ||
181 | |||
182 | bool MapObject::operator!=(const MapObject& other) const | ||
183 | { | ||
184 | return id != other.id; | ||
185 | } | ||
186 | |||
187 | MapObjectEntry::MapObjectEntry(const MapObject& object, int posx, int posy) : object(object) | ||
188 | { | ||
189 | position = std::make_pair(posx, posy); | ||
190 | } | ||
191 | |||
192 | const MapObject& MapObjectEntry::getObject() const | ||
193 | { | ||
194 | return object; | ||
195 | } | ||
196 | |||
197 | std::pair<int, int> MapObjectEntry::getPosition() const | ||
198 | { | ||
199 | return position; | ||
200 | } | ||
201 | |||
202 | MapObjectEntry::Item& MapObjectEntry::getItem(std::string str) | ||
203 | { | ||
204 | return items[str]; | ||
205 | } | ||
206 | |||
207 | const std::map<std::string, MapObjectEntry::Item>& MapObjectEntry::getItems() const | ||
208 | { | ||
209 | return items; | ||
210 | } | ||
211 | |||
212 | void MapObjectEntry::addItem(std::string id, Item& item) | ||
213 | { | ||
214 | items[id] = item; | ||
215 | } | ||
216 | |||
217 | void MapObjectEntry::setPosition(int x, int y) | ||
218 | { | ||
219 | position = std::make_pair(x, y); | ||
220 | } | ||
221 | |||
222 | bool MapObjectEntry::operator==(const MapObjectEntry& other) const | ||
223 | { | ||
224 | return (object == other.object) && (position == other.position); | ||
225 | } | ||
226 | |||
227 | bool MapObjectEntry::operator!=(const MapObjectEntry& other) const | ||
228 | { | ||
229 | return (object != other.object) && (position != other.position); | ||
230 | } | ||
231 | |||
232 | VariableChoiceValidator::VariableChoiceValidator(World& world, MapObjectEntry::Item& item) : world(world), item(item) | ||
233 | { | ||
234 | |||
235 | } | ||
50 | 236 | ||
51 | for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next) | 237 | wxObject* VariableChoiceValidator::Clone() const |
238 | { | ||
239 | return new VariableChoiceValidator(world, item); | ||
240 | } | ||
241 | |||
242 | bool VariableChoiceValidator::TransferFromWindow() | ||
243 | { | ||
244 | wxChoice* choice = (wxChoice*) GetWindow(); | ||
245 | int sel = choice->GetSelection(); | ||
246 | int val = (intptr_t) choice->GetClientData(sel); | ||
247 | item.intvalue = val; | ||
248 | world.setDirty(true); | ||
249 | |||
250 | return true; | ||
251 | } | ||
252 | |||
253 | bool VariableChoiceValidator::TransferToWindow() | ||
254 | { | ||
255 | wxChoice* choice = (wxChoice*) GetWindow(); | ||
256 | for (size_t i=0; i<choice->GetCount(); i++) | ||
52 | { | 257 | { |
53 | if (!xmlStrcmp(node->name, (const xmlChar*) "sprite")) | 258 | if ((intptr_t) choice->GetClientData(i) == item.intvalue) |
54 | { | ||
55 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
56 | std::string spriteFile = (char*) key; | ||
57 | xmlFree(key); | ||
58 | |||
59 | sprite = wxImage(spriteFile); | ||
60 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "action")) | ||
61 | { | 259 | { |
62 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | 260 | choice->SetSelection(i); |
63 | action = (char*) key; | 261 | return true; |
64 | xmlFree(key); | ||
65 | } else if (!xmlStrcmp(node->name, (const xmlChar*) "size")) | ||
66 | { | ||
67 | xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); | ||
68 | sscanf((char*) key, "%d,%d", &width, &height); | ||
69 | xmlFree(key); | ||
70 | } | 262 | } |
71 | } | 263 | } |
264 | |||
265 | return false; | ||
266 | } | ||
72 | 267 | ||
73 | xmlFreeDoc(doc); | 268 | bool VariableChoiceValidator::Validate(wxWindow*) |
269 | { | ||
270 | return true; | ||
74 | } | 271 | } |
75 | 272 | ||
76 | wxBitmap MapObject::getSprite() const | 273 | SliderItemValidator::SliderItemValidator(World& world, MapObjectEntry::Item& item) : world(world), item(item) |
77 | { | 274 | { |
78 | return sprite; | 275 | |
79 | } | 276 | } |
80 | 277 | ||
81 | std::string MapObject::getAction() const | 278 | wxObject* SliderItemValidator::Clone() const |
82 | { | 279 | { |
83 | return action; | 280 | return new SliderItemValidator(world, item); |
84 | } | 281 | } |
85 | 282 | ||
86 | int MapObject::getWidth() const | 283 | bool SliderItemValidator::TransferFromWindow() |
87 | { | 284 | { |
88 | return width; | 285 | wxSlider* slider = (wxSlider*) GetWindow(); |
286 | item.intvalue = slider->GetValue(); | ||
287 | world.setDirty(true); | ||
288 | |||
289 | return true; | ||
89 | } | 290 | } |
90 | 291 | ||
91 | int MapObject::getHeight() const | 292 | bool SliderItemValidator::TransferToWindow() |
92 | { | 293 | { |
93 | return height; | 294 | wxSlider* slider = (wxSlider*) GetWindow(); |
295 | slider->SetValue(item.intvalue); | ||
296 | |||
297 | return true; | ||
94 | } | 298 | } |
95 | 299 | ||
96 | std::string MapObject::getType() const | 300 | bool SliderItemValidator::Validate(wxWindow*) |
97 | { | 301 | { |
98 | return type; | 302 | return true; |
99 | } | 303 | } |