OSDN Git Service

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