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_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
|
||||||
|
|
25
src/gui.c
25
src/gui.c
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef enum {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HEALTH,
|
HEALTH,
|
||||||
|
DAGGER,
|
||||||
FLESH,
|
FLESH,
|
||||||
TREASURE,
|
TREASURE,
|
||||||
ITEM_COUNT
|
ITEM_COUNT
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
21
src/skill.c
21
src/skill.c
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -57,4 +59,4 @@ void
|
||||||
texturecache_close(void)
|
texturecache_close(void)
|
||||||
{
|
{
|
||||||
ht_destroy_custom(textures, (void(*)(void*)) texture_destroy);
|
ht_destroy_custom(textures, (void(*)(void*)) texture_destroy);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue