Item entity
This commit is contained in:
@@ -36,7 +36,7 @@ target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
|
|||||||
# DUSK_OPENGL_LEGACY
|
# DUSK_OPENGL_LEGACY
|
||||||
DUSK_LINUX
|
DUSK_LINUX
|
||||||
DUSK_DISPLAY_SIZE_DYNAMIC
|
DUSK_DISPLAY_SIZE_DYNAMIC
|
||||||
DUSK_DISPLAY_WIDTH_DEFAULT=640
|
DUSK_DISPLAY_WIDTH_DEFAULT=854
|
||||||
DUSK_DISPLAY_HEIGHT_DEFAULT=480
|
DUSK_DISPLAY_HEIGHT_DEFAULT=480
|
||||||
DUSK_DISPLAY_SCREEN_HEIGHT=240
|
DUSK_DISPLAY_SCREEN_HEIGHT=240
|
||||||
DUSK_INPUT_KEYBOARD
|
DUSK_INPUT_KEYBOARD
|
||||||
|
|||||||
@@ -6,25 +6,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rpg/cutscene/item/cutsceneitem.h"
|
#include "rpg/cutscene/item/cutsceneitem.h"
|
||||||
#include "rpg/item/backpack.h"
|
#include "rpg/item/itemgive.h"
|
||||||
#include "ui/rpg/uitextboxmain.h"
|
#include "ui/rpg/uitextboxmain.h"
|
||||||
#include "util/string.h"
|
|
||||||
|
|
||||||
void cutsceneItemGiveStart(
|
void cutsceneItemGiveStart(
|
||||||
const cutsceneitem_t *item,
|
const cutsceneitem_t *item,
|
||||||
cutsceneitemdata_t *data
|
cutsceneitemdata_t *data
|
||||||
) {
|
) {
|
||||||
backpackAdd(item->itemGive.item, item->itemGive.quantity);
|
itemGive(item->itemGive.item, item->itemGive.quantity);
|
||||||
|
|
||||||
char_t msg[CUTSCENE_TEXT_MAX_CHARS];
|
|
||||||
stringFormat(
|
|
||||||
msg,
|
|
||||||
CUTSCENE_TEXT_MAX_CHARS - 1,
|
|
||||||
"Received %s x%u",
|
|
||||||
ITEMS[item->itemGive.item].name,
|
|
||||||
(uint32_t)item->itemGive.quantity
|
|
||||||
);
|
|
||||||
uiTextboxMainSetText(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t cutsceneItemGiveUpdate(
|
bool_t cutsceneItemGiveUpdate(
|
||||||
|
|||||||
@@ -15,4 +15,5 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
add_subdirectory(anim)
|
add_subdirectory(anim)
|
||||||
add_subdirectory(interact)
|
add_subdirectory(interact)
|
||||||
add_subdirectory(npc)
|
add_subdirectory(npc)
|
||||||
|
add_subdirectory(item)
|
||||||
add_subdirectory(global)
|
add_subdirectory(global)
|
||||||
@@ -8,12 +8,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "rpg/entity/player.h"
|
#include "rpg/entity/player.h"
|
||||||
#include "npc/npc.h"
|
#include "npc/npc.h"
|
||||||
|
#include "item/entityitem.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ENTITY_TYPE_NULL,
|
ENTITY_TYPE_NULL,
|
||||||
|
|
||||||
ENTITY_TYPE_PLAYER,
|
ENTITY_TYPE_PLAYER,
|
||||||
ENTITY_TYPE_NPC,
|
ENTITY_TYPE_NPC,
|
||||||
|
ENTITY_TYPE_ITEM,
|
||||||
|
|
||||||
ENTITY_TYPE_COUNT
|
ENTITY_TYPE_COUNT
|
||||||
} entitytype_enum_t;
|
} entitytype_enum_t;
|
||||||
@@ -23,6 +25,7 @@ typedef uint8_t entitytype_t;
|
|||||||
typedef union {
|
typedef union {
|
||||||
player_t player;
|
player_t player;
|
||||||
npc_t npc;
|
npc_t npc;
|
||||||
|
entityitem_t item;
|
||||||
} entitytypedata_t;
|
} entitytypedata_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -50,5 +53,10 @@ static const entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
|||||||
[ENTITY_TYPE_NPC] = {
|
[ENTITY_TYPE_NPC] = {
|
||||||
.init = npcInit,
|
.init = npcInit,
|
||||||
.movement = npcMovement,
|
.movement = npcMovement,
|
||||||
|
},
|
||||||
|
|
||||||
|
[ENTITY_TYPE_ITEM] = {
|
||||||
|
.init = entityItemInit,
|
||||||
|
.movement = entityItemMovement,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -40,6 +40,14 @@ void entityInteractWith(entity_t *player, entity_t *target) {
|
|||||||
// entityTurn(player, player->direction); // Redundant (for now)
|
// entityTurn(player, player->direction); // Redundant (for now)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ENTITY_INTERACT_CALLBACK:
|
||||||
|
assertNotNull(
|
||||||
|
target->interact.data.callback,
|
||||||
|
"Interact callback pointer cannot be NULL"
|
||||||
|
);
|
||||||
|
target->interact.data.callback(player, target);
|
||||||
|
break;
|
||||||
|
|
||||||
case ENTITY_INTERACT_NULL:
|
case ENTITY_INTERACT_NULL:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Copyright (c) 2026 Dominic Masters
|
||||||
|
#
|
||||||
|
# This software is released under the MIT License.
|
||||||
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
# Sources
|
||||||
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
entityitem.c
|
||||||
|
)
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "entityitem.h"
|
||||||
|
#include "rpg/entity/entity.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
#include "rpg/item/itemgive.h"
|
||||||
|
#include "ui/rpg/uitextboxmain.h"
|
||||||
|
|
||||||
|
void entityItemInit(entity_t *entity) {
|
||||||
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
|
entity->interact.type = ENTITY_INTERACT_CALLBACK;
|
||||||
|
entity->interact.data.callback = entityItemInteract;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityItemSet(
|
||||||
|
entity_t *entity,
|
||||||
|
const itemid_t item,
|
||||||
|
const uint8_t quantity
|
||||||
|
) {
|
||||||
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
|
entity->data.item.item = item;
|
||||||
|
entity->data.item.quantity = quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityItemInteract(entity_t *player, entity_t *target) {
|
||||||
|
assertNotNull(player, "Player entity pointer cannot be NULL");
|
||||||
|
assertNotNull(target, "Target entity pointer cannot be NULL");
|
||||||
|
|
||||||
|
itemGive(target->data.item.item, target->data.item.quantity);
|
||||||
|
target->data.item.collected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityItemMovement(entity_t *entity) {
|
||||||
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
|
if(!entity->data.item.collected) return;
|
||||||
|
if(uiTextboxMainIsActive()) return;
|
||||||
|
|
||||||
|
entity->type = ENTITY_TYPE_NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "rpg/item/item.h"
|
||||||
|
|
||||||
|
typedef struct entity_s entity_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
itemid_t item;
|
||||||
|
uint8_t quantity;
|
||||||
|
bool_t collected;
|
||||||
|
} entityitem_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes an item entity. Wires up the interact component so that
|
||||||
|
* interacting with the entity gives its item and removes it.
|
||||||
|
*
|
||||||
|
* @param entity Pointer to the entity structure to initialize.
|
||||||
|
*/
|
||||||
|
void entityItemInit(entity_t *entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the item and quantity represented by an item entity.
|
||||||
|
*
|
||||||
|
* @param entity Pointer to the entity structure.
|
||||||
|
* @param item The item ID to give when picked up.
|
||||||
|
* @param quantity The quantity to give when picked up.
|
||||||
|
*/
|
||||||
|
void entityItemSet(
|
||||||
|
entity_t *entity,
|
||||||
|
const itemid_t item,
|
||||||
|
const uint8_t quantity
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interact callback for item entities. Gives the entity's item to the
|
||||||
|
* player and shows the pickup message. The entity itself is removed once
|
||||||
|
* the message has been dismissed, via entityItemMovement.
|
||||||
|
*
|
||||||
|
* @param player Pointer to the player entity.
|
||||||
|
* @param target Pointer to the item entity being picked up.
|
||||||
|
*/
|
||||||
|
void entityItemInteract(entity_t *player, entity_t *target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update callback for item entities. Removes the entity once its pickup
|
||||||
|
* message has been dismissed. No-op if the item hasn't been collected.
|
||||||
|
*
|
||||||
|
* @param entity Pointer to the entity structure to update.
|
||||||
|
*/
|
||||||
|
void entityItemMovement(entity_t *entity);
|
||||||
@@ -8,6 +8,7 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
|||||||
PUBLIC
|
PUBLIC
|
||||||
inventory.c
|
inventory.c
|
||||||
backpack.c
|
backpack.c
|
||||||
|
itemgive.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Item Definitions
|
# Item Definitions
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "itemgive.h"
|
||||||
|
#include "rpg/item/backpack.h"
|
||||||
|
#include "ui/rpg/uitextboxmain.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
|
void itemGive(const itemid_t item, const uint8_t quantity) {
|
||||||
|
backpackAdd(item, quantity);
|
||||||
|
|
||||||
|
char_t msg[ITEM_GIVE_MESSAGE_MAX_CHARS];
|
||||||
|
stringFormat(
|
||||||
|
msg,
|
||||||
|
ITEM_GIVE_MESSAGE_MAX_CHARS - 1,
|
||||||
|
"Received %s x%u",
|
||||||
|
ITEMS[item].name,
|
||||||
|
(uint32_t)quantity
|
||||||
|
);
|
||||||
|
uiTextboxMainSetText(msg);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "rpg/item/item.h"
|
||||||
|
|
||||||
|
#define ITEM_GIVE_MESSAGE_MAX_CHARS 256
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a quantity of an item to the player's backpack and shows a
|
||||||
|
* "Received <item> x<quantity>" message in the main textbox.
|
||||||
|
*
|
||||||
|
* @param item The item ID to give.
|
||||||
|
* @param quantity The quantity to give.
|
||||||
|
*/
|
||||||
|
void itemGive(const itemid_t item, const uint8_t quantity);
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "rpg.h"
|
#include "rpg.h"
|
||||||
#include "entity/entity.h"
|
#include "entity/entity.h"
|
||||||
#include "rpg/entity/npc/npcpath.h"
|
#include "rpg/entity/npc/npcpath.h"
|
||||||
|
#include "rpg/entity/item/entityitem.h"
|
||||||
#include "rpg/overworld/map.h"
|
#include "rpg/overworld/map.h"
|
||||||
#include "rpg/overworld/maparea.h"
|
#include "rpg/overworld/maparea.h"
|
||||||
#include "rpg/cutscene/cutscenesystem.h"
|
#include "rpg/cutscene/cutscenesystem.h"
|
||||||
@@ -48,6 +49,14 @@ errorret_t rpgInit(void) {
|
|||||||
|
|
||||||
mapSpawnEntity(3, (worldpos_t){ 8, 8, 1 });
|
mapSpawnEntity(3, (worldpos_t){ 8, 8, 1 });
|
||||||
|
|
||||||
|
// TEST: Place an item entity.
|
||||||
|
uint8_t itemEntIndex = entityGetAvailable();
|
||||||
|
assertTrue(itemEntIndex != 0xFF, "No available entity slots!.");
|
||||||
|
entity_t *itemEnt = &ENTITIES[itemEntIndex];
|
||||||
|
entityInit(itemEnt, ENTITY_TYPE_ITEM);
|
||||||
|
entityItemSet(itemEnt, ITEM_ID_POTION, 1);
|
||||||
|
entityPositionSet(itemEnt, (worldpos_t){ 12, 2, 0 });
|
||||||
|
|
||||||
// TEST: Create a test map area.
|
// TEST: Create a test map area.
|
||||||
uint8_t areaIndex = mapAreaAdd(
|
uint8_t areaIndex = mapAreaAdd(
|
||||||
(worldpos_t){ 11, 3, 0 },
|
(worldpos_t){ 11, 3, 0 },
|
||||||
|
|||||||
Reference in New Issue
Block a user