- A tooltip on first play will explain how it works - A tooltip on levelup will display skill info - A setting is introduced to disable tooltips
This commit is contained in:
parent
5f754d551a
commit
358c0c7ddc
|
@ -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
|
||||
|
|
18
src/gui.c
18
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;
|
||||
|
|
|
@ -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, ...);
|
||||
|
||||
|
|
|
@ -19,19 +19,10 @@
|
|||
#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,
|
||||
static Sprite *
|
||||
render_frame_on_texture(Uint32 width,
|
||||
Uint32 height,
|
||||
Position offset,
|
||||
Camera *cam)
|
||||
{
|
||||
Sprite *frame = sprite_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);
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
|
|
15
src/input.c
15
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;
|
||||
}
|
||||
|
|
10
src/input.h
10
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
|
||||
|
|
98
src/main.c
98
src/main.c
|
@ -52,6 +52,55 @@
|
|||
#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 + <NUM>",
|
||||
" Where <NUM> 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,
|
||||
|
@ -72,6 +121,8 @@ 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;
|
||||
|
@ -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);
|
||||
|
|
16
src/player.c
16
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 };
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define POS(x, y) (Position) { x, y }
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
|
|
|
@ -29,6 +29,8 @@ static Settings settings;
|
|||
|
||||
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 *
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
typedef struct Settings {
|
||||
bool music_enabled;
|
||||
bool sound_enabled;
|
||||
bool tooltips_enabled;
|
||||
bool howto_tooltip_shown;
|
||||
} Settings;
|
||||
|
||||
void
|
||||
|
|
110
src/skill.c
110
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);
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef struct SkillBar_t {
|
|||
SkillBar *
|
||||
skillbar_create(SDL_Renderer*);
|
||||
|
||||
void
|
||||
bool
|
||||
skillbar_check_skill_activation(SkillBar*, Player*);
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* BreakHack - A dungeone crawler RPG
|
||||
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "camera.h"
|
||||
#include "sprite.h"
|
||||
|
||||
Sprite *
|
||||
tooltip_create(char **content, Camera*);
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue