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->hasPath = 0;
mynpc->owns_path = false;
mynpc->face = 1;
mynpc->face = 0;
mynpc->paused = 0;
mynpc->has_dialog = 0;
mynpc->xpath = NULL;

View file

@ -91,44 +91,49 @@ void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) {
free(fscore);
}
// TODO : Fix
int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
int16_t dest, NPC *npc) {
int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t start,
int16_t dest, bool is_alloc, NPC *npc) {
if(npc_clear_path(npc))
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++) {
if(npc_append_path((next % w) * T_WIDTH, (next / h) * T_HEIGHT, npc)) {
for(i = 0; i < PATHFIND_MAX_ITER; i++) {
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;
}
next = came_from[next];
if(next == spos) {
if(npc_append_path((spos % w) * T_WIDTH, (spos / h) * T_HEIGHT,
npc))
prev = came_from[prev];
if(prev == start){
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;
break;
}
if(prev == -1)
goto as_recons_fail;
}
uint16_t tx, ty;
// 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];
ty = npc->ypath[i];
npc->xpath[i] = npc->xpath[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] = ty;
}
}*/
free(came_from);
if(is_alloc)
free(came_from);
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:
free(came_from);
if(is_alloc)
free(came_from);
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) {
int32_t i, j;
int32_t w = full_map->w;
int32_t h = full_map->h;
int32_t w = full_map->w/T_WIDTH/PXSIZE;
int32_t h = full_map->h/T_HEIGHT/PXSIZE;
int32_t x = (npc->curx >> PRECISION) / T_WIDTH;
int32_t y = (npc->cury >> PRECISION) / T_HEIGHT;
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;
if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h)
return 2;
/*if(dest_x < 0 || dest_x > w || dest_y < 0 || dest_x > h)
return 2;*/
if(map[spos])
return 2;
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 *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);
came_from = 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);
return 4;
}
for(i = 0; i < w * h; i++)
visited[i] = 1;
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++)
fscore[i] = 255;
} else {
is_alloc = false;
visited = (void *)xyram;
gscore = (void *)(xyram + w * h);
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 by = y;
for(int iter = 0; iter < 64; iter++) {
for(int iter = 0; iter < PATHFIND_MAX_ITER; iter++) {
bscore = 255;
/* Cheapest known tile */
/* 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) {
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)*/
;
}
visited[by * w + bx] = 1;
@ -276,8 +288,9 @@ void update_npcs(Game *game) {
}
for(i = 0; i < npc_count; i++) {
update_npc(&npc_stack[i]);
/*npc_pathfind(game->player.x, game->player.y, game->map_level,
&npc_stack[i]);*/
/*Temp debug*/
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 <stdint.h>
/*Maximum iterations before the pathfinding considers the target unreacheable*/
#define PATHFIND_MAX_ITER 64
enum {
NPC_NONE = 0,
@ -14,7 +17,6 @@ enum {
NPC_HOSTILE = 2, // to the player
NPC_ALL = 3
};
/* /!\ Warning /!\
* Do not keep hard references to non-static NPCs, as they will likely move
* in the stack */