summaryrefslogtreecommitdiff
path: root/src/resources/mapreader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/resources/mapreader.cpp')
-rw-r--r--src/resources/mapreader.cpp155
1 files changed, 109 insertions, 46 deletions
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index b812b2ce..c4cb7447 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -1,39 +1,39 @@
/*
* The Mana World
- * Copyright 2004 The Mana World Development Team
+ * Copyright (C) 2004 The Mana World Development Team
*
* This file is part of The Mana World.
*
- * The Mana World is free software; you can redistribute it and/or modify
+ * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
- * The Mana World is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with The Mana World; if not, write to the Free Software
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "mapreader.h"
-
#include <cassert>
#include <iostream>
#include <zlib.h>
-#include "resourcemanager.h"
+#include "animation.h"
#include "image.h"
+#include "mapreader.h"
+#include "resourcemanager.h"
#include "../log.h"
#include "../map.h"
#include "../tileset.h"
#include "../utils/base64.h"
-#include "../utils/tostring.h"
+#include "../utils/stringutils.h"
#include "../utils/xml.h"
const unsigned int DEFAULT_TILE_WIDTH = 32;
@@ -205,14 +205,11 @@ Map *MapReader::readMap(xmlNodePtr node, const std::string &path)
// Take the filename off the path
const std::string pathDir = path.substr(0, path.rfind("/") + 1);
- //xmlChar *prop = xmlGetProp(node, BAD_CAST "version");
- //xmlFree(prop);
-
const int w = XML::getProperty(node, "width", 0);
const int h = XML::getProperty(node, "height", 0);
- const int tw = XML::getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH);
- const int th = XML::getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT);
- Map *map = new Map(w, h, tw, th);
+ const int tilew = XML::getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH);
+ const int tileh = XML::getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT);
+ Map *map = new Map(w, h, tilew, tileh);
for_each_xml_child_node(childNode, node)
{
@@ -233,6 +230,12 @@ Map *MapReader::readMap(xmlNodePtr node, const std::string &path)
}
else if (xmlStrEqual(childNode->name, BAD_CAST "objectgroup"))
{
+ // The object group offset is applied to each object individually
+ const int tileOffsetX = XML::getProperty(childNode, "x", 0);
+ const int tileOffsetY = XML::getProperty(childNode, "y", 0);
+ const int offsetX = tileOffsetX * tilew;
+ const int offsetY = tileOffsetY * tileh;
+
for_each_xml_child_node(objectNode, childNode)
{
if (xmlStrEqual(objectNode->name, BAD_CAST "object"))
@@ -253,7 +256,8 @@ Map *MapReader::readMap(xmlNodePtr node, const std::string &path)
const int objY = XML::getProperty(objectNode, "y", 0);
logger->log("- Loading object name: %s type: %s at %d:%d",
- objName.c_str(), objType.c_str(), objX, objY);
+ objName.c_str(), objType.c_str(),
+ objX, objY);
if (objType == "PARTICLE_EFFECT")
{
@@ -262,7 +266,9 @@ Map *MapReader::readMap(xmlNodePtr node, const std::string &path)
continue;
}
- map->addParticleEffect(objName, objX, objY);
+ map->addParticleEffect(objName,
+ objX + offsetX,
+ objY + offsetY);
}
else
{
@@ -297,7 +303,8 @@ void MapReader::readProperties(xmlNodePtr node, Properties *props)
static void setTile(Map *map, MapLayer *layer, int x, int y, int gid)
{
const Tileset * const set = map->getTilesetWithGid(gid);
- if (layer) {
+ if (layer)
+ {
// Set regular tile on a layer
Image * const img = set ? set->get(gid - set->getFirstGid()) : 0;
layer->setTile(x, y, img);
@@ -313,12 +320,12 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
// Layers are not necessarily the same size as the map
const int w = XML::getProperty(node, "width", map->getWidth());
const int h = XML::getProperty(node, "height", map->getHeight());
- const int offsetX = XML::getProperty(node, "xoffset", 0);
- const int offsetY = XML::getProperty(node, "yoffset", 0);
+ const int offsetX = XML::getProperty(node, "x", 0);
+ const int offsetY = XML::getProperty(node, "y", 0);
const std::string name = XML::getProperty(node, "name", "");
- const bool isFringeLayer = (name == "Fringe");
- const bool isCollisionLayer = (name == "Collision");
+ const bool isFringeLayer = (name.substr(0,6) == "Fringe");
+ const bool isCollisionLayer = (name.substr(0,9) == "Collision");
MapLayer *layer = 0;
@@ -361,7 +368,7 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
while (*charStart) {
if (*charStart != ' ' && *charStart != '\t' &&
- *charStart != '\n')
+ *charStart != '\n')
{
*charIndex = *charStart;
charIndex++;
@@ -401,6 +408,12 @@ void MapReader::readLayer(xmlNodePtr node, Map *map)
setTile(map, layer, x, y, gid);
+ TileAnimation* ani = map->getAnimationForGid(gid);
+ if (ani)
+ {
+ ani->addAffectedTile(layer, x + y * w);
+ }
+
x++;
if (x == w) {
x = 0; y++;
@@ -446,46 +459,96 @@ Tileset *MapReader::readTileset(xmlNodePtr node,
const std::string &path,
Map *map)
{
+ int firstGid = XML::getProperty(node, "firstgid", 0);
+ XML::Document* doc = NULL;
+ Tileset *set = NULL;
+
if (xmlHasProp(node, BAD_CAST "source"))
{
- logger->log("Warning: External tilesets not supported yet.");
- return NULL;
+ std::string filename = XML::getProperty(node, "source", "");
+ while (filename.substr(0, 3) == "../")
+ filename.erase(0, 3); // Remove "../"
+ doc = new XML::Document(filename);
+ node = doc->rootNode();
+ firstGid += XML::getProperty(node, "firstgid", 0);
}
- const int firstGid = XML::getProperty(node, "firstgid", 0);
const int tw = XML::getProperty(node, "tilewidth", map->getTileWidth());
const int th = XML::getProperty(node, "tileheight", map->getTileHeight());
for_each_xml_child_node(childNode, node)
{
- if (!xmlStrEqual(childNode->name, BAD_CAST "image"))
- continue;
+ if (xmlStrEqual(childNode->name, BAD_CAST "image"))
+ {
+ const std::string source = XML::getProperty(childNode, "source", "");
- const std::string source = XML::getProperty(childNode, "source", "");
+ if (!source.empty())
+ {
+ std::string sourceStr = source;
+ sourceStr.erase(0, 3); // Remove "../"
+
+ ResourceManager *resman = ResourceManager::getInstance();
+ Image* tilebmp = resman->getImage(sourceStr);
- if (!source.empty())
+ if (tilebmp)
+ {
+ set = new Tileset(tilebmp, tw, th, firstGid);
+ tilebmp->decRef();
+ }
+ else {
+ logger->log("Warning: Failed to load tileset (%s)",
+ source.c_str());
+ }
+ }
+ }
+ else if (xmlStrEqual(childNode->name, BAD_CAST "tile"))
{
- std::string sourceStr = source;
- sourceStr.erase(0, 3); // Remove "../"
+ for_each_xml_child_node(tileNode, childNode)
+ {
+ if (!xmlStrEqual(tileNode->name, BAD_CAST "properties")) continue;
- ResourceManager *resman = ResourceManager::getInstance();
- Image* tilebmp = resman->getImage(sourceStr);
+ int tileGID = firstGid + XML::getProperty(childNode, "id", 0);
- if (tilebmp)
- {
- Tileset *set = new Tileset(tilebmp, tw, th, firstGid);
- tilebmp->decRef();
- return set;
- }
- else {
- logger->log("Warning: Failed to load tileset (%s)",
- source.c_str());
+ // read tile properties to a map for simpler handling
+ std::map<std::string, int> tileProperties;
+ for_each_xml_child_node(propertyNode, tileNode)
+ {
+ if (!xmlStrEqual(propertyNode->name, BAD_CAST "property")) continue;
+ std::string name = XML::getProperty(propertyNode, "name", "");
+ int value = XML::getProperty(propertyNode, "value", 0);
+ tileProperties[name] = value;
+ logger->log("Tile Prop of %d \"%s\" = \"%d\"", tileGID, name.c_str(), value);
+ }
+
+ // create animation
+ if (!set) continue;
+
+ Animation *ani = new Animation;
+ for (int i = 0; ;i++)
+ {
+ std::map<std::string, int>::iterator iFrame, iDelay;
+ iFrame = tileProperties.find("animation-frame" + toString(i));
+ iDelay = tileProperties.find("animation-delay" + toString(i));
+ if (iFrame != tileProperties.end() && iDelay != tileProperties.end())
+ {
+ ani->addFrame(set->get(iFrame->second), iDelay->second, 0, 0);
+ } else {
+ break;
+ }
+ }
+
+ if (ani->getLength() > 0)
+ {
+ map->addAnimation(tileGID, new TileAnimation(ani));
+ logger->log("Animation length: %d", ani->getLength());
+ } else {
+ delete ani;
+ }
}
}
-
- // Only one image element expected
- break;
}
- return NULL;
+ delete doc;
+
+ return set;
}