OSDN Git Service

[Refactor] #37353 inside_arena を player_type から floor_type へ移動. / Move inside_arena...
[hengband/hengband.git] / src / player-damage.c
1 #include "angband.h"
2 #include "core.h"
3 #include "util.h"
4 #include "term.h"
5
6 #include "avatar.h"
7 #include "cmd-dump.h"
8 #include "realm-song.h"
9 #include "floor.h"
10 #include "artifact.h"
11 #include "object-flavor.h"
12 #include "object-hook.h"
13 #include "object-broken.h"
14 #include "player-move.h"
15 #include "player-damage.h"
16 #include "player-personality.h"
17 #include "player-status.h"
18 #include "player-effects.h"
19 #include "player-class.h"
20 #include "monster-spell.h"
21 #include "world.h"
22 #include "view-mainwindow.h"
23 #include "quest.h"
24 #include "report.h"
25 #include "wild.h"
26 #include "save.h"
27 #include "files.h"
28
29
30
31 /*!
32 * @brief アイテムが指定確率で破損するかどうかを判定する /
33 * Destroys a type of item on a given percent chance
34 * @param typ 破損判定関数ポインタ
35 * @param perc 基本確率
36 * @return 破損したアイテムの数
37 * @details
38 * Note that missiles are no longer necessarily all destroyed
39 * Destruction taken from "melee.c" code for "stealing".
40 * New-style wands and rods handled correctly. -LM-
41 * Returns number of items destroyed.
42 */
43 int inven_damage(inven_func typ, int perc)
44 {
45         INVENTORY_IDX i;
46         int j, k, amt;
47         object_type *o_ptr;
48         GAME_TEXT o_name[MAX_NLEN];
49
50         if (CHECK_MULTISHADOW(p_ptr)) return 0;
51
52         if (p_ptr->current_floor_ptr->inside_arena) return 0;
53
54         /* Count the casualties */
55         k = 0;
56
57         /* Scan through the slots backwards */
58         for (i = 0; i < INVEN_PACK; i++)
59         {
60                 o_ptr = &p_ptr->inventory_list[i];
61                 if (!o_ptr->k_idx) continue;
62
63                 /* Hack -- for now, skip artifacts */
64                 if (object_is_artifact(o_ptr)) continue;
65
66                 /* Give this item slot a shot at death */
67                 if ((*typ)(o_ptr))
68                 {
69                         /* Count the casualties */
70                         for (amt = j = 0; j < o_ptr->number; ++j)
71                         {
72                                 if (randint0(100) < perc) amt++;
73                         }
74
75                         /* Some casualities */
76                         if (amt)
77                         {
78                                 object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
79
80                                 msg_format(_("%s(%c)が%s壊れてしまった!", "%sour %s (%c) %s destroyed!"),
81 #ifdef JP
82                                         o_name, index_to_label(i), ((o_ptr->number > 1) ?
83                                                 ((amt == o_ptr->number) ? "全部" : (amt > 1 ? "何個か" : "一個")) : ""));
84 #else
85                                         ((o_ptr->number > 1) ? ((amt == o_ptr->number) ? "All of y" :
86                                                 (amt > 1 ? "Some of y" : "One of y")) : "Y"), o_name, index_to_label(i), ((amt > 1) ? "were" : "was"));
87 #endif
88
89 #ifdef JP
90                                 if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (p_ptr->inventory_list[INVEN_BOW].name1 == ART_CRIMSON))
91                                         msg_print("やりやがったな!");
92                                 else if ((p_ptr->pseikaku == SEIKAKU_CHARGEMAN))
93                                 {
94                                         if (randint0(2) == 0) msg_print(_("ジュラル星人め!", ""));
95                                         else msg_print(_("弱い者いじめは止めるんだ!", ""));
96                                 }
97 #endif
98
99                                 /* Potions smash open */
100                                 if (object_is_potion(o_ptr))
101                                 {
102                                         (void)potion_smash_effect(0, p_ptr->y, p_ptr->x, o_ptr->k_idx);
103                                 }
104
105                                 /* Reduce the charges of rods/wands */
106                                 reduce_charges(o_ptr, amt);
107
108                                 /* Destroy "amt" items */
109                                 inven_item_increase(i, -amt);
110                                 inven_item_optimize(i);
111
112                                 /* Count the casualties */
113                                 k += amt;
114                         }
115                 }
116         }
117
118         /* Return the casualty count */
119         return (k);
120 }
121
122
123 /*!
124 * @brief 酸攻撃による装備のAC劣化処理 /
125 * Acid has hit the player, attempt to affect some armor.
126 * @return 装備による軽減があったならTRUEを返す
127 * @details
128 * Note that the "base armor" of an object never changes.
129 * If any armor is damaged (or resists), the player takes less damage.
130 */
131 static bool acid_minus_ac(player_type *creature_ptr)
132 {
133         object_type *o_ptr = NULL;
134         BIT_FLAGS flgs[TR_FLAG_SIZE];
135         GAME_TEXT o_name[MAX_NLEN];
136
137         /* Pick a (possibly empty) creature_ptr->inventory_list slot */
138         switch (randint1(7))
139         {
140         case 1: o_ptr = &creature_ptr->inventory_list[INVEN_RARM]; break;
141         case 2: o_ptr = &creature_ptr->inventory_list[INVEN_LARM]; break;
142         case 3: o_ptr = &creature_ptr->inventory_list[INVEN_BODY]; break;
143         case 4: o_ptr = &creature_ptr->inventory_list[INVEN_OUTER]; break;
144         case 5: o_ptr = &creature_ptr->inventory_list[INVEN_HANDS]; break;
145         case 6: o_ptr = &creature_ptr->inventory_list[INVEN_HEAD]; break;
146         case 7: o_ptr = &creature_ptr->inventory_list[INVEN_FEET]; break;
147         }
148
149         if (!o_ptr->k_idx) return (FALSE);
150         if (!object_is_armour(o_ptr)) return (FALSE);
151
152         object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
153         object_flags(o_ptr, flgs);
154         /* No damage left to be done */
155         if (o_ptr->ac + o_ptr->to_a <= 0)
156         {
157                 msg_format(_("%sは既にボロボロだ!", "Your %s is already crumble!"), o_name);
158                 return (FALSE);
159         }
160
161         /* Object resists */
162         if (have_flag(flgs, TR_IGNORE_ACID))
163         {
164                 msg_format(_("しかし%sには効果がなかった!", "Your %s is unaffected!"), o_name);
165                 return (TRUE);
166         }
167
168         msg_format(_("%sが酸で腐食した!", "Your %s is corroded!"), o_name);
169
170         /* Damage the item */
171         o_ptr->to_a--;
172
173         /* Calculate bonuses */
174         creature_ptr->update |= (PU_BONUS);
175         creature_ptr->window |= (PW_EQUIP | PW_PLAYER);
176
177         calc_android_exp(creature_ptr);
178
179         /* Item was damaged */
180         return (TRUE);
181 }
182
183
184 /*!
185 * @brief 酸属性によるプレイヤー損害処理 /
186 * Hurt the player with Acid
187 * @param dam 基本ダメージ量
188 * @param kb_str ダメージ原因記述
189 * @param monspell 原因となったモンスター特殊攻撃ID
190 * @param aura オーラよるダメージが原因ならばTRUE
191 * @return 修正HPダメージ量
192 */
193 HIT_POINT acid_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
194 {
195         HIT_POINT get_damage;
196         int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
197         bool double_resist = IS_OPPOSE_ACID();
198
199         /* Total Immunity */
200         if (p_ptr->immune_acid || (dam <= 0))
201         {
202                 learn_spell(monspell);
203                 return 0;
204         }
205
206         /* Vulnerability (Ouch!) */
207         if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
208         if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
209
210         /* Resist the damage */
211         if (p_ptr->resist_acid) dam = (dam + 2) / 3;
212         if (double_resist) dam = (dam + 2) / 3;
213
214         if (aura || !CHECK_MULTISHADOW(p_ptr))
215         {
216                 if ((!(double_resist || p_ptr->resist_acid)) &&
217                         one_in_(HURT_CHANCE))
218                         (void)do_dec_stat(p_ptr, A_CHR);
219
220                 /* If any armor gets hit, defend the player */
221                 if (acid_minus_ac(p_ptr)) dam = (dam + 1) / 2;
222         }
223
224         get_damage = take_hit(p_ptr, aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
225
226         /* Inventory damage */
227         if (!aura && !(double_resist && p_ptr->resist_acid))
228                 inven_damage(set_acid_destroy, inv);
229         return get_damage;
230 }
231
232
233 /*!
234 * @brief 電撃属性によるプレイヤー損害処理 /
235 * Hurt the player with electricity
236 * @param dam 基本ダメージ量
237 * @param kb_str ダメージ原因記述
238 * @param monspell 原因となったモンスター特殊攻撃ID
239 * @param aura オーラよるダメージが原因ならばTRUE
240 * @return 修正HPダメージ量
241 */
242 HIT_POINT elec_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
243 {
244         HIT_POINT get_damage;
245         int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
246         bool double_resist = IS_OPPOSE_ELEC();
247
248         /* Total immunity */
249         if (p_ptr->immune_elec || (dam <= 0))
250         {
251                 learn_spell(monspell);
252                 return 0;
253         }
254
255         /* Vulnerability (Ouch!) */
256         if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
257         if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
258         if (PRACE_IS_(p_ptr, RACE_ANDROID)) dam += dam / 3;
259
260         /* Resist the damage */
261         if (p_ptr->resist_elec) dam = (dam + 2) / 3;
262         if (double_resist) dam = (dam + 2) / 3;
263
264         if (aura || !CHECK_MULTISHADOW(p_ptr))
265         {
266                 if ((!(double_resist || p_ptr->resist_elec)) &&
267                         one_in_(HURT_CHANCE))
268                         (void)do_dec_stat(p_ptr, A_DEX);
269         }
270
271         get_damage = take_hit(p_ptr, aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
272
273         /* Inventory damage */
274         if (!aura && !(double_resist && p_ptr->resist_elec))
275                 inven_damage(set_elec_destroy, inv);
276
277         return get_damage;
278 }
279
280
281 /*!
282 * @brief 火炎属性によるプレイヤー損害処理 /
283 * Hurt the player with Fire
284 * @param dam 基本ダメージ量
285 * @param kb_str ダメージ原因記述
286 * @param monspell 原因となったモンスター特殊攻撃ID
287 * @param aura オーラよるダメージが原因ならばTRUE
288 * @return 修正HPダメージ量
289 */
290 HIT_POINT fire_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
291 {
292         HIT_POINT get_damage;
293         int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
294         bool double_resist = IS_OPPOSE_FIRE();
295
296         /* Totally immune */
297         if (p_ptr->immune_fire || (dam <= 0))
298         {
299                 learn_spell(monspell);
300                 return 0;
301         }
302
303         /* Vulnerability (Ouch!) */
304         if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
305         if (PRACE_IS_(p_ptr, RACE_ENT)) dam += dam / 3;
306         if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
307
308         /* Resist the damage */
309         if (p_ptr->resist_fire) dam = (dam + 2) / 3;
310         if (double_resist) dam = (dam + 2) / 3;
311
312         if (aura || !CHECK_MULTISHADOW(p_ptr))
313         {
314                 if ((!(double_resist || p_ptr->resist_fire)) &&
315                         one_in_(HURT_CHANCE))
316                         (void)do_dec_stat(p_ptr, A_STR);
317         }
318
319         get_damage = take_hit(p_ptr, aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
320
321         /* Inventory damage */
322         if (!aura && !(double_resist && p_ptr->resist_fire))
323                 inven_damage(set_fire_destroy, inv);
324
325         return get_damage;
326 }
327
328
329 /*!
330 * @brief 冷気属性によるプレイヤー損害処理 /
331 * Hurt the player with Cold
332 * @param dam 基本ダメージ量
333 * @param kb_str ダメージ原因記述
334 * @param monspell 原因となったモンスター特殊攻撃ID
335 * @param aura オーラよるダメージが原因ならばTRUE
336 * @return 修正HPダメージ量
337 */
338 HIT_POINT cold_dam(HIT_POINT dam, concptr kb_str, int monspell, bool aura)
339 {
340         HIT_POINT get_damage;
341         int inv = (dam < 30) ? 1 : (dam < 60) ? 2 : 3;
342         bool double_resist = IS_OPPOSE_COLD();
343
344         /* Total immunity */
345         if (p_ptr->immune_cold || (dam <= 0))
346         {
347                 learn_spell(monspell);
348                 return 0;
349         }
350
351         /* Vulnerability (Ouch!) */
352         if (p_ptr->muta3 & MUT3_VULN_ELEM) dam *= 2;
353         if (p_ptr->special_defense & KATA_KOUKIJIN) dam += dam / 3;
354
355         /* Resist the damage */
356         if (p_ptr->resist_cold) dam = (dam + 2) / 3;
357         if (double_resist) dam = (dam + 2) / 3;
358
359         if (aura || !CHECK_MULTISHADOW(p_ptr))
360         {
361                 if ((!(double_resist || p_ptr->resist_cold)) &&
362                         one_in_(HURT_CHANCE))
363                         (void)do_dec_stat(p_ptr, A_STR);
364         }
365
366         get_damage = take_hit(p_ptr, aura ? DAMAGE_NOESCAPE : DAMAGE_ATTACK, dam, kb_str, monspell);
367
368         /* Inventory damage */
369         if (!aura && !(double_resist && p_ptr->resist_cold))
370                 inven_damage(set_cold_destroy, inv);
371
372         return get_damage;
373 }
374
375
376 /*
377  * Decreases players hit points and sets death flag if necessary
378  *
379  * Invulnerability needs to be changed into a "shield"
380  *
381  * Hack -- this function allows the user to save (or quit)
382  * the game when he dies, since the "You die." message is shown before
383  * setting the player to "dead".
384  */
385
386 int take_hit(player_type *creature_ptr, int damage_type, HIT_POINT damage, concptr hit_from, int monspell)
387 {
388         int old_chp = creature_ptr->chp;
389
390         char death_message[1024];
391         char tmp[1024];
392
393         int warning = (creature_ptr->mhp * hitpoint_warn / 10);
394         if (creature_ptr->is_dead) return 0;
395
396         if (creature_ptr->sutemi) damage *= 2;
397         if (creature_ptr->special_defense & KATA_IAI) damage += (damage + 4) / 5;
398
399         if (easy_band) damage = (damage + 1) / 2;
400
401         if (damage_type != DAMAGE_USELIFE)
402         {
403                 disturb(p_ptr, TRUE, TRUE);
404                 if (auto_more)
405                 {
406                         creature_ptr->now_damaged = TRUE;
407                 }
408         }
409
410         if (monspell >= 0) learn_spell(monspell);
411
412         /* Mega-Hack -- Apply "invulnerability" */
413         if ((damage_type != DAMAGE_USELIFE) && (damage_type != DAMAGE_LOSELIFE))
414         {
415                 if (IS_INVULN() && (damage < 9000))
416                 {
417                         if (damage_type == DAMAGE_FORCE)
418                         {
419                                 msg_print(_("バリアが切り裂かれた!", "The attack cuts your shield of invulnerability open!"));
420                         }
421                         else if (one_in_(PENETRATE_INVULNERABILITY))
422                         {
423                                 msg_print(_("無敵のバリアを破って攻撃された!", "The attack penetrates your shield of invulnerability!"));
424                         }
425                         else
426                         {
427                                 return 0;
428                         }
429                 }
430
431                 if (CHECK_MULTISHADOW(p_ptr))
432                 {
433                         if (damage_type == DAMAGE_FORCE)
434                         {
435                                 msg_print(_("幻影もろとも体が切り裂かれた!", "The attack hits Shadow together with you!"));
436                         }
437                         else if (damage_type == DAMAGE_ATTACK)
438                         {
439                                 msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, you are unharmed!"));
440                                 return 0;
441                         }
442                 }
443
444                 if (creature_ptr->wraith_form)
445                 {
446                         if (damage_type == DAMAGE_FORCE)
447                         {
448                                 msg_print(_("半物質の体が切り裂かれた!", "The attack cuts through your ethereal body!"));
449                         }
450                         else
451                         {
452                                 damage /= 2;
453                                 if ((damage == 0) && one_in_(2)) damage = 1;
454                         }
455                 }
456
457                 if (creature_ptr->special_defense & KATA_MUSOU)
458                 {
459                         damage /= 2;
460                         if ((damage == 0) && one_in_(2)) damage = 1;
461                 }
462         } /* not if LOSELIFE USELIFE */
463
464         /* Hurt the player */
465         creature_ptr->chp -= damage;
466         if (damage_type == DAMAGE_GENO && creature_ptr->chp < 0)
467         {
468                 damage += creature_ptr->chp;
469                 creature_ptr->chp = 0;
470         }
471
472         /* Display the hitpoints */
473         creature_ptr->redraw |= (PR_HP);
474
475         creature_ptr->window |= (PW_PLAYER);
476
477         if (damage_type != DAMAGE_GENO && creature_ptr->chp == 0)
478         {
479                 chg_virtue(creature_ptr, V_SACRIFICE, 1);
480                 chg_virtue(creature_ptr, V_CHANCE, 2);
481         }
482
483         /* Dead player */
484         if (creature_ptr->chp < 0)
485         {
486                 bool android = (creature_ptr->prace == RACE_ANDROID ? TRUE : FALSE);
487
488 #ifdef JP       /* 死んだ時に強制終了して死を回避できなくしてみた by Habu */
489                 if (!cheat_save)
490                         if (!save_player()) msg_print("セーブ失敗!");
491 #endif
492
493                 sound(SOUND_DEATH);
494
495                 chg_virtue(creature_ptr, V_SACRIFICE, 10);
496
497                 handle_stuff();
498                 creature_ptr->leaving = TRUE;
499
500                 /* Note death */
501                 creature_ptr->is_dead = TRUE;
502
503                 if (creature_ptr->current_floor_ptr->inside_arena)
504                 {
505                         concptr m_name = r_name + r_info[arena_info[creature_ptr->arena_number].r_idx].name;
506                         msg_format(_("あなたは%sの前に敗れ去った。", "You are beaten by %s."), m_name);
507                         msg_print(NULL);
508                         if (record_arena) exe_write_diary(p_ptr, NIKKI_ARENA, -1 - creature_ptr->arena_number, m_name);
509                 }
510                 else
511                 {
512                         QUEST_IDX q_idx = quest_number(p_ptr->current_floor_ptr->dun_level);
513                         bool seppuku = streq(hit_from, "Seppuku");
514                         bool winning_seppuku = creature_ptr->total_winner && seppuku;
515
516                         play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_GAMEOVER);
517
518 #ifdef WORLD_SCORE
519                         /* Make screen dump */
520                         screen_dump = make_screen_dump();
521 #endif
522
523                         /* Note cause of death */
524                         if (seppuku)
525                         {
526                                 strcpy(creature_ptr->died_from, hit_from);
527 #ifdef JP
528                                 if (!winning_seppuku) strcpy(creature_ptr->died_from, "切腹");
529 #endif
530                         }
531                         else
532                         {
533                                 char dummy[1024];
534 #ifdef JP
535                                 sprintf(dummy, "%s%s%s", !creature_ptr->paralyzed ? "" : creature_ptr->free_act ? "彫像状態で" : "麻痺状態で", creature_ptr->image ? "幻覚に歪んだ" : "", hit_from);
536 #else
537                                 sprintf(dummy, "%s%s", hit_from, !creature_ptr->paralyzed ? "" : " while helpless");
538 #endif
539                                 my_strcpy(creature_ptr->died_from, dummy, sizeof creature_ptr->died_from);
540                         }
541
542                         /* No longer a winner */
543                         creature_ptr->total_winner = FALSE;
544
545                         if (winning_seppuku)
546                         {
547                                 exe_write_diary(p_ptr, NIKKI_BUNSHOU, 0, _("勝利の後切腹した。", "did Seppuku after the winning."));
548                         }
549                         else
550                         {
551                                 char buf[20];
552
553                                 if (creature_ptr->current_floor_ptr->inside_arena)
554                                         strcpy(buf, _("アリーナ", "in the Arena"));
555                                 else if (!p_ptr->current_floor_ptr->dun_level)
556                                         strcpy(buf, _("地上", "on the surface"));
557                                 else if (q_idx && (is_fixed_quest_idx(q_idx) &&
558                                         !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
559                                         strcpy(buf, _("クエスト", "in a quest"));
560                                 else
561                                         sprintf(buf, _("%d階", "level %d"), (int)p_ptr->current_floor_ptr->dun_level);
562
563                                 sprintf(tmp, _("%sで%sに殺された。", "killed by %s %s."), buf, creature_ptr->died_from);
564                                 exe_write_diary(p_ptr, NIKKI_BUNSHOU, 0, tmp);
565                         }
566
567                         exe_write_diary(p_ptr, NIKKI_GAMESTART, 1, _("-------- ゲームオーバー --------", "--------   Game  Over   --------"));
568                         exe_write_diary(p_ptr, NIKKI_BUNSHOU, 1, "\n\n\n\n");
569
570                         flush();
571
572                         if (get_check_strict(_("画面を保存しますか?", "Dump the screen? "), CHECK_NO_HISTORY))
573                         {
574                                 do_cmd_save_screen();
575                         }
576
577                         flush();
578
579                         /* Initialize "last message" buffer */
580                         if (creature_ptr->last_message) string_free(creature_ptr->last_message);
581                         creature_ptr->last_message = NULL;
582
583                         /* Hack -- Note death */
584                         if (!last_words)
585                         {
586 #ifdef JP
587                                 msg_format("あなたは%sました。", android ? "壊れ" : "死に");
588 #else
589                                 msg_print(android ? "You are broken." : "You die.");
590 #endif
591
592                                 msg_print(NULL);
593                         }
594                         else
595                         {
596                                 if (winning_seppuku)
597                                 {
598                                         get_rnd_line(_("seppuku_j.txt", "seppuku.txt"), 0, death_message);
599                                 }
600                                 else
601                                 {
602                                         get_rnd_line(_("death_j.txt", "death.txt"), 0, death_message);
603                                 }
604
605                                 do
606                                 {
607 #ifdef JP
608                                         while (!get_string(winning_seppuku ? "辞世の句: " : "断末魔の叫び: ", death_message, 1024));
609 #else
610                                         while (!get_string("Last word: ", death_message, 1024));
611 #endif
612                                 } while (winning_seppuku && !get_check_strict(_("よろしいですか?", "Are you sure? "), CHECK_NO_HISTORY));
613
614                                 if (death_message[0] == '\0')
615                                 {
616 #ifdef JP
617                                         strcpy(death_message, format("あなたは%sました。", android ? "壊れ" : "死に"));
618 #else
619                                         strcpy(death_message, android ? "You are broken." : "You die.");
620 #endif
621                                 }
622                                 else creature_ptr->last_message = string_make(death_message);
623
624 #ifdef JP
625                                 if (winning_seppuku)
626                                 {
627                                         int i, len;
628                                         int w = Term->wid;
629                                         int h = Term->hgt;
630                                         int msg_pos_x[9] = { 5,  7,  9, 12,  14,  17,  19,  21, 23 };
631                                         int msg_pos_y[9] = { 3,  4,  5,  4,   5,   4,   5,   6,  4 };
632                                         concptr str;
633                                         char* str2;
634
635                                         Term_clear();
636
637                                         /* 桜散る */
638                                         for (i = 0; i < 40; i++)
639                                                 Term_putstr(randint0(w / 2) * 2, randint0(h), 2, TERM_VIOLET, "υ");
640
641                                         str = death_message;
642                                         if (strncmp(str, "「", 2) == 0) str += 2;
643
644                                         str2 = my_strstr(str, "」");
645                                         if (str2 != NULL) *str2 = '\0';
646
647                                         i = 0;
648                                         while (i < 9)
649                                         {
650                                                 str2 = my_strstr(str, " ");
651                                                 if (str2 == NULL) len = strlen(str);
652                                                 else len = str2 - str;
653
654                                                 if (len != 0)
655                                                 {
656                                                         Term_putstr_v(w * 3 / 4 - 2 - msg_pos_x[i] * 2, msg_pos_y[i], len,
657                                                                 TERM_WHITE, str);
658                                                         if (str2 == NULL) break;
659                                                         i++;
660                                                 }
661                                                 str = str2 + 1;
662                                                 if (*str == 0) break;
663                                         }
664
665                                         /* Hide cursor */
666                                         Term_putstr(w - 1, h - 1, 1, TERM_WHITE, " ");
667
668                                         flush();
669 #ifdef WORLD_SCORE
670                                         /* Make screen dump */
671                                         screen_dump = make_screen_dump();
672 #endif
673
674                                         /* Wait a key press */
675                                         (void)inkey();
676                                 }
677                                 else
678 #endif
679                                         msg_print(death_message);
680                         }
681                 }
682
683                 /* Dead */
684                 return damage;
685         }
686
687         handle_stuff();
688
689         /* Hitpoint warning */
690         if (creature_ptr->chp < warning)
691         {
692                 /* Hack -- bell on first notice */
693                 if (old_chp > warning) bell();
694
695                 sound(SOUND_WARN);
696
697                 if (record_danger && (old_chp > warning))
698                 {
699                         if (creature_ptr->image && damage_type == DAMAGE_ATTACK)
700                                 hit_from = _("何か", "something");
701
702                         sprintf(tmp, _("%sによってピンチに陥った。", "A critical situation because of %s."), hit_from);
703                         exe_write_diary(p_ptr, NIKKI_BUNSHOU, 0, tmp);
704                 }
705
706                 if (auto_more)
707                 {
708                         /* stop auto_more even if DAMAGE_USELIFE */
709                         creature_ptr->now_damaged = TRUE;
710                 }
711
712                 msg_print(_("*** 警告:低ヒット・ポイント! ***", "*** LOW HITPOINT WARNING! ***"));
713                 msg_print(NULL);
714                 flush();
715         }
716         if (creature_ptr->wild_mode && !creature_ptr->leaving && (creature_ptr->chp < MAX(warning, creature_ptr->mhp / 5)))
717         {
718                 change_wild_mode(creature_ptr, FALSE);
719         }
720         return damage;
721 }