OSDN Git Service

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