diff options
Diffstat (limited to 'src/entity.c')
-rw-r--r-- | src/entity.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/entity.c b/src/entity.c new file mode 100644 index 0000000..75ad7ec --- /dev/null +++ b/src/entity.c @@ -0,0 +1,100 @@ +#include "entity.h" +#include "entitytag.h" +#include "map.h" +#include "game.h" +#include <stdio.h> +#include <string.h> + +static void +_points(Entity *this, int ox, int oy, int *x0, int *x1, int *y0, int *y1) +{ + *x0 = this->pos[0] - this->width / 2 + ox; + *y0 = this->pos[1] - this->width / 2 + oy; + *x1 = *x0 + this->width - 1; + *y1 = *y0 + this->height - 1; +} + +unsigned int +entity_type(const char *typename) +{ + for (unsigned i = 0; i < num_entitytags; i++) + if (strcmp(typename, entitytags[i].name) == 0) + return i + 1; + printf("unknown type '%s'\n", typename); + return 0; +} + +bool +entity_collide(Entity *this, int ox, int oy) +{ + int x0, y0, x1, y1; + _points(this, ox, oy, &x0, &x1, &y0, &y1); + return (map_get_px(x0, y0) == 1 || map_get_px(x0, y1) == 1 || + map_get_px(x1, y0) == 1 || map_get_px(x1, y1) == 1); +} + +bool +entity_meet(Entity *this, Entity *other) +{ + int tx0, ty0, tx1, ty1; + int ox0, oy0, ox1, oy1; + _points(this, 0, 0, &tx0, &tx1, &ty0, &ty1); + _points(other, 0, 0, &ox0, &ox1, &oy0, &oy1); + return (tx0 < ox1 && tx1 > ox0 && ty0 < oy1 && ty1 > oy0); +} + +Entity * +entity_place_meeting(Entity *this, struct Game *g, unsigned int type) +{ + for (__auto_type i = 0; i < MAX_ENTITIES; i++) + if (this != &g->entities[i] && g->entities[i].type == type && + entity_meet(this, &g->entities[i])) + return &g->entities[i]; + return NULL; +} + +void +entity_move(Entity *this, [[maybe_unused]] struct Game *g) +{ + if (this->ignore_solids) { + for (int a = 0; a < 2; a++) { + const double sum = this->vel[a] + this->rem[a]; + int spd = (int)sum; + this->rem[a] = sum - spd; + this->pos[a] += spd; + } + return; + } + if (entity_collide(this, 0, 0)) { + this->vel[0] = 0.0; + this->vel[1] = 0.0; + this->rem[0] = 0.0; + this->rem[1] = 0.0; + return; + } + for (int a = 0; a < 2; a++) { + const double sum = this->vel[a] + this->rem[a]; + int spd = (int)sum; + this->rem[a] = sum - spd; + const int sign = (spd > 0) - (spd < 0); + if (sign == 0) + continue; + while (spd != 0) { + this->pos[a] += sign; + if (entity_collide(this, 0, 0)) { + this->pos[a] -= sign; + this->rem[a] = 0.0; + this->vel[a] = 0.0; + break; + } + spd -= sign; + } + } +} + +Entity * +entity_init(Entity *this, unsigned int type, int x, int y) +{ + entitytags[type - 1].init(this, x, y); + return this; +} |