Implemented reading spawn zones on maps. Monsters now spawn according to spawn zones.
This commit is contained in:
parent
c2cc6e83ab
commit
0493252a08
Crawler
@ -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