OSDN Git Service

Merge pull request #769 from iks3/feature-add-item-abilities-a18
[hengbandforosx/hengbandosx.git] / src / info-reader / ego-reader.cpp
1 #include "info-reader/ego-reader.h"
2 #include "info-reader/kind-info-tokens-table.h"
3 #include "main/angband-headers.h"
4 #include "object-enchant/object-ego.h"
5 #include "object-enchant/tr-types.h"
6 #include "util/bit-flags-calculator.h"
7 #include "util/string-processor.h"
8 #include "view/display-messages.h"
9 #include <string>
10 #include <utility>
11
12 /*!
13  * @brief テキストトークンを走査してフラグを一つ得る(エゴ用) /
14  * Grab one flag in a ego-item_type from a textual string
15  * @param e_ptr 保管先のエゴ構造体参照ポインタ
16  * @param what 参照元の文字列ポインタ
17  * @return エラーがあった場合1、エラーがない場合0を返す
18  */
19 static bool grab_one_ego_item_flag(ego_item_type *e_ptr, concptr what)
20 {
21     if (k_info_flags.find(what) != k_info_flags.end()) {
22         add_flag(e_ptr->flags, k_info_flags[what]);
23         return 0;
24     }
25
26     if (FlagGroup<TRG>::grab_one_flag(e_ptr->gen_flags, k_info_gen_flags, what))
27         return 0;
28
29     msg_format(_("未知の名のあるアイテム・フラグ '%s'。", "Unknown ego-item flag '%s'."), what);
30     return 1;
31 }
32
33 static bool grab_ego_generate_flags(ego_generate_type &xtra, concptr what)
34 {
35     if (k_info_flags.find(what) != k_info_flags.end()) {
36         xtra.tr_flags.push_back(k_info_flags[what]);
37         return 0;
38     }
39
40     auto it = k_info_gen_flags.find(what);
41     if (it != k_info_gen_flags.end()) {
42         xtra.trg_flags.push_back(it->second);
43         return false;
44     }
45
46     return true;
47 }
48
49
50 /*!
51  * @brief アイテムエゴ情報(e_info)のパース関数 /
52  * Initialize the "e_info" array, by parsing an ascii "template" file
53  * @param buf テキスト列
54  * @param head ヘッダ構造体
55  * @return エラーコード
56  */
57 errr parse_e_info(char *buf, angband_header *head)
58 {
59     static ego_item_type *e_ptr = NULL;
60     error_idx = 0;
61     char *s, *t;
62     if (buf[0] == 'N') {
63         s = angband_strchr(buf + 2, ':');
64         if (!s)
65             return 1;
66
67         *s++ = '\0';
68 #ifdef JP
69         if (!*s)
70             return 1;
71 #endif
72         int i = atoi(buf + 2);
73         if (i < error_idx)
74             return 4;
75         if (i >= head->info_num)
76             return 2;
77
78         error_idx = i;
79         e_ptr = &e_info[i];
80 #ifdef JP
81         e_ptr->name = std::string(s);
82 #endif
83     } else if (!e_ptr) {
84         return 3;
85     }
86 #ifdef JP
87     /* 英語名を読むルーチンを追加 */
88     /* 'E' から始まる行は英語名 */
89     else if (buf[0] == 'E') {
90         /* nothing to do */
91     }
92 #else
93     else if (buf[0] == 'E') {
94         s = buf + 2;
95         e_ptr->name = std::string(s);
96     }
97 #endif
98     else if (buf[0] == 'X') {
99         int slot, rating;
100         if (2 != sscanf(buf + 2, "%d:%d", &slot, &rating))
101             return 1;
102
103         e_ptr->slot = (INVENTORY_IDX)slot;
104         e_ptr->rating = (PRICE)rating;
105     } else if (buf[0] == 'W') {
106         int level, rarity, pad2;
107         long cost;
108
109         if (4 != sscanf(buf + 2, "%d:%d:%d:%ld", &level, &rarity, &pad2, &cost))
110             return 1;
111
112         e_ptr->level = level;
113         e_ptr->rarity = (RARITY)rarity;
114         e_ptr->cost = cost;
115     } else if (buf[0] == 'C') {
116         int th, td, ta, pval;
117
118         if (4 != sscanf(buf + 2, "%d:%d:%d:%d", &th, &td, &ta, &pval))
119             return 1;
120
121         e_ptr->max_to_h = (HIT_PROB)th;
122         e_ptr->max_to_d = (HIT_POINT)td;
123         e_ptr->max_to_a = (ARMOUR_CLASS)ta;
124         e_ptr->max_pval = (PARAMETER_VALUE)pval;
125     } else if (buf[0] == 'U') {
126         byte n;
127         n = grab_one_activation_flag(buf + 2);
128         if (n > 0) {
129             e_ptr->act_idx = n;
130         } else {
131             return 5;
132         }
133     } else if (buf[0] == 'F') {
134         for (s = buf + 2; *s;) {
135             /* loop */
136             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
137                 ;
138
139             if (*t) {
140                 *t++ = '\0';
141                 while ((*t == ' ') || (*t == '|'))
142                     t++;
143             }
144
145             if (0 != grab_one_ego_item_flag(e_ptr, s))
146                 return 5;
147
148             s = t;
149         }
150     } else if (buf[0] == 'G') {
151         ego_generate_type xtra;
152
153         s = angband_strstr(buf + 2, ":");
154         if (!s)
155             return 1;
156
157         *s++ = '\0';
158
159         if (2 != sscanf(buf + 2, "%d/%d", &xtra.mul, &xtra.dev))
160             return 1;
161
162         for (; *s;) {
163             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
164                 ;
165
166             if (*t) {
167                 *t++ = '\0';
168                 while ((*t == ' ') || (*t == '|'))
169                     t++;
170             }
171
172             if (grab_ego_generate_flags(xtra, s))
173                 return 5;
174
175             s = t;
176         }
177
178         e_ptr->xtra_flags.push_back(std::move(xtra));
179     } else {
180         return 6;
181     }
182
183     return 0;
184 }