diff --git a/CMakeLists.txt b/CMakeLists.txt index b1dc6f6..9a207d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,6 +119,7 @@ add_executable(breakhack src/skill src/projectile src/vector2d + src/map_room_modifiers ) target_link_libraries(breakhack diff --git a/assets/Sounds/FX/dagger_pickup.wav b/assets/Sounds/FX/dagger_pickup.wav new file mode 100644 index 0000000..03f09b0 Binary files /dev/null and b/assets/Sounds/FX/dagger_pickup.wav differ diff --git a/data/maproombuilder.lua b/data/maproombuilder.lua index d800435..6be0406 100644 --- a/data/maproombuilder.lua +++ b/data/maproombuilder.lua @@ -371,6 +371,10 @@ function module.build_square_room(map, room) if room.goal then add_level_exit(map); end + + if CURRENT_LEVEL > 2 and random(10) == 1 then + set_modifier(map, "WINDY"); + end end function module.load_textures(map) diff --git a/src/item_builder.c b/src/item_builder.c index 5a06dac..3ee41c6 100644 --- a/src/item_builder.c +++ b/src/item_builder.c @@ -70,7 +70,7 @@ pickup_dagger(Item *item, Player *player) { player->daggers += (Uint32) item->value; - mixer_play_effect(SWORD_HIT); + mixer_play_effect(DAGGER_PICKUP); if (item->value > 1) gui_log("You collect %u daggers", (Uint32) item->value); else diff --git a/src/map_lua.c b/src/map_lua.c index 7f52db0..3d73a13 100644 --- a/src/map_lua.c +++ b/src/map_lua.c @@ -89,6 +89,26 @@ SDL_Renderer* luaL_checksdlrenderer(lua_State *L) return renderer; } +static int +l_map_set_current_room_modifier(lua_State *L) +{ + const char *modifier; + + Map *map = luaL_checkmap(L, 1); + modifier = luaL_checkstring(L, 2); + + Room *room; + if (strcmp(modifier, "WINDY") == 0) { + room = map->rooms[map->currentRoom.x][map->currentRoom.y]; + room->modifier.type = RMOD_TYPE_WINDY; + room->modifier.data.wind.direction = VECTOR2D_LEFT; + } else { + luaL_error(L, "Unknown room modifier: %s", modifier); + return 1; + } + return 0; +} + static int l_map_set_current_room(lua_State *L) { @@ -379,6 +399,9 @@ generate_map(unsigned int level, const char *file, SDL_Renderer *renderer) lua_pushcfunction(L, l_map_set_current_room); lua_setglobal(L, "set_current_room"); + lua_pushcfunction(L, l_map_set_current_room_modifier); + lua_setglobal(L, "set_modifier"); + lua_pushcfunction(L, l_add_monster); lua_setglobal(L, "add_monster"); diff --git a/src/map_room_modifiers.c b/src/map_room_modifiers.c new file mode 100644 index 0000000..996102f --- /dev/null +++ b/src/map_room_modifiers.c @@ -0,0 +1,41 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * 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 . + */ + +#include +#include "map_room_modifiers.h" +#include "player.h" +#include "roommatrix.h" +#include "position.h" + +void +map_room_modifier_player_effect(Player *player, + RoomMatrix *matrix, + Vector2d *direction, + void (*move_cb)(Player*, RoomMatrix*, Vector2d)) +{ + Position matrixPos = position_to_matrix_coords(&player->sprite->pos); + if (matrix->modifier->type == RMOD_TYPE_WINDY + && !vector2d_equals(*direction, VECTOR2D_NODIR) + && matrixPos.x > 0 && matrixPos.x < MAP_ROOM_WIDTH-1 + && matrixPos.y > 0 && matrixPos.y < MAP_ROOM_HEIGHT-1) + { + if (!vector2d_is_opposite(*direction, matrix->modifier->data.wind.direction)) { + move_cb(player, matrix, matrix->modifier->data.wind.direction); + } + } +} diff --git a/src/map_room_modifiers.h b/src/map_room_modifiers.h index 70c5752..875dfb1 100644 --- a/src/map_room_modifiers.h +++ b/src/map_room_modifiers.h @@ -1,6 +1,29 @@ +/* + * BreakHack - A dungeone crawler RPG + * Copyright (C) 2018 Linus Probert + * + * 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 . + */ + #ifndef MAP_ROOM_MODIFIERS_H_ #define MAP_ROOM_MODIFIERS_H_ +#include "vector2d.h" + +// Forward declares +typedef struct Player_t Player; +typedef struct RoomMatrix_t RoomMatrix; typedef enum RoomModifierType_e { RMOD_TYPE_NONE, @@ -20,4 +43,10 @@ typedef struct RoomModifierData_t { RoomModifierDataContainer data; } RoomModifierData; +void +map_room_modifier_player_effect(Player*, + RoomMatrix*, + Vector2d *direction, + void (*)(Player*, RoomMatrix*, Vector2d)); + #endif // MAP_ROOM_MODIFIERS_H_ diff --git a/src/mixer.c b/src/mixer.c index 6b4b869..34f71b4 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -79,6 +79,7 @@ load_effects(void) effects[PLAYER_HIT0] = load_effect("Sounds/FX/fistpunch_vocal_01.wav"); effects[PLAYER_HIT1] = load_effect("Sounds/FX/fistpunch_vocal_02.wav"); effects[PLAYER_HIT2] = load_effect("Sounds/FX/fistpunch_vocal_03.wav"); + effects[DAGGER_PICKUP] = load_effect("Sounds/FX/dagger_pickup.wav"); } void diff --git a/src/mixer.h b/src/mixer.h index 2a0d143..c3c2e28 100644 --- a/src/mixer.h +++ b/src/mixer.h @@ -53,6 +53,7 @@ typedef enum Fx_t { PLAYER_HIT0, PLAYER_HIT1, PLAYER_HIT2, + DAGGER_PICKUP, LAST_EFFECT } Fx; diff --git a/src/particle_engine.c b/src/particle_engine.c index ccf515e..db51487 100644 --- a/src/particle_engine.c +++ b/src/particle_engine.c @@ -200,7 +200,7 @@ particle_engine_speed_lines(Position pos, Dimension dim, bool horizontal) void particle_engine_wind(Vector2d direction) { - static SDL_Color color = { 255, 255, 255, 255 }; + static SDL_Color color = { 0, 0, 255, 255 }; unsigned int count = 5; Position pos = { 0, 0 }; @@ -218,8 +218,8 @@ particle_engine_wind(Vector2d direction) x = get_random(dim.width) + pos.x; y = get_random(dim.height) + pos.y; - w = get_random(2) + 1; - h = get_random(2) + 1; + w = get_random(2) + 2; + h = get_random(2) + 2; velocity = get_random(500) + 500; @@ -292,6 +292,9 @@ 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_Rect box = { pos.x, pos.y, p->dim.width, p->dim.height }; SDL_SetRenderDrawColor(cam->renderer, p->color.r, @@ -299,6 +302,9 @@ render_particle(Particle *p, Camera *cam) p->color.b, p->color.a); SDL_RenderFillRect(cam->renderer, &box); + + // Reset the blend mode + SDL_SetRenderDrawBlendMode(cam->renderer, SDL_BLENDMODE_BLEND); } void diff --git a/src/player.c b/src/player.c index 481c1da..e279026 100644 --- a/src/player.c +++ b/src/player.c @@ -159,47 +159,30 @@ has_collided(Player *player, RoomMatrix *matrix) } static void -move_left(Player *player, RoomMatrix *matrix) +set_clip_for_direction(Player *player, Vector2d *direction) { - player->sprite->clip.y = 16; - player->sprite->pos.x -= TILE_DIMENSION; - if (has_collided(player, matrix)) - player->sprite->pos.x += TILE_DIMENSION; - else - player_step(player); + if (vector2d_equals(*direction, VECTOR2D_LEFT)) + player->sprite->clip.y = 16; + else if (vector2d_equals(*direction, VECTOR2D_RIGHT)) + player->sprite->clip.y = 32; + else if (vector2d_equals(*direction, VECTOR2D_UP)) + player->sprite->clip.y = 48; + else if (vector2d_equals(*direction, VECTOR2D_DOWN)) + player->sprite->clip.y = 0; } static void -move_right(Player *player, RoomMatrix *matrix) +move(Player *player, RoomMatrix *matrix, Vector2d direction) { - player->sprite->clip.y = 32; - player->sprite->pos.x += TILE_DIMENSION; - if (has_collided(player, matrix)) - player->sprite->pos.x -= TILE_DIMENSION; - else - player_step(player); -} - -static void -move_up(Player *player, RoomMatrix *matrix) -{ - player->sprite->clip.y = 48; - player->sprite->pos.y -= TILE_DIMENSION; - if (has_collided(player, matrix)) - player->sprite->pos.y += TILE_DIMENSION; - else - player_step(player); -} - -static void -move_down(Player *player, RoomMatrix *matrix) -{ - player->sprite->clip.y = 0; - player->sprite->pos.y += TILE_DIMENSION; - if (has_collided(player, matrix)) - player->sprite->pos.y -= TILE_DIMENSION; - else + set_clip_for_direction(player, &direction); + player->sprite->pos.x += TILE_DIMENSION * (int) direction.x; + player->sprite->pos.y += TILE_DIMENSION * (int) direction.y; + if (has_collided(player, matrix)) { + player->sprite->pos.x -= TILE_DIMENSION * (int) direction.x; + player->sprite->pos.y -= TILE_DIMENSION * (int) direction.y; + } else { player_step(player); + } } void @@ -219,24 +202,23 @@ static void handle_movement_input(Player *player, RoomMatrix *matrix, SDL_Event *event) { static unsigned int step = 1; - bool moved = false; + Vector2d direction = VECTOR2D_NODIR; + + if (keyboard_direction_press(LEFT, event)) + direction = VECTOR2D_LEFT; + if (keyboard_direction_press(RIGHT, event)) + direction = VECTOR2D_RIGHT; + if (keyboard_direction_press(UP, event)) + direction = VECTOR2D_UP; + if (keyboard_direction_press(DOWN, event)) + direction = VECTOR2D_DOWN; + + if (!vector2d_equals(direction, VECTOR2D_NODIR)) + move(player, matrix, direction); + + map_room_modifier_player_effect(player, matrix, &direction, move); + - if (keyboard_direction_press(LEFT, event)) { - move_left(player, matrix); - moved = true; - } - if (keyboard_direction_press(RIGHT, event)) { - move_right(player, matrix); - moved = true; - } - if (keyboard_direction_press(UP, event)) { - move_up(player, matrix); - moved = true; - } - if (keyboard_direction_press(DOWN, event)) { - move_down(player, matrix); - moved = true; - } #ifdef DEBUG if (keyboard_mod_press(SDLK_SPACE, KMOD_CTRL, event)) { Position pos = player->sprite->pos; @@ -247,7 +229,7 @@ handle_movement_input(Player *player, RoomMatrix *matrix, SDL_Event *event) } #endif // DEBUG - if (moved) { + if (!vector2d_equals(VECTOR2D_NODIR, direction)) { player->sprite->clip.x = 16*step; ++step; step = step % 4; diff --git a/src/position.c b/src/position.c index 2a0d387..cd0249e 100644 --- a/src/position.c +++ b/src/position.c @@ -19,7 +19,8 @@ #include "position.h" #include "defines.h" -Position position_to_matrix_coords(Position *src) +Position +position_to_matrix_coords(Position *src) { unsigned int room_px_width, room_px_height; Position pos; @@ -33,7 +34,8 @@ Position position_to_matrix_coords(Position *src) return pos; } -Position position_to_room_coords(Position *src) +Position +position_to_room_coords(Position *src) { unsigned int room_px_width, room_px_height; Position pos; @@ -53,7 +55,8 @@ position_equals(const Position *p1, const Position *p2) return p1->x == p2->x && p1->y == p2->y; } -bool position_in_room(Position *pos, Position *roomPos) +bool +position_in_room(Position *pos, Position *roomPos) { int room_px_width, room_px_height, room_x_px, room_y_px; diff --git a/src/projectile.c b/src/projectile.c index 838d98e..6810db7 100644 --- a/src/projectile.c +++ b/src/projectile.c @@ -78,7 +78,7 @@ projectile_update(Projectile *p, UpdateData *data) Position collisionPos = p->sprite->pos; if (p->velocity.x > 0) collisionPos.x += TILE_DIMENSION; - else if(p->velocity.y > 0) + if(p->velocity.y > 0) collisionPos.y += TILE_DIMENSION; Position roomPos = position_to_matrix_coords(&collisionPos); diff --git a/src/roommatrix.c b/src/roommatrix.c index 002b1ed..cd1e199 100644 --- a/src/roommatrix.c +++ b/src/roommatrix.c @@ -65,6 +65,7 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m) rm->roomPos = m->currentRoom; r = m->rooms[rm->roomPos.x][rm->roomPos.y]; + rm->modifier = &r->modifier; for (i = 0; i < MAP_ROOM_WIDTH; ++i) { for (j = 0; j < MAP_ROOM_HEIGHT; ++j) { diff --git a/src/roommatrix.h b/src/roommatrix.h index 16fc0c0..514dbf8 100644 --- a/src/roommatrix.h +++ b/src/roommatrix.h @@ -23,6 +23,7 @@ #include "defines.h" #include "position.h" #include "camera.h" +#include "map_room_modifiers.h" typedef struct Sprite_t Sprite; typedef struct Map_t Map; @@ -40,11 +41,12 @@ typedef struct { LinkedList *items; } RoomSpace; -typedef struct { +typedef struct RoomMatrix_t { RoomSpace spaces[MAP_ROOM_WIDTH][MAP_ROOM_HEIGHT]; Position roomPos; Position playerRoomPos; Position mousePos; + RoomModifierData *modifier; } RoomMatrix; RoomMatrix* roommatrix_create(void); diff --git a/src/vector2d.c b/src/vector2d.c index 5eb5cf5..9063577 100644 --- a/src/vector2d.c +++ b/src/vector2d.c @@ -4,4 +4,10 @@ bool vector2d_equals(Vector2d v1, Vector2d v2) { return v1.x == v2.x && v1.y == v2.y; -} \ No newline at end of file +} + +bool +vector2d_is_opposite(Vector2d v1, Vector2d v2) +{ + return (v1.x > 0 && v2.x < 0) ^ (v1.y > 0 && v2.y < 0); +} diff --git a/src/vector2d.h b/src/vector2d.h index 20f9fdb..d76a30e 100644 --- a/src/vector2d.h +++ b/src/vector2d.h @@ -35,4 +35,7 @@ typedef struct Vector2d_t { bool vector2d_equals(Vector2d, Vector2d); +bool +vector2d_is_opposite(Vector2d, Vector2d); + #endif // VECTOR2D_H_