summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-02-11 20:59:12 +0300
committerAndrei Karas <akaras@inbox.ru>2014-02-11 22:24:04 +0300
commitaf8863d722f06153877d289b939b5ba84713621d (patch)
treecbb97e2ea203d40615c49803c50b7f3c82f53ad6
parent0148cb8ad0e071464f09ada9eb41625dee038cb8 (diff)
downloadmanaplus-af8863d722f06153877d289b939b5ba84713621d.tar.gz
manaplus-af8863d722f06153877d289b939b5ba84713621d.tar.bz2
manaplus-af8863d722f06153877d289b939b5ba84713621d.tar.xz
manaplus-af8863d722f06153877d289b939b5ba84713621d.zip
add support for map layer replacments.
This can be used for mods.
-rw-r--r--src/resources/beingcommon.cpp6
-rw-r--r--src/resources/beingcommon.h24
-rw-r--r--src/resources/db/colordb.cpp2
-rw-r--r--src/resources/db/itemdb.cpp4
-rw-r--r--src/resources/mapreader.cpp82
-rw-r--r--src/resources/mapreader.h16
-rw-r--r--src/utils/xml.h3
7 files changed, 112 insertions, 25 deletions
diff --git a/src/resources/beingcommon.cpp b/src/resources/beingcommon.cpp
index 7b7a57d9e..388312b34 100644
--- a/src/resources/beingcommon.cpp
+++ b/src/resources/beingcommon.cpp
@@ -49,7 +49,9 @@ void BeingCommon::readBasicAttributes(BeingInfo *const info,
info->setHpBarOffsetY(XML::getProperty(node, "hpBarOffsetY", 0));
}
-void BeingCommon::getIncludeFiles(const std::string &dir, StringVect &list)
+void BeingCommon::getIncludeFiles(const std::string &dir,
+ StringVect &list,
+ const std::string &ext)
{
const std::string path = dir + "/";
StringVect tempList;
@@ -57,7 +59,7 @@ void BeingCommon::getIncludeFiles(const std::string &dir, StringVect &list)
FOR_EACH (StringVectCIter, it, tempList)
{
const std::string &str = *it;
- if (findLast(str, ".xml"))
+ if (findLast(str, ext))
list.push_back(str);
}
std::sort(list.begin(), list.end());
diff --git a/src/resources/beingcommon.h b/src/resources/beingcommon.h
index 6124de5a1..2c9741a2c 100644
--- a/src/resources/beingcommon.h
+++ b/src/resources/beingcommon.h
@@ -30,11 +30,21 @@
class BeingInfo;
#define loadXmlDir(name, function) \
- StringVect listVect; \
- BeingCommon::getIncludeFiles(paths.getStringValue( \
- name), listVect); \
- FOR_EACH (StringVectCIter, itVect, listVect) \
- function(*itVect);
+ { \
+ StringVect listVect; \
+ BeingCommon::getIncludeFiles(paths.getStringValue( \
+ name), listVect, ".xml"); \
+ FOR_EACH (StringVectCIter, itVect, listVect) \
+ function(*itVect); \
+ }
+
+#define loadXmlDir2(name, function, ext) \
+ { \
+ StringVect listVect; \
+ BeingCommon::getIncludeFiles(name, listVect, ext); \
+ FOR_EACH (StringVectCIter, itVect, listVect) \
+ function(*itVect); \
+ }
namespace BeingCommon
{
@@ -42,7 +52,9 @@ namespace BeingCommon
XmlNodePtrConst node,
const std::string &hoverCursor);
- void getIncludeFiles(const std::string &dir, StringVect &list);
+ void getIncludeFiles(const std::string &dir,
+ StringVect &list,
+ const std::string &ext);
}
#endif // RESOURCES_BEINGCOMMON_H
diff --git a/src/resources/db/colordb.cpp b/src/resources/db/colordb.cpp
index 630c1c902..a358bebe7 100644
--- a/src/resources/db/colordb.cpp
+++ b/src/resources/db/colordb.cpp
@@ -53,7 +53,7 @@ void ColorDB::load()
loadHair(paths.getStringValue("hairColorPatchFile"), colors);
StringVect list;
BeingCommon::getIncludeFiles(paths.getStringValue(
- "hairColorPatchDir"), list);
+ "hairColorPatchDir"), list, ".xml");
FOR_EACH (StringVectCIter, it2, list)
loadHair(*it2, colors);
diff --git a/src/resources/db/itemdb.cpp b/src/resources/db/itemdb.cpp
index abc164493..931377639 100644
--- a/src/resources/db/itemdb.cpp
+++ b/src/resources/db/itemdb.cpp
@@ -217,7 +217,9 @@ void ItemDB::load()
loadXmlFile(paths.getStringValue("itemsPatchFile"), tagNum);
StringVect list;
- BeingCommon::getIncludeFiles(paths.getStringValue("itemsPatchDir"), list);
+ BeingCommon::getIncludeFiles(paths.getStringValue("itemsPatchDir"),
+ list,
+ ".xml");
FOR_EACH (StringVectCIter, it, list)
loadXmlFile(*it, tagNum);
}
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index 1e59b1673..5cf6d3337 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -30,6 +30,7 @@
#include "tileset.h"
#include "resources/animation.h"
+#include "resources/beingcommon.h"
#include "resources/image.h"
#include "resources/resourcemanager.h"
@@ -42,6 +43,15 @@
#include "debug.h"
+typedef std::map<std::string, XmlNodePtr>::iterator LayerInfoIterator;
+typedef std::set<XML::Document*>::iterator DocIterator;
+
+namespace
+{
+ std::map<std::string, XmlNodePtr> mKnownLayers;
+ std::set<XML::Document*> mKnownDocs;
+} // namespace
+
static int inflateMemory(unsigned char *restrict const in,
const unsigned int inLength,
unsigned char *&restrict out,
@@ -182,28 +192,47 @@ int inflateMemory(unsigned char *restrict const in,
return outLength;
}
+void MapReader::addLayerToList(const std::string &fileName)
+{
+ XML::Document *doc = new XML::Document(fileName);
+ XmlNodePtrConst node = doc->rootNode();
+ if (!node)
+ {
+ delete doc;
+ return;
+ }
+
+ for_each_xml_child_node(childNode, node)
+ {
+ if (!xmlNameEqual(childNode, "layer"))
+ continue;
+ std::string name = XML::getProperty(childNode, "name", "");
+ if (name.empty())
+ continue;
+ name = toLower(name);
+ logger->log("found patch layer: " + name);
+ LayerInfoIterator it = mKnownLayers.find(name);
+ mKnownLayers[name] = childNode;
+ mKnownDocs.insert(doc);
+ }
+}
+
Map *MapReader::readMap(const std::string &restrict filename,
const std::string &restrict realFilename)
{
BLOCK_START("MapReader::readMap")
logger->log("Attempting to read map %s", realFilename.c_str());
- // Load the file through resource manager
- const ResourceManager *const resman = ResourceManager::getInstance();
- int fileSize;
- void *const buffer = resman->loadFile(realFilename, fileSize);
- Map *map = nullptr;
- if (!buffer)
+ XML::Document doc(realFilename);
+ if (!doc.isLoaded())
{
BLOCK_END("MapReader::readMap")
return createEmptyMap(filename, realFilename);
}
- XML::Document doc(reinterpret_cast<const char*>(buffer), fileSize);
- free(buffer);
-
XmlNodePtrConst node = doc.rootNode();
+ Map *map = nullptr;
// Parse the inflated map data
if (node)
{
@@ -231,6 +260,24 @@ Map *MapReader::readMap(const std::string &restrict filename,
return map;
}
+void MapReader::loadLayers(const std::string &path)
+{
+ loadXmlDir2(path, addLayerToList, ".tmx");
+}
+
+void MapReader::unloadTempLayers()
+{
+ FOR_EACH (DocIterator, it, mKnownDocs)
+ delete (*it);
+ mKnownLayers.clear();
+ mKnownDocs.clear();
+}
+
+static void loadReplaceLayer(LayerInfoIterator &it, Map *const map)
+{
+ MapReader::readLayer((*it).second, map);
+}
+
Map *MapReader::readMap(XmlNodePtrConst node, const std::string &path)
{
if (!node)
@@ -256,6 +303,9 @@ Map *MapReader::readMap(XmlNodePtrConst node, const std::string &path)
return nullptr;
}
+ logger->log("loading replace layer list");
+ loadLayers(path + "_replace.d");
+
Map *const map = new Map(w, h, tilew, tileh);
const std::string fileName = path.substr(path.rfind("/") + 1);
@@ -284,7 +334,18 @@ Map *MapReader::readMap(XmlNodePtrConst node, const std::string &path)
}
else if (xmlNameEqual(childNode, "layer"))
{
- readLayer(childNode, map);
+ std::string name = XML::getProperty(childNode, "name", "");
+ name = toLower(name);
+ LayerInfoIterator it = mKnownLayers.find(name);
+ if (it == mKnownLayers.end())
+ {
+ readLayer(childNode, map);
+ }
+ else
+ {
+ logger->log("load replace layer: " + name);
+ loadReplaceLayer(it, map);
+ }
}
else if (xmlNameEqual(childNode, "properties"))
{
@@ -377,6 +438,7 @@ Map *MapReader::readMap(XmlNodePtrConst node, const std::string &path)
map->setActorsFix(0, atoi(map->getProperty("actorsfix").c_str()));
map->reduce();
map->setWalkLayer(resman->getWalkLayer(fileName, map));
+ unloadTempLayers();
return map;
}
diff --git a/src/resources/mapreader.h b/src/resources/mapreader.h
index 4f84f1a1a..27cbd665b 100644
--- a/src/resources/mapreader.h
+++ b/src/resources/mapreader.h
@@ -59,6 +59,11 @@ class MapReader final
const std::string &restrict realFilename)
A_WARN_UNUSED;
+ /**
+ * Reads a map layer and adds it to the given map.
+ */
+ static void readLayer(const XmlNodePtr node, Map *const map);
+
private:
/**
* Reads the properties element.
@@ -70,11 +75,6 @@ class MapReader final
static void readProperties(const XmlNodePtrConst node,
Properties *const props);
- /**
- * Reads a map layer and adds it to the given map.
- */
- static void readLayer(const XmlNodePtr node, Map *const map);
-
static bool readBase64Layer(const XmlNodePtrConst childNode,
Map *const map,
MapLayer *const layer,
@@ -100,6 +100,12 @@ class MapReader final
Map *const map) A_WARN_UNUSED;
static void updateMusic(Map *const map);
+
+ static void addLayerToList(const std::string &fileName);
+
+ static void loadLayers(const std::string &path);
+
+ static void unloadTempLayers();
};
#endif // RESOURCES_MAPREADER_H
diff --git a/src/utils/xml.h b/src/utils/xml.h
index 5c1fb7605..48d60cda7 100644
--- a/src/utils/xml.h
+++ b/src/utils/xml.h
@@ -90,6 +90,9 @@ namespace XML
*/
XmlNodePtr rootNode() A_WARN_UNUSED;
+ bool isLoaded() const
+ { return mDoc != nullptr; }
+
private:
xmlDocPtr mDoc;
};