OSDN Git Service

[Refactor] #40457 Renamed avatar.c/h from player/ to player-info/
[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 "core/player-redraw-types.h"
5 #include "core/player-update-types.h"
6 #include "core/speed-table.h"
7 #include "core/stuff-handler.h"
8 #include "dungeon/dungeon-flag-types.h"
9 #include "dungeon/dungeon.h"
10 #include "floor/cave.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-remover.h"
25 #include "monster-floor/monster-summon.h"
26 #include "monster-floor/place-monster-types.h"
27 #include "monster-race/monster-race-hook.h"
28 #include "monster-race/monster-race.h"
29 #include "monster-race/race-flags-ability2.h"
30 #include "monster-race/race-flags-resistance.h"
31 #include "monster-race/race-flags1.h"
32 #include "monster-race/race-flags2.h"
33 #include "monster-race/race-flags3.h"
34 #include "monster-race/race-flags4.h"
35 #include "monster-race/race-flags7.h"
36 #include "monster-race/race-flags8.h"
37 #include "monster-race/race-indice-types.h"
38 #include "monster/monster-describer.h"
39 #include "monster/monster-description-types.h"
40 #include "monster/monster-flag-types.h"
41 #include "monster/monster-info.h"
42 #include "monster/monster-list.h"
43 #include "monster/monster-status-setter.h" // todo 相互依存. 後で何とかする.
44 #include "monster/monster-update.h"
45 #include "monster/smart-learn-types.h"
46 #include "mspell/mspell-mask-definitions.h"
47 #include "object-enchant/object-curse.h"
48 #include "player-info/avatar.h"
49 #include "player/player-personalities-types.h"
50 #include "player/special-defense-types.h"
51 #include "spell-kind/spells-random.h"
52 #include "spell/spells-summon.h"
53 #include "status/experience.h"
54 #include "system/floor-type-definition.h"
55 #include "view/display-messages.h"
56 #include "world/world.h"
57
58 /*!
59  * @brief モンスターIDからPOWERFULフラグの有無を取得する /
60  * @param floor_ptr 現在フロアへの参照ポインタ
61  * @param m_idx モンスターID
62  * @return POWERFULフラグがあればTRUE、なければFALSEを返す。
63  */
64 bool monster_is_powerful(floor_type *floor_ptr, MONSTER_IDX m_idx)
65 {
66     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
67     monster_race *r_ptr = &r_info[m_ptr->r_idx];
68     bool powerful = r_ptr->flags2 & RF2_POWERFUL ? TRUE : FALSE;
69     return powerful;
70 }
71
72 /*!
73  * @brief モンスターIDからモンスターのレベルを取得する(ただし最低1を保証する) /
74  * @param m_idx モンスターID
75  * @return モンスターのレベル
76  */
77 DEPTH monster_level_idx(floor_type *floor_ptr, MONSTER_IDX m_idx)
78 {
79     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
80     monster_race *r_ptr = &r_info[m_ptr->r_idx];
81     DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
82     return rlev;
83 }
84
85 /*!
86  * @brief モンスターに与えたダメージの修正処理 /
87  * Modify the physical damage done to the monster.
88  * @param target_ptr プレーヤーへの参照ポインタ
89  * @param m_ptr ダメージを受けるモンスターの構造体参照ポインタ
90  * @param dam ダメージ基本値
91  * @param is_psy_spear 攻撃手段が光の剣ならばTRUE
92  * @return 修正を行った結果のダメージ量
93  * @details
94  * <pre>
95  * (for example when it's invulnerable or shielded)
96  * ToDo: Accept a damage-type to calculate the modified damage from
97  * things like fire, frost, lightning, poison, ... attacks.
98  * "type" is not yet used and should be 0.
99  * </pre>
100  */
101 HIT_POINT mon_damage_mod(player_type *target_ptr, monster_type *m_ptr, HIT_POINT dam, bool is_psy_spear)
102 {
103     monster_race *r_ptr = &r_info[m_ptr->r_idx];
104
105     if ((r_ptr->flagsr & RFR_RES_ALL) && dam > 0) {
106         dam /= 100;
107         if ((dam == 0) && one_in_(3))
108             dam = 1;
109     }
110
111     if (monster_invulner_remaining(m_ptr)) {
112         if (is_psy_spear) {
113             if (!target_ptr->blind && is_seen(target_ptr, m_ptr)) {
114                 msg_print(_("バリアを切り裂いた!", "The barrier is penetrated!"));
115             }
116         } else if (!one_in_(PENETRATE_INVULNERABILITY)) {
117             return 0;
118         }
119     }
120
121     return dam;
122 }
123
124 /*!
125  * @brief モンスターに与えたダメージを元に経験値を加算する /
126  * Calculate experience point to be get
127  * @param dam 与えたダメージ量
128  * @param m_ptr ダメージを与えたモンスターの構造体参照ポインタ
129  * @return なし
130  * @details
131  * <pre>
132  * Even the 64 bit operation is not big enough to avoid overflaw
133  * unless we carefully choose orders of multiplication and division.
134  * Get the coefficient first, and multiply (potentially huge) base
135  * experience point of a monster later.
136  * </pre>
137  */
138 static void get_exp_from_mon(player_type *target_ptr, HIT_POINT dam, monster_type *m_ptr)
139 {
140     monster_race *r_ptr = &r_info[m_ptr->r_idx];
141
142     if (!monster_is_valid(m_ptr))
143         return;
144     if (is_pet(m_ptr) || target_ptr->phase_out)
145         return;
146
147     /*!
148      * todo 変数宣言と代入を同時に実行するとコンパイル警告が出る
149      * ここの整形は実施せず保留
150      */
151     s32b new_exp;
152     u32b new_exp_frac;
153     s32b div_h;
154     u32b div_l;
155
156     /*
157      * - Ratio of monster's level to player's level effects
158      * - Varying speed effects
159      * - Get a fraction in proportion of damage point
160      */
161     new_exp = r_ptr->level * SPEED_TO_ENERGY(m_ptr->mspeed) * dam;
162     new_exp_frac = 0;
163     div_h = 0L;
164     div_l = (target_ptr->max_plv + 2) * SPEED_TO_ENERGY(r_ptr->speed);
165
166     /* Use (average maxhp * 2) as a denominator */
167     if (!(r_ptr->flags1 & RF1_FORCE_MAXHP))
168         s64b_mul(&div_h, &div_l, 0, r_ptr->hdice * (ironman_nightmare ? 2 : 1) * (r_ptr->hside + 1));
169     else
170         s64b_mul(&div_h, &div_l, 0, r_ptr->hdice * (ironman_nightmare ? 2 : 1) * r_ptr->hside * 2);
171
172     /* Special penalty in the wilderness */
173     if (!target_ptr->current_floor_ptr->dun_level && (!(r_ptr->flags8 & RF8_WILD_ONLY) || !(r_ptr->flags1 & RF1_UNIQUE)))
174         s64b_mul(&div_h, &div_l, 0, 5);
175
176     /* Do division first to prevent overflaw */
177     s64b_div(&new_exp, &new_exp_frac, div_h, div_l);
178
179     /* Special penalty for mutiply-monster */
180     if ((r_ptr->flags2 & RF2_MULTIPLY) || (m_ptr->r_idx == MON_DAWN)) {
181         int monnum_penarty = r_ptr->r_akills / 400;
182         if (monnum_penarty > 8)
183             monnum_penarty = 8;
184
185         while (monnum_penarty--) {
186             /* Divide by 4 */
187             s64b_RSHIFT(new_exp, new_exp_frac, 2);
188         }
189     }
190
191     /* Special penalty for rest_and_shoot exp scum */
192     if ((m_ptr->dealt_damage > m_ptr->max_maxhp) && (m_ptr->hp >= 0)) {
193         int over_damage = m_ptr->dealt_damage / m_ptr->max_maxhp;
194         if (over_damage > 32)
195             over_damage = 32;
196
197         while (over_damage--) {
198             /* 9/10 for once */
199             s64b_mul(&new_exp, &new_exp_frac, 0, 9);
200             s64b_div(&new_exp, &new_exp_frac, 0, 10);
201         }
202     }
203
204     s64b_mul(&new_exp, &new_exp_frac, 0, r_ptr->mexp);
205     gain_exp_64(target_ptr, new_exp, new_exp_frac);
206 }
207
208 /*!
209  * @brief モンスターの時限ステータスを取得する
210  * @param floor_ptr 現在フロアへの参照ポインタ
211  * @return m_idx モンスターの参照ID
212  * @return mproc_type モンスターの時限ステータスID
213  * @return 残りターン値
214  */
215 int get_mproc_idx(floor_type *floor_ptr, MONSTER_IDX m_idx, int mproc_type)
216 {
217     s16b *cur_mproc_list = floor_ptr->mproc_list[mproc_type];
218     for (int i = floor_ptr->mproc_max[mproc_type] - 1; i >= 0; i--) {
219         if (cur_mproc_list[i] == m_idx)
220             return i;
221     }
222
223     return -1;
224 }
225
226 /*!
227  * @brief モンスターの時限ステータスリストを追加する
228  * @param floor_ptr 現在フロアへの参照ポインタ
229  * @return m_idx モンスターの参照ID
230  * @return mproc_type 追加したいモンスターの時限ステータスID
231  * @return なし
232  */
233 void mproc_add(floor_type *floor_ptr, MONSTER_IDX m_idx, int mproc_type)
234 {
235     if (floor_ptr->mproc_max[mproc_type] < current_world_ptr->max_m_idx) {
236         floor_ptr->mproc_list[mproc_type][floor_ptr->mproc_max[mproc_type]++] = (s16b)m_idx;
237     }
238 }
239
240 /*!
241  * @brief モンスターの時限ステータスリストを初期化する / Initialize monster process
242  * @param floor_ptr 現在フロアへの参照ポインタ
243  * @return なし
244  */
245 void mproc_init(floor_type *floor_ptr)
246 {
247     /* Reset "target_ptr->current_floor_ptr->mproc_max[]" */
248     for (int i = 0; i < MAX_MTIMED; i++) {
249         floor_ptr->mproc_max[i] = 0;
250     }
251
252     /* Process the monsters (backwards) */
253     for (MONSTER_IDX i = floor_ptr->m_max - 1; i >= 1; i--) {
254         monster_type *m_ptr;
255         m_ptr = &floor_ptr->m_list[i];
256
257         /* Ignore "dead" monsters */
258         if (!monster_is_valid(m_ptr))
259             continue;
260
261         for (int cmi = 0; cmi < MAX_MTIMED; cmi++) {
262             if (m_ptr->mtimed[cmi])
263                 mproc_add(floor_ptr, i, cmi);
264         }
265     }
266 }
267
268 static u32b csleep_noise;
269
270 /*!
271  * @brief モンスターの各種状態値を時間経過により更新するサブルーチン
272  * @param floor_ptr 現在フロアへの参照ポインタ
273  * @param m_idx モンスター参照ID
274  * @param mtimed_idx 更新するモンスターの時限ステータスID
275  * @return なし
276  */
277 static void process_monsters_mtimed_aux(player_type *target_ptr, MONSTER_IDX m_idx, int mtimed_idx)
278 {
279     monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
280
281     switch (mtimed_idx) {
282     case MTIMED_CSLEEP: {
283         monster_race *r_ptr = &r_info[m_ptr->r_idx];
284
285         /* Assume does not wake up */
286         bool test = FALSE;
287
288         /* Hack -- Require proximity */
289         if (m_ptr->cdis < AAF_LIMIT) {
290             /* Handle "sensing radius" */
291             if (m_ptr->cdis <= (is_pet(m_ptr) ? ((r_ptr->aaf > MAX_SIGHT) ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf)) {
292                 /* We may wake up */
293                 test = TRUE;
294             }
295
296             /* Handle "sight" and "aggravation" */
297             else if ((m_ptr->cdis <= MAX_SIGHT) && (player_has_los_bold(target_ptr, m_ptr->fy, m_ptr->fx))) {
298                 /* We may wake up */
299                 test = TRUE;
300             }
301         }
302
303         if (!test)
304             break;
305
306         u32b notice = randint0(1024);
307
308         /* Nightmare monsters are more alert */
309         if (ironman_nightmare)
310             notice /= 2;
311
312         /* Hack -- See if monster "notices" player */
313         if ((notice * notice * notice) > csleep_noise)
314             break;
315
316         /* Hack -- amount of "waking" */
317         /* Wake up faster near the player */
318         int d = (m_ptr->cdis < AAF_LIMIT / 2) ? (AAF_LIMIT / m_ptr->cdis) : 1;
319
320         /* Hack -- amount of "waking" is affected by speed of player */
321         d = (d * SPEED_TO_ENERGY(target_ptr->pspeed)) / 10;
322         if (d < 0)
323             d = 1;
324
325         /* Monster wakes up "a little bit" */
326
327         /* Still asleep */
328         if (!set_monster_csleep(target_ptr, m_idx, monster_csleep_remaining(m_ptr) - d)) {
329             /* Notice the "not waking up" */
330             if (is_original_ap_and_seen(target_ptr, m_ptr)) {
331                 /* Hack -- Count the ignores */
332                 if (r_ptr->r_ignore < MAX_UCHAR)
333                     r_ptr->r_ignore++;
334             }
335
336             break;
337         }
338
339         /* Notice the "waking up" */
340         if (m_ptr->ml) {
341             GAME_TEXT m_name[MAX_NLEN];
342             monster_desc(target_ptr, m_name, m_ptr, 0);
343             msg_format(_("%^sが目を覚ました。", "%^s wakes up."), m_name);
344         }
345
346         if (is_original_ap_and_seen(target_ptr, m_ptr)) {
347             /* Hack -- Count the wakings */
348             if (r_ptr->r_wake < MAX_UCHAR)
349                 r_ptr->r_wake++;
350         }
351
352         break;
353     }
354
355     case MTIMED_FAST:
356         /* Reduce by one, note if expires */
357         if (set_monster_fast(target_ptr, m_idx, monster_fast_remaining(m_ptr) - 1)) {
358             if (is_seen(target_ptr, m_ptr)) {
359                 GAME_TEXT m_name[MAX_NLEN];
360                 monster_desc(target_ptr, m_name, m_ptr, 0);
361                 msg_format(_("%^sはもう加速されていない。", "%^s is no longer fast."), m_name);
362             }
363         }
364
365         break;
366
367     case MTIMED_SLOW:
368         /* Reduce by one, note if expires */
369         if (set_monster_slow(target_ptr, m_idx, monster_slow_remaining(m_ptr) - 1)) {
370             if (is_seen(target_ptr, m_ptr)) {
371                 GAME_TEXT m_name[MAX_NLEN];
372                 monster_desc(target_ptr, m_name, m_ptr, 0);
373                 msg_format(_("%^sはもう減速されていない。", "%^s is no longer slow."), m_name);
374             }
375         }
376
377         break;
378
379     case MTIMED_STUNNED: {
380         int rlev = r_info[m_ptr->r_idx].level;
381
382         /* Recover from stun */
383         if (set_monster_stunned(target_ptr, m_idx, (randint0(10000) <= rlev * rlev) ? 0 : (monster_stunned_remaining(m_ptr) - 1))) {
384             /* Message if visible */
385             if (is_seen(target_ptr, m_ptr)) {
386                 GAME_TEXT m_name[MAX_NLEN];
387                 monster_desc(target_ptr, m_name, m_ptr, 0);
388                 msg_format(_("%^sは朦朧状態から立ち直った。", "%^s is no longer stunned."), m_name);
389             }
390         }
391
392         break;
393     }
394
395     case MTIMED_CONFUSED: {
396         /* Reduce the confusion */
397         if (!set_monster_confused(target_ptr, m_idx, monster_confused_remaining(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1)))
398             break;
399         /* Message if visible */
400         if (is_seen(target_ptr, m_ptr)) {
401             GAME_TEXT m_name[MAX_NLEN];
402             monster_desc(target_ptr, m_name, m_ptr, 0);
403             msg_format(_("%^sは混乱から立ち直った。", "%^s is no longer confused."), m_name);
404         }
405
406         break;
407     }
408
409     case MTIMED_MONFEAR: {
410         /* Reduce the fear */
411         if (!set_monster_monfear(target_ptr, m_idx, monster_fear_remaining(m_ptr) - randint1(r_info[m_ptr->r_idx].level / 20 + 1)))
412             break;
413
414         /* Visual note */
415         if (is_seen(target_ptr, m_ptr)) {
416             GAME_TEXT m_name[MAX_NLEN];
417 #ifdef JP
418 #else
419             char m_poss[80];
420
421             /* Acquire the monster possessive */
422             monster_desc(target_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
423 #endif
424             monster_desc(target_ptr, m_name, m_ptr, 0);
425 #ifdef JP
426             msg_format("%^sは勇気を取り戻した。", m_name);
427 #else
428             msg_format("%^s recovers %s courage.", m_name, m_poss);
429 #endif
430         }
431
432         break;
433     }
434
435     case MTIMED_INVULNER: {
436         /* Reduce by one, note if expires */
437         if (!set_monster_invulner(target_ptr, m_idx, monster_invulner_remaining(m_ptr) - 1, TRUE))
438             break;
439
440         if (is_seen(target_ptr, m_ptr)) {
441             GAME_TEXT m_name[MAX_NLEN];
442             monster_desc(target_ptr, m_name, m_ptr, 0);
443             msg_format(_("%^sはもう無敵でない。", "%^s is no longer invulnerable."), m_name);
444         }
445
446         break;
447     }
448     }
449 }
450
451 /*!
452  * @brief 全モンスターの各種状態値を時間経過により更新するメインルーチン
453  * @param mtimed_idx 更新するモンスターの時限ステータスID
454  * @param target_ptr プレーヤーへの参照ポインタ
455  * @return なし
456  * @details
457  * Process the counters of monsters (once per 10 game turns)\n
458  * These functions are to process monsters' counters same as player's.
459  */
460 void process_monsters_mtimed(player_type *target_ptr, int mtimed_idx)
461 {
462     floor_type *floor_ptr = target_ptr->current_floor_ptr;
463     s16b *cur_mproc_list = floor_ptr->mproc_list[mtimed_idx];
464
465     /* Hack -- calculate the "player noise" */
466     if (mtimed_idx == MTIMED_CSLEEP)
467         csleep_noise = (1L << (30 - target_ptr->skill_stl));
468
469     /* Process the monsters (backwards) */
470     for (int i = floor_ptr->mproc_max[mtimed_idx] - 1; i >= 0; i--) {
471         process_monsters_mtimed_aux(target_ptr, cur_mproc_list[i], mtimed_idx);
472     }
473 }
474
475 /*!
476  * @brief モンスターへの魔力消去処理
477  * @param target_ptr プレーヤーへの参照ポインタ
478  * @param m_idx 魔力消去を受けるモンスターの参照ID
479  * @return なし
480  */
481 void dispel_monster_status(player_type *target_ptr, MONSTER_IDX m_idx)
482 {
483     monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
484     GAME_TEXT m_name[MAX_NLEN];
485
486     monster_desc(target_ptr, m_name, m_ptr, 0);
487     if (set_monster_invulner(target_ptr, m_idx, 0, TRUE)) {
488         if (m_ptr->ml)
489             msg_format(_("%sはもう無敵ではない。", "%^s is no longer invulnerable."), m_name);
490     }
491
492     if (set_monster_fast(target_ptr, m_idx, 0)) {
493         if (m_ptr->ml)
494             msg_format(_("%sはもう加速されていない。", "%^s is no longer fast."), m_name);
495     }
496
497     if (set_monster_slow(target_ptr, m_idx, 0)) {
498         if (m_ptr->ml)
499             msg_format(_("%sはもう減速されていない。", "%^s is no longer slow."), m_name);
500     }
501 }
502
503 /*!
504  * @brief モンスターの経験値取得処理
505  * @param target_ptr プレーヤーへの参照ポインタ
506  * @param m_idx 経験値を得るモンスターの参照ID
507  * @param s_idx 撃破されたモンスター種族の参照ID
508  * @return なし
509  */
510 void monster_gain_exp(player_type *target_ptr, MONSTER_IDX m_idx, MONRACE_IDX s_idx)
511 {
512     monster_type *m_ptr;
513     monster_race *r_ptr;
514     monster_race *s_ptr;
515     if (m_idx <= 0 || s_idx <= 0)
516         return;
517
518     floor_type *floor_ptr = target_ptr->current_floor_ptr;
519     m_ptr = &floor_ptr->m_list[m_idx];
520
521     if (!monster_is_valid(m_ptr))
522         return;
523
524     r_ptr = &r_info[m_ptr->r_idx];
525     s_ptr = &r_info[s_idx];
526
527     if (target_ptr->phase_out)
528         return;
529
530     if (!r_ptr->next_exp)
531         return;
532
533     int new_exp = s_ptr->mexp * s_ptr->level / (r_ptr->level + 2);
534     if (m_idx == target_ptr->riding)
535         new_exp = (new_exp + 1) / 2;
536     if (!floor_ptr->dun_level)
537         new_exp /= 5;
538     m_ptr->exp += new_exp;
539     if (m_ptr->mflag2 & MFLAG2_CHAMELEON)
540         return;
541
542     if (m_ptr->exp < r_ptr->next_exp) {
543         if (m_idx == target_ptr->riding)
544             target_ptr->update |= PU_BONUS;
545         return;
546     }
547
548     GAME_TEXT m_name[MAX_NLEN];
549     int old_hp = m_ptr->hp;
550     int old_maxhp = m_ptr->max_maxhp;
551     int old_r_idx = m_ptr->r_idx;
552     byte old_sub_align = m_ptr->sub_align;
553
554     /* Hack -- Reduce the racial counter of previous monster */
555     real_r_ptr(m_ptr)->cur_num--;
556
557     monster_desc(target_ptr, m_name, m_ptr, 0);
558     m_ptr->r_idx = r_ptr->next_r_idx;
559
560     /* Count the monsters on the level */
561     real_r_ptr(m_ptr)->cur_num++;
562
563     m_ptr->ap_r_idx = m_ptr->r_idx;
564     r_ptr = &r_info[m_ptr->r_idx];
565
566     if (r_ptr->flags1 & RF1_FORCE_MAXHP) {
567         m_ptr->max_maxhp = maxroll(r_ptr->hdice, r_ptr->hside);
568     } else {
569         m_ptr->max_maxhp = damroll(r_ptr->hdice, r_ptr->hside);
570     }
571     if (ironman_nightmare) {
572         HIT_POINT hp = m_ptr->max_maxhp * 2L;
573         m_ptr->max_maxhp = MIN(30000, hp);
574     }
575
576     m_ptr->maxhp = m_ptr->max_maxhp;
577     m_ptr->hp = old_hp * m_ptr->maxhp / old_maxhp;
578
579     /* dealt damage is 0 at initial*/
580     m_ptr->dealt_damage = 0;
581
582     /* Extract the monster base speed */
583     m_ptr->mspeed = get_mspeed(floor_ptr, r_ptr);
584
585     /* Sub-alignment of a monster */
586     if (!is_pet(m_ptr) && !(r_ptr->flags3 & (RF3_EVIL | RF3_GOOD)))
587         m_ptr->sub_align = old_sub_align;
588     else {
589         m_ptr->sub_align = SUB_ALIGN_NEUTRAL;
590         if (r_ptr->flags3 & RF3_EVIL)
591             m_ptr->sub_align |= SUB_ALIGN_EVIL;
592         if (r_ptr->flags3 & RF3_GOOD)
593             m_ptr->sub_align |= SUB_ALIGN_GOOD;
594     }
595
596     m_ptr->exp = 0;
597
598     if (is_pet(m_ptr) || m_ptr->ml) {
599         if (!ignore_unview || player_can_see_bold(target_ptr, m_ptr->fy, m_ptr->fx)) {
600             if (target_ptr->image) {
601                 monster_race *hallu_race;
602
603                 do {
604                     hallu_race = &r_info[randint1(max_r_idx - 1)];
605                 } while (!hallu_race->name || (hallu_race->flags1 & RF1_UNIQUE));
606                 msg_format(_("%sは%sに進化した。", "%^s evolved into %s."), m_name, r_name + hallu_race->name);
607             } else {
608                 msg_format(_("%sは%sに進化した。", "%^s evolved into %s."), m_name, r_name + r_ptr->name);
609             }
610         }
611
612         if (!target_ptr->image)
613             r_info[old_r_idx].r_xtra1 |= MR1_EVOLUTION;
614
615         /* Now you feel very close to this pet. */
616         m_ptr->parent_m_idx = 0;
617     }
618
619     update_monster(target_ptr, m_idx, FALSE);
620     lite_spot(target_ptr, m_ptr->fy, m_ptr->fx);
621
622     if (m_idx == target_ptr->riding)
623         target_ptr->update |= PU_BONUS;
624 }
625
626 /*!
627  * @brief モンスターのHPをダメージに応じて減算する /
628  * Decreases monsters hit points, handling monster death.
629  * @param dam 与えたダメージ量
630  * @param m_idx ダメージを与えたモンスターのID
631  * @param fear ダメージによってモンスターが恐慌状態に陥ったならばTRUEを返す
632  * @param note モンスターが倒された際の特別なメッセージ述語
633  * @return なし
634  * @details
635  * <pre>
636  * We return TRUE if the monster has been killed (and deleted).
637  * We announce monster death (using an optional "death message"
638  * if given, and a otherwise a generic killed/destroyed message).
639  * Only "physical attacks" can induce the "You have slain" message.
640  * Missile and Spell attacks will induce the "dies" message, or
641  * various "specialized" messages.  Note that "You have destroyed"
642  * and "is destroyed" are synonyms for "You have slain" and "dies".
643  * Hack -- unseen monsters yield "You have killed it." message.
644  * Added fear (DGK) and check whether to print fear messages -CWS
645  * Made name, sex, and capitalization generic -BEN-
646  * As always, the "ghost" processing is a total hack.
647  * Hack -- we "delay" fear messages by passing around a "fear" flag.
648  * Consider decreasing monster experience over time, say,
649  * by using "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))"
650  * instead of simply "(m_exp * m_lev) / (p_lev)", to make the first
651  * monster worth more than subsequent monsters.  This would also need
652  * to induce changes in the monster recall code.
653  * </pre>
654  */
655 bool mon_take_hit(player_type *target_ptr, MONSTER_IDX m_idx, HIT_POINT dam, bool *fear, concptr note)
656 {
657     monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
658     monster_race *r_ptr = &r_info[m_ptr->r_idx];
659     monster_type exp_mon;
660
661     /* Innocent until proven otherwise */
662     bool innocent = TRUE, thief = FALSE;
663     int i;
664     HIT_POINT expdam;
665
666     (void)COPY(&exp_mon, m_ptr, monster_type);
667
668     expdam = (m_ptr->hp > dam) ? dam : m_ptr->hp;
669
670     get_exp_from_mon(target_ptr, expdam, &exp_mon);
671
672     /* Genocided by chaos patron */
673     if (!monster_is_valid(m_ptr))
674         m_idx = 0;
675
676     /* Redraw (later) if needed */
677     if (target_ptr->health_who == m_idx)
678         target_ptr->redraw |= (PR_HEALTH);
679     if (target_ptr->riding == m_idx)
680         target_ptr->redraw |= (PR_UHEALTH);
681
682     (void)set_monster_csleep(target_ptr, m_idx, 0);
683
684     /* Hack - Cancel any special player stealth magics. -LM- */
685     if (target_ptr->special_defense & NINJA_S_STEALTH) {
686         set_superstealth(target_ptr, FALSE);
687     }
688
689     /* Genocided by chaos patron */
690     if (!m_idx)
691         return TRUE;
692
693     m_ptr->hp -= dam;
694     m_ptr->dealt_damage += dam;
695
696     if (m_ptr->dealt_damage > m_ptr->max_maxhp * 100)
697         m_ptr->dealt_damage = m_ptr->max_maxhp * 100;
698
699     if (current_world_ptr->wizard) {
700         msg_format(_("合計%d/%dのダメージを与えた。", "You do %d (out of %d) damage."), m_ptr->dealt_damage, m_ptr->maxhp);
701     }
702
703     /* It is dead now */
704     if (m_ptr->hp < 0) {
705         GAME_TEXT m_name[MAX_NLEN];
706
707         if (r_info[m_ptr->r_idx].flags7 & RF7_TANUKI) {
708             /* You might have unmasked Tanuki first time */
709             r_ptr = &r_info[m_ptr->r_idx];
710             m_ptr->ap_r_idx = m_ptr->r_idx;
711             if (r_ptr->r_sights < MAX_SHORT)
712                 r_ptr->r_sights++;
713         }
714
715         if (m_ptr->mflag2 & MFLAG2_CHAMELEON) {
716             /* You might have unmasked Chameleon first time */
717             r_ptr = real_r_ptr(m_ptr);
718             if (r_ptr->r_sights < MAX_SHORT)
719                 r_ptr->r_sights++;
720         }
721
722         if (!(m_ptr->smart & SM_CLONED)) {
723             /* When the player kills a Unique, it stays dead */
724             if (r_ptr->flags1 & RF1_UNIQUE) {
725                 r_ptr->max_num = 0;
726
727                 /* Mega-Hack -- Banor & Lupart */
728                 if ((m_ptr->r_idx == MON_BANOR) || (m_ptr->r_idx == MON_LUPART)) {
729                     r_info[MON_BANORLUPART].max_num = 0;
730                     r_info[MON_BANORLUPART].r_pkills++;
731                     r_info[MON_BANORLUPART].r_akills++;
732                     if (r_info[MON_BANORLUPART].r_tkills < MAX_SHORT)
733                         r_info[MON_BANORLUPART].r_tkills++;
734                 } else if (m_ptr->r_idx == MON_BANORLUPART) {
735                     r_info[MON_BANOR].max_num = 0;
736                     r_info[MON_BANOR].r_pkills++;
737                     r_info[MON_BANOR].r_akills++;
738                     if (r_info[MON_BANOR].r_tkills < MAX_SHORT)
739                         r_info[MON_BANOR].r_tkills++;
740                     r_info[MON_LUPART].max_num = 0;
741                     r_info[MON_LUPART].r_pkills++;
742                     r_info[MON_LUPART].r_akills++;
743                     if (r_info[MON_LUPART].r_tkills < MAX_SHORT)
744                         r_info[MON_LUPART].r_tkills++;
745                 }
746             }
747
748             /* When the player kills a Nazgul, it stays dead */
749             else if (r_ptr->flags7 & RF7_NAZGUL)
750                 r_ptr->max_num--;
751         }
752
753         /* Count all monsters killed */
754         if (r_ptr->r_akills < MAX_SHORT)
755             r_ptr->r_akills++;
756
757         /* Recall even invisible uniques or winners */
758         if ((m_ptr->ml && !target_ptr->image) || (r_ptr->flags1 & RF1_UNIQUE)) {
759             /* Count kills this life */
760             if ((m_ptr->mflag2 & MFLAG2_KAGE) && (r_info[MON_KAGE].r_pkills < MAX_SHORT))
761                 r_info[MON_KAGE].r_pkills++;
762             else if (r_ptr->r_pkills < MAX_SHORT)
763                 r_ptr->r_pkills++;
764
765             /* Count kills in all lives */
766             if ((m_ptr->mflag2 & MFLAG2_KAGE) && (r_info[MON_KAGE].r_tkills < MAX_SHORT))
767                 r_info[MON_KAGE].r_tkills++;
768             else if (r_ptr->r_tkills < MAX_SHORT)
769                 r_ptr->r_tkills++;
770
771             /* Hack -- Auto-recall */
772             monster_race_track(target_ptr, m_ptr->ap_r_idx);
773         }
774
775         monster_desc(target_ptr, m_name, m_ptr, MD_TRUE_NAME);
776
777         /* Don't kill Amberites */
778         if ((r_ptr->flags3 & RF3_AMBERITE) && one_in_(2)) {
779             int curses = 1 + randint1(3);
780             bool stop_ty = FALSE;
781             int count = 0;
782
783             msg_format(_("%^sは恐ろしい血の呪いをあなたにかけた!", "%^s puts a terrible blood curse on you!"), m_name);
784             curse_equipment(target_ptr, 100, 50);
785
786             do {
787                 stop_ty = activate_ty_curse(target_ptr, stop_ty, &count);
788             } while (--curses);
789         }
790
791         if (r_ptr->flags2 & RF2_CAN_SPEAK) {
792             char line_got[1024];
793             if (!get_rnd_line(_("mondeath_j.txt", "mondeath.txt"), m_ptr->r_idx, line_got)) {
794                 msg_format("%^s %s", m_name, line_got);
795             }
796
797 #ifdef WORLD_SCORE
798             if (m_ptr->r_idx == MON_SERPENT) {
799                 screen_dump = make_screen_dump(target_ptr, process_autopick_file_command);
800             }
801 #endif
802         }
803
804         if (!(d_info[target_ptr->dungeon_idx].flags1 & DF1_BEGINNER)) {
805             if (!target_ptr->current_floor_ptr->dun_level && !target_ptr->ambush_flag && !target_ptr->current_floor_ptr->inside_arena) {
806                 chg_virtue(target_ptr, V_VALOUR, -1);
807             } else if (r_ptr->level > target_ptr->current_floor_ptr->dun_level) {
808                 if (randint1(10) <= (r_ptr->level - target_ptr->current_floor_ptr->dun_level))
809                     chg_virtue(target_ptr, V_VALOUR, 1);
810             }
811             if (r_ptr->level > 60) {
812                 chg_virtue(target_ptr, V_VALOUR, 1);
813             }
814             if (r_ptr->level >= 2 * (target_ptr->lev + 1))
815                 chg_virtue(target_ptr, V_VALOUR, 2);
816         }
817
818         if (r_ptr->flags1 & RF1_UNIQUE) {
819             if (r_ptr->flags3 & (RF3_EVIL | RF3_GOOD))
820                 chg_virtue(target_ptr, V_HARMONY, 2);
821
822             if (r_ptr->flags3 & RF3_GOOD) {
823                 chg_virtue(target_ptr, V_UNLIFE, 2);
824                 chg_virtue(target_ptr, V_VITALITY, -2);
825             }
826
827             if (one_in_(3))
828                 chg_virtue(target_ptr, V_INDIVIDUALISM, -1);
829         }
830
831         if (m_ptr->r_idx == MON_BEGGAR || m_ptr->r_idx == MON_LEPER) {
832             chg_virtue(target_ptr, V_COMPASSION, -1);
833         }
834
835         if ((r_ptr->flags3 & RF3_GOOD) && ((r_ptr->level) / 10 + (3 * target_ptr->current_floor_ptr->dun_level) >= randint1(100)))
836             chg_virtue(target_ptr, V_UNLIFE, 1);
837
838         if (r_ptr->d_char == 'A') {
839             if (r_ptr->flags1 & RF1_UNIQUE)
840                 chg_virtue(target_ptr, V_FAITH, -2);
841             else if ((r_ptr->level) / 10 + (3 * target_ptr->current_floor_ptr->dun_level) >= randint1(100)) {
842                 if (r_ptr->flags3 & RF3_GOOD)
843                     chg_virtue(target_ptr, V_FAITH, -1);
844                 else
845                     chg_virtue(target_ptr, V_FAITH, 1);
846             }
847         } else if (r_ptr->flags3 & RF3_DEMON) {
848             if (r_ptr->flags1 & RF1_UNIQUE)
849                 chg_virtue(target_ptr, V_FAITH, 2);
850             else if ((r_ptr->level) / 10 + (3 * target_ptr->current_floor_ptr->dun_level) >= randint1(100))
851                 chg_virtue(target_ptr, V_FAITH, 1);
852         }
853
854         if ((r_ptr->flags3 & RF3_UNDEAD) && (r_ptr->flags1 & RF1_UNIQUE))
855             chg_virtue(target_ptr, V_VITALITY, 2);
856
857         if (r_ptr->r_deaths) {
858             if (r_ptr->flags1 & RF1_UNIQUE) {
859                 chg_virtue(target_ptr, V_HONOUR, 10);
860             } else if ((r_ptr->level) / 10 + (2 * target_ptr->current_floor_ptr->dun_level) >= randint1(100)) {
861                 chg_virtue(target_ptr, V_HONOUR, 1);
862             }
863         }
864         if ((r_ptr->flags2 & RF2_MULTIPLY) && (r_ptr->r_akills > 1000) && one_in_(10)) {
865             chg_virtue(target_ptr, V_VALOUR, -1);
866         }
867
868         for (i = 0; i < 4; i++) {
869             if (r_ptr->blow[i].d_dice != 0)
870                 innocent = FALSE; /* Murderer! */
871
872             if ((r_ptr->blow[i].effect == RBE_EAT_ITEM) || (r_ptr->blow[i].effect == RBE_EAT_GOLD))
873
874                 thief = TRUE; /* Thief! */
875         }
876
877         /* The new law says it is illegal to live in the dungeon */
878         if (r_ptr->level != 0)
879             innocent = FALSE;
880
881         if (thief) {
882             if (r_ptr->flags1 & RF1_UNIQUE)
883                 chg_virtue(target_ptr, V_JUSTICE, 3);
884             else if (1 + ((r_ptr->level) / 10 + (2 * target_ptr->current_floor_ptr->dun_level)) >= randint1(100))
885                 chg_virtue(target_ptr, V_JUSTICE, 1);
886         } else if (innocent) {
887             chg_virtue(target_ptr, V_JUSTICE, -1);
888         }
889
890         if ((r_ptr->flags3 & RF3_ANIMAL) && !(r_ptr->flags3 & RF3_EVIL) && !(r_ptr->flags4 & ~(RF4_NOMAGIC_MASK))
891             && !(r_ptr->a_ability_flags1 & ~(RF5_NOMAGIC_MASK)) && !(r_ptr->a_ability_flags2 & ~(RF6_NOMAGIC_MASK))) {
892             if (one_in_(4))
893                 chg_virtue(target_ptr, V_NATURE, -1);
894         }
895
896         if ((r_ptr->flags1 & RF1_UNIQUE) && record_destroy_uniq) {
897             char note_buf[160];
898             sprintf(note_buf, "%s%s", r_name + r_ptr->name, (m_ptr->smart & SM_CLONED) ? _("(クローン)", "(Clone)") : "");
899             exe_write_diary(target_ptr, DIARY_UNIQUE, 0, note_buf);
900         }
901
902         /* Make a sound */
903         sound(SOUND_KILL);
904
905         /* Death by Missile/Spell attack */
906         if (note) {
907             msg_format("%^s%s", m_name, note);
908         }
909
910         /* Death by physical attack -- invisible monster */
911         else if (!m_ptr->ml) {
912 #ifdef JP
913             if (is_echizen(target_ptr))
914                 msg_format("せっかくだから%sを殺した。", m_name);
915             else
916                 msg_format("%sを殺した。", m_name);
917 #else
918             msg_format("You have killed %s.", m_name);
919 #endif
920
921         }
922
923         /* Death by Physical attack -- non-living monster */
924         else if (!monster_living(m_ptr->r_idx)) {
925             bool explode = FALSE;
926
927             for (i = 0; i < 4; i++) {
928                 if (r_ptr->blow[i].method == RBM_EXPLODE)
929                     explode = TRUE;
930             }
931
932             /* Special note at death */
933             if (explode)
934                 msg_format(_("%sは爆発して粉々になった。", "%^s explodes into tiny shreds."), m_name);
935             else {
936 #ifdef JP
937                 if (is_echizen(target_ptr))
938                     msg_format("せっかくだから%sを倒した。", m_name);
939                 else
940                     msg_format("%sを倒した。", m_name);
941 #else
942                 msg_format("You have destroyed %s.", m_name);
943 #endif
944             }
945         }
946
947         /* Death by Physical attack -- living monster */
948         else {
949 #ifdef JP
950             if (is_echizen(target_ptr))
951                 msg_format("せっかくだから%sを葬り去った。", m_name);
952             else
953                 msg_format("%sを葬り去った。", m_name);
954 #else
955             msg_format("You have slain %s.", m_name);
956 #endif
957         }
958         if ((r_ptr->flags1 & RF1_UNIQUE) && !(m_ptr->smart & SM_CLONED) && !vanilla_town) {
959             for (i = 0; i < MAX_BOUNTY; i++) {
960                 if ((current_world_ptr->bounty_r_idx[i] == m_ptr->r_idx) && !(m_ptr->mflag2 & MFLAG2_CHAMELEON)) {
961                     msg_format(_("%sの首には賞金がかかっている。", "There is a price on %s's head."), m_name);
962                     break;
963                 }
964             }
965         }
966
967         /* Generate treasure */
968         monster_death(target_ptr, m_idx, TRUE);
969
970         /* Mega hack : replace IKETA to BIKETAL */
971         if ((m_ptr->r_idx == MON_IKETA) && !(target_ptr->current_floor_ptr->inside_arena || target_ptr->phase_out)) {
972             POSITION dummy_y = m_ptr->fy;
973             POSITION dummy_x = m_ptr->fx;
974             BIT_FLAGS mode = 0L;
975             if (is_pet(m_ptr))
976                 mode |= PM_FORCE_PET;
977             delete_monster_idx(target_ptr, m_idx);
978             if (summon_named_creature(target_ptr, 0, dummy_y, dummy_x, MON_BIKETAL, mode)) {
979                 msg_print(_("「ハァッハッハッハ!!私がバイケタルだ!!」", "Uwa-hahaha!  *I* am Biketal!"));
980             }
981         } else {
982             delete_monster_idx(target_ptr, m_idx);
983         }
984
985         get_exp_from_mon(target_ptr, (long)exp_mon.max_maxhp * 2, &exp_mon);
986
987         /* Not afraid */
988         (*fear) = FALSE;
989
990         /* Monster is dead */
991         return TRUE;
992     }
993
994     /* Mega-Hack -- Pain cancels fear */
995     if (monster_fear_remaining(m_ptr) && (dam > 0)) {
996         /* Cure fear */
997         if (set_monster_monfear(target_ptr, m_idx, monster_fear_remaining(m_ptr) - randint1(dam))) {
998             /* No more fear */
999             (*fear) = FALSE;
1000         }
1001     }
1002
1003     /* Sometimes a monster gets scared by damage */
1004     if (!monster_fear_remaining(m_ptr) && !(r_ptr->flags3 & (RF3_NO_FEAR))) {
1005         /* Percentage of fully healthy */
1006         int percentage = (100L * m_ptr->hp) / m_ptr->maxhp;
1007
1008         /*
1009          * Run (sometimes) if at 10% or less of max hit points,
1010          * or (usually) when hit for half its current hit points
1011          */
1012         if ((randint1(10) >= percentage) || ((dam >= m_ptr->hp) && (randint0(100) < 80))) {
1013             /* Hack -- note fear */
1014             (*fear) = TRUE;
1015
1016             /* Hack -- Add some timed fear */
1017             (void)set_monster_monfear(target_ptr, m_idx, (randint1(10) + (((dam >= m_ptr->hp) && (percentage > 7)) ? 20 : ((11 - percentage) * 5))));
1018         }
1019     }
1020
1021     /* Not dead yet */
1022     return FALSE;
1023 }
1024
1025 bool monster_is_valid(monster_type *m_ptr) { return (m_ptr->r_idx != 0); }
1026
1027 TIME_EFFECT monster_csleep_remaining(monster_type *m_ptr) { return m_ptr->mtimed[MTIMED_CSLEEP]; }
1028
1029 TIME_EFFECT monster_fast_remaining(monster_type *m_ptr) { return m_ptr->mtimed[MTIMED_FAST]; }
1030
1031 TIME_EFFECT monster_slow_remaining(monster_type *m_ptr) { return m_ptr->mtimed[MTIMED_SLOW]; }
1032
1033 TIME_EFFECT monster_stunned_remaining(monster_type *m_ptr) { return m_ptr->mtimed[MTIMED_STUNNED]; }
1034
1035 TIME_EFFECT monster_confused_remaining(monster_type *m_ptr) { return m_ptr->mtimed[MTIMED_CONFUSED]; }
1036
1037 TIME_EFFECT monster_fear_remaining(monster_type *m_ptr) { return m_ptr->mtimed[MTIMED_MONFEAR]; }
1038
1039 TIME_EFFECT monster_invulner_remaining(monster_type *m_ptr) { return m_ptr->mtimed[MTIMED_INVULNER]; }