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"