Merge branch 'dev' into npc_upgrade

This commit is contained in:
attilavs2 2024-08-02 19:02:23 +02:00
commit 10d44d6a88
29 changed files with 466 additions and 110 deletions

View file

@ -10,3 +10,4 @@ IndentCaseBlocks: true
IncludeBlocks: Regroup IncludeBlocks: Regroup
AllowShortBlocksOnASingleLine: Empty AllowShortBlocksOnASingleLine: Empty
ColumnLimit: 80 ColumnLimit: 80
AllowShortEnumsOnASingleLine: false

View file

@ -34,6 +34,7 @@ set(SOURCES
src/npc.c src/npc.c
src/events.c src/events.c
src/animation.c src/animation.c
src/inventory.c
# ... # ...
) )
# Shared assets, fx-9860G-only assets and fx-CG-50-only assets # Shared assets, fx-9860G-only assets and fx-CG-50-only assets
@ -56,6 +57,8 @@ set(ASSETS
set(ASSETS_cg set(ASSETS_cg
assets-cg/player_male.png assets-cg/player_male.png
assets-cg/player_female.png assets-cg/player_female.png
assets-cg/player_male_inv.png
assets-cg/player_female_inv.png
assets-cg/npc/char/npc_male.png assets-cg/npc/char/npc_male.png
assets-cg/npc/char/npc_female.png assets-cg/npc/char/npc_female.png
assets-cg/npc/char/npc_milkman.png assets-cg/npc/char/npc_milkman.png
@ -69,6 +72,10 @@ set(ASSETS_cg
assets-cg/INFO_Icon.png assets-cg/INFO_Icon.png
assets-cg/player_face.png assets-cg/player_face.png
assets-cg/font.png assets-cg/font.png
assets-cg/inventory.png
assets-cg/items.png
assets-cg/selection.png
assets-cg/selected.png
) )
set(ASSETS_cg_EGA64 set(ASSETS_cg_EGA64
@ -83,6 +90,8 @@ set(ASSETS_fx
assets-fx/SGN_Icon.png assets-fx/SGN_Icon.png
assets-fx/player_face.png assets-fx/player_face.png
assets-fx/font.png assets-fx/font.png
assets-fx/selection.png
assets-fx/selected.png
# ... # ...
) )
@ -98,6 +107,8 @@ set(ASSETS_fx_1b
assets-fx/1b/npc/face/npc_milkman.png assets-fx/1b/npc/face/npc_milkman.png
assets-fx/1b/npc/face/npc_police.png assets-fx/1b/npc/face/npc_police.png
assets-fx/1b/INFO_Icon.png assets-fx/1b/INFO_Icon.png
assets-fx/1b/inventory.png
assets-fx/1b/items.png
# ... # ...
) )
@ -112,7 +123,9 @@ set(ASSETS_fx_2b
assets-fx/2b/npc/face/npc_female.png assets-fx/2b/npc/face/npc_female.png
assets-fx/2b/npc/face/npc_milkman.png assets-fx/2b/npc/face/npc_milkman.png
assets-fx/2b/npc/face/npc_police.png assets-fx/2b/npc/face/npc_police.png
assets-fx/1b/INFO_Icon.png assets-fx/2b/INFO_Icon.png
assets-fx/2b/inventory.png
assets-fx/2b/items.png
# ... # ...
) )

BIN
assets-cg/base_slot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

BIN
assets-cg/inventory.ase Normal file

Binary file not shown.

BIN
assets-cg/inventory.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
assets-cg/items.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 684 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

BIN
assets-cg/selected.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

BIN
assets-cg/selection.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

View file

@ -1,3 +1,11 @@
INFO_Icon.png: INFO_Icon.png:
type: bopti-image type: bopti-image
name: INFO_Icon_img name: INFO_Icon_img
inventory.png:
type: bopti-image
name: inventory_img
items.png:
type: bopti-image
name: items_img

BIN
assets-fx/1b/inventory.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

BIN
assets-fx/1b/items.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

View file

@ -1,3 +1,11 @@
INFO_Icon.png: INFO_Icon.png:
type: bopti-image type: bopti-image
name: INFO_Icon_img name: INFO_Icon_img
inventory.png:
type: bopti-image
name: inventory_img
items.png:
type: bopti-image
name: items_img

BIN
assets-fx/2b/inventory.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

BIN
assets-fx/2b/items.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

View file

@ -17,6 +17,14 @@ SGN_Icon.png:
type: bopti-image type: bopti-image
name: SGN_Icon_img name: SGN_Icon_img
selection.png:
type: bopti-image
name: selection_img
selected.png:
type: bopti-image
name: selected_img
font.png: font.png:
name: fontRPG name: fontRPG
type: font type: font

BIN
assets-fx/selected.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

BIN
assets-fx/selection.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

View file

@ -142,7 +142,7 @@ def convert_map(input: str, output: str, params: dict, target):
indoor = int(input_map.get_property("indoor")) indoor = int(input_map.get_property("indoor"))
except Exception as e: except Exception as e:
# Show a warning # Show a warning
print(f"WARNING: Indoor property not found.\n") print(f"WARNING: Indoor property not found.")
if indoor: if indoor:
# Get the indoor tileset # Get the indoor tileset

View file

@ -12,6 +12,9 @@
#define GRAYMODEOK 1 #define GRAYMODEOK 1
#endif #endif
#define SLOT_NUM 9
#define SLOT_COLUMNS 3
#if GINT_RENDER_RGB #if GINT_RENDER_RGB
/* The tile size */ /* The tile size */
#define T_HEIGHT 16 #define T_HEIGHT 16
@ -22,9 +25,15 @@
/* The size of the player */ /* The size of the player */
#define P_WIDTH 16 #define P_WIDTH 16
#define P_HEIGHT 16 #define P_HEIGHT 16
/*Max number of dynamic NPCs.*/ /* Max number of dynamic NPCs. */
#define NPC_STACK_SIZE 256 #define NPC_STACK_SIZE 256
/* The position of the slots in the inventory */
#define SLOT_Y 87
#define SLOT_X_EQUIPPED 222
#define SLOT_X 272
#define SLOT_W 28
#define SLOT_H 27
#define SLOT_SPACING 32
#else #else
/* The tile size */ /* The tile size */
#define T_HEIGHT 8 #define T_HEIGHT 8
@ -35,9 +44,15 @@
/* The player size */ /* The player size */
#define P_WIDTH 8 #define P_WIDTH 8
#define P_HEIGHT 8 #define P_HEIGHT 8
/*Max number of "dynamic" NPCs. We are starved for static ram on fx !*/ /* Max number of "dynamic" NPCs. We are starved for static ram on fx ! */
#define NPC_STACK_SIZE 32 #define NPC_STACK_SIZE 32
/* The position of the slots in the inventory */
#define SLOT_Y 24
#define SLOT_X_EQUIPPED 72
#define SLOT_X 88
#define SLOT_W 8
#define SLOT_H 8
#define SLOT_SPACING 12
#endif #endif
/* SPEED should NOT be 8 or bigger: it may cause bugs when handling /* SPEED should NOT be 8 or bigger: it may cause bugs when handling

View file

@ -48,7 +48,7 @@ int (*_operations[OP_AMOUNT])(int, int) = {_op_null, _op_set, _op_add, _op_sub,
#define MIN(a, b) a < b ? a : b #define MIN(a, b) a < b ? a : b
char _message_buffer[MESSAGE_BUFFER_SZ]; char *_message_buffer;
char *events_parse_string(EventHandler *handler, char *message) { char *events_parse_string(EventHandler *handler, char *message) {
size_t message_pos = 0; size_t message_pos = 0;
char in_token = 0; char in_token = 0;

View file

@ -15,7 +15,11 @@ typedef struct {
unsigned int vars; unsigned int vars;
} EventHandler; } EventHandler;
typedef enum { T_NULL, T_VAR_EDIT, T_AMOUNT } Token; typedef enum {
T_NULL,
T_VAR_EDIT,
T_AMOUNT
} Token;
typedef enum { typedef enum {
OP_NULL, OP_NULL,

View file

@ -1,6 +1,7 @@
#include "game.h" #include "game.h"
#include "config.h" #include "config.h"
#include "inventory.h"
#include "map.h" #include "map.h"
#include "mapdata.h" #include "mapdata.h"
#include "npc.h" #include "npc.h"
@ -35,6 +36,11 @@ void game_init(Game *game) {
events_init_handler(&game->handler); events_init_handler(&game->handler);
events_bind_variable(&game->handler, (int *)&game->player.life, "life"); events_bind_variable(&game->handler, (int *)&game->player.life, "life");
events_bind_variable(&game->handler, &game->mana, "mana"); events_bind_variable(&game->handler, &game->mana, "mana");
inventory_init(&game->inventory);
/* For debugging */
game->inventory.slots[5].i = I_GLOVE;
game->inventory.slots[1].i = I_ARMOR;
game->inventory.slots[8].i = I_TALISMAN;
// reload_npc(&game); // reload_npc(&game);
} }
@ -121,8 +127,10 @@ void game_render_indicator(Game *game) {
/* Draw everything. */ /* Draw everything. */
void game_draw(Game *game) { 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 */ * 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) if(game->map_level->indoor)
dclear(C_WHITE); dclear(C_WHITE);
map_render_by_layer(game, BACKGROUND); map_render_by_layer(game, BACKGROUND);
@ -135,6 +143,7 @@ void game_draw(Game *game) {
dprint(8, 8, C_BLACK, "npc_count: %d", npc_count); dprint(8, 8, C_BLACK, "npc_count: %d", npc_count);
dprint(8, 16, C_BLACK, "Mana: %d", game->mana); dprint(8, 16, C_BLACK, "Mana: %d", game->mana);
dprint(8, 24, C_BLACK, "X: %d Y: %d", game->player.x, game->player.y); dprint(8, 24, C_BLACK, "X: %d Y: %d", game->player.x, game->player.y);
inventory_draw(&game->inventory, &game->player);
} }
/* Key management */ /* Key management */
@ -149,98 +158,161 @@ void game_get_inputs(Game *game) {
if(keydown(KEY_EXIT)) if(keydown(KEY_EXIT))
game->exittoOS = true; game->exittoOS = true;
/* Player actions - Prototypes in player.h and implementation in player.c */ /* Inventory */
if(keydown(KEY_LEFT)) if(keydown(KEY_ALPHA)) {
player_move(game, D_LEFT); game->inventory.open = !game->inventory.open;
if(keydown(KEY_RIGHT)) /* TODO: Make something cleaner */
player_move(game, D_RIGHT); while(keydown(KEY_ALPHA)) {
if(keydown(KEY_UP)) clearevents();
player_move(game, D_UP); sleep();
if(keydown(KEY_DOWN)) }
player_move(game, D_DOWN); } else if(game->inventory.open) {
if(keydown(KEY_SHIFT)) if(keydown(KEY_LEFT))
player_action(game); inventory_move_selection(&game->inventory, D_LEFT);
if(keydown(KEY_OPTN)) { /* TODO: Make something cleaner */
game->player.is_male = !game->player.is_male; 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_OPTN))
inventory_move_from_selected(&game->inventory);
/* TODO: Make something cleaner */ /* TODO: Make something cleaner */
while(keydown(KEY_OPTN)) { while(keydown(KEY_OPTN)) {
clearevents(); clearevents();
sleep(); sleep();
} }
} if(keydown(KEY_SQUARE)) {
Player *player = &game->player; inventory_use(&game->inventory, &game->player);
if(keydown(KEY_SHIFT)) { }
uint32_t i; if(keydown(KEY_F1)) {
for(i = 0; i < game->map_level->nbPortal; i++) { inventory_unequip(&game->inventory, IT_TALISMAN);
Portal *portal = &game->map_level->portals[i]; }
if(player->x >= (int)portal->collider.x1 * PXSIZE && if(keydown(KEY_F2)) {
player->x < (int)portal->collider.x2 * PXSIZE && inventory_unequip(&game->inventory, IT_ARMOR);
player->y >= (int)portal->collider.y1 * PXSIZE && }
player->y < (int)portal->collider.y2 * PXSIZE) { if(keydown(KEY_F3)) {
Portal *dest_portal = (Portal *)portal->portal; inventory_unequip(&game->inventory, IT_WEAPON);
Collider dest_collider = dest_portal->collider; }
Map *dest_map = (Map *)portal->map; if(keydown(KEY_SHIFT))
player->x = (dest_collider.x1 + dest_collider.x2) / 2 * PXSIZE; game->inventory.selected = game->inventory.selection;
player->y = (dest_collider.y1 + dest_collider.y2) / 2 * PXSIZE; } else {
game->map_level = dest_map; /* Player actions - Prototypes in player.h and implementation in
/* TODO: Make something cleaner */ * player.c */
while(keydown(KEY_SHIFT)) { if(keydown(KEY_LEFT))
clearevents(); player_move(game, D_LEFT);
sleep(); if(keydown(KEY_RIGHT))
player_move(game, D_RIGHT);
if(keydown(KEY_UP))
player_move(game, D_UP);
if(keydown(KEY_DOWN))
player_move(game, D_DOWN);
if(keydown(KEY_SHIFT))
player_action(game);
if(keydown(KEY_OPTN)) {
game->player.is_male = !game->player.is_male;
/* TODO: Make something cleaner */
while(keydown(KEY_OPTN)) {
clearevents();
sleep();
}
}
Player *player = &game->player;
if(keydown(KEY_SHIFT)) {
uint32_t i;
for(i = 0; i < game->map_level->nbPortal; i++) {
Portal *portal = &game->map_level->portals[i];
if(player->x >= (int)portal->collider.x1 * PXSIZE &&
player->x < (int)portal->collider.x2 * PXSIZE &&
player->y >= (int)portal->collider.y1 * PXSIZE &&
player->y < (int)portal->collider.y2 * PXSIZE) {
Portal *dest_portal = (Portal *)portal->portal;
Collider dest_collider = dest_portal->collider;
Map *dest_map = (Map *)portal->map;
player->x =
(dest_collider.x1 + dest_collider.x2) / 2 * PXSIZE;
player->y =
(dest_collider.y1 + dest_collider.y2) / 2 * PXSIZE;
game->map_level = dest_map;
/* TODO: Make something cleaner */
while(keydown(KEY_SHIFT)) {
clearevents();
sleep();
}
} }
} }
} }
}
/*Temp debug*/ /*Temp debug*/
if(keydown(KEY_F1)) { if(keydown(KEY_F1)) {
NPC *mynpc = npc_create(); NPC *mynpc = npc_create();
if(mynpc) { if(mynpc) {
mynpc->curx = (player->x << PRECISION) / PXSIZE; mynpc->curx = (player->x << PRECISION) / PXSIZE;
mynpc->cury = (player->y << PRECISION) / PXSIZE; mynpc->cury = (player->y << PRECISION) / PXSIZE;
mynpc->x = player->x; mynpc->x = player->x;
mynpc->y = player->x; mynpc->y = player->x;
mynpc->hasPath = 0; mynpc->hasPath = 0;
mynpc->owns_path = false; mynpc->owns_path = false;
mynpc->face = 1; mynpc->face = 1;
mynpc->paused = 0; mynpc->paused = 0;
mynpc->has_dialog = 0; mynpc->has_dialog = 0;
mynpc->xpath = NULL; mynpc->xpath = NULL;
mynpc->ypath = NULL; mynpc->ypath = NULL;
}
while(keydown(KEY_F1)) {
clearevents();
}
} }
while(keydown(KEY_F1)) { if(keydown(KEY_F2)) {
clearevents(); npc_remove_pos(0);
while(keydown(KEY_F2)) {
clearevents();
}
} }
}
if(keydown(KEY_F2)) {
npc_remove_pos(0);
while(keydown(KEY_F2)) {
clearevents();
}
}
/* Display Debug Information on screen */ /* Display Debug Information on screen */
#if DEBUGMODE #if DEBUGMODE
if(keydown(KEY_F1)) { if(keydown(KEY_F1)) {
game->debug_map = !game->debug_map; game->debug_map = !game->debug_map;
} }
if(keydown(KEY_F2)) { if(keydown(KEY_F2)) {
game->debug_player = !game->debug_player; game->debug_player = !game->debug_player;
} }
if(keydown(KEY_F3)) { if(keydown(KEY_F3)) {
game->debug_extra = !game->debug_extra; game->debug_extra = !game->debug_extra;
} }
#endif #endif
/* if USB is enabled - keybinding for screencapture */ /* if USB is enabled - keybinding for screencapture */
#if USB_FEATURE #if USB_FEATURE
if(keydown(KEY_7)) if(keydown(KEY_7))
game->screenshot = true; game->screenshot = true;
if(keydown(KEY_8)) if(keydown(KEY_8))
game->record = !game->record; game->record = !game->record;
#endif // USB_FEATURE #endif // USB_FEATURE
}
} }
void game_update_animations(Game *game, unsigned char ms) { void game_update_animations(Game *game, unsigned char ms) {

View file

@ -8,14 +8,59 @@
#include <stdint.h> #include <stdint.h>
/* The direction where the player is going to. */ /* The direction where the player is going to. */
typedef enum { D_UP, D_DOWN, D_LEFT, D_RIGHT } Direction; typedef enum {
D_UP,
D_DOWN,
D_LEFT,
D_RIGHT
} Direction;
typedef enum { P_LEFTUP = -1, P_CENTER = 0, P_RIGHTDOWN = 1 } Checkpos; typedef enum {
P_LEFTUP = -1,
P_CENTER = 0,
P_RIGHTDOWN = 1
} Checkpos;
typedef enum {
I_NONE,
I_ARMOR,
I_GLOVE,
I_SWORD,
I_BEER,
I_MILK,
I_TALISMAN,
I_AMOUNT
} Item;
typedef enum {
IT_NONE,
IT_TALISMAN,
IT_ARMOR,
IT_WEAPON,
IT_FOOD,
IT_AMOUNT
} ItemType;
typedef struct {
Item i : 4;
unsigned char durability;
} Slot;
typedef struct {
/* Backpack slots. */
Slot slots[SLOT_NUM];
/* Equipped items: first slot: talisman, second slot: armor, last slot:
weapon. */
Slot equipped[3];
/* 1 if the inventory is open. */
char open : 1;
char selected;
char selection;
} Inventory;
typedef struct { typedef struct {
uint32_t x1, y1; uint32_t x1, y1;
uint32_t x2, y2; uint32_t x2, y2;
} Collider; } Collider;
/* Struct that define player parameters */ /* Struct that define player parameters */
@ -109,6 +154,7 @@ typedef struct {
uint8_t current_group; uint8_t current_group;
uint8_t hostile_to_group; uint8_t hostile_to_group;
/* uint16_t to keep the struct aligned */
uint16_t __padding; uint16_t __padding;
} NPC; } NPC;
@ -178,6 +224,7 @@ typedef struct {
bool debug_extra; bool debug_extra;
Animation npc_animation; Animation npc_animation;
Inventory inventory;
int mana; /* Only for testing events TODO: Remove this! */ int mana; /* Only for testing events TODO: Remove this! */
} Game; } Game;

