OSDN Git Service

[Refactor] #38862 Moved view-mainwindow.c/h to display-main-window.c/h
[hengband/hengband.git] / src / knowledge / knowledge-inventory.c
1 /*
2  * @brief 装備の耐性を表示する
3  * @date 2020/04/20
4  * @author Hourier
5  */
6
7 #include "angband.h"
8 #include "knowledge/knowledge-inventory.h"
9 #include "cmd/dump-util.h"
10 #include "core/show-file.h"
11 #include "object-flavor.h"
12 #include "market/store-util.h"
13 #include "floor-town.h"
14 #include "object-hook.h"
15 #include "object/object-kind.h"
16
17 static concptr inven_res_label = _(
18         "                               酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
19         "                               AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
20
21 #define IM_FLAG_STR  _("*", "* ")
22 #define HAS_FLAG_STR _("+", "+ ")
23 #define NO_FLAG_STR  _("・", ". ")
24
25
26 /*!
27  * @brief 4元素耐性を表示する
28  * @param immunity 4元素耐性の種類 (二重?)
29  * @param resistance 4元素耐性
30  * @param flags 耐性配列へのポインタ
31  * @param fff 一時ファイルへのポインタ
32  * @return なし
33  */
34 static void print_im_or_res_flag(int immunity, int resistance, BIT_FLAGS *flags, FILE *fff)
35 {
36         fputs(have_flag(flags, immunity) ? IM_FLAG_STR :
37               (have_flag(flags, resistance) ? HAS_FLAG_STR : NO_FLAG_STR), fff);
38 }
39
40
41 /*!
42  * @brief 4元素以外の耐性を表示する
43  * @param tr 耐性
44  * @param flags 耐性配列へのポインタ
45  * @param fff 一時ファイルへのポインタ
46  * @return なし
47  */
48 static void print_flag(int tr, BIT_FLAGS *flags, FILE *fff)
49 {
50         fputs(have_flag(flags, tr) ? HAS_FLAG_STR : NO_FLAG_STR, fff);
51 }
52
53
54 /*!
55  * @brief 特殊なアイテムかどうかを調べる
56  * @param o_ptr アイテムへの参照ポインタ
57  * @param tval アイテム主分類番号
58  * @return 特殊なアイテムならTRUE
59  */
60 static bool determine_spcial_item_type(object_type *o_ptr, OBJECT_TYPE_VALUE tval)
61 {
62         bool is_special_item_type = (object_is_wearable(o_ptr) && object_is_ego(o_ptr))
63                 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
64                 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
65                 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
66                 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
67                 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
68                 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
69                 || object_is_artifact(o_ptr);
70
71         return is_special_item_type;
72 }
73
74
75 /*!
76  * @brief アイテムに耐性の表示をする必要があるかを判定する
77  * @param o_ptr アイテムへの参照ポインタ
78  * @param tval アイテム主分類番号
79  * @return 必要があるならTRUE
80  */
81 static bool check_item_knowledge(object_type *o_ptr, OBJECT_TYPE_VALUE tval)
82 {
83         if (o_ptr->k_idx == 0) return FALSE;
84         if (o_ptr->tval != tval) return FALSE;
85         if (!object_is_known(o_ptr)) return FALSE;
86         if (!determine_spcial_item_type(o_ptr, tval)) return FALSE;
87
88         return TRUE;
89 }
90
91
92 /*!
93  * todo ここの関数から表示用の関数に移したい
94  * @brief 鑑定済アイテムの耐性を表示する
95  * @param o_ptr アイテムへの参照ポインタ
96  * @param fff 一時ファイルへの参照ポインタ
97  * @return なし
98  */
99 static void display_identified_resistances_flag(object_type *o_ptr, FILE *fff)
100 {
101         BIT_FLAGS flags[TR_FLAG_SIZE];
102         object_flags_known(o_ptr, flags);
103
104         print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID, flags, fff);
105         print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC, flags, fff);
106         print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE, flags, fff);
107         print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD, flags, fff);
108         print_flag(TR_RES_POIS, flags, fff);
109         print_flag(TR_RES_LITE, flags, fff);
110         print_flag(TR_RES_DARK, flags, fff);
111         print_flag(TR_RES_SHARDS, flags, fff);
112         print_flag(TR_RES_SOUND, flags, fff);
113         print_flag(TR_RES_NETHER, flags, fff);
114         print_flag(TR_RES_NEXUS, flags, fff);
115         print_flag(TR_RES_CHAOS, flags, fff);
116         print_flag(TR_RES_DISEN, flags, fff);
117
118         fputs(" ", fff);
119
120         print_flag(TR_RES_BLIND, flags, fff);
121         print_flag(TR_RES_FEAR, flags, fff);
122         print_flag(TR_RES_CONF, flags, fff);
123         print_flag(TR_FREE_ACT, flags, fff);
124         print_flag(TR_SEE_INVIS, flags, fff);
125         print_flag(TR_HOLD_EXP, flags, fff);
126         print_flag(TR_TELEPATHY, flags, fff);
127         print_flag(TR_SLOW_DIGEST, flags, fff);
128         print_flag(TR_REGEN, flags, fff);
129         print_flag(TR_LEVITATION, flags, fff);
130
131         fputc('\n', fff);
132 }
133
134
135 /*!
136  * @brief アイテム1つ当たりの耐性を表示する
137  * @param creature_ptr プレーヤーへの参照ポインタ
138  * @param fff 一時ファイルへの参照ポインタ
139  * @param o_ptr アイテムへの参照ポインタ
140  * @param where アイテムの場所 (手持ち、家等) を示す文字列への参照ポインタ
141  * @return なし
142  */
143 static void do_cmd_knowledge_inventory_aux(player_type *creature_ptr, FILE *fff, object_type *o_ptr, char *where)
144 {
145         int i = 0;
146         GAME_TEXT o_name[MAX_NLEN];
147         object_desc(creature_ptr, o_name, o_ptr, OD_NAME_ONLY);
148         while (o_name[i] && (i < 26))
149         {
150 #ifdef JP
151                 if (iskanji(o_name[i])) i++;
152 #endif
153                 i++;
154         }
155
156         if (i < 28)
157         {
158                 while (i < 28)
159                 {
160                         o_name[i] = ' '; i++;
161                 }
162         }
163
164         o_name[i] = '\0';
165
166         fprintf(fff, "%s %s", where, o_name);
167
168         if (!OBJECT_IS_FULL_KNOWN(o_ptr))
169         {
170                 fputs(_("-------不明--------------- -------不明---------\n",
171                         "-------unknown------------ -------unknown------\n"), fff);
172                 return;
173         }
174
175         display_identified_resistances_flag(o_ptr, fff);
176 }
177
178
179 /*!
180  * @brief 9行おきにラベルを追加する
181  * @param label_number 現在の行数
182  * @param fff 一時ファイルへの参照ポインタ
183  * @return なし
184  */
185 static void add_res_label(int *label_number, FILE *fff)
186 {
187         (*label_number)++;
188         if (*label_number == 9)
189         {
190                 *label_number = 0;
191                 fprintf(fff, "%s\n", inven_res_label);
192         }
193 }
194
195
196 /*!
197  * @brief 9行ごとに行数をリセットする
198  * @param label_number 現在の行数
199  * @param fff 一時ファイルへの参照ポインタ
200  * @return なし
201  */
202 static void reset_label_number(int *label_number, FILE *fff)
203 {
204         if (*label_number == 0) return;
205
206         for (; *label_number < 9; (*label_number)++)
207         {
208                 fputc('\n', fff);
209         }
210
211         *label_number = 0;
212         fprintf(fff, "%s\n", inven_res_label);
213 }
214
215
216 /*!
217  * 装備中のアイテムについて、耐性を表示する
218  * @param creature_ptr プレーヤーへの参照ポインタ
219  * @param tval アイテム主分類番号
220  * @param label_number 現在の行数
221  * @param fff ファイルへの参照ポインタ
222  * @return なし
223  */
224 static void show_wearing_equipment_resistances(player_type *creature_ptr, OBJECT_TYPE_VALUE tval, int *label_number, FILE *fff)
225 {
226         char where[32];
227         strcpy(where, _("装", "E "));
228         for (int i = INVEN_RARM; i < INVEN_TOTAL; i++)
229         {
230                 object_type *o_ptr = &creature_ptr->inventory_list[i];
231                 if (!check_item_knowledge(o_ptr, tval))
232                         continue;
233
234                 do_cmd_knowledge_inventory_aux(creature_ptr, fff, o_ptr, where);
235                 add_res_label(label_number, fff);
236         }
237 }
238
239
240 /*!
241  * 手持ち中のアイテムについて、耐性を表示する
242  * @param creature_ptr プレーヤーへの参照ポインタ
243  * @param tval アイテム主分類番号
244  * @param label_number 現在の行数
245  * @param fff ファイルへの参照ポインタ
246  * @return なし
247  */
248 static void show_holding_equipment_resistances(player_type *creature_ptr, OBJECT_TYPE_VALUE tval, int *label_number, FILE *fff)
249 {
250         char where[32];
251         strcpy(where, _("持", "I "));
252         for (int i = 0; i < INVEN_PACK; i++)
253         {
254                 object_type *o_ptr = &creature_ptr->inventory_list[i];
255                 if (!check_item_knowledge(o_ptr, tval))
256                         continue;
257
258                 do_cmd_knowledge_inventory_aux(creature_ptr, fff, o_ptr, where);
259                 add_res_label(label_number, fff);
260         }
261 }
262
263
264 /*!
265  * 我が家のアイテムについて、耐性を表示する
266  * @param creature_ptr プレーヤーへの参照ポインタ
267  * @param tval アイテム主分類番号
268  * @param label_number 現在の行数
269  * @param fff ファイルへの参照ポインタ
270  * @return なし
271  */
272 static void show_home_equipment_resistances(player_type *creature_ptr, OBJECT_TYPE_VALUE tval, int *label_number, FILE *fff)
273 {
274         store_type *store_ptr;
275         store_ptr = &town_info[1].store[STORE_HOME];
276         char where[32];
277         strcpy(where, _("家", "H "));
278         for (int i = 0; i < store_ptr->stock_num; i++)
279         {
280                 object_type *o_ptr = &store_ptr->stock[i];
281                 if (!check_item_knowledge(o_ptr, tval))
282                         continue;
283
284                 do_cmd_knowledge_inventory_aux(creature_ptr, fff, o_ptr, where);
285                 add_res_label(label_number, fff);
286         }
287 }
288
289
290 /*
291  * @brief Display *ID* ed weapons/armors's resistances
292  * @param creature_ptr プレーヤーへの参照ポインタ
293  * @return なし
294  */
295 void do_cmd_knowledge_inventory(player_type *creature_ptr)
296 {
297         FILE *fff = NULL;
298         GAME_TEXT file_name[FILE_NAME_SIZE];
299         if (!open_temporary_file(&fff, file_name)) return;
300
301         fprintf(fff, "%s\n", inven_res_label);
302         int label_number = 0;
303         for (OBJECT_TYPE_VALUE tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
304         {
305                 reset_label_number(&label_number, fff);
306                 show_wearing_equipment_resistances(creature_ptr, tval, &label_number, fff);
307                 show_holding_equipment_resistances(creature_ptr, tval, &label_number, fff);
308                 show_home_equipment_resistances(creature_ptr, tval, &label_number, fff);
309         }
310
311         my_fclose(fff);
312         (void)show_file(creature_ptr, TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
313         fd_kill(file_name);
314 }