OSDN Git Service

b7a3488e182989691413fc4af50dcb0e835c8715
[hengband/hengband.git] / src / monster / monster-describer.c
1 #include "monster/monster-describer.h"
2 #include "floor/floor.h"
3 #include "io/files-util.h"
4 #include "monster-race/race-flags1.h"
5 #include "monster/monster-description-types.h"
6 #include "monster/monster-flag-types.h"
7 #include "monster/monster2.h" // todo 相互参照している.
8
9 /*!
10  * @brief モンスターの呼称を作成する / Build a string describing a monster in some way.
11  * @param desc 記述出力先の文字列参照ポインタ
12  * @param m_ptr モンスターの参照ポインタ
13  * @param mode 呼称オプション
14  * @return なし
15  */
16 void monster_desc(player_type *player_ptr, char *desc, monster_type *m_ptr, BIT_FLAGS mode)
17 {
18     monster_race *r_ptr;
19     r_ptr = &r_info[m_ptr->ap_r_idx];
20     concptr name = (mode & MD_TRUE_NAME) ? (r_name + real_r_ptr(m_ptr)->name) : (r_name + r_ptr->name);
21     GAME_TEXT silly_name[1024];
22     bool named = FALSE;
23     if (player_ptr->image && !(mode & MD_IGNORE_HALLU)) {
24         if (one_in_(2)) {
25             if (!get_rnd_line(_("silly_j.txt", "silly.txt"), m_ptr->r_idx, silly_name))
26                 named = TRUE;
27         }
28
29         if (!named) {
30             monster_race *hallu_race;
31
32             do {
33                 hallu_race = &r_info[randint1(max_r_idx - 1)];
34             } while (!hallu_race->name || (hallu_race->flags1 & RF1_UNIQUE));
35
36             strcpy(silly_name, (r_name + hallu_race->name));
37         }
38
39         name = silly_name;
40     }
41
42     bool seen = (m_ptr && ((mode & MD_ASSUME_VISIBLE) || (!(mode & MD_ASSUME_HIDDEN) && m_ptr->ml)));
43     bool pron = (m_ptr && ((seen && (mode & MD_PRON_VISIBLE)) || (!seen && (mode & MD_PRON_HIDDEN))));
44
45     /* First, try using pronouns, or describing hidden monsters */
46     floor_type *floor_ptr = player_ptr->current_floor_ptr;
47     if (!seen || pron) {
48         int kind = 0x00;
49         if (r_ptr->flags1 & (RF1_FEMALE))
50             kind = 0x20;
51         else if (r_ptr->flags1 & (RF1_MALE))
52             kind = 0x10;
53
54         if (!m_ptr || !pron)
55             kind = 0x00;
56
57         concptr res = _("何か", "it");
58         switch (kind + (mode & (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE))) {
59 #ifdef JP
60         case 0x00:
61             res = "何か";
62             break;
63         case 0x00 + (MD_OBJECTIVE):
64             res = "何か";
65             break;
66         case 0x00 + (MD_POSSESSIVE):
67             res = "何かの";
68             break;
69         case 0x00 + (MD_POSSESSIVE | MD_OBJECTIVE):
70             res = "何か自身";
71             break;
72         case 0x00 + (MD_INDEF_HIDDEN):
73             res = "何か";
74             break;
75         case 0x00 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
76             res = "何か";
77             break;
78         case 0x00 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
79             res = "何か";
80             break;
81         case 0x00 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
82             res = "それ自身";
83             break;
84 #else
85         case 0x00:
86             res = "it";
87             break;
88         case 0x00 + (MD_OBJECTIVE):
89             res = "it";
90             break;
91         case 0x00 + (MD_POSSESSIVE):
92             res = "its";
93             break;
94         case 0x00 + (MD_POSSESSIVE | MD_OBJECTIVE):
95             res = "itself";
96             break;
97         case 0x00 + (MD_INDEF_HIDDEN):
98             res = "something";
99             break;
100         case 0x00 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
101             res = "something";
102             break;
103         case 0x00 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
104             res = "something's";
105             break;
106         case 0x00 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
107             res = "itself";
108             break;
109 #endif
110
111 #ifdef JP
112         case 0x10:
113             res = "彼";
114             break;
115         case 0x10 + (MD_OBJECTIVE):
116             res = "彼";
117             break;
118         case 0x10 + (MD_POSSESSIVE):
119             res = "彼の";
120             break;
121         case 0x10 + (MD_POSSESSIVE | MD_OBJECTIVE):
122             res = "彼自身";
123             break;
124         case 0x10 + (MD_INDEF_HIDDEN):
125             res = "誰か";
126             break;
127         case 0x10 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
128             res = "誰か";
129             break;
130         case 0x10 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
131             res = "誰かの";
132             break;
133         case 0x10 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
134             res = "彼自身";
135             break;
136 #else
137         case 0x10:
138             res = "he";
139             break;
140         case 0x10 + (MD_OBJECTIVE):
141             res = "him";
142             break;
143         case 0x10 + (MD_POSSESSIVE):
144             res = "his";
145             break;
146         case 0x10 + (MD_POSSESSIVE | MD_OBJECTIVE):
147             res = "himself";
148             break;
149         case 0x10 + (MD_INDEF_HIDDEN):
150             res = "someone";
151             break;
152         case 0x10 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
153             res = "someone";
154             break;
155         case 0x10 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
156             res = "someone's";
157             break;
158         case 0x10 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
159             res = "himself";
160             break;
161 #endif
162
163 #ifdef JP
164         case 0x20:
165             res = "彼女";
166             break;
167         case 0x20 + (MD_OBJECTIVE):
168             res = "彼女";
169             break;
170         case 0x20 + (MD_POSSESSIVE):
171             res = "彼女の";
172             break;
173         case 0x20 + (MD_POSSESSIVE | MD_OBJECTIVE):
174             res = "彼女自身";
175             break;
176         case 0x20 + (MD_INDEF_HIDDEN):
177             res = "誰か";
178             break;
179         case 0x20 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
180             res = "誰か";
181             break;
182         case 0x20 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
183             res = "誰かの";
184             break;
185         case 0x20 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
186             res = "彼女自身";
187             break;
188 #else
189         case 0x20:
190             res = "she";
191             break;
192         case 0x20 + (MD_OBJECTIVE):
193             res = "her";
194             break;
195         case 0x20 + (MD_POSSESSIVE):
196             res = "her";
197             break;
198         case 0x20 + (MD_POSSESSIVE | MD_OBJECTIVE):
199             res = "herself";
200             break;
201         case 0x20 + (MD_INDEF_HIDDEN):
202             res = "someone";
203             break;
204         case 0x20 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
205             res = "someone";
206             break;
207         case 0x20 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
208             res = "someone's";
209             break;
210         case 0x20 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
211             res = "herself";
212             break;
213 #endif
214         }
215
216         (void)strcpy(desc, res);
217         return;
218     }
219
220     /* Handle visible monsters, "reflexive" request */
221     if ((mode & (MD_POSSESSIVE | MD_OBJECTIVE)) == (MD_POSSESSIVE | MD_OBJECTIVE)) {
222         /* The monster is visible, so use its gender */
223         if (r_ptr->flags1 & (RF1_FEMALE))
224             strcpy(desc, _("彼女自身", "herself"));
225         else if (r_ptr->flags1 & (RF1_MALE))
226             strcpy(desc, _("彼自身", "himself"));
227         else
228             strcpy(desc, _("それ自身", "itself"));
229         return;
230     }
231
232     /* Handle all other visible monster requests */
233     /* Tanuki? */
234     if (is_pet(m_ptr) && !is_original_ap(m_ptr)) {
235 #ifdef JP
236         char *t;
237         char buf[128];
238         strcpy(buf, name);
239         t = buf;
240         while (strncmp(t, "』", 2) && *t)
241             t++;
242         if (*t) {
243             *t = '\0';
244             (void)sprintf(desc, "%s?』", buf);
245         } else
246             (void)sprintf(desc, "%s?", name);
247 #else
248         (void)sprintf(desc, "%s?", name);
249 #endif
250     } else {
251         if ((r_ptr->flags1 & RF1_UNIQUE) && !(player_ptr->image && !(mode & MD_IGNORE_HALLU))) {
252             if ((m_ptr->mflag2 & MFLAG2_CHAMELEON) && !(mode & MD_TRUE_NAME)) {
253 #ifdef JP
254                 char *t;
255                 char buf[128];
256                 strcpy(buf, name);
257                 t = buf;
258                 while (strncmp(t, "』", 2) && *t)
259                     t++;
260                 if (*t) {
261                     *t = '\0';
262                     (void)sprintf(desc, "%s?』", buf);
263                 } else
264                     (void)sprintf(desc, "%s?", name);
265 #else
266                 (void)sprintf(desc, "%s?", name);
267 #endif
268             } else if (player_ptr->phase_out && !(player_ptr->riding && (&floor_ptr->m_list[player_ptr->riding] == m_ptr))) {
269                 (void)sprintf(desc, _("%sもどき", "fake %s"), name);
270             } else {
271                 (void)strcpy(desc, name);
272             }
273         } else if (mode & MD_INDEF_VISIBLE) {
274 #ifdef JP
275             (void)strcpy(desc, "");
276 #else
277             (void)strcpy(desc, is_a_vowel(name[0]) ? "an " : "a ");
278 #endif
279             (void)strcat(desc, name);
280         } else {
281             if (is_pet(m_ptr))
282                 (void)strcpy(desc, _("あなたの", "your "));
283             else
284                 (void)strcpy(desc, _("", "the "));
285
286             (void)strcat(desc, name);
287         }
288     }
289
290     if (m_ptr->nickname) {
291         char buf[128];
292         sprintf(buf, _("「%s」", " called %s"), quark_str(m_ptr->nickname));
293         strcat(desc, buf);
294     }
295
296     if (player_ptr->riding && (&floor_ptr->m_list[player_ptr->riding] == m_ptr)) {
297         strcat(desc, _("(乗馬中)", "(riding)"));
298     }
299
300     if ((mode & MD_IGNORE_HALLU) && (m_ptr->mflag2 & MFLAG2_CHAMELEON)) {
301         if (r_ptr->flags1 & RF1_UNIQUE) {
302             strcat(desc, _("(カメレオンの王)", "(Chameleon Lord)"));
303         } else {
304             strcat(desc, _("(カメレオン)", "(Chameleon)"));
305         }
306     }
307
308     if ((mode & MD_IGNORE_HALLU) && !is_original_ap(m_ptr)) {
309         strcat(desc, format("(%s)", r_name + r_info[m_ptr->r_idx].name));
310     }
311
312     /* Handle the Possessive as a special afterthought */
313     if (mode & MD_POSSESSIVE) {
314         (void)strcat(desc, _("の", "'s"));
315     }
316 }