diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c9c152..86099c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,6 +178,7 @@ add_executable(breakhack src/hiscore src/object src/gui_util + src/tooltip ) # Sqlite has some warnings that I we don't need to see diff --git a/src/gui.c b/src/gui.c index 0aaa162..479e7fb 100644 --- a/src/gui.c +++ b/src/gui.c @@ -27,6 +27,7 @@ #include "map.h" #include "texturecache.h" #include "gui_util.h" +#include "tooltip.h" #define DEFAULT_LOG { NULL, LOG_LINES_COUNT, 0, 200 } #define DEFAULT_EVENT_MESSAGES { NULL, 5, 0, 200 } @@ -41,7 +42,7 @@ static struct LogData_t { unsigned int strlen; } log_data = DEFAULT_LOG; -static struct GuiEventMsgData_t { +static struct GuiEventMsgs { char **messages; unsigned int len; unsigned int count; @@ -180,6 +181,7 @@ gui_create(Camera *cam) gui->sprites = linkedlist_create(); gui->health = linkedlist_create(); gui->xp_bar = linkedlist_create(); + gui->activeTooltip = NULL; for (i = 0; i < LOG_LINES_COUNT; ++i) { t = texture_create(); @@ -464,6 +466,14 @@ gui_event_message(const char *fmt, ...) event_messages.count++; } +void +gui_render_tooltip(Gui *gui, Camera *cam) +{ + if (gui->activeTooltip) { + sprite_render(gui->activeTooltip, cam); + } +} + void gui_render_log(Gui *gui, Camera *cam) { @@ -520,8 +530,9 @@ gui_render_event_message(Gui *gui, Camera *cam) void gui_clear_message_log(void) { - for (size_t i = 0; i < event_messages.count; ++i) + for (size_t i = 0; i < event_messages.count; ++i) { free(event_messages.messages[i]); + } event_messages.count = 0; for (size_t i = 0; i < log_data.count; ++i) @@ -549,8 +560,9 @@ destroy_event_messages(void) if (event_messages.messages == NULL) return; - for (unsigned int i = 0; i < event_messages.count; ++i) + for (unsigned int i = 0; i < event_messages.count; ++i) { free(event_messages.messages[i]); + } free(event_messages.messages); event_messages.messages = NULL; diff --git a/src/gui.h b/src/gui.h index 91d5791..e70f563 100644 --- a/src/gui.h +++ b/src/gui.h @@ -42,13 +42,14 @@ typedef enum Label_e { LABEL_COUNT } LabelIndex; -typedef struct { +typedef struct Gui { LinkedList *sprites; LinkedList *health; LinkedList *xp_bar; Sprite *bottomFrame; Sprite *rightFrame; Sprite *labels[LABEL_COUNT]; + Sprite *activeTooltip; Texture *log_lines[LOG_LINES_COUNT]; Texture *event_message; Timer *event_message_timer; @@ -69,6 +70,9 @@ gui_render_log(Gui*, Camera*); void gui_render_event_message(Gui*, Camera*); +void +gui_render_tooltip(Gui*, Camera*); + void gui_log(const char *fmt, ...); diff --git a/src/gui_util.c b/src/gui_util.c index 2e7c9cb..5908341 100644 --- a/src/gui_util.c +++ b/src/gui_util.c @@ -19,20 +19,11 @@ #include "texturecache.h" #include "gui_util.h" -static SDL_Rect frame_top_left = { 16, 160, 16, 16 }; -static SDL_Rect frame_top_right = { 48, 160, 16, 16 }; -static SDL_Rect frame_bottom_left = { 16, 192, 16, 16 }; -static SDL_Rect frame_bottom_right = { 48, 192, 16, 16 }; -static SDL_Rect frame_top = { 32, 160, 16, 16 }; -static SDL_Rect frame_bottom = { 32, 192, 16, 16 }; -static SDL_Rect frame_center = { 32, 176, 16, 16 }; -static SDL_Rect frame_left = { 16, 176, 16, 16 }; -static SDL_Rect frame_right = { 48, 176, 16, 16 }; - -Sprite * -gui_util_create_frame_sprite(Uint32 width, - Uint32 height, - Camera *cam) +static Sprite * +render_frame_on_texture(Uint32 width, + Uint32 height, + Position offset, + Camera *cam) { Sprite *frame = sprite_create(); Texture *texture = texture_create(); @@ -48,11 +39,21 @@ gui_util_create_frame_sprite(Uint32 width, texture_create_blank(texture, SDL_TEXTUREACCESS_TARGET, cam->renderer); - Texture *source = texturecache_get("GUI/GUI0.png"); SDL_SetRenderTarget(cam->renderer, texture->texture); SDL_RenderClear(cam->renderer); + SDL_Rect frame_top_left = CLIP16(offset.x, offset.y); + SDL_Rect frame_top_right = CLIP16(offset.x + 32, offset.y); + SDL_Rect frame_bottom_left = CLIP16(offset.x, offset.y + 32); + SDL_Rect frame_bottom_right = CLIP16(offset.x + 32, offset.y + 32); + SDL_Rect frame_top = CLIP16(offset.x + 16, offset.y); + SDL_Rect frame_bottom = CLIP16(offset.x + 16, offset.y + 32); + SDL_Rect frame_center = CLIP16(offset.x + 16, offset.y + 16); + SDL_Rect frame_left = CLIP16(offset.x, offset.y + 16); + SDL_Rect frame_right = CLIP16(offset.x + 32, offset.y + 16); + + Texture *source = texturecache_get("GUI/GUI0.png"); SDL_Rect box = { 0, 0, 16, 16 }; unsigned int i, j; for (i = 0; i < width; ++i) { @@ -108,6 +109,24 @@ gui_util_create_frame_sprite(Uint32 width, } } } + SDL_SetRenderTarget(cam->renderer, NULL); + return frame; } + +Sprite * +gui_util_create_frame_sprite(Uint32 width, + Uint32 height, + Camera *cam) +{ + return render_frame_on_texture(width, height, POS(16, 16*10), cam); +} + +Sprite * +gui_util_create_tooltip_frame_sprite(Uint32 width, + Uint32 height, + Camera *cam) +{ + return render_frame_on_texture(width, height, POS(16*13, 16*13), cam); +} diff --git a/src/gui_util.h b/src/gui_util.h index 52e4d7f..6698fef 100644 --- a/src/gui_util.h +++ b/src/gui_util.h @@ -25,3 +25,8 @@ Sprite * gui_util_create_frame_sprite(Uint32 width, Uint32 height, Camera*); + +Sprite * +gui_util_create_tooltip_frame_sprite(Uint32 width, + Uint32 height, + Camera*); diff --git a/src/input.c b/src/input.c index a53db62..cb8182d 100644 --- a/src/input.c +++ b/src/input.c @@ -107,6 +107,21 @@ get_event_modkey(SDL_Event *event) key = KEY_CTRL_S; break; case SDLK_m: key = KEY_CTRL_M; break; + case SDLK_d: + key = KEY_CTRL_D; break; + } + } else if (event->key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) { + switch (event->key.keysym.sym) { + case SDLK_1: + key = KEY_SHIFT_NUM1; break; + case SDLK_2: + key = KEY_SHIFT_NUM2; break; + case SDLK_3: + key = KEY_SHIFT_NUM3; break; + case SDLK_4: + key = KEY_SHIFT_NUM4; break; + case SDLK_5: + key = KEY_SHIFT_NUM5; break; default: key = 0; break; } diff --git a/src/input.h b/src/input.h index c2a39fb..78e3f1b 100644 --- a/src/input.h +++ b/src/input.h @@ -39,8 +39,14 @@ #define KEY_ESC 16384 #define KEY_ENTER 32768 -#define KEY_CTRL_M 1 -#define KEY_CTRL_S 2 +#define KEY_CTRL_M 0x1 +#define KEY_CTRL_S 0x2 +#define KEY_CTRL_D 0x4 +#define KEY_SHIFT_NUM1 0x8 +#define KEY_SHIFT_NUM2 0x10 +#define KEY_SHIFT_NUM3 0x20 +#define KEY_SHIFT_NUM4 0x40 +#define KEY_SHIFT_NUM5 0x80 #define MBUTTON_LEFT 1 #define MBUTTON_MIDDLE 2 diff --git a/src/main.c b/src/main.c index b81f781..ca9389e 100644 --- a/src/main.c +++ b/src/main.c @@ -52,29 +52,80 @@ #include "screen.h" #include "hiscore.h" #include "io_util.h" +#include "tooltip.h" + +static char *skills_tooltip[] = { + "CONGRATULATIONS!", + "", + " You have aquired a new skill!", + "", + " Skills are listed in the bar below the game screen.", + "", + "", + " SKILL INFO: CTRL + ", + " Where is the skill number (1-5)", + "", + " DISABLE TOOLTIPS: CTRL + D", + "", + "", + "Press ESC to close", + NULL +}; + +static char *how_to_play_tooltip[] = { + "HOW TO PLAY", + "", + " NAVIGATION: Use ARROWS or WASD or HJKL to move", + "", + " ATTACK: Walk into a monster to attack it", + "", + " THROW DAGGER: Press 4 then chose a direction (navigation keys)", + "", + " DRINK HEALTH: Press 5 (if you need health and have potions)", + "", + " TOGGLE MUSIC: CTRL + M", + "", + " TOGGLE SOUND: CTRL + S", + "", + " TOGGLE MENU: ESC", + "", + " Your stats and inventory are listed in the right panel", + "", + "", + " GOOD LUCK!", + " May your death be quick and painless...", + "", + "", + "", + "Press ESC to close", + NULL +}; + typedef enum Turn_t { PLAYER, MONSTER } Turn; -static SDL_Window *gWindow = NULL; -static SDL_Renderer *gRenderer = NULL; -static Player *gPlayer = NULL; -static Map *gMap = NULL; -static RoomMatrix *gRoomMatrix = NULL; -static Gui *gGui = NULL; -static SkillBar *gSkillBar = NULL; -static Pointer *gPointer = NULL; -static Menu *mainMenu = NULL; -static Menu *inGameMenu = NULL; -static Timer *menuTimer = NULL; -static Camera *gCamera = NULL; -static Screen *creditsScreen = NULL; -static Screen *scoreScreen = NULL; -static unsigned int cLevel = 1; -static float deltaTime = 1.0; -static double renderScale = 1.0; +static SDL_Window *gWindow = NULL; +static SDL_Renderer *gRenderer = NULL; +static Player *gPlayer = NULL; +static Map *gMap = NULL; +static RoomMatrix *gRoomMatrix = NULL; +static Gui *gGui = NULL; +static SkillBar *gSkillBar = NULL; +static Pointer *gPointer = NULL; +static Menu *mainMenu = NULL; +static Menu *inGameMenu = NULL; +static Timer *menuTimer = NULL; +static Camera *gCamera = NULL; +static Screen *creditsScreen = NULL; +static Screen *scoreScreen = NULL; +static Sprite *new_skill_tooltip = NULL; +static Sprite *howto_tooltip = NULL; +static unsigned int cLevel = 1; +static float deltaTime = 1.0; +static double renderScale = 1.0; static GameState gGameState; static SDL_Rect gameViewport; static SDL_Rect skillBarViewport; @@ -218,12 +269,17 @@ startGame(void *unused) gGameState = PLAYING; if (gPlayer) player_destroy(gPlayer); - gPlayer = player_create(WARRIOR, gRenderer); + gPlayer = player_create(WARRIOR, gCamera); mixer_play_music(GAME_MUSIC0 + get_random(2)); resetGame(); gui_clear_message_log(); gui_log("The Dungeon Crawl begins!"); gui_event_message("Welcome to the dungeon!"); + + Settings *settings = settings_get(); + if (!settings->howto_tooltip_shown) + gGui->activeTooltip = howto_tooltip; + settings->howto_tooltip_shown = true; } static void @@ -249,6 +305,7 @@ static void goToMainMenu(void *unused) { UNUSED(unused); + gui_clear_message_log(); gGameState = MENU; menu_destroy(inGameMenu); inGameMenu = NULL; @@ -291,16 +348,25 @@ createMenu(Menu **menu, struct MENU_ITEM menu_items[], unsigned int size) } } +static void +showHowToTooltip(void *unused) +{ + UNUSED(unused); + toggleInGameMenu(NULL); + gGui->activeTooltip = howto_tooltip; +} + static void initInGameMenu(void) { struct MENU_ITEM menu_items[] = { { "RESUME", toggleInGameMenu }, + { "HOW TO PLAY", showHowToTooltip }, { "MAIN MENU", goToMainMenu }, { "QUIT", exitGame }, }; - createMenu(&inGameMenu, menu_items, 3); + createMenu(&inGameMenu, menu_items, 4); } static void @@ -412,6 +478,9 @@ init(void) hiscore_init(); initMainMenu(); + howto_tooltip = tooltip_create(how_to_play_tooltip, gCamera); + new_skill_tooltip = tooltip_create(skills_tooltip, gCamera); + gCamera->pos = (Position) { 0, 0 }; gGameState = MENU; @@ -426,7 +495,7 @@ handle_main_input(void) || gGameState == IN_GAME_MENU || gGameState == GAME_OVER) { - if (input_key_is_pressed(&input, KEY_ESC)) + if (!gGui->activeTooltip && input_key_is_pressed(&input, KEY_ESC)) toggleInGameMenu(NULL); } @@ -436,6 +505,8 @@ handle_main_input(void) gGameState = MENU; else if (gGameState == MENU && input_key_is_pressed(&input, KEY_ESC)) gGameState = QUIT; + else if (gGui->activeTooltip && input_key_is_pressed(&input, KEY_ESC)) + gGui->activeTooltip = NULL; if (input_modkey_is_pressed(&input, KEY_CTRL_M)) { if (mixer_toggle_music(&gGameState)) @@ -450,6 +521,15 @@ handle_main_input(void) else gui_log("Sound disabled"); } + + if (input_modkey_is_pressed(&input, KEY_CTRL_D)) { + Settings *s = settings_get(); + s->tooltips_enabled = !s->tooltips_enabled; + if (s->tooltips_enabled) + gui_log("Tooltips enabled"); + else + gui_log("Tooltips disabled"); + } } static bool @@ -518,6 +598,7 @@ populateUpdateData(UpdateData *data, float deltatime) data->map = gMap; data->matrix = gRoomMatrix; data->input = &input; + data->gui = gGui; data->deltatime = deltatime; } @@ -531,9 +612,14 @@ run_game_update(void) menu_update(inGameMenu, &input); populateUpdateData(&updateData, deltaTime); + bool skillActivated = false; if (playerLevel != gPlayer->stats.lvl) { playerLevel = gPlayer->stats.lvl; - skillbar_check_skill_activation(gSkillBar, gPlayer); + skillActivated = skillbar_check_skill_activation(gSkillBar, + gPlayer); + } + if (skillActivated && settings_get()->tooltips_enabled && playerLevel < 5) { + gGui->activeTooltip = new_skill_tooltip; } map_clear_expired_entities(gMap, gPlayer); @@ -601,6 +687,7 @@ run_game_render(void) SDL_RenderSetViewport(gRenderer, NULL); particle_engine_render_global(gCamera); + gui_render_tooltip(gGui, gCamera); if (gGameState == IN_GAME_MENU) { SDL_Rect dimmer = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT }; @@ -630,7 +717,6 @@ run_game(void) gui_event_message("NEW HIGHSCORE"); gui_log("NEW HIGHSCORE"); } - gui_event_message("Press ESC to open menu"); mixer_play_effect(SPLAT); gGameState = GAME_OVER; createInGameGameOverMenu(); @@ -750,6 +836,8 @@ void close(void) if (inGameMenu) menu_destroy(inGameMenu); + sprite_destroy(howto_tooltip); + sprite_destroy(new_skill_tooltip); camera_destroy(gCamera); roommatrix_destroy(gRoomMatrix); gui_destroy(gGui); diff --git a/src/player.c b/src/player.c index 8af18d4..3225da3 100644 --- a/src/player.c +++ b/src/player.c @@ -428,7 +428,7 @@ build_sword_animation(Player *p, SDL_Renderer *renderer) } Player* -player_create(class_t class, SDL_Renderer *renderer) +player_create(class_t class, Camera *cam) { Player *player = malloc(sizeof(Player)); player->sprite = sprite_create(); @@ -451,7 +451,7 @@ player_create(class_t class, SDL_Renderer *renderer) player->animationTimer = timer_create(); player->swordAnimation = animation_create(5); - build_sword_animation(player, renderer); + build_sword_animation(player, cam->renderer); memset(&player->skills, 0, PLAYER_SKILL_COUNT * sizeof(Skill*)); @@ -480,16 +480,16 @@ player_create(class_t class, SDL_Renderer *renderer) case WARRIOR: m_strcpy(asset, 100, "Commissions/Warrior.png"); player->stats = (Stats) WARRIOR_STATS; - player->skills[0] = skill_create(FLURRY); - player->skills[1] = skill_create(BASH); - player->skills[2] = skill_create(CHARGE); - player->skills[3] = skill_create(DAGGER_THROW); + player->skills[0] = skill_create(FLURRY, cam); + player->skills[1] = skill_create(BASH, cam); + player->skills[2] = skill_create(CHARGE, cam); + player->skills[3] = skill_create(DAGGER_THROW, cam); break; } - player->skills[4] = skill_create(SIP_HEALTH); + player->skills[4] = skill_create(SIP_HEALTH, cam); - sprite_load_texture(player->sprite, asset, 0, renderer); + sprite_load_texture(player->sprite, asset, 0, cam->renderer); player->sprite->pos = (Position) { TILE_DIMENSION, TILE_DIMENSION }; player->sprite->dim = GAME_DIMENSION; player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; diff --git a/src/player.h b/src/player.h index e8af448..2e921a2 100644 --- a/src/player.h +++ b/src/player.h @@ -79,7 +79,7 @@ typedef struct Player { } Player; Player* -player_create(class_t, SDL_Renderer*); +player_create(class_t, Camera*); ExperienceData player_get_xp_data(Player*); diff --git a/src/position.h b/src/position.h index 421a860..e50d1b0 100644 --- a/src/position.h +++ b/src/position.h @@ -21,6 +21,8 @@ #include +#define POS(x, y) (Position) { x, y } + typedef struct { int x; int y; diff --git a/src/settings.c b/src/settings.c index fdce103..489e1b1 100644 --- a/src/settings.c +++ b/src/settings.c @@ -27,8 +27,10 @@ static sqlite3 *db = NULL; static Settings settings; -static const char *KEY_MUSIC_ENABLED = "music_enabled"; -static const char *KEY_SOUND_ENABLED = "sound_enabled"; +static const char *KEY_MUSIC_ENABLED = "music_enabled"; +static const char *KEY_SOUND_ENABLED = "sound_enabled"; +static const char *KEY_TOOLTIPS_ENABLED = "tooltips_enabled"; +static const char *KEY_HOW_TO_PLAY_SHOWN = "how_to_play_shown"; static DbQuery MIGRATE_COMMANDS[] = { @@ -49,6 +51,8 @@ set_default_settings(void) { settings.music_enabled = true; settings.sound_enabled = true; + settings.tooltips_enabled = true; + settings.howto_tooltip_shown = false; } static void @@ -82,6 +86,14 @@ load_settings_cb(void *unused, int count, char **values, char **colNames) settings.music_enabled = (bool)atoi(values[i + 1]); i += 2; } + else if (!strcmp(KEY_HOW_TO_PLAY_SHOWN, values[i])) { + settings.howto_tooltip_shown = (bool)atoi(values[i + 1]); + i += 2; + } + else if (!strcmp(KEY_TOOLTIPS_ENABLED, values[i])) { + settings.tooltips_enabled = (bool)atoi(values[i + 1]); + i += 2; + } } return 0; } @@ -127,6 +139,8 @@ settings_save(void) { save_setting_int(KEY_SOUND_ENABLED, settings.sound_enabled); save_setting_int(KEY_MUSIC_ENABLED, settings.music_enabled); + save_setting_int(KEY_TOOLTIPS_ENABLED, settings.tooltips_enabled); + save_setting_int(KEY_HOW_TO_PLAY_SHOWN, settings.howto_tooltip_shown); } Settings * diff --git a/src/settings.h b/src/settings.h index 99a7857..91d5a25 100644 --- a/src/settings.h +++ b/src/settings.h @@ -24,6 +24,8 @@ typedef struct Settings { bool music_enabled; bool sound_enabled; + bool tooltips_enabled; + bool howto_tooltip_shown; } Settings; void diff --git a/src/skill.c b/src/skill.c index c303ea1..b512d0b 100644 --- a/src/skill.c +++ b/src/skill.c @@ -35,6 +35,106 @@ #include "animation.h" #include "artifact.h" #include "trap.h" +#include "tooltip.h" + +static char *flurry_tooltip[] = { + "FLURRY", + "", + " Hits an adjecant enemy with a flurry of three strikes.", + " Each strike has the same odds of hitting as a regular attack", + "", + "COOLDOWN:", + " 5 turns", + "", + "USAGE:", + " activate the skill (press 1)", + " followed by a direction (left, right, up or down)", + "", + "", + "Press ESC to close", + NULL +}; + +static char *bash_tooltip[] = { + "BASH", + "", + " Bashes an adjecant enemy with your shield", + " On a successful hit the target will be stunned for 2 turns", + "", + "COOLDOWN:", + " 2 turns", + "", + "USAGE:", + " activate the skill (press 2)", + " followed by a direction (left, right, up or down)", + "", + "", + "Press ESC to close", + NULL +}; + +static char *charge_tooltip[] = { + "CHARGE", + "", + " You charge in a chosen direction into the first obstructing", + " object. Charging into an enemy can deliver massive damage.", + "", + " Damage is affected by charge distance.", + " Longer distance, more damage.", + "", + "COOLDOWN:", + " 5 turns", + "", + "USAGE:", + " activate the skill (press 3)", + " followed by a direction (left, right, up or down)", + "", + "", + "Press ESC to close", + NULL +}; + +static char *dagger_tooltip[] = { + "THROW DAGGER", + "", + " You throw a dagger in the chosen direction.", + "", + " Damage is affected by throwing distance.", + " Longer distance, more damage.", + "", + " Dagger supply is not infinite, your current dagger", + " inventory is displayed in the panel to the right.", + "", + "COOLDOWN:", + " 0 turns", + "", + "USAGE:", + " activate the skill (press 4)", + " followed by a direction (left, right, up or down)", + "", + "", + "Press ESC to close", + NULL +}; + +static char *health_tooltip[] = { + "DRINK HEALTH", + "", + " You take a sip from your health vial", + "", + " The current amount of sips in your vials is", + " dsplayed in the panel to the right.", + "", + "COOLDOWN:", + " 0 turns", + "", + "USAGE:", + " Sip health (press 5)", + "", + "", + "Press ESC to close", + NULL +}; static Skill * create_default(const char *s_label, Sprite *s) @@ -50,6 +150,7 @@ create_default(const char *s_label, Sprite *s) skill->available = NULL; skill->use = NULL; skill->levelcap = 1; + skill->tooltip = NULL; return skill; } @@ -410,24 +511,29 @@ create_charge(void) } Skill* -skill_create(enum SkillType t) +skill_create(enum SkillType t, Camera *cam) { Skill *skill; switch (t) { case FLURRY: skill = create_flurry(); + skill->tooltip = tooltip_create(flurry_tooltip, cam); break; case SIP_HEALTH: skill = create_sip_health(); + skill->tooltip = tooltip_create(health_tooltip, cam); break; case CHARGE: skill = create_charge(); + skill->tooltip = tooltip_create(charge_tooltip, cam); break; case DAGGER_THROW: skill = create_throw_dagger(); + skill->tooltip = tooltip_create(dagger_tooltip, cam); break; case BASH: skill = create_bash(); + skill->tooltip = tooltip_create(bash_tooltip, cam); break; default: fatal("Unknown SkillType %u", (unsigned int) t); @@ -444,5 +550,7 @@ void skill_destroy(Skill *skill) { sprite_destroy(skill->icon); + if (skill->tooltip) + sprite_destroy(skill->tooltip); free(skill); } diff --git a/src/skill.h b/src/skill.h index a027cea..df42675 100644 --- a/src/skill.h +++ b/src/skill.h @@ -52,10 +52,11 @@ typedef struct Skill_t { bool active; bool (*available)(Player*); bool (*use)(struct Skill_t*, SkillData*); + Sprite *tooltip; } Skill; Skill* -skill_create(enum SkillType); +skill_create(enum SkillType, Camera *cam); void skill_destroy(Skill*); diff --git a/src/skillbar.c b/src/skillbar.c index 0ef70e3..709ec5b 100644 --- a/src/skillbar.c +++ b/src/skillbar.c @@ -26,6 +26,7 @@ #include "texturecache.h" #include "particle_engine.h" #include "update_data.h" +#include "gui.h" static void load_texture(SkillBar *bar, const char *path, SDL_Renderer *renderer) @@ -34,7 +35,7 @@ load_texture(SkillBar *bar, const char *path, SDL_Renderer *renderer) t->dim.width = 16; t->dim.height = 16; - for (unsigned int i = 0; i < 10; ++i) { + for (unsigned int i = 0; i < 5; ++i) { char buffer[4]; Sprite *s = sprite_create(); s->pos = (Position) { i * 32 + 20, 20 }; @@ -73,7 +74,7 @@ skillbar_create(SDL_Renderer *renderer) return bar; } -void +bool skillbar_check_skill_activation(SkillBar *bar, Player *player) { for (int i = 0; i < PLAYER_SKILL_COUNT; ++i) { @@ -85,6 +86,8 @@ skillbar_check_skill_activation(SkillBar *bar, Player *player) timer_start(bar->skillSparkleTimer); } + + return timer_started(bar->skillSparkleTimer); } static void @@ -256,8 +259,17 @@ skillbar_update(SkillBar *bar, UpdateData *data) { Input *input = data->input; - unsigned int key = 0; - for (int i = 0; i < 10; ++i) { + for (int i = 0; i < 5; ++i) { + if (!data->player->skills[i]) + continue; + if (input_modkey_is_pressed(input, KEY_SHIFT_NUM1 << i)) { + data->gui->activeTooltip = data->player->skills[i]->tooltip; + return; + } + } + + Uint32 key = 0; + for (int i = 0; i < 5; ++i) { if (!input_key_is_pressed(input, KEY_NUM0 << i)) continue; key = i; diff --git a/src/skillbar.h b/src/skillbar.h index 89aaef4..9cb24ff 100644 --- a/src/skillbar.h +++ b/src/skillbar.h @@ -39,7 +39,7 @@ typedef struct SkillBar_t { SkillBar * skillbar_create(SDL_Renderer*); -void +bool skillbar_check_skill_activation(SkillBar*, Player*); void diff --git a/src/tooltip.c b/src/tooltip.c new file mode 100644 index 0000000..4c46740 --- /dev/null +++ b/src/tooltip.c @@ -0,0 +1,64 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "tooltip.h" +#include "gui_util.h" +#include "defines.h" +#include "gui.h" + +Sprite * +tooltip_create(char **content, Camera *cam) +{ + int rowCount = 0; + char **contentIndex = content; + while (*contentIndex) { + rowCount++; + contentIndex++; + } + + Sprite *sprite = gui_util_create_tooltip_frame_sprite(BOTTOM_GUI_WIDTH/16 - 6, + (Uint32) ((rowCount * 10 + 48)/16), + cam); + sprite->pos.x = 48; + sprite->pos.y = 96; + Texture *texture = sprite->textures[0]; + Texture *text = texture_create(); + texture_load_font(text, "GUI/SDS_8x8.ttf", LOG_FONT_SIZE, 0); + SDL_SetRenderTarget(cam->renderer, texture->texture); + SDL_Rect renderBox = { 16, 16, 0, 0 }; + + while (*content) { + if (strlen(*content) > 0) { + texture_load_from_text(text, + *content, + C_WHITE, + C_WHITE, + cam->renderer); + renderBox.w = text->dim.width; + renderBox.h = text->dim.height; + texture_render(text, &renderBox, cam); + } + + renderBox.y += 10; + content++; + } + SDL_SetRenderTarget(cam->renderer, NULL); + texture_destroy(text); + + return sprite; +} diff --git a/src/tooltip.h b/src/tooltip.h new file mode 100644 index 0000000..136729d --- /dev/null +++ b/src/tooltip.h @@ -0,0 +1,25 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "camera.h" +#include "sprite.h" + +Sprite * +tooltip_create(char **content, Camera*); diff --git a/src/update_data.h b/src/update_data.h index c3a5164..ca15601 100644 --- a/src/update_data.h +++ b/src/update_data.h @@ -22,11 +22,13 @@ #include "player.h" #include "map.h" #include "roommatrix.h" +#include "gui.h" typedef struct UpdateData { Player *player; Map *map; RoomMatrix *matrix; + Gui *gui; Input *input; float deltatime; } UpdateData;