OSDN Git Service

[Refactor] #37353 monster_is_powerful() と monster_level_idx() を monster-status.c...
[hengband/hengband.git] / src / monster-status.c
1 #include "angband.h"
2 #include "floor.h"
3 #include "grid.h"
4 #include "monster.h"
5 #include "monster-status.h"
6 #include "monster-spell.h"
7 #include "spells-summon.h"
8 #include "monsterrace-hook.h"
9 #include "object-curse.h"
10 #include "artifact.h"
11 #include "avatar.h"
12
13
14 /*!
15 * @brief モンスターIDからPOWERFULフラグの有無を取得する /
16 * @param m_idx モンスターID
17 * @return POWERFULフラグがあればTRUE、なければFALSEを返す。
18 */
19 bool monster_is_powerful(MONSTER_IDX m_idx)
20 {
21         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
22         monster_race *r_ptr = &r_info[m_ptr->r_idx];
23         bool powerful = r_ptr->flags2 & RF2_POWERFUL ? TRUE : FALSE;
24         return powerful;
25 }
26
27 /*!
28 * @brief モンスターIDからモンスターのレベルを取得する(ただし最低1を保証する) /
29 * @param m_idx モンスターID
30 * @return モンスターのレベル
31 */
32 DEPTH monster_level_idx(MONSTER_IDX m_idx)
33 {
34         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
35         monster_race *r_ptr = &r_info[m_ptr->r_idx];
36         DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
37         return rlev;
38 }
39
40 /*!
41  * @brief モンスターに与えたダメージの修正処理 /
42  * Modify the physical damage done to the monster.
43  * @param m_ptr ダメージを受けるモンスターの構造体参照ポインタ
44  * @param dam ダメージ基本値
45  * @param is_psy_spear 攻撃手段が光の剣ならばTRUE
46  * @return 修正を行った結果のダメージ量
47  * @details
48  * <pre>
49  * (for example when it's invulnerable or shielded)
50  * ToDo: Accept a damage-type to calculate the modified damage from
51  * things like fire, frost, lightning, poison, ... attacks.
52  * "type" is not yet used and should be 0.
53  * </pre>
54  */
55 HIT_POINT mon_damage_mod(monster_type *m_ptr, HIT_POINT dam, bool is_psy_spear)
56 {
57         monster_race *r_ptr = &r_info[m_ptr->r_idx];
58
59         if ((r_ptr->flagsr & RFR_RES_ALL) && dam > 0)
60         {
61                 dam /= 100;
62                 if ((dam == 0) && one_in_(3)) dam = 1;
63         }
64
65         if (MON_INVULNER(m_ptr))
66         {
67                 if (is_psy_spear)
68                 {
69                         if (!p_ptr->blind && is_seen(m_ptr))
70                         {
71                                 msg_print(_("バリアを切り裂いた!", "The barrier is penetrated!"));
72                         }
73                 }
74                 else if (!one_in_(PENETRATE_INVULNERABILITY))
75                 {
76                         return (0);
77                 }
78         }
79         return (dam);
80 }
81
82
83
84 /*!
85  * @brief モンスターに与えたダメージを元に経験値を加算する /
86  * Calculate experience point to be get
87  * @param dam 与えたダメージ量
88  * @param m_ptr ダメージを与えたモンスターの構造体参照ポインタ
89  * @return なし
90  * @details
91  * <pre>
92  * Even the 64 bit operation is not big enough to avoid overflaw
93  * unless we carefully choose orders of multiplication and division.
94  * Get the coefficient first, and multiply (potentially huge) base
95  * experience point of a monster later.
96  * </pre>
97  */
98 static void get_exp_from_mon(HIT_POINT dam, monster_type *m_ptr)
99 {
100         monster_race *r_ptr = &r_info[m_ptr->r_idx];
101
102         s32b new_exp;
103         u32b new_exp_frac;
104         s32b div_h;
105         u32b div_l;
106
107         if (!monster_is_valid(m_ptr)) return;
108         if (is_pet(m_ptr) || p_ptr->inside_battle) return;
109
110         /*
111          * - Ratio of monster's level to player's level effects
112          * - Varying speed effects
113          * - Get a fraction in proportion of damage point
114          */
115         new_exp = r_ptr->level * SPEED_TO_ENERGY(m_ptr->mspeed) * dam;
116         new_exp_frac = 0;
117         div_h = 0L;
118         div_l = (p_ptr->max_plv + 2) * SPEED_TO_ENERGY(r_ptr->speed);
119
120         /* Use (average maxhp * 2) as a denominator */
121         if (!(r_ptr->flags1 & RF1_FORCE_MAXHP))
122                 s64b_mul(&div_h, &div_l, 0, r_ptr->hdice * (ironman_nightmare ? 2 : 1) * (r_ptr->hside + 1));
123         else
124                 s64b_mul(&div_h, &div_l, 0, r_ptr->hdice * (ironman_nightmare ? 2 : 1) * r_ptr->hside * 2);
125
126         /* Special penalty in the wilderness */
127         if (!current_floor_ptr->dun_level && (!(r_ptr->flags8 & RF8_WILD_ONLY) || !(r_ptr->flags1 & RF1_UNIQUE)))
128                 s64b_mul(&div_h, &div_l, 0, 5);
129
130         /* Do division first to prevent overflaw */
131         s64b_div(&new_exp, &new_exp_frac, div_h, div_l);
132
133         /* Special penalty for mutiply-monster */
134         if ((r_ptr->flags2 & RF2_MULTIPLY) || (m_ptr->r_idx == MON_DAWN))
135         {
136                 int monnum_penarty = r_ptr->r_akills / 400;
137                 if (monnum_penarty > 8) monnum_penarty = 8;
138
139                 while (monnum_penarty--)
140                 {
141                         /* Divide by 4 */
142                         s64b_RSHIFT(new_exp, new_exp_frac, 2);
143                 }
144         }
145
146         /* Special penalty for rest_and_shoot exp scum */
147         if ((m_ptr->dealt_damage > m_ptr->max_maxhp) && (m_ptr->hp >= 0))
148         {
149                 int over_damage = m_ptr->dealt_damage / m_ptr->max_maxhp;
150                 if (over_damage > 32) over_damage = 32;
151
152                 while (over_damage--)
153                 {
154                         /* 9/10 for once */
155                         s64b_mul(&new_exp, &new_exp_frac, 0, 9);
156                         s64b_div(&new_exp, &new_exp_frac, 0, 10);
157                 }
158         }
159
160         /* Finally multiply base experience point of the monster */
161         s64b_mul(&new_exp, &new_exp_frac, 0, r_ptr->mexp);
162
163         /* Gain experience */
164         gain_exp_64(new_exp, new_exp_frac);
165 }
166
167
168
169 /*!
170 * @brief モンスターの時限ステータスを取得する
171 * @return m_idx モンスターの参照ID
172 * @return mproc_type モンスターの時限ステータスID
173 * @return 残りターン値
174 */
175 int get_mproc_idx(MONSTER_IDX m_idx, int mproc_type)
176 {
177         s16b *cur_mproc_list = current_floor_ptr->mproc_list[mproc_type];
178         int i;
179
180         for (i = current_floor_ptr->mproc_max[mproc_type] - 1; i >= 0; i--)
181         {
182                 if (cur_mproc_list[i] == m_idx) return i;
183         }
184
185         return -1;
186 }
187
188 /*!
189 * @brief モンスターの時限ステータスリストを追加する
190 * @return m_idx モンスターの参照ID
191 * @return mproc_type 追加したいモンスターの時限ステータスID
192 * @return なし
193 */
194 static void mproc_add(MONSTER_IDX m_idx, int mproc_type)
195 {
196         if (current_floor_ptr->mproc_max[mproc_type] < current_floor_ptr->max_m_idx) current_floor_ptr->mproc_list[mproc_type][current_floor_ptr->mproc_max[mproc_type]++] = (s16b)m_idx;
197 }
198
199
200 /*!
201 * @brief モンスターの時限ステータスリストを削除
202 * @return m_idx モンスターの参照ID
203 * @return mproc_type 削除したいモンスターの時限ステータスID
204 * @return なし
205 */
206 static void mproc_remove(MONSTER_IDX m_idx, int mproc_type)
207 {
208         int mproc_idx = get_mproc_idx(m_idx, mproc_type);
209         if (mproc_idx >= 0) current_floor_ptr->mproc_list[mproc_type][mproc_idx] = current_floor_ptr->mproc_list[mproc_type][--current_floor_ptr->mproc_max[mproc_type]];
210 }
211
212
213 /*!
214 * @brief モンスターの時限ステータスリストを初期化する / Initialize monster process
215 * @return なし
216 */
217 void mproc_init(void)
218 {
219         monster_type *m_ptr;
220         MONSTER_IDX i;
221         int cmi;
222
223         /* Reset "current_floor_ptr->mproc_max[]" */
224         for (cmi = 0; cmi < MAX_MTIMED; cmi++) current_floor_ptr->mproc_max[cmi] = 0;
225
226         /* Process the monsters (backwards) */
227         for (i = m_max - 1; i >= 1; i--)
228         {
229                 /* Access the monster */
230                 m_ptr = &current_floor_ptr->m_list[i];
231
232                 /* Ignore "dead" monsters */
233                 if (!monster_is_valid(m_ptr)) continue;
234
235                 for (cmi = 0; cmi < MAX_MTIMED; cmi++)
236                 {
237                         if (m_ptr->mtimed[cmi]) mproc_add(i, cmi);
238                 }
239         }
240 }
241
242
243 /*!
244 * @brief モンスターの睡眠状態値をセットする。0で起きる。 /
245 * Set "m_ptr->mtimed[MTIMED_CSLEEP]", notice observable changes
246 * @param m_idx モンスター参照ID
247 * @param v セットする値
248 * @return 別途更新処理が必要な場合TRUEを返す
249 */
250 bool set_monster_csleep(MONSTER_IDX m_idx, int v)
251 {
252         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
253         bool notice = FALSE;
254         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
255
256         /* Open */
257         if (v)
258         {
259                 if (!MON_CSLEEP(m_ptr))
260                 {
261                         mproc_add(m_idx, MTIMED_CSLEEP);
262                         notice = TRUE;
263                 }
264         }
265
266         /* Shut */
267         else
268         {
269                 if (MON_CSLEEP(m_ptr))
270                 {
271                         mproc_remove(m_idx, MTIMED_CSLEEP);
272                         notice = TRUE;
273                 }
274         }
275
276         /* Use the value */
277         m_ptr->mtimed[MTIMED_CSLEEP] = (s16b)v;
278
279         if (!notice) return FALSE;
280
281         if (m_ptr->ml)
282         {
283                 /* Update health bar as needed */
284                 if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
285                 if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
286         }
287
288         if (r_info[m_ptr->r_idx].flags7 & RF7_HAS_LD_MASK) p_ptr->update |= (PU_MON_LITE);
289
290         return TRUE;
291 }
292
293
294 /*!
295 * @brief モンスターの加速状態値をセット /
296 * Set "m_ptr->mtimed[MTIMED_FAST]", notice observable changes
297 * @param m_idx モンスター参照ID
298 * @param v セットする値
299 * @return 別途更新処理が必要な場合TRUEを返す
300 */
301 bool set_monster_fast(MONSTER_IDX m_idx, int v)
302 {
303         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
304         bool notice = FALSE;
305         v = (v > 200) ? 200 : (v < 0) ? 0 : v;
306
307         /* Open */
308         if (v)
309         {
310                 if (!MON_FAST(m_ptr))
311                 {
312                         mproc_add(m_idx, MTIMED_FAST);
313                         notice = TRUE;
314                 }
315         }
316
317         /* Shut */
318         else
319         {
320                 if (MON_FAST(m_ptr))
321                 {
322                         mproc_remove(m_idx, MTIMED_FAST);
323                         notice = TRUE;
324                 }
325         }
326
327         /* Use the value */
328         m_ptr->mtimed[MTIMED_FAST] = (s16b)v;
329
330         if (!notice) return FALSE;
331
332         if ((p_ptr->riding == m_idx) && !p_ptr->leaving) p_ptr->update |= (PU_BONUS);
333
334         return TRUE;
335 }
336
337
338 /*
339 * Set "m_ptr->mtimed[MTIMED_SLOW]", notice observable changes
340 */
341 bool set_monster_slow(MONSTER_IDX m_idx, int v)
342 {
343         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
344         bool notice = FALSE;
345         v = (v > 200) ? 200 : (v < 0) ? 0 : v;
346
347         /* Open */
348         if (v)
349         {
350                 if (!MON_SLOW(m_ptr))
351                 {
352                         mproc_add(m_idx, MTIMED_SLOW);
353                         notice = TRUE;
354                 }
355         }
356
357         /* Shut */
358         else
359         {
360                 if (MON_SLOW(m_ptr))
361                 {
362                         mproc_remove(m_idx, MTIMED_SLOW);
363                         notice = TRUE;
364                 }
365         }
366
367         /* Use the value */
368         m_ptr->mtimed[MTIMED_SLOW] = (s16b)v;
369
370         if (!notice) return FALSE;
371
372         if ((p_ptr->riding == m_idx) && !p_ptr->leaving) p_ptr->update |= (PU_BONUS);
373
374         return TRUE;
375 }
376
377
378 /*!
379 * @brief モンスターの朦朧状態値をセット /
380 * Set "m_ptr->mtimed[MTIMED_STUNNED]", notice observable changes
381 * @param m_idx モンスター参照ID
382 * @param v セットする値
383 * @return 別途更新処理が必要な場合TRUEを返す
384 */
385 bool set_monster_stunned(MONSTER_IDX m_idx, int v)
386 {
387         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
388         bool notice = FALSE;
389         v = (v > 200) ? 200 : (v < 0) ? 0 : v;
390
391         /* Open */
392         if (v)
393         {
394                 if (!MON_STUNNED(m_ptr))
395                 {
396                         mproc_add(m_idx, MTIMED_STUNNED);
397                         notice = TRUE;
398                 }
399         }
400
401         /* Shut */
402         else
403         {
404                 if (MON_STUNNED(m_ptr))
405                 {
406                         mproc_remove(m_idx, MTIMED_STUNNED);
407                         notice = TRUE;
408                 }
409         }
410
411         /* Use the value */
412         m_ptr->mtimed[MTIMED_STUNNED] = (s16b)v;
413
414         return notice;
415 }
416
417
418 /*!
419 * @brief モンスターの混乱状態値をセット /
420 * Set "m_ptr->mtimed[MTIMED_CONFUSED]", notice observable changes
421 * @param m_idx モンスター参照ID
422 * @param v セットする値
423 * @return 別途更新処理が必要な場合TRUEを返す
424 */
425 bool set_monster_confused(MONSTER_IDX m_idx, int v)
426 {
427         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
428         bool notice = FALSE;
429         v = (v > 200) ? 200 : (v < 0) ? 0 : v;
430
431         /* Open */
432         if (v)
433         {
434                 if (!MON_CONFUSED(m_ptr))
435                 {
436                         mproc_add(m_idx, MTIMED_CONFUSED);
437                         notice = TRUE;
438                 }
439         }
440
441         /* Shut */
442         else
443         {
444                 if (MON_CONFUSED(m_ptr))
445                 {
446                         mproc_remove(m_idx, MTIMED_CONFUSED);
447                         notice = TRUE;
448                 }
449         }
450
451         /* Use the value */
452         m_ptr->mtimed[MTIMED_CONFUSED] = (s16b)v;
453
454         return notice;
455 }
456
457
458 /*!
459 * @brief モンスターの恐慌状態値をセット /
460 * Set "m_ptr->mtimed[MTIMED_MONFEAR]", notice observable changes
461 * @param m_idx モンスター参照ID
462 * @param v セットする値
463 * @return 別途更新処理が必要な場合TRUEを返す
464 */
465 bool set_monster_monfear(MONSTER_IDX m_idx, int v)
466 {
467         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
468         bool notice = FALSE;
469         v = (v > 200) ? 200 : (v < 0) ? 0 : v;
470
471         /* Open */
472         if (v)
473         {
474                 if (!MON_MONFEAR(m_ptr))
475                 {
476                         mproc_add(m_idx, MTIMED_MONFEAR);
477                         notice = TRUE;
478                 }
479         }
480
481         /* Shut */
482         else
483         {
484                 if (MON_MONFEAR(m_ptr))
485                 {
486                         mproc_remove(m_idx, MTIMED_MONFEAR);
487                         notice = TRUE;
488                 }
489         }
490
491         /* Use the value */
492         m_ptr->mtimed[MTIMED_MONFEAR] = (s16b)v;
493
494         if (!notice) return FALSE;
495
496         if (m_ptr->ml)
497         {
498                 /* Update health bar as needed */
499                 if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
500                 if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
501         }
502
503         return TRUE;
504 }
505
506
507 /*!
508 * @brief モンスターの無敵状態値をセット /
509 * Set "m_ptr->mtimed[MTIMED_INVULNER]", notice observable changes
510 * @param m_idx モンスター参照ID
511 * @param v セットする値
512 * @param energy_need TRUEならば無敵解除時に行動ターン消費を行う
513 * @return 別途更新処理が必要な場合TRUEを返す
514 */
515 bool set_monster_invulner(MONSTER_IDX m_idx, int v, bool energy_need)
516 {
517         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
518         bool notice = FALSE;
519         v = (v > 200) ? 200 : (v < 0) ? 0 : v;
520
521         /* Open */
522         if (v)
523         {
524                 if (!MON_INVULNER(m_ptr))
525                 {
526                         mproc_add(m_idx, MTIMED_INVULNER);
527                         notice = TRUE;
528                 }
529         }
530
531         /* Shut */
532         else
533         {
534                 if (MON_INVULNER(m_ptr))
535                 {
536                         mproc_remove(m_idx, MTIMED_INVULNER);
537                         if (energy_need && !p_ptr->wild_mode) m_ptr->energy_need += ENERGY_NEED();
538                         notice = TRUE;
539                 }
540         }
541
542         /* Use the value */
543         m_ptr->mtimed[MTIMED_INVULNER] = (s16b)v;
544
545         if (!notice) return FALSE;
546
547         if (m_ptr->ml)
548         {
549                 /* Update health bar as needed */
550                 if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
551                 if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
552         }
553
554         return TRUE;
555 }
556
557
558 static u32b csleep_noise;
559
560 /*!
561 * @brief モンスターの各種状態値を時間経過により更新するサブルーチン
562 * @param m_idx モンスター参照ID
563 * @param mtimed_idx 更新するモンスターの時限ステータスID
564 * @return なし
565 */
566 static void process_monsters_mtimed_aux(MONSTER_IDX m_idx, int mtimed_idx)
567 {
568         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
569
570         switch (mtimed_idx)
571         {
572         case MTIMED_CSLEEP:
573         {
574                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
575
576                 /* Assume does not wake up */
577                 bool test = FALSE;
578
579                 /* Hack -- Require proximity */
580                 if (m_ptr->cdis < AAF_LIMIT)
581                 {
582                         /* Handle "sensing radius" */
583                         if (m_ptr->cdis <= (is_pet(m_ptr) ? ((r_ptr->aaf > MAX_SIGHT) ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf))
584                         {
585                                 /* We may wake up */
586                                 test = TRUE;
587                         }
588
589                         /* Handle "sight" and "aggravation" */
590                         else if ((m_ptr->cdis <= MAX_SIGHT) && (player_has_los_bold(m_ptr->fy, m_ptr->fx)))
591                         {
592                                 /* We may wake up */
593                                 test = TRUE;
594                         }
595                 }
596
597                 if (test)
598                 {
599                         u32b notice = randint0(1024);
600
601                         /* Nightmare monsters are more alert */
602                         if (ironman_nightmare) notice /= 2;
603
604                         /* Hack -- See if monster "notices" player */
605                         if ((notice * notice * notice) <= csleep_noise)
606                         {
607                                 /* Hack -- amount of "waking" */
608                                 /* Wake up faster near the player */
609                                 int d = (m_ptr->cdis < AAF_LIMIT / 2) ? (AAF_LIMIT / m_ptr->cdis) : 1;
610
611                                 /* Hack -- amount of "waking" is affected by speed of player */
612                                 d = (d * SPEED_TO_ENERGY(p_ptr->pspeed)) / 10;
613                                 if (d < 0) d = 1;
614
615                                 /* Monster wakes up "a little bit" */
616
617                                 /* Still asleep */
618                                 if (!set_monster_csleep(m_idx, MON_CSLEEP(m_ptr) - d))
619                                 {
620                                         /* Notice the "not waking up" */
621                                         if (is_original_ap_and_seen(m_ptr))
622                                         {
623                                                 /* Hack -- Count the ignores */
624                                                 if (r_ptr->r_ignore < MAX_UCHAR) r_ptr->r_ignore++;
625                                         }
626                                 }
627
628                                 /* Just woke up */
629                                 else
630                                 {
631                                         /* Notice the "waking up" */
632                                         if (m_ptr->ml)
633                                         {
634                                                 GAME_TEXT m_name[MAX_NLEN];
635                                                 monster_desc(m_name, m_ptr, 0);
636                                                 msg_format(_("%^sが目を覚ました。", "%^s wakes up."), m_name);
637                                         }
638
639                                         if (is_original_ap_and_seen(m_ptr))
640                                         {
641                                                 /* Hack -- Count the wakings */
642                                                 if (r_ptr->r_wake < MAX_UCHAR) r_ptr->r_wake++;
643                                         }
644                                 }
645                         }
646                 }
647                 break;
648         }
649
650         case MTIMED_FAST:
651                 /* Reduce by one, note if expires */
652                 if (set_monster_fast(m_idx, MON_FAST(m_ptr) - 1))
653                 {
654                         if (is_seen(m_ptr))
655                         {
656                                 GAME_TEXT m_name[MAX_NLEN];
657                                 monster_desc(m_name, m_ptr, 0);
658                                 msg_format(_("%^sはもう加速されていない。", "%^s is no longer fast."), m_name);
659                         }
660                 }
661                 break;
662
663         case MTIMED_SLOW:
664                 /* Reduce by one, note if expires */
665                 if (set_monster_slow(m_idx, MON_SLOW(m_ptr) - 1))
666                 {
667                         if (is_seen(m_ptr))
668                         {
669                                 GAME_TEXT m_name[MAX_NLEN];
670                                 monster_desc(m_name, m_ptr, 0);
671                                 msg_format(_("%^sはもう減速されていない。", "%^s is no longer slow."), m_name);
672                         }
673                 }
674                 break;
675
676         case MTIMED_STUNNED:
677         {
678                 int rlev = r_info[m_ptr->r_idx].level;
679
680                 /* Recover from stun */
681                 if (set_monster_stunned(m_idx, (randint0(10000) <= rlev * rlev) ? 0 : (MON_STUNNED(m_ptr) - 1)))
682                 {
683                         /* Message if visible */
684                         if (is_seen(m_ptr))
685                         {
686                                 GAME_TEXT m_name[MAX_NLEN];
687                                 monster_desc(m_name, m_ptr, 0);
688                                 msg_format(_("%^sは朦朧状態から立ち直った。", "%^s is no longer stunned."), m_name);
689                         }
690                 }
691                 break;
692         }
693
694         case MTIMED_CONFUSED:
695                 /* Reduce the confusion */
696                 if (set_monster_confused(m_idx, MON_CONFUSED(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1)))
697                 {
698                         /* Message if visible */
699                         if (is_seen(m_ptr))
700                         {
701                                 GAME_TEXT m_name[MAX_NLEN];
702                                 monster_desc(m_name, m_ptr, 0);
703                                 msg_format(_("%^sは混乱から立ち直った。", "%^s is no longer confused."), m_name);
704                         }
705                 }
706                 break;
707
708         case MTIMED_MONFEAR:
709                 /* Reduce the fear */
710                 if (set_monster_monfear(m_idx, MON_MONFEAR(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1)))
711                 {
712                         /* Visual note */
713                         if (is_seen(m_ptr))
714                         {
715                                 GAME_TEXT m_name[MAX_NLEN];
716 #ifndef JP
717                                 char m_poss[80];
718
719                                 /* Acquire the monster possessive */
720                                 monster_desc(m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
721 #endif
722                                 monster_desc(m_name, m_ptr, 0);
723 #ifdef JP
724                                 msg_format("%^sは勇気を取り戻した。", m_name);
725 #else
726                                 msg_format("%^s recovers %s courage.", m_name, m_poss);
727 #endif
728                         }
729                 }
730                 break;
731
732         case MTIMED_INVULNER:
733                 /* Reduce by one, note if expires */
734                 if (set_monster_invulner(m_idx, MON_INVULNER(m_ptr) - 1, TRUE))
735                 {
736                         if (is_seen(m_ptr))
737                         {
738                                 GAME_TEXT m_name[MAX_NLEN];
739                                 monster_desc(m_name, m_ptr, 0);
740                                 msg_format(_("%^sはもう無敵でない。", "%^s is no longer invulnerable."), m_name);
741                         }
742                 }
743                 break;
744         }
745 }
746
747
748 /*!
749 * @brief 全モンスターの各種状態値を時間経過により更新するメインルーチン
750 * @param mtimed_idx 更新するモンスターの時限ステータスID
751 * @return なし
752 * @details
753 * Process the counters of monsters (once per 10 game turns)\n
754 * These functions are to process monsters' counters same as player's.
755 */
756 void process_monsters_mtimed(int mtimed_idx)
757 {
758         int  i;
759         s16b *cur_mproc_list = current_floor_ptr->mproc_list[mtimed_idx];
760
761         /* Hack -- calculate the "player noise" */
762         if (mtimed_idx == MTIMED_CSLEEP) csleep_noise = (1L << (30 - p_ptr->skill_stl));
763
764         /* Process the monsters (backwards) */
765         for (i = current_floor_ptr->mproc_max[mtimed_idx] - 1; i >= 0; i--)
766         {
767                 /* Access the monster */
768                 process_monsters_mtimed_aux(cur_mproc_list[i], mtimed_idx);
769         }
770 }
771
772 /*!
773 * @brief モンスターへの魔力消去処理
774 * @param m_idx 魔力消去を受けるモンスターの参照ID
775 * @return なし
776 */
777 void dispel_monster_status(MONSTER_IDX m_idx)
778 {
779         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
780         GAME_TEXT m_name[MAX_NLEN];
781
782         monster_desc(m_name, m_ptr, 0);
783         if (set_monster_invulner(m_idx, 0, TRUE))
784         {
785                 if (m_ptr->ml) msg_format(_("%sはもう無敵ではない。", "%^s is no longer invulnerable."), m_name);
786         }
787         if (set_monster_fast(m_idx, 0))
788         {
789                 if (m_ptr->ml) msg_format(_("%sはもう加速されていない。", "%^s is no longer fast."), m_name);
790         }
791         if (set_monster_slow(m_idx, 0))
792         {
793                 if (m_ptr->ml) msg_format(_("%sはもう減速されていない。", "%^s is no longer slow."), m_name);
794         }
795 }
796
797 /*!
798 * @brief モンスターの時間停止処理
799 * @param num 時間停止を行った敵が行動できる回数
800 * @param who 時間停止処理の主体ID
801 * @param vs_player TRUEならば時間停止開始処理を行う
802 * @return 時間停止が行われている状態ならばTRUEを返す
803 */
804 bool process_the_world(int num, MONSTER_IDX who, bool vs_player)
805 {
806         monster_type *m_ptr = &current_floor_ptr->m_list[hack_m_idx];  /* the world monster */
807
808         if (current_world_ptr->timewalk_m_idx) return (FALSE);
809
810         if (vs_player)
811         {
812                 GAME_TEXT m_name[MAX_NLEN];
813                 monster_desc(m_name, m_ptr, 0);
814
815                 if (who == 1)
816                         msg_format(_("「『ザ・ワールド』!時は止まった!」", "%s yells 'The World! Time has stopped!'"), m_name);
817                 else if (who == 3)
818                         msg_format(_("「時よ!」", "%s yells 'Time!'"), m_name);
819                 else msg_print("hek!");
820
821                 msg_print(NULL);
822         }
823
824         /* This monster cast spells */
825         current_world_ptr->timewalk_m_idx = hack_m_idx;
826
827         if (vs_player) do_cmd_redraw();
828
829         while (num--)
830         {
831                 if (!monster_is_valid(m_ptr)) break;
832                 process_monster(current_world_ptr->timewalk_m_idx);
833                 reset_target(m_ptr);
834                 handle_stuff();
835
836                 if (vs_player) Term_xtra(TERM_XTRA_DELAY, 500);
837         }
838
839         p_ptr->redraw |= (PR_MAP);
840         p_ptr->update |= (PU_MONSTERS);
841         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
842
843         current_world_ptr->timewalk_m_idx = 0;
844         if (vs_player || (player_has_los_bold(m_ptr->fy, m_ptr->fx) && projectable(p_ptr->y, p_ptr->x, m_ptr->fy, m_ptr->fx)))
845         {
846                 msg_print(_("「時は動きだす…」", "You feel time flowing around you once more."));
847                 msg_print(NULL);
848         }
849
850         handle_stuff();
851         return (TRUE);
852 }
853
854 /*!
855 * @brief モンスターの経験値取得処理
856 * @param m_idx 経験値を得るモンスターの参照ID
857 * @param s_idx 撃破されたモンスター種族の参照ID
858 * @return なし
859 */
860 void monster_gain_exp(MONSTER_IDX m_idx, MONRACE_IDX s_idx)
861 {
862         monster_type *m_ptr;
863         monster_race *r_ptr;
864         monster_race *s_ptr;
865         int new_exp;
866         if (m_idx <= 0 || s_idx <= 0) return;
867
868         m_ptr = &current_floor_ptr->m_list[m_idx];
869
870         if (!monster_is_valid(m_ptr)) return;
871
872         r_ptr = &r_info[m_ptr->r_idx];
873         s_ptr = &r_info[s_idx];
874
875         if (p_ptr->inside_battle) return;
876
877         if (!r_ptr->next_exp) return;
878
879         new_exp = s_ptr->mexp * s_ptr->level / (r_ptr->level + 2);
880         if (m_idx == p_ptr->riding) new_exp = (new_exp + 1) / 2;
881         if (!current_floor_ptr->dun_level) new_exp /= 5;
882         m_ptr->exp += new_exp;
883         if (m_ptr->mflag2 & MFLAG2_CHAMELEON) return;
884
885         if (m_ptr->exp >= r_ptr->next_exp)
886         {
887                 GAME_TEXT m_name[MAX_NLEN];
888                 int old_hp = m_ptr->hp;
889                 int old_maxhp = m_ptr->max_maxhp;
890                 int old_r_idx = m_ptr->r_idx;
891                 byte old_sub_align = m_ptr->sub_align;
892
893                 /* Hack -- Reduce the racial counter of previous monster */
894                 real_r_ptr(m_ptr)->cur_num--;
895
896                 monster_desc(m_name, m_ptr, 0);
897                 m_ptr->r_idx = r_ptr->next_r_idx;
898
899                 /* Count the monsters on the level */
900                 real_r_ptr(m_ptr)->cur_num++;
901
902                 m_ptr->ap_r_idx = m_ptr->r_idx;
903                 r_ptr = &r_info[m_ptr->r_idx];
904
905                 if (r_ptr->flags1 & RF1_FORCE_MAXHP)
906                 {
907                         m_ptr->max_maxhp = maxroll(r_ptr->hdice, r_ptr->hside);
908                 }
909                 else
910                 {
911                         m_ptr->max_maxhp = damroll(r_ptr->hdice, r_ptr->hside);
912                 }
913                 if (ironman_nightmare)
914                 {
915                         HIT_POINT hp = m_ptr->max_maxhp * 2L;
916                         m_ptr->max_maxhp = MIN(30000, hp);
917                 }
918                 m_ptr->maxhp = m_ptr->max_maxhp;
919                 m_ptr->hp = old_hp * m_ptr->maxhp / old_maxhp;
920
921                 /* dealt damage is 0 at initial*/
922                 m_ptr->dealt_damage = 0;
923
924                 /* Extract the monster base speed */
925                 m_ptr->mspeed = get_mspeed(r_ptr);
926
927                 /* Sub-alignment of a monster */
928                 if (!is_pet(m_ptr) && !(r_ptr->flags3 & (RF3_EVIL | RF3_GOOD)))
929                         m_ptr->sub_align = old_sub_align;
930                 else
931                 {
932                         m_ptr->sub_align = SUB_ALIGN_NEUTRAL;
933                         if (r_ptr->flags3 & RF3_EVIL) m_ptr->sub_align |= SUB_ALIGN_EVIL;
934                         if (r_ptr->flags3 & RF3_GOOD) m_ptr->sub_align |= SUB_ALIGN_GOOD;
935                 }
936
937                 m_ptr->exp = 0;
938
939                 if (is_pet(m_ptr) || m_ptr->ml)
940                 {
941                         if (!ignore_unview || player_can_see_bold(m_ptr->fy, m_ptr->fx))
942                         {
943                                 if (p_ptr->image)
944                                 {
945                                         monster_race *hallu_race;
946
947                                         do
948                                         {
949                                                 hallu_race = &r_info[randint1(max_r_idx - 1)];
950                                         } while (!hallu_race->name || (hallu_race->flags1 & RF1_UNIQUE));
951                                         msg_format(_("%sは%sに進化した。", "%^s evolved into %s."), m_name, r_name + hallu_race->name);
952                                 }
953                                 else
954                                 {
955                                         msg_format(_("%sは%sに進化した。", "%^s evolved into %s."), m_name, r_name + r_ptr->name);
956                                 }
957                         }
958
959                         if (!p_ptr->image) r_info[old_r_idx].r_xtra1 |= MR1_SINKA;
960
961                         /* Now you feel very close to this pet. */
962                         m_ptr->parent_m_idx = 0;
963                 }
964                 update_monster(m_idx, FALSE);
965                 lite_spot(m_ptr->fy, m_ptr->fx);
966         }
967         if (m_idx == p_ptr->riding) p_ptr->update |= PU_BONUS;
968 }
969
970 /*!
971  * @brief モンスターのHPをダメージに応じて減算する /
972  * Decreases monsters hit points, handling monster death.
973  * @param dam 与えたダメージ量
974  * @param m_idx ダメージを与えたモンスターのID
975  * @param fear ダメージによってモンスターが恐慌状態に陥ったならばTRUEを返す
976  * @param note モンスターが倒された際の特別なメッセージ述語
977  * @return なし
978  * @details
979  * <pre>
980  * We return TRUE if the monster has been killed (and deleted).
981  * We announce monster death (using an optional "death message"
982  * if given, and a otherwise a generic killed/destroyed message).
983  * Only "physical attacks" can induce the "You have slain" message.
984  * Missile and Spell attacks will induce the "dies" message, or
985  * various "specialized" messages.  Note that "You have destroyed"
986  * and "is destroyed" are synonyms for "You have slain" and "dies".
987  * Hack -- unseen monsters yield "You have killed it." message.
988  * Added fear (DGK) and check whether to print fear messages -CWS
989  * Made name, sex, and capitalization generic -BEN-
990  * As always, the "ghost" processing is a total hack.
991  * Hack -- we "delay" fear messages by passing around a "fear" flag.
992  * Consider decreasing monster experience over time, say,
993  * by using "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))"
994  * instead of simply "(m_exp * m_lev) / (p_lev)", to make the first
995  * monster worth more than subsequent monsters.  This would also need
996  * to induce changes in the monster recall code.
997  * </pre>
998  */
999 bool mon_take_hit(MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
1000 {
1001         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
1002         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1003         monster_type exp_mon;
1004
1005         /* Innocent until proven otherwise */
1006         bool innocent = TRUE, thief = FALSE;
1007         int i;
1008         HIT_POINT expdam;
1009
1010         (void)COPY(&exp_mon, m_ptr, monster_type);
1011
1012         expdam = (m_ptr->hp > dam) ? dam : m_ptr->hp;
1013
1014         get_exp_from_mon(expdam, &exp_mon);
1015
1016         /* Genocided by chaos patron */
1017         if (!monster_is_valid(m_ptr)) m_idx = 0;
1018
1019         /* Redraw (later) if needed */
1020         if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
1021         if (p_ptr->riding == m_idx) p_ptr->redraw |= (PR_UHEALTH);
1022
1023         (void)set_monster_csleep(m_idx, 0);
1024
1025         /* Hack - Cancel any special player stealth magics. -LM- */
1026         if (p_ptr->special_defense & NINJA_S_STEALTH)
1027         {
1028                 set_superstealth(FALSE);
1029         }
1030
1031         /* Genocided by chaos patron */
1032         if (!m_idx) return TRUE;
1033
1034         m_ptr->hp -= dam;
1035         m_ptr->dealt_damage += dam;
1036
1037         if (m_ptr->dealt_damage > m_ptr->max_maxhp * 100) m_ptr->dealt_damage = m_ptr->max_maxhp * 100;
1038
1039         if (p_ptr->wizard)
1040         {
1041                 msg_format(_("合計%d/%dのダメージを与えた。", "You do %d (out of %d) damage."), m_ptr->dealt_damage, m_ptr->maxhp);
1042         }
1043
1044         /* It is dead now */
1045         if (m_ptr->hp < 0)
1046         {
1047                 GAME_TEXT m_name[MAX_NLEN];
1048
1049                 if (r_info[m_ptr->r_idx].flags7 & RF7_TANUKI)
1050                 {
1051                         /* You might have unmasked Tanuki first time */
1052                         r_ptr = &r_info[m_ptr->r_idx];
1053                         m_ptr->ap_r_idx = m_ptr->r_idx;
1054                         if (r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
1055                 }
1056
1057                 if (m_ptr->mflag2 & MFLAG2_CHAMELEON)
1058                 {
1059                         /* You might have unmasked Chameleon first time */
1060                         r_ptr = real_r_ptr(m_ptr);
1061                         if (r_ptr->r_sights < MAX_SHORT) r_ptr->r_sights++;
1062                 }
1063
1064                 if (!(m_ptr->smart & SM_CLONED))
1065                 {
1066                         /* When the player kills a Unique, it stays dead */
1067                         if (r_ptr->flags1 & RF1_UNIQUE)
1068                         {
1069                                 r_ptr->max_num = 0;
1070
1071                                 /* Mega-Hack -- Banor & Lupart */
1072                                 if ((m_ptr->r_idx == MON_BANOR) || (m_ptr->r_idx == MON_LUPART))
1073                                 {
1074                                         r_info[MON_BANORLUPART].max_num = 0;
1075                                         r_info[MON_BANORLUPART].r_pkills++;
1076                                         r_info[MON_BANORLUPART].r_akills++;
1077                                         if (r_info[MON_BANORLUPART].r_tkills < MAX_SHORT) r_info[MON_BANORLUPART].r_tkills++;
1078                                 }
1079                                 else if (m_ptr->r_idx == MON_BANORLUPART)
1080                                 {
1081                                         r_info[MON_BANOR].max_num = 0;
1082                                         r_info[MON_BANOR].r_pkills++;
1083                                         r_info[MON_BANOR].r_akills++;
1084                                         if (r_info[MON_BANOR].r_tkills < MAX_SHORT) r_info[MON_BANOR].r_tkills++;
1085                                         r_info[MON_LUPART].max_num = 0;
1086                                         r_info[MON_LUPART].r_pkills++;
1087                                         r_info[MON_LUPART].r_akills++;
1088                                         if (r_info[MON_LUPART].r_tkills < MAX_SHORT) r_info[MON_LUPART].r_tkills++;
1089                                 }
1090                         }
1091
1092                         /* When the player kills a Nazgul, it stays dead */
1093                         else if (r_ptr->flags7 & RF7_NAZGUL) r_ptr->max_num--;
1094                 }
1095
1096                 /* Count all monsters killed */
1097                 if (r_ptr->r_akills < MAX_SHORT) r_ptr->r_akills++;
1098
1099                 /* Recall even invisible uniques or winners */
1100                 if ((m_ptr->ml && !p_ptr->image) || (r_ptr->flags1 & RF1_UNIQUE))
1101                 {
1102                         /* Count kills this life */
1103                         if ((m_ptr->mflag2 & MFLAG2_KAGE) && (r_info[MON_KAGE].r_pkills < MAX_SHORT)) r_info[MON_KAGE].r_pkills++;
1104                         else if (r_ptr->r_pkills < MAX_SHORT) r_ptr->r_pkills++;
1105
1106                         /* Count kills in all lives */
1107                         if ((m_ptr->mflag2 & MFLAG2_KAGE) && (r_info[MON_KAGE].r_tkills < MAX_SHORT)) r_info[MON_KAGE].r_tkills++;
1108                         else if (r_ptr->r_tkills < MAX_SHORT) r_ptr->r_tkills++;
1109
1110                         /* Hack -- Auto-recall */
1111                         monster_race_track(m_ptr->ap_r_idx);
1112                 }
1113
1114                 /* Extract monster name */
1115                 monster_desc(m_name, m_ptr, MD_TRUE_NAME);
1116
1117                 /* Don't kill Amberites */
1118                 if ((r_ptr->flags3 & RF3_AMBERITE) && one_in_(2))
1119                 {
1120                         int curses = 1 + randint1(3);
1121                         bool stop_ty = FALSE;
1122                         int count = 0;
1123
1124                         msg_format(_("%^sは恐ろしい血の呪いをあなたにかけた!", "%^s puts a terrible blood curse on you!"), m_name);
1125                         curse_equipment(100, 50);
1126
1127                         do
1128                         {
1129                                 stop_ty = activate_ty_curse(stop_ty, &count);
1130                         } while (--curses);
1131                 }
1132
1133                 if (r_ptr->flags2 & RF2_CAN_SPEAK)
1134                 {
1135                         char line_got[1024];
1136                         if (!get_rnd_line(_("mondeath_j.txt", "mondeath.txt"), m_ptr->r_idx, line_got))
1137                         {
1138                                 msg_format("%^s %s", m_name, line_got);
1139                         }
1140
1141 #ifdef WORLD_SCORE
1142                         if (m_ptr->r_idx == MON_SERPENT)
1143                         {
1144                                 screen_dump = make_screen_dump();
1145                         }
1146 #endif
1147                 }
1148
1149                 if (!(d_info[p_ptr->dungeon_idx].flags1 & DF1_BEGINNER))
1150                 {
1151                         if (!current_floor_ptr->dun_level && !p_ptr->ambush_flag && !p_ptr->inside_arena)
1152                         {
1153                                 chg_virtue(V_VALOUR, -1);
1154                         }
1155                         else if (r_ptr->level > current_floor_ptr->dun_level)
1156                         {
1157                                 if (randint1(10) <= (r_ptr->level - current_floor_ptr->dun_level))
1158                                         chg_virtue(V_VALOUR, 1);
1159                         }
1160                         if (r_ptr->level > 60)
1161                         {
1162                                 chg_virtue(V_VALOUR, 1);
1163                         }
1164                         if (r_ptr->level >= 2 * (p_ptr->lev + 1))
1165                                 chg_virtue(V_VALOUR, 2);
1166                 }
1167
1168                 if (r_ptr->flags1 & RF1_UNIQUE)
1169                 {
1170                         if (r_ptr->flags3 & (RF3_EVIL | RF3_GOOD)) chg_virtue(V_HARMONY, 2);
1171
1172                         if (r_ptr->flags3 & RF3_GOOD)
1173                         {
1174                                 chg_virtue(V_UNLIFE, 2);
1175                                 chg_virtue(V_VITALITY, -2);
1176                         }
1177
1178                         if (one_in_(3)) chg_virtue(V_INDIVIDUALISM, -1);
1179                 }
1180
1181                 if (m_ptr->r_idx == MON_BEGGAR || m_ptr->r_idx == MON_LEPER)
1182                 {
1183                         chg_virtue(V_COMPASSION, -1);
1184                 }
1185
1186                 if ((r_ptr->flags3 & RF3_GOOD) && ((r_ptr->level) / 10 + (3 * current_floor_ptr->dun_level) >= randint1(100)))
1187                         chg_virtue(V_UNLIFE, 1);
1188
1189                 if (r_ptr->d_char == 'A')
1190                 {
1191                         if (r_ptr->flags1 & RF1_UNIQUE)
1192                                 chg_virtue(V_FAITH, -2);
1193                         else if ((r_ptr->level) / 10 + (3 * current_floor_ptr->dun_level) >= randint1(100))
1194                         {
1195                                 if (r_ptr->flags3 & RF3_GOOD) chg_virtue(V_FAITH, -1);
1196                                 else chg_virtue(V_FAITH, 1);
1197                         }
1198                 }
1199                 else if (r_ptr->flags3 & RF3_DEMON)
1200                 {
1201                         if (r_ptr->flags1 & RF1_UNIQUE)
1202                                 chg_virtue(V_FAITH, 2);
1203                         else if ((r_ptr->level) / 10 + (3 * current_floor_ptr->dun_level) >= randint1(100))
1204                                 chg_virtue(V_FAITH, 1);
1205                 }
1206
1207                 if ((r_ptr->flags3 & RF3_UNDEAD) && (r_ptr->flags1 & RF1_UNIQUE))
1208                         chg_virtue(V_VITALITY, 2);
1209
1210                 if (r_ptr->r_deaths)
1211                 {
1212                         if (r_ptr->flags1 & RF1_UNIQUE)
1213                         {
1214                                 chg_virtue(V_HONOUR, 10);
1215                         }
1216                         else if ((r_ptr->level) / 10 + (2 * current_floor_ptr->dun_level) >= randint1(100))
1217                         {
1218                                 chg_virtue(V_HONOUR, 1);
1219                         }
1220                 }
1221                 if ((r_ptr->flags2 & RF2_MULTIPLY) && (r_ptr->r_akills > 1000) && one_in_(10))
1222                 {
1223                         chg_virtue(V_VALOUR, -1);
1224                 }
1225
1226                 for (i = 0; i < 4; i++)
1227                 {
1228                         if (r_ptr->blow[i].d_dice != 0) innocent = FALSE; /* Murderer! */
1229
1230                         if ((r_ptr->blow[i].effect == RBE_EAT_ITEM)
1231                                 || (r_ptr->blow[i].effect == RBE_EAT_GOLD))
1232
1233                                 thief = TRUE; /* Thief! */
1234                 }
1235
1236                 /* The new law says it is illegal to live in the dungeon */
1237                 if (r_ptr->level != 0) innocent = FALSE;
1238
1239                 if (thief)
1240                 {
1241                         if (r_ptr->flags1 & RF1_UNIQUE)
1242                                 chg_virtue(V_JUSTICE, 3);
1243                         else if (1 + ((r_ptr->level) / 10 + (2 * current_floor_ptr->dun_level)) >= randint1(100))
1244                                 chg_virtue(V_JUSTICE, 1);
1245                 }
1246                 else if (innocent)
1247                 {
1248                         chg_virtue(V_JUSTICE, -1);
1249                 }
1250
1251                 if ((r_ptr->flags3 & RF3_ANIMAL) && !(r_ptr->flags3 & RF3_EVIL) && !(r_ptr->flags4 & ~(RF4_NOMAGIC_MASK)) && !(r_ptr->a_ability_flags1 & ~(RF5_NOMAGIC_MASK)) && !(r_ptr->a_ability_flags2 & ~(RF6_NOMAGIC_MASK)))
1252                 {
1253                         if (one_in_(4)) chg_virtue(V_NATURE, -1);
1254                 }
1255
1256                 if ((r_ptr->flags1 & RF1_UNIQUE) && record_destroy_uniq)
1257                 {
1258                         char note_buf[160];
1259                         sprintf(note_buf, "%s%s", r_name + r_ptr->name, (m_ptr->smart & SM_CLONED) ? _("(クローン)", "(Clone)") : "");
1260                         do_cmd_write_nikki(NIKKI_UNIQUE, 0, note_buf);
1261                 }
1262
1263                 /* Make a sound */
1264                 sound(SOUND_KILL);
1265
1266                 /* Death by Missile/Spell attack */
1267                 if (note)
1268                 {
1269                         msg_format("%^s%s", m_name, note);
1270                 }
1271
1272                 /* Death by physical attack -- invisible monster */
1273                 else if (!m_ptr->ml)
1274                 {
1275 #ifdef JP
1276                         if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
1277                                 msg_format("せっかくだから%sを殺した。", m_name);
1278                         else
1279                                 msg_format("%sを殺した。", m_name);
1280 #else
1281                         msg_format("You have killed %s.", m_name);
1282 #endif
1283
1284                 }
1285
1286                 /* Death by Physical attack -- non-living monster */
1287                 else if (!monster_living(m_ptr->r_idx))
1288                 {
1289                         bool explode = FALSE;
1290
1291                         for (i = 0; i < 4; i++)
1292                         {
1293                                 if (r_ptr->blow[i].method == RBM_EXPLODE) explode = TRUE;
1294                         }
1295
1296                         /* Special note at death */
1297                         if (explode)
1298                                 msg_format(_("%sは爆発して粉々になった。", "%^s explodes into tiny shreds."), m_name);
1299                         else
1300                         {
1301 #ifdef JP
1302                                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
1303                                         msg_format("せっかくだから%sを倒した。", m_name);
1304                                 else
1305                                         msg_format("%sを倒した。", m_name);
1306 #else
1307                                 msg_format("You have destroyed %s.", m_name);
1308 #endif
1309                         }
1310                 }
1311
1312                 /* Death by Physical attack -- living monster */
1313                 else
1314                 {
1315 #ifdef JP
1316                         if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON))
1317                                 msg_format("せっかくだから%sを葬り去った。", m_name);
1318                         else
1319                                 msg_format("%sを葬り去った。", m_name);
1320 #else
1321                         msg_format("You have slain %s.", m_name);
1322 #endif
1323
1324                 }
1325                 if ((r_ptr->flags1 & RF1_UNIQUE) && !(m_ptr->smart & SM_CLONED) && !vanilla_town)
1326                 {
1327                         for (i = 0; i < MAX_KUBI; i++)
1328                         {
1329                                 if ((current_world_ptr->bounty_r_idx[i] == m_ptr->r_idx) && !(m_ptr->mflag2 & MFLAG2_CHAMELEON))
1330                                 {
1331                                         msg_format(_("%sの首には賞金がかかっている。", "There is a price on %s's head."), m_name);
1332                                         break;
1333                                 }
1334                         }
1335                 }
1336
1337                 /* Generate treasure */
1338                 monster_death(m_idx, TRUE);
1339
1340                 /* Mega hack : replace IKETA to BIKETAL */
1341                 if ((m_ptr->r_idx == MON_IKETA) && !(p_ptr->inside_arena || p_ptr->inside_battle))
1342                 {
1343                         POSITION dummy_y = m_ptr->fy;
1344                         POSITION dummy_x = m_ptr->fx;
1345                         BIT_FLAGS mode = 0L;
1346                         if (is_pet(m_ptr)) mode |= PM_FORCE_PET;
1347                         delete_monster_idx(m_idx);
1348                         if (summon_named_creature(0, dummy_y, dummy_x, MON_BIKETAL, mode))
1349                         {
1350                                 msg_print(_("「ハァッハッハッハ!!私がバイケタルだ!!」", "Uwa-hahaha!  *I* am Biketal!"));
1351                         }
1352                 }
1353                 else
1354                 {
1355                         delete_monster_idx(m_idx);
1356                 }
1357
1358                 get_exp_from_mon((long)exp_mon.max_maxhp * 2, &exp_mon);
1359
1360                 /* Not afraid */
1361                 (*fear) = FALSE;
1362
1363                 /* Monster is dead */
1364                 return (TRUE);
1365         }
1366
1367
1368 #ifdef ALLOW_FEAR
1369
1370         /* Mega-Hack -- Pain cancels fear */
1371         if (MON_MONFEAR(m_ptr) && (dam > 0))
1372         {
1373                 /* Cure fear */
1374                 if (set_monster_monfear(m_idx, MON_MONFEAR(m_ptr) - randint1(dam)))
1375                 {
1376                         /* No more fear */
1377                         (*fear) = FALSE;
1378                 }
1379         }
1380
1381         /* Sometimes a monster gets scared by damage */
1382         if (!MON_MONFEAR(m_ptr) && !(r_ptr->flags3 & (RF3_NO_FEAR)))
1383         {
1384                 /* Percentage of fully healthy */
1385                 int percentage = (100L * m_ptr->hp) / m_ptr->maxhp;
1386
1387                 /*
1388                  * Run (sometimes) if at 10% or less of max hit points,
1389                  * or (usually) when hit for half its current hit points
1390                  */
1391                 if ((randint1(10) >= percentage) || ((dam >= m_ptr->hp) && (randint0(100) < 80)))
1392                 {
1393                         /* Hack -- note fear */
1394                         (*fear) = TRUE;
1395
1396                         /* Hack -- Add some timed fear */
1397                         (void)set_monster_monfear(m_idx, (randint1(10) +
1398                                 (((dam >= m_ptr->hp) && (percentage > 7)) ?
1399                                         20 : ((11 - percentage) * 5))));
1400                 }
1401         }
1402
1403 #endif
1404
1405         /* Not dead yet */
1406         return (FALSE);
1407 }
1408
1409 bool monster_is_valid(monster_type *m_ptr)
1410 {
1411         return (m_ptr->r_idx != 0);
1412 }