diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/birth.cc | 7 | ||||
-rw-r--r-- | src/cmd4.cc | 2 | ||||
-rw-r--r-- | src/game.hpp | 13 | ||||
-rw-r--r-- | src/generate.cc | 105 | ||||
-rw-r--r-- | src/init2.cc | 8 | ||||
-rw-r--r-- | src/level_marker.cc | 12 | ||||
-rw-r--r-- | src/level_marker.hpp | 25 | ||||
-rw-r--r-- | src/loadsave.cc | 26 | ||||
-rw-r--r-- | src/variable.cc | 6 | ||||
-rw-r--r-- | src/variable.hpp | 2 |
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]; |