Use pathfinding algorithm to determine teleport validity.
This commit is contained in:
		
							parent
							
								
									c97886fbbe
								
							
						
					
					
						commit
						46e3c7f7e7
					
				| @ -4,8 +4,6 @@ | ||||
| #include "olcUTIL_Animate2D.h" | ||||
| #include "Monster.h" | ||||
| 
 | ||||
| #define INFINITE 999999 | ||||
| 
 | ||||
| struct Bullet{ | ||||
| 	friend class Crawler; | ||||
| 	vf2d pos; | ||||
|  | ||||
| @ -306,10 +306,10 @@ bool Wizard::RightClickAbility(){ | ||||
| 	float dist=std::clamp(geom2d::line<float>{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; | ||||
|  | ||||
| @ -10,4 +10,6 @@ | ||||
| #define INCLUDE_PLAYER_BULLET_LIST extern std::vector<std::unique_ptr<Bullet>>PLAYER_BULLET_LIST; | ||||
| #define INCLUDE_PARTICLE_LIST extern std::vector<Particle>PARTICLE_LIST; | ||||
| 
 | ||||
| #define ACCESS_PLAYER Player&p=game->GetPlayer(); | ||||
| #define ACCESS_PLAYER Player&p=game->GetPlayer(); | ||||
| 
 | ||||
| #define INFINITE 999999 | ||||
| @ -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::rect<int>tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)}); | ||||
|                 geom2d::rect<int>tile=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::rect<int>posPerimeter{{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; | ||||
| } | ||||
| @ -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); | ||||
| }; | ||||
| @ -435,6 +435,7 @@ std::vector<Buff>Player::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.
 | ||||
| } | ||||
| @ -44,6 +44,7 @@ struct Player{ | ||||
| 	vf2d teleportStartPosition={}; | ||||
| 	std::pair<std::string,float> notEnoughManaDisplay={"",0}; | ||||
| 	std::pair<std::string,float> notificationDisplay={"",0}; | ||||
| 	float teleportAttemptWaitTime=0; //If a teleport fails, we wait awhile before trying again, it's expensive.
 | ||||
| 	State state=State::NORMAL; | ||||
| 	Animate2D::Animation<AnimationState>animation; | ||||
| 	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::vector<Buff>GetBuffs(BuffType buff); | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user