/** * 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); }