/*!
* @brief キー入力に応じてゲーム内コマンドを実行する
- * @date 2020/05/10
+ * @date 2022/02/20
* @author Hourier
- * @todo Ctrl+C がShift+Q に認識されている。仕様の可能性も高いが要確認
*/
#include "io/input-key-processor.h"
#include "cmd-visual/cmd-visuals.h"
#include "core/asking-player.h"
#include "core/player-redraw-types.h"
-#include "core/player-update-types.h"
#include "core/special-internal-keys.h"
#include "dungeon/dungeon-flag-types.h"
-#include "dungeon/dungeon.h"
#include "dungeon/quest.h" //!< @do_cmd_quest() がある。後で移設する.
+#include "effect/spells-effect-util.h"
#include "floor/wild.h"
#include "game-option/birth-options.h"
#include "game-option/disturbance-options.h"
#include "mind/mind-sniper.h"
#include "mind/mind-weaponsmith.h"
#include "mind/snipe-types.h"
+#include "player-base/player-class.h"
#include "player-info/class-info.h"
+#include "player-info/samurai-data-type.h"
+#include "player-info/sniper-data-type.h"
#include "player-status/player-energy.h"
#include "player/attack-defense-types.h"
#include "player/digestion-processor.h"
#include "store/cmd-store.h"
#include "store/home.h"
#include "store/store-util.h"
+#include "system/dungeon-info.h"
#include "system/floor-type-definition.h"
#include "system/player-type-definition.h"
+#include "system/redrawing-flags-updater.h"
#include "term/screen-processor.h"
#include "util/int-char-converter.h"
#include "view/display-messages.h"
#include "window/display-sub-windows.h"
#include "wizard/cmd-wizard.h"
#include "world/world.h"
+#include <optional>
+#include <string>
/*!
* @brief ウィザードモードへの導入処理
* @param player_ptr プレイヤーへの参照ポインタ
* @return 実際にウィザードモードへ移行したらTRUEを返す。
*/
-bool enter_wizard_mode(player_type *player_ptr)
+bool enter_wizard_mode(PlayerType *player_ptr)
{
if (!w_ptr->noscore) {
if (!allow_debug_opts) {
* @param player_ptr プレイヤーへの参照ポインタ
* @return 実際にデバッグコマンドへ移行したらTRUEを返す。
*/
-static bool enter_debug_mode(player_type *player_ptr)
+static bool enter_debug_mode(PlayerType *player_ptr)
{
if (!w_ptr->noscore) {
if (!allow_debug_opts) {
* / Parse and execute the current command Give "Warning" on illegal commands.
* @todo Make some "blocks"
*/
-void process_command(player_type *player_ptr)
+void process_command(PlayerType *player_ptr)
{
COMMAND_CODE old_now_message = now_message;
repeat_check();
now_message = 0;
- if ((player_ptr->pclass == CLASS_SNIPER) && (player_ptr->concent))
- player_ptr->reset_concent = true;
+ auto sniper_data = PlayerClass(player_ptr).get_specific_data<sniper_data_type>();
+ if (sniper_data && sniper_data->concent > 0) {
+ sniper_data->reset_concent = true;
+ }
- floor_type *floor_ptr = player_ptr->current_floor_ptr;
+ auto *floor_ptr = player_ptr->current_floor_ptr;
switch (command_cmd) {
case ESCAPE:
case ' ':
msg_print(_("ウィザードモード突入。", "Wizard mode on."));
}
- player_ptr->update |= (PU_MONSTERS);
+ auto &rfu = RedrawingFlagsUpdater::get_instance();
+ rfu.set_flag(StatusRedrawingFlag::MONSTER_STATUSES);
player_ptr->redraw |= (PR_TITLE);
break;
}
break;
}
case 'w': {
- if (!player_ptr->wild_mode)
+ if (!player_ptr->wild_mode) {
do_cmd_wield(player_ptr);
+ }
break;
}
case 't': {
- if (!player_ptr->wild_mode)
+ if (!player_ptr->wild_mode) {
do_cmd_takeoff(player_ptr);
+ }
break;
}
case 'd': {
- if (!player_ptr->wild_mode)
+ if (!player_ptr->wild_mode) {
do_cmd_drop(player_ptr);
+ }
break;
}
break;
}
case '+': {
- if (!player_ptr->wild_mode)
+ if (!player_ptr->wild_mode) {
do_cmd_alter(player_ptr);
+ }
break;
}
case 'T': {
- if (!player_ptr->wild_mode)
+ if (!player_ptr->wild_mode) {
do_cmd_tunnel(player_ptr);
+ }
break;
}
break;
}
case '.': {
- if (!player_ptr->wild_mode)
+ if (!player_ptr->wild_mode) {
do_cmd_run(player_ptr);
+ }
break;
}
break;
}
case 'S': {
- if (player_ptr->action == ACTION_SEARCH)
+ if (player_ptr->action == ACTION_SEARCH) {
set_action(player_ptr, ACTION_NONE);
- else
+ } else {
set_action(player_ptr, ACTION_SEARCH);
+ }
break;
}
break;
}
case '<': {
- if (!player_ptr->wild_mode && !floor_ptr->dun_level && !floor_ptr->inside_arena && !floor_ptr->inside_quest) {
- if (vanilla_town)
+ if (!player_ptr->wild_mode && !floor_ptr->dun_level && !floor_ptr->inside_arena && !inside_quest(floor_ptr->quest_number)) {
+ if (vanilla_town) {
break;
+ }
if (player_ptr->ambush_flag) {
msg_print(_("襲撃から逃げるにはマップの端まで移動しなければならない。", "To flee the ambush you have to reach the edge of the map."));
}
change_wild_mode(player_ptr, false);
- } else
+ } else {
do_cmd_go_up(player_ptr);
+ }
break;
}
case '>': {
- if (player_ptr->wild_mode)
+ if (player_ptr->wild_mode) {
change_wild_mode(player_ptr, false);
- else
+ } else {
do_cmd_go_down(player_ptr);
+ }
break;
}
break;
}
case 'G': {
- if (player_ptr->pclass == CLASS_SORCERER || player_ptr->pclass == CLASS_RED_MAGE || player_ptr->pclass == CLASS_ELEMENTALIST)
+ PlayerClass pc(player_ptr);
+ if (pc.is_every_magic() || pc.equals(PlayerClassType::ELEMENTALIST)) {
msg_print(_("呪文を学習する必要はない!", "You don't have to learn spells!"));
- else if (player_ptr->pclass == CLASS_SAMURAI)
+ } else if (pc.equals(PlayerClassType::SAMURAI)) {
do_cmd_gain_hissatsu(player_ptr);
- else if (player_ptr->pclass == CLASS_MAGIC_EATER)
+ } else if (pc.equals(PlayerClassType::MAGIC_EATER)) {
import_magic_device(player_ptr);
- else
+ } else {
do_cmd_study(player_ptr);
+ }
break;
}
case 'b': {
- if ((player_ptr->pclass == CLASS_MINDCRAFTER) || (player_ptr->pclass == CLASS_BERSERKER) || (player_ptr->pclass == CLASS_NINJA)
- || (player_ptr->pclass == CLASS_MIRROR_MASTER))
+ PlayerClass pc(player_ptr);
+ if (pc.can_browse()) {
do_cmd_mind_browse(player_ptr);
- else if (player_ptr->pclass == CLASS_ELEMENTALIST)
+ } else if (pc.equals(PlayerClassType::ELEMENTALIST)) {
do_cmd_element_browse(player_ptr);
- else if (player_ptr->pclass == CLASS_SMITH)
+ } else if (pc.equals(PlayerClassType::SMITH)) {
do_cmd_kaji(player_ptr, true);
- else if (player_ptr->pclass == CLASS_MAGIC_EATER)
+ } else if (pc.equals(PlayerClassType::MAGIC_EATER)) {
do_cmd_magic_eater(player_ptr, true, false);
- else if (player_ptr->pclass == CLASS_SNIPER)
+ } else if (pc.equals(PlayerClassType::SNIPER)) {
do_cmd_snipe_browse(player_ptr);
- else
+ } else {
do_cmd_browse(player_ptr);
+ }
break;
}
break;
}
- if ((player_ptr->pclass == CLASS_WARRIOR) || (player_ptr->pclass == CLASS_ARCHER) || (player_ptr->pclass == CLASS_CAVALRY)) {
+ PlayerClass pc(player_ptr);
+ if (pc.equals(PlayerClassType::WARRIOR) || pc.equals(PlayerClassType::ARCHER) || pc.equals(PlayerClassType::CAVALRY)) {
msg_print(_("呪文を唱えられない!", "You cannot cast spells!"));
break;
}
- if (floor_ptr->dun_level && d_info[player_ptr->dungeon_idx].flags.has(DF::NO_MAGIC) && (player_ptr->pclass != CLASS_BERSERKER)
- && (player_ptr->pclass != CLASS_SMITH)) {
+ const auto &dungeon = dungeons_info[player_ptr->dungeon_idx];
+ auto non_magic_class = pc.equals(PlayerClassType::BERSERKER);
+ non_magic_class |= pc.equals(PlayerClassType::SMITH);
+ if (floor_ptr->dun_level && dungeon.flags.has(DungeonFeatureType::NO_MAGIC) && !non_magic_class) {
msg_print(_("ダンジョンが魔法を吸収した!", "The dungeon absorbs all attempted magic!"));
msg_print(nullptr);
break;
}
- if (player_ptr->anti_magic && (player_ptr->pclass != CLASS_BERSERKER) && (player_ptr->pclass != CLASS_SMITH)) {
+ if (player_ptr->anti_magic && !non_magic_class) {
concptr which_power = _("魔法", "magic");
switch (player_ptr->pclass) {
- case CLASS_MINDCRAFTER:
+ case PlayerClassType::MINDCRAFTER:
which_power = _("超能力", "psionic powers");
break;
- case CLASS_IMITATOR:
+ case PlayerClassType::IMITATOR:
which_power = _("ものまね", "imitation");
break;
- case CLASS_SAMURAI:
+ case PlayerClassType::SAMURAI:
which_power = _("必殺剣", "hissatsu");
break;
- case CLASS_MIRROR_MASTER:
+ case PlayerClassType::MIRROR_MASTER:
which_power = _("鏡魔法", "mirror magic");
break;
- case CLASS_NINJA:
+ case PlayerClassType::NINJA:
which_power = _("忍術", "ninjutsu");
break;
- case CLASS_ELEMENTALIST:
+ case PlayerClassType::ELEMENTALIST:
which_power = _("元素魔法", "magic");
break;
default:
- if (mp_ptr->spell_book == TV_LIFE_BOOK)
+ if (mp_ptr->spell_book == ItemKindType::LIFE_BOOK) {
which_power = _("祈り", "prayer");
+ }
break;
}
break;
}
- if (is_shero(player_ptr) && (player_ptr->pclass != CLASS_BERSERKER)) {
+ if (is_shero(player_ptr) && !pc.equals(PlayerClassType::BERSERKER)) {
msg_format(_("狂戦士化していて頭が回らない!", "You cannot think directly!"));
PlayerEnergy(player_ptr).reset_player_turn();
break;
}
- if ((player_ptr->pclass == CLASS_MINDCRAFTER) || (player_ptr->pclass == CLASS_BERSERKER) || (player_ptr->pclass == CLASS_NINJA)
- || (player_ptr->pclass == CLASS_MIRROR_MASTER))
+ if (pc.can_browse()) {
do_cmd_mind(player_ptr);
- else if (player_ptr->pclass == CLASS_ELEMENTALIST)
+ } else if (pc.equals(PlayerClassType::ELEMENTALIST)) {
do_cmd_element(player_ptr);
- else if (player_ptr->pclass == CLASS_IMITATOR)
+ } else if (pc.equals(PlayerClassType::IMITATOR)) {
do_cmd_mane(player_ptr, false);
- else if (player_ptr->pclass == CLASS_MAGIC_EATER)
+ } else if (pc.equals(PlayerClassType::MAGIC_EATER)) {
do_cmd_magic_eater(player_ptr, false, false);
- else if (player_ptr->pclass == CLASS_SAMURAI)
+ } else if (pc.equals(PlayerClassType::SAMURAI)) {
do_cmd_hissatsu(player_ptr);
- else if (player_ptr->pclass == CLASS_BLUE_MAGE)
+ } else if (pc.equals(PlayerClassType::BLUE_MAGE)) {
do_cmd_cast_learned(player_ptr);
- else if (player_ptr->pclass == CLASS_SMITH)
+ } else if (pc.equals(PlayerClassType::SMITH)) {
do_cmd_kaji(player_ptr, false);
- else if (player_ptr->pclass == CLASS_SNIPER)
+ } else if (pc.equals(PlayerClassType::SNIPER)) {
do_cmd_snipe(player_ptr);
- else
+ } else {
(void)do_cmd_cast(player_ptr);
+ }
break;
}
break;
}
case 'u': {
- if (use_command && !rogue_like_commands)
+ if (use_command && !rogue_like_commands) {
do_cmd_use(player_ptr);
- else
+ } else {
do_cmd_use_staff(player_ptr);
+ }
break;
}
}
case '=': {
do_cmd_options(player_ptr);
- (void)combine_and_reorder_home(player_ptr, STORE_HOME);
+ (void)combine_and_reorder_home(player_ptr, StoreSaleType::HOME);
do_cmd_redraw(player_ptr);
break;
}
break;
}
case '`': {
- if (!player_ptr->wild_mode)
+ if (!player_ptr->wild_mode) {
do_cmd_travel(player_ptr);
- if (player_ptr->special_defense & KATA_MUSOU) {
- set_action(player_ptr, ACTION_NONE);
}
+ PlayerClass(player_ptr).break_samurai_stance({ SamuraiStanceType::MUSOU });
break;
}
default: {
- if (flush_failure)
+ if (flush_failure) {
flush();
+ }
if (one_in_(2)) {
- char error_m[1024];
sound(SOUND_ILLEGAL);
- if (!get_rnd_line(_("error_j.txt", "error.txt"), 0, error_m))
- msg_print(error_m);
+ const auto error_mes = get_random_line(_("error_j.txt", "error.txt"), 0);
+ if (error_mes.has_value()) {
+ msg_print(error_mes.value());
+ }
} else {
prt(_(" '?' でヘルプが表示されます。", "Type '?' for help."), 0, 0);
}
}
}
- if (!player_ptr->energy_use && !now_message)
+ if (!player_ptr->energy_use && !now_message) {
now_message = old_now_message;
+ }
}