Files
dusk/archive/rpg/entity/player.c
2025-10-06 19:14:52 -05:00

115 lines
3.3 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 "input/input.h"
#include "display/scene/overworld/sceneoverworld.h"
#include "display/tileset/tileset_entities.h"
void playerInit(entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
}
void playerMovement(entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
// Update velocity.
vec2 dir = {
inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT),
inputAxis(INPUT_ACTION_DOWN, INPUT_ACTION_UP)
};
if(dir[0] == 0 && dir[1] == 0) return;
glm_vec2_normalize(dir);
entity->velocity[0] += PLAYER_SPEED * dir[0];
entity->velocity[1] += PLAYER_SPEED * dir[1];
// Update direction.
if(dir[0] > 0) {
if(entity->direction == DIRECTION_RIGHT) {
entity->direction = DIRECTION_RIGHT;
} else {
if(dir[1] < 0) {
entity->direction = DIRECTION_UP;
} else if(dir[1] > 0) {
entity->direction = DIRECTION_DOWN;
} else {
entity->direction = DIRECTION_RIGHT;
}
}
} else if(dir[0] < 0) {
if(entity->direction == DIRECTION_LEFT) {
entity->direction = DIRECTION_LEFT;
} else {
if(dir[1] < 0) {
entity->direction = DIRECTION_UP;
} else if(dir[1] > 0) {
entity->direction = DIRECTION_DOWN;
} else {
entity->direction = DIRECTION_LEFT;
}
}
} else if(dir[1] < 0) {
entity->direction = DIRECTION_UP;
} else if(dir[1] > 0) {
entity->direction = DIRECTION_DOWN;
}
}
void playerInteraction(entity_t *entity) {
assertNotNull(entity, "Entity pointer cannot be NULL");
if(!inputPressed(INPUT_ACTION_ACCEPT)) return;
physicsbox_t interactBox;
// Get direction vector
directionGetVec2(entity->direction, interactBox.min);
// Scale by interact range
glm_vec2_scale(interactBox.min, PLAYER_INTERACTION_RANGE, interactBox.min);
// Add entity position, this makes the center of the box.
glm_vec2_add(interactBox.min, entity->position, interactBox.min);
// Copy to max
glm_vec2_copy(interactBox.min, interactBox.max);
// Size of the hitbox
vec2 halfSize = {
TILESET_ENTITIES.tileWidth * PLAYER_INTERACTION_SIZE * 0.5f,
TILESET_ENTITIES.tileHeight * PLAYER_INTERACTION_SIZE * 0.5f
};
// Subtract from min, add to max.
glm_vec2_sub(interactBox.min, halfSize, interactBox.min);
glm_vec2_add(interactBox.max, halfSize, interactBox.max);
// For each entity
entity_t *start = entity->map->entities;
entity_t *end = &entity->map->entities[entity->map->entityCount];
vec2 otherSize = { TILESET_ENTITIES.tileWidth, TILESET_ENTITIES.tileHeight };
physicsbox_t otherBox;
physicsboxboxresult_t result;
do {
if(start->type != ENTITY_TYPE_NPC) continue;
// Setup other box.
glm_vec2_copy(start->position, otherBox.min);
glm_vec2_copy(start->position, otherBox.max);
glm_vec2_sub(otherBox.min, otherSize, otherBox.min);
glm_vec2_add(otherBox.min, otherSize, otherBox.max);
physicsBoxCheckBox(interactBox, otherBox, &result);
if(!result.hit) continue;
printf("Interacted with entity at (%.2f, %.2f)\n", start->position[0], start->position[1]);
break;
} while(++start != end);
}