Implemented reading spawn zones on maps. Monsters now spawn according to spawn zones.
This commit is contained in:
		
							parent
							
								
									9a2af45245
								
							
						
					
					
						commit
						57d7f3344b
					
				| @ -102,7 +102,7 @@ bool Warrior::AutoAttack(){ | ||||
| 
 | ||||
| bool Warrior::Ability1(){ | ||||
| 	ACCESS_PLAYER | ||||
| 	game->AddEffect(Effect(p.pos,0.1,AnimationState::BATTLECRY_EFFECT,1,0.3)); | ||||
| 	game->AddEffect(Effect(p.pos,0.1,AnimationState::BATTLECRY_EFFECT,p.upperLevel,1,0.3)); | ||||
| 	p.AddBuff(BuffType::ATTACK_UP,10,0.1); | ||||
| 	p.AddBuff(BuffType::DAMAGE_REDUCTION,10,0.1); | ||||
| 	for(Monster&m:MONSTER_LIST){ | ||||
|  | ||||
| @ -1034,16 +1034,18 @@ void Crawler::LoadLevel(MapName map){ | ||||
| 	foregroundTileGroups.clear(); | ||||
| 	currentLevel=map; | ||||
| 	WORLD_SIZE={MAP_DATA[map].MapData.width,MAP_DATA[map].MapData.height}; | ||||
| 	for(SpawnerTag&spawner:MAP_DATA[map].SpawnerData){ | ||||
| 	for(auto key:MAP_DATA[map].SpawnerData){ | ||||
| 		SpawnerTag&spawnData=MAP_DATA[map].SpawnerData[key.first]; | ||||
| 		std::vector<std::pair<MonsterName,vf2d>>monster_list; | ||||
| 		vf2d spawnerRadius=vf2d{spawner.ObjectData.GetFloat("width"),spawner.ObjectData.GetFloat("height")}/2; | ||||
| 		for(XMLTag&property:spawner.properties){ | ||||
| 			int monsterTypeID=property.GetInteger("value")-1; | ||||
| 		 | ||||
| 		vf2d spawnerRadius=vf2d{spawnData.ObjectData.GetFloat("width"),spawnData.ObjectData.GetFloat("height")}/2; | ||||
| 		for(XMLTag&monster:spawnData.monsters){ | ||||
| 			int monsterTypeID=monster.GetInteger("value")-1; | ||||
| 			if(monsterTypeID>=0&&monsterTypeID<MonsterName::END){ | ||||
| 				monster_list.push_back({MonsterName(monsterTypeID),{rand()%int(spawnerRadius.x)-spawnerRadius.x/2,rand()%int(spawnerRadius.y)-spawnerRadius.y/2}}); | ||||
| 				monster_list.push_back({MonsterName(monsterTypeID),{monster.GetInteger("x")-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-spawnData.ObjectData.GetFloat("y")}}); | ||||
| 			} | ||||
| 		} | ||||
| 		SPAWNER_LIST.push_back(MonsterSpawner{{spawner.ObjectData.GetFloat("x")+spawnerRadius.x,spawner.ObjectData.GetFloat("y")+spawnerRadius.y},spawnerRadius,monster_list}); | ||||
| 		SPAWNER_LIST.push_back(MonsterSpawner{{spawnData.ObjectData.GetFloat("x"),spawnData.ObjectData.GetFloat("y")},spawnerRadius*2,monster_list}); | ||||
| 	} | ||||
| 	for(int x=0;x<WORLD_SIZE.x;x++){ | ||||
| 		for(int y=0;y<WORLD_SIZE.y;y++){ | ||||
|  | ||||
| @ -392,7 +392,7 @@ Key Player::GetFacingDirection(){ | ||||
| 
 | ||||
| void Player::Moved(){ | ||||
| 	for(MonsterSpawner&spawner:SPAWNER_LIST){ | ||||
| 		if(!spawner.SpawnTriggered()&&geom2d::contains(geom2d::ellipse<float>{spawner.GetPos(),spawner.GetRange()},pos)){ | ||||
| 		if(!spawner.SpawnTriggered()&&geom2d::contains(geom2d::rect<float>{spawner.GetPos(),spawner.GetRange()},pos)){ | ||||
| 			spawner.SetTriggered(true); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -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++; | ||||
|          | ||||
| 
 | ||||
|         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(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); | ||||
| 
 | ||||
|                         //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"; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             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); | ||||
|             return newTag; | ||||
|         }; | ||||
| 
 | ||||
|                     //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"; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         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"; | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| #define VERSION_MAJOR 0 | ||||
| #define VERSION_MINOR 2 | ||||
| #define VERSION_PATCH 0 | ||||
| #define VERSION_BUILD 528 | ||||
| #define VERSION_BUILD 547 | ||||
| 
 | ||||
| #define stringify(a) stringify_(a) | ||||
| #define stringify_(a) #a | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="192" height="203" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="45"> | ||||
| <map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="192" height="203" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="59"> | ||||
|  <tileset firstgid="1" source="../maps/grass_tiles_24x24.tsx"/> | ||||
|  <tileset firstgid="784" source="../maps/grass_tiles_modded.tsx"/> | ||||
|  <layer id="5" name="Collision Layer" width="192" height="203"> | ||||
| @ -1044,7 +1044,6 @@ | ||||
|   <object id="8" name="Spawn Group 2" type="SpawnGroup" x="1461.33" y="3090.67" width="521.333" height="534.667"> | ||||
|    <ellipse/> | ||||
|   </object> | ||||
|   <object id="10" name="Spawn Group 3" type="SpawnGroup" x="2261.33" y="3040" width="242.667" height="592"/> | ||||
|   <object id="12" name="Spawn Group 4" type="SpawnGroup" x="3029.33" y="2946.67" width="513.333" height="509.333"> | ||||
|    <ellipse/> | ||||
|   </object> | ||||
| @ -1054,9 +1053,6 @@ | ||||
|   <object id="14" name="Spawn Group 6" type="SpawnGroup" x="3182.67" y="1885.33" width="625.333" height="249.333"> | ||||
|    <ellipse/> | ||||
|   </object> | ||||
|   <object id="15" x="3352" y="2328"> | ||||
|    <ellipse/> | ||||
|   </object> | ||||
|   <object id="16" name="Spawn Group 7" type="SpawnGroup" x="3109.33" y="1048" width="729.333" height="225.333"> | ||||
|    <ellipse/> | ||||
|   </object> | ||||
| @ -1133,6 +1129,56 @@ | ||||
|    <point/> | ||||
|   </object> | ||||
|   <object id="44" name="Player Spawn" type="PlayerSpawnLocation" x="456" y="3288" width="24" height="24"/> | ||||
|   <object id="45" name="Blue Slime" type="Monster" x="1560" y="3270"> | ||||
|    <properties> | ||||
|     <property name="Type" type="int" propertytype="MonsterName" value="2"/> | ||||
|     <property name="spawner" type="object" value="8"/> | ||||
|    </properties> | ||||
|    <point/> | ||||
|   </object> | ||||
|   <object id="52" name="Blue Slime" type="Monster" x="1578" y="3402"> | ||||
|    <properties> | ||||
|     <property name="Type" type="int" propertytype="MonsterName" value="2"/> | ||||
|     <property name="spawner" type="object" value="8"/> | ||||
|    </properties> | ||||
|    <point/> | ||||
|   </object> | ||||
|   <object id="53" name="Blue Slime" type="Monster" x="2292" y="3204"> | ||||
|    <properties> | ||||
|     <property name="Type" type="int" propertytype="MonsterName" value="2"/> | ||||
|     <property name="spawner" type="object" value="58"/> | ||||
|    </properties> | ||||
|    <point/> | ||||
|   </object> | ||||
|   <object id="54" name="Blue Slime" type="Monster" x="1746" y="3174"> | ||||
|    <properties> | ||||
|     <property name="Type" type="int" propertytype="MonsterName" value="2"/> | ||||
|     <property name="spawner" type="object" value="8"/> | ||||
|    </properties> | ||||
|    <point/> | ||||
|   </object> | ||||
|   <object id="55" name="Blue Slime" type="Monster" x="1860" y="3336"> | ||||
|    <properties> | ||||
|     <property name="Type" type="int" propertytype="MonsterName" value="2"/> | ||||
|     <property name="spawner" type="object" value="8"/> | ||||
|    </properties> | ||||
|    <point/> | ||||
|   </object> | ||||
|   <object id="56" name="Blue Slime" type="Monster" x="1776" y="3420"> | ||||
|    <properties> | ||||
|     <property name="Type" type="int" propertytype="MonsterName" value="2"/> | ||||
|     <property name="spawner" type="object" value="8"/> | ||||
|    </properties> | ||||
|    <point/> | ||||
|   </object> | ||||
|   <object id="57" name="Blue Slime" type="Monster" x="1704" y="3240"> | ||||
|    <properties> | ||||
|     <property name="Type" type="int" propertytype="MonsterName" value="2"/> | ||||
|     <property name="spawner" type="object" value="8"/> | ||||
|    </properties> | ||||
|    <point/> | ||||
|   </object> | ||||
|   <object id="58" name="Spawn Group 3" type="SpawnGroup" x="2220" y="3018" width="242.667" height="592"/> | ||||
|  </objectgroup> | ||||
|  <objectgroup id="7" name="Transition Layerxzs"> | ||||
|   <object id="40" type="LowerZone" x="1596" y="1134" width="372" height="684"/> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user