1 #include "wizard/fixed-artifacts-spoiler.h"
2 #include "io/files-util.h"
3 #include "object/object-kind-hook.h"
4 #include "system/angband-version.h"
5 #include "system/artifact-type-definition.h"
6 #include "system/baseitem-info.h"
7 #include "system/item-entity.h"
8 #include "system/player-type-definition.h"
9 #include "util/angband-files.h"
10 #include "view/display-messages.h"
11 #include "wizard/artifact-analyzer.h"
12 #include "wizard/spoiler-util.h"
16 * @brief フラグ名称を出力する汎用関数
17 * @param header ヘッダに出力するフラグ群の名前
18 * @param descriptions フラグ名リスト
19 * @param separator フラグ表示の区切り記号
21 void spoiler_outlist(std::string_view header, const std::vector<std::string> &descriptions, char separator)
23 if (descriptions.empty()) {
27 std::string line = spoiler_indent;
28 if (!header.empty()) {
29 line.append(header).append(" ");
32 for (size_t i = 0; i < descriptions.size(); i++) {
33 auto elem = descriptions[i];
34 if (i < descriptions.size() - 1) {
35 elem.push_back(separator);
39 if (line.length() + elem.length() <= MAX_LINE_LEN) {
44 if (line.length() > 1 && line[line.length() - 1] == ' ' && line[line.length() - 2] == list_separator) {
45 line[line.length() - 2] = '\0';
46 fprintf(spoiler_file, "%s\n", line.data());
47 line = spoiler_indent;
50 fprintf(spoiler_file, "%s\n", line.data());
56 fprintf(spoiler_file, "%s\n", line.data());
60 * @brief アーティファクト情報を出力するためにダミー生成を行う
61 * @param fixed_artifact_idx 生成するアーティファクトID
62 * @return 生成したアーティファクト (連番で埋まっているので不存在例外は吐かない)
64 static ItemEntity make_fake_artifact(FixedArtifactId fixed_artifact_idx)
66 const auto &artifact = ArtifactsInfo::get_instance().get_artifact(fixed_artifact_idx);
67 const auto bi_id = lookup_baseitem_id(artifact.bi_key);
70 item.fixed_artifact_idx = fixed_artifact_idx;
71 item.pval = artifact.pval;
72 item.ac = artifact.ac;
73 item.dd = artifact.dd;
74 item.ds = artifact.ds;
75 item.to_a = artifact.to_a;
76 item.to_h = artifact.to_h;
77 item.to_d = artifact.to_d;
78 item.weight = artifact.weight;
83 * @brief アーティファクト一件をスポイラー出力する /
84 * Create a spoiler file entry for an artifact
85 * @param art_ptr アーティファクト情報をまとめた構造体の参照ポインタ
87 static void spoiler_print_art(obj_desc_list *art_ptr)
89 const auto *pval_ptr = &art_ptr->pval_info;
90 fprintf(spoiler_file, "%s\n", art_ptr->description.data());
91 if (!pval_ptr->pval_desc.empty()) {
93 ss << pval_ptr->pval_desc << _("の修正:", " to");
94 spoiler_outlist(ss.str(), pval_ptr->pval_affects, item_separator);
97 spoiler_outlist(_("対:", "Slay"), art_ptr->slays, item_separator);
98 spoiler_outlist(_("武器属性:", ""), art_ptr->brands, list_separator);
99 spoiler_outlist(_("免疫:", "Immunity to"), art_ptr->immunities, item_separator);
100 spoiler_outlist(_("耐性:", "Resist"), art_ptr->resistances, item_separator);
101 spoiler_outlist(_("弱点:", "Vulnerable"), art_ptr->vulnerabilities, item_separator);
102 spoiler_outlist(_("維持:", "Sustain"), art_ptr->sustenances, item_separator);
103 spoiler_outlist("", art_ptr->misc_magic, list_separator);
105 if (!art_ptr->addition.empty()) {
106 fprintf(spoiler_file, _("%s追加: %s\n", "%sAdditional %s\n"), spoiler_indent.data(), art_ptr->addition.data());
109 if (!art_ptr->activation.empty()) {
110 fprintf(spoiler_file, _("%s発動: %s\n", "%sActivates for %s\n"), spoiler_indent.data(), art_ptr->activation.data());
113 fprintf(spoiler_file, "%s%s\n\n", spoiler_indent.data(), art_ptr->misc_desc.data());
117 * @brief アーティファクト情報のスポイラー出力を行うメインルーチン
119 SpoilerOutputResultType spoil_fixed_artifact()
121 const auto &path = path_build(ANGBAND_DIR_USER, "artifact.txt");
122 spoiler_file = angband_fopen(path, FileOpenMode::WRITE);
124 return SpoilerOutputResultType::FILE_OPEN_FAILED;
127 std::stringstream ss;
128 ss << "Artifact Spoilers for Hengband Version " << get_version();
129 spoiler_underline(ss.str());
130 for (const auto &[tval_list, name] : group_artifact_list) {
131 spoiler_blanklines(2);
132 spoiler_underline(name);
133 spoiler_blanklines(1);
135 for (auto tval : tval_list) {
136 for (const auto &[a_idx, artifact] : artifacts_info) {
137 if (artifact.bi_key.tval() != tval) {
141 const auto item = make_fake_artifact(a_idx);
143 obj_desc_list artifact_descriptions;
144 object_analyze(&dummy, &item, &artifact_descriptions);
145 spoiler_print_art(&artifact_descriptions);
150 return ferror(spoiler_file) || angband_fclose(spoiler_file) ? SpoilerOutputResultType::FILE_CLOSE_FAILED
151 : SpoilerOutputResultType::SUCCESSFUL;