OSDN Git Service

[Refactor] #39073 Delete friend_align and check_pets_num_and_align().
[hengbandforosx/hengbandosx.git] / src / player-status.c
index 2f55414..59160a8 100644 (file)
@@ -1,7 +1,17 @@
 #include "angband.h"
-#include "artifact.h"
 #include "player-status.h"
+
+#include "artifact.h"
 #include "avatar.h"
+#include "spells-status.h"
+#include "object-hook.h"
+#include "monsterrace-hook.h"
+#include "mutation.h"
+#include "patron.h"
+
+/* Hack, monk armour */
+static bool monk_armour_aux;
+static bool monk_notify_aux;
 
 /*
  * Return alignment title
@@ -119,7 +129,7 @@ void calc_bonuses(void)
        bool old_mighty_throw = p_ptr->mighty_throw;
 
        /* Current feature under player. */
-       feature_type *f_ptr = &f_info[cave[p_ptr->y][p_ptr->x].feat];
+       feature_type *f_ptr = &f_info[current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].feat];
 
        /* Save the old armor class */
        ARMOUR_CLASS old_dis_ac = p_ptr->dis_ac;
@@ -155,11 +165,11 @@ void calc_bonuses(void)
        /* Start with "normal" speed */
        new_speed = 110;
 
-       /* Start with a single blow per turn */
+       /* Start with a single blow per current_world_ptr->game_turn */
        p_ptr->num_blow[0] = 1;
        p_ptr->num_blow[1] = 1;
 
-       /* Start with a single shot per turn */
+       /* Start with a single shot per current_world_ptr->game_turn */
        p_ptr->num_fire = 100;
 
        /* Reset the "xtra" tval */
@@ -244,7 +254,7 @@ void calc_bonuses(void)
        p_ptr->hidarite = FALSE;
        p_ptr->no_flowed = FALSE;
 
-       p_ptr->align = friend_align;
+       p_ptr->align = 0;
 
        if (p_ptr->mimic_form) tmp_rp_ptr = &mimic_info[p_ptr->mimic_form];
        else tmp_rp_ptr = &race_info[p_ptr->prace];
@@ -1793,7 +1803,7 @@ void calc_bonuses(void)
        }
        else
        {
-               monster_type *riding_m_ptr = &m_list[p_ptr->riding];
+               monster_type *riding_m_ptr = &current_floor_ptr->m_list[p_ptr->riding];
                monster_race *riding_r_ptr = &r_info[riding_m_ptr->r_idx];
                SPEED speed = riding_m_ptr->mspeed;
 
@@ -2162,7 +2172,7 @@ void calc_bonuses(void)
                                }
                                else
                                {
-                                       penalty = r_info[m_list[p_ptr->riding].r_idx].level - p_ptr->skill_exp[GINOU_RIDING] / 80;
+                                       penalty = r_info[current_floor_ptr->m_list[p_ptr->riding].r_idx].level - p_ptr->skill_exp[GINOU_RIDING] / 80;
                                        penalty += 30;
                                        if (penalty < 30) penalty = 30;
                                }
@@ -2201,7 +2211,7 @@ void calc_bonuses(void)
                }
                else
                {
-                       penalty = r_info[m_list[p_ptr->riding].r_idx].level - p_ptr->skill_exp[GINOU_RIDING] / 80;
+                       penalty = r_info[current_floor_ptr->m_list[p_ptr->riding].r_idx].level - p_ptr->skill_exp[GINOU_RIDING] / 80;
                        penalty += 30;
                        if (penalty < 30) penalty = 30;
                }
@@ -2637,11 +2647,9 @@ void calc_bonuses(void)
                if ((inventory[i].tval == TV_CRAFT_BOOK) && (inventory[i].sval == 2)) have_kabe = TRUE;
        }
 
-       for (this_o_idx = cave[p_ptr->y][p_ptr->x].o_idx; this_o_idx; this_o_idx = next_o_idx)
+       for (this_o_idx = current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].o_idx; this_o_idx; this_o_idx = next_o_idx)
        {
-               o_ptr = &o_list[this_o_idx];
-
-               /* Acquire next object */
+               o_ptr = &current_floor_ptr->o_list[this_o_idx];
                next_o_idx = o_ptr->next_o_idx;
 
 #if 0
@@ -2810,8 +2818,8 @@ static void calc_torch(void)
        }
 
        /* max radius is 14 (was 5) without rewriting other code -- */
