OSDN Git Service

[Fix] #39526 update_gambling_monsters() 中のゼロ除算を回避するよう修正. / Fix division by zero in...
[hengbandforosx/hengbandosx.git] / src / bldg.c
index bd84380..1d44aa2 100644 (file)
 
 #include "angband.h"
 #include "util.h"
+#include "term.h"
 
+#include "core.h"
+#include "cmd-dump.h"
+#include "cmd-magiceat.h"
 #include "floor.h"
 #include "floor-events.h"
 #include "floor-save.h"
+#include "autopick.h"
+#include "objectkind.h"
 #include "object-boost.h"
 #include "object-flavor.h"
 #include "object-hook.h"
 
 #include "avatar.h"
 #include "bldg.h"
+#include "dungeon.h"
 #include "mutation.h"
 #include "quest.h"
 #include "artifact.h"
 #include "cmd-spell.h"
 #include "rumor.h"
-#include "player-status.h"
+#include "spells.h"
+#include "spells-object.h"
 #include "spells-status.h"
 #include "realm-hex.h"
 #include "dungeon-file.h"
 
 #include "files.h"
+#include "player-status.h"
 #include "player-effects.h"
+#include "player-class.h"
+#include "player-personality.h"
+#include "player-inventory.h"
 #include "scores.h"
 #include "shoot.h"
+#include "view-mainwindow.h"
+#include "monsterrace.h"
+#include "autopick.h"
+
+
+/*
+ * Buildings
+ */
+building_type building[MAX_BLDG];
+
+MONRACE_IDX battle_mon[4];
+u32b mon_odds[4];
+int battle_odds;
+PRICE kakekin;
+int sel_monster;
+
+bool reinit_wilderness = FALSE;
+MONSTER_IDX today_mon;
 
 /*!
  * @brief 闘技場のモンスターID及び報酬アイテムテーブル
@@ -95,12 +125,6 @@ const arena_type arena_info[MAX_ARENA_MONS + 2] =
        { MON_HAGURE,        TV_SCROLL, SV_SCROLL_ARTIFACT            },
 };
 
-
-/*!
- * ループ中で / hack as in leave_store in store.c
- */
-static bool leave_bldg = FALSE;
-
 /*!
  * @brief 施設毎に設定された種族、職業、魔法領域フラグがプレイヤーと一致するかを判定する。
  * @details 各種ギルドや寺院など、特定の職業ならば優遇措置を得られる施設、
@@ -177,7 +201,7 @@ static bool is_member(building_type *bldg)
  * @param max_row 末尾行番号
  * @return なし
  */
-static void clear_bldg(int min_row, int max_row)
+void clear_bldg(int min_row, int max_row)
 {
        int   i;
 
@@ -326,14 +350,14 @@ static void arena_comm(int cmd)
                                                msg_print(NULL);
                                        
                                                p_ptr->exit_bldg = FALSE;
-                                               reset_tim_flags();
+                                               reset_tim_flags(p_ptr);
 
                                                /* Save the surface floor as saved floor */
                                                prepare_change_floor_mode(CFM_SAVE_FLOORS);
 
                                                p_ptr->inside_arena = TRUE;
                                                p_ptr->leaving = TRUE;
-                                               leave_bldg = TRUE;
+                                               p_ptr->leave_bldg = TRUE;
                                        }
                                        else
                                        {
@@ -356,14 +380,14 @@ static void arena_comm(int cmd)
                        else
                        {
                                p_ptr->exit_bldg = FALSE;
-                               reset_tim_flags();
+                               reset_tim_flags(p_ptr);
 
                                /* Save the surface floor as saved floor */
                                prepare_change_floor_mode(CFM_SAVE_FLOORS);
 
                                p_ptr->inside_arena = TRUE;
                                p_ptr->leaving = TRUE;
-                               leave_bldg = TRUE;
+                               p_ptr->leave_bldg = TRUE;
                        }
                        break;
                case BACT_POSTER:
@@ -1405,12 +1429,12 @@ static bool gamble_comm(int cmd)
                        {
                                msg_print(_("「今回は儲けたな!でも次はこっちが勝ってやるからな、絶対に!」",
                                                        "You came out a winner! We'll win next time, I'm sure."));
-                               chg_virtue(V_CHANCE, 3);
+                               chg_virtue(p_ptr, V_CHANCE, 3);
                        }
                        else
                        {
                                msg_print(_("「金をスッてしまったな、わはは!うちに帰った方がいいぜ。」", "You lost gold! Haha, better head home."));
-                               chg_virtue(V_CHANCE, -3);
+                               chg_virtue(p_ptr, V_CHANCE, -3);
                        }
                }
                msg_print(NULL);
