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:
parent
97af927004
commit
ac180d1efb
|
@ -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
|
||||
|
|
25
src/gui.c
25
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);
|
||||
|
|
|
@ -38,6 +38,7 @@ typedef enum Label_e {
|
|||
GOLD_LABEL,
|
||||
DUNGEON_LEVEL_LABEL,
|
||||
HEALTH_POTION_LABEL,
|
||||
DAGGER_LABEL,
|
||||
LABEL_COUNT
|
||||
} LabelIndex;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef enum {
|
|||
|
||||
typedef enum {
|
||||
HEALTH,
|
||||
DAGGER,
|
||||
FLESH,
|
||||
TREASURE,
|
||||
ITEM_COUNT
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
21
src/skill.c
21
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;
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef struct Skill_t {
|
|||
bool actionRequired;
|
||||
bool instantUse;
|
||||
bool active;
|
||||
bool (*available)(Player*);
|
||||
bool (*use)(struct Skill_t*, SkillData*);
|
||||
} Skill;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue