Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ root = true

[*]
insert_final_newline = true
trim_trailing_whitespace = true

[*.{c,h}]
charset = utf-8
Expand Down
6 changes: 4 additions & 2 deletions .vimrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ packadd termdebug
let g:termdebug_wide = 1

" INDENTING:
set tabstop=4
set shiftwidth=4
set noexpandtab " tabs are tabs, not spaces
set copyindent
set softtabstop=0
set tabstop=8
set shiftwidth=8

au FileType c,h setl tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab
23 changes: 13 additions & 10 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,20 @@
#include "camera.h"
#include "linkedlist.h"

/**
* \brief A game item struct
*/
typedef struct Item_t {
Sprite *sprite;
LinkedList *subsprites;
bool collected;
bool openable;
bool opened;
char label[50];
double price;
double value;
LinkedList *items;
void (*effect)(struct Item_t *, Player *);
Sprite *sprite; /**< The item sprite */
LinkedList *subsprites; /**< A list of sub-sprites */
bool collected; /**< If the item has been collected */
bool openable; /**< Can the item be opened? */
bool opened; /**< Has the item been opened? */
char label[50]; /**< The Item label */
double price; /**< The item price (for vendor) */
double value; /**< Value, the item value. Eg. Gold */
LinkedList *items; /**< Sub items */
void (*effect)(struct Item_t *, Player *); /**< Item effect callback */
} Item;

Item *
Expand Down
46 changes: 46 additions & 0 deletions src/item_builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,52 @@ item_builder_build_key(unsigned int type)
return item;
}

static void
pickup_bloodlust(Item *item, Player *player)
{
gui_log("You drink a bloodlust potion. Rage pulses through your veins.");
player->effects.effect = POTION_BLOODLUST;
player->effects.damage_multiplier = 4;
sprite_set_color_mod(player->sprite, 255, 25, 45);
}

static void
pickup_frost(Item *item, Player *player)
{
gui_log("You drink a frost potion. Your skin is ice.");
player->effects.effect = POTION_FROST;
player->effects.damage_reduction = 2 * player->stats.lvl;
sprite_set_color_mod(player->sprite, 94, 156, 255);
}

Item *
item_builder_build_potion(PotionEffect effect)
{
Item *item;

assert(effect != POTION_NONE);

switch (effect) {
case POTION_BLOODLUST:
item = create_item("Items/Potion.png",
NULL,
CLIP16(48, 32),
pickup_bloodlust);
break;
case POTION_FROST:
item = create_item("Items/Potion.png",
NULL,
CLIP16(96, 0),
pickup_frost);
break;
case POTION_NONE:
default:
break;
}

return item;
}

