npc interact turn to face player
This commit is contained in:
@@ -43,9 +43,6 @@ void entityUpdate(entity_t *entity) {
|
|||||||
entityAnimUpdate(entity);
|
entityAnimUpdate(entity);
|
||||||
|
|
||||||
// Movement code.
|
// Movement code.
|
||||||
if(ENTITY_CALLBACKS[entity->type].freeMovement != NULL) {
|
|
||||||
ENTITY_CALLBACKS[entity->type].freeMovement(entity);
|
|
||||||
}
|
|
||||||
if(
|
if(
|
||||||
cutsceneModeIsInputAllowed() &&
|
cutsceneModeIsInputAllowed() &&
|
||||||
ENTITY_CALLBACKS[entity->type].movement != NULL
|
ENTITY_CALLBACKS[entity->type].movement != NULL
|
||||||
|
|||||||
@@ -37,20 +37,6 @@ typedef struct {
|
|||||||
* @param entity Pointer to the entity to move.
|
* @param entity Pointer to the entity to move.
|
||||||
*/
|
*/
|
||||||
void (*movement)(entity_t *entity);
|
void (*movement)(entity_t *entity);
|
||||||
|
|
||||||
/**
|
|
||||||
* Free movement callback. Always runs regardless of cutscene state.
|
|
||||||
* @param entity Pointer to the entity to move.
|
|
||||||
*/
|
|
||||||
void (*freeMovement)(entity_t *entity);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interaction callback for the entity type.
|
|
||||||
* @param player Pointer to the player entity.
|
|
||||||
* @param entity Pointer to the entity to interact with.
|
|
||||||
* @return True if the entity handled the interaction, false otherwise.
|
|
||||||
*/
|
|
||||||
bool_t (*interact)(entity_t *player, entity_t *entity);
|
|
||||||
} entitycallback_t;
|
} entitycallback_t;
|
||||||
|
|
||||||
static const entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
static const entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
||||||
@@ -64,7 +50,5 @@ static const entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
|||||||
[ENTITY_TYPE_NPC] = {
|
[ENTITY_TYPE_NPC] = {
|
||||||
.init = npcInit,
|
.init = npcInit,
|
||||||
.movement = npcMovement,
|
.movement = npcMovement,
|
||||||
.freeMovement = npcFreeMovement,
|
|
||||||
.interact = npcInteract
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -21,11 +21,20 @@ void entityInteractWith(entity_t *player, entity_t *target) {
|
|||||||
"Interact cutscene pointer cannot be NULL"
|
"Interact cutscene pointer cannot be NULL"
|
||||||
);
|
);
|
||||||
cutsceneSystemStartCutscene(target->interact.data.cutscene);
|
cutsceneSystemStartCutscene(target->interact.data.cutscene);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case ENTITY_INTERACT_PRINT:
|
case ENTITY_INTERACT_PRINT:
|
||||||
uiTextboxMainSetText(target->interact.data.message);
|
uiTextboxMainSetText(target->interact.data.message);
|
||||||
return;
|
|
||||||
|
// If NPC turn to face player.
|
||||||
|
if(target->type == ENTITY_TYPE_NPC) {
|
||||||
|
target->data.npc.interactState = NPC_INTERACT_STATE_CONVERSING;
|
||||||
|
target->animation = ENTITY_ANIM_IDLE;
|
||||||
|
entityTurn(target, entityDirGetOpposite(player->direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
// entityTurn(player, player->direction); // Redundant (for now)
|
||||||
|
break;
|
||||||
|
|
||||||
case ENTITY_INTERACT_NULL:
|
case ENTITY_INTERACT_NULL:
|
||||||
break;
|
break;
|
||||||
@@ -34,7 +43,4 @@ void entityInteractWith(entity_t *player, entity_t *target) {
|
|||||||
assertUnreachable("Unknown entity interact type");
|
assertUnreachable("Unknown entity interact type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(ENTITY_CALLBACKS[target->type].interact == NULL) return;
|
|
||||||
ENTITY_CALLBACKS[target->type].interact(player, target);
|
|
||||||
}
|
|
||||||
@@ -16,8 +16,11 @@ typedef struct entity_s entity_t;
|
|||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ENTITY_INTERACT_NULL = 0,
|
ENTITY_INTERACT_NULL = 0,
|
||||||
|
|
||||||
ENTITY_INTERACT_CUTSCENE,
|
ENTITY_INTERACT_CUTSCENE,
|
||||||
ENTITY_INTERACT_PRINT,
|
ENTITY_INTERACT_PRINT,
|
||||||
|
ENTITY_INTERACT_CALLBACK,
|
||||||
|
|
||||||
ENTITY_INTERACT_COUNT
|
ENTITY_INTERACT_COUNT
|
||||||
} entityinteracttype_t;
|
} entityinteracttype_t;
|
||||||
|
|
||||||
@@ -27,6 +30,7 @@ typedef enum {
|
|||||||
typedef union {
|
typedef union {
|
||||||
const cutscene_t *cutscene;
|
const cutscene_t *cutscene;
|
||||||
const char_t *message;
|
const char_t *message;
|
||||||
|
void (*callback)(entity_t *player, entity_t *target);
|
||||||
} entityinteractdata_t;
|
} entityinteractdata_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,17 +12,27 @@
|
|||||||
#include "rpg/rpgtextbox.h"
|
#include "rpg/rpgtextbox.h"
|
||||||
|
|
||||||
const npcmovecallback_t NPC_MOVE_CALLBACKS[NPC_MOVE_TYPE_COUNT] = {
|
const npcmovecallback_t NPC_MOVE_CALLBACKS[NPC_MOVE_TYPE_COUNT] = {
|
||||||
[NPC_MOVE_TYPE_NULL] = { NULL, NULL },
|
[NPC_MOVE_TYPE_NULL] = { 0 },
|
||||||
[NPC_MOVE_TYPE_RANDOM_TURN] = { npcRandomTurnInit, npcRandomTurnMovement },
|
|
||||||
|
[NPC_MOVE_TYPE_RANDOM_TURN] = {
|
||||||
|
npcRandomTurnInit,
|
||||||
|
npcRandomTurnMovement
|
||||||
|
},
|
||||||
|
|
||||||
[NPC_MOVE_TYPE_RANDOM_WALK] = {
|
[NPC_MOVE_TYPE_RANDOM_WALK] = {
|
||||||
npcRandomWalkInit,
|
npcRandomWalkInit,
|
||||||
npcRandomWalkMovement
|
npcRandomWalkMovement
|
||||||
},
|
},
|
||||||
|
|
||||||
[NPC_MOVE_TYPE_RANDOM_TURN_AND_WALK] = {
|
[NPC_MOVE_TYPE_RANDOM_TURN_AND_WALK] = {
|
||||||
npcRandomTurnAndWalkInit,
|
npcRandomTurnAndWalkInit,
|
||||||
npcRandomTurnAndWalkMovement
|
npcRandomTurnAndWalkMovement
|
||||||
},
|
},
|
||||||
[NPC_MOVE_TYPE_PATH] = { npcPathInit, npcPathMovement, true },
|
|
||||||
|
[NPC_MOVE_TYPE_PATH] = {
|
||||||
|
npcPathInit,
|
||||||
|
npcPathMovement
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void npcInit(entity_t *entity) {
|
void npcInit(entity_t *entity) {
|
||||||
@@ -40,23 +50,10 @@ void npcSetMoveType(entity_t *entity, const npcmovetype_t moveType) {
|
|||||||
|
|
||||||
void npcMovement(entity_t *entity) {
|
void npcMovement(entity_t *entity) {
|
||||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
|
|
||||||
npc_t *npc = &entity->data.npc;
|
npc_t *npc = &entity->data.npc;
|
||||||
|
if(npc->interactState != NPC_INTERACT_STATE_NONE) return;
|
||||||
|
|
||||||
const npcmovecallback_t *cb = &NPC_MOVE_CALLBACKS[npc->moveType];
|
const npcmovecallback_t *cb = &NPC_MOVE_CALLBACKS[npc->moveType];
|
||||||
if(!cb->alwaysRun && cb->movement != NULL) cb->movement(entity);
|
if(cb->movement != NULL) cb->movement(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void npcFreeMovement(entity_t *entity) {
|
|
||||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
|
||||||
npc_t *npc = &entity->data.npc;
|
|
||||||
const npcmovecallback_t *cb = &NPC_MOVE_CALLBACKS[npc->moveType];
|
|
||||||
if(cb->alwaysRun && cb->movement != NULL) cb->movement(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool_t npcInteract(entity_t *player, entity_t *npc) {
|
|
||||||
assertNotNull(player, "Player entity pointer cannot be NULL");
|
|
||||||
assertNotNull(npc, "NPC entity pointer cannot be NULL");
|
|
||||||
|
|
||||||
cutsceneSystemStartCutscene(&TEST_CUTSCENE);
|
|
||||||
// rpgTextboxShow(RPG_TEXTBOX_POS_BOTTOM, "Hello World!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -13,6 +13,12 @@
|
|||||||
|
|
||||||
typedef struct entity_s entity_t;
|
typedef struct entity_s entity_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NPC_INTERACT_STATE_NONE,
|
||||||
|
NPC_INTERACT_STATE_CONVERSING,
|
||||||
|
NPC_INTERACT_STATE_COUNT
|
||||||
|
} npcinteractstate_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NPC_MOVE_TYPE_NULL,
|
NPC_MOVE_TYPE_NULL,
|
||||||
NPC_MOVE_TYPE_RANDOM_TURN,
|
NPC_MOVE_TYPE_RANDOM_TURN,
|
||||||
@@ -30,6 +36,7 @@ typedef union {
|
|||||||
} npcmovedata_t;
|
} npcmovedata_t;
|
||||||
|
|
||||||
typedef struct npc_s {
|
typedef struct npc_s {
|
||||||
|
npcinteractstate_t interactState;
|
||||||
npcmovetype_t moveType;
|
npcmovetype_t moveType;
|
||||||
npcmovedata_t moveData;
|
npcmovedata_t moveData;
|
||||||
} npc_t;
|
} npc_t;
|
||||||
@@ -39,8 +46,6 @@ typedef struct {
|
|||||||
void (*init)(npc_t *npc);
|
void (*init)(npc_t *npc);
|
||||||
/** Called each movement tick. */
|
/** Called each movement tick. */
|
||||||
void (*movement)(entity_t *entity);
|
void (*movement)(entity_t *entity);
|
||||||
/** True if movement runs regardless of cutscene state. */
|
|
||||||
bool_t alwaysRun;
|
|
||||||
} npcmovecallback_t;
|
} npcmovecallback_t;
|
||||||
|
|
||||||
extern const npcmovecallback_t NPC_MOVE_CALLBACKS[NPC_MOVE_TYPE_COUNT];
|
extern const npcmovecallback_t NPC_MOVE_CALLBACKS[NPC_MOVE_TYPE_COUNT];
|
||||||
@@ -73,12 +78,4 @@ void npcMovement(entity_t *entity);
|
|||||||
*
|
*
|
||||||
* @param entity Pointer to the entity structure to update.
|
* @param entity Pointer to the entity structure to update.
|
||||||
*/
|
*/
|
||||||
void npcFreeMovement(entity_t *entity);
|
void npcFreeMovement(entity_t *entity);
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles interaction with an NPC entity.
|
|
||||||
*
|
|
||||||
* @param player Pointer to the player entity.
|
|
||||||
* @param npc Pointer to the NPC entity.
|
|
||||||
*/
|
|
||||||
bool_t npcInteract(entity_t *player, entity_t *npc);
|
|
||||||
Reference in New Issue
Block a user