Added dagger throw skill

There are still some quirks that could need some love surrounding this
skill. Check the reset countdown for example.
This commit is contained in:
Linus Probert 2018-03-10 22:04:03 +01:00
parent 63f7ccd6b3
commit c360aa75ee
10 changed files with 143 additions and 12 deletions

View File

@ -50,7 +50,8 @@
/* Quality of life stuff */ /* Quality of life stuff */
#define DEFAULT_DIMENSION (Dimension) { 16, 16 } #define DEFAULT_DIMENSION (Dimension) { 16, 16 }
#define GAME_DIMENSION (Dimension) { TILE_DIMENSION, TILE_DIMENSION } #define GAME_DIMENSION (Dimension) { TILE_DIMENSION, TILE_DIMENSION }
#define CLIP16(x, y) (SDL_Rect) { x, y, 16, 16 } #define CLIP16(x, y) (SDL_Rect) { x, y, 16, 16 }
#define CLIP32(x, y) (SDL_Rect) { x, y, 32, 32 }
/* Windows and compile crap */ /* Windows and compile crap */
#ifdef _WIN32 #ifdef _WIN32

View File

@ -461,7 +461,7 @@ run_game(void)
gui_update_player_stats(gGui, gPlayer, gMap, gRenderer); gui_update_player_stats(gGui, gPlayer, gMap, gRenderer);
particle_engine_update(deltaTime); particle_engine_update(deltaTime);
player_update(gPlayer, deltaTime); player_update(gPlayer, gRoomMatrix, deltaTime);
roommatrix_update_with_player(gRoomMatrix, gPlayer); roommatrix_update_with_player(gRoomMatrix, gPlayer);
if (currentTurn == PLAYER) { if (currentTurn == PLAYER) {

View File

@ -31,6 +31,7 @@
#include "random.h" #include "random.h"
#include "projectile.h" #include "projectile.h"
#include "texturecache.h" #include "texturecache.h"
#include "vector2d.h"
#define ENGINEER_STATS { 12, 12, 5, 7, 2, 2, 1 } #define ENGINEER_STATS { 12, 12, 5, 7, 2, 2, 1 }
#define MAGE_STATS { 12, 12, 5, 7, 1, 2, 1 } #define MAGE_STATS { 12, 12, 5, 7, 1, 2, 1 }
@ -402,6 +403,7 @@ player_create(class_t class, SDL_Renderer *renderer)
player->stats = (Stats) WARRIOR_STATS; player->stats = (Stats) WARRIOR_STATS;
player->skills[0] = skill_create(FLURRY); player->skills[0] = skill_create(FLURRY);
player->skills[1] = skill_create(CHARGE); player->skills[1] = skill_create(CHARGE);
player->skills[2] = skill_create(DAGGER_THROW);
break; break;
} }
@ -502,7 +504,7 @@ player_reset_steps(Player *p)
player_print(p); player_print(p);
} }
void player_update(Player *player, float deltatime) void player_update(Player *player, RoomMatrix *rm, float deltatime)
{ {
if (!player->projectiles) if (!player->projectiles)
return; return;
@ -514,7 +516,7 @@ void player_update(Player *player, float deltatime)
while (current) { while (current) {
Projectile *p = current->data; Projectile *p = current->data;
projectile_update(p, deltatime); projectile_update(p, player, rm, deltatime);
if (!p->alive) { if (!p->alive) {
if (last == NULL) if (last == NULL)
player->projectiles = current->next; player->projectiles = current->next;
@ -528,6 +530,7 @@ void player_update(Player *player, float deltatime)
current->next = NULL; current->next = NULL;
linkedlist_destroy(&current); linkedlist_destroy(&current);
current = next; current = next;
action_spent(player);
} else { } else {
last = current; last = current;
current = current->next; current = current->next;

View File

@ -77,7 +77,7 @@ void
player_reset_steps(Player*); player_reset_steps(Player*);
void void
player_update(Player*, float deltatime); player_update(Player*, RoomMatrix*, float deltatime);
void void
player_render(Player*, Camera*); player_render(Player*, Camera*);

View File

@ -1,5 +1,52 @@
/*
* BreakHack - A dungeone crawler RPG
* Copyright (C) 2018 Linus Probert <linus.probert@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "projectile.h" #include "projectile.h"
#include "util.h" #include "util.h"
#include "texturecache.h"
#include "player.h"
#include "monster.h"
#include "mixer.h"
static void
onDaggerRender(Sprite *s)
{
if (!timer_started(s->renderTimer))
timer_start(s->renderTimer);
if (timer_get_ticks(s->renderTimer) > 100) {
timer_start(s->renderTimer);
s->clip.x += 16;
s->clip.x = s->clip.x % 64;
}
}
Projectile *
projectile_dagger_create(void)
{
Projectile *p = projectile_create();
sprite_set_texture(p->sprite, texturecache_add("Extras/Dagger.png"), 0);
p->sprite->onRender = onDaggerRender;
p->sprite->animate = false;
p->sprite->clip = CLIP16(0, 0);
p->sprite->dim = (Dimension) { 32, 32 };
return p;
}
Projectile * Projectile *
projectile_create(void) projectile_create(void)
@ -9,23 +56,47 @@ projectile_create(void)
p->velocity = VECTOR2D_NODIR; p->velocity = VECTOR2D_NODIR;
p->alive = true; p->alive = true;
p->lifetime = timer_create(); p->lifetime = timer_create();
p->onRender = NULL;
timer_start(p->lifetime); timer_start(p->lifetime);
return p; return p;
} }
void void
projectile_update(Projectile *p, float deltatime) projectile_update(Projectile *p, Player *player, RoomMatrix *rm, float deltatime)
{ {
p->sprite->pos.x += (int) (p->velocity.x * deltatime); p->sprite->pos.x += (int) (p->velocity.x * deltatime);
p->sprite->pos.y += (int) (p->velocity.y * deltatime); p->sprite->pos.y += (int) (p->velocity.y * deltatime);
if (timer_get_ticks(p->lifetime) > 2000) if (timer_get_ticks(p->lifetime) > 2000)
p->alive = false; p->alive = false;
Position collisionPos = p->sprite->pos;
if (p->velocity.x > 0)
collisionPos.x += TILE_DIMENSION;
else if(p->velocity.y > 0)
collisionPos.y += TILE_DIMENSION;
Position roomPos = position_to_matrix_coords(&collisionPos);
RoomSpace *space = &rm->spaces[roomPos.x][roomPos.y];
if (!space->occupied)
return;
if (space->player)
return;
if (space->monster) {
Uint32 dmg = stats_fight(&player->stats, &space->monster->stats);
monster_hit(space->monster, dmg);
mixer_play_effect(SWORD_HIT);
}
p->alive = false;
} }
void void
projectile_render(Projectile *p, Camera *cam) projectile_render(Projectile *p, Camera *cam)
{ {
if (p->onRender)
p->onRender(p);
sprite_render(p->sprite, cam); sprite_render(p->sprite, cam);
} }

View File

@ -24,19 +24,28 @@
#include "camera.h" #include "camera.h"
#include "vector2d.h" #include "vector2d.h"
#include "timer.h" #include "timer.h"
#include "roommatrix.h"
typedef struct Prjectile_t { // Forward declare
struct Player_t;
typedef struct Projectile_t {
Sprite *sprite; Sprite *sprite;
Vector2d velocity; Vector2d velocity;
Timer *lifetime; Timer *lifetime;
bool alive; bool alive;
Timer *animation_timer;
void (*onRender)(struct Projectile_t*);
} Projectile; } Projectile;
Projectile *
projectile_dagger_create(void);
Projectile * Projectile *
projectile_create(void); projectile_create(void);
void void
projectile_update(Projectile*, float deltatime); projectile_update(Projectile*, struct Player_t*, RoomMatrix *rm, float deltatime);
void void
projectile_render(Projectile*, Camera*); projectile_render(Projectile*, Camera*);

View File

@ -29,6 +29,8 @@
#include "gui.h" #include "gui.h"
#include "random.h" #include "random.h"
#include "particle_engine.h" #include "particle_engine.h"
#include "projectile.h"
#include "linkedlist.h"
static void static void
set_player_clip_for_direction(Player *player, Vector2d *direction) set_player_clip_for_direction(Player *player, Vector2d *direction)
@ -120,6 +122,44 @@ create_flurry(void)
return skill; return skill;
} }
static bool
skill_throw_dagger(Skill *skill, SkillData *data)
{
UNUSED(skill);
UNUSED(data);
Projectile *p = projectile_dagger_create();
if (vector2d_equals(VECTOR2D_UP, data->direction))
p->velocity = (Vector2d) { 0, -300 };
else if (vector2d_equals(VECTOR2D_DOWN, data->direction))
p->velocity = (Vector2d) { 0, 300 };
else if (vector2d_equals(VECTOR2D_RIGHT, data->direction))
p->velocity = (Vector2d) { 300, 0 };
else
p->velocity = (Vector2d) { -300, 0 };
p->sprite->pos = data->player->sprite->pos;
linkedlist_append(&data->player->projectiles, p);
return true;
}
static Skill *
create_throw_dagger(void)
{
Texture *t = texturecache_add("Extras/Dagger.png");
Sprite *s = sprite_create();
sprite_set_texture(s, t, 0);
s->dim = DEFAULT_DIMENSION;
s->clip = CLIP16(0, 0);
s->fixed = true;
Skill *skill = create_default("Throw dagger", s);
skill->instantUse = false;
skill->use = skill_throw_dagger;
skill->actionRequired = false;
return skill;
}
static bool static bool
skill_sip_health(Skill *skill, SkillData *data) skill_sip_health(Skill *skill, SkillData *data)
{ {
@ -238,6 +278,8 @@ skill_create(enum SkillType t)
return create_sip_health(); return create_sip_health();
case CHARGE: case CHARGE:
return create_charge(); return create_charge();
case DAGGER_THROW:
return create_throw_dagger();
default: default:
fatal("Unknown SkillType %u", (unsigned int) t); fatal("Unknown SkillType %u", (unsigned int) t);
return NULL; return NULL;

View File

@ -30,6 +30,7 @@ struct Player_t;
enum SkillType { enum SkillType {
FLURRY, FLURRY,
CHARGE, CHARGE,
DAGGER_THROW,
SIP_HEALTH SIP_HEALTH
}; };

View File

@ -35,6 +35,7 @@ sprite_create_default(void)
s->fixed = false; s->fixed = false;
s->animate = true; s->animate = true;
s->hidden = false; s->hidden = false;
s->onRender = NULL;
return s; return s;
} }
@ -90,11 +91,13 @@ sprite_set_texture(Sprite *s, Texture *t, int index)
s->textures[index] = t; s->textures[index] = t;
} }
void sprite_render(Sprite *s, Camera *cam) void
sprite_render(Sprite *s, Camera *cam)
{ {
if (s->hidden) if (s->hidden)
return; return;
if (s->onRender)
s->onRender(s);
if (s->textures[1] && s->animate) { if (s->textures[1] && s->animate) {
if (!timer_started(s->renderTimer)) if (!timer_started(s->renderTimer))
timer_start(s->renderTimer); timer_start(s->renderTimer);

View File

@ -38,6 +38,7 @@ typedef struct Sprite_t {
bool fixed; bool fixed;
bool animate; bool animate;
bool hidden; bool hidden;
void (*onRender)(Sprite*);
} Sprite; } Sprite;
Sprite* sprite_create(void); Sprite* sprite_create(void);