OSDN Git Service

[Refactor] #3453 アーティファクトのスポイラー出力先が'artifact.txt' しかなく、今後の拡張可能性も低く、リテラルのコピペなので、1箇所にまとめた
[hengbandforosx/hengbandosx.git] / src / wizard / fixed-artifacts-spoiler.cpp
index 4721982..20d853c 100644 (file)
-#include "wizard/fixed-artifacts-spoiler.h"
+#include "wizard/fixed-artifacts-spoiler.h"
 #include "io/files-util.h"
 #include "object/object-kind-hook.h"
 #include "system/angband-version.h"
 #include "system/artifact-type-definition.h"
-#include "system/object-type-definition.h"
+#include "system/baseitem-info.h"
+#include "system/item-entity.h"
 #include "system/player-type-definition.h"
 #include "util/angband-files.h"
 #include "view/display-messages.h"
 #include "wizard/artifact-analyzer.h"
 #include "wizard/spoiler-util.h"
+#include <sstream>
 
 /*!
  * @brief フラグ名称を出力する汎用関数
  * @param header ヘッダに出力するフラグ群の名前
- * @param list フラグ名リスト
+ * @param descriptions フラグ名リスト
  * @param separator フラグ表示の区切り記号
- * @todo 固定アーティファクトとランダムアーティファクトで共用、ここに置くべきかは要調整.
  */
