No player?

This commit is contained in:
Carlos Sanchez 2024-08-19 02:24:19 -04:00
parent 06385f8311
commit ed2614fb30
2 changed files with 140 additions and 94 deletions

14
ecs2.h
View File

@ -102,4 +102,18 @@ typedef int ecs_eid;
} \ } \
} }
// Add a system function which automatically calls your given function with
// pre-pulled items from the entity component arrays. The new function is
// named the same as the old one, just with _run appeneded
#define ECS_SYSTEM5(ecsname, fname, type1, type2, type3, type4, type5) \
void fname##_run(ecsname *_ecs, ecs_eid eid) { \
ecs_cid _ecsflags = \
type1##_fl | type2##_fl | type3##_fl | type4##_fl | type5##_fl; \
if (ecsname##_match(_ecs, eid, _ecsflags)) { \
fname(_ecs->c_##type1 + eid, _ecs->c_##type2 + eid, \
_ecs->c_##type3 + eid, _ecs->c_##type4 + eid, \
_ecs->c_##type5 + eid); \
} \
}
#endif #endif

178
maze.c
View File

@ -80,6 +80,21 @@ struct vec2i dirtovec(uint8_t dir) {
return result; return result;
} }
mfloat_t dirtoyaw(uint8_t dir) {
switch (dir) {
case DIREAST:
return MPI_2;
case DIRWEST:
return -MPI_2;
case DIRNORTH:
return 0;
case DIRSOUTH:
return MPI;
default:
return 0;
}
}
int maze_visited(uint8_t *maze, int x, int y, int size) { int maze_visited(uint8_t *maze, int x, int y, int size) {
return (maze[x + y * size] & MAZEVISIT) > 0; return (maze[x + y * size] & MAZEVISIT) > 0;
} }
@ -327,6 +342,8 @@ void sys_camera(ecs_camera *cam, ecs_placement *p) {
cam->camera->pos = p->pos; cam->camera->pos = p->pos;
cam->camera->yaw = p->rot.x; cam->camera->yaw = p->rot.x;
cam->camera->pitch = p->rot.y; cam->camera->pitch = p->rot.y;
// eprintf("CAM: %f %f POS: %f %f %f\n", cam->camera->yaw, cam->camera->pitch,
// cam->camera->pos.x, cam->camera->pos.y, cam->camera->pos.z);
} }
void sys_world(ecs_world *w) { void sys_world(ecs_world *w) {
@ -373,40 +390,51 @@ void sys_world(ecs_world *w) {
} }
} }
// // A general position within the maze, and a pointer to the maze itself. enum {
// // Can be used to traverse the maze SAI_INIT,
// typedef struct { SAI_READY,
// uint8_t *maze; SAI_GAMEPLAY,
// struct vec2i pos; // tile position within maze };
// int size;
// uint8_t dir; // facing dir (see DIREAST/DIRSOUTH/etc);
// } ecs_maze;
// // Use a timer and a destination to move simply through // State for tracking a smart ai moving through the maze.
// typedef struct {
//
// } ecs_mazemove;
// State for tracking ai moving through the maze.
typedef struct { typedef struct {
uint8_t state; uint8_t state;
// uint8_t nextdir; uint8_t rotstate;
uint8_t dir;
uint32_t timer; uint32_t timer;
struct vec2i mpos;
} ecs_smartai; } ecs_smartai;
// typedef struct { static void sys_smartai(ecs_smartai *smartai, ecs_worldstate *ws,
// uint8_t *maze; ecs_autonav *anav, ecs_autorotate *arot) {
// // What state the game is in, such as game initialize, animation, running, const int actiontime = ws->state->fps / 2;
// etc uint8_t state; const int rotdelaytime = 2 * actiontime / 5;
// } ecs_world; switch (smartai->state) {
case SAI_INIT:
// everything in the maze is controlled by the CPU. As such, movement // Here, we wait until the world state is spinup, in which
// is as simple as "go here by this time". No need to complicate the // case we can spawn and face
// components? if (ws->state->state == WSTATE_SPINUP) {
/* smartai->mpos = ws->state->start;
static void sys_ecs_smartai(ecs_smartai *smartai, ecs_maze *maze, anav->dest.x = ws->state->cellsize * (ws->state->start.x + 0.5);
ecs_moveto *mt, ecs_rotateto *rt) { anav->dest.z = ws->state->cellsize * (ws->state->start.y + 0.5);
int actiontime = fps / 2; anav->timer = 0;
smartai->dir = maze_longesthallway(
ws->state->maze, MAZESIZE, ws->state->start.x, ws->state->start.y);
arot->dest.x = dirtoyaw(smartai->dir);
arot->timer = 0;
smartai->state = SAI_READY;
eprintf("PLAYER READY: %f %f (%f), waiting for spinup\n", anav->dest.x,
anav->dest.z, arot->dest.x);
}
break;
case SAI_READY:
if (ws->state->state == WSTATE_GAMEPLAY) {
smartai->state = SAI_GAMEPLAY;
eprintf("PLAYER STARTING GAMEPLAY\n");
}
break;
case SAI_GAMEPLAY:
// Normal gameplay: move through the maze, etc.
// Some states are triggered based on the timer // Some states are triggered based on the timer
if (smartai->timer > 0) { if (smartai->timer > 0) {
smartai->timer--; smartai->timer--;
@ -417,58 +445,62 @@ static void sys_ecs_smartai(ecs_smartai *smartai, ecs_maze *maze,
// really line up like it does on the windows screensaver but it's // really line up like it does on the windows screensaver but it's
// close enough for me. // close enough for me.
if (smartai->timer == 0) { if (smartai->timer == 0) {
if (smartai->state == 1) { if (smartai->rotstate == 1) {
eprintf("TURNING RIGHT\n"); eprintf("TURNING RIGHT\n");
rt->dstrot.x = rt->dstrot.x + MPI_2; arot->dest.x += MPI_2;
rt->timer = actiontime; arot->timer = actiontime;
maze->dir = TURNRIGHT(maze->dir); smartai->dir = TURNRIGHT(smartai->dir);
smartai->state = 0; smartai->rotstate = 0;
} else if (smartai->state == 2) { } else if (smartai->rotstate == 2) {
eprintf("TURNING LEFT\n"); eprintf("TURNING LEFT\n");
rt->dstrot.x = rt->dstrot.x - MPI_2; arot->dest.x -= MPI_2;
rt->timer = actiontime; arot->timer = actiontime;
maze->dir = TURNLEFT(maze->dir); smartai->dir = TURNLEFT(smartai->dir);
smartai->state = 0; smartai->rotstate = 0;
} }
} }
// Only decide to do things if you're not moving anymore. Movement is the most // Only decide to do things if you're not moving anymore. Movement is the
// important thing // most important thing
if (mt->timer == 0) { if (anav->timer == 0) {
eprintf("SMARTAI: %d TIMER: %d DIR: %d POS: (%f, %f)\n", smartai->state, eprintf("SMARTAI: %d TIMER: %d DIR: %d POS: (%f, %f)\n",
smartai->timer, maze->dir, mt->pos.x, mt->pos.z); smartai->rotstate, smartai->timer, smartai->dir, anav->dest.x,
anav->dest.z);
// Player can only move forward if there's nothing in front of them // 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, if (maze_connected(ws->state->maze, smartai->mpos.x, smartai->mpos.y,
maze->dir)) { MAZESIZE, smartai->dir)) {
struct vec2i movement = dirtovec(maze->dir); struct vec2i movement = dirtovec(smartai->dir);
maze->pos.x += movement.x; smartai->mpos.x += movement.x;
maze->pos.y += movement.y; smartai->mpos.y += movement.y;
mt->timer = actiontime; anav->timer = actiontime;
mt->dst.x += HSCALE * movement.x; anav->dest.x += ws->state->cellsize * movement.x;
mt->dst.z += HSCALE * movement.y; anav->dest.z += ws->state->cellsize * movement.y;
smartai->state = 0; smartai->rotstate = 0;
} }
// Figure out if a rotation should be scheduled
if (smartai->timer <= 0) { if (smartai->timer <= 0) {
// Ok we might be moving, we might not be. Let's go ahead and calculate // 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. // rotation based on the FUTURE direction we want to turn.
uint8_t rightdir = TURNRIGHT(maze->dir); uint8_t rightdir = TURNRIGHT(smartai->dir);
uint8_t leftdir = TURNLEFT(maze->dir); uint8_t leftdir = TURNLEFT(smartai->dir);
if (maze_connected(maze->maze, maze->pos.x, maze->pos.y, maze->size, if (maze_connected(ws->state->maze, smartai->mpos.x, smartai->mpos.y,
rightdir)) { MAZESIZE, rightdir)) {
// Always choose right over left // Always choose right over left
smartai->state = 1; smartai->rotstate = 1;
smartai->timer = 2 * actiontime / 5; smartai->timer = rotdelaytime;
eprintf("WILL TURN RIGHT TO: %d\n", rightdir); eprintf("WILL TURN RIGHT TO: %d\n", rightdir);
} else if (!maze_connected(maze->maze, maze->pos.x, maze->pos.y, } else if (!maze_connected(ws->state->maze, smartai->mpos.x,
maze->size, maze->dir)) { smartai->mpos.y, MAZESIZE, smartai->dir)) {
// We only move left if the player can't move forward or right // We only move left if the player can't move forward or right
smartai->state = 2; smartai->rotstate = 2;
smartai->timer = 2 * actiontime / 5; smartai->timer = rotdelaytime;
eprintf("WILL TURN LEFT (stuck) TO: %d\n", leftdir); eprintf("WILL TURN LEFT (stuck) TO: %d\n", leftdir);
} }
} }
} }
break;
}
} }
*/
// static void sys_ecs_world(ecs_world *world, ecs_maze *maze, ecs_moveto *mt, // static void sys_ecs_world(ecs_world *world, ecs_maze *maze, ecs_moveto *mt,
// ecs_rotateto *rt) {} // ecs_rotateto *rt) {}
@ -481,9 +513,9 @@ ECS_COMPONENT(ecs_autonav);
ECS_COMPONENT(ecs_autorotate); ECS_COMPONENT(ecs_autorotate);
ECS_COMPONENT(ecs_placement); ECS_COMPONENT(ecs_placement);
ECS_COMPONENT(ecs_camera); ECS_COMPONENT(ecs_camera);
ECS_COMPONENT(ecs_smartai);
// ECS_COMPONENT(ecs_moveto); // ECS_COMPONENT(ecs_moveto);
// ECS_COMPONENT(ecs_rotateto); // ECS_COMPONENT(ecs_rotateto);
// ECS_COMPONENT(ecs_smartai);
// ECS_COMPONENT(ecs_camera); // ECS_COMPONENT(ecs_camera);
// ECS_COMPONENT(ecs_maze); // ECS_COMPONENT(ecs_maze);
ECS_END(mecs) ECS_END(mecs)
@ -495,10 +527,10 @@ ECS_CID(ecs_autonav, 2);
ECS_CID(ecs_autorotate, 3); ECS_CID(ecs_autorotate, 3);
ECS_CID(ecs_placement, 4); ECS_CID(ecs_placement, 4);
ECS_CID(ecs_camera, 5); ECS_CID(ecs_camera, 5);
ECS_CID(ecs_smartai, 6);
// ECS_CID(ecs_moveto, 0); // ECS_CID(ecs_moveto, 0);
// ECS_CID(ecs_rotateto, 1); // ECS_CID(ecs_rotateto, 1);
// ECS_CID(ecs_smartai, 2);
// ECS_CID(ecs_camera, 3); // ECS_CID(ecs_camera, 3);
// ECS_CID(ecs_maze, 4); // ECS_CID(ecs_maze, 4);
@ -506,6 +538,8 @@ ECS_SYSTEM1(mecs, sys_world, ecs_world);
ECS_SYSTEM2(mecs, sys_autonav, ecs_autonav, ecs_placement); ECS_SYSTEM2(mecs, sys_autonav, ecs_autonav, ecs_placement);
ECS_SYSTEM2(mecs, sys_autorotate, ecs_autorotate, ecs_placement); ECS_SYSTEM2(mecs, sys_autorotate, ecs_autorotate, ecs_placement);
ECS_SYSTEM2(mecs, sys_camera, ecs_camera, ecs_placement); ECS_SYSTEM2(mecs, sys_camera, ecs_camera, ecs_placement);
ECS_SYSTEM4(mecs, sys_smartai, ecs_smartai, ecs_worldstate, ecs_autonav,
ecs_autorotate);
// ECS_SYSTEM1(mecs, sys_ecs_moveto, ecs_moveto); // ECS_SYSTEM1(mecs, sys_ecs_moveto, ecs_moveto);
// ECS_SYSTEM1(mecs, sys_ecs_rotateto, ecs_rotateto); // ECS_SYSTEM1(mecs, sys_ecs_rotateto, ecs_rotateto);
// ECS_SYSTEM2(mecs, sys_ecs_moveto_camera, ecs_moveto, ecs_camera); // ECS_SYSTEM2(mecs, sys_ecs_moveto_camera, ecs_moveto, ecs_camera);
@ -656,9 +690,13 @@ int main() { // int argc, char **argv) {
ecs_eid playerid = mecs_newentity(&ecs, 0); ecs_eid playerid = mecs_newentity(&ecs, 0);
eprintf("Player eid: %d\n", playerid); eprintf("Player eid: %d\n", playerid);
ECS_SETCOMPONENT(&ecs, playerid, ecs_worldstate){.state = &wstate}; ECS_SETCOMPONENT(&ecs, playerid, ecs_worldstate){.state = &wstate};
ECS_SETCOMPONENT(&ecs, playerid, ecs_placement){.pos = render.camera.pos};
ECS_SETCOMPONENT(&ecs, playerid, ecs_camera){.camera = &render.camera}; ECS_SETCOMPONENT(&ecs, playerid, ecs_camera){.camera = &render.camera};
ECS_SETCOMPONENT(&ecs, playerid, ecs_autonav){.timer = 0}; ECS_SETCOMPONENT(&ecs, playerid, ecs_autonav){.timer = 0,
.dest = render.camera.pos};
ECS_SETCOMPONENT(&ecs, playerid, ecs_autorotate){.timer = 0}; ECS_SETCOMPONENT(&ecs, playerid, ecs_autorotate){.timer = 0};
ECS_SETCOMPONENT(&ecs, playerid,
ecs_smartai){.state = SAI_INIT, .rotstate = 0, .timer = 0};
// if (playerid == -1) { // if (playerid == -1) {
// dieerr("WHY IS PLAYERID -1???\n"); // dieerr("WHY IS PLAYERID -1???\n");
@ -721,16 +759,10 @@ int main() { // int argc, char **argv) {
for (int i = 0; i < ECS_MAXENTITIES; i++) { for (int i = 0; i < ECS_MAXENTITIES; i++) {
sys_world_run(&ecs, i); sys_world_run(&ecs, i);
sys_smartai_run(&ecs, i);
sys_autonav_run(&ecs, i); sys_autonav_run(&ecs, i);
sys_autorotate_run(&ecs, i); sys_autorotate_run(&ecs, i);
sys_camera_run(&ecs, i); sys_camera_run(&ecs, i);
// sys_ecs_world_run(&ecs, i);
// sys_ecs_smartai_run(&ecs, i);
// sys_ecs_moveto_run(&ecs, i);
// sys_ecs_rotateto_run(&ecs, i);
// sys_ecs_moveto_camera_run(&ecs, i);
// sys_ecs_rotateto_camera_run(&ecs, i);
} }
totaldrawn = 0; totaldrawn = 0;