#include "entity.h" #include "entitytag.h" #include "map.h" #include "game.h" #include #include 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) { if (typename == NULL) return 0; 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; } unsigned int entity_type_parent(unsigned int type) { if (type == 0) return 0; if (entitytags[type - 1].parent != NULL) return entity_type(entitytags[type - 1].parent); return 0; } bool entity_is_type(unsigned int type, unsigned int search) { do { if (type == search) return true; type = entity_type_parent(type); } while (type != 0); return false; } 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 = MAX_ENTITIES - 1; i >= 0; i--) if (this != &g->entities[i] && entity_is_type(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, const char *name, int x, int y, int w, int h) { entitytags[type - 1].init(this, name, x, y, w, h); return this; }