@@ -1430,9 +1454,9 @@ void update_gambling_monsters(void)
        int mon_level;
        int power[4];
        bool tekitou;
-       bool old_inside_battle = p_ptr->inside_battle;
+       bool old_inside_battle = p_ptr->phase_out;
 
-       for (i = 0; i < max_d_idx; i++)
+       for (i = 0; i < current_world_ptr->max_d_idx; i++)
                if (max_dl < max_dlv[i]) max_dl = max_dlv[i];
 
        mon_level = randint1(MIN(max_dl, 122)) + 5;
@@ -1458,9 +1482,9 @@ void update_gambling_monsters(void)
                        while (1)
                        {
                                get_mon_num_prep(monster_can_entry_arena, NULL);
-                               p_ptr->inside_battle = TRUE;
+                               p_ptr->phase_out = TRUE;
                                r_idx = get_mon_num(mon_level);
-                               p_ptr->inside_battle = old_inside_battle;
+                               p_ptr->phase_out = old_inside_battle;
                                if (!r_idx) continue;
 
                                if ((r_info[r_idx].flags1 & RF1_UNIQUE) || (r_info[r_idx].flags7 & RF7_UNIQUE2))
@@ -1507,11 +1531,11 @@ void update_gambling_monsters(void)
                        if (r_ptr->flagsr & RFR_RES_ALL) power[i] *= 100000;
                        if (r_ptr->arena_ratio) power[i] = power[i] * r_ptr->arena_ratio / 100;
 
-
                        total += power[i];
                }
                for (i = 0; i < 4; i++)
                {
+                       if (power[i] <= 0) break;
                        power[i] = total * 60 / power[i];
                        if (tekitou && ((power[i] < 160) || power[i] > 1500)) break;
                        if ((power[i] < 160) && randint0(20)) break;
@@ -1533,10 +1557,10 @@ static bool kakutoujou(void)
        char out_val[160], tmp_str[80];
        concptr p;
 
-       if ((current_world_ptr->game_turn - old_battle) > TURNS_PER_TICK * 250)
+       if ((current_world_ptr->game_turn - current_world_ptr->arena_start_turn) > TURNS_PER_TICK * 250)
        {
                update_gambling_monsters();
-               old_battle = current_world_ptr->game_turn;
+               current_world_ptr->arena_start_turn = current_world_ptr->game_turn;
        }
 
        screen_save();
@@ -1634,15 +1658,15 @@ static bool kakutoujou(void)
                        battle_odds = MAX(wager+1, wager * battle_odds / 100);
                        kakekin = wager;
                        p_ptr->au -= wager;
-                       reset_tim_flags();
+                       reset_tim_flags(p_ptr);
 
                        /* Save the surface floor as saved floor */
                        prepare_change_floor_mode(CFM_SAVE_FLOORS);
 
-                       p_ptr->inside_battle = TRUE;
+                       p_ptr->phase_out = TRUE;
                        p_ptr->leaving = TRUE;
+                       p_ptr->leave_bldg = TRUE;
 
-                       leave_bldg = TRUE;
                        screen_load();
 
                        return (TRUE);
@@ -1777,10 +1801,10 @@ static bool kankin(void)
        GAME_TEXT o_name[MAX_NLEN];
        object_type *o_ptr;
 
-       /* Loop for inventory and right/left arm */
+       /* Loop for p_ptr->inventory_list and right/left arm */
        for (i = 0; i <= INVEN_LARM; i++)
        {
-               o_ptr = &inventory[i];
+               o_ptr = &p_ptr->inventory_list[i];
 
                /* Living Tsuchinoko worthes $1000000 */
                if ((o_ptr->tval == TV_CAPTURE) && (o_ptr->pval == MON_TSUCHINOKO))
@@ -1803,7 +1827,7 @@ static bool kankin(void)
 
        for (i = 0; i < INVEN_PACK; i++)
        {
-               o_ptr = &inventory[i];
+               o_ptr = &p_ptr->inventory_list[i];
 
                /* Corpse of Tsuchinoko worthes $200000 */
                if ((o_ptr->tval == TV_CORPSE) && (o_ptr->sval == SV_CORPSE) && (o_ptr->pval == MON_TSUCHINOKO))
@@ -1826,7 +1850,7 @@ static bool kankin(void)
 
        for (i = 0; i < INVEN_PACK; i++)
        {
-               o_ptr = &inventory[i];
+               o_ptr = &p_ptr->inventory_list[i];
 
                /* Bones of Tsuchinoko worthes $100000 */
                if ((o_ptr->tval == TV_CORPSE) && (o_ptr->sval == SV_SKELETON) && (o_ptr->pval == MON_TSUCHINOKO))
@@ -1849,7 +1873,7 @@ static bool kankin(void)
 
        for (i = 0; i < INVEN_PACK; i++)
        {
-               o_ptr = &inventory[i];
+               o_ptr = &p_ptr->inventory_list[i];
                if ((o_ptr->tval == TV_CORPSE) && (o_ptr->sval == SV_CORPSE) && (streq(r_name + r_info[o_ptr->pval].name, r_name + r_info[today_mon].name)))
                {
                        char buf[MAX_NLEN+20];
@@ -1870,7 +1894,7 @@ static bool kankin(void)
 
        for (i = 0; i < INVEN_PACK; i++)
        {
-               o_ptr = &inventory[i];
+               o_ptr = &p_ptr->inventory_list[i];
 
                if ((o_ptr->tval == TV_CORPSE) && (o_ptr->sval == SV_SKELETON) && (streq(r_name + r_info[o_ptr->pval].name, r_name + r_info[today_mon].name)))
                {
@@ -1895,7 +1919,7 @@ static bool kankin(void)
                /* Need reverse order --- Positions will be changed in the loop */
                for (i = INVEN_PACK-1; i >= 0; i--)
                {
-                       o_ptr = &inventory[i];
+                       o_ptr = &p_ptr->inventory_list[i];
                        if ((o_ptr->tval == TV_CORPSE) && (o_ptr->pval == current_world_ptr->bounty_r_idx[j]))
                        {
                                char buf[MAX_NLEN+20];
@@ -1914,7 +1938,7 @@ static bool kankin(void)
                                inven_item_increase(i, -o_ptr->number);
                                inven_item_describe(i);
                                inven_item_optimize(i);
-                               chg_virtue(V_JUSTICE, 5);
+                               chg_virtue(p_ptr, V_JUSTICE, 5);
                                current_world_ptr->bounty_r_idx[j] += 10000;
 
                                change = TRUE;
@@ -1925,7 +1949,7 @@ static bool kankin(void)
                                inven_item_describe(i);
                                inven_item_optimize(i);
 
-                               chg_virtue(V_JUSTICE, 5);
+                               chg_virtue(p_ptr, V_JUSTICE, 5);
                                current_world_ptr->bounty_r_idx[j] += 10000;
 
                                /* Count number of unique corpses already handed */
@@ -1937,7 +1961,7 @@ static bool kankin(void)
 
                                /* Prepare to make a prize */
                                object_prep(&forge, lookup_kind(prize_list[num-1].tval, prize_list[num-1].sval));
-                               apply_magic(&forge, current_floor_ptr->object_level, AM_NO_FIXED_ART);
+                               apply_magic(&forge, p_ptr->current_floor_ptr->object_level, AM_NO_FIXED_ART);
 
                                object_aware(&forge);
                                object_known(&forge);
@@ -1993,7 +2017,7 @@ static bool inn_comm(int cmd)
                                return FALSE;
                        }
                        msg_print(_("バーテンはいくらかの食べ物とビールをくれた。", "The barkeep gives you some gruel and a beer."));
-                       (void)set_food(PY_FOOD_MAX - 1);
+                       (void)set_food(p_ptr, PY_FOOD_MAX - 1);
                        break;
 
                case BACT_REST: /* Rest for the night */
@@ -2010,9 +2034,9 @@ static bool inn_comm(int cmd)
 
                                extract_day_hour_min(&prev_day, &prev_hour, &prev_min);
                                if ((prev_hour >= 6) && (prev_hour <= 17)) 
-                                       do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("宿屋に泊まった。", "stay over daytime at the inn."));
+                                       exe_write_diary(p_ptr, NIKKI_BUNSHOU, 0, _("宿屋に泊まった。", "stay over daytime at the inn."));
                                else
-                                       do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("宿屋に泊まった。", "stay over night at the inn."));
+                                       exe_write_diary(p_ptr, NIKKI_BUNSHOU, 0, _("宿屋に泊まった。", "stay over night at the inn."));
                                
                                current_world_ptr->game_turn = (current_world_ptr->game_turn / (TURNS_PER_TICK * TOWN_DAWN / 2) + 1) * (TURNS_PER_TICK * TOWN_DAWN / 2);
                                if (current_world_ptr->dungeon_turn < current_world_ptr->dungeon_turn_limit)
@@ -2023,7 +2047,7 @@ static bool inn_comm(int cmd)
 
                                prevent_turn_overflow();
 
-                               if ((prev_hour >= 18) && (prev_hour <= 23)) do_cmd_write_nikki(NIKKI_HIGAWARI, 0, NULL);
+                               if ((prev_hour >= 18) && (prev_hour <= 23)) exe_write_diary(p_ptr, NIKKI_HIGAWARI, 0, NULL);
                                p_ptr->chp = p_ptr->mhp;
 
                                if (ironman_nightmare)
@@ -2033,17 +2057,17 @@ static bool inn_comm(int cmd)
                                        /* Have some nightmares */
                                        while(1)
                                        {
-                                               sanity_blast(NULL, FALSE);
+                                               sanity_blast(p_ptr, NULL, FALSE);
                                                if (!one_in_(3)) break;
                                        }
 
                                        msg_print(_("あなたは絶叫して目を覚ました。", "You awake screaming."));
-                                       do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("悪夢にうなされてよく眠れなかった。", "be troubled by a nightmare."));
+                                       exe_write_diary(p_ptr, NIKKI_BUNSHOU, 0, _("悪夢にうなされてよく眠れなかった。", "be troubled by a nightmare."));
                                }
                                else
                                {
-                                       set_blind(0);
-                                       set_confused(0);
+                                       set_blind(p_ptr, 0);
+                                       set_confused(p_ptr, 0);
                                        p_ptr->stun = 0;
                                        p_ptr->chp = p_ptr->mhp;
                                        p_ptr->csp = p_ptr->msp;
@@ -2063,12 +2087,12 @@ static bool inn_comm(int cmd)
                                        if ((prev_hour >= 6) && (prev_hour <= 17))
                                        {
                                                msg_print(_("あなたはリフレッシュして目覚め、夕方を迎えた。", "You awake refreshed for the evening."));
-                                               do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("夕方を迎えた。", "awake refreshed."));
+                                               exe_write_diary(p_ptr, NIKKI_BUNSHOU, 0, _("夕方を迎えた。", "awake refreshed."));
                                        }
                                        else
                                        {
                                                msg_print(_("あなたはリフレッシュして目覚め、新たな日を迎えた。", "You awake refreshed for the new day."));
-                                               do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("すがすがしい朝を迎えた。", "awake refreshed."));
+                                               exe_write_diary(p_ptr, NIKKI_BUNSHOU, 0, _("すがすがしい朝を迎えた。", "awake refreshed."));
                                        }
                                }
                        }
@@ -2146,7 +2170,7 @@ static void castle_quest(void)
        clear_bldg(4, 18);
 
        /* Current quest of the building */
-       q_index = current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].special;
+       q_index = p_ptr->current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].special;
 
        /* Is there a quest available at the building? */
        if (!q_index)
