diff --git a/VisualStudio/Hengband/Hengband.vcxproj b/VisualStudio/Hengband/Hengband.vcxproj
index 449ba07672..6624aa990a 100644
--- a/VisualStudio/Hengband/Hengband.vcxproj
+++ b/VisualStudio/Hengband/Hengband.vcxproj
@@ -1427,6 +1427,7 @@
+
@@ -1595,7 +1596,7 @@
-
+
diff --git a/VisualStudio/Hengband/Hengband.vcxproj.filters b/VisualStudio/Hengband/Hengband.vcxproj.filters
index c4433f0e47..64c583efe3 100644
--- a/VisualStudio/Hengband/Hengband.vcxproj.filters
+++ b/VisualStudio/Hengband/Hengband.vcxproj.filters
@@ -2520,6 +2520,9 @@
monster
+
+ save
+
@@ -3824,9 +3827,6 @@
monster-floor
-
- system
-
game-option
@@ -5457,6 +5457,15 @@
floor
+
+ save
+
+
+ system\enums
+
+
+ system\enums
+
@@ -5724,6 +5733,9 @@
{a5b8bf13-a675-4500-8b4c-37ea664757eb}
+
+ {31491e27-d3e4-4605-b68a-c2c00d563479}
+
diff --git a/src/Makefile.am b/src/Makefile.am
index e53a518b57..f9c295e724 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -929,7 +929,6 @@ hengband_SOURCES = \
system/dungeon-info.cpp system/dungeon-info.h \
system/floor-type-definition.cpp system/floor-type-definition.h \
system/grid-type-definition.cpp system/grid-type-definition.h \
- system/game-option-types.h \
system/h-basic.h system/h-config.h \
system/h-system.h system/h-type.h \
system/inner-game-data.cpp system/inner-game-data.h \
@@ -943,6 +942,9 @@ hengband_SOURCES = \
system/terrain-type-definition.cpp system/terrain-type-definition.h \
system/gamevalue.h \
\
+ system/enums/game-option-page.h \
+ system/enums/grid-flow.h \
+ \
target/grid-selector.cpp target/grid-selector.h \
target/projection-path-calculator.cpp target/projection-path-calculator.h \
target/target-checker.cpp target/target-checker.h \
diff --git a/src/birth/auto-roller.cpp b/src/birth/auto-roller.cpp
index 4cbc603953..aff7d10900 100644
--- a/src/birth/auto-roller.cpp
+++ b/src/birth/auto-roller.cpp
@@ -10,12 +10,14 @@
#include "player/player-personality.h"
#include "player/player-sex.h"
#include "player/player-status-table.h"
-#include "system/game-option-types.h"
+#include "system/enums/game-option-page.h"
#include "system/player-type-definition.h"
#include "term/screen-processor.h"
#include "term/term-color-types.h"
#include "term/z-form.h"
#include "util/int-char-converter.h"
+#include
+#include
/*! オートローラの能力値的要求水準 / Autoroll limit */
int16_t stat_limit[6];
@@ -36,8 +38,8 @@ static int32_t get_autoroller_prob(int *minval)
/* 1 percent of the valid random space (60^6 && 72 item_names = { _("年齢", "age"), _("身長(cm)", "height"), _("体重(kg)", "weight"), _("社会的地位", "social class") };
clear_from(10);
put_str(_("2/4/6/8で項目選択、+/-で値の増減、Enterで次へ", "2/4/6/8 for Select, +/- for Change value, Enter for Goto next"), 11, 10);
put_str(
@@ -385,9 +384,10 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
put_str(_("体格/地位の最小値/最大値を設定して下さい。", "Set minimum/maximum attribute."), 10, 10);
put_str(_(" 項 目 最小値 最大値", " Parameter Min Max"), 13, 20);
- int mval[MAXITEMS];
- int cval[MAXITEMS];
- for (int i = 0; i < MAXITEMS; i++) {
+ constexpr auto max_items = 8;
+ int mval[max_items]{};
+ int cval[max_items]{};
+ for (int i = 0; i < max_items; i++) {
int m;
switch (i) {
case 0: /* Minimum age */
@@ -445,12 +445,12 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
mval[4] = lb_to_kg(mval[4]);
mval[5] = lb_to_kg(mval[5]);
#endif
- for (auto i = 0; i < MAXITEMS; i++) {
+ for (auto i = 0; i < max_items; i++) {
cval[i] = mval[i];
}
for (int i = 0; i < 4; i++) {
- auto buf = format("%-12s (%3d - %3d)", itemname[i], mval[i * 2], mval[i * 2 + 1]);
+ auto buf = format("%-12s (%3d - %3d)", item_names[i].data(), mval[i * 2], mval[i * 2 + 1]);
put_str(buf, 14 + i, 20);
for (int j = 0; j < 2; j++) {
buf = format(" %3d", cval[i * 2 + j]);
@@ -460,17 +460,17 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
std::string cur;
int cs = 0;
- int os = MAXITEMS;
+ int os = max_items;
while (true) {
if (cs != os) {
constexpr auto accept = _("決定する", "Accept");
- if (os == MAXITEMS) {
+ if (os == max_items) {
c_put_str(TERM_WHITE, accept, 19, 35);
} else {
c_put_str(TERM_WHITE, cur, 14 + os / 2, 45 + 8 * (os % 2));
}
- if (cs == MAXITEMS) {
+ if (cs == max_items) {
c_put_str(TERM_YELLOW, accept, 19, 35);
} else {
cur = format(" %3d", cval[cs]);
@@ -492,7 +492,7 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
case ' ':
case '\r':
case '\n':
- if (cs == MAXITEMS) {
+ if (cs == max_items) {
break;
}
cs++;
@@ -506,11 +506,11 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
break;
case '2':
case 'j':
- if (cs < MAXITEMS) {
+ if (cs < max_items) {
cs += 2;
}
- if (cs > MAXITEMS) {
- cs = MAXITEMS;
+ if (cs > max_items) {
+ cs = max_items;
}
break;
case '4':
@@ -521,13 +521,13 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
break;
case '6':
case 'l':
- if (cs < MAXITEMS) {
+ if (cs < max_items) {
cs++;
}
break;
case '-':
case '<':
- if (cs != MAXITEMS) {
+ if (cs != max_items) {
if (cs % 2) {
if (cval[cs] > cval[cs - 1]) {
cval[cs]--;
@@ -544,7 +544,7 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
break;
case '+':
case '>':
- if (cs != MAXITEMS) {
+ if (cs != max_items) {
if (cs % 2) {
if (cval[cs] < mval[cs]) {
cval[cs]++;
@@ -560,7 +560,7 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
break;
case 'm':
- if (cs != MAXITEMS) {
+ if (cs != max_items) {
if (cs % 2) {
if (cval[cs] < mval[cs]) {
cval[cs] = mval[cs];
@@ -576,7 +576,7 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
break;
case 'n':
- if (cs != MAXITEMS) {
+ if (cs != max_items) {
if (cs % 2) {
if (cval[cs] > cval[cs - 1]) {
cval[cs] = cval[cs - 1];
@@ -600,7 +600,7 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
break;
case '=':
screen_save();
- do_cmd_options_aux(player_ptr, OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
screen_load();
break;
default:
@@ -608,7 +608,7 @@ bool get_chara_limits(PlayerType *player_ptr, chara_limit_type *chara_limit_ptr)
break;
}
- if (c == ESCAPE || ((c == ' ' || c == '\r' || c == '\n') && cs == MAXITEMS)) {
+ if (c == ESCAPE || ((c == ' ' || c == '\r' || c == '\n') && cs == max_items)) {
break;
}
}
diff --git a/src/birth/birth-util.cpp b/src/birth/birth-util.cpp
index b4429e822d..70e4fa43fe 100644
--- a/src/birth/birth-util.cpp
+++ b/src/birth/birth-util.cpp
@@ -2,9 +2,10 @@
#include "cmd-io/cmd-gameoption.h"
#include "core/show-file.h"
#include "main/sound-of-music.h"
-#include "system/game-option-types.h"
+#include "system/enums/game-option-page.h"
#include "system/player-type-definition.h"
#include "term/screen-processor.h"
+#include
/*!
* @brief プレイヤー作成を中断して変愚蛮怒を終了する
@@ -19,7 +20,7 @@ void birth_quit(void)
* @param player_ptr プレイヤーへの参照ポインタ
* @param helpfile ファイル名
*/
-void show_help(PlayerType *player_ptr, concptr helpfile)
+void show_help(PlayerType *player_ptr, std::string_view helpfile)
{
screen_save();
FileDisplayer(player_ptr->name).display(true, helpfile, 0, 0);
@@ -28,7 +29,7 @@ void show_help(PlayerType *player_ptr, concptr helpfile)
void birth_help_option(PlayerType *player_ptr, char c, BirthKind bk)
{
- concptr help_file;
+ std::string help_file;
switch (bk) {
case BirthKind::RACE:
help_file = _("jraceclas.txt#TheRaces", "raceclas.txt#TheRaces");
@@ -54,7 +55,7 @@ void birth_help_option(PlayerType *player_ptr, char c, BirthKind bk)
show_help(player_ptr, help_file);
} else if (c == '=') {
screen_save();
- do_cmd_options_aux(player_ptr, OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
screen_load();
} else if (c != '2' && c != '4' && c != '6' && c != '8') {
bell();
diff --git a/src/birth/birth-util.h b/src/birth/birth-util.h
index bc3801ce96..f1ed406886 100644
--- a/src/birth/birth-util.h
+++ b/src/birth/birth-util.h
@@ -1,6 +1,6 @@
#pragma once
-#include "system/angband.h"
+#include
enum class BirthKind {
REALM,
@@ -12,5 +12,5 @@ enum class BirthKind {
class PlayerType;
void birth_quit();
-void show_help(PlayerType *player_ptr, concptr helpfile);
+void show_help(PlayerType *player_ptr, std::string_view helpfile);
void birth_help_option(PlayerType *player_ptr, char c, BirthKind bk);
diff --git a/src/birth/birth-wizard.cpp b/src/birth/birth-wizard.cpp
index a9247cfcd8..4acd808ba0 100644
--- a/src/birth/birth-wizard.cpp
+++ b/src/birth/birth-wizard.cpp
@@ -30,7 +30,7 @@
#include "player/player-status-table.h"
#include "player/player-status.h"
#include "player/process-name.h"
-#include "system/game-option-types.h"
+#include "system/enums/game-option-page.h"
#include "system/player-type-definition.h"
#include "system/redrawing-flags-updater.h"
#include "term/screen-processor.h"
@@ -47,16 +47,6 @@
#include "world/world.h"
#include
-/*!
- * オートローラーの内容を描画する間隔 /
- * How often the autoroller will update the display and pause
- * to check for user interuptions.
- * Bigger values will make the autoroller faster, but slower
- * system may have problems because the user can't stop the
- * autoroller for this number of rolls.
- */
-#define AUTOROLLER_STEP 54321L
-
static void display_initial_birth_message(PlayerType *player_ptr)
{
term_clear();
@@ -80,7 +70,7 @@ static void display_help_on_sex_select(PlayerType *player_ptr, char c)
do_cmd_help(player_ptr);
} else if (c == '=') {
screen_save();
- do_cmd_options_aux(player_ptr, OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
screen_load();
} else if (c != '4' && c != '6') {
bell();
@@ -273,7 +263,7 @@ static bool let_player_build_character(PlayerType *player_ptr)
static void display_initial_options(PlayerType *player_ptr)
{
const auto expfact_mod = static_cast(get_expfact(player_ptr)) - 100;
- int16_t adj[A_MAX];
+ int16_t adj[A_MAX]{};
for (int i = 0; i < A_MAX; i++) {
adj[i] = rp_ptr->r_adj[i] + cp_ptr->c_adj[i] + ap_ptr->a_adj[i];
}
@@ -303,7 +293,7 @@ static void display_initial_options(PlayerType *player_ptr)
clear_from(10);
screen_save();
- do_cmd_options_aux(player_ptr, OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
screen_load();
}
@@ -399,7 +389,13 @@ static bool decide_body_spec(PlayerType *player_ptr, chara_limit_type chara_limi
static bool display_auto_roller_count(PlayerType *player_ptr, const int col)
{
- if ((auto_round % AUTOROLLER_STEP) != 0) {
+ /*!
+ * @details ここで指定された回数だけロールする度にその時の結果を画面に表示する
+ * @todo この定数を定義した時代に比べて、CPUパワーが相当に上がっている.
+ * 表示部で足を引っ張っているので、タイマで数えて0.1秒/表示 くらいで良いと思われる.
+ */
+ constexpr auto roll_results_per_display = 54321;
+ if ((auto_round % roll_results_per_display) != 0) {
return false;
}
diff --git a/src/birth/character-builder.cpp b/src/birth/character-builder.cpp
index ad387ba6fb..ef1321f9a0 100644
--- a/src/birth/character-builder.cpp
+++ b/src/birth/character-builder.cpp
@@ -74,7 +74,7 @@ static void write_birth_diary(PlayerType *player_ptr)
}
if (player_ptr->element) {
- const auto mes_element = format(_("%s元素系統に%sを選択した。", "%schose %s system."), indent, get_element_title(player_ptr->element));
+ const auto mes_element = format(_("%s元素系統に%sを選択した。", "%schose %s system."), indent, get_element_title(player_ptr->element).data());
exe_write_diary(floor, DiaryKind::DESCRIPTION, 1, mes_element);
}
diff --git a/src/cmd-io/cmd-gameoption.cpp b/src/cmd-io/cmd-gameoption.cpp
index 4ae730c1e1..1fef513f70 100644
--- a/src/cmd-io/cmd-gameoption.cpp
+++ b/src/cmd-io/cmd-gameoption.cpp
@@ -14,7 +14,7 @@
#include "io/input-key-acceptor.h"
#include "io/write-diary.h"
#include "main/sound-of-music.h"
-#include "system/game-option-types.h"
+#include "system/enums/game-option-page.h"
#include "system/player-type-definition.h"
#include "system/redrawing-flags-updater.h"
#include "term/gameterm.h"
@@ -27,16 +27,16 @@
#include "view/display-messages.h"
#include "view/display-symbol.h"
#include "world/world.h"
+#include
-#define OPT_NUM 15
-
+namespace {
struct opts {
char key;
- concptr name;
+ std::string name;
int row;
};
-static opts option_fields[OPT_NUM] = {
+const std::vector option_fields = {
{ '1', _(" キー入力 オプション", "Input Options"), 3 },
{ '2', _(" マップ画面 オプション", "Map Screen Options"), 4 },
{ '3', _(" テキスト表示 オプション", "Text Display Options"), 5 },
@@ -55,6 +55,7 @@ static opts option_fields[OPT_NUM] = {
{ 'b', _(" 初期 オプション (参照のみ)", "Birth Options (Browse Only)"), 18 },
{ 'c', _(" 詐欺 オプション", "Cheat Options"), 19 },
};
+}
/*!
* @brief セーブ頻度ターンの次の値を返す
@@ -91,79 +92,65 @@ static int16_t toggle_frequency(int16_t current)
* @brief 自動セーブオプションを変更するコマンドのメインルーチン
* @param info 表示メッセージ
*/
-static void do_cmd_options_autosave(PlayerType *player_ptr, concptr info)
+static void do_cmd_options_autosave(PlayerType *player_ptr, std::string_view info)
{
- char ch;
- int i, k = 0, n = 2;
+ auto k = 0;
+ constexpr auto n = 2;
term_clear();
while (true) {
- prt(format(_("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ", "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info), 0, 0);
- for (i = 0; i < n; i++) {
+ prt(format(_("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ", "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info.data()), 0, 0);
+ for (auto i = 0; i < n; i++) {
byte a = TERM_WHITE;
if (i == k) {
a = TERM_L_BLUE;
}
- c_prt(a, format("%-48s: %s (%s)", autosave_info[i].o_desc, (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")), autosave_info[i].o_text), i + 2, 0);
+ const auto &autosave = autosave_info[i];
+ c_prt(a, format("%-48s: %s (%s)", autosave.description.data(), (*autosave.value ? _("はい ", "yes") : _("いいえ", "no ")), autosave.text.data()), i + 2, 0);
}
prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
move_cursor(k + 2, 50);
- ch = inkey();
+ auto ch = inkey();
+ auto &autosave = autosave_info[k];
switch (ch) {
- case ESCAPE: {
+ case ESCAPE:
return;
- }
-
case '-':
- case '8': {
+ case '8':
k = (n + k - 1) % n;
break;
- }
-
case ' ':
case '\n':
case '\r':
- case '2': {
+ case '2':
k = (k + 1) % n;
break;
- }
-
case 'y':
case 'Y':
- case '6': {
-
- (*autosave_info[k].o_var) = true;
+ case '6':
+ *autosave.value = true;
k = (k + 1) % n;
break;
- }
-
case 'n':
case 'N':
- case '4': {
- (*autosave_info[k].o_var) = false;
+ case '4':
+ *autosave.value = false;
k = (k + 1) % n;
break;
- }
-
case 'f':
- case 'F': {
+ case 'F':
autosave_freq = toggle_frequency(autosave_freq);
prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
break;
- }
-
- case '?': {
+ case '?':
FileDisplayer(player_ptr->name).display(true, _("joption.txt#Autosave", "option.txt#Autosave"), 0, 0);
term_clear();
break;
- }
-
- default: {
+ default:
bell();
break;
}
- }
}
}
@@ -352,8 +339,9 @@ static void do_cmd_options_cheat(const FloorType &floor, std::string_view player
a = TERM_L_BLUE;
}
- const auto yesno = *cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ");
- c_prt(enum2i(a), format("%-48s: %s (%s)", cheat_info[i].o_desc, yesno, cheat_info[i].o_text), i + 2, 0);
+ const auto &cheat = cheat_info[i];
+ const auto yesno = *cheat.value ? _("はい ", "yes") : _("いいえ", "no ");
+ c_prt(enum2i(a), format("%-48s: %s (%s)", cheat.description.data(), yesno, cheat.text.data()), i + 2, 0);
}
move_cursor(k + 2, 50);
@@ -363,6 +351,7 @@ static void do_cmd_options_cheat(const FloorType &floor, std::string_view player
ch = I2D(dir);
}
+ const auto &cheat = cheat_info[k];
switch (ch) {
case ESCAPE:
return;
@@ -385,19 +374,19 @@ static void do_cmd_options_cheat(const FloorType &floor, std::string_view player
_("詐欺オプションをONにして、スコアを残せなくなった。", "gave up sending score to use cheating options."));
}
- world.noscore |= cheat_info[k].o_set * 256 + cheat_info[k].o_bit;
- *cheat_info[k].o_var = true;
+ world.noscore |= cheat.flag_position * 256 + cheat.offset;
+ *cheat.value = true;
k = (k + 1) % n;
break;
}
case 'n':
case 'N':
case '4':
- *cheat_info[k].o_var = false;
+ *cheat.value = false;
k = (k + 1) % n;
break;
case '?':
- FileDisplayer(player_name).display(true, std::string(_("joption.txt#", "option.txt#")).append(cheat_info[k].o_text), 0, 0);
+ FileDisplayer(player_name).display(true, std::string(_("joption.txt#", "option.txt#")).append(cheat.text), 0, 0);
term_clear();
break;
default:
@@ -412,15 +401,13 @@ static void do_cmd_options_cheat(const FloorType &floor, std::string_view player
*/
void extract_option_vars(void)
{
- for (int i = 0; option_info[i].o_desc; i++) {
- int os = option_info[i].o_set;
- int ob = option_info[i].o_bit;
- if (option_info[i].o_var) {
- if (g_option_flags[os] & (1UL << ob)) {
- (*option_info[i].o_var) = true;
- } else {
- (*option_info[i].o_var) = false;
- }
+ for (auto &option : option_info) {
+ int os = option.flag_position;
+ int ob = option.offset;
+ if (g_option_flags[os] & (1UL << ob)) {
+ *option.value = true;
+ } else {
+ *option.value = false;
}
}
}
@@ -444,7 +431,7 @@ void do_cmd_options(PlayerType *player_ptr)
screen_save();
const auto &world = AngbandWorld::get_instance();
while (true) {
- int n = OPT_NUM;
+ auto n = std::ssize(option_fields);
if (!world.noscore && !allow_debug_opts) {
n--;
}
@@ -457,7 +444,7 @@ void do_cmd_options(PlayerType *player_ptr)
if (i == y) {
a = TERM_L_BLUE;
}
- term_putstr(5, option_fields[i].row, -1, a, format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
+ term_putstr(5, option_fields[i].row, -1, a, format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name.data()));
}
prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to , Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
@@ -510,37 +497,37 @@ void do_cmd_options(PlayerType *player_ptr)
switch (k) {
case '1': {
- do_cmd_options_aux(player_ptr, OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::INPUT, _("キー入力オプション", "Input Options"));
break;
}
case '2': {
- do_cmd_options_aux(player_ptr, OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
break;
}
case '3': {
- do_cmd_options_aux(player_ptr, OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::TEXT, _("テキスト表示オプション", "Text Display Options"));
break;
}
case '4': {
- do_cmd_options_aux(player_ptr, OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
break;
}
case '5': {
- do_cmd_options_aux(player_ptr, OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
break;
}
case '6': {
- do_cmd_options_aux(player_ptr, OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
break;
}
case 'R':
case 'r': {
- do_cmd_options_aux(player_ptr, OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
break;
}
case 'B':
case 'b': {
- do_cmd_options_aux(player_ptr, OPT_PAGE_BIRTH,
+ do_cmd_options_aux(player_ptr, GameOptionPage::BIRTH,
(!world.wizard || !allow_debug_opts) ? _("初期オプション(参照のみ)", "Birth Options(browse only)")
: _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
break;
@@ -646,54 +633,57 @@ void do_cmd_options(PlayerType *player_ptr)
}
/*!
- * @brief 標準オプションを変更するコマンドのサブルーチン /
- * Interact with some options
+ * @brief 標準オプションを変更するコマンドのサブルーチン
* @param page オプションページ番号
* @param info 表示メッセージ
*/
-void do_cmd_options_aux(PlayerType *player_ptr, game_option_types page, concptr info)
+void do_cmd_options_aux(PlayerType *player_ptr, GameOptionPage page, std::string_view info)
{
char ch;
- int i, k = 0, n = 0, l;
+ int k = 0, n = 0, l;
int opt[MAIN_TERM_MIN_ROWS]{};
const auto &world = AngbandWorld::get_instance();
- const auto browse_only = (page == OPT_PAGE_BIRTH) && world.character_generated && (!world.wizard || !allow_debug_opts);
- for (i = 0; i < MAIN_TERM_MIN_ROWS; i++) {
+ const auto browse_only = (page == GameOptionPage::BIRTH) && world.character_generated && (!world.wizard || !allow_debug_opts);
+ for (auto i = 0; i < MAIN_TERM_MIN_ROWS; i++) {
opt[i] = 0;
}
- for (i = 0; option_info[i].o_desc; i++) {
- if (option_info[i].o_page == page) {
- opt[n++] = i;
+ auto option_num = 0;
+ for (auto &option : option_info) {
+ if (option.page == page) {
+ opt[n++] = option_num;
}
+
+ option_num++;
}
term_clear();
while (true) {
DIRECTION dir;
constexpr auto command = _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) ");
- prt(format(command, info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept")), 0, 0);
- if (page == OPT_PAGE_AUTODESTROY) {
+ prt(format(command, info.data(), browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept")), 0, 0);
+ if (page == GameOptionPage::AUTODESTROY) {
constexpr auto mes = _("以下のオプションは、簡易自動破壊を使用するときのみ有効", "Following options will protect items from easy auto-destroyer.");
c_prt(TERM_YELLOW, mes, 6, _(6, 3));
}
- for (i = 0; i < n; i++) {
+ for (auto i = 0; i < n; i++) {
byte a = TERM_WHITE;
if (i == k) {
a = TERM_L_BLUE;
}
- const auto reply = *option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ");
- const auto label = format("%-48s: %s (%.19s)", option_info[opt[i]].o_desc, reply, option_info[opt[i]].o_text);
- if ((page == OPT_PAGE_AUTODESTROY) && i > 2) {
+ const auto &option = option_info[opt[i]];
+ const auto reply = *option.value ? _("はい ", "yes") : _("いいえ", "no ");
+ const auto label = format("%-48s: %s (%.19s)", option.description.data(), reply, option.text.data());
+ if ((page == GameOptionPage::AUTODESTROY) && i > 2) {
c_prt(a, label, i + 5, 0);
} else {
c_prt(a, label, i + 2, 0);
}
}
- if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) {
+ if ((page == GameOptionPage::AUTODESTROY) && (k > 2)) {
l = 3;
} else {
l = 0;
@@ -706,58 +696,54 @@ void do_cmd_options_aux(PlayerType *player_ptr, game_option_types page, concptr
ch = I2D(dir);
}
+ const auto &option = option_info[opt[k]];
switch (ch) {
- case ESCAPE: {
+ case ESCAPE:
return;
- }
case '-':
- case '8': {
+ case '8':
k = (n + k - 1) % n;
break;
- }
case ' ':
case '\n':
case '\r':
- case '2': {
+ case '2':
k = (k + 1) % n;
break;
- }
case 'y':
case 'Y':
- case '6': {
+ case '6':
if (browse_only) {
break;
}
- (*option_info[opt[k]].o_var) = true;
+
+ *option.value = true;
k = (k + 1) % n;
break;
- }
case 'n':
case 'N':
- case '4': {
+ case '4':
if (browse_only) {
break;
}
- (*option_info[opt[k]].o_var) = false;
+
+ *option.value = false;
k = (k + 1) % n;
break;
- }
case 't':
- case 'T': {
+ case 'T':
if (!browse_only) {
- (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
+ *option.value = !*option.value;
}
+
break;
- }
- case '?': {
- FileDisplayer(player_ptr->name).display(true, std::string(_("joption.txt#", "option.txt#")).append(option_info[opt[k]].o_text), 0, 0);
+ case '?':
+ FileDisplayer(player_ptr->name).display(true, std::string(_("joption.txt#", "option.txt#")).append(option.text), 0, 0);
term_clear();
break;
- }
- default: {
+ default:
bell();
break;
}
- }
}
}
diff --git a/src/cmd-io/cmd-gameoption.h b/src/cmd-io/cmd-gameoption.h
index 006b44a2ae..cf777779ee 100644
--- a/src/cmd-io/cmd-gameoption.h
+++ b/src/cmd-io/cmd-gameoption.h
@@ -1,9 +1,9 @@
#pragma once
-#include "system/angband.h"
-#include "system/game-option-types.h"
+#include
+enum class GameOptionPage : int;
class PlayerType;
void extract_option_vars();
-void do_cmd_options_aux(PlayerType *player_ptr, game_option_types page, concptr info);
+void do_cmd_options_aux(PlayerType *player_ptr, GameOptionPage page, std::string_view info);
void do_cmd_options(PlayerType *player_ptr);
diff --git a/src/game-option/option-types-table.cpp b/src/game-option/option-types-table.cpp
index 82919072ba..0936e70f9f 100644
--- a/src/game-option/option-types-table.cpp
+++ b/src/game-option/option-types-table.cpp
@@ -9,325 +9,335 @@
#include "game-option/play-record-options.h"
#include "game-option/special-options.h"
#include "game-option/text-display-options.h"
-#include "system/game-option-types.h"
+#include "locale/language-switcher.h"
+#include "system/enums/game-option-page.h"
+#include
+
+GameOption::GameOption(bool *value, bool norm, uint8_t set, uint8_t bits, std::string &&text, std::string &&description, const std::optional &page)
+ : value(value)
+ , default_value(norm)
+ , flag_position(set)
+ , offset(bits)
+ , text(std::move(text))
+ , description(std::move(description))
+ , page(page)
+{
+}
/*!
* @brief オプションテーブル /
* Available Options
*/
-const std::vector option_info = {
+const std::vector option_info = {
/*** Input Options ***/
- { &rogue_like_commands, false, OPT_PAGE_INPUT, 0, 0, "rogue_like_commands", _("ローグ風キー配置を使用する", "Rogue-like commands") },
+ { &rogue_like_commands, false, 0, 0, "rogue_like_commands", _("ローグ風キー配置を使用する", "Rogue-like commands"), GameOptionPage::INPUT },
- { &always_pickup, false, OPT_PAGE_INPUT, 0, 5, "always_pickup", _("常にアイテムを拾う", "Pick things up by default") },
+ { &always_pickup, false, 0, 5, "always_pickup", _("常にアイテムを拾う", "Pick things up by default"), GameOptionPage::INPUT },
- { &carry_query_flag, false, OPT_PAGE_INPUT, 0, 3, "carry_query_flag", _("アイテムを拾う前に確認する", "Prompt before picking things up") },
+ { &carry_query_flag, false, 0, 3, "carry_query_flag", _("アイテムを拾う前に確認する", "Prompt before picking things up"), GameOptionPage::INPUT },
- { &quick_messages, true, OPT_PAGE_INPUT, 0, 1, "quick_messages", _("クイック・メッセージを使用する", "Activate quick messages") },
+ { &quick_messages, true, 0, 1, "quick_messages", _("クイック・メッセージを使用する", "Activate quick messages"), GameOptionPage::INPUT },
- { &auto_more, false, OPT_PAGE_INPUT, 2, 6, "auto_more", _("キー待ちしないで連続でメッセージを表示する", "Automatically clear '-more-' prompts") },
+ { &auto_more, false, 2, 6, "auto_more", _("キー待ちしないで連続でメッセージを表示する", "Automatically clear '-more-' prompts"), GameOptionPage::INPUT },
- { &skip_more, false, OPT_PAGE_INPUT, 2, 18, "skip_more", _("キー待ちしないで全てのメッセージを読み飛ばす", "Automatically skip all messages.") },
+ { &skip_more, false, 2, 18, "skip_more", _("キー待ちしないで全てのメッセージを読み飛ばす", "Automatically skip all messages."), GameOptionPage::INPUT },
- { &command_menu, true, OPT_PAGE_INPUT, 2, 7, "command_menu", _("メニューによりコマンド選択を有効にする", "Enable command selection menu") },
+ { &command_menu, true, 2, 7, "command_menu", _("メニューによりコマンド選択を有効にする", "Enable command selection menu"), GameOptionPage::INPUT },
- { &other_query_flag, false, OPT_PAGE_INPUT, 0, 2, "other_query_flag", _("床上のアイテムを使用するときに確認する", "Prompt for floor item selection") },
+ { &other_query_flag, false, 0, 2, "other_query_flag", _("床上のアイテムを使用するときに確認する", "Prompt for floor item selection"), GameOptionPage::INPUT },
- { &use_old_target, false, OPT_PAGE_INPUT, 0, 4, "use_old_target", _("常に以前のターゲットを指定する", "Use old target by default") },
+ { &use_old_target, false, 0, 4, "use_old_target", _("常に以前のターゲットを指定する", "Use old target by default"), GameOptionPage::INPUT },
- { &always_repeat, true, OPT_PAGE_INPUT, 0, 6, "always_repeat", _("コマンド自動繰り返し", "Repeat obvious commands") },
+ { &always_repeat, true, 0, 6, "always_repeat", _("コマンド自動繰り返し", "Repeat obvious commands"), GameOptionPage::INPUT },
- { &confirm_destroy, false, OPT_PAGE_INPUT, 5, 3, "confirm_destroy",
- _("「無価値」なアイテムを破壊する時確認する", "Prompt for destruction of known worthless items") },
+ { &confirm_destroy, false, 5, 3, "confirm_destroy",
+ _("「無価値」なアイテムを破壊する時確認する", "Prompt for destruction of known worthless items"), GameOptionPage::INPUT },
- { &confirm_wear, true, OPT_PAGE_INPUT, 5, 4, "confirm_wear", _("呪われた物を装備する時確認する", "Confirm to wear/wield known cursed items") },
+ { &confirm_wear, true, 5, 4, "confirm_wear", _("呪われた物を装備する時確認する", "Confirm to wear/wield known cursed items"), GameOptionPage::INPUT },
- { &confirm_quest, true, OPT_PAGE_INPUT, 1, 9, "confirm_quest", _("クエストを諦めて階段で逃げる前に確認する", "Prompt before exiting a quest level") },
+ { &confirm_quest, true, 1, 9, "confirm_quest", _("クエストを諦めて階段で逃げる前に確認する", "Prompt before exiting a quest level"), GameOptionPage::INPUT },
- { &target_pet, false, OPT_PAGE_INPUT, 2, 5, "target_pet", _("ペットをターゲットにする", "Allow targeting pets") },
+ { &target_pet, false, 2, 5, "target_pet", _("ペットをターゲットにする", "Allow targeting pets"), GameOptionPage::INPUT },
- { &easy_open, true, OPT_PAGE_INPUT, 5, 7, "easy_open", _("自動的にドアを開ける", "Automatically open doors") },
+ { &easy_open, true, 5, 7, "easy_open", _("自動的にドアを開ける", "Automatically open doors"), GameOptionPage::INPUT },
- { &easy_disarm, true, OPT_PAGE_INPUT, 5, 8, "easy_disarm", _("自動的に罠を解除する", "Automatically disarm traps") },
+ { &easy_disarm, true, 5, 8, "easy_disarm", _("自動的に罠を解除する", "Automatically disarm traps"), GameOptionPage::INPUT },
- { &easy_floor, true, OPT_PAGE_INPUT, 5, 9, "easy_floor", _("床上で重なったアイテムをリストする", "Display floor stacks in a list") },
+ { &easy_floor, true, 5, 9, "easy_floor", _("床上で重なったアイテムをリストする", "Display floor stacks in a list"), GameOptionPage::INPUT },
- { &use_command, false, OPT_PAGE_INPUT, 5, 10, "use_command", _("「使う(a)」コマンドでアイテムを何でも使える", "Allow unified use command") },
+ { &use_command, false, 5, 10, "use_command", _("「使う(a)」コマンドでアイテムを何でも使える", "Allow unified use command"), GameOptionPage::INPUT },
- { &over_exert, false, OPT_PAGE_INPUT, 0, 29, "over_exert", _("MPが足りなくても魔法に挑戦する", "Allow casting spells when short of mana") },
+ { &over_exert, false, 0, 29, "over_exert", _("MPが足りなくても魔法に挑戦する", "Allow casting spells when short of mana"), GameOptionPage::INPUT },
- { &numpad_as_cursorkey, true, OPT_PAGE_INPUT, 2, 31, "numpad_as_cursorkey",
- _("エディタ内でテンキーをカーソルキーとして使う", "Use numpad keys as cursor keys in editor mode") },
+ { &numpad_as_cursorkey, true, 2, 31, "numpad_as_cursorkey",
+ _("エディタ内でテンキーをカーソルキーとして使う", "Use numpad keys as cursor keys in editor mode"), GameOptionPage::INPUT },
/*** Map Screen Options ***/
- { ¢er_player, false, OPT_PAGE_MAPSCREEN, 5, 11, "center_player", _("常にプレイヤーを中心に置く(*遅い*)", "Center map while walking (*slow*)") },
+ { ¢er_player, false, 5, 11, "center_player", _("常にプレイヤーを中心に置く(*遅い*)", "Center map while walking (*slow*)"), GameOptionPage::MAPSCREEN },
- { ¢er_running, true, OPT_PAGE_MAPSCREEN, 5, 12, "center_running", _("走っている時でも中心に置く", "Centering even while running") },
+ { ¢er_running, true, 5, 12, "center_running", _("走っている時でも中心に置く", "Centering even while running"), GameOptionPage::MAPSCREEN },
- { &view_yellow_lite, true, OPT_PAGE_MAPSCREEN, 1, 28, "view_yellow_lite", _("明かりの範囲を特別な色で表示する", "Use special colors for torch-lit grids") },
+ { &view_yellow_lite, true, 1, 28, "view_yellow_lite", _("明かりの範囲を特別な色で表示する", "Use special colors for torch-lit grids"), GameOptionPage::MAPSCREEN },
- { &view_bright_lite, true, OPT_PAGE_MAPSCREEN, 1, 29, "view_bright_lite", _("視界の範囲を特別な色で表示する", "Use special colors for 'viewable' grids") },
+ { &view_bright_lite, true, 1, 29, "view_bright_lite", _("視界の範囲を特別な色で表示する", "Use special colors for 'viewable' grids"), GameOptionPage::MAPSCREEN },
- { &view_granite_lite, true, OPT_PAGE_MAPSCREEN, 1, 30, "view_granite_lite", _("壁を特別な色で表示する(重い)", "Use special colors for wall grids (slow)") },
+ { &view_granite_lite, true, 1, 30, "view_granite_lite", _("壁を特別な色で表示する(重い)", "Use special colors for wall grids (slow)"), GameOptionPage::MAPSCREEN },
- { &view_special_lite, true, OPT_PAGE_MAPSCREEN, 1, 31, "view_special_lite",
- _("床を特別な色で表示する(重い)", "Use special colors for floor grids (slow)") },
+ { &view_special_lite, true, 1, 31, "view_special_lite",
+ _("床を特別な色で表示する(重い)", "Use special colors for floor grids (slow)"), GameOptionPage::MAPSCREEN },
- { &view_perma_grids, true, OPT_PAGE_MAPSCREEN, 1, 6, "view_perma_grids", _("明るい場所はそのままにする", "Map remembers all perma-lit grids") },
+ { &view_perma_grids, true, 1, 6, "view_perma_grids", _("明るい場所はそのままにする", "Map remembers all perma-lit grids"), GameOptionPage::MAPSCREEN },
- { &view_torch_grids, false, OPT_PAGE_MAPSCREEN, 1, 7, "view_torch_grids", _("明かりで照らした場所はそのままにする", "Map remembers all torch-lit grids") },
+ { &view_torch_grids, false, 1, 7, "view_torch_grids", _("明かりで照らした場所はそのままにする", "Map remembers all torch-lit grids"), GameOptionPage::MAPSCREEN },
- { &view_unsafe_grids, true, OPT_PAGE_MAPSCREEN, 1, 8, "view_unsafe_grids", _("トラップ感知済みでない場所を表示する", "Map marked by detect traps") },
+ { &view_unsafe_grids, true, 1, 8, "view_unsafe_grids", _("トラップ感知済みでない場所を表示する", "Map marked by detect traps"), GameOptionPage::MAPSCREEN },
- { &view_hidden_walls, true, OPT_PAGE_MAPSCREEN, 1, 2, "view_hidden_walls", _("壁の中に囲まれた壁を表示する", "Map walls hidden in other walls") },
+ { &view_hidden_walls, true, 1, 2, "view_hidden_walls", _("壁の中に囲まれた壁を表示する", "Map walls hidden in other walls"), GameOptionPage::MAPSCREEN },
- { &view_unsafe_walls, false, OPT_PAGE_MAPSCREEN, 1, 1, "view_unsafe_walls", _("トラップ未感知の壁の中に囲まれた壁を表示する", "Map hidden walls not marked by detect traps") },
+ { &view_unsafe_walls, false, 1, 1, "view_unsafe_walls", _("トラップ未感知の壁の中に囲まれた壁を表示する", "Map hidden walls not marked by detect traps"), GameOptionPage::MAPSCREEN },
- { &view_reduce_view, false, OPT_PAGE_MAPSCREEN, 1, 17, "view_reduce_view", _("街では視野を狭くする", "Reduce view-radius in town") },
+ { &view_reduce_view, false, 1, 17, "view_reduce_view", _("街では視野を狭くする", "Reduce view-radius in town"), GameOptionPage::MAPSCREEN },
- { &fresh_before, true, OPT_PAGE_MAPSCREEN, 1, 23, "fresh_before", _("連続コマンド中に画面を再描画し続ける", "Flush output while in repeated command") },
+ { &fresh_before, true, 1, 23, "fresh_before", _("連続コマンド中に画面を再描画し続ける", "Flush output while in repeated command"), GameOptionPage::MAPSCREEN },
- { &fresh_after, false, OPT_PAGE_MAPSCREEN, 1, 24, "fresh_after", _("コマンド後に画面を常に再描画し続ける", "Flush output after monster's move") },
+ { &fresh_after, false, 1, 24, "fresh_after", _("コマンド後に画面を常に再描画し続ける", "Flush output after monster's move"), GameOptionPage::MAPSCREEN },
- { &fresh_once, false, OPT_PAGE_MAPSCREEN, 1, 10, "fresh_once", _("キー入力毎に一度だけ画面を再描画する", "Flush output once per key input") },
+ { &fresh_once, false, 1, 10, "fresh_once", _("キー入力毎に一度だけ画面を再描画する", "Flush output once per key input"), GameOptionPage::MAPSCREEN },
- { &fresh_message, false, OPT_PAGE_MAPSCREEN, 1, 25, "fresh_message", _("メッセージの後に画面を再描画する", "Flush output after every message") },
+ { &fresh_message, false, 1, 25, "fresh_message", _("メッセージの後に画面を再描画する", "Flush output after every message"), GameOptionPage::MAPSCREEN },
- { &hilite_player, false, OPT_PAGE_MAPSCREEN, 1, 27, "hilite_player", _("プレイヤーにカーソルを合わせる", "Highlight the player with the cursor") },
+ { &hilite_player, false, 1, 27, "hilite_player", _("プレイヤーにカーソルを合わせる", "Highlight the player with the cursor"), GameOptionPage::MAPSCREEN },
- { &display_path, true, OPT_PAGE_MAPSCREEN, 2, 8, "display_path", _("魔法や矢の軌跡を表示する", "Display actual path before shooting") },
+ { &display_path, true, 2, 8, "display_path", _("魔法や矢の軌跡を表示する", "Display actual path before shooting"), GameOptionPage::MAPSCREEN },
/*** Text Display Options ***/
- { &plain_descriptions, true, OPT_PAGE_TEXT, 5, 1, "plain_descriptions", _("アイテムの記述を簡略にする", "Plain object descriptions") },
+ { &plain_descriptions, true, 5, 1, "plain_descriptions", _("アイテムの記述を簡略にする", "Plain object descriptions"), GameOptionPage::TEXT },
- { &plain_pickup, false, OPT_PAGE_TEXT, 6, 6, "plain_pickup", _("「拾った」メッセージを簡略化する", "Plain pickup messages(japanese only)") },
+ { &plain_pickup, false, 6, 6, "plain_pickup", _("「拾った」メッセージを簡略化する", "Plain pickup messages(japanese only)"), GameOptionPage::TEXT },
- { &always_show_list, true, OPT_PAGE_TEXT, 4, 0, "always_show_list", _("選択時には常に一覧を表示する", "Always show list when choosing items") },
+ { &always_show_list, true, 4, 0, "always_show_list", _("選択時には常に一覧を表示する", "Always show list when choosing items"), GameOptionPage::TEXT },
- { &depth_in_feet, false, OPT_PAGE_TEXT, 0, 7, "depth_in_feet", _("ダンジョンの深さをフィートで表示する", "Show dungeon level in feet") },
+ { &depth_in_feet, false, 0, 7, "depth_in_feet", _("ダンジョンの深さをフィートで表示する", "Show dungeon level in feet"), GameOptionPage::TEXT },
- { &show_labels, true, OPT_PAGE_TEXT, 0, 10, "show_labels", _("装備一覧で装備場所を表示する", "Show labels in object listings") },
+ { &show_labels, true, 0, 10, "show_labels", _("装備一覧で装備場所を表示する", "Show labels in object listings"), GameOptionPage::TEXT },
- { &show_weights, true, OPT_PAGE_TEXT, 0, 11, "show_weights", _("アイテム一覧で重量を表示する", "Show weights in object listings") },
+ { &show_weights, true, 0, 11, "show_weights", _("アイテム一覧で重量を表示する", "Show weights in object listings"), GameOptionPage::TEXT },
- { &show_item_graph, true, OPT_PAGE_TEXT, 2, 0, "show_item_graph", _("アイテムのシンボルを表示する", "Show items graphics") },
+ { &show_item_graph, true, 2, 0, "show_item_graph", _("アイテムのシンボルを表示する", "Show items graphics"), GameOptionPage::TEXT },
- { &equippy_chars, true, OPT_PAGE_TEXT, 1, 12, "equippy_chars", _("ステータスに文字で装備を表示する", "Display 'equippy' chars") },
+ { &equippy_chars, true, 1, 12, "equippy_chars", _("ステータスに文字で装備を表示する", "Display 'equippy' chars"), GameOptionPage::TEXT },
- { &display_mutations, false, OPT_PAGE_TEXT, 5, 0, "display_mutations", _("'C'コマンドで突然変異を表示する", "Display mutations in 'C'haracter Display") },
+ { &display_mutations, false, 5, 0, "display_mutations", _("'C'コマンドで突然変異を表示する", "Display mutations in 'C'haracter Display"), GameOptionPage::TEXT },
- { &compress_savefile, false, OPT_PAGE_TEXT, 1, 26, "compress_savefile", _("セーブ・ファイル中のメッセージを圧縮する", "Compress messages in savefiles") },
+ { &compress_savefile, false, 1, 26, "compress_savefile", _("セーブ・ファイル中のメッセージを圧縮する", "Compress messages in savefiles"), GameOptionPage::TEXT },
- { &abbrev_extra, false, OPT_PAGE_TEXT, 2, 10, "abbrev_extra",
- _("アイテムに追加耐性/能力の略称を刻む", "Describe obj's extra resistances by abbreviation") },
+ { &abbrev_extra, false, 2, 10, "abbrev_extra",
+ _("アイテムに追加耐性/能力の略称を刻む", "Describe obj's extra resistances by abbreviation"), GameOptionPage::TEXT },
- { &abbrev_all, true, OPT_PAGE_TEXT, 2, 11, "abbrev_all", _("アイテムに全ての耐性/能力の略称を刻む", "Describe obj's all resistances by abbreviation") },
+ { &abbrev_all, true, 2, 11, "abbrev_all", _("アイテムに全ての耐性/能力の略称を刻む", "Describe obj's all resistances by abbreviation"), GameOptionPage::TEXT },
- { &exp_need, false, OPT_PAGE_TEXT, 2, 12, "exp_need", _("次のレベルに必要な経験値を表示する", "Show the experience needed for next level") },
+ { &exp_need, false, 2, 12, "exp_need", _("次のレベルに必要な経験値を表示する", "Show the experience needed for next level"), GameOptionPage::TEXT },
- { &ignore_unview, false, OPT_PAGE_TEXT, 2, 13, "ignore_unview", _("視界外のモンスターの行動を表示しない", "Ignore out-of-sight monster behavior") },
+ { &ignore_unview, false, 2, 13, "ignore_unview", _("視界外のモンスターの行動を表示しない", "Ignore out-of-sight monster behavior"), GameOptionPage::TEXT },
- { &show_ammo_detail, true, OPT_PAGE_TEXT, 2, 14, "show_ammo_detail", _("矢弾のダメージの説明を表示する", "Show description of ammo damage") },
+ { &show_ammo_detail, true, 2, 14, "show_ammo_detail", _("矢弾のダメージの説明を表示する", "Show description of ammo damage"), GameOptionPage::TEXT },
- { &show_ammo_no_crit, false, OPT_PAGE_TEXT, 2, 15, "show_ammo_no_crit",
- _("会心を考慮しない場合の矢弾のダメージを表示する", "Show ammo damage with no critical") },
+ { &show_ammo_no_crit, false, 2, 15, "show_ammo_no_crit",
+ _("会心を考慮しない場合の矢弾のダメージを表示する", "Show ammo damage with no critical"), GameOptionPage::TEXT },
- { &show_ammo_crit_ratio, false, OPT_PAGE_TEXT, 2, 16, "show_ammo_crit_ratio", _("矢弾の会心発生率を表示する", "Show critical ratio of ammo") },
+ { &show_ammo_crit_ratio, false, 2, 16, "show_ammo_crit_ratio", _("矢弾の会心発生率を表示する", "Show critical ratio of ammo"), GameOptionPage::TEXT },
- { &show_actual_value, true, OPT_PAGE_TEXT, 2, 17, "show_actual_value", _("技能値等に実値を並記する", "Show actual values of skills or etc.") },
+ { &show_actual_value, true, 2, 17, "show_actual_value", _("技能値等に実値を並記する", "Show actual values of skills or etc."), GameOptionPage::TEXT },
/*** Game-Play ***/
- { &stack_force_notes, true, OPT_PAGE_GAMEPLAY, 0, 8, "stack_force_notes", _("異なる銘のアイテムをまとめる", "Merge inscriptions when stacking") },
+ { &stack_force_notes, true, 0, 8, "stack_force_notes", _("異なる銘のアイテムをまとめる", "Merge inscriptions when stacking"), GameOptionPage::GAMEPLAY },
- { &stack_force_costs, false, OPT_PAGE_GAMEPLAY, 0, 9, "stack_force_costs", _("異なる割引表示のアイテムをまとめる", "Merge discounts when stacking") },
+ { &stack_force_costs, false, 0, 9, "stack_force_costs", _("異なる割引表示のアイテムをまとめる", "Merge discounts when stacking"), GameOptionPage::GAMEPLAY },
- { &expand_list, true, OPT_PAGE_GAMEPLAY, 1, 5, "expand_list", _("「一覧」コマンドを拡張する", "Expand the power of the list commands") },
+ { &expand_list, true, 1, 5, "expand_list", _("「一覧」コマンドを拡張する", "Expand the power of the list commands"), GameOptionPage::GAMEPLAY },
- { &small_levels, true, OPT_PAGE_GAMEPLAY, 0, 30, "small_levels", _("非常に小さいフロアの生成を可能にする", "Allow unusually small dungeon levels") },
+ { &small_levels, true, 0, 30, "small_levels", _("非常に小さいフロアの生成を可能にする", "Allow unusually small dungeon levels"), GameOptionPage::GAMEPLAY },
- { &always_small_levels, false, OPT_PAGE_GAMEPLAY, 2, 3, "always_small_levels",
- _("常に非常に小さいフロアを生成する", "Always create unusually small dungeon levels") },
+ { &always_small_levels, false, 2, 3, "always_small_levels",
+ _("常に非常に小さいフロアを生成する", "Always create unusually small dungeon levels"), GameOptionPage::GAMEPLAY },
- { &empty_levels, true, OPT_PAGE_GAMEPLAY, 0, 31, "empty_levels", _("空っぽの「アリーナ」レベルの生成を可能にする", "Allow empty 'arena' levels") },
+ { &empty_levels, true, 0, 31, "empty_levels", _("空っぽの「アリーナ」レベルの生成を可能にする", "Allow empty 'arena' levels"), GameOptionPage::GAMEPLAY },
- { &bound_walls_perm, true, OPT_PAGE_GAMEPLAY, 2, 1, "bound_walls_perm", _("ダンジョンの外壁を永久岩にする", "Boundary walls become 'permanent wall'") },
+ { &bound_walls_perm, true, 2, 1, "bound_walls_perm", _("ダンジョンの外壁を永久岩にする", "Boundary walls become 'permanent wall'"), GameOptionPage::GAMEPLAY },
- { &last_words, true, OPT_PAGE_GAMEPLAY, 0, 28, "last_words", _("キャラクターが死んだ時遺言をのこす", "Leave last words when your character dies") },
+ { &last_words, true, 0, 28, "last_words", _("キャラクターが死んだ時遺言をのこす", "Leave last words when your character dies"), GameOptionPage::GAMEPLAY },
- { &auto_dump, false, OPT_PAGE_GAMEPLAY, 4, 5, "auto_dump", _("自動的にキャラクターの記録をファイルに書き出す", "Dump a character record automatically") },
+ { &auto_dump, false, 4, 5, "auto_dump", _("自動的にキャラクターの記録をファイルに書き出す", "Dump a character record automatically"), GameOptionPage::GAMEPLAY },
#ifdef WORLD_SCORE
- { &send_score, true, OPT_PAGE_GAMEPLAY, 4, 6, "send_score", _("スコアサーバにスコアを送る", "Send score dump to the world score server") },
+ { &send_score, true, 4, 6, "send_score", _("スコアサーバにスコアを送る", "Send score dump to the world score server"), GameOptionPage::GAMEPLAY },
#else
- { &send_score, false, OPT_PAGE_HIDE, 4, 6, "send_score", _("スコアサーバにスコアを送る", "Send score dump to the world score server") },
+ { &send_score, false, 4, 6, "send_score", _("スコアサーバにスコアを送る", "Send score dump to the world score server"), GameOptionPage::HIDE },
#endif
- { &allow_debug_opts, false, OPT_PAGE_GAMEPLAY, 6, 11, "allow_debug_opts", _("デバッグ/詐欺オプションを許可する", "Allow use of debug/cheat options") },
+ { &allow_debug_opts, false, 6, 11, "allow_debug_opts", _("デバッグ/詐欺オプションを許可する", "Allow use of debug/cheat options"), GameOptionPage::GAMEPLAY },
/*** Disturbance ***/
- { &find_ignore_stairs, false, OPT_PAGE_DISTURBANCE, 0, 16, "find_ignore_stairs", _("階段は通過する", "Run past stairs") },
+ { &find_ignore_stairs, false, 0, 16, "find_ignore_stairs", _("階段は通過する", "Run past stairs"), GameOptionPage::DISTURBANCE },
- { &find_ignore_doors, true, OPT_PAGE_DISTURBANCE, 0, 17, "find_ignore_doors", _("ドアは通過する", "Run through open doors") },
+ { &find_ignore_doors, true, 0, 17, "find_ignore_doors", _("ドアは通過する", "Run through open doors"), GameOptionPage::DISTURBANCE },
- { &find_cut, false, OPT_PAGE_DISTURBANCE, 0, 18, "find_cut", _("曲り角を斜めに最短距離で通過する", "Run past known corners") },
+ { &find_cut, false, 0, 18, "find_cut", _("曲り角を斜めに最短距離で通過する", "Run past known corners"), GameOptionPage::DISTURBANCE },
- { &check_abort, true, OPT_PAGE_DISTURBANCE, 1, 18, "check_abort", _("連続コマンドはキー入力で中断する", "Check for user abort while in repeated command") },
+ { &check_abort, true, 1, 18, "check_abort", _("連続コマンドはキー入力で中断する", "Check for user abort while in repeated command"), GameOptionPage::DISTURBANCE },
- { &flush_failure, true, OPT_PAGE_DISTURBANCE, 1, 20, "flush_failure", _("様々なミス発生時に入力をクリアする", "Flush input on various failures") },
+ { &flush_failure, true, 1, 20, "flush_failure", _("様々なミス発生時に入力をクリアする", "Flush input on various failures"), GameOptionPage::DISTURBANCE },
- { &flush_disturb, false, OPT_PAGE_DISTURBANCE, 1, 21, "flush_disturb", _("障害発生時に入力をクリアする", "Flush input whenever disturbed") },
+ { &flush_disturb, false, 1, 21, "flush_disturb", _("障害発生時に入力をクリアする", "Flush input whenever disturbed"), GameOptionPage::DISTURBANCE },
- { &disturb_move, false, OPT_PAGE_DISTURBANCE, 0, 20, "disturb_move", _("どこのモンスターが動いても行動を中止する", "Disturb whenever any monster moves") },
+ { &disturb_move, false, 0, 20, "disturb_move", _("どこのモンスターが動いても行動を中止する", "Disturb whenever any monster moves"), GameOptionPage::DISTURBANCE },
- { &disturb_high, true, OPT_PAGE_DISTURBANCE, 1, 3, "disturb_high",
- _("レベルの高いモンスターが動いたら行動を中止する", "Disturb whenever high-level monster moves") },
+ { &disturb_high, true, 1, 3, "disturb_high",
+ _("レベルの高いモンスターが動いたら行動を中止する", "Disturb whenever high-level monster moves"), GameOptionPage::DISTURBANCE },
- { &disturb_unknown, true, OPT_PAGE_DISTURBANCE, 0, 26, "disturb_unknown",
- _("レベル不明のモンスターが動いたら行動を中止する", "Disturb whenever unknown-level monster moves") },
+ { &disturb_unknown, true, 0, 26, "disturb_unknown",
+ _("レベル不明のモンスターが動いたら行動を中止する", "Disturb whenever unknown-level monster moves"), GameOptionPage::DISTURBANCE },
- { &disturb_near, true, OPT_PAGE_DISTURBANCE, 0, 21, "disturb_near",
- _("視界内のモンスターが動いたら行動を中止する", "Disturb whenever viewable monster moves") },
+ { &disturb_near, true, 0, 21, "disturb_near",
+ _("視界内のモンスターが動いたら行動を中止する", "Disturb whenever viewable monster moves"), GameOptionPage::DISTURBANCE },
- { &disturb_pets, false, OPT_PAGE_DISTURBANCE, 5, 6, "disturb_pets", _("視界内のペットが動いたら行動を中止する", "Disturb when visible pets move") },
+ { &disturb_pets, false, 5, 6, "disturb_pets", _("視界内のペットが動いたら行動を中止する", "Disturb when visible pets move"), GameOptionPage::DISTURBANCE },
- { &disturb_panel, true, OPT_PAGE_DISTURBANCE, 0, 22, "disturb_panel", _("画面スクロール時に行動を中止する", "Disturb whenever map panel changes") },
+ { &disturb_panel, true, 0, 22, "disturb_panel", _("画面スクロール時に行動を中止する", "Disturb whenever map panel changes"), GameOptionPage::DISTURBANCE },
- { &disturb_state, true, OPT_PAGE_DISTURBANCE, 0, 23, "disturb_state",
- _("自分のステータス変化時に行動を中止する", "Disturb whenever player state changes") },
+ { &disturb_state, true, 0, 23, "disturb_state",
+ _("自分のステータス変化時に行動を中止する", "Disturb whenever player state changes"), GameOptionPage::DISTURBANCE },
- { &disturb_minor, true, OPT_PAGE_DISTURBANCE, 0, 24, "disturb_minor", _("些細なことが起きても行動を中止する", "Disturb whenever boring things happen") },
+ { &disturb_minor, true, 0, 24, "disturb_minor", _("些細なことが起きても行動を中止する", "Disturb whenever boring things happen"), GameOptionPage::DISTURBANCE },
- { &ring_bell, false, OPT_PAGE_DISTURBANCE, 0, 14, "ring_bell", _("エラー時にビープ音を鳴らす", "Audible bell (on errors, etc)") },
+ { &ring_bell, false, 0, 14, "ring_bell", _("エラー時にビープ音を鳴らす", "Audible bell (on errors, etc)"), GameOptionPage::DISTURBANCE },
- { &disturb_trap_detect, true, OPT_PAGE_DISTURBANCE, 0, 27, "disturb_trap_detect",
- _("トラップ感知範囲外に出る直前に行動を中止する", "Disturb when leaving trap detected area") },
+ { &disturb_trap_detect, true, 0, 27, "disturb_trap_detect",
+ _("トラップ感知範囲外に出る直前に行動を中止する", "Disturb when leaving trap detected area"), GameOptionPage::DISTURBANCE },
- { &alert_trap_detect, true, OPT_PAGE_DISTURBANCE, 0, 25, "alert_trap_detect",
- _("トラップ感知範囲外に出る直前に警告する", "Alert when leaving trap detected area") },
+ { &alert_trap_detect, true, 0, 25, "alert_trap_detect",
+ _("トラップ感知範囲外に出る直前に警告する", "Alert when leaving trap detected area"), GameOptionPage::DISTURBANCE },
/*** Birth Options ***/
- { &smart_learn, true, OPT_PAGE_BIRTH, 1, 14, "smart_learn", _("モンスターは失敗を学習する(*)", "Monsters learn from their mistakes (*)") },
+ { &smart_learn, true, 1, 14, "smart_learn", _("モンスターは失敗を学習する(*)", "Monsters learn from their mistakes (*)"), GameOptionPage::BIRTH },
- { &smart_cheat, false, OPT_PAGE_BIRTH, 1, 15, "smart_cheat", _("モンスターはプレイヤーの弱みを突く(*)", "Monsters exploit players weaknesses (*)") },
+ { &smart_cheat, false, 1, 15, "smart_cheat", _("モンスターはプレイヤーの弱みを突く(*)", "Monsters exploit players weaknesses (*)"), GameOptionPage::BIRTH },
- { &vanilla_town, false, OPT_PAGE_BIRTH, 6, 0, "vanilla_town", _("元祖の街/クエストと荒野なし", "Use 'vanilla' town without quests and wilderness") },
+ { &vanilla_town, false, 6, 0, "vanilla_town", _("元祖の街/クエストと荒野なし", "Use 'vanilla' town without quests and wilderness"), GameOptionPage::BIRTH },
- { &lite_town, false, OPT_PAGE_BIRTH, 6, 1, "lite_town", _("小規模な街/荒野なし", "Use 'lite' town without a wilderness") },
+ { &lite_town, false, 6, 1, "lite_town", _("小規模な街/荒野なし", "Use 'lite' town without a wilderness"), GameOptionPage::BIRTH },
- { &ironman_shops, false, OPT_PAGE_BIRTH, 6, 2, "ironman_shops", _("(鉄人用)店を使用しない(*)", "Stores are permanently closed (*)") },
+ { &ironman_shops, false, 6, 2, "ironman_shops", _("(鉄人用)店を使用しない(*)", "Stores are permanently closed (*)"), GameOptionPage::BIRTH },
- { &ironman_small_levels, false, OPT_PAGE_BIRTH, 6, 3, "ironman_small_levels",
- _("(鉄人用)常に非常に小さいフロアを生成(*)", "Always create unusually small dungeon levels (*)") },
+ { &ironman_small_levels, false, 6, 3, "ironman_small_levels",
+ _("(鉄人用)常に非常に小さいフロアを生成(*)", "Always create unusually small dungeon levels (*)"), GameOptionPage::BIRTH },
- { &ironman_downward, false, OPT_PAGE_BIRTH, 6, 4, "ironman_downward", _("(鉄人用)帰還と上り階段なし(*)", "Disable recall and use of up stairs (*)") },
+ { &ironman_downward, false, 6, 4, "ironman_downward", _("(鉄人用)帰還と上り階段なし(*)", "Disable recall and use of up stairs (*)"), GameOptionPage::BIRTH },
- { &ironman_empty_levels, false, OPT_PAGE_BIRTH, 6, 8, "ironman_empty_levels",
- _("(鉄人用)常に空っぽのアリーナレベルを生成(*)", "Always create empty 'arena' levels (*)") },
+ { &ironman_empty_levels, false, 6, 8, "ironman_empty_levels",
+ _("(鉄人用)常に空っぽのアリーナレベルを生成(*)", "Always create empty 'arena' levels (*)"), GameOptionPage::BIRTH },
- { &ironman_rooms, false, OPT_PAGE_BIRTH, 6, 12, "ironman_rooms", _("(鉄人用)常に普通でない部屋を生成する(*)", "Always generate very unusual rooms (*)") },
+ { &ironman_rooms, false, 6, 12, "ironman_rooms", _("(鉄人用)常に普通でない部屋を生成する(*)", "Always generate very unusual rooms (*)"), GameOptionPage::BIRTH },
- { &ironman_nightmare, false, OPT_PAGE_BIRTH, 6, 18, "ironman_nightmare",
- _("(鉄人用)悪夢モード(これは全く不条理です!)(*)", "Nightmare mode(it isn't even remotely fair!)(*)") },
+ { &ironman_nightmare, false, 6, 18, "ironman_nightmare",
+ _("(鉄人用)悪夢モード(これは全く不条理です!)(*)", "Nightmare mode(it isn't even remotely fair!)(*)"), GameOptionPage::BIRTH },
- { &left_hander, false, OPT_PAGE_BIRTH, 6, 13, "left_hander", _("左利きである", "Left-Hander") },
+ { &left_hander, false, 6, 13, "left_hander", _("左利きである", "Left-Hander"), GameOptionPage::BIRTH },
- { &preserve_mode, true, OPT_PAGE_BIRTH, 6, 14, "preserve_mode", _("伝説のアイテムを取り逃しても再生成される(*)", "Preserve artifacts (*)") },
+ { &preserve_mode, true, 6, 14, "preserve_mode", _("伝説のアイテムを取り逃しても再生成される(*)", "Preserve artifacts (*)"), GameOptionPage::BIRTH },
- { &autoroller, true, OPT_PAGE_BIRTH, 6, 15, "autoroller", _("能力値にオートローラー使用(*)", "Allow use of autoroller for stats (*)") },
+ { &autoroller, true, 6, 15, "autoroller", _("能力値にオートローラー使用(*)", "Allow use of autoroller for stats (*)"), GameOptionPage::BIRTH },
- { &autochara, false, OPT_PAGE_BIRTH, 6, 16, "autochara", _("体格/地位にオートローラー使用", "Autoroll for weight, height and social status") },
+ { &autochara, false, 6, 16, "autochara", _("体格/地位にオートローラー使用", "Autoroll for weight, height and social status"), GameOptionPage::BIRTH },
- { &powerup_home, true, OPT_PAGE_BIRTH, 4, 3, "powerup_home", _("我が家を拡張する(*)", "Increase capacity of your home (*)") },
+ { &powerup_home, true, 4, 3, "powerup_home", _("我が家を拡張する(*)", "Increase capacity of your home (*)"), GameOptionPage::BIRTH },
- { &keep_savefile, true, OPT_PAGE_BIRTH, 4, 4, "keep_savefile", _("同一のセーブファイルでゲームを開始する", "Start game with same savefile thet is loaded") },
+ { &keep_savefile, true, 4, 4, "keep_savefile", _("同一のセーブファイルでゲームを開始する", "Start game with same savefile thet is loaded"), GameOptionPage::BIRTH },
/*** Easy Object Auto-Destroyer ***/
- { &destroy_items, false, OPT_PAGE_AUTODESTROY, 7, 0, "destroy_items", _("アイテムの簡易自動破壊を使用する", "Use easy auto-destroyer") },
+ { &destroy_items, false, 7, 0, "destroy_items", _("アイテムの簡易自動破壊を使用する", "Use easy auto-destroyer"), GameOptionPage::AUTODESTROY },
- { &destroy_feeling, false, OPT_PAGE_AUTODESTROY, 7, 8, "destroy_feeling", _("簡易鑑定したとき自動破壊を適用する", "Apply auto-destroy as sense feeling") },
+ { &destroy_feeling, false, 7, 8, "destroy_feeling", _("簡易鑑定したとき自動破壊を適用する", "Apply auto-destroy as sense feeling"), GameOptionPage::AUTODESTROY },
- { &destroy_identify, false, OPT_PAGE_AUTODESTROY, 7, 9, "destroy_identify", _("鑑定したとき自動破壊を適用する", "Apply auto-destroy as identify an item") },
+ { &destroy_identify, false, 7, 9, "destroy_identify", _("鑑定したとき自動破壊を適用する", "Apply auto-destroy as identify an item"), GameOptionPage::AUTODESTROY },
- { &leave_worth, true, OPT_PAGE_AUTODESTROY, 7, 2, "leave_worth", _("価値があるアイテムは壊さない", "Auto-destroyer leaves known worthy items") },
+ { &leave_worth, true, 7, 2, "leave_worth", _("価値があるアイテムは壊さない", "Auto-destroyer leaves known worthy items"), GameOptionPage::AUTODESTROY },
- { &leave_equip, false, OPT_PAGE_AUTODESTROY, 7, 3, "leave_equip", _("武器/防具は壊さない", "Auto-destroyer leaves weapons and armour") },
+ { &leave_equip, false, 7, 3, "leave_equip", _("武器/防具は壊さない", "Auto-destroyer leaves weapons and armour"), GameOptionPage::AUTODESTROY },
- { &leave_chest, true, OPT_PAGE_AUTODESTROY, 7, 7, "leave_chest", _("開封されていない箱は壊さない", "Auto-destroyer leaves closed chests") },
+ { &leave_chest, true, 7, 7, "leave_chest", _("開封されていない箱は壊さない", "Auto-destroyer leaves closed chests"), GameOptionPage::AUTODESTROY },
- { &leave_wanted, true, OPT_PAGE_AUTODESTROY, 7, 4, "leave_wanted", _("賞金首の死体/骨は壊さない", "Auto-destroyer leaves wanted corpses") },
+ { &leave_wanted, true, 7, 4, "leave_wanted", _("賞金首の死体/骨は壊さない", "Auto-destroyer leaves wanted corpses"), GameOptionPage::AUTODESTROY },
- { &leave_corpse, false, OPT_PAGE_AUTODESTROY, 7, 5, "leave_corpse", _("死体/骨は壊さない", "Auto-destroyer leaves corpses and skeletons") },
+ { &leave_corpse, false, 7, 5, "leave_corpse", _("死体/骨は壊さない", "Auto-destroyer leaves corpses and skeletons"), GameOptionPage::AUTODESTROY },
- { &leave_junk, false, OPT_PAGE_AUTODESTROY, 7, 6, "leave_junk", _("がらくたは壊さない", "Auto-destroyer leaves junk") },
+ { &leave_junk, false, 7, 6, "leave_junk", _("がらくたは壊さない", "Auto-destroyer leaves junk"), GameOptionPage::AUTODESTROY },
- { &leave_special, true, OPT_PAGE_AUTODESTROY, 7, 1, "leave_special",
- _("種族/職業で特別に必要なアイテムは壊さない", "Auto-destroyer leaves items your race/class needs") },
+ { &leave_special, true, 7, 1, "leave_special",
+ _("種族/職業で特別に必要なアイテムは壊さない", "Auto-destroyer leaves items your race/class needs"), GameOptionPage::AUTODESTROY },
/*** Play-record Options ***/
- { &record_fix_art, true, OPT_PAGE_PLAYRECORD, 4, 11, "record_fix_art", _("固定アーティファクトの入手を記録する", "Record fixed artifacts") },
+ { &record_fix_art, true, 4, 11, "record_fix_art", _("固定アーティファクトの入手を記録する", "Record fixed artifacts"), GameOptionPage::PLAYRECORD },
- { &record_rand_art, true, OPT_PAGE_PLAYRECORD, 4, 12, "record_rand_art", _("ランダムアーティファクトの入手を記録する", "Record random artifacts") },
+ { &record_rand_art, true, 4, 12, "record_rand_art", _("ランダムアーティファクトの入手を記録する", "Record random artifacts"), GameOptionPage::PLAYRECORD },
- { &record_destroy_uniq, true, OPT_PAGE_PLAYRECORD, 4, 13, "record_destroy_uniq",
- _("ユニークモンスターを倒したときを記録する", "Record when destroy unique monster") },
+ { &record_destroy_uniq, true, 4, 13, "record_destroy_uniq",
+ _("ユニークモンスターを倒したときを記録する", "Record when destroy unique monster"), GameOptionPage::PLAYRECORD },
- { &record_fix_quest, true, OPT_PAGE_PLAYRECORD, 4, 14, "record_fix_quest", _("固定クエストの達成を記録する", "Record fixed quests") },
+ { &record_fix_quest, true, 4, 14, "record_fix_quest", _("固定クエストの達成を記録する", "Record fixed quests"), GameOptionPage::PLAYRECORD },
- { &record_rand_quest, true, OPT_PAGE_PLAYRECORD, 4, 15, "record_rand_quest", _("ランダムクエストの達成を記録する", "Record random quests") },
+ { &record_rand_quest, true, 4, 15, "record_rand_quest", _("ランダムクエストの達成を記録する", "Record random quests"), GameOptionPage::PLAYRECORD },
- { &record_maxdepth, true, OPT_PAGE_PLAYRECORD, 4, 16, "record_maxdepth", _("最深階を更新したときに記録する", "Record movements to deepest level") },
+ { &record_maxdepth, true, 4, 16, "record_maxdepth", _("最深階を更新したときに記録する", "Record movements to deepest level"), GameOptionPage::PLAYRECORD },
- { &record_stair, true, OPT_PAGE_PLAYRECORD, 4, 17, "record_stair", _("階の移動を記録する", "Record recall and stair movements") },
+ { &record_stair, true, 4, 17, "record_stair", _("階の移動を記録する", "Record recall and stair movements"), GameOptionPage::PLAYRECORD },
- { &record_buy, true, OPT_PAGE_PLAYRECORD, 4, 18, "record_buy", _("アイテムの購入を記録する", "Record purchased items") },
+ { &record_buy, true, 4, 18, "record_buy", _("アイテムの購入を記録する", "Record purchased items"), GameOptionPage::PLAYRECORD },
- { &record_sell, false, OPT_PAGE_PLAYRECORD, 4, 19, "record_sell", _("アイテムの売却を記録する", "Record sold items") },
+ { &record_sell, false, 4, 19, "record_sell", _("アイテムの売却を記録する", "Record sold items"), GameOptionPage::PLAYRECORD },
- { &record_danger, true, OPT_PAGE_PLAYRECORD, 4, 20, "record_danger", _("ピンチになったときを記録する", "Record hitpoint warning") },
+ { &record_danger, true, 4, 20, "record_danger", _("ピンチになったときを記録する", "Record hitpoint warning"), GameOptionPage::PLAYRECORD },
- { &record_arena, true, OPT_PAGE_PLAYRECORD, 4, 21, "record_arena", _("アリーナでの勝利を記録する", "Record arena victories") },
+ { &record_arena, true, 4, 21, "record_arena", _("アリーナでの勝利を記録する", "Record arena victories"), GameOptionPage::PLAYRECORD },
- { &record_ident, true, OPT_PAGE_PLAYRECORD, 4, 22, "record_ident", _("未判明のアイテムの識別を記録する", "Record first identified items") },
+ { &record_ident, true, 4, 22, "record_ident", _("未判明のアイテムの識別を記録する", "Record first identified items"), GameOptionPage::PLAYRECORD },
- { &record_named_pet, false, OPT_PAGE_PLAYRECORD, 4, 23, "record_named_pet", _("名前つきペットの情報を記録する", "Record information about named pets") },
-
- /*** End of Table ***/
- { nullptr, 0, 0, 0, 0, nullptr, nullptr }
+ { &record_named_pet, false, 4, 23, "record_named_pet", _("名前つきペットの情報を記録する", "Record information about named pets"), GameOptionPage::PLAYRECORD },
};
/*!
* チートオプションの定義テーブル / Cheating options
*/
-const std::vector cheat_info = {
- { &cheat_peek, false, 255, 0x01, 0x00, "cheat_peek", _("アイテムの生成をのぞき見る", "Peek into object creation") },
+const std::vector cheat_info = {
+ { &cheat_peek, false, 0x01, 0x00, "cheat_peek", _("アイテムの生成をのぞき見る", "Peek into object creation") },
- { &cheat_hear, false, 255, 0x02, 0x00, "cheat_hear", _("モンスターの生成をのぞき見る", "Peek into monster creation") },
+ { &cheat_hear, false, 0x02, 0x00, "cheat_hear", _("モンスターの生成をのぞき見る", "Peek into monster creation") },
- { &cheat_room, false, 255, 0x04, 0x00, "cheat_room", _("ダンジョンの生成をのぞき見る", "Peek into dungeon creation") },
+ { &cheat_room, false, 0x04, 0x00, "cheat_room", _("ダンジョンの生成をのぞき見る", "Peek into dungeon creation") },
- { &cheat_xtra, false, 255, 0x08, 0x00, "cheat_xtra", _("その他の事をのぞき見る", "Peek into something else") },
+ { &cheat_xtra, false, 0x08, 0x00, "cheat_xtra", _("その他の事をのぞき見る", "Peek into something else") },
- { &cheat_know, false, 255, 0x10, 0x00, "cheat_know", _("完全なモンスターの思い出を知る", "Know complete monster info") },
+ { &cheat_know, false, 0x10, 0x00, "cheat_know", _("完全なモンスターの思い出を知る", "Know complete monster info") },
- { &cheat_live, false, 255, 0x20, 0x00, "cheat_live", _("死を回避することを可能にする", "Allow player to avoid death") },
+ { &cheat_live, false, 0x20, 0x00, "cheat_live", _("死を回避することを可能にする", "Allow player to avoid death") },
- { &cheat_save, false, 255, 0x40, 0x00, "cheat_save", _("死んだ時セーブするか確認する", "Ask for saving death") },
+ { &cheat_save, false, 0x40, 0x00, "cheat_save", _("死んだ時セーブするか確認する", "Ask for saving death") },
- { &cheat_diary_output, false, 255, 0x80, 0x00, "cheat_diary_output", _("ウィザードログを日記に出力する", "Output wizard log to diary.") },
+ { &cheat_diary_output, false, 0x80, 0x00, "cheat_diary_output", _("ウィザードログを日記に出力する", "Output wizard log to diary.") },
- { &cheat_turn, false, 255, 0x81, 0x00, "cheat_turn", _("ゲームメッセージにターン表示を行う", "Put turn in game messages.") },
+ { &cheat_turn, false, 0x81, 0x00, "cheat_turn", _("ゲームメッセージにターン表示を行う", "Put turn in game messages.") },
- { &cheat_sight, false, 255, 0x82, 0x00, "cheat_sight", _("「見る」コマンドを拡張する。", "Expand \"L\"ook command.") },
+ { &cheat_sight, false, 0x82, 0x00, "cheat_sight", _("「見る」コマンドを拡張する。", "Expand \"L\"ook command.") },
- { &cheat_immortal, false, 255, 0x83, 0x00, "cheat_immortal", _("完全な不滅状態になる。", "Completely immortal.") }
+ { &cheat_immortal, false, 0x83, 0x00, "cheat_immortal", _("完全な不滅状態になる。", "Completely immortal.") }
};
/*!
* 自動セーブオプションテーブル
*/
-const std::vector autosave_info = {
- { &autosave_l, false, 255, 0x01, 0x00, "autosave_l", _("新しい階に入る度に自動セーブする", "Autosave when entering new levels") },
+const std::vector autosave_info = {
+ { &autosave_l, false, 0x01, 0x00, "autosave_l", _("新しい階に入る度に自動セーブする", "Autosave when entering new levels") },
- { &autosave_t, false, 255, 0x02, 0x00, "autosave_t", _("一定ターン毎に自動セーブする", "Timed autosave") },
+ { &autosave_t, false, 0x02, 0x00, "autosave_t", _("一定ターン毎に自動セーブする", "Timed autosave") },
};
diff --git a/src/game-option/option-types-table.h b/src/game-option/option-types-table.h
index 8bffe1732c..670e53f61d 100644
--- a/src/game-option/option-types-table.h
+++ b/src/game-option/option-types-table.h
@@ -1,28 +1,23 @@
#pragma once
-#include "system/angband.h"
+#include
+#include
+#include
#include
-/*
- * Available "options"
- * - Address of actual option variable (or nullptr)
- * - Normal Value (TRUE or FALSE)
- * - Option Page Number (or zero)
- * - Savefile Set (or zero)
- * - Savefile Bit in that set
- * - Textual name (or nullptr)
- * - Textual description
- */
-struct option_type {
- bool *o_var{};
- byte o_norm{};
- byte o_page{};
- byte o_set{};
- byte o_bit{};
- concptr o_text{};
- concptr o_desc{};
+enum class GameOptionPage : int;
+class GameOption {
+public:
+ GameOption(bool *value, bool norm, uint8_t set, uint8_t bits, std::string &&text, std::string &&description, const std::optional &page = std::nullopt);
+ bool *value;
+ bool default_value;
+ uint8_t flag_position;
+ uint8_t offset;
+ std::string text;
+ std::string description;
+ std::optional page;
};
-extern const std::vector option_info;
-extern const std::vector cheat_info;
-extern const std::vector autosave_info;
+extern const std::vector option_info;
+extern const std::vector cheat_info;
+extern const std::vector autosave_info;
diff --git a/src/grid/grid.cpp b/src/grid/grid.cpp
index f5a86e3fcb..9c55a4bb8d 100644
--- a/src/grid/grid.cpp
+++ b/src/grid/grid.cpp
@@ -43,6 +43,7 @@
#include "player/player-status.h"
#include "room/rooms-builder.h"
#include "system/dungeon-info.h"
+#include "system/enums/grid-flow.h"
#include "system/floor-type-definition.h"
#include "system/grid-type-definition.h"
#include "system/item-entity.h"
@@ -667,7 +668,7 @@ void update_flow(PlayerType *player_ptr)
flow_y = player_ptr->y;
flow_x = player_ptr->x;
- for (auto i = 0; i < FLOW_MAX; i++) {
+ for (const auto gf : GRID_FLOW_RANGE) {
// 幅優先探索用のキュー。
std::queue que;
que.emplace(player_ptr->y, player_ptr->x);
@@ -680,8 +681,8 @@ void update_flow(PlayerType *player_ptr)
/* Add the "children" */
for (auto d = 0; d < 8; d++) {
- byte m = grid.costs[i] + 1;
- byte n = grid.dists[i] + 1;
+ uint8_t m = grid.costs.at(gf) + 1;
+ const uint8_t n = grid.dists.at(gf) + 1;
const Pos2D pos_neighbor(pos.y + ddy_ddd[d], pos.x + ddx_ddd[d]);
/* Ignore player's grid */
@@ -695,14 +696,16 @@ void update_flow(PlayerType *player_ptr)
}
/* Ignore "pre-stamped" entries */
- if ((grid_neighbor.dists[i] != 0) && (grid_neighbor.dists[i] <= n) && (grid_neighbor.costs[i] <= m)) {
+ auto &cost_neighbor = grid_neighbor.costs.at(gf);
+ auto &dist_neighbor = grid_neighbor.dists.at(gf);
+ if ((dist_neighbor != 0) && (dist_neighbor <= n) && (cost_neighbor <= m)) {
continue;
}
/* Ignore "walls", "holes" and "rubble" */
auto can_move = false;
- switch (i) {
- case FLOW_CAN_FLY:
+ switch (gf) {
+ case GridFlow::CAN_FLY:
can_move = grid_neighbor.cave_has_flag(TerrainCharacteristics::MOVE) || grid_neighbor.cave_has_flag(TerrainCharacteristics::CAN_FLY);
break;
default:
@@ -715,11 +718,11 @@ void update_flow(PlayerType *player_ptr)
}
/* Save the flow cost */
- if (grid_neighbor.costs[i] == 0 || (grid_neighbor.costs[i] > m)) {
- grid_neighbor.costs[i] = m;
+ if (cost_neighbor == 0 || (cost_neighbor > m)) {
+ cost_neighbor = m;
}
- if (grid_neighbor.dists[i] == 0 || (grid_neighbor.dists[i] > n)) {
- grid_neighbor.dists[i] = n;
+ if (dist_neighbor == 0 || (dist_neighbor > n)) {
+ dist_neighbor = n;
}
// 敵のプレイヤーに対する移動道のりの最大値(この値以上は処理を打ち切る).
diff --git a/src/io/interpret-pref-file.cpp b/src/io/interpret-pref-file.cpp
index 7fd5e683c0..71af696bf8 100644
--- a/src/io/interpret-pref-file.cpp
+++ b/src/io/interpret-pref-file.cpp
@@ -14,7 +14,7 @@
#include "io/input-key-requester.h"
#include "io/tokenizer.h"
#include "system/baseitem-info.h"
-#include "system/game-option-types.h"
+#include "system/enums/game-option-page.h"
#include "system/monster-race-info.h"
#include "system/player-type-definition.h"
#include "system/terrain-type-definition.h"
@@ -23,8 +23,6 @@
#include "view/display-messages.h"
#include "world/world.h"
-#define MAX_MACRO_CHARS 16128 // 1つのマクロキー押下で実行可能なコマンド最大数 (エスケープシーケンス含む).
-
std::optional histpref_buf;
/*!
@@ -338,18 +336,14 @@ static bool interpret_v_token(char *buf)
static void interpret_xy_token(PlayerType *player_ptr, char *buf)
{
const auto &world = AngbandWorld::get_instance();
- for (int i = 0; option_info[i].o_desc; i++) {
- bool is_option = option_info[i].o_var != nullptr;
- is_option &= option_info[i].o_text != nullptr;
- is_option &= streq(option_info[i].o_text, buf + 2);
- if (!is_option) {
+ for (auto &option : option_info) {
+ if (option.text != buf + 2) {
continue;
}
- int os = option_info[i].o_set;
- int ob = option_info[i].o_bit;
-
- if ((player_ptr->playing || world.character_xtra) && (OPT_PAGE_BIRTH == option_info[i].o_page) && !world.wizard) {
+ int os = option.flag_position;
+ int ob = option.offset;
+ if ((player_ptr->playing || world.character_xtra) && (GameOptionPage::BIRTH == option.page) && !world.wizard) {
msg_format(_("初期オプションは変更できません! '%s'", "Birth options can not be changed! '%s'"), buf);
msg_print(nullptr);
return;
@@ -357,12 +351,12 @@ static void interpret_xy_token(PlayerType *player_ptr, char *buf)
if (buf[0] == 'X') {
g_option_flags[os] &= ~(1UL << ob);
- (*option_info[i].o_var) = false;
+ *option.value = false;
return;
}
g_option_flags[os] |= (1UL << ob);
- (*option_info[i].o_var) = true;
+ *option.value = true;
return;
}
@@ -449,7 +443,9 @@ static bool decide_template_modifier(int tok, char **zz)
*/
static bool interpret_macro_keycodes(int tok, char **zz)
{
- char buf_aux[MAX_MACRO_CHARS]{};
+ //!< @details 1つのマクロキー押下で実行可能なコマンド最大数 (エスケープシーケンス含む).
+ constexpr auto max_macro_chars = 16128;
+ char buf_aux[max_macro_chars]{};
if (max_macrotrigger >= MAX_MACRO_TRIG) {
msg_print(_("マクロトリガーの設定が多すぎます!", "Too many macro triggers!"));
return false;
diff --git a/src/io/report.cpp b/src/io/report.cpp
index bf90663d23..17a67ccc13 100644
--- a/src/io/report.cpp
+++ b/src/io/report.cpp
@@ -272,7 +272,7 @@ bool report_score(PlayerType *player_ptr)
personality_desc.append(_(ap_ptr->no ? "の" : "", " "));
PlayerRealm pr(player_ptr);
- auto realm1_name = PlayerClass(player_ptr).equals(PlayerClassType::ELEMENTALIST) ? get_element_title(player_ptr->element) : pr.realm1().get_name().data();
+ const auto &realm1_name = PlayerClass(player_ptr).equals(PlayerClassType::ELEMENTALIST) ? get_element_title(player_ptr->element) : pr.realm1().get_name().string();
score_ss << format("name: %s\n", player_ptr->name)
<< format("version: %s\n", AngbandSystem::get_instance().build_version_expression(VersionExpression::FULL).data())
<< format("score: %ld\n", calc_score(player_ptr))
@@ -287,7 +287,7 @@ bool report_score(PlayerType *player_ptr)
<< format("race: %s\n", rp_ptr->title.data())
<< format("class: %s\n", cp_ptr->title.data())
<< format("seikaku: %s\n", personality_desc.data())
- << format("realm1: %s\n", realm1_name)
+ << format("realm1: %s\n", realm1_name.data())
<< format("realm2: %s\n", pr.realm2().get_name().data())
<< format("killer: %s\n", player_ptr->died_from.data())
<< "-----charcter dump-----\n";
diff --git a/src/main/game-data-initializer.cpp b/src/main/game-data-initializer.cpp
index a0aeef6caa..1677fea3bb 100644
--- a/src/main/game-data-initializer.cpp
+++ b/src/main/game-data-initializer.cpp
@@ -57,15 +57,11 @@ void init_other(PlayerType *player_ptr)
macro_patterns.assign(MACRO_MAX, {});
macro_actions.assign(MACRO_MAX, {});
macro_buffers.assign(FILE_READ_BUFF_SIZE, {});
- for (auto i = 0; option_info[i].o_desc; i++) {
- int os = option_info[i].o_set;
- int ob = option_info[i].o_bit;
- if (option_info[i].o_var == nullptr) {
- continue;
- }
-
+ for (auto &option : option_info) {
+ int os = option.flag_position;
+ int ob = option.offset;
g_option_masks[os] |= (1UL << ob);
- if (option_info[i].o_norm) {
+ if (option.default_value) {
set_bits(g_option_flags[os], 1U << ob);
} else {
reset_bits(g_option_flags[os], 1U << ob);
diff --git a/src/mind/mind-elementalist.cpp b/src/mind/mind-elementalist.cpp
index 7c490e1850..4bbb798852 100644
--- a/src/mind/mind-elementalist.cpp
+++ b/src/mind/mind-elementalist.cpp
@@ -54,8 +54,8 @@
#include "spell-kind/spells-world.h"
#include "status/bad-status-setter.h"
#include "status/base-status.h"
+#include "system/enums/game-option-page.h"
#include "system/floor-type-definition.h"
-#include "system/game-option-types.h"
#include "system/grid-type-definition.h"
#include "system/monster-entity.h"
#include "system/monster-race-info.h"
@@ -104,9 +104,9 @@ enum class ElementSpells {
* @brief 元素魔法タイプ構造体
*/
struct element_type {
- std::string_view title; //!< 領域名
+ std::string title; //!< 領域名
std::array type; //!< 属性タイプリスト
- std::array name; //!< 属性名リスト
+ std::array name; //!< 属性名リスト
std::unordered_map extra; //!< 追加属性タイプ
};
@@ -120,8 +120,8 @@ struct element_power {
using element_type_list = const std::unordered_map;
using element_power_list = const std::unordered_map;
-using element_tip_list = const std::unordered_map;
-using element_text_list = const std::unordered_map;
+using element_tip_list = const std::unordered_map;
+using element_text_list = const std::unordered_map;
// clang-format off
/*!
@@ -294,10 +294,10 @@ static element_text_list element_texts = {
* @param realm_idx 領域番号
* @return 領域名
*/
-concptr get_element_title(int realm_idx)
+const std::string &get_element_title(int realm_idx)
{
auto realm = i2enum(realm_idx);
- return element_types.at(realm).title.data();
+ return element_types.at(realm).title;
}
/*!
@@ -305,7 +305,7 @@ concptr get_element_title(int realm_idx)
* @param realm_idx 領域番号
* @return 領域で使用できる属性リスト
*/
-static std::array get_element_types(int realm_idx)
+static const std::array &get_element_types(int realm_idx)
{
auto realm = i2enum(realm_idx);
return element_types.at(realm).type;
@@ -319,7 +319,7 @@ static std::array get_element_types(int realm_idx)
*/
AttributeType get_element_type(int realm_idx, int n)
{
- return get_element_types(realm_idx)[n];
+ return get_element_types(realm_idx).at(n);
}
/*!
@@ -345,9 +345,9 @@ static AttributeType get_element_spells_type(PlayerType *player_ptr, int n)
* @param realm_idx 領域番号
* @return 領域で使用できる属性の名称リスト
*/
-static std::array get_element_names(int realm_idx)
+static const std::array &get_element_names(int realm_idx)
{
- auto realm = i2enum(realm_idx);
+ const auto realm = i2enum(realm_idx);
return element_types.at(realm).name;
}
@@ -357,9 +357,9 @@ static std::array get_element_names(int realm_idx)
* @param n 属性の何番目か
* @return 属性名
*/
-concptr get_element_name(int realm_idx, int n)
+const std::string &get_element_name(int realm_idx, int n)
{
- return get_element_names(realm_idx)[n].data();
+ return get_element_names(realm_idx).at(n);
}
/*!
@@ -970,7 +970,7 @@ void display_element_spell_list(PlayerType *player_ptr, int y, int x)
}
const auto elem = get_elemental_elem(player_ptr, i);
- const auto name = format(spell.name, get_element_name(player_ptr->element, elem));
+ const auto name = format(spell.name, get_element_name(player_ptr->element, elem).data());
const auto mana_cost = decide_element_mana_cost(player_ptr, spell);
const auto chance = decide_element_chance(player_ptr, spell);
@@ -990,7 +990,7 @@ void display_element_spell_list(PlayerType *player_ptr, int y, int x)
* @param type 魔法攻撃属性
* @return 効果があるならTRUE、なければFALSE
*/
-bool is_elemental_genocide_effective(MonsterRaceInfo *r_ptr, AttributeType type)
+static bool is_elemental_genocide_effective(MonsterRaceInfo *r_ptr, AttributeType type)
{
switch (type) {
case AttributeType::FIRE:
@@ -1048,19 +1048,18 @@ bool is_elemental_genocide_effective(MonsterRaceInfo *r_ptr, AttributeType type)
*/
ProcessResult effect_monster_elemental_genocide(PlayerType *player_ptr, EffectMonster *em_ptr)
{
- auto type = get_element_type(player_ptr->element, 0);
- auto name = get_element_name(player_ptr->element, 0);
- bool b = is_elemental_genocide_effective(em_ptr->r_ptr, type);
-
+ const auto &name = get_element_name(player_ptr->element, 0);
if (em_ptr->seen_msg) {
- msg_format(_("%sが%sを包み込んだ。", "The %s surrounds %s."), name, em_ptr->m_name);
+ msg_format(_("%sが%sを包み込んだ。", "The %s surrounds %s."), name.data(), em_ptr->m_name);
}
if (em_ptr->seen) {
em_ptr->obvious = true;
}
- if (!b) {
+ const auto type = get_element_type(player_ptr->element, 0);
+ const auto is_effective = is_elemental_genocide_effective(em_ptr->r_ptr, type);
+ if (!is_effective) {
if (em_ptr->seen_msg) {
msg_format(_("%sには効果がなかった。", "%s^ is unaffected."), em_ptr->m_name);
}
@@ -1109,7 +1108,7 @@ bool has_element_resist(PlayerType *player_ptr, ElementRealmType realm, PLAYER_L
static void display_realm_cursor(int i, int n, term_color_type color)
{
char sym;
- concptr name;
+ std::string name;
if (i == n) {
sym = '*';
name = _("ランダム", "Random");
@@ -1118,7 +1117,7 @@ static void display_realm_cursor(int i, int n, term_color_type color)
name = element_types.at(i2enum(i + 1)).title.data();
}
- c_put_str(color, format("%c) %s", sym, name), 12 + (i / 5), 2 + 15 * (i % 5));
+ c_put_str(color, format("%c) %s", sym, name.data()), 12 + (i / 5), 2 + 15 * (i % 5));
}
/*!
@@ -1218,7 +1217,7 @@ static int get_element_realm(PlayerType *player_ptr, int is, int n)
if (c == '=') {
screen_save();
- do_cmd_options_aux(player_ptr, OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
+ do_cmd_options_aux(player_ptr, GameOptionPage::BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
screen_load();
} else if (c != '2' && c != '4' && c != '6' && c != '8') {
bell();
diff --git a/src/mind/mind-elementalist.h b/src/mind/mind-elementalist.h
index 974e265f61..986c415ec4 100644
--- a/src/mind/mind-elementalist.h
+++ b/src/mind/mind-elementalist.h
@@ -2,6 +2,7 @@
#include "effect/attribute-types.h"
#include "system/angband.h"
+#include
enum class ElementRealmType {
FIRE = 1,
@@ -19,9 +20,9 @@ class PlayerType;
class EffectMonster;
struct rc_type;
-concptr get_element_title(int realm_idx);
+const std::string &get_element_title(int realm_idx);
AttributeType get_element_type(int realm_idx, int n);
-concptr get_element_name(int realm_idx, int n);
+const std::string &get_element_name(int realm_idx, int n);
void do_cmd_element(PlayerType *player_ptr);
void do_cmd_element_browse(PlayerType *player_ptr);
void display_element_spell_list(PlayerType *player_ptr, int y = 1, int x = 1);
diff --git a/src/monster-floor/monster-safety-hiding.cpp b/src/monster-floor/monster-safety-hiding.cpp
index f1c36e48bf..11aeae523a 100644
--- a/src/monster-floor/monster-safety-hiding.cpp
+++ b/src/monster-floor/monster-safety-hiding.cpp
@@ -51,11 +51,11 @@ static coordinate_candidate sweep_safe_coordinate(PlayerType *player_ptr, MONSTE
}
if (m_ptr->mflag2.has_not(MonsterConstantFlagType::NOFLOW)) {
- byte dist = g_ptr->get_distance(r_ptr);
+ const auto dist = g_ptr->get_distance(r_ptr->get_grid_flow_type());
if (dist == 0) {
continue;
}
- if (dist > floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].get_distance(r_ptr) + 2 * d) {
+ if (dist > floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].get_distance(r_ptr->get_grid_flow_type()) + 2 * d) {
continue;
}
}
diff --git a/src/monster-floor/monster-sweep-grid.cpp b/src/monster-floor/monster-sweep-grid.cpp
index fed8092269..cc5bd96363 100644
--- a/src/monster-floor/monster-sweep-grid.cpp
+++ b/src/monster-floor/monster-sweep-grid.cpp
@@ -55,7 +55,7 @@ bool MonsterSweepGrid::get_movable_grid()
auto x2 = this->player_ptr->x;
this->will_run = this->mon_will_run();
Pos2D pos_monster_from(monster_from.fy, monster_from.fx);
- const auto no_flow = monster_from.mflag2.has(MonsterConstantFlagType::NOFLOW) && (floor.get_grid(pos_monster_from).get_cost(&monrace) > 2);
+ const auto no_flow = monster_from.mflag2.has(MonsterConstantFlagType::NOFLOW) && (floor.get_grid(pos_monster_from).get_cost(monrace.get_grid_flow_type()) > 2);
this->can_pass_wall = monrace.feature_flags.has(MonsterFeatureType::PASS_WALL) && (!monster_from.is_riding() || has_pass_wall(this->player_ptr));
if (!this->will_run && monster_from.target_y) {
Pos2D pos_target(monster_from.target_y, monster_from.target_x);
@@ -141,14 +141,15 @@ void MonsterSweepGrid::check_hiding_grid(POSITION *y, POSITION *x, POSITION *y2,
return;
}
+ const auto gf = r_ptr->get_grid_flow_type();
if ((!los(this->player_ptr, m_ptr->fy, m_ptr->fx, this->player_ptr->y, this->player_ptr->x) || !projectable(this->player_ptr, m_ptr->fy, m_ptr->fx, this->player_ptr->y, this->player_ptr->x))) {
- if (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].get_distance(r_ptr) >= MAX_PLAYER_SIGHT / 2) {
+ if (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].get_distance(gf) >= MAX_PLAYER_SIGHT / 2) {
return;
}
}
this->search_room_to_run(y, x);
- if (this->done || (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].get_distance(r_ptr) >= 3)) {
+ if (this->done || (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].get_distance(gf) >= 3)) {
return;
}
@@ -249,9 +250,9 @@ void MonsterSweepGrid::search_pet_runnable_grid(POSITION *y, POSITION *x, bool n
*/
void MonsterSweepGrid::sweep_movable_grid(POSITION *yp, POSITION *xp, bool no_flow)
{
- auto &floor = *this->player_ptr->current_floor_ptr;
- auto &monster = floor.m_list[this->m_idx];
- auto &monrace = monster.get_monrace();
+ const auto &floor = *this->player_ptr->current_floor_ptr;
+ const auto &monster = floor.m_list[this->m_idx];
+ const auto &monrace = monster.get_monrace();
if (!this->check_movable_grid(yp, xp, no_flow)) {
return;
}
@@ -260,14 +261,15 @@ void MonsterSweepGrid::sweep_movable_grid(POSITION *yp, POSITION *xp, bool no_fl
auto x1 = monster.fx;
const Pos2D pos(y1, x1);
const auto &grid = floor.get_grid(pos);
+ const auto gf = monrace.get_grid_flow_type();
if (grid.has_los() && projectable(this->player_ptr, this->player_ptr->y, this->player_ptr->x, y1, x1)) {
- if ((distance(y1, x1, this->player_ptr->y, this->player_ptr->x) == 1) || (monrace.freq_spell > 0) || (grid.get_cost(&monrace) > 5)) {
+ if ((distance(y1, x1, this->player_ptr->y, this->player_ptr->x) == 1) || (monrace.freq_spell > 0) || (grid.get_cost(gf) > 5)) {
return;
}
}
auto use_scent = false;
- if (grid.get_cost(&monrace)) {
+ if (grid.get_cost(gf)) {
this->best = 999;
} else if (grid.when) {
const auto p_pos = this->player_ptr->get_position();
@@ -316,16 +318,17 @@ bool MonsterSweepGrid::check_movable_grid(POSITION *yp, POSITION *xp, const bool
*/
bool MonsterSweepGrid::sweep_ranged_attack_grid(POSITION *yp, POSITION *xp)
{
- auto *floor_ptr = this->player_ptr->current_floor_ptr;
- auto *m_ptr = &floor_ptr->m_list[this->m_idx];
- auto *r_ptr = &m_ptr->get_monrace();
- auto y1 = m_ptr->fy;
- auto x1 = m_ptr->fx;
+ const auto *floor_ptr = this->player_ptr->current_floor_ptr;
+ const auto *m_ptr = &floor_ptr->m_list[this->m_idx];
+ const auto *r_ptr = &m_ptr->get_monrace();
+ const auto y1 = m_ptr->fy;
+ const auto x1 = m_ptr->fx;
if (projectable(this->player_ptr, y1, x1, this->player_ptr->y, this->player_ptr->x)) {
return false;
}
- auto now_cost = (int)floor_ptr->grid_array[y1][x1].get_cost(r_ptr);
+ const auto gf = r_ptr->get_grid_flow_type();
+ int now_cost = floor_ptr->grid_array[y1][x1].get_cost(gf);
if (now_cost == 0) {
now_cost = 999;
}
@@ -345,7 +348,7 @@ bool MonsterSweepGrid::sweep_ranged_attack_grid(POSITION *yp, POSITION *xp)
}
const auto &grid = floor_ptr->get_grid(pos);
- this->cost = grid.get_cost(r_ptr);
+ this->cost = grid.get_cost(gf);
if (!this->is_best_cost(pos.y, pos.x, now_cost)) {
continue;
}
@@ -421,7 +424,7 @@ bool MonsterSweepGrid::sweep_runnable_away_grid(POSITION *yp, POSITION *xp)
}
auto dis = distance(y, x, y1, x1);
- auto s = 5000 / (dis + 3) - 500 / (floor_ptr->grid_array[y][x].get_distance(r_ptr) + 1);
+ auto s = 5000 / (dis + 3) - 500 / (floor_ptr->grid_array[y][x].get_distance(r_ptr->get_grid_flow_type()) + 1);
if (s < 0) {
s = 0;
}
@@ -464,7 +467,8 @@ void MonsterSweepGrid::determine_when_cost(POSITION *yp, POSITION *xp, POSITION
this->best = when;
} else {
const auto &monrace = floor_ptr->m_list[this->m_idx].get_monrace();
- this->cost = monrace.behavior_flags.has_any_of({ MonsterBehaviorType::BASH_DOOR, MonsterBehaviorType::OPEN_DOOR }) ? g_ptr->get_distance(&monrace) : g_ptr->get_cost(&monrace);
+ const auto gf = monrace.get_grid_flow_type();
+ this->cost = monrace.behavior_flags.has_any_of({ MonsterBehaviorType::BASH_DOOR, MonsterBehaviorType::OPEN_DOOR }) ? g_ptr->get_distance(gf) : g_ptr->get_cost(gf);
if ((this->cost == 0) || (this->best < this->cost)) {
continue;
}
diff --git a/src/racial/racial-draconian.cpp b/src/racial/racial-draconian.cpp
index 30664bc3e7..62c0b70f7b 100644
--- a/src/racial/racial-draconian.cpp
+++ b/src/racial/racial-draconian.cpp
@@ -6,11 +6,14 @@
#include "system/player-type-definition.h"
#include "target/target-getter.h"
#include "view/display-messages.h"
+#include
+#include
+#include
-static void decide_breath_kind(PlayerType *player_ptr, AttributeType *breath_type, concptr *breath_type_description)
+static std::optional> decide_breath_kind(PlayerType *player_ptr)
{
if (randint1(100) >= player_ptr->lev) {
- return;
+ return std::nullopt;
}
switch (player_ptr->pclass) {
@@ -22,14 +25,10 @@ static void decide_breath_kind(PlayerType *player_ptr, AttributeType *breath_typ
case PlayerClassType::ARCHER:
case PlayerClassType::SMITH:
if (one_in_(3)) {
- *breath_type = AttributeType::MISSILE;
- *breath_type_description = _("エレメント", "the elements");
- } else {
- *breath_type = AttributeType::SHARDS;
- *breath_type_description = _("破片", "shards");
+ return std::pair(AttributeType::MISSILE, _("エレメント", "the elements"));
}
- break;
+ return std::pair(AttributeType::SHARDS, _("破片", "shards"));
case PlayerClassType::MAGE:
case PlayerClassType::WARRIOR_MAGE:
case PlayerClassType::HIGH_MAGE:
@@ -39,100 +38,77 @@ static void decide_breath_kind(PlayerType *player_ptr, AttributeType *breath_typ
case PlayerClassType::BLUE_MAGE:
case PlayerClassType::MIRROR_MASTER:
if (one_in_(3)) {
- *breath_type = AttributeType::MANA;
- *breath_type_description = _("魔力", "mana");
- } else {
- *breath_type = AttributeType::DISENCHANT;
- *breath_type_description = _("劣化", "disenchantment");
+ return std::pair(AttributeType::MANA, _("魔力", "mana"));
}
- break;
+ return std::pair(AttributeType::DISENCHANT, _("劣化", "disenchantment"));
case PlayerClassType::CHAOS_WARRIOR:
- if (!one_in_(3)) {
- *breath_type = AttributeType::CONFUSION;
- *breath_type_description = _("混乱", "confusion");
- } else {
- *breath_type = AttributeType::CHAOS;
- *breath_type_description = _("カオス", "chaos");
+ if (one_in_(3)) {
+ return std::pair(AttributeType::CHAOS, _("カオス", "chaos"));
}
- break;
+ return std::pair(AttributeType::CONFUSION, _("混乱", "confusion"));
case PlayerClassType::MONK:
case PlayerClassType::SAMURAI:
case PlayerClassType::FORCETRAINER:
- if (!one_in_(3)) {
- *breath_type = AttributeType::CONFUSION;
- *breath_type_description = _("混乱", "confusion");
- } else {
- *breath_type = AttributeType::SOUND;
- *breath_type_description = _("轟音", "sound");
+ if (one_in_(3)) {
+ return std::pair(AttributeType::SOUND, _("轟音", "sound"));
}
- break;
+ return std::pair(AttributeType::CONFUSION, _("混乱", "confusion"));
case PlayerClassType::MINDCRAFTER:
- if (!one_in_(3)) {
- *breath_type = AttributeType::CONFUSION;
- *breath_type_description = _("混乱", "confusion");
- } else {
- *breath_type = AttributeType::PSI;
- *breath_type_description = _("精神エネルギー", "mental energy");
+ if (one_in_(3)) {
+ return std::pair(AttributeType::PSI, _("精神エネルギー", "mental energy"));
}
- break;
+ return std::pair(AttributeType::CONFUSION, _("混乱", "confusion"));
case PlayerClassType::PRIEST:
case PlayerClassType::PALADIN:
if (one_in_(3)) {
- *breath_type = AttributeType::HELL_FIRE;
- *breath_type_description = _("地獄の劫火", "hellfire");
- } else {
- *breath_type = AttributeType::HOLY_FIRE;
- *breath_type_description = _("聖なる炎", "holy fire");
+ return std::pair(AttributeType::HELL_FIRE, _("地獄の劫火", "hellfire"));
}
- break;
+ return std::pair(AttributeType::HOLY_FIRE, _("聖なる炎", "holy fire"));
case PlayerClassType::ROGUE:
case PlayerClassType::NINJA:
if (one_in_(3)) {
- *breath_type = AttributeType::DARK;
- *breath_type_description = _("暗黒", "darkness");
- } else {
- *breath_type = AttributeType::POIS;
- *breath_type_description = _("毒", "poison");
+ return std::pair(AttributeType::DARK, _("暗黒", "darkness"));
}
- break;
+ return std::pair(AttributeType::POIS, _("毒", "poison"));
case PlayerClassType::BARD:
- if (!one_in_(3)) {
- *breath_type = AttributeType::SOUND;
- *breath_type_description = _("轟音", "sound");
- } else {
- *breath_type = AttributeType::CONFUSION;
- *breath_type_description = _("混乱", "confusion");
+ if (one_in_(3)) {
+ return std::pair(AttributeType::CONFUSION, _("混乱", "confusion"));
}
- break;
- case PlayerClassType::ELEMENTALIST:
- *breath_type = get_element_type(player_ptr->element, 0);
- *breath_type_description = get_element_name(player_ptr->element, 0);
- break;
+ return std::pair(AttributeType::SOUND, _("轟音", "sound"));
+ case PlayerClassType::ELEMENTALIST: {
+ const auto type = get_element_type(player_ptr->element, 0);
+ const std::string name(get_element_name(player_ptr->element, 0));
+ return std::pair(type, name);
+ }
default:
- break;
+ return std::nullopt;
}
}
bool draconian_breath(PlayerType *player_ptr)
{
- AttributeType breath_type = (one_in_(3) ? AttributeType::COLD : AttributeType::FIRE);
- concptr breath_type_description = ((breath_type == AttributeType::COLD) ? _("冷気", "cold") : _("炎", "fire"));
+ auto breath_type = one_in_(3) ? AttributeType::COLD : AttributeType::FIRE;
+ std::string breath_type_description((breath_type == AttributeType::COLD) ? _("冷気", "cold") : _("炎", "fire"));
DIRECTION dir;
if (!get_aim_dir(player_ptr, &dir)) {
return false;
}
- decide_breath_kind(player_ptr, &breath_type, &breath_type_description);
- stop_mouth(player_ptr);
- msg_format(_("あなたは%sのブレスを吐いた。", "You breathe %s."), breath_type_description);
+ const auto special_breath = decide_breath_kind(player_ptr);
+ if (special_breath) {
+ breath_type = special_breath->first;
+ breath_type_description = special_breath->second;
+ }
+ stop_mouth(player_ptr);
+ msg_format(_("あなたは%sのブレスを吐いた。", "You breathe %s."), breath_type_description.data());
fire_breath(player_ptr, breath_type, dir, player_ptr->lev * 2, (player_ptr->lev / 15) + 1);
return true;
}
diff --git a/src/save/info-writer.cpp b/src/save/info-writer.cpp
index 226b58f58c..6cf7873c13 100644
--- a/src/save/info-writer.cpp
+++ b/src/save/info-writer.cpp
@@ -120,14 +120,10 @@ void wr_options()
wr_bool(autosave_t);
wr_s16b(autosave_freq);
- for (int i = 0; option_info[i].o_desc; i++) {
- int os = option_info[i].o_set;
- int ob = option_info[i].o_bit;
- if (!option_info[i].o_var) {
- continue;
- }
-
- if (*option_info[i].o_var) {
+ for (auto &option : option_info) {
+ int os = option.flag_position;
+ int ob = option.offset;
+ if (*option.value) {
g_option_flags[os] |= (1UL << ob);
} else {
g_option_flags[os] &= ~(1UL << ob);
diff --git a/src/system/enums/game-option-page.h b/src/system/enums/game-option-page.h
new file mode 100644
index 0000000000..9efc8570e5
--- /dev/null
+++ b/src/system/enums/game-option-page.h
@@ -0,0 +1,13 @@
+#pragma once
+
+enum class GameOptionPage : int {
+ INPUT,
+ MAPSCREEN,
+ TEXT,
+ GAMEPLAY,
+ DISTURBANCE,
+ BIRTH,
+ AUTODESTROY,
+ PLAYRECORD,
+ HIDE,
+};
diff --git a/src/system/enums/grid-flow.h b/src/system/enums/grid-flow.h
new file mode 100644
index 0000000000..d29e9af1df
--- /dev/null
+++ b/src/system/enums/grid-flow.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "util/enum-range.h"
+
+enum class GridFlow : int {
+ NORMAL = 0,
+ CAN_FLY = 1,
+ MAX = 2,
+};
+
+constexpr EnumRange GRID_FLOW_RANGE(GridFlow::NORMAL, GridFlow::MAX);
diff --git a/src/system/game-option-types.h b/src/system/game-option-types.h
deleted file mode 100644
index f4a8c702fe..0000000000
--- a/src/system/game-option-types.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-enum game_option_types {
- OPT_PAGE_INPUT,
- OPT_PAGE_MAPSCREEN,
- OPT_PAGE_TEXT,
- OPT_PAGE_GAMEPLAY,
- OPT_PAGE_DISTURBANCE,
- OPT_PAGE_BIRTH,
- OPT_PAGE_AUTODESTROY,
- OPT_PAGE_PLAYRECORD,
- OPT_PAGE_HIDE,
-};
diff --git a/src/system/grid-type-definition.cpp b/src/system/grid-type-definition.cpp
index 9556711159..60532272e7 100644
--- a/src/system/grid-type-definition.cpp
+++ b/src/system/grid-type-definition.cpp
@@ -2,10 +2,18 @@
#include "monster/monster-util.h"
#include "room/door-definition.h"
#include "system/angband-system.h"
-#include "system/monster-race-info.h"
+#include "system/enums/grid-flow.h"
#include "system/terrain-type-definition.h"
#include "util/bit-flags-calculator.h"
+Grid::Grid()
+{
+ for (const auto gf : GRID_FLOW_RANGE) {
+ this->costs[gf] = 0;
+ this->dists[gf] = 0;
+ }
+}
+
/*!
* @brief 指定座標がFLOOR属性を持ったマスかどうかを返す
* @param Y 指定Y座標
@@ -98,19 +106,14 @@ bool Grid::has_monster() const
return is_monster(this->m_idx);
}
-byte Grid::get_cost(const MonsterRaceInfo *r_ptr) const
-{
- return this->costs[get_grid_flow_type(r_ptr)];
-}
-
-byte Grid::get_distance(const MonsterRaceInfo *r_ptr) const
+uint8_t Grid::get_cost(GridFlow gf) const
{
- return this->dists[get_grid_flow_type(r_ptr)];
+ return this->costs.at(gf);
}
-flow_type Grid::get_grid_flow_type(const MonsterRaceInfo *r_ptr) const
+uint8_t Grid::get_distance(GridFlow gf) const
{
- return r_ptr->feature_flags.has(MonsterFeatureType::CAN_FLY) ? FLOW_CAN_FLY : FLOW_NORMAL;
+ return this->dists.at(gf);
}
/*
@@ -140,15 +143,15 @@ bool Grid::is_symbol(const int ch) const
void Grid::reset_costs()
{
- for (auto &cost : this->costs) {
- cost = 0;
+ for (const auto gf : GRID_FLOW_RANGE) {
+ this->costs[gf] = 0;
}
}
void Grid::reset_dists()
{
- for (auto &dist : this->dists) {
- dist = 0;
+ for (const auto gf : GRID_FLOW_RANGE) {
+ this->dists[gf] = 0;
}
}
diff --git a/src/system/grid-type-definition.h b/src/system/grid-type-definition.h
index dfe91f4670..e0845a7312 100644
--- a/src/system/grid-type-definition.h
+++ b/src/system/grid-type-definition.h
@@ -2,6 +2,7 @@
#include "object/object-index-list.h"
#include "system/angband.h"
+#include