1 #include "wizard/artifact-analyzer.h"
2 #include "flavor/flavor-describer.h"
3 #include "flavor/object-flavor-types.h"
4 #include "object-enchant/object-ego.h"
5 #include "object-enchant/trc-types.h"
6 #include "object-enchant/trg-types.h"
7 #include "object/object-flags.h"
8 #include "object/object-info.h"
9 #include "system/artifact-type-definition.h"
10 #include "system/object-type-definition.h"
11 #include "util/bit-flags-calculator.h"
12 #include "util/quarks.h"
13 #include "wizard/spoiler-util.h"
16 * @brief アーティファクトの特性一覧を出力する /
17 * Write a line to the spoiler file and then "underline" it with hypens
18 * @param art_flags アーティファクトのフラグ群
19 * @param flag_ptr フラグ記述情報の参照ポインタ
20 * @param desc_ptr 記述内容を返すための文字列参照ポインタ
21 * @param n_elmnts フラグの要素数
22 * @return desc_ptrと同じアドレス
25 * This function does most of the actual "analysis". Given a set of bit flags
26 * (which will be from one of the flags fields from the object in question),
27 * a "flag description structure", a "description list", and the number of
28 * elements in the "flag description structure", this function sets the
29 * "description list" members to the appropriate descriptions contained in
30 * the "flag description structure".
31 * The possibly updated description pointer is returned.
34 static concptr *spoiler_flag_aux(const BIT_FLAGS art_flags[TR_FLAG_SIZE], const flag_desc *flag_ptr, concptr *desc_ptr, const int n_elmnts)
36 for (int i = 0; i < n_elmnts; ++i)
37 if (has_flag(art_flags, flag_ptr[i].flag))
38 *desc_ptr++ = flag_ptr[i].desc;
44 * @brief アイテムの特定記述内容を返す /
45 * Acquire a "basic" description "The Cloak of Death [1,+10]"
46 * @param o_ptr 記述を得たいオブジェクトの参照ポインタ
47 * @param desc_ptr 記述内容を返すための文字列参照ポインタ
50 static void analyze_general(player_type *player_ptr, object_type *o_ptr, char *desc_ptr)
52 describe_flavor(player_ptr, desc_ptr, o_ptr, OD_NAME_AND_ENCHANT | OD_STORE | OD_DEBUG);
56 * @brief アーティファクトがプレイヤーに与えるpval修正を構造体に収める /
57 * List "player traits" altered by an artifact's pval. These include stats,
58 * speed, infravision, tunneling, stealth, searching, and extra attacks.
59 * @param o_ptr オブジェクト構造体の参照ポインタ
60 * @param pi_ptr pval修正構造体の参照ポインタ
63 static void analyze_pval(player_type *player_ptr, object_type *o_ptr, pval_info_type *pi_ptr)
65 BIT_FLAGS flgs[TR_FLAG_SIZE];
66 concptr *affects_list;
68 pi_ptr->pval_desc[0] = '\0';
72 object_flags(player_ptr, o_ptr, flgs);
73 affects_list = pi_ptr->pval_affects;
74 sprintf(pi_ptr->pval_desc, "%s%d", o_ptr->pval >= 0 ? "+" : "", o_ptr->pval);
75 if (has_flag(flgs, TR_STR) && has_flag(flgs, TR_INT) && has_flag(flgs, TR_WIS) && has_flag(flgs, TR_DEX) && has_flag(flgs, TR_CON)
76 && has_flag(flgs, TR_CHR)) {
77 *affects_list++ = _("全能力", "All stats");
78 } else if (has_flag(flgs, TR_STR) || has_flag(flgs, TR_INT) || has_flag(flgs, TR_WIS) || has_flag(flgs, TR_DEX) || has_flag(flgs, TR_CON)
79 || has_flag(flgs, TR_CHR)) {
80 affects_list = spoiler_flag_aux(flgs, stat_flags_desc, affects_list, N_ELEMENTS(stat_flags_desc));
83 affects_list = spoiler_flag_aux(flgs, pval_flags1_desc, affects_list, N_ELEMENTS(pval_flags1_desc));
88 * @brief アーティファクトの種族スレイ特性を構造体に収める /
89 * Note the slaying specialties of a weapon
90 * @param o_ptr オブジェクト構造体の参照ポインタ
91 * @param slay_list 種族スレイ構造体の参照ポインタ
94 static void analyze_slay(player_type *player_ptr, object_type *o_ptr, concptr *slay_list)
96 BIT_FLAGS flgs[TR_FLAG_SIZE];
97 object_flags(player_ptr, o_ptr, flgs);
98 slay_list = spoiler_flag_aux(flgs, slay_flags_desc, slay_list, N_ELEMENTS(slay_flags_desc));
103 * @brief アーティファクトの属性ブランド特性を構造体に収める /
104 * Note an object's elemental brands
105 * @param o_ptr オブジェクト構造体の参照ポインタ
106 * @param brand_list 属性ブランド構造体の参照ポインタ
109 static void analyze_brand(player_type *player_ptr, object_type *o_ptr, concptr *brand_list)
111 BIT_FLAGS flgs[TR_FLAG_SIZE];
112 object_flags(player_ptr, o_ptr, flgs);
113 brand_list = spoiler_flag_aux(flgs, brand_flags_desc, brand_list, N_ELEMENTS(brand_flags_desc));
118 * @brief アーティファクトの通常耐性を構造体に収める /
119 * Note an object's elemental brands
120 * @param o_ptr オブジェクト構造体の参照ポインタ
121 * @param resist_list 通常耐性構造体の参照ポインタ
124 static void analyze_resist(player_type *player_ptr, object_type *o_ptr, concptr *resist_list)
126 BIT_FLAGS flgs[TR_FLAG_SIZE];
127 object_flags(player_ptr, o_ptr, flgs);
128 resist_list = spoiler_flag_aux(flgs, resist_flags_desc, resist_list, N_ELEMENTS(resist_flags_desc));
133 * @brief アーティファクトの免疫特性を構造体に収める /
134 * Note the immunities granted by an object
135 * @param o_ptr オブジェクト構造体の参照ポインタ
136 * @param immune_list 免疫構造体の参照ポインタ
139 static void analyze_immune(player_type *player_ptr, object_type *o_ptr, concptr *immune_list)
141 BIT_FLAGS flgs[TR_FLAG_SIZE];
142 object_flags(player_ptr, o_ptr, flgs);
143 immune_list = spoiler_flag_aux(flgs, immune_flags_desc, immune_list, N_ELEMENTS(immune_flags_desc));
148 * @brief アーティファクトの維持特性を構造体に収める /
149 * Note which stats an object sustains
150 * @param o_ptr オブジェクト構造体の参照ポインタ
151 * @param sustain_list 維持特性構造体の参照ポインタ
154 static void analyze_sustains(player_type *player_ptr, object_type *o_ptr, concptr *sustain_list)
156 BIT_FLAGS flgs[TR_FLAG_SIZE];
157 object_flags(player_ptr, o_ptr, flgs);
158 if (has_flag(flgs, TR_SUST_STR) && has_flag(flgs, TR_SUST_INT) && has_flag(flgs, TR_SUST_WIS) && has_flag(flgs, TR_SUST_DEX)
159 && has_flag(flgs, TR_SUST_CON) && has_flag(flgs, TR_SUST_CHR)) {
160 *sustain_list++ = _("全能力", "All stats");
161 } else if (has_flag(flgs, TR_SUST_STR) || has_flag(flgs, TR_SUST_INT) || has_flag(flgs, TR_SUST_WIS) || has_flag(flgs, TR_SUST_DEX)
162 || has_flag(flgs, TR_SUST_CON) || has_flag(flgs, TR_SUST_CHR)) {
163 sustain_list = spoiler_flag_aux(flgs, sustain_flags_desc, sustain_list, N_ELEMENTS(sustain_flags_desc));
166 *sustain_list = NULL;
170 * @brief アーティファクトのその他の特性を構造体に収める /
171 * Note miscellaneous powers bestowed by an artifact such as see invisible,
172 * free action, permanent light, etc.
173 * @param o_ptr オブジェクト構造体の参照ポインタ
174 * @param misc_list その他の特性構造体の参照ポインタ
177 static void analyze_misc_magic(player_type *player_ptr, object_type *o_ptr, concptr *misc_list)
179 BIT_FLAGS flgs[TR_FLAG_SIZE];
182 object_flags(player_ptr, o_ptr, flgs);
183 misc_list = spoiler_flag_aux(flgs, misc_flags2_desc, misc_list, N_ELEMENTS(misc_flags2_desc));
184 misc_list = spoiler_flag_aux(flgs, misc_flags3_desc, misc_list, N_ELEMENTS(misc_flags3_desc));
186 if (has_flag(flgs, TR_LITE_1))
189 if (has_flag(flgs, TR_LITE_2))
192 if (has_flag(flgs, TR_LITE_3))
195 if (has_flag(flgs, TR_LITE_M1))
198 if (has_flag(flgs, TR_LITE_M2))
201 if (has_flag(flgs, TR_LITE_M3))
204 if (o_ptr->name2 == EGO_LITE_SHINE)
207 if (has_flag(flgs, TR_LITE_FUEL)) {
209 sprintf(desc, _("それは燃料補給によって明かり(半径 %d)を授ける。", "It provides light (radius %d) when fueled."), (int)rad);
212 sprintf(desc, _("永久光源(半径 %d)", "Permanent Light(radius %d)"), (int)rad);
215 sprintf(desc, _("永久光源(半径-%d)。", "Permanent Light(radius -%d)"), (int)-rad);
219 *misc_list++ = quark_str(quark_add(desc));
221 if (has_flag(flgs, TR_TY_CURSE))
222 *misc_list++ = _("太古の怨念", "Ancient Curse");
224 if (o_ptr->curse_flags & TRC_PERMA_CURSE)
225 *misc_list++ = _("永遠の呪い", "Permanently Cursed");
226 else if (o_ptr->curse_flags & TRC_HEAVY_CURSE)
227 *misc_list++ = _("強力な呪い", "Heavily Cursed");
228 else if (o_ptr->curse_flags & TRC_CURSED)
229 *misc_list++ = _("呪い", "Cursed");
231 if (has_flag(flgs, TR_ADD_L_CURSE))
232 *misc_list++ = _("呪いを増やす", "Cursing");
234 if (has_flag(flgs, TR_ADD_H_CURSE))
235 *misc_list++ = _("強力な呪いを増やす", "Heavily Cursing");
241 * @brief アーティファクトの追加ランダム特性を構造体に収める /
242 * Note additional ability and/or resistance of fixed artifacts
243 * @param o_ptr オブジェクト構造体の参照ポインタ
244 * @param addition 追加ランダム耐性構造体の参照ポインタ
247 static void analyze_addition(object_type *o_ptr, char *addition)
249 artifact_type *a_ptr = &a_info[o_ptr->name1];
250 strcpy(addition, "");
252 if (a_ptr->gen_flags.has_all_of({ TRG::XTRA_POWER, TRG::XTRA_H_RES })) {
253 strcat(addition, _("能力and耐性", "Ability and Resistance"));
254 } else if (a_ptr->gen_flags.has(TRG::XTRA_POWER)) {
255 strcat(addition, _("能力", "Ability"));
256 if (a_ptr->gen_flags.has(TRG::XTRA_RES_OR_POWER))
257 strcat(addition, _("(1/2でand耐性)", "(plus Resistance about 1/2)"));
258 } else if (a_ptr->gen_flags.has(TRG::XTRA_H_RES)) {
259 strcat(addition, _("耐性", "Resistance"));
260 if (a_ptr->gen_flags.has(TRG::XTRA_RES_OR_POWER))
261 strcat(addition, _("(1/2でand能力)", "(plus Ability about 1/2)"));
262 } else if (a_ptr->gen_flags.has(TRG::XTRA_RES_OR_POWER))
263 strcat(addition, _("能力or耐性", "Ability or Resistance"));
265 if (a_ptr->gen_flags.has(TRG::XTRA_DICE)) {
266 if (strlen(addition) > 0)
267 strcat(addition, _("、", ", "));
268 strcat(addition, _("ダイス数", "Dice number"));
273 * @brief アーティファクトの基本情報を文字列に収める /
274 * Determine the minimum depth an artifact can appear, its rarity, its weight,
275 * and its value in gold pieces
276 * @param o_ptr オブジェクト構造体の参照ポインタ
277 * @param misc_desc 基本情報を収める文字列参照ポインタ
280 static void analyze_misc(object_type *o_ptr, char *misc_desc)
282 artifact_type *a_ptr = &a_info[o_ptr->name1];
283 sprintf(misc_desc, _("レベル %d, 希少度 %u, %d.%d kg, $%ld", "Level %d, Rarity %u, %d.%d lbs, %ld Gold"), (int)a_ptr->level, a_ptr->rarity,
284 _(lbtokg1(a_ptr->weight), a_ptr->weight / 10), _(lbtokg2(a_ptr->weight), a_ptr->weight % 10), (long int)a_ptr->cost);
288 * @brief アーティファクトの情報全体を構造体に収める /
289 * Fill in an object description structure for a given object
290 * and its value in gold pieces
291 * @param player_ptr プレーヤーへの参照ポインタ
292 * @param o_ptr オブジェクト構造体の参照ポインタ
293 * @param desc_ptr 全アーティファクト情報を収める文字列参照ポインタ
296 void object_analyze(player_type *player_ptr, object_type *o_ptr, obj_desc_list *desc_ptr)
298 analyze_general(player_ptr, o_ptr, desc_ptr->description);
299 analyze_pval(player_ptr, o_ptr, &desc_ptr->pval_info);
300 analyze_brand(player_ptr, o_ptr, desc_ptr->brands);
301 analyze_slay(player_ptr, o_ptr, desc_ptr->slays);
302 analyze_immune(player_ptr, o_ptr, desc_ptr->immunities);
303 analyze_resist(player_ptr, o_ptr, desc_ptr->resistances);
304 analyze_sustains(player_ptr, o_ptr, desc_ptr->sustains);
305 analyze_misc_magic(player_ptr, o_ptr, desc_ptr->misc_magic);
306 analyze_addition(o_ptr, desc_ptr->addition);
307 analyze_misc(o_ptr, desc_ptr->misc_desc);
308 desc_ptr->activation = activation_explanation(player_ptr, o_ptr);
312 * @brief ランダムアーティファクト1件を解析する /
313 * Fill in an object description structure for a given object
314 * @param player_ptr プレーヤーへの参照ポインタ
315 * @param o_ptr ランダムアーティファクトのオブジェクト構造体参照ポインタ
316 * @param desc_ptr 記述内容を収める構造体参照ポインタ
319 void random_artifact_analyze(player_type *player_ptr, object_type *o_ptr, obj_desc_list *desc_ptr)
321 analyze_general(player_ptr, o_ptr, desc_ptr->description);
322 analyze_pval(player_ptr, o_ptr, &desc_ptr->pval_info);
323 analyze_brand(player_ptr, o_ptr, desc_ptr->brands);
324 analyze_slay(player_ptr, o_ptr, desc_ptr->slays);
325 analyze_immune(player_ptr, o_ptr, desc_ptr->immunities);
326 analyze_resist(player_ptr, o_ptr, desc_ptr->resistances);
327 analyze_sustains(player_ptr, o_ptr, desc_ptr->sustains);
328 analyze_misc_magic(player_ptr, o_ptr, desc_ptr->misc_magic);
329 desc_ptr->activation = activation_explanation(player_ptr, o_ptr);
330 sprintf(desc_ptr->misc_desc, _("重さ %d.%d kg", "Weight %d.%d lbs"), _(lbtokg1(o_ptr->weight), o_ptr->weight / 10),
331 _(lbtokg2(o_ptr->weight), o_ptr->weight % 10));