Merge branch 'master' into feature/pits

This commit is contained in:
Linus Probert 2018-03-24 12:53:43 +01:00
commit 1206ec8a2d
11 changed files with 178 additions and 52 deletions

View File

@ -60,6 +60,10 @@
#define UNUSED(x) (void)(x)
#define UNPACK_COLOR(color) color.r, color.g, color.b, color.a
#define C_WHITE (SDL_Color) { 255, 255, 255, 255 }
#define C_BLACK (SDL_Color) { 0, 0, 0, 255 }
typedef enum Direction_t {
UP, DOWN, LEFT, RIGHT
} Direction;

View File

@ -459,6 +459,7 @@ static void
run_game(void)
{
static UpdateData updateData;
static unsigned int playerLevel = 1;
map_clear_dead_monsters(gMap, gPlayer);
map_clear_collected_items(gMap);
@ -469,6 +470,10 @@ run_game(void)
roommatrix_build_lightmap(gRoomMatrix);
populateUpdateData(&updateData, deltaTime);
if (playerLevel != gPlayer->stats.lvl) {
playerLevel = gPlayer->stats.lvl;
skillbar_check_skill_activation(gSkillBar, gPlayer);
}
gui_update_player_stats(gGui, gPlayer, gMap, gRenderer);
particle_engine_update(deltaTime);
player_update(&updateData);
@ -490,7 +495,7 @@ run_game(void)
SDL_RenderSetViewport(gRenderer, &gameViewport);
map_render(gMap, &gCamera);
particle_engine_render(&gCamera);
particle_engine_render_game(&gCamera);
if (!is_player_dead())
player_render(gPlayer, &gCamera);
@ -513,6 +518,7 @@ run_game(void)
BOTTOM_GUI_HEIGHT, &gCamera);
SDL_RenderSetViewport(gRenderer, NULL);
particle_engine_render_global(&gCamera);
if (gGameState == IN_GAME_MENU) {
SDL_Rect dimmer = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 150);

View File

