-/*!
+/*!
* @brief 町の施設処理 / Building commands
* @date 2013/12/23
* @author
#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"
#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"
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!");
}
}
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);
}
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++;
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);
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);
}