static Item *
create_treasure(int current_level)
{
Expand Down
3 changes: 3 additions & 0 deletions src/item_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ item_builder_build_treasure(Treasure type, double goldAmt);
Item *
item_builder_build_key(unsigned int type);

Item *
item_builder_build_potion(PotionEffect type);

void
item_builder_close(void);

Expand Down
21 changes: 17 additions & 4 deletions src/monster.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ has_collided(Monster *monster, RoomMatrix *matrix, Vector2d direction)
CombatResult result = stats_fight(&monster->stats,
&space->player->stats);

result.dmg -= space->player->effects.damage_reduction;

player_hit(space->player, result.dmg);

if (result.dmg > 0) {
Expand Down Expand Up @@ -530,7 +532,7 @@ monster_coward_walk(Monster *m, RoomMatrix *rm)
static void
on_monster_move(Monster *m, const Position *origPos, Map *map, RoomMatrix *rm)
{
Position currentTilePos = position_to_matrix_coords(&m->sprite->pos);
Position currentTilePos = position_to_matrix_coords(&m->sprite->pos);
Player *player = rm->spaces[rm->playerRoomPos.x][rm->playerRoomPos.y].player;
if (player) {
Uint32 range = 3 + player_has_artifact(player, IMPROVED_HEARING) * 2;
Expand Down Expand Up @@ -780,14 +782,14 @@ monster_update_stats_for_level(Monster *m, unsigned int level)
void
monster_drop_loot(Monster *monster, Map *map, Player *player)
{
static unsigned int treasure_drop_chance = 1;
unsigned int item_drop_chance = 1;
static Uint32 treasure_drop_chance = 1;
static Uint32 item_drop_chance = 1;
static Uint32 potion_drop_chance = 30;

if (monster->sprite->state == SPRITE_STATE_FALLING)
return;

Item *item;
Item *items[3];
unsigned int item_count = 0;
bool player_full_health = player->stats.hp >= player->stats.maxhp;

Expand Down Expand Up @@ -831,6 +833,17 @@ monster_drop_loot(Monster *monster, Map *map, Player *player)
if (player->stats.hp < player->stats.maxhp / 2)
item_drop_chance = 0;

/* TODO: This hardcoded size is a bit risky. Capacity is good but
* perhaps a dynamic array would be safer just in case? */
Item *items[4];
if (player_has_potion_effect(player, POTION_NONE) && get_random(potion_drop_chance) == 0) {
if (get_random(1) == 0)
item = item_builder_build_potion(POTION_BLOODLUST);
else
item = item_builder_build_potion(POTION_FROST);
item->sprite->pos = monsterTilePos;
items[item_count++] = item;
}
if (get_random(treasure_drop_chance) == 0) {
item = item_builder_build_item(TREASURE, map->level);
item->sprite->pos = monsterTilePos;
Expand Down
5 changes: 5 additions & 0 deletions src/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#include "object.h"
#include "gui.h"
#include "util.h"
#include "mixer.h"
#include "random.h"
Expand Down Expand Up @@ -85,6 +86,10 @@ object_damage(Object *o, Player *p)
{
if (!o->damage)
return;
if (player_has_potion_effect(p, POTION_FROST)) {
gui_log("Your frost skin protects you from damage");
return;
}
p->stats.hp -= o->damage;
player_hit(p, o->damage);
}
Expand Down
21 changes: 19 additions & 2 deletions src/player.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ on_monster_collision(Player *player,
CombatResult result = stats_fight(&player->stats,
&monster->stats);

if (player->effects.damage_multiplier > 0) {
result.dmg *= player->effects.damage_multiplier;
}

mixer_play_effect(SWING0 + get_random(2));
monster_hit(monster, result.dmg, result.critical);
animation_run(player->swordAnimation);
Expand Down Expand Up @@ -233,7 +237,7 @@ player_has_collided(Player *p, RoomSpace *space)
return !p->phase_count && space->monster && space->monster->sprite->state != SPRITE_STATE_FALLING;
}

static bool
static bool
has_collided(Player *player, RoomMatrix *matrix, Vector2d direction)
{
Position roomCoord = position_to_room_coords(&player->sprite->pos);
Expand Down Expand Up @@ -514,7 +518,7 @@ build_sword_animation(Player *p, SDL_Renderer *renderer)
p->swordAnimation->sprite->rotationPoint = (SDL_Point) { 16, 16 };
}

Player*
Player*
player_create(class_t class, Camera *cam)
{
Player *player = malloc(sizeof(Player));
Expand Down Expand Up @@ -547,6 +551,7 @@ player_create(class_t class, Camera *cam)

memset(&player->skills,
0, PLAYER_SKILL_COUNT * sizeof(Skill*));
memset(&player->effects, 0, sizeof(PlayerEffects));

for (size_t i = 0; i < LAST_ARTIFACT_EFFECT; ++i)
player->equipment.artifacts[i].level = 0;
Expand Down Expand Up @@ -602,6 +607,12 @@ player_reset_on_levelchange(Player *player)
player->sprite->pos = (Position) {
TILE_DIMENSION, TILE_DIMENSION };
player->equipment.keys = 0;

/* Reset all active potions */
memset(&player->effects, 0, sizeof(PlayerEffects));

/* Reset the player sprite */
sprite_set_color_mod(player->sprite, 255, 255, 255);
}

ExperienceData
Expand Down Expand Up @@ -823,6 +834,12 @@ player_add_artifact(Player *p, Artifact *a)
p->equipment.hasArtifacts = true;
}

bool
player_has_potion_effect(Player *p, PotionEffect effect)
{
return effect == p->effects.effect;
}

void
player_set_falling(Player *player)
{
Expand Down
16 changes: 16 additions & 0 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ typedef struct Animation Animation;
typedef enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR } class_t;
typedef enum PlayerState { ALIVE, DEAD } state_t;

typedef enum {
POTION_NONE,
POTION_FROST,
POTION_BLOODLUST
} PotionEffect;

typedef struct PlayerStatData {
unsigned int total_steps;
unsigned int steps;
Expand Down Expand Up @@ -67,6 +73,12 @@ typedef struct PlayerStateData {
bool shopOwnerKiller;
} PlayerStateData;

typedef struct PlayerEffects {
PotionEffect effect;
uint8_t damage_multiplier;
uint8_t damage_reduction;
} PlayerEffects;

typedef struct Player {
Sprite *sprite;
Stats stats;
Expand All @@ -84,6 +96,7 @@ typedef struct Player {
Animation *swordAnimation;
PlayerEquipment equipment;
PlayerStateData stateData;
PlayerEffects effects;
} Player;

Player*
Expand Down Expand Up @@ -137,5 +150,8 @@ player_has_artifact(Player *, MagicalEffect);
void
player_add_artifact(Player*, Artifact*);

bool
player_has_potion_effect(Player*, PotionEffect);

void
player_set_falling(Player*);
11 changes: 10 additions & 1 deletion src/sprite.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ sprite_create(void)
return sprite_create_default();
}

void
void
sprite_load_texture(Sprite *sprite,
const char *path,
int index,
Expand Down Expand Up @@ -116,6 +116,15 @@ sprite_set_alpha(Sprite *s, Uint8 alpha)
texture_set_alpha(s->textures[1], alpha);
}

void
sprite_set_color_mod(Sprite *s, Uint8 r, Uint8 g, Uint8 b)
{
if (s->textures[0])
texture_set_color_mod(s->textures[0], r, g, b);
if (s->textures[1])
texture_set_color_mod(s->textures[1], r, g, b);
}

void
sprite_update(Sprite *s, UpdateData *data)
{
Expand Down
2 changes: 2 additions & 0 deletions src/sprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ sprite_set_blend_mode(Sprite*, SDL_BlendMode);
void
sprite_set_alpha(Sprite*, Uint8);

void sprite_set_color_mod(Sprite*, Uint8, Uint8, Uint8);

void
sprite_destroy(Sprite *);

Expand Down
13 changes: 10 additions & 3 deletions src/texture.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,14 @@ texture_set_alpha(Texture *t, Uint8 alpha)
SDL_SetTextureAlphaMod(t->texture, alpha);
}

void
void
texture_set_color_mod(Texture *t, Uint8 r, Uint8 g, Uint8 b)
{
assert(t->texture);
SDL_SetTextureColorMod(t->texture, r, g, b);
}

void
texture_render(Texture *texture, SDL_Rect *box, Camera *cam)
{
if (!texture->texture)
Expand All @@ -255,7 +262,7 @@ texture_render(Texture *texture, SDL_Rect *box, Camera *cam)
texture_render_clip(texture, box, NULL, cam);
}

void
void
texture_render_clip(Texture *texture, SDL_Rect *box, SDL_Rect *clip, Camera *cam)
{
if (!texture->texture)
Expand All @@ -276,7 +283,7 @@ texture_render_clip(Texture *texture, SDL_Rect *box, SDL_Rect *clip, Camera *cam
texture->lastAccess = SDL_GetTicks();
}

void
void
texture_render_clip_ex(Texture *texture, SDL_Rect *box, SDL_Rect *clip, double angle, SDL_Point *point,
SDL_FlipMode flipType, Camera *cam)
{
Expand Down
3 changes: 3 additions & 0 deletions src/texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ texture_set_scale_mode(Texture*, SDL_ScaleMode);
void
texture_set_alpha(Texture*, Uint8);

void
texture_set_color_mod(Texture*, Uint8, Uint8, Uint8);

void
texture_render(Texture*, SDL_Rect*, Camera*);

Expand Down
Loading