OSDN Git Service

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