summaryrefslogtreecommitdiff
path: root/src/entity.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/entity.c')
-rw-r--r--src/entity.c100
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;
+}