Initial part of the rewrite for the autowalker to fix the pathing and aiming issues.
This commit is contained in:
		
							parent
							
								
									63eaea3536
								
							
						
					
					
						commit
						c894f6e094
					
				
					 2 changed files with 45 additions and 75 deletions
				
			
		
							
								
								
									
										114
									
								
								autowalker.cpp
									
										
									
									
									
								
							
							
						
						
									
										114
									
								
								autowalker.cpp
									
										
									
									
									
								
							|  | @ -2,6 +2,7 @@ | |||
| #include "ai_debug.hpp" | ||||
| #include "gui/ritual_ui.hpp" | ||||
| #include "game_level.hpp" | ||||
| #define DEBUG | ||||
| 
 | ||||
| struct InventoryStats { | ||||
|   int healing = 0; | ||||
|  | @ -102,20 +103,23 @@ void Autowalker::process_combat() { | |||
|     if(fsm.in_state(gui::State::ATTACKING)) { | ||||
|       send_event(gui::Event::TICK); | ||||
|     } else { | ||||
|       send_event(gui::Event::ATTACK);; | ||||
|       send_event(gui::Event::ATTACK); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| Point Autowalker::get_current_position() { | ||||
|   return GameDB::player_position().location; | ||||
| } | ||||
| 
 | ||||
| void Autowalker::path_fail(Matrix& bad_paths, Point pos) { | ||||
| void Autowalker::path_fail(const std::string& msg, Matrix& bad_paths, Point pos) { | ||||
|   status(L"PATH FAIL"); | ||||
|   log(L"Autowalk failed to find a path."); | ||||
| #ifdef DEBUG | ||||
|   matrix::dump("MOVE FAIL PATHS", bad_paths, pos.x, pos.y); | ||||
|   dbc::sentinel(fmt::format("[{}]: Autowalk failed to find a path.", msg)); | ||||
| #else | ||||
|   log(L"Autowalk failed to find a path."); | ||||
|   (void)bad_paths; // shutup compiler errors
 | ||||
|   (void)pos; | ||||
|   (void)msg; | ||||
|   send_event(gui::Event::STAIRS_DOWN); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| bool Autowalker::path_player(Pathing& paths, Point& target_out) { | ||||
|  | @ -125,77 +129,29 @@ bool Autowalker::path_player(Pathing& paths, Point& target_out) { | |||
|   if(!found) { | ||||
|     // failed to find a linear path, try diagonal
 | ||||
|     if(!paths.random_walk(target_out, false, PATHING_TOWARD, 8, 8)) { | ||||
|       path_fail(paths.$paths, target_out); | ||||
|       path_fail("random_walk", paths.$paths, target_out); | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if(!level.map->can_move(target_out)) { | ||||
|     path_fail(paths.$paths, target_out); | ||||
|     path_fail("level_map->can_move", paths.$paths, target_out); | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void Autowalker::rotate_player(Point current, Point target) { | ||||
|   int delta_x = int(target.x) - int(current.x); | ||||
|   int delta_y = int(target.y) - int(current.y); | ||||
| void Autowalker::rotate_player(Point target) { | ||||
|   auto rayview = fsm.$main_ui.$rayview; | ||||
| 
 | ||||
|   int facing = fsm.$main_ui.$compass_dir; | ||||
|   int target_facing = 0; | ||||
|   // auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT;
 | ||||
|   auto dir = gui::Event::ROTATE_LEFT; | ||||
| 
 | ||||
|   /* This is a massive pile of garbage. Need a way
 | ||||
|    * to determine player facing direction without | ||||
|    * hacking into the compass, and also do accurate | ||||
|    * turns. | ||||
|    */ | ||||
|   if(delta_x == -1 && delta_y == 0) { | ||||
|     // west
 | ||||
|     target_facing = 4; | ||||
|   } else if(delta_x == 1 && delta_y == 0) { | ||||
|     // east
 | ||||
|     target_facing = 0; | ||||
|   } else if(delta_x == 0 && delta_y == 1) { | ||||
|     // south
 | ||||
|     target_facing = 2; | ||||
|   } else if(delta_x == 0 && delta_y == -1) { | ||||
|     // north
 | ||||
|     target_facing = 6; | ||||
|   } else if(delta_x == 1 && delta_y == -1) { | ||||
|     // north east
 | ||||
|     target_facing = 7; | ||||
|   } else if(delta_x == 1 && delta_y == 1) { | ||||
|     // south east
 | ||||
|     target_facing = 1; | ||||
|   } else if(delta_x == -1 && delta_y == 1) { | ||||
|     // south west
 | ||||
|     target_facing = 3; | ||||
|   } else if(delta_x == -1 && delta_y == -1) { | ||||
|     // north west
 | ||||
|     target_facing = 5; | ||||
|   } else { | ||||
|     dbc::sentinel( | ||||
|         fmt::format("got more than 8 direction result: " | ||||
|           "current={},{} " | ||||
|           "target={},{} " | ||||
|           "delta={},{} ", | ||||
|           current.x, current.y, | ||||
|           target.x, target.y, | ||||
|           delta_x, delta_y)); | ||||
|   } | ||||
| 
 | ||||
|   auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT; | ||||
| 
 | ||||
|   while(facing != target_facing) { | ||||
|   while(rayview->aiming_at != target) { | ||||
|     send_event(dir); | ||||
|     facing = fsm.$main_ui.$compass_dir; | ||||
|     while(fsm.in_state(gui::State::ROTATING)) send_event(gui::Event::TICK); | ||||
|   } | ||||
| 
 | ||||
|   while(fsm.in_state(gui::State::ROTATING)) send_event(gui::Event::TICK); | ||||
| 
 | ||||
|   dbc::check(fsm.$main_ui.$compass_dir == target_facing, | ||||
|       "player isn't facing the correct direction"); | ||||
| } | ||||
| 
 | ||||
| ai::State Autowalker::update_state(ai::State start) { | ||||
|  | @ -240,14 +196,11 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) { | |||
|   } else if(action.name == "kill_enemy") { | ||||
|     status(L"KILLING ENEMY"); | ||||
| 
 | ||||
|     // TODO: find the enemy and then rotate toward them
 | ||||
|     Point current = get_current_position(); | ||||
|     if(fsm.in_state(gui::State::IN_COMBAT)) { | ||||
|       rotate_player(current, {current.x - 1, current.y - 1}); | ||||
|       dbc::log("TODO: you should find the enemy and face them instead of THIS GARBAGE!"); | ||||
|       if(face_enemy()) { | ||||
|         process_combat(); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     process_combat(); | ||||
|   } else if(action.name == "use_healing") { | ||||
|     status(L"USING HEALING"); | ||||
|     player_use_healing(); | ||||
|  | @ -332,16 +285,17 @@ void Autowalker::autowalk() { | |||
| 
 | ||||
| void Autowalker::process_move(Pathing& paths) { | ||||
|   auto world = GameDB::current_world(); | ||||
|   Point current = get_current_position(); | ||||
|   Point target = current; | ||||
|   // target has to start at the player location then...
 | ||||
|   auto target = GameDB::player_position().location; | ||||
| 
 | ||||
|   // ... target gets modified as an out parameter to find the path
 | ||||
|   if(!path_player(paths, target)) { | ||||
|     close_status(); | ||||
|     log(L"No paths found, aborting autowalk."); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   rotate_player(current, target); | ||||
|   rotate_player(target); | ||||
| 
 | ||||
|   // what are we aiming at?
 | ||||
|   auto aimed_at = camera_aim(); | ||||
|  | @ -383,3 +337,19 @@ void Autowalker::player_use_healing() { | |||
| void Autowalker::start_autowalk() { | ||||
|   fsm.autowalking = true; | ||||
| } | ||||
| 
 | ||||
| bool Autowalker::face_enemy() { | ||||
|   auto& level = GameDB::current_level(); | ||||
|   auto player_at = GameDB::player_position(); | ||||
| 
 | ||||
|   auto [found, neighbors] = level.collision->neighbors(player_at.location, true); | ||||
| 
 | ||||
|   if(found) { | ||||
|     auto enemy_pos = level.world->get<components::Position>(neighbors[0]); | ||||
|     rotate_player(enemy_pos.location); | ||||
|   } else { | ||||
|     dbc::log("No enemies nearby, moving on."); | ||||
|   } | ||||
| 
 | ||||
|   return found; | ||||
| } | ||||
|  |  | |||
|  | @ -28,9 +28,8 @@ struct Autowalker { | |||
|   void send_event(gui::Event ev); | ||||
|   void process_combat(); | ||||
|   bool path_player(Pathing& paths, Point &target_out); | ||||
|   void path_fail(Matrix& bad_paths, Point pos); | ||||
|   Point get_current_position(); | ||||
|   void rotate_player(Point current, Point target); | ||||
|   void path_fail(const std::string& msg, Matrix& bad_paths, Point pos); | ||||
|   void rotate_player(Point target); | ||||
|   void process_move(Pathing& paths); | ||||
|   void log(std::wstring msg); | ||||
|   void status(std::wstring msg); | ||||
|  | @ -43,4 +42,5 @@ struct Autowalker { | |||
| 
 | ||||
|   Pathing path_to_enemies(); | ||||
|   Pathing path_to_items(); | ||||
|   bool face_enemy(); | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Zed A. Shaw
						Zed A. Shaw