npc : Debug pathfinding

This commit is contained in:
attilavs2 2024-08-02 23:15:48 +02:00
parent 10d44d6a88
commit 84043e31e7
3 changed files with 43 additions and 28 deletions

View file

@ -273,7 +273,7 @@ void game_get_inputs(Game *game) {
mynpc->y = player->x; mynpc->y = player->x;
mynpc->hasPath = 0; mynpc->hasPath = 0;
mynpc->owns_path = false; mynpc->owns_path = false;
mynpc->face = 1; mynpc->face = 0;
mynpc->paused = 0; mynpc->paused = 0;
mynpc->has_dialog = 0; mynpc->has_dialog = 0;
mynpc->xpath = NULL; mynpc->xpath = NULL;

View file

@ -91,44 +91,49 @@ void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) {
free(fscore); free(fscore);
} }
// TODO : Fix int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t start,
int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos, int16_t dest, bool is_alloc, NPC *npc) {
int16_t dest, NPC *npc) {
if(npc_clear_path(npc)) if(npc_clear_path(npc))
goto as_recons_fail; goto as_recons_fail;
int16_t next = came_from[dest]; int16_t prev = came_from[dest];
unsigned int i; uint32_t i;
int x, y;
for(i = 0; i < 64; i++) { for(i = 0; i < PATHFIND_MAX_ITER; i++) {
if(npc_append_path((next % w) * T_WIDTH, (next / h) * T_HEIGHT, npc)) { x = ((prev%w)*T_WIDTH + T_WIDTH/2) << PRECISION;
y = ((prev/w)*T_HEIGHT + T_HEIGHT/2) << PRECISION;
if(npc_append_path(x,y,npc)) {
goto as_recons_fail; goto as_recons_fail;
} }
prev = came_from[prev];
next = came_from[next]; if(prev == start){
if(next == spos) { x = ((prev%w)*T_WIDTH + T_WIDTH/2) << PRECISION;
if(npc_append_path((spos % w) * T_WIDTH, (spos / h) * T_HEIGHT, y = ((prev/w)*T_HEIGHT + T_HEIGHT/2) << PRECISION;
npc)) if(npc_append_path(x,y,npc))
goto as_recons_fail; goto as_recons_fail;
break; break;
} }
if(prev == -1)
goto as_recons_fail;
} }
uint16_t tx, ty; uint16_t tx, ty;
// Flip the path because it started from the end // Flip the path because it started from the end
for(i = 0; i < npc->path_length / 2; i++) { /*for(i = 0; i < npc->path_length / 2; i++) {
tx = npc->xpath[i]; tx = npc->xpath[i];
ty = npc->ypath[i]; ty = npc->ypath[i];
npc->xpath[i] = npc->xpath[npc->path_length - i - 1]; npc->xpath[i] = npc->xpath[npc->path_length - i - 1];
npc->ypath[i] = npc->ypath[npc->path_length - i - 1]; npc->ypath[i] = npc->ypath[npc->path_length - i - 1];
npc->ypath[npc->path_length - i - 1] = tx; npc->ypath[npc->path_length - i - 1] = tx;
npc->ypath[npc->path_length - i - 1] = ty; npc->ypath[npc->path_length - i - 1] = ty;
} }*/
free(came_from); if(is_alloc)
free(came_from);
npc->hasPath = true; npc->hasPath = true;
@ -136,7 +141,8 @@ int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
as_recons_fail: as_recons_fail:
free(came_from); if(is_alloc)
free(came_from);
return 1; return 1;
} }
@ -148,8 +154,8 @@ uint32_t xyram = 0xe500e000 + 32;
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) { int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
int32_t i, j; int32_t i, j;
int32_t w = full_map->w; int32_t w = full_map->w/T_WIDTH/PXSIZE;
int32_t h = full_map->h; int32_t h = full_map->h/T_HEIGHT/PXSIZE;
int32_t x = (npc->curx >> PRECISION) / T_WIDTH; int32_t x = (npc->curx >> PRECISION) / T_WIDTH;
int32_t y = (npc->cury >> PRECISION) / T_HEIGHT; int32_t y = (npc->cury >> PRECISION) / T_HEIGHT;
dest_x /= T_WIDTH; dest_x /= T_WIDTH;
@ -158,8 +164,8 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
uint8_t *map = full_map->walkable; uint8_t *map = full_map->walkable;
if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h) /*if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h)
return 2; return 2;*/
if(map[spos]) if(map[spos])
return 2; return 2;
if(map[dest_y * w + dest_x]) if(map[dest_y * w + dest_x])
@ -172,7 +178,11 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
uint8_t *gscore; uint8_t *gscore;
uint8_t *fscore; uint8_t *fscore;
if(isSH3() || w * h * 5 > 1024 * 15) { bool is_alloc;
if(1 || isSH3() || w * h * 5 > 1024 * 15) {
is_alloc = true;
visited = malloc(w * h); visited = malloc(w * h);
came_from = malloc(w * h * 2); came_from = malloc(w * h * 2);
gscore = malloc(w * h * 2); gscore = malloc(w * h * 2);
@ -182,6 +192,7 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
free(came_from); free(came_from);
return 4; return 4;
} }
for(i = 0; i < w * h; i++) for(i = 0; i < w * h; i++)
visited[i] = 1; visited[i] = 1;
for(i = 0; i < w * h; i++) for(i = 0; i < w * h; i++)
@ -191,6 +202,8 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
for(i = 0; i < w * h; i++) for(i = 0; i < w * h; i++)
fscore[i] = 255; fscore[i] = 255;
} else { } else {
is_alloc = false;
visited = (void *)xyram; visited = (void *)xyram;
gscore = (void *)(xyram + w * h); gscore = (void *)(xyram + w * h);
fscore = (void *)(xyram + w * h * 2); fscore = (void *)(xyram + w * h * 2);
@ -213,7 +226,7 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
int32_t bx = x; int32_t bx = x;
int32_t by = y; int32_t by = y;
for(int iter = 0; iter < 64; iter++) { for(int iter = 0; iter < PATHFIND_MAX_ITER; iter++) {
bscore = 255; bscore = 255;
/* Cheapest known tile */ /* Cheapest known tile */
/* Could be improved with a priority queue*/ /* Could be improved with a priority queue*/
@ -230,9 +243,8 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
} }
if(bx == dest_x && by == dest_y) { if(bx == dest_x && by == dest_y) {
as_clean(visited, gscore, fscore); as_clean(visited, gscore, fscore);
return 1 /*as_reconstruct_path(came_from, w, h, spos, return 0; /*as_reconstruct_path(came_from, w, h, spos,
dest_y * w + dest_x, npc)*/ dest_y * w + dest_x, npc)*/
;
} }
visited[by * w + bx] = 1; visited[by * w + bx] = 1;
@ -276,8 +288,9 @@ void update_npcs(Game *game) {
} }
for(i = 0; i < npc_count; i++) { for(i = 0; i < npc_count; i++) {
update_npc(&npc_stack[i]); update_npc(&npc_stack[i]);
/*npc_pathfind(game->player.x, game->player.y, game->map_level, /*Temp debug*/
&npc_stack[i]);*/ game->mana = npc_pathfind(game->player.x, game->player.y, game->map_level,
&npc_stack[i]);
} }
} }

View file

@ -7,6 +7,9 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
/*Maximum iterations before the pathfinding considers the target unreacheable*/
#define PATHFIND_MAX_ITER 64
enum { enum {
NPC_NONE = 0, NPC_NONE = 0,
@ -14,7 +17,6 @@ enum {
NPC_HOSTILE = 2, // to the player NPC_HOSTILE = 2, // to the player
NPC_ALL = 3 NPC_ALL = 3
}; };
/* /!\ Warning /!\ /* /!\ Warning /!\
* Do not keep hard references to non-static NPCs, as they will likely move * Do not keep hard references to non-static NPCs, as they will likely move
* in the stack */ * in the stack */