diff --git a/maze.c b/maze.c index 07dd48e..e35254a 100644 --- a/maze.c +++ b/maze.c @@ -71,6 +71,8 @@ typedef struct { // State for tracking ai moving through the maze. typedef struct { uint8_t state; + // uint8_t nextdir; + uint32_t timer; } ecs_smartai; 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_moveto *mt = HECS_ENTITYCOMPONENT(ecs_moveto *, id, mtid, ecs); ecs_rotateto *rt = HECS_ENTITYCOMPONENT(ecs_rotateto *, id, rtid, ecs); - // Player can only move if the previous timer expired - // if (mt->timer == 0) { - // // Player can only move forward if they can't turn right - // uint8_t rightdir = TURNRIGHT(maze->dir); - // if (!maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size, - // rightdir)) { - // struct vec2i movement = dirtovec(maze->dir); - // maze->pos.x += movement.x; - // maze->pos.y += movement.y; - // mt->timer = fps / 2; - // mt->dst.x += HSCALE * movement.x; - // mt->dst.z += HSCALE * movement.y; - // // smartai->state = 0; // We are no longer stuck, you can turn right - // } - // } - // At this point, - if (mt->timer == 0) { // && rt->timer == 0) { - // eprintf("SMARTAI: %d DIR: %d POS: (%f, %f)\n", smartai->state, maze->dir, - // mt->pos.x, mt->pos.z); - // We can only do things if we're not moving and not rotating - // First, we see if we can turn right. If so, go for it. - uint8_t newdir = TURNRIGHT(maze->dir); - if (smartai->state == 0 && rt->timer == 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; + int actiontime = fps / 2; + // Some states are triggered based on the timer + if (smartai->timer > 0) { + smartai->timer--; + } + // The rotation is delayed to make it feel a bit more like the original + // maze, which I think determined rotation and direction upon entering + // a tile. I instead calculate that in the middle of the tile. It doesn't + // really line up like it does on the windows screensaver but it's + // close enough for me. + if (smartai->timer == 0) { + if (smartai->state == 1) { + eprintf("TURNING RIGHT\n"); + rt->dstrot.x = rt->dstrot.x + MPI_2; + rt->timer = actiontime; + maze->dir = TURNRIGHT(maze->dir); + smartai->state = 0; + } else if (smartai->state == 2) { + eprintf("TURNING LEFT\n"); + rt->dstrot.x = rt->dstrot.x - MPI_2; + rt->timer = actiontime; + maze->dir = TURNLEFT(maze->dir); + smartai->state = 0; } - // -=------------ SEPARATE - // Now, we see if we can move in the direction we're now facing. If so, - // begin an animation to move there. Otherwise, turn left - if (!maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size, - maze->dir)) { - if (rt->timer <= 0) { - rt->dstrot.x = rt->rot.x - MPI_2; - rt->timer = fps / 2; - maze->dir = TURNLEFT(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 + } + // Only decide to do things if you're not moving anymore. Movement is the most + // important thing + if (mt->timer == 0) { + eprintf("SMARTAI: %d TIMER: %d DIR: %d POS: (%f, %f)\n", smartai->state, + smartai->timer, maze->dir, mt->pos.x, mt->pos.z); + // Player can only move forward if there's nothing in front of them + if (maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size, + maze->dir)) { struct vec2i movement = dirtovec(maze->dir); maze->pos.x += movement.x; maze->pos.y += movement.y; - mt->timer = fps / 2; + mt->timer = actiontime; mt->dst.x += HSCALE * movement.x; 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){ .maze = maze, .pos = playerstart, .size = MAZESIZE, .dir = DIRSOUTH}; 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]); // -----------------------------------