151
src/inventory.c Normal file
View file

@ -0,0 +1,151 @@
#include "inventory.h"
#include <gint/display.h>
#include <string.h>
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;
char item_types[I_AMOUNT] = {IT_NONE, IT_ARMOR, IT_WEAPON, IT_WEAPON,
IT_FOOD, IT_FOOD, IT_TALISMAN};
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);
for(i = 0; i < SLOT_NUM; i++) {
dsubimage(SLOT_X + (i % SLOT_COLUMNS) * SLOT_SPACING,
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,
inventory->equipped[i].i * SLOT_W, 0, SLOT_W, SLOT_H,
DIMAGE_NONE);
}
#if GINT_RENDER_RGB
/* Render the player between the two swords if we are on cg. */
dimage(183, 20,
player->is_male ? &player_male_inv_img : &player_female_inv_img);
#endif
}
/* TODO: Stats. */
}
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_from_selected(Inventory *inventory) {
if(inventory->selected < 0)
return;
Slot current = inventory->slots[inventory->selection];
Slot new = inventory->slots[inventory->selected];
inventory->slots[inventory->selection] = new;
inventory->slots[inventory->selected] = current;
}
void inventory_use(Inventory *inventory, Player *player) {
Item item = inventory->slots[inventory->selection].i;
switch(item_types[item]) {
case IT_TALISMAN:
inventory->equipped[0] = inventory->slots[inventory->selection];
break;
case IT_ARMOR:
inventory->equipped[1] = inventory->slots[inventory->selection];
break;
case IT_WEAPON:
inventory->equipped[2] = inventory->slots[inventory->selection];
break;
case IT_FOOD:
/* TODO */
break;
default:
break;
}
inventory->slots[inventory->selection].i = I_NONE;
inventory->slots[inventory->selection].durability = 255;
}
void inventory_unequip(Inventory *inventory, ItemType type) {
if(inventory->slots[inventory->selection].i)
return;
switch(type) {
case IT_TALISMAN:
inventory->slots[inventory->selection] = inventory->equipped[0];
inventory->equipped[0].i = I_NONE;
inventory->equipped[0].durability = 255;
break;
case IT_ARMOR:
inventory->slots[inventory->selection] = inventory->equipped[1];
inventory->equipped[1].i = I_NONE;
inventory->equipped[1].durability = 255;
break;
case IT_WEAPON:
inventory->slots[inventory->selection] = inventory->equipped[2];
inventory->equipped[2].i = I_NONE;
inventory->equipped[2].durability = 255;
break;
default:
break;
}
}
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;
}
}

