diff --git a/Makefile.am b/Makefile.am index 634e037c..57eca823 100644 --- a/Makefile.am +++ b/Makefile.am @@ -56,7 +56,7 @@ else helapordo_SOURCES = endif -helapordo_SOURCES += src/core/game_core.c src/utils/game_utils.c src/utils/game_init.c src/utils/game_fight.c src/utils/game_debug.c src/core/equips.c src/ser/ser_core.c src/utils/saves.c src/utils/turn_op.c src/utils/rooms.c src/utils/artifacts.c src/utils/specials.c src/main.c src/core/sprites.c src/utils/floors.c koliseo/src/koliseo.c sprites4curses/s4c-animate/animate.c src/animations/mummy_shuffle.c src/animations/ghost_spell.c src/animations/boar_scream.c src/animations/troll_club.c src/animations/goblin_shoot.c src/animations/zombie_walk.c src/animations/imp_fireball.c src/animations/werewolf_transform.c src/animations/knight_tapis.c src/animations/mage_spark.c src/animations/archer_drop.c src/animations/assassin_poof.c src/animations/crawlingdude_crawl.c src/animations/srwarthog_square.c src/animations/headlessninja_throw.c src/animations/bluetroll_wonder.c src/animations/enter_door.c src/animations/alt_chest_opening.c src/core/game_lore.c src/core/game_lore_alt.c src/palette.c +helapordo_SOURCES += src/core/game_core.c src/utils/game_utils.c src/utils/game_init.c src/utils/game_fight.c src/utils/game_debug.c src/core/equips.c src/ser/ser_core.c src/utils/saves.c src/utils/turn_op.c src/utils/rooms.c src/utils/artifacts.c src/utils/specials.c src/main.c src/core/sprites.c src/utils/floors.c koliseo/src/koliseo.c sprites4curses/s4c-animate/animate.c src/animations/mummy_shuffle.c src/animations/ghost_spell.c src/animations/boar_scream.c src/animations/troll_club.c src/animations/goblin_shoot.c src/animations/zombie_walk.c src/animations/imp_fireball.c src/animations/werewolf_transform.c src/animations/knight_tapis.c src/animations/mage_spark.c src/animations/archer_drop.c src/animations/assassin_poof.c src/animations/crawlingdude_crawl.c src/animations/srwarthog_square.c src/animations/headlessninja_throw.c src/animations/bluetroll_wonder.c src/animations/enter_door.c src/animations/alt_chest_opening.c src/core/game_lore.c src/core/game_lore_alt.c src/palette.c src/bsp/bsp.c if HL_RAYLIB_BUILD AM_CFLAGS += -DHELAPORDO_RAYLIB_BUILD helapordo_SOURCES += src/build-rl/helapordo_raylib.c src/build-rl/game_rl.c @@ -232,6 +232,7 @@ clean: -rm src/animations/*.o -rm src/palette.* -rm src/ser/*.o + -rm src/bsp/*.o -rm koliseo/src/*.o -rm ./*.o -rm src/anvil__helapordo.* @@ -249,6 +250,7 @@ cleanob: -rm src/core/*.o -rm src/utils/*.o -rm src/ser/*.o + -rm src/bsp/*.o -rm ./scripts/save2l/*.o @echo -e "\033[1;33mDone.\e[0m" diff --git a/README.md b/README.md index feb69f49..3bc366b5 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ I try to upload precompiled binaries for the ncurses build: - - `x86_64-Linux` : [download latest](https://github.com/jgabaut/helapordo/releases/download/1.4.5/helapordo-nc-1.4.5-Linux-x86_64.zip) + - `x86_64-Linux` : [download latest](https://github.com/jgabaut/helapordo/releases/download/1.4.6/helapordo-nc-1.4.6-Linux-x86_64.zip) - `aarch64-Linux` (from [Termux](https://f-droid.org/packages/com.termux/) on Android). - - `x86_64-w64-mingw32` (*JUST A DEMO.* Any help with debugging the full game is welcome.) : [download latest](https://github.com/jgabaut/helapordo/releases/download/1.4.5/helapordo.exe-nc-1.4.5-w64-mingw32-x86_64.zip) + - `x86_64-w64-mingw32` (*JUST A DEMO.* Any help with debugging the full game is welcome.) : [download latest](https://github.com/jgabaut/helapordo/releases/download/1.4.6/helapordo.exe-nc-1.4.6-w64-mingw32-x86_64.zip) - - `darwin-arm64` : [download latest](https://github.com/jgabaut/helapordo/releases/download/1.4.3/helapordo-nc-1.4.3-darwin-arm64.zip) (Available = `1.4.3`. Latest = `1.4.5`) + - `darwin-arm64` : [download latest](https://github.com/jgabaut/helapordo/releases/download/1.4.5/helapordo-nc-1.4.5-darwin-arm64.zip) (Available = `1.4.5`. Latest = `1.4.6`) - You should always check if the releases page has a newer build for you than the one linked here. - 📦 v1.4.5 19/04/2024 + 📦 v1.4.6 29/04/2024 https://github.com/jgabaut/helapordo/releases ## Building diff --git a/configure.ac b/configure.ac index 577046df..9441a31e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ # Define the package name and version -AC_INIT([helapordo], [1.4.5], [jgabaut@github.com]) +AC_INIT([helapordo], [1.4.6], [jgabaut@github.com]) # Verify automake version and enable foreign option AM_INIT_AUTOMAKE([foreign -Wall]) @@ -187,7 +187,7 @@ AM_CONDITIONAL([USE_EMOJI_BUILD], [test "$enable_emoji" = "yes"]) # Set a default version number if not specified externally AC_ARG_VAR([VERSION], [Version number]) if test -z "$VERSION"; then - VERSION="1.4.5" + VERSION="1.4.6" fi # Output variables to the config.h header diff --git a/docs/helapordo.doxyfile b/docs/helapordo.doxyfile index 1685bac1..0ebd2821 100644 --- a/docs/helapordo.doxyfile +++ b/docs/helapordo.doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = helapordo # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.4.5 +PROJECT_NUMBER = 1.4.6 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/format b/format index 59085870..497e6a9e 100755 --- a/format +++ b/format @@ -14,8 +14,9 @@ SRC_BUILD_NC_DIR="src/build-nc" SRC_BUILD_NC_W64_DIR="src/build-nc-w64" SRC_BUILD_RL_DIR="src/build-rl" SRC_SER_DIR="src/ser" +SRC_BSP_DIR="src/bsp" -hlpd_SOURCES=("$SRC_DIR"/*.c "$SRC_DIR"/*.h "$SRC_CORE_DIR"/*.c "$SRC_CORE_DIR"/*.h "$SRC_UTILS_DIR"/*.c "$SRC_UTILS_DIR"/*.h "$SRC_BUILD_NC_DIR"/*.c "$SRC_BUILD_NC_DIR"/*.h "$SRC_BUILD_NC_W64_DIR"/*.c "$SRC_BUILD_NC_W64_DIR"/*.h "$SRC_BUILD_RL_DIR"/*.c "$SRC_BUILD_RL_DIR"/*.h "$SRC_SER_DIR"/*.c "$SRC_SER_DIR"/*.h ) +hlpd_SOURCES=("$SRC_DIR"/*.c "$SRC_DIR"/*.h "$SRC_CORE_DIR"/*.c "$SRC_CORE_DIR"/*.h "$SRC_UTILS_DIR"/*.c "$SRC_UTILS_DIR"/*.h "$SRC_BUILD_NC_DIR"/*.c "$SRC_BUILD_NC_DIR"/*.h "$SRC_BUILD_NC_W64_DIR"/*.c "$SRC_BUILD_NC_W64_DIR"/*.h "$SRC_BUILD_RL_DIR"/*.c "$SRC_BUILD_RL_DIR"/*.h "$SRC_SER_DIR"/*.c "$SRC_SER_DIR"/*.h "$SRC_BSP_DIR"/*.c "$SRC_BSP_DIR"*/.h ) CONFIG_FILE=".astylerc" printf "Running \033[1;34mastyle -s4 --style=linux\e[0m for all source files.\n" diff --git a/invil b/invil index fc307afe..7d416977 160000 --- a/invil +++ b/invil @@ -1 +1 @@ -Subproject commit fc307afe14c3c8ccd117b97cfc5d366d0b4c39d1 +Subproject commit 7d416977306ae19d30aa403f133f016474d0b1d1 diff --git a/kazoj/bone/const.c b/kazoj/bone/const.c index 96972d37..708d9a65 100644 --- a/kazoj/bone/const.c +++ b/kazoj/bone/const.c @@ -10,7 +10,7 @@ void fail(char* msg, int ex, int val) { int main(void) { int check = -1; - if ( ! (( check = strcmp(VERSION, "1.4.5") ) == 0)) { + if ( ! (( check = strcmp(VERSION, "1.4.6") ) == 0)) { fail("VERSION",0,check); }; if ( ! (HLP_MAX_INDEX == 31) ) { diff --git a/kazoj/bone/const_rl.c b/kazoj/bone/const_rl.c index 298ed4ae..5e0f0afc 100644 --- a/kazoj/bone/const_rl.c +++ b/kazoj/bone/const_rl.c @@ -10,7 +10,7 @@ void fail(char* msg, int ex, int val) { int main(void) { int check = -1; - if ( ! (( check = strcmp(VERSION, "1.4.5") ) == 0)) { + if ( ! (( check = strcmp(VERSION, "1.4.6") ) == 0)) { fail("VERSION",0,check); }; if ( ! (HLP_MAX_INDEX == 31) ) { diff --git a/koliseo b/koliseo index 15367a84..c777489f 160000 --- a/koliseo +++ b/koliseo @@ -1 +1 @@ -Subproject commit 15367a8479e4cff33737d8a8ab84637866336114 +Subproject commit c777489f30c60904988482aad891b67ec3acca8b diff --git a/s4c-scripts b/s4c-scripts index 91f980e0..8feaf803 160000 --- a/s4c-scripts +++ b/s4c-scripts @@ -1 +1 @@ -Subproject commit 91f980e0fb74b3c5bb436821ddc3ff4fd41f6076 +Subproject commit 8feaf8033740d83c996b13f5851058f4b76e9297 diff --git a/src/bsp/bsp.c b/src/bsp/bsp.c new file mode 100644 index 00000000..4ad622fc --- /dev/null +++ b/src/bsp/bsp.c @@ -0,0 +1,327 @@ +// +// Directly inspired -basically stolen- from bsp-dungeon-generator by Matúš ÄŽurica. +// +// Reference repo: https://github.com/mtsdurica/bsp-dungeon-generator +// Original license: MIT. +// The author of the original code gave permission to re-license it to shit helapordo with just one license. +// +// jgabaut @ github.com/jgabaut +// SPDX-License-Identifier: GPL-3.0-only +/* + Copyright (C) 2022-2024 jgabaut + + 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, version 3 of the License. + + 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 "bsp.h" + +/** + * Set horizontal wall in Floor layout. + * @param w The BSP_Wall to carve + * @param floor The Floor to carve into + */ +static void set_horizontal_wall(BSP_Wall *w, Floor *floor) +{ + for (int x = w->start_x; x <= w->end_x; x++) { + int tmp_x = x; + int tmp_y = w->start_y; + if ((tmp_x == w->start_x && tmp_y == w->start_y) + || (tmp_x == w->end_x && tmp_y == w->end_y)) + floor->floor_layout[x][w->start_y] = 0; + else + floor->floor_layout[x][w->start_y] = 0; + } +} + +/** + * Set vertical wall in Floor layout. + * @param w The BSP_Wall to carve + * @param floor The Floor to carve into + */ +static void set_vertical_wall(BSP_Wall *w, Floor *floor) +{ + for (int y = w->start_y; y <= w->end_y; y++) { + int tmp_x = w->start_x; + int tmp_y = y; + if ((tmp_x == w->start_x && tmp_y == w->start_y) + || (tmp_x == w->end_x && tmp_y == w->end_y)) + floor->floor_layout[w->start_x][y] = 0; + else + floor->floor_layout[w->start_x][y] = 0; + } +} + +/** + * Return a random integer between min and max. + * @param min Min bound + * @param max Max bound + * @return A random integer within the bounds + */ +int random_in_range(int min, int max) +{ + // If min is greater than max, swap them + if (min > max) { + int temp = min; + min = max; + max = temp; + } + + // Generate a random number within the range [min, max] + return min + hlpd_rand() % (max - min + 1); +} + +/** + * Set center values for a BSP_Room from its walls data + * @param room Pointer to the BSP_Room to set the center for. + */ +static void set_room_center(BSP_Room *room) +{ + int center_x, center_y; + center_x = room->walls[WALL_TOP].start_x + (room->walls[WALL_TOP].end_x - room->walls[WALL_TOP].start_x) / 2; + center_y = room->walls[WALL_RIGHT].start_y + (room->walls[WALL_RIGHT].end_y - room->walls[WALL_RIGHT].start_y) / 2; + room->center_x = center_x; + room->center_y = center_y; +} + +/** + * Prepares base room for bsp. + * @param floor Floor to set the base room to. + * @return BSP_Room Base BSP room + */ +static BSP_Room prep_bsp_baseroom(Floor *floor) +{ + BSP_Room new_room = (BSP_Room) { + .walls[WALL_TOP] = (BSP_Wall) { + .start_x = 0, + .start_y = 0, + .end_x = FLOOR_MAX_COLS - 1, + .end_y = 0 + }, + .walls[WALL_BOTTOM] = (BSP_Wall) { + .start_x = 0, + .start_y = FLOOR_MAX_ROWS - 1, + .end_x = FLOOR_MAX_COLS - 1, + .end_y = FLOOR_MAX_ROWS - 1 + }, + .walls[WALL_LEFT] = (BSP_Wall) { + .start_x = 0, + .start_y = 0, + .end_x = 0, + .end_y = FLOOR_MAX_ROWS - 1 + }, + .walls[WALL_RIGHT] = (BSP_Wall) { + .start_x = FLOOR_MAX_COLS - 1, + .start_y = 0, + .end_x = FLOOR_MAX_COLS - 1, + .end_y = FLOOR_MAX_ROWS - 1 + }, + .child_left = NULL, + .child_right = NULL, + .center_x = 0, + .center_y = 0, + }; + set_horizontal_wall(&new_room.walls[WALL_TOP], floor); + set_horizontal_wall(&new_room.walls[WALL_BOTTOM], floor); + set_vertical_wall(&new_room.walls[WALL_LEFT], floor); + set_vertical_wall(&new_room.walls[WALL_RIGHT], floor); + set_room_center(&new_room); + return new_room; +} + +static void bsp_gen_vert_split(BSP_Room *room, Floor *floor); + +/** + * Generate horizontal split + * + * @param room The parent room to split + * @param floor The Floor holding the floor_layout + */ +static void bsp_gen_horiz_split(BSP_Room *room, Floor *floor) +{ + if (room == NULL) + return; + + if (room->walls[WALL_LEFT].start_y + (BSP_ROOM_SIZE / 2) >= room->walls[WALL_LEFT].end_y - (BSP_ROOM_SIZE / 2)) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): passed BSP_Room can't be split further", __func__); + return; + } + + int rand_y = + random_in_range(room->walls[WALL_LEFT].start_y + (BSP_ROOM_SIZE / 2), room->walls[WALL_LEFT].end_y - (BSP_ROOM_SIZE / 2)); + + BSP_Wall new_split = (BSP_Wall) { + .start_x = room->walls[WALL_TOP].start_x, + .start_y = rand_y, + .end_x = room->walls[WALL_TOP].end_x, + .end_y = rand_y, + }; + + BSP_Room child1 = (BSP_Room) { + .walls[WALL_TOP] = room->walls[WALL_TOP], + .walls[WALL_BOTTOM] = new_split, + .walls[WALL_LEFT] = (BSP_Wall) { + .start_x = room->walls[WALL_TOP].start_x, + .start_y = room->walls[WALL_TOP].start_y, + .end_x = new_split.start_x, + .end_y = new_split.start_y + }, + .walls[WALL_RIGHT] = (BSP_Wall) { + .start_x = room->walls[WALL_TOP].end_x, + .start_y = room->walls[WALL_TOP].end_y, + .end_x = new_split.end_x, + .end_y = new_split.end_y + }, + .child_left = NULL, + .child_right = NULL, + .center_x = 0, + .center_y = 0, + }; + room->child_left = &child1; + + BSP_Room child2 = (BSP_Room) { + .walls[WALL_TOP] = new_split, + .walls[WALL_BOTTOM] = room->walls[WALL_BOTTOM], + .walls[WALL_LEFT] = (BSP_Wall) { + .start_x = new_split.start_x, + .start_y = new_split.start_y, + .end_x = room->walls[WALL_BOTTOM].start_x, + .end_y = room->walls[WALL_BOTTOM].start_y + }, + .walls[WALL_RIGHT] = (BSP_Wall) { + .start_x = new_split.end_x, + .start_y = new_split.end_y, + .end_x = room->walls[WALL_BOTTOM].end_x, + .end_y = room->walls[WALL_BOTTOM].end_y + }, + .child_left = NULL, + .child_right = NULL, + .center_x = 0, + .center_y = 0, + }; + room->child_right = &child2; + + set_horizontal_wall(&new_split, floor); + + bsp_gen_vert_split(&child1, floor); + set_room_center(&child1); + + bsp_gen_vert_split(&child2, floor); + set_room_center(&child2); + // Carve corridor between coupled rooms + for (int i = child2.center_y; i > child1.center_y; i--) + floor->floor_layout[child2.center_x][i] = 1; +} + +/** + * Generate vertical split + * + * @param room The parent room to split + * @param floor The Floor holding the floor_layout + */ +static void bsp_gen_vert_split(BSP_Room *room, Floor *floor) +{ + if (room == NULL) + return; + + if (room->walls[WALL_TOP].start_x + BSP_ROOM_SIZE >= room->walls[WALL_TOP].end_x - BSP_ROOM_SIZE) + return; + + int rand_x = random_in_range(room->walls[WALL_TOP].start_x + BSP_ROOM_SIZE, room->walls[WALL_TOP].end_x - BSP_ROOM_SIZE); + + BSP_Wall new_split = (BSP_Wall) { + .start_x = rand_x, + .start_y = room->walls[WALL_TOP].start_y, + .end_x = rand_x, + .end_y = room->walls[WALL_BOTTOM].start_y, + }; + + BSP_Room child1 = (BSP_Room) { + .walls[WALL_TOP] = (BSP_Wall) { + .start_x = room->walls[WALL_TOP].start_x, + .start_y = room->walls[WALL_TOP].start_y, + .end_x = new_split.start_x, + .end_y = new_split.start_y + }, + .walls[WALL_BOTTOM] = (BSP_Wall) { + .start_x = room->walls[WALL_BOTTOM].start_x, + .start_y = room->walls[WALL_BOTTOM].start_y, + .end_x = new_split.end_x, + .end_y = new_split.end_y + }, + .walls[WALL_LEFT] = room->walls[WALL_LEFT], + .walls[WALL_RIGHT] = new_split, + .child_left = NULL, + .child_right = NULL, + .center_x = 0, + .center_y = 0, + }; + + room->child_left = &child1; + + BSP_Room child2 = (BSP_Room) { + .walls[WALL_TOP] = (BSP_Wall) { + .start_x = new_split.start_x, + .start_y = new_split.start_y, + .end_x = room->walls[WALL_TOP].end_x, + .end_y = room->walls[WALL_TOP].end_y + }, + .walls[WALL_BOTTOM] = (BSP_Wall) { + .start_x = new_split.end_x, + .start_y = new_split.end_y, + .end_x = room->walls[WALL_BOTTOM].end_x, + .end_y = room->walls[WALL_BOTTOM].end_y + }, + .walls[WALL_LEFT] = new_split, + .walls[WALL_RIGHT] = room->walls[WALL_RIGHT], + .child_left = NULL, + .child_right = NULL, + .center_x = 0, + .center_y = 0, + }; + + room->child_right = &child2; + + set_vertical_wall(&new_split, floor); + + bsp_gen_horiz_split(&child1, floor); + set_room_center(&child1); + + bsp_gen_horiz_split(&child2, floor); + set_room_center(&child2); + // Carve corridor between coupled rooms + for (int i = child2.center_x; i > child1.center_x; i--) + floor->floor_layout[i][child2.center_y] = 1; +} + +/** + * Prepares the floor layout with BSP. + * @param floor the Floor whose layout is to be prepared + * @param base_x Base x coordinate + * @param base_y Base y coordinate + */ +void floor_bsp_gen(Floor* floor, int base_x, int base_y) +{ + for (size_t i = 0; i < FLOOR_MAX_ROWS; i++) { + for (size_t j = 0; j < FLOOR_MAX_COLS; j++) { + floor->floor_layout[i][j] = 1; + } + } + + BSP_Room base_room = prep_bsp_baseroom(floor); + + if (hlpd_rand() % 2) { + bsp_gen_vert_split(&base_room, floor); + } else { + bsp_gen_horiz_split(&base_room, floor); + } +} diff --git a/src/bsp/bsp.h b/src/bsp/bsp.h new file mode 100644 index 00000000..2c53e70b --- /dev/null +++ b/src/bsp/bsp.h @@ -0,0 +1,61 @@ +// +// Directly inspired -basically stolen- from bsp-dungeon-generator by Matúš ÄŽurica. +// +// Reference repo: https://github.com/mtsdurica/bsp-dungeon-generator +// Original license: MIT. +// The author of the original code gave permission to re-license it to shit helapordo with just one license. +// +// jgabaut @ github.com/jgabaut +// SPDX-License-Identifier: GPL-3.0-only +/* + Copyright (C) 2022-2024 jgabaut + + 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, version 3 of the License. + + 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 BSP_H_ +#define BSP_H_ + +#include "../utils/floors.h" + +typedef struct BSP_Wall { + int start_x; + int start_y; + int end_x; + int end_y; +} BSP_Wall; + +enum BSP_Wall_Index { + WALL_TOP, + WALL_RIGHT, + WALL_BOTTOM, + WALL_LEFT, +}; + +#define BSP_WALL_INDEX_MAX WALL_LEFT + +struct BSP_Room; + +typedef struct BSP_Room { + BSP_Wall walls[BSP_WALL_INDEX_MAX+1]; + struct BSP_Room* child_left; // Left/top + struct BSP_Room* child_right; // Right/bottom + int center_x; + int center_y; +} BSP_Room; + +#define BSP_ROOM_SIZE 4 + +void floor_bsp_gen(Floor* floor, int base_x, int base_y); + +#endif diff --git a/src/build-nc-w64/helapordo_win.c b/src/build-nc-w64/helapordo_win.c index 45792e87..7ddaae81 100644 --- a/src/build-nc-w64/helapordo_win.c +++ b/src/build-nc-w64/helapordo_win.c @@ -62,7 +62,7 @@ void gameloop_Win(int argc, char **argv) bool is_localexe = ( argv[0][0] == '.'); (whoami = strrchr(argv[0], '\\')) ? ++whoami : (whoami = argv[0]); - char seed[PATH_SEED_BUFSIZE] = {0}; + char seed[PATH_SEED_BUFSIZE+1] = {0}; do { default_kls = kls_new_conf(KLS_DEFAULT_SIZE * 8, default_kls_conf); temporary_kls = kls_new_conf(KLS_DEFAULT_SIZE * 8, temporary_kls_conf); diff --git a/src/build-nc/helapordo.c b/src/build-nc/helapordo.c index d71aa203..32212bf9 100644 --- a/src/build-nc/helapordo.c +++ b/src/build-nc/helapordo.c @@ -88,7 +88,7 @@ void gameloop(int argc, char **argv) NULL ); - char seed[PATH_SEED_BUFSIZE] = {0}; + char seed[PATH_SEED_BUFSIZE+1] = {0}; bool is_seeded = false; @@ -1263,9 +1263,9 @@ void gameloop(int argc, char **argv) load_info->enemy_index = gamestate->current_enemy_index; log_tag("debug_log.txt", "[DEBUG]", "%s(): load_info->enemy_index: {%i}", __func__, load_info->enemy_index); - gamestate->path->seed[PATH_SEED_BUFSIZE-1] = '\0'; - strncpy(seed, gamestate->path->seed, PATH_SEED_BUFSIZE); - seed[PATH_SEED_BUFSIZE-1] = '\0'; + gamestate->path->seed[PATH_SEED_BUFSIZE] = '\0'; + memcpy(seed, gamestate->path->seed, PATH_SEED_BUFSIZE); + seed[PATH_SEED_BUFSIZE] = '\0'; log_tag("debug_log.txt", "[DEBUG]", "Seed after loading: [%s]", seed); @@ -2075,10 +2075,27 @@ void gameloop(int argc, char **argv) //Init floor rooms init_floor_rooms(current_floor); - //Random walk #1 - floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. - //Random walk #2 - floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + if (G_EXPERIMENTAL_ON != 1) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing random walk init, no experimental.", __func__); + //Random walk #1 + floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. + //Random walk #2 + floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + current_floor->from_bsp = false; + } else { + if ((hlpd_rand() % 101) > 20) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing bsp init", __func__); + floor_bsp_gen(current_floor, center_x, center_y); + current_floor->from_bsp = true; + } else { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing random walk init", __func__); + //Random walk #1 + floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. + //Random walk #2 + floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + current_floor->from_bsp = false; + } + } //Set floor explored matrix load_floor_explored(current_floor); @@ -2086,9 +2103,35 @@ void gameloop(int argc, char **argv) //Set room types floor_set_room_types(current_floor); - log_tag("debug_log.txt", "[DEBUG]", "Putting player at center: {%i,%i}", center_x, center_y); - player->floor_x = center_x; - player->floor_y = center_y; + if (G_EXPERIMENTAL_ON != 1) { + log_tag("debug_log.txt", "[DEBUG]", "Putting player at center: {%i,%i}", center_x, center_y); + player->floor_x = center_x; + player->floor_y = center_y; + } else { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Finding HOME room x/y for floor, and putting player there", __func__); + int home_room_x = -1; + int home_room_y = -1; + bool done_looking = false; + for(size_t i=0; i < FLOOR_MAX_COLS && !done_looking; i++) { + for (size_t j=0; j < FLOOR_MAX_ROWS && !done_looking; j++) { + if (current_floor->roomclass_layout[i][j] == HOME) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Found HOME room at {x:%i, y:%i}.", __func__, i, j); + home_room_x = i; + home_room_y = j; + done_looking = true; + } + } + } + if (!done_looking) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Could not find HOME room.", __func__); + kls_free(default_kls); + kls_free(temporary_kls); + exit(EXIT_FAILURE); + } + log_tag("debug_log.txt", "[DEBUG]", "Putting player at HOME room: {%i,%i}", home_room_x, home_room_y); + player->floor_x = home_room_x; + player->floor_y = home_room_y; + } } //TODO: handle finishing all floors @@ -2116,9 +2159,11 @@ void gameloop(int argc, char **argv) && (load_info->save_type == ENEMIES_SAVE)) { enemyTotal = loaded_roomtotalenemies; } else { + if (!load_info->done_loading) { + log_tag("debug_log.txt", "[DEBUG-PREP]", + "Setting load_info->done_loading to 1."); + } load_info->done_loading = 1; - log_tag("debug_log.txt", "[DEBUG-PREP]", - "Set load_info->done_loading to 1."); } Room *current_room = NULL; @@ -2367,10 +2412,27 @@ void gameloop(int argc, char **argv) floor_layout[center_x][center_y] = 1; //Init floor rooms init_floor_rooms(current_floor); - //Random walk #1 - floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. - //Random walk #2 - floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + if (G_EXPERIMENTAL_ON != 1) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing random walk init, no experimental.", __func__); + //Random walk #1 + floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. + //Random walk #2 + floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + current_floor->from_bsp = false; + } else { + if ((hlpd_rand() % 101) > 20) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing bsp init", __func__); + floor_bsp_gen(current_floor, center_x, center_y); + current_floor->from_bsp = true; + } else { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing random walk init", __func__); + //Random walk #1 + floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. + //Random walk #2 + floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + current_floor->from_bsp = false; + } + } //Set floor explored matrix load_floor_explored(current_floor); //Set room types diff --git a/src/build-rl/helapordo_raylib.c b/src/build-rl/helapordo_raylib.c index 3247014f..8fb9d7ce 100644 --- a/src/build-rl/helapordo_raylib.c +++ b/src/build-rl/helapordo_raylib.c @@ -588,10 +588,27 @@ void gameloop_rl(int argc, char** argv) //Init floor rooms init_floor_rooms(current_floor); - //Random walk #1 - floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. - //Random walk #2 - floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + if (G_EXPERIMENTAL_ON != 1) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing random walk init, no experimental.", __func__); + //Random walk #1 + floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. + //Random walk #2 + floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + current_floor->from_bsp = false; + } else { + if ((hlpd_rand() % 101) > 20) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing bsp init", __func__); + floor_bsp_gen(current_floor, center_x, center_y); + current_floor->from_bsp = true; + } else { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing random walk init", __func__); + //Random walk #1 + floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. + //Random walk #2 + floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + current_floor->from_bsp = false; + } + } //Set floor explored matrix load_floor_explored(current_floor); @@ -599,6 +616,36 @@ void gameloop_rl(int argc, char** argv) //Set room types floor_set_room_types(current_floor); + if (G_EXPERIMENTAL_ON != 1) { + log_tag("debug_log.txt", "[DEBUG]", "Putting player at center: {%i,%i}", center_x, center_y); + current_x = center_x; + current_y = center_y; + } else { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Finding HOME room x/y for floor, and putting player there", __func__); + int home_room_x = -1; + int home_room_y = -1; + bool done_looking = false; + for(size_t i=0; i < FLOOR_MAX_COLS && !done_looking; i++) { + for (size_t j=0; j < FLOOR_MAX_ROWS && !done_looking; j++) { + if (current_floor->roomclass_layout[i][j] == HOME) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Found HOME room at {x:%i, y:%i}.", __func__, i, j); + home_room_x = i; + home_room_y = j; + done_looking = true; + } + } + } + if (!done_looking) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Could not find HOME room.", __func__); + kls_free(default_kls); + kls_free(temporary_kls); + exit(EXIT_FAILURE); + } + log_tag("debug_log.txt", "[DEBUG]", "Putting player at HOME room: {%i,%i}", home_room_x, home_room_y); + current_x = home_room_x; + current_y = home_room_y; + } + int screenWidth = 800; int screenHeight = 450; @@ -688,16 +735,64 @@ void gameloop_rl(int argc, char** argv) //Init floor rooms init_floor_rooms(current_floor); - //Random walk #1 - floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. - //Random walk #2 - floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + if (G_EXPERIMENTAL_ON != 1) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing random walk init, no experimental.", __func__); + //Random walk #1 + floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. + //Random walk #2 + floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + current_floor->from_bsp = false; + } else { + if ((hlpd_rand() % 101) > 20) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing bsp init", __func__); + floor_bsp_gen(current_floor, center_x, center_y); + current_floor->from_bsp = true; + } else { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Doing random walk init", __func__); + //Random walk #1 + floor_random_walk(current_floor, center_x, center_y, 100, 1); // Perform 100 steps of random walk, reset floor_layout if needed. + //Random walk #2 + floor_random_walk(current_floor, center_x, center_y, 100, 0); // Perform 100 more steps of random walk, DON'T reset floor_layout if needed. + current_floor->from_bsp = false; + } + } //Set floor explored matrix load_floor_explored(current_floor); //Set room types floor_set_room_types(current_floor); + + if (G_EXPERIMENTAL_ON != 1) { + log_tag("debug_log.txt", "[DEBUG]", "Putting player at center: {%i,%i}", center_x, center_y); + current_x = center_x; + current_y = center_y; + } else { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Finding HOME room x/y for floor, and putting player there", __func__); + int home_room_x = -1; + int home_room_y = -1; + bool done_looking = false; + for(size_t i=0; i < FLOOR_MAX_COLS && !done_looking; i++) { + for (size_t j=0; j < FLOOR_MAX_ROWS && !done_looking; j++) { + if (current_floor->roomclass_layout[i][j] == HOME) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Found HOME room at {x:%i, y:%i}.", __func__, i, j); + home_room_x = i; + home_room_y = j; + done_looking = true; + } + } + } + if (!done_looking) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Could not find HOME room.", __func__); + kls_free(default_kls); + kls_free(temporary_kls); + exit(EXIT_FAILURE); + } + log_tag("debug_log.txt", "[DEBUG]", "Putting player at HOME room: {%i,%i}", home_room_x, home_room_y); + current_x = home_room_x; + current_y = home_room_y; + } + } if (IsKeyPressed(KEY_UP)) { step_floor(current_floor, ¤t_x, @@ -861,14 +956,17 @@ void gameloop_rl(int argc, char** argv) FLOOR_MAX_ROWS * sprite_w_factor, }; - draw_floor_view(current_floor, current_x, current_y, sprite_w_factor, &floor_r); + if (G_EXPERIMENTAL_ON != 1) { + draw_floor_view(current_floor, current_x, current_y, sprite_w_factor, &floor_r); + } else { + display_roomclass_layout(current_floor, &floor_r, sprite_w_factor); + } /* int center_x = FLOOR_MAX_COLS / 2; int center_y = FLOOR_MAX_ROWS / 2; draw_floor_view(current_floor, center_x, center_y, sprite_w_factor, &floor_r); */ - //display_roomclass_layout(current_floor, &floor_r, sprite_w_factor); //display_floor_layout(current_floor, &floor_r, sprite_w_factor); //display_explored_layout(current_floor, &floor_r, sprite_w_factor); /* diff --git a/src/core/game_core.h b/src/core/game_core.h index ba0c48cf..f27735c6 100644 --- a/src/core/game_core.h +++ b/src/core/game_core.h @@ -232,16 +232,16 @@ extern char *G_SEEDED_RUN_ARG; /** * Current patch release. */ -#define HELAPORDO_PATCH_VERSION 5 +#define HELAPORDO_PATCH_VERSION 6 /** * Current version string identifier, with MAJOR.MINOR.PATCH format. */ -#define VERSION "1.4.5" +#define VERSION "1.4.6" #define HELAPORDO_SAVEFILE_VERSION "0.1.7" -#define HELAPORDO_BINSAVEFILE_VERSION "0.0.2" +#define HELAPORDO_BINSAVEFILE_VERSION "0.0.3" /** * Defines current API version number from HELAPORDO_MAJOR_VERSION, HELAPORDO_MINOR_VERSION and HELAPORDO_PATCH_VERSION. @@ -1219,10 +1219,10 @@ typedef struct Path { int luck; /**< Defines global luck value.*/ int prize; /**< Defines the reward for getting to length*/ int loreCounter; /**< Counts how many lore prompts have been displayed*/ - Wincon *win_condition; /**> Defines the win condition for the current game.*/ - Saveslot *current_saveslot; /** Defines current Saveslot for the game.*/ - char seed[PATH_SEED_BUFSIZE]; /** Contains seed for current run.*/ - int64_t* rng_advancements; /** Pointer to current advancements for rng.*/ + Wincon *win_condition; /**< Defines the win condition for the current game.*/ + Saveslot *current_saveslot; /**< Defines current Saveslot for the game.*/ + char seed[PATH_SEED_BUFSIZE+1]; /**< Contains seed for current run.*/ + int64_t* rng_advancements; /**< Pointer to current advancements for rng.*/ } Path; /** @@ -1695,6 +1695,7 @@ typedef struct Floor { roomClass roomclass_layout[FLOOR_MAX_COLS][FLOOR_MAX_ROWS]; /**< roomClass matrix for class value for rooms of this floor.*/ int explored_matrix[FLOOR_MAX_COLS][FLOOR_MAX_ROWS]; /**< Int matrix for explored value for rooms of this floor.*/ int explored_area; /**< Holds how many cells we explored.*/ + bool from_bsp; /**< Flag for floors generated using bsp.*/ //TODO: add some pointer to a loot instance, initialised for floors having some flag active.*/ } Floor; diff --git a/src/main.c b/src/main.c index 9d97ccbc..3dceb996 100644 --- a/src/main.c +++ b/src/main.c @@ -58,6 +58,8 @@ Koliseo *temporary_kls = NULL; int main(int argc, char **argv) { + // Registering the signal handler for SIGINT (Ctrl+C) + signal(SIGINT, ctrl_c_handler); //Randomise seed srand(time(NULL)); diff --git a/src/ser/ser_core.c b/src/ser/ser_core.c index 2d86e677..64c13da8 100644 --- a/src/ser/ser_core.c +++ b/src/ser/ser_core.c @@ -67,6 +67,9 @@ bool readSerSaveHeader(const char* filename, SerSaveHeader* data) size_t read_blobs = fread(&header_size, sizeof(header_size), 1, file); if (read_blobs != 1) { log_tag("debug_log.txt", "[ERROR]", "%s(): Failed reading blob.", __func__); +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD fclose(file); kls_free(default_kls); kls_free(temporary_kls); @@ -91,6 +94,11 @@ bool readSerSaveHeader(const char* filename, SerSaveHeader* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Size {%li} is less than expected {%li}.", __func__, header_size, sersh_size); #endif + +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD + fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -103,6 +111,11 @@ bool readSerSaveHeader(const char* filename, SerSaveHeader* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Size {%li} is greater than expected {%li}.", __func__, header_size, sersh_size); #endif + +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD + fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -120,6 +133,11 @@ bool readSerSaveHeader(const char* filename, SerSaveHeader* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Remaining file length {%li} is less than stored header size {%li}.", __func__, length, header_size); #endif + +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD + fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -145,6 +163,11 @@ bool readSerSaveHeader(const char* filename, SerSaveHeader* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Size {%li} is less than expected {%li}.", __func__, length, expected_len); #endif + +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD + fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -164,6 +187,9 @@ bool readSerSaveHeader(const char* filename, SerSaveHeader* data) read_blobs = fread(data, sizeof(SerSaveHeader), 1, file); if (read_blobs != 1) { log_tag("debug_log.txt", "[ERROR]", "%s(): Failed reading blob.", __func__); +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD fclose(file); kls_free(default_kls); kls_free(temporary_kls); @@ -173,6 +199,9 @@ bool readSerSaveHeader(const char* filename, SerSaveHeader* data) // Close the file fclose(file); } else { +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD fprintf(stderr, "%s(): Error opening file {%s} for reading\n", __func__, filename); log_tag("debug_log.txt", "[ERROR]", "%s(): Error opening file {%s} for reading", __func__, filename); return false; @@ -2116,6 +2145,7 @@ bool deser_Floor(SerFloor* ser, Floor* deser) } deser->explored_area = ser->explored_area; + deser->from_bsp = ser->from_bsp; return true; } @@ -2172,6 +2202,7 @@ bool ser_Floor(Floor* deser, SerFloor* ser) } ser->explored_area = deser->explored_area; + ser->from_bsp = deser->from_bsp; return true; } @@ -2424,6 +2455,9 @@ bool readSerGamestate(const char* filename, size_t offset, SerGamestate* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Total file size {%li} is less than passed offset {%li}", __func__, tot_length, offset); #endif +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -2445,6 +2479,9 @@ bool readSerGamestate(const char* filename, size_t offset, SerGamestate* data) if (read_blobs != 1) { log_tag("debug_log.txt", "[ERROR]", "%s(): Failed reading blob.", __func__); fclose(file); +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD kls_free(default_kls); kls_free(temporary_kls); exit(EXIT_FAILURE); @@ -2468,6 +2505,9 @@ bool readSerGamestate(const char* filename, size_t offset, SerGamestate* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Size {%li} is less than expected {%li}.", __func__, blob_size, sergmst_size); #endif +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -2480,6 +2520,9 @@ bool readSerGamestate(const char* filename, size_t offset, SerGamestate* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Size {%li} is greater than expected {%li}.", __func__, blob_size, sergmst_size); #endif +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -2497,6 +2540,9 @@ bool readSerGamestate(const char* filename, size_t offset, SerGamestate* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Remaining file length {%li} is less than stored header size {%li}.", __func__, remaining_length, blob_size); #endif +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -2512,6 +2558,9 @@ bool readSerGamestate(const char* filename, size_t offset, SerGamestate* data) #else log_tag("debug_log.txt", "[ERROR]", "%s(): Size {%li} is less than expected {%li}.", __func__, remaining_length, expected_len); #endif +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD fprintf(stderr, "%s(): Failed reading {%s}.\n", __func__, filename); fclose(file); kls_free(default_kls); @@ -2531,6 +2580,9 @@ bool readSerGamestate(const char* filename, size_t offset, SerGamestate* data) if (read_blobs != 1) { log_tag("debug_log.txt", "[ERROR]", "%s(): Failed reading blob.", __func__); fclose(file); +#ifdef HELAPORDO_CURSES_BUILD + endwin(); +#endif // HELAPORDO_CURSES_BUILD kls_free(default_kls); kls_free(temporary_kls); exit(EXIT_FAILURE); diff --git a/src/ser/ser_core.h b/src/ser/ser_core.h index 377391f2..31d2f31a 100644 --- a/src/ser/ser_core.h +++ b/src/ser/ser_core.h @@ -694,6 +694,7 @@ typedef struct SerFloor { roomClass roomclass_layout[FLOOR_MAX_COLS][FLOOR_MAX_ROWS]; /**< roomClass matrix for class value for rooms of this floor.*/ int8_t explored_matrix[FLOOR_MAX_COLS][FLOOR_MAX_ROWS]; /**< Int matrix for explored value for rooms of this floor.*/ int8_t explored_area; /**< Holds how many cells we explored.*/ + bool from_bsp; /**< Flag for floors generated using bsp.*/ #ifdef __GNUC__ } SerFloor; #else @@ -769,10 +770,10 @@ typedef struct SerPath { int8_t luck; /**< Defines global luck value.*/ int8_t prize; /**< Defines the reward for getting to length*/ int8_t loreCounter; /**< Counts how many lore prompts have been displayed*/ - SerWincon win_condition; /**> Defines the win condition for the current game.*/ - SerSaveslot current_saveslot; /** Defines current SerSaveslot for the game.*/ - char seed[SERPATH_SEED_BUFSIZE]; /** Holds seed for current run.*/ - int64_t rng_advancements; /** Current advancements for rng.*/ + SerWincon win_condition; /**< Defines the win condition for the current game.*/ + SerSaveslot current_saveslot; /**< Defines current SerSaveslot for the game.*/ + char seed[SERPATH_SEED_BUFSIZE+1]; /**< Holds seed for current run.*/ + int64_t rng_advancements; /**< Current advancements for rng.*/ #ifdef __GNUC__ } SerPath; #else diff --git a/src/utils/floors.c b/src/utils/floors.c index 6c097581..d264012c 100644 --- a/src/utils/floors.c +++ b/src/utils/floors.c @@ -175,10 +175,25 @@ void floor_set_room_types(Floor *floor) { int placed_rooms = 0; - // Assume the center room is the HOME room int center_x = FLOOR_MAX_COLS / 2; int center_y = FLOOR_MAX_ROWS / 2; - floor->roomclass_layout[center_x][center_y] = HOME; + + int home_x; + int home_y; + + if (!(floor->from_bsp)) { + // Assume the center room is the HOME room + home_x = center_x; + home_y = center_y; + log_tag("debug_log.txt", "[DEBUG]", "%s(): Centered HOME is at {x:%i, y:%i}", __func__, home_x, home_y); + } else { + do { + home_x = hlpd_rand() % FLOOR_MAX_COLS; + home_y = hlpd_rand() % FLOOR_MAX_ROWS; + } while (floor->floor_layout[home_x][home_y] != 1); + log_tag("debug_log.txt", "[DEBUG]", "%s(): Random HOME is at {x:%i, y:%i}", __func__, home_x, home_y); + } + floor->roomclass_layout[home_x][home_y] = HOME; placed_rooms++; /* @@ -240,7 +255,7 @@ void floor_set_room_types(Floor *floor) shop_x = hlpd_rand() % max_x + 1; shop_y = hlpd_rand() % max_y + 1; } while (floor->floor_layout[shop_x][shop_y] != 1 - && (shop_x != center_x || shop_y != center_y)); + && (shop_x != home_x || shop_y != home_y)); } else { // Select a valid random room as the SHOP shop_x = hlpd_rand() % max_x + 1; @@ -248,7 +263,7 @@ void floor_set_room_types(Floor *floor) shop_attemps--; } } while (floor->floor_layout[shop_x][shop_y] != 1 - || calc_distance(shop_x, shop_y, center_x, center_y) < 2); + || calc_distance(shop_x, shop_y, home_x, home_y) < 2); floor->roomclass_layout[shop_x][shop_y] = SHOP; placed_rooms++; @@ -268,7 +283,7 @@ void floor_set_room_types(Floor *floor) boss_x = hlpd_rand() % max_x + 1; boss_y = hlpd_rand() % max_y + 1; } while (floor->floor_layout[boss_x][boss_y] != 1 - && (boss_x != center_x || boss_y != center_y) + && (boss_x != home_x || boss_y != home_y) && (boss_x != shop_x || boss_y != shop_y)); } else { // Select a valid random room as the SHOP @@ -277,7 +292,7 @@ void floor_set_room_types(Floor *floor) boss_attemps--; } } while (floor->floor_layout[boss_x][boss_y] != 1 - || (calc_distance(boss_x, boss_y, center_x, center_y) < 4) + || (calc_distance(boss_x, boss_y, home_x, home_y) < 4) || (calc_distance(boss_x, boss_y, shop_x, shop_y) < 4)); floor->roomclass_layout[boss_x][boss_y] = BOSS; @@ -304,7 +319,7 @@ void floor_set_room_types(Floor *floor) treasure_x = hlpd_rand() % max_x + 1; treasure_y = hlpd_rand() % max_y + 1; } while (floor->floor_layout[treasure_x][treasure_y] != 1 - && (treasure_x != center_x || treasure_y != center_y) + && (treasure_x != home_x || treasure_y != home_y) && (treasure_x != shop_x || treasure_y != shop_y) && (treasure_x != boss_x || treasure_y != boss_y)); break; @@ -315,7 +330,7 @@ void floor_set_room_types(Floor *floor) treasure_attemps--; } } while (floor->floor_layout[treasure_x][treasure_y] != 1 - || (calc_distance(treasure_x, treasure_y, center_x, center_y) < + || (calc_distance(treasure_x, treasure_y, home_x, home_y) < 4) || (calc_distance(treasure_x, treasure_y, shop_x, shop_y) < 4) || (calc_distance(treasure_x, treasure_y, boss_x, boss_y) < @@ -345,7 +360,25 @@ void floor_set_room_types(Floor *floor) } } - while (floor->area > (placed_rooms * 6)) { + if (G_EXPERIMENTAL_ON == 1 && floor->from_bsp) { + log_tag("debug_log.txt", "[DEBUG]", "%s(): Floor is from_bsp. Setting floor->area", __func__); + floor->area = 0; + for (size_t i = 0; i < FLOOR_MAX_ROWS; i++) { + for (size_t j = 0; j < FLOOR_MAX_COLS; j++) { + if (floor->roomclass_layout[j][i] != WALL) { + floor->area += 1; + } + } + } + } + + int enemy_area_ratio; + if (floor->from_bsp) { + enemy_area_ratio = 10; + } else { + enemy_area_ratio = 6; + } + while (floor->area > (placed_rooms * enemy_area_ratio)) { //Spice it up with enemy rooms int enemy_x = -1; int enemy_y = -1; @@ -353,13 +386,16 @@ void floor_set_room_types(Floor *floor) enemy_x = hlpd_rand() % max_x; enemy_y = hlpd_rand() % max_y; } while (floor->floor_layout[enemy_x][enemy_y] != 1 - && floor->roomclass_layout[enemy_x][enemy_y] != BASIC); + || floor->roomclass_layout[enemy_x][enemy_y] != BASIC); floor->roomclass_layout[enemy_x][enemy_y] = ENEMIES; placed_rooms++; + log_tag("debug_log.txt", "[DEBUG]", "%s(): Placed enemy room at {%i,%i}", __func__, enemy_x, enemy_y); } /* fclose(logfile); */ + + log_tag("debug_log.txt", "[DEBUG]", "%s(): Center room class at {%i,%i} is {%s}", __func__, center_x, center_y, stringFromRoom(floor->roomclass_layout[center_x][center_y])); } /** @@ -706,7 +742,11 @@ void draw_cell(Floor *floor, int cell_x, int cell_y, WINDOW *win, if (isWall > 0) { ch = '#'; #ifndef _WIN32 - isColored = S4C_PURPLE; + if (floor->from_bsp) { + isColored = S4C_DARK_PURPLE; + } else { + isColored = S4C_PURPLE; + } #else isColored = S4C_WIN_PURPLE; #endif @@ -737,7 +777,11 @@ void draw_cell(Floor *floor, int cell_x, int cell_y, WINDOW *win, case WALL: { ch = '#'; #ifndef _WIN32 - isColored = S4C_BLUE; + if (floor->from_bsp) { + isColored = S4C_DARK_BLUE; + } else { + isColored = S4C_BLUE; + } #else isColored = S4C_WIN_BLUE; #endif @@ -746,7 +790,11 @@ void draw_cell(Floor *floor, int cell_x, int cell_y, WINDOW *win, case BASIC: { ch = '.'; #ifndef _WIN32 - isColored = S4C_LIGHT_BROWN; + if (floor->from_bsp) { + isColored = S4C_DARK_OLIVE; + } else { + isColored = S4C_LIGHT_BROWN; + } #else isColored = S4C_WIN_WHITE; #endif @@ -755,7 +803,11 @@ void draw_cell(Floor *floor, int cell_x, int cell_y, WINDOW *win, case HOME: { ch = 'H'; #ifndef _WIN32 - isColored = S4C_WHITE; + if (floor->from_bsp) { + isColored = S4C_LIGHT_OLIVE; + } else { + isColored = S4C_WHITE; + } #else isColored = S4C_WIN_WHITE; #endif @@ -764,7 +816,11 @@ void draw_cell(Floor *floor, int cell_x, int cell_y, WINDOW *win, case BOSS: { ch = 'B'; #ifndef _WIN32 - isColored = S4C_RED; + if (floor->from_bsp) { + isColored = S4C_CHERRY; + } else { + isColored = S4C_RED; + } #else isColored = S4C_WIN_RED; #endif @@ -773,7 +829,11 @@ void draw_cell(Floor *floor, int cell_x, int cell_y, WINDOW *win, case TREASURE: { ch = '*'; #ifndef _WIN32 - isColored = S4C_ORANGE; + if (floor->from_bsp) { + isColored = S4C_LIGHT_ORANGE; + } else { + isColored = S4C_ORANGE; + } #else isColored = S4C_WIN_WHITE_ON_RED; #endif @@ -782,7 +842,11 @@ void draw_cell(Floor *floor, int cell_x, int cell_y, WINDOW *win, case SHOP: { ch = '$'; #ifndef _WIN32 - isColored = S4C_MAGENTA; + if (floor->from_bsp) { + isColored = S4C_TEAL; + } else { + isColored = S4C_MAGENTA; + } #else isColored = S4C_WIN_WHITE_ON_PURPLE; #endif @@ -791,7 +855,11 @@ void draw_cell(Floor *floor, int cell_x, int cell_y, WINDOW *win, case ENEMIES: { ch = '^'; #ifndef _WIN32 - isColored = S4C_CYAN; + if (floor->from_bsp) { + isColored = S4C_DARK_CYAN; + } else { + isColored = S4C_CYAN; + } #else isColored = S4C_WIN_CYAN; #endif diff --git a/src/utils/game_debug.h b/src/utils/game_debug.h index c54f5b0d..6213658e 100644 --- a/src/utils/game_debug.h +++ b/src/utils/game_debug.h @@ -2,6 +2,8 @@ #define GAME_DEBUG_H #include "floors.h" +//TODO This inclusion could be in a better place +#include "../bsp/bsp.h" #ifdef _WIN32 #else diff --git a/src/utils/game_utils.c b/src/utils/game_utils.c index 6ce922f3..5214a49c 100644 --- a/src/utils/game_utils.c +++ b/src/utils/game_utils.c @@ -19,6 +19,29 @@ //Functions useful in many areas // +/** + * Function to handle Ctrl+C signal + */ +void ctrl_c_handler(int signum) +{ + log_tag("debug_log.txt", "[DEBUG]", "%s(): Ctrl+C received. Cleaning up memory...", __func__); +#ifdef HELAPORDO_CURSES_BUILD + if (stdscr != NULL) { + endwin(); + log_tag("debug_log.txt", "[CLEANUP]", "%s(): Ended window mode", __func__); + } +#endif // HELAPORDO_CURSES_BUILD + if (default_kls != NULL) { + kls_free(default_kls); + log_tag("debug_log.txt", "[CLEANUP]", "%s(): Cleaned default_kls", __func__); + } + if (temporary_kls != NULL) { + kls_free(temporary_kls); + log_tag("debug_log.txt", "[CLEANUP]", "%s(): Cleaned temporary_kls", __func__); + } + exit(0); +} + /** * Takes a Wincon and a Path pointers and a winconClass and initialises the passed Wincon. * @see Wincon @@ -485,6 +508,8 @@ void dbg_Gamestate(Gamestate *gmst) log_tag("debug_log.txt", "[GAMESTATE]", "Current floor: {"); log_tag("debug_log.txt", "[Floor]", "index: {%i}", gmst->current_floor->index); + log_tag("debug_log.txt", "[Floor]", "from_bsp: {%s}", + (gmst->current_floor->from_bsp ? "true" : "false")); if (gmst->current_floor->desc != NULL) { log_tag("debug_log.txt", "[Floor]", "desc: {%s}", gmst->current_floor->desc); @@ -5333,7 +5358,7 @@ unsigned long hlpd_hash(unsigned char *str) * Sets the passed buffer up to be a random seed. Only chars >= 0, <= Z; not including the symbols between digits and letters. * @param buffer The buffer to set. */ -void gen_random_seed(char buffer[PATH_SEED_BUFSIZE]) +void gen_random_seed(char buffer[PATH_SEED_BUFSIZE+1]) { log_tag("debug_log.txt", "[DEBUG]", "%s(): Creating a random seed.", __func__); int len = (hlpd_rand_docount(false) % (PATH_SEED_BUFSIZE-8)) +8; // Min len should be 8 @@ -5344,7 +5369,7 @@ void gen_random_seed(char buffer[PATH_SEED_BUFSIZE]) } while (r_ch >= ':' && r_ch <= '@'); // We reject chars between the digits and upperscore letters buffer[i] = r_ch; } - buffer[PATH_SEED_BUFSIZE-1] = '\0'; + buffer[PATH_SEED_BUFSIZE] = '\0'; } /** diff --git a/src/utils/game_utils.h b/src/utils/game_utils.h index 17dcefd2..c59c6321 100644 --- a/src/utils/game_utils.h +++ b/src/utils/game_utils.h @@ -52,8 +52,10 @@ #include #include #include +#include #include "../core/game_core.h" +void ctrl_c_handler(int signum); void initWincon(Wincon * w, Path * p, winconClass class); void printGlobVars(void); @@ -306,6 +308,6 @@ void useConsumable(Fighter * f, Enemy * e, Boss * b, char *string, int isBoss); int hlpd_rand_docount(bool count); int hlpd_rand(void); unsigned long hlpd_hash(unsigned char *str); -void gen_random_seed(char buffer[PATH_SEED_BUFSIZE]); +void gen_random_seed(char buffer[PATH_SEED_BUFSIZE+1]); bool check_seed(char buffer[PATH_SEED_BUFSIZE]); #endif diff --git a/src/utils/rooms.c b/src/utils/rooms.c index d7ae60b6..a3455a22 100644 --- a/src/utils/rooms.c +++ b/src/utils/rooms.c @@ -3499,6 +3499,8 @@ void initRoom(Room *r, Fighter *f, int index, roomClass type, int enemyTotal, log_tag("debug_log.txt", "[DEBUG]", "initRoom() for BASIC"); r->class = type; log_tag("debug_log.txt", "[TODO]", "initRoom() for BASIC"); + kls_free(default_kls); + kls_free(temporary_kls); exit(EXIT_FAILURE); } break; @@ -3506,6 +3508,8 @@ void initRoom(Room *r, Fighter *f, int index, roomClass type, int enemyTotal, log_tag("debug_log.txt", "[DEBUG]", "initRoom() for WALL"); r->class = type; log_tag("debug_log.txt", "[TODO]", "initRoom() for WALL"); + kls_free(default_kls); + kls_free(temporary_kls); exit(EXIT_FAILURE); } break; diff --git a/src/utils/saves.c b/src/utils/saves.c index 82928ee0..3a355c39 100644 --- a/src/utils/saves.c +++ b/src/utils/saves.c @@ -139,10 +139,12 @@ bool set_Saveslot_name(FILE *file, Saveslot *sv) log_tag("debug_log.txt", "[WARN]", "%s(): Failed readSerGamestate() for {%s}.", __func__, path_to_sv_file); return false; } else { - strncpy(buf, ser_gmst.player.name, 50); + ser_gmst.player.name[49] = '\0'; + memcpy(buf, ser_gmst.player.name, 50); } } - strncpy(sv->name, buf, 50); + buf[49] = '\0'; + memcpy(sv->name, buf, 50); sv->name[49] = '\0'; return true; } diff --git a/stego.lock b/stego.lock index 25bc28c9..faee7f8a 100644 --- a/stego.lock +++ b/stego.lock @@ -65,3 +65,4 @@ errortestsdir = "kulpo" "1.4.3" = "Major files refactor, rooms.h drops circular dependency on helapordo.h, rl build has interactive floor generation" "1.4.4" = "Print seed, add experimental binary saves support" "1.4.5" = "Update logic to save/load RNG advancements, add seeded runs, Path holds a string seed to be used with hlpd_hash(), bump koliseo to 0.4.2, invil to 0.2.12, amboso to 2.0.6" +"1.4.6" = "Handle SIGINT, Add bsp floor layour generation, based on mtsdurica, fix terminal left in a bad state on binary save errors, bump invil to 0.2.13, koliseo to 0.4.3, s4c-scripts to 0.1.1"