physics stuff
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* 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/overworld/maparea.h"
|
||||
|
||||
static uint32_t TEST_ENTER_COUNT;
|
||||
static uint32_t TEST_STEP_COUNT;
|
||||
static uint32_t TEST_EXIT_COUNT;
|
||||
|
||||
static void testAreaCallback(entity_t *entity, const uint8_t trigger) {
|
||||
if(trigger == MAP_TRIGGER_ENTER) TEST_ENTER_COUNT++;
|
||||
else if(trigger == MAP_TRIGGER_STEP) TEST_STEP_COUNT++;
|
||||
else if(trigger == MAP_TRIGGER_EXIT) TEST_EXIT_COUNT++;
|
||||
}
|
||||
|
||||
static void testMapAreaReset(void) {
|
||||
memoryZero(MAP_AREAS, sizeof(MAP_AREAS));
|
||||
TEST_ENTER_COUNT = 0;
|
||||
TEST_STEP_COUNT = 0;
|
||||
TEST_EXIT_COUNT = 0;
|
||||
}
|
||||
|
||||
static entity_t testEntityAt(const entitytype_t type, const worldpos_t pos) {
|
||||
entity_t entity;
|
||||
memoryZero(&entity, sizeof(entity));
|
||||
entity.id = 0;
|
||||
entity.type = type;
|
||||
entity.position = pos;
|
||||
return entity;
|
||||
}
|
||||
|
||||
static void test_mapAreaCheckEntityFiresEnterAndExit(void **state) {
|
||||
testMapAreaReset();
|
||||
mapAreaAdd(
|
||||
(worldpos_t){ 0, 0, 0 }, (worldpos_t){ 5, 5, 0 },
|
||||
testAreaCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
||||
);
|
||||
|
||||
entity_t entity = testEntityAt(ENTITY_TYPE_PLAYER, (worldpos_t){ 10, 10, 0 });
|
||||
mapAreaCheckEntity(&entity);
|
||||
assert_int_equal(TEST_ENTER_COUNT, 0);
|
||||
|
||||
entity.position = (worldpos_t){ 2, 2, 0 };
|
||||
mapAreaCheckEntity(&entity);
|
||||
assert_int_equal(TEST_ENTER_COUNT, 1);
|
||||
assert_int_equal(TEST_STEP_COUNT, 0);
|
||||
|
||||
entity.position = (worldpos_t){ 10, 10, 0 };
|
||||
mapAreaCheckEntity(&entity);
|
||||
assert_int_equal(TEST_EXIT_COUNT, 1);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
static void test_mapAreaCheckEntityStepFiresOncePerNewTile(void **state) {
|
||||
testMapAreaReset();
|
||||
mapAreaAdd(
|
||||
(worldpos_t){ 0, 0, 0 }, (worldpos_t){ 5, 5, 0 },
|
||||
testAreaCallback, MAP_AREA_NOTIFY_ALL, MAP_TRIGGER_ALL
|
||||
);
|
||||
|
||||
entity_t entity = testEntityAt(ENTITY_TYPE_PLAYER, (worldpos_t){ 1, 1, 0 });
|
||||
mapAreaCheckEntity(&entity);
|
||||
assert_int_equal(TEST_ENTER_COUNT, 1);
|
||||
assert_int_equal(TEST_STEP_COUNT, 0);
|
||||
|
||||
// Same tile, checked repeatedly (simulating multiple frames without the
|
||||
// entity moving) - STEP must not fire.
|
||||
mapAreaCheckEntity(&entity);
|
||||
mapAreaCheckEntity(&entity);
|
||||
assert_int_equal(TEST_STEP_COUNT, 0);
|
||||
|
||||
// Moves to a new tile, still inside - STEP fires once.
|
||||
entity.position = (worldpos_t){ 2, 1, 0 };
|
||||
mapAreaCheckEntity(&entity);
|
||||
assert_int_equal(TEST_STEP_COUNT, 1);
|
||||
|
||||
// Same new tile again over multiple calls - no additional STEP.
|
||||
mapAreaCheckEntity(&entity);
|
||||
mapAreaCheckEntity(&entity);
|
||||
assert_int_equal(TEST_STEP_COUNT, 1);
|
||||
|
||||
// Another new tile - STEP fires again.
|
||||
entity.position = (worldpos_t){ 3, 1, 0 };
|
||||
mapAreaCheckEntity(&entity);
|
||||
assert_int_equal(TEST_STEP_COUNT, 2);
|
||||
|
||||
assert_int_equal(TEST_ENTER_COUNT, 1);
|
||||
assert_int_equal(TEST_EXIT_COUNT, 0);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
static void test_mapAreaCheckEntityNotifyFlagsRespected(void **state) {
|
||||
testMapAreaReset();
|
||||
mapAreaAdd(
|
||||
(worldpos_t){ 0, 0, 0 }, (worldpos_t){ 5, 5, 0 },
|
||||
testAreaCallback, MAP_AREA_NOTIFY_PLAYER, MAP_TRIGGER_ALL
|
||||
);
|
||||
|
||||
entity_t npc = testEntityAt(ENTITY_TYPE_NPC, (worldpos_t){ 1, 1, 0 });
|
||||
mapAreaCheckEntity(&npc);
|
||||
assert_int_equal(TEST_ENTER_COUNT, 0);
|
||||
|
||||
entity_t player = testEntityAt(ENTITY_TYPE_PLAYER, (worldpos_t){ 1, 1, 0 });
|
||||
mapAreaCheckEntity(&player);
|
||||
assert_int_equal(TEST_ENTER_COUNT, 1);
|
||||
|
||||
assert_int_equal(memoryGetAllocatedCount(), 0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_mapAreaCheckEntityFiresEnterAndExit),
|
||||
cmocka_unit_test(test_mapAreaCheckEntityStepFiresOncePerNewTile),
|
||||
cmocka_unit_test(test_mapAreaCheckEntityNotifyFlagsRespected),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
Reference in New Issue
Block a user