OSDN Git Service

[Refactor] #1710 Definitions QUEST_STATUS_* to enum class QuestStatusType
[hengbandforosx/hengbandosx.git] / src / wizard / wizard-game-modifier.cpp
1 /*!
2  * @brief ゲーム属性を変更するデバッグコマンド
3  * @date 2021/03/07
4  */
5
6 #include "wizard/wizard-game-modifier.h"
7 #include "core/asking-player.h"
8 #include "dungeon/quest.h"
9 #include "info-reader/fixed-map-parser.h"
10 #include "io/input-key-requester.h"
11 #include "market/arena.h"
12 #include "monster-race/monster-race.h"
13 #include "monster-race/race-flags1.h"
14 #include "monster-race/race-flags7.h"
15 #include "player-info/self-info.h"
16 #include "system/floor-type-definition.h"
17 #include "system/monster-race-definition.h"
18 #include "system/player-type-definition.h"
19 #include "system/system-variables.h"
20 #include "term/screen-processor.h"
21 #include "util/bit-flags-calculator.h"
22 #include "util/int-char-converter.h"
23 #include "view/display-messages.h"
24 #include "wizard/wizard-special-process.h"
25 #include <array>
26 #include <sstream>
27 #include <string>
28 #include <tuple>
29 #include <vector>
30
31 void wiz_enter_quest(player_type *player_ptr);
32 void wiz_complete_quest(player_type *player_ptr);
33 void wiz_restore_monster_max_num();
34
35 /*!
36  * @brief ゲーム設定コマンド一覧表
37  */
38 constexpr std::array wizard_game_modifier_menu_table = {
39     std::make_tuple('t', _("プレイ時間変更", "Modify played time")),
40     std::make_tuple('q', _("現在のクエストを完了", "Complete current quest")),
41     std::make_tuple('Q', _("クエストに突入", "Enter quest")),
42     std::make_tuple('u', _("ユニーク/ナズグルの生存数を復元", "Restore living info of unique/nazgul")),
43     std::make_tuple('g', _("モンスター闘技場出場者更新", "Update gambling monster")),
44 };
45
46 /*!
47  * @brief ゲーム設定コマンドの一覧を表示する
48  */
49 void display_wizard_game_modifier_menu()
50 {
51     for (auto y = 1U; y <= wizard_game_modifier_menu_table.size(); y++)
52         term_erase(14, y, 64);
53
54     int r = 1;
55     int c = 15;
56     for (const auto &[symbol, desc] : wizard_game_modifier_menu_table) {
57         std::stringstream ss;
58         ss << symbol << ") " << desc;
59         put_str(ss.str().c_str(), r++, c);
60     }
61 }
62
63 /*!
64  * @brief ゲーム設定コマンドの入力を受け付ける
65  * @param player_ptr プレイヤーの情報へのポインタ
66  */
67 void wizard_game_modifier(player_type *player_ptr)
68 {
69     screen_save();
70     display_wizard_game_modifier_menu();
71
72     char cmd;
73     get_com("Player Command: ", &cmd, false);
74     screen_load();
75
76     switch (cmd) {
77     case ESCAPE:
78     case ' ':
79     case '\n':
80     case '\r':
81         break;
82     case 'g':
83         update_gambling_monsters(player_ptr);
84         break;
85     case 'q':
86         wiz_complete_quest(player_ptr);
87         break;
88     case 'Q':
89         wiz_enter_quest(player_ptr);
90         break;
91     case 'u':
92         wiz_restore_monster_max_num();
93         break;
94     case 't':
95         set_gametime();
96         break;
97     }
98 }
99
100 /*!
101  * @brief 指定したクエストに突入する
102  * @param プレイヤーの情報へのポインタ
103  */
104 void wiz_enter_quest(player_type* player_ptr)
105 {
106     char ppp[30];
107     char tmp_val[5];
108     int tmp_int;
109     sprintf(ppp, "QuestID (0-%d):", max_q_idx - 1);
110     sprintf(tmp_val, "%d", 0);
111
112     if (!get_string(ppp, tmp_val, 3))
113         return;
114
115     tmp_int = atoi(tmp_val);
116     if ((tmp_int < 0) || (tmp_int >= max_q_idx))
117         return;
118
119     init_flags = i2enum<init_flags_type>(INIT_SHOW_TEXT | INIT_ASSIGN);
120     player_ptr->current_floor_ptr->inside_quest = (QUEST_IDX)tmp_int;
121     parse_fixed_map(player_ptr, "q_info.txt", 0, 0, 0, 0);
122     quest[tmp_int].status = QuestStatusType::TAKEN;
123     if (quest[tmp_int].dungeon == 0)
124         exe_enter_quest(player_ptr, (QUEST_IDX)tmp_int);
125 }
126
127 /*!
128  * @brief 指定したクエストを完了させる
129  * @param プレイヤーの情報へのポインタ
130  */
131 void wiz_complete_quest(player_type *player_ptr)
132 {
133     if (!player_ptr->current_floor_ptr->inside_quest) {
134         msg_print("No current quest");
135         msg_print(nullptr);
136         return;
137     }
138
139     if (quest[player_ptr->current_floor_ptr->inside_quest].status == QuestStatusType::TAKEN)
140         complete_quest(player_ptr, player_ptr->current_floor_ptr->inside_quest);
141 }
142
143 void wiz_restore_monster_max_num()
144 {
145     MONRACE_IDX r_idx = command_arg;
146     if (r_idx <= 0) {
147         std::stringstream ss;
148         ss << "Monster race (1-" << r_info.size() << "): ";
149
150         char tmp_val[160] = "\0";
151         if (!get_string(ss.str().c_str(), tmp_val, 5))
152             return;
153
154         r_idx = (MONRACE_IDX)atoi(tmp_val);
155         if (r_idx <= 0 || r_idx >= static_cast<MONRACE_IDX>(r_info.size()))
156             return;
157     }
158
159     monster_race *r_ptr = &r_info[r_idx];
160     if (r_ptr->name.empty()) {
161         msg_print("そのモンスターは存在しません。");
162         msg_print(nullptr);
163         return;
164     }
165
166     MONSTER_NUMBER n = 0;
167     if (any_bits(r_ptr->flags1, RF1_UNIQUE))
168         n = 1;
169     else if (any_bits(r_ptr->flags7, RF7_NAZGUL))
170         n = MAX_NAZGUL_NUM;
171
172     if (n == 0) {
173         msg_print("出現数に制限がないモンスターです。");
174         msg_print(nullptr);
175         return;
176     }
177
178     r_ptr->max_num = n;
179     r_ptr->r_pkills = 0;
180     r_ptr->r_akills = 0;
181
182     std::stringstream ss;
183     ss << r_ptr->name << _("の出現数を復元しました。", " can appear again now.");
184     msg_print(ss.str().c_str());
185     msg_print(nullptr);
186 }