OSDN Git Service

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