From 25240241e91dc913d20fbb93aa4acc9433dda6a0 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sun, 15 Mar 2015 20:58:02 -0400 Subject: Map editor can now save and load (but not edit) entities in maps --- tools/mapedit/CMakeLists.txt | 1 + tools/mapedit/src/map.cpp | 64 ++++++++++++++++++++++++---- tools/mapedit/src/map.h | 11 +++++ tools/mapedit/src/object.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++++ tools/mapedit/src/object.h | 47 +++++++++++++++++++++ tools/mapedit/src/widget.cpp | 12 ++++++ 6 files changed, 227 insertions(+), 7 deletions(-) create mode 100644 tools/mapedit/src/object.cpp create mode 100644 tools/mapedit/src/object.h (limited to 'tools') diff --git a/tools/mapedit/CMakeLists.txt b/tools/mapedit/CMakeLists.txt index ffc9f05..9343f06 100644 --- a/tools/mapedit/CMakeLists.txt +++ b/tools/mapedit/CMakeLists.txt @@ -43,6 +43,7 @@ add_executable(AromatherapyMapEditor src/frame.cpp src/widget.cpp src/tile_widget.cpp + src/object.cpp ) target_link_libraries(AromatherapyMapEditor ${ALL_LIBS}) install(TARGETS AromatherapyMapEditor RUNTIME DESTINATION ${BIN_DIR}) diff --git a/tools/mapedit/src/map.cpp b/tools/mapedit/src/map.cpp index 3a24ace..b0440fb 100644 --- a/tools/mapedit/src/map.cpp +++ b/tools/mapedit/src/map.cpp @@ -54,6 +54,31 @@ Map::Map(std::string filename) xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); rightmap = (char*) key; xmlFree(key); + } else if (!xmlStrcmp(node->name, (const xmlChar*) "entities")) + { + for (xmlNodePtr entityNode = node->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next) + { + if (!xmlStrcmp(entityNode->name, (const xmlChar*) "entity")) + { + MapObjectEntry data; + for (xmlNodePtr entityDataNode = entityNode->xmlChildrenNode; entityDataNode != NULL; entityDataNode = entityDataNode->next) + { + if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-type")) + { + xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1); + data.object = MapObject::getAllObjects().at((char*) key); + xmlFree(key); + } else if (!xmlStrcmp(entityDataNode->name, (const xmlChar*) "entity-position")) + { + xmlChar* key = xmlNodeListGetString(doc, entityDataNode->xmlChildrenNode, 1); + sscanf((char*) key, "%lf,%lf", &data.position.first, &data.position.second); + xmlFree(key); + } + } + + objects.push_back(data); + } + } } } @@ -69,6 +94,7 @@ Map::Map(const Map& map) leftmap = map.leftmap; rightmap = map.rightmap; dirty = map.dirty; + objects = map.objects; } Map::Map(Map&& map) : Map() @@ -95,6 +121,7 @@ void swap(Map& first, Map& second) std::swap(first.leftmap, second.leftmap); std::swap(first.rightmap, second.rightmap); std::swap(first.dirty, second.dirty); + std::swap(first.objects, second.objects); } #define MY_ENCODING "ISO-8859-1" @@ -131,21 +158,39 @@ void Map::save(std::string name) rc = xmlTextWriterWriteElement(writer, (xmlChar*) "environment", (xmlChar*) mapdata_out.str().c_str()); if (rc < 0) throw MapWriteException(name); - if (leftmap != "") - { - rc = xmlTextWriterWriteElement(writer, (xmlChar*) "leftmap", (xmlChar*) leftmap.c_str()); - if (rc < 0) throw MapWriteException(name); - } + rc = xmlTextWriterWriteElement(writer, (xmlChar*) "leftmap", (xmlChar*) leftmap.c_str()); + if (rc < 0) throw MapWriteException(name); + + rc = xmlTextWriterWriteElement(writer, (xmlChar*) "rightmap", (xmlChar*) rightmap.c_str()); + if (rc < 0) throw MapWriteException(name); - if (rightmap != "") + rc = xmlTextWriterStartElement(writer, (xmlChar*) "entities"); + if (rc < 0) throw MapWriteException(name); + + for (auto object : objects) { - rc = xmlTextWriterWriteElement(writer, (xmlChar*) "rightmap", (xmlChar*) rightmap.c_str()); + rc = xmlTextWriterStartElement(writer, (xmlChar*) "entity"); + if (rc < 0) throw MapWriteException(name); + + rc = xmlTextWriterWriteElement(writer, (xmlChar*) "entity-type", (xmlChar*) object.object->getType().c_str()); + if (rc < 0) throw MapWriteException(name); + + std::ostringstream entpos_out; + entpos_out << object.position.first << "," << object.position.second; + + rc = xmlTextWriterWriteElement(writer, (xmlChar*) "entity-position", (xmlChar*) entpos_out.str().c_str()); + if (rc < 0) throw MapWriteException(name); + + rc = xmlTextWriterEndElement(writer); if (rc < 0) throw MapWriteException(name); } rc = xmlTextWriterEndElement(writer); if (rc < 0) throw MapWriteException(name); + rc = xmlTextWriterEndElement(writer); + if (rc < 0) throw MapWriteException(name); + rc = xmlTextWriterEndDocument(writer); if (rc < 0) throw MapWriteException(name); @@ -180,3 +225,8 @@ void Map::setTitle(std::string title) dirty = true; this->title = title; } + +std::list Map::getObjects() +{ + return objects; +} diff --git a/tools/mapedit/src/map.h b/tools/mapedit/src/map.h index 45ec7e1..52e047d 100644 --- a/tools/mapedit/src/map.h +++ b/tools/mapedit/src/map.h @@ -3,6 +3,10 @@ #include #include +#include +#include +#include "object.h" +#include const int TILE_WIDTH = 8; const int TILE_HEIGHT = 8; @@ -39,6 +43,11 @@ class MapWriteException: public std::exception std::string mapname; }; +struct MapObjectEntry { + std::shared_ptr object; + std::pair position; +}; + class Map { public: Map(); @@ -55,8 +64,10 @@ class Map { bool hasUnsavedChanges() const; void setTileAt(int x, int y, int tile); int getTileAt(int x, int y) const; + std::list getObjects(); private: + std::list objects; int* mapdata; std::string title; std::string leftmap; diff --git a/tools/mapedit/src/object.cpp b/tools/mapedit/src/object.cpp new file mode 100644 index 0000000..4cd267d --- /dev/null +++ b/tools/mapedit/src/object.cpp @@ -0,0 +1,99 @@ +#include "object.h" +#include +#include +#include + +static std::map> allObjects; +static bool objsInit = false; + +const std::map> MapObject::getAllObjects() +{ + if (!objsInit) + { + DIR* dir = opendir("../../../entities/"); + if (dir != NULL) + { + struct dirent* ent; + while ((ent = readdir(dir)) != NULL) + { + std::string path = ent->d_name; + if ((path.length() >= 4) && (path.substr(path.length() - 4, 4) == ".xml")) + { + std::string name = path.substr(0, path.length() - 4); + auto obj = std::make_shared(name.c_str()); + + allObjects[name] = obj; + } + } + } + + objsInit = true; + } + + return allObjects; +} + +MapObject::MapObject(const char* filename) +{ + type = filename; + + xmlDocPtr doc = xmlParseFile(("../../../entities/" + std::string(filename) + ".xml").c_str()); + if (doc == nullptr) throw MapObjectLoadException(filename); + + xmlNodePtr top = xmlDocGetRootElement(doc); + if (top == nullptr) throw MapObjectLoadException(filename); + + if (xmlStrcmp(top->name, (const xmlChar*) "entity-def")) + { + throw MapObjectLoadException(filename); + } + + for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next) + { + if (!xmlStrcmp(node->name, (const xmlChar*) "sprite")) + { + xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + std::string spriteFile = (char*) key; + xmlFree(key); + + sprite = wxImage("../../" + spriteFile); + } else if (!xmlStrcmp(node->name, (const xmlChar*) "action")) + { + xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + action = (char*) key; + xmlFree(key); + } else if (!xmlStrcmp(node->name, (const xmlChar*) "size")) + { + xmlChar* key = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + sscanf((char*) key, "%d,%d", &width, &height); + xmlFree(key); + } + } + + xmlFreeDoc(doc); +} + +wxBitmap MapObject::getSprite() const +{ + return sprite; +} + +std::string MapObject::getAction() const +{ + return action; +} + +int MapObject::getWidth() const +{ + return width; +} + +int MapObject::getHeight() const +{ + return height; +} + +std::string MapObject::getType() const +{ + return type; +} diff --git a/tools/mapedit/src/object.h b/tools/mapedit/src/object.h new file mode 100644 index 0000000..bfb493c --- /dev/null +++ b/tools/mapedit/src/object.h @@ -0,0 +1,47 @@ +#ifndef OBJECT_H +#define OBJECT_H + +#include + +#ifndef WX_PRECOMP +#include +#endif + +#include +#include + +class MapObjectLoadException: public std::exception +{ + public: + MapObjectLoadException(std::string mapname) : mapname(mapname) {} + + virtual const char* what() const throw() + { + return ("An error occured loading map object " + mapname).c_str(); + } + + private: + std::string mapname; +}; + +class MapObject { + public: + MapObject(const char* filename); + + static const std::map> getAllObjects(); + + std::string getType() const; + wxBitmap getSprite() const; + std::string getAction() const; + int getWidth() const; + int getHeight() const; + + private: + std::string type; + wxBitmap sprite; + std::string action; + int width; + int height; +}; + +#endif diff --git a/tools/mapedit/src/widget.cpp b/tools/mapedit/src/widget.cpp index 9c8dae3..d7f1a51 100644 --- a/tools/mapedit/src/widget.cpp +++ b/tools/mapedit/src/widget.cpp @@ -53,12 +53,24 @@ void MapeditWidget::OnPaint(wxPaintEvent& event) } } + for (auto object : map->getObjects()) + { + tiles_dc.SelectObject(wxNullBitmap); + + wxBitmap sprite = object.object->getSprite(); + tiles_dc.SelectObject(sprite); + + dc.StretchBlit(object.position.first*scale-vX, object.position.second*scale-vY, object.object->getWidth()*scale, object.object->getHeight()*scale, &tiles_dc, 0, 0, object.object->getWidth(), object.object->getHeight()); + } + if (mouseIsIn) { int tile = tileWidget->getSelected(); int x = (mousePos.x + vX) / (TILE_WIDTH * scale); int y = (mousePos.y + vY) / (TILE_HEIGHT * scale); + tiles_dc.SelectObject(wxNullBitmap); + tiles_dc.SelectObject(tiles); dc.StretchBlit(x*TILE_WIDTH*scale-vX, y*TILE_HEIGHT*scale-vY, TILE_WIDTH*scale, TILE_HEIGHT*scale, &tiles_dc, tile%8*TILE_WIDTH, tile/8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); wxPen pen(*wxGREEN, 2); -- cgit 1.4.1