106 lines
2.4 KiB
C
106 lines
2.4 KiB
C
#include "entity.h"
|
|
#include "game.h"
|
|
#include "map.h"
|
|
#include "cfg.h"
|
|
#include "entitytag.h"
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <stdio.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 *type)
|
|
{
|
|
for (unsigned int i = 0; i < num_entitytags; i++)
|
|
if (strcmp(type, entitytags[i].name) == 0)
|
|
return i + 1;
|
|
fprintf(stderr, "unknown type '%s'\n", type);
|
|
return 0;
|
|
}
|
|
|
|
bool
|
|
entity_collide(Entity *this, [[maybe_unused]] Game *g, 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, Game *g, unsigned int type)
|
|
{
|
|
for (int 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, Game *g)
|
|
{
|
|
this->bonk_ceiling = false;
|
|
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, g, 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, g, 0, 0)) {
|
|
this->pos[a] -= sign;
|
|
this->rem[a] = 0.0;
|
|
this->vel[a] = 0.0;
|
|
if (a == 1 && sign == -1)
|
|
this->bonk_ceiling = true;
|
|
break;
|
|
}
|
|
spd -= sign;
|
|
}
|
|
}
|
|
}
|
|
|
|
Entity *
|
|
entity_init(Entity *this, unsigned int type, int x, int y)
|
|
{
|
|
entitytags[type - 1].init(this, x, y);
|
|
return this;
|
|
}
|