OSDN Git Service

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