physics stuff
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
include(dusktest)
|
||||
|
||||
# Tests
|
||||
dusktest(test_entitydir.c)
|
||||
dusktest(test_entity.c)
|
||||
|
||||
# Subdirs
|
||||
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "dusktest.h"
|
||||
#include "util/memory.h"
|
||||
#include "rpg/entity/entity.h"
|
||||
|
||||
static void testEntitiesReset(void) {
|
||||
memoryZero(ENTITIES, sizeof(ENTITIES));
|
||||
}
|
||||
|
||||
static void testEntityPlace(
|
||||
const uint8_t index,
|
||||
const entitytype_t type,
|
||||
const vec3 position,
|
||||
const entitydir_t direction
|
||||
) {
|
||||
entityInit(&ENTITIES[index], type);
|
||||
ENTITIES[index].direction = direction;
|
||||
const vec3 extents = ENTITY_PHYSICS_EXTENTS_DEFAULT;
|
||||
physicsBodyInit(&ENTITIES[index].body, position, extents);
|
||||
}
|
||||
|
||||
static void test_entityGetFacingFindsEntityAhead(void **state) {
|
||||
testEntitiesReset();
|
||||
testEntityPlace(0, ENTITY_TYPE_PLAYER, (vec3){ 0.0f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_EAST);
|
||||
testEntityPlace(1, ENTITY_TYPE_NPC, (vec3){ 1.0f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_NORTH);
|
||||
|
||||
entity_t *result = entityGetFacing(&ENTITIES[0], ENTITY_INTERACT_RANGE);
|
||||
assert_ptr_equal(result, &ENTITIES[1]);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
static void test_entityGetFacingIgnoresEntityBehind(void **state) {
|
||||
testEntitiesReset();
|
||||
testEntityPlace(0, ENTITY_TYPE_PLAYER, (vec3){ 0.0f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_EAST);
|
||||
testEntityPlace(1, ENTITY_TYPE_NPC, (vec3){ -2.0f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_NORTH);
|
||||
|
||||
entity_t *result = entityGetFacing(&ENTITIES[0], ENTITY_INTERACT_RANGE);
|
||||
assert_null(result);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
static void test_entityGetFacingIgnoresEntityToSide(void **state) {
|
||||
testEntitiesReset();
|
||||
testEntityPlace(0, ENTITY_TYPE_PLAYER, (vec3){ 0.0f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_EAST);
|
||||
testEntityPlace(1, ENTITY_TYPE_NPC, (vec3){ 0.0f, 3.0f, 0.0f },
|
||||
ENTITY_DIR_NORTH);
|
||||
|
||||
entity_t *result = entityGetFacing(&ENTITIES[0], ENTITY_INTERACT_RANGE);
|
||||
assert_null(result);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
static void test_entityGetFacingReturnsNullWhenNothingInRange(void **state) {
|
||||
testEntitiesReset();
|
||||
testEntityPlace(0, ENTITY_TYPE_PLAYER, (vec3){ 0.0f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_EAST);
|
||||
|
||||
entity_t *result = entityGetFacing(&ENTITIES[0], ENTITY_INTERACT_RANGE);
|
||||
assert_null(result);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
static void test_entityGetFacingPicksNearest(void **state) {
|
||||
testEntitiesReset();
|
||||
testEntityPlace(0, ENTITY_TYPE_PLAYER, (vec3){ 0.0f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_EAST);
|
||||
// Farther candidate placed at the lower array index, to prove the
|
||||
// result is chosen by distance, not array/insertion order.
|
||||
testEntityPlace(1, ENTITY_TYPE_NPC, (vec3){ 1.5f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_NORTH);
|
||||
testEntityPlace(2, ENTITY_TYPE_NPC, (vec3){ 1.0f, 0.0f, 0.0f },
|
||||
ENTITY_DIR_NORTH);
|
||||
|
||||
entity_t *result = entityGetFacing(&ENTITIES[0], ENTITY_INTERACT_RANGE);
|
||||
assert_ptr_equal(result, &ENTITIES[2]);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_entityGetFacingFindsEntityAhead),
|
||||
cmocka_unit_test(test_entityGetFacingIgnoresEntityBehind),
|
||||
cmocka_unit_test(test_entityGetFacingIgnoresEntityToSide),
|
||||
cmocka_unit_test(test_entityGetFacingReturnsNullWhenNothingInRange),
|
||||
cmocka_unit_test(test_entityGetFacingPicksNearest),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "dusktest.h"
|
||||
#include "util/memory.h"
|
||||
#include "rpg/entity/entitydir.h"
|
||||
|
||||
static void test_entityDirToVec2(void **state) {
|
||||
vec2 out;
|
||||
|
||||
entityDirToVec2(ENTITY_DIR_NORTH, out);
|
||||
assert_float_equal(out[0], 0.0f, 0.0001f);
|
||||
assert_float_equal(out[1], 1.0f, 0.0001f);
|
||||
|
||||
entityDirToVec2(ENTITY_DIR_EAST, out);
|
||||
assert_float_equal(out[0], 1.0f, 0.0001f);
|
||||
assert_float_equal(out[1], 0.0f, 0.0001f);
|
||||
|
||||
entityDirToVec2(ENTITY_DIR_SOUTH, out);
|
||||
assert_float_equal(out[0], 0.0f, 0.0001f);
|
||||
assert_float_equal(out[1], -1.0f, 0.0001f);
|
||||
|
||||
entityDirToVec2(ENTITY_DIR_WEST, out);
|
||||
assert_float_equal(out[0], -1.0f, 0.0001f);
|
||||
assert_float_equal(out[1], 0.0f, 0.0001f);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
static void test_entityDirFromVec2Cardinal(void **state) {
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ 0.0f, 1.0f }), ENTITY_DIR_NORTH
|
||||
);
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ 1.0f, 0.0f }), ENTITY_DIR_EAST
|
||||
);
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ 0.0f, -1.0f }), ENTITY_DIR_SOUTH
|
||||
);
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ -1.0f, 0.0f }), ENTITY_DIR_WEST
|
||||
);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
static void test_entityDirFromVec2DominantAxis(void **state) {
|
||||
// |x| > |y| picks east/west regardless of y's sign.
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ 2.0f, 1.0f }), ENTITY_DIR_EAST
|
||||
);
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ -2.0f, -1.0f }), ENTITY_DIR_WEST
|
||||
);
|
||||
|
||||
// |y| >= |x| picks north/south.
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ 1.0f, 2.0f }), ENTITY_DIR_NORTH
|
||||
);
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ -1.0f, -3.0f }), ENTITY_DIR_SOUTH
|
||||
);
|
||||
|
||||
// Exact diagonal ties break toward north/south.
|
||||
assert_int_equal(
|
||||
entityDirFromVec2((vec2){ 0.7f, 0.7f }), ENTITY_DIR_NORTH
|
||||
);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_entityDirToVec2),
|
||||
cmocka_unit_test(test_entityDirFromVec2Cardinal),
|
||||
cmocka_unit_test(test_entityDirFromVec2DominantAxis),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
Reference in New Issue
Block a user