OSDN Git Service

Merge pull request #765 from sikabane-works/release/3.0.0Alpha17
[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     for (int i = 0; i < TR_FLAG_MAX; i++) {
22         if (streq(what, k_info_flags[i])) {
23             add_flag(e_ptr->flags, i);
24             return 0;
25         }
26     }
27
28     if (FlagGroup<TRG>::grab_one_flag(e_ptr->gen_flags, k_info_gen_flags, what))
29         return 0;
30
31     msg_format(_("未知の名のあるアイテム・フラグ '%s'。", "Unknown ego-item flag '%s'."), what);
32     return 1;
33 }
34
35 static bool grab_ego_generate_flags(ego_generate_type &xtra, concptr what)
36 {
37     for (int i = 0; i < TR_FLAG_MAX; i++) {
38         if (streq(what, k_info_flags[i])) {
39             xtra.tr_flags.push_back(static_cast<tr_type>(i));
40             return false;
41         }
42     }
43
44     auto it = k_info_gen_flags.find(what);
45     if (it != k_info_gen_flags.end()) {
46         xtra.trg_flags.push_back(it->second);
47         return false;
48     }
49
50     return true;
51 }
52
53
54 /*!
55  * @brief アイテムエゴ情報(e_info)のパース関数 /
56  * Initialize the "e_info" array, by parsing an ascii "template" file
57  * @param buf テキスト列
58  * @param head ヘッダ構造体
59  * @return エラーコード
60  */
61 errr parse_e_info(char *buf, angband_header *head)
62 {
63     static ego_item_type *e_ptr = NULL;
64     error_idx = -1;
65     error_line = -1;
66     char *s, *t;
67     if (buf[0] == 'N') {
68         s = angband_strchr(buf + 2, ':');
69         if (!s)
70             return 1;
71
72         *s++ = '\0';
73 #ifdef JP
74         if (!*s)
75             return 1;
76 #endif
77         int i = atoi(buf + 2);
78         if (i < error_idx)
79             return 4;
80         if (i >= head->info_num)
81             return 2;
82
83         error_idx = i;
84         e_ptr = &e_info[i];
85 #ifdef JP
86         e_ptr->name = std::string(s);
87 #endif
88     } else if (!e_ptr) {
89         return 3;
90     }
91 #ifdef JP
92     /* 英語名を読むルーチンを追加 */
93     /* 'E' から始まる行は英語名 */
94     else if (buf[0] == 'E') {
95         /* nothing to do */
96     }
97 #else
98     else if (buf[0] == 'E') {
99         s = buf + 2;
100         e_ptr->name = std::string(s);
101     }
102 #endif
103     else if (buf[0] == 'X') {
104         int slot, rating;
105         if (2 != sscanf(buf + 2, "%d:%d", &slot, &rating))
106             return 1;
107
108         e_ptr->slot = (INVENTORY_IDX)slot;
109         e_ptr->rating = (PRICE)rating;
110     } else if (buf[0] == 'W') {
111         int level, rarity, pad2;
112         long cost;
113
114         if (4 != sscanf(buf + 2, "%d:%d:%d:%ld", &level, &rarity, &pad2, &cost))
115             return 1;
116
117         e_ptr->level = level;
118         e_ptr->rarity = (RARITY)rarity;
119         e_ptr->cost = cost;
120     } else if (buf[0] == 'C') {
121         int th, td, ta, pval;
122
123         if (4 != sscanf(buf + 2, "%d:%d:%d:%d", &th, &td, &ta, &pval))
124             return 1;
125
126         e_ptr->max_to_h = (HIT_PROB)th;
127         e_ptr->max_to_d = (HIT_POINT)td;
128         e_ptr->max_to_a = (ARMOUR_CLASS)ta;
129         e_ptr->max_pval = (PARAMETER_VALUE)pval;
130     } else if (buf[0] == 'U') {
131         byte n;
132         n = grab_one_activation_flag(buf + 2);
133         if (n > 0) {
134             e_ptr->act_idx = n;
135         } else {
136             return 5;
137         }
138     } else if (buf[0] == 'F') {
139         for (s = buf + 2; *s;) {
140             /* loop */
141             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
142                 ;
143
144             if (*t) {
145                 *t++ = '\0';
146                 while ((*t == ' ') || (*t == '|'))
147                     t++;
148             }
149
150             if (0 != grab_one_ego_item_flag(e_ptr, s))
151                 return 5;
152
153             s = t;
154         }
155     } else if (buf[0] == 'G') {
156         ego_generate_type xtra;
157
158         s = angband_strstr(buf + 2, ":");
159         if (!s)
160             return 1;
161
162         *s++ = '\0';
163
164         if (2 != sscanf(buf + 2, "%d/%d", &xtra.mul, &xtra.dev))
165             return 1;
166
167         for (; *s;) {
168             for (t = s; *t && (*t != ' ') && (*t != '|'); ++t)
169                 ;
170
171             if (*t) {
172                 *t++ = '\0';
173                 while ((*t == ' ') || (*t == '|'))
174                     t++;
175             }
176
177             if (grab_ego_generate_flags(xtra, s))
178                 return 5;
179
180             s = t;
181         }
182
183         e_ptr->xtra_flags.push_back(std::move(xtra));
184     } else {
185         return 6;
186     }
187
188     return 0;
189 }