Interact
This commit is contained in:
@@ -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
|
||||
)
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user