summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Cotton <steve@s.cotton.clara.co.uk>2009-04-03 03:11:15 +0100
committerBjørn Lindeijer <bjorn@lindeijer.nl>2009-04-16 11:34:39 +0200
commitbb216d7fb966156b8ea2ecb284b680309b92585b (patch)
treec418b5e455cb8e01eb30e091d040c7a0256d0dc6
parent1d48fa06e9f1bdca6ca28b2b43c8a1bc01a96dca (diff)
downloadmana-bb216d7fb966156b8ea2ecb284b680309b92585b.tar.gz
mana-bb216d7fb966156b8ea2ecb284b680309b92585b.tar.bz2
mana-bb216d7fb966156b8ea2ecb284b680309b92585b.tar.xz
mana-bb216d7fb966156b8ea2ecb284b680309b92585b.zip
Collision layer generation tool
-rw-r--r--tools/tmxcopy/Makefile5
-rw-r--r--tools/tmxcopy/map.cpp70
-rw-r--r--tools/tmxcopy/map.hpp18
-rw-r--r--tools/tmxcopy/tmxcollide.cpp104
4 files changed, 196 insertions, 1 deletions
diff --git a/tools/tmxcopy/Makefile b/tools/tmxcopy/Makefile
index 975e1980..d061f36e 100644
--- a/tools/tmxcopy/Makefile
+++ b/tools/tmxcopy/Makefile
@@ -3,7 +3,7 @@ CFLAGS=-g -ggdb -O0 -Wall -c `pkg-config --cflags libxml-2.0`
LDFLAGS=`pkg-config --libs libxml-2.0`
SOURCES_UTILS=base64.cpp map.cpp xmlutils.cpp zlibutils.cpp
OBJECTS_UTILS=$(SOURCES_UTILS:.cpp=.o)
-EXECUTABLES=tmxcopy tmx_random_fill
+EXECUTABLES=tmxcopy tmx_random_fill tmxcollide
all: $(SOURCES_UTILS) $(EXECUTABLES)
make clean
@@ -14,6 +14,9 @@ tmxcopy: tmxcopy.o $(OBJECTS_UTILS)
tmx_random_fill: tmx_random_fill.o $(OBJECTS_UTILS)
$(CC) $(LDFLAGS) tmx_random_fill.o $(OBJECTS_UTILS) -o $@
+tmxcollide: tmxcollide.o $(OBJECTS_UTILS)
+ $(CC) $(LDFLAGS) tmxcollide.o $(OBJECTS_UTILS) -o $@
+
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
diff --git a/tools/tmxcopy/map.cpp b/tools/tmxcopy/map.cpp
index 30f16a2d..109d1742 100644
--- a/tools/tmxcopy/map.cpp
+++ b/tools/tmxcopy/map.cpp
@@ -440,6 +440,76 @@ bool Map::randomFill(Map* templateMap, const std::string& destLayerName,
return true;
}
+bool Map::translateAllLayers(Map* templateMap, const std::string& destLayerName,
+ const ConfigurationOptions& config)
+{
+ bool checkPassed = true;
+ if (templateMap->getNumberOfLayers() != 2)
+ {
+ std::cerr<<"Error: template should have exactly 2 layers"<<std::endl;
+ checkPassed = false;
+ }
+ if (!config.createMissingLayers && !getLayer(destLayerName))
+ {
+ std::cerr<<"Error: target map has no layer named \""<<destLayerName<<"\""<<std::endl
+ <<"(and the command-line \"create layers\" option was not used)"<<std::endl;
+ checkPassed = false;
+ }
+ if (!checkPassed) return false;
+
+ //FIXME - as is, this will add tilesets that are in the template but
+ //not used in the main map
+ std::map<int, int> tilesetTranslation = addAndTranslateTilesets(templateMap);
+
+ //Lacking a better name, we'll say this is translating visible layers to collision
+ std::map<Tile, Tile> collisionTranslation;
+
+ Layer* fromLayer = templateMap->getLayer(0);
+ Layer* toLayer = templateMap->getLayer(1);
+ for (int xy = (templateMap->getWidth() * templateMap->getHeight() -1);
+ xy >= 0; xy--)
+ {
+ Tile& fromTile = fromLayer->at(xy);
+ Tile& toTile = toLayer->at(xy);
+ if (!fromTile.empty())
+ {
+ collisionTranslation[fromTile] = toTile; //FIXME - just getting it compiling so far
+ }
+ }
+
+ /* Now apply that template to the game map */
+ Layer* destLayer = getLayer(destLayerName);
+ if (!destLayer)
+ {
+ destLayer = new Layer(destLayerName, mWidth * mHeight);
+ mLayers.push_back(destLayer);
+ std::cout<<"Created new layer "<<destLayerName<<std::endl;
+ }
+
+ for (std::vector<Layer*>::iterator layer = mLayers.begin();
+ layer != mLayers.end();
+ layer++)
+ {
+ if ((*layer)->getName() == destLayerName)
+ continue;
+
+ for (int xy = mWidth * mHeight -1; xy >= 0; xy--)
+ {
+ Tile& fromTile = (*layer)->at(xy);
+ Tile& toTile = destLayer->at(xy);
+ std::map<Tile,Tile>::iterator iteratedTile = collisionTranslation.find(fromTile);
+
+ if (iteratedTile != collisionTranslation.end())
+ {
+ toTile = (*iteratedTile).second;
+ }
+ }
+
+ }
+
+ return true;
+}
+
int Map::save(std::string filename)
diff --git a/tools/tmxcopy/map.hpp b/tools/tmxcopy/map.hpp
index 4b0ab59a..d6cd3d1a 100644
--- a/tools/tmxcopy/map.hpp
+++ b/tools/tmxcopy/map.hpp
@@ -78,6 +78,17 @@ struct Tile
{
return (tileset == -1);
}
+
+ /* This is to allow std::map<Tile,Tile> */
+ bool operator< (const Tile& b) const
+ {
+ return ((tileset < b.tileset) || (index < b.index));
+ }
+
+ bool operator!= (const Tile& b) const
+ {
+ return ((tileset != b.tileset) || (index != b.index));
+ }
};
typedef std::vector<Tile> LayerTiles;
@@ -131,6 +142,13 @@ class Map
int destX, int destY, int destWidth, int destHeight,
const ConfigurationOptions& config);
+ /**
+ * Translates a layer - using the template, generates collision from visible layers (for example).
+ * TODO - avoid confusion with the math term "translate"
+ */
+ bool translateAllLayers(Map* templateMap, const std::string& destLayerName,
+ const ConfigurationOptions& config);
+
int save(std::string filename);
int getNumberOfLayers() { return mLayers.size(); }
diff --git a/tools/tmxcopy/tmxcollide.cpp b/tools/tmxcopy/tmxcollide.cpp
new file mode 100644
index 00000000..2ce6f90b
--- /dev/null
+++ b/tools/tmxcopy/tmxcollide.cpp
@@ -0,0 +1,104 @@
+/*
+ * TMXTranslate / TMXCollide
+ * Copyright (C) 2007 Philipp Sehmisch
+ * Copyright (C) 2009 Steve Cotton
+ *
+ * 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.
+ *
+ * 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <iostream>
+#include <string>
+#include <unistd.h>
+
+#include "map.hpp"
+
+void printUsage()
+{
+ std::cerr<<"Usage: tmxcollide [-c] mapFile destLayer templateFile [-o outfile]"<<std::endl
+ <<" -c create layers, if they don't already exist in the target"<<std::endl
+ <<" -o save results to outfile, instead of overwriting the original"<<std::endl
+ <<std::endl
+ <<"Using the template, translate visible layers to the collision layer"<<std::endl
+ <<"TODO - more help here"<<std::endl;
+}
+
+int main(int argc, char * argv[] )
+{
+ ConfigurationOptions config = {0};
+ std::string outFile;
+
+ int opt;
+ while ((opt = getopt(argc, argv, "co:")) != -1)
+ {
+ switch (opt)
+ {
+ case 'c':
+ config.createMissingLayers = true;
+ break;
+ case 'o':
+ if (optarg)
+ {
+ outFile = optarg;
+ } else {
+ printUsage();
+ return -1;
+ }
+ break;
+ case '?':
+ std::cerr<<"Unrecognized option"<<std::endl;
+ printUsage();
+ return -1;
+ }
+ }
+
+ if ((argc-optind) < 3)
+ {
+ std::cerr<<"Too few args"<<std::endl;
+ printUsage();
+ return -1;
+ }
+ if ((argc-optind) > 3)
+ {
+ std::cerr<<"Too many args"<<std::endl;
+ printUsage();
+ return -1;
+ }
+
+ std::string mapFile = argv[optind+0];
+ std::string destLayer = argv[optind+1];
+ std::string templateFile = argv[optind+2];
+ if (outFile.empty())
+ {
+ outFile = mapFile;
+ }
+
+ try
+ {
+ Map* mainMap = new Map(mapFile);
+ Map* templateMap = new Map(templateFile);
+ if (mainMap->translateAllLayers(templateMap, destLayer, config))
+ {
+ mainMap->save(outFile);
+ } else {
+ return -1;
+ }
+ delete mainMap;
+ delete templateMap;
+ }
+ catch (int)
+ {
+ return -1;
+ }
+}