OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[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 "monster-race/race-indice-types.h"
16 #include "player-info/self-info.h"
17 #include "system/floor-type-definition.h"
18 #include "system/monster-race-info.h"
19 #include "system/player-type-definition.h"
20 #include "system/system-variables.h"
21 #include "term/screen-processor.h"
22 #include "util/bit-flags-calculator.h"
23 #include "util/int-char-converter.h"
24 #include "view/display-messages.h"
25 #include "wizard/wizard-special-process.h"
26 #include <array>
27 #include <sstream>
28 #include <string>
29 #include <tuple>
30 #include <vector>
31
32 void wiz_enter_quest(PlayerType *player_ptr);
33 void wiz_complete_quest(PlayerType *player_ptr);
34 void wiz_restore_monster_max_num(MonsterRaceId r_idx);
35
36 /*!
37  * @brief ゲーム設定コマンド一覧表
38  */
39 constexpr std::array wizard_game_modifier_menu_table = {
40     std::make_tuple('t', _("プレイ時間変更", "Modify played time")),
41     std::make_tuple('q', _("現在のクエストを完了", "Complete current quest")),
42     std::make_tuple('Q', _("クエストに突入", "Enter quest")),
43     std::make_tuple('u', _("ユニーク/ナズグルの生存数を復元", "Restore living info of unique/nazgul")),
44     std::make_tuple('g', _("モンスター闘技場出場者更新", "Update gambling monster")),
45 };
46
47 /*!
48  * @brief ゲーム設定コマンドの一覧を表示する
49  */
50 void display_wizard_game_modifier_menu()
51 {
52     for (auto y = 1U; y <= wizard_game_modifier_menu_table.size(); y++) {
53         term_erase(14, y, 64);
54     }
55
56     int r = 1;
57     int c = 15;
58     for (const auto &[symbol, desc] : wizard_game_modifier_menu_table) {
59         std::stringstream ss;
60         ss << symbol << ") " << desc;
61         put_str(ss.str(), r++, c);
62     }
63 }
64
65 /*!
66  * @brief ゲーム設定コマンドの入力を受け付ける
67  * @param player_ptr プレイヤーの情報へのポインタ
68  */
69 void wizard_game_modifier(PlayerType *player_ptr)
70 {
71     screen_save();
72     display_wizard_game_modifier_menu();
73
74     const auto command = input_command("Player Command: ");
75     const auto cmd = command.value_or(ESCAPE);
76     screen_load();
77
78     switch (cmd) {
79     case ESCAPE:
80     case ' ':
81     case '\n':
82     case '\r':
83         break;
84     case 'g':
85         update_gambling_monsters(player_ptr);
86         break;
87     case 'q':
88         wiz_complete_quest(player_ptr);
89         break;
90     case 'Q':
91         wiz_enter_quest(player_ptr);
92         break;
93     case 'u':
94         wiz_restore_monster_max_num(i2enum<MonsterRaceId>(command_arg));
95         break;
96     case 't':
97         set_gametime();
98         break;
99     }
100 }
101
102 /*!
103  * @brief 指定したクエストに突入する
104  * @param プレイヤーの情報へのポインタ
105  */
106 void wiz_enter_quest(PlayerType *player_ptr)
107 {
108     auto &quest_list = QuestList::get_instance();
109     const auto quest_max = enum2i(quest_list.rbegin()->first);
110     const auto quest_num = input_numerics("QuestID", 0, quest_max - 1, QuestId::NONE);
111     if (!quest_num.has_value()) {
112         return;
113     }
114
115     auto q_idx = quest_num.value();
116     init_flags = i2enum<init_flags_type>(INIT_SHOW_TEXT | INIT_ASSIGN);
117     player_ptr->current_floor_ptr->quest_number = q_idx;
118     parse_fixed_map(player_ptr, QUEST_DEFINITION_LIST, 0, 0, 0, 0);
119     quest_list[q_idx].status = QuestStatusType::TAKEN;
120     if (quest_list[q_idx].dungeon == 0) {
121         exe_enter_quest(player_ptr, q_idx);
122     }
123 }
124
125 /*!
126  * @brief 指定したクエストを完了させる
127  * @param プレイヤーの情報へのポインタ
128  */
129 void wiz_complete_quest(PlayerType *player_ptr)
130 {
131     if (!inside_quest(player_ptr->current_floor_ptr->quest_number)) {
132         msg_print("No current quest");
133         msg_print(nullptr);
134         return;
135     }
136
137     const auto &quest_list = QuestList::get_instance();
138     if (quest_list[player_ptr->current_floor_ptr->quest_number].status == QuestStatusType::TAKEN) {
139         complete_quest(player_ptr, player_ptr->current_floor_ptr->quest_number);
140     }
141 }
142
143 void wiz_restore_monster_max_num(MonsterRaceId r_idx)
144 {
145     if (!MonsterRace(r_idx).is_valid()) {
146         const auto restore_monrace_id = input_numerics("MonsterID", 1, monraces_info.size() - 1, MonsterRaceId::FILTHY_URCHIN);
147         if (!restore_monrace_id.has_value()) {
148             return;
149         }
150
151         r_idx = restore_monrace_id.value();
152     }
153
154     auto *r_ptr = &monraces_info[r_idx];
155     auto n = 0;
156     if (r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
157         n = 1;
158     } else if (r_ptr->population_flags.has(MonsterPopulationType::NAZGUL)) {
159         n = MAX_NAZGUL_NUM;
160     }
161
162     if (n == 0) {
163         msg_print(_("出現数に制限がないモンスターです。", "This monster can appear any time."));
164         msg_print(nullptr);
165         return;
166     }
167
168     r_ptr->max_num = n;
169     r_ptr->r_pkills = 0;
170     r_ptr->r_akills = 0;
171
172     std::stringstream ss;
173     ss << r_ptr->name << _("の出現数を復元しました。", " can appear again now.");
174     msg_print(ss.str());
175     msg_print(nullptr);
176 }