Fixed rotation completely?
This commit is contained in:
parent
819f7e7f76
commit
29c5ece6da
4
ecs2.h
4
ecs2.h
@ -5,7 +5,7 @@
|
||||
#ifndef __HALOO3D_ECS2_H
|
||||
#define __HALOO3D_ECS2_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef ECS_MAXENTITIES
|
||||
#define ECS_MAXENTITIES 1024
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
#define ECS_MAXCTYPES 63 // uint64 bits minus one
|
||||
|
||||
typedef uint64_t ecs_cid;
|
||||
typedef unsigned long long ecs_cid;
|
||||
typedef int ecs_eid;
|
||||
|
||||
#define ECS_START(name) \
|
||||
|
2
haloo3d
2
haloo3d
@ -1 +1 @@
|
||||
Subproject commit 92fd1294cb6b910f7de2817d60b536738a2ecc7a
|
||||
Subproject commit 8d814bd4abae2fb0113e5675f838ed2caa4e938f
|
80
maze.c
80
maze.c
@ -17,8 +17,8 @@
|
||||
// INteresting flags for performance comparisons
|
||||
#define FASTFILL
|
||||
|
||||
#define WIDTH 480
|
||||
#define HEIGHT 300
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 200
|
||||
#define ASPECT ((float)WIDTH / HEIGHT)
|
||||
#define SCREENSCALE 2
|
||||
#define SWIDTH (WIDTH * SCREENSCALE)
|
||||
@ -29,7 +29,7 @@
|
||||
#define AVGWEIGHT 0.85
|
||||
|
||||
// Game options
|
||||
#define MAZESIZE 5
|
||||
#define MAZESIZE 15
|
||||
#define HSCALE 1.5
|
||||
|
||||
// Maze grows in the positive direction
|
||||
@ -444,18 +444,30 @@ enum {
|
||||
// State for tracking a smart ai moving through the maze.
|
||||
typedef struct {
|
||||
uint8_t state;
|
||||
uint8_t rotstate;
|
||||
// uint8_t rotstate;
|
||||
uint8_t dir;
|
||||
uint32_t timer;
|
||||
mfloat_t rotchange;
|
||||
struct vec2i mpos;
|
||||
worldstate *ws;
|
||||
haloo3d_obj_instance *startmarker;
|
||||
} ecs_smartai;
|
||||
|
||||
int smartai_mazeend(ecs_smartai *smartai) {
|
||||
if (smartai->mpos.x == smartai->ws->end.x &&
|
||||
smartai->mpos.y == smartai->ws->end.y) {
|
||||
eprintf("YOU WIN\n");
|
||||
smartai->ws->state = WSTATE_GAMEOVER;
|
||||
smartai->state = SAI_INIT;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
||||
ecs_autonav *anav, ecs_autorotate *arot) {
|
||||
const int actiontime = smartai->ws->fps / (2 * speed);
|
||||
const int rotdelaytime = 2 * actiontime / 5;
|
||||
const int rotdelaytime = actiontime / 2; // 2 * actiontime / 5;
|
||||
switch (smartai->state) {
|
||||
case SAI_INIT:
|
||||
// Here, we wait until the world state is spinup, in which
|
||||
@ -498,32 +510,19 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
||||
// 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->rotstate == 1) {
|
||||
eprintf("TURNING RIGHT\n");
|
||||
arot->dest.x += MPI_2;
|
||||
arot->timer = actiontime;
|
||||
smartai->dir = TURNRIGHT(smartai->dir);
|
||||
smartai->rotstate = 0;
|
||||
} else if (smartai->rotstate == 2) {
|
||||
eprintf("TURNING LEFT\n");
|
||||
arot->dest.x -= MPI_2;
|
||||
arot->timer = actiontime;
|
||||
smartai->dir = TURNLEFT(smartai->dir);
|
||||
smartai->rotstate = 0;
|
||||
}
|
||||
if (smartai->timer == 0 && smartai->rotchange) {
|
||||
eprintf("TURNING BY %f\n", smartai->rotchange);
|
||||
arot->dest.x += smartai->rotchange;
|
||||
smartai->rotchange = 0;
|
||||
arot->timer = actiontime;
|
||||
}
|
||||
// Only decide to do things if you're not moving anymore. Movement is the
|
||||
// most important thing
|
||||
if (anav->timer == 0) {
|
||||
eprintf("SMARTAI: %d TIMER: %d DIR: %d POS: (%f, %f)\n",
|
||||
smartai->rotstate, smartai->timer, smartai->dir, p->pos.x,
|
||||
eprintf("SMARTAI: %f TIMER: %d DIR: %d POS: (%f, %f)\n",
|
||||
smartai->rotchange, smartai->timer, smartai->dir, p->pos.x,
|
||||
p->pos.z);
|
||||
if (smartai->mpos.x == smartai->ws->end.x &&
|
||||
smartai->mpos.y == smartai->ws->end.y) {
|
||||
eprintf("YOU WIN\n");
|
||||
smartai->ws->state = WSTATE_GAMEOVER;
|
||||
smartai->state = SAI_INIT;
|
||||
if (smartai_mazeend(smartai)) {
|
||||
return;
|
||||
}
|
||||
// Player can only move forward if there's nothing in front of them
|
||||
@ -535,11 +534,10 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
||||
anav->timer = actiontime;
|
||||
anav->dest.x = p->pos.x + smartai->ws->cellsize * movement.x;
|
||||
anav->dest.z = p->pos.z + smartai->ws->cellsize * movement.y;
|
||||
smartai->rotstate = 0;
|
||||
}
|
||||
// Figure out if a rotation should be scheduled
|
||||
if (smartai->timer <= 0 && !(smartai->mpos.x == smartai->ws->end.x &&
|
||||
smartai->mpos.y == smartai->ws->end.y)) {
|
||||
if (!(smartai->mpos.x == smartai->ws->end.x &&
|
||||
smartai->mpos.y == smartai->ws->end.y)) {
|
||||
// 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(smartai->dir);
|
||||
@ -547,15 +545,23 @@ static void sys_smartai(ecs_smartai *smartai, ecs_placement *p,
|
||||
if (maze_connected(smartai->ws->maze, smartai->mpos.x, smartai->mpos.y,
|
||||
MAZESIZE, rightdir)) {
|
||||
// Always choose right over left
|
||||
smartai->rotstate = 1;
|
||||
smartai->rotchange += MPI_2;
|
||||
smartai->timer = rotdelaytime;
|
||||
smartai->dir = TURNRIGHT(smartai->dir);
|
||||
eprintf("WILL TURN RIGHT TO: %d\n", rightdir);
|
||||
} else if (!maze_connected(smartai->ws->maze, smartai->mpos.x,
|
||||
smartai->mpos.y, MAZESIZE, smartai->dir)) {
|
||||
// We only move left if the player can't move forward or right
|
||||
smartai->rotstate = 2;
|
||||
smartai->timer = rotdelaytime;
|
||||
eprintf("WILL TURN LEFT (stuck) TO: %d\n", leftdir);
|
||||
} else {
|
||||
// This while loop lets us turn around if necessary, so reaching a
|
||||
// dead end isn't super painful waiting for two rotations
|
||||
while (!maze_connected(smartai->ws->maze, smartai->mpos.x,
|
||||
smartai->mpos.y, MAZESIZE, smartai->dir)) {
|
||||
// We seem to have reached a wall. Do we need to turn ALL the way
|
||||
// around? We only move left if the player can't move forward or
|
||||
// right
|
||||
smartai->rotchange -= MPI_2;
|
||||
smartai->timer = rotdelaytime;
|
||||
smartai->dir = TURNLEFT(smartai->dir);
|
||||
eprintf("WILL TURN LEFT (stuck) TO: %d\n", leftdir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -850,7 +856,7 @@ int main() { // int argc, char **argv) {
|
||||
ECS_SETCOMPONENT(&ecs, playerid, ecs_autorotate){.timer = 0};
|
||||
ECS_SETCOMPONENT(&ecs, playerid, ecs_smartai){.state = SAI_INIT,
|
||||
.ws = &wstate,
|
||||
.rotstate = 0,
|
||||
.rotchange = 0,
|
||||
.timer = 0,
|
||||
.startmarker = starti};
|
||||
|
||||
|
1330
resources/specwall.ppm
Normal file
1330
resources/specwall.ppm
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user