OSDN Git Service

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