@@ -2620,7 +2644,7 @@ static PRICE compare_weapons(PRICE bcost)
        concptr q, s;
        TERM_LEN row = 2;
        TERM_LEN wid = 38, mgn = 2;
-       bool old_character_xtra = character_xtra;
+       bool old_character_xtra = current_world_ptr->character_xtra;
        char ch;
        PRICE total = 0;
        PRICE cost = 0; /* First time no price */
@@ -2629,7 +2653,7 @@ static PRICE compare_weapons(PRICE bcost)
        clear_bldg(0, 22);
 
        /* Store copy of original wielded weapon */
-       i_ptr = &inventory[INVEN_RARM];
+       i_ptr = &p_ptr->inventory_list[INVEN_RARM];
        object_copy(&orig_weapon, i_ptr);
 
        item_tester_hook = item_tester_hook_orthodox_melee_weapons;
@@ -2638,7 +2662,7 @@ static PRICE compare_weapons(PRICE bcost)
        q = _("第一の武器は?", "What is your first weapon? ");
        s = _("比べるものがありません。", "You have nothing to compare.");
 
-       o_ptr[0] = choose_object(&item, q, s, (USE_EQUIP | USE_INVEN | IGNORE_BOTHHAND_SLOT));
+       o_ptr[0] = choose_object(p_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | IGNORE_BOTHHAND_SLOT), 0);
        if (!o_ptr[0])
        {
                screen_load();
@@ -2656,7 +2680,7 @@ static PRICE compare_weapons(PRICE bcost)
                item_tester_hook = item_tester_hook_orthodox_melee_weapons;
 
                /* Hack -- prevent "icky" message */
-               character_xtra = TRUE;
+               current_world_ptr->character_xtra = TRUE;
 
                /* Diaplay selected weapon's infomation */
                for (i = 0; i < n; i++)
@@ -2681,7 +2705,7 @@ static PRICE compare_weapons(PRICE bcost)
                p_ptr->update |= PU_BONUS;
                handle_stuff();
 
-               character_xtra = old_character_xtra;
+               current_world_ptr->character_xtra = old_character_xtra;
 
 #ifdef JP
                put_str(format("[ 比較対象: 's'で変更 ($%d) ]", cost), 1, (wid + mgn));
@@ -2709,7 +2733,7 @@ static PRICE compare_weapons(PRICE bcost)
                        s = _("比べるものがありません。", "You have nothing to compare.");
 
                        /* Get the second weapon */
-                       o_ptr[1] = choose_object(&item2, q, s, (USE_EQUIP | USE_INVEN | IGNORE_BOTHHAND_SLOT));
+                       o_ptr[1] = choose_object(p_ptr, &item2, q, s, (USE_EQUIP | USE_INVEN | IGNORE_BOTHHAND_SLOT), 0);
                        if (!o_ptr[1]) continue;
 
                        total += cost;
@@ -2899,7 +2923,7 @@ static PRICE repair_broken_weapon_aux(PRICE bcost)
        /* Only forge broken weapons */
        item_tester_hook = item_tester_hook_broken_weapon;
 
-       o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_EQUIP));
+       o_ptr = choose_object(p_ptr, &item, q, s, (USE_INVEN | USE_EQUIP), 0);
        if (!o_ptr) return (0);
 
        /* It is worthless */
