From 6135d60ddcdc25f7c5d566d4c70200da715e3db6 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 18 Jun 2026 13:34:36 -0500 Subject: [PATCH] Interact --- src/dusk/rpg/entity/CMakeLists.txt | 3 +- src/dusk/rpg/entity/entity.h | 3 ++ src/dusk/rpg/entity/entityanim.h | 2 +- src/dusk/rpg/entity/entityinteract.c | 40 +++++++++++++++++++++++ src/dusk/rpg/entity/entityinteract.h | 49 ++++++++++++++++++++++++++++ src/dusk/rpg/entity/player.c | 7 ++-- src/dusk/rpg/rpg.c | 3 ++ 7 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 src/dusk/rpg/entity/entityinteract.c create mode 100644 src/dusk/rpg/entity/entityinteract.h diff --git a/src/dusk/rpg/entity/CMakeLists.txt b/src/dusk/rpg/entity/CMakeLists.txt index f6e4cda5..a254c108 100644 --- a/src/dusk/rpg/entity/CMakeLists.txt +++ b/src/dusk/rpg/entity/CMakeLists.txt @@ -8,7 +8,8 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} PUBLIC entity.c entityanim.c + entitydir.c + entityinteract.c npc.c player.c - entitydir.c ) \ No newline at end of file diff --git a/src/dusk/rpg/entity/entity.h b/src/dusk/rpg/entity/entity.h index 38ef9884..8bf19129 100644 --- a/src/dusk/rpg/entity/entity.h +++ b/src/dusk/rpg/entity/entity.h @@ -8,6 +8,7 @@ #pragma once #include "entitydir.h" #include "entityanim.h" +#include "entityinteract.h" #include "entitytype.h" #include "npc.h" @@ -25,6 +26,8 @@ typedef struct entity_s { entityanim_t animation; fixed_t animTime; + + entityinteract_t interact; } entity_t; extern entity_t ENTITIES[ENTITY_COUNT]; diff --git a/src/dusk/rpg/entity/entityanim.h b/src/dusk/rpg/entity/entityanim.h index a09f0847..0a125126 100644 --- a/src/dusk/rpg/entity/entityanim.h +++ b/src/dusk/rpg/entity/entityanim.h @@ -9,7 +9,7 @@ #include "dusk.h" #include "util/fixed.h" -#define ENTITY_ANIM_TURN_DURATION FIXED(0.12f) +#define ENTITY_ANIM_TURN_DURATION FIXED(0.06f) #define ENTITY_ANIM_WALK_DURATION FIXED(0.1f) typedef struct entity_s entity_t; diff --git a/src/dusk/rpg/entity/entityinteract.c b/src/dusk/rpg/entity/entityinteract.c new file mode 100644 index 00000000..d3b3ca7f --- /dev/null +++ b/src/dusk/rpg/entity/entityinteract.c @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "entity.h" +#include "assert/assert.h" +#include "console/console.h" +#include "rpg/cutscene/cutscenesystem.h" + +void entityInteractWith(entity_t *player, entity_t *target) { + assertNotNull(player, "Player entity pointer cannot be NULL"); + assertNotNull(target, "Target entity pointer cannot be NULL"); + + switch(target->interact.type) { + case ENTITY_INTERACT_CUTSCENE: + assertNotNull( + target->interact.data.cutscene, + "Interact cutscene pointer cannot be NULL" + ); + cutsceneSystemStartCutscene(target->interact.data.cutscene); + return; + + case ENTITY_INTERACT_PRINT: + consolePrint(target->interact.data.message); + return; + + case ENTITY_INTERACT_NULL: + break; + + default: + assertUnreachable("Unknown entity interact type"); + break; + } + + if(ENTITY_CALLBACKS[target->type].interact == NULL) return; + ENTITY_CALLBACKS[target->type].interact(player, target); +} diff --git a/src/dusk/rpg/entity/entityinteract.h b/src/dusk/rpg/entity/entityinteract.h new file mode 100644 index 00000000..27a1efd6 --- /dev/null +++ b/src/dusk/rpg/entity/entityinteract.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" +#include "rpg/cutscene/cutscene.h" + +typedef struct entity_s entity_t; + +/** + * Describes the type of interaction an entity supports. + */ +typedef enum { + ENTITY_INTERACT_NULL = 0, + ENTITY_INTERACT_CUTSCENE, + ENTITY_INTERACT_PRINT, + ENTITY_INTERACT_COUNT +} entityinteracttype_t; + +/** + * Per-type data for an entity's interact component. + */ +typedef union { + const cutscene_t *cutscene; + char_t message[32]; +} entityinteractdata_t; + +/** + * Interact component attached to any entity that can be interacted with. + * Set type to ENTITY_INTERACT_NULL to mark the entity as non-interactable. + */ +typedef struct { + entityinteracttype_t type; + entityinteractdata_t data; +} entityinteract_t; + +/** + * Attempts to interact with the target entity on behalf of the player. + * Dispatches via the interact component; falls back to the entity type + * callback if no component is set. + * + * @param player Pointer to the player entity. + * @param target Pointer to the entity to interact with. + */ +void entityInteractWith(entity_t *player, entity_t *target); diff --git a/src/dusk/rpg/entity/player.c b/src/dusk/rpg/entity/player.c index 22b915c5..e2dffe33 100644 --- a/src/dusk/rpg/entity/player.c +++ b/src/dusk/rpg/entity/player.c @@ -43,12 +43,11 @@ void playerInput(entity_t *entity) { worldunits_t relX, relY; entityDirGetRelative(entity->direction, &relX, &relY); worldpos_t cur = fixedToWorldPos(entity->position); - entity_t *interact = entityGetAt( + entity_t *target = entityGetAt( (worldpos_t){ cur.x + relX, cur.y + relY, cur.z } ); - if(interact != NULL && ENTITY_CALLBACKS[interact->type].interact != NULL) { - if(ENTITY_CALLBACKS[interact->type].interact(entity, interact)) return; - } + if(target == NULL) return; + entityInteractWith(entity, target); } } \ No newline at end of file diff --git a/src/dusk/rpg/rpg.c b/src/dusk/rpg/rpg.c index b003f60e..57b02a7e 100644 --- a/src/dusk/rpg/rpg.c +++ b/src/dusk/rpg/rpg.c @@ -13,6 +13,7 @@ #include "rpgcamera.h" #include "rpgtextbox.h" #include "util/memory.h" +#include "util/string.h" #include "assert/assert.h" errorret_t rpgInit(void) { @@ -43,6 +44,8 @@ errorret_t rpgInit(void) { entity_t *npc = &ENTITIES[npcIndex]; entityInit(npc, ENTITY_TYPE_NPC); worldPosToFixed(&(worldpos_t){ 3, 3, 0 }, npc->position); + npc->interact.type = ENTITY_INTERACT_PRINT; + stringCopy(npc->interact.data.message, "hello world", 32); // All Good! errorOk();