X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fcmd-building%2Fcmd-building.cpp;h=617ef99021aa1045ccc52e702ba17cf153920a38;hb=e1631059b268108ea3a3f002ce887f9c9f63c073;hp=b494962a099c0641722a1ad1ea557964f5791b64;hpb=f7f110d857a87d1355b7957402f92a9947642bb9;p=hengbandforosx%2Fhengbandosx.git diff --git a/src/cmd-building/cmd-building.cpp b/src/cmd-building/cmd-building.cpp index b494962a0..617ef9902 100644 --- a/src/cmd-building/cmd-building.cpp +++ b/src/cmd-building/cmd-building.cpp @@ -1,4 +1,4 @@ -/*! +/*! * @brief 町の施設処理 / Building commands * @date 2013/12/23 * @author @@ -17,8 +17,6 @@ #include "cmd-building/cmd-inn.h" #include "cmd-io/cmd-dump.h" #include "core/asking-player.h" -#include "core/player-redraw-types.h" -#include "core/player-update-types.h" #include "core/scores.h" #include "core/show-file.h" #include "core/special-internal-keys.h" @@ -57,11 +55,14 @@ #include "spell-kind/spells-perception.h" #include "spell-kind/spells-world.h" #include "spell/spells-status.h" +#include "system/angband-exceptions.h" +#include "system/angband-system.h" #include "system/building-type-definition.h" #include "system/floor-type-definition.h" #include "system/grid-type-definition.h" #include "system/item-entity.h" #include "system/player-type-definition.h" +#include "system/redrawing-flags-updater.h" #include "system/terrain-type-definition.h" #include "term/gameterm.h" #include "term/screen-processor.h" @@ -84,218 +85,225 @@ bool reinit_wilderness = false; static void town_history(PlayerType *player_ptr) { screen_save(); - (void)show_file(player_ptr, true, _("jbldg.txt", "bldg.txt"), nullptr, 0, 0); + (void)show_file(player_ptr, true, _("jbldg.txt", "bldg.txt"), 0, 0); screen_load(); } /*! - * @brief 施設の処理実行メインルーチン / Execute a building command + * @brief 施設の処理実行メインルーチン * @param player_ptr プレイヤーへの参照ポインタ * @param bldg 施設構造体の参照ポインタ * @param i 実行したい施設のサービステーブルの添字 + * @return 施設から別フロアへ移動するか否か (アリーナ/モンスター闘技場のみtrue) */ -static void bldg_process_command(PlayerType *player_ptr, building_type *bldg, int i) +static bool bldg_process_command(PlayerType *player_ptr, building_type *bldg, int i) { msg_flag = false; msg_erase(); - - PRICE bcost; - if (is_owner(player_ptr, bldg)) { - bcost = bldg->member_costs[i]; - } else { - bcost = bldg->other_costs[i]; - } - - /* action restrictions */ - if (((bldg->action_restr[i] == 1) && !is_member(player_ptr, bldg)) || ((bldg->action_restr[i] == 2) && !is_owner(player_ptr, bldg))) { + const auto can_be_owner = is_owner(player_ptr, bldg); + const auto building_cost = can_be_owner ? bldg->member_costs[i] : bldg->other_costs[i]; + if (((bldg->action_restr[i] == 1) && !is_member(player_ptr, bldg)) || ((bldg->action_restr[i] == 2) && !can_be_owner)) { msg_print(_("それを選択する権利はありません!", "You have no right to choose that!")); - return; + return false; } - auto bact = bldg->actions[i]; - if ((bact != BACT_RECHARGE) && (((bldg->member_costs[i] > player_ptr->au) && is_owner(player_ptr, bldg)) || ((bldg->other_costs[i] > player_ptr->au) && !is_owner(player_ptr, bldg)))) { + const auto building_action = bldg->actions[i]; + if ((building_action != BACT_RECHARGE) && (((bldg->member_costs[i] > player_ptr->au) && can_be_owner) || ((bldg->other_costs[i] > player_ptr->au) && !can_be_owner))) { msg_print(_("お金が足りません!", "You do not have the gold!")); - return; + return false; } - bool paid = false; - switch (bact) { + switch (building_action) { case BACT_NOTHING: /* Do nothing */ - break; + return false; case BACT_RESEARCH_ITEM: - paid = identify_fully(player_ptr, false); - break; + if (identify_fully(player_ptr, false)) { + player_ptr->au -= building_cost; + } + + return false; case BACT_TOWN_HISTORY: town_history(player_ptr); - break; + return false; case BACT_RACE_LEGENDS: race_legends(player_ptr); - break; + return false; case BACT_QUEST: castle_quest(player_ptr); - break; + return false; case BACT_KING_LEGENDS: case BACT_ARENA_LEGENDS: case BACT_LEGENDS: show_highclass(player_ptr); - break; + return false; case BACT_POSTER: case BACT_ARENA_RULES: case BACT_ARENA: - arena_comm(player_ptr, bact); - break; + return arena_comm(player_ptr, building_action); case BACT_IN_BETWEEN: case BACT_CRAPS: case BACT_SPIN_WHEEL: case BACT_DICE_SLOTS: case BACT_GAMBLE_RULES: case BACT_POKER: - gamble_comm(player_ptr, bact); - break; + gamble_comm(player_ptr, building_action); + return false; case BACT_REST: case BACT_RUMORS: case BACT_FOOD: - paid = inn_comm(player_ptr, bact); - break; + if (inn_comm(player_ptr, building_action)) { + player_ptr->au -= building_cost; + } + + return false; case BACT_RESEARCH_MONSTER: - paid = research_mon(player_ptr); - break; + if (research_mon(player_ptr)) { + player_ptr->au -= building_cost; + } + + return false; case BACT_COMPARE_WEAPONS: - paid = true; - bcost = compare_weapons(player_ptr, bcost); - break; + player_ptr->au -= compare_weapons(player_ptr, building_cost); + return false; case BACT_ENCHANT_WEAPON: - enchant_item(player_ptr, bcost, 1, 1, 0, FuncItemTester(&ItemEntity::allow_enchant_melee_weapon)); - break; + enchant_item(player_ptr, building_cost, 1, 1, 0, FuncItemTester(&ItemEntity::allow_enchant_melee_weapon)); + return false; case BACT_ENCHANT_ARMOR: - enchant_item(player_ptr, bcost, 0, 0, 1, FuncItemTester(&ItemEntity::is_protector)); - break; + enchant_item(player_ptr, building_cost, 0, 0, 1, FuncItemTester(&ItemEntity::is_protector)); + return false; case BACT_RECHARGE: building_recharge(player_ptr); - break; + return false; case BACT_RECHARGE_ALL: building_recharge_all(player_ptr); - break; + return false; case BACT_IDENTS: - if (!get_check(_("持ち物を全て鑑定してよろしいですか?", "Do you pay to identify all your possession? "))) { - break; + if (!input_check(_("持ち物を全て鑑定してよろしいですか?", "Do you pay to identify all your possession? "))) { + return false; } + identify_pack(player_ptr); msg_print(_(" 持ち物全てが鑑定されました。", "Your possessions have been identified.")); - paid = true; - break; + player_ptr->au -= building_cost; + return false; case BACT_IDENT_ONE: - paid = ident_spell(player_ptr, false); - break; + if (ident_spell(player_ptr, false)) { + player_ptr->au -= building_cost; + } + + return false; case BACT_LEARN: do_cmd_study(player_ptr); - break; + return false; case BACT_HEALING: - paid = cure_critical_wounds(player_ptr, 200); - break; + if (cure_critical_wounds(player_ptr, 200)) { + player_ptr->au -= building_cost; + } + + return false; case BACT_RESTORE: - paid = restore_all_status(player_ptr); - break; + if (restore_all_status(player_ptr)) { + player_ptr->au -= building_cost; + } + + return false; case BACT_ENCHANT_ARROWS: - enchant_item(player_ptr, bcost, 1, 1, 0, FuncItemTester(&ItemEntity::is_ammo)); - break; + enchant_item(player_ptr, building_cost, 1, 1, 0, FuncItemTester(&ItemEntity::is_ammo)); + return false; case BACT_ENCHANT_BOW: - enchant_item(player_ptr, bcost, 1, 1, 0, TvalItemTester(ItemKindType::BOW)); - break; - + enchant_item(player_ptr, building_cost, 1, 1, 0, TvalItemTester(ItemKindType::BOW)); + return false; case BACT_RECALL: if (recall_player(player_ptr, 1)) { - paid = true; + player_ptr->au -= building_cost; } - break; + return false; case BACT_TELEPORT_LEVEL: screen_save(); clear_bldg(4, 20); - paid = free_level_recall(player_ptr); - screen_load(); - break; + if (free_level_recall(player_ptr)) { + player_ptr->au -= building_cost; + } + screen_load(); + return false; case BACT_LOSE_MUTATION: { auto muta = player_ptr->muta; if (player_ptr->ppersonality == PERSONALITY_LUCKY) { // ラッキーマンの白オーラは突然変異治療の対象外 muta.reset(PlayerMutationType::GOOD_LUCK); } + if (muta.any()) { while (!lose_mutation(player_ptr, 0)) { ; } - paid = true; - break; + + player_ptr->au -= building_cost; + return false; } msg_print(_("治すべき突然変異が無い。", "You have no mutations.")); msg_print(nullptr); - break; + return false; } - case BACT_BATTLE: - monster_arena_comm(player_ptr); - break; - + return monster_arena_comm(player_ptr); case BACT_TSUCHINOKO: tsuchinoko(); - break; - + return false; case BACT_BOUNTY: show_bounty(); - break; - + return false; case BACT_TARGET: today_target(player_ptr); - break; - + return false; case BACT_KANKIN: exchange_cash(player_ptr); - break; - + return false; case BACT_HEIKOUKA: msg_print(_("平衡化の儀式を行なった。", "You received an equalization ritual.")); - set_virtue(player_ptr, V_COMPASSION, 0); - set_virtue(player_ptr, V_HONOUR, 0); - set_virtue(player_ptr, V_JUSTICE, 0); - set_virtue(player_ptr, V_SACRIFICE, 0); - set_virtue(player_ptr, V_KNOWLEDGE, 0); - set_virtue(player_ptr, V_FAITH, 0); - set_virtue(player_ptr, V_ENLIGHTEN, 0); - set_virtue(player_ptr, V_ENCHANT, 0); - set_virtue(player_ptr, V_CHANCE, 0); - set_virtue(player_ptr, V_NATURE, 0); - set_virtue(player_ptr, V_HARMONY, 0); - set_virtue(player_ptr, V_VITALITY, 0); - set_virtue(player_ptr, V_UNLIFE, 0); - set_virtue(player_ptr, V_PATIENCE, 0); - set_virtue(player_ptr, V_TEMPERANCE, 0); - set_virtue(player_ptr, V_DILIGENCE, 0); - set_virtue(player_ptr, V_VALOUR, 0); - set_virtue(player_ptr, V_INDIVIDUALISM, 0); + set_virtue(player_ptr, Virtue::COMPASSION, 0); + set_virtue(player_ptr, Virtue::HONOUR, 0); + set_virtue(player_ptr, Virtue::JUSTICE, 0); + set_virtue(player_ptr, Virtue::SACRIFICE, 0); + set_virtue(player_ptr, Virtue::KNOWLEDGE, 0); + set_virtue(player_ptr, Virtue::FAITH, 0); + set_virtue(player_ptr, Virtue::ENLIGHTEN, 0); + set_virtue(player_ptr, Virtue::ENCHANT, 0); + set_virtue(player_ptr, Virtue::CHANCE, 0); + set_virtue(player_ptr, Virtue::NATURE, 0); + set_virtue(player_ptr, Virtue::HARMONY, 0); + set_virtue(player_ptr, Virtue::VITALITY, 0); + set_virtue(player_ptr, Virtue::UNLIFE, 0); + set_virtue(player_ptr, Virtue::PATIENCE, 0); + set_virtue(player_ptr, Virtue::TEMPERANCE, 0); + set_virtue(player_ptr, Virtue::DILIGENCE, 0); + set_virtue(player_ptr, Virtue::VALOUR, 0); + set_virtue(player_ptr, Virtue::INDIVIDUALISM, 0); initialize_virtues(player_ptr); - paid = true; - break; - + player_ptr->au -= building_cost; + return false; case BACT_TELE_TOWN: - paid = tele_town(player_ptr); - break; + if (!tele_town(player_ptr)) { + return false; + } + player_ptr->au -= building_cost; + return true; case BACT_EVAL_AC: - paid = eval_ac(player_ptr->dis_ac + player_ptr->dis_to_a); - break; + if (eval_ac(player_ptr->dis_ac + player_ptr->dis_to_a)) { + player_ptr->au -= building_cost; + } + return false; case BACT_BROKEN_WEAPON: - paid = true; - bcost = repair_broken_weapon(player_ptr, bcost); - break; - } - - if (paid) { - player_ptr->au -= bcost; + player_ptr->au -= repair_broken_weapon(player_ptr, building_cost); + return false; + default: + THROW_EXCEPTION(std::logic_error, "Invalid building action is specified!"); } } @@ -311,26 +319,26 @@ void do_cmd_building(PlayerType *player_ptr) PlayerEnergy energy(player_ptr); energy.set_player_turn_energy(100); - - if (!cave_has_flag_bold(player_ptr->current_floor_ptr, player_ptr->y, player_ptr->x, TerrainCharacteristics::BLDG)) { + const auto p_pos = player_ptr->get_position(); + if (!cave_has_flag_bold(player_ptr->current_floor_ptr, p_pos.y, p_pos.x, TerrainCharacteristics::BLDG)) { msg_print(_("ここには建物はない。", "You see no building here.")); return; } - TermCenteredOffsetSetter tcos(MAIN_TERM_MIN_COLS, MAIN_TERM_MIN_ROWS); - - int which = terrains_info[player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x].feat].subtype; + int which = player_ptr->current_floor_ptr->get_grid(p_pos).get_terrain().subtype; building_type *bldg; - bldg = &building[which]; + bldg = &buildings[which]; reinit_wilderness = false; if ((which == 2) && (player_ptr->arena_number < 0)) { msg_print(_("「敗者に用はない。」", "'There's no place here for a LOSER like you!'")); return; - } else if ((which == 2) && player_ptr->current_floor_ptr->inside_arena) { - if (!player_ptr->exit_bldg && player_ptr->current_floor_ptr->m_cnt > 0) { + } + + if ((which == 2) && player_ptr->current_floor_ptr->inside_arena) { + if (!w_ptr->get_arena() && player_ptr->current_floor_ptr->m_cnt > 0) { prt(_("ゲートは閉まっている。モンスターがあなたを待っている!", "The gates are closed. The monster awaits!"), 0, 0); } else { prepare_change_floor_mode(player_ptr, CFM_SAVE_FLOORS | CFM_NO_RETURN); @@ -341,18 +349,22 @@ void do_cmd_building(PlayerType *player_ptr) } return; - } else if (player_ptr->phase_out) { + } + + TermCenteredOffsetSetter tcos(MAIN_TERM_MIN_COLS, MAIN_TERM_MIN_ROWS); + + auto &system = AngbandSystem::get_instance(); + if (system.is_phase_out()) { prepare_change_floor_mode(player_ptr, CFM_SAVE_FLOORS | CFM_NO_RETURN); player_ptr->leaving = true; - player_ptr->phase_out = false; + system.set_phase_out(false); command_new = SPECIAL_KEY_BUILDING; energy.reset_player_turn(); return; - } else { - player_ptr->oldpy = player_ptr->y; - player_ptr->oldpx = player_ptr->x; } + player_ptr->oldpy = player_ptr->y; + player_ptr->oldpx = player_ptr->x; forget_lite(player_ptr->current_floor_ptr); forget_view(player_ptr->current_floor_ptr); w_ptr->character_icky_depth++; @@ -362,38 +374,32 @@ void do_cmd_building(PlayerType *player_ptr) command_new = 0; display_buikding_service(player_ptr, bldg); - player_ptr->leave_bldg = false; play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_BUILD); - bool validcmd; - while (!player_ptr->leave_bldg) { - validcmd = false; + while (true) { prt("", 1, 0); - building_prt_gold(player_ptr); - - char command = inkey(); - + const auto command = inkey(); if (command == ESCAPE) { - player_ptr->leave_bldg = true; player_ptr->current_floor_ptr->inside_arena = false; - player_ptr->phase_out = false; + system.set_phase_out(false); break; } + auto is_valid_command = false; int i; for (i = 0; i < 8; i++) { if (bldg->letters[i] && (bldg->letters[i] == command)) { - validcmd = true; + is_valid_command = true; break; } } - if (validcmd) { - bldg_process_command(player_ptr, bldg, i); - } - + const auto should_leave = is_valid_command ? bldg_process_command(player_ptr, bldg, i) : false; handle_stuff(player_ptr); + if (should_leave) { + break; + } } select_floor_music(player_ptr); @@ -408,7 +414,25 @@ void do_cmd_building(PlayerType *player_ptr) w_ptr->character_icky_depth--; term_clear(); - player_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_BONUS | PU_LITE | PU_MON_LITE); - player_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_EQUIPPY | PR_MAP); - player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON); + auto &rfu = RedrawingFlagsUpdater::get_instance(); + static constexpr auto flags_srf = { + StatusRecalculatingFlag::VIEW, + StatusRecalculatingFlag::MONSTER_STATUSES, + StatusRecalculatingFlag::BONUS, + StatusRecalculatingFlag::LITE, + StatusRecalculatingFlag::MONSTER_LITE, + }; + rfu.set_flags(flags_srf); + static constexpr auto flags_mwrf = { + MainWindowRedrawingFlag::BASIC, + MainWindowRedrawingFlag::EXTRA, + MainWindowRedrawingFlag::EQUIPPY, + MainWindowRedrawingFlag::MAP, + }; + rfu.set_flags(flags_mwrf); + static constexpr auto flags_swrf = { + SubWindowRedrawingFlag::OVERHEAD, + SubWindowRedrawingFlag::DUNGEON, + }; + rfu.set_flags(flags_swrf); }