@@ -2926,7 +2950,7 @@ static PRICE repair_broken_weapon_aux(PRICE bcost)
        /* Only forge broken weapons */
        item_tester_hook = item_tester_hook_orthodox_melee_weapons;
 
-       mo_ptr = choose_object(&mater, q, s, (USE_INVEN | USE_EQUIP));
+       mo_ptr = choose_object(p_ptr, &mater, q, s, (USE_INVEN | USE_EQUIP), 0);
        if (!mo_ptr) return (0);
        if (mater == item)
        {
@@ -3108,7 +3132,7 @@ static PRICE repair_broken_weapon_aux(PRICE bcost)
        o_ptr->discount = 99;
 
        p_ptr->total_weight += o_ptr->weight;
-       calc_android_exp();
+       calc_android_exp(p_ptr);
 
        /* Decrease material object */
        inven_item_increase(mater, -1);
@@ -3162,7 +3186,7 @@ static bool enchant_item(PRICE cost, HIT_PROB to_hit, HIT_POINT to_dam, ARMOUR_C
        q = _("どのアイテムを改良しますか?", "Improve which item? ");
        s = _("改良できるものがありません。", "You have nothing to improve.");
 
-       o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_EQUIP | IGNORE_BOTHHAND_SLOT));
+       o_ptr = choose_object(p_ptr, &item, q, s, (USE_INVEN | USE_EQUIP | IGNORE_BOTHHAND_SLOT), item_tester_tval);
        if (!o_ptr) return (FALSE);
 
        /* Check if the player has enough money */
