summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2017-09-07 12:53:57 +0200
committerBardur Arantsson <bardur@scientician.net>2017-09-07 12:53:57 +0200
commit39e1689130e87732cf410aaea7458dfdc399d50e (patch)
tree1dab000e95f28816522ea0997f022ec8ca64ef40 /src
parentb4dafbb7604b8840c702455022096e8c17c8726b (diff)
Move special_level[] to Game struct
Refactor into a multi_array<> to make it more robust.
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/birth.cc7
-rw-r--r--src/cmd4.cc2
-rw-r--r--src/game.hpp13
-rw-r--r--src/generate.cc105
-rw-r--r--src/init2.cc8
-rw-r--r--src/level_marker.cc12
-rw-r--r--src/level_marker.hpp25
-rw-r--r--src/loadsave.cc26
-rw-r--r--src/variable.cc6
-rw-r--r--src/variable.hpp2
11 files changed, 152 insertions, 55 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4967e826..30ceb76c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -36,6 +36,7 @@ SET(SRCS_COMMON
init1.cc
init2.cc
joke.cc
+ level_marker.cc
levels.cc
loadsave.cc
lua_bind.cc
diff --git a/src/birth.cc b/src/birth.cc
index 7d54d3a3..f677e6e1 100644
--- a/src/birth.cc
+++ b/src/birth.cc
@@ -571,6 +571,7 @@ static void player_wipe()
auto &r_info = game->edit_data.r_info;
auto &k_info = game->edit_data.k_info;
auto &a_info = game->edit_data.a_info;
+ auto &level_markers = game->level_markers;
/* Wipe special levels */
wipe_saved();
@@ -585,11 +586,11 @@ static void player_wipe()
p_ptr->lives = 0;
/* Wipe the towns */
- for (std::size_t i = 0; i < d_info.size(); i++)
+ for (auto &&i: level_markers)
{
- for (std::size_t j = 0; j < MAX_DUNGEON_DEPTH; j++)
+ for (auto &&j: i)
{
- special_lvl[j][i] = 0;
+ j = level_marker::NORMAL;
}
}
diff --git a/src/cmd4.cc b/src/cmd4.cc
index 7c878ae7..a820da41 100644
--- a/src/cmd4.cc
+++ b/src/cmd4.cc
@@ -2758,7 +2758,7 @@ void do_cmd_feeling()
{
char buf[1024];
- if (get_dungeon_save(buf) || generate_special_feeling || (dungeon_flags & DF_DESC_ALWAYS))
+ if (get_dungeon_save(buf) || game->generate_special_feeling || (dungeon_flags & DF_DESC_ALWAYS))
{
if (!get_level_desc(buf)) msg_print("Someone forgot to describe this level!");
else msg_print(buf);
diff --git a/src/game.hpp b/src/game.hpp
index f92dbdde..4f84f52c 100644
--- a/src/game.hpp
+++ b/src/game.hpp
@@ -7,6 +7,7 @@
#include "game_edit_data.hpp"
#include "grid.hpp"
#include "h-basic.h"
+#include "level_marker.hpp"
#include "messages.hpp"
#include "player_defs.hpp"
#include "random_artifact.hpp"
@@ -14,6 +15,8 @@
#include "timer_type_fwd.hpp"
#include "wilderness_map.hpp"
+#include <boost/multi_array.hpp>
+
/**
* All structures for the game itself.
*/
@@ -81,4 +84,14 @@ struct Game {
*/
std::vector<timer_type *> timers;
+ /**
+ * Level markers for 'special' levels.
+ */
+ boost::multi_array<level_marker, 2> level_markers { };
+
+ /**
+ * Generate a special level feeling?
+ */
+ bool generate_special_feeling = false;
+
};
diff --git a/src/generate.cc b/src/generate.cc
index 3a99a7fa..ba485faf 100644
--- a/src/generate.cc
+++ b/src/generate.cc
@@ -8070,17 +8070,27 @@ static bool_ cave_gen()
bool_ build_special_level()
{
auto const &d_info = game->edit_data.d_info;
+ auto &level_markers = game->level_markers;
+
+ /* No special levels on the surface */
+ if (!dun_level)
+ {
+ return FALSE;
+ }
+
+ auto const level = dun_level - d_info[dungeon_type].mindepth;
char buf[80];
- int y, x, ystart = 2, xstart = 2;
- s16b level;
- /* No special levels on the surface */
- if (!dun_level) return FALSE;
+ if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type]))
+ {
+ return FALSE;
+ }
- level = dun_level - d_info[dungeon_type].mindepth;
- if ((!get_dungeon_save(buf)) && (special_lvl[level][dungeon_type])) return FALSE;
- if (!get_dungeon_special(buf)) return FALSE;
+ if (!get_dungeon_special(buf))
+ {
+ return FALSE;
+ }
/* Big town */
cur_hgt = MAX_HGT;
@@ -8095,9 +8105,9 @@ bool_ build_special_level()
panel_col_min = max_panel_cols * (SCREEN_WID / 2);
/* Start with perm walls */
- for (y = 0; y < cur_hgt; y++)
+ for (int y = 0; y < cur_hgt; y++)
{
- for (x = 0; x < cur_wid; x++)
+ for (int x = 0; x < cur_wid; x++)
{
cave_set_feat(y, x, FEAT_PERM_SOLID);
}
@@ -8109,10 +8119,12 @@ bool_ build_special_level()
get_mon_num_prep();
init_flags = INIT_CREATE_DUNGEON | INIT_POSITION;
+ int ystart = 2;
+ int xstart = 2;
process_dungeon_file(buf, &ystart, &xstart, cur_hgt, cur_wid, TRUE, TRUE);
- special_lvl[level][dungeon_type] = REGEN_HACK;
- generate_special_feeling = TRUE;
+ game->level_markers[level][dungeon_type] = level_marker::REGENERATE;
+ game->generate_special_feeling = true;
/* Special feeling because it's special */
good_item_flag = TRUE;
@@ -8133,26 +8145,36 @@ bool_ build_special_level()
static void wipe_special_level()
{
auto const &d_info = game->edit_data.d_info;
-
- s16b level;
- char buf[80];
+ auto &level_markers = game->level_markers;
/* No special levels on the surface */
- if (!dun_level) return;
+ if (!dun_level)
+ {
+ return;
+ }
+ /* Fire off hooks */
process_hooks_new(HOOK_LEVEL_REGEN, NULL, NULL);
/* Calculate relative depth */
- level = dun_level - d_info[dungeon_type].mindepth;
+ auto const level = dun_level - d_info[dungeon_type].mindepth;
- /* No special level at this depth */
- if ((!get_dungeon_save(buf)) &&
- special_lvl[level][dungeon_type]) return;
- if (!get_dungeon_special(buf)) return;
+ /* No special level at this depth? */
+ char buf[80];
+ if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type]))
+ {
+ return;
+ }
+ if (!get_dungeon_special(buf))
+ {
+ return;
+ }
/* Clear the Mega-Hack flag */
- if (special_lvl[level][dungeon_type] == REGEN_HACK)
- special_lvl[level][dungeon_type] = FALSE;
+ if (level_markers[level][dungeon_type] == level_marker::REGENERATE)
+ {
+ level_markers[level][dungeon_type] = level_marker::NORMAL;
+ }
}
/*
@@ -8161,26 +8183,36 @@ static void wipe_special_level()
static void finalise_special_level()
{
auto const &d_info = game->edit_data.d_info;
-
- s16b level;
- char buf[80];
+ auto &level_markers = game->level_markers;
/* No special levels on the surface */
- if (!dun_level) return;
+ if (!dun_level)
+ {
+ return;
+ }
+ /* Fire hooks */
process_hooks_new(HOOK_LEVEL_END_GEN, NULL, NULL);
/* Calculate relative depth */
- level = dun_level - d_info[dungeon_type].mindepth;
+ auto const level = dun_level - d_info[dungeon_type].mindepth;
- /* No special level at this depth */
- if ((!get_dungeon_save(buf)) &&
- special_lvl[level][dungeon_type]) return;
- if (!get_dungeon_special(buf)) return;
+ /* No special level at this depth? */
+ char buf[80];
+ if ((!get_dungeon_save(buf)) && !is_normal_level(level_markers[level][dungeon_type]))
+ {
+ return;
+ }
+ if (!get_dungeon_special(buf))
+ {
+ return;
+ }
/* Set the "generated" flag */
- if (special_lvl[level][dungeon_type] == REGEN_HACK)
- special_lvl[level][dungeon_type] = TRUE;
+ if (level_markers[level][dungeon_type] == level_marker::REGENERATE)
+ {
+ level_markers[level][dungeon_type] = level_marker::SPECIAL;
+ }
}
/*
@@ -8234,6 +8266,7 @@ void generate_cave()
{
auto const &d_info = game->edit_data.d_info;
auto &a_info = game->edit_data.a_info;
+ auto const &level_markers = game->level_markers;
auto d_ptr = &d_info[dungeon_type];
int tester_1, tester_2;
@@ -8244,7 +8277,7 @@ void generate_cave()
/* The dungeon is not ready */
character_dungeon = FALSE;
- generate_special_feeling = FALSE;
+ game->generate_special_feeling = false;
/* Initialize the flags with the basic dungeon flags */
if (!dun_level)
@@ -8302,8 +8335,8 @@ void generate_cave()
/* No saved level -- generate new one */
if (!loaded)
{
- if (!get_dungeon_special(buf) ||
- !special_lvl[dun_level - d_info[dungeon_type].mindepth][dungeon_type])
+ auto const level = dun_level - d_info[dungeon_type].mindepth;
+ if (!get_dungeon_special(buf) || is_normal_level(level_markers[level][dungeon_type]))
{
get_level_flags();
}
diff --git a/src/init2.cc b/src/init2.cc
index 6e130ac4..894e4767 100644
--- a/src/init2.cc
+++ b/src/init2.cc
@@ -620,6 +620,7 @@ static errr init_other()
auto const &r_info = game->edit_data.r_info;
auto const &k_info = game->edit_data.k_info;
auto const &a_info = game->edit_data.a_info;
+ auto &level_markers = game->level_markers;
/*** Prepare the "dungeon" information ***/
@@ -647,11 +648,8 @@ static errr init_other()
/* Allocate and Wipe the max dungeon level */
max_dlv = make_array<s16b>(d_info.size());
- /* Allocate and Wipe the special levels */
- for (std::size_t i = 0; i < MAX_DUNGEON_DEPTH; i++)
- {
- special_lvl[i] = make_array<bool_>(d_info.size());
- }
+ /* Allocate level markers */
+ level_markers.resize(boost::extents[MAX_DUNGEON_DEPTH][d_info.size()]);
/* Allocate and wipe each line of the cave */
cave = new cave_type *[MAX_HGT];
diff --git a/src/level_marker.cc b/src/level_marker.cc
new file mode 100644
index 00000000..ee1d8ebe
--- /dev/null
+++ b/src/level_marker.cc
@@ -0,0 +1,12 @@
+#include "level_marker.hpp"
+
+EnumStringMap<level_marker> const &level_marker_values()
+{
+ auto static instance = new EnumStringMap<level_marker> {
+ { level_marker::NORMAL, "normal" },
+ { level_marker::SPECIAL, "special" },
+ { level_marker::REGENERATE, "regenerate" }
+ };
+
+ return *instance;
+}
diff --git a/src/level_marker.hpp b/src/level_marker.hpp
new file mode 100644
index 00000000..07925b70
--- /dev/null
+++ b/src/level_marker.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <tome/enum_string_map.hpp>
+
+/**
+ * Markers for 'special' levels.
+ */
+enum class level_marker {
+ NORMAL,
+ SPECIAL,
+ REGENERATE
+};
+
+/**
+ * Is the level "normal"?
+ */
+inline bool is_normal_level(level_marker m)
+{
+ return m == level_marker::NORMAL;
+}
+
+/**
+ * Bidrectional map between enum and strings.
+ */
+EnumStringMap<level_marker> const &level_marker_values();
diff --git a/src/loadsave.cc b/src/loadsave.cc
index 3d45bf0f..3c843a36 100644
--- a/src/loadsave.cc
+++ b/src/loadsave.cc
@@ -454,6 +454,28 @@ static void do_random_spell(random_spell *s_ptr, ls_flag_t flag)
do_std_bool(&s_ptr->untried, flag);
}
+static void do_level_marker(level_marker *marker, ls_flag_t flag)
+{
+ std::string v;
+
+ if (flag == ls_flag_t::SAVE)
+ {
+ v = level_marker_values().stringify(*marker);
+ }
+
+ do_std_string(v, flag);
+
+ if (flag == ls_flag_t::LOAD)
+ {
+ bool valid = level_marker_values().parse(v.c_str(), marker);
+ if (!valid)
+ {
+ note(fmt::format("Bad level marker: {}!", v).c_str());
+ abort();
+ }
+ }
+}
+
/*
* Misc. other data
*/
@@ -496,12 +518,12 @@ static bool_ do_extra(ls_flag_t flag)
{
for (std::size_t j = 0; j < tmp16u; j++)
{
- do_bool(&special_lvl[j][i], flag);
+ do_level_marker(&game->level_markers[j][i], flag);
}
}
}
- do_bool(&generate_special_feeling, flag);
+ do_std_bool(&game->generate_special_feeling, flag);
/* Load the quick start data */
do_quick_start(flag, game->previous_char);
diff --git a/src/variable.cc b/src/variable.cc
index 7734c26b..ae40676f 100644
--- a/src/variable.cc
+++ b/src/variable.cc
@@ -577,12 +577,6 @@ s16b plots[MAX_PLOTS];
random_quest random_quests[MAX_RANDOM_QUEST];
/*
- * Special levels
- */
-bool_ *special_lvl[MAX_DUNGEON_DEPTH];
-bool_ generate_special_feeling = FALSE;
-
-/*
* Dungeon flags
*/
DECLARE_FLAG_ZERO_IMPL(dungeon_flag_set, dungeon_flags);
diff --git a/src/variable.hpp b/src/variable.hpp
index 6dd45d0e..73d63be7 100644
--- a/src/variable.hpp
+++ b/src/variable.hpp
@@ -168,8 +168,6 @@ extern bool_ *k_allow_special;
extern bool_ *a_allow_special;
extern s16b plots[MAX_PLOTS];
extern random_quest random_quests[MAX_RANDOM_QUEST];
-extern bool_ *special_lvl[MAX_DUNGEON_DEPTH];
-extern bool_ generate_special_feeling;
DECLARE_FLAG_ZERO_INTF(dungeon_flag_set, dungeon_flags);
extern s16b schools_count;
extern school_type schools[SCHOOLS_MAX];