@ -45,7 +45,9 @@ All rights reserved.
# include "safemap.h"
# include "safemap.h"
# include "ItemMapData.h"
# include "ItemMapData.h"
# include "Class.h"
# include "Class.h"
# include "MonsterData.h"
INCLUDE_MONSTER_DATA
using MapName = std : : string ;
using MapName = std : : string ;
using namespace olc ;
using namespace olc ;
@ -61,7 +63,7 @@ struct XMLTag{
float GetFloat ( std : : string dataTag ) ;
float GetFloat ( std : : string dataTag ) ;
double GetDouble ( std : : string dataTag ) ;
double GetDouble ( std : : string dataTag ) ;
bool GetBool ( std : : string dataTag ) ;
bool GetBool ( std : : string dataTag ) ;
std : : string GetString ( std : : string dataTag ) ;
std : : string GetString ( std : : string dataTag ) const ;
} ;
} ;
struct ForegroundTileTag : public XMLTag {
struct ForegroundTileTag : public XMLTag {
@ -224,13 +226,13 @@ class TMXParser{
double XMLTag : : GetDouble ( std : : string dataTag ) {
double XMLTag : : GetDouble ( std : : string dataTag ) {
return std : : stod ( data [ dataTag ] ) ;
return std : : stod ( data [ dataTag ] ) ;
}
}
std : : string XMLTag : : GetString ( std : : string dataTag ) {
std : : string XMLTag : : GetString ( std : : string dataTag ) const {
return data [ dataTag ] ;
return data . at ( dataTag ) ;
}
}
bool XMLTag : : GetBool ( std : : string dataTag ) {
bool XMLTag : : GetBool ( std : : string dataTag ) {
if ( data [ dataTag ] = = " 0 " | | data [ dataTag ] = = " false " ) {
if ( data [ dataTag ] = = " 0 " | | data [ dataTag ] = = " false " ) {
return false ;
return false ;
} else {
} else {
return true ;
return true ;
}
}
}
}
@ -246,7 +248,7 @@ class TMXParser{
bool Property : : GetBool ( ) {
bool Property : : GetBool ( ) {
if ( value = = " 0 " ) {
if ( value = = " 0 " ) {
return false ;
return false ;
} else {
} else {
return true ;
return true ;
}
}
}
}
@ -396,7 +398,7 @@ class TMXParser{
# if _DEBUG
# if _DEBUG
if ( _DEBUG_MAP_LOAD_INFO ) LOG ( " Tag: " < < newTag . tag < < " \n " ) ;
if ( _DEBUG_MAP_LOAD_INFO ) LOG ( " Tag: " < < newTag . tag < < " \n " ) ;
# endif
# endif
} else {
} else {
std : : string key = data . substr ( 0 , data . find ( " = " ) ) ;
std : : string key = data . substr ( 0 , data . find ( " = " ) ) ;
std : : string value = data . substr ( data . find ( " = " ) + 1 , std : : string : : npos ) ;
std : : string value = data . substr ( data . find ( " = " ) + 1 , std : : string : : npos ) ;
@ -416,6 +418,16 @@ class TMXParser{
XMLTag newTag = ReadNextTag ( ) ;
XMLTag newTag = ReadNextTag ( ) ;
auto ParseMonsterTemplateName = [ ] ( const XMLTag & monsterTag ) {
std : : string monsterName = monsterTag . GetString ( " template " ) . substr ( " ../maps/Monsters/ " s . length ( ) ) ;
monsterName = monsterName . substr ( 0 , monsterName . find ( " .tx " ) ) ;
return monsterName ;
} ;
if ( newTag . tag ! = " property " & & newTag . tag ! = " properties " & & monsterPropertyTagCount = = 0 ) {
ERR ( std : : format ( " WARNING! Monster {} at ({},{}) in Map {} does not have a spawn set! " , ParseMonsterTemplateName ( monsterTag ) , monsterTag . GetFloat ( " x " ) , monsterTag . GetFloat ( " y " ) , fileName ) ) ;
}
if ( newTag . tag = = " object " & & newTag . data [ " type " ] ! = " StagePlate " ) {
if ( newTag . tag = = " object " & & newTag . data [ " type " ] ! = " StagePlate " ) {
currentStagePlate = nullptr ;
currentStagePlate = nullptr ;
}
}
@ -433,10 +445,10 @@ class TMXParser{
if ( newTag . data . find ( " class " ) = = newTag . data . end ( ) ) ERR ( std : : format ( " WARNING! Map {} does not have a class set! " , fileName ) ) ;
if ( newTag . data . find ( " class " ) = = newTag . data . end ( ) ) ERR ( std : : format ( " WARNING! Map {} does not have a class set! " , fileName ) ) ;
if ( newTag . data [ " class " ] ! = " Map " ) ERR ( std : : format ( " WARNING! Map {} is not set to the map class! Class is set to {} instead. " , fileName , newTag . data [ " class " ] ) ) ;
if ( newTag . data [ " class " ] ! = " Map " ) ERR ( std : : format ( " WARNING! Map {} is not set to the map class! Class is set to {} instead. " , fileName , newTag . data [ " class " ] ) ) ;
parsedMapInfo . MapData = { stoi ( newTag . data [ " width " ] ) , stoi ( newTag . data [ " height " ] ) , stoi ( newTag . data [ " tilewidth " ] ) , stoi ( newTag . data [ " tileheight " ] ) } ;
parsedMapInfo . MapData = { stoi ( newTag . data [ " width " ] ) , stoi ( newTag . data [ " height " ] ) , stoi ( newTag . data [ " tilewidth " ] ) , stoi ( newTag . data [ " tileheight " ] ) } ;
} else
} else
if ( newTag . tag = = " tileset " ) {
if ( newTag . tag = = " tileset " ) {
parsedMapInfo . TilesetData . push_back ( newTag ) ;
parsedMapInfo . TilesetData . push_back ( newTag ) ;
} else
} else
if ( newTag . tag = = " layer " ) {
if ( newTag . tag = = " layer " ) {
LayerTag l = { newTag } ;
LayerTag l = { newTag } ;
parsedMapInfo . LayerData . push_back ( l ) ;
parsedMapInfo . LayerData . push_back ( l ) ;
@ -447,86 +459,84 @@ class TMXParser{
parsedMapInfo . SpawnerData [ newTag . GetInteger ( " id " ) ] = { newTag } ;
parsedMapInfo . SpawnerData [ newTag . GetInteger ( " id " ) ] = { newTag } ;
prevSpawner = newTag . GetInteger ( " id " ) ;
prevSpawner = newTag . GetInteger ( " id " ) ;
}
}
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Layer Unlock Condition " & & currentLayerTag ! = nullptr ) {
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Layer Unlock Condition " & & currentLayerTag ! = nullptr ) {
currentLayerTag - > unlockCondition = newTag . data [ " value " ] ;
currentLayerTag - > unlockCondition = newTag . data [ " value " ] ;
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Upper? " & & prevZoneData ! = nullptr ) {
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Upper? " & & prevZoneData ! = nullptr ) {
prevZoneData - > isUpper = newTag . GetBool ( " value " ) ;
prevZoneData - > isUpper = newTag . GetBool ( " value " ) ;
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Optimize " & & newTag . data [ " value " ] = = " true " ) {
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Optimize " & & newTag . data [ " value " ] = = " true " ) {
parsedMapInfo . MapData . optimized = true ;
parsedMapInfo . MapData . optimized = true ;
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Boss Title Display " ) {
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Boss Title Display " ) {
parsedMapInfo . SpawnerData [ prevSpawner ] . bossNameDisplay = newTag . data [ " value " ] ;
parsedMapInfo . SpawnerData [ prevSpawner ] . bossNameDisplay = newTag . data [ " value " ] ;
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Level Type " ) {
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Level Type " ) {
parsedMapInfo . mapType = newTag . data [ " value " ] ;
parsedMapInfo . mapType = newTag . data [ " value " ] ;
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Background Music " ) {
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Background Music " ) {
if ( newTag . data [ " value " ] ! = " None " ) { //None is a default value that we ignore.
if ( newTag . data [ " value " ] ! = " None " ) { //None is a default value that we ignore.
parsedMapInfo . bgmSongName = newTag . data [ " value " ] ;
parsedMapInfo . bgmSongName = newTag . data [ " value " ] ;
}
}
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " name " ] . starts_with ( " Dev Completion Time " ) ) {
if ( newTag . tag = = " property " & & newTag . data [ " name " ] . starts_with ( " Dev Completion Time " ) ) {
if ( newTag . data . count ( " value " ) ) { //None is a default value that we ignore.
if ( newTag . data . count ( " value " ) ) { //None is a default value that we ignore.
size_t classStartPos = " Dev Completion Time - " s . length ( ) ;
size_t classStartPos = " Dev Completion Time - " s . length ( ) ;
std : : string className = newTag . data [ " name " ] . substr ( classStartPos , newTag . data [ " name " ] . find ( ' ' , classStartPos ) - classStartPos ) ;
std : : string className = newTag . data [ " name " ] . substr ( classStartPos , newTag . data [ " name " ] . find ( ' ' , classStartPos ) - classStartPos ) ;
parsedMapInfo . devCompletionTrialTime [ classutils : : StringToClass ( className ) ] = newTag . GetFloat ( " value " ) ;
parsedMapInfo . devCompletionTrialTime [ classutils : : StringToClass ( className ) ] = newTag . GetFloat ( " value " ) ;
}
}
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Backdrop " ) {
if ( newTag . tag = = " property " & & newTag . data [ " name " ] = = " Backdrop " ) {
if ( newTag . data [ " value " ] ! = " None " ) { //None is a default value that we ignore.
if ( newTag . data [ " value " ] ! = " None " ) { //None is a default value that we ignore.
parsedMapInfo . backdrop = newTag . data [ " value " ] ;
parsedMapInfo . backdrop = newTag . data [ " value " ] ;
}
}
} else
} else
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " AudioEnvironmentalSound " ) {
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " AudioEnvironmentalSound " ) {
parsedMapInfo . environmentalAudioData . emplace_back ( ) ;
parsedMapInfo . environmentalAudioData . emplace_back ( ) ;
prevAudioData = & parsedMapInfo . environmentalAudioData . back ( ) ;
prevAudioData = & parsedMapInfo . environmentalAudioData . back ( ) ;
prevAudioData - > SetPos ( { newTag . GetFloat ( " x " ) , newTag . GetFloat ( " y " ) } ) ;
prevAudioData - > SetPos ( { newTag . GetFloat ( " x " ) , newTag . GetFloat ( " y " ) } ) ;
} else
} else
if ( newTag . tag = = " property " & & newTag . data [ " propertytype " ] = = " EnvironmentalSounds " ) {
if ( newTag . tag = = " property " & & newTag . data [ " propertytype " ] = = " EnvironmentalSounds " ) {
if ( newTag . data [ " value " ] ! = " None " ) { //None is a default value that we ignore.
if ( newTag . data [ " value " ] ! = " None " ) { //None is a default value that we ignore.
prevAudioData - > SetAudioName ( newTag . data [ " value " ] ) ;
prevAudioData - > SetAudioName ( newTag . data [ " value " ] ) ;
}
}
} else
} else
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " PlayerSpawnLocation " ) {
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " PlayerSpawnLocation " ) {
float width = 1.f ;
float width = 1.f ;
float height = 1.f ;
float height = 1.f ;
if ( newTag . data . count ( " width " ) > 0 ) width = newTag . GetFloat ( " width " ) ;
if ( newTag . data . count ( " width " ) > 0 ) width = newTag . GetFloat ( " width " ) ;
if ( newTag . data . count ( " height " ) > 0 ) height = newTag . GetFloat ( " height " ) ;
if ( newTag . data . count ( " height " ) > 0 ) height = newTag . GetFloat ( " height " ) ;
parsedMapInfo . MapData . playerSpawnLocation = { int ( newTag . GetFloat ( " x " ) - width / 2 ) , int ( newTag . GetFloat ( " y " ) - height / 2 ) } ;
parsedMapInfo . MapData . playerSpawnLocation = { int ( newTag . GetFloat ( " x " ) - width / 2 ) , int ( newTag . GetFloat ( " y " ) - height / 2 ) } ;
} else
} else
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " NPC " ) {
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " NPC " ) {
if ( inNPCTag ) parsedMapInfo . npcs . push_back ( NPCData { npcTag } ) ;
if ( inNPCTag ) parsedMapInfo . npcs . push_back ( NPCData { npcTag } ) ;
npcTag = newTag ;
npcTag = newTag ;
inNPCTag = true ;
inNPCTag = true ;
} else
} else
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " Monster " ) {
if ( newTag . tag = = " object " & & newTag . data [ " template " ] . starts_with ( " ../maps/ Monsters " ) ) {
monsterTag = newTag ;
monsterTag = newTag ;
monsterPropertyTagCount = 0 ;
monsterPropertyTagCount = 0 ;
} else
} else
if ( newTag . tag = = " property " & & inNPCTag ) {
if ( newTag . tag = = " property " & & inNPCTag ) {
npcTag . data [ newTag . data [ " name " ] ] = newTag . data [ " value " ] ;
npcTag . data [ newTag . data [ " name " ] ] = newTag . data [ " value " ] ;
}
} else
if ( newTag . tag = = " property " & & monsterPropertyTagCount = = 0 ) {
if ( newTag . tag = = " property " & & monsterPropertyTagCount = = 0 ) {
if ( newTag . data [ " value " ] = = " None " ) ERR ( std : : format ( " WARNING! Invalid monster type provided: {} in map {} " , newTag . data [ " value " ] , fileName ) ) ;
std : : string monsterName = ParseMonsterTemplateName ( monsterTag ) ;
monsterTag . data [ " value " ] = newTag . data [ " value " ] ;
if ( ! MONSTER_DATA . count ( monsterName ) ) ERR ( std : : format ( " WARNING! Could not find monster type {} " , monsterName ) ) ;
parsedMapInfo . spawns . insert ( newTag . GetString ( " value " ) ) ;
parsedMapInfo . spawns . insert ( monsterName ) ;
monsterPropertyTagCount + + ;
} else
if ( newTag . tag = = " property " & & monsterPropertyTagCount = = 1 ) {
spawnerLinkTag = newTag ;
spawnerLinkTag = newTag ;
monsterTag . data [ " value " ] = monsterName ;
monsterTag . data [ " spawnerLink " ] = spawnerLinkTag . data [ " value " ] ;
monsterTag . data [ " spawnerLink " ] = spawnerLinkTag . data [ " value " ] ;
accumulatedMonsterTags . push_back ( monsterTag ) ;
accumulatedMonsterTags . push_back ( monsterTag ) ;
monsterPropertyTagCount = - 1 ;
monsterPropertyTagCount = - 1 ;
} else
} else
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " StagePlate " ) {
if ( newTag . tag = = " object " & & newTag . data [ " type " ] = = " StagePlate " ) {
if ( newTag . GetInteger ( " id " ) ! = 0 ) {
if ( newTag . GetInteger ( " id " ) ! = 0 ) {
stagePlates [ newTag . GetInteger ( " id " ) ] = { newTag } ;
stagePlates [ newTag . GetInteger ( " id " ) ] = { newTag } ;
currentStagePlate = & stagePlates . at ( newTag . GetInteger ( " id " ) ) ;
currentStagePlate = & stagePlates . at ( newTag . GetInteger ( " id " ) ) ;
}
}
} else
} else
if ( newTag . tag = = " property " & & currentStagePlate ! = nullptr ) {
if ( newTag . tag = = " property " & & currentStagePlate ! = nullptr ) {
currentStagePlate - > properties [ newTag . data [ " name " ] ] = { newTag . data [ " name " ] , newTag . data [ " value " ] } ;
currentStagePlate - > properties [ newTag . data [ " name " ] ] = { newTag . data [ " name " ] , newTag . data [ " value " ] } ;
} else
} else
@ -586,7 +596,7 @@ class TMXParser{
if ( accumulator . length ( ) > 1 & & accumulator . find ( ' > ' ) ! = std : : string : : npos ) {
if ( accumulator . length ( ) > 1 & & accumulator . find ( ' > ' ) ! = std : : string : : npos ) {
accumulator = " " ; //Restart because this tag has nothing in it!
accumulator = " " ; //Restart because this tag has nothing in it!
}
}
} else {
} else {
//Start reading in data for this layer.
//Start reading in data for this layer.
std : : vector < int > rowData ;
std : : vector < int > rowData ;
while ( data . find ( " , " ) ! = std : : string : : npos ) {
while ( data . find ( " , " ) ! = std : : string : : npos ) {