-       /* see cave.c:update_lite() and defines.h:LITE_MAX */
-       if (d_info[dungeon_type].flags1 & DF1_DARKNESS && p_ptr->cur_lite > 1)
+       /* see current_floor_ptr->grid_array.c:update_lite() and defines.h:LITE_MAX */
+       if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS && p_ptr->cur_lite > 1)
                p_ptr->cur_lite = 1;
 
        /*
@@ -3672,8 +3680,6 @@ void update_creature(player_type *creature_ptr)
                creature_ptr->update &= ~(PU_AUTODESTROY);
                autopick_delayed_alter();
        }
-
-       /* Combine the pack */
        if (creature_ptr->update & (PU_COMBINE))
        {
                creature_ptr->update &= ~(PU_COMBINE);
@@ -3802,11 +3808,515 @@ bool player_has_no_spellbooks(void)
                if (o_ptr->k_idx && check_book_realm(o_ptr->tval, o_ptr->sval)) return FALSE;
        }
 
-       for (i = cave[p_ptr->y][p_ptr->x].o_idx; i; i = o_ptr->next_o_idx)
+       for (i = current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].o_idx; i; i = o_ptr->next_o_idx)
        {
-               o_ptr = &o_list[i];
+               o_ptr = &current_floor_ptr->o_list[i];
                if (o_ptr->k_idx && (o_ptr->marked & OM_FOUND) && check_book_realm(o_ptr->tval, o_ptr->sval)) return FALSE;
        }
 
        return TRUE;
 }
