OSDN Git Service

Merge pull request #595 from sikabane-works/release/3.0.0Alpha13
[hengbandforosx/hengbandosx.git] / src / flavor / object-flavor.cpp
1 /*!
2  *  @brief オブジェクトの記述処理 / Mbject flavor code
3  *  @date 2014/01/03
4  *  @author
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
6  *\n
7  * This software may be copied and distributed for educational, research,\n
8  * and not for profit purposes provided that this copyright and statement\n
9  * are included in all such copies.  Other copyrights may also apply.\n
10  */
11
12 #include "flavor/object-flavor.h"
13 #include "cmd-item/cmd-smith.h"
14 #include "combat/shoot.h"
15 #include "flavor/flag-inscriptions-table.h"
16 #include "flavor/flavor-util.h"
17 #include "flavor/object-flavor-types.h"
18 #include "game-option/text-display-options.h"
19 #include "grid/trap.h"
20 #include "inventory/inventory-slot-types.h"
21 #include "io/files-util.h"
22 #include "mind/mind-sniper.h"
23 #include "mind/mind-weaponsmith.h"
24 #include "monster-race/monster-race.h"
25 #include "monster-race/race-flags1.h"
26 #include "object-enchant/object-ego.h"
27 #include "object-enchant/special-object-flags.h"
28 #include "object-enchant/tr-types.h"
29 #include "object-enchant/trg-types.h"
30 #include "object-hook/hook-checker.h"
31 #include "object-hook/hook-enchant.h"
32 #include "object-hook/hook-quest.h"
33 #include "object/object-flags.h"
34 #include "object/object-info.h"
35 #include "object/object-kind.h"
36 #include "perception/object-perception.h"
37 #include "player/player-class.h"
38 #include "player/player-status.h"
39 #include "sv-definition/sv-food-types.h"
40 #include "sv-definition/sv-lite-types.h"
41 #include "util/bit-flags-calculator.h"
42 #include "util/quarks.h"
43 #include "util/string-processor.h"
44 #include "world/world.h"
45 #ifdef JP
46 #include "locale/japanese.h"
47 #else
48 #include "locale/english.h"
49 #endif
50
51 /*!
52  * @brief 最初から簡易な名称が明らかになるベースアイテムの判定。 /  Certain items, if aware, are known instantly
53  * @param i ベースアイテムID
54  * @return 簡易名称を明らかにするならTRUEを返す。
55  * @details
56  * This function is used only by "flavor_init()"
57  */
58 static bool object_easy_know(int i)
59 {
60     object_kind *k_ptr = &k_info[i];
61     switch (k_ptr->tval) {
62     case TV_LIFE_BOOK:
63     case TV_SORCERY_BOOK:
64     case TV_NATURE_BOOK:
65     case TV_CHAOS_BOOK:
66     case TV_DEATH_BOOK:
67     case TV_TRUMP_BOOK:
68     case TV_ARCANE_BOOK:
69     case TV_CRAFT_BOOK:
70     case TV_DEMON_BOOK:
71     case TV_CRUSADE_BOOK:
72     case TV_MUSIC_BOOK:
73     case TV_HISSATSU_BOOK:
74     case TV_HEX_BOOK:
75         return TRUE;
76     case TV_FLASK:
77     case TV_JUNK:
78     case TV_BOTTLE:
79     case TV_SKELETON:
80     case TV_SPIKE:
81     case TV_WHISTLE:
82         return TRUE;
83     case TV_FOOD:
84     case TV_POTION:
85     case TV_SCROLL:
86     case TV_ROD:
87         return TRUE;
88
89     default:
90         break;
91     }
92
93     return FALSE;
94 }
95
96 /*!
97  * @brief 各種語彙からランダムな名前を作成する / Create a name from random parts.
98  * @param out_string 作成した名を保管する参照ポインタ
99  * @return なし
100  * @details 日本語の場合 aname_j.txt 英語の場合確率に応じて
101  * syllables 配列と elvish.txt を組み合わせる。\n
102  */
103 void get_table_name_aux(char *out_string)
104 {
105 #ifdef JP
106     char syllable[80];
107     get_rnd_line("aname_j.txt", 1, syllable);
108     strcpy(out_string, syllable);
109     get_rnd_line("aname_j.txt", 2, syllable);
110     strcat(out_string, syllable);
111 #else
112 #define MAX_SYLLABLES 164 /* Used with scrolls (see below) */
113
114     static concptr syllables[MAX_SYLLABLES] = { "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek",
115         "bie", "bin", "bit", "bjor", "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf", "dan", "den", "der", "doe", "dok", "eep", "el", "eng",
116         "er", "ere", "erk", "esh", "evs", "fa", "fid", "flit", "for", "fri", "fu", "gan", "gar", "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion",
117         "ip", "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech", "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur", "nag", "nej",
118         "nelg", "nep", "ner", "nes", "nis", "nih", "nin", "o", "od", "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po", "pot", "prok", "re",
119         "rea", "rhov", "ri", "ro", "rog", "rok", "rol", "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna", "sne", "snik", "sno", "so", "sol", "sri",
120         "sta", "sun", "ta", "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u", "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
121         "wed", "werg", "wex", "whon", "wun", "x", "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on", "foo", "ju", "xuxu" };
122
123     int testcounter = randint1(3) + 1;
124     strcpy(out_string, "");
125     if (randint1(3) == 2) {
126         while (testcounter--)
127             strcat(out_string, syllables[randint0(MAX_SYLLABLES)]);
128     } else {
129         char syllable[80];
130         testcounter = randint1(2) + 1;
131         while (testcounter--) {
132             (void)get_rnd_line("elvish.txt", 0, syllable);
133             strcat(out_string, syllable);
134         }
135     }
136
137     out_string[0] = toupper(out_string[1]);
138     out_string[16] = '\0';
139 #endif
140 }
141
142 /*!
143  * @brief ランダムな名前をアーティファクト銘として整形する。 / Create a name from random parts with quotes.
144  * @param out_string 作成した名を保管する参照ポインタ
145  * @return なし
146  * @details get_table_name_aux()ほぼ完全に実装を依存している。
147  */
148 void get_table_name(char *out_string)
149 {
150     char buff[80];
151     get_table_name_aux(buff);
152     sprintf(out_string, _("『%s』", "'%s'"), buff);
153 }
154
155 /*!
156  * @brief ランダムなシンダリン銘を作成する / Make random Sindarin name
157  * @param out_string 作成した名を保管する参照ポインタ
158  * @return なし
159  * @details sname.txtが語幹の辞書となっている。
160  */
161 void get_table_sindarin_aux(char *out_string)
162 {
163     char syllable[80];
164 #ifdef JP
165     char tmp[80];
166 #endif
167
168     get_rnd_line("sname.txt", 1, syllable);
169     strcpy(_(tmp, out_string), syllable);
170     get_rnd_line("sname.txt", 2, syllable);
171 #ifdef JP
172     strcat(tmp, syllable);
173     sindarin_to_kana(out_string, tmp);
174 #else
175     strcat(out_string, syllable);
176 #endif
177 }
178
179 /*!
180  * @brief シンダリン銘をアーティファクト用に整形する。 / Make random Sindarin name with quotes
181  * @param out_string 作成した名を保管する参照ポインタ
182  * @return なし
183  * @details get_table_sindarin_aux()ほぼ完全に実装を依存している。
184  */
185 void get_table_sindarin(char *out_string)
186 {
187     char buff[80];
188     get_table_sindarin_aux(buff);
189     sprintf(out_string, _("『%s』", "'%s'"), buff);
190 }
191
192 /*!
193  * @brief ベースアイテムの未確定名を共通tval間でシャッフルする / Shuffle flavor indices of a group of objects with given tval
194  * @param tval シャッフルしたいtval
195  * @return なし
196  * @details 巻物、各種魔道具などに利用される。
197  */
198 static void shuffle_flavors(tval_type tval)
199 {
200     KIND_OBJECT_IDX *k_idx_list;
201     KIND_OBJECT_IDX k_idx_list_num = 0;
202     C_MAKE(k_idx_list, max_k_idx, KIND_OBJECT_IDX);
203     for (KIND_OBJECT_IDX i = 0; i < max_k_idx; i++) {
204         object_kind *k_ptr = &k_info[i];
205         if (k_ptr->tval != tval)
206             continue;
207
208         if (!k_ptr->flavor)
209             continue;
210
211         if (has_flag(k_ptr->flags, TR_FIXED_FLAVOR))
212             continue;
213
214         k_idx_list[k_idx_list_num] = i;
215         k_idx_list_num++;
216     }
217
218     for (KIND_OBJECT_IDX i = 0; i < k_idx_list_num; i++) {
219         object_kind *k1_ptr = &k_info[k_idx_list[i]];
220         object_kind *k2_ptr = &k_info[k_idx_list[randint0(k_idx_list_num)]];
221         s16b tmp = k1_ptr->flavor;
222         k1_ptr->flavor = k2_ptr->flavor;
223         k2_ptr->flavor = tmp;
224     }
225
226     C_KILL(k_idx_list, max_k_idx, s16b);
227 }
228
229 /*!
230  * @brief ゲーム開始時に行われるベースアイテムの初期化ルーチン / Prepare the "variable" part of the "k_info" array.
231  * @param なし
232  * @return なし
233  */
234 void flavor_init(void)
235 {
236     u32b state_backup[4];
237     Rand_state_backup(state_backup);
238     Rand_state_set(current_world_ptr->seed_flavor);
239     for (KIND_OBJECT_IDX i = 0; i < max_k_idx; i++) {
240         object_kind *k_ptr = &k_info[i];
241         if (!k_ptr->flavor_name)
242             continue;
243
244         k_ptr->flavor = i;
245     }
246
247     shuffle_flavors(TV_RING);
248     shuffle_flavors(TV_AMULET);
249     shuffle_flavors(TV_STAFF);
250     shuffle_flavors(TV_WAND);
251     shuffle_flavors(TV_ROD);
252     shuffle_flavors(TV_FOOD);
253     shuffle_flavors(TV_POTION);
254     shuffle_flavors(TV_SCROLL);
255     Rand_state_restore(state_backup);
256     for (KIND_OBJECT_IDX i = 1; i < max_k_idx; i++) {
257         object_kind *k_ptr = &k_info[i];
258         if (!k_ptr->name)
259             continue;
260
261         if (!k_ptr->flavor)
262             k_ptr->aware = TRUE;
263
264         k_ptr->easy_know = object_easy_know(i);
265     }
266 }
267
268 /*!
269  * @brief nameバッファ内からベースアイテム名を返す / Strip an "object name" into a buffer
270  * @param buf ベースアイテム格納先の参照ポインタ
271  * @param k_idx ベースアイテムID
272  * @return なし
273  */
274 void strip_name(char *buf, KIND_OBJECT_IDX k_idx)
275 {
276     object_kind *k_ptr = &k_info[k_idx];
277     concptr str = (k_name + k_ptr->name);
278     while ((*str == ' ') || (*str == '&'))
279         str++;
280
281     char *t;
282     for (t = buf; *str; str++) {
283 #ifdef JP
284         if (iskanji(*str)) {
285             *t++ = *str++;
286             *t++ = *str;
287             continue;
288         }
289 #endif
290         if (*str != '~')
291             *t++ = *str;
292     }
293
294     *t = '\0';
295 }