OSDN Git Service

[Refactor] #39964 Separated autopick-registry.c/h from autopick.c/h
[hengband/hengband.git] / src / autopick / autopick-registry.c
1 /*!
2  * @brief 自動拾いにアイテムを登録する
3  * @date 2020/04/26
4  * @author Hourier
5  */
6  
7 #include "angband.h"
8 #include "autopick/autopick-registry.h"
9 #include "autopick/autopick-util.h"
10 #include "autopick/autopick-methods-table.h"
11 #include "autopick/autopick-reader-writer.h"
12 #include "autopick/autopick-entry.h"
13 #include "autopick/autopick-finder.h"
14 #include "autopick/autopick-adder.h"
15 #include "object-hook.h"
16 #include "object/object-kind.h"
17 #include "object-flavor.h"
18 #include "util.h"
19 #include "files.h"
20
21 static const char autoregister_header[] = "?:$AUTOREGISTER";
22
23 /*
24  *  Clear auto registered lines in the picktype.prf .
25  */
26 static bool clear_auto_register(player_type *player_ptr)
27 {
28         char pref_file[1024];
29         path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_WITH_PNAME));
30         FILE *pref_fff;
31         pref_fff = my_fopen(pref_file, "r");
32
33         if (!pref_fff)
34         {
35                 path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_DEFAULT));
36                 pref_fff = my_fopen(pref_file, "r");
37         }
38
39         if (!pref_fff)
40         {
41                 return TRUE;
42         }
43
44         char tmp_file[1024];
45         FILE *tmp_fff;
46         tmp_fff = my_fopen_temp(tmp_file, sizeof(tmp_file));
47         if (!tmp_fff)
48         {
49                 fclose(pref_fff);
50                 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
51                 msg_print(NULL);
52                 return FALSE;
53         }
54
55         bool autoregister = FALSE;
56         int num = 0;
57         char buf[1024];
58         while (TRUE)
59         {
60                 if (my_fgets(pref_fff, buf, sizeof(buf))) break;
61
62                 if (autoregister)
63                 {
64                         if (buf[0] != '#' && buf[0] != '?') num++;
65                         continue;
66                 }
67
68                 if (streq(buf, autoregister_header))
69                 {
70                         autoregister = TRUE;
71                 }
72                 else
73                 {
74                         fprintf(tmp_fff, "%s\n", buf);
75                 }
76         }
77
78         my_fclose(pref_fff);
79         my_fclose(tmp_fff);
80
81         bool okay = TRUE;
82         if (num)
83         {
84                 msg_format(_("以前のキャラクター用の自動設定(%d行)が残っています。",
85                         "Auto registered lines (%d lines) for previous character are remaining."), num);
86                 strcpy(buf, _("古い設定行は削除します。よろしいですか?", "These lines will be deleted.  Are you sure? "));
87
88                 if (!get_check(buf))
89                 {
90                         okay = FALSE;
91                         autoregister = FALSE;
92
93                         msg_print(_("エディタのカット&ペースト等を使って必要な行を避難してください。",
94                                 "Use cut & paste of auto picker editor (_) to keep old prefs."));
95                 }
96         }
97
98         if (autoregister)
99         {
100                 tmp_fff = my_fopen(tmp_file, "r");
101                 pref_fff = my_fopen(pref_file, "w");
102
103                 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
104                         fprintf(pref_fff, "%s\n", buf);
105
106                 my_fclose(pref_fff);
107                 my_fclose(tmp_fff);
108         }
109
110         fd_kill(tmp_file);
111         return okay;
112 }
113
114
115 /*
116  *  Automatically register an auto-destroy preference line
117  */
118 bool autopick_autoregister(player_type *player_ptr, object_type *o_ptr)
119 {
120         autopick_type an_entry, *entry = &an_entry;
121         int match_autopick = find_autopick_list(player_ptr, o_ptr);
122         if (match_autopick != -1)
123         {
124                 concptr what;
125                 byte act = autopick_list[match_autopick].action;
126                 if (act & DO_AUTOPICK) what = _("自動で拾う", "auto-pickup");
127                 else if (act & DO_AUTODESTROY) what = _("自動破壊する", "auto-destroy");
128                 else if (act & DONT_AUTOPICK) what = _("放置する", "leave on floor");
129                 else what = _("確認して拾う", "query auto-pickup");
130
131                 msg_format(_("そのアイテムは既に%sように設定されています。", "The object is already registered to %s."), what);
132                 return FALSE;
133         }
134
135         if ((object_is_known(o_ptr) && object_is_artifact(o_ptr)) ||
136                 ((o_ptr->ident & IDENT_SENSE) &&
137                 (o_ptr->feeling == FEEL_TERRIBLE || o_ptr->feeling == FEEL_SPECIAL)))
138         {
139                 GAME_TEXT o_name[MAX_NLEN];
140                 object_desc(player_ptr, o_name, o_ptr, 0);
141                 msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
142                 return FALSE;
143         }
144
145         if (!player_ptr->autopick_autoregister)
146         {
147                 if (!clear_auto_register(player_ptr)) return FALSE;
148         }
149
150         char buf[1024];
151         char pref_file[1024];
152         FILE *pref_fff;
153         path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_WITH_PNAME));
154         pref_fff = my_fopen(pref_file, "r");
155
156         if (!pref_fff)
157         {
158                 path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_DEFAULT));
159                 pref_fff = my_fopen(pref_file, "r");
160         }
161
162         if (pref_fff)
163         {
164                 while (TRUE)
165                 {
166                         if (my_fgets(pref_fff, buf, sizeof(buf)))
167                         {
168                                 player_ptr->autopick_autoregister = FALSE;
169                                 break;
170                         }
171
172                         if (streq(buf, autoregister_header))
173                         {
174                                 player_ptr->autopick_autoregister = TRUE;
175                                 break;
176                         }
177                 }
178
179                 fclose(pref_fff);
180         }
181         else
182         {
183                 /*
184                  * File could not be opened for reading.  Assume header not
185                  * present.
186                  */
187                 player_ptr->autopick_autoregister = FALSE;
188         }
189
190         pref_fff = my_fopen(pref_file, "a");
191         if (!pref_fff)
192         {
193                 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), pref_file);
194                 msg_print(NULL);
195                 return FALSE;
196         }
197
198         if (!player_ptr->autopick_autoregister)
199         {
200                 fprintf(pref_fff, "%s\n", autoregister_header);
201
202                 fprintf(pref_fff, "%s\n", _("# *警告!!* 以降の行は自動登録されたものです。",
203                         "# *Warning!* The lines below will be deleted later."));
204                 fprintf(pref_fff, "%s\n", _("# 後で自動的に削除されますので、必要な行は上の方へ移動しておいてください。",
205                         "# Keep it by cut & paste if you need these lines for future characters."));
206                 player_ptr->autopick_autoregister = TRUE;
207         }
208
209         autopick_entry_from_object(player_ptr, entry, o_ptr);
210         entry->action = DO_AUTODESTROY;
211         add_autopick_list(entry);
212
213         concptr tmp = autopick_line_from_entry(entry);
214         fprintf(pref_fff, "%s\n", tmp);
215         string_free(tmp);
216         fclose(pref_fff);
217         return TRUE;
218 }