diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 5174c93f..2f601fe4 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -802,8 +802,8 @@ void AiL::RenderWorld(float fElapsedTime){ count++; } if(player->teleportAnimationTimer>0){ - playerScale.x=120*float(abs(pow(player->teleportAnimationTimer-0.175f,3))); - pos=player->teleportStartPosition.lerp(player->teleportTarget,(0.35f-player->teleportAnimationTimer)/0.35f); + playerScale.x=120*float(abs(pow(player->teleportAnimationTimer-"Wizard.Right Click Ability.AnimationTime"_F/2,3))); + pos=player->teleportStartPosition.lerp(player->teleportTarget,("Wizard.Right Click Ability.AnimationTime"_F-player->teleportAnimationTimer)/"Wizard.Right Click Ability.AnimationTime"_F); } const std::vectorattackBuffs=player->GetStatBuffs({"Attack","Attack %"}); view.DrawPartialRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,attackBuffs.size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*attackBuffs[0].duration))),uint8_t(255*abs(sin(1.4*attackBuffs[0].duration)))}:WHITE); @@ -898,9 +898,9 @@ void AiL::RenderWorld(float fElapsedTime){ #ifdef _DEBUG if("debug_collision_boxes"_I){ if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; - view.FillRectDecal(vi2d{x,y}*GetCurrentMapData().tilewidth+collision.pos,collision.size,{0,0,0,128}); - view.DrawRectDecal(vi2d{x,y}*GetCurrentMapData().tilewidth+collision.pos,collision.size,GREY); + geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; + view.FillRectDecal(vf2d{float(x),float(y)}*float(GetCurrentMapData().tilewidth)+collision.pos,collision.size,{0,0,0,128}); + view.DrawRectDecal(vf2d{float(x),float(y)}*float(GetCurrentMapData().tilewidth)+collision.pos,collision.size,GREY); } } #endif @@ -926,9 +926,9 @@ void AiL::RenderWorld(float fElapsedTime){ #ifdef _DEBUG if("debug_collision_boxes"_I){ if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; - view.FillRectDecal(vi2d{x,y}*GetCurrentMapData().tilewidth+collision.pos,collision.size,{0,0,0,128}); - view.DrawRectDecal(vi2d{x,y}*GetCurrentMapData().tilewidth+collision.pos,collision.size,GREY); + geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; + view.FillRectDecal(vf2d{float(x),float(y)}*float(GetCurrentMapData().tilewidth)+collision.pos,collision.size,{0,0,0,128}); + view.DrawRectDecal(vf2d{float(x),float(y)}*float(GetCurrentMapData().tilewidth)+collision.pos,collision.size,GREY); } } #endif @@ -948,6 +948,17 @@ void AiL::RenderWorld(float fElapsedTime){ } }break; } + for(int y2=0;y2<2;y2++){ + for(int x2=0;x2<2;x2++){ + vf2d tilePos=vf2d{float(x),float(y)}*24; + vf2d gridPos=tilePos+pathfinder.gridSpacing*vf2d{float(x2),float(y2)}; + Pixel col=RED; + if(!pathfinder.nodes[gridPos].bObstacle&&!pathfinder.nodes[gridPos].bObstacleUpper){ + col=GREEN; + } + view.FillRectDecal(gridPos,pathfinder.gridSpacing,{col.r,col.g,col.b,128}); + } + } }else{ if(GetCurrentMap().backdrop.length()>0){ vf2d tileWorldPos=vi2d{x,y}*GetCurrentMapData().tilewidth; @@ -1067,11 +1078,19 @@ void AiL::RenderWorld(float fElapsedTime){ RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)}); float distToPlayer=geom2d::line(player->GetPos(),tile->pos+vf2d{12,12}).length(); if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tile->tileSheet.tileset->collision[tile->tileID].collision; + geom2d::rectcollision=tile->tileSheet.tileset->collision[tile->tileID].collision; distToPlayer/=4; if(distToPlayer<1){distToPlayer=1;} view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))}); view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))}); + #ifdef _DEBUG + if("debug_collision_boxes_snapping"_I){ + if(fmod(tile->pos.x+collision.pos.x,1.f)!=0.f||fmod(tile->pos.y+collision.pos.y,1.f)!=0.f){ + view.DrawShadowStringPropDecal(tile->pos+collision.pos-vf2d{0,24},(tile->pos+collision.pos).str(),RED,BLACK,{0.5f,1.f},24.f); + view.DrawShadowStringPropDecal(tile->pos+collision.pos+vf2d{0,24},((tile->pos+collision.pos)+(collision.size)).str(),GREEN,BLACK,{0.5f,1.f},24.f); + } + } + #endif } } #pragma endregion @@ -1092,11 +1111,19 @@ void AiL::RenderWorld(float fElapsedTime){ RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)}); float distToPlayer=geom2d::line(player->GetPos(),tile->pos+vf2d{12,12}).length(); if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tile->tileSheet.tileset->collision[tile->tileID].collision; + geom2d::rectcollision=tile->tileSheet.tileset->collision[tile->tileID].collision; distToPlayer/=4; if(distToPlayer<1){distToPlayer=1;} view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))}); view.DrawRectDecal(tile->pos+collision.pos,collision.size,{128,0,0,uint8_t(255/sqrt(distToPlayer))}); + #ifdef _DEBUG + if("debug_collision_boxes_snapping"_I){ + if(fmod(tile->pos.x+collision.pos.x,1.f)!=0.f||fmod(tile->pos.y+collision.pos.y,1.f)!=0.f){ + view.DrawShadowStringPropDecal(tile->pos+collision.pos-vf2d{0,24},(tile->pos+collision.pos).str(),RED,BLACK,{0.5f,1.f},24.f); + view.DrawShadowStringPropDecal(tile->pos+collision.pos+vf2d{0,24},((tile->pos+collision.pos)+(collision.size)).str(),GREEN,BLACK,{0.5f,1.f},24.f); + } + } + #endif } } #pragma endregion @@ -1124,9 +1151,9 @@ void AiL::RenderWorld(float fElapsedTime){ #ifdef _DEBUG if("debug_collision_boxes"_I){ if(tileSheet.tileset->collision.find(tileSheetIndex)!=tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; - view.FillRectDecal(vi2d{x,y}*game->GetCurrentMapData().tilewidth+collision.pos,collision.size,{0,0,0,128}); - view.DrawRectDecal(vi2d{x,y}*game->GetCurrentMapData().tilewidth+collision.pos,collision.size,GREY); + geom2d::rectcollision=tileSheet.tileset->collision[tileSheetIndex].collision; + view.FillRectDecal(vf2d{float(x),float(y)}*float(game->GetCurrentMapData().tilewidth)+collision.pos,collision.size,{0,0,0,128}); + view.DrawRectDecal(vf2d{float(x),float(y)}*float(game->GetCurrentMapData().tilewidth)+collision.pos,collision.size,GREY); } } #endif @@ -1210,7 +1237,7 @@ void AiL::RenderWorld(float fElapsedTime){ RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)}); float distToPlayer=geom2d::line(player->GetPos(),tile->pos+vf2d{12,12}).length(); if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tile->tileSheet.tileset->collision[tile->tileID].collision; + geom2d::rectcollision=tile->tileSheet.tileset->collision[tile->tileID].collision; distToPlayer/=4; if(distToPlayer<1){distToPlayer=1;} view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))}); @@ -1235,7 +1262,7 @@ void AiL::RenderWorld(float fElapsedTime){ RenderTile(*tile,{255,255,255,uint8_t(255-tile->tileOpacity/TileGroup::FADE_TIME*TileGroup::FADE_AMT)}); float distToPlayer=geom2d::line(player->GetPos(),tile->pos+vf2d{12,12}).length(); if(distToPlayer<24*3&&tile->tileOpacity>0&&tile->tileSheet.tileset->collision.find(tile->tileID)!=tile->tileSheet.tileset->collision.end()){ - geom2d::rectcollision=tile->tileSheet.tileset->collision[tile->tileID].collision; + geom2d::rectcollision=tile->tileSheet.tileset->collision[tile->tileID].collision; distToPlayer/=4; if(distToPlayer<1){distToPlayer=1;} view.FillRectDecal(tile->pos+collision.pos,collision.size,{255,0,0,uint8_t(128*tile->tileOpacity/sqrt(distToPlayer))}); @@ -1895,7 +1922,7 @@ TilesheetData AiL::GetTileSheet(MapName map,int tileID){ } bool AiL::HasTileCollision(MapName map,vf2d pos,bool upperLevel){ - geom2d::rectcollisionRect=GetTileCollision(map,pos,upperLevel); + geom2d::rectcollisionRect=GetTileCollision(map,pos,upperLevel); vi2d collisionRectSnapPos=vi2d{pos/float(game->GetCurrentMapData().tilewidth)}*game->GetCurrentMapData().tilewidth; collisionRect.pos+=collisionRectSnapPos; return geom2d::overlaps(collisionRect,pos); @@ -1905,7 +1932,7 @@ bool AiL::IsBridgeLayer(LayerTag&layer){ return layer.tag.data.find("class")!=layer.tag.data.end()&&layer.tag.data["class"]=="Bridge"; } -geom2d::rectAiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){ +geom2d::rectAiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){ if(pos.x<0||pos.y<0||pos.x>=GetCurrentMapData().width*game->GetCurrentMapData().tilewidth||pos.y>=GetCurrentMapData().height*game->GetCurrentMapData().tilewidth)return NO_COLLISION; if(GetCurrentMap().optimizedTile)return NO_COLLISION; //Overworld map has no collision. @@ -1919,13 +1946,13 @@ geom2d::rectAiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){ break; } } - if(!hasTerrain)return geom2d::rect({0,0},{GetCurrentMapData().tilewidth,GetCurrentMapData().tilewidth}); //We assume no terrain means we can't walk on this. + if(!hasTerrain)return geom2d::rect({0.f,0.f},{float(GetCurrentMapData().tilewidth),float(GetCurrentMapData().tilewidth)}); //We assume no terrain means we can't walk on this. #pragma region Lower Bridge Collision Check if(!upperLevel){ //We are looking for lower bridge collisions. for(ZoneData&zone:MAP_DATA[map].ZoneData["LowerBridgeCollision"]){ if(geom2d::contains(zone.zone,pos)){ - return {{0,0},{game->GetCurrentMapData().tilewidth,game->GetCurrentMapData().tilewidth}}; + return {{0,0},{float(game->GetCurrentMapData().tilewidth),float(game->GetCurrentMapData().tilewidth)}}; } } } @@ -1940,13 +1967,13 @@ geom2d::rectAiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){ return NO_COLLISION; } } - geom2d::rectfoundRect=NO_COLLISION; + geom2d::rectfoundRect=NO_COLLISION; for(int counter=0;LayerTag&layer:MAP_DATA[map].LayerData){ //auto HasNoClass=[&](){return layer.tag.data.find("class")==layer.tag.data.end();}; if(counter!=bridgeLayerIndex){ int tileID=layer.tiles[int(pos.y)/GetCurrentMapData().tilewidth][int(pos.x)/GetCurrentMapData().tilewidth]-1; if(tileID!=-1&&GetTileSheet(map,tileID%1000000).tileset->collision.find(tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1)!=GetTileSheet(map,tileID%1000000).tileset->collision.end()){ - geom2d::rectcollisionRect=GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision; + geom2d::rectcollisionRect=GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision; if(foundRect.pos==NO_COLLISION.pos&&foundRect.size==NO_COLLISION.size){ foundRect=collisionRect; }else{ diff --git a/Adventures in Lestoria/AdventuresInLestoria.h b/Adventures in Lestoria/AdventuresInLestoria.h index 137917dd..38f1a994 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.h +++ b/Adventures in Lestoria/AdventuresInLestoria.h @@ -133,7 +133,7 @@ public: bool OnUserUpdate(float fElapsedTime) override; bool OnUserDestroy() override; public: - geom2d::rectNO_COLLISION={}; + geom2d::rectNO_COLLISION={{0.f,0.f,},{0.f,0.f}}; TileTransformedView view; void InitializeLevel(std::string mapFile,MapName map); void LoadLevel(MapName map); @@ -166,7 +166,7 @@ public: //tileID is the tile number from the tilesets. TilesheetData GetTileSheet(MapName map,int tileID); //Gets the rectangle of the tile collision at this tile. If upperLevel is set to true, the collision tile must be in a Bridge class layer for the tile to hit. Also, zones containing LowerBridgeCollision will apply when upperLevel is set to false. - geom2d::rectGetTileCollision(MapName map,vf2d pos,bool upperLevel=false); + geom2d::rectGetTileCollision(MapName map,vf2d pos,bool upperLevel=false); //Checks if the point resides inside of a collision tile. bool HasTileCollision(MapName map,vf2d pos,bool upperLevel=false); const MapName&GetCurrentLevel()const; diff --git a/Adventures in Lestoria/Map.h b/Adventures in Lestoria/Map.h index 3eecc87d..811b777d 100644 --- a/Adventures in Lestoria/Map.h +++ b/Adventures in Lestoria/Map.h @@ -50,7 +50,7 @@ public: }; struct TileCollisionData{ - geom2d::rectcollision; + geom2d::rectcollision; }; struct TilesetData{ @@ -59,7 +59,7 @@ struct TilesetData{ bool isTerrain=false; std::mapforegroundTiles; std::mapupperForegroundTiles; - std::mapcollision; + std::mapcollision; std::mapstaircaseTiles; std::map>animationData; std::setreflectiveData; @@ -75,7 +75,7 @@ struct TilesheetData{ struct TileRenderData{ TilesheetData tileSheet; - vi2d pos; + vf2d pos; vi2d tileSheetPos; int tileID; int layerID; diff --git a/Adventures in Lestoria/Monster.cpp b/Adventures in Lestoria/Monster.cpp index 8aa7dc11..f91d9642 100644 --- a/Adventures in Lestoria/Monster.cpp +++ b/Adventures in Lestoria/Monster.cpp @@ -116,8 +116,8 @@ void Monster::PerformIdleAnimation(){ bool Monster::SetX(float x){ vf2d newPos={x,pos.y}; vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth; - geom2d::rectcollisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); - if(collisionRect.pos==vi2d{0,0}&&collisionRect.size==vi2d{1,1}){ + geom2d::rectcollisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); + if(collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size){ pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult())); Moved(); return true; @@ -135,8 +135,8 @@ bool Monster::SetX(float x){ bool Monster::SetY(float y){ vf2d newPos={pos.x,y}; vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth; - geom2d::rectcollisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); - if(collisionRect.pos==vi2d{0,0}&&collisionRect.size==vi2d{1,1}){ + geom2d::rectcollisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); + if(collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size){ pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult())); Moved(); return true; @@ -234,6 +234,18 @@ void Monster::Draw(){ game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK); } game->view.DrawPartialRotatedDecal(GetPos()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),0,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(GetFacingDirection()==RIGHT?-1:1),GetSizeMult()),GetBuffs(BuffType::SLOWDOWN).size()>0?Pixel{uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(128+127*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration)))}:WHITE); + + + for(float index=0.f;indexpathIndex+1){ + col=GREY; + } + game->view.FillRectDecal(path.GetSplinePoint(index).pos,{1,1},col); + } for(size_t counter=0;Pathfinding::sPoint2D&point:path.points){ Pixel col=CYAN; @@ -243,7 +255,7 @@ void Monster::Draw(){ if(counter>pathIndex+1){ col=YELLOW; } - game->view.FillRectDecal(point.pos*float(game->GetCurrentMapData().tilewidth),{3,3},col); + game->view.FillRectDecal(point.pos,{3,3},col); counter++; } } @@ -266,6 +278,7 @@ void Monster::Collision(Monster&m){ void Monster::Collision(){ if(strategy=="Run Towards"&&GetState()==State::MOVE_TOWARDS&&util::random(float(Monster::STRATEGY::_GetInt(*this,"BumpStopChance",strategy)))<1){//The run towards strategy causes state to return to normal upon a collision. SetState(State::NORMAL); + targetAcquireTimer=0; } } void Monster::SetVelocity(vf2d vel){ @@ -423,11 +436,12 @@ void Monster::PathAroundBehavior(float fElapsedTime){ facingDirection=LEFT; } }else{ - if(size_t(pathIndex+1)>=path.points.size()){ + if(pathIndex>=path.points.size()){ //We have reached the end of the path! + pathIndex=0; targetAcquireTimer=0; }else{ - pathIndex+=0.2f; + pathIndex+=0.5f; } } } else { diff --git a/Adventures in Lestoria/Pathfinding.cpp b/Adventures in Lestoria/Pathfinding.cpp index eff23de2..d7c13a35 100644 --- a/Adventures in Lestoria/Pathfinding.cpp +++ b/Adventures in Lestoria/Pathfinding.cpp @@ -41,19 +41,29 @@ All rights reserved. INCLUDE_game +const vi2d Pathfinding::gridSpacing=vf2d{12,12}; + void Pathfinding::Initialize(){ nodes.clear(); sNode*lastNodeAdded=nullptr; - for (int x = 0; x < game->GetCurrentMapData().width; x+=gridSpacing.x) - for (int y = 0; y < game->GetCurrentMapData().height; y+=gridSpacing.y) + for (int x = 0; x < game->GetCurrentMapData().width*24; x+=gridSpacing.x) + for (int y = 0; y < game->GetCurrentMapData().height*24; y+=gridSpacing.y) { sNode&node=nodes[{x,y}]; node.x = x; // ...because we give each node its own coordinates node.y = y; // ...because we give each node its own coordinates - geom2d::recttile=game->GetTileCollision(game->GetCurrentLevel(),{float(x*gridSpacing.x),float(y*gridSpacing.y)}); - node.bObstacle = tile.pos!=game->NO_COLLISION.pos||tile.size!=game->NO_COLLISION.size; - tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x*gridSpacing.x),float(y*gridSpacing.y)},true); - node.bObstacleUpper = tile.pos!=game->NO_COLLISION.pos||tile.size!=game->NO_COLLISION.size; + geom2d::recttile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)}); + if(tile.pos==game->NO_COLLISION.pos&&tile.size==game->NO_COLLISION.size){ + node.bObstacle=false; + }else{ + node.bObstacle=geom2d::overlaps(vf2d{fmodf(x+gridSpacing.x/2,24),fmodf(y+gridSpacing.y/2,24)},tile); + } + tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)},true); + if(tile.pos==game->NO_COLLISION.pos&&tile.size==game->NO_COLLISION.size){ + node.bObstacleUpper=false; + }else{ + node.bObstacleUpper=geom2d::overlaps(vf2d{fmodf(x,24),fmodf(y,24)},tile); + } node.parent = nullptr; node.bVisited = false; if(nodes.size()==1){//This is the first node added, set as the start node. @@ -63,24 +73,28 @@ void Pathfinding::Initialize(){ } for (auto&[key,node]:nodes){ - if(nodes.find({node.x,node.y-1})!=nodes.end()){ - node.vecNeighbours.push_back(&node); + if(nodes.find({node.x,node.y-gridSpacing.y})!=nodes.end()){ + node.vecNeighbours.push_back(&nodes[{node.x,node.y-gridSpacing.y}]); } - if(nodes.find({node.x,node.y+1})!=nodes.end()){ - node.vecNeighbours.push_back(&node); + if(nodes.find({node.x,node.y+gridSpacing.y})!=nodes.end()){ + node.vecNeighbours.push_back(&nodes[{node.x,node.y+gridSpacing.y}]); } - if(nodes.find({node.x-1,node.y})!=nodes.end()){ - node.vecNeighbours.push_back(&node); + if(nodes.find({node.x-gridSpacing.x,node.y})!=nodes.end()){ + node.vecNeighbours.push_back(&nodes[{node.x-gridSpacing.x,node.y}]); } - if(nodes.find({node.x+1,node.y})!=nodes.end()){ - node.vecNeighbours.push_back(&node); + if(nodes.find({node.x+gridSpacing.x,node.y})!=nodes.end()){ + node.vecNeighbours.push_back(&nodes[{node.x+gridSpacing.x,node.y}]); } } } std::vector Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos,float maxRange,bool upperLevel){ float dist=float(sqrt(pow(endPos.x-startPos.x,2)+pow(endPos.y-startPos.y,2))); - if(dist>maxRange*game->GetCurrentMapData().tilewidth)return {}; + if(dist>maxRange*game->GetCurrentMapData().tilewidth)return{}; + + startPos=vi2d(startPos/gridSpacing.x)*gridSpacing.x; + endPos=vi2d(endPos/gridSpacing.x)*gridSpacing.x; + if(nodes.find(startPos)==nodes.end())return{}; if(nodes.find(endPos)==nodes.end())return{}; @@ -133,7 +147,7 @@ std::vector Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos,float maxRa nodeCurrent->bVisited = true; for (auto nodeNeighbour : nodeCurrent->vecNeighbours) { - if (!nodeNeighbour->bVisited && ((!upperLevel && nodeNeighbour->bObstacle == 0)||(upperLevel && nodeNeighbour->bObstacleUpper==0))) + if (!nodeNeighbour->bVisited && ((!upperLevel && !nodeNeighbour->bObstacle)||(upperLevel && !nodeNeighbour->bObstacleUpper))) listNotTestedNodes.push_back(nodeNeighbour); float fPossiblyLowerGoal = nodeCurrent->fLocalGoal + distance(nodeCurrent, nodeNeighbour); @@ -178,7 +192,7 @@ Pathfinding::sSpline Pathfinding::Solve_WalkPath(vf2d startPos,vf2d endPos,float void Pathfinding::sSpline::Initialize(const std::vector&points){ this->points.clear(); for(const vf2d&point:points){ - this->points.push_back({point}); + this->points.push_back({vf2d{point}+gridSpacing/2}); } fTotalSplineLength=0.f; for (int i = 0; i < this->points.size(); i++) diff --git a/Adventures in Lestoria/Pathfinding.h b/Adventures in Lestoria/Pathfinding.h index 70872dfd..50745a61 100644 --- a/Adventures in Lestoria/Pathfinding.h +++ b/Adventures in Lestoria/Pathfinding.h @@ -77,7 +77,7 @@ struct Pathfinding{ sNode *nodeStart = nullptr; sNode *nodeEnd = nullptr; - const vi2d gridSpacing = {12,12}; //Decrease this for more precision + const static vi2d gridSpacing; //Decrease this for more precision void Initialize(); //maxRange in tiles. Returns the path as points. diff --git a/Adventures in Lestoria/Player.cpp b/Adventures in Lestoria/Player.cpp index 1007c40b..efec135f 100644 --- a/Adventures in Lestoria/Player.cpp +++ b/Adventures in Lestoria/Player.cpp @@ -107,7 +107,7 @@ void Player::ForceSetPos(vf2d pos){ bool Player::SetX(float x){ vf2d newPos={x,pos.y}; vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth; - geom2d::rectcollisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); + geom2d::rectcollisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); #pragma region lambdas auto NoTileCollisionExistsHere=[&](){return collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size;}; #pragma endregion @@ -133,7 +133,7 @@ bool Player::SetX(float x){ bool Player::SetY(float y){ vf2d newPos={pos.x,y}; vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth; - geom2d::rectcollisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); + geom2d::rectcollisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel); #pragma region lambdas auto NoTileCollisionExistsHere=[&](){return collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size;}; #pragma endregion diff --git a/Adventures in Lestoria/TSXParser.h b/Adventures in Lestoria/TSXParser.h index 5a718b3b..6daa6062 100644 --- a/Adventures in Lestoria/TSXParser.h +++ b/Adventures in Lestoria/TSXParser.h @@ -51,7 +51,7 @@ struct Tileset{ bool isTerrain=false; std::map ForegroundTileData; std::map UpperForegroundTileData; - std::map CollisionData; + std::map CollisionData; std::map StaircaseData; std::map> AnimationData; std::set ReflectiveData; @@ -178,7 +178,7 @@ class TSXParser{ } else if (newTag.tag=="object"&&previousTag=="tile"){ TileCollisionData data; - data.collision=geom2d::rect{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}}; + data.collision=geom2d::rect{{newTag.GetFloat("x"),newTag.GetFloat("y")},{newTag.GetFloat("width"),newTag.GetFloat("height")}}; if(parsedTilesetInfo.CollisionData.count(previousTagID)){ #ifdef _DEBUG if(_DEBUG_MAP_LOAD_INFO)ERR("WARNING! There was already collision data defined for tile "< - + diff --git a/Adventures in Lestoria/olcPGEX_TransformedView.h b/Adventures in Lestoria/olcPGEX_TransformedView.h index 2955c70f..10201b3c 100644 --- a/Adventures in Lestoria/olcPGEX_TransformedView.h +++ b/Adventures in Lestoria/olcPGEX_TransformedView.h @@ -644,12 +644,12 @@ namespace olc void TransformedView::FillRectDecal(const olc::vf2d & pos, const olc::vf2d & size, const olc::Pixel col) { - pge->FillRectDecal(WorldToScreen(pos), (size * m_vWorldScale).ceil(), col); + pge->FillRectDecal(WorldToScreen(pos), size * m_vWorldScale, col); } void TransformedView::DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col) { - pge->DrawRectDecal(WorldToScreen(pos), (size * m_vWorldScale).ceil(), col); + pge->DrawRectDecal(WorldToScreen(pos), size * m_vWorldScale, col); } void TransformedView::DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p) diff --git a/Adventures in Lestoria/olcPixelGameEngine.h b/Adventures in Lestoria/olcPixelGameEngine.h index 39465712..bc97d09f 100644 --- a/Adventures in Lestoria/olcPixelGameEngine.h +++ b/Adventures in Lestoria/olcPixelGameEngine.h @@ -3,7 +3,7 @@ olcPixelGameEngine.h +-------------------------------------------------------------+ -| OneLoneCoder Pixel Game Engine v2.23 | +| OneLoneCoder Pixel Game Engine v2.24 | | "What do you need? Pixels... Lots of Pixels..." - javidx9 | +-------------------------------------------------------------+ @@ -197,11 +197,11 @@ Anonymous Pirate...Return To Monkey Island Special thanks to my Patreons too - I wont name you on here, but I've certainly enjoyed my tea and flapjacks :D - +- In Memory of SaladinAkara 25.06.2023 - Author ~~~~~~ -David Barr, aka javidx9, (c) OneLoneCoder 2018, 2019, 2020, 2021, 2022 +David Barr, aka javidx9, (c) OneLoneCoder 2018, 2019, 2020, 2021, 2022, 2023, 2024 */ #pragma endregion @@ -322,6 +322,7 @@ Fix Pixel -= operator (thanks Au Lit) 2.22: = Fix typo on dragged file buffers for unicode builds 2.23: Fixed Emscripten host sizing errors - Thanks Moros Fixed v2d_generic.clamp() function +2.24: Fix FillTexturedTriangle() to remove const-ref !! Apple Platforms will not see these updates immediately - Sorry, I dont have a mac to test... !! !! Volunteers willing to help appreciated, though PRs are manually integrated with credit !! @@ -404,7 +405,7 @@ return 0; #include "olcUTIL_Geometry2D.h" #pragma endregion -#define PGE_VER 223 +#define PGE_VER 224 // O------------------------------------------------------------------------------O // | COMPILER CONFIGURATION ODDITIES | @@ -1115,7 +1116,7 @@ namespace olc void FillTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, Pixel p = olc::WHITE); void FillTriangle(const olc::vi2d& pos1, const olc::vi2d& pos2, const olc::vi2d& pos3, Pixel p = olc::WHITE); // Fill a textured and coloured triangle - void FillTexturedTriangle(const std::vector& vPoints, std::vector vTex, std::vector vColour, olc::Sprite* sprTex); + void FillTexturedTriangle(std::vector vPoints, std::vector vTex, std::vector vColour, olc::Sprite* sprTex); void FillTexturedPolygon(const std::vector& vPoints, const std::vector& vTex, const std::vector& vColour, olc::Sprite* sprTex, olc::DecalStructure structure = olc::DecalStructure::LIST); // Draws an entire sprite at location (x,y) void DrawSprite(int32_t x, int32_t y, Sprite* sprite, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE, std::functioncolorFunc=[](Pixel&in){return in;}); @@ -2311,8 +2312,8 @@ namespace olc auto rol = [&](void) { pattern = (pattern << 1) | (pattern >> 31); return pattern & 1; }; olc::vi2d p1(x1, y1), p2(x2, y2); - //if (!ClipLineToScreen(p1, p2)) - // return; + if (!ClipLineToScreen(p1, p2)) + return; x1 = p1.x; y1 = p1.y; x2 = p2.x; y2 = p2.y; @@ -2706,7 +2707,7 @@ namespace olc } } - void PixelGameEngine::FillTexturedTriangle(const std::vector& vPoints, std::vector vTex, std::vector vColour, olc::Sprite* sprTex) + void PixelGameEngine::FillTexturedTriangle(std::vector vPoints, std::vector vTex, std::vector vColour, olc::Sprite* sprTex) { olc::vi2d p1 = vPoints[0]; olc::vi2d p2 = vPoints[1]; @@ -3149,7 +3150,7 @@ namespace olc di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; di.uv[i] = uv[i]; di.tint[i] = tint; - di.w[i] = 1.0f; + di.w[i] = depth[i]; } di.mode = nDecalMode; di.structure = nDecalStructure; diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 9c1efbbb..5638d3c2 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