|
|
|
@ -74,12 +74,25 @@ void Pathing::clear_target(const Point &at) { |
|
|
|
|
$input[at.y][at.x] = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Pathing::random_walk(Point &out, bool random, int direction, size_t dir_count) { |
|
|
|
|
/*
|
|
|
|
|
* This is a weird discovery, but if you randomly select a starting point on |
|
|
|
|
* the 8 compass, but only check 4 directions from there, it does the best |
|
|
|
|
* pathing so far. It will walk around items, navigate around enemies, find |
|
|
|
|
* paths through corners, etc. If you change slice_count/dist_count to just |
|
|
|
|
* 4 it fails more frequently. |
|
|
|
|
* |
|
|
|
|
* Look in the autowalker.cpp:path_player function for an example of what |
|
|
|
|
* I'm doing. I start with 4/8 and it finds paths 99% of the time, but |
|
|
|
|
* if that fails I do a full 8 direction search. This weirdly finds the |
|
|
|
|
* best directions to go more often. |
|
|
|
|
*/ |
|
|
|
|
bool Pathing::random_walk(Point &out, bool random, |
|
|
|
|
int direction, size_t slice_count, size_t dist_size) |
|
|
|
|
{ |
|
|
|
|
bool zero_found = false; |
|
|
|
|
dbc::check(dir_count == 4 || dir_count == 8, "Only 8 or 4 directions allowed."); |
|
|
|
|
|
|
|
|
|
// first 4 directions are n/s/e/w for most enemies
|
|
|
|
|
std::array<Point, 8> dirs{{ |
|
|
|
|
std::array<Point, DIRECTION_MAX> dirs{{ |
|
|
|
|
{out.x,out.y-1}, // north
|
|
|
|
|
{out.x+1,out.y}, // east
|
|
|
|
|
{out.x,out.y+1}, // south
|
|
|
|
@ -92,19 +105,22 @@ bool Pathing::random_walk(Point &out, bool random, int direction, size_t dir_cou |
|
|
|
|
{out.x-1,out.y-1} // north west
|
|
|
|
|
}}; |
|
|
|
|
|
|
|
|
|
dbc::check(slice_count <= dirs.size(), "slize_count must be <= DIRECTION_MAX"); |
|
|
|
|
dbc::check(dist_size <= dirs.size(), "dist_size must be <= DIRECTION_MAX"); |
|
|
|
|
|
|
|
|
|
// get the current dijkstra number
|
|
|
|
|
int cur = $paths[out.y][out.x]; |
|
|
|
|
|
|
|
|
|
// pick a random start of directions
|
|
|
|
|
// BUG: is uniform inclusive of the dir.size()?
|
|
|
|
|
int rand_start = Random::uniform<int>(0, dir_count); |
|
|
|
|
int rand_start = Random::uniform<int>(0, dist_size); |
|
|
|
|
|
|
|
|
|
// go through all possible directions
|
|
|
|
|
for(size_t i = 0; i < dir_count; i++) { |
|
|
|
|
for(size_t i = 0; i < slice_count; i++) { |
|
|
|
|
// but start at the random start, effectively randomizing
|
|
|
|
|
// which valid direction to go
|
|
|
|
|
// BUG: this might be wrong given the above ranom from 0-size
|
|
|
|
|
Point dir = dirs[(i + rand_start) % dir_count]; |
|
|
|
|
Point dir = dirs[(i + rand_start) % dist_size]; |
|
|
|
|
if(!shiterator::inbounds($paths, dir.x, dir.y)) continue; //skip unpathable stuff
|
|
|
|
|
int weight = cur - $paths[dir.y][dir.x]; |
|
|
|
|
|
|
|
|
|