@ -32,11 +32,13 @@ typedef struct Particle_t {
unsigned int movetime;
unsigned int lifetime;
bool fixed;
Uint8 blend_mode;
SDL_Color color;
} Particle;
typedef struct Engine_t {
LinkedList *particles;
LinkedList *global_particles;
LinkedList *game_particles;
} Engine;
static Engine *engine = NULL;
@ -51,6 +53,7 @@ create_particle(void)
p->movetime = 100;
p->lifetime = 100;
p->fixed = false;
p->blend_mode = SDL_BLENDMODE_MOD;
p->color = (SDL_Color) { 255, 255, 255, 255 };
return p;
}
@ -69,7 +72,8 @@ particle_engine_init(void)
fatal("Engine already initiated");
engine = ec_malloc(sizeof(Engine));
engine->particles = linkedlist_create();
engine->game_particles = linkedlist_create();
engine->global_particles = linkedlist_create();
}
void
@ -104,7 +108,7 @@ particle_engine_bloodspray(Position pos, Dimension dim, unsigned int count)
p->lifetime = lt;
p->dim = (Dimension) { w, h };
p->color = (SDL_Color) { 255, 0, 0, 255 };
linkedlist_append(&engine->particles, p);
linkedlist_append(&engine->game_particles, p);
}
}
@ -140,7 +144,7 @@ create_explosion(Position pos, Dimension dim, unsigned int c_count, ...)
p->lifetime = lt;
p->dim = (Dimension) { 2, 2 };
p->color = colors[get_random((unsigned int) c_count-1)];
linkedlist_append(&engine->particles, p);
linkedlist_append(&engine->game_particles, p);
}
free(colors);
}
@ -193,7 +197,38 @@ particle_engine_speed_lines(Position pos, Dimension dim, bool horizontal)
else
p->dim = (Dimension) { 2, 20 };
p->color = color;
linkedlist_append(&engine->particles, p);
linkedlist_append(&engine->game_particles, p);
}
}
void
particle_engine_sparkle(Position pos, Dimension dim)
{
for (unsigned int i = 0; i < 10; ++i) {
int x, y, yv, alpha;
unsigned int lt;
Particle *p;
x = get_random(dim.width) + pos.x;
y = get_random(dim.height) + pos.y;
alpha = get_random(155) + 100;
yv = (get_random(100) + 100) * -1;
lt = get_random(20);
p = create_particle();
p->pos = (Position) { x, y };
p->velocity = (Vector2d) { (float) 0, (float) yv };
p->movetime = lt;
p->lifetime = lt;
p->blend_mode = SDL_BLENDMODE_BLEND;
p->dim = (Dimension) { 2, 2 };
p->color = C_WHITE;
p->color.a = alpha;
p->fixed = true;
linkedlist_append(&engine->global_particles, p);
}
}
@ -233,7 +268,7 @@ particle_engine_wind(Vector2d direction)
p->dim = (Dimension) { w, h };
p->color = color;
p->fixed = true;
linkedlist_append(&engine->particles, p);
linkedlist_append(&engine->game_particles, p);
}
}
@ -247,40 +282,34 @@ move_particle(Particle *particle, float deltaTime)
particle->pos.y += (int) (particle->velocity.y * deltaTime);
}
void
particle_engine_update(float deltaTime)
static void
update_particles(LinkedList **particles, float deltaTime)
{
check_engine();
LinkedList *current, *last;
current = engine->particles;
last = NULL;
while (current) {
Particle *particle = current->data;
LinkedList *cleared = linkedlist_create();
while (*particles) {
Particle *particle = linkedlist_pop(particles);
if (particle->movetime)
particle->movetime--;
if (particle->lifetime > 0) {
particle->lifetime--;
move_particle(current->data, deltaTime);
last = current;
current = current->next;
move_particle(particle, deltaTime);
linkedlist_push(&cleared, particle);
} else {
if (!last) {
engine->particles = current->next;
free(current->data);
free(current);
current = engine->particles;
} else {
last->next = current->next;
free(current->data);
free(current);
current = last->next;
}
free(particle);
}
}
*particles = cleared;
}
void
particle_engine_update(float deltaTime)
{
check_engine();
update_particles(&engine->global_particles, deltaTime);
update_particles(&engine->game_particles, deltaTime);
}
static void
@ -292,8 +321,7 @@ render_particle(Particle *p, Camera *cam)
else
pos = camera_to_camera_position(cam, &p->pos);
// Make the particles look visible on all surfaces
SDL_SetRenderDrawBlendMode(cam->renderer, SDL_BLENDMODE_MOD);
SDL_SetRenderDrawBlendMode(cam->renderer, p->blend_mode);
SDL_Rect box = { pos.x, pos.y, p->dim.width, p->dim.height };
SDL_SetRenderDrawColor(cam->renderer,
@ -307,24 +335,37 @@ render_particle(Particle *p, Camera *cam)
SDL_SetRenderDrawBlendMode(cam->renderer, SDL_BLENDMODE_BLEND);
}
void
particle_engine_render(Camera *cam)
static void
render_particles(LinkedList *particles, Camera *cam)
{
check_engine();
LinkedList *particles = engine->particles;
while (particles) {
render_particle(particles->data, cam);
particles = particles->next;
LinkedList *render_list = particles;
while (render_list) {
render_particle(render_list->data, cam);
render_list = render_list->next;
}
}
void
particle_engine_render_game(Camera *cam)
{
render_particles(engine->game_particles, cam);
}
void
particle_engine_render_global(Camera *cam)
{
render_particles(engine->global_particles, cam);
}
void
particle_engine_clear(void)
{
check_engine();
while (engine->particles)
free(linkedlist_pop(&engine->particles));
while (engine->game_particles)
free(linkedlist_pop(&engine->game_particles));
}
void
@ -332,8 +373,8 @@ particle_engine_close(void)
{
check_engine();
while (engine->particles)
free(linkedlist_pop(&engine->particles));
while (engine->game_particles)
free(linkedlist_pop(&engine->game_particles));
free(engine);
engine = NULL;

View File

@ -40,6 +40,9 @@ particle_engine_eldritch_explosion(Position, Dimension);
void
particle_engine_speed_lines(Position, Dimension, bool horizontal);
void
particle_engine_sparkle(Position, Dimension);
void
particle_engine_wind(Vector2d direction);
@ -47,7 +50,10 @@ void
particle_engine_update(float deltatime);
void
particle_engine_render(Camera*);
particle_engine_render_game(Camera*);
void
particle_engine_render_global(Camera*);
void
particle_engine_clear(void);

View File

@ -271,8 +271,10 @@ check_skill_activation(Player *player, RoomMatrix *matrix, SDL_Event *event)
continue;
Skill *skill = player->skills[i];
if (skill->levelcap > player->stats.lvl)
continue;
if (skill->available && !skill->available(player))
continue;
continue;
skill->active = (selected - 1) == i && !skill->active && skill->resetCountdown == 0;
if (skill->active && skill->instantUse) {
SkillData skillData = { player, matrix, VECTOR2D_NODIR };

View File

@ -49,7 +49,7 @@ pointer_handle_event(Pointer *p, SDL_Event *event)
#ifdef DEBUG
if (event->type == SDL_MOUSEBUTTONDOWN) {
Dimension dim = { 10, 10 };
particle_engine_eldritch_explosion(p->sprite->pos, dim);
particle_engine_sparkle(p->sprite->pos, dim);
}
#endif // DEBUG
}

View File

@ -90,13 +90,15 @@ projectile_update(Projectile *p, UpdateData *data)
return;
if (space->monster) {
Uint32 dmg = stats_fight(&data->player->stats, &space->monster->stats);
Stats tmpStats = data->player->stats;
tmpStats.dmg *= 2;
Uint32 dmg = stats_fight(&tmpStats, &space->monster->stats);
if (dmg > 0) {
gui_log("Your dagger pierced %s for %u damage", space->monster->lclabel, dmg);
mixer_play_effect(SWORD_HIT);
data->player->hits += 1;
}
if (get_random(2) == 0) {
if (get_random(2) >= 1) {
Item *item = item_builder_build_item(DAGGER, 1);
item->sprite->pos = space->monster->sprite->pos;
linkedlist_append(&data->map->items, item);

View File

@ -59,6 +59,7 @@ create_default(const char *s_label, Sprite *s)
skill->active = false;
skill->available = NULL;
skill->use = NULL;
skill->levelcap = 1;
return skill;
}
@ -120,6 +121,7 @@ create_flurry(void)
s->clip = CLIP32(0, 0);
s->fixed = true;
Skill *skill = create_default("Flurry", s);
skill->levelcap = 2;
skill->use = skill_use_flurry;
return skill;
}
@ -169,6 +171,7 @@ create_throw_dagger(void)
s->clip = CLIP32(64, 0);
s->fixed = true;
Skill *skill = create_default("Throw dagger", s);
skill->levelcap = 1;
skill->instantUse = false;
skill->resetTime = 1;
skill->available = skill_throw_dagger_available;
@ -201,6 +204,7 @@ create_sip_health(void)
s->clip = CLIP16(0, 0);
s->fixed = true;
Skill *skill = create_default("Sip health", s);
skill->levelcap = 1;
skill->instantUse = true;
skill->available = skill_sip_health_available;
skill->use = skill_sip_health;
@ -297,6 +301,7 @@ create_charge(void)
s->clip = CLIP32(32, 0);
s->fixed = true;
Skill *skill = create_default("Charge", s);
skill->levelcap = 4;
skill->use = skill_charge;
return skill;
}

View File

@ -45,6 +45,7 @@ typedef struct Skill_t {
Sprite *icon;
unsigned int resetTime;
unsigned int resetCountdown;
unsigned int levelcap;
bool actionRequired;
bool instantUse;
bool active;

View File

@ -24,6 +24,7 @@
#include "sprite.h"
#include "keyboard.h"
#include "texturecache.h"
#include "particle_engine.h"
static void
load_texture(SkillBar *bar, const char *path, SDL_Renderer *renderer)
@ -66,12 +67,27 @@ skillbar_create(SDL_Renderer *renderer)
SkillBar *bar = ec_malloc(sizeof(SkillBar));
bar->sprites = linkedlist_create();
bar->activationTimer = timer_create();
bar->skillSparkleTimer = timer_create();
bar->lastActivation = 0;
load_texture(bar, "GUI/GUI0.png", renderer);
load_countdown_sprites(bar);
return bar;
}
void
skillbar_check_skill_activation(SkillBar *bar, Player *player)
{
for (int i = 0; i < PLAYER_SKILL_COUNT; ++i) {
if (!player->skills[i])
continue;
if (player->skills[i]->levelcap != player->stats.lvl)
continue;
timer_start(bar->skillSparkleTimer);
}
}
static void
render_frame(Camera *cam)
{
@ -169,21 +185,58 @@ render_skill_unavailable(SkillBar *bar, Player *player, Camera *cam)
static SDL_Rect unavailableSkillBox = { 0, 0, 32, 32 };
for (int i = 0; i < PLAYER_SKILL_COUNT; ++i) {
bool unavailable = false;
SDL_Color color;
if (!player->skills[i])
continue;
Skill *skill = player->skills[i];
if (skill->resetCountdown || (skill->available && !skill->available(player))) {
if (skill->levelcap > player->stats.lvl) {
unavailable = true;
color = (SDL_Color) { 0, 0, 0, 220 };
} else if (skill->resetCountdown
|| (skill->available && !skill->available(player)))
{
unavailable = true;
color = (SDL_Color) { 255, 0, 0, 70 };
}
if (unavailable) {
unavailableSkillBox.x = i * 32;
SDL_SetRenderDrawColor(cam->renderer, 255, 0, 0, 70);
SDL_SetRenderDrawColor(cam->renderer, UNPACK_COLOR(color));
SDL_RenderFillRect(cam->renderer, &unavailableSkillBox);
if (skill->resetCountdown) {
render_skill_countdown(bar, i, skill->resetCountdown, cam);
render_skill_countdown(bar,
i,
skill->resetCountdown,
cam);
}
}
}
}
static void
render_skill_sparkles(SkillBar *bar, Player *player)
{
if (timer_get_ticks(bar->skillSparkleTimer) > 1500) {
timer_stop(bar->skillSparkleTimer);
return;
}
Position pos = { 0, GAME_VIEW_HEIGHT };
Dimension dim = { 32, 32 };
for (int i = 0; i < PLAYER_SKILL_COUNT; ++i) {
if (!player->skills[i])
continue;
else if (player->skills[i]->levelcap != player->stats.lvl)
continue;
pos.x += 32 * i;
particle_engine_sparkle(pos, dim);
}
}
void
skillbar_render(SkillBar *bar, Player *player, Camera *cam)
{
@ -192,6 +245,8 @@ skillbar_render(SkillBar *bar, Player *player, Camera *cam)
render_sprites(bar, cam);
render_skill_unavailable(bar, player, cam);
render_activation_indicator(bar, cam);
if (timer_started(bar->skillSparkleTimer))
render_skill_sparkles(bar, player);
}
void

View File

@ -29,12 +29,16 @@ typedef struct SkillBar_t {
LinkedList *sprites;
Sprite *countdowns[PLAYER_SKILL_COUNT];
Timer *activationTimer;
Timer *skillSparkleTimer;
unsigned int lastActivation;
} SkillBar;
SkillBar *
skillbar_create(SDL_Renderer*);
void
skillbar_check_skill_activation(SkillBar*, Player*);
void
skillbar_render(SkillBar*, Player*, Camera*);