@@ -3231,7 +3255,7 @@ static bool enchant_item(PRICE cost, HIT_PROB to_hit, HIT_POINT to_dam, ARMOUR_C
                /* Charge the money */
                p_ptr->au -= (cost * o_ptr->number);
 
-               if (item >= INVEN_RARM) calc_android_exp();
+               if (item >= INVEN_RARM) calc_android_exp(p_ptr);
 
                /* Something happened */
                return (TRUE);
@@ -3275,7 +3299,7 @@ static void building_recharge(void)
        q = _("どのアイテムに魔力を充填しますか? ", "Recharge which item? ");
        s = _("魔力を充填すべきアイテムがない。", "You have nothing to recharge.");
 
-       o_ptr = choose_object(&item, q, s, (USE_INVEN | USE_FLOOR));
+       o_ptr = choose_object(p_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
        if (!o_ptr) return;
 
        k_ptr = &k_info[o_ptr->k_idx];
@@ -3477,7 +3501,7 @@ static void building_recharge_all(void)
        /* Calculate cost */
        for ( i = 0; i < INVEN_PACK; i++)
        {
-               o_ptr = &inventory[i];
+               o_ptr = &p_ptr->inventory_list[i];
                                
                /* skip non magic device */
                if (o_ptr->tval < TV_STAFF || o_ptr->tval > TV_ROD) continue;
@@ -3541,7 +3565,7 @@ static void building_recharge_all(void)
        
        for (i = 0; i < INVEN_PACK; i++)
        {
-               o_ptr = &inventory[i];
+               o_ptr = &p_ptr->inventory_list[i];
                k_ptr = &k_info[o_ptr->k_idx];
 
                /* skip non magic device */
@@ -3590,84 +3614,6 @@ static void building_recharge_all(void)
 }
 
 /*!
- * @brief 町間のテレポートを行うメインルーチン。
- * @return テレポート処理を決定したか否か
- */
-bool tele_town(void)
-{
-       int i;
-       POSITION x, y;
-       int num = 0;
-
-       if (current_floor_ptr->dun_level)
-       {
-               msg_print(_("この魔法は地上でしか使えない!", "This spell can only be used on the surface!"));
-               return FALSE;
-       }
-
-       if (p_ptr->inside_arena || p_ptr->inside_battle)
-       {
-               msg_print(_("この魔法は外でしか使えない!", "This spell can only be used outside!"));
-               return FALSE;
-       }
-
-       screen_save();
-       clear_bldg(4, 10);
-
-       for (i = 1; i < max_towns; i++)
-       {
-               char buf[80];
-
-               if ((i == NO_TOWN) || (i == SECRET_TOWN) || (i == p_ptr->town_num) || !(p_ptr->visit & (1L << (i - 1)))) continue;
-
-               sprintf(buf, "%c) %-20s", I2A(i - 1), town_info[i].name);
-               prt(buf, 5 + i, 5);
-               num++;
-       }
-
-       if (!num)
-       {
-               msg_print(_("まだ行けるところがない。", "You have not yet visited any town."));
-               msg_print(NULL);
-               screen_load();
-               return FALSE;
-       }
-
-       prt(_("どこに行きますか:", "Which town you go: "), 0, 0);
-       while(1)
-       {
-               i = inkey();
-
-               if (i == ESCAPE)
-               {
-                       screen_load();
-                       return FALSE;
-               }
-               else if ((i < 'a') || (i > ('a'+max_towns-2))) continue;
-               else if (((i-'a'+1) == p_ptr->town_num) || ((i-'a'+1) == NO_TOWN) || ((i-'a'+1) == SECRET_TOWN) || !(p_ptr->visit & (1L << (i-'a')))) continue;
-               break;
-       }
-
-       for (y = 0; y < current_world_ptr->max_wild_y; y++)
-       {
-               for (x = 0; x < current_world_ptr->max_wild_x; x++)
-               {
-                       if(wilderness[y][x].town == (i-'a'+1))
-                       {
-                               p_ptr->wilderness_y = y;
-                               p_ptr->wilderness_x = x;
-                       }
-               }
-       }
-
-       p_ptr->leaving = TRUE;
-       leave_bldg = TRUE;
-       p_ptr->teleport_town = TRUE;
-       screen_load();
-       return TRUE;
-}
-
-/*!
  * @brief 施設でモンスターの情報を知るメインルーチン / research_mon -KMW-
  * @return 常にTRUEを返す。
  * @todo 返り値が意味不明なので直した方が良いかもしれない。
@@ -3837,7 +3783,6 @@ static bool research_mon(void)
        /* Scan the monster memory */
        while (notpicked)
        {
-               /* Extract a race */
                r_idx = who[i];
 
                /* Hack -- Begin the prompt */
@@ -3849,7 +3794,6 @@ static bool research_mon(void)
                /* Interact */
                while (1)
                {
-                       /* Recall */
                        if (recall)
                        {
                                /*** Recall on screen ***/
@@ -3870,13 +3814,11 @@ static bool research_mon(void)
                                old_i = i;
                        }
 
-                       /* Command */
                        query = inkey();
 
                        /* Normal commands */
                        if (query != 'r') break;
 
-                       /* Toggle recall */
                        recall = !recall;
                }
 
@@ -4024,13 +3966,13 @@ static void bldg_process_command(building_type *bldg, int i)
                paid = ident_spell(FALSE);
                break;
        case BACT_LEARN:
-               do_cmd_study();
+               do_cmd_study(p_ptr);
                break;
        case BACT_HEALING: /* needs work */
-               paid = cure_critical_wounds(200);
+               paid = cure_critical_wounds(p_ptr, 200);
                break;
        case BACT_RESTORE: /* needs work */
-               paid = restore_all_status();
+               paid = restore_all_status(p_ptr);
                break;
        case BACT_ENCHANT_ARROWS:
                item_tester_hook = item_tester_hook_ammo;
@@ -4054,7 +3996,7 @@ static void bldg_process_command(building_type *bldg, int i)
                if (p_ptr->muta1 || p_ptr->muta2 || (p_ptr->muta3 & ~MUT3_GOOD_LUCK) ||
                        (p_ptr->pseikaku != SEIKAKU_LUCKY && (p_ptr->muta3 & MUT3_GOOD_LUCK)))
                {
-                       while(!lose_mutation(0));
+                       while(!lose_mutation(p_ptr, 0));
                        paid = TRUE;
                }
                else
@@ -4086,25 +4028,25 @@ static void bldg_process_command(building_type *bldg, int i)
 
        case BACT_HEIKOUKA:
                msg_print(_("平衡化の儀式を行なった。", "You received an equalization ritual."));
-               set_virtue(V_COMPASSION, 0);
-               set_virtue(V_HONOUR, 0);
-               set_virtue(V_JUSTICE, 0);
-               set_virtue(V_SACRIFICE, 0);
-               set_virtue(V_KNOWLEDGE, 0);
-               set_virtue(V_FAITH, 0);
-               set_virtue(V_ENLIGHTEN, 0);
-               set_virtue(V_ENCHANT, 0);
-               set_virtue(V_CHANCE, 0);
-               set_virtue(V_NATURE, 0);
-               set_virtue(V_HARMONY, 0);
-               set_virtue(V_VITALITY, 0);
-               set_virtue(V_UNLIFE, 0);
-               set_virtue(V_PATIENCE, 0);
-               set_virtue(V_TEMPERANCE, 0);
-               set_virtue(V_DILIGENCE, 0);
-               set_virtue(V_VALOUR, 0);
-               set_virtue(V_INDIVIDUALISM, 0);
-               get_virtues();
+               set_virtue(p_ptr, V_COMPASSION, 0);
+               set_virtue(p_ptr, V_HONOUR, 0);
+               set_virtue(p_ptr, V_JUSTICE, 0);
+               set_virtue(p_ptr, V_SACRIFICE, 0);
+               set_virtue(p_ptr, V_KNOWLEDGE, 0);
+               set_virtue(p_ptr, V_FAITH, 0);
+               set_virtue(p_ptr, V_ENLIGHTEN, 0);
+               set_virtue(p_ptr, V_ENCHANT, 0);
+               set_virtue(p_ptr, V_CHANCE, 0);
+               set_virtue(p_ptr, V_NATURE, 0);
+               set_virtue(p_ptr, V_HARMONY, 0);
+               set_virtue(p_ptr, V_VITALITY, 0);
+               set_virtue(p_ptr, V_UNLIFE, 0);
+               set_virtue(p_ptr, V_PATIENCE, 0);
+               set_virtue(p_ptr, V_TEMPERANCE, 0);
+               set_virtue(p_ptr, V_DILIGENCE, 0);
+               set_virtue(p_ptr, V_VALOUR, 0);
+               set_virtue(p_ptr, V_INDIVIDUALISM, 0);
+               get_virtues(p_ptr);
                paid = TRUE;
                break;
 
@@ -4149,7 +4091,7 @@ void do_cmd_bldg(void)
                return;
        }
 
-       which = f_info[current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].feat].subtype;
+       which = f_info[p_ptr->current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].feat].subtype;
 
        bldg = &building[which];
 
@@ -4163,7 +4105,7 @@ void do_cmd_bldg(void)
        }
        else if ((which == 2) && p_ptr->inside_arena)
        {
-               if (!p_ptr->exit_bldg && m_cnt > 0)
+               if (!p_ptr->exit_bldg && p_ptr->current_floor_ptr->m_cnt > 0)
                {
                        prt(_("ゲートは閉まっている。モンスターがあなたを待っている!", "The gates are closed.  The monster awaits!"), 0, 0);
                }
@@ -4184,13 +4126,13 @@ void do_cmd_bldg(void)
 
                return;
        }
