|
|
|
@ -31,7 +31,7 @@ struct LayerTag{ |
|
|
|
|
|
|
|
|
|
struct SpawnerTag{ |
|
|
|
|
XMLTag ObjectData; |
|
|
|
|
std::vector<XMLTag>properties; |
|
|
|
|
std::vector<XMLTag>monsters; |
|
|
|
|
std::string str(); |
|
|
|
|
friend std::ostream& operator << (std::ostream& os, SpawnerTag& rhs); |
|
|
|
|
}; |
|
|
|
@ -40,10 +40,10 @@ struct Map{ |
|
|
|
|
MapTag MapData; |
|
|
|
|
std::vector<XMLTag> TilesetData; |
|
|
|
|
std::vector<LayerTag> LayerData; |
|
|
|
|
std::vector<SpawnerTag> SpawnerData; |
|
|
|
|
std::map<int,SpawnerTag> SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID.
|
|
|
|
|
std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData; |
|
|
|
|
std::string FormatLayerData(std::ostream& os, std::vector<LayerTag>tiles); |
|
|
|
|
std::string FormatSpawnerData(std::ostream& os, std::vector<SpawnerTag>tiles); |
|
|
|
|
std::string FormatSpawnerData(std::ostream& os, std::map<int,SpawnerTag>tiles); |
|
|
|
|
friend std::ostream& operator << (std::ostream& os, Map& rhs); |
|
|
|
|
friend std::ostream& operator << (std::ostream& os, std::vector<XMLTag>& rhs); |
|
|
|
|
}; |
|
|
|
@ -56,6 +56,10 @@ class TMXParser{ |
|
|
|
|
bool buildingSpawner=false; |
|
|
|
|
SpawnerTag obj; |
|
|
|
|
void ParseTag(std::string tag); |
|
|
|
|
int monsterPropertyTagCount=-1; |
|
|
|
|
XMLTag monsterTag; |
|
|
|
|
XMLTag spawnerLinkTag; |
|
|
|
|
std::vector<XMLTag>accumulatedMonsterTags; |
|
|
|
|
public: |
|
|
|
|
TMXParser(std::string file); |
|
|
|
|
}; |
|
|
|
@ -108,8 +112,8 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData; |
|
|
|
|
} |
|
|
|
|
std::string SpawnerTag::str() { |
|
|
|
|
std::string displayStr=ObjectData.tag+"\n"+ObjectData.FormatTagData(ObjectData.data); |
|
|
|
|
for(XMLTag tag:properties){ |
|
|
|
|
displayStr+=" ("+tag.FormatTagData(tag.data)+" )\n"; |
|
|
|
|
for(XMLTag&monster:monsters){ |
|
|
|
|
displayStr+=" ("+monster.FormatTagData(monster.data)+" )\n"; |
|
|
|
|
} |
|
|
|
|
return displayStr; |
|
|
|
|
} |
|
|
|
@ -124,10 +128,10 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData; |
|
|
|
|
} |
|
|
|
|
return displayStr; |
|
|
|
|
} |
|
|
|
|
std::string Map::FormatSpawnerData(std::ostream& os, std::vector<SpawnerTag>tiles) { |
|
|
|
|
std::string Map::FormatSpawnerData(std::ostream& os, std::map<int,SpawnerTag>tiles) { |
|
|
|
|
std::string displayStr; |
|
|
|
|
for (int i=0;i<SpawnerData.size();i++) { |
|
|
|
|
displayStr+=SpawnerData[i].str(); |
|
|
|
|
for (auto key:SpawnerData) { |
|
|
|
|
displayStr+=SpawnerData[key.first].str(); |
|
|
|
|
} |
|
|
|
|
return displayStr; |
|
|
|
|
} |
|
|
|
@ -150,51 +154,58 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData; |
|
|
|
|
return parsedMapInfo; |
|
|
|
|
} |
|
|
|
|
void TMXParser::ParseTag(std::string tag) { |
|
|
|
|
XMLTag newTag; |
|
|
|
|
//First character is a '<' so we discard it.
|
|
|
|
|
tag.erase(0,1); tag.erase(tag.length()-1,1); //Erase the first and last characters in the tag. Now parse by spaces.
|
|
|
|
|
std::stringstream s(tag); //Turn it into a string stream to now parse into individual whitespaces.
|
|
|
|
|
std::string data; |
|
|
|
|
while (s.good()) { |
|
|
|
|
int quotationMarkCount=0; |
|
|
|
|
bool pastEquals=false; |
|
|
|
|
data=""; |
|
|
|
|
bool valid=false; |
|
|
|
|
while(s.good()){ |
|
|
|
|
int character=s.get(); |
|
|
|
|
if(character=='"'){ |
|
|
|
|
quotationMarkCount++; |
|
|
|
|
} |
|
|
|
|
if(character==' '&"ationMarkCount%2==0){ |
|
|
|
|
valid=true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
data+=character; |
|
|
|
|
if(pastEquals&"ationMarkCount%2==0){ |
|
|
|
|
valid=true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if(character=='='&"ationMarkCount%2==0){ |
|
|
|
|
pastEquals=true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto ReadNextTag=[&](){ |
|
|
|
|
XMLTag newTag; |
|
|
|
|
//First character is a '<' so we discard it.
|
|
|
|
|
tag.erase(0,1); tag.erase(tag.length()-1,1); //Erase the first and last characters in the tag. Now parse by spaces.
|
|
|
|
|
std::stringstream s(tag); //Turn it into a string stream to now parse into individual whitespaces.
|
|
|
|
|
std::string data; |
|
|
|
|
while (s.good()) { |
|
|
|
|
int quotationMarkCount=0; |
|
|
|
|
bool pastEquals=false; |
|
|
|
|
data=""; |
|
|
|
|
bool valid=false; |
|
|
|
|
while(s.good()){ |
|
|
|
|
int character=s.get(); |
|
|
|
|
if(character=='"'){ |
|
|
|
|
quotationMarkCount++; |
|
|
|
|
} |
|
|
|
|
if(character==' '&"ationMarkCount%2==0){ |
|
|
|
|
valid=true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
data+=character; |
|
|
|
|
if(pastEquals&"ationMarkCount%2==0){ |
|
|
|
|
valid=true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if(character=='='&"ationMarkCount%2==0){ |
|
|
|
|
pastEquals=true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if(valid&&data.length()>0){ |
|
|
|
|
if (newTag.tag.length()==0) { //Tag's empty, so first line is the tag.
|
|
|
|
|
newTag.tag=data; |
|
|
|
|
std::cout<<"Tag: "<<newTag.tag<<"\n"; |
|
|
|
|
} else { |
|
|
|
|
std::string key = data.substr(0,data.find("=")); |
|
|
|
|
std::string value = data.substr(data.find("=")+1,std::string::npos); |
|
|
|
|
if(valid&&data.length()>0){ |
|
|
|
|
if (newTag.tag.length()==0) { //Tag's empty, so first line is the tag.
|
|
|
|
|
newTag.tag=data; |
|
|
|
|
std::cout<<"Tag: "<<newTag.tag<<"\n"; |
|
|
|
|
} else { |
|
|
|
|
std::string key = data.substr(0,data.find("=")); |
|
|
|
|
std::string value = data.substr(data.find("=")+1,std::string::npos); |
|
|
|
|
|
|
|
|
|
//Strip Quotation marks.
|
|
|
|
|
value = value.substr(1,std::string::npos); |
|
|
|
|
value = value.substr(0,value.length()-1); |
|
|
|
|
//Strip Quotation marks.
|
|
|
|
|
value = value.substr(1,std::string::npos); |
|
|
|
|
value = value.substr(0,value.length()-1); |
|
|
|
|
|
|
|
|
|
newTag.data[key]=value; |
|
|
|
|
std::cout<<" "<<key<<":"<<newTag.data[key]<<"\n"; |
|
|
|
|
newTag.data[key]=value; |
|
|
|
|
std::cout<<" "<<key<<":"<<newTag.data[key]<<"\n"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return newTag; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
XMLTag newTag=ReadNextTag(); |
|
|
|
|
|
|
|
|
|
if (newTag.tag=="map") { |
|
|
|
|
parsedMapInfo.MapData={stoi(newTag.data["width"]),stoi(newTag.data["height"])}; |
|
|
|
@ -207,12 +218,7 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData; |
|
|
|
|
parsedMapInfo.LayerData.push_back(l); |
|
|
|
|
}else
|
|
|
|
|
if (newTag.tag=="object"&&newTag.data["type"]=="SpawnGroup") { |
|
|
|
|
if(buildingSpawner){ |
|
|
|
|
parsedMapInfo.SpawnerData.push_back(obj); |
|
|
|
|
} |
|
|
|
|
buildingSpawner=true; |
|
|
|
|
obj={newTag}; |
|
|
|
|
goto spawnerResetSkip; |
|
|
|
|
parsedMapInfo.SpawnerData[newTag.GetInteger("id")]={newTag}; |
|
|
|
|
} else
|
|
|
|
|
if (newTag.tag=="object"&&newTag.data["type"]=="PlayerSpawnLocation") { |
|
|
|
|
parsedMapInfo.MapData.playerSpawnLocation={newTag.GetInteger("x")-newTag.GetInteger("width")/2,newTag.GetInteger("y")-newTag.GetInteger("height")/2}; |
|
|
|
@ -232,19 +238,25 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData; |
|
|
|
|
parsedMapInfo.ZoneData[newTag.data["type"]]=zones;
|
|
|
|
|
} |
|
|
|
|
}else |
|
|
|
|
if (newTag.tag=="property"&&buildingSpawner) { |
|
|
|
|
if(newTag.data["propertytype"]=="MonsterName"){ |
|
|
|
|
obj.properties.push_back(newTag); |
|
|
|
|
} |
|
|
|
|
goto spawnerResetSkip; |
|
|
|
|
if (newTag.tag=="object"&&newTag.data["type"]=="Monster") { |
|
|
|
|
//XMLTag monsterTag=ReadNextTag();
|
|
|
|
|
//XMLTag spawnerLinkTag=ReadNextTag();
|
|
|
|
|
//newTag.data["value"]=monsterTag.GetInteger("value"); //Value now contains which monster name this spawn represents.
|
|
|
|
|
monsterTag=newTag; |
|
|
|
|
monsterPropertyTagCount=0; |
|
|
|
|
} else |
|
|
|
|
if (newTag.tag=="property"&&monsterPropertyTagCount==0) { |
|
|
|
|
monsterTag.data["value"]=newTag.data["value"]; |
|
|
|
|
monsterPropertyTagCount++; |
|
|
|
|
} else
|
|
|
|
|
if (newTag.tag=="property"&&monsterPropertyTagCount==1) { |
|
|
|
|
spawnerLinkTag=newTag; |
|
|
|
|
monsterTag.data["spawnerLink"]=spawnerLinkTag.data["value"]; |
|
|
|
|
accumulatedMonsterTags.push_back(monsterTag); |
|
|
|
|
monsterPropertyTagCount=-1; |
|
|
|
|
} else { |
|
|
|
|
std::cout<<"Unsupported tag format! Ignoring."<<"\n"; |
|
|
|
|
} |
|
|
|
|
if(buildingSpawner){ |
|
|
|
|
parsedMapInfo.SpawnerData.push_back(obj); |
|
|
|
|
} |
|
|
|
|
buildingSpawner=false; |
|
|
|
|
spawnerResetSkip: |
|
|
|
|
std::cout<<"\n"<<"=============\n"; |
|
|
|
|
} |
|
|
|
|
TMXParser::TMXParser(std::string file){ |
|
|
|
@ -289,8 +301,8 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(buildingSpawner){ |
|
|
|
|
parsedMapInfo.SpawnerData.push_back(obj); |
|
|
|
|
for(XMLTag&monster:accumulatedMonsterTags){ |
|
|
|
|
parsedMapInfo.SpawnerData[monster.GetInteger("spawnerLink")].monsters.push_back(monster); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::cout<<"Parsed Map Data:\n"<<parsedMapInfo<<"\n"; |
|
|
|
|