diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 6079f867..31d1f060 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -550,6 +550,8 @@ void Crawler::PopulateRenderLists(){ backgroundEffectsUpper.clear(); foregroundEffectsLower.clear(); foregroundEffectsUpper.clear(); + endZones.clear(); + upperEndZones.clear(); tilePreparationList.clear(); tileForegroundList.clear(); @@ -595,6 +597,15 @@ void Crawler::PopulateRenderLists(){ backgroundEffectsLower.push_back(e); } } + + for(ZoneData&zone:MAP_DATA[GetCurrentLevel()].ZoneData["EndZone"]){ + if(zone.isUpper){ + upperEndZones.push_back(zone); + }else{ + endZones.push_back(zone); + } + } + std::sort(monstersBeforeUpper.begin(),monstersBeforeUpper.end(),[](Monster*m1,Monster*m2){return m1->GetPos().yGetPos().y;}); std::sort(monstersBeforeLower.begin(),monstersBeforeLower.end(),[](Monster*m1,Monster*m2){return m1->GetPos().yGetPos().y;}); std::sort(monstersAfterUpper.begin(),monstersAfterUpper.end(),[](Monster*m1,Monster*m2){return m1->GetPos().yGetPos().y;}); @@ -652,6 +663,12 @@ void Crawler::RenderWorld(float fElapsedTime){ } }; + auto RenderZone=[&](geom2d::rect&zone){ + game->SetDecalMode(DecalMode::ADDITIVE); + view.DrawDecal(zone.pos,GFX["finishring.png"].Decal(),vf2d(zone.size)/vf2d(GFX["finishring.png"].Sprite()->Size()),{255,255,255,uint8_t(abs(sin(game->levelTime))*255)}); + game->SetDecalMode(DecalMode::NORMAL); + }; + enum class RenderMode{ REFLECTIVE_TILES, NORMAL_TILES, @@ -785,6 +802,9 @@ void Crawler::RenderWorld(float fElapsedTime){ for(Effect*e:backgroundEffectsLower){ e->rendered=false; } + for(ZoneData&zone:endZones){ + RenderZone(zone.zone); + } for(Monster*m:monstersBeforeLower){ m->Draw(); } @@ -933,6 +953,9 @@ void Crawler::RenderWorld(float fElapsedTime){ for(Effect*e:backgroundEffectsUpper){ e->rendered=false; } + for(ZoneData&zone:upperEndZones){ + RenderZone(zone.zone); + } for(Monster*m:monstersBeforeUpper){ m->Draw(); } @@ -1288,14 +1311,13 @@ void Crawler::LoadLevel(MapName map){ return zoneSet.second; } } - return std::vector>{}; + return std::vector{}; }; - - for(geom2d::rect&zone:GetUpperZones()){ - int zoneX=zone.pos.x/game->GetCurrentMap().tilewidth; //snap to grid - int zoneY=zone.pos.y/game->GetCurrentMap().tilewidth; - int zoneW=zone.right().start.x/game->GetCurrentMap().tilewidth-zoneX; - int zoneH=zone.bottom().start.y/game->GetCurrentMap().tilewidth-zoneY; + for(ZoneData&zone:GetUpperZones()){ + int zoneX=zone.zone.pos.x/game->GetCurrentMap().tilewidth; //snap to grid + int zoneY=zone.zone.pos.y/game->GetCurrentMap().tilewidth; + int zoneW=zone.zone.right().start.x/game->GetCurrentMap().tilewidth-zoneX; + int zoneH=zone.zone.bottom().start.y/game->GetCurrentMap().tilewidth-zoneY; for(int x=zoneX;xCrawler::GetTileCollision(MapName map,vf2d pos,bool upperLevel) if(pos.x<0||pos.y<0||pos.x>=GetCurrentMap().width*game->GetCurrentMap().tilewidth||pos.y>=GetCurrentMap().height*game->GetCurrentMap().tilewidth)return NO_COLLISION; #pragma region Lower Bridge Collision Check if(!upperLevel){ //We are looking for lower bridge collisions. - for(geom2d::rect&zone:MAP_DATA[map].ZoneData["LowerBridgeCollision"]){ - if(geom2d::contains(zone,pos)){ + for(ZoneData&zone:MAP_DATA[map].ZoneData["LowerBridgeCollision"]){ + if(geom2d::contains(zone.zone,pos)){ return {{0,0},{game->GetCurrentMap().tilewidth,game->GetCurrentMap().tilewidth}}; } } @@ -1505,7 +1527,7 @@ MapName Crawler::GetCurrentLevel(){ return currentLevel; } -std::map>>&Crawler::GetZoneData(MapName map){ +std::map>&Crawler::GetZoneData(MapName map){ return MAP_DATA[map].ZoneData; } diff --git a/Crawler/Crawler.h b/Crawler/Crawler.h index f1496310..f14e9dd6 100644 --- a/Crawler/Crawler.h +++ b/Crawler/Crawler.h @@ -63,6 +63,7 @@ public: private: std::vector>foregroundEffects,backgroundEffects,foregroundEffectsToBeInserted,backgroundEffectsToBeInserted; std::vectortilePreparationList,tileForegroundList; + std::vectorendZones,upperEndZones; std::vectorcircleCooldownPoints; std::mapMAP_TILESETS; vf2d worldShake={}; @@ -139,7 +140,7 @@ public: bool HasTileCollision(MapName map,vf2d pos,bool upperLevel=false); MapName GetCurrentLevel(); bool IsBridgeLayer(LayerTag&layer); - std::map>>&GetZoneData(MapName map); + std::map>&GetZoneData(MapName map); void PopulateRenderLists(); void ChangePlayerClass(Class cl); std::string GetString(std::string key); diff --git a/Crawler/Crawler.tiled-project b/Crawler/Crawler.tiled-project index ba5ae5ac..fe25f51f 100644 --- a/Crawler/Crawler.tiled-project +++ b/Crawler/Crawler.tiled-project @@ -66,6 +66,11 @@ "drawFill": true, "id": 23, "members": [ + { + "name": "Upper?", + "type": "bool", + "value": false + } ], "name": "EndZone", "type": "class", diff --git a/Crawler/Monster.cpp b/Crawler/Monster.cpp index acd9c6aa..d6ce3cda 100644 --- a/Crawler/Monster.cpp +++ b/Crawler/Monster.cpp @@ -257,14 +257,14 @@ bool Monster::SetPos(vf2d pos){ return resultX|resultY; } void Monster::Moved(){ - ZoneData&zoneData=game->GetZoneData(game->GetCurrentLevel()); - for(geom2d::rect&upperLevelZone:zoneData["UpperZone"]){ - if(geom2d::overlaps(upperLevelZone,pos)){ + std::map>&zoneData=game->GetZoneData(game->GetCurrentLevel()); + for(ZoneData&upperLevelZone:zoneData["UpperZone"]){ + if(geom2d::overlaps(upperLevelZone.zone,pos)){ upperLevel=true; } } - for(geom2d::rect&lowerLevelZone:zoneData["LowerZone"]){ - if(geom2d::overlaps(lowerLevelZone,pos)){ + for(ZoneData&lowerLevelZone:zoneData["LowerZone"]){ + if(geom2d::overlaps(lowerLevelZone.zone,pos)){ upperLevel=false; } } diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index 47af91e2..2863555b 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -604,14 +604,14 @@ void Player::Moved(){ spawner.SetTriggered(true); } } - ZoneData&zoneData=game->GetZoneData(game->GetCurrentLevel()); - for(geom2d::rect&upperLevelZone:zoneData["UpperZone"]){ - if(geom2d::overlaps(upperLevelZone,pos)){ + std::map>&zoneData=game->GetZoneData(game->GetCurrentLevel()); + for(ZoneData&upperLevelZone:zoneData["UpperZone"]){ + if(geom2d::overlaps(upperLevelZone.zone,pos)){ upperLevel=true; } } - for(geom2d::rect&lowerLevelZone:zoneData["LowerZone"]){ - if(geom2d::overlaps(lowerLevelZone,pos)){ + for(ZoneData&lowerLevelZone:zoneData["LowerZone"]){ + if(geom2d::overlaps(lowerLevelZone.zone,pos)){ upperLevel=false; } } diff --git a/Crawler/TMXParser.h b/Crawler/TMXParser.h index dae028d0..3f5012d4 100644 --- a/Crawler/TMXParser.h +++ b/Crawler/TMXParser.h @@ -76,6 +76,11 @@ struct SpawnerTag{ friend std::ostream& operator << (std::ostream& os, SpawnerTag& rhs); }; +struct ZoneData{ + geom2d::rectzone; + bool isUpper=false; +}; + struct Map{ MapTag MapData; std::string name; @@ -85,7 +90,7 @@ struct Map{ std::string mapType=""; std::setspawns; std::map SpawnerData; //Spawn groups have IDs, mobs associate which spawner they are tied to via this ID. - std::map>> ZoneData; + std::map> ZoneData; std::string FormatLayerData(std::ostream& os, std::vectortiles); std::string FormatSpawnerData(std::ostream& os, std::maptiles); friend std::ostream& operator << (std::ostream& os, Map& rhs); @@ -114,6 +119,7 @@ class TMXParser{ bool buildingSpawner=false; SpawnerTag obj; int prevSpawner; + ZoneData*prevZoneData=nullptr; void ParseTag(std::string tag); int monsterPropertyTagCount=-1; XMLTag monsterTag; @@ -126,7 +132,6 @@ class TMXParser{ TMXParser(std::string file); }; -typedef std::map>> ZoneData; //#define TMX_PARSER_SETUP //Toggle for code-writing. #ifdef TMX_PARSER_SETUP @@ -161,7 +166,7 @@ typedef std::map>> ZoneData; return std::stod(data[dataTag]); } bool XMLTag::GetBool(std::string dataTag) { - if (data[dataTag]=="0") { + if (data[dataTag]=="0"||data[dataTag]=="false") { return false; } else { return true; @@ -315,6 +320,9 @@ typedef std::map>> ZoneData; prevSpawner=newTag.GetInteger("id"); } } else + if(newTag.tag=="property"&&newTag.data["name"]=="Upper?"&&prevZoneData!=nullptr){ + prevZoneData->isUpper=newTag.GetBool("value"); + }else if (newTag.tag=="property"&&newTag.data["name"]=="Optimize"&&newTag.data["value"]=="true") { parsedMapInfo.MapData.optimized=true; } else @@ -357,12 +365,13 @@ typedef std::map>> ZoneData; if (newTag.tag=="object"&&newTag.data.find("type")!=newTag.data.end()){ //This is an object with a type that doesn't fit into other categories, we can add it to ZoneData. if(parsedMapInfo.ZoneData.find(newTag.data["type"])!=parsedMapInfo.ZoneData.end()){ - std::vector>&zones=parsedMapInfo.ZoneData[newTag.data["type"]]; - zones.push_back({{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}}); + std::vector&zones=parsedMapInfo.ZoneData.at(newTag.data["type"]); + zones.emplace_back(geom2d::rect{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}}); + prevZoneData=&zones.back(); } else { - std::vector>zones; - zones.push_back({{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}}); - parsedMapInfo.ZoneData[newTag.data["type"]]=zones; + std::vector&zones=parsedMapInfo.ZoneData[newTag.data["type"]]; + zones.emplace_back(geom2d::rect{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}}); + prevZoneData=&zones.back(); } }else{ if(_DEBUG_MAP_LOAD_INFO)std::cout<<"Unsupported tag format! Ignoring."<<"\n"; @@ -423,9 +432,9 @@ typedef std::map>> ZoneData; SpawnerTag&spawner=spawnerData.second; for(auto&zoneData:parsedMapInfo.ZoneData){ if(zoneData.first=="UpperZone"){ - std::vector>&zones=zoneData.second; - for(geom2d::rect&zone:zones){ - if(geom2d::overlaps(zone,geom2d::rect{{spawner.ObjectData.GetInteger("x"),spawner.ObjectData.GetInteger("y")},{spawner.ObjectData.GetInteger("width"),spawner.ObjectData.GetInteger("height")}})){ + std::vector&zones=zoneData.second; + for(ZoneData&zone:zones){ + if(geom2d::overlaps(zone.zone,geom2d::rect{{spawner.ObjectData.GetInteger("x"),spawner.ObjectData.GetInteger("y")},{spawner.ObjectData.GetInteger("width"),spawner.ObjectData.GetInteger("height")}})){ spawner.upperLevel=true; goto continueSpawnerLoop; } diff --git a/Crawler/Version.h b/Crawler/Version.h index 92ba25a7..5db2fc83 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -33,7 +33,7 @@ SUCH DAMAGE. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 2886 +#define VERSION_BUILD 2903 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Crawler/assets/Campaigns/1_1_v2.tmx b/Crawler/assets/Campaigns/1_1_v2.tmx index cf8a7bc0..2752890c 100644 --- a/Crawler/assets/Campaigns/1_1_v2.tmx +++ b/Crawler/assets/Campaigns/1_1_v2.tmx @@ -1,5 +1,5 @@ - + @@ -1269,7 +1269,11 @@ - + + + + + @@ -1965,6 +1969,6 @@ - + diff --git a/Crawler/assets/config/gfx/gfx.txt b/Crawler/assets/config/gfx/gfx.txt index 9232fd76..9fee7653 100644 --- a/Crawler/assets/config/gfx/gfx.txt +++ b/Crawler/assets/config/gfx/gfx.txt @@ -38,6 +38,7 @@ Images GFX_SlimeKing_Cast = monsters/Slime King - Cast.png GFX_SkillOverlayIcon = skill_overlay_icon.png GFX_SkillOverlayIconOverlay = skill_overlay_icon_overlay.png + GFX_FinishRing = finishring.png # Ability Icons GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png diff --git a/Crawler/assets/finishring.png b/Crawler/assets/finishring.png new file mode 100644 index 00000000..61ca8204 Binary files /dev/null and b/Crawler/assets/finishring.png differ