OSDN Git Service

[Refactor] #3286 Removed player-redraw-types.h
[hengbandforosx/hengbandosx.git] / src / cmd-item / cmd-equipment.cpp
index 3fdd31f..7dcd17a 100644 (file)
@@ -4,8 +4,6 @@
 #include "autopick/autopick.h"
 #include "avatar/avatar.h"
 #include "core/asking-player.h"
-#include "core/player-redraw-types.h"
-#include "core/player-update-types.h"
 #include "core/window-redrawer.h"
 #include "dungeon/quest.h" //!< @todo 違和感、何故アイテムを装備するとクエストの成功判定が走るのか?.
 #include "flavor/flavor-describer.h"
 #include "spell-kind/spells-perception.h"
 #include "status/action-setter.h"
 #include "status/shape-changer.h"
-#include "system/object-type-definition.h"
+#include "system/item-entity.h"
 #include "system/player-type-definition.h"
+#include "system/redrawing-flags-updater.h"
 #include "term/screen-processor.h"
+#include "term/z-form.h"
+#include "util/bit-flags-calculator.h"
 #include "util/int-char-converter.h"
 #include "view/display-inventory.h"
 #include "view/display-messages.h"
 /*!
  * @brief 装備時にアイテムを呪う処理
  */
-static void do_curse_on_equip(OBJECT_IDX slot, ObjectType *o_ptr, PlayerType *player_ptr)
+static void do_curse_on_equip(OBJECT_IDX slot, ItemEntity *o_ptr, PlayerType *player_ptr)
 {
+    auto &rfu = RedrawingFlagsUpdater::get_instance();
     if (set_anubis_and_chariot(player_ptr) && ((slot == INVEN_MAIN_HAND) || (slot == INVEN_SUB_HAND))) {
 
-        ObjectType *anubis = &(player_ptr->inventory_list[INVEN_MAIN_HAND]);
-        ObjectType *chariot = &(player_ptr->inventory_list[INVEN_SUB_HAND]);
+        ItemEntity *anubis = &(player_ptr->inventory_list[INVEN_MAIN_HAND]);
+        ItemEntity *chariot = &(player_ptr->inventory_list[INVEN_SUB_HAND]);
 
         anubis->curse_flags.set(CurseTraitType::PERSISTENT_CURSE);
         anubis->curse_flags.set(CurseTraitType::HEAVY_CURSE);
@@ -68,22 +70,23 @@ static void do_curse_on_equip(OBJECT_IDX slot, ObjectType *o_ptr, PlayerType *pl
         chariot->curse_flags.set(CurseTraitType::HEAVY_CURSE);
         chariot->curse_flags.set(CurseTraitType::BERS_RAGE);
         chariot->curse_flags.set(CurseTraitType::VUL_CURSE);
-        
+
         msg_format(_("『銀の戦車』プラス『アヌビス神』二刀流ッ!", "*Silver Chariot* plus *Anubis God* Two Swords!"));
-        player_ptr->update |= (PU_BONUS);
+        rfu.set_flag(StatusRedrawingFlag::BONUS);
         return;
     }
 
-    if ((object_flags(o_ptr).has(TR_PERSISTENT_CURSE) || o_ptr->curse_flags.has(CurseTraitType::PERSISTENT_CURSE)) 
-        && o_ptr->curse_flags.has_not(CurseTraitType::HEAVY_CURSE)) {
-
-        GAME_TEXT o_name[MAX_NLEN];
-        describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
-        o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
-        msg_format(_("悪意に満ちた黒いオーラが%sをとりまいた...", "There is a malignant black aura surrounding your %s..."), o_name);
-        o_ptr->feeling = FEEL_NONE;
-        player_ptr->update |= (PU_BONUS);
+    auto should_curse = object_flags(o_ptr).has(TR_PERSISTENT_CURSE) || o_ptr->curse_flags.has(CurseTraitType::PERSISTENT_CURSE);
+    should_curse &= o_ptr->curse_flags.has_not(CurseTraitType::HEAVY_CURSE);
+    if (!should_curse) {
+        return;
     }
+
+    const auto item_name = describe_flavor(player_ptr, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
+    o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
+    msg_format(_("悪意に満ちた黒いオーラが%sをとりまいた...", "There is a malignant black aura surrounding your %s..."), item_name.data());
+    o_ptr->feeling = FEEL_NONE;
+    rfu.set_flag(StatusRedrawingFlag::BONUS);
 }
 
 /*!
@@ -91,19 +94,20 @@ static void do_curse_on_equip(OBJECT_IDX slot, ObjectType *o_ptr, PlayerType *pl
  */
 void do_cmd_equip(PlayerType *player_ptr)
 {
-    char out_val[160];
     command_wrk = true;
-    if (easy_floor)
+    if (easy_floor) {
         command_wrk = USE_EQUIP;
+    }
 
     screen_save();
     (void)show_equipment(player_ptr, 0, USE_FULL, AllMatchItemTester());
     auto weight = calc_inventory_weight(player_ptr);
     auto weight_lim = calc_weight_limit(player_ptr);
+    const auto mes = _("装備: 合計 %3d.%1d kg (限界の%d%%) コマンド: ", "Equipment: carrying %d.%d pounds (%d%% of capacity). Command: ");
 #ifdef JP
-    sprintf(out_val, "装備: 合計 %3d.%1d kg (限界の%d%%) コマンド: ", lb_to_kg_integer(weight), lb_to_kg_fraction(weight), weight * 100 / weight_lim);
+    const auto out_val = format(mes, lb_to_kg_integer(weight), lb_to_kg_fraction(weight), weight * 100 / weight_lim);
 #else
-    sprintf(out_val, "Equipment: carrying %d.%d pounds (%d%% of capacity). Command: ", weight / 10, weight % 10, weight * 100 / weight_lim);
+    const auto out_val = format(mes, weight / 10, weight % 10, weight * 100 / weight_lim);
 #endif
 
     prt(out_val, 0, 0);
@@ -128,45 +132,48 @@ void do_cmd_equip(PlayerType *player_ptr)
 void do_cmd_wield(PlayerType *player_ptr)
 {
     OBJECT_IDX item, slot;
-    ObjectType forge;
-    ObjectType *q_ptr;
-    ObjectType *o_ptr;
+    ItemEntity forge;
+    ItemEntity *q_ptr;
+    ItemEntity *o_ptr;
     concptr act;
-    GAME_TEXT o_name[MAX_NLEN];
     OBJECT_IDX need_switch_wielding = 0;
     PlayerClass(player_ptr).break_samurai_stance({ SamuraiStanceType::MUSOU });
 
     concptr q = _("どれを装備しますか? ", "Wear/Wield which item? ");
     concptr s = _("装備可能なアイテムがない。", "You have nothing you can wear or wield.");
     o_ptr = choose_object(player_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), FuncItemTester(item_tester_hook_wear, player_ptr));
-    if (!o_ptr)
+    if (!o_ptr) {
         return;
+    }
 
     slot = wield_slot(player_ptr, o_ptr);
 
     const auto o_ptr_mh = &player_ptr->inventory_list[INVEN_MAIN_HAND];
     const auto o_ptr_sh = &player_ptr->inventory_list[INVEN_SUB_HAND];
-
-    switch (o_ptr->tval) {
+    const auto tval = o_ptr->bi_key.tval();
+    switch (tval) {
     case ItemKindType::CAPTURE:
     case ItemKindType::SHIELD:
     case ItemKindType::CARD:
         if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND) && has_melee_weapon(player_ptr, INVEN_SUB_HAND)) {
             q = _("どちらの武器と取り替えますか?", "Replace which weapon? ");
             s = _("おっと。", "Oops.");
-            if (!choose_object(player_ptr, &slot, q, s, (USE_EQUIP | IGNORE_BOTHHAND_SLOT), FuncItemTester(&ObjectType::is_melee_weapon)))
+            if (!choose_object(player_ptr, &slot, q, s, (USE_EQUIP | IGNORE_BOTHHAND_SLOT), FuncItemTester(&ItemEntity::is_melee_weapon))) {
                 return;
+            }
 
-            if (slot == INVEN_MAIN_HAND)
+            if (slot == INVEN_MAIN_HAND) {
                 need_switch_wielding = INVEN_SUB_HAND;
-        } else if (has_melee_weapon(player_ptr, INVEN_SUB_HAND))
+            }
+        } else if (has_melee_weapon(player_ptr, INVEN_SUB_HAND)) {
             slot = INVEN_MAIN_HAND;
-        else if (o_ptr_mh->k_idx && o_ptr_sh->k_idx &&
-                 ((o_ptr->tval == ItemKindType::CAPTURE) || (!o_ptr_mh->is_melee_weapon() && !o_ptr_sh->is_melee_weapon()))) {
+        } else if (o_ptr_mh->is_valid() && o_ptr_sh->is_valid() &&
+                   ((tval == ItemKindType::CAPTURE) || (!o_ptr_mh->is_melee_weapon() && !o_ptr_sh->is_melee_weapon()))) {
             q = _("どちらの手に装備しますか?", "Equip which hand? ");
             s = _("おっと。", "Oops.");
-            if (!choose_object(player_ptr, &slot, q, s, (USE_EQUIP), FuncItemTester(&ObjectType::is_wieldable_in_etheir_hand)))
+            if (!choose_object(player_ptr, &slot, q, s, (USE_EQUIP), FuncItemTester(&ItemEntity::is_wieldable_in_etheir_hand))) {
                 return;
+            }
         }
 
         break;
@@ -175,27 +182,32 @@ void do_cmd_wield(PlayerType *player_ptr)
     case ItemKindType::POLEARM:
     case ItemKindType::SWORD:
         if (slot == INVEN_SUB_HAND) {
-            if (!get_check(_("二刀流で戦いますか?", "Dual wielding? ")))
+            if (!get_check(_("二刀流で戦いますか?", "Dual wielding? "))) {
                 slot = INVEN_MAIN_HAND;
-        } else if (!o_ptr_mh->k_idx && has_melee_weapon(player_ptr, INVEN_SUB_HAND)) {
-            if (!get_check(_("二刀流で戦いますか?", "Dual wielding? ")))
+            }
+        } else if (!o_ptr_mh->is_valid() && has_melee_weapon(player_ptr, INVEN_SUB_HAND)) {
+            if (!get_check(_("二刀流で戦いますか?", "Dual wielding? "))) {
                 slot = INVEN_SUB_HAND;
-        } else if (o_ptr_mh->k_idx && o_ptr_sh->k_idx) {
+            }
+        } else if (o_ptr_mh->is_valid() && o_ptr_sh->is_valid()) {
             q = _("どちらの手に装備しますか?", "Equip which hand? ");
             s = _("おっと。", "Oops.");
-            if (!choose_object(player_ptr, &slot, q, s, (USE_EQUIP), FuncItemTester(&ObjectType::is_wieldable_in_etheir_hand)))
+            if (!choose_object(player_ptr, &slot, q, s, (USE_EQUIP), FuncItemTester(&ItemEntity::is_wieldable_in_etheir_hand))) {
                 return;
+            }
 
-            if ((slot == INVEN_SUB_HAND) && !has_melee_weapon(player_ptr, INVEN_MAIN_HAND))
+            if ((slot == INVEN_SUB_HAND) && !has_melee_weapon(player_ptr, INVEN_MAIN_HAND)) {
                 need_switch_wielding = INVEN_MAIN_HAND;
+            }
         }
 
         break;
     case ItemKindType::RING:
-        if (player_ptr->inventory_list[INVEN_SUB_RING].k_idx && player_ptr->inventory_list[INVEN_MAIN_RING].k_idx)
+        if (player_ptr->inventory_list[INVEN_SUB_RING].is_valid() && player_ptr->inventory_list[INVEN_MAIN_RING].is_valid()) {
             q = _("どちらの指輪と取り替えますか?", "Replace which ring? ");
-        else
+        } else {
             q = _("どちらの手に装備しますか?", "Equip which hand? ");
+        }
 
         s = _("おっと。", "Oops.");
         player_ptr->select_ring_slot = true;
@@ -212,48 +224,50 @@ void do_cmd_wield(PlayerType *player_ptr)
     }
 
     if (player_ptr->inventory_list[slot].is_cursed()) {
-        describe_flavor(player_ptr, o_name, &player_ptr->inventory_list[slot], OD_OMIT_PREFIX | OD_NAME_ONLY);
+        const auto item_name = describe_flavor(player_ptr, &player_ptr->inventory_list[slot], OD_OMIT_PREFIX | OD_NAME_ONLY);
 #ifdef JP
-        msg_format("%s%sは呪われているようだ。", describe_use(player_ptr, slot), o_name);
+        msg_format("%s%sは呪われているようだ。", describe_use(player_ptr, slot), item_name.data());
 #else
-        msg_format("The %s you are %s appears to be cursed.", o_name, describe_use(player_ptr, slot));
+        msg_format("The %s you are %s appears to be cursed.", item_name.data(), describe_use(player_ptr, slot));
 #endif
         return;
     }
 
-    if (confirm_wear && ((o_ptr->is_cursed() && o_ptr->is_known()) || ((o_ptr->ident & IDENT_SENSE) && (FEEL_BROKEN <= o_ptr->feeling) && (o_ptr->feeling <= FEEL_CURSED)))) {
-        char dummy[MAX_NLEN + 80];
-        describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
-        sprintf(dummy, _("本当に%s{呪われている}を使いますか?", "Really use the %s {cursed}? "), o_name);
-
-        if (!get_check(dummy))
+    auto should_equip_cursed = o_ptr->is_cursed() && o_ptr->is_known();
+    should_equip_cursed |= any_bits(o_ptr->ident, IDENT_SENSE) && (FEEL_BROKEN <= o_ptr->feeling) && (o_ptr->feeling <= FEEL_CURSED);
+    should_equip_cursed &= confirm_wear;
+    if (should_equip_cursed) {
+        const auto item_name = describe_flavor(player_ptr, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
+        if (!get_check(format(_("本当に%s{呪われている}を使いますか?", "Really use the %s {cursed}? "), item_name.data()))) {
             return;
+        }
     }
 
     PlayerRace pr(player_ptr);
-    if ((o_ptr->name1 == ART_STONEMASK) && o_ptr->is_known() && !pr.equals(PlayerRaceType::VAMPIRE) && !pr.equals(PlayerRaceType::ANDROID)) {
-        char dummy[MAX_NLEN + 100];
-        describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
-        sprintf(dummy,
-            _("%sを装備すると吸血鬼になります。よろしいですか?", "%s will transform you into a vampire permanently when equipped. Do you become a vampire? "),
-            o_name);
-
-        if (!get_check(dummy))
+    auto should_change_vampire = o_ptr->is_specific_artifact(FixedArtifactId::STONEMASK);
+    should_change_vampire &= o_ptr->is_known();
+    should_change_vampire &= !pr.equals(PlayerRaceType::VAMPIRE);
+    should_change_vampire &= !pr.equals(PlayerRaceType::ANDROID);
+    if (should_change_vampire) {
+        const auto item_name = describe_flavor(player_ptr, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
+        constexpr auto mes = _("%sを装備すると吸血鬼になります。よろしいですか?",
+            "%s will transform you into a vampire permanently when equipped. Do you become a vampire? ");
+        if (!get_check(format(mes, item_name.data()))) {
             return;
+        }
     }
 
     sound(SOUND_WIELD);
     if (need_switch_wielding && !player_ptr->inventory_list[need_switch_wielding].is_cursed()) {
-        ObjectType *slot_o_ptr = &player_ptr->inventory_list[slot];
-        ObjectType *switch_o_ptr = &player_ptr->inventory_list[need_switch_wielding];
-        ObjectType object_tmp;
-        ObjectType *otmp_ptr = &object_tmp;
-        GAME_TEXT switch_name[MAX_NLEN];
-        describe_flavor(player_ptr, switch_name, switch_o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
+        ItemEntity *slot_o_ptr = &player_ptr->inventory_list[slot];
+        ItemEntity *switch_o_ptr = &player_ptr->inventory_list[need_switch_wielding];
+        ItemEntity object_tmp;
+        ItemEntity *otmp_ptr = &object_tmp;
+        const auto item_name = describe_flavor(player_ptr, switch_o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
         otmp_ptr->copy_from(switch_o_ptr);
         switch_o_ptr->copy_from(slot_o_ptr);
         slot_o_ptr->copy_from(otmp_ptr);
-        msg_format(_("%sを%sに構えなおした。", "You wield %s at %s hand."), switch_name,
+        msg_format(_("%sを%sに構えなおした。", "You wield %s at %s hand."), item_name.data(),
             (slot == INVEN_MAIN_HAND) ? (left_hander ? _("左手", "left") : _("右手", "right")) : (left_hander ? _("右手", "right") : _("左手", "left")));
         slot = need_switch_wielding;
     }
@@ -277,11 +291,12 @@ void do_cmd_wield(PlayerType *player_ptr)
     }
 
     o_ptr = &player_ptr->inventory_list[slot];
-    if (o_ptr->k_idx)
+    if (o_ptr->is_valid()) {
         (void)inven_takeoff(player_ptr, slot, 255);
+    }
 
     o_ptr->copy_from(q_ptr);
-    o_ptr->marked |= OM_TOUCHED;
+    o_ptr->marked.set(OmType::TOUCHED);
     player_ptr->equip_cnt++;
 
 #define STR_WIELD_HAND_RIGHT _("%s(%c)を右手に装備した。", "You are wielding %s (%c) in your right hand.")
@@ -290,17 +305,19 @@ void do_cmd_wield(PlayerType *player_ptr)
 
     switch (slot) {
     case INVEN_MAIN_HAND:
-        if (o_ptr->allow_two_hands_wielding() && (empty_hands(player_ptr, false) == EMPTY_HAND_SUB) && can_two_hands_wielding(player_ptr))
+        if (o_ptr->allow_two_hands_wielding() && (empty_hands(player_ptr, false) == EMPTY_HAND_SUB) && can_two_hands_wielding(player_ptr)) {
             act = STR_WIELD_HANDS_TWO;
-        else
+        } else {
             act = (left_hander ? STR_WIELD_HAND_LEFT : STR_WIELD_HAND_RIGHT);
+        }
 
         break;
     case INVEN_SUB_HAND:
-        if (o_ptr->allow_two_hands_wielding() && (empty_hands(player_ptr, false) == EMPTY_HAND_MAIN) && can_two_hands_wielding(player_ptr))
+        if (o_ptr->allow_two_hands_wielding() && (empty_hands(player_ptr, false) == EMPTY_HAND_MAIN) && can_two_hands_wielding(player_ptr)) {
             act = STR_WIELD_HANDS_TWO;
-        else
+        } else {
             act = (left_hander ? STR_WIELD_HAND_RIGHT : STR_WIELD_HAND_LEFT);
+        }
 
         break;
     case INVEN_BOW:
@@ -314,23 +331,33 @@ void do_cmd_wield(PlayerType *player_ptr)
         break;
     }
 
-    describe_flavor(player_ptr, o_name, o_ptr, 0);
-    msg_format(act, o_name, index_to_label(slot));
+    const auto item_name = describe_flavor(player_ptr, o_ptr, 0);
+    msg_format(act, item_name.data(), index_to_label(slot));
     if (o_ptr->is_cursed()) {
         msg_print(_("うわ! すさまじく冷たい!", "Oops! It feels deathly cold!"));
-        chg_virtue(player_ptr, V_HARMONY, -1);
+        chg_virtue(player_ptr, Virtue::HARMONY, -1);
         o_ptr->ident |= (IDENT_SENSE);
     }
 
     do_curse_on_equip(slot, o_ptr, player_ptr);
-
-    if ((o_ptr->name1 == ART_STONEMASK) && !pr.equals(PlayerRaceType::VAMPIRE) && !pr.equals(PlayerRaceType::ANDROID))
-        change_race(player_ptr, PlayerRaceType::VAMPIRE, "");
+    if (o_ptr->is_specific_artifact(FixedArtifactId::STONEMASK)) {
+        auto is_specific_race = pr.equals(PlayerRaceType::VAMPIRE);
+        is_specific_race |= pr.equals(PlayerRaceType::ANDROID);
+        if (!is_specific_race) {
+            change_race(player_ptr, PlayerRaceType::VAMPIRE, "");
+        }
+    }
 
     calc_android_exp(player_ptr);
-    player_ptr->update |= PU_BONUS | PU_TORCH | PU_MANA;
-    player_ptr->redraw |= PR_EQUIPPY;
-    player_ptr->window_flags |= PW_INVEN | PW_EQUIP | PW_PLAYER;
+    const auto flags_srf = {
+        StatusRedrawingFlag::BONUS,
+        StatusRedrawingFlag::TORCH,
+        StatusRedrawingFlag::MP,
+    };
+    auto &rfu = RedrawingFlagsUpdater::get_instance();
+    rfu.set_flags(flags_srf);
+    rfu.set_flag(MainWindowRedrawingFlag::EQUIPPY);
+    player_ptr->window_flags |= PW_INVENTORY | PW_EQUIPMENT | PW_PLAYER;
 }
 
 /*!
@@ -339,17 +366,19 @@ void do_cmd_wield(PlayerType *player_ptr)
 void do_cmd_takeoff(PlayerType *player_ptr)
 {
     OBJECT_IDX item;
-    ObjectType *o_ptr;
+    ItemEntity *o_ptr;
     PlayerClass pc(player_ptr);
     pc.break_samurai_stance({ SamuraiStanceType::MUSOU });
 
     concptr q = _("どれを装備からはずしますか? ", "Take off which item? ");
     concptr s = _("はずせる装備がない。", "You are not wearing anything to take off.");
     o_ptr = choose_object(player_ptr, &item, q, s, (USE_EQUIP | IGNORE_BOTHHAND_SLOT));
-    if (!o_ptr)
+    if (!o_ptr) {
         return;
+    }
 
     PlayerEnergy energy(player_ptr);
+    auto &rfu = RedrawingFlagsUpdater::get_instance();
     if (o_ptr->is_cursed()) {
         if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE) || !pc.equals(PlayerClassType::BERSERKER)) {
             msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed."));
@@ -361,8 +390,8 @@ void do_cmd_takeoff(PlayerType *player_ptr)
             o_ptr->ident |= (IDENT_SENSE);
             o_ptr->curse_flags.clear();
             o_ptr->feeling = FEEL_NONE;
-            player_ptr->update |= PU_BONUS;
-            player_ptr->window_flags |= PW_EQUIP;
+            rfu.set_flag(StatusRedrawingFlag::BONUS);
+            player_ptr->window_flags |= PW_EQUIPMENT;
             msg_print(_("呪いを打ち破った。", "You break the curse."));
         } else {
             msg_print(_("装備を外せなかった。", "You couldn't remove the equipment."));
@@ -376,7 +405,12 @@ void do_cmd_takeoff(PlayerType *player_ptr)
     (void)inven_takeoff(player_ptr, item, 255);
     verify_equip_slot(player_ptr, item);
     calc_android_exp(player_ptr);
-    player_ptr->update |= PU_BONUS | PU_TORCH | PU_MANA;
-    player_ptr->redraw |= PR_EQUIPPY;
-    player_ptr->window_flags |= PW_INVEN | PW_EQUIP | PW_PLAYER;
+    const auto flags_srf = {
+        StatusRedrawingFlag::BONUS,
+        StatusRedrawingFlag::TORCH,
+        StatusRedrawingFlag::MP,
+    };
+    rfu.set_flags(flags_srf);
+    rfu.set_flag(MainWindowRedrawingFlag::EQUIPPY);
+    player_ptr->window_flags |= PW_INVENTORY | PW_EQUIPMENT | PW_PLAYER;
 }