From ac180d1efb64f07c30216d5c6283cea4e1d6a247 Mon Sep 17 00:00:00 2001 From: Linus_Probert Date: Tue, 13 Mar 2018 16:13:54 +0100 Subject: [PATCH] Limit the number of daggers carried. There is a "dagger count" on the player now. Also added the "dagger" item that can be dropped by monsters. --- CMakeLists.txt | 4 +++- src/gui.c | 25 +++++++++++++++++++++---- src/gui.h | 1 + src/item_builder.c | 23 +++++++++++++++++++++-- src/item_builder.h | 1 + src/map_lua.c | 2 +- src/monster.c | 12 +++++++----- src/player.c | 5 ++++- src/player.h | 1 + src/projectile.c | 14 ++++++++++++++ src/skill.c | 21 +++++++++++++++++++++ src/skill.h | 1 + src/skillbar.c | 7 +++++-- src/texturecache.c | 4 +++- 14 files changed, 104 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 491a7df..b1dc6f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -205,7 +205,8 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES Debug) SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT "Release") SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ".") -SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS +if (WIN32) + SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${CMAKE_SOURCE_DIR}/bin/libFLAC-8.dll ${CMAKE_SOURCE_DIR}/bin/libfreetype-6.dll ${CMAKE_SOURCE_DIR}/bin/libmodplug-1.dll @@ -221,6 +222,7 @@ SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${CMAKE_SOURCE_DIR}/bin/SDL2_ttf.dll ${CMAKE_SOURCE_DIR}/bin/zlib1.dll ) +endif (WIN32) include(InstallRequiredSystemLibraries) INSTALL(TARGETS breakhack diff --git a/src/gui.c b/src/gui.c index bcc90de..031e5a8 100644 --- a/src/gui.c +++ b/src/gui.c @@ -30,8 +30,8 @@ #define DEFAULT_LOG { NULL, 50, 0, 200 } #define DEFAULT_EVENT_MESSAGES { NULL, 5, 0, 200 } -#define POS_Y_COLLECTABLES 64 -#define POS_Y_XPBAR 112 +#define POS_Y_COLLECTABLES 64 +#define POS_Y_XPBAR 128 static SDL_Rect frame_top_left = { 16, 160, 16, 16 }; static SDL_Rect frame_top_right = { 48, 160, 16, 16 }; @@ -151,7 +151,7 @@ init_sprites(Gui *gui) s = sprite_create(); s->fixed = true; sprite_set_texture(s, t, 0); - s->clip = (SDL_Rect) { 0, 0, 16, 16 }; + s->clip = CLIP16(0, 0); s->pos = (Position) { 16, POS_Y_COLLECTABLES }; linkedlist_append(&gui->sprites, s); @@ -159,9 +159,17 @@ init_sprites(Gui *gui) s = sprite_create(); s->fixed = true; sprite_set_texture(s, t, 0); - s->clip = (SDL_Rect) { 16, 16, 16, 16 }; + s->clip = CLIP16(16, 16); s->pos = (Position) { 16, POS_Y_COLLECTABLES + 16 }; linkedlist_append(&gui->sprites, s); + + t = texturecache_add("Items/ShortWep.png"); + s = sprite_create(); + s->fixed = true; + sprite_set_texture(s, t, 0); + s->clip = CLIP16(0, 0); + s->pos = (Position) { 16, POS_Y_COLLECTABLES + 32 }; + linkedlist_append(&gui->sprites, s); } Gui* @@ -190,6 +198,7 @@ gui_create(void) gui->labels[DUNGEON_LEVEL_LABEL] = create_label_sprite((Position) { 16, POS_Y_XPBAR + 18 + (2*14) }); gui->labels[HEALTH_POTION_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 5 }); gui->labels[GOLD_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 16 + 5 }); + gui->labels[DAGGER_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 32 + 5 }); gui_malloc_log(); gui_malloc_eventmessages(); @@ -303,6 +312,7 @@ gui_update_player_stats(Gui *gui, Player *player, Map *map, SDL_Renderer *render static int max_health = -1; static int current_health = -1; static int current_potion_sips = -1; + static int current_dagger_count = -1; static SDL_Color color = { 255, 255, 255, 255 }; @@ -337,6 +347,13 @@ gui_update_player_stats(Gui *gui, Player *player, Map *map, SDL_Renderer *render current_potion_sips = player->potion_sips; } + if (current_dagger_count != (int) player->daggers) { + m_sprintf(buffer, 200, "x %u", (unsigned int) player->daggers); + texture_load_from_text(gui->labels[DAGGER_LABEL]->textures[0], buffer, color, renderer); + gui->labels[DAGGER_LABEL]->dim = gui->labels[DAGGER_LABEL]->textures[0]->dim; + current_dagger_count = (int) player->daggers; + } + if (last_gold != player->gold) { m_sprintf(buffer, 200, "x %.2f", player->gold); texture_load_from_text(gui->labels[GOLD_LABEL]->textures[0], buffer, color, renderer); diff --git a/src/gui.h b/src/gui.h index 0c0121d..c211269 100644 --- a/src/gui.h +++ b/src/gui.h @@ -38,6 +38,7 @@ typedef enum Label_e { GOLD_LABEL, DUNGEON_LEVEL_LABEL, HEALTH_POTION_LABEL, + DAGGER_LABEL, LABEL_COUNT } LabelIndex; diff --git a/src/item_builder.c b/src/item_builder.c index cb2d329..5a06dac 100644 --- a/src/item_builder.c +++ b/src/item_builder.c @@ -65,6 +65,18 @@ drink_health(Item *item, Player *player) gui_log("You collect %u sips of health", (unsigned int) item->value); } +static void +pickup_dagger(Item *item, Player *player) +{ + player->daggers += (Uint32) item->value; + + mixer_play_effect(SWORD_HIT); + if (item->value > 1) + gui_log("You collect %u daggers", (Uint32) item->value); + else + gui_log("You collect a dagger"); +} + static Item * create_item(const char *path, SDL_Rect clip, void (*cb)(Item*, Player*)) { @@ -150,8 +162,9 @@ create_treasure(int current_level) Item * item_builder_build_item(ItemKey key, int level) { - static const char *path_flesh = "Items/Flesh.png"; - static const char *path_potion = "Items/Potion.png"; + static const char *path_flesh = "Items/Flesh.png"; + static const char *path_potion = "Items/Potion.png"; + static const char *path_short_wep = "Items/ShortWep.png"; check_builder(); @@ -172,6 +185,12 @@ item_builder_build_item(ItemKey key, int level) &drink_health); item->value = 1 + get_random(level); break; + case DAGGER: + item = create_item(path_short_wep, + CLIP16(0, 0), + &pickup_dagger); + item->value = 1; + break; default: fatal("in item_builder_build() : Unhandled item key %d", key); break; diff --git a/src/item_builder.h b/src/item_builder.h index 4331bb1..043e62c 100644 --- a/src/item_builder.h +++ b/src/item_builder.h @@ -35,6 +35,7 @@ typedef enum { typedef enum { HEALTH, + DAGGER, FLESH, TREASURE, ITEM_COUNT diff --git a/src/map_lua.c b/src/map_lua.c index 8a596b2..7f52db0 100644 --- a/src/map_lua.c +++ b/src/map_lua.c @@ -408,7 +408,7 @@ generate_map(unsigned int level, const char *file, SDL_Renderer *renderer) // Reset the map map->currentRoom = (Position) { 0, 0 }; - debug("Done"); + debug("Running lua script %s: Done", file); return map; } diff --git a/src/monster.c b/src/monster.c index 16eb9a9..9f04c12 100644 --- a/src/monster.c +++ b/src/monster.c @@ -344,7 +344,7 @@ monster_drop_loot(Monster *monster, Map *map, Player *player) unsigned int item_drop_chance = 1; Item *item; - Item *items[2]; + Item *items[3]; unsigned int item_count = 0; bool player_full_health = player->stats.hp >= player->stats.maxhp; @@ -358,14 +358,16 @@ monster_drop_loot(Monster *monster, Map *map, Player *player) } if (get_random(item_drop_chance) == 0) { ItemKey key; - if (!player_full_health) - key = get_random(TREASURE - 1); - else - key = HEALTH; + key = get_random(DAGGER); item = item_builder_build_item(key, map->level); item->sprite->pos = monster->sprite->pos; items[item_count++] = item; } + if (!player_full_health && get_random(2) == 0) { + item = item_builder_build_item(FLESH, map->level); + item->sprite->pos = monster->sprite->pos; + items[item_count++] = item; + } if (item_count == 0) return; diff --git a/src/player.c b/src/player.c index 32d3b8e..06636a8 100644 --- a/src/player.c +++ b/src/player.c @@ -289,6 +289,8 @@ check_skill_activation(Player *player, RoomMatrix *matrix, SDL_Event *event) continue; Skill *skill = player->skills[i]; + if (skill->available && !skill->available(player)) + continue; skill->active = (selected - 1) == i && !skill->active && skill->resetCountdown == 0; if (skill->active && skill->instantUse) { SkillData skillData = { player, matrix, VECTOR2D_NODIR }; @@ -366,9 +368,10 @@ player_create(class_t class, SDL_Renderer *renderer) { Player *player = malloc(sizeof(Player)); player->sprite = sprite_create(); + player->daggers = 10; player->total_steps = 0; player->steps = 0; - player->xp = 0; + player->xp = 0; player->hits = 0; player->kills = 0; player->misses = 0; diff --git a/src/player.h b/src/player.h index f8ca671..606826d 100644 --- a/src/player.h +++ b/src/player.h @@ -44,6 +44,7 @@ typedef struct Player_t { ActionText *hitText; ActionText *missText; Stats stats; + unsigned int daggers; LinkedList *projectiles; unsigned int xp; unsigned int total_steps; diff --git a/src/projectile.c b/src/projectile.c index 0c7a487..aafd2f3 100644 --- a/src/projectile.c +++ b/src/projectile.c @@ -24,6 +24,8 @@ #include "monster.h" #include "mixer.h" #include "gui.h" +#include "item_builder.h" +#include "random.h" static void onDaggerRender(Sprite *s) @@ -93,6 +95,18 @@ projectile_update(Projectile *p, Player *player, RoomMatrix *rm, float deltatime mixer_play_effect(SWORD_HIT); player->hits += 1; } + /* + * TODO(Linus): This can be fixed so that daggers + * can be retrieved. Probably best to create an "UpdateData" container that + * can be sent as arguments down the update queue. + + if (get_random(1) == 0) { + debug("Adding dagger item"); + Item *item = item_builder_build_item(DAGGER, 1); + item->sprite->pos = space->monster->sprite->pos; + linkedlist_append(&map->items, item); + } + */ monster_hit(space->monster, dmg); } p->alive = false; diff --git a/src/skill.c b/src/skill.c index 2990b50..ae24753 100644 --- a/src/skill.c +++ b/src/skill.c @@ -57,6 +57,7 @@ create_default(const char *s_label, Sprite *s) skill->actionRequired = true; skill->instantUse = false; skill->active = false; + skill->available = NULL; skill->use = NULL; return skill; } @@ -123,11 +124,22 @@ create_flurry(void) return skill; } +static bool +skill_throw_dagger_available(Player *player) +{ + return player->daggers > 0; +} + static bool skill_throw_dagger(Skill *skill, SkillData *data) { UNUSED(skill); + if (data->player->daggers == 0) + return false; + + data->player->daggers--; + Projectile *p = projectile_dagger_create(); if (vector2d_equals(VECTOR2D_UP, data->direction)) p->velocity = (Vector2d) { 0, -DAGGER_VELOCITY }; @@ -158,11 +170,19 @@ create_throw_dagger(void) s->fixed = true; Skill *skill = create_default("Throw dagger", s); skill->instantUse = false; + skill->resetTime = 1; + skill->available = skill_throw_dagger_available; skill->use = skill_throw_dagger; skill->actionRequired = false; return skill; } +static bool +skill_sip_health_available(Player *player) +{ + return player->potion_sips > 0 && player->stats.hp != player->stats.maxhp; +} + static bool skill_sip_health(Skill *skill, SkillData *data) { @@ -182,6 +202,7 @@ create_sip_health(void) s->fixed = true; Skill *skill = create_default("Sip health", s); skill->instantUse = true; + skill->available = skill_sip_health_available; skill->use = skill_sip_health; skill->resetTime = 0; return skill; diff --git a/src/skill.h b/src/skill.h index 81325a2..982aef4 100644 --- a/src/skill.h +++ b/src/skill.h @@ -48,6 +48,7 @@ typedef struct Skill_t { bool actionRequired; bool instantUse; bool active; + bool (*available)(Player*); bool (*use)(struct Skill_t*, SkillData*); } Skill; diff --git a/src/skillbar.c b/src/skillbar.c index ce1cab0..c63f6fa 100644 --- a/src/skillbar.c +++ b/src/skillbar.c @@ -172,11 +172,14 @@ render_skill_unavailable(SkillBar *bar, Player *player, Camera *cam) if (!player->skills[i]) continue; - if (player->skills[i]->resetCountdown > 0) { + Skill *skill = player->skills[i]; + if (skill->resetCountdown || (skill->available && !skill->available(player))) { unavailableSkillBox.x = i * 32; SDL_SetRenderDrawColor(cam->renderer, 255, 0, 0, 70); SDL_RenderFillRect(cam->renderer, &unavailableSkillBox); - render_skill_countdown(bar, i, player->skills[i]->resetCountdown, cam); + if (skill->resetCountdown) { + render_skill_countdown(bar, i, skill->resetCountdown, cam); + } } } } diff --git a/src/texturecache.c b/src/texturecache.c index b37e362..31e6771 100644 --- a/src/texturecache.c +++ b/src/texturecache.c @@ -39,6 +39,8 @@ texturecache_add(const char *path) texture_load_from_file(t, path, renderer); ht_set(textures, path, t); debug("Cached texture: %s", path); + } else { + debug("Retrieved cached texture: %s", path); } return t; @@ -57,4 +59,4 @@ void texturecache_close(void) { ht_destroy_custom(textures, (void(*)(void*)) texture_destroy); -} \ No newline at end of file +}