Actually working maze

This commit is contained in:
Carlos Sanchez 2024-08-18 06:37:04 -04:00
parent 21894acdb0
commit e09d1a2413

106
maze.c
View File

@ -71,6 +71,8 @@ typedef struct {
// State for tracking ai moving through the maze. // State for tracking ai moving through the maze.
typedef struct { typedef struct {
uint8_t state; uint8_t state;
// uint8_t nextdir;
uint32_t timer;
} ecs_smartai; } ecs_smartai;
struct vec2i dirtovec(uint8_t dir) { struct vec2i dirtovec(uint8_t dir) {
@ -207,60 +209,65 @@ static void sys_ecs_smartai(haloo_ecs *ecs, hecs_eidt id, hecs_cidt said,
ecs_maze *maze = HECS_ENTITYCOMPONENT(ecs_maze *, id, mzid, ecs); ecs_maze *maze = HECS_ENTITYCOMPONENT(ecs_maze *, id, mzid, ecs);
ecs_moveto *mt = HECS_ENTITYCOMPONENT(ecs_moveto *, id, mtid, ecs); ecs_moveto *mt = HECS_ENTITYCOMPONENT(ecs_moveto *, id, mtid, ecs);
ecs_rotateto *rt = HECS_ENTITYCOMPONENT(ecs_rotateto *, id, rtid, ecs); ecs_rotateto *rt = HECS_ENTITYCOMPONENT(ecs_rotateto *, id, rtid, ecs);
// Player can only move if the previous timer expired int actiontime = fps / 2;
// if (mt->timer == 0) { // Some states are triggered based on the timer
// // Player can only move forward if they can't turn right if (smartai->timer > 0) {
// uint8_t rightdir = TURNRIGHT(maze->dir); smartai->timer--;
// if (!maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size, }
// rightdir)) { // The rotation is delayed to make it feel a bit more like the original
// struct vec2i movement = dirtovec(maze->dir); // maze, which I think determined rotation and direction upon entering
// maze->pos.x += movement.x; // a tile. I instead calculate that in the middle of the tile. It doesn't
// maze->pos.y += movement.y; // really line up like it does on the windows screensaver but it's
// mt->timer = fps / 2; // close enough for me.
// mt->dst.x += HSCALE * movement.x; if (smartai->timer == 0) {
// mt->dst.z += HSCALE * movement.y; if (smartai->state == 1) {
// // smartai->state = 0; // We are no longer stuck, you can turn right eprintf("TURNING RIGHT\n");
// } rt->dstrot.x = rt->dstrot.x + MPI_2;
// } rt->timer = actiontime;
// At this point, maze->dir = TURNRIGHT(maze->dir);
if (mt->timer == 0) { // && rt->timer == 0) { smartai->state = 0;
// eprintf("SMARTAI: %d DIR: %d POS: (%f, %f)\n", smartai->state, maze->dir, } else if (smartai->state == 2) {
// mt->pos.x, mt->pos.z); eprintf("TURNING LEFT\n");
// We can only do things if we're not moving and not rotating rt->dstrot.x = rt->dstrot.x - MPI_2;
// First, we see if we can turn right. If so, go for it. rt->timer = actiontime;
uint8_t newdir = TURNRIGHT(maze->dir); maze->dir = TURNLEFT(maze->dir);
if (smartai->state == 0 && rt->timer == 0 && smartai->state = 0;
maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size,
newdir)) {
rt->dstrot.x = rt->rot.x + MPI_2;
rt->timer = fps / 2;
maze->dir = newdir;
smartai->state = 2;
// We are turning and want to move forward, do not turn right again
eprintf("TURN RIGHT TO: %d\n", maze->dir);
return;
} }
// -=------------ SEPARATE }
// Now, we see if we can move in the direction we're now facing. If so, // Only decide to do things if you're not moving anymore. Movement is the most
// begin an animation to move there. Otherwise, turn left // important thing
if (!maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size, if (mt->timer == 0) {
maze->dir)) { eprintf("SMARTAI: %d TIMER: %d DIR: %d POS: (%f, %f)\n", smartai->state,
if (rt->timer <= 0) { smartai->timer, maze->dir, mt->pos.x, mt->pos.z);
rt->dstrot.x = rt->rot.x - MPI_2; // Player can only move forward if there's nothing in front of them
rt->timer = fps / 2; if (maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size,
maze->dir = TURNLEFT(maze->dir); maze->dir)) {
eprintf("TURN LEFT (stuck): %d\n", maze->dir);
smartai->state = 1; // We are stuck, do not turn right
}
} else {
// Move in the direction
struct vec2i movement = dirtovec(maze->dir); struct vec2i movement = dirtovec(maze->dir);
maze->pos.x += movement.x; maze->pos.x += movement.x;
maze->pos.y += movement.y; maze->pos.y += movement.y;
mt->timer = fps / 2; mt->timer = actiontime;
mt->dst.x += HSCALE * movement.x; mt->dst.x += HSCALE * movement.x;
mt->dst.z += HSCALE * movement.y; mt->dst.z += HSCALE * movement.y;
smartai->state = 0; // We are no longer stuck, you can turn right smartai->state = 0;
}
if (smartai->timer <= 0) {
// Ok we might be moving, we might not be. Let's go ahead and calculate
// rotation based on the FUTURE direction we want to turn.
uint8_t rightdir = TURNRIGHT(maze->dir);
uint8_t leftdir = TURNLEFT(maze->dir);
if (maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size,
rightdir)) {
// Always choose right over left
smartai->state = 1;
smartai->timer = 2 * actiontime / 5;
eprintf("WILL TURN RIGHT TO: %d\n", rightdir);
} else if (!maze_connected(maze->maze, maze->pos.x, maze->pos.y,
maze->size, maze->dir)) {
// We only move left if the player can't move forward or right
smartai->state = 2;
smartai->timer = 2 * actiontime / 5;
eprintf("WILL TURN LEFT (stuck) TO: %d\n", leftdir);
}
} }
} }
} }
@ -416,7 +423,8 @@ int main() { // int argc, char **argv) {
HECS_SETCOMPONENT(ecs_maze, &ecs, playerid){ HECS_SETCOMPONENT(ecs_maze, &ecs, playerid){
.maze = maze, .pos = playerstart, .size = MAZESIZE, .dir = DIRSOUTH}; .maze = maze, .pos = playerstart, .size = MAZESIZE, .dir = DIRSOUTH};
HECS_SETCOMPONENT(ecs_camera, &ecs, playerid) & render.camera; HECS_SETCOMPONENT(ecs_camera, &ecs, playerid) & render.camera;
HECS_SETCOMPONENT(ecs_smartai, &ecs, playerid){.state = 0}; HECS_SETCOMPONENT(ecs_smartai, &ecs, playerid){.state = 0,
.timer = 0}; //, .nextdir = 0};
eprintf("Player component mask: %lx\n", ecs.e_components[playerid]); eprintf("Player component mask: %lx\n", ecs.e_components[playerid]);
// ----------------------------------- // -----------------------------------