X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fbldg.c;h=47eab3d57b13f3403c0ced3d4e5d26f178e2aab8;hb=61fd54c1ee47a6c98fdd7d549f313f36c14f20b0;hp=41c7e8d4e74208604e3089793f6c2555e648491f;hpb=ab484e7c3993ee621a2496bb205db98aca648850;p=hengband%2Fhengband.git diff --git a/src/bldg.c b/src/bldg.c index 41c7e8d4e..47eab3d57 100644 --- a/src/bldg.c +++ b/src/bldg.c @@ -13,15 +13,108 @@ */ #include "angband.h" +#include "util.h" + +#include "core.h" +#include "cmd-dump.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 "monster.h" #include "monsterrace-hook.h" #include "melee.h" +#include "wild.h" #include "world.h" +#include "sort.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-status.h" +#include "realm-hex.h" +#include "dungeon-file.h" + +#include "files.h" +#include "player-effects.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; /*! - * ループ中で / hack as in leave_store in store.c + * @brief 闘技場のモンスターID及び報酬アイテムテーブル */ -static bool leave_bldg = FALSE; +const arena_type arena_info[MAX_ARENA_MONS + 2] = +{ + { MON_NOBORTA, TV_AMULET, SV_AMULET_ADORNMENT }, + { MON_MORI_TROLL, TV_FOOD, SV_FOOD_PINT_OF_WINE }, + { MON_IMP, TV_POTION, SV_POTION_SPEED }, + { MON_LION_HEART, 0, 0 }, + { MON_MASTER_YEEK, TV_POTION, SV_POTION_CURING }, + { MON_SABRE_TIGER, TV_WAND, SV_WAND_STONE_TO_MUD }, + { MON_LIZARD_KING, TV_WAND, SV_WAND_TELEPORT_AWAY }, + { MON_WYVERN, TV_POTION, SV_POTION_HEALING }, + { MON_ARCH_VILE, TV_POTION, SV_POTION_RESISTANCE }, + { MON_ELF_LORD , TV_POTION, SV_POTION_ENLIGHTENMENT }, + { MON_GHOUL_KING, TV_FOOD, SV_FOOD_RESTORING }, + { MON_COLBRAN, TV_RING, SV_RING_ELEC }, + { MON_BICLOPS, TV_WAND, SV_WAND_ACID_BALL }, + { MON_M_MINDCRAFTER, TV_POTION, SV_POTION_SELF_KNOWLEDGE }, + { MON_GROO, TV_SCROLL, SV_SCROLL_ACQUIREMENT }, + { MON_RAAL, TV_SCROLL, SV_SCROLL_STAR_DESTRUCTION }, + { MON_DREADMASTER, TV_WAND, SV_WAND_HYPODYNAMIA }, + { MON_ULTRA_PALADIN, TV_STAFF, SV_STAFF_DISPEL_EVIL }, + { MON_BARNEY, TV_RING, SV_RING_RES_CHAOS }, + { MON_TROLL_KING, TV_SCROLL, SV_SCROLL_MASS_GENOCIDE }, + { MON_BARON_HELL, TV_POTION, SV_POTION_AUGMENTATION }, + { MON_F_ANGEL, TV_SCROLL, SV_SCROLL_RUNE_OF_PROTECTION }, + { MON_G_C_DRAKE, TV_WAND, SV_WAND_DRAGON_FIRE }, + { MON_IRON_LICH, TV_STAFF, SV_STAFF_DESTRUCTION }, + { MON_DROLEM, TV_POTION, SV_POTION_STAR_HEALING }, + { MON_G_TITAN, TV_WAND, SV_WAND_GENOCIDE }, + { MON_G_BALROG, TV_POTION, SV_POTION_EXPERIENCE }, + { MON_ELDER_VAMPIRE, TV_RING, SV_RING_SUSTAIN }, + { MON_NIGHTWALKER, TV_WAND, SV_WAND_STRIKING }, + { MON_S_TYRANNO, TV_SCROLL, SV_SCROLL_STAR_ACQUIREMENT }, + { MON_G_MASTER_MYS, TV_ROD, SV_ROD_IDENTIFY }, + { MON_LORD_CHAOS, TV_POTION, SV_POTION_LIFE }, + { MON_SHADOWLORD, TV_POTION, SV_POTION_STAR_ENLIGHTENMENT }, + { MON_ULT_BEHOLDER, TV_AMULET, SV_AMULET_REFLECTION }, + { MON_JABBERWOCK, TV_ROD, SV_ROD_HEALING }, + { MON_LOCKE_CLONE, TV_WAND, SV_WAND_DISINTEGRATE }, + { MON_WYRM_SPACE, TV_ROD, SV_ROD_RESTORATION }, + { MON_SHAMBLER, TV_SCROLL, SV_SCROLL_STAR_ACQUIREMENT }, + { MON_BLACK_REAVER, TV_RING, SV_RING_LORDLY }, + { MON_FENGHUANG, TV_STAFF, SV_STAFF_THE_MAGI }, + { MON_WYRM_POWER, TV_SCROLL, SV_SCROLL_ARTIFACT }, + { 0, 0, 0 }, /* Victory prizing */ + { MON_HAGURE, TV_SCROLL, SV_SCROLL_ARTIFACT }, +}; /*! * @brief 施設毎に設定された種族、職業、魔法領域フラグがプレイヤーと一致するかを判定する。 @@ -99,7 +192,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; @@ -216,7 +309,7 @@ static void show_building(building_type* bldg) static void arena_comm(int cmd) { monster_race *r_ptr; - cptr name; + concptr name; switch (cmd) @@ -255,7 +348,7 @@ static void arena_comm(int cmd) p_ptr->inside_arena = TRUE; p_ptr->leaving = TRUE; - leave_bldg = TRUE; + p_ptr->leave_bldg = TRUE; } else { @@ -285,7 +378,7 @@ static void arena_comm(int cmd) p_ptr->inside_arena = TRUE; p_ptr->leaving = TRUE; - leave_bldg = TRUE; + p_ptr->leave_bldg = TRUE; } break; case BACT_POSTER: @@ -729,8 +822,8 @@ static void display_cards(void) int i, j; char suitcolor[4] = {TERM_YELLOW, TERM_L_RED, TERM_L_BLUE, TERM_L_GREEN}; #ifdef JP - cptr suit[4] = {"★", "●", "¶", "†"}; - cptr card_grph[13][7] = {{"A %s ", + concptr suit[4] = {"★", "●", "¶", "†"}; + concptr card_grph[13][7] = {{"A %s ", " 変 ", " 愚 ", " 蛮 ", @@ -821,7 +914,7 @@ static void display_cards(void) " υ ∂ ", " σ ノ %s", " K"}}; - cptr joker_grph[7] = { " ", + concptr joker_grph[7] = { " ", " J ", " O ", " K ", @@ -831,8 +924,8 @@ static void display_cards(void) #else - cptr suit[4] = {"[]", "qp", "<>", "db"}; - cptr card_grph[13][7] = {{"A %s ", + concptr suit[4] = {"[]", "qp", "<>", "db"}; + concptr card_grph[13][7] = {{"A %s ", " He ", " ng ", " ba ", @@ -923,7 +1016,7 @@ static void display_cards(void) " c & ", " v__/ %s", " K"}}; - cptr joker_grph[7] = { " ", + concptr joker_grph[7] = { " ", " J ", " O ", " K ", @@ -1045,7 +1138,7 @@ static bool gamble_comm(int cmd) s32b oldgold; char out_val[160], tmp_str[80], again; - cptr p; + concptr p; screen_save(); @@ -1342,10 +1435,10 @@ static bool gamble_comm(int cmd) } /*! - * @brief モンスター闘技場に参加するモンスターをリセットする。 + * @brief モンスター闘技場に参加するモンスターを更新する。 * @return なし */ -void battle_monsters(void) +void update_gambling_monsters(void) { int total, i; int max_dl = 0; @@ -1357,15 +1450,15 @@ void battle_monsters(void) for (i = 0; i < max_d_idx; i++) if (max_dl < max_dlv[i]) max_dl = max_dlv[i]; - mon_level = randint1(MIN(max_dl, 122))+5; + mon_level = randint1(MIN(max_dl, 122)) + 5; if (randint0(100) < 60) { - i = randint1(MIN(max_dl, 122))+5; + i = randint1(MIN(max_dl, 122)) + 5; mon_level = MAX(i, mon_level); } if (randint0(100) < 30) { - i = randint1(MIN(max_dl, 122))+5; + i = randint1(MIN(max_dl, 122)) + 5; mon_level = MAX(i, mon_level); } @@ -1373,7 +1466,7 @@ void battle_monsters(void) { total = 0; tekitou = FALSE; - for(i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { MONRACE_IDX r_idx; int j; @@ -1391,8 +1484,8 @@ void battle_monsters(void) } for (j = 0; j < i; j++) - if(r_idx == battle_mon[j]) break; - if (jflagsr & (RFR_IM_ACID | RFR_IM_ELEC | RFR_IM_FIRE | RFR_IM_COLD | RFR_IM_POIS)); @@ -1415,7 +1508,7 @@ void battle_monsters(void) if (r_ptr->speed < 110) power[i] = power[i] * (r_ptr->speed - 20) / 100; if (num_taisei > 2) - power[i] = power[i] * (num_taisei*2+5) / 10; + power[i] = power[i] * (num_taisei * 2 + 5) / 10; else if (r_ptr->a_ability_flags2 & RF6_INVULNER) power[i] = power[i] * 4 / 3; else if (r_ptr->a_ability_flags2 & RF6_HEAL) @@ -1432,9 +1525,9 @@ void battle_monsters(void) total += power[i]; } - for (i=0;i<4;i++) + for (i = 0; i < 4; i++) { - power[i] = total*60/power[i]; + power[i] = total * 60 / power[i]; if (tekitou && ((power[i] < 160) || power[i] > 1500)) break; if ((power[i] < 160) && randint0(20)) break; if (power[i] < 101) power[i] = 100 + randint1(5); @@ -1450,15 +1543,15 @@ void battle_monsters(void) */ static bool kakutoujou(void) { - s32b maxbet; - s32b wager; + PRICE maxbet; + PRICE wager; char out_val[160], tmp_str[80]; - cptr p; + concptr p; - if ((turn - old_battle) > TURNS_PER_TICK*250) + if ((current_world_ptr->game_turn - old_battle) > TURNS_PER_TICK * 250) { - battle_monsters(); - old_battle = turn; + update_gambling_monsters(); + old_battle = current_world_ptr->game_turn; } screen_save(); @@ -1509,9 +1602,9 @@ static bool kakutoujou(void) else bell(); } - clear_bldg(4,4); - for (i=0;i<4;i++) - if (i !=sel_monster) clear_bldg(i+5,i+5); + clear_bldg(4, 4); + for (i = 0; i < 4; i++) + if (i != sel_monster) clear_bldg(i + 5, i + 5); maxbet = p_ptr->lev * 200; @@ -1564,7 +1657,7 @@ static bool kakutoujou(void) p_ptr->inside_battle = TRUE; p_ptr->leaving = TRUE; - leave_bldg = TRUE; + p_ptr->leave_bldg = TRUE; screen_load(); return (TRUE); @@ -1625,10 +1718,10 @@ static void shoukinkubi(void) for (i = 0; i < MAX_KUBI; i++) { byte color; - cptr done_mark; - monster_race *r_ptr = &r_info[(kubi_r_idx[i] > 10000 ? kubi_r_idx[i] - 10000 : kubi_r_idx[i])]; + concptr done_mark; + monster_race *r_ptr = &r_info[(current_world_ptr->bounty_r_idx[i] > 10000 ? current_world_ptr->bounty_r_idx[i] - 10000 : current_world_ptr->bounty_r_idx[i])]; - if (kubi_r_idx[i] > 10000) + if (current_world_ptr->bounty_r_idx[i] > 10000) { color = TERM_RED; done_mark = _("(済)", "(done)"); @@ -1699,10 +1792,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)) @@ -1725,7 +1818,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)) @@ -1748,7 +1841,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)) @@ -1771,7 +1864,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]; @@ -1792,7 +1885,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))) { @@ -1817,8 +1910,8 @@ 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]; - if ((o_ptr->tval == TV_CORPSE) && (o_ptr->pval == kubi_r_idx[j])) + 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]; int num, k; @@ -1830,14 +1923,14 @@ static bool kankin(void) if (!get_check(buf)) continue; #if 0 /* Obsoleted */ - msg_format(_("賞金 %ld$を手に入れた。", "You get %ldgp."), (r_info[kubi_r_idx[j]].level + 1) * 300 * o_ptr->number); - p_ptr->au += (r_info[kubi_r_idx[j]].level+1) * 300 * o_ptr->number; + msg_format(_("賞金 %ld$を手に入れた。", "You get %ldgp."), (r_info[current_world_ptr->bounty_r_idx[j]].level + 1) * 300 * o_ptr->number); + p_ptr->au += (r_info[current_world_ptr->bounty_r_idx[j]].level+1) * 300 * o_ptr->number; p_ptr->redraw |= (PR_GOLD); inven_item_increase(i, -o_ptr->number); inven_item_describe(i); inven_item_optimize(i); chg_virtue(V_JUSTICE, 5); - kubi_r_idx[j] += 10000; + current_world_ptr->bounty_r_idx[j] += 10000; change = TRUE; #endif /* Obsoleted */ @@ -1848,20 +1941,19 @@ static bool kankin(void) inven_item_optimize(i); chg_virtue(V_JUSTICE, 5); - kubi_r_idx[j] += 10000; + current_world_ptr->bounty_r_idx[j] += 10000; /* Count number of unique corpses already handed */ for (num = 0, k = 0; k < MAX_KUBI; k++) { - if (kubi_r_idx[k] >= 10000) num++; + if (current_world_ptr->bounty_r_idx[k] >= 10000) num++; } msg_format(_("これで合計 %d ポイント獲得しました。" ,"You earned %d point%s total."), num, (num > 1 ? "s" : "")); /* Prepare to make a prize */ object_prep(&forge, lookup_kind(prize_list[num-1].tval, prize_list[num-1].sval)); - apply_magic(&forge, object_level, AM_NO_FIXED_ART); + apply_magic(&forge, current_floor_ptr->object_level, AM_NO_FIXED_ART); - /* Identify it fully */ object_aware(&forge); object_known(&forge); @@ -1928,7 +2020,7 @@ static bool inn_comm(int cmd) } else { - s32b oldturn = turn; + s32b oldturn = current_world_ptr->game_turn; int prev_day, prev_hour, prev_min; extract_day_hour_min(&prev_day, &prev_hour, &prev_min); @@ -1937,11 +2029,11 @@ static bool inn_comm(int cmd) else do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("宿屋に泊まった。", "stay over night at the inn.")); - turn = (turn / (TURNS_PER_TICK * TOWN_DAWN / 2) + 1) * (TURNS_PER_TICK * TOWN_DAWN / 2); - if (dungeon_turn < dungeon_turn_limit) + 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) { - dungeon_turn += MIN((turn - oldturn), TURNS_PER_TICK * 250) * INN_DUNGEON_TURN_ADJ; - if (dungeon_turn > dungeon_turn_limit) dungeon_turn = dungeon_turn_limit; + current_world_ptr->dungeon_turn += MIN((current_world_ptr->game_turn - oldturn), TURNS_PER_TICK * 250) * INN_DUNGEON_TURN_ADJ; + if (current_world_ptr->dungeon_turn > current_world_ptr->dungeon_turn_limit) current_world_ptr->dungeon_turn = current_world_ptr->dungeon_turn_limit; } prevent_turn_overflow(); @@ -2017,7 +2109,7 @@ static bool inn_comm(int cmd) static void get_questinfo(IDX questnum, bool do_init) { int i; - IDX old_quest; + QUEST_IDX old_quest; GAME_TEXT tmp_str[80]; /* Clear the text */ @@ -2060,16 +2152,16 @@ static void get_questinfo(IDX questnum, bool do_init) */ static void castle_quest(void) { - IDX q_index = 0; - monster_race *r_ptr; - quest_type *q_ptr; - cptr name; + QUEST_IDX q_index = 0; + monster_race *r_ptr; + quest_type *q_ptr; + concptr name; clear_bldg(4, 18); /* Current quest of the building */ - q_index = cave[p_ptr->y][p_ptr->x].special; + q_index = current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].special; /* Is there a quest available at the building? */ if (!q_index) @@ -2166,124 +2258,6 @@ static void town_history(void) } /*! - * @brief 射撃時クリティカルによるダメージ期待値修正計算(スナイパーの集中処理と武器経験値) / critical happens at i / 10000 - * @param plus_ammo 矢弾のダメージ修正 - * @param plus_bow 弓のダメージ修正 - * @return ダメージ期待値 - * @note 基本ダメージ量と重量はこの部位では計算に加わらない。 - */ -HIT_POINT calc_crit_ratio_shot(HIT_POINT plus_ammo, HIT_POINT plus_bow) -{ - HIT_POINT i; - object_type *j_ptr = &inventory[INVEN_BOW]; - - /* Extract "shot" power */ - i = p_ptr->to_h_b + plus_ammo; - - if (p_ptr->tval_ammo == TV_BOLT) - i = (p_ptr->skill_thb + (p_ptr->weapon_exp[0][j_ptr->sval] / 400 + i) * BTH_PLUS_ADJ); - else - i = (p_ptr->skill_thb + ((p_ptr->weapon_exp[0][j_ptr->sval] - (WEAPON_EXP_MASTER / 2)) / 200 + i) * BTH_PLUS_ADJ); - - /* Snipers can shot more critically with crossbows */ - if (p_ptr->concent) i += ((i * p_ptr->concent) / 5); - if ((p_ptr->pclass == CLASS_SNIPER) && (p_ptr->tval_ammo == TV_BOLT)) i *= 2; - - /* Good bow makes more critical */ - i += plus_bow * 8 * (p_ptr->concent ? p_ptr->concent + 5 : 5); - - if (i < 0) i = 0; - - return i; -} - -/*! - * @brief 射撃時クリティカルによるダメージ期待値修正計算(重量依存部分) / critical happens at i / 10000 - * @param weight 武器の重量 - * @param plus_ammo 矢弾のダメージ修正 - * @param plus_bow 弓のダメージ修正 - * @param dam 基本ダメージ量 - * @return ダメージ期待値 - */ -HIT_POINT calc_expect_crit_shot(WEIGHT weight, int plus_ammo, int plus_bow, HIT_POINT dam) -{ - u32b num; - int i, k, crit; - i = calc_crit_ratio_shot(plus_ammo, plus_bow); - - k = 0; - num = 0; - - crit = MIN(500, 900/weight); - num += dam * 3 /2 * crit; - k = crit; - - crit = MIN(500, 1350/weight); - crit -= k; - num += dam * 2 * crit; - k += crit; - - if(k < 500) - { - crit = 500 - k; - num += dam * 3 * crit; - } - - num /= 500; - - num *= i; - num += (10000 - i) * dam; - num /= 10000; - - return num; -} - -/*! - * @brief 攻撃時クリティカルによるダメージ期待値修正計算(重量と毒針処理) / critical happens at i / 10000 - * @param weight 武器の重量 - * @param plus 武器のダメージ修正 - * @param dam 基本ダメージ - * @param meichuu 命中値 - * @param dokubari 毒針処理か否か - * @return ダメージ期待値 - */ -HIT_POINT calc_expect_crit(WEIGHT weight, int plus, HIT_POINT dam, s16b meichuu, bool dokubari) -{ - u32b k, num; - int i; - - if(dokubari) return dam; - - i = (weight + (meichuu * 3 + plus * 5) + p_ptr->skill_thn); - if (i < 0) i = 0; - - k = weight; - num = 0; - - if (k < 400) num += (2 * dam + 5) * (400 - k); - if (k < 700) num += (2 * dam + 10) * (MIN(700, k + 650) - MAX(400, k)); - if (k > (700 - 650) && k < 900) num += (3 * dam + 15) * (MIN(900, k + 650) - MAX(700, k)); - if (k > (900 - 650) && k < 1300) num += (3 * dam + 20) * (MIN(1300, k + 650) - MAX(900, k)); - if (k > (1300 - 650)) num += (7 * dam / 2 + 25) * MIN(650, k - (1300 - 650)); - - num /= 650; - if(p_ptr->pclass == CLASS_NINJA) - { - num *= i; - num += (4444 - i) * dam; - num /= 4444; - } - else - { - num *= i; - num += (5000 - i) * dam; - num /= 5000; - } - - return num; -} - -/*! * @brief 攻撃時スレイによるダメージ期待値修正計算 / critical happens at i / 10000 * @param dam 基本ダメージ * @param mult スレイ倍率(掛け算部分) @@ -2353,7 +2327,7 @@ static u32b calc_expect_dice(u32b dam, int mult, int div, bool force, WEIGHT wei * the current +dam of the player.\n * @return なし */ -static void show_weapon_dmg(int r, int c, int mindice, int maxdice, int blows, int dam_bonus, cptr attr, byte color) +static void show_weapon_dmg(int r, int c, int mindice, int maxdice, int blows, int dam_bonus, concptr attr, byte color) { GAME_TEXT tmp_str[80]; int mindam, maxdam; @@ -2658,7 +2632,7 @@ static PRICE compare_weapons(PRICE bcost) object_type *o_ptr[2]; object_type orig_weapon; object_type *i_ptr; - cptr q, s; + concptr q, s; TERM_LEN row = 2; TERM_LEN wid = 38, mgn = 2; bool old_character_xtra = character_xtra; @@ -2670,7 +2644,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; @@ -2680,7 +2654,7 @@ static PRICE compare_weapons(PRICE bcost) s = _("比べるものがありません。", "You have nothing to compare."); o_ptr[0] = choose_object(&item, q, s, (USE_EQUIP | USE_INVEN | IGNORE_BOTHHAND_SLOT)); - if (!o_ptr) + if (!o_ptr[0]) { screen_load(); return (0); @@ -2751,7 +2725,7 @@ static PRICE compare_weapons(PRICE bcost) /* Get the second weapon */ o_ptr[1] = choose_object(&item2, q, s, (USE_EQUIP | USE_INVEN | IGNORE_BOTHHAND_SLOT)); - if (!o_ptr) continue; + if (!o_ptr[1]) continue; total += cost; cost = bcost / 2; @@ -2816,23 +2790,13 @@ static bool eval_ac(ARMOUR_CLASS iAC) screen_save(); clear_bldg(0, 22); -#ifdef JP - put_str(format("あなたの現在のAC: %3d", iAC), row++, 0); - put_str(format("ダメージ軽減率 : %3d%%", protection), row++, 0); - row++; - - put_str("敵のレベル :", row + 0, 0); - put_str("回避率 :", row + 1, 0); - put_str("ダメージ期待値 :", row + 2, 0); -#else - put_str(format("Your current AC : %3d", iAC), row++, 0); - put_str(format("Protection rate : %3d%%", protection), row++, 0); + put_str(format(_("あなたの現在のAC: %3d", "Your current AC : %3d"), iAC), row++, 0); + put_str(format(_("ダメージ軽減率 : %3d%%", "Protection rate : %3d%%"), protection), row++, 0); row++; - put_str("Level of Monster:", row + 0, 0); - put_str("Dodge Rate :", row + 1, 0); - put_str("Average Damage :", row + 2, 0); -#endif + put_str(_("敵のレベル :", "Level of Monster:"), row + 0, 0); + put_str(_("回避率 :", "Dodge Rate :"), row + 1, 0); + put_str(_("ダメージ期待値 :", "Average Damage :"), row + 2, 0); for (col = 17 + 1, lvl = 0; lvl <= 100; lvl += 10, col += 5) { @@ -2937,7 +2901,7 @@ static PRICE repair_broken_weapon_aux(PRICE bcost) int i, dd_bonus, ds_bonus; KIND_OBJECT_IDX k_idx; char basenm[MAX_NLEN]; - cptr q, s; + concptr q, s; int row = 7; clear_bldg(0, 22); @@ -3202,7 +3166,7 @@ static bool enchant_item(PRICE cost, HIT_PROB to_hit, HIT_POINT to_dam, ARMOUR_C OBJECT_IDX item; bool okay = FALSE; object_type *o_ptr; - cptr q, s; + concptr q, s; int maxenchant = (p_ptr->lev / 5); char tmp_str[MAX_NLEN]; @@ -3307,7 +3271,7 @@ static void building_recharge(void) DEPTH lev; object_type *o_ptr; object_kind *k_ptr; - cptr q, s; + concptr q, s; PRICE price; PARAMETER_VALUE charges; int max_charges; @@ -3441,8 +3405,7 @@ static void building_recharge(void) if (o_ptr->tval == TV_ROD) { #ifdef JP -if (get_check(format("そのロッドを$%d で再充填しますか?", - price))) + if (get_check(format("そのロッドを$%d で再充填しますか?", price))) #else if (get_check(format("Recharge the %s for %d gold? ", ((o_ptr->number > 1) ? "rods" : "rod"), price))) @@ -3488,8 +3451,6 @@ if (get_check(format("そのロッドを$%d で再充填しますか?", #else msg_format("%^s %s recharged for %d gold.", tmp_str, ((o_ptr->number > 1) ? "were" : "was"), price); #endif - - /* Combine / Reorder the pack (later) */ p_ptr->update |= (PU_COMBINE | PU_REORDER); p_ptr->window |= (PW_INVEN); @@ -3531,7 +3492,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; @@ -3595,7 +3556,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 */ @@ -3632,8 +3593,6 @@ static void building_recharge_all(void) /* Give feedback */ msg_format(_("$%d で再充填しました。", "You pay %d gold."), total_cost); msg_print(NULL); - - /* Combine / Reorder the pack (later) */ p_ptr->update |= (PU_COMBINE | PU_REORDER); p_ptr->window |= (PW_INVEN); @@ -3646,83 +3605,6 @@ static void building_recharge_all(void) } /*! - * @brief 町間のテレポートを行うメインルーチン。 - * @return テレポート処理を決定したか否か - */ -bool tele_town(void) -{ - int i, x, y; - int num = 0; - - if (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[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 < max_wild_y; y++) - { - for (x = 0; x < 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 返り値が意味不明なので直した方が良いかもしれない。 @@ -3740,9 +3622,9 @@ static bool research_mon(void) MONSTER_IDX *who; /* XTRA HACK WHATSEARCH */ - bool all = FALSE; - bool uniq = FALSE; - bool norm = FALSE; + bool all = FALSE; + bool uniq = FALSE; + bool norm = FALSE; char temp[80] = ""; /* XTRA HACK REMEMBER_IDX */ @@ -3756,7 +3638,6 @@ static bool research_mon(void) "Enter character to be identified(^A:All,^U:Uniqs,^N:Non uniqs,^M:Name): "), &sym, FALSE)) { - /* Restore */ screen_load(); return (FALSE); @@ -3790,8 +3671,6 @@ static bool research_mon(void) if (!get_string(_("名前(英語の場合小文字で可)", "Enter name:"),temp, 70)) { temp[0]=0; - - /* Restore */ screen_load(); return FALSE; @@ -3810,9 +3689,8 @@ static bool research_mon(void) /* Display the result */ prt(buf, 16, 10); - /* Allocate the "who" array */ - C_MAKE(who, max_r_idx, IDX); + C_MAKE(who, max_r_idx, MONRACE_IDX); /* Collect matching monsters */ for (n = 0, i = 1; i < max_r_idx; i++) @@ -3869,9 +3747,7 @@ static bool research_mon(void) if (!n) { /* Free the "who" array */ - C_KILL(who, max_r_idx, IDX); - - /* Restore */ + C_KILL(who, max_r_idx, MONRACE_IDX); screen_load(); return (FALSE); @@ -3884,12 +3760,7 @@ static bool research_mon(void) /* Sort if needed */ if (why) { - /* Select the sort method */ - ang_sort_comp = ang_sort_comp_hook; - ang_sort_swap = ang_sort_swap_hook; - - /* Sort the array */ - ang_sort(who, &why, n); + ang_sort(who, &why, n, ang_sort_comp_hook, ang_sort_swap_hook); } @@ -3936,7 +3807,6 @@ static bool research_mon(void) old_i = i; } - /* Command */ query = inkey(); /* Normal commands */ @@ -3975,9 +3845,7 @@ static bool research_mon(void) /* prt(buf, 5, 5);*/ /* Free the "who" array */ - C_KILL(who, max_r_idx, IDX); - - /* Restore */ + C_KILL(who, max_r_idx, MONRACE_IDX); screen_load(); return (!notpicked); @@ -3995,7 +3863,6 @@ static void bldg_process_command(building_type *bldg, int i) BACT_IDX bact = bldg->actions[i]; PRICE bcost; bool paid = FALSE; - int amt; msg_flag = FALSE; msg_erase(); @@ -4109,50 +3976,19 @@ static void bldg_process_command(building_type *bldg, int i) item_tester_tval = TV_BOW; enchant_item(bcost, 1, 1, 0); break; + case BACT_RECALL: - if (recall_player(1)) paid = TRUE; + if (recall_player(p_ptr, 1)) paid = TRUE; break; - case BACT_TELEPORT_LEVEL: - { - IDX select_dungeon; - DEPTH max_depth; + case BACT_TELEPORT_LEVEL: clear_bldg(4, 20); - select_dungeon = choose_dungeon(_("にテレポート", "teleport"), 4, 0); - show_building(bldg); - if (!select_dungeon) return; - - max_depth = d_info[select_dungeon].maxdepth; - - /* Limit depth in Angband */ - if (select_dungeon == DUNGEON_ANGBAND) - { - if (quest[QUEST_OBERON].status != QUEST_STATUS_FINISHED) max_depth = 98; - else if(quest[QUEST_SERPENT].status != QUEST_STATUS_FINISHED) max_depth = 99; - } - amt = get_quantity(format(_("%sの何階にテレポートしますか?", "Teleport to which level of %s? "), - d_name + d_info[select_dungeon].name), (QUANTITY)max_depth); - - if (amt > 0) - { - p_ptr->word_recall = 1; - p_ptr->recall_dungeon = select_dungeon; - max_dlv[p_ptr->recall_dungeon] = ((amt > d_info[select_dungeon].maxdepth) ? d_info[select_dungeon].maxdepth : ((amt < d_info[select_dungeon].mindepth) ? d_info[select_dungeon].mindepth : amt)); - if (record_maxdepth) - do_cmd_write_nikki(NIKKI_TRUMP, select_dungeon, _("トランプタワーで", "at Trump Tower")); - - msg_print(_("回りの大気が張りつめてきた...", "The air about you becomes charged...")); - - paid = TRUE; - p_ptr->redraw |= (PR_STATUS); - } + paid = free_level_recall(p_ptr); break; - } + case BACT_LOSE_MUTATION: - if (p_ptr->muta1 || p_ptr->muta2 || - (p_ptr->muta3 & ~MUT3_GOOD_LUCK) || - (p_ptr->pseikaku != SEIKAKU_LUCKY && - (p_ptr->muta3 & MUT3_GOOD_LUCK))) + 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)); paid = TRUE; @@ -4163,21 +3999,27 @@ static void bldg_process_command(building_type *bldg, int i) msg_print(NULL); } break; + case BACT_BATTLE: kakutoujou(); break; + case BACT_TSUCHINOKO: tsuchinoko(); break; + case BACT_KUBI: shoukinkubi(); break; + case BACT_TARGET: today_target(); break; + case BACT_KANKIN: kankin(); break; + case BACT_HEIKOUKA: msg_print(_("平衡化の儀式を行なった。", "You received an equalization ritual.")); set_virtue(V_COMPASSION, 0); @@ -4201,12 +4043,15 @@ static void bldg_process_command(building_type *bldg, int i) get_virtues(); paid = TRUE; break; + case BACT_TELE_TOWN: paid = tele_town(); break; + case BACT_EVAL_AC: paid = eval_ac(p_ptr->dis_ac + p_ptr->dis_to_a); break; + case BACT_BROKEN_WEAPON: paid = TRUE; bcost = repair_broken_weapon(bcost); @@ -4220,42 +4065,6 @@ static void bldg_process_command(building_type *bldg, int i) } /*! - * @brief クエスト入り口にプレイヤーが乗った際の処理 / Do building commands - * @return なし - */ -void do_cmd_quest(void) -{ - if(p_ptr->wild_mode) return; - - p_ptr->energy_use = 100; - - if (!cave_have_flag_bold(p_ptr->y, p_ptr->x, FF_QUEST_ENTER)) - { - msg_print(_("ここにはクエストの入口はない。", "You see no quest level here.")); - return; - } - else - { - msg_print(_("ここにはクエストへの入口があります。", "There is an entry of a quest.")); - if (!get_check(_("クエストに入りますか?", "Do you enter? "))) return; - if ((p_ptr->pseikaku == SEIKAKU_COMBAT) || (inventory[INVEN_BOW].name1 == ART_CRIMSON)) - msg_print(_("『とにかく入ってみようぜぇ。』", "")); - - /* Player enters a new quest */ - p_ptr->oldpy = 0; - p_ptr->oldpx = 0; - - leave_quest_check(); - - if (quest[p_ptr->inside_quest].type != QUEST_TYPE_RANDOM) dun_level = 1; - p_ptr->inside_quest = cave[p_ptr->y][p_ptr->x].special; - - p_ptr->leaving = TRUE; - } -} - - -/*! * @brief 施設入り口にプレイヤーが乗った際の処理 / Do building commands * @return なし */ @@ -4268,7 +4077,7 @@ void do_cmd_bldg(void) if(p_ptr->wild_mode) return; - p_ptr->energy_use = 100; + take_turn(p_ptr, 100); if (!cave_have_flag_bold(p_ptr->y, p_ptr->x, FF_BLDG)) { @@ -4276,7 +4085,7 @@ void do_cmd_bldg(void) return; } - which = f_info[cave[p_ptr->y][p_ptr->x].feat].subtype; + which = f_info[current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].feat].subtype; bldg = &building[which]; @@ -4290,7 +4099,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 && current_floor_ptr->m_cnt > 0) { prt(_("ゲートは閉まっている。モンスターがあなたを待っている!", "The gates are closed. The monster awaits!"), 0, 0); } @@ -4306,7 +4115,7 @@ void do_cmd_bldg(void) command_new = SPECIAL_KEY_BUILDING; /* No energy needed to re-enter the arena */ - p_ptr->energy_use = 0; + free_turn(p_ptr); } return; @@ -4323,7 +4132,7 @@ void do_cmd_bldg(void) command_new = SPECIAL_KEY_BUILDING; /* No energy needed to re-enter the arena */ - p_ptr->energy_use = 0; + free_turn(p_ptr); return; } @@ -4344,11 +4153,11 @@ void do_cmd_bldg(void) 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); @@ -4359,7 +4168,7 @@ 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; break; @@ -4405,118 +4214,93 @@ void do_cmd_bldg(void) /*! - * @brief クエスト突入時のメッセージテーブル / Array of places to find an inscription - */ -static cptr find_quest[] = -{ - _("床にメッセージが刻まれている:", "You find the following inscription in the floor"), - _("壁にメッセージが刻まれている:", "You see a message inscribed in the wall"), - _("メッセージを見つけた:", "There is a sign saying"), - _("何かが階段の上に書いてある:", "Something is written on the staircase"), - _("巻物を見つけた。メッセージが書いてある:", "You find a scroll with the following message"), -}; - - -/*! - * @brief クエストの導入メッセージを表示する / Discover quest - * @param q_idx 開始されたクエストのID + * @brief 今日の賞金首を確定する / Determine today's bounty monster + * @return なし + * @note conv_old is used if loaded 0.0.3 or older save file */ -void quest_discovery(QUEST_IDX q_idx) +void determine_today_mon(bool conv_old) { - quest_type *q_ptr = &quest[q_idx]; - monster_race *r_ptr = &r_info[q_ptr->r_idx]; - MONSTER_NUMBER q_num = q_ptr->max_num; - GAME_TEXT name[MAX_NLEN]; - - /* No quest index */ - if (!q_idx) return; - - strcpy(name, (r_name + r_ptr->name)); - - msg_print(find_quest[rand_range(0, 4)]); - msg_print(NULL); + int max_dl = 3, i; + bool old_inside_battle = p_ptr->inside_battle; + monster_race *r_ptr; - if (q_num == 1) + if (!conv_old) { - /* Unique */ - - /* Hack -- "unique" monsters must be "unique" */ - if ((r_ptr->flags1 & RF1_UNIQUE) && (0 == r_ptr->max_num)) - { - msg_print(_("この階は以前は誰かによって守られていたようだ…。", "It seems that this level was protected by someone before...")); - /* The unique is already dead */ - quest[q_idx].status = QUEST_STATUS_FINISHED; - q_ptr->complev = 0; - update_playtime(); - q_ptr->comptime = playtime; - } - else + for (i = 0; i < max_d_idx; i++) { - msg_format(_("注意せよ!この階は%sによって守られている!", "Beware, this level is protected by %s!"), name); + if (max_dlv[i] < d_info[i].mindepth) continue; + if (max_dl < max_dlv[i]) max_dl = max_dlv[i]; } } - else + else max_dl = MAX(max_dlv[DUNGEON_ANGBAND], 3); + + p_ptr->inside_battle = TRUE; + get_mon_num_prep(NULL, NULL); + + while (1) { - /* Normal monsters */ -#ifndef JP - plural_aux(name); -#endif - msg_format(_("注意しろ!この階は%d体の%sによって守られている!", "Be warned, this level is guarded by %d %s!"), q_num, name); + 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->inside_battle = old_inside_battle; } + /*! - * @brief 新しく入ったダンジョンの階層に固定されている一般のクエストを探し出しIDを返す。 - * / Hack -- Check if a level is a "quest" level - * @param level 検索対象になる階 - * @return クエストIDを返す。該当がない場合0を返す。 + * @brief 賞金首となるユニークを確定する / Determine bounty uniques + * @return なし */ -QUEST_IDX quest_number(DEPTH level) +void determine_bounty_uniques(void) { - QUEST_IDX i; - - /* Check quests */ - if (p_ptr->inside_quest) - return (p_ptr->inside_quest); + int i, j; + MONRACE_IDX tmp; + monster_race *r_ptr; - for (i = 0; i < max_q_idx; i++) + get_mon_num_prep(NULL, NULL); + for (i = 0; i < MAX_KUBI; i++) { - if (quest[i].status != QUEST_STATUS_TAKEN) continue; + 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 ((quest[i].type == QUEST_TYPE_KILL_LEVEL) && - !(quest[i].flags & QUEST_FLAG_PRESET) && - (quest[i].level == level) && - (quest[i].dungeon == dungeon_type)) - return (i); - } + if (!(r_ptr->flags1 & RF1_UNIQUE)) continue; - /* Check for random quest */ - return (random_quest_number(level)); -} + if (!(r_ptr->flags9 & (RF9_DROP_CORPSE | RF9_DROP_SKELETON))) continue; -/*! - * @brief 新しく入ったダンジョンの階層に固定されているランダムクエストを探し出しIDを返す。 - * @param level 検索対象になる階 - * @return クエストIDを返す。該当がない場合0を返す。 - */ -QUEST_IDX random_quest_number(DEPTH level) -{ - QUEST_IDX i; + if (r_ptr->rarity > 100) continue; + + if (no_questor_or_bounty_uniques(current_world_ptr->bounty_r_idx[i])) continue; - if (dungeon_type != DUNGEON_ANGBAND) return 0; + for (j = 0; j < i; j++) + if (current_world_ptr->bounty_r_idx[i] == current_world_ptr->bounty_r_idx[j]) break; - for (i = MIN_RANDOM_QUEST; i < MAX_RANDOM_QUEST + 1; i++) + if (j == i) break; + } + } + + /* Sort them */ + for (i = 0; i < MAX_KUBI - 1; i++) { - if ((quest[i].type == QUEST_TYPE_RANDOM) && - (quest[i].status == QUEST_STATUS_TAKEN) && - (quest[i].level == level) && - (quest[i].dungeon == DUNGEON_ANGBAND)) + for (j = i; j < MAX_KUBI; j++) { - return i; + 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; + } } } - - return 0; }