1 #include "flavor/named-item-describer.h"
2 #include "flavor/flavor-util.h"
3 #include "flavor/object-flavor-types.h"
4 #include "flavor/tval-description-switcher.h"
5 #include "game-option/text-display-options.h"
6 #include "mind/mind-weaponsmith.h"
7 #include "object-enchant/object-ego.h"
8 #include "object-enchant/special-object-flags.h"
9 #include "object-enchant/tr-types.h"
10 #include "object-hook/hook-enchant.h"
11 #include "object/object-flags.h"
12 #include "perception/object-perception.h"
13 #include "system/artifact-type-definition.h"
14 #include "util/bit-flags-calculator.h"
15 #include "util/quarks.h"
16 #include "util/string-processor.h"
19 #include "locale/english.h"
20 #include "monster-race/monster-race.h"
21 #include "monster-race/race-flags1.h"
24 static void check_object_known_aware(player_type *player_ptr, flavor_type *flavor_ptr)
26 object_flags(player_ptr, flavor_ptr->o_ptr, flavor_ptr->tr_flags);
27 if (object_is_aware(flavor_ptr->o_ptr))
28 flavor_ptr->aware = TRUE;
30 if (object_is_known(flavor_ptr->o_ptr))
31 flavor_ptr->known = TRUE;
33 if (flavor_ptr->aware && ((flavor_ptr->mode & OD_NO_FLAVOR) || plain_descriptions))
34 flavor_ptr->flavor = FALSE;
36 if ((flavor_ptr->mode & OD_STORE) || (flavor_ptr->o_ptr->ident & IDENT_STORE)) {
37 flavor_ptr->flavor = FALSE;
38 flavor_ptr->aware = TRUE;
39 flavor_ptr->known = TRUE;
42 if (flavor_ptr->mode & OD_FORCE_FLAVOR) {
43 flavor_ptr->aware = FALSE;
44 flavor_ptr->flavor = TRUE;
45 flavor_ptr->known = FALSE;
46 flavor_ptr->flavor_k_ptr = flavor_ptr->k_ptr;
50 static void set_base_name(flavor_type *flavor_ptr)
52 if (!flavor_ptr->aware || !has_flag(flavor_ptr->tr_flags, TR_FULL_NAME))
55 flavor_ptr->basenm = (flavor_ptr->known && (flavor_ptr->o_ptr->name1 != 0)) ? a_name + a_info[flavor_ptr->o_ptr->name1].name : flavor_ptr->kindname;
59 static void describe_prefix_ja(flavor_type *flavor_ptr)
61 flavor_ptr->s = flavor_ptr->basenm[0] == '&' ? flavor_ptr->basenm + 2 : flavor_ptr->basenm;
62 if (flavor_ptr->mode & OD_OMIT_PREFIX)
65 if (flavor_ptr->o_ptr->number > 1) {
66 flavor_ptr->t = object_desc_count_japanese(flavor_ptr->t, flavor_ptr->o_ptr);
67 flavor_ptr->t = object_desc_str(flavor_ptr->t, "の ");
72 * @brief アーティファクトの表記処理
73 * @param アイテム表記への参照ポインタ
75 * @details 英語の場合アーティファクトは The が付くので分かるが、日本語では分からないのでマークをつける.
77 static void describe_artifact_prefix_ja(flavor_type *flavor_ptr)
79 if (!flavor_ptr->known)
82 if (object_is_fixed_artifact(flavor_ptr->o_ptr))
83 flavor_ptr->t = object_desc_str(flavor_ptr->t, "★");
84 else if (flavor_ptr->o_ptr->art_name)
85 flavor_ptr->t = object_desc_str(flavor_ptr->t, "☆");
89 * @brief アーティファクトの説明表記
90 * @param flavor_ptr アイテム表記への参照ポインタ
92 * @details ランダムアーティファクト、固定アーティファクト、エゴの順に評価する
94 static void describe_artifact_ja(flavor_type *flavor_ptr)
96 if (!flavor_ptr->known)
99 if (flavor_ptr->o_ptr->art_name) {
100 concptr temp = quark_str(flavor_ptr->o_ptr->art_name);
102 /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
103 /* 英語版のセーブファイルから来た 'of XXX' は,「XXXの」と表示する */
104 if (strncmp(temp, "of ", 3) == 0) {
105 flavor_ptr->t = object_desc_str(flavor_ptr->t, &temp[3]);
106 flavor_ptr->t = object_desc_str(flavor_ptr->t, "の");
107 } else if ((strncmp(temp, "『", 2) != 0) && (strncmp(temp, "《", 2) != 0) && (temp[0] != '\''))
108 flavor_ptr->t = object_desc_str(flavor_ptr->t, temp);
113 if (flavor_ptr->o_ptr->name1 && !has_flag(flavor_ptr->tr_flags, TR_FULL_NAME)) {
114 artifact_type *a_ptr = &a_info[flavor_ptr->o_ptr->name1];
115 /* '『' から始まらない伝説のアイテムの名前は最初に付加する */
116 if (strncmp(a_name + a_ptr->name, "『", 2) != 0)
117 flavor_ptr->t = object_desc_str(flavor_ptr->t, a_name + a_ptr->name);
122 if (object_is_ego(flavor_ptr->o_ptr)) {
123 ego_item_type *e_ptr = &e_info[flavor_ptr->o_ptr->name2];
124 flavor_ptr->t = object_desc_str(flavor_ptr->t, e_name + e_ptr->name);
129 * @brief ランダムアーティファクトの表記
130 * @param flavor_ptr アイテム表記への参照ポインタ
131 * @return ランダムアーティファクトならTRUE、違うならFALSE
132 * @details ランダムアーティファクトの名前はセーブファイルに記録されるので、英語版の名前もそれらしく変換する.
134 static bool describe_random_artifact_body_ja(flavor_type *flavor_ptr)
136 if (flavor_ptr->o_ptr->art_name == 0)
141 strcpy(temp, quark_str(flavor_ptr->o_ptr->art_name));
142 if (strncmp(temp, "『", 2) == 0 || strncmp(temp, "《", 2) == 0) {
143 flavor_ptr->t = object_desc_str(flavor_ptr->t, temp);
150 itemp = strlen(temp);
152 flavor_ptr->t = object_desc_str(flavor_ptr->t, "『");
153 flavor_ptr->t = object_desc_str(flavor_ptr->t, &temp[1]);
154 flavor_ptr->t = object_desc_str(flavor_ptr->t, "』");
158 static void describe_ego_body_ja(flavor_type *flavor_ptr)
160 if (!flavor_ptr->o_ptr->inscription)
163 concptr str = quark_str(flavor_ptr->o_ptr->inscription);
179 concptr str_aux = angband_strchr(quark_str(flavor_ptr->o_ptr->inscription), '#');
180 flavor_ptr->t = object_desc_str(flavor_ptr->t, "『");
181 flavor_ptr->t = object_desc_str(flavor_ptr->t, &str_aux[1]);
182 flavor_ptr->t = object_desc_str(flavor_ptr->t, "』");
186 * @brief アーティファクトのアイテム名を表記する
187 * @param flavor_ptr アイテム表記への参照ポインタ
189 * @details '『'から始まる伝説のアイテムの名前は最後に付加する
191 static void describe_artifact_body_ja(flavor_type *flavor_ptr)
193 if (!flavor_ptr->known)
196 if (describe_random_artifact_body_ja(flavor_ptr))
199 if (object_is_fixed_artifact(flavor_ptr->o_ptr)) {
200 artifact_type *a_ptr = &a_info[flavor_ptr->o_ptr->name1];
201 if (strncmp(a_name + a_ptr->name, "『", 2) == 0)
202 flavor_ptr->t = object_desc_str(flavor_ptr->t, a_name + a_ptr->name);
207 describe_ego_body_ja(flavor_ptr);
211 static void describe_vowel(flavor_type *flavor_ptr)
214 switch (*flavor_ptr->s) {
216 vowel = is_a_vowel(flavor_ptr->modstr[0]);
219 vowel = is_a_vowel(*flavor_ptr->kindname);
222 vowel = is_a_vowel(*flavor_ptr->s);
227 flavor_ptr->t = object_desc_str(flavor_ptr->t, "an ");
229 flavor_ptr->t = object_desc_str(flavor_ptr->t, "a ");
233 * @brief 0個、1個、2個以上の時に個数を書き分ける処理 / Process to write the number when there are 0, 1, or 2 or more.
234 * @param flavor_ptr アイテム表記への参照ポインタ / Reference pointer to item's flavor
235 * @return 1個ならFALSE、0または2個以上ならTRUE / If the number of items is 1, then FALE is returned, and if 0 or 2 or more, then TRUE is returned
236 * @details 1個なら後続処理実行 / If the number of items is 1, then the continuous process will be run.
238 static bool describe_prefix_en(flavor_type *flavor_ptr)
240 if (flavor_ptr->o_ptr->number <= 0) {
241 flavor_ptr->t = object_desc_str(flavor_ptr->t, "no more ");
245 if (flavor_ptr->o_ptr->number == 1)
248 flavor_ptr->t = object_desc_num(flavor_ptr->t, flavor_ptr->o_ptr->number);
249 flavor_ptr->t = object_desc_chr(flavor_ptr->t, ' ');
253 static void describe_artifact_prefix_en(flavor_type *flavor_ptr)
255 flavor_ptr->s = flavor_ptr->basenm + 2;
256 if (flavor_ptr->mode & OD_OMIT_PREFIX)
259 if (describe_prefix_en(flavor_ptr))
262 if ((flavor_ptr->known && object_is_artifact(flavor_ptr->o_ptr))
263 || ((flavor_ptr->o_ptr->tval == TV_CORPSE) && (r_info[flavor_ptr->o_ptr->pval].flags1 & RF1_UNIQUE))) {
264 flavor_ptr->t = object_desc_str(flavor_ptr->t, "The ");
268 describe_vowel(flavor_ptr);
271 static void describe_basename_en(flavor_type *flavor_ptr)
273 flavor_ptr->s = flavor_ptr->basenm;
274 if (flavor_ptr->mode & OD_OMIT_PREFIX)
277 if (describe_prefix_en(flavor_ptr))
280 if (flavor_ptr->known && object_is_artifact(flavor_ptr->o_ptr))
281 flavor_ptr->t = object_desc_str(flavor_ptr->t, "The ");
284 static void describe_artifact_body_en(flavor_type *flavor_ptr)
286 if (!flavor_ptr->known || has_flag(flavor_ptr->tr_flags, TR_FULL_NAME))
289 if (flavor_ptr->o_ptr->art_name) {
290 flavor_ptr->t = object_desc_chr(flavor_ptr->t, ' ');
291 flavor_ptr->t = object_desc_str(flavor_ptr->t, quark_str(flavor_ptr->o_ptr->art_name));
295 if (object_is_fixed_artifact(flavor_ptr->o_ptr)) {
296 artifact_type *a_ptr = &a_info[flavor_ptr->o_ptr->name1];
297 flavor_ptr->t = object_desc_chr(flavor_ptr->t, ' ');
298 flavor_ptr->t = object_desc_str(flavor_ptr->t, a_name + a_ptr->name);
302 if (object_is_ego(flavor_ptr->o_ptr)) {
303 ego_item_type *e_ptr = &e_info[flavor_ptr->o_ptr->name2];
304 flavor_ptr->t = object_desc_chr(flavor_ptr->t, ' ');
305 flavor_ptr->t = object_desc_str(flavor_ptr->t, e_name + e_ptr->name);
308 if (flavor_ptr->o_ptr->inscription && angband_strchr(quark_str(flavor_ptr->o_ptr->inscription), '#')) {
309 concptr str = angband_strchr(quark_str(flavor_ptr->o_ptr->inscription), '#');
310 flavor_ptr->t = object_desc_chr(flavor_ptr->t, ' ');
311 flavor_ptr->t = object_desc_str(flavor_ptr->t, &str[1]);
318 * @param flavor_ptr アイテム表記への参照ポインタ
320 * @details ランダムアーティファクト、固定アーティファクト、エゴの順に評価する
322 static void describe_inscription(flavor_type *flavor_ptr)
324 for (flavor_ptr->s0 = NULL; *flavor_ptr->s || flavor_ptr->s0;) {
325 if (!*flavor_ptr->s) {
326 flavor_ptr->s = flavor_ptr->s0 + 1;
327 flavor_ptr->s0 = NULL;
328 } else if ((*flavor_ptr->s == '#') && !flavor_ptr->s0) {
329 flavor_ptr->s0 = flavor_ptr->s;
330 flavor_ptr->s = flavor_ptr->modstr;
331 flavor_ptr->modstr = "";
332 } else if ((*flavor_ptr->s == '%') && !flavor_ptr->s0) {
333 flavor_ptr->s0 = flavor_ptr->s;
334 flavor_ptr->s = flavor_ptr->kindname;
335 flavor_ptr->kindname = "";
340 else if (*flavor_ptr->s == '~') {
341 if (!(flavor_ptr->mode & OD_NO_PLURAL) && (flavor_ptr->o_ptr->number != 1)) {
342 char k = flavor_ptr->t[-1];
343 if ((k == 's') || (k == 'h'))
344 *flavor_ptr->t++ = 'e';
346 *flavor_ptr->t++ = 's';
353 *flavor_ptr->t++ = *flavor_ptr->s++;
357 void describe_named_item(player_type *player_ptr, flavor_type *flavor_ptr)
359 check_object_known_aware(player_ptr, flavor_ptr);
360 switch_tval_description(flavor_ptr);
361 set_base_name(flavor_ptr);
362 flavor_ptr->t = flavor_ptr->tmp_val;
364 describe_prefix_ja(flavor_ptr);
365 describe_artifact_prefix_ja(flavor_ptr);
368 if (flavor_ptr->basenm[0] == '&')
369 describe_artifact_prefix_en(flavor_ptr);
371 describe_basename_en(flavor_ptr);
375 if (object_is_smith(player_ptr, flavor_ptr->o_ptr))
376 flavor_ptr->t = object_desc_str(flavor_ptr->t, format("鍛冶師%sの", player_ptr->name));
378 describe_artifact_ja(flavor_ptr);
381 describe_inscription(flavor_ptr);
382 *flavor_ptr->t = '\0';
385 describe_artifact_body_ja(flavor_ptr);
387 if (object_is_smith(player_ptr, flavor_ptr->o_ptr))
388 flavor_ptr->t = object_desc_str(flavor_ptr->t, format(" of %s the Smith", player_ptr->name));
390 describe_artifact_body_en(flavor_ptr);