diff --git a/CMakeLists.txt b/CMakeLists.txt index 8929d39..42d2918 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(breakhack src/roommatrix src/position src/monster + src/stats ) target_link_libraries(breakhack diff --git a/TODO.txt b/TODO.txt index a538234..c884a07 100644 --- a/TODO.txt +++ b/TODO.txt @@ -5,7 +5,8 @@ x Add enemies (generated through lua) x Lua bindings for creation x Making some better generation and randomeness x Move "clip" from texture to sprite -o Hitting enemies +x Hitting enemies +- Nicer enemy hits (Text textures, healthbars?) - Moving enemies - Lower levels - XP diff --git a/linkedlist/linkedlist.c b/linkedlist/linkedlist.c index 9166d7f..9e07039 100644 --- a/linkedlist/linkedlist.c +++ b/linkedlist/linkedlist.c @@ -120,8 +120,10 @@ void linkedlist_destroy(LinkedList **head) linkedlist_destroy(&(*head)->next); - free((*head)->data); - (*head)->data = NULL; + if ((*head)->data != NULL) { + free((*head)->data); + (*head)->data = NULL; + } free(*head); *head = NULL; } diff --git a/src/main.c b/src/main.c index e6f3c15..52ef5d3 100644 --- a/src/main.c +++ b/src/main.c @@ -30,9 +30,9 @@ bool initSDL() //Dimension dim = (Dimension) { 1920, 1080 }; double scale = 1.0; - if (dim.height > 1080) { + if (dim.height > 768) { printf("[**] Hi resolution screen detected (%u x %u)\n", dim.width, dim.height); - scale = ((double) dim.height)/1080; + scale = ((double) dim.height)/768; printf("[**] Scaling by %f\n", scale); } @@ -115,9 +115,9 @@ bool handle_events() if (event.type == SDL_QUIT) { quit = true; } else { - gPlayer->sprite->handle_event(gPlayer->sprite, - gRoomMatrix, - &event); + gPlayer->handle_event(gPlayer, + gRoomMatrix, + &event); camera_follow_position(&gCamera, &gPlayer->sprite->pos); map_set_current_room(gMap, &gPlayer->sprite->pos); } @@ -136,6 +136,7 @@ void run() timer_start(fpsTimer); quit = handle_events(); + map_clear_dead_monsters(gMap); roommatrix_populate_from_map(gRoomMatrix, gMap); roommatrix_add_lightsource(gRoomMatrix, &gPlayer->sprite->pos); diff --git a/src/map.c b/src/map.c index 04d38c2..3516921 100644 --- a/src/map.c +++ b/src/map.c @@ -75,6 +75,34 @@ map_add_monster_texture(Map *map, const char *path, SDL_Renderer *renderer) return t; } +void +map_clear_dead_monsters(Map *map) +{ + LinkedList *last, *current, *next; + + last = NULL; + current = map->monsters; + + while (current != NULL) { + if (((Monster*) current->data)->stats.hp <= 0) { + if (last == NULL) + map->monsters = current->next; + else + last->next = current->next; + + monster_destroy(current->data); + current->data = NULL; + next = current->next; + current->next = NULL; + linkedlist_destroy(¤t); + current = next; + continue; + } + last = current; + current = current->next; + } +} + void map_add_monster(Map *map, Monster *m) { diff --git a/src/map.h b/src/map.h index 4f70743..14c80f5 100644 --- a/src/map.h +++ b/src/map.h @@ -48,6 +48,8 @@ void map_add_decoration(Map *map, Position *tile_pos, MapTile*); Texture* map_add_monster_texture(Map*, const char *path, SDL_Renderer*); +void map_clear_dead_monsters(Map*); + void map_add_monster(Map*, Monster*); void map_render(Map*, Camera*); diff --git a/src/monster.c b/src/monster.c index c60bd70..a8798d7 100644 --- a/src/monster.c +++ b/src/monster.c @@ -1,5 +1,7 @@ #include "monster.h" #include "util.h" +#include "player.h" +#include "monster.h" Monster* monster_create() @@ -7,6 +9,7 @@ monster_create() Monster *m = ec_malloc(sizeof(Monster)); m->sprite = sprite_create(); m->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; + m->stats = (Stats) { 11, 1, 0, 0, 1 }; return m; } diff --git a/src/monster.h b/src/monster.h index 6cbd3ae..39a3232 100644 --- a/src/monster.h +++ b/src/monster.h @@ -5,7 +5,7 @@ #include "sprite.h" #include "stats.h" -typedef struct { +typedef struct Monster_t { Sprite *sprite; Stats stats; } Monster; diff --git a/src/player.c b/src/player.c index e6f8b9a..1e84431 100644 --- a/src/player.c +++ b/src/player.c @@ -1,64 +1,74 @@ #include #include "player.h" +#include "monster.h" static Stats classStats[] = { - (Stats) { 11, 11, 11, 1 }, /* ENGINEER */ - (Stats) { 11, 11, 11, 1 }, /* MAGE */ - (Stats) { 11, 11, 11, 1 }, /* PALADIN */ - (Stats) { 11, 11, 11, 2 }, /* ROGUE */ - (Stats) { 11, 11, 11, 1 }, /* WARRIOR */ + (Stats) { 11, 5, 7, 2, 1 }, /* ENGINEER */ + (Stats) { 11, 5, 7, 2, 1 }, /* MAGE */ + (Stats) { 11, 5, 7, 2, 1 }, /* PALADIN */ + (Stats) { 11, 5, 7, 2, 2 }, /* ROGUE */ + (Stats) { 11, 5, 7, 2, 1 }, /* WARRIOR */ }; static bool -has_collided(Sprite *sprite, RoomMatrix *matrix) +has_collided(Player *player, RoomMatrix *matrix) { - Position roomCoord = position_to_room_coords(&sprite->pos); + bool collided = false; + + Position roomCoord = position_to_room_coords(&player->sprite->pos); if (roomCoord.x != matrix->roomPos.x || roomCoord.y != matrix->roomPos.y) { - return false; + return collided; } - Position matrixPos = position_to_matrix_coords(&sprite->pos); - return matrix->spaces[matrixPos.x][matrixPos.y].occupied; + Position matrixPos = position_to_matrix_coords(&player->sprite->pos); + RoomSpace *space = &matrix->spaces[matrixPos.x][matrixPos.y]; + collided = space->occupied; + + if (space->monster != NULL) { + stats_fight(&player->stats, &space->monster->stats); + } + + return collided; } static void -move_left(Sprite *sprite, RoomMatrix *matrix) +move_left(Player *player, RoomMatrix *matrix) { - sprite->clip.y = 16; - sprite->pos.x -= TILE_DIMENSION; - if (has_collided(sprite, matrix)) - sprite->pos.x += TILE_DIMENSION; + player->sprite->clip.y = 16; + player->sprite->pos.x -= TILE_DIMENSION; + if (has_collided(player, matrix)) + player->sprite->pos.x += TILE_DIMENSION; } static -void move_right(Sprite *sprite, RoomMatrix *matrix) +void move_right(Player *player, RoomMatrix *matrix) { - sprite->clip.y = 32; - sprite->pos.x += TILE_DIMENSION; - if (has_collided(sprite, matrix)) - sprite->pos.x -= TILE_DIMENSION; + player->sprite->clip.y = 32; + player->sprite->pos.x += TILE_DIMENSION; + if (has_collided(player, matrix)) + player->sprite->pos.x -= TILE_DIMENSION; } static -void move_up(Sprite *sprite, RoomMatrix *matrix) +void move_up(Player *player, RoomMatrix *matrix) { - sprite->clip.y = 48; - sprite->pos.y -= TILE_DIMENSION; - if (has_collided(sprite, matrix)) - sprite->pos.y += TILE_DIMENSION; + player->sprite->clip.y = 48; + player->sprite->pos.y -= TILE_DIMENSION; + if (has_collided(player, matrix)) + player->sprite->pos.y += TILE_DIMENSION; } static -void move_down(Sprite *sprite, RoomMatrix *matrix) +void move_down(Player *player, RoomMatrix *matrix) { - sprite->clip.y = 0; - sprite->pos.y += TILE_DIMENSION; - if (has_collided(sprite, matrix)) - sprite->pos.y -= TILE_DIMENSION; + player->sprite->clip.y = 0; + player->sprite->pos.y += TILE_DIMENSION; + if (has_collided(player, matrix)) + player->sprite->pos.y -= TILE_DIMENSION; } static -void handle_player_input(Sprite *sprite, RoomMatrix *matrix, SDL_Event *event) +void handle_player_input(Player *player, RoomMatrix *matrix, SDL_Event *event) { static unsigned int step = 1; @@ -66,22 +76,22 @@ void handle_player_input(Sprite *sprite, RoomMatrix *matrix, SDL_Event *event) switch (event->key.keysym.sym) { case SDLK_LEFT: case SDLK_h: - move_left(sprite, matrix); + move_left(player, matrix); break; case SDLK_RIGHT: case SDLK_l: - move_right(sprite, matrix); + move_right(player, matrix); break; case SDLK_UP: case SDLK_k: - move_up(sprite, matrix); + move_up(player, matrix); break; case SDLK_DOWN: case SDLK_j: - move_down(sprite, matrix); + move_down(player, matrix); break; } - sprite->clip.x = 16*step; + player->sprite->clip.x = 16*step; if (step == 3) step = 0; else @@ -124,7 +134,7 @@ player_create(class_t class, SDL_Renderer *renderer) player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; player->sprite->textures[0]->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION }; - player->sprite->handle_event = &handle_player_input; + player->handle_event = &handle_player_input; return player; } diff --git a/src/player.h b/src/player.h index a75714c..066a434 100644 --- a/src/player.h +++ b/src/player.h @@ -8,9 +8,10 @@ enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR }; typedef enum PlayerClass class_t; -typedef struct { +typedef struct Player_t { Sprite *sprite; Stats stats; + void (*handle_event)(struct Player_t*, RoomMatrix*, SDL_Event*); } Player; Player* player_create(class_t, SDL_Renderer*); diff --git a/src/roommatrix.c b/src/roommatrix.c index 301c593..d01622d 100644 --- a/src/roommatrix.c +++ b/src/roommatrix.c @@ -25,12 +25,18 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m) for (i = 0; i < MAP_ROOM_WIDTH; ++i) { for (j = 0; j < MAP_ROOM_HEIGHT; ++j) { if (r->tiles[i][j]) { - rm->spaces[i][j].occupied = r->tiles[i][j]->collider; - rm->spaces[i][j].lightsource = r->tiles[i][j]->lightsource; + rm->spaces[i][j].occupied = + r->tiles[i][j]->collider; + + rm->spaces[i][j].lightsource = + r->tiles[i][j]->lightsource; } if (r->decorations[i][j]) { - rm->spaces[i][j].occupied |= r->decorations[i][j]->collider; - rm->spaces[i][j].lightsource |= r->decorations[i][j]->lightsource; + rm->spaces[i][j].occupied |= + r->decorations[i][j]->collider; + + rm->spaces[i][j].lightsource |= + r->decorations[i][j]->lightsource; } } } @@ -40,8 +46,13 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m) monster = linkedlist_get(&m->monsters, i); if (!position_in_room(&monster->sprite->pos, &m->currentRoom)) continue; - monster_matrix_pos = position_to_matrix_coords(&monster->sprite->pos); - rm->spaces[monster_matrix_pos.x][monster_matrix_pos.y].occupied = true; + monster_matrix_pos = + position_to_matrix_coords(&monster->sprite->pos); + + rm->spaces[monster_matrix_pos.x][monster_matrix_pos.y] + .occupied = true; + rm->spaces[monster_matrix_pos.x][monster_matrix_pos.y] + .monster = monster; } } @@ -85,7 +96,8 @@ set_light_for_tile(RoomMatrix *matrix, int x, int y) for (i = x_min; i <= x_max; ++i) { for (j = y_min; j <= y_max; ++j) { lightval = matrix->spaces[i][j].light; - distance_modifier = abs(x-i) == abs(y-j) ? abs(x-i) + 1 : max(abs(x-i), abs(y-j)); + distance_modifier = abs(x-i) == abs(y-j) ? + abs(x-i) + 1 : max(abs(x-i), abs(y-j)); lightval += 255 - (distance_modifier * 50); lightval = min(255, lightval); lightval = max(0, lightval); @@ -136,7 +148,7 @@ void roommatrix_reset(RoomMatrix *m) m->spaces[i][j].occupied = false; m->spaces[i][j].lightsource = false; m->spaces[i][j].light = 0; - m->spaces[i][j].character = NULL; + m->spaces[i][j].monster = NULL; m->spaces[i][j].player = NULL; } } diff --git a/src/roommatrix.h b/src/roommatrix.h index 9e5960c..95ec9e6 100644 --- a/src/roommatrix.h +++ b/src/roommatrix.h @@ -8,13 +8,15 @@ typedef struct Sprite_t Sprite; typedef struct Map_t Map; +typedef struct Monster_t Monster; +typedef struct Player_t Player; typedef struct { bool occupied; bool lightsource; unsigned int light; - Sprite* character; - Sprite* player; + Monster* monster; + Player* player; } RoomSpace; typedef struct { diff --git a/src/sprite.c b/src/sprite.c index 3afe6a5..12eedfe 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -12,8 +12,7 @@ Sprite* sprite_create_default() (SDL_Rect) { 0, 0, 16, 16 }, false, pos, NULL, - 0, - NULL + 0 }; s->renderTimer = timer_create(); diff --git a/src/sprite.h b/src/sprite.h index 33c0ea6..aa2d598 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -16,7 +16,6 @@ typedef struct Sprite_t { Position pos; Timer *renderTimer; unsigned int texture_index; - void (*handle_event)(struct Sprite_t*, RoomMatrix*, SDL_Event*); } Sprite; Sprite* sprite_create(); diff --git a/src/stats.c b/src/stats.c new file mode 100644 index 0000000..b2735cc --- /dev/null +++ b/src/stats.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include "stats.h" + +void +stats_fight(Stats *attacker, Stats *defender) +{ + unsigned int atkRoll, defRoll, dmgRoll; + bool critical = false; + + srand(time(NULL)); + atkRoll = (rand() % 20); + if (atkRoll == 20) + critical = true; + atkRoll += attacker->atk; + defRoll = (rand() % 20) + defender->def; + + printf("Attacking: %d, Defending: %d\n", atkRoll, defRoll); + if (atkRoll > defRoll) { + dmgRoll = (rand() % 8) + attacker->dmg; + defender->hp -= dmgRoll; + if (critical) + defender->hp -= dmgRoll; + } + printf("Attacker hp: %d, Defender hp: %d\n", attacker->hp, defender->hp); +} diff --git a/src/stats.h b/src/stats.h index 4e0628a..cf8dc8a 100644 --- a/src/stats.h +++ b/src/stats.h @@ -2,10 +2,14 @@ #define STATS_H_ typedef struct { - unsigned int hp; /* Hit points */ - unsigned int dmg; /* Damage modifier */ - unsigned int atk; /* Attack rating */ - unsigned int speed; /* Speed */ + int hp; /* Hit points */ + int dmg; /* Damage modifier */ + int atk; /* Attack rating */ + int def; /* Defence rating */ + int speed; /* Speed */ } Stats; +void +stats_fight(Stats *attacker, Stats *defender); + #endif // STATS_H_