From b26cf53e91460b69095ae7ae39400acc47d5fd5c Mon Sep 17 00:00:00 2001 From: mibi88 <76903855+mibi88@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:14:04 +0200 Subject: [PATCH] Inventory item selection. --- CMakeLists.txt | 4 +++ assets-fx/fxconv-metadata.txt | 8 +++++ src/game.c | 46 ++++++++++++++++++++++-- src/game.h | 3 ++ src/inventory.c | 66 +++++++++++++++++++++++++++++++++-- src/inventory.h | 5 ++- 6 files changed, 126 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae1e57a..6d258ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,8 @@ set(ASSETS_cg assets-cg/font.png assets-cg/inventory.png assets-cg/items.png + assets-cg/selection.png + assets-cg/selected.png ) set(ASSETS_cg_EGA64 @@ -88,6 +90,8 @@ set(ASSETS_fx assets-fx/SGN_Icon.png assets-fx/player_face.png assets-fx/font.png + assets-fx/selection.png + assets-fx/selected.png # ... ) diff --git a/assets-fx/fxconv-metadata.txt b/assets-fx/fxconv-metadata.txt index 1d7d0f9..b3556bf 100644 --- a/assets-fx/fxconv-metadata.txt +++ b/assets-fx/fxconv-metadata.txt @@ -17,6 +17,14 @@ SGN_Icon.png: type: bopti-image name: SGN_Icon_img +selection.png: + type: bopti-image + name: selection_img + +selected.png: + type: bopti-image + name: selected_img + font.png: name: fontRPG type: font diff --git a/src/game.c b/src/game.c index 0b5306e..61f8987 100644 --- a/src/game.c +++ b/src/game.c @@ -36,6 +36,7 @@ void game_init(Game *game) { events_init_handler(&game->handler); events_bind_variable(&game->handler, (int *)&game->player.life, "life"); events_bind_variable(&game->handler, &game->mana, "mana"); + inventory_init(&game->inventory); // reload_npc(&game); } @@ -122,8 +123,10 @@ void game_render_indicator(Game *game) { /* Draw everything. */ void game_draw(Game *game) { - /*Only clear if we are inside, the screen is guaranteed to be filled + /* Only clear if we are inside, the screen is guaranteed to be filled * otherwise */ + /* (Mibi88) if we do so, we should only use opaque tiles in the background + layer (it's currently not the case), to artefacts when rendering dialogs. */ if(game->map_level->indoor) dclear(C_WHITE); map_render_by_layer(game, BACKGROUND); @@ -136,7 +139,7 @@ void game_draw(Game *game) { dprint(8, 8, C_BLACK, "npc_count: %d", npc_count); dprint(8, 16, C_BLACK, "Mana: %d", game->mana); dprint(8, 24, C_BLACK, "X: %d Y: %d", game->player.x, game->player.y); - inventory_draw(game, &game->inventory); + inventory_draw(&game->inventory, &game->player); } /* Key management */ @@ -159,6 +162,45 @@ void game_get_inputs(Game *game) { clearevents(); sleep(); } + } else if(game->inventory.open) { + if(keydown(KEY_LEFT)) + inventory_move_selection(&game->inventory, D_LEFT); + /* TODO: Make something cleaner */ + while(keydown(KEY_LEFT)) { + clearevents(); + sleep(); + } + if(keydown(KEY_RIGHT)) + inventory_move_selection(&game->inventory, D_RIGHT); + /* TODO: Make something cleaner */ + while(keydown(KEY_RIGHT)) { + clearevents(); + sleep(); + } + if(keydown(KEY_UP)) + inventory_move_selection(&game->inventory, D_UP); + /* TODO: Make something cleaner */ + while(keydown(KEY_UP)) { + clearevents(); + sleep(); + } + if(keydown(KEY_DOWN)) + inventory_move_selection(&game->inventory, D_DOWN); + /* TODO: Make something cleaner */ + while(keydown(KEY_DOWN)) { + clearevents(); + sleep(); + } + if(keydown(KEY_SHIFT)) + game->inventory.selected = game->inventory.selection; + if(keydown(KEY_OPTN)) { + game->player.is_male = !game->player.is_male; + /* TODO: Make something cleaner */ + while(keydown(KEY_OPTN)) { + clearevents(); + sleep(); + } + } } else { /* Player actions - Prototypes in player.h and implementation in * player.c */ diff --git a/src/game.h b/src/game.h index be88cd4..9670a4c 100644 --- a/src/game.h +++ b/src/game.h @@ -45,6 +45,8 @@ typedef struct { Slot equipped[3]; /* 1 if the inventory is open. */ char open : 1; + char selected; + char selection; } Inventory; typedef struct { @@ -142,6 +144,7 @@ typedef struct { uint8_t current_group; uint8_t hostile_to_group; + /* uint16_t to keep the struct aligned */ uint16_t __padding; } NPC; diff --git a/src/inventory.c b/src/inventory.c index b2a1145..5289fc1 100644 --- a/src/inventory.c +++ b/src/inventory.c @@ -1,13 +1,24 @@ #include "inventory.h" #include +#include extern bopti_image_t inventory_img; extern bopti_image_t items_img; +extern bopti_image_t selection_img; +extern bopti_image_t selected_img; extern bopti_image_t player_male_inv_img; extern bopti_image_t player_female_inv_img; -void inventory_draw(Game *game, Inventory *inventory) { +void inventory_init(Inventory *inventory) { + inventory->open = 0; + memset(inventory->slots, 0, sizeof(Slot)*SLOT_NUM); + memset(inventory->equipped, 0, sizeof(Slot)*3); + inventory->selected = -1; + inventory->selection = 0; +} + +void inventory_draw(Inventory *inventory, Player *player) { size_t i; if(inventory->open) { dimage(0, 0, &inventory_img); @@ -16,6 +27,16 @@ void inventory_draw(Game *game, Inventory *inventory) { SLOT_Y + (i / SLOT_COLUMNS) * SLOT_SPACING, &items_img, inventory->slots[i].i * SLOT_W, 0, SLOT_W, SLOT_H, DIMAGE_NONE); + if(i == inventory->selection){ + dimage(SLOT_X + (i % SLOT_COLUMNS) * SLOT_SPACING, + SLOT_Y + (i / SLOT_COLUMNS) * SLOT_SPACING, + &selection_img); + } + if(i == inventory->selected){ + dimage(SLOT_X + (i % SLOT_COLUMNS) * SLOT_SPACING, + SLOT_Y + (i / SLOT_COLUMNS) * SLOT_SPACING, + &selected_img); + } } for(i = 0; i < 3; i++) { dsubimage(SLOT_X_EQUIPPED, SLOT_Y + i * SLOT_SPACING, &items_img, @@ -25,8 +46,47 @@ void inventory_draw(Game *game, Inventory *inventory) { #if GINT_RENDER_RGB /* Render the player between the two swords if we are on cg. */ dimage(183, 20, - game->player.is_male ? &player_male_inv_img - : &player_female_inv_img); + player->is_male ? &player_male_inv_img : &player_female_inv_img); #endif } } + +char inventory_add(Inventory *inventory, Item item) { + size_t i; + for(i = 0; i < SLOT_NUM; i++) { + if(!inventory->slots[i].i) { + inventory->slots[i].i = item; + inventory->slots[i].durability = 255; + return 0; + } + } + return 1; +} + +void inventory_move_selection(Inventory *inventory, Direction direction) { + switch(direction) { + case D_UP: + inventory->selection -= SLOT_COLUMNS; + if(inventory->selection < 0) + inventory->selection = 0; + break; + case D_DOWN: + inventory->selection += SLOT_COLUMNS; + if(inventory->selection >= SLOT_NUM) { + inventory->selection = SLOT_NUM - 1; + } + break; + case D_LEFT: + if(inventory->selection > 0) { + inventory->selection--; + } + break; + case D_RIGHT: + if(inventory->selection < SLOT_NUM - 1) { + inventory->selection++; + } + break; + default: + break; + } +} diff --git a/src/inventory.h b/src/inventory.h index b8a0368..4e547f6 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -4,6 +4,9 @@ /* The structs related to the inventory are defined in game.h */ #include "game.h" -void inventory_draw(Game *game, Inventory *inventory); +void inventory_init(Inventory *inventory); +void inventory_draw(Inventory *inventory, Player *player); +char inventory_add(Inventory *inventory, Item item); +void inventory_move_selection(Inventory *inventory, Direction direction); #endif