This commit is contained in:
2025-10-08 14:17:58 -05:00
parent 46f820690d
commit 67604eca8d
17 changed files with 230 additions and 165 deletions

View File

@@ -6,22 +6,25 @@
*/
#include "entity.h"
#include "rpg/world/map.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "display/tileset/tileset_entities.h"
#include "time/time.h"
#include "util/math.h"
void entityInit(entity_t *entity, const entitytype_t type, map_t *map) {
entity_t ENTITIES[ENTITY_COUNT];
void entityInit(entity_t *entity, const entitytype_t type) {
assertNotNull(entity, "Entity pointer cannot be NULL");
assertNotNull(map, "Map pointer cannot be NULL");
assertTrue(type < ENTITY_TYPE_COUNT, "Invalid entity type");
assertTrue(type != ENTITY_TYPE_NULL, "Cannot have NULL entity type");
assertTrue(
entity >= ENTITIES && entity < ENTITIES + ENTITY_COUNT,
"Entity pointer is out of bounds"
);
memoryZero(entity, sizeof(entity_t));
entity->type = type;
entity->map = map;
// Init. I did use a callback struct but it was not flexible enough.
switch(type) {
@@ -42,66 +45,4 @@ void entityUpdate(entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
assertTrue(entity->type < ENTITY_TYPE_COUNT, "Invalid entity type");
assertTrue(entity->type != ENTITY_TYPE_NULL, "Cannot have NULL entity type");
// Handle movement logic
switch(entity->type) {
case ENTITY_TYPE_PLAYER:
playerMovement(entity);
break;
case ENTITY_TYPE_NPC:
npcUpdate(entity);
break;
default:
break;
}
// Apply velocity
if(entity->velocity[0] != 0.0f || entity->velocity[1] != 0.0f) {
entity->position[0] += entity->velocity[0] * TIME.delta;
entity->position[1] += entity->velocity[1] * TIME.delta;
// Hit test on other entities.
entity_t *start = entity->map->entities;
entity_t *end = &entity->map->entities[entity->map->entityCount];
// Our hitbox
physicscircle_t self;
glm_vec2_copy(entity->position, self.position);
self.radius = TILESET_ENTITIES.tileWidth / 2.0f;
physicscircle_t other;
other.radius = self.radius;
// TODO: what if multiple collisions?
do {
if(start == entity) continue;
if(start->type == ENTITY_TYPE_NULL) continue;
glm_vec2_copy(start->position, other.position);
physicscirclecircleresult_t result;
physicsCircleCheckCircle(self, other, &result);
if(result.hit) {
entity->position[0] -= result.normal[0] * result.depth;
entity->position[1] -= result.normal[1] * result.depth;
break;
}
} while((start++) != end);
// Friction (and dampening)
entity->velocity[0] *= ENTITY_FRICTION * TIME.delta;
entity->velocity[1] *= ENTITY_FRICTION * TIME.delta;
if(mathAbs(entity->velocity[0]) < ENTITY_MIN_VELOCITY) {
entity->velocity[0] = 0.0f;
}
if(mathAbs(entity->velocity[1]) < ENTITY_MIN_VELOCITY) {
entity->velocity[1] = 0.0f;
}
}
if(entity->type == ENTITY_TYPE_PLAYER) {
playerInteraction(entity);
}
}