2017-12-19 19:42:05 +01:00
|
|
|
#include <stdio.h>
|
2017-12-19 21:00:02 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2017-11-30 21:00:47 +01:00
|
|
|
#include "player.h"
|
2017-12-15 08:08:45 +01:00
|
|
|
#include "monster.h"
|
2017-12-19 21:00:02 +01:00
|
|
|
#include "util.h"
|
2018-01-23 14:11:03 +01:00
|
|
|
#include "gui.h"
|
2018-01-24 21:14:34 +01:00
|
|
|
#include "item.h"
|
2017-11-30 21:00:47 +01:00
|
|
|
|
2017-12-22 15:15:40 +01:00
|
|
|
#define ENGINEER_STATS { 12, 12, 5, 7, 2, 1, 1 }
|
|
|
|
#define MAGE_STATS { 12, 12, 5, 7, 2, 1, 1 }
|
|
|
|
#define PALADIN_STATS { 12, 12, 5, 7, 2, 1, 1 }
|
|
|
|
#define ROGUE_STATS { 12, 12, 5, 7, 2, 2, 1 }
|
|
|
|
#define WARRIOR_STATS { 12, 12, 5, 7, 2, 1, 1 }
|
2017-12-12 11:20:08 +01:00
|
|
|
|
|
|
|
static bool
|
2017-12-15 08:08:45 +01:00
|
|
|
has_collided(Player *player, RoomMatrix *matrix)
|
2017-12-05 15:03:20 +01:00
|
|
|
{
|
2017-12-15 08:08:45 +01:00
|
|
|
bool collided = false;
|
|
|
|
|
|
|
|
Position roomCoord = position_to_room_coords(&player->sprite->pos);
|
2018-01-25 10:45:05 +01:00
|
|
|
if (roomCoord.x != matrix->roomPos.x
|
|
|
|
|| roomCoord.y != matrix->roomPos.y) {
|
2017-12-15 08:08:45 +01:00
|
|
|
return collided;
|
|
|
|
}
|
|
|
|
|
|
|
|
Position matrixPos = position_to_matrix_coords(&player->sprite->pos);
|
|
|
|
RoomSpace *space = &matrix->spaces[matrixPos.x][matrixPos.y];
|
|
|
|
collided = space->occupied;
|
|
|
|
|
|
|
|
if (space->monster != NULL) {
|
2017-12-15 15:03:29 +01:00
|
|
|
unsigned int hit = stats_fight(&player->stats,
|
|
|
|
&space->monster->stats);
|
2017-12-18 12:12:24 +01:00
|
|
|
monster_hit(space->monster, hit);
|
2017-12-17 13:43:41 +01:00
|
|
|
|
2017-12-21 08:31:25 +01:00
|
|
|
if (hit > 0)
|
|
|
|
player->hits += 1;
|
|
|
|
else
|
|
|
|
player->misses += 1;
|
|
|
|
|
2018-01-23 22:54:02 +01:00
|
|
|
if (hit > 0)
|
2018-01-25 10:45:05 +01:00
|
|
|
gui_log("You hit %s for %u damage",
|
|
|
|
space->monster->lclabel, hit);
|
2018-01-23 22:54:02 +01:00
|
|
|
else
|
2018-01-25 10:45:05 +01:00
|
|
|
gui_log("You missed %s", space->monster->lclabel);
|
2018-01-23 14:11:03 +01:00
|
|
|
|
2017-12-17 13:43:41 +01:00
|
|
|
if (space->monster->stats.hp <= 0) {
|
|
|
|
// TODO(Linus): This needs some love later on.
|
2017-12-21 08:31:25 +01:00
|
|
|
player->kills += 1;
|
2017-12-17 13:43:41 +01:00
|
|
|
player->xp += 10;
|
2018-01-23 14:11:03 +01:00
|
|
|
|
2018-01-25 10:45:05 +01:00
|
|
|
gui_log("You killed %s and gained %d xp",
|
|
|
|
space->monster->lclabel, 10);
|
2017-12-17 13:43:41 +01:00
|
|
|
}
|
2018-01-24 06:41:37 +01:00
|
|
|
} else if (collided) {
|
|
|
|
gui_log("Ouch! There is something in the way");
|
2017-12-06 11:44:17 +01:00
|
|
|
}
|
|
|
|
|
2018-01-24 21:14:34 +01:00
|
|
|
if (space->item != NULL) {
|
|
|
|
if (space->item->effect)
|
|
|
|
space->item->effect(space->item, player);
|
|
|
|
space->item->collected = true;
|
|
|
|
}
|
|
|
|
|
2017-12-15 08:08:45 +01:00
|
|
|
return collided;
|
2017-12-05 15:03:20 +01:00
|
|
|
}
|
|
|
|
|
2017-12-17 13:43:41 +01:00
|
|
|
static void
|
2017-12-19 21:00:02 +01:00
|
|
|
player_step(Player *p)
|
2017-12-17 13:43:41 +01:00
|
|
|
{
|
|
|
|
p->total_steps++;
|
|
|
|
p->steps++;
|
2017-12-18 15:26:56 +01:00
|
|
|
p->missText->pos = p->sprite->pos;
|
|
|
|
p->hitText->pos = p->sprite->pos;
|
2017-12-17 13:43:41 +01:00
|
|
|
}
|
|
|
|
|
2017-12-12 11:20:08 +01:00
|
|
|
static void
|
2017-12-15 08:08:45 +01:00
|
|
|
move_left(Player *player, RoomMatrix *matrix)
|
2017-12-05 15:03:20 +01:00
|
|
|
{
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->clip.y = 16;
|
|
|
|
player->sprite->pos.x -= TILE_DIMENSION;
|
2017-12-17 13:43:41 +01:00
|
|
|
if (has_collided(player, matrix)) {
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->pos.x += TILE_DIMENSION;
|
2017-12-17 13:43:41 +01:00
|
|
|
}
|
2017-12-19 21:00:02 +01:00
|
|
|
player_step(player);
|
2017-12-05 15:03:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
2017-12-15 08:08:45 +01:00
|
|
|
void move_right(Player *player, RoomMatrix *matrix)
|
2017-12-05 15:03:20 +01:00
|
|
|
{
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->clip.y = 32;
|
|
|
|
player->sprite->pos.x += TILE_DIMENSION;
|
2017-12-17 13:43:41 +01:00
|
|
|
if (has_collided(player, matrix)) {
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->pos.x -= TILE_DIMENSION;
|
2017-12-17 13:43:41 +01:00
|
|
|
}
|
2017-12-19 21:00:02 +01:00
|
|
|
player_step(player);
|
2017-12-05 15:03:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
2017-12-15 08:08:45 +01:00
|
|
|
void move_up(Player *player, RoomMatrix *matrix)
|
2017-12-05 15:03:20 +01:00
|
|
|
{
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->clip.y = 48;
|
|
|
|
player->sprite->pos.y -= TILE_DIMENSION;
|
2017-12-17 13:43:41 +01:00
|
|
|
if (has_collided(player, matrix)) {
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->pos.y += TILE_DIMENSION;
|
2017-12-17 13:43:41 +01:00
|
|
|
}
|
2017-12-19 21:00:02 +01:00
|
|
|
player_step(player);
|
2017-12-05 15:03:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
2017-12-15 08:08:45 +01:00
|
|
|
void move_down(Player *player, RoomMatrix *matrix)
|
2017-12-05 15:03:20 +01:00
|
|
|
{
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->clip.y = 0;
|
|
|
|
player->sprite->pos.y += TILE_DIMENSION;
|
2017-12-17 13:43:41 +01:00
|
|
|
if (has_collided(player, matrix)) {
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->pos.y -= TILE_DIMENSION;
|
2017-12-17 13:43:41 +01:00
|
|
|
}
|
2017-12-19 21:00:02 +01:00
|
|
|
player_step(player);
|
2017-12-05 15:03:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
2017-12-15 08:08:45 +01:00
|
|
|
void handle_player_input(Player *player, RoomMatrix *matrix, SDL_Event *event)
|
2017-11-30 21:00:47 +01:00
|
|
|
{
|
|
|
|
static unsigned int step = 1;
|
|
|
|
|
|
|
|
if (event->type == SDL_KEYDOWN) {
|
|
|
|
switch (event->key.keysym.sym) {
|
2017-12-05 15:03:20 +01:00
|
|
|
case SDLK_LEFT:
|
2017-12-13 23:20:54 +01:00
|
|
|
case SDLK_h:
|
2017-12-15 08:08:45 +01:00
|
|
|
move_left(player, matrix);
|
2017-12-05 15:03:20 +01:00
|
|
|
break;
|
|
|
|
case SDLK_RIGHT:
|
2017-12-13 23:20:54 +01:00
|
|
|
case SDLK_l:
|
2017-12-15 08:08:45 +01:00
|
|
|
move_right(player, matrix);
|
2017-12-05 15:03:20 +01:00
|
|
|
break;
|
|
|
|
case SDLK_UP:
|
2017-12-13 23:20:54 +01:00
|
|
|
case SDLK_k:
|
2017-12-15 08:08:45 +01:00
|
|
|
move_up(player, matrix);
|
2017-12-05 15:03:20 +01:00
|
|
|
break;
|
|
|
|
case SDLK_DOWN:
|
2017-12-13 23:20:54 +01:00
|
|
|
case SDLK_j:
|
2017-12-15 08:08:45 +01:00
|
|
|
move_down(player, matrix);
|
2017-12-05 15:03:20 +01:00
|
|
|
break;
|
2017-11-30 21:00:47 +01:00
|
|
|
}
|
2017-12-15 08:08:45 +01:00
|
|
|
player->sprite->clip.x = 16*step;
|
2017-11-30 21:00:47 +01:00
|
|
|
if (step == 3)
|
|
|
|
step = 0;
|
|
|
|
else
|
|
|
|
++step;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-18 15:26:56 +01:00
|
|
|
static void
|
|
|
|
player_load_texts(Player *p, SDL_Renderer *renderer)
|
|
|
|
{
|
|
|
|
ActionText *t = actiontext_create();
|
|
|
|
actiontext_load_font(t, "assets/GUI/SDS_6x6.ttf", 14);
|
2017-12-19 21:00:02 +01:00
|
|
|
t->color = (SDL_Color) { 255, 100, 0, 255 };
|
2017-12-18 15:26:56 +01:00
|
|
|
actiontext_set_text(t, "HIT", renderer);
|
|
|
|
t->pos = p->sprite->pos;
|
|
|
|
p->hitText = t;
|
|
|
|
|
|
|
|
t = actiontext_create();
|
|
|
|
actiontext_load_font(t, "assets/GUI/SDS_6x6.ttf", 14);
|
2017-12-19 21:00:02 +01:00
|
|
|
t->color = (SDL_Color) { 255, 255, 0, 255 };
|
2017-12-18 15:26:56 +01:00
|
|
|
actiontext_set_text(t, "MISS", renderer);
|
|
|
|
t->pos = p->sprite->pos;
|
|
|
|
p->missText = t;
|
|
|
|
}
|
|
|
|
|
2017-12-12 11:20:08 +01:00
|
|
|
Player*
|
|
|
|
player_create(class_t class, SDL_Renderer *renderer)
|
2017-11-30 21:00:47 +01:00
|
|
|
{
|
2017-12-12 11:20:08 +01:00
|
|
|
Player *player = malloc(sizeof(Player));
|
|
|
|
player->sprite = sprite_create();
|
2017-12-21 08:31:25 +01:00
|
|
|
player->total_steps = 0;
|
|
|
|
player->steps = 0;
|
|
|
|
player->xp = 0;
|
|
|
|
player->hits = 0;
|
|
|
|
player->kills = 0;
|
|
|
|
player->misses = 0;
|
2018-01-25 10:45:05 +01:00
|
|
|
player->gold = 0;
|
2017-11-30 21:00:47 +01:00
|
|
|
|
2017-12-12 11:20:08 +01:00
|
|
|
char asset[100];
|
2017-11-30 21:00:47 +01:00
|
|
|
switch (class) {
|
|
|
|
case ENGINEER:
|
2017-12-19 22:51:00 +01:00
|
|
|
m_strcpy(asset, 100, "assets/Commissions/Engineer.png");
|
2017-12-19 19:42:05 +01:00
|
|
|
player->stats = (Stats) ENGINEER_STATS;
|
2017-11-30 21:00:47 +01:00
|
|
|
break;
|
|
|
|
case MAGE:
|
2017-12-19 22:51:00 +01:00
|
|
|
m_strcpy(asset, 100, "assets/Commissions/Mage.png");
|
2017-12-19 19:42:05 +01:00
|
|
|
player->stats = (Stats) MAGE_STATS;
|
2017-11-30 21:00:47 +01:00
|
|
|
break;
|
|
|
|
case PALADIN:
|
2017-12-19 22:51:00 +01:00
|
|
|
m_strcpy(asset, 100, "assets/Commissions/Paladin.png");
|
2017-12-19 19:42:05 +01:00
|
|
|
player->stats = (Stats) PALADIN_STATS;
|
2017-11-30 21:00:47 +01:00
|
|
|
break;
|
|
|
|
case ROGUE:
|
2017-12-19 22:51:00 +01:00
|
|
|
m_strcpy(asset, 100, "assets/Commissions/Rogue.png");
|
2017-12-19 19:42:05 +01:00
|
|
|
player->stats = (Stats) ROGUE_STATS;
|
2017-11-30 21:00:47 +01:00
|
|
|
break;
|
|
|
|
case WARRIOR:
|
2017-12-19 22:51:00 +01:00
|
|
|
m_strcpy(asset, 100, "assets/Commissions/Warrior.png");
|
2017-12-19 19:42:05 +01:00
|
|
|
player->stats = (Stats) WARRIOR_STATS;
|
2017-11-30 21:00:47 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-12-12 11:20:08 +01:00
|
|
|
sprite_load_texture(player->sprite, asset, 0, renderer);
|
|
|
|
player->sprite->pos = (Position) { TILE_DIMENSION, TILE_DIMENSION };
|
2017-12-14 12:01:05 +01:00
|
|
|
player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 };
|
2017-12-12 11:20:08 +01:00
|
|
|
player->sprite->textures[0]->dim = (Dimension) {
|
|
|
|
TILE_DIMENSION, TILE_DIMENSION };
|
2017-12-15 08:08:45 +01:00
|
|
|
player->handle_event = &handle_player_input;
|
2017-11-30 21:00:47 +01:00
|
|
|
|
2017-12-18 15:26:56 +01:00
|
|
|
player_load_texts(player, renderer);
|
|
|
|
|
2017-11-30 21:00:47 +01:00
|
|
|
return player;
|
|
|
|
}
|
2017-12-12 11:20:08 +01:00
|
|
|
|
2017-12-17 13:43:41 +01:00
|
|
|
void
|
2017-12-18 15:26:56 +01:00
|
|
|
player_hit(Player *p, unsigned int dmg)
|
|
|
|
{
|
|
|
|
if (dmg > 0) {
|
|
|
|
p->hitText->active = true;
|
|
|
|
p->missText->active = false;
|
|
|
|
} else {
|
|
|
|
p->missText->active = true;
|
|
|
|
p->hitText->active = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
player_render(Player *player, Camera *cam)
|
|
|
|
{
|
|
|
|
sprite_render(player->sprite, cam);
|
|
|
|
actiontext_render(player->hitText, cam);
|
|
|
|
actiontext_render(player->missText, cam);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-12-17 13:43:41 +01:00
|
|
|
player_print(Player *p)
|
|
|
|
{
|
|
|
|
Position roomPos = position_to_matrix_coords(&p->sprite->pos);
|
|
|
|
Position pos = p->sprite->pos;
|
|
|
|
|
2018-01-23 22:54:02 +01:00
|
|
|
debug("\n");
|
|
|
|
debug("--------=== <[ Player Stats ]> ===--------");
|
|
|
|
debug("HP: %d", p->stats.hp);
|
|
|
|
debug("Level: %u\tXP:\t%u", p->stats.lvl, p->xp);
|
2018-01-25 10:45:05 +01:00
|
|
|
debug("Gold: %.2f", p->gold);
|
2018-01-23 22:54:02 +01:00
|
|
|
debug("Hits: %u\tMisses:\t%u", p->hits, p->misses);
|
|
|
|
debug("Kills: %u", p->kills);
|
|
|
|
debug("Steps: %u", p->total_steps);
|
|
|
|
debug("Pos: %dx%d\tRoomPos: %dx%d", pos.x, pos.y,
|
2017-12-21 08:31:25 +01:00
|
|
|
roomPos.x, roomPos.y);
|
2018-01-23 22:54:02 +01:00
|
|
|
debug("------------------------------------------");
|
2017-12-17 13:43:41 +01:00
|
|
|
}
|
|
|
|
|
2017-12-18 15:26:56 +01:00
|
|
|
void
|
|
|
|
player_reset_steps(Player *p)
|
|
|
|
{
|
|
|
|
p->steps = 0;
|
|
|
|
player_print(p);
|
|
|
|
}
|
|
|
|
|
2017-12-12 11:20:08 +01:00
|
|
|
void
|
|
|
|
player_destroy(Player *player)
|
|
|
|
{
|
|
|
|
if (player->sprite)
|
|
|
|
sprite_destroy(player->sprite);
|
2017-12-18 15:26:56 +01:00
|
|
|
actiontext_destroy(player->hitText);
|
|
|
|
actiontext_destroy(player->missText);
|
2017-12-12 11:20:08 +01:00
|
|
|
|
|
|
|
free(player);
|
|
|
|
}
|