115 lines
3.3 KiB
C
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);
|
|
} |