OSDN Git Service

5356f2915589b371b151151dee5a595cc7b8c32d
[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 "locale/vowel-checker.h"
5 #include "monster-race/race-flags1.h"
6 #include "monster/monster-description-types.h"
7 #include "monster/monster-flag-types.h"
8 #include "monster/monster-info.h"
9 #include "util/quarks.h"
10 #include "view/display-messages.h"
11
12 /*!
13  * @brief モンスターの呼称を作成する / Build a string describing a monster in some way.
14  * @param desc 記述出力先の文字列参照ポインタ
15  * @param m_ptr モンスターの参照ポインタ
16  * @param mode 呼称オプション
17  * @return なし
18  */
19 void monster_desc(player_type *player_ptr, char *desc, monster_type *m_ptr, BIT_FLAGS mode)
20 {
21     monster_race *r_ptr;
22     r_ptr = &r_info[m_ptr->ap_r_idx];
23     concptr name = (mode & MD_TRUE_NAME) ? (r_name + real_r_ptr(m_ptr)->name) : (r_name + r_ptr->name);
24     GAME_TEXT silly_name[1024];
25     bool named = FALSE;
26     if (player_ptr->image && !(mode & MD_IGNORE_HALLU)) {
27         if (one_in_(2)) {
28             if (!get_rnd_line(_("silly_j.txt", "silly.txt"), m_ptr->r_idx, silly_name))
29                 named = TRUE;
30         }
31
32         if (!named) {
33             monster_race *hallu_race;
34
35             do {
36                 hallu_race = &r_info[randint1(max_r_idx - 1)];
37             } while (!hallu_race->name || (hallu_race->flags1 & RF1_UNIQUE));
38
39             strcpy(silly_name, (r_name + hallu_race->name));
40         }
41
42         name = silly_name;
43     }
44
45     bool seen = (m_ptr && ((mode & MD_ASSUME_VISIBLE) || (!(mode & MD_ASSUME_HIDDEN) && m_ptr->ml)));
46     bool pron = (m_ptr && ((seen && (mode & MD_PRON_VISIBLE)) || (!seen && (mode & MD_PRON_HIDDEN))));
47
48     /* First, try using pronouns, or describing hidden monsters */
49     floor_type *floor_ptr = player_ptr->current_floor_ptr;
50     if (!seen || pron) {
51         int kind = 0x00;
52         if (r_ptr->flags1 & (RF1_FEMALE))
53             kind = 0x20;
54         else if (r_ptr->flags1 & (RF1_MALE))
55             kind = 0x10;
56
57         if (!m_ptr || !pron)
58             kind = 0x00;
59
60         concptr res = _("何か", "it");
61         switch (kind + (mode & (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE))) {
62         case 0x00:
63             res = _("何か", "it");
64             break;
65         case 0x00 + (MD_OBJECTIVE):
66             res = _("何か", "it");
67             break;
68         case 0x00 + (MD_POSSESSIVE):
69             res = _("何かの", "its");
70             break;
71         case 0x00 + (MD_POSSESSIVE | MD_OBJECTIVE):
72             res = _("何か自身", "itself");
73             break;
74         case 0x00 + (MD_INDEF_HIDDEN):
75             res = _("何か", "something");
76             break;
77         case 0x00 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
78             res = _("何か", "something");
79             break;
80         case 0x00 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
81             res = _("何か", "something's");
82             break;
83         case 0x00 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
84             res = _("それ自身", "itself");
85             break;
86         case 0x10:
87             res = _("彼", "he");
88             break;
89         case 0x10 + (MD_OBJECTIVE):
90             res = _("彼", "him");
91             break;
92         case 0x10 + (MD_POSSESSIVE):
93             res = _("彼の", "his");
94             break;
95         case 0x10 + (MD_POSSESSIVE | MD_OBJECTIVE):
96             res = _("彼自身", "himself");
97             break;
98         case 0x10 + (MD_INDEF_HIDDEN):
99             res = _("誰か", "someone");
100             break;
101         case 0x10 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
102             res = _("誰か", "someone");
103             break;
104         case 0x10 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
105             res = _("誰かの", "someone's");
106             break;
107         case 0x10 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
108             res = _("彼自身", "himself");
109             break;
110         case 0x20:
111             res = _("彼女", "she");
112             break;
113         case 0x20 + (MD_OBJECTIVE):
114             res = _("彼女", "her");
115             break;
116         case 0x20 + (MD_POSSESSIVE):
117             res = _("彼女の", "her");
118             break;
119         case 0x20 + (MD_POSSESSIVE | MD_OBJECTIVE):
120             res = _("彼女自身", "herself");
121             break;
122         case 0x20 + (MD_INDEF_HIDDEN):
123             res = _("誰か", "someone");
124             break;
125         case 0x20 + (MD_INDEF_HIDDEN | MD_OBJECTIVE):
126             res = _("誰か", "someone");
127             break;
128         case 0x20 + (MD_INDEF_HIDDEN | MD_POSSESSIVE):
129             res = _("誰かの", "someone's");
130             break;
131         case 0x20 + (MD_INDEF_HIDDEN | MD_POSSESSIVE | MD_OBJECTIVE):
132             res = _("彼女自身", "herself");
133             break;
134         }
135
136         (void)strcpy(desc, res);
137         return;
138     }
139
140     /* Handle visible monsters, "reflexive" request */
141     if ((mode & (MD_POSSESSIVE | MD_OBJECTIVE)) == (MD_POSSESSIVE | MD_OBJECTIVE)) {
142         /* The monster is visible, so use its gender */
143         if (r_ptr->flags1 & (RF1_FEMALE))
144             strcpy(desc, _("彼女自身", "herself"));
145         else if (r_ptr->flags1 & (RF1_MALE))
146             strcpy(desc, _("彼自身", "himself"));
147         else
148             strcpy(desc, _("それ自身", "itself"));
149         return;
150     }
151
152     /* Handle all other visible monster requests */
153     /* Tanuki? */
154     if (is_pet(m_ptr) && !is_original_ap(m_ptr)) {
155 #ifdef JP
156         char *t;
157         char buf[128];
158         strcpy(buf, name);
159         t = buf;
160         while (strncmp(t, "』", 2) && *t)
161             t++;
162         if (*t) {
163             *t = '\0';
164             (void)sprintf(desc, "%s?』", buf);
165         } else
166             (void)sprintf(desc, "%s?", name);
167 #else
168         (void)sprintf(desc, "%s?", name);
169 #endif
170     } else {
171         if ((r_ptr->flags1 & RF1_UNIQUE) && !(player_ptr->image && !(mode & MD_IGNORE_HALLU))) {
172             if ((m_ptr->mflag2 & MFLAG2_CHAMELEON) && !(mode & MD_TRUE_NAME)) {
173 #ifdef JP
174                 char *t;
175                 char buf[128];
176                 strcpy(buf, name);
177                 t = buf;
178                 while (strncmp(t, "』", 2) && *t)
179                     t++;
180                 if (*t) {
181                     *t = '\0';
182                     (void)sprintf(desc, "%s?』", buf);
183                 } else
184                     (void)sprintf(desc, "%s?", name);
185 #else
186                 (void)sprintf(desc, "%s?", name);
187 #endif
188             } else if (player_ptr->phase_out && !(player_ptr->riding && (&floor_ptr->m_list[player_ptr->riding] == m_ptr))) {
189                 (void)sprintf(desc, _("%sもどき", "fake %s"), name);
190             } else {
191                 (void)strcpy(desc, name);
192             }
193         } else if (mode & MD_INDEF_VISIBLE) {
194 #ifdef JP
195             (void)strcpy(desc, "");
196 #else
197             (void)strcpy(desc, is_a_vowel(name[0]) ? "an " : "a ");
198 #endif
199             (void)strcat(desc, name);
200         } else {
201             if (is_pet(m_ptr))
202                 (void)strcpy(desc, _("あなたの", "your "));
203             else
204                 (void)strcpy(desc, _("", "the "));
205
206             (void)strcat(desc, name);
207         }
208     }
209
210     if (m_ptr->nickname) {
211         char buf[128];
212         sprintf(buf, _("「%s」", " called %s"), quark_str(m_ptr->nickname));
213         strcat(desc, buf);
214     }
215
216     if (player_ptr->riding && (&floor_ptr->m_list[player_ptr->riding] == m_ptr)) {
217         strcat(desc, _("(乗馬中)", "(riding)"));
218     }
219
220     if ((mode & MD_IGNORE_HALLU) && (m_ptr->mflag2 & MFLAG2_CHAMELEON)) {
221         if (r_ptr->flags1 & RF1_UNIQUE) {
222             strcat(desc, _("(カメレオンの王)", "(Chameleon Lord)"));
223         } else {
224             strcat(desc, _("(カメレオン)", "(Chameleon)"));
225         }
226     }
227
228     if ((mode & MD_IGNORE_HALLU) && !is_original_ap(m_ptr)) {
229         strcat(desc, format("(%s)", r_name + r_info[m_ptr->r_idx].name));
230     }
231
232     /* Handle the Possessive as a special afterthought */
233     if (mode & MD_POSSESSIVE) {
234         (void)strcat(desc, _("の", "'s"));
235     }
236 }
237
238 /*!
239  * @brief ダメージを受けたモンスターの様子を記述する / Dump a message describing a monster's reaction to damage
240  * @param player_ptr プレーヤーへの参照ポインタ
241  * @param m_idx モンスター情報ID
242  * @param dam 与えたダメージ
243  * @return なし
244  * @details
245  * Technically should attempt to treat "Beholder"'s as jelly's
246  */
247 void message_pain(player_type *player_ptr, MONSTER_IDX m_idx, HIT_POINT dam)
248 {
249     monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
250     monster_race *r_ptr = &r_info[m_ptr->r_idx];
251
252     GAME_TEXT m_name[MAX_NLEN];
253
254     monster_desc(player_ptr, m_name, m_ptr, 0);
255
256     if (dam == 0) {
257         msg_format(_("%^sはダメージを受けていない。", "%^s is unharmed."), m_name);
258         return;
259     }
260
261     HIT_POINT newhp = m_ptr->hp;
262     HIT_POINT oldhp = newhp + dam;
263     HIT_POINT tmp = (newhp * 100L) / oldhp;
264     PERCENTAGE percentage = tmp;
265
266     if (angband_strchr(",ejmvwQ", r_ptr->d_char)) {
267         if (percentage > 95)
268             msg_format(_("%^sはほとんど気にとめていない。", "%^s barely notices."), m_name);
269         else if (percentage > 75)
270             msg_format(_("%^sはしり込みした。", "%^s flinches."), m_name);
271         else if (percentage > 50)
272             msg_format(_("%^sは縮こまった。", "%^s squelches."), m_name);
273         else if (percentage > 35)
274             msg_format(_("%^sは痛みに震えた。", "%^s quivers in pain."), m_name);
275         else if (percentage > 20)
276             msg_format(_("%^sは身もだえした。", "%^s writhes about."), m_name);
277         else if (percentage > 10)
278             msg_format(_("%^sは苦痛で身もだえした。", "%^s writhes in agony."), m_name);
279         else
280             msg_format(_("%^sはぐにゃぐにゃと痙攣した。", "%^s jerks limply."), m_name);
281         return;
282     }
283
284     if (angband_strchr("l", r_ptr->d_char)) {
285         if (percentage > 95)
286             msg_format(_("%^sはほとんど気にとめていない。", "%^s barely notices."), m_name);
287         else if (percentage > 75)
288             msg_format(_("%^sはしり込みした。", "%^s flinches."), m_name);
289         else if (percentage > 50)
290             msg_format(_("%^sは躊躇した。", "%^s hesitates."), m_name);
291         else if (percentage > 35)
292             msg_format(_("%^sは痛みに震えた。", "%^s quivers in pain."), m_name);
293         else if (percentage > 20)
294             msg_format(_("%^sは身もだえした。", "%^s writhes about."), m_name);
295         else if (percentage > 10)
296             msg_format(_("%^sは苦痛で身もだえした。", "%^s writhes in agony."), m_name);
297         else
298             msg_format(_("%^sはぐにゃぐにゃと痙攣した。", "%^s jerks limply."), m_name);
299         return;
300     }
301
302     if (angband_strchr("g#+<>", r_ptr->d_char)) {
303         if (percentage > 95)
304             msg_format(_("%sは攻撃を気にとめていない。", "%^s ignores the attack."), m_name);
305         else if (percentage > 75)
306             msg_format(_("%sは攻撃に肩をすくめた。", "%^s shrugs off the attack."), m_name);
307         else if (percentage > 50)
308             msg_format(_("%^sは雷鳴のように吠えた。", "%^s roars thunderously."), m_name);
309         else if (percentage > 35)
310             msg_format(_("%^sは苦しげに吠えた。", "%^s rumbles."), m_name);
311         else if (percentage > 20)
312             msg_format(_("%^sはうめいた。", "%^s grunts."), m_name);
313         else if (percentage > 10)
314             msg_format(_("%^sは躊躇した。", "%^s hesitates."), m_name);
315         else
316             msg_format(_("%^sはくしゃくしゃになった。", "%^s crumples."), m_name);
317         return;
318     }
319
320     if (angband_strchr("JMR", r_ptr->d_char) || !isalpha(r_ptr->d_char)) {
321         if (percentage > 95)
322             msg_format(_("%^sはほとんど気にとめていない。", "%^s barely notices."), m_name);
323         else if (percentage > 75)
324             msg_format(_("%^sはシーッと鳴いた。", "%^s hisses."), m_name);
325         else if (percentage > 50)
326             msg_format(_("%^sは怒って頭を上げた。", "%^s rears up in anger."), m_name);
327         else if (percentage > 35)
328             msg_format(_("%^sは猛然と威嚇した。", "%^s hisses furiously."), m_name);
329         else if (percentage > 20)
330             msg_format(_("%^sは身もだえした。", "%^s writhes about."), m_name);
331         else if (percentage > 10)
332             msg_format(_("%^sは苦痛で身もだえした。", "%^s writhes in agony."), m_name);
333         else
334             msg_format(_("%^sはぐにゃぐにゃと痙攣した。", "%^s jerks limply."), m_name);
335         return;
336     }
337
338     if (angband_strchr("f", r_ptr->d_char)) {
339         if (percentage > 95)
340             msg_format(_("%sは攻撃に肩をすくめた。", "%^s shrugs off the attack."), m_name);
341         else if (percentage > 75)
342             msg_format(_("%^sは吠えた。", "%^s roars."), m_name);
343         else if (percentage > 50)
344             msg_format(_("%^sは怒って吠えた。", "%^s growls angrily."), m_name);
345         else if (percentage > 35)
346             msg_format(_("%^sは痛みでシーッと鳴いた。", "%^s hisses with pain."), m_name);
347         else if (percentage > 20)
348             msg_format(_("%^sは痛みで弱々しく鳴いた。", "%^s mewls in pain."), m_name);
349         else if (percentage > 10)
350             msg_format(_("%^sは苦痛にうめいた。", "%^s hisses in agony."), m_name);
351         else
352             msg_format(_("%sは哀れな鳴き声を出した。", "%^s mewls pitifully."), m_name);
353         return;
354     }
355
356     if (angband_strchr("acFIKS", r_ptr->d_char)) {
357         if (percentage > 95)
358             msg_format(_("%sは攻撃を気にとめていない。", "%^s ignores the attack."), m_name);
359         else if (percentage > 75)
360             msg_format(_("%^sはキーキー鳴いた。", "%^s chitters."), m_name);
361         else if (percentage > 50)
362             msg_format(_("%^sはヨロヨロ逃げ回った。", "%^s scuttles about."), m_name);
363         else if (percentage > 35)
364             msg_format(_("%^sはうるさく鳴いた。", "%^s twitters."), m_name);
365         else if (percentage > 20)
366             msg_format(_("%^sは痛みに痙攣した。", "%^s jerks in pain."), m_name);
367         else if (percentage > 10)
368             msg_format(_("%^sは苦痛で痙攣した。", "%^s jerks in agony."), m_name);
369         else
370             msg_format(_("%^sはピクピクひきつった。", "%^s twitches."), m_name);
371         return;
372     }
373
374     if (angband_strchr("B", r_ptr->d_char)) {
375         if (percentage > 95)
376             msg_format(_("%^sはさえずった。", "%^s chirps."), m_name);
377         else if (percentage > 75)
378             msg_format(_("%^sはピーピー鳴いた。", "%^s twitters."), m_name);
379         else if (percentage > 50)
380             msg_format(_("%^sはギャーギャー鳴いた。", "%^s squawks."), m_name);
381         else if (percentage > 35)
382             msg_format(_("%^sはギャーギャー鳴きわめいた。", "%^s chatters."), m_name);
383         else if (percentage > 20)
384             msg_format(_("%^sは苦しんだ。", "%^s jeers."), m_name);
385         else if (percentage > 10)
386             msg_format(_("%^sはのたうち回った。", "%^s flutters about."), m_name);
387         else
388             msg_format(_("%^sはキーキーと鳴き叫んだ。", "%^s squeaks."), m_name);
389         return;
390     }
391
392     if (angband_strchr("duDLUW", r_ptr->d_char)) {
393         if (percentage > 95)
394             msg_format(_("%sは攻撃を気にとめていない。", "%^s ignores the attack."), m_name);
395         else if (percentage > 75)
396             msg_format(_("%^sはしり込みした。", "%^s flinches."), m_name);
397         else if (percentage > 50)
398             msg_format(_("%^sは痛みでシーッと鳴いた。", "%^s hisses in pain."), m_name);
399         else if (percentage > 35)
400             msg_format(_("%^sは痛みでうなった。", "%^s snarls with pain."), m_name);
401         else if (percentage > 20)
402             msg_format(_("%^sは痛みに吠えた。", "%^s roars with pain."), m_name);
403         else if (percentage > 10)
404             msg_format(_("%^sは苦しげに叫んだ。", "%^s gasps."), m_name);
405         else
406             msg_format(_("%^sは弱々しくうなった。", "%^s snarls feebly."), m_name);
407         return;
408     }
409
410     if (angband_strchr("s", r_ptr->d_char)) {
411         if (percentage > 95)
412             msg_format(_("%sは攻撃を気にとめていない。", "%^s ignores the attack."), m_name);
413         else if (percentage > 75)
414             msg_format(_("%sは攻撃に肩をすくめた。", "%^s shrugs off the attack."), m_name);
415         else if (percentage > 50)
416             msg_format(_("%^sはカタカタと笑った。", "%^s rattles."), m_name);
417         else if (percentage > 35)
418             msg_format(_("%^sはよろめいた。", "%^s stumbles."), m_name);
419         else if (percentage > 20)
420             msg_format(_("%^sはカタカタ言った。", "%^s rattles."), m_name);
421         else if (percentage > 10)
422             msg_format(_("%^sはよろめいた。", "%^s staggers."), m_name);
423         else
424             msg_format(_("%^sはガタガタ言った。", "%^s clatters."), m_name);
425         return;
426     }
427
428     if (angband_strchr("z", r_ptr->d_char)) {
429         if (percentage > 95)
430             msg_format(_("%sは攻撃を気にとめていない。", "%^s ignores the attack."), m_name);
431         else if (percentage > 75)
432             msg_format(_("%sは攻撃に肩をすくめた。", "%^s shrugs off the attack."), m_name);
433         else if (percentage > 50)
434             msg_format(_("%^sはうめいた。", "%^s groans."), m_name);
435         else if (percentage > 35)
436             msg_format(_("%sは苦しげにうめいた。", "%^s moans."), m_name);
437         else if (percentage > 20)
438             msg_format(_("%^sは躊躇した。", "%^s hesitates."), m_name);
439         else if (percentage > 10)
440             msg_format(_("%^sはうなった。", "%^s grunts."), m_name);
441         else
442             msg_format(_("%^sはよろめいた。", "%^s staggers."), m_name);
443         return;
444     }
445
446     if (angband_strchr("G", r_ptr->d_char)) {
447         if (percentage > 95)
448             msg_format(_("%sは攻撃を気にとめていない。", "%^s ignores the attack."), m_name);
449         else if (percentage > 75)
450             msg_format(_("%sは攻撃に肩をすくめた。", "%^s shrugs off the attack."), m_name);
451         else if (percentage > 50)
452             msg_format(_("%sはうめいた。", "%^s moans."), m_name);
453         else if (percentage > 35)
454             msg_format(_("%^sは泣きわめいた。", "%^s wails."), m_name);
455         else if (percentage > 20)
456             msg_format(_("%^sは吠えた。", "%^s howls."), m_name);
457         else if (percentage > 10)
458             msg_format(_("%sは弱々しくうめいた。", "%^s moans softly."), m_name);
459         else
460             msg_format(_("%^sはかすかにうめいた。", "%^s sighs."), m_name);
461         return;
462     }
463
464     if (angband_strchr("CZ", r_ptr->d_char)) {
465         if (percentage > 95)
466             msg_format(_("%^sは攻撃に肩をすくめた。", "%^s shrugs off the attack."), m_name);
467         else if (percentage > 75)
468             msg_format(_("%^sは痛みでうなった。", "%^s snarls with pain."), m_name);
469         else if (percentage > 50)
470             msg_format(_("%^sは痛みでキャンキャン吠えた。", "%^s yelps in pain."), m_name);
471         else if (percentage > 35)
472             msg_format(_("%^sは痛みで鳴きわめいた。", "%^s howls in pain."), m_name);
473         else if (percentage > 20)
474             msg_format(_("%^sは苦痛のあまり鳴きわめいた。", "%^s howls in agony."), m_name);
475         else if (percentage > 10)
476             msg_format(_("%^sは苦痛でもだえ苦しんだ。", "%^s writhes in agony."), m_name);
477         else
478             msg_format(_("%^sは弱々しく吠えた。", "%^s yelps feebly."), m_name);
479         return;
480     }
481
482     if (angband_strchr("Xbilqrt", r_ptr->d_char)) {
483         if (percentage > 95)
484             msg_format(_("%^sは攻撃を気にとめていない。", "%^s ignores the attack."), m_name);
485         else if (percentage > 75)
486             msg_format(_("%^sは痛みでうなった。", "%^s grunts with pain."), m_name);
487         else if (percentage > 50)
488             msg_format(_("%^sは痛みで叫んだ。", "%^s squeals in pain."), m_name);
489         else if (percentage > 35)
490             msg_format(_("%^sは痛みで絶叫した。", "%^s shrieks in pain."), m_name);
491         else if (percentage > 20)
492             msg_format(_("%^sは苦痛のあまり絶叫した。", "%^s shrieks in agony."), m_name);
493         else if (percentage > 10)
494             msg_format(_("%^sは苦痛でもだえ苦しんだ。", "%^s writhes in agony."), m_name);
495         else
496             msg_format(_("%^sは弱々しく叫んだ。", "%^s cries out feebly."), m_name);
497         return;
498     }
499
500     if (percentage > 95)
501         msg_format(_("%^sは攻撃に肩をすくめた。", "%^s shrugs off the attack."), m_name);
502     else if (percentage > 75)
503         msg_format(_("%^sは痛みでうなった。", "%^s grunts with pain."), m_name);
504     else if (percentage > 50)
505         msg_format(_("%^sは痛みで叫んだ。", "%^s cries out in pain."), m_name);
506     else if (percentage > 35)
507         msg_format(_("%^sは痛みで絶叫した。", "%^s screams in pain."), m_name);
508     else if (percentage > 20)
509         msg_format(_("%^sは苦痛のあまり絶叫した。", "%^s screams in agony."), m_name);
510     else if (percentage > 10)
511         msg_format(_("%^sは苦痛でもだえ苦しんだ。", "%^s writhes in agony."), m_name);
512     else
513         msg_format(_("%^sは弱々しく叫んだ。", "%^s cries out feebly."), m_name);
514 }