Maze complete v1
This commit is contained in:
parent
52daa83f2f
commit
0fdfc7e4c2
12
ecs2.h
12
ecs2.h
@ -59,6 +59,16 @@ typedef int ecs_eid;
|
|||||||
ecs_cid _realcomps = ECS_SELFFLAG | _comps; \
|
ecs_cid _realcomps = ECS_SELFFLAG | _comps; \
|
||||||
return (_ecs->entities[_eid] & _realcomps) == _realcomps; \
|
return (_ecs->entities[_eid] & _realcomps) == _realcomps; \
|
||||||
} \
|
} \
|
||||||
|
/* fill given list with eids of entities that match. careful with size */ \
|
||||||
|
static int name##_query(name *_ecs, ecs_cid _comps, ecs_eid *out) { \
|
||||||
|
int count = 0; \
|
||||||
|
for (int i = 0; i < ECS_MAXENTITIES; i++) { \
|
||||||
|
if (name##_match(_ecs, i, _comps)) { \
|
||||||
|
out[count++] = i; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
return count; \
|
||||||
|
} \
|
||||||
/* Calculate the eid from a double ecs pointer. Useful to get eid in sys */ \
|
/* Calculate the eid from a double ecs pointer. Useful to get eid in sys */ \
|
||||||
static ecs_eid name##_eid(name **_ecs) { \
|
static ecs_eid name##_eid(name **_ecs) { \
|
||||||
return (ecs_eid)(_ecs - (*_ecs)->c_##name); \
|
return (ecs_eid)(_ecs - (*_ecs)->c_##name); \
|
||||||
@ -68,6 +78,8 @@ typedef int ecs_eid;
|
|||||||
// Create an ECS component within an ECS struct
|
// Create an ECS component within an ECS struct
|
||||||
#define ECS_COMPONENT(type) type c_##type[ECS_MAXENTITIES];
|
#define ECS_COMPONENT(type) type c_##type[ECS_MAXENTITIES];
|
||||||
|
|
||||||
|
#define ECS_GETCOMPONENT(_ecs, eid, type) (_ecs)->c_##type[eid]
|
||||||
|
|
||||||
// Define the CIDs necessary to access a component (each component MUST
|
// Define the CIDs necessary to access a component (each component MUST
|
||||||
// have a unique id and I can't do that inside a macro without requiring
|
// have a unique id and I can't do that inside a macro without requiring
|
||||||
// extensions)
|
// extensions)
|
||||||
|
2
haloo3d
2
haloo3d
@ -1 +1 @@
|
|||||||
Subproject commit 917dfe41aa118cefe36779c9bba7957160cc52e4
|
Subproject commit b6347c5360b84079a50d943d4b1fe8e0edd946b8
|
112
maze.c
112
maze.c
@ -48,7 +48,7 @@
|
|||||||
#define PRINTMAZE
|
#define PRINTMAZE
|
||||||
// Max amount of flip polys to generate in maze. actual amount can be lower,
|
// Max amount of flip polys to generate in maze. actual amount can be lower,
|
||||||
// but there will always at least be 1
|
// but there will always at least be 1
|
||||||
#define MAXFLIPPOLYS 17
|
#define MAXFLIPPOLYS 6
|
||||||
// Min space between flip polys
|
// Min space between flip polys
|
||||||
#define FLIPPOLYBUFFER 3
|
#define FLIPPOLYBUFFER 3
|
||||||
|
|
||||||
@ -58,6 +58,8 @@
|
|||||||
#define MAZEVISIT 4
|
#define MAZEVISIT 4
|
||||||
#define MAZEFLIP 8
|
#define MAZEFLIP 8
|
||||||
|
|
||||||
|
#define MAZETYPEFLIP 1
|
||||||
|
|
||||||
// When you rightshift these values, you "turn right".
|
// When you rightshift these values, you "turn right".
|
||||||
// NOTE: north in this case is "towards the screen" because it moves in the
|
// NOTE: north in this case is "towards the screen" because it moves in the
|
||||||
// positive direction. In this case, it's actually wound in the opposite
|
// positive direction. In this case, it's actually wound in the opposite
|
||||||
@ -84,7 +86,7 @@ const char POLYNAMES[NUMPOLYS][20] = {"tetrahedron"};
|
|||||||
float ditherstart = -1;
|
float ditherstart = -1;
|
||||||
float ditherend = 8;
|
float ditherend = 8;
|
||||||
float fov = 90.0;
|
float fov = 90.0;
|
||||||
float minlight = 0.25;
|
float minlight = 0.15;
|
||||||
float speed = 1.0;
|
float speed = 1.0;
|
||||||
int fps = 45;
|
int fps = 45;
|
||||||
uint16_t sky = 0xF000;
|
uint16_t sky = 0xF000;
|
||||||
@ -276,7 +278,13 @@ void create_flippoly(struct vec2i mazepos, haloo3d_easyinstancer *ins,
|
|||||||
(mazepos.y + 0.5) * world->state->cellsize);
|
(mazepos.y + 0.5) * world->state->cellsize);
|
||||||
ecs_eid id = mecs_newentity(ecs, 0);
|
ecs_eid id = mecs_newentity(ecs, 0);
|
||||||
mallocordie(poly->lighting, sizeof(struct vec3));
|
mallocordie(poly->lighting, sizeof(struct vec3));
|
||||||
|
// vec3(poly->lighting->v, 0, 0, -1); //-MPI / 4, -1);
|
||||||
vec3(poly->lighting->v, 0, -MPI / 4, -1);
|
vec3(poly->lighting->v, 0, -MPI / 4, -1);
|
||||||
|
ECS_SETCOMPONENT(ecs, id, ecs_placement){
|
||||||
|
.pos = {.x = (mazepos.x + 0.5) * world->state->cellsize,
|
||||||
|
.y = 0.35,
|
||||||
|
.z = (mazepos.y + 0.5) * world->state->cellsize},
|
||||||
|
.rot = {.x = 0, .y = MPI * 0.3}};
|
||||||
ECS_SETCOMPONENT(ecs, id, ecs_syncgrow){.obj = poly,
|
ECS_SETCOMPONENT(ecs, id, ecs_syncgrow){.obj = poly,
|
||||||
.scale = &world->scaleto,
|
.scale = &world->scaleto,
|
||||||
.basescale = poly->scale.x,
|
.basescale = poly->scale.x,
|
||||||
@ -285,6 +293,11 @@ void create_flippoly(struct vec2i mazepos, haloo3d_easyinstancer *ins,
|
|||||||
.render = ins->render,
|
.render = ins->render,
|
||||||
.ws = world->state,
|
.ws = world->state,
|
||||||
.diefunc = kill_flippoly};
|
.diefunc = kill_flippoly};
|
||||||
|
ECS_SETCOMPONENT(ecs, id, ecs_autorotate){
|
||||||
|
.dest = {.x = MPI * 60 * 60 * 24, .y = 0}, .timer = fps * 60 * 60 * 24};
|
||||||
|
ECS_SETCOMPONENT(ecs, id, ecs_object) poly;
|
||||||
|
ECS_SETCOMPONENT(ecs, id, ecs_mazeentity){.type = MAZETYPEFLIP,
|
||||||
|
.mpos = mazepos};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate walls AND create paintings. Kind of doing too much
|
// Generate walls AND create paintings. Kind of doing too much
|
||||||
@ -394,8 +407,13 @@ void sys_camera(ecs_camera *cam, ecs_placement *p) {
|
|||||||
(*cam)->pitch = p->rot.y;
|
(*cam)->pitch = p->rot.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we do anything with the lookvec? idk...
|
void sys_object(ecs_object *obj, ecs_placement *p) {
|
||||||
void sys_object(ecs_object *obj, ecs_placement *p) { (*obj)->pos = p->pos; }
|
(*obj)->pos = p->pos;
|
||||||
|
YAWP2VEC(p->rot.x, p->rot.y, (*obj)->lookvec.v);
|
||||||
|
// eprintf("OBJ: %f %f %f (%f %f %f)\n", (*obj)->pos.x, (*obj)->pos.y,
|
||||||
|
// (*obj)->pos.z, (*obj)->lookvec.x, (*obj)->lookvec.y,
|
||||||
|
// (*obj)->lookvec.z);
|
||||||
|
}
|
||||||
|
|
||||||
void sys_dieoninit(ecs_dieoninit *die, mecs **ecs) {
|
void sys_dieoninit(ecs_dieoninit *die, mecs **ecs) {
|
||||||
if (die->ws->state == WSTATE_INIT) {
|
if (die->ws->state == WSTATE_INIT) {
|
||||||
@ -425,6 +443,9 @@ void sys_world(ecs_world *w, mecs **ecs) {
|
|||||||
for (int i = 0; i < MAXFLIPPOLYS; i++) {
|
for (int i = 0; i < MAXFLIPPOLYS; i++) {
|
||||||
struct vec2i m = {.x = rand() % w->state->size,
|
struct vec2i m = {.x = rand() % w->state->size,
|
||||||
.y = rand() % w->state->size};
|
.y = rand() % w->state->size};
|
||||||
|
if (m.x == w->state->start.x && m.y == w->state->start.y) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int yc = m.y - FLIPPOLYBUFFER; yc < m.y + FLIPPOLYBUFFER; yc++) {
|
for (int yc = m.y - FLIPPOLYBUFFER; yc < m.y + FLIPPOLYBUFFER; yc++) {
|
||||||
if (yc < 0 || yc >= w->state->size)
|
if (yc < 0 || yc >= w->state->size)
|
||||||
continue;
|
continue;
|
||||||
@ -473,11 +494,7 @@ void sys_world(ecs_world *w, mecs **ecs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum { SAI_INIT, SAI_READY, SAI_GAMEPLAY, SAI_FLIP, SAI_HOLD };
|
||||||
SAI_INIT,
|
|
||||||
SAI_READY,
|
|
||||||
SAI_GAMEPLAY,
|
|
||||||
};
|
|
||||||
|
|
||||||
int smartai_mazeend(ecs_smartai *smartai) {
|
int smartai_mazeend(ecs_smartai *smartai) {
|
||||||
if (smartai->mpos.x == smartai->ws->end.x &&
|
if (smartai->mpos.x == smartai->ws->end.x &&
|
||||||
@ -491,7 +508,7 @@ int smartai_mazeend(ecs_smartai *smartai) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sys_smartai(ecs_smartai *smartai, ecs_placement *p, ecs_autonav *anav,
|
void sys_smartai(ecs_smartai *smartai, ecs_placement *p, ecs_autonav *anav,
|
||||||
ecs_autorotate *arot) {
|
ecs_autorotate *arot, mecs **ecs, ecs_camera *cam) {
|
||||||
const int actiontime = fps / (2 * speed);
|
const int actiontime = fps / (2 * speed);
|
||||||
const int rotdelaytime = actiontime / 2; // 2 * actiontime / 5;
|
const int rotdelaytime = actiontime / 2; // 2 * actiontime / 5;
|
||||||
switch (smartai->state) {
|
switch (smartai->state) {
|
||||||
@ -499,6 +516,9 @@ void sys_smartai(ecs_smartai *smartai, ecs_placement *p, ecs_autonav *anav,
|
|||||||
// Here, we wait until the world state is spinup, in which
|
// Here, we wait until the world state is spinup, in which
|
||||||
// case we can spawn and face
|
// case we can spawn and face
|
||||||
if (smartai->ws->state == WSTATE_SPINUP) {
|
if (smartai->ws->state == WSTATE_SPINUP) {
|
||||||
|
// Reset up vector (even though I like starting upside down, it's a
|
||||||
|
// bit jarring)
|
||||||
|
vec3((*cam)->up.v, 0, 1, 0);
|
||||||
smartai->mpos = smartai->ws->start;
|
smartai->mpos = smartai->ws->start;
|
||||||
smartai->dir =
|
smartai->dir =
|
||||||
maze_longesthallway(smartai->ws->maze, smartai->ws->size,
|
maze_longesthallway(smartai->ws->maze, smartai->ws->size,
|
||||||
@ -551,6 +571,31 @@ void sys_smartai(ecs_smartai *smartai, ecs_placement *p, ecs_autonav *anav,
|
|||||||
if (smartai_mazeend(smartai)) {
|
if (smartai_mazeend(smartai)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int mazeind = smartai->mpos.x + smartai->mpos.y * smartai->ws->size;
|
||||||
|
// I'm being SUPER lazy and we don't do proper collision detection with
|
||||||
|
// ecs, we just detect the tile and assign objects to tiles
|
||||||
|
// clang-format off
|
||||||
|
if (smartai->ws->maze[mazeind] & MAZEFLIP) {
|
||||||
|
ecs_eid eids[ECS_MAXENTITIES];
|
||||||
|
int count = mecs_query(*ecs, ecs_mazeentity_fl | ecs_placement_fl, eids);
|
||||||
|
eprintf("CHECKING MAZEFLIP (%d entities)\n", count);
|
||||||
|
for(int i = 0; i < count; i++) {
|
||||||
|
ecs_mazeentity * mze = &ECS_GETCOMPONENT(*ecs, eids[i], ecs_mazeentity);
|
||||||
|
if(mze->mpos.x == smartai->mpos.x && mze->mpos.y == smartai->mpos.y) {
|
||||||
|
eprintf("FLIPPING WORLD\n");
|
||||||
|
smartai->state = SAI_FLIP;
|
||||||
|
smartai->timer = 0;
|
||||||
|
// To be SUPER lazy, we just remove the flag and move the object
|
||||||
|
// somewhere else
|
||||||
|
ecs_placement * pl = &ECS_GETCOMPONENT(*ecs, eids[i], ecs_placement);
|
||||||
|
pl->pos.y = -10000;
|
||||||
|
smartai->ws->maze[mazeind] &= ~MAZEFLIP;
|
||||||
|
smartai->upsidedown = !smartai->upsidedown;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
// 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(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y,
|
if (maze_connected(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y,
|
||||||
smartai->ws->size, smartai->dir)) {
|
smartai->ws->size, smartai->dir)) {
|
||||||
@ -592,7 +637,41 @@ void sys_smartai(ecs_smartai *smartai, ecs_placement *p, ecs_autonav *anav,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case SAI_FLIP:
|
||||||
|
smartai->timer++;
|
||||||
|
mfloat_t towards = smartai->upsidedown ? -1 : 1;
|
||||||
|
if (smartai->timer >= actiontime) {
|
||||||
|
eprintf("FLIP COMPLETE\n");
|
||||||
|
smartai->timer = actiontime / 8;
|
||||||
|
smartai->state = SAI_HOLD;
|
||||||
|
vec3((*cam)->up.v, 0, towards, 0);
|
||||||
|
} else {
|
||||||
|
mfloat_t angle = MPI * smartai->timer / actiontime;
|
||||||
|
mfloat_t y = towards * -cos(angle);
|
||||||
|
mfloat_t x = towards * -sin(angle);
|
||||||
|
switch (smartai->dir) {
|
||||||
|
case DIRNORTH:
|
||||||
|
vec3((*cam)->up.v, -x, y, 0);
|
||||||
|
break;
|
||||||
|
case DIRSOUTH:
|
||||||
|
vec3((*cam)->up.v, x, y, 0);
|
||||||
|
break;
|
||||||
|
case DIREAST:
|
||||||
|
vec3((*cam)->up.v, 0, y, x);
|
||||||
|
break;
|
||||||
|
case DIRWEST:
|
||||||
|
vec3((*cam)->up.v, 0, y, -x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SAI_HOLD:
|
||||||
|
smartai->timer--;
|
||||||
|
if (smartai->timer <= 0) {
|
||||||
|
eprintf("HOLD COMPLETE\n");
|
||||||
|
smartai->state = SAI_GAMEPLAY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -684,8 +763,8 @@ 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_SYSTEM2(mecs, sys_object, ecs_object, ecs_placement);
|
ECS_SYSTEM2(mecs, sys_object, ecs_object, ecs_placement);
|
||||||
ECS_SYSTEM4(mecs, sys_smartai, ecs_smartai, ecs_placement, ecs_autonav,
|
ECS_SYSTEM6(mecs, sys_smartai, ecs_smartai, ecs_placement, ecs_autonav,
|
||||||
ecs_autorotate);
|
ecs_autorotate, mecs, ecs_camera);
|
||||||
ECS_SYSTEM3(mecs, sys_mouseai, ecs_mouseai, ecs_placement, ecs_autonav);
|
ECS_SYSTEM3(mecs, sys_mouseai, ecs_mouseai, ecs_placement, ecs_autonav);
|
||||||
|
|
||||||
void init_floortexture(haloo3d_fb *floort) {
|
void init_floortexture(haloo3d_fb *floort) {
|
||||||
@ -1045,12 +1124,13 @@ int main() { // int argc, char **argv) {
|
|||||||
.ws = &wstate,
|
.ws = &wstate,
|
||||||
.rotchange = 0,
|
.rotchange = 0,
|
||||||
.timer = 0,
|
.timer = 0,
|
||||||
|
.upsidedown = 0,
|
||||||
.startmarker = starti};
|
.startmarker = starti};
|
||||||
|
|
||||||
ecs_eid mouseid = mecs_newentity(&ecs, 0);
|
ecs_eid mouseid = mecs_newentity(&ecs, 0);
|
||||||
eprintf("Mouse eid: %d\n", mouseid);
|
eprintf("Mouse eid: %d\n", mouseid);
|
||||||
ECS_SETCOMPONENT(&ecs, mouseid,
|
ECS_SETCOMPONENT(&ecs, mouseid, ecs_placement){.pos = mousei->pos,
|
||||||
ecs_placement){.pos = mousei->pos}; // we don't use rot
|
.rot = {.x = 0, .y = 0}};
|
||||||
ECS_SETCOMPONENT(&ecs, mouseid, ecs_autonav){.timer = 0};
|
ECS_SETCOMPONENT(&ecs, mouseid, ecs_autonav){.timer = 0};
|
||||||
ECS_SETCOMPONENT(&ecs, mouseid, ecs_object) mousei;
|
ECS_SETCOMPONENT(&ecs, mouseid, ecs_object) mousei;
|
||||||
ECS_SETCOMPONENT(&ecs, mouseid, ecs_mouseai){.state = SAI_INIT,
|
ECS_SETCOMPONENT(&ecs, mouseid, ecs_mouseai){.state = SAI_INIT,
|
||||||
@ -1111,6 +1191,8 @@ int main() { // int argc, char **argv) {
|
|||||||
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);
|
||||||
|
// NOTE: must run object BEFORE billboard so that billboard
|
||||||
|
// overrides the rotation from object (we want this)
|
||||||
sys_object_run(&ecs, i);
|
sys_object_run(&ecs, i);
|
||||||
sys_billboard_run(&ecs, i);
|
sys_billboard_run(&ecs, i);
|
||||||
sys_dieoninit_run(&ecs, i);
|
sys_dieoninit_run(&ecs, i);
|
||||||
|
@ -76,13 +76,14 @@ typedef struct {
|
|||||||
|
|
||||||
// State for tracking a smart ai moving through the maze.
|
// State for tracking a smart ai moving through the maze.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t state;
|
int32_t timer;
|
||||||
uint8_t dir;
|
|
||||||
uint32_t timer;
|
|
||||||
mfloat_t rotchange;
|
mfloat_t rotchange;
|
||||||
struct vec2i mpos;
|
struct vec2i mpos;
|
||||||
worldstate *ws;
|
worldstate *ws;
|
||||||
haloo3d_obj_instance *startmarker;
|
haloo3d_obj_instance *startmarker;
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t dir;
|
||||||
|
uint8_t upsidedown;
|
||||||
} ecs_smartai;
|
} ecs_smartai;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -101,6 +102,14 @@ typedef struct {
|
|||||||
void (*diefunc)(haloo3d_obj_instance *);
|
void (*diefunc)(haloo3d_obj_instance *);
|
||||||
} ecs_dieoninit;
|
} ecs_dieoninit;
|
||||||
|
|
||||||
|
// A component which indicates where in a maze an entity is.
|
||||||
|
// This is tile-based and so entities can't overlap (here at least),
|
||||||
|
// but just in case, there's an entity type too
|
||||||
|
typedef struct {
|
||||||
|
struct vec2i mpos;
|
||||||
|
uint8_t type;
|
||||||
|
} ecs_mazeentity;
|
||||||
|
|
||||||
// Setup ECS system for our game
|
// Setup ECS system for our game
|
||||||
ECS_START(mecs)
|
ECS_START(mecs)
|
||||||
ECS_COMPONENT(ecs_world);
|
ECS_COMPONENT(ecs_world);
|
||||||
@ -114,6 +123,7 @@ ECS_COMPONENT(ecs_billboard);
|
|||||||
ECS_COMPONENT(ecs_dieoninit);
|
ECS_COMPONENT(ecs_dieoninit);
|
||||||
ECS_COMPONENT(ecs_mouseai);
|
ECS_COMPONENT(ecs_mouseai);
|
||||||
ECS_COMPONENT(ecs_object);
|
ECS_COMPONENT(ecs_object);
|
||||||
|
ECS_COMPONENT(ecs_mazeentity);
|
||||||
ECS_END(mecs)
|
ECS_END(mecs)
|
||||||
|
|
||||||
// And then a copy of the components here... that sucksssss
|
// And then a copy of the components here... that sucksssss
|
||||||
@ -129,5 +139,6 @@ ECS_CID(ecs_billboard, 8);
|
|||||||
ECS_CID(ecs_dieoninit, 9);
|
ECS_CID(ecs_dieoninit, 9);
|
||||||
ECS_CID(ecs_mouseai, 10);
|
ECS_CID(ecs_mouseai, 10);
|
||||||
ECS_CID(ecs_object, 11);
|
ECS_CID(ecs_object, 11);
|
||||||
|
ECS_CID(ecs_mazeentity, 12);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user