OSDN Git Service

[Fix] #1473 呪術の詠唱停止時に配列外アクセスが発生する事象を修正した / Resolved the issue that out-of-order acces...
authorHourier <66951241+Hourier@users.noreply.github.com>
Tue, 14 Sep 2021 13:34:37 +0000 (22:34 +0900)
committerHourier <66951241+Hourier@users.noreply.github.com>
Tue, 14 Sep 2021 14:13:49 +0000 (23:13 +0900)
src/cmd-action/cmd-spell.cpp
src/racial/racial-switcher.cpp
src/spell-realm/spells-hex.cpp
src/spell-realm/spells-hex.h
src/status/action-setter.cpp

index 8924272..6e4ea0b 100644 (file)
@@ -1020,7 +1020,7 @@ bool do_cmd_cast(player_type *player_ptr)
             msg_print(_("これ以上新しい呪文を詠唱することはできない。", "Can not cast more spells."));
             flush();
             if (player_ptr->lev >= 35) {
-                flag = SpellHex(player_ptr).stop_one_spell();
+                flag = SpellHex(player_ptr).stop_spells_with_selection();
             }
 
             if (!flag) {
index 15b3d85..4895260 100644 (file)
@@ -92,7 +92,7 @@ bool switch_class_racial_execution(player_type *player_ptr, const int32_t comman
         return sword_dancing(player_ptr);
     case CLASS_HIGH_MAGE:
         if (player_ptr->realm1 == REALM_HEX) {
-            auto retval = SpellHex(player_ptr).stop_one_spell();
+            auto retval = SpellHex(player_ptr).stop_spells_with_selection();
             if (retval) {
                 PlayerEnergy(player_ptr).set_player_turn_energy(10);
             }
index e552518..3bd51d7 100644 (file)
@@ -60,7 +60,7 @@ SpellHex::SpellHex(player_type *player_ptr, monap_type *monap_ptr)
 /*!
  * @brief プレイヤーが詠唱中の全呪術を停止する
  */
-bool SpellHex::stop_all_spells()
+void SpellHex::stop_all_spells()
 {
     for (auto spell : this->casting_spells) {
         exe_spell(this->player_ptr, REALM_HEX, spell, SPELL_STOP);
@@ -74,13 +74,13 @@ bool SpellHex::stop_all_spells()
 
     this->player_ptr->update |= PU_BONUS | PU_HP | PU_MANA | PU_SPELLS;
     this->player_ptr->redraw |= PR_EXTRA | PR_HP | PR_MANA;
-    return true;
 }
 
 /*!
- * @brief プレイヤーが詠唱中の呪術から一つを選んで停止する
+ * @brief プレイヤーが詠唱中の呪術から選択式で一つまたは全てを停止する
+ * @return 停止したらtrue、停止をキャンセルしたらfalse
  */
-bool SpellHex::stop_one_spell()
+bool SpellHex::stop_spells_with_selection()
 {
     if (!this->is_spelling_any()) {
         msg_print(_("呪文を詠唱していません。", "You are not casting a spell."));
@@ -89,7 +89,8 @@ bool SpellHex::stop_one_spell()
 
     auto casting_num = this->player_ptr->magic_num2[0];
     if ((casting_num == 1) || (this->player_ptr->lev < 35)) {
-        return this->stop_all_spells();
+        this->stop_all_spells();
+        return true;
     }
 
     char out_val[160];
@@ -97,7 +98,11 @@ bool SpellHex::stop_one_spell()
         I2A(0), I2A(casting_num - 1));
     screen_save();
     char choice = 0;
-    auto is_selected = select_spell_stopping(out_val, choice);
+    auto [is_all, is_selected] = select_spell_stopping(out_val, choice);
+    if (is_all) {
+        return true;
+    }
+
     screen_load();
     if (is_selected) {
         auto n = this->casting_spells[A2I(choice)];
@@ -116,31 +121,33 @@ bool SpellHex::stop_one_spell()
  * @param spells 詠唱中の呪術リスト
  * @param out_val 呪文名
  * @param choice 選択した呪文
- * @return 選択が完了したらtrue、キャンセルならばfalse
+ * @return
+ * Item1: 全ての呪文を中断するならばtrue、1つの呪文を中断するならばfalse
+ * Item2: 選択が完了したらtrue、キャンセルならばfalse
  */
-bool SpellHex::select_spell_stopping(char *out_val, char &choice)
+std::tuple<bool, bool> SpellHex::select_spell_stopping(char *out_val, char &choice)
 {
     while (true) {
         this->display_casting_spells_list();
         if (!get_com(out_val, &choice, true)) {
-            return false;
+            return std::make_tuple(false, false);
         }
 
         if (isupper(choice)) {
             choice = static_cast<char>(tolower(choice));
         }
 
-        /* All */
         if (choice == 'l') {
             screen_load();
-            return this->stop_all_spells();
+            this->stop_all_spells();
+            return std::make_tuple(true, true);
         }
 
         if ((choice < I2A(0)) || (choice > I2A(this->player_ptr->magic_num2[0] - 1))) {
             continue;
         }
 
-        return true;
+        return std::make_tuple(false, true);
     }
 }
 
index 6d4102a..97c3588 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "system/angband.h"
 #include "realm/realm-hex-numbers.h"
+#include <tuple>
 
 enum class SpellHexRevengeType : byte {
     NONE = 0,
@@ -18,9 +19,9 @@ public:
     SpellHex(player_type *player_ptr, monap_type *monap_ptr);
     virtual ~SpellHex() = default;
 
-    bool stop_one_spell();
+    bool stop_spells_with_selection();
     void decrease_mana();
-    bool stop_all_spells();
+    void stop_all_spells();
     bool is_casting_full_capacity() const;
     void continue_revenge();
     void store_vengeful_damage(HIT_POINT dam);
@@ -45,7 +46,7 @@ private:
     std::vector<int> casting_spells;
     monap_type *monap_ptr = nullptr;
     
-    bool select_spell_stopping(char *out_val, char &choice);
+    std::tuple<bool, bool> select_spell_stopping(char *out_val, char &choice);
     void display_casting_spells_list();
     bool process_mana_cost(const bool need_restart);
     bool check_restart();
index 9022d20..6b6f986 100644 (file)
@@ -84,7 +84,7 @@ void set_action(player_type *player_ptr, uint8_t typ)
         stop_singing(player_ptr);
 
     if (prev_typ == ACTION_SPELL) {
-        (void)SpellHex(player_ptr).stop_one_spell();
+        (void)SpellHex(player_ptr).stop_spells_with_selection();
     }
 
     switch (player_ptr->action) {