-void spoiler_outlist(concptr header, concptr *list, char separator)
+void spoiler_outlist(std::string_view header, const std::vector<std::string> &descriptions, char separator)
 {
-    char line[MAX_LINE_LEN + 20], buf[80];
-    if (*list == nullptr)
+    if (descriptions.empty()) {
         return;
+    }
 
-    strcpy(line, spoiler_indent);
-    if (header && (header[0])) {
-        strcat(line, header);
-        strcat(line, " ");
+    std::string line = spoiler_indent;
+    if (!header.empty()) {
+        line.append(header).append(" ");
     }
 
-    int buf_len;
-    int line_len = strlen(line);
-    while (true) {
-        strcpy(buf, *list);
-        buf_len = strlen(buf);
-        if (list[1]) {
-            sprintf(buf + buf_len, "%c ", separator);
-            buf_len += 2;
+    for (size_t i = 0; i < descriptions.size(); i++) {
+        auto elem = descriptions[i];
+        if (i < descriptions.size() - 1) {
+            elem.push_back(separator);
+            elem.push_back(' ');
         }
 
-        if (line_len + buf_len <= MAX_LINE_LEN) {
-            strcat(line, buf);
-            line_len += buf_len;
-        } else {
-            if (line_len > 1 && line[line_len - 1] == ' ' && line[line_len - 2] == list_separator) {
-                line[line_len - 2] = '\0';
-                fprintf(spoiler_file, "%s\n", line);
-                sprintf(line, "%s%s", spoiler_indent, buf);
-            } else {
-                fprintf(spoiler_file, "%s\n", line);
-                concptr ident2 = "      ";
-                sprintf(line, "%s%s", ident2, buf);
-            }
-
-            line_len = strlen(line);
+        if (line.length() + elem.length() <= MAX_LINE_LEN) {
+            line.append(elem);
+            continue;
         }
 
-        if (!*++list)
-            break;
+        if (line.length() > 1 && line[line.length() - 1] == ' ' && line[line.length() - 2] == list_separator) {
+            line[line.length() - 2] = '\0';
+            fprintf(spoiler_file, "%s\n", line.data());
+            line = spoiler_indent;
+            line.append(elem);
+        } else {
+            fprintf(spoiler_file, "%s\n", line.data());
+            line = "      ";
+            line.append(elem);
+        }
     }
 
-    fprintf(spoiler_file, "%s\n", line);
+    fprintf(spoiler_file, "%s\n", line.data());
 }
 
 /*!
- * @brief バッファにアーティファクト出力情報ヘッダを収める /
+ * @brief アーティファクト情報を出力するためにダミー生成を行う
+ * @param fixed_artifact_idx 生成するアーティファクトID
+ * @return 生成したアーティファクト (連番で埋まっているので不存在例外は吐かない)
  */
-static void print_header(void)
+static ItemEntity make_fake_artifact(FixedArtifactId fixed_artifact_idx)
 {
-    char buf[360];
-    char title[180];
-    put_version(title);
-    sprintf(buf, "Artifact Spoilers for Hengband Version %s", title);
-    spoiler_underline(buf);
-}
-
-/*!
- * @brief アーティファクト情報を出力するためにダミー生成を行う /
- * Hack -- Create a "forged" artifact
- * @param o_ptr 一時生成先を保管するオブジェクト構造体
- * @param name1 生成するアーティファクトID
- * @return 生成が成功した場合TRUEを返す
- */
-static bool make_fake_artifact(object_type *o_ptr, ARTIFACT_IDX name1)
-{
-    artifact_type *a_ptr = &a_info[name1];
-    if (a_ptr->name.empty())
-        return false;
-
-    OBJECT_IDX i = lookup_kind(a_ptr->tval, a_ptr->sval);
-    if (!i)
-        return false;
-
-    o_ptr->prep(i);
-    o_ptr->name1 = name1;
-    o_ptr->pval = a_ptr->pval;
-    o_ptr->ac = a_ptr->ac;
-    o_ptr->dd = a_ptr->dd;
-    o_ptr->ds = a_ptr->ds;
-    o_ptr->to_a = a_ptr->to_a;
-    o_ptr->to_h = a_ptr->to_h;
-    o_ptr->to_d = a_ptr->to_d;
-    o_ptr->weight = a_ptr->weight;
-    return true;
+    const auto &artifact = ArtifactsInfo::get_instance().get_artifact(fixed_artifact_idx);
+    const auto bi_id = lookup_baseitem_id(artifact.bi_key);
+    ItemEntity item;
+    item.prep(bi_id);
+    item.fixed_artifact_idx = fixed_artifact_idx;
+    item.pval = artifact.pval;
+    item.ac = artifact.ac;
+    item.dd = artifact.dd;
+    item.ds = artifact.ds;
+    item.to_a = artifact.to_a;
+    item.to_h = artifact.to_h;
+    item.to_d = artifact.to_d;
+    item.weight = artifact.weight;
+    return item;
 }
 
 /*!
@@ -112,69 +86,65 @@ static bool make_fake_artifact(object_type *o_ptr, ARTIFACT_IDX name1)
  */
 static void spoiler_print_art(obj_desc_list *art_ptr)
 {
-    pval_info_type *pval_ptr = &art_ptr->pval_info;
-    char buf[80];
-    fprintf(spoiler_file, "%s\n", art_ptr->description);
-    if (pval_ptr->pval_desc[0]) {
-        sprintf(buf, _("%sの修正:", "%s to"), pval_ptr->pval_desc);
-        spoiler_outlist(buf, pval_ptr->pval_affects, item_separator);
+    const auto *pval_ptr = &art_ptr->pval_info;
+    fprintf(spoiler_file, "%s\n", art_ptr->description.data());
+    if (!pval_ptr->pval_desc.empty()) {
+        std::stringstream ss;
+        ss << pval_ptr->pval_desc << _("の修正:", " to");
+        spoiler_outlist(ss.str(), pval_ptr->pval_affects, item_separator);
     }
 
     spoiler_outlist(_("対:", "Slay"), art_ptr->slays, item_separator);
     spoiler_outlist(_("武器属性:", ""), art_ptr->brands, list_separator);
     spoiler_outlist(_("免疫:", "Immunity to"), art_ptr->immunities, item_separator);
     spoiler_outlist(_("耐性:", "Resist"), art_ptr->resistances, item_separator);
-    spoiler_outlist(_("弱点:", "Vulnerable"), art_ptr->vulnerables, item_separator);
-    spoiler_outlist(_("維持:", "Sustain"), art_ptr->sustains, item_separator);
+    spoiler_outlist(_("弱点:", "Vulnerable"), art_ptr->vulnerabilities, item_separator);
+    spoiler_outlist(_("維持:", "Sustain"), art_ptr->sustenances, item_separator);
     spoiler_outlist("", art_ptr->misc_magic, list_separator);
 
-    if (art_ptr->addition[0])
-        fprintf(spoiler_file, _("%s追加: %s\n", "%sAdditional %s\n"), spoiler_indent, art_ptr->addition);
+    if (!art_ptr->addition.empty()) {
+        fprintf(spoiler_file, _("%s追加: %s\n", "%sAdditional %s\n"), spoiler_indent, art_ptr->addition.data());
+    }
 
-    if (art_ptr->activation)
-        fprintf(spoiler_file, _("%s発動: %s\n", "%sActivates for %s\n"), spoiler_indent, art_ptr->activation);
+    if (!art_ptr->activation.empty()) {
+        fprintf(spoiler_file, _("%s発動: %s\n", "%sActivates for %s\n"), spoiler_indent, art_ptr->activation.data());
+    }
 
-    fprintf(spoiler_file, "%s%s\n\n", spoiler_indent, art_ptr->misc_desc);
+    fprintf(spoiler_file, "%s%s\n\n", spoiler_indent, art_ptr->misc_desc.data());
 }
 
 /*!
- * @brief アーティファクト情報のスポイラー出力を行うメインルーチン /
- * Create a spoiler file for artifacts
- * @param fname 生成ファイル名
+ * @brief アーティファクト情報のスポイラー出力を行うメインルーチン
  */
-SpoilerOutputResultType spoil_fixed_artifact(concptr fname)
+SpoilerOutputResultType spoil_fixed_artifact()
 {
-    char buf[1024];
-    path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
-    spoiler_file = angband_fopen(buf, "w");
+    const auto &path = path_build(ANGBAND_DIR_USER, "artifact.txt");
+    spoiler_file = angband_fopen(path, FileOpenMode::WRITE);
     if (!spoiler_file) {
-        return SpoilerOutputResultType::SPOILER_OUTPUT_FAIL_FOPEN;
+        return SpoilerOutputResultType::FILE_OPEN_FAILED;
     }
 
-    print_header();
+    spoiler_underline(std::string("Artifact Spoilers for Hengband Version ").append(get_version()).data());
     for (const auto &[tval_list, name] : group_artifact_list) {
         spoiler_blanklines(2);
         spoiler_underline(name);
         spoiler_blanklines(1);
 
         for (auto tval : tval_list) {
-            for (const auto &a_ref : a_info) {
-                if (a_ref.tval != tval)
-                    continue;
-
-                object_type obj;
-                obj.wipe();
-                if (!make_fake_artifact(&obj, a_ref.idx))
+            for (const auto &[a_idx, artifact] : artifacts_info) {
+                if (artifact.bi_key.tval() != tval) {
                     continue;
+                }
 
+                const auto item = make_fake_artifact(a_idx);
                 PlayerType dummy;
-                obj_desc_list artifact;
-                object_analyze(&dummy, &obj, &artifact);
-                spoiler_print_art(&artifact);
+                obj_desc_list artifact_descriptions;
+                object_analyze(&dummy, &item, &artifact_descriptions);
+                spoiler_print_art(&artifact_descriptions);
             }
         }
     }
 
-    return ferror(spoiler_file) || angband_fclose(spoiler_file) ? SpoilerOutputResultType::SPOILER_OUTPUT_FAIL_FCLOSE
-                                                                : SpoilerOutputResultType::SPOILER_OUTPUT_SUCCESS;
+    return ferror(spoiler_file) || angband_fclose(spoiler_file) ? SpoilerOutputResultType::FILE_CLOSE_FAILED
+                                                                : SpoilerOutputResultType::SUCCESSFUL;
 }