summary refs log tree commit diff stats
path: root/tools/mapedit/src/object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mapedit/src/object.cpp')
-rw-r--r--tools/mapedit/src/object.cpp304
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
6static std::map<std::string, std::shared_ptr<MapObject>> allObjects; 7static std::map<std::string, MapObject> allObjects;
7static bool objsInit = false; 8static bool objsInit = false;
8 9
9const std::map<std::string, std::shared_ptr<MapObject>> MapObject::getAllObjects() 10const 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
36MapObject::MapObject(const char* filename) 137MapObject::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); 142std::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")) 147std::string MapObject::getName() const
47 { 148{
48 throw MapObjectLoadException(filename); 149 return name;
49 } 150}
151
152wxBitmap MapObject::getSprite() const
153{
154 return sprite;
155}
156
157int MapObject::getWidth() const
158{
159 return width;
160}
161
162int MapObject::getHeight() const
163{
164 return height;
165}
166
167const std::map<std::string, MapObject::Input>& MapObject::getInputs() const
168{
169 return inputs;
170}
171
172const MapObject::Input& MapObject::getInput(std::string id) const
173{
174 return inputs.at(id);
175}
176
177bool MapObject::operator==(const MapObject& other) const
178{
179 return id == other.id;
180}
181
182bool MapObject::operator!=(const MapObject& other) const
183{
184 return id != other.id;
185}
186
187MapObjectEntry::MapObjectEntry(const MapObject& object, int posx, int posy) : object(object)
188{
189 position = std::make_pair(posx, posy);
190}
191
192const MapObject& MapObjectEntry::getObject() const
193{
194 return object;
195}
196
197std::pair<int, int> MapObjectEntry::getPosition() const
198{
199 return position;
200}
201
202MapObjectEntry::Item& MapObjectEntry::getItem(std::string str)
203{
204 return items[str];
205}
206
207const std::map<std::string, MapObjectEntry::Item>& MapObjectEntry::getItems() const
208{
209 return items;
210}
211
212void MapObjectEntry::addItem(std::string id, Item& item)
213{
214 items[id] = item;
215}
216
217void MapObjectEntry::setPosition(int x, int y)
218{
219 position = std::make_pair(x, y);
220}
221
222bool MapObjectEntry::operator==(const MapObjectEntry& other) const
223{
224 return (object == other.object) && (position == other.position);
225}
226
227bool MapObjectEntry::operator!=(const MapObjectEntry& other) const
228{
229 return (object != other.object) && (position != other.position);
230}
231
232VariableChoiceValidator::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) 237wxObject* VariableChoiceValidator::Clone() const
238{
239 return new VariableChoiceValidator(world, item);
240}
241
242bool 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
253bool 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); 268bool VariableChoiceValidator::Validate(wxWindow*)
269{
270 return true;
74} 271}
75 272
76wxBitmap MapObject::getSprite() const 273SliderItemValidator::SliderItemValidator(World& world, MapObjectEntry::Item& item) : world(world), item(item)
77{ 274{
78 return sprite; 275
79} 276}
80 277
81std::string MapObject::getAction() const 278wxObject* SliderItemValidator::Clone() const
82{ 279{
83 return action; 280 return new SliderItemValidator(world, item);
84} 281}
85 282
86int MapObject::getWidth() const 283bool 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
91int MapObject::getHeight() const 292bool 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
96std::string MapObject::getType() const 300bool SliderItemValidator::Validate(wxWindow*)
97{ 301{
98 return type; 302 return true;
99} 303}