+
+void take_turn(player_type *creature_ptr, PERCENTAGE need_cost)
+{
+       creature_ptr->energy_use = (ENERGY)need_cost;
+}
+
+void free_turn(player_type *creature_ptr)
+{
+       creature_ptr->energy_use = 0;
+}
+
+/*!
+ * @brief プレイヤーを指定座標に配置する / Place the player in the dungeon XXX XXX
+ * @param x 配置先X座標
+ * @param y 配置先Y座標
+ * @return 配置に成功したらTRUE
+ */
+bool player_place(POSITION y, POSITION x)
+{
+       /* Paranoia XXX XXX */
+       if (current_floor_ptr->grid_array[y][x].m_idx != 0) return FALSE;
+
+       /* Save player location */
+       p_ptr->y = y;
+       p_ptr->x = x;
+
+       /* Success */
+       return TRUE;
+}
+
+/*!
+ * @brief 種族アンバライトが出血時パターンの上に乗った際のペナルティ処理
+ * @return なし
+ */
+void wreck_the_pattern(void)
+{
+       int to_ruin = 0;
+       POSITION r_y, r_x;
+       int pattern_type = f_info[current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].feat].subtype;
+
+       if (pattern_type == PATTERN_TILE_WRECKED)
+       {
+               /* Ruined already */
+               return;
+       }
+
+       msg_print(_("パターンを血で汚してしまった!", "You bleed on the Pattern!"));
+       msg_print(_("何か恐ろしい事が起こった!", "Something terrible happens!"));
+
+       if (!IS_INVULN()) take_hit(DAMAGE_NOESCAPE, damroll(10, 8), _("パターン損壊", "corrupting the Pattern"), -1);
+       to_ruin = randint1(45) + 35;
+
+       while (to_ruin--)
+       {
+               scatter(&r_y, &r_x, p_ptr->y, p_ptr->x, 4, 0);
+
+               if (pattern_tile(r_y, r_x) &&
+                       (f_info[current_floor_ptr->grid_array[r_y][r_x].feat].subtype != PATTERN_TILE_WRECKED))
+               {
+                       cave_set_feat(r_y, r_x, feat_pattern_corrupted);
+               }
+       }
+
+       cave_set_feat(p_ptr->y, p_ptr->x, feat_pattern_corrupted);
+}
+
+
+/*!
+ * @brief ELDRITCH_HORRORによるプレイヤーの精神破壊処理
+ * @param m_ptr ELDRITCH_HORRORを引き起こしたモンスターの参照ポインタ
+ * @param necro 暗黒領域魔法の詠唱失敗によるものならばTRUEを返す
+ * @return なし
+ */
+void sanity_blast(monster_type *m_ptr, bool necro)
+{
+       int power = 100;
+
+       if (p_ptr->inside_battle || !character_dungeon) return;
+
+       if (!necro && m_ptr)
+       {
+               GAME_TEXT m_name[MAX_NLEN];
+               monster_race *r_ptr = &r_info[m_ptr->ap_r_idx];
+
+               power = r_ptr->level / 2;
+
+               monster_desc(m_name, m_ptr, 0);
+
+               if (!(r_ptr->flags1 & RF1_UNIQUE))
+               {
+                       if (r_ptr->flags1 & RF1_FRIENDS)
+                               power /= 2;
+               }
+               else power *= 2;
+
+               if (!is_loading_now)
+                       return; /* No effect yet, just loaded... */
+
+               if (!m_ptr->ml)
+                       return; /* Cannot see it for some reason */
+
+               if (!(r_ptr->flags2 & RF2_ELDRITCH_HORROR))
+                       return;
+
+               if (is_pet(m_ptr))
+                       return; /* Pet eldritch horrors are safe most of the time */
+
+               if (randint1(100) > power) return;
+
+               if (saving_throw(p_ptr->skill_sav - power))
+               {
+                       return; /* Save, no adverse effects */
+               }
+
+               if (p_ptr->image)
+               {
+                       /* Something silly happens... */
+                       msg_format(_("%s%sの顔を見てしまった!", "You behold the %s visage of %s!"),
+                               funny_desc[randint0(MAX_SAN_FUNNY)], m_name);
+
+                       if (one_in_(3))
+                       {
+                               msg_print(funny_comments[randint0(MAX_SAN_COMMENT)]);
+                               p_ptr->image = p_ptr->image + randint1(r_ptr->level);
+                       }
+
+                       return; /* Never mind; we can't see it clearly enough */
+               }
+
+               /* Something frightening happens... */
+               msg_format(_("%s%sの顔を見てしまった!", "You behold the %s visage of %s!"),
+                       horror_desc[randint0(MAX_SAN_HORROR)], m_name);
+
+               r_ptr->r_flags2 |= RF2_ELDRITCH_HORROR;
+
+               /* Demon characters are unaffected */
+               if (prace_is_(RACE_IMP) || prace_is_(RACE_DEMON) || (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_DEMON)) return;
+               if (p_ptr->wizard) return;
+
+               /* Undead characters are 50% likely to be unaffected */
+               if (prace_is_(RACE_SKELETON) || prace_is_(RACE_ZOMBIE)
+                       || prace_is_(RACE_VAMPIRE) || prace_is_(RACE_SPECTRE) ||
+                       (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_UNDEAD))
+               {
+                       if (saving_throw(25 + p_ptr->lev)) return;
+               }
+       }
+       else if (!necro)
+       {
+               monster_race *r_ptr;
+               GAME_TEXT m_name[MAX_NLEN];
+               concptr desc;
+
+               get_mon_num_prep(get_nightmare, NULL);
+
+               r_ptr = &r_info[get_mon_num(MAX_DEPTH)];
+               power = r_ptr->level + 10;
+               desc = r_name + r_ptr->name;
+
+               get_mon_num_prep(NULL, NULL);
+
+#ifndef JP
+               if (!(r_ptr->flags1 & RF1_UNIQUE))
+                       sprintf(m_name, "%s %s", (is_a_vowel(desc[0]) ? "an" : "a"), desc);
+               else
+#endif
+                       sprintf(m_name, "%s", desc);
+
+               if (!(r_ptr->flags1 & RF1_UNIQUE))
+               {
+                       if (r_ptr->flags1 & RF1_FRIENDS) power /= 2;
+               }
+               else power *= 2;
+
+               if (saving_throw(p_ptr->skill_sav * 100 / power))
+               {
+                       msg_format(_("夢の中で%sに追いかけられた。", "%^s chases you through your dreams."), m_name);
+                       /* Safe */
+                       return;
+               }
+
+               if (p_ptr->image)
+               {
+                       /* Something silly happens... */
+                       msg_format(_("%s%sの顔を見てしまった!", "You behold the %s visage of %s!"),
+                               funny_desc[randint0(MAX_SAN_FUNNY)], m_name);
+
+                       if (one_in_(3))
+                       {
+                               msg_print(funny_comments[randint0(MAX_SAN_COMMENT)]);
+                               p_ptr->image = p_ptr->image + randint1(r_ptr->level);
+                       }
+
+                       /* Never mind; we can't see it clearly enough */
+                       return;
+               }
+
+               /* Something frightening happens... */
+               msg_format(_("%s%sの顔を見てしまった!", "You behold the %s visage of %s!"),
+                       horror_desc[randint0(MAX_SAN_HORROR)], desc);
+
+               r_ptr->r_flags2 |= RF2_ELDRITCH_HORROR;
+
+               if (!p_ptr->mimic_form)
+               {
+                       switch (p_ptr->prace)
+                       {
+                               /* Demons may make a saving throw */
+                       case RACE_IMP:
+                       case RACE_DEMON:
+                               if (saving_throw(20 + p_ptr->lev)) return;
+                               break;
+                               /* Undead may make a saving throw */
+                       case RACE_SKELETON:
+                       case RACE_ZOMBIE:
+                       case RACE_SPECTRE:
+                       case RACE_VAMPIRE:
+                               if (saving_throw(10 + p_ptr->lev)) return;
+                               break;
+                       }
+               }
+               else
+               {
+                       /* Demons may make a saving throw */
+                       if (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_DEMON)
+                       {
+                               if (saving_throw(20 + p_ptr->lev)) return;
+                       }
+                       /* Undead may make a saving throw */
+                       else if (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_UNDEAD)
+                       {
+                               if (saving_throw(10 + p_ptr->lev)) return;
+                       }
+               }
+       }
+       else
+       {
+               msg_print(_("ネクロノミコンを読んで正気を失った!", "Your sanity is shaken by reading the Necronomicon!"));
+       }
+
+       if (saving_throw(p_ptr->skill_sav - power))
+       {
+               return;
+       }
+
+       do {
+               (void)do_dec_stat(A_INT);
+       } while (randint0(100) > p_ptr->skill_sav && one_in_(2));
+
+       do {
+               (void)do_dec_stat(A_WIS);
+       } while (randint0(100) > p_ptr->skill_sav && one_in_(2));
+
+       switch (randint1(21))
+       {
+       case 1:
+               if (!(p_ptr->muta3 & MUT3_MORONIC) && one_in_(5))
+               {
+                       if ((p_ptr->stat_use[A_INT] < 4) && (p_ptr->stat_use[A_WIS] < 4))
+                       {
+                               msg_print(_("あなたは完璧な馬鹿になったような気がした。しかしそれは元々だった。", "You current_world_ptr->game_turn into an utter moron!"));
+                       }
+                       else
+                       {
+                               msg_print(_("あなたは完璧な馬鹿になった!", "You current_world_ptr->game_turn into an utter moron!"));
+                       }
+
+                       if (p_ptr->muta3 & MUT3_HYPER_INT)
+                       {
+                               msg_print(_("あなたの脳は生体コンピュータではなくなった。", "Your brain is no longer a living computer."));
+                               p_ptr->muta3 &= ~(MUT3_HYPER_INT);
+                       }
+                       p_ptr->muta3 |= MUT3_MORONIC;
+               }
+               break;
+       case 2:
+       case 3:
+       case 4:
+               if (!(p_ptr->muta2 & MUT2_COWARDICE) && !p_ptr->resist_fear)
+               {
+                       msg_print(_("あなたはパラノイアになった!", "You become paranoid!"));
+
+                       /* Duh, the following should never happen, but anyway... */
+                       if (p_ptr->muta3 & MUT3_FEARLESS)
+                       {
+                               msg_print(_("あなたはもう恐れ知らずではなくなった。", "You are no longer fearless."));
+                               p_ptr->muta3 &= ~(MUT3_FEARLESS);
+                       }
+
+                       p_ptr->muta2 |= MUT2_COWARDICE;
+               }
+               break;
+       case 5:
+       case 6:
+       case 7:
+               if (!(p_ptr->muta2 & MUT2_HALLU) && !p_ptr->resist_chaos)
+               {
+                       msg_print(_("幻覚をひき起こす精神錯乱に陥った!", "You are afflicted by a hallucinatory insanity!"));
+                       p_ptr->muta2 |= MUT2_HALLU;
+               }
+               break;
+       case 8:
+       case 9:
+       case 10:
+               if (!(p_ptr->muta2 & MUT2_BERS_RAGE))
+               {
+                       msg_print(_("激烈な感情の発作におそわれるようになった!", "You become subject to fits of berserk rage!"));
+                       p_ptr->muta2 |= MUT2_BERS_RAGE;
+               }
+               break;
+       case 11:
+       case 12:
+       case 13:
+       case 14:
+       case 15:
+       case 16:
+               /* Brain smash */
+               if (!p_ptr->resist_conf)
+               {
+                       (void)set_confused(p_ptr->confused + randint0(4) + 4);
+               }
+               if (!p_ptr->free_act)
+               {
+                       (void)set_paralyzed(p_ptr->paralyzed + randint0(4) + 4);
+               }
+               if (!p_ptr->resist_chaos)
+               {
+                       (void)set_image(p_ptr->image + randint0(250) + 150);
+               }
+               break;
+       case 17:
+       case 18:
+       case 19:
+       case 20:
+       case 21:
+               /* Amnesia */
+               if (lose_all_info())
+                       msg_print(_("あまりの恐怖に全てのことを忘れてしまった!", "You forget everything in your utmost terror!"));
+               break;
+       }
+
+       p_ptr->update |= PU_BONUS;
+       handle_stuff();
+}
+
+
+/*!
+ * @brief プレイヤーの経験値について整合性のためのチェックと調整を行う /
+ * Advance experience levels and print experience
+ * @return なし
+ */
+void check_experience(void)
+{
+       bool level_reward = FALSE;
+       bool level_mutation = FALSE;
+       bool level_inc_stat = FALSE;
+       bool android = (p_ptr->prace == RACE_ANDROID ? TRUE : FALSE);
+       PLAYER_LEVEL old_lev = p_ptr->lev;
+
+       /* Hack -- lower limit */
+       if (p_ptr->exp < 0) p_ptr->exp = 0;
+       if (p_ptr->max_exp < 0) p_ptr->max_exp = 0;
+       if (p_ptr->max_max_exp < 0) p_ptr->max_max_exp = 0;
+
+       /* Hack -- upper limit */
+       if (p_ptr->exp > PY_MAX_EXP) p_ptr->exp = PY_MAX_EXP;
+       if (p_ptr->max_exp > PY_MAX_EXP) p_ptr->max_exp = PY_MAX_EXP;
+       if (p_ptr->max_max_exp > PY_MAX_EXP) p_ptr->max_max_exp = PY_MAX_EXP;
+
+       /* Hack -- maintain "max" experience */
+       if (p_ptr->exp > p_ptr->max_exp) p_ptr->max_exp = p_ptr->exp;
+
+       /* Hack -- maintain "max max" experience */
+       if (p_ptr->max_exp > p_ptr->max_max_exp) p_ptr->max_max_exp = p_ptr->max_exp;
+
+       /* Redraw experience */
+       p_ptr->redraw |= (PR_EXP);
+       handle_stuff();
+
+
+       /* Lose levels while possible */
+       while ((p_ptr->lev > 1) &&
+               (p_ptr->exp < ((android ? player_exp_a : player_exp)[p_ptr->lev - 2] * p_ptr->expfact / 100L)))
+       {
+               /* Lose a level */
+               p_ptr->lev--;
+               p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
+               p_ptr->redraw |= (PR_LEV | PR_TITLE);
+               p_ptr->window |= (PW_PLAYER);
+               handle_stuff();
+       }
+
+
+       /* Gain levels while possible */
+       while ((p_ptr->lev < PY_MAX_LEVEL) &&
+               (p_ptr->exp >= ((android ? player_exp_a : player_exp)[p_ptr->lev - 1] * p_ptr->expfact / 100L)))
+       {
+               /* Gain a level */
+               p_ptr->lev++;
+
+               /* Save the highest level */
+               if (p_ptr->lev > p_ptr->max_plv)
+               {
+                       p_ptr->max_plv = p_ptr->lev;
+
+                       if ((p_ptr->pclass == CLASS_CHAOS_WARRIOR) ||
+                               (p_ptr->muta2 & MUT2_CHAOS_GIFT))
+                       {
+                               level_reward = TRUE;
+                       }
+                       if (p_ptr->prace == RACE_BEASTMAN)
+                       {
+                               if (one_in_(5)) level_mutation = TRUE;
+                       }
+                       level_inc_stat = TRUE;
+
+                       do_cmd_write_nikki(NIKKI_LEVELUP, p_ptr->lev, NULL);
+               }
+
+               sound(SOUND_LEVEL);
+
+               msg_format(_("レベル %d にようこそ。", "Welcome to level %d."), p_ptr->lev);
+
+               p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
+               p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);
+               p_ptr->window |= (PW_PLAYER | PW_SPELL | PW_INVEN);
+
+               /* HPとMPの上昇量を表示 */
+               level_up = 1;
+               handle_stuff();
+
+               level_up = 0;
+
+               if (level_inc_stat)
+               {
+                       if (!(p_ptr->max_plv % 10))
+                       {
+                               int choice;
+                               screen_save();
+                               while (1)
+                               {
+                                       int n;
+                                       char tmp[32];
+
+                                       cnv_stat(p_ptr->stat_max[0], tmp);
+                                       prt(format(_("        a) 腕力 (現在値 %s)", "        a) Str (cur %s)"), tmp), 2, 14);
+                                       cnv_stat(p_ptr->stat_max[1], tmp);
+                                       prt(format(_("        b) 知能 (現在値 %s)", "        a) Int (cur %s)"), tmp), 3, 14);
+                                       cnv_stat(p_ptr->stat_max[2], tmp);
+                                       prt(format(_("        c) 賢さ (現在値 %s)", "        a) Wis (cur %s)"), tmp), 4, 14);
+                                       cnv_stat(p_ptr->stat_max[3], tmp);
+                                       prt(format(_("        d) 器用 (現在値 %s)", "        a) Dex (cur %s)"), tmp), 5, 14);
+                                       cnv_stat(p_ptr->stat_max[4], tmp);
+                                       prt(format(_("        e) 耐久 (現在値 %s)", "        a) Con (cur %s)"), tmp), 6, 14);
+                                       cnv_stat(p_ptr->stat_max[5], tmp);
+                                       prt(format(_("        f) 魅力 (現在値 %s)", "        a) Chr (cur %s)"), tmp), 7, 14);
+
+                                       prt("", 8, 14);
+                                       prt(_("        どの能力値を上げますか?", "        Which stat do you want to raise?"), 1, 14);
+
+                                       while (1)
+                                       {
+                                               choice = inkey();
+                                               if ((choice >= 'a') && (choice <= 'f')) break;
+                                       }
+                                       for (n = 0; n < A_MAX; n++)
+                                               if (n != choice - 'a')
+                                                       prt("", n + 2, 14);
+                                       if (get_check(_("よろしいですか?", "Are you sure? "))) break;
+                               }
+                               do_inc_stat(choice - 'a');
+                               screen_load();
+                       }
+                       else if (!(p_ptr->max_plv % 2))
+                               do_inc_stat(randint0(6));
+               }
+
+               if (level_mutation)
+               {
+                       msg_print(_("あなたは変わった気がする...", "You feel different..."));
+                       (void)gain_mutation(p_ptr, 0);
+                       level_mutation = FALSE;
+               }
+
+               /*
+                * 報酬でレベルが上ると再帰的に check_experience() が
+                * 呼ばれるので順番を最後にする。
+                */
+               if (level_reward)
+               {
+                       gain_level_reward(0);
+                       level_reward = FALSE;
+               }
+
+               p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
+               p_ptr->redraw |= (PR_LEV | PR_TITLE);
+               p_ptr->window |= (PW_PLAYER | PW_SPELL);
+               handle_stuff();
+       }
+
+       /* Load an autopick preference file */
+       if (old_lev != p_ptr->lev) autopick_load_pref(FALSE);
+}
+