From 46e3c7f7e7b41e8dd6caed2541dcffbb6926f4cb Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Thu, 6 Jul 2023 03:22:05 -0500 Subject: [PATCH] Use pathfinding algorithm to determine teleport validity. --- Crawler/Bullet.h | 2 -- Crawler/Class.cpp | 4 ++-- Crawler/DEFINES.h | 4 +++- Crawler/Pathfinding.cpp | 30 ++++++++++++++++++++++++------ Crawler/Pathfinding.h | 3 ++- Crawler/Player.cpp | 5 +++-- Crawler/Player.h | 4 +++- Crawler/Version.h | 2 +- 8 files changed, 38 insertions(+), 16 deletions(-) diff --git a/Crawler/Bullet.h b/Crawler/Bullet.h index 52e1790a..6964307e 100644 --- a/Crawler/Bullet.h +++ b/Crawler/Bullet.h @@ -4,8 +4,6 @@ #include "olcUTIL_Animate2D.h" #include "Monster.h" -#define INFINITE 999999 - struct Bullet{ friend class Crawler; vf2d pos; diff --git a/Crawler/Class.cpp b/Crawler/Class.cpp index 9c109f80..40f907d1 100644 --- a/Crawler/Class.cpp +++ b/Crawler/Class.cpp @@ -306,10 +306,10 @@ bool Wizard::RightClickAbility(){ float dist=std::clamp(geom2d::line{p.GetPos(),game->GetWorldMousePos()}.length(),0.f,6.5f*24); vf2d teleportPoint=p.GetPos()+pointTowardsMouse*dist; while(dist>0&&game->HasTileCollision(game->GetCurrentLevel(),teleportPoint)&&p.CanPathfindTo(p.GetPos(),teleportPoint)){ - dist--; + dist-=24; teleportPoint=p.GetPos()+pointTowardsMouse*dist; } - if(dist>0){ + if(dist>0&&p.CanPathfindTo(p.GetPos(),teleportPoint)){ p.SetState(State::TELEPORT); p.teleportAnimationTimer=0.35; p.teleportTarget=teleportPoint; diff --git a/Crawler/DEFINES.h b/Crawler/DEFINES.h index 6ec4956d..83766edf 100644 --- a/Crawler/DEFINES.h +++ b/Crawler/DEFINES.h @@ -10,4 +10,6 @@ #define INCLUDE_PLAYER_BULLET_LIST extern std::vector>PLAYER_BULLET_LIST; #define INCLUDE_PARTICLE_LIST extern std::vectorPARTICLE_LIST; -#define ACCESS_PLAYER Player&p=game->GetPlayer(); \ No newline at end of file +#define ACCESS_PLAYER Player&p=game->GetPlayer(); + +#define INFINITE 999999 \ No newline at end of file diff --git a/Crawler/Pathfinding.cpp b/Crawler/Pathfinding.cpp index 13bf631f..883bae0f 100644 --- a/Crawler/Pathfinding.cpp +++ b/Crawler/Pathfinding.cpp @@ -11,7 +11,7 @@ void Pathfinding::Initialize(){ { nodes[y * game->WORLD_SIZE.x + x].x = x; // ...because we give each node its own coordinates nodes[y * game->WORLD_SIZE.x + x].y = y; - geom2d::recttile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)}); + geom2d::recttile=game->GetTileCollision(game->GetCurrentLevel(),{float(x*24),float(y*24)}); nodes[y * game->WORLD_SIZE.x + x].bObstacle = tile.pos!=game->NO_COLLISION.pos||tile.size!=game->NO_COLLISION.size; nodes[y * game->WORLD_SIZE.x + x].parent = nullptr; nodes[y * game->WORLD_SIZE.x + x].bVisited = false; @@ -35,13 +35,25 @@ void Pathfinding::Initialize(){ nodeEnd = &nodes[(game->WORLD_SIZE.y / 2) * game->WORLD_SIZE.x + game->WORLD_SIZE.x-2]; } -int Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos){ +int Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos,float maxRange){ + float dist=sqrt(pow(endPos.x-startPos.x,2)+pow(endPos.y-startPos.y,2)); + if(dist>maxRange*24)return maxRange; + nodeStart=&nodes[int(startPos.y/24)*game->WORLD_SIZE.x+int(startPos.x/24)]; nodeEnd=&nodes[int(endPos.y/24)*game->WORLD_SIZE.x+int(endPos.x/24)]; + + + geom2d::rectposPerimeter{{int(std::min(startPos.x,endPos.x)),int(std::min(startPos.y,endPos.y))},{int(abs(endPos.x-startPos.x)),int(abs(endPos.y-startPos.y))}}; + posPerimeter.pos={int(std::clamp(posPerimeter.pos.x-maxRange*24,0.f,game->WORLD_SIZE.x*24.f)),int(std::clamp(posPerimeter.pos.y-maxRange*24,0.f,game->WORLD_SIZE.y*24.f))}; + posPerimeter.size={int(std::clamp(posPerimeter.size.x+maxRange*24*2,0.f,game->WORLD_SIZE.x*24.f-posPerimeter.pos.x)),int(std::clamp(posPerimeter.size.y+maxRange*24*2,0.f,game->WORLD_SIZE.y*24.f-posPerimeter.pos.y))}; for (int x = 0; x < game->WORLD_SIZE.x; x++){ for (int y = 0; y < game->WORLD_SIZE.y; y++){ - nodes[y*game->WORLD_SIZE.x + x].bVisited = false; + if(geom2d::overlaps(posPerimeter,vi2d{x*24,y*24})){ + nodes[y*game->WORLD_SIZE.x + x].bVisited = false; + } else { + nodes[y*game->WORLD_SIZE.x + x].bVisited = true; + } nodes[y*game->WORLD_SIZE.x + x].fGlobalGoal = INFINITY; nodes[y*game->WORLD_SIZE.x + x].fLocalGoal = INFINITY; nodes[y*game->WORLD_SIZE.x + x].parent = nullptr; // No parents @@ -92,15 +104,21 @@ int Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos){ } } - int pathLength=0; if (nodeEnd != nullptr) { + int pathLength=INFINITE; sNode *p = nodeEnd; while (p->parent != nullptr) { - pathLength++; + if(pathLength==INFINITE){ + pathLength=1; + } else { + pathLength++; + } p = p->parent; } + return pathLength; + } else { + return INFINITE; } - return pathLength; } \ No newline at end of file diff --git a/Crawler/Pathfinding.h b/Crawler/Pathfinding.h index bfec4e83..efac4884 100644 --- a/Crawler/Pathfinding.h +++ b/Crawler/Pathfinding.h @@ -20,5 +20,6 @@ struct Pathfinding{ sNode *nodeEnd = nullptr; void Initialize(); - int Solve_AStar(vf2d startPos,vf2d endPos); + //maxRange in tiles. + int Solve_AStar(vf2d startPos,vf2d endPos,float maxRange=8); }; \ No newline at end of file diff --git a/Crawler/Player.cpp b/Crawler/Player.cpp index 47b12d57..52ea9e38 100644 --- a/Crawler/Player.cpp +++ b/Crawler/Player.cpp @@ -435,6 +435,7 @@ std::vectorPlayer::GetBuffs(BuffType buff){ return filteredBuffs; } -bool Player::CanPathfindTo(vf2d pos,vf2d targetPos){ - return path.Solve_AStar(pos,targetPos)<8;//We'll say 7 tiles or less is close enough to 650 range. Have a little bit of wiggle room. +bool Player::CanPathfindTo(vf2d pos,vf2d targetPos,float range){ + int pathLength=path.Solve_AStar(pos,targetPos); + return pathLength<8;//We'll say 7 tiles or less is close enough to 650 range. Have a little bit of wiggle room. } \ No newline at end of file diff --git a/Crawler/Player.h b/Crawler/Player.h index 4e595a2e..31ea66bd 100644 --- a/Crawler/Player.h +++ b/Crawler/Player.h @@ -44,6 +44,7 @@ struct Player{ vf2d teleportStartPosition={}; std::pair notEnoughManaDisplay={"",0}; std::pair notificationDisplay={"",0}; + float teleportAttemptWaitTime=0; //If a teleport fails, we wait awhile before trying again, it's expensive. State state=State::NORMAL; Animate2D::Animationanimation; Animate2D::AnimationState internal_animState; @@ -89,7 +90,8 @@ struct Player{ bool HasIframes(); void UpdateWalkingAnimation(Key direction); void UpdateIdleAnimation(Key direction); - bool CanPathfindTo(vf2d pos,vf2d targetPos); + //The range is the search range in tiles. + bool CanPathfindTo(vf2d pos,vf2d targetPos,float range=8); void AddBuff(BuffType type,float duration,float intensity); std::vectorGetBuffs(BuffType buff); diff --git a/Crawler/Version.h b/Crawler/Version.h index 07b0bd56..33e4fe2b 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -2,7 +2,7 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 424 +#define VERSION_BUILD 440 #define stringify(a) stringify_(a) #define stringify_(a) #a