Better labels, more treasure
This commit is contained in:
parent
574e34ce4b
commit
969af2f8c2
|
@ -46,39 +46,39 @@ local state = {
|
|||
local enemies = {
|
||||
|
||||
-- PESTS
|
||||
{ texturePaths.pest0, texturePaths.pest1, 0, 0, "Beetle" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 0, "Beetle" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 32, 0, "Beetle" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 0, "Beetle" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 64, 0, "Large Grub" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 80, 0, "Small Grub" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 96, 0, "Slim Worm" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 112, 0, "Fat Worm" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 0, 0, "A Beetle" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 0, "A Beetle" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 32, 0, "A Beetle" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 0, "A Beetle" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 64, 0, "A Large Grub" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 80, 0, "A Small Grub" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 96, 0, "A Slim Worm" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 112, 0, "A Fat Worm" },
|
||||
|
||||
--{ texturePaths.pest0, texturePaths.pest1, 0, 16, "Female Dragonfly" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 16, "Fly" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 32, 16, "Larva" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 16, "Moth" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 16, "A Fly" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 32, 16, "A Larva" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 16, "A Moth" },
|
||||
--{ texturePaths.pest0, texturePaths.pest1, 64, 16 },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 80, 16, "Gnat" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 80, 16, "A Gnat" },
|
||||
|
||||
{ texturePaths.pest0, texturePaths.pest1, 0, 32, "Small Spider" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 32, "Medium Spider" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 32, 32, "Large Spider" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 32, "Small Scorpion" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 64, 32, "Medium Scorpion" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 80, 32, "Large Scorpion" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 0, 32, "A Small Spider" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 32, "A Medium Spider" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 32, 32, "A Large Spider" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 32, "A Small Scorpion" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 64, 32, "A Medium Scorpion" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 80, 32, "A Large Scorpion" },
|
||||
|
||||
{ texturePaths.pest0, texturePaths.pest1, 0, 48, "Slug" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 48, "Large Slug" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 0, 48, "A Slug" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 48, "A Large Slug" },
|
||||
--{ texturePaths.pest0, texturePaths.pest1, 32, 48 },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 48, "Red Slug" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 64, 48, "Large Red Slug" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 48, "A Red Slug" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 64, 48, "A Large Red Slug" },
|
||||
|
||||
{ texturePaths.pest0, texturePaths.pest1, 0, 64, "Giant Brown Ant" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 64, "Giant Black Ant" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 32, 64, "Giant Gold Ant" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 64, "Giant Silver Ant" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 0, 64, "A Giant Brown Ant" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 16, 64, "A Giant Black Ant" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 32, 64, "A Giant Gold Ant" },
|
||||
{ texturePaths.pest0, texturePaths.pest1, 48, 64, "A Giant Silver Ant" },
|
||||
|
||||
--{ texturePaths.pest0, texturePaths.pest1, 0, 80 },
|
||||
--{ texturePaths.pest0, texturePaths.pest1, 16, 80 },
|
||||
|
@ -113,10 +113,10 @@ local enemies = {
|
|||
--{ texturePaths.undead0, texturePaths.undead1, 96, 16, "", state.passive, state.agressive };
|
||||
--{ texturePaths.undead0, texturePaths.undead1, 112, 16, "", state.passive, state.agressive };
|
||||
|
||||
{ texturePaths.undead0, texturePaths.undead1, 0, 32, "Skeleton", state.passive, state.agressive };
|
||||
{ texturePaths.undead0, texturePaths.undead1, 16, 32, "Umber Skeleton", state.passive, state.agressive };
|
||||
{ texturePaths.undead0, texturePaths.undead1, 32, 32, "Caustic Skeleton", state.passive, state.agressive };
|
||||
{ texturePaths.undead0, texturePaths.undead1, 48, 32, "Black Skeleton", state.passive, state.agressive };
|
||||
{ texturePaths.undead0, texturePaths.undead1, 0, 32, "A Skeleton", state.passive, state.agressive };
|
||||
{ texturePaths.undead0, texturePaths.undead1, 16, 32, "An Umber Skeleton", state.passive, state.agressive };
|
||||
{ texturePaths.undead0, texturePaths.undead1, 32, 32, "A Caustic Skeleton", state.passive, state.agressive };
|
||||
{ texturePaths.undead0, texturePaths.undead1, 48, 32, "A Black Skeleton", state.passive, state.agressive };
|
||||
--{ texturePaths.undead0, texturePaths.undead1, 64, 32, "", state.passive, state.agressive };
|
||||
--{ texturePaths.undead0, texturePaths.undead1, 80, 32, "", state.passive, state.agressive };
|
||||
--{ texturePaths.undead0, texturePaths.undead1, 96, 32, "", state.passive, state.agressive };
|
||||
|
|
|
@ -8,6 +8,8 @@ item_create(void)
|
|||
Item *item = ec_malloc(sizeof(Item));
|
||||
item->sprite = NULL;
|
||||
item->collected = false;
|
||||
m_strcpy(item->label, 50, "");
|
||||
item->value = 0.0;
|
||||
item->effect = NULL;
|
||||
return item;
|
||||
}
|
||||
|
@ -23,4 +25,4 @@ item_destroy(Item *item)
|
|||
if (item->sprite)
|
||||
sprite_destroy(item->sprite);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
typedef struct Item_t {
|
||||
Sprite *sprite;
|
||||
bool collected;
|
||||
char label[50];
|
||||
double value;
|
||||
void (*effect)(struct Item_t *, Player *);
|
||||
} Item;
|
||||
|
||||
|
@ -23,4 +25,4 @@ item_render(Item*, Camera*);
|
|||
void
|
||||
item_destroy(Item*);
|
||||
|
||||
#endif // ITEM_H_
|
||||
#endif // ITEM_H_
|
||||
|
|
|
@ -36,48 +36,118 @@ load_texture(const char *path)
|
|||
}
|
||||
|
||||
static void
|
||||
add_health(Item *item, Player *player)
|
||||
eat_flesh(Item *item, Player *player)
|
||||
{
|
||||
UNUSED(item);
|
||||
|
||||
int original_hp = player->stats.hp;
|
||||
player->stats.hp += 2;
|
||||
player->stats.hp += item->value;
|
||||
if (player->stats.hp > player->stats.maxhp)
|
||||
player->stats.hp = player->stats.maxhp;
|
||||
|
||||
gui_log("You gained %d health", player->stats.hp - original_hp);
|
||||
gui_log("You eat some foul meat and gain %d health", player->stats.hp - original_hp);
|
||||
}
|
||||
|
||||
static void
|
||||
drink_health(Item *item, Player *player)
|
||||
{
|
||||
int original_hp = player->stats.hp;
|
||||
player->stats.hp += item->value;
|
||||
if (player->stats.hp > player->stats.maxhp)
|
||||
player->stats.hp = player->stats.maxhp;
|
||||
|
||||
gui_log("You drink a health potion and gain %d health", player->stats.hp - original_hp);
|
||||
}
|
||||
|
||||
static Item *
|
||||
create_health(void)
|
||||
create_item(const char *path, SDL_Rect clip, void (*cb)(Item*, Player*))
|
||||
{
|
||||
Texture *t;
|
||||
Item *item;
|
||||
|
||||
item = item_create();
|
||||
t = load_texture("assets/Items/Potion.png");
|
||||
t = load_texture(path);
|
||||
|
||||
item->sprite = sprite_create();
|
||||
sprite_set_texture(item->sprite, t, 0);
|
||||
item->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 };
|
||||
item->effect = &add_health;
|
||||
item->sprite->clip = clip;
|
||||
item->effect = cb;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
static void
|
||||
pickup_gold(Item *item, Player *player)
|
||||
{
|
||||
player->gold += item->value;
|
||||
gui_log("You pick up %s", &item->label);
|
||||
}
|
||||
|
||||
static Item *
|
||||
create_treasure(void)
|
||||
{
|
||||
unsigned int value = rand() % TREASURE_COUNT;
|
||||
double amt = (unsigned int) rand() % 40;
|
||||
char label[50];
|
||||
|
||||
SDL_Rect clip = { 0, 0, 16, 16 };
|
||||
switch (value) {
|
||||
case COPPER:
|
||||
m_sprintf(&label[0], 50, "%d copper", amt);
|
||||
amt /= 100;
|
||||
break;
|
||||
case SILVER:
|
||||
m_sprintf(&label[0], 50, "%d silver", amt);
|
||||
clip.x = 48;
|
||||
amt /= 10;
|
||||
break;
|
||||
case GOLD:
|
||||
m_sprintf(&label[0], 50, "%d gold", amt);
|
||||
clip.y = 16;
|
||||
break;
|
||||
case PLATINUM:
|
||||
m_sprintf(&label[0], 50, "%d platinum", amt);
|
||||
clip.x = 48;
|
||||
clip.y = 16;
|
||||
amt *= 10;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (amt > 15 && amt < 30)
|
||||
clip.x += 16;
|
||||
else if (amt <= 15)
|
||||
clip.x += 32;
|
||||
|
||||
Item *item = create_item("assets/Items/Money.png", clip, &pickup_gold);
|
||||
m_strcpy(item->label, 50, label);
|
||||
item->value = amt;
|
||||
return item;
|
||||
}
|
||||
|
||||
Item *
|
||||
item_builder_build_item(ItemKey key)
|
||||
{
|
||||
static const char *path_flesh = "assets/Items/Flesh.png";
|
||||
static const char *path_potion = "assets/Items/Potion.png";
|
||||
|
||||
check_builder();
|
||||
|
||||
Item *item = NULL;
|
||||
switch (key) {
|
||||
case HEALTH:
|
||||
item = create_health();
|
||||
break;
|
||||
default:
|
||||
fatal("in item_builder_build() : Unhandled item key %d", key);
|
||||
break;
|
||||
case TREASURE:
|
||||
item = create_treasure();
|
||||
break;
|
||||
case FLESH:
|
||||
item = create_item(path_flesh, (SDL_Rect) { 0, 0, 16, 16 }, &eat_flesh);
|
||||
item->value = 1;
|
||||
break;
|
||||
case HEALTH:
|
||||
item = create_item(path_potion, (SDL_Rect) { 0, 0, 16, 16 }, &drink_health);
|
||||
item->value = 1 + (rand() % 2);
|
||||
break;
|
||||
default:
|
||||
fatal("in item_builder_build() : Unhandled item key %d", key);
|
||||
break;
|
||||
}
|
||||
|
||||
return item;
|
||||
|
@ -88,4 +158,4 @@ item_builder_close(void)
|
|||
{
|
||||
ht_destroy_custom(builder->textures, (void (*)(void*)) &texture_destroy);
|
||||
free(builder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,18 @@ typedef struct {
|
|||
} ItemBuilder;
|
||||
|
||||
typedef enum {
|
||||
HEALTH
|
||||
COPPER,
|
||||
SILVER,
|
||||
GOLD,
|
||||
PLATINUM,
|
||||
TREASURE_COUNT
|
||||
} Treasure;
|
||||
|
||||
typedef enum {
|
||||
TREASURE,
|
||||
FLESH,
|
||||
HEALTH,
|
||||
ITEM_COUNT
|
||||
} ItemKey;
|
||||
|
||||
void
|
||||
|
@ -22,4 +33,4 @@ item_builder_build_item(ItemKey key);
|
|||
void
|
||||
item_builder_close(void);
|
||||
|
||||
#endif // ITEMBUILDER_H_
|
||||
#endif // ITEMBUILDER_H_
|
||||
|
|
11
src/map.c
11
src/map.c
|
@ -106,13 +106,12 @@ map_clear_dead_monsters(Map *map)
|
|||
else
|
||||
last->next = current->next;
|
||||
|
||||
// TODO(Linus): We should really move this code somewhere else, perhaps to monster.c?
|
||||
// Create a health drop
|
||||
Monster *monster = current->data;
|
||||
Item *item = item_builder_build_item(HEALTH);
|
||||
item->sprite->pos = monster->sprite->pos;
|
||||
linkedlist_append(&map->items, item);
|
||||
gui_log("%s dropped a health potion", monster->label);
|
||||
|
||||
// Loot drops
|
||||
Item *item = monster_drop_loot(monster);
|
||||
if (item)
|
||||
linkedlist_append(&map->items, item);
|
||||
|
||||
monster_destroy(monster);
|
||||
current->data = NULL;
|
||||
|
|
|
@ -207,8 +207,10 @@ l_add_monster(lua_State *L)
|
|||
monster->state.normal = nstate;
|
||||
monster->state.challenge = cstate;
|
||||
monster->state.current = nstate;
|
||||
if (strlen(label))
|
||||
if (strlen(label)) {
|
||||
monster->label = label;
|
||||
monster->lclabel = to_lower(label);
|
||||
}
|
||||
|
||||
map_add_monster(map, monster);
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "monster.h"
|
||||
#include "util.h"
|
||||
#include "player.h"
|
||||
#include "monster.h"
|
||||
#include "random.h"
|
||||
#include "gui.h"
|
||||
#include "item.h"
|
||||
#include "item_builder.h"
|
||||
|
||||
static void
|
||||
monster_load_texts(Monster *m, SDL_Renderer *renderer)
|
||||
|
@ -36,6 +39,7 @@ monster_create(SDL_Renderer *renderer)
|
|||
m->state.challenge = AGRESSIVE;
|
||||
m->state.current = m->state.normal;
|
||||
m->label = NULL;
|
||||
m->lclabel = NULL;
|
||||
|
||||
monster_load_texts(m, renderer);
|
||||
|
||||
|
@ -69,9 +73,9 @@ has_collided(Monster *monster, RoomMatrix *matrix)
|
|||
player_hit(space->player, dmg);
|
||||
|
||||
if (dmg > 0)
|
||||
gui_log("Monster '%s' hit you for %u damage", monster->label, dmg);
|
||||
gui_log("%s hit you for %u damage", monster->label, dmg);
|
||||
else
|
||||
gui_log("Monster '%s' missed you", monster->label);
|
||||
gui_log("%s missed you", monster->label);
|
||||
}
|
||||
|
||||
return space->occupied;
|
||||
|
@ -234,6 +238,23 @@ monster_hit(Monster *monster, unsigned int dmg)
|
|||
monster->state.current = monster->state.challenge;
|
||||
}
|
||||
|
||||
Item *
|
||||
monster_drop_loot(Monster *monster)
|
||||
{
|
||||
static unsigned int drop_chance = 3;
|
||||
unsigned int drop;
|
||||
|
||||
if ((rand() % drop_chance) != 0)
|
||||
return NULL;
|
||||
|
||||
drop = rand() % ITEM_COUNT;
|
||||
Item *item = item_builder_build_item(drop);
|
||||
item->sprite->pos = monster->sprite->pos;
|
||||
gui_log("%s dropped something", monster->label);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void
|
||||
monster_render(Monster *m, Camera *cam)
|
||||
{
|
||||
|
@ -250,6 +271,8 @@ monster_destroy(Monster *m)
|
|||
sprite_destroy(m->sprite);
|
||||
if (m->label)
|
||||
free(m->label);
|
||||
if (m->lclabel)
|
||||
free(m->lclabel);
|
||||
if (m->hitText)
|
||||
actiontext_destroy(m->hitText);
|
||||
if (m->missText)
|
||||
|
|
|
@ -16,6 +16,7 @@ typedef struct {
|
|||
|
||||
typedef struct Monster_t {
|
||||
char *label;
|
||||
char *lclabel;
|
||||
Sprite *sprite;
|
||||
ActionText *hitText;
|
||||
ActionText *missText;
|
||||
|
@ -33,6 +34,8 @@ void monster_render(Monster*, Camera*);
|
|||
|
||||
void monster_hit(Monster*, unsigned int dmg);
|
||||
|
||||
Item *monster_drop_loot(Monster*);
|
||||
|
||||
void monster_destroy(Monster*);
|
||||
|
||||
#endif // MONSTER_H_
|
||||
|
|
13
src/player.c
13
src/player.c
|
@ -20,7 +20,8 @@ has_collided(Player *player, RoomMatrix *matrix)
|
|||
bool collided = false;
|
||||
|
||||
Position roomCoord = position_to_room_coords(&player->sprite->pos);
|
||||
if (roomCoord.x != matrix->roomPos.x || roomCoord.y != matrix->roomPos.y) {
|
||||
if (roomCoord.x != matrix->roomPos.x
|
||||
|| roomCoord.y != matrix->roomPos.y) {
|
||||
return collided;
|
||||
}
|
||||
|
||||
|
@ -39,16 +40,18 @@ has_collided(Player *player, RoomMatrix *matrix)
|
|||
player->misses += 1;
|
||||
|
||||
if (hit > 0)
|
||||
gui_log("You hit '%s' for %u damage", space->monster->label, hit);
|
||||
gui_log("You hit %s for %u damage",
|
||||
space->monster->lclabel, hit);
|
||||
else
|
||||
gui_log("You missed '%s'", space->monster->label);
|
||||
gui_log("You missed %s", space->monster->lclabel);
|
||||
|
||||
if (space->monster->stats.hp <= 0) {
|
||||
// TODO(Linus): This needs some love later on.
|
||||
player->kills += 1;
|
||||
player->xp += 10;
|
||||
|
||||
gui_log("You killed '%s' and gained %d xp", space->monster->label, 10);
|
||||
gui_log("You killed %s and gained %d xp",
|
||||
space->monster->lclabel, 10);
|
||||
}
|
||||
} else if (collided) {
|
||||
gui_log("Ouch! There is something in the way");
|
||||
|
@ -177,6 +180,7 @@ player_create(class_t class, SDL_Renderer *renderer)
|
|||
player->hits = 0;
|
||||
player->kills = 0;
|
||||
player->misses = 0;
|
||||
player->gold = 0;
|
||||
|
||||
char asset[100];
|
||||
switch (class) {
|
||||
|
@ -244,6 +248,7 @@ player_print(Player *p)
|
|||
debug("--------=== <[ Player Stats ]> ===--------");
|
||||
debug("HP: %d", p->stats.hp);
|
||||
debug("Level: %u\tXP:\t%u", p->stats.lvl, p->xp);
|
||||
debug("Gold: %.2f", p->gold);
|
||||
debug("Hits: %u\tMisses:\t%u", p->hits, p->misses);
|
||||
debug("Kills: %u", p->kills);
|
||||
debug("Steps: %u", p->total_steps);
|
||||
|
|
|
@ -21,6 +21,7 @@ typedef struct Player_t {
|
|||
unsigned int hits;
|
||||
unsigned int kills;
|
||||
unsigned int misses;
|
||||
double gold;
|
||||
void (*handle_event)(struct Player_t*, RoomMatrix*, SDL_Event*);
|
||||
} Player;
|
||||
|
||||
|
|
17
src/util.c
17
src/util.c
|
@ -3,6 +3,7 @@
|
|||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
|
@ -140,3 +141,19 @@ timestamp(char *tstamp, size_t sz)
|
|||
free(tm_info);
|
||||
#endif // _MSC_VER
|
||||
}
|
||||
|
||||
char *
|
||||
to_lower(const char *str)
|
||||
{
|
||||
char *lcstr;
|
||||
unsigned int i;
|
||||
|
||||
lcstr = ec_malloc((strlen(str) + 1) * sizeof(char));
|
||||
|
||||
for (i = 0; i < strlen(str); ++i) {
|
||||
lcstr[i] = tolower(str[i]);
|
||||
}
|
||||
lcstr[i] = '\0';
|
||||
|
||||
return lcstr;
|
||||
}
|
||||
|
|
|
@ -28,4 +28,7 @@ m_sprintf(char *dest, size_t destsz, const char *format, ...);
|
|||
void
|
||||
timestamp(char *tstamp, size_t sz);
|
||||
|
||||
char *
|
||||
to_lower(const char *str);
|
||||
|
||||
#endif // UTIL_H_
|
||||
|
|
Loading…
Reference in New Issue