OSDN Git Service

2c66aa24b73f33f991d980c487ab2589c3841954
[hengbandforosx/hengbandosx.git] / src / knowledge / knowledge-self.cpp
1 /*!
2  * @brief 自己に関する情報を表示する
3  * @date 2020/04/24
4  * @author Hourier
5  */
6
7 #include <cstdlib>
8
9 #include "knowledge-self.h"
10 #include "birth/birth-explanations-table.h"
11 #include "core/show-file.h"
12 #include "flavor/flavor-describer.h"
13 #include "floor/floor-town.h"
14 #include "info-reader/fixed-map-parser.h"
15 #include "io-dump/dump-util.h"
16 #include "player-info/avatar.h"
17 #include "player-info/alignment.h"
18 #include "player/player-class.h"
19 #include "player/player-status-table.h"
20 #include "player/race-info-table.h"
21 #include "store/store-util.h"
22 #include "system/object-type-definition.h"
23 #include "system/player-type-definition.h"
24 #include "util/angband-files.h"
25 #include "util/buffer-shaper.h"
26 #include "util/int-char-converter.h"
27 #include "util/string-processor.h"
28 #include "world/world.h"
29 #include <string>
30
31 /*
32  * List virtues & status
33  */
34 void do_cmd_knowledge_virtues(player_type *creature_ptr)
35 {
36     FILE *fff = NULL;
37     GAME_TEXT file_name[FILE_NAME_SIZE];
38     if (!open_temporary_file(&fff, file_name))
39         return;
40
41     std::unique_ptr<PlayerAlignment> alignment(new PlayerAlignment(creature_ptr));
42     std::string alg = alignment->your_alignment();
43     fprintf(fff, _("現在の属性 : %s\n\n", "Your alignment : %s\n\n"), alg.c_str());
44     dump_virtues(creature_ptr, fff);
45     angband_fclose(fff);
46     (void)show_file(creature_ptr, TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
47     fd_kill(file_name);
48 }
49
50 /*!
51  * @brief 自分に関する情報を画面に表示する
52  * @param creature_ptr プレーヤーへの参照ポインタ
53  * @param fff ファイルポインタ
54  * @return なし
55  */
56 static void dump_yourself(player_type *creature_ptr, FILE *fff)
57 {
58     if (!fff)
59         return;
60
61     char temp[80 * 10];
62     shape_buffer(race_explanations[creature_ptr->prace], 78, temp, sizeof(temp));
63     fprintf(fff, "\n\n");
64     fprintf(fff, _("種族: %s\n", "Race: %s\n"), race_info[creature_ptr->prace].title);
65     concptr t = temp;
66
67     for (int i = 0; i < 10; i++) {
68         if (t[0] == 0)
69             break;
70         fprintf(fff, "%s\n", t);
71         t += strlen(t) + 1;
72     }
73
74     shape_buffer(class_explanations[creature_ptr->pclass], 78, temp, sizeof(temp));
75     fprintf(fff, "\n");
76     fprintf(fff, _("職業: %s\n", "Class: %s\n"), class_info[creature_ptr->pclass].title);
77
78     t = temp;
79     for (int i = 0; i < 10; i++) {
80         if (t[0] == 0)
81             break;
82         fprintf(fff, "%s\n", t);
83         t += strlen(t) + 1;
84     }
85
86     shape_buffer(personality_explanations[creature_ptr->pseikaku], 78, temp, sizeof(temp));
87     fprintf(fff, "\n");
88     fprintf(fff, _("性格: %s\n", "Pesonality: %s\n"), personality_info[creature_ptr->pseikaku].title);
89
90     t = temp;
91     for (int i = 0; i < A_MAX; i++) {
92         if (t[0] == 0)
93             break;
94         fprintf(fff, "%s\n", t);
95         t += strlen(t) + 1;
96     }
97
98     fprintf(fff, "\n");
99     if (creature_ptr->realm1) {
100         shape_buffer(realm_explanations[technic2magic(creature_ptr->realm1) - 1], 78, temp, sizeof(temp));
101         fprintf(fff, _("魔法: %s\n", "Realm: %s\n"), realm_names[creature_ptr->realm1]);
102
103         t = temp;
104         for (int i = 0; i < A_MAX; i++) {
105             if (t[0] == 0)
106                 break;
107
108             fprintf(fff, "%s\n", t);
109             t += strlen(t) + 1;
110         }
111     }
112
113     fprintf(fff, "\n");
114     if (creature_ptr->realm2) {
115         shape_buffer(realm_explanations[technic2magic(creature_ptr->realm2) - 1], 78, temp, sizeof(temp));
116         fprintf(fff, _("魔法: %s\n", "Realm: %s\n"), realm_names[creature_ptr->realm2]);
117
118         t = temp;
119         for (int i = 0; i < A_MAX; i++) {
120             if (t[0] == 0)
121                 break;
122
123             fprintf(fff, "%s\n", t);
124             t += strlen(t) + 1;
125         }
126     }
127 }
128
129 /*!
130  * @brief 勝利済みの職業をダンプする
131  * @param fff ファイルストリームのポインタ
132  * @return なし
133  */
134 static void dump_winner_classes(FILE *fff)
135 {
136     int n = current_world_ptr->sf_winner.count();
137     concptr ss = n > 1 ? _("", "s") : "";
138     fprintf(fff, _("*勝利*済みの職業%s : %d\n", "Class of *Winner%s* : %d\n"), ss, n);
139     if (n == 0)
140         return;
141
142     size_t max_len = 75;
143     std::string s = "";
144     std::string l = "";
145     for (int c = 0; c < MAX_CLASS; c++) {
146         if (current_world_ptr->sf_winner.has_not(static_cast<player_class_type>(c)))
147             continue;
148
149         auto &cl = class_info[c];
150         auto t = std::string(cl.title);
151
152         if (current_world_ptr->sf_retired.has_not(static_cast<player_class_type>(c)))
153             t = "(" + t + ")";
154
155         if (l.size() + t.size() + 2 > max_len) {
156             fprintf(fff, " %s\n", str_rtrim(l).c_str());
157             l = "";
158         }
159         if (l.size() > 0)
160             l += ", ";
161         l += t;
162     }
163
164     if (l.size() > 0)
165         fprintf(fff, " %s\n", str_rtrim(l).c_str());
166 }
167
168 /*
169  * List virtues & status
170  *
171  */
172 void do_cmd_knowledge_stat(player_type *creature_ptr)
173 {
174     FILE *fff = NULL;
175     GAME_TEXT file_name[FILE_NAME_SIZE];
176     if (!open_temporary_file(&fff, file_name))
177         return;
178
179     update_playtime();
180     u32b play_time = current_world_ptr->play_time;
181     u32b all_time = current_world_ptr->sf_play_time + play_time;
182     fprintf(fff, _("現在のプレイ時間 : %d:%02d:%02d\n", "Current Play Time is %d:%02d:%02d\n"), play_time / (60 * 60), (play_time / 60) % 60, play_time % 60);
183     fprintf(fff, _("合計のプレイ時間 : %d:%02d:%02d\n", "  Total play Time is %d:%02d:%02d\n"), all_time / (60 * 60), (all_time / 60) % 60, all_time % 60);
184     fputs("\n", fff);
185
186     int percent
187         = (int)(((long)creature_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) / (2 * creature_ptr->hitdie + ((PY_MAX_LEVEL - 1 + 3) * (creature_ptr->hitdie + 1))));
188
189     if (creature_ptr->knowledge & KNOW_HPRATE)
190         fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
191     else
192         fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
193
194     fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
195     for (int v_nr = 0; v_nr < A_MAX; v_nr++) {
196         if ((creature_ptr->knowledge & KNOW_STAT) || creature_ptr->stat_max[v_nr] == creature_ptr->stat_max_max[v_nr])
197             fprintf(fff, "%s 18/%d\n", stat_names[v_nr], creature_ptr->stat_max_max[v_nr] - 18);
198         else
199             fprintf(fff, "%s ???\n", stat_names[v_nr]);
200     }
201
202     dump_yourself(creature_ptr, fff);
203     dump_winner_classes(fff);
204     angband_fclose(fff);
205
206     (void)show_file(creature_ptr, TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
207     fd_kill(file_name);
208 }
209
210 /*
211  * List my home
212  * @param player_ptr プレーヤーへの参照ポインタ
213  * @return なし
214  */
215 void do_cmd_knowledge_home(player_type *player_ptr)
216 {
217     parse_fixed_map(player_ptr, "w_info.txt", 0, 0, current_world_ptr->max_wild_y, current_world_ptr->max_wild_x);
218
219     FILE *fff = NULL;
220     GAME_TEXT file_name[FILE_NAME_SIZE];
221     if (!open_temporary_file(&fff, file_name))
222         return;
223
224     store_type *store_ptr;
225     store_ptr = &town_info[1].store[STORE_HOME];
226
227     if (store_ptr->stock_num) {
228 #ifdef JP
229         TERM_LEN x = 1;
230 #endif
231         fprintf(fff, _("  [ 我が家のアイテム ]\n", "  [Home Inventory]\n"));
232         concptr paren = ")";
233         GAME_TEXT o_name[MAX_NLEN];
234         for (int i = 0; i < store_ptr->stock_num; i++) {
235 #ifdef JP
236             if ((i % 12) == 0)
237                 fprintf(fff, "\n ( %d ページ )\n", x++);
238             describe_flavor(player_ptr, o_name, &store_ptr->stock[i], 0);
239             if (strlen(o_name) <= 80 - 3) {
240                 fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
241             } else {
242                 int n;
243                 char *t;
244                 for (n = 0, t = o_name; n < 80 - 3; n++, t++)
245                     if (iskanji(*t)) {
246                         t++;
247                         n++;
248                     }
249                 if (n == 81 - 3)
250                     n = 79 - 3; /* 最後が漢字半分 */
251
252                 fprintf(fff, "%c%s %.*s\n", I2A(i % 12), paren, n, o_name);
253                 fprintf(fff, "   %.77s\n", o_name + n);
254             }
255 #else
256             describe_flavor(player_ptr, o_name, &store_ptr->stock[i], 0);
257             fprintf(fff, "%c%s %s\n", I2A(i % 12), paren, o_name);
258 #endif
259         }
260
261         fprintf(fff, "\n\n");
262     }
263
264     angband_fclose(fff);
265     (void)show_file(player_ptr, TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
266     fd_kill(file_name);
267 }