Files
dusk/src/rpg/entity/entity.c
2025-11-04 09:03:36 -06:00

111 lines
2.9 KiB
C

/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "entity.h"
#include "assert/assert.h"
#include "util/memory.h"
#include "time/time.h"
#include "util/math.h"
entity_t ENTITIES[ENTITY_COUNT];
void entityInit(entity_t *entity, const entitytype_t type) {
assertNotNull(entity, "Entity 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->id = (uint8_t)(entity - ENTITIES);
entity->type = type;
if(ENTITY_CALLBACKS[type].init != NULL) ENTITY_CALLBACKS[type].init(entity);
}
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");
// What state is the entity in?
if(entity->animation != ENTITY_ANIM_IDLE) {
// Entity is mid animation, tick it (down).
entity->animFrame--;
if(entity->animFrame == 0) entity->animation = ENTITY_ANIM_IDLE;
return;
}
// Movement code.
if(ENTITY_CALLBACKS[entity->type].movement != NULL) {
ENTITY_CALLBACKS[entity->type].movement(entity);
}
}
void entityTurn(entity_t *entity, const entitydir_t direction) {
entity->direction = direction;
entity->animation = ENTITY_ANIM_TURN;
entity->animFrame = ENTITY_ANIM_TURN_DURATION;
}
void entityWalk(entity_t *entity, const entitydir_t direction) {
// TODO: Animation, delay, etc.
entity->direction = direction;
// Where are we moving?
uint8_t newX, newY;
newX = entity->position.x;
newY = entity->position.y;
{
int8_t relX, relY;
entityDirGetRelative(direction, &relX, &relY);
newX += relX;
newY += relY;
}
// TODO: Tile in way?
// TODO: Map bounds in way?
// Entity in way?
entity_t *start = ENTITIES;
do {
if(
start == entity ||
entity->type == ENTITY_TYPE_NULL ||
start->position.x != newX ||
start->position.y != newY ||
start->position.z != entity->position.z
) {
start++;
continue;
}
return;// Blocked
} while(start < &ENTITIES[ENTITY_COUNT]);
// Move.
entity->position.x = newX;
entity->position.y = newY;
entity->animation = ENTITY_ANIM_WALK;
entity->animFrame = ENTITY_ANIM_WALK_DURATION;// TODO: Running vs walking
}
entity_t * entityGetAt(const worldpos_t position) {
entity_t *ent = ENTITIES;
do {
if(ent->type == ENTITY_TYPE_NULL) continue;
if(ent->position.x != position.x) continue;
if(ent->position.y != position.y) continue;
if(ent->position.z != position.z) continue;
return ent;
} while(++ent, ent < &ENTITIES[ENTITY_COUNT]);
return NULL;
}