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.
This commit is contained in:
Linus_Probert 2018-03-13 16:13:54 +01:00
parent 97af927004
commit ac180d1efb
14 changed files with 104 additions and 17 deletions

View File

@ -205,7 +205,8 @@ endif (NOT CMAKE_BUILD_TYPE MATCHES Debug)
SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT "Release") SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT "Release")
SET(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ".") 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/libFLAC-8.dll
${CMAKE_SOURCE_DIR}/bin/libfreetype-6.dll ${CMAKE_SOURCE_DIR}/bin/libfreetype-6.dll
${CMAKE_SOURCE_DIR}/bin/libmodplug-1.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/SDL2_ttf.dll
${CMAKE_SOURCE_DIR}/bin/zlib1.dll ${CMAKE_SOURCE_DIR}/bin/zlib1.dll
) )
endif (WIN32)
include(InstallRequiredSystemLibraries) include(InstallRequiredSystemLibraries)
INSTALL(TARGETS breakhack INSTALL(TARGETS breakhack

View File

@ -30,8 +30,8 @@
#define DEFAULT_LOG { NULL, 50, 0, 200 } #define DEFAULT_LOG { NULL, 50, 0, 200 }
#define DEFAULT_EVENT_MESSAGES { NULL, 5, 0, 200 } #define DEFAULT_EVENT_MESSAGES { NULL, 5, 0, 200 }
#define POS_Y_COLLECTABLES 64 #define POS_Y_COLLECTABLES 64
#define POS_Y_XPBAR 112 #define POS_Y_XPBAR 128
static SDL_Rect frame_top_left = { 16, 160, 16, 16 }; static SDL_Rect frame_top_left = { 16, 160, 16, 16 };
static SDL_Rect frame_top_right = { 48, 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 = sprite_create();
s->fixed = true; s->fixed = true;
sprite_set_texture(s, t, 0); 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 }; s->pos = (Position) { 16, POS_Y_COLLECTABLES };
linkedlist_append(&gui->sprites, s); linkedlist_append(&gui->sprites, s);
@ -159,9 +159,17 @@ init_sprites(Gui *gui)
s = sprite_create(); s = sprite_create();
s->fixed = true; s->fixed = true;
sprite_set_texture(s, t, 0); 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 }; s->pos = (Position) { 16, POS_Y_COLLECTABLES + 16 };
linkedlist_append(&gui->sprites, s); 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* 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[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[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[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_log();
gui_malloc_eventmessages(); 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 max_health = -1;
static int current_health = -1; static int current_health = -1;
static int current_potion_sips = -1; static int current_potion_sips = -1;
static int current_dagger_count = -1;
static SDL_Color color = { 255, 255, 255, 255 }; 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; 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) { if (last_gold != player->gold) {
m_sprintf(buffer, 200, "x %.2f", player->gold); m_sprintf(buffer, 200, "x %.2f", player->gold);
texture_load_from_text(gui->labels[GOLD_LABEL]->textures[0], buffer, color, renderer); texture_load_from_text(gui->labels[GOLD_LABEL]->textures[0], buffer, color, renderer);

View File

@ -38,6 +38,7 @@ typedef enum Label_e {
GOLD_LABEL, GOLD_LABEL,
DUNGEON_LEVEL_LABEL, DUNGEON_LEVEL_LABEL,
HEALTH_POTION_LABEL, HEALTH_POTION_LABEL,
DAGGER_LABEL,
LABEL_COUNT LABEL_COUNT
} LabelIndex; } LabelIndex;

View File

@ -65,6 +65,18 @@ drink_health(Item *item, Player *player)
gui_log("You collect %u sips of health", (unsigned int) item->value); 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 * static Item *
create_item(const char *path, SDL_Rect clip, void (*cb)(Item*, Player*)) create_item(const char *path, SDL_Rect clip, void (*cb)(Item*, Player*))
{ {
@ -150,8 +162,9 @@ create_treasure(int current_level)
Item * Item *
item_builder_build_item(ItemKey key, int level) item_builder_build_item(ItemKey key, int level)
{ {
static const char *path_flesh = "Items/Flesh.png"; static const char *path_flesh = "Items/Flesh.png";
static const char *path_potion = "Items/Potion.png"; static const char *path_potion = "Items/Potion.png";
static const char *path_short_wep = "Items/ShortWep.png";
check_builder(); check_builder();
@ -172,6 +185,12 @@ item_builder_build_item(ItemKey key, int level)
&drink_health); &drink_health);
item->value = 1 + get_random(level); item->value = 1 + get_random(level);
break; break;
case DAGGER:
item = create_item(path_short_wep,
CLIP16(0, 0),
&pickup_dagger);
item->value = 1;
break;
default: default:
fatal("in item_builder_build() : Unhandled item key %d", key); fatal("in item_builder_build() : Unhandled item key %d", key);
break; break;

View File

@ -35,6 +35,7 @@ typedef enum {
typedef enum { typedef enum {
HEALTH, HEALTH,
DAGGER,
FLESH, FLESH,
TREASURE, TREASURE,
ITEM_COUNT ITEM_COUNT

View File

@ -408,7 +408,7 @@ generate_map(unsigned int level, const char *file, SDL_Renderer *renderer)
// Reset the map // Reset the map
map->currentRoom = (Position) { 0, 0 }; map->currentRoom = (Position) { 0, 0 };
debug("Done"); debug("Running lua script %s: Done", file);
return map; return map;
} }

View File

@ -344,7 +344,7 @@ monster_drop_loot(Monster *monster, Map *map, Player *player)
unsigned int item_drop_chance = 1; unsigned int item_drop_chance = 1;
Item *item; Item *item;
Item *items[2]; Item *items[3];
unsigned int item_count = 0; unsigned int item_count = 0;
bool player_full_health = player->stats.hp >= player->stats.maxhp; 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) { if (get_random(item_drop_chance) == 0) {
ItemKey key; ItemKey key;
if (!player_full_health) key = get_random(DAGGER);
key = get_random(TREASURE - 1);
else
key = HEALTH;
item = item_builder_build_item(key, map->level); item = item_builder_build_item(key, map->level);
item->sprite->pos = monster->sprite->pos; item->sprite->pos = monster->sprite->pos;
items[item_count++] = item; 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) if (item_count == 0)
return; return;

View File

@ -289,6 +289,8 @@ check_skill_activation(Player *player, RoomMatrix *matrix, SDL_Event *event)
continue; continue;
Skill *skill = player->skills[i]; Skill *skill = player->skills[i];
if (skill->available && !skill->available(player))
continue;
skill->active = (selected - 1) == i && !skill->active && skill->resetCountdown == 0; skill->active = (selected - 1) == i && !skill->active && skill->resetCountdown == 0;
if (skill->active && skill->instantUse) { if (skill->active && skill->instantUse) {
SkillData skillData = { player, matrix, VECTOR2D_NODIR }; SkillData skillData = { player, matrix, VECTOR2D_NODIR };
@ -366,9 +368,10 @@ player_create(class_t class, SDL_Renderer *renderer)
{ {
Player *player = malloc(sizeof(Player)); Player *player = malloc(sizeof(Player));
player->sprite = sprite_create(); player->sprite = sprite_create();
player->daggers = 10;
player->total_steps = 0; player->total_steps = 0;
player->steps = 0; player->steps = 0;
player->xp = 0; player->xp = 0;
player->hits = 0; player->hits = 0;
player->kills = 0; player->kills = 0;
player->misses = 0; player->misses = 0;

View File

@ -44,6 +44,7 @@ typedef struct Player_t {
ActionText *hitText; ActionText *hitText;
ActionText *missText; ActionText *missText;
Stats stats; Stats stats;
unsigned int daggers;
LinkedList *projectiles; LinkedList *projectiles;
unsigned int xp; unsigned int xp;
unsigned int total_steps; unsigned int total_steps;

View File

@ -24,6 +24,8 @@
#include "monster.h" #include "monster.h"
#include "mixer.h" #include "mixer.h"
#include "gui.h" #include "gui.h"
#include "item_builder.h"
#include "random.h"
static void static void
onDaggerRender(Sprite *s) onDaggerRender(Sprite *s)
@ -93,6 +95,18 @@ projectile_update(Projectile *p, Player *player, RoomMatrix *rm, float deltatime
mixer_play_effect(SWORD_HIT); mixer_play_effect(SWORD_HIT);
player->hits += 1; 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); monster_hit(space->monster, dmg);
} }
p->alive = false; p->alive = false;

View File

@ -57,6 +57,7 @@ create_default(const char *s_label, Sprite *s)
skill->actionRequired = true; skill->actionRequired = true;
skill->instantUse = false; skill->instantUse = false;
skill->active = false; skill->active = false;
skill->available = NULL;
skill->use = NULL; skill->use = NULL;
return skill; return skill;
} }
@ -123,11 +124,22 @@ create_flurry(void)
return skill; return skill;
} }
static bool
skill_throw_dagger_available(Player *player)
{
return player->daggers > 0;
}
static bool static bool
skill_throw_dagger(Skill *skill, SkillData *data) skill_throw_dagger(Skill *skill, SkillData *data)
{ {
UNUSED(skill); UNUSED(skill);
if (data->player->daggers == 0)
return false;
data->player->daggers--;
Projectile *p = projectile_dagger_create(); Projectile *p = projectile_dagger_create();
if (vector2d_equals(VECTOR2D_UP, data->direction)) if (vector2d_equals(VECTOR2D_UP, data->direction))
p->velocity = (Vector2d) { 0, -DAGGER_VELOCITY }; p->velocity = (Vector2d) { 0, -DAGGER_VELOCITY };
@ -158,11 +170,19 @@ create_throw_dagger(void)
s->fixed = true; s->fixed = true;
Skill *skill = create_default("Throw dagger", s); Skill *skill = create_default("Throw dagger", s);
skill->instantUse = false; skill->instantUse = false;
skill->resetTime = 1;
skill->available = skill_throw_dagger_available;
skill->use = skill_throw_dagger; skill->use = skill_throw_dagger;
skill->actionRequired = false; skill->actionRequired = false;
return skill; return skill;
} }
static bool
skill_sip_health_available(Player *player)
{
return player->potion_sips > 0 && player->stats.hp != player->stats.maxhp;
}
static bool static bool
skill_sip_health(Skill *skill, SkillData *data) skill_sip_health(Skill *skill, SkillData *data)
{ {
@ -182,6 +202,7 @@ create_sip_health(void)
s->fixed = true; s->fixed = true;
Skill *skill = create_default("Sip health", s); Skill *skill = create_default("Sip health", s);
skill->instantUse = true; skill->instantUse = true;
skill->available = skill_sip_health_available;
skill->use = skill_sip_health; skill->use = skill_sip_health;
skill->resetTime = 0; skill->resetTime = 0;
return skill; return skill;

View File

@ -48,6 +48,7 @@ typedef struct Skill_t {
bool actionRequired; bool actionRequired;
bool instantUse; bool instantUse;
bool active; bool active;
bool (*available)(Player*);
bool (*use)(struct Skill_t*, SkillData*); bool (*use)(struct Skill_t*, SkillData*);
} Skill; } Skill;

View File

@ -172,11 +172,14 @@ render_skill_unavailable(SkillBar *bar, Player *player, Camera *cam)
if (!player->skills[i]) if (!player->skills[i])
continue; continue;
if (player->skills[i]->resetCountdown > 0) { Skill *skill = player->skills[i];
if (skill->resetCountdown || (skill->available && !skill->available(player))) {
unavailableSkillBox.x = i * 32; unavailableSkillBox.x = i * 32;
SDL_SetRenderDrawColor(cam->renderer, 255, 0, 0, 70); SDL_SetRenderDrawColor(cam->renderer, 255, 0, 0, 70);
SDL_RenderFillRect(cam->renderer, &unavailableSkillBox); 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);
}
} }
} }
} }

View File

@ -39,6 +39,8 @@ texturecache_add(const char *path)
texture_load_from_file(t, path, renderer); texture_load_from_file(t, path, renderer);
ht_set(textures, path, t); ht_set(textures, path, t);
debug("Cached texture: %s", path); debug("Cached texture: %s", path);
} else {
debug("Retrieved cached texture: %s", path);
} }
return t; return t;