15
src/inventory.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef INVENTORY_H
#define INVENTORY_H
/* The structs related to the inventory are defined in game.h */
#include "game.h"
void inventory_init(Inventory *inventory);
void inventory_draw(Inventory *inventory, Player *player);
char inventory_add(Inventory *inventory, Item item);
void inventory_move_from_selected(Inventory *inventory);
void inventory_use(Inventory *inventory, Player *player);
void inventory_unequip(Inventory *inventory, ItemType type);
void inventory_move_selection(Inventory *inventory, Direction direction);
#endif

View file

@ -32,31 +32,34 @@
extern Map *worldRPG[]; extern Map *worldRPG[];
/* Game data (defined in "game.h")*/ /* Game data (defined in "game.h")*/
Game game = {NULL, Game game = {
{12 * PXSIZE, NULL,
36 * PXSIZE, {12 * PXSIZE,
0, 36 * PXSIZE,
0, 0,
100, 0,
SPEED, 100,
false, SPEED,
0, false,
false, 0,
false, false,
true, false,
{}}, true,
{{}, {}, 0}, {}},
false, {{}, {}, 0},
false, false,
false, false,
0, false,
0,
/* debug variables*/ /* debug variables*/
false, false,
false, false,
false, false,
{}, {},
100}; {},
100,
};
/* screen capture management code. TODO: Clean this up! */ /* screen capture management code. TODO: Clean this up! */
@ -117,6 +120,17 @@ int main(void) {
} }
timer_start(timer); timer_start(timer);
extern char *_message_buffer;
_message_buffer = NULL;
_message_buffer = malloc(MESSAGE_BUFFER_SZ);
if(!_message_buffer) {
dtext(64, 64, C_BLACK,
"Failed to allocate the message buffer: not "
"enough RAM available. Press any key to quit.");
dupdate();
getkey();
return 0;
}
game_init(&game); game_init(&game);
#if USB_FEATURE #if USB_FEATURE
@ -213,5 +227,6 @@ int main(void) {
#endif #endif
timer_stop(timer); timer_stop(timer);
free(_message_buffer);
return 1; return 1;
} }

View file

@ -13,7 +13,6 @@ enum {
NPC_FRIENDLY = 1, // The player's team NPC_FRIENDLY = 1, // The player's team
NPC_HOSTILE = 2, // to the player NPC_HOSTILE = 2, // to the player
NPC_ALL = 3 NPC_ALL = 3
}; };
/* /!\ Warning /!\ /* /!\ Warning /!\