OSDN Git Service

fa08c6ae2a4eaba901f22ec1bb8b53580d08a59a
[hengband/hengband.git] / src / flavor / object-flavor.c
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 "flavor/flag-inscriptions-table.h"
15 #include "flavor/flavor-util.h"
16 #include "flavor/object-flavor-types.h"
17 #include "game-option/text-display-options.h"
18 #include "grid/trap.h"
19 #include "inventory/inventory-slot-types.h"
20 #include "io/files-util.h"
21 #include "mind/mind-sniper.h"
22 #include "mind/mind-weaponsmith.h"
23 #include "monster-race/monster-race.h"
24 #include "monster-race/race-flags1.h"
25 #include "object-enchant/object-ego.h"
26 #include "object-enchant/special-object-flags.h"
27 #include "object-enchant/tr-types.h"
28 #include "object-enchant/trg-types.h"
29 #include "object-hook/hook-checker.h"
30 #include "object-hook/hook-enchant.h"
31 #include "object-hook/hook-quest.h"
32 #include "object/object-flags.h"
33 #include "object/object-info.h"
34 #include "object/object-kind.h"
35 #include "perception/object-perception.h"
36 #include "player/player-class.h"
37 #include "player/player-status.h"
38 #include "combat/shoot.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
90     return FALSE;
91 }
92
93 /*!
94  * @brief 各種語彙からランダムな名前を作成する / Create a name from random parts.
95  * @param out_string 作成した名を保管する参照ポインタ
96  * @return なし
97  * @details 日本語の場合 aname_j.txt 英語の場合確率に応じて
98  * syllables 配列と elvish.txt を組み合わせる。\n
99  */
100 void get_table_name_aux(char *out_string)
101 {
102 #ifdef JP
103     char syllable[80];
104     get_rnd_line("aname_j.txt", 1, syllable);
105     strcpy(out_string, syllable);
106     get_rnd_line("aname_j.txt", 2, syllable);
107     strcat(out_string, syllable);
108 #else
109 #define MAX_SYLLABLES 164 /* Used with scrolls (see below) */
110
111     static concptr syllables[MAX_SYLLABLES] = { "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze", "ash", "aus", "ban", "bar", "bat", "bek",
112         "bie", "bin", "bit", "bjor", "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf", "dan", "den", "der", "doe", "dok", "eep", "el", "eng",
113         "er", "ere", "erk", "esh", "evs", "fa", "fid", "flit", "for", "fri", "fu", "gan", "gar", "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion",
114         "ip", "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech", "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur", "nag", "nej",
115         "nelg", "nep", "ner", "nes", "nis", "nih", "nin", "o", "od", "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po", "pot", "prok", "re",
116         "rea", "rhov", "ri", "ro", "rog", "rok", "rol", "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna", "sne", "snik", "sno", "so", "sol", "sri",
117         "sta", "sun", "ta", "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u", "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
118         "wed", "werg", "wex", "whon", "wun", "x", "yerg", "yp", "zun", "tri", "blaa", "jah", "bul", "on", "foo", "ju", "xuxu" };
119
120     int testcounter = randint1(3) + 1;
121     strcpy(out_string, "");
122     if (randint1(3) == 2) {
123         while (testcounter--)
124             strcat(out_string, syllables[randint0(MAX_SYLLABLES)]);
125     } else {
126         char syllable[80];
127         testcounter = randint1(2) + 1;
128         while (testcounter--) {
129             (void)get_rnd_line("elvish.txt", 0, syllable);
130             strcat(out_string, syllable);
131         }
132     }
133
134     out_string[0] = toupper(out_string[1]);
135     out_string[16] = '\0';
136 #endif
137 }
138
139 /*!
140  * @brief ランダムな名前をアーティファクト銘として整形する。 / Create a name from random parts with quotes.
141  * @param out_string 作成した名を保管する参照ポインタ
142  * @return なし
143  * @details get_table_name_aux()ほぼ完全に実装を依存している。
144  */
145 void get_table_name(char *out_string)
146 {
147     char buff[80];
148     get_table_name_aux(buff);
149     sprintf(out_string, _("『%s』", "'%s'"), buff);
150 }
151
152 /*!
153  * @brief ランダムなシンダリン銘を作成する / Make random Sindarin name
154  * @param out_string 作成した名を保管する参照ポインタ
155  * @return なし
156  * @details sname.txtが語幹の辞書となっている。
157  */
158 void get_table_sindarin_aux(char *out_string)
159 {
160     char syllable[80];
161 #ifdef JP
162     char tmp[80];
163 #endif
164
165     get_rnd_line("sname.txt", 1, syllable);
166     strcpy(_(tmp, out_string), syllable);
167     get_rnd_line("sname.txt", 2, syllable);
168 #ifdef JP
169     strcat(tmp, syllable);
170     sindarin_to_kana(out_string, tmp);
171 #else
172     strcat(out_string, syllable);
173 #endif
174 }
175
176 /*!
177  * @brief シンダリン銘をアーティファクト用に整形する。 / Make random Sindarin name with quotes
178  * @param out_string 作成した名を保管する参照ポインタ
179  * @return なし
180  * @details get_table_sindarin_aux()ほぼ完全に実装を依存している。
181  */
182 void get_table_sindarin(char *out_string)
183 {
184     char buff[80];
185     get_table_sindarin_aux(buff);
186     sprintf(out_string, _("『%s』", "'%s'"), buff);
187 }
188
189 /*!
190  * @brief ベースアイテムの未確定名を共通tval間でシャッフルする / Shuffle flavor indices of a group of objects with given tval
191  * @param tval シャッフルしたいtval
192  * @return なし
193  * @details 巻物、各種魔道具などに利用される。
194  */
195 static void shuffle_flavors(tval_type tval)
196 {
197     KIND_OBJECT_IDX *k_idx_list;
198     KIND_OBJECT_IDX k_idx_list_num = 0;
199     C_MAKE(k_idx_list, max_k_idx, KIND_OBJECT_IDX);
200     for (KIND_OBJECT_IDX i = 0; i < max_k_idx; i++) {
201         object_kind *k_ptr = &k_info[i];
202         if (k_ptr->tval != tval)
203             continue;
204
205         if (!k_ptr->flavor)
206             continue;
207
208         if (has_flag(k_ptr->flags, TR_FIXED_FLAVOR))
209             continue;
210
211         k_idx_list[k_idx_list_num] = i;
212         k_idx_list_num++;
213     }
214
215     for (KIND_OBJECT_IDX i = 0; i < k_idx_list_num; i++) {
216         object_kind *k1_ptr = &k_info[k_idx_list[i]];
217         object_kind *k2_ptr = &k_info[k_idx_list[randint0(k_idx_list_num)]];
218         s16b tmp = k1_ptr->flavor;
219         k1_ptr->flavor = k2_ptr->flavor;
220         k2_ptr->flavor = tmp;
221     }
222
223     C_KILL(k_idx_list, max_k_idx, s16b);
224 }
225
226 /*!
227  * @brief ゲーム開始時に行われるベースアイテムの初期化ルーチン / Prepare the "variable" part of the "k_info" array.
228  * @param なし
229  * @return なし
230  */
231 void flavor_init(void)
232 {
233     u32b state_backup[4];
234     Rand_state_backup(state_backup);
235     Rand_state_set(current_world_ptr->seed_flavor);
236     for (KIND_OBJECT_IDX i = 0; i < max_k_idx; i++) {
237         object_kind *k_ptr = &k_info[i];
238         if (!k_ptr->flavor_name)
239             continue;
240
241         k_ptr->flavor = i;
242     }
243
244     shuffle_flavors(TV_RING);
245     shuffle_flavors(TV_AMULET);
246     shuffle_flavors(TV_STAFF);
247     shuffle_flavors(TV_WAND);
248     shuffle_flavors(TV_ROD);
249     shuffle_flavors(TV_FOOD);
250     shuffle_flavors(TV_POTION);
251     shuffle_flavors(TV_SCROLL);
252     Rand_state_restore(state_backup);
253     for (KIND_OBJECT_IDX i = 1; i < max_k_idx; i++) {
254         object_kind *k_ptr = &k_info[i];
255         if (!k_ptr->name)
256             continue;
257
258         if (!k_ptr->flavor)
259             k_ptr->aware = TRUE;
260
261         k_ptr->easy_know = object_easy_know(i);
262     }
263 }
264
265 /*!
266  * @brief nameバッファ内からベースアイテム名を返す / Strip an "object name" into a buffer
267  * @param buf ベースアイテム格納先の参照ポインタ
268  * @param k_idx ベースアイテムID
269  * @return なし
270  */
271 void strip_name(char *buf, KIND_OBJECT_IDX k_idx)
272 {
273     object_kind *k_ptr = &k_info[k_idx];
274     concptr str = (k_name + k_ptr->name);
275     while ((*str == ' ') || (*str == '&'))
276         str++;
277
278     char *t;
279     for (t = buf; *str; str++) {
280 #ifdef JP
281         if (iskanji(*str)) {
282             *t++ = *str++;
283             *t++ = *str;
284             continue;
285         }
286 #endif
287         if (*str != '~')
288             *t++ = *str;
289     }
290
291     *t = '\0';
292 }