Fixed bug where external tileset firstgid would be incorrect

I fixed a bug where the firstgid variable would be wrong when parsing TMX files which contain external tilesets.

For example you might have a TMX file that looks like this:

map.tmx

...

actions.tsx

...

It would try to read the firstgid attribute from actions.tsx instead of map.tmx (and hence get it wrong, 0 instead of 1). This caused all the tile properties in my actions.tsx to be out of whack. I’ve attached the patch as a seperate file, I’ll also include the contents below if that’s easier:

From 48ab7e84eff367c752d3800a50c6f3ed7c6194ad Mon Sep 17 00:00:00 2001
From: Martin Sherburn 
Date: Tue, 1 Nov 2011 21:39:09 +0000
Subject: [PATCH] Fixed bug where external tileset firstgid would be incorrect

---
 cocos2dx/include/CCTMXXMLParser.h                  |    2 ++
 cocos2dx/tileMap_parallax_nodes/CCTMXXMLParser.cpp |    5 ++++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/cocos2dx/include/CCTMXXMLParser.h b/cocos2dx/include/CCTMXXMLParser.h
index 34f7617..9ab37ad 100755
--- a/cocos2dx/include/CCTMXXMLParser.h
+++ b/cocos2dx/include/CCTMXXMLParser.h
@@ -183,6 +183,8 @@ namespace cocos2d {
        std::string m_sCurrentString;
        //! tile properties
        CCDictionary* m_pTileProperties;
+       //! first gid of external tileset
+       unsigned int m_uExternalFirstGid;
    };

 }// namespace cocos2d
diff --git a/cocos2dx/tileMap_parallax_nodes/CCTMXXMLParser.cpp b/cocos2dx/tileMap_parallax_nodes/CCTMXXMLParser.cpp
index 9819fe5..b2f0fbf 100644
--- a/cocos2dx/tileMap_parallax_nodes/CCTMXXMLParser.cpp
+++ b/cocos2dx/tileMap_parallax_nodes/CCTMXXMLParser.cpp
@@ -160,6 +160,7 @@ namespace cocos2d {
         ,m_bStoringCharacters(false)       
        ,m_pProperties(NULL)
        ,m_pTileProperties(NULL)
+       ,m_uExternalFirstGid(0)
    {
    }
    CCTMXMapInfo::~CCTMXMapInfo()
@@ -289,13 +290,15 @@ namespace cocos2d {
            if (externalTilesetFilename != "")
            {
                externalTilesetFilename = CCFileUtils::fullPathFromRelativeFile(externalTilesetFilename.c_str(), pTMXMapInfo->getTMXFileName());
+               m_uExternalFirstGid = (unsigned int)atoi(valueForKey("firstgid", attributeDict));
                pTMXMapInfo->parseXMLFile(externalTilesetFilename.c_str());
+               m_uExternalFirstGid = 0;
            }
            else
            {
                CCTMXTilesetInfo *tileset = new CCTMXTilesetInfo();
                tileset->m_sName = valueForKey("name", attributeDict);
-               tileset->m_uFirstGid = (unsigned int)atoi(valueForKey("firstgid", attributeDict));
+               tileset->m_uFirstGid = m_uExternalFirstGid ? m_uExternalFirstGid : (unsigned int)atoi(valueForKey("firstgid", attributeDict));
                tileset->m_uSpacing = (unsigned int)atoi(valueForKey("spacing", attributeDict));
                tileset->m_uMargin = (unsigned int)atoi(valueForKey("margin", attributeDict));
                CCSize s;
-- 
1.5.6.1.1071.g76fb


0001-external-tileset-bug.patch.zip (1.1 KB)

Is it because the engine doesn’t support the version of the generated TMX files?

Yes maybe, I created these files with Tiled Map Editor v0.7.1 which is the latest version as of the time of writing. And certainly with this version the firstgid attribute is not within the .tsx file. However, I’ve just looked inside the cocos2d-x tests folder at tests/Res/TileMaps/orthogonal-test1.tmx & orthogonal-test1.tsx. In these files the firstgid attribute is specified in both the .tmx AND the .tsx file. So it looks like the format has indeed changed in the latest version of Tiled Map Editor. With my code change the firstgid attribute in the parent .tmx will take precedence over the .tsx file. Which in my mind makes more sense because the gid should be unique across all tilesets, and if you were to import 2 different .tsx files which had the same firstgid attribute or overlaping gids then you would have a problem. If you specify the firstgid in the TMX file then you can ensure the gids are unique across all tilesets, which I imagine is what prompted the change to the file format.