-       else if (p_ptr->inside_battle)
+       else if (p_ptr->phase_out)
        {
                /* Don't save the arena as saved floor */
                prepare_change_floor_mode(CFM_SAVE_FLOORS | CFM_NO_RETURN);
 
                p_ptr->leaving = TRUE;
-               p_ptr->inside_battle = FALSE;
+               p_ptr->phase_out = FALSE;
 
                /* Re-enter the monster arena */
                command_new = SPECIAL_KEY_BUILDING;
@@ -4206,22 +4148,22 @@ void do_cmd_bldg(void)
                p_ptr->oldpx = p_ptr->x;
        }
 
-       forget_lite();
+       forget_lite(p_ptr->current_floor_ptr);
        forget_view();
 
        /* Hack -- Increase "icky" depth */
-       character_icky++;
+       current_world_ptr->character_icky++;
 
        command_arg = 0;
        command_rep = 0;
        command_new = 0;
 
        show_building(bldg);
-       leave_bldg = FALSE;
+       p_ptr->leave_bldg = FALSE;
 
        play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_BUILD);
 
-       while (!leave_bldg)
+       while (!p_ptr->leave_bldg)
        {
                validcmd = FALSE;
                prt("", 1, 0);
@@ -4232,9 +4174,9 @@ void do_cmd_bldg(void)
 
                if (command == ESCAPE)
                {
-                       leave_bldg = TRUE;
+                       p_ptr->leave_bldg = TRUE;
                        p_ptr->inside_arena = FALSE;
-                       p_ptr->inside_battle = FALSE;
+                       p_ptr->phase_out = FALSE;
                        break;
                }
 
@@ -4255,7 +4197,7 @@ void do_cmd_bldg(void)
                handle_stuff();
        }
 
