OSDN Git Service

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