OSDN Git Service

[Refactor] #37353 コメント整理 / Refactor comments.
[hengband/hengband.git] / src / effects.c
1 /*!
2  * @file effects.c
3  * @brief プレイヤーのステータス管理 / effects of various "objects"
4  * @date 2014/01/01
5  * @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
7  *\n
8  * This software may be copied and distributed for educational, research,\n
9  * and not for profit purposes provided that this copyright and statement\n
10  * are included in all such copies.  Other copyrights may also apply.\n
11  *\n
12  * 2013 Deskull rearranged comment for Doxygen.\n
13  */
14
15 #include "angband.h"
16
17 /*!
18  * @brief プレイヤーの継続行動を設定する。
19  * @param typ 継続行動のID\n
20  * #ACTION_NONE / #ACTION_SEARCH / #ACTION_REST / #ACTION_LEARN / #ACTION_FISH / #ACTION_KAMAE / #ACTION_KATA / #ACTION_SING / #ACTION_HAYAGAKE / #ACTION_SPELL から選択。
21  * @return なし
22  */
23 void set_action(ACTION_IDX typ)
24 {
25         int prev_typ = p_ptr->action;
26
27         if (typ == prev_typ)
28         {
29                 return;
30         }
31         else
32         {
33                 switch (prev_typ)
34                 {
35                         case ACTION_SEARCH:
36                         {
37                                 msg_print(_("探索をやめた。", "You no longer walk carefully."));
38                                 p_ptr->redraw |= (PR_SPEED);
39                                 break;
40                         }
41                         case ACTION_REST:
42                         {
43                                 resting = 0;
44                                 break;
45                         }
46                         case ACTION_LEARN:
47                         {
48                                 msg_print(_("学習をやめた。", "You stop Learning"));
49                                 new_mane = FALSE;
50                                 break;
51                         }
52                         case ACTION_KAMAE:
53                         {
54                                 msg_print(_("構えをといた。", "You stop assuming the posture."));
55                                 p_ptr->special_defense &= ~(KAMAE_MASK);
56                                 break;
57                         }
58                         case ACTION_KATA:
59                         {
60                                 msg_print(_("型を崩した。", "You stop assuming the posture."));
61                                 p_ptr->special_defense &= ~(KATA_MASK);
62                                 p_ptr->update |= (PU_MONSTERS);
63                                 p_ptr->redraw |= (PR_STATUS);
64                                 break;
65                         }
66                         case ACTION_SING:
67                         {
68                                 msg_print(_("歌うのをやめた。", "You stop singing."));
69                                 break;
70                         }
71                         case ACTION_HAYAGAKE:
72                         {
73                                 msg_print(_("足が重くなった。", "You are no longer walking extremely fast."));
74                                 p_ptr->energy_use = 100;
75                                 break;
76                         }
77                         case ACTION_SPELL:
78                         {
79                                 msg_print(_("呪文の詠唱を中断した。", "You stopped spelling all spells."));
80                                 break;
81                         }
82                 }
83         }
84
85         p_ptr->action = typ;
86
87         /* If we are requested other action, stop singing */
88         if (prev_typ == ACTION_SING) stop_singing();
89         if (prev_typ == ACTION_SPELL) stop_hex_spell();
90
91         switch (p_ptr->action)
92         {
93                 case ACTION_SEARCH:
94                 {
95                         msg_print(_("注意深く歩き始めた。", "You begin to walk carefully."));
96                         p_ptr->redraw |= (PR_SPEED);
97                         break;
98                 }
99                 case ACTION_LEARN:
100                 {
101                         msg_print(_("学習を始めた。", "You begin Learning"));
102                         break;
103                 }
104                 case ACTION_FISH:
105                 {
106                         msg_print(_("水面に糸を垂らした...", "You begin fishing..."));
107                         break;
108                 }
109                 case ACTION_HAYAGAKE:
110                 {
111                         msg_print(_("足が羽のように軽くなった。", "You begin to walk extremely fast."));
112                         break;
113                 }
114                 default:
115                 {
116                         break;
117                 }
118         }
119
120         /* Recalculate bonuses */
121         p_ptr->update |= (PU_BONUS);
122
123         /* Redraw the state */
124         p_ptr->redraw |= (PR_STATE);
125 }
126
127 /*!
128  * @brief プレイヤーの全ての時限効果をリセットする。 / reset timed flags
129  * @return なし
130  */
131 void reset_tim_flags(void)
132 {
133         p_ptr->fast = 0;            /* Timed -- Fast */
134         p_ptr->lightspeed = 0;
135         p_ptr->slow = 0;            /* Timed -- Slow */
136         p_ptr->blind = 0;           /* Timed -- Blindness */
137         p_ptr->paralyzed = 0;       /* Timed -- Paralysis */
138         p_ptr->confused = 0;        /* Timed -- Confusion */
139         p_ptr->afraid = 0;          /* Timed -- Fear */
140         p_ptr->image = 0;           /* Timed -- Hallucination */
141         p_ptr->poisoned = 0;        /* Timed -- Poisoned */
142         p_ptr->cut = 0;             /* Timed -- Cut */
143         p_ptr->stun = 0;            /* Timed -- Stun */
144
145         p_ptr->protevil = 0;        /* Timed -- Protection */
146         p_ptr->invuln = 0;          /* Timed -- Invulnerable */
147         p_ptr->ult_res = 0;
148         p_ptr->hero = 0;            /* Timed -- Heroism */
149         p_ptr->shero = 0;           /* Timed -- Super Heroism */
150         p_ptr->shield = 0;          /* Timed -- Shield Spell */
151         p_ptr->blessed = 0;         /* Timed -- Blessed */
152         p_ptr->tim_invis = 0;       /* Timed -- Invisibility */
153         p_ptr->tim_infra = 0;       /* Timed -- Infra Vision */
154         p_ptr->tim_regen = 0;       /* Timed -- Regeneration */
155         p_ptr->tim_stealth = 0;     /* Timed -- Stealth */
156         p_ptr->tim_esp = 0;
157         p_ptr->wraith_form = 0;     /* Timed -- Wraith Form */
158         p_ptr->tim_levitation = 0;
159         p_ptr->tim_sh_touki = 0;
160         p_ptr->tim_sh_fire = 0;
161         p_ptr->tim_sh_holy = 0;
162         p_ptr->tim_eyeeye = 0;
163         p_ptr->magicdef = 0;
164         p_ptr->resist_magic = 0;
165         p_ptr->tsuyoshi = 0;
166         p_ptr->kabenuke = 0;
167         p_ptr->tim_res_nether = 0;
168         p_ptr->tim_res_time = 0;
169         p_ptr->tim_mimic = 0;
170         p_ptr->mimic_form = 0;
171         p_ptr->tim_reflect = 0;
172         p_ptr->multishadow = 0;
173         p_ptr->dustrobe = 0;
174         p_ptr->action = ACTION_NONE;
175
176
177         p_ptr->oppose_acid = 0;     /* Timed -- oppose acid */
178         p_ptr->oppose_elec = 0;     /* Timed -- oppose lightning */
179         p_ptr->oppose_fire = 0;     /* Timed -- oppose heat */
180         p_ptr->oppose_cold = 0;     /* Timed -- oppose cold */
181         p_ptr->oppose_pois = 0;     /* Timed -- oppose poison */
182
183         p_ptr->word_recall = 0;
184         p_ptr->alter_reality = 0;
185         p_ptr->sutemi = FALSE;
186         p_ptr->counter = FALSE;
187         p_ptr->ele_attack = 0;
188         p_ptr->ele_immune = 0;
189         p_ptr->special_attack = 0L;
190         p_ptr->special_defense = 0L;
191
192         while(p_ptr->energy_need < 0) p_ptr->energy_need += ENERGY_NEED();
193         world_player = FALSE;
194
195         if (prace_is_(RACE_DEMON) && (p_ptr->lev > 44)) p_ptr->oppose_fire = 1;
196         if ((p_ptr->pclass == CLASS_NINJA) && (p_ptr->lev > 44)) p_ptr->oppose_pois = 1;
197         if (p_ptr->pclass == CLASS_BERSERKER) p_ptr->shero = 1;
198
199         if (p_ptr->riding)
200         {
201                 (void)set_monster_fast(p_ptr->riding, 0);
202                 (void)set_monster_slow(p_ptr->riding, 0);
203                 (void)set_monster_invulner(p_ptr->riding, 0, FALSE);
204         }
205
206         if (p_ptr->pclass == CLASS_BARD)
207         {
208                 SINGING_SONG_EFFECT(p_ptr) = 0;
209                 SINGING_SONG_ID(p_ptr) = 0;
210         }
211 }
212
213 /*!
214  * @brief プレイヤーに魔力消去効果を与える。
215  * @return なし
216  */
217 void dispel_player(void)
218 {
219         (void)set_fast(0, TRUE);
220         (void)set_lightspeed(0, TRUE);
221         (void)set_slow(0, TRUE);
222         (void)set_shield(0, TRUE);
223         (void)set_blessed(0, TRUE);
224         (void)set_tsuyoshi(0, TRUE);
225         (void)set_hero(0, TRUE);
226         (void)set_shero(0, TRUE);
227         (void)set_protevil(0, TRUE);
228         (void)set_invuln(0, TRUE);
229         (void)set_wraith_form(0, TRUE);
230         (void)set_kabenuke(0, TRUE);
231         (void)set_tim_res_nether(0, TRUE);
232         (void)set_tim_res_time(0, TRUE);
233         /* by henkma */
234         (void)set_tim_reflect(0,TRUE);
235         (void)set_multishadow(0,TRUE);
236         (void)set_dustrobe(0,TRUE);
237
238         (void)set_tim_invis(0, TRUE);
239         (void)set_tim_infra(0, TRUE);
240         (void)set_tim_esp(0, TRUE);
241         (void)set_tim_regen(0, TRUE);
242         (void)set_tim_stealth(0, TRUE);
243         (void)set_tim_levitation(0, TRUE);
244         (void)set_tim_sh_touki(0, TRUE);
245         (void)set_tim_sh_fire(0, TRUE);
246         (void)set_tim_sh_holy(0, TRUE);
247         (void)set_tim_eyeeye(0, TRUE);
248         (void)set_magicdef(0, TRUE);
249         (void)set_resist_magic(0, TRUE);
250         (void)set_oppose_acid(0, TRUE);
251         (void)set_oppose_elec(0, TRUE);
252         (void)set_oppose_fire(0, TRUE);
253         (void)set_oppose_cold(0, TRUE);
254         (void)set_oppose_pois(0, TRUE);
255         (void)set_ultimate_res(0, TRUE);
256         (void)set_mimic(0, 0, TRUE);
257         (void)set_ele_attack(0, 0);
258         (void)set_ele_immune(0, 0);
259
260         /* Cancel glowing hands */
261         if (p_ptr->special_attack & ATTACK_CONFUSE)
262         {
263                 p_ptr->special_attack &= ~(ATTACK_CONFUSE);
264                 msg_print(_("手の輝きがなくなった。", "Your hands stop glowing."));
265         }
266
267         if (music_singing_any() || hex_spelling_any())
268         {
269                 cptr str = (music_singing_any()) ? _("歌", "singing") : _("呪文", "spelling");
270                 INTERUPTING_SONG_EFFECT(p_ptr) = SINGING_SONG_EFFECT(p_ptr);
271                 SINGING_SONG_EFFECT(p_ptr) = MUSIC_NONE;
272                 msg_format(_("%sが途切れた。", "Your %s is interrupted."), str);
273                 p_ptr->action = ACTION_NONE;
274
275                 /* Recalculate bonuses */
276                 p_ptr->update |= (PU_BONUS | PU_HP);
277
278                 /* Redraw map */
279                 p_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE);
280
281                 /* Update monsters */
282                 p_ptr->update |= (PU_MONSTERS);
283
284                 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
285
286                 p_ptr->energy_need += ENERGY_NEED();
287         }
288 }
289
290
291 /*!
292  * @brief 変身効果の継続時間と変身先をセットする / Set "p_ptr->tim_mimic", and "p_ptr->mimic_form", notice observable changes
293  * @param v 継続時間
294  * @param p 変身内容
295  * @param do_dec 現在の継続時間より長い値のみ上書きする
296  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
297  */
298 bool set_mimic(TIME_EFFECT v, IDX p, bool do_dec)
299 {
300         bool notice = FALSE;
301
302         /* Hack -- Force good values */
303         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
304
305         if (p_ptr->is_dead) return FALSE;
306
307         /* Open */
308         if (v)
309         {
310                 if (p_ptr->tim_mimic && (p_ptr->mimic_form == p) && !do_dec)
311                 {
312                         if (p_ptr->tim_mimic > v) return FALSE;
313                 }
314                 else if ((!p_ptr->tim_mimic) || (p_ptr->mimic_form != p))
315                 {
316                         msg_print(_("自分の体が変わってゆくのを感じた。", "You feel that your body changes."));
317                         p_ptr->mimic_form = p;
318                         notice = TRUE;
319                 }
320         }
321
322         /* Shut */
323         else
324         {
325                 if (p_ptr->tim_mimic)
326                 {
327                         msg_print(_("変身が解けた。", "You are no longer transformed."));
328                         if (p_ptr->mimic_form == MIMIC_DEMON) set_oppose_fire(0, TRUE);
329                         p_ptr->mimic_form=0;
330                         notice = TRUE;
331                         p = 0;
332                 }
333         }
334
335         /* Use the value */
336         p_ptr->tim_mimic = v;
337
338         /* Nothing to notice */
339         if (!notice)
340                 return (FALSE);
341
342         /* Disturb */
343         if (disturb_state) disturb(0, 1);
344
345         /* Redraw title */
346         p_ptr->redraw |= (PR_BASIC | PR_STATUS);
347
348         /* Recalculate bonuses */
349         p_ptr->update |= (PU_BONUS | PU_HP);
350
351         handle_stuff();
352
353         /* Result */
354         return (TRUE);
355 }
356
357 /*!
358  * @brief 盲目の継続時間をセットする / Set "p_ptr->blind", notice observable changes
359  * @param v 継続時間
360  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
361  * @details
362  * Note the use of "PU_UN_LITE" and "PU_UN_VIEW", which is needed to\n
363  * memorize any terrain features which suddenly become "visible".\n
364  * Note that blindness is currently the only thing which can affect\n
365  * "player_can_see_bold()".\n
366  */
367 bool set_blind(TIME_EFFECT v)
368 {
369         bool notice = FALSE;
370
371         /* Hack -- Force good values */
372         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
373
374         if (p_ptr->is_dead) return FALSE;
375
376         /* Open */
377         if (v)
378         {
379                 if (!p_ptr->blind)
380                 {
381                         if (p_ptr->prace == RACE_ANDROID)
382                         {
383                                 msg_print(_("センサーをやられた!", "You are blind!"));
384                         }
385                         else
386                         {
387                                 msg_print(_("目が見えなくなってしまった!", "You are blind!"));
388                         }
389
390                         notice = TRUE;
391                         chg_virtue(V_ENLIGHTEN, -1);
392                 }
393         }
394
395         /* Shut */
396         else
397         {
398                 if (p_ptr->blind)
399                 {
400                         if (p_ptr->prace == RACE_ANDROID)
401                         {
402                                 msg_print(_("センサーが復旧した。", "You can see again."));
403                         }
404                         else
405                         {
406                                 msg_print(_("やっと目が見えるようになった。", "You can see again."));
407                         }
408
409                         notice = TRUE;
410                 }
411         }
412
413         /* Use the value */
414         p_ptr->blind = v;
415
416         /* Redraw status bar */
417         p_ptr->redraw |= (PR_STATUS);
418
419         /* Nothing to notice */
420         if (!notice) return (FALSE);
421
422         /* Disturb */
423         if (disturb_state) disturb(0, 0);
424
425         /* Fully update the visuals */
426         p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE | PU_VIEW | PU_LITE | PU_MONSTERS | PU_MON_LITE);
427
428         /* Redraw map */
429         p_ptr->redraw |= (PR_MAP);
430
431         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
432
433         /* Handle stuff */
434         handle_stuff();
435
436         /* Result */
437         return (TRUE);
438 }
439
440
441 /*!
442  * @brief 混乱の継続時間をセットする / Set "p_ptr->confused", notice observable changes
443  * @param v 継続時間
444  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
445  */
446 bool set_confused(TIME_EFFECT v)
447 {
448         bool notice = FALSE;
449
450         /* Hack -- Force good values */
451         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
452
453         if (p_ptr->is_dead) return FALSE;
454
455         /* Open */
456         if (v)
457         {
458                 if (!p_ptr->confused)
459                 {
460                         msg_print(_("あなたは混乱した!", "You are confused!"));
461
462                         if (p_ptr->action == ACTION_LEARN)
463                         {
464                                 msg_print(_("学習が続けられない!", "You cannot continue Learning!"));
465                                 new_mane = FALSE;
466
467                                 p_ptr->redraw |= (PR_STATE);
468                                 p_ptr->action = ACTION_NONE;
469                         }
470                         if (p_ptr->action == ACTION_KAMAE)
471                         {
472                                 msg_print(_("構えがとけた。", "Your posture gets loose."));
473                                 p_ptr->special_defense &= ~(KAMAE_MASK);
474                                 p_ptr->update |= (PU_BONUS);
475                                 p_ptr->redraw |= (PR_STATE);
476                                 p_ptr->action = ACTION_NONE;
477                         }
478                         else if (p_ptr->action == ACTION_KATA)
479                         {
480                                 msg_print(_("型が崩れた。", "Your posture gets loose."));
481                                 p_ptr->special_defense &= ~(KATA_MASK);
482                                 p_ptr->update |= (PU_BONUS);
483                                 p_ptr->update |= (PU_MONSTERS);
484                                 p_ptr->redraw |= (PR_STATE);
485                                 p_ptr->redraw |= (PR_STATUS);
486                                 p_ptr->action = ACTION_NONE;
487                         }
488
489                         /* Sniper */
490                         if (p_ptr->concent) reset_concentration(TRUE);
491
492                         /* Hex */
493                         if (hex_spelling_any()) stop_hex_spell_all();
494
495                         notice = TRUE;
496                         p_ptr->counter = FALSE;
497                         chg_virtue(V_HARMONY, -1);
498                 }
499         }
500
501         /* Shut */
502         else
503         {
504                 if (p_ptr->confused)
505                 {
506                         msg_print(_("やっと混乱がおさまった。", "You feel less confused now."));
507                         p_ptr->special_attack &= ~(ATTACK_SUIKEN);
508                         notice = TRUE;
509                 }
510         }
511
512         /* Use the value */
513         p_ptr->confused = v;
514
515         /* Redraw status bar */
516         p_ptr->redraw |= (PR_STATUS);
517
518         /* Nothing to notice */
519         if (!notice) return (FALSE);
520
521         /* Disturb */
522         if (disturb_state) disturb(0, 0);
523
524         /* Handle stuff */
525         handle_stuff();
526
527         /* Result */
528         return (TRUE);
529 }
530
531
532 /*!
533  * @brief 毒の継続時間をセットする / Set "p_ptr->poisoned", notice observable changes
534  * @param v 継続時間
535  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
536  */
537 bool set_poisoned(TIME_EFFECT v)
538 {
539         bool notice = FALSE;
540
541         /* Hack -- Force good values */
542         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
543
544         if (p_ptr->is_dead) return FALSE;
545
546         /* Open */
547         if (v)
548         {
549                 if (!p_ptr->poisoned)
550                 {
551                         msg_print(_("毒に侵されてしまった!", "You are poisoned!"));
552                         notice = TRUE;
553                 }
554         }
555
556         /* Shut */
557         else
558         {
559                 if (p_ptr->poisoned)
560                 {
561                         msg_print(_("やっと毒の痛みがなくなった。", "You are no longer poisoned."));
562                         notice = TRUE;
563                 }
564         }
565
566         /* Use the value */
567         p_ptr->poisoned = v;
568
569         /* Redraw status bar */
570         p_ptr->redraw |= (PR_STATUS);
571
572         /* Nothing to notice */
573         if (!notice) return (FALSE);
574
575         /* Disturb */
576         if (disturb_state) disturb(0, 0);
577
578         /* Handle stuff */
579         handle_stuff();
580
581         /* Result */
582         return (TRUE);
583 }
584
585
586 /*!
587  * @brief 恐怖の継続時間をセットする / Set "p_ptr->afraid", notice observable changes
588  * @param v 継続時間
589  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
590  */
591 bool set_afraid(TIME_EFFECT v)
592 {
593         bool notice = FALSE;
594
595         /* Hack -- Force good values */
596         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
597
598         if (p_ptr->is_dead) return FALSE;
599
600         /* Open */
601         if (v)
602         {
603                 if (!p_ptr->afraid)
604                 {
605                         msg_print(_("何もかも恐くなってきた!", "You are terrified!"));
606
607                         if (p_ptr->special_defense & KATA_MASK)
608                         {
609                                 msg_print(_("型が崩れた。", "Your posture gets loose."));
610                                 p_ptr->special_defense &= ~(KATA_MASK);
611                                 p_ptr->update |= (PU_BONUS);
612                                 p_ptr->update |= (PU_MONSTERS);
613                                 p_ptr->redraw |= (PR_STATE);
614                                 p_ptr->redraw |= (PR_STATUS);
615                                 p_ptr->action = ACTION_NONE;
616                         }
617
618                         notice = TRUE;
619                         p_ptr->counter = FALSE;
620                         chg_virtue(V_VALOUR, -1);
621                 }
622         }
623
624         /* Shut */
625         else
626         {
627                 if (p_ptr->afraid)
628                 {
629                         msg_print(_("やっと恐怖を振り払った。", "You feel bolder now."));
630                         notice = TRUE;
631                 }
632         }
633
634         /* Use the value */
635         p_ptr->afraid = v;
636
637         /* Redraw status bar */
638         p_ptr->redraw |= (PR_STATUS);
639
640         /* Nothing to notice */
641         if (!notice) return (FALSE);
642
643         /* Disturb */
644         if (disturb_state) disturb(0, 0);
645
646         /* Handle stuff */
647         handle_stuff();
648
649         /* Result */
650         return (TRUE);
651 }
652
653 /*!
654  * @brief 麻痺の継続時間をセットする / Set "p_ptr->paralyzed", notice observable changes
655  * @param v 継続時間
656  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
657  */
658 bool set_paralyzed(TIME_EFFECT v)
659 {
660         bool notice = FALSE;
661
662         /* Hack -- Force good values */
663         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
664
665         if (p_ptr->is_dead) return FALSE;
666
667         /* Open */
668         if (v)
669         {
670                 if (!p_ptr->paralyzed)
671                 {
672                         msg_print(_("体が麻痺してしまった!", "You are paralyzed!"));
673                         /* Sniper */
674                         if (p_ptr->concent) reset_concentration(TRUE);
675
676                         /* Hex */
677                         if (hex_spelling_any()) stop_hex_spell_all();
678
679                         p_ptr->counter = FALSE;
680                         notice = TRUE;
681                 }
682         }
683
684         /* Shut */
685         else
686         {
687                 if (p_ptr->paralyzed)
688                 {
689                         msg_print(_("やっと動けるようになった。", "You can move again."));
690                         notice = TRUE;
691                 }
692         }
693
694         /* Use the value */
695         p_ptr->paralyzed = v;
696
697         /* Redraw status bar */
698         p_ptr->redraw |= (PR_STATUS);
699
700         /* Nothing to notice */
701         if (!notice) return (FALSE);
702
703         /* Disturb */
704         if (disturb_state) disturb(0, 0);
705
706         /* Redraw the state */
707         p_ptr->redraw |= (PR_STATE);
708
709         /* Handle stuff */
710         handle_stuff();
711
712         /* Result */
713         return (TRUE);
714 }
715
716 /*!
717  * @brief 幻覚の継続時間をセットする / Set "p_ptr->image", notice observable changes
718  * @param v 継続時間
719  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
720  * @details Note that we must redraw the map when hallucination changes.
721  */
722 bool set_image(TIME_EFFECT v)
723 {
724         bool notice = FALSE;
725
726         /* Hack -- Force good values */
727         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
728
729         if (p_ptr->is_dead) return FALSE;
730
731
732         /* Open */
733         if (v)
734         {
735                 set_tsuyoshi(0, TRUE);
736                 if (!p_ptr->image)
737                 {
738                         msg_print(_("ワーオ!何もかも虹色に見える!", "Oh, wow! Everything looks so cosmic now!"));
739
740                         /* Sniper */
741                         if (p_ptr->concent) reset_concentration(TRUE);
742
743                         p_ptr->counter = FALSE;
744                         notice = TRUE;
745                 }
746         }
747
748         /* Shut */
749         else
750         {
751                 if (p_ptr->image)
752                 {
753                         msg_print(_("やっとはっきりと物が見えるようになった。", "You can see clearly again."));
754                         notice = TRUE;
755                 }
756         }
757
758         /* Use the value */
759         p_ptr->image = v;
760
761         /* Redraw status bar */
762         p_ptr->redraw |= (PR_STATUS);
763
764         /* Nothing to notice */
765         if (!notice) return (FALSE);
766
767         /* Disturb */
768         if (disturb_state) disturb(0, 1);
769
770         /* Redraw map */
771         p_ptr->redraw |= (PR_MAP);
772
773         /* Update the health bar */
774         p_ptr->redraw |= (PR_HEALTH | PR_UHEALTH);
775
776         /* Update monsters */
777         p_ptr->update |= (PU_MONSTERS);
778
779         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
780
781         /* Handle stuff */
782         handle_stuff();
783
784         /* Result */
785         return (TRUE);
786 }
787
788 /*!
789  * @brief 加速の継続時間をセットする / Set "p_ptr->fast", notice observable changes
790  * @param v 継続時間
791  * @param do_dec 現在の継続時間より長い値のみ上書きする
792  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
793  */
794 bool set_fast(TIME_EFFECT v, bool do_dec)
795 {
796         bool notice = FALSE;
797
798         /* Hack -- Force good values */
799         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
800
801         if (p_ptr->is_dead) return FALSE;
802
803         /* Open */
804         if (v)
805         {
806                 if (p_ptr->fast && !do_dec)
807                 {
808                         if (p_ptr->fast > v) return FALSE;
809                 }
810                 else if (!IS_FAST() && !p_ptr->lightspeed)
811                 {
812                         msg_print(_("素早く動けるようになった!", "You feel yourself moving much faster!"));
813                         notice = TRUE;
814                         chg_virtue(V_PATIENCE, -1);
815                         chg_virtue(V_DILIGENCE, 1);
816                 }
817         }
818
819         /* Shut */
820         else
821         {
822                 if (p_ptr->fast && !p_ptr->lightspeed && !music_singing(MUSIC_SPEED) && !music_singing(MUSIC_SHERO))
823                 {
824                         msg_print(_("動きの素早さがなくなったようだ。", "You feel yourself slow down."));
825                         notice = TRUE;
826                 }
827         }
828
829         /* Use the value */
830         p_ptr->fast = v;
831
832         /* Nothing to notice */
833         if (!notice) return (FALSE);
834
835         /* Disturb */
836         if (disturb_state) disturb(0, 0);
837
838         /* Recalculate bonuses */
839         p_ptr->update |= (PU_BONUS);
840
841         /* Handle stuff */
842         handle_stuff();
843
844         /* Result */
845         return (TRUE);
846 }
847
848 /*!
849  * @brief 光速移動の継続時間をセットする / Set "p_ptr->lightspeed", notice observable changes
850  * @param v 継続時間
851  * @param do_dec 現在の継続時間より長い値のみ上書きする
852  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
853  */
854 bool set_lightspeed(TIME_EFFECT v, bool do_dec)
855 {
856         bool notice = FALSE;
857
858         /* Hack -- Force good values */
859         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
860
861         if (p_ptr->is_dead) return FALSE;
862
863         if (p_ptr->wild_mode) v = 0;
864
865         /* Open */
866         if (v)
867         {
868                 if (p_ptr->lightspeed && !do_dec)
869                 {
870                         if (p_ptr->lightspeed > v) return FALSE;
871                 }
872                 else if (!p_ptr->lightspeed)
873                 {
874                         msg_print(_("非常に素早く動けるようになった!", "You feel yourself moving extremely faster!"));
875                         notice = TRUE;
876                         chg_virtue(V_PATIENCE, -1);
877                         chg_virtue(V_DILIGENCE, 1);
878                 }
879         }
880
881         /* Shut */
882         else
883         {
884                 if (p_ptr->lightspeed)
885                 {
886                         msg_print(_("動きの素早さがなくなったようだ。", "You feel yourself slow down."));
887                         notice = TRUE;
888                 }
889         }
890
891         /* Use the value */
892         p_ptr->lightspeed = v;
893
894         /* Nothing to notice */
895         if (!notice) return (FALSE);
896
897         /* Disturb */
898         if (disturb_state) disturb(0, 0);
899
900         /* Recalculate bonuses */
901         p_ptr->update |= (PU_BONUS);
902
903         /* Handle stuff */
904         handle_stuff();
905
906         /* Result */
907         return (TRUE);
908 }
909
910 /*!
911  * @brief 減速の継続時間をセットする / Set "p_ptr->slow", notice observable changes
912  * @param v 継続時間
913  * @param do_dec 現在の継続時間より長い値のみ上書きする
914  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
915  */
916 bool set_slow(TIME_EFFECT v, bool do_dec)
917 {
918         bool notice = FALSE;
919
920         /* Hack -- Force good values */
921         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
922
923         if (p_ptr->is_dead) return FALSE;
924
925         /* Open */
926         if (v)
927         {
928                 if (p_ptr->slow && !do_dec)
929                 {
930                         if (p_ptr->slow > v) return FALSE;
931                 }
932                 else if (!p_ptr->slow)
933                 {
934                         msg_print(_("体の動きが遅くなってしまった!", "You feel yourself moving slower!"));
935                         notice = TRUE;
936                 }
937         }
938
939         /* Shut */
940         else
941         {
942                 if (p_ptr->slow)
943                 {
944                         msg_print(_("動きの遅さがなくなったようだ。", "You feel yourself speed up."));
945                         notice = TRUE;
946                 }
947         }
948
949         /* Use the value */
950         p_ptr->slow = v;
951
952         /* Nothing to notice */
953         if (!notice) return (FALSE);
954
955         /* Disturb */
956         if (disturb_state) disturb(0, 0);
957
958         /* Recalculate bonuses */
959         p_ptr->update |= (PU_BONUS);
960
961         /* Handle stuff */
962         handle_stuff();
963
964         /* Result */
965         return (TRUE);
966 }
967
968
969 /*!
970  * @brief 肌石化の継続時間をセットする / Set "p_ptr->shield", notice observable changes
971  * @param v 継続時間
972  * @param do_dec 現在の継続時間より長い値のみ上書きする
973  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
974  */
975 bool set_shield(TIME_EFFECT v, bool do_dec)
976 {
977         bool notice = FALSE;
978
979         /* Hack -- Force good values */
980         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
981
982         if (p_ptr->is_dead) return FALSE;
983
984         /* Open */
985         if (v)
986         {
987                 if (p_ptr->shield && !do_dec)
988                 {
989                         if (p_ptr->shield > v) return FALSE;
990                 }
991                 else if (!p_ptr->shield)
992                 {
993                         msg_print(_("肌が石になった。", "Your skin turns to stone."));
994                         notice = TRUE;
995                 }
996         }
997
998         /* Shut */
999         else
1000         {
1001                 if (p_ptr->shield)
1002                 {
1003                         msg_print(_("肌が元に戻った。", "Your skin returns to normal."));
1004                         notice = TRUE;
1005                 }
1006         }
1007
1008         /* Use the value */
1009         p_ptr->shield = v;
1010
1011         /* Redraw status bar */
1012         p_ptr->redraw |= (PR_STATUS);
1013
1014         /* Nothing to notice */
1015         if (!notice) return (FALSE);
1016
1017         /* Disturb */
1018         if (disturb_state) disturb(0, 0);
1019
1020         /* Recalculate bonuses */
1021         p_ptr->update |= (PU_BONUS);
1022
1023         /* Handle stuff */
1024         handle_stuff();
1025
1026         /* Result */
1027         return (TRUE);
1028 }
1029
1030
1031 /*!
1032  * @brief つぶれるの継続時間をセットする / Set "p_ptr->tsubureru", notice observable changes
1033  * @param v 継続時間
1034  * @param do_dec 現在の継続時間より長い値のみ上書きする
1035  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1036  */
1037 bool set_tsubureru(TIME_EFFECT v, bool do_dec)
1038 {
1039         bool notice = FALSE;
1040
1041         /* Hack -- Force good values */
1042         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1043
1044         if (p_ptr->is_dead) return FALSE;
1045
1046         /* Open */
1047         if (v)
1048         {
1049                 if (p_ptr->tsubureru && !do_dec)
1050                 {
1051                         if (p_ptr->tsubureru > v) return FALSE;
1052                 }
1053                 else if (!p_ptr->tsubureru)
1054                 {
1055                         msg_print(_("横に伸びた。", "Your body expands horizontally."));
1056                         notice = TRUE;
1057                 }
1058         }
1059
1060         /* Shut */
1061         else
1062         {
1063                 if (p_ptr->tsubureru)
1064                 {
1065                         msg_print(_("もう横に伸びていない。", "Your body returns to normal."));
1066                         notice = TRUE;
1067                 }
1068         }
1069
1070         /* Use the value */
1071         p_ptr->tsubureru = v;
1072
1073         /* Redraw status bar */
1074         p_ptr->redraw |= (PR_STATUS);
1075
1076         /* Nothing to notice */
1077         if (!notice) return (FALSE);
1078
1079         /* Disturb */
1080         if (disturb_state) disturb(0, 0);
1081
1082         /* Recalculate bonuses */
1083         p_ptr->update |= (PU_BONUS);
1084
1085         /* Handle stuff */
1086         handle_stuff();
1087
1088         /* Result */
1089         return (TRUE);
1090 }
1091
1092
1093 /*!
1094  * @brief 魔法の鎧の継続時間をセットする / Set "p_ptr->magicdef", notice observable changes
1095  * @param v 継続時間
1096  * @param do_dec 現在の継続時間より長い値のみ上書きする
1097  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1098  */
1099 bool set_magicdef(TIME_EFFECT v, bool do_dec)
1100 {
1101         bool notice = FALSE;
1102
1103         /* Hack -- Force good values */
1104         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1105
1106         if (p_ptr->is_dead) return FALSE;
1107
1108         /* Open */
1109         if (v)
1110         {
1111                 if (p_ptr->magicdef && !do_dec)
1112                 {
1113                         if (p_ptr->magicdef > v) return FALSE;
1114                 }
1115                 else if (!p_ptr->magicdef)
1116                 {
1117                         msg_print(_("魔法の防御力が増したような気がする。", "You feel more resistant to magic."));
1118                         notice = TRUE;
1119                 }
1120         }
1121
1122         /* Shut */
1123         else
1124         {
1125                 if (p_ptr->magicdef)
1126                 {
1127                         msg_print(_("魔法の防御力が元に戻った。", "You feel less resistant to magic."));
1128                         notice = TRUE;
1129                 }
1130         }
1131
1132         /* Use the value */
1133         p_ptr->magicdef = v;
1134
1135         /* Redraw status bar */
1136         p_ptr->redraw |= (PR_STATUS);
1137
1138         /* Nothing to notice */
1139         if (!notice) return (FALSE);
1140
1141         /* Disturb */
1142         if (disturb_state) disturb(0, 0);
1143
1144         /* Recalculate bonuses */
1145         p_ptr->update |= (PU_BONUS);
1146
1147         /* Handle stuff */
1148         handle_stuff();
1149
1150         /* Result */
1151         return (TRUE);
1152 }
1153
1154 /*!
1155  * @brief 祝福の継続時間をセットする / Set "p_ptr->blessed", notice observable changes
1156  * @param v 継続時間
1157  * @param do_dec 現在の継続時間より長い値のみ上書きする
1158  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1159  */
1160 bool set_blessed(TIME_EFFECT v, bool do_dec)
1161 {
1162         bool notice = FALSE;
1163
1164         /* Hack -- Force good values */
1165         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1166
1167         if (p_ptr->is_dead) return FALSE;
1168
1169         /* Open */
1170         if (v)
1171         {
1172                 if (p_ptr->blessed && !do_dec)
1173                 {
1174                         if (p_ptr->blessed > v) return FALSE;
1175                 }
1176                 else if (!IS_BLESSED())
1177                 {
1178                         msg_print(_("高潔な気分になった!", "You feel righteous!"));
1179                         notice = TRUE;
1180                 }
1181         }
1182
1183         /* Shut */
1184         else
1185         {
1186                 if (p_ptr->blessed && !music_singing(MUSIC_BLESS))
1187                 {
1188                         msg_print(_("高潔な気分が消え失せた。", "The prayer has expired."));
1189                         notice = TRUE;
1190                 }
1191         }
1192
1193         /* Use the value */
1194         p_ptr->blessed = v;
1195
1196         /* Redraw status bar */
1197         p_ptr->redraw |= (PR_STATUS);
1198
1199         /* Nothing to notice */
1200         if (!notice) return (FALSE);
1201
1202         /* Disturb */
1203         if (disturb_state) disturb(0, 0);
1204
1205         /* Recalculate bonuses */
1206         p_ptr->update |= (PU_BONUS);
1207
1208         /* Handle stuff */
1209         handle_stuff();
1210
1211         /* Result */
1212         return (TRUE);
1213 }
1214
1215
1216 /*!
1217  * @brief 士気高揚の継続時間をセットする / Set "p_ptr->hero", notice observable changes
1218  * @param v 継続時間
1219  * @param do_dec 現在の継続時間より長い値のみ上書きする
1220  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1221  */
1222 bool set_hero(TIME_EFFECT v, bool do_dec)
1223 {
1224         bool notice = FALSE;
1225
1226         /* Hack -- Force good values */
1227         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1228
1229         if (p_ptr->is_dead) return FALSE;
1230
1231         /* Open */
1232         if (v)
1233         {
1234                 if (p_ptr->hero && !do_dec)
1235                 {
1236                         if (p_ptr->hero > v) return FALSE;
1237                 }
1238                 else if (!IS_HERO())
1239                 {
1240                         msg_print(_("ヒーローになった気がする!", "You feel like a hero!"));
1241                         notice = TRUE;
1242                 }
1243         }
1244
1245         /* Shut */
1246         else
1247         {
1248                 if (p_ptr->hero && !music_singing(MUSIC_HERO) && !music_singing(MUSIC_SHERO))
1249                 {
1250                         msg_print(_("ヒーローの気分が消え失せた。", "The heroism wears off."));
1251                         notice = TRUE;
1252                 }
1253         }
1254
1255         /* Use the value */
1256         p_ptr->hero = v;
1257
1258         /* Redraw status bar */
1259         p_ptr->redraw |= (PR_STATUS);
1260
1261         /* Nothing to notice */
1262         if (!notice) return (FALSE);
1263
1264         /* Disturb */
1265         if (disturb_state) disturb(0, 0);
1266
1267         /* Recalculate bonuses */
1268         p_ptr->update |= (PU_BONUS);
1269
1270         /* Recalculate hitpoints */
1271         p_ptr->update |= (PU_HP);
1272
1273         /* Handle stuff */
1274         handle_stuff();
1275
1276         /* Result */
1277         return (TRUE);
1278 }
1279
1280 /*!
1281  * @brief 狂戦士化の継続時間をセットする / Set "p_ptr->shero", notice observable changes
1282  * @param v 継続時間/ 0ならば無条件にリセット
1283  * @param do_dec FALSEの場合現在の継続時間より長い値のみ上書きする
1284  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1285  */
1286 bool set_shero(TIME_EFFECT v, bool do_dec)
1287 {
1288         bool notice = FALSE;
1289
1290         /* Hack -- Force good values */
1291         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1292
1293         if (p_ptr->is_dead) return FALSE;
1294
1295         if (p_ptr->pclass == CLASS_BERSERKER) v = 1;
1296         /* Open */
1297         if (v)
1298         {
1299                 if (p_ptr->shero && !do_dec)
1300                 {
1301                         if (p_ptr->shero > v) return FALSE;
1302                 }
1303                 else if (!p_ptr->shero)
1304                 {
1305                         msg_print(_("殺戮マシーンになった気がする!", "You feel like a killing machine!"));
1306                         notice = TRUE;
1307                 }
1308         }
1309
1310         /* Shut */
1311         else
1312         {
1313                 if (p_ptr->shero)
1314                 {
1315                         msg_print(_("野蛮な気持ちが消え失せた。", "You feel less Berserk."));
1316                         notice = TRUE;
1317                 }
1318         }
1319
1320         /* Use the value */
1321         p_ptr->shero = v;
1322
1323         /* Redraw status bar */
1324         p_ptr->redraw |= (PR_STATUS);
1325
1326         /* Nothing to notice */
1327         if (!notice) return (FALSE);
1328
1329         /* Disturb */
1330         if (disturb_state) disturb(0, 0);
1331
1332         /* Recalculate bonuses */
1333         p_ptr->update |= (PU_BONUS);
1334
1335         /* Recalculate hitpoints */
1336         p_ptr->update |= (PU_HP);
1337
1338         /* Handle stuff */
1339         handle_stuff();
1340
1341         /* Result */
1342         return (TRUE);
1343 }
1344
1345 /*!
1346  * @brief 対邪悪結界の継続時間をセットする / Set "p_ptr->protevil", notice observable changes
1347  * @param v 継続時間
1348  * @param do_dec 現在の継続時間より長い値のみ上書きする
1349  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1350  */
1351 bool set_protevil(TIME_EFFECT v, bool do_dec)
1352 {
1353         bool notice = FALSE;
1354
1355         /* Hack -- Force good values */
1356         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1357
1358         if (p_ptr->is_dead) return FALSE;
1359
1360         /* Open */
1361         if (v)
1362         {
1363                 if (p_ptr->protevil && !do_dec)
1364                 {
1365                         if (p_ptr->protevil > v) return FALSE;
1366                 }
1367                 else if (!p_ptr->protevil)
1368                 {
1369                         msg_print(_("邪悪なる存在から守られているような感じがする!", "You feel safe from evil!"));
1370                         notice = TRUE;
1371                 }
1372         }
1373
1374         /* Shut */
1375         else
1376         {
1377                 if (p_ptr->protevil)
1378                 {
1379                         msg_print(_("邪悪なる存在から守られている感じがなくなった。", "You no longer feel safe from evil."));
1380                         notice = TRUE;
1381                 }
1382         }
1383
1384         /* Use the value */
1385         p_ptr->protevil = v;
1386
1387         /* Redraw status bar */
1388         p_ptr->redraw |= (PR_STATUS);
1389
1390         /* Nothing to notice */
1391         if (!notice) return (FALSE);
1392
1393         /* Disturb */
1394         if (disturb_state) disturb(0, 0);
1395
1396         /* Handle stuff */
1397         handle_stuff();
1398
1399         /* Result */
1400         return (TRUE);
1401 }
1402
1403 /*!
1404  * @brief 幽体化の継続時間をセットする / Set "p_ptr->wraith_form", notice observable changes
1405  * @param v 継続時間
1406  * @param do_dec 現在の継続時間より長い値のみ上書きする
1407  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1408  */
1409 bool set_wraith_form(TIME_EFFECT v, bool do_dec)
1410 {
1411         bool notice = FALSE;
1412
1413         /* Hack -- Force good values */
1414         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1415
1416         if (p_ptr->is_dead) return FALSE;
1417
1418         /* Open */
1419         if (v)
1420         {
1421                 if (p_ptr->wraith_form && !do_dec)
1422                 {
1423                         if (p_ptr->wraith_form > v) return FALSE;
1424                 }
1425                 else if (!p_ptr->wraith_form)
1426                 {
1427                         msg_print(_("物質界を離れて幽鬼のような存在になった!", "You leave the physical world and turn into a wraith-being!"));
1428                         notice = TRUE;
1429                         chg_virtue(V_UNLIFE, 3);
1430                         chg_virtue(V_HONOUR, -2);
1431                         chg_virtue(V_SACRIFICE, -2);
1432                         chg_virtue(V_VALOUR, -5);
1433
1434                         /* Redraw map */
1435                         p_ptr->redraw |= (PR_MAP);
1436
1437                         /* Update monsters */
1438                         p_ptr->update |= (PU_MONSTERS);
1439
1440                         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1441                 }
1442         }
1443
1444         /* Shut */
1445         else
1446         {
1447                 if (p_ptr->wraith_form)
1448                 {
1449                         msg_print(_("不透明になった感じがする。", "You feel opaque."));
1450                         notice = TRUE;
1451
1452                         /* Redraw map */
1453                         p_ptr->redraw |= (PR_MAP);
1454
1455                         /* Update monsters */
1456                         p_ptr->update |= (PU_MONSTERS);
1457
1458                         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1459                 }
1460         }
1461
1462         /* Use the value */
1463         p_ptr->wraith_form = v;
1464
1465         /* Redraw status bar */
1466         p_ptr->redraw |= (PR_STATUS);
1467
1468         /* Nothing to notice */
1469         if (!notice) return (FALSE);
1470
1471         /* Disturb */
1472         if (disturb_state) disturb(0, 0);
1473
1474         /* Recalculate bonuses */
1475         p_ptr->update |= (PU_BONUS);
1476
1477         /* Handle stuff */
1478         handle_stuff();
1479
1480         /* Result */
1481         return (TRUE);
1482
1483 }
1484
1485 /*!
1486  * @brief 無傷球の継続時間をセットする / Set "p_ptr->invuln", notice observable changes
1487  * @param v 継続時間
1488  * @param do_dec 現在の継続時間より長い値のみ上書きする
1489  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1490  */
1491 bool set_invuln(TIME_EFFECT v, bool do_dec)
1492 {
1493         bool notice = FALSE;
1494
1495         /* Hack -- Force good values */
1496         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1497
1498         if (p_ptr->is_dead) return FALSE;
1499
1500         /* Open */
1501         if (v)
1502         {
1503                 if (p_ptr->invuln && !do_dec)
1504                 {
1505                         if (p_ptr->invuln > v) return FALSE;
1506                 }
1507                 else if (!IS_INVULN())
1508                 {
1509                         msg_print(_("無敵だ!", "Invulnerability!"));
1510                         notice = TRUE;
1511
1512                         chg_virtue(V_UNLIFE, -2);
1513                         chg_virtue(V_HONOUR, -2);
1514                         chg_virtue(V_SACRIFICE, -3);
1515                         chg_virtue(V_VALOUR, -5);
1516
1517                         /* Redraw map */
1518                         p_ptr->redraw |= (PR_MAP);
1519
1520                         /* Update monsters */
1521                         p_ptr->update |= (PU_MONSTERS);
1522
1523                         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1524                 }
1525         }
1526
1527         /* Shut */
1528         else
1529         {
1530                 if (p_ptr->invuln && !music_singing(MUSIC_INVULN))
1531                 {
1532                         msg_print(_("無敵ではなくなった。", "The invulnerability wears off."));
1533                         notice = TRUE;
1534
1535                         /* Redraw map */
1536                         p_ptr->redraw |= (PR_MAP);
1537
1538                         /* Update monsters */
1539                         p_ptr->update |= (PU_MONSTERS);
1540
1541                         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1542
1543                         p_ptr->energy_need += ENERGY_NEED();
1544                 }
1545         }
1546
1547         /* Use the value */
1548         p_ptr->invuln = v;
1549
1550         /* Redraw status bar */
1551         p_ptr->redraw |= (PR_STATUS);
1552
1553         /* Nothing to notice */
1554         if (!notice) return (FALSE);
1555
1556         /* Disturb */
1557         if (disturb_state) disturb(0, 0);
1558
1559         /* Recalculate bonuses */
1560         p_ptr->update |= (PU_BONUS);
1561
1562         /* Handle stuff */
1563         handle_stuff();
1564
1565         /* Result */
1566         return (TRUE);
1567 }
1568
1569 /*!
1570  * @brief 時限ESPの継続時間をセットする / Set "p_ptr->tim_esp", notice observable changes
1571  * @param v 継続時間
1572  * @param do_dec 現在の継続時間より長い値のみ上書きする
1573  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1574  */
1575 bool set_tim_esp(TIME_EFFECT v, bool do_dec)
1576 {
1577         bool notice = FALSE;
1578
1579         /* Hack -- Force good values */
1580         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1581
1582         if (p_ptr->is_dead) return FALSE;
1583
1584         /* Open */
1585         if (v)
1586         {
1587                 if (p_ptr->tim_esp && !do_dec)
1588                 {
1589                         if (p_ptr->tim_esp > v) return FALSE;
1590                 }
1591                 else if (!IS_TIM_ESP())
1592                 {
1593                         msg_print(_("意識が広がった気がする!", "You feel your consciousness expand!"));
1594                         notice = TRUE;
1595                 }
1596         }
1597
1598         /* Shut */
1599         else
1600         {
1601                 if (p_ptr->tim_esp && !music_singing(MUSIC_MIND))
1602                 {
1603                         msg_print(_("意識は元に戻った。", "Your consciousness contracts again."));
1604                         notice = TRUE;
1605                 }
1606         }
1607
1608         /* Use the value */
1609         p_ptr->tim_esp = v;
1610
1611         /* Redraw status bar */
1612         p_ptr->redraw |= (PR_STATUS);
1613
1614         /* Nothing to notice */
1615         if (!notice) return (FALSE);
1616
1617         /* Disturb */
1618         if (disturb_state) disturb(0, 0);
1619
1620         /* Recalculate bonuses */
1621         p_ptr->update |= (PU_BONUS);
1622
1623         /* Update the monsters */
1624         p_ptr->update |= (PU_MONSTERS);
1625
1626         /* Handle stuff */
1627         handle_stuff();
1628
1629         /* Result */
1630         return (TRUE);
1631 }
1632
1633 /*!
1634  * @brief 時限透明視の継続時間をセットする / Set "p_ptr->tim_invis", notice observable changes
1635  * @param v 継続時間
1636  * @param do_dec 現在の継続時間より長い値のみ上書きする
1637  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1638  */
1639 bool set_tim_invis(TIME_EFFECT v, bool do_dec)
1640 {
1641         bool notice = FALSE;
1642
1643         /* Hack -- Force good values */
1644         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1645
1646         if (p_ptr->is_dead) return FALSE;
1647
1648         /* Open */
1649         if (v)
1650         {
1651                 if (p_ptr->tim_invis && !do_dec)
1652                 {
1653                         if (p_ptr->tim_invis > v) return FALSE;
1654                 }
1655                 else if (!p_ptr->tim_invis)
1656                 {
1657                         msg_print(_("目が非常に敏感になった気がする!", "Your eyes feel very sensitive!"));
1658                         notice = TRUE;
1659                 }
1660         }
1661
1662         /* Shut */
1663         else
1664         {
1665                 if (p_ptr->tim_invis)
1666                 {
1667                         msg_print(_("目の敏感さがなくなったようだ。", "Your eyes feel less sensitive."));
1668                         notice = TRUE;
1669                 }
1670         }
1671
1672         /* Use the value */
1673         p_ptr->tim_invis = v;
1674
1675         /* Redraw status bar */
1676         p_ptr->redraw |= (PR_STATUS);
1677
1678         /* Nothing to notice */
1679         if (!notice) return (FALSE);
1680
1681         /* Disturb */
1682         if (disturb_state) disturb(0, 0);
1683
1684         /* Recalculate bonuses */
1685         p_ptr->update |= (PU_BONUS);
1686
1687         /* Update the monsters */
1688         p_ptr->update |= (PU_MONSTERS);
1689
1690         /* Handle stuff */
1691         handle_stuff();
1692
1693         /* Result */
1694         return (TRUE);
1695 }
1696
1697 /*!
1698  * @brief 時限赤外線視力の継続時間をセットする / Set "p_ptr->tim_infra", notice observable changes
1699  * @param v 継続時間
1700  * @param do_dec 現在の継続時間より長い値のみ上書きする
1701  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1702  */
1703 bool set_tim_infra(TIME_EFFECT v, bool do_dec)
1704 {
1705         bool notice = FALSE;
1706
1707         /* Hack -- Force good values */
1708         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1709
1710         if (p_ptr->is_dead) return FALSE;
1711
1712         /* Open */
1713         if (v)
1714         {
1715                 if (p_ptr->tim_infra && !do_dec)
1716                 {
1717                         if (p_ptr->tim_infra > v) return FALSE;
1718                 }
1719                 else if (!p_ptr->tim_infra)
1720                 {
1721                         msg_print(_("目がランランと輝き始めた!", "Your eyes begin to tingle!"));
1722                         notice = TRUE;
1723                 }
1724         }
1725
1726         /* Shut */
1727         else
1728         {
1729                 if (p_ptr->tim_infra)
1730                 {
1731                         msg_print(_("目の輝きがなくなった。", "Your eyes stop tingling."));
1732                         notice = TRUE;
1733                 }
1734         }
1735
1736         /* Use the value */
1737         p_ptr->tim_infra = v;
1738
1739         /* Redraw status bar */
1740         p_ptr->redraw |= (PR_STATUS);
1741
1742         /* Nothing to notice */
1743         if (!notice) return (FALSE);
1744
1745         /* Disturb */
1746         if (disturb_state) disturb(0, 0);
1747
1748         /* Recalculate bonuses */
1749         p_ptr->update |= (PU_BONUS);
1750
1751         /* Update the monsters */
1752         p_ptr->update |= (PU_MONSTERS);
1753
1754         /* Handle stuff */
1755         handle_stuff();
1756
1757         /* Result */
1758         return (TRUE);
1759 }
1760
1761 /*!
1762  * @brief 時限急回復の継続時間をセットする / Set "p_ptr->tim_regen", notice observable changes
1763  * @param v 継続時間
1764  * @param do_dec 現在の継続時間より長い値のみ上書きする
1765  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1766  */
1767 bool set_tim_regen(TIME_EFFECT v, bool do_dec)
1768 {
1769         bool notice = FALSE;
1770
1771         /* Hack -- Force good values */
1772         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1773
1774         if (p_ptr->is_dead) return FALSE;
1775
1776         /* Open */
1777         if (v)
1778         {
1779                 if (p_ptr->tim_regen && !do_dec)
1780                 {
1781                         if (p_ptr->tim_regen > v) return FALSE;
1782                 }
1783                 else if (!p_ptr->tim_regen)
1784                 {
1785                         msg_print(_("回復力が上がった!", "You feel yourself regenerating quickly!"));
1786                         notice = TRUE;
1787                 }
1788         }
1789
1790         /* Shut */
1791         else
1792         {
1793                 if (p_ptr->tim_regen)
1794                 {
1795                         msg_print(_("素早く回復する感じがなくなった。", "You feel yourself regenerating slowly."));
1796                         notice = TRUE;
1797                 }
1798         }
1799
1800         /* Use the value */
1801         p_ptr->tim_regen = v;
1802
1803         /* Redraw status bar */
1804         p_ptr->redraw |= (PR_STATUS);
1805
1806         /* Nothing to notice */
1807         if (!notice) return (FALSE);
1808
1809         /* Disturb */
1810         if (disturb_state) disturb(0, 0);
1811
1812         /* Recalculate bonuses */
1813         p_ptr->update |= (PU_BONUS);
1814
1815         /* Handle stuff */
1816         handle_stuff();
1817
1818         /* Result */
1819         return (TRUE);
1820 }
1821
1822 /*!
1823  * @brief 隠密の歌の継続時間をセットする / Set "p_ptr->tim_stealth", notice observable changes
1824  * @param v 継続時間
1825  * @param do_dec 現在の継続時間より長い値のみ上書きする
1826  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1827  */
1828 bool set_tim_stealth(TIME_EFFECT v, bool do_dec)
1829 {
1830         bool notice = FALSE;
1831
1832         /* Hack -- Force good values */
1833         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1834
1835         if (p_ptr->is_dead) return FALSE;
1836
1837         /* Open */
1838         if (v)
1839         {
1840                 if (p_ptr->tim_stealth && !do_dec)
1841                 {
1842                         if (p_ptr->tim_stealth > v) return FALSE;
1843                 }
1844                 else if (!IS_TIM_STEALTH())
1845                 {
1846                         msg_print(_("足音が小さくなった!", "You begin to walk silently!"));
1847                         notice = TRUE;
1848                 }
1849         }
1850
1851         /* Shut */
1852         else
1853         {
1854                 if (p_ptr->tim_stealth && !music_singing(MUSIC_STEALTH))
1855                 {
1856                         msg_print(_("足音が大きくなった。", "You no longer walk silently."));
1857                         notice = TRUE;
1858                 }
1859         }
1860
1861         /* Use the value */
1862         p_ptr->tim_stealth = v;
1863
1864         /* Redraw status bar */
1865         p_ptr->redraw |= (PR_STATUS);
1866
1867         /* Nothing to notice */
1868         if (!notice) return (FALSE);
1869
1870         /* Disturb */
1871         if (disturb_state) disturb(0, 0);
1872
1873         /* Recalculate bonuses */
1874         p_ptr->update |= (PU_BONUS);
1875
1876         /* Handle stuff */
1877         handle_stuff();
1878
1879         /* Result */
1880         return (TRUE);
1881 }
1882
1883 /*!
1884  * @brief 超隠密状態をセットする
1885  * @param set TRUEならば超隠密状態になる。
1886  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1887  */
1888 bool set_superstealth(bool set)
1889 {
1890         bool notice = FALSE;
1891
1892         if (p_ptr->is_dead) return FALSE;
1893
1894         /* Open */
1895         if (set)
1896         {
1897                 if (!(p_ptr->special_defense & NINJA_S_STEALTH))
1898                 {
1899                         if (cave[p_ptr->y][p_ptr->x].info & CAVE_MNLT)
1900                         {
1901                                 msg_print(_("敵の目から薄い影の中に覆い隠された。", "You are mantled in weak shadow from ordinary eyes."));
1902                                 p_ptr->monlite = p_ptr->old_monlite = TRUE;
1903                         }
1904                         else
1905                         {
1906                                 msg_print(_("敵の目から影の中に覆い隠された!", "You are mantled in shadow from ordinary eyes!"));
1907                                 p_ptr->monlite = p_ptr->old_monlite = FALSE;
1908                         }
1909
1910                         notice = TRUE;
1911
1912                         /* Use the value */
1913                         p_ptr->special_defense |= NINJA_S_STEALTH;
1914                 }
1915         }
1916
1917         /* Shut */
1918         else
1919         {
1920                 if (p_ptr->special_defense & NINJA_S_STEALTH)
1921                 {
1922                         msg_print(_("再び敵の目にさらされるようになった。", "You are exposed to common sight once more."));
1923                         notice = TRUE;
1924
1925                         /* Use the value */
1926                         p_ptr->special_defense &= ~(NINJA_S_STEALTH);
1927                 }
1928         }
1929
1930         /* Nothing to notice */
1931         if (!notice) return (FALSE);
1932
1933         /* Redraw status bar */
1934         p_ptr->redraw |= (PR_STATUS);
1935
1936         /* Disturb */
1937         if (disturb_state) disturb(0, 0);
1938
1939         /* Result */
1940         return (TRUE);
1941 }
1942
1943 /*!
1944  * @brief 一時的浮遊の継続時間をセットする / Set "p_ptr->tim_levitation", notice observable changes
1945  * @param v 継続時間
1946  * @param do_dec 現在の継続時間より長い値のみ上書きする
1947  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
1948  */
1949 bool set_tim_levitation(TIME_EFFECT v, bool do_dec)
1950 {
1951         bool notice = FALSE;
1952
1953         /* Hack -- Force good values */
1954         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
1955
1956         if (p_ptr->is_dead) return FALSE;
1957
1958         /* Open */
1959         if (v)
1960         {
1961                 if (p_ptr->tim_levitation && !do_dec)
1962                 {
1963                         if (p_ptr->tim_levitation > v) return FALSE;
1964                 }
1965                 else if (!p_ptr->tim_levitation)
1966                 {
1967                         msg_print(_("体が宙に浮き始めた。", "You begin to fly!"));
1968                         notice = TRUE;
1969                 }
1970         }
1971
1972         /* Shut */
1973         else
1974         {
1975                 if (p_ptr->tim_levitation)
1976                 {
1977                         msg_print(_("もう宙に浮かべなくなった。", "You stop flying."));
1978                         notice = TRUE;
1979                 }
1980         }
1981
1982         /* Use the value */
1983         p_ptr->tim_levitation = v;
1984
1985         /* Redraw status bar */
1986         p_ptr->redraw |= (PR_STATUS);
1987
1988         /* Nothing to notice */
1989         if (!notice) return (FALSE);
1990
1991         /* Disturb */
1992         if (disturb_state) disturb(0, 0);
1993
1994         /* Recalculate bonuses */
1995         p_ptr->update |= (PU_BONUS);
1996
1997         /* Handle stuff */
1998         handle_stuff();
1999
2000         /* Result */
2001         return (TRUE);
2002 }
2003
2004 /*!
2005  * @brief 一時的闘気のオーラの継続時間をセットする / Set "p_ptr->tim_sh_touki", notice observable changes
2006  * @param v 継続時間
2007  * @param do_dec 現在の継続時間より長い値のみ上書きする
2008  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2009  */
2010 bool set_tim_sh_touki(TIME_EFFECT v, bool do_dec)
2011 {
2012         bool notice = FALSE;
2013
2014         /* Hack -- Force good values */
2015         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2016
2017         if (p_ptr->is_dead) return FALSE;
2018
2019         /* Open */
2020         if (v)
2021         {
2022                 if (p_ptr->tim_sh_touki && !do_dec)
2023                 {
2024                         if (p_ptr->tim_sh_touki > v) return FALSE;
2025                 }
2026                 else if (!p_ptr->tim_sh_touki)
2027                 {
2028                         msg_print(_("体が闘気のオーラで覆われた。", "You have enveloped by the aura of the Force!"));
2029                         notice = TRUE;
2030                 }
2031         }
2032
2033         /* Shut */
2034         else
2035         {
2036                 if (p_ptr->tim_sh_touki)
2037                 {
2038                         msg_print(_("闘気が消えた。", "Aura of the Force disappeared."));
2039                         notice = TRUE;
2040                 }
2041         }
2042
2043         /* Use the value */
2044         p_ptr->tim_sh_touki = v;
2045
2046         /* Redraw status bar */
2047         p_ptr->redraw |= (PR_STATUS);
2048
2049         /* Nothing to notice */
2050         if (!notice) return (FALSE);
2051
2052         /* Disturb */
2053         if (disturb_state) disturb(0, 0);
2054
2055         /* Handle stuff */
2056         handle_stuff();
2057
2058         /* Result */
2059         return (TRUE);
2060 }
2061
2062 /*!
2063  * @brief 一時的火炎のオーラの継続時間をセットする / Set "p_ptr->tim_sh_fire", notice observable changes
2064  * @param v 継続時間
2065  * @param do_dec 現在の継続時間より長い値のみ上書きする
2066  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2067  */
2068 bool set_tim_sh_fire(TIME_EFFECT v, bool do_dec)
2069 {
2070         bool notice = FALSE;
2071
2072         /* Hack -- Force good values */
2073         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2074
2075         if (p_ptr->is_dead) return FALSE;
2076
2077         /* Open */
2078         if (v)
2079         {
2080                 if (p_ptr->tim_sh_fire && !do_dec)
2081                 {
2082                         if (p_ptr->tim_sh_fire > v) return FALSE;
2083                 }
2084                 else if (!p_ptr->tim_sh_fire)
2085                 {
2086                         msg_print(_("体が炎のオーラで覆われた。", "You have enveloped by fiery aura!"));
2087                         notice = TRUE;
2088                 }
2089         }
2090
2091         /* Shut */
2092         else
2093         {
2094                 if (p_ptr->tim_sh_fire)
2095                 {
2096                         msg_print(_("炎のオーラが消えた。", "Fiery aura disappeared."));
2097                         notice = TRUE;
2098                 }
2099         }
2100
2101         /* Use the value */
2102         p_ptr->tim_sh_fire = v;
2103
2104         /* Redraw status bar */
2105         p_ptr->redraw |= (PR_STATUS);
2106
2107         /* Nothing to notice */
2108         if (!notice) return (FALSE);
2109
2110         /* Disturb */
2111         if (disturb_state) disturb(0, 0);
2112
2113         /* Recalculate bonuses */
2114         p_ptr->update |= (PU_BONUS);
2115
2116         /* Handle stuff */
2117         handle_stuff();
2118
2119         /* Result */
2120         return (TRUE);
2121 }
2122
2123 /*!
2124  * @brief 一時的聖なるのオーラの継続時間をセットする / Set "p_ptr->tim_sh_holy", notice observable changes
2125  * @param v 継続時間
2126  * @param do_dec 現在の継続時間より長い値のみ上書きする
2127  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2128  */
2129 bool set_tim_sh_holy(TIME_EFFECT v, bool do_dec)
2130 {
2131         bool notice = FALSE;
2132
2133         /* Hack -- Force good values */
2134         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2135
2136         if (p_ptr->is_dead) return FALSE;
2137
2138         /* Open */
2139         if (v)
2140         {
2141                 if (p_ptr->tim_sh_holy && !do_dec)
2142                 {
2143                         if (p_ptr->tim_sh_holy > v) return FALSE;
2144                 }
2145                 else if (!p_ptr->tim_sh_holy)
2146                 {
2147                         msg_print(_("体が聖なるオーラで覆われた。", "You have enveloped by holy aura!"));
2148                         notice = TRUE;
2149                 }
2150         }
2151
2152         /* Shut */
2153         else
2154         {
2155                 if (p_ptr->tim_sh_holy)
2156                 {
2157                         msg_print(_("聖なるオーラが消えた。", "Holy aura disappeared."));
2158                         notice = TRUE;
2159                 }
2160         }
2161
2162         /* Use the value */
2163         p_ptr->tim_sh_holy = v;
2164
2165         /* Redraw status bar */
2166         p_ptr->redraw |= (PR_STATUS);
2167
2168         /* Nothing to notice */
2169         if (!notice) return (FALSE);
2170
2171         /* Disturb */
2172         if (disturb_state) disturb(0, 0);
2173
2174         /* Recalculate bonuses */
2175         p_ptr->update |= (PU_BONUS);
2176
2177         /* Handle stuff */
2178         handle_stuff();
2179
2180         /* Result */
2181         return (TRUE);
2182 }
2183
2184 /*!
2185  * @brief 目には目をの残り時間をセットする / Set "p_ptr->tim_eyeeye", notice observable changes
2186  * @param v 継続時間
2187  * @param do_dec 現在の継続時間より長い値のみ上書きする
2188  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2189  */
2190 bool set_tim_eyeeye(TIME_EFFECT v, bool do_dec)
2191 {
2192         bool notice = FALSE;
2193
2194         /* Hack -- Force good values */
2195         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2196
2197         if (p_ptr->is_dead) return FALSE;
2198
2199         /* Open */
2200         if (v)
2201         {
2202                 if (p_ptr->tim_eyeeye && !do_dec)
2203                 {
2204                         if (p_ptr->tim_eyeeye > v) return FALSE;
2205                 }
2206                 else if (!p_ptr->tim_eyeeye)
2207                 {
2208                         msg_print(_("法の守り手になった気がした!", "You feel like a keeper of commandments!"));
2209                         notice = TRUE;
2210                 }
2211         }
2212
2213         /* Shut */
2214         else
2215         {
2216                 if (p_ptr->tim_eyeeye)
2217                 {
2218                         msg_print(_("懲罰を執行することができなくなった。", "You no longer feel like a keeper."));
2219                         notice = TRUE;
2220                 }
2221         }
2222
2223         /* Use the value */
2224         p_ptr->tim_eyeeye = v;
2225
2226         /* Redraw status bar */
2227         p_ptr->redraw |= (PR_STATUS);
2228
2229         /* Nothing to notice */
2230         if (!notice) return (FALSE);
2231
2232         /* Disturb */
2233         if (disturb_state) disturb(0, 0);
2234
2235         /* Recalculate bonuses */
2236         p_ptr->update |= (PU_BONUS);
2237
2238         /* Handle stuff */
2239         handle_stuff();
2240
2241         /* Result */
2242         return (TRUE);
2243 }
2244
2245
2246 /*!
2247  * @brief 一時的魔法防御の継続時間をセットする / Set "p_ptr->resist_magic", notice observable changes
2248  * @param v 継続時間
2249  * @param do_dec 現在の継続時間より長い値のみ上書きする
2250  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2251  */
2252 bool set_resist_magic(TIME_EFFECT v, bool do_dec)
2253 {
2254         bool notice = FALSE;
2255
2256         /* Hack -- Force good values */
2257         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2258
2259         if (p_ptr->is_dead) return FALSE;
2260
2261         /* Open */
2262         if (v)
2263         {
2264                 if (p_ptr->resist_magic && !do_dec)
2265                 {
2266                         if (p_ptr->resist_magic > v) return FALSE;
2267                 }
2268                 else if (!p_ptr->resist_magic)
2269                 {
2270                         msg_print(_("魔法への耐性がついた。", "You have been protected from magic!"));
2271                         notice = TRUE;
2272                 }
2273         }
2274
2275         /* Shut */
2276         else
2277         {
2278                 if (p_ptr->resist_magic)
2279                 {
2280                         msg_print(_("魔法に弱くなった。", "You are no longer protected from magic."));
2281                         notice = TRUE;
2282                 }
2283         }
2284
2285         /* Use the value */
2286         p_ptr->resist_magic = v;
2287
2288         /* Redraw status bar */
2289         p_ptr->redraw |= (PR_STATUS);
2290
2291         /* Nothing to notice */
2292         if (!notice) return (FALSE);
2293
2294         /* Disturb */
2295         if (disturb_state) disturb(0, 0);
2296
2297         /* Recalculate bonuses */
2298         p_ptr->update |= (PU_BONUS);
2299
2300         /* Handle stuff */
2301         handle_stuff();
2302
2303         /* Result */
2304         return (TRUE);
2305 }
2306
2307 /*!
2308  * @brief 一時的反射の継続時間をセットする / Set "p_ptr->tim_reflect", notice observable changes
2309  * @param v 継続時間
2310  * @param do_dec 現在の継続時間より長い値のみ上書きする
2311  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2312  */
2313 bool set_tim_reflect(TIME_EFFECT v, bool do_dec)
2314 {
2315         bool notice = FALSE;
2316
2317         /* Hack -- Force good values */
2318         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2319
2320         if (p_ptr->is_dead) return FALSE;
2321
2322         /* Open */
2323         if (v)
2324         {
2325                 if (p_ptr->tim_reflect && !do_dec)
2326                 {
2327                         if (p_ptr->tim_reflect > v) return FALSE;
2328                 }
2329                 else if (!p_ptr->tim_reflect)
2330                 {
2331                         msg_print(_("体の表面が滑かになった気がする。", "Your body becames smooth."));
2332                         notice = TRUE;
2333                 }
2334         }
2335
2336         /* Shut */
2337         else
2338         {
2339                 if (p_ptr->tim_reflect)
2340                 {
2341                         msg_print(_("体の表面が滑かでなくなった。", "Your body is no longer smooth."));
2342                         notice = TRUE;
2343                 }
2344         }
2345
2346         /* Use the value */
2347         p_ptr->tim_reflect = v;
2348
2349         /* Redraw status bar */
2350         p_ptr->redraw |= (PR_STATUS);
2351
2352         /* Nothing to notice */
2353         if (!notice) return (FALSE);
2354
2355         /* Disturb */
2356         if (disturb_state) disturb(0, 0);
2357
2358         /* Recalculate bonuses */
2359         p_ptr->update |= (PU_BONUS);
2360
2361         /* Handle stuff */
2362         handle_stuff();
2363
2364         /* Result */
2365         return (TRUE);
2366 }
2367
2368
2369 /*
2370  * Set "p_ptr->multishadow", notice observable changes
2371  */
2372 bool set_multishadow(TIME_EFFECT v, bool do_dec)
2373 {
2374         bool notice = FALSE;
2375
2376         /* Hack -- Force good values */
2377         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2378
2379         if (p_ptr->is_dead) return FALSE;
2380
2381         /* Open */
2382         if (v)
2383         {
2384                 if (p_ptr->multishadow && !do_dec)
2385                 {
2386                         if (p_ptr->multishadow > v) return FALSE;
2387                 }
2388                 else if (!p_ptr->multishadow)
2389                 {
2390                         msg_print(_("あなたの周りに幻影が生まれた。", "Your Shadow enveloped you."));
2391                         notice = TRUE;
2392                 }
2393         }
2394
2395         /* Shut */
2396         else
2397         {
2398                 if (p_ptr->multishadow)
2399                 {
2400                         msg_print(_("幻影が消えた。", "Your Shadow disappears."));
2401                         notice = TRUE;
2402                 }
2403         }
2404
2405         /* Use the value */
2406         p_ptr->multishadow = v;
2407
2408         /* Redraw status bar */
2409         p_ptr->redraw |= (PR_STATUS);
2410
2411         /* Nothing to notice */
2412         if (!notice) return (FALSE);
2413
2414         /* Disturb */
2415         if (disturb_state) disturb(0, 0);
2416
2417         /* Recalculate bonuses */
2418         p_ptr->update |= (PU_BONUS);
2419
2420         /* Handle stuff */
2421         handle_stuff();
2422
2423         /* Result */
2424         return (TRUE);
2425 }
2426
2427 /*!
2428  * @brief 一時的破片のオーラの継続時間をセットする / Set "p_ptr->dustrobe", notice observable changes
2429  * @param v 継続時間
2430  * @param do_dec 現在の継続時間より長い値のみ上書きする
2431  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2432  */
2433 bool set_dustrobe(TIME_EFFECT v, bool do_dec)
2434 {
2435         bool notice = FALSE;
2436
2437         /* Hack -- Force good values */
2438         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2439
2440         if (p_ptr->is_dead) return FALSE;
2441
2442         /* Open */
2443         if (v)
2444         {
2445                 if (p_ptr->dustrobe && !do_dec)
2446                 {
2447                         if (p_ptr->dustrobe > v) return FALSE;
2448                 }
2449                 else if (!p_ptr->dustrobe)
2450                 {
2451                         msg_print(_("体が鏡のオーラで覆われた。", "You were enveloped by mirror shards."));
2452                         notice = TRUE;
2453                 }
2454         }
2455
2456         /* Shut */
2457         else
2458         {
2459                 if (p_ptr->dustrobe)
2460                 {
2461                         msg_print(_("鏡のオーラが消えた。", "The mirror shards disappear."));
2462                         notice = TRUE;
2463                 }
2464         }
2465
2466         /* Use the value */
2467         p_ptr->dustrobe = v;
2468
2469         /* Redraw status bar */
2470         p_ptr->redraw |= (PR_STATUS);
2471
2472         /* Nothing to notice */
2473         if (!notice) return (FALSE);
2474
2475         /* Disturb */
2476         if (disturb_state) disturb(0, 0);
2477
2478         /* Recalculate bonuses */
2479         p_ptr->update |= (PU_BONUS);
2480
2481         /* Handle stuff */
2482         handle_stuff();
2483
2484         /* Result */
2485         return (TRUE);
2486 }
2487
2488 /*!
2489  * @brief 一時的壁抜けの継続時間をセットする / Set "p_ptr->kabenuke", notice observable changes
2490  * @param v 継続時間
2491  * @param do_dec 現在の継続時間より長い値のみ上書きする
2492  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2493  */
2494 bool set_kabenuke(TIME_EFFECT v, bool do_dec)
2495 {
2496         bool notice = FALSE;
2497
2498         /* Hack -- Force good values */
2499         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2500
2501         if (p_ptr->is_dead) return FALSE;
2502
2503         /* Open */
2504         if (v)
2505         {
2506                 if (p_ptr->kabenuke && !do_dec)
2507                 {
2508                         if (p_ptr->kabenuke > v) return FALSE;
2509                 }
2510                 else if (!p_ptr->kabenuke)
2511                 {
2512                         msg_print(_("体が半物質の状態になった。", "You became ethereal form."));
2513                         notice = TRUE;
2514                 }
2515         }
2516
2517         /* Shut */
2518         else
2519         {
2520                 if (p_ptr->kabenuke)
2521                 {
2522                         msg_print(_("体が物質化した。", "You are no longer in an ethereal form."));
2523                         notice = TRUE;
2524                 }
2525         }
2526
2527         /* Use the value */
2528         p_ptr->kabenuke = v;
2529
2530         /* Redraw status bar */
2531         p_ptr->redraw |= (PR_STATUS);
2532
2533         /* Nothing to notice */
2534         if (!notice) return (FALSE);
2535
2536         /* Disturb */
2537         if (disturb_state) disturb(0, 0);
2538
2539         /* Recalculate bonuses */
2540         p_ptr->update |= (PU_BONUS);
2541
2542         /* Handle stuff */
2543         handle_stuff();
2544
2545         /* Result */
2546         return (TRUE);
2547 }
2548
2549 /*!
2550  * @brief オクレ兄さんの継続時間をセットする / Set "p_ptr->tsuyoshi", notice observable changes
2551  * @param v 継続時間
2552  * @param do_dec 現在の継続時間より長い値のみ上書きする
2553  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2554  */
2555 bool set_tsuyoshi(TIME_EFFECT v, bool do_dec)
2556 {
2557         bool notice = FALSE;
2558
2559         /* Hack -- Force good values */
2560         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2561
2562         if (p_ptr->is_dead) return FALSE;
2563
2564         /* Open */
2565         if (v)
2566         {
2567                 if (p_ptr->tsuyoshi && !do_dec)
2568                 {
2569                         if (p_ptr->tsuyoshi > v) return FALSE;
2570                 }
2571                 else if (!p_ptr->tsuyoshi)
2572                 {
2573                         msg_print(_("「オクレ兄さん!」", "Brother OKURE!"));
2574                         notice = TRUE;
2575                         chg_virtue(V_VITALITY, 2);
2576                 }
2577         }
2578
2579         /* Shut */
2580         else
2581         {
2582                 if (p_ptr->tsuyoshi)
2583                 {
2584                         msg_print(_("肉体が急速にしぼんでいった。", "Your body had quickly shriveled."));
2585
2586                         (void)dec_stat(A_CON, 20, TRUE);
2587                         (void)dec_stat(A_STR, 20, TRUE);
2588
2589                         notice = TRUE;
2590                         chg_virtue(V_VITALITY, -3);
2591                 }
2592         }
2593
2594         /* Use the value */
2595         p_ptr->tsuyoshi = v;
2596
2597         /* Redraw status bar */
2598         p_ptr->redraw |= (PR_STATUS);
2599
2600         /* Nothing to notice */
2601         if (!notice) return (FALSE);
2602
2603         /* Disturb */
2604         if (disturb_state) disturb(0, 0);
2605
2606         /* Recalculate bonuses */
2607         p_ptr->update |= (PU_BONUS);
2608
2609         /* Recalculate hitpoints */
2610         p_ptr->update |= (PU_HP);
2611
2612         /* Handle stuff */
2613         handle_stuff();
2614
2615         /* Result */
2616         return (TRUE);
2617 }
2618
2619 /*!
2620  * @brief 一時的元素スレイの継続時間をセットする / Set a temporary elemental brand. Clear all other brands. Print status messages. -LM-
2621  * @param attack_type スレイのタイプID
2622  * @param v 継続時間
2623  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2624  */
2625 bool set_ele_attack(u32b attack_type, TIME_EFFECT v)
2626 {
2627         /* Hack -- Force good values */
2628         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2629
2630         /* Clear all elemental attacks (only one is allowed at a time). */
2631         if ((p_ptr->special_attack & (ATTACK_ACID)) && (attack_type != ATTACK_ACID))
2632         {
2633                 p_ptr->special_attack &= ~(ATTACK_ACID);
2634                 msg_print(_("酸で攻撃できなくなった。", "Your temporary acidic brand fades away."));
2635         }
2636         if ((p_ptr->special_attack & (ATTACK_ELEC)) && (attack_type != ATTACK_ELEC))
2637         {
2638                 p_ptr->special_attack &= ~(ATTACK_ELEC);
2639                 msg_print(_("電撃で攻撃できなくなった。", "Your temporary electrical brand fades away."));
2640         }
2641         if ((p_ptr->special_attack & (ATTACK_FIRE)) && (attack_type != ATTACK_FIRE))
2642         {
2643                 p_ptr->special_attack &= ~(ATTACK_FIRE);
2644                 msg_print(_("火炎で攻撃できなくなった。", "Your temporary fiery brand fades away."));
2645         }
2646         if ((p_ptr->special_attack & (ATTACK_COLD)) && (attack_type != ATTACK_COLD))
2647         {
2648                 p_ptr->special_attack &= ~(ATTACK_COLD);
2649                 msg_print(_("冷気で攻撃できなくなった。", "Your temporary frost brand fades away."));
2650         }
2651         if ((p_ptr->special_attack & (ATTACK_POIS)) && (attack_type != ATTACK_POIS))
2652         {
2653                 p_ptr->special_attack &= ~(ATTACK_POIS);
2654                 msg_print(_("毒で攻撃できなくなった。", "Your temporary poison brand fades away."));
2655         }
2656
2657         if ((v) && (attack_type))
2658         {
2659                 /* Set attack type. */
2660                 p_ptr->special_attack |= (attack_type);
2661
2662                 /* Set duration. */
2663                 p_ptr->ele_attack = v;
2664
2665                 /* Message. */
2666 #ifdef JP
2667                 msg_format("%sで攻撃できるようになった!",
2668                              ((attack_type == ATTACK_ACID) ? "酸" :
2669                               ((attack_type == ATTACK_ELEC) ? "電撃" :
2670                                ((attack_type == ATTACK_FIRE) ? "火炎" : 
2671                                 ((attack_type == ATTACK_COLD) ? "冷気" : 
2672                                  ((attack_type == ATTACK_POIS) ? "毒" : 
2673                                         "(なし)"))))));
2674 #else
2675                 msg_format("For a while, the blows you deal will %s",
2676                              ((attack_type == ATTACK_ACID) ? "melt with acid!" :
2677                               ((attack_type == ATTACK_ELEC) ? "shock your foes!" :
2678                                ((attack_type == ATTACK_FIRE) ? "burn with fire!" : 
2679                                 ((attack_type == ATTACK_COLD) ? "chill to the bone!" : 
2680                                  ((attack_type == ATTACK_POIS) ? "poison your enemies!" : 
2681                                         "do nothing special."))))));
2682 #endif
2683         }
2684
2685         /* Disturb */
2686         if (disturb_state) disturb(0, 0);
2687
2688         /* Redraw status bar */
2689         p_ptr->redraw |= (PR_STATUS);
2690
2691         p_ptr->update |= (PU_BONUS);
2692
2693         /* Handle stuff */
2694         handle_stuff();
2695
2696         return (TRUE);
2697 }
2698
2699 /*!
2700  * @brief 一時的元素免疫の継続時間をセットする / Set a temporary elemental brand.  Clear all other brands.  Print status messages. -LM-
2701  * @param immune_type 免疫のタイプID
2702  * @param v 継続時間
2703  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2704  */
2705 bool set_ele_immune(u32b immune_type, TIME_EFFECT v)
2706 {
2707         /* Hack -- Force good values */
2708         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2709
2710         /* Clear all elemental attacks (only one is allowed at a time). */
2711         if ((p_ptr->special_defense & (DEFENSE_ACID)) && (immune_type != DEFENSE_ACID))
2712         {
2713                 p_ptr->special_defense &= ~(DEFENSE_ACID);
2714                 msg_print(_("酸の攻撃で傷つけられるようになった。。", "You are no longer immune to acid."));
2715         }
2716         if ((p_ptr->special_defense & (DEFENSE_ELEC)) && (immune_type != DEFENSE_ELEC))
2717         {
2718                 p_ptr->special_defense &= ~(DEFENSE_ELEC);
2719                 msg_print(_("電撃の攻撃で傷つけられるようになった。。", "You are no longer immune to electricity."));
2720         }
2721         if ((p_ptr->special_defense & (DEFENSE_FIRE)) && (immune_type != DEFENSE_FIRE))
2722         {
2723                 p_ptr->special_defense &= ~(DEFENSE_FIRE);
2724                 msg_print(_("火炎の攻撃で傷つけられるようになった。。", "You are no longer immune to fire."));
2725         }
2726         if ((p_ptr->special_defense & (DEFENSE_COLD)) && (immune_type != DEFENSE_COLD))
2727         {
2728                 p_ptr->special_defense &= ~(DEFENSE_COLD);
2729                 msg_print(_("冷気の攻撃で傷つけられるようになった。。", "You are no longer immune to cold."));
2730         }
2731         if ((p_ptr->special_defense & (DEFENSE_POIS)) && (immune_type != DEFENSE_POIS))
2732         {
2733                 p_ptr->special_defense &= ~(DEFENSE_POIS);
2734                 msg_print(_("毒の攻撃で傷つけられるようになった。。", "You are no longer immune to poison."));
2735         }
2736
2737         if ((v) && (immune_type))
2738         {
2739                 /* Set attack type. */
2740                 p_ptr->special_defense |= (immune_type);
2741
2742                 /* Set duration. */
2743                 p_ptr->ele_immune = v;
2744
2745                 /* Message. */
2746 #ifdef JP
2747                 msg_format("%sの攻撃を受けつけなくなった!",
2748                              ((immune_type == DEFENSE_ACID) ? "酸" :
2749                               ((immune_type == DEFENSE_ELEC) ? "電撃" :
2750                                ((immune_type == DEFENSE_FIRE) ? "火炎" : 
2751                                 ((immune_type == DEFENSE_COLD) ? "冷気" : 
2752                                  ((immune_type == DEFENSE_POIS) ? "毒" : 
2753                                         "(なし)"))))));
2754 #else
2755                 msg_format("For a while, You are immune to %s",
2756                              ((immune_type == DEFENSE_ACID) ? "acid!" :
2757                               ((immune_type == DEFENSE_ELEC) ? "electricity!" :
2758                                ((immune_type == DEFENSE_FIRE) ? "fire!" : 
2759                                 ((immune_type == DEFENSE_COLD) ? "cold!" : 
2760                                  ((immune_type == DEFENSE_POIS) ? "poison!" : 
2761                                         "do nothing special."))))));
2762 #endif
2763         }
2764
2765         /* Disturb */
2766         if (disturb_state) disturb(0, 0);
2767
2768         /* Redraw status bar */
2769         p_ptr->redraw |= (PR_STATUS);
2770
2771         p_ptr->update |= (PU_BONUS);
2772
2773         /* Handle stuff */
2774         handle_stuff();
2775
2776         return (TRUE);
2777 }
2778
2779 /*!
2780  * @brief 一時的酸耐性の継続時間をセットする / Set "p_ptr->oppose_acid", notice observable changes
2781  * @param v 継続時間
2782  * @param do_dec 現在の継続時間より長い値のみ上書きする
2783  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2784  */
2785 bool set_oppose_acid(TIME_EFFECT v, bool do_dec)
2786 {
2787         bool notice = FALSE;
2788
2789         /* Hack -- Force good values */
2790         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2791
2792         if (p_ptr->is_dead) return FALSE;
2793
2794         /* Open */
2795         if (v)
2796         {
2797                 if (p_ptr->oppose_acid && !do_dec)
2798                 {
2799                         if (p_ptr->oppose_acid > v) return FALSE;
2800                 }
2801                 else if (!IS_OPPOSE_ACID())
2802                 {
2803                         msg_print(_("酸への耐性がついた気がする!", "You feel resistant to acid!"));
2804                         notice = TRUE;
2805                 }
2806         }
2807
2808         /* Shut */
2809         else
2810         {
2811                 if (p_ptr->oppose_acid && !music_singing(MUSIC_RESIST) && !(p_ptr->special_defense & KATA_MUSOU))
2812                 {
2813                         msg_print(_("酸への耐性が薄れた気がする。", "You feel less resistant to acid."));
2814                         notice = TRUE;
2815                 }
2816         }
2817
2818         /* Use the value */
2819         p_ptr->oppose_acid = v;
2820
2821         /* Nothing to notice */
2822         if (!notice) return (FALSE);
2823
2824         /* Redraw status bar */
2825         p_ptr->redraw |= (PR_STATUS);
2826
2827         /* Disturb */
2828         if (disturb_state) disturb(0, 0);
2829
2830         /* Handle stuff */
2831         handle_stuff();
2832
2833         /* Result */
2834         return (TRUE);
2835 }
2836
2837 /*!
2838  * @brief 一時的電撃耐性の継続時間をセットする / Set "p_ptr->oppose_elec", notice observable changes
2839  * @param v 継続時間
2840  * @param do_dec 現在の継続時間より長い値のみ上書きする
2841  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2842  */
2843 bool set_oppose_elec(TIME_EFFECT v, bool do_dec)
2844 {
2845         bool notice = FALSE;
2846
2847         /* Hack -- Force good values */
2848         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2849
2850         if (p_ptr->is_dead) return FALSE;
2851
2852         /* Open */
2853         if (v)
2854         {
2855                 if (p_ptr->oppose_elec && !do_dec)
2856                 {
2857                         if (p_ptr->oppose_elec > v) return FALSE;
2858                 }
2859                 else if (!IS_OPPOSE_ELEC())
2860                 {
2861                         msg_print(_("電撃への耐性がついた気がする!", "You feel resistant to electricity!"));
2862                         notice = TRUE;
2863                 }
2864         }
2865
2866         /* Shut */
2867         else
2868         {
2869                 if (p_ptr->oppose_elec && !music_singing(MUSIC_RESIST) && !(p_ptr->special_defense & KATA_MUSOU))
2870                 {
2871                         msg_print(_("電撃への耐性が薄れた気がする。", "You feel less resistant to electricity."));
2872                         notice = TRUE;
2873                 }
2874         }
2875
2876         /* Use the value */
2877         p_ptr->oppose_elec = v;
2878
2879         /* Nothing to notice */
2880         if (!notice) return (FALSE);
2881
2882         /* Redraw status bar */
2883         p_ptr->redraw |= (PR_STATUS);
2884
2885         /* Disturb */
2886         if (disturb_state) disturb(0, 0);
2887
2888         /* Handle stuff */
2889         handle_stuff();
2890
2891         /* Result */
2892         return (TRUE);
2893 }
2894
2895 /*!
2896  * @brief 一時的火炎耐性の継続時間をセットする / Set "p_ptr->oppose_fire", notice observable changes
2897  * @param v 継続時間
2898  * @param do_dec 現在の継続時間より長い値のみ上書きする
2899  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2900  */
2901 bool set_oppose_fire(TIME_EFFECT v, bool do_dec)
2902 {
2903         bool notice = FALSE;
2904
2905         /* Hack -- Force good values */
2906         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2907
2908         if (p_ptr->is_dead) return FALSE;
2909
2910         if ((prace_is_(RACE_DEMON) && (p_ptr->lev > 44)) || (p_ptr->mimic_form == MIMIC_DEMON)) v = 1;
2911         /* Open */
2912         if (v)
2913         {
2914                 if (p_ptr->oppose_fire && !do_dec)
2915                 {
2916                         if (p_ptr->oppose_fire > v) return FALSE;
2917                 }
2918                 else if (!IS_OPPOSE_FIRE())
2919                 {
2920                         msg_print(_("火への耐性がついた気がする!", "You feel resistant to fire!"));
2921                         notice = TRUE;
2922                 }
2923         }
2924
2925         /* Shut */
2926         else
2927         {
2928                 if (p_ptr->oppose_fire && !music_singing(MUSIC_RESIST) && !(p_ptr->special_defense & KATA_MUSOU))
2929                 {
2930                         msg_print(_("火への耐性が薄れた気がする。", "You feel less resistant to fire."));
2931                         notice = TRUE;
2932                 }
2933         }
2934
2935         /* Use the value */
2936         p_ptr->oppose_fire = v;
2937
2938         /* Nothing to notice */
2939         if (!notice) return (FALSE);
2940
2941         /* Redraw status bar */
2942         p_ptr->redraw |= (PR_STATUS);
2943
2944         /* Disturb */
2945         if (disturb_state) disturb(0, 0);
2946
2947         /* Handle stuff */
2948         handle_stuff();
2949
2950         /* Result */
2951         return (TRUE);
2952 }
2953
2954 /*!
2955  * @brief 一時的冷気耐性の継続時間をセットする / Set "p_ptr->oppose_cold", notice observable changes
2956  * @param v 継続時間
2957  * @param do_dec 現在の継続時間より長い値のみ上書きする
2958  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
2959  */
2960 bool set_oppose_cold(TIME_EFFECT v, bool do_dec)
2961 {
2962         bool notice = FALSE;
2963
2964         /* Hack -- Force good values */
2965         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
2966
2967         if (p_ptr->is_dead) return FALSE;
2968
2969         /* Open */
2970         if (v)
2971         {
2972                 if (p_ptr->oppose_cold && !do_dec)
2973                 {
2974                         if (p_ptr->oppose_cold > v) return FALSE;
2975                 }
2976                 else if (!IS_OPPOSE_COLD())
2977                 {
2978                         msg_print(_("冷気への耐性がついた気がする!", "You feel resistant to cold!"));
2979                         notice = TRUE;
2980                 }
2981         }
2982
2983         /* Shut */
2984         else
2985         {
2986                 if (p_ptr->oppose_cold && !music_singing(MUSIC_RESIST) && !(p_ptr->special_defense & KATA_MUSOU))
2987                 {
2988                         msg_print(_("冷気への耐性が薄れた気がする。", "You feel less resistant to cold."));
2989                         notice = TRUE;
2990                 }
2991         }
2992
2993         /* Use the value */
2994         p_ptr->oppose_cold = v;
2995
2996         /* Nothing to notice */
2997         if (!notice) return (FALSE);
2998
2999         /* Redraw status bar */
3000         p_ptr->redraw |= (PR_STATUS);
3001
3002         /* Disturb */
3003         if (disturb_state) disturb(0, 0);
3004
3005         /* Handle stuff */
3006         handle_stuff();
3007
3008         /* Result */
3009         return (TRUE);
3010 }
3011
3012 /*!
3013  * @brief 一時的毒耐性の継続時間をセットする / Set "p_ptr->oppose_pois", notice observable changes
3014  * @param v 継続時間
3015  * @param do_dec 現在の継続時間より長い値のみ上書きする
3016  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
3017  */
3018 bool set_oppose_pois(TIME_EFFECT v, bool do_dec)
3019 {
3020         bool notice = FALSE;
3021
3022         /* Hack -- Force good values */
3023         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
3024
3025         if ((p_ptr->pclass == CLASS_NINJA) && (p_ptr->lev > 44)) v = 1;
3026         if (p_ptr->is_dead) return FALSE;
3027
3028         /* Open */
3029         if (v)
3030         {
3031                 if (p_ptr->oppose_pois && !do_dec)
3032                 {
3033                         if (p_ptr->oppose_pois > v) return FALSE;
3034                 }
3035                 else if (!IS_OPPOSE_POIS())
3036                 {
3037                         msg_print(_("毒への耐性がついた気がする!", "You feel resistant to poison!"));
3038                         notice = TRUE;
3039                 }
3040         }
3041
3042         /* Shut */
3043         else
3044         {
3045                 if (p_ptr->oppose_pois && !music_singing(MUSIC_RESIST) && !(p_ptr->special_defense & KATA_MUSOU))
3046                 {
3047                         msg_print(_("毒への耐性が薄れた気がする。", "You feel less resistant to poison."));
3048                         notice = TRUE;
3049                 }
3050         }
3051
3052         /* Use the value */
3053         p_ptr->oppose_pois = v;
3054
3055         /* Nothing to notice */
3056         if (!notice) return (FALSE);
3057
3058         /* Redraw status bar */
3059         p_ptr->redraw |= (PR_STATUS);
3060
3061         /* Disturb */
3062         if (disturb_state) disturb(0, 0);
3063
3064         /* Handle stuff */
3065         handle_stuff();
3066
3067         /* Result */
3068         return (TRUE);
3069 }
3070
3071 /*!
3072  * @brief 朦朧の継続時間をセットする / Set "p_ptr->stun", notice observable changes
3073  * @param v 継続時間
3074  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
3075  * @details
3076  * Note the special code to only notice "range" changes.
3077  */
3078 bool set_stun(TIME_EFFECT v)
3079 {
3080         int old_aux, new_aux;
3081         bool notice = FALSE;
3082
3083
3084         /* Hack -- Force good values */
3085         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
3086
3087         if (p_ptr->is_dead) return FALSE;
3088
3089         if (prace_is_(RACE_GOLEM) || ((p_ptr->pclass == CLASS_BERSERKER) && (p_ptr->lev > 34))) v = 0;
3090
3091         /* Knocked out */
3092         if (p_ptr->stun > 100)
3093         {
3094                 old_aux = 3;
3095         }
3096
3097         /* Heavy stun */
3098         else if (p_ptr->stun > 50)
3099         {
3100                 old_aux = 2;
3101         }
3102
3103         /* Stun */
3104         else if (p_ptr->stun > 0)
3105         {
3106                 old_aux = 1;
3107         }
3108
3109         /* None */
3110         else
3111         {
3112                 old_aux = 0;
3113         }
3114
3115         /* Knocked out */
3116         if (v > 100)
3117         {
3118                 new_aux = 3;
3119         }
3120
3121         /* Heavy stun */
3122         else if (v > 50)
3123         {
3124                 new_aux = 2;
3125         }
3126
3127         /* Stun */
3128         else if (v > 0)
3129         {
3130                 new_aux = 1;
3131         }
3132
3133         /* None */
3134         else
3135         {
3136                 new_aux = 0;
3137         }
3138
3139         /* Increase cut */
3140         if (new_aux > old_aux)
3141         {
3142                 /* Describe the state */
3143                 switch (new_aux)
3144                 {
3145                         /* Stun */
3146                         case 1: msg_print(_("意識がもうろうとしてきた。", "You have been stunned.")); break;
3147
3148                         /* Heavy stun */
3149                         case 2: msg_print(_("意識がひどくもうろうとしてきた。", "You have been heavily stunned.")); break;
3150
3151                         /* Knocked out */
3152                         case 3: msg_print(_("頭がクラクラして意識が遠のいてきた。", "You have been knocked out.")); break;
3153                 }
3154
3155                 if (randint1(1000) < v || one_in_(16))
3156                 {
3157                         msg_print(_("割れるような頭痛がする。", "A vicious blow hits your head."));
3158
3159                         if (one_in_(3))
3160                         {
3161                                 if (!p_ptr->sustain_int) (void)do_dec_stat(A_INT);
3162                                 if (!p_ptr->sustain_wis) (void)do_dec_stat(A_WIS);
3163                         }
3164                         else if (one_in_(2))
3165                         {
3166                                 if (!p_ptr->sustain_int) (void)do_dec_stat(A_INT);
3167                         }
3168                         else
3169                         {
3170                                 if (!p_ptr->sustain_wis) (void)do_dec_stat(A_WIS);
3171                         }
3172                 }
3173                 if (p_ptr->special_defense & KATA_MASK)
3174                 {
3175                         msg_print(_("型が崩れた。", "Your posture gets loose."));
3176                         p_ptr->special_defense &= ~(KATA_MASK);
3177                         p_ptr->update |= (PU_BONUS);
3178                         p_ptr->update |= (PU_MONSTERS);
3179                         p_ptr->redraw |= (PR_STATE);
3180                         p_ptr->redraw |= (PR_STATUS);
3181                         p_ptr->action = ACTION_NONE;
3182                 }
3183
3184                 /* Sniper */
3185                 if (p_ptr->concent) reset_concentration(TRUE);
3186
3187                 /* Hex */
3188                 if (hex_spelling_any()) stop_hex_spell_all();
3189
3190                 /* Notice */
3191                 notice = TRUE;
3192         }
3193
3194         /* Decrease cut */
3195         else if (new_aux < old_aux)
3196         {
3197                 /* Describe the state */
3198                 switch (new_aux)
3199                 {
3200                         /* None */
3201                   case 0:
3202                         msg_print(_("やっと朦朧状態から回復した。", "You are no longer stunned."));
3203
3204                         if (disturb_state) disturb(0, 0);
3205                         break;
3206                 }
3207
3208                 /* Notice */
3209                 notice = TRUE;
3210         }
3211
3212         /* Use the value */
3213         p_ptr->stun = v;
3214
3215         /* No change */
3216         if (!notice) return (FALSE);
3217
3218         /* Disturb */
3219         if (disturb_state) disturb(0, 0);
3220
3221         /* Recalculate bonuses */
3222         p_ptr->update |= (PU_BONUS);
3223
3224         /* Redraw the "stun" */
3225         p_ptr->redraw |= (PR_STUN);
3226
3227         /* Handle stuff */
3228         handle_stuff();
3229
3230         /* Result */
3231         return (TRUE);
3232 }
3233
3234
3235 /*!
3236  * @brief 出血の継続時間をセットする / Set "p_ptr->cut", notice observable changes
3237  * @param v 継続時間
3238  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
3239  * @details
3240  * Note the special code to only notice "range" changes.
3241  */
3242 bool set_cut(TIME_EFFECT v)
3243 {
3244         int old_aux, new_aux;
3245         bool notice = FALSE;
3246
3247         /* Hack -- Force good values */
3248         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
3249
3250         if (p_ptr->is_dead) return FALSE;
3251
3252         if ((p_ptr->prace == RACE_GOLEM ||
3253             p_ptr->prace == RACE_SKELETON ||
3254             p_ptr->prace == RACE_SPECTRE ||
3255                 (p_ptr->prace == RACE_ZOMBIE && p_ptr->lev > 11)) &&
3256             !p_ptr->mimic_form)
3257                 v = 0;
3258
3259         /* Mortal wound */
3260         if (p_ptr->cut > 1000)
3261         {
3262                 old_aux = 7;
3263         }
3264
3265         /* Deep gash */
3266         else if (p_ptr->cut > 200)
3267         {
3268                 old_aux = 6;
3269         }
3270
3271         /* Severe cut */
3272         else if (p_ptr->cut > 100)
3273         {
3274                 old_aux = 5;
3275         }
3276
3277         /* Nasty cut */
3278         else if (p_ptr->cut > 50)
3279         {
3280                 old_aux = 4;
3281         }
3282
3283         /* Bad cut */
3284         else if (p_ptr->cut > 25)
3285         {
3286                 old_aux = 3;
3287         }
3288
3289         /* Light cut */
3290         else if (p_ptr->cut > 10)
3291         {
3292                 old_aux = 2;
3293         }
3294
3295         /* Graze */
3296         else if (p_ptr->cut > 0)
3297         {
3298                 old_aux = 1;
3299         }
3300
3301         /* None */
3302         else
3303         {
3304                 old_aux = 0;
3305         }
3306
3307         /* Mortal wound */
3308         if (v > 1000)
3309         {
3310                 new_aux = 7;
3311         }
3312
3313         /* Deep gash */
3314         else if (v > 200)
3315         {
3316                 new_aux = 6;
3317         }
3318
3319         /* Severe cut */
3320         else if (v > 100)
3321         {
3322                 new_aux = 5;
3323         }
3324
3325         /* Nasty cut */
3326         else if (v > 50)
3327         {
3328                 new_aux = 4;
3329         }
3330
3331         /* Bad cut */
3332         else if (v > 25)
3333         {
3334                 new_aux = 3;
3335         }
3336
3337         /* Light cut */
3338         else if (v > 10)
3339         {
3340                 new_aux = 2;
3341         }
3342
3343         /* Graze */
3344         else if (v > 0)
3345         {
3346                 new_aux = 1;
3347         }
3348
3349         /* None */
3350         else
3351         {
3352                 new_aux = 0;
3353         }
3354
3355         /* Increase cut */
3356         if (new_aux > old_aux)
3357         {
3358                 /* Describe the state */
3359                 switch (new_aux)
3360                 {
3361                         /* Graze */
3362                         case 1: msg_print(_("かすり傷を負ってしまった。", "You have been given a graze.")); break;
3363
3364                         /* Light cut */
3365                         case 2: msg_print(_("軽い傷を負ってしまった。", "You have been given a light cut.")); break;
3366
3367                         /* Bad cut */
3368                         case 3: msg_print(_("ひどい傷を負ってしまった。", "You have been given a bad cut.")); break;
3369
3370                         /* Nasty cut */
3371                         case 4: msg_print(_("大変な傷を負ってしまった。", "You have been given a nasty cut.")); break;
3372
3373                         /* Severe cut */
3374                         case 5: msg_print(_("重大な傷を負ってしまった。", "You have been given a severe cut.")); break;
3375
3376                         /* Deep gash */
3377                         case 6: msg_print(_("ひどい深手を負ってしまった。", "You have been given a deep gash.")); break;
3378
3379                         /* Mortal wound */
3380                         case 7: msg_print(_("致命的な傷を負ってしまった。", "You have been given a mortal wound.")); break;
3381                 }
3382
3383                 /* Notice */
3384                 notice = TRUE;
3385
3386                 if (randint1(1000) < v || one_in_(16))
3387                 {
3388                         if (!p_ptr->sustain_chr)
3389                         {
3390                                 msg_print(_("ひどい傷跡が残ってしまった。", "You have been horribly scarred."));
3391                                 do_dec_stat(A_CHR);
3392                         }
3393                 }
3394         }
3395
3396         /* Decrease cut */
3397         else if (new_aux < old_aux)
3398         {
3399                 /* Describe the state */
3400                 switch (new_aux)
3401                 {
3402                         /* None */
3403                         case 0:
3404                         msg_format(_("やっと%s。", "You are no longer bleeding."), p_ptr->prace == RACE_ANDROID ? "怪我が直った" : "出血が止まった");
3405
3406                         if (disturb_state) disturb(0, 0);
3407                         break;
3408                 }
3409
3410                 /* Notice */
3411                 notice = TRUE;
3412         }
3413
3414         /* Use the value */
3415         p_ptr->cut = v;
3416
3417         /* No change */
3418         if (!notice) return (FALSE);
3419
3420         /* Disturb */
3421         if (disturb_state) disturb(0, 0);
3422
3423         /* Recalculate bonuses */
3424         p_ptr->update |= (PU_BONUS);
3425
3426         /* Redraw the "cut" */
3427         p_ptr->redraw |= (PR_CUT);
3428
3429         /* Handle stuff */
3430         handle_stuff();
3431
3432         /* Result */
3433         return (TRUE);
3434 }
3435
3436 /*!
3437  * @brief 空腹状態をセットする / Set "p_ptr->food", notice observable changes
3438  * @param v 継続時間
3439  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
3440  * @details
3441  * Set "", notice observable changes\n
3442  *\n
3443  * The "p_ptr->food" variable can get as large as 20000, allowing the
3444  * addition of the most "filling" item, Elvish Waybread, which adds
3445  * 7500 food units, without overflowing the 32767 maximum limit.\n
3446  *\n
3447  * Perhaps we should disturb the player with various messages,
3448  * especially messages about hunger status changes.  \n
3449  *\n
3450  * Digestion of food is handled in "dungeon.c", in which, normally,
3451  * the player digests about 20 food units per 100 game turns, more
3452  * when "fast", more when "regenerating", less with "slow digestion",
3453  * but when the player is "gorged", he digests 100 food units per 10
3454  * game turns, or a full 1000 food units per 100 game turns.\n
3455  *\n
3456  * Note that the player's speed is reduced by 10 units while gorged,
3457  * so if the player eats a single food ration (5000 food units) when
3458  * full (15000 food units), he will be gorged for (5000/100)*10 = 500
3459  * game turns, or 500/(100/5) = 25 player turns (if nothing else is
3460  * affecting the player speed).\n
3461  */
3462 bool set_food(TIME_EFFECT v)
3463 {
3464         int old_aux, new_aux;
3465
3466         bool notice = FALSE;
3467
3468         /* Hack -- Force good values */
3469         v = (v > 20000) ? 20000 : (v < 0) ? 0 : v;
3470
3471         /* Fainting / Starving */
3472         if (p_ptr->food < PY_FOOD_FAINT)
3473         {
3474                 old_aux = 0;
3475         }
3476
3477         /* Weak */
3478         else if (p_ptr->food < PY_FOOD_WEAK)
3479         {
3480                 old_aux = 1;
3481         }
3482
3483         /* Hungry */
3484         else if (p_ptr->food < PY_FOOD_ALERT)
3485         {
3486                 old_aux = 2;
3487         }
3488
3489         /* Normal */
3490         else if (p_ptr->food < PY_FOOD_FULL)
3491         {
3492                 old_aux = 3;
3493         }
3494
3495         /* Full */
3496         else if (p_ptr->food < PY_FOOD_MAX)
3497         {
3498                 old_aux = 4;
3499         }
3500
3501         /* Gorged */
3502         else
3503         {
3504                 old_aux = 5;
3505         }
3506
3507         /* Fainting / Starving */
3508         if (v < PY_FOOD_FAINT)
3509         {
3510                 new_aux = 0;
3511         }
3512
3513         /* Weak */
3514         else if (v < PY_FOOD_WEAK)
3515         {
3516                 new_aux = 1;
3517         }
3518
3519         /* Hungry */
3520         else if (v < PY_FOOD_ALERT)
3521         {
3522                 new_aux = 2;
3523         }
3524
3525         /* Normal */
3526         else if (v < PY_FOOD_FULL)
3527         {
3528                 new_aux = 3;
3529         }
3530
3531         /* Full */
3532         else if (v < PY_FOOD_MAX)
3533         {
3534                 new_aux = 4;
3535         }
3536
3537         /* Gorged */
3538         else
3539         {
3540                 new_aux = 5;
3541         }
3542
3543         if (old_aux < 1 && new_aux > 0)
3544                 chg_virtue(V_PATIENCE, 2);
3545         else if (old_aux < 3 && (old_aux != new_aux))
3546                 chg_virtue(V_PATIENCE, 1);
3547         if (old_aux == 2)
3548                 chg_virtue(V_TEMPERANCE, 1);
3549         if (old_aux == 0)
3550                 chg_virtue(V_TEMPERANCE, -1);
3551
3552         /* Food increase */
3553         if (new_aux > old_aux)
3554         {
3555                 /* Describe the state */
3556                 switch (new_aux)
3557                 {
3558                         /* Weak */
3559                         case 1: msg_print(_("まだ空腹で倒れそうだ。", "You are still weak.")); break;
3560
3561                         /* Hungry */
3562                         case 2: msg_print(_("まだ空腹だ。", "You are still hungry.")); break;
3563
3564                         /* Normal */
3565                         case 3: msg_print(_("空腹感がおさまった。", "You are no longer hungry.")); break;
3566
3567                         /* Full */
3568                         case 4: msg_print(_("満腹だ!", "You are full!")); break;
3569
3570                         /* Bloated */
3571                         case 5:
3572                         msg_print(_("食べ過ぎだ!", "You have gorged yourself!"));
3573                         chg_virtue(V_HARMONY, -1);
3574                         chg_virtue(V_PATIENCE, -1);
3575                         chg_virtue(V_TEMPERANCE, -2);
3576
3577                         break;
3578                 }
3579
3580                 /* Change */
3581                 notice = TRUE;
3582         }
3583
3584         /* Food decrease */
3585         else if (new_aux < old_aux)
3586         {
3587                 /* Describe the state */
3588                 switch (new_aux)
3589                 {
3590                         /* Fainting / Starving */
3591                         case 0: msg_print(_("あまりにも空腹で気を失ってしまった!", "You are getting faint from hunger!")); break;
3592
3593                         /* Weak */
3594                         case 1: msg_print(_("お腹が空いて倒れそうだ。", "You are getting weak from hunger!")); break;
3595
3596                         /* Hungry */
3597                         case 2: msg_print(_("お腹が空いてきた。", "You are getting hungry.")); break;
3598
3599                         /* Normal */
3600                         case 3: msg_print(_("満腹感がなくなった。", "You are no longer full.")); break;
3601
3602                         /* Full */
3603                         case 4: msg_print(_("やっとお腹がきつくなくなった。", "You are no longer gorged.")); break;
3604                 }
3605
3606                 if (p_ptr->wild_mode && (new_aux < 2))
3607                 {
3608                         change_wild_mode();
3609                 }
3610
3611                 /* Change */
3612                 notice = TRUE;
3613         }
3614
3615         /* Use the value */
3616         p_ptr->food = v;
3617
3618         /* Nothing to notice */
3619         if (!notice) return (FALSE);
3620
3621         /* Disturb */
3622         if (disturb_state) disturb(0, 0);
3623
3624         /* Recalculate bonuses */
3625         p_ptr->update |= (PU_BONUS);
3626
3627         /* Redraw hunger */
3628         p_ptr->redraw |= (PR_HUNGER);
3629
3630         /* Handle stuff */
3631         handle_stuff();
3632
3633         /* Result */
3634         return (TRUE);
3635 }
3636
3637 /*!
3638  * @brief プレイヤーの基本能力値を増加させる / Increases a stat by one randomized level -RAK-
3639  * @param stat 上昇させるステータスID
3640  * @return 実際に上昇した場合TRUEを返す。
3641  * @details
3642  * Note that this function (used by stat potions) now restores\n
3643  * the stat BEFORE increasing it.\n
3644  */
3645 bool inc_stat(int stat)
3646 {
3647         BASE_STATUS value, gain;
3648
3649         /* Then augment the current/max stat */
3650         value = p_ptr->stat_cur[stat];
3651
3652         /* Cannot go above 18/100 */
3653         if (value < p_ptr->stat_max_max[stat])
3654         {
3655                 /* Gain one (sometimes two) points */
3656                 if (value < 18)
3657                 {
3658                         gain = ((randint0(100) < 75) ? 1 : 2);
3659                         value += gain;
3660                 }
3661
3662                 /* Gain 1/6 to 1/3 of distance to 18/100 */
3663                 else if (value < (p_ptr->stat_max_max[stat]-2))
3664                 {
3665                         /* Approximate gain value */
3666                         gain = (((p_ptr->stat_max_max[stat]) - value) / 2 + 3) / 2;
3667
3668                         /* Paranoia */
3669                         if (gain < 1) gain = 1;
3670
3671                         /* Apply the bonus */
3672                         value += randint1(gain) + gain / 2;
3673
3674                         /* Maximal value */
3675                         if (value > (p_ptr->stat_max_max[stat]-1)) value = p_ptr->stat_max_max[stat]-1;
3676                 }
3677
3678                 /* Gain one point at a time */
3679                 else
3680                 {
3681                         value++;
3682                 }
3683
3684                 /* Save the new value */
3685                 p_ptr->stat_cur[stat] = value;
3686
3687                 /* Bring up the maximum too */
3688                 if (value > p_ptr->stat_max[stat])
3689                 {
3690                         p_ptr->stat_max[stat] = value;
3691                 }
3692
3693                 /* Recalculate bonuses */
3694                 p_ptr->update |= (PU_BONUS);
3695
3696                 /* Success */
3697                 return (TRUE);
3698         }
3699
3700         /* Nothing to gain */
3701         return (FALSE);
3702 }
3703
3704 /*!
3705  * @brief プレイヤーの基本能力値を減少させる / Decreases a stat by an amount indended to vary from 0 to 100 percent.
3706  * @param stat 減少させるステータスID
3707  * @param amount 減少させる基本量
3708  * @param permanent TRUEならば現在の最大値を減少させる
3709  * @return 実際に減少した場合TRUEを返す。
3710  * @details
3711  *\n
3712  * Amount could be a little higher in extreme cases to mangle very high\n
3713  * stats from massive assaults.  -CWS\n
3714  *\n
3715  * Note that "permanent" means that the *given* amount is permanent,\n
3716  * not that the new value becomes permanent.  This may not work exactly\n
3717  * as expected, due to "weirdness" in the algorithm, but in general,\n
3718  * if your stat is already drained, the "max" value will not drop all\n
3719  * the way down to the "cur" value.\n
3720  */
3721 bool dec_stat(int stat, int amount, int permanent)
3722 {
3723         BASE_STATUS cur, max;
3724         int loss, same;
3725         bool res = FALSE;
3726
3727
3728         /* Acquire current value */
3729         cur = p_ptr->stat_cur[stat];
3730         max = p_ptr->stat_max[stat];
3731
3732         /* Note when the values are identical */
3733         same = (cur == max);
3734
3735         /* Damage "current" value */
3736         if (cur > 3)
3737         {
3738                 /* Handle "low" values */
3739                 if (cur <= 18)
3740                 {
3741                         if (amount > 90) cur--;
3742                         if (amount > 50) cur--;
3743                         if (amount > 20) cur--;
3744                         cur--;
3745                 }
3746
3747                 /* Handle "high" values */
3748                 else
3749                 {
3750                         /* Hack -- Decrement by a random amount between one-quarter */
3751                         /* and one-half of the stat bonus times the percentage, with a */
3752                         /* minimum damage of half the percentage. -CWS */
3753                         loss = (((cur-18) / 2 + 1) / 2 + 1);
3754
3755                         /* Paranoia */
3756                         if (loss < 1) loss = 1;
3757
3758                         /* Randomize the loss */
3759                         loss = ((randint1(loss) + loss) * amount) / 100;
3760
3761                         /* Maximal loss */
3762                         if (loss < amount/2) loss = amount/2;
3763
3764                         /* Lose some points */
3765                         cur = cur - loss;
3766
3767                         /* Hack -- Only reduce stat to 17 sometimes */
3768                         if (cur < 18) cur = (amount <= 20) ? 18 : 17;
3769                 }
3770
3771                 /* Prevent illegal values */
3772                 if (cur < 3) cur = 3;
3773
3774                 /* Something happened */
3775                 if (cur != p_ptr->stat_cur[stat]) res = TRUE;
3776         }
3777
3778         /* Damage "max" value */
3779         if (permanent && (max > 3))
3780         {
3781                 chg_virtue(V_SACRIFICE, 1);
3782                 if (stat == A_WIS || stat == A_INT)
3783                         chg_virtue(V_ENLIGHTEN, -2);
3784
3785                 /* Handle "low" values */
3786                 if (max <= 18)
3787                 {
3788                         if (amount > 90) max--;
3789                         if (amount > 50) max--;
3790                         if (amount > 20) max--;
3791                         max--;
3792                 }
3793
3794                 /* Handle "high" values */
3795                 else
3796                 {
3797                         /* Hack -- Decrement by a random amount between one-quarter */
3798                         /* and one-half of the stat bonus times the percentage, with a */
3799                         /* minimum damage of half the percentage. -CWS */
3800                         loss = (((max-18) / 2 + 1) / 2 + 1);
3801                         loss = ((randint1(loss) + loss) * amount) / 100;
3802                         if (loss < amount/2) loss = amount/2;
3803
3804                         /* Lose some points */
3805                         max = max - loss;
3806
3807                         /* Hack -- Only reduce stat to 17 sometimes */
3808                         if (max < 18) max = (amount <= 20) ? 18 : 17;
3809                 }
3810
3811                 /* Hack -- keep it clean */
3812                 if (same || (max < cur)) max = cur;
3813
3814                 /* Something happened */
3815                 if (max != p_ptr->stat_max[stat]) res = TRUE;
3816         }
3817
3818         /* Apply changes */
3819         if (res)
3820         {
3821                 /* Actually set the stat to its new value. */
3822                 p_ptr->stat_cur[stat] = cur;
3823                 p_ptr->stat_max[stat] = max;
3824
3825                 /* Redisplay the stats later */
3826                 p_ptr->redraw |= (PR_STATS);
3827
3828                 /* Recalculate bonuses */
3829                 p_ptr->update |= (PU_BONUS);
3830         }
3831
3832         return (res);
3833 }
3834
3835
3836 /*!
3837  * @brief プレイヤーの基本能力値を回復させる / Restore a stat.  Return TRUE only if this actually makes a difference.
3838  * @param stat 回復ステータスID
3839  * @return 実際に回復した場合TRUEを返す。
3840  */
3841 bool res_stat(int stat)
3842 {
3843         /* Restore if needed */
3844         if (p_ptr->stat_cur[stat] != p_ptr->stat_max[stat])
3845         {
3846                 /* Restore */
3847                 p_ptr->stat_cur[stat] = p_ptr->stat_max[stat];
3848
3849                 /* Recalculate bonuses */
3850                 p_ptr->update |= (PU_BONUS);
3851
3852                 /* Redisplay the stats later */
3853                 p_ptr->redraw |= (PR_STATS);
3854
3855                 /* Success */
3856                 return (TRUE);
3857         }
3858
3859         /* Nothing to restore */
3860         return (FALSE);
3861 }
3862
3863
3864 /*
3865  * Increase players hit points, notice effects
3866  */
3867 bool hp_player(int num)
3868 {
3869         int vir;
3870         vir = virtue_number(V_VITALITY);
3871
3872         if(num <= 0) return (FALSE);
3873
3874         if(vir)
3875         {
3876                 num = num * (p_ptr->virtues[vir - 1] + 1250) / 1250;
3877         }
3878         /* Healing needed */
3879         if (p_ptr->chp < p_ptr->mhp)
3880         {
3881                 if ((num > 0) && (p_ptr->chp < (p_ptr->mhp/3)))
3882                         chg_virtue(V_TEMPERANCE, 1);
3883                 /* Gain hitpoints */
3884                 p_ptr->chp += num;
3885
3886                 /* Enforce maximum */
3887                 if (p_ptr->chp >= p_ptr->mhp)
3888                 {
3889                         p_ptr->chp = p_ptr->mhp;
3890                         p_ptr->chp_frac = 0;
3891                 }
3892
3893                 /* Redraw */
3894                 p_ptr->redraw |= (PR_HP);
3895
3896                 p_ptr->window |= (PW_PLAYER);
3897
3898                 /* Heal 0-4 */
3899                 if (num < 5)
3900                 {
3901                         msg_print(_("少し気分が良くなった。", "You feel a little better."));
3902                 }
3903
3904                 /* Heal 5-14 */
3905                 else if (num < 15)
3906                 {
3907                         msg_print(_("気分が良くなった。", "You feel better."));
3908                 }
3909
3910                 /* Heal 15-34 */
3911                 else if (num < 35)
3912                 {
3913                         msg_print(_("とても気分が良くなった。", "You feel much better."));
3914                 }
3915
3916                 /* Heal 35+ */
3917                 else
3918                 {
3919                         msg_print(_("ひじょうに気分が良くなった。", "You feel very good."));
3920                 }
3921
3922                 /* Notice */
3923                 return (TRUE);
3924         }
3925
3926         /* Ignore */
3927         return (FALSE);
3928 }
3929
3930
3931 /*
3932  * Array of stat "descriptions"
3933  */
3934 static cptr desc_stat_pos[] =
3935 {
3936         _("強く", "strong"),
3937         _("知的に", "smart"),
3938         _("賢く", "wise"),
3939         _("器用に", "dextrous"),
3940         _("健康に", "healthy"),
3941         _("美しく", "cute")
3942 };
3943
3944
3945 /*
3946  * Array of stat "descriptions"
3947  */
3948 static cptr desc_stat_neg[] =
3949 {
3950         _("弱く", "weak"),
3951         _("無知に", "stupid"),
3952         _("愚かに", "naive"),
3953         _("不器用に", "clumsy"),
3954         _("不健康に", "sickly"),
3955         _("醜く", "ugly")
3956 };
3957
3958
3959 /*
3960  * Lose a "point"
3961  */
3962 bool do_dec_stat(int stat)
3963 {
3964         bool sust = FALSE;
3965
3966         /* Access the "sustain" */
3967         switch (stat)
3968         {
3969                 case A_STR: if (p_ptr->sustain_str) sust = TRUE; break;
3970                 case A_INT: if (p_ptr->sustain_int) sust = TRUE; break;
3971                 case A_WIS: if (p_ptr->sustain_wis) sust = TRUE; break;
3972                 case A_DEX: if (p_ptr->sustain_dex) sust = TRUE; break;
3973                 case A_CON: if (p_ptr->sustain_con) sust = TRUE; break;
3974                 case A_CHR: if (p_ptr->sustain_chr) sust = TRUE; break;
3975         }
3976
3977         /* Sustain */
3978         if (sust && (!ironman_nightmare || randint0(13)))
3979         {
3980                 msg_format(_("%sなった気がしたが、すぐに元に戻った。", "You feel %s for a moment, but the feeling passes."),
3981                                         desc_stat_neg[stat]);
3982
3983                 /* Notice effect */
3984                 return (TRUE);
3985         }
3986
3987         /* Attempt to reduce the stat */
3988         if (dec_stat(stat, 10, (ironman_nightmare && !randint0(13))))
3989         {
3990                 msg_format(_("ひどく%sなった気がする。", "You feel very %s."), desc_stat_neg[stat]);
3991
3992                 /* Notice effect */
3993                 return (TRUE);
3994         }
3995
3996         /* Nothing obvious */
3997         return (FALSE);
3998 }
3999
4000
4001 /*
4002  * Restore lost "points" in a stat
4003  */
4004 bool do_res_stat(int stat)
4005 {
4006         /* Attempt to increase */
4007         if (res_stat(stat))
4008         {
4009                 msg_format(_("元通りに%sなった気がする。", "You feel less %s."), desc_stat_pos[stat]);
4010
4011                 /* Notice */
4012                 return (TRUE);
4013         }
4014
4015         /* Nothing obvious */
4016         return (FALSE);
4017 }
4018
4019
4020 /*
4021  * Gain a "point" in a stat
4022  */
4023 bool do_inc_stat(int stat)
4024 {
4025         bool res;
4026
4027         /* Restore strength */
4028         res = res_stat(stat);
4029
4030         /* Attempt to increase */
4031         if (inc_stat(stat))
4032         {
4033                 if (stat == A_WIS)
4034                 {
4035                         chg_virtue(V_ENLIGHTEN, 1);
4036                         chg_virtue(V_FAITH, 1);
4037                 }
4038                 else if (stat == A_INT)
4039                 {
4040                         chg_virtue(V_KNOWLEDGE, 1);
4041                         chg_virtue(V_ENLIGHTEN, 1);
4042                 }
4043                 else if (stat == A_CON)
4044                         chg_virtue(V_VITALITY, 1);
4045
4046                 msg_format(_("ワーオ!とても%sなった!", "Wow!  You feel very %s!"), desc_stat_pos[stat]);
4047
4048                 /* Notice */
4049                 return (TRUE);
4050         }
4051
4052         /* Restoration worked */
4053         if (res)
4054         {
4055                 msg_format(_("元通りに%sなった気がする。", "You feel less %s."), desc_stat_pos[stat]);
4056
4057                 /* Notice */
4058                 return (TRUE);
4059         }
4060
4061         /* Nothing obvious */
4062         return (FALSE);
4063 }
4064
4065
4066 /*
4067  * Restores any drained experience
4068  */
4069 bool restore_level(void)
4070 {
4071         /* Restore experience */
4072         if (p_ptr->exp < p_ptr->max_exp)
4073         {
4074                 msg_print(_("経験値が戻ってきた気がする。", "You feel your experience returning."));
4075
4076                 /* Restore the experience */
4077                 p_ptr->exp = p_ptr->max_exp;
4078
4079                 /* Check the experience */
4080                 check_experience();
4081
4082                 /* Did something */
4083                 return (TRUE);
4084         }
4085
4086         /* No effect */
4087         return (FALSE);
4088 }
4089
4090 /*
4091  * Forget everything
4092  */
4093 bool lose_all_info(void)
4094 {
4095         int i;
4096
4097         chg_virtue(V_KNOWLEDGE, -5);
4098         chg_virtue(V_ENLIGHTEN, -5);
4099
4100         /* Forget info about objects */
4101         for (i = 0; i < INVEN_TOTAL; i++)
4102         {
4103                 object_type *o_ptr = &inventory[i];
4104
4105                 /* Skip non-objects */
4106                 if (!o_ptr->k_idx) continue;
4107
4108                 /* Allow "protection" by the MENTAL flag */
4109                 if (o_ptr->ident & (IDENT_MENTAL)) continue;
4110
4111                 /* Remove "default inscriptions" */
4112                 o_ptr->feeling = FEEL_NONE;
4113
4114                 /* Hack -- Clear the "empty" flag */
4115                 o_ptr->ident &= ~(IDENT_EMPTY);
4116
4117                 /* Hack -- Clear the "known" flag */
4118                 o_ptr->ident &= ~(IDENT_KNOWN);
4119
4120                 /* Hack -- Clear the "felt" flag */
4121                 o_ptr->ident &= ~(IDENT_SENSE);
4122         }
4123
4124         /* Recalculate bonuses */
4125         p_ptr->update |= (PU_BONUS);
4126
4127         /* Combine / Reorder the pack (later) */
4128         p_ptr->notice |= (PN_COMBINE | PN_REORDER);
4129
4130         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
4131
4132         /* Mega-Hack -- Forget the map */
4133         wiz_dark();
4134
4135         /* It worked */
4136         return (TRUE);
4137 }
4138
4139
4140 void do_poly_wounds(void)
4141 {
4142         /* Changed to always provide at least _some_ healing */
4143         s16b wounds = p_ptr->cut;
4144         s16b hit_p = (p_ptr->mhp - p_ptr->chp);
4145         s16b change = damroll(p_ptr->lev, 5);
4146         bool Nasty_effect = one_in_(5);
4147
4148         if (!(wounds || hit_p || Nasty_effect)) return;
4149
4150         msg_print(_("傷がより軽いものに変化した。", "Your wounds are polymorphed into less serious ones."));
4151         hp_player(change);
4152         if (Nasty_effect)
4153         {
4154                 msg_print(_("新たな傷ができた!", "A new wound was created!"));
4155                 take_hit(DAMAGE_LOSELIFE, change / 2, _("変化した傷", "a polymorphed wound"), -1);
4156                 set_cut(change);
4157         }
4158         else
4159         {
4160                 set_cut(p_ptr->cut - (change / 2));
4161         }
4162 }
4163
4164
4165 /*
4166  * Change player race
4167  */
4168 void change_race(CHARACTER_IDX new_race, cptr effect_msg)
4169 {
4170         cptr title = race_info[new_race].title;
4171         int  old_race = p_ptr->prace;
4172
4173 #ifdef JP
4174         msg_format("あなたは%s%sに変化した!", effect_msg, title);
4175 #else
4176         msg_format("You turn into %s %s%s!", (!effect_msg[0] && is_a_vowel(title[0]) ? "an" : "a"), effect_msg, title);
4177 #endif
4178
4179         chg_virtue(V_CHANCE, 2);
4180
4181         if (p_ptr->prace < 32)
4182         {
4183                 p_ptr->old_race1 |= 1L << p_ptr->prace;
4184         }
4185         else
4186         {
4187                 p_ptr->old_race2 |= 1L << (p_ptr->prace - 32);
4188         }
4189         p_ptr->prace = new_race;
4190         rp_ptr = &race_info[p_ptr->prace];
4191
4192         /* Experience factor */
4193         p_ptr->expfact = rp_ptr->r_exp + cp_ptr->c_exp;
4194
4195         /*
4196          * The speed bonus of Klackons and Sprites are disabled
4197          * and the experience penalty is decreased.
4198          */
4199         if (((p_ptr->pclass == CLASS_MONK) || (p_ptr->pclass == CLASS_FORCETRAINER) || (p_ptr->pclass == CLASS_NINJA)) && ((p_ptr->prace == RACE_KLACKON) || (p_ptr->prace == RACE_SPRITE)))
4200                 p_ptr->expfact -= 15;
4201
4202         /* Get character's height and weight */
4203         get_height_weight();
4204
4205         /* Hitdice */
4206         if (p_ptr->pclass == CLASS_SORCERER)
4207                 p_ptr->hitdie = rp_ptr->r_mhp/2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
4208         else
4209                 p_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
4210
4211         do_cmd_rerate(FALSE);
4212
4213         /* The experience level may be modified */
4214         check_experience();
4215
4216         p_ptr->redraw |= (PR_BASIC);
4217
4218         p_ptr->update |= (PU_BONUS);
4219
4220         handle_stuff();
4221
4222         /* Load an autopick preference file */
4223         if (old_race != p_ptr->prace) autopick_load_pref(FALSE);
4224
4225         /* Player's graphic tile may change */
4226         lite_spot(p_ptr->y, p_ptr->x);
4227 }
4228
4229
4230 void do_poly_self(void)
4231 {
4232         int power = p_ptr->lev;
4233
4234         msg_print(_("あなたは変化の訪れを感じた...", "You feel a change coming over you..."));
4235         chg_virtue(V_CHANCE, 1);
4236
4237         if ((power > randint0(20)) && one_in_(3) && (p_ptr->prace != RACE_ANDROID))
4238         {
4239                 char effect_msg[80] = "";
4240                 CHARACTER_IDX new_race;
4241
4242                 /* Some form of racial polymorph... */
4243                 power -= 10;
4244
4245                 if ((power > randint0(5)) && one_in_(4))
4246                 {
4247                         /* sex change */
4248                         power -= 2;
4249
4250                         if (p_ptr->psex == SEX_MALE)
4251                         {
4252                                 p_ptr->psex = SEX_FEMALE;
4253                                 sp_ptr = &sex_info[p_ptr->psex];
4254                                 sprintf(effect_msg, _("女性の", "female "));
4255                         }
4256                         else
4257                         {
4258                                 p_ptr->psex = SEX_MALE;
4259                                 sp_ptr = &sex_info[p_ptr->psex];
4260                                 sprintf(effect_msg, _("男性の", "male "));
4261                         }
4262                 }
4263
4264                 if ((power > randint0(30)) && one_in_(5))
4265                 {
4266                         int tmp = 0;
4267
4268                         /* Harmful deformity */
4269                         power -= 15;
4270
4271                         while (tmp < 6)
4272                         {
4273                                 if (one_in_(2))
4274                                 {
4275                                         (void)dec_stat(tmp, randint1(6) + 6, one_in_(3));
4276                                         power -= 1;
4277                                 }
4278                                 tmp++;
4279                         }
4280
4281                         /* Deformities are discriminated against! */
4282                         (void)dec_stat(A_CHR, randint1(6), TRUE);
4283
4284                         if (effect_msg[0])
4285                         {
4286                                 char tmp_msg[10];
4287                                 sprintf(tmp_msg,_("%s", "%s "),effect_msg);
4288                                 sprintf(effect_msg,_("奇形の%s", "deformed %s "),tmp_msg);
4289                         }
4290                         else
4291                         {
4292                                 sprintf(effect_msg,_("奇形の", "deformed "));
4293                         }
4294                 }
4295
4296                 while ((power > randint0(20)) && one_in_(10))
4297                 {
4298                         /* Polymorph into a less mutated form */
4299                         power -= 10;
4300
4301                         if (!lose_mutation(0))
4302                         msg_print(_("奇妙なくらい普通になった気がする。", "You feel oddly normal."));
4303                 }
4304
4305                 do
4306                 {
4307                         new_race = (CHARACTER_IDX)randint0(MAX_RACES);
4308                 }
4309                 while ((new_race == p_ptr->prace) || (new_race == RACE_ANDROID));
4310
4311                 change_race(new_race, effect_msg);
4312         }
4313
4314         if ((power > randint0(30)) && one_in_(6))
4315         {
4316                 int tmp = 0;
4317
4318                 /* Abomination! */
4319                 power -= 20;
4320                 msg_format(_("%sの構成が変化した!", "Your internal organs are rearranged!"), p_ptr->prace == RACE_ANDROID ? "機械" : "内臓");
4321
4322                 while (tmp < 6)
4323                 {
4324                         (void)dec_stat(tmp, randint1(6) + 6, one_in_(3));
4325                         tmp++;
4326                 }
4327                 if (one_in_(6))
4328                 {
4329                         msg_print(_("現在の姿で生きていくのは困難なようだ!", "You find living difficult in your present form!"));
4330                         take_hit(DAMAGE_LOSELIFE, damroll(randint1(10), p_ptr->lev), _("致命的な突然変異", "a lethal mutation"), -1);
4331
4332                         power -= 10;
4333                 }
4334         }
4335
4336         if ((power > randint0(20)) && one_in_(4))
4337         {
4338                 power -= 10;
4339
4340                 get_max_stats();
4341                 do_cmd_rerate(FALSE);
4342         }
4343
4344         while ((power > randint0(15)) && one_in_(3))
4345         {
4346                 power -= 7;
4347                 (void)gain_random_mutation(0);
4348         }
4349
4350         if (power > randint0(5))
4351         {
4352                 power -= 5;
4353                 do_poly_wounds();
4354         }
4355
4356         /* Note: earlier deductions may have left power < 0 already. */
4357         while (power > 0)
4358         {
4359                 mutate_player();
4360                 power--;
4361         }
4362 }
4363
4364
4365 /*
4366  * Decreases players hit points and sets death flag if necessary
4367  *
4368  * Invulnerability needs to be changed into a "shield"
4369  *
4370  * Hack -- this function allows the user to save (or quit)
4371  * the game when he dies, since the "You die." message is shown before
4372  * setting the player to "dead".
4373  */
4374
4375 int take_hit(int damage_type, HIT_POINT damage, cptr hit_from, int monspell)
4376 {
4377         int old_chp = p_ptr->chp;
4378
4379         char death_message[1024];
4380         char tmp[1024];
4381
4382         int warning = (p_ptr->mhp * hitpoint_warn / 10);
4383
4384         /* Paranoia */
4385         if (p_ptr->is_dead) return 0;
4386
4387         if (p_ptr->sutemi) damage *= 2;
4388         if (p_ptr->special_defense & KATA_IAI) damage += (damage + 4) / 5;
4389
4390         if (easy_band) damage = (damage+1)/2;
4391
4392         if (damage_type != DAMAGE_USELIFE)
4393         {
4394                 /* Disturb */
4395                 disturb(1, 1);
4396                 if (auto_more)
4397                 {
4398                         now_damaged = TRUE;
4399                 }
4400         }
4401
4402         if (monspell >= 0) learn_spell(monspell);
4403
4404         /* Mega-Hack -- Apply "invulnerability" */
4405         if ((damage_type != DAMAGE_USELIFE) && (damage_type != DAMAGE_LOSELIFE))
4406         {
4407                 if (IS_INVULN() && (damage < 9000))
4408                 {
4409                         if (damage_type == DAMAGE_FORCE)
4410                         {
4411                                 msg_print(_("バリアが切り裂かれた!", "The attack cuts your shield of invulnerability open!"));
4412                         }
4413                         else if (one_in_(PENETRATE_INVULNERABILITY))
4414                         {
4415                                 msg_print(_("無敵のバリアを破って攻撃された!", "The attack penetrates your shield of invulnerability!"));
4416                         }
4417                         else
4418                         {
4419                                 return 0;
4420                         }
4421                 }
4422
4423                 if (CHECK_MULTISHADOW())
4424                 {
4425                         if (damage_type == DAMAGE_FORCE)
4426                         {
4427                                 msg_print(_("幻影もろとも体が切り裂かれた!", "The attack hits Shadow together with you!"));
4428                         }
4429                         else if (damage_type == DAMAGE_ATTACK)
4430                         {
4431                                 msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, you are unharmed!"));
4432                                 return 0;
4433                         }
4434                 }
4435
4436                 if (p_ptr->wraith_form)
4437                 {
4438                         if (damage_type == DAMAGE_FORCE)
4439                         {
4440                                 msg_print(_("半物質の体が切り裂かれた!", "The attack cuts through your ethereal body!"));
4441                         }
4442                         else
4443                         {
4444                                 damage /= 2;
4445                                 if ((damage == 0) && one_in_(2)) damage = 1;
4446                         }
4447                 }
4448
4449                 if (p_ptr->special_defense & KATA_MUSOU)
4450                 {
4451                         damage /= 2;
4452                         if ((damage == 0) && one_in_(2)) damage = 1;
4453                 }
4454         } /* not if LOSELIFE USELIFE */
4455
4456         /* Hurt the player */
4457         p_ptr->chp -= damage;
4458         if(damage_type == DAMAGE_GENO && p_ptr->chp < 0)
4459         {
4460                 damage += p_ptr->chp;
4461                 p_ptr->chp = 0;
4462         }
4463
4464         /* Display the hitpoints */
4465         p_ptr->redraw |= (PR_HP);
4466
4467         p_ptr->window |= (PW_PLAYER);
4468
4469         if (damage_type != DAMAGE_GENO && p_ptr->chp == 0)
4470         {
4471                 chg_virtue(V_SACRIFICE, 1);
4472                 chg_virtue(V_CHANCE, 2);
4473         }
4474
4475         /* Dead player */
4476         if (p_ptr->chp < 0)
4477         {
4478                 bool android = (p_ptr->prace == RACE_ANDROID ? TRUE : FALSE);
4479
4480 #ifdef JP       /* 死んだ時に強制終了して死を回避できなくしてみた by Habu */
4481                 if (!cheat_save)
4482                         if(!save_player()) msg_print("セーブ失敗!");
4483 #endif
4484
4485                 sound(SOUND_DEATH);
4486
4487                 chg_virtue(V_SACRIFICE, 10);
4488
4489                 handle_stuff();
4490
4491                 /* Leaving */
4492                 p_ptr->leaving = TRUE;
4493
4494                 /* Note death */
4495                 p_ptr->is_dead = TRUE;
4496
4497                 if (p_ptr->inside_arena)
4498                 {
4499                         cptr m_name = r_name+r_info[arena_info[p_ptr->arena_number].r_idx].name;
4500                         msg_format(_("あなたは%sの前に敗れ去った。", "You are beaten by %s."), m_name);
4501                         msg_print(NULL);
4502                         if (record_arena) do_cmd_write_nikki(NIKKI_ARENA, -1 - p_ptr->arena_number, m_name);
4503                 }
4504                 else
4505                 {
4506                         QUEST_IDX q_idx = quest_number(dun_level);
4507                         bool seppuku = streq(hit_from, "Seppuku");
4508                         bool winning_seppuku = p_ptr->total_winner && seppuku;
4509
4510                         play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_GAMEOVER);
4511
4512 #ifdef WORLD_SCORE
4513                         /* Make screen dump */
4514                         screen_dump = make_screen_dump();
4515 #endif
4516
4517                         /* Note cause of death */
4518                         if (seppuku)
4519                         {
4520                                 strcpy(p_ptr->died_from, hit_from);
4521 #ifdef JP
4522                                 if (!winning_seppuku) strcpy(p_ptr->died_from, "切腹");
4523 #endif
4524                         }
4525                         else
4526                         {
4527                                 char dummy[1024];
4528 #ifdef JP
4529                                 sprintf(dummy, "%s%s%s", !p_ptr->paralyzed ? "" : p_ptr->free_act ? "彫像状態で" : "麻痺状態で", p_ptr->image ? "幻覚に歪んだ" : "", hit_from);
4530 #else
4531                                 sprintf(dummy, "%s%s", hit_from, !p_ptr->paralyzed ? "" : " while helpless");
4532 #endif
4533                                 my_strcpy(p_ptr->died_from, dummy, sizeof p_ptr->died_from);
4534                         }
4535
4536                         /* No longer a winner */
4537                         p_ptr->total_winner = FALSE;
4538
4539                         if (winning_seppuku)
4540                         {
4541                                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("勝利の後切腹した。", "did Seppuku after the winning."));
4542                         }
4543                         else
4544                         {
4545                                 char buf[20];
4546
4547                                 if (p_ptr->inside_arena)
4548                                         strcpy(buf,_("アリーナ", "in the Arena"));
4549                                 else if (!dun_level)
4550                                         strcpy(buf,_("地上", "on the surface"));
4551                                 else if (q_idx && (is_fixed_quest_idx(q_idx) &&
4552                                          !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
4553                                         strcpy(buf,_("クエスト", "in a quest"));
4554                                 else
4555                                         sprintf(buf,_("%d階", "level %d"), (int)dun_level);
4556
4557                                 sprintf(tmp, _("%sで%sに殺された。", "killed by %s %s."), buf, p_ptr->died_from);
4558                                 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, tmp);
4559                         }
4560
4561                         do_cmd_write_nikki(NIKKI_GAMESTART, 1, _("-------- ゲームオーバー --------", "--------   Game  Over   --------"));
4562                         do_cmd_write_nikki(NIKKI_BUNSHOU, 1, "\n\n\n\n");
4563
4564                         flush();
4565
4566                         if (get_check_strict(_("画面を保存しますか?", "Dump the screen? "), CHECK_NO_HISTORY))
4567                         {
4568                                 do_cmd_save_screen();
4569                         }
4570
4571                         flush();
4572
4573                         /* Initialize "last message" buffer */
4574                         if (p_ptr->last_message) string_free(p_ptr->last_message);
4575                         p_ptr->last_message = NULL;
4576
4577                         /* Hack -- Note death */
4578                         if (!last_words)
4579                         {
4580 #ifdef JP
4581                                 msg_format("あなたは%sました。", android ? "壊れ" : "死に");
4582 #else
4583                                 msg_print(android ? "You are broken." : "You die.");
4584 #endif
4585
4586                                 msg_print(NULL);
4587                         }
4588                         else
4589                         {
4590                                 if (winning_seppuku)
4591                                 {
4592                                         get_rnd_line(_("seppuku_j.txt", "seppuku.txt"), 0, death_message);
4593                                 }
4594                                 else
4595                                 {
4596                                         get_rnd_line(_("death_j.txt", "death.txt"), 0, death_message);
4597                                 }
4598
4599                                 do
4600                                 {
4601 #ifdef JP
4602                                         while (!get_string(winning_seppuku ? "辞世の句: " : "断末魔の叫び: ", death_message, 1024)) ;
4603 #else
4604                                         while (!get_string("Last word: ", death_message, 1024)) ;
4605 #endif
4606                                 }
4607                                 while (winning_seppuku && !get_check_strict(_("よろしいですか?", "Are you sure? "), CHECK_NO_HISTORY));
4608
4609                                 if (death_message[0] == '\0')
4610                                 {
4611 #ifdef JP
4612                                         strcpy(death_message, format("あなたは%sました。", android ? "壊れ" : "死に"));
4613 #else
4614                                         strcpy(death_message, android ? "You are broken." : "You die.");
4615 #endif
4616                                 }
4617                                 else p_ptr->last_message = string_make(death_message);
4618
4619 #ifdef JP
4620                                 if (winning_seppuku)
4621                                 {
4622                                         int i, len;
4623                                         int w = Term->wid;
4624                                         int h = Term->hgt;
4625                                         int msg_pos_x[9] = {  5,  7,  9, 12,  14,  17,  19,  21, 23};
4626                                         int msg_pos_y[9] = {  3,  4,  5,  4,   5,   4,   5,   6,  4};
4627                                         cptr str;
4628                                         char* str2;
4629
4630                                         Term_clear();
4631
4632                                         /* 桜散る */
4633                                         for (i = 0; i < 40; i++)
4634                                                 Term_putstr(randint0(w / 2) * 2, randint0(h), 2, TERM_VIOLET, "υ");
4635
4636                                         str = death_message;
4637                                         if (strncmp(str, "「", 2) == 0) str += 2;
4638
4639                                         str2 = my_strstr(str, "」");
4640                                         if (str2 != NULL) *str2 = '\0';
4641
4642                                         i = 0;
4643                                         while (i < 9)
4644                                         {
4645                                                 str2 = my_strstr(str, " ");
4646                                                 if (str2 == NULL) len = strlen(str);
4647                                                 else len = str2 - str;
4648
4649                                                 if (len != 0)
4650                                                 {
4651                                                         Term_putstr_v(w * 3 / 4 - 2 - msg_pos_x[i] * 2, msg_pos_y[i], len,
4652                                                         TERM_WHITE, str);
4653                                                         if (str2 == NULL) break;
4654                                                         i++;
4655                                                 }
4656                                                 str = str2 + 1;
4657                                                 if (*str == 0) break;
4658                                         }
4659
4660                                         /* Hide cursor */
4661                                         Term_putstr(w-1, h-1, 1, TERM_WHITE, " ");
4662
4663                                         flush();
4664 #ifdef WORLD_SCORE
4665                                         /* Make screen dump */
4666                                         screen_dump = make_screen_dump();
4667 #endif
4668
4669                                         /* Wait a key press */
4670                                         (void)inkey();
4671                                 }
4672                                 else
4673 #endif
4674                                         msg_print(death_message);
4675                         }
4676                 }
4677
4678                 /* Dead */
4679                 return damage;
4680         }
4681
4682         handle_stuff();
4683
4684         /* Hitpoint warning */
4685         if (p_ptr->chp < warning)
4686         {
4687                 /* Hack -- bell on first notice */
4688                 if (old_chp > warning) bell();
4689
4690                 sound(SOUND_WARN);
4691
4692                 if (record_danger && (old_chp > warning))
4693                 {
4694                         if (p_ptr->image && damage_type == DAMAGE_ATTACK)
4695                                 hit_from = _("何か", "something");
4696
4697                         sprintf(tmp,_("%sによってピンチに陥った。", "A critical situation because of %s."),hit_from);
4698                         do_cmd_write_nikki(NIKKI_BUNSHOU, 0, tmp);
4699                 }
4700
4701                 if (auto_more)
4702                 {
4703                         /* stop auto_more even if DAMAGE_USELIFE */
4704                         now_damaged = TRUE;
4705                 }
4706
4707                 msg_print(_("*** 警告:低ヒット・ポイント! ***", "*** LOW HITPOINT WARNING! ***"));
4708                 msg_print(NULL);
4709                 flush();
4710         }
4711         if (p_ptr->wild_mode && !p_ptr->leaving && (p_ptr->chp < MAX(warning, p_ptr->mhp/5)))
4712         {
4713                 change_wild_mode();
4714         }
4715         return damage;
4716 }
4717
4718
4719 /*
4720  * Gain experience
4721  */
4722 void gain_exp_64(s32b amount, u32b amount_frac)
4723 {
4724         if (p_ptr->is_dead) return;
4725
4726         if (p_ptr->prace == RACE_ANDROID) return;
4727
4728         /* Gain some experience */
4729         s64b_add(&(p_ptr->exp), &(p_ptr->exp_frac), amount, amount_frac);
4730
4731         /* Slowly recover from experience drainage */
4732         if (p_ptr->exp < p_ptr->max_exp)
4733         {
4734                 /* Gain max experience (20%) (was 10%) */
4735                 p_ptr->max_exp += amount / 5;
4736         }
4737
4738         /* Check Experience */
4739         check_experience();
4740 }
4741
4742
4743 /*
4744  * Gain experience
4745  */
4746 void gain_exp(s32b amount)
4747 {
4748         gain_exp_64(amount, 0L);
4749 }
4750
4751
4752 void calc_android_exp(void)
4753 {
4754         int i;
4755         u32b total_exp = 0;
4756         if (p_ptr->is_dead) return;
4757
4758         if (p_ptr->prace != RACE_ANDROID) return;
4759
4760         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4761         {
4762                 object_type *o_ptr = &inventory[i];
4763                 object_type forge;
4764                 object_type *q_ptr = &forge;
4765                 u32b value, exp;
4766                 DEPTH level = MAX(k_info[o_ptr->k_idx].level - 8, 1);
4767
4768                 if ((i == INVEN_RIGHT) || (i == INVEN_LEFT) || (i == INVEN_NECK) || (i == INVEN_LITE)) continue;
4769                 if (!o_ptr->k_idx) continue;
4770
4771                 /* Wipe the object */
4772                 object_wipe(q_ptr);
4773
4774                 object_copy(q_ptr, o_ptr);
4775                 q_ptr->discount = 0;
4776                 q_ptr->curse_flags = 0L;
4777
4778                 if (object_is_fixed_artifact(o_ptr))
4779                 {
4780                         level = (level + MAX(a_info[o_ptr->name1].level - 8, 5)) / 2;
4781                         level += MIN(20, a_info[o_ptr->name1].rarity/(a_info[o_ptr->name1].gen_flags & TRG_INSTA_ART ? 10 : 3));
4782                 }
4783                 else if (object_is_ego(o_ptr))
4784                 {
4785                         level += MAX(3, (e_info[o_ptr->name2].rating - 5)/2);
4786                 }
4787                 else if (o_ptr->art_name)
4788                 {
4789                         s32b total_flags = flag_cost(o_ptr, o_ptr->pval);
4790                         int fake_level;
4791
4792                         if (!object_is_weapon_ammo(o_ptr))
4793                         {
4794                                 /* For armors */
4795                                 if (total_flags < 15000) fake_level = 10;
4796                                 else if (total_flags < 35000) fake_level = 25;
4797                                 else fake_level = 40;
4798                         }
4799                         else
4800                         {
4801                                 /* For weapons */
4802                                 if (total_flags < 20000) fake_level = 10;
4803                                 else if (total_flags < 45000) fake_level = 25;
4804                                 else fake_level = 40;
4805                         }
4806
4807                         level = MAX(level, (level + MAX(fake_level - 8, 5)) / 2 + 3);
4808                 }
4809
4810                 value = object_value_real(q_ptr);
4811
4812                 if (value <= 0) continue;
4813                 if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_ABUNAI_MIZUGI) && (p_ptr->pseikaku != SEIKAKU_SEXY)) value /= 32;
4814                 if (value > 5000000L) value = 5000000L;
4815                 if ((o_ptr->tval == TV_DRAG_ARMOR) || (o_ptr->tval == TV_CARD)) level /= 2;
4816
4817                 if (object_is_artifact(o_ptr) || object_is_ego(o_ptr) ||
4818                     (o_ptr->tval == TV_DRAG_ARMOR) ||
4819                     ((o_ptr->tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM)) ||
4820                     ((o_ptr->tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD)) ||
4821                     ((o_ptr->tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES)) ||
4822                     ((o_ptr->tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE)) ||
4823                     ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_DIAMOND_EDGE)))
4824                 {
4825                         if (level > 65) level = 35 + (level - 65) / 5;
4826                         else if (level > 35) level = 25 + (level - 35) / 3;
4827                         else if (level > 15) level = 15 + (level - 15) / 2;
4828                         exp = MIN(100000L, value) / 2 * level * level;
4829                         if (value > 100000L)
4830                                 exp += (value - 100000L) / 8 * level * level;
4831                 }
4832                 else
4833                 {
4834                         exp = MIN(100000L, value) * level;
4835                         if (value > 100000L)
4836                                 exp += (value - 100000L) / 4  * level;
4837                 }
4838                 if ((((i == INVEN_RARM) || (i == INVEN_LARM)) && (buki_motteruka(i))) || (i == INVEN_BOW)) total_exp += exp / 48;
4839                 else total_exp += exp / 16;
4840                 if (i == INVEN_BODY) total_exp += exp / 32;
4841         }
4842         p_ptr->exp = p_ptr->max_exp = total_exp;
4843
4844         /* Check Experience */
4845         check_experience();
4846 }
4847
4848
4849 /*
4850  * Lose experience
4851  */
4852 void lose_exp(s32b amount)
4853 {
4854         if (p_ptr->prace == RACE_ANDROID) return;
4855
4856         /* Never drop below zero experience */
4857         if (amount > p_ptr->exp) amount = p_ptr->exp;
4858
4859         /* Lose some experience */
4860         p_ptr->exp -= amount;
4861
4862         /* Check Experience */
4863         check_experience();
4864 }
4865
4866
4867 /*
4868  * Drain experience
4869  * If resisted to draining, return FALSE
4870  */
4871 bool drain_exp(s32b drain, s32b slip, int hold_exp_prob)
4872 {
4873         /* Androids and their mimics are never drained */
4874         if (p_ptr->prace == RACE_ANDROID) return FALSE;
4875
4876         if (p_ptr->hold_exp && (randint0(100) < hold_exp_prob))
4877         {
4878                 /* Hold experience */
4879                 msg_print(_("しかし自己の経験値を守りきった!", "You keep hold of your experience!"));
4880                 return FALSE;
4881         }
4882
4883         /* Hold experience failed */
4884         if (p_ptr->hold_exp)
4885         {
4886                 msg_print(_("経験値を少し吸い取られた気がする!", "You feel your experience slipping away!"));
4887                 lose_exp(slip);
4888         }
4889         else
4890         {
4891                 msg_print(_("経験値が体から吸い取られた気がする!", "You feel your experience draining away!"));
4892                 lose_exp(drain);
4893         }
4894
4895         return TRUE;
4896 }
4897
4898
4899 bool set_ultimate_res(TIME_EFFECT v, bool do_dec)
4900 {
4901         bool notice = FALSE;
4902
4903         /* Hack -- Force good values */
4904         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
4905
4906         if (p_ptr->is_dead) return FALSE;
4907
4908         /* Open */
4909         if (v)
4910         {
4911                 if (p_ptr->ult_res && !do_dec)
4912                 {
4913                         if (p_ptr->ult_res > v) return FALSE;
4914                 }
4915                 else if (!p_ptr->ult_res)
4916                 {
4917                         msg_print(_("あらゆることに対して耐性がついた気がする!", "You feel resistant!"));
4918                         notice = TRUE;
4919                 }
4920         }
4921
4922         /* Shut */
4923         else
4924         {
4925                 if (p_ptr->ult_res)
4926                 {
4927                         msg_print(_("あらゆることに対する耐性が薄れた気がする。", "You feel less resistant"));
4928                         notice = TRUE;
4929                 }
4930         }
4931
4932         /* Use the value */
4933         p_ptr->ult_res = v;
4934
4935         /* Redraw status bar */
4936         p_ptr->redraw |= (PR_STATUS);
4937
4938         /* Nothing to notice */
4939         if (!notice) return (FALSE);
4940
4941         /* Disturb */
4942         if (disturb_state) disturb(0, 0);
4943
4944         /* Recalculate bonuses */
4945         p_ptr->update |= (PU_BONUS);
4946
4947         /* Handle stuff */
4948         handle_stuff();
4949
4950         /* Result */
4951         return (TRUE);
4952 }
4953
4954 bool set_tim_res_nether(TIME_EFFECT v, bool do_dec)
4955 {
4956         bool notice = FALSE;
4957
4958         /* Hack -- Force good values */
4959         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
4960
4961         if (p_ptr->is_dead) return FALSE;
4962
4963         /* Open */
4964         if (v)
4965         {
4966                 if (p_ptr->tim_res_nether && !do_dec)
4967                 {
4968                         if (p_ptr->tim_res_nether > v) return FALSE;
4969                 }
4970                 else if (!p_ptr->tim_res_nether)
4971                 {
4972                         msg_print(_("地獄の力に対して耐性がついた気がする!", "You feel nether resistant!"));
4973                         notice = TRUE;
4974                 }
4975         }
4976
4977         /* Shut */
4978         else
4979         {
4980                 if (p_ptr->tim_res_nether)
4981                 {
4982                         msg_print(_("地獄の力に対する耐性が薄れた気がする。", "You feel less nether resistant"));
4983                         notice = TRUE;
4984                 }
4985         }
4986
4987         /* Use the value */
4988         p_ptr->tim_res_nether = v;
4989
4990         /* Redraw status bar */
4991         p_ptr->redraw |= (PR_STATUS);
4992
4993         /* Nothing to notice */
4994         if (!notice) return (FALSE);
4995
4996         /* Disturb */
4997         if (disturb_state) disturb(0, 0);
4998
4999         /* Recalculate bonuses */
5000         p_ptr->update |= (PU_BONUS);
5001
5002         /* Handle stuff */
5003         handle_stuff();
5004
5005         /* Result */
5006         return (TRUE);
5007 }
5008
5009 bool set_tim_res_time(TIME_EFFECT v, bool do_dec)
5010 {
5011         bool notice = FALSE;
5012
5013         /* Hack -- Force good values */
5014         v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
5015
5016         if (p_ptr->is_dead) return FALSE;
5017
5018         /* Open */
5019         if (v)
5020         {
5021                 if (p_ptr->tim_res_time && !do_dec)
5022                 {
5023                         if (p_ptr->tim_res_time > v) return FALSE;
5024                 }
5025                 else if (!p_ptr->tim_res_time)
5026                 {
5027                         msg_print(_("時間逆転の力に対して耐性がついた気がする!", "You feel time resistant!"));
5028                         notice = TRUE;
5029                 }
5030         }
5031
5032         /* Shut */
5033         else
5034         {
5035                 if (p_ptr->tim_res_time)
5036                 {
5037                         msg_print(_("時間逆転の力に対する耐性が薄れた気がする。", "You feel less time resistant"));
5038                         notice = TRUE;
5039                 }
5040         }
5041
5042         /* Use the value */
5043         p_ptr->tim_res_time = v;
5044
5045         /* Redraw status bar */
5046         p_ptr->redraw |= (PR_STATUS);
5047
5048         /* Nothing to notice */
5049         if (!notice) return (FALSE);
5050
5051         /* Disturb */
5052         if (disturb_state) disturb(0, 0);
5053
5054         /* Recalculate bonuses */
5055         p_ptr->update |= (PU_BONUS);
5056
5057         /* Handle stuff */
5058         handle_stuff();
5059
5060         /* Result */
5061         return (TRUE);
5062 }
5063
5064
5065 /*
5066  * Choose a warrior-mage elemental attack. -LM-
5067  */
5068 bool choose_ele_attack(void)
5069 {
5070         int num;
5071
5072         char choice;
5073
5074         if (!buki_motteruka(INVEN_RARM) && !buki_motteruka(INVEN_LARM))
5075         {
5076                 msg_format(_("武器を持たないと魔法剣は使えない。", "You cannot use temporary branding with no weapon."));
5077                 return FALSE;
5078         }
5079
5080         /* Save screen */
5081         screen_save();
5082
5083         num = (p_ptr->lev - 20) / 5;
5084         c_prt(TERM_RED,    _("        a) 焼棄", "        a) Fire Brand"), 2, 14);
5085
5086         if (num >= 2) 
5087                 c_prt(TERM_L_WHITE,_("        b) 凍結", "        b) Cold Brand"), 3, 14);
5088         else 
5089                 prt("", 3, 14);
5090         
5091         if (num >= 3) 
5092                 c_prt(TERM_GREEN,  _("        c) 毒殺", "        c) Poison Brand"), 4, 14);
5093         else 
5094                 prt("", 4, 14);
5095
5096         if (num >= 4) 
5097                 c_prt(TERM_L_DARK, _("        d) 溶解", "        d) Acid Brand"), 5, 14);
5098         else 
5099                 prt("", 5, 14);
5100
5101         if (num >= 5) 
5102                 c_prt(TERM_BLUE,   _("        e) 電撃", "        e) Elec Brand"), 6, 14);
5103         else 
5104                 prt("", 6, 14);
5105
5106         prt("", 7, 14);
5107         prt("", 8, 14);
5108         prt("", 9, 14);
5109
5110         prt("", 1, 0);
5111         prt(_("        どの元素攻撃をしますか?", "        Choose a temporary elemental brand "), 1, 14);
5112
5113         choice = inkey();
5114
5115         if ((choice == 'a') || (choice == 'A')) 
5116                 set_ele_attack(ATTACK_FIRE, p_ptr->lev/2 + randint1(p_ptr->lev/2));
5117         else if (((choice == 'b') || (choice == 'B')) && (num >= 2))
5118                 set_ele_attack(ATTACK_COLD, p_ptr->lev/2 + randint1(p_ptr->lev/2));
5119         else if (((choice == 'c') || (choice == 'C')) && (num >= 3))
5120                 set_ele_attack(ATTACK_POIS, p_ptr->lev/2 + randint1(p_ptr->lev/2));
5121         else if (((choice == 'd') || (choice == 'D')) && (num >= 4))
5122                 set_ele_attack(ATTACK_ACID, p_ptr->lev/2 + randint1(p_ptr->lev/2));
5123         else if (((choice == 'e') || (choice == 'E')) && (num >= 5))
5124                 set_ele_attack(ATTACK_ELEC, p_ptr->lev/2 + randint1(p_ptr->lev/2));
5125         else
5126         {
5127                 msg_print(_("魔法剣を使うのをやめた。", "You cancel the temporary branding."));
5128                 screen_load();
5129                 return FALSE;
5130         }
5131         /* Load screen */
5132         screen_load();
5133         return TRUE;
5134 }
5135
5136
5137 /*
5138  * Choose a elemental immune. -LM-
5139  */
5140 bool choose_ele_immune(TIME_EFFECT immune_turn)
5141 {
5142         char choice;
5143
5144         /* Save screen */
5145         screen_save();
5146
5147         c_prt(TERM_RED,    _("        a) 火炎", "        a) Immune Fire"), 2, 14);
5148         c_prt(TERM_L_WHITE,_("        b) 冷気", "        b) Immune Cold"), 3, 14);
5149         c_prt(TERM_L_DARK, _("        c) 酸", "        c) Immune Acid"), 4, 14);
5150         c_prt(TERM_BLUE,   _("        d) 電撃", "        d) Immune Elec"), 5, 14);
5151
5152         prt("", 6, 14);
5153         prt("", 7, 14);
5154         prt("", 8, 14);
5155         prt("", 9, 14);
5156
5157         prt("", 1, 0);
5158         prt(_("        どの元素の免疫をつけますか?", "        Choose a temporary elemental immune "), 1, 14);
5159
5160         choice = inkey();
5161
5162         if ((choice == 'a') || (choice == 'A')) 
5163                 set_ele_immune(DEFENSE_FIRE, immune_turn);
5164         else if ((choice == 'b') || (choice == 'B'))
5165                 set_ele_immune(DEFENSE_COLD, immune_turn);
5166         else if ((choice == 'c') || (choice == 'C'))
5167                 set_ele_immune(DEFENSE_ACID, immune_turn);
5168         else if ((choice == 'd') || (choice == 'D'))
5169                 set_ele_immune(DEFENSE_ELEC, immune_turn);
5170         else
5171         {
5172                 msg_print(_("免疫を付けるのをやめた。", "You cancel the temporary immune."));
5173                 screen_load();
5174                 return FALSE;
5175         }
5176         /* Load screen */
5177         screen_load();
5178         return TRUE;
5179 }
5180