-       select_floor_music();
+       select_floor_music(p_ptr);
 
        msg_flag = FALSE;
        msg_erase();
@@ -4267,7 +4209,7 @@ void do_cmd_bldg(void)
        }
 
        /* Hack -- Decrease "icky" depth */
-       character_icky--;
+       current_world_ptr->character_icky--;
 
        Term_clear();
 
@@ -4275,3 +4217,96 @@ void do_cmd_bldg(void)
        p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_EQUIPPY | PR_MAP);
        p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
 }
+
+
+/*!
+ * @brief 今日の賞金首を確定する / Determine today's bounty monster
+ * @return なし
+ * @note conv_old is used if loaded 0.0.3 or older save file
+ */
+void determine_today_mon(bool conv_old)
+{
+       int max_dl = 3, i;
+       bool old_inside_battle = p_ptr->phase_out;
+       monster_race *r_ptr;
+
+       if (!conv_old)
+       {
+               for (i = 0; i < current_world_ptr->max_d_idx; i++)
+               {
+                       if (max_dlv[i] < d_info[i].mindepth) continue;
+                       if (max_dl < max_dlv[i]) max_dl = max_dlv[i];
+               }
+       }
+       else max_dl = MAX(max_dlv[DUNGEON_ANGBAND], 3);
+
+       p_ptr->phase_out = TRUE;
+       get_mon_num_prep(NULL, NULL);
+
+       while (1)
+       {
+               today_mon = get_mon_num(max_dl);
+               r_ptr = &r_info[today_mon];
+
+               if (r_ptr->flags1 & RF1_UNIQUE) continue;
+               if (r_ptr->flags7 & (RF7_NAZGUL | RF7_UNIQUE2)) continue;
+               if (r_ptr->flags2 & RF2_MULTIPLY) continue;
+               if ((r_ptr->flags9 & (RF9_DROP_CORPSE | RF9_DROP_SKELETON)) != (RF9_DROP_CORPSE | RF9_DROP_SKELETON)) continue;
+               if (r_ptr->level < MIN(max_dl / 2, 40)) continue;
+               if (r_ptr->rarity > 10) continue;
+               break;
+       }
+
+       p_ptr->today_mon = 0;
+       p_ptr->phase_out = old_inside_battle;
+}
+
+
+
+/*!
+ * @brief 賞金首となるユニークを確定する / Determine bounty uniques
+ * @return なし
+ */
+void determine_bounty_uniques(void)
+{
+       int i, j;
+       MONRACE_IDX tmp;
+       monster_race *r_ptr;
+
+       get_mon_num_prep(NULL, NULL);
+       for (i = 0; i < MAX_KUBI; i++)
+       {
+               while (1)
+               {
+                       current_world_ptr->bounty_r_idx[i] = get_mon_num(MAX_DEPTH - 1);
+                       r_ptr = &r_info[current_world_ptr->bounty_r_idx[i]];
+
+                       if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
+
+                       if (!(r_ptr->flags9 & (RF9_DROP_CORPSE | RF9_DROP_SKELETON))) continue;
+
+                       if (r_ptr->rarity > 100) continue;
+
+                       if (no_questor_or_bounty_uniques(current_world_ptr->bounty_r_idx[i])) continue;
+
+                       for (j = 0; j < i; j++)
+                               if (current_world_ptr->bounty_r_idx[i] == current_world_ptr->bounty_r_idx[j]) break;
+
+                       if (j == i) break;
+               }
+       }
+
+       /* Sort them */
+       for (i = 0; i < MAX_KUBI - 1; i++)
+       {
+               for (j = i; j < MAX_KUBI; j++)
+               {
+                       if (r_info[current_world_ptr->bounty_r_idx[i]].level > r_info[current_world_ptr->bounty_r_idx[j]].level)
+                       {
+                               tmp = current_world_ptr->bounty_r_idx[i];
+                               current_world_ptr->bounty_r_idx[i] = current_world_ptr->bounty_r_idx[j];
+                               current_world_ptr->bounty_r_idx[j] = tmp;
+                       }
+               }
+       }
+}