1 #include "wizard/fixed-artifacts-spoiler.h"
2 #include "io/files-util.h"
3 #include "system/angband-system.h"
4 #include "system/artifact-type-definition.h"
5 #include "system/item-entity.h"
6 #include "system/player-type-definition.h"
7 #include "util/angband-files.h"
8 #include "view/display-messages.h"
9 #include "wizard/artifact-analyzer.h"
10 #include "wizard/spoiler-util.h"
14 * @brief フラグ名称を出力する汎用関数
15 * @param header ヘッダに出力するフラグ群の名前
16 * @param descriptions フラグ名リスト
17 * @param separator フラグ表示の区切り記号
19 void spoiler_outlist(std::string_view header, const std::vector<std::string> &descriptions, char separator, std::ofstream &ofs)
21 if (descriptions.empty()) {
25 std::stringstream line;
26 line << spoiler_indent;
27 if (!header.empty()) {
28 line << header << " ";
32 ss << list_separator << ' ';
33 const auto last_separator = ss.str();
34 for (size_t i = 0; i < descriptions.size(); i++) {
35 std::stringstream element;
36 element << descriptions[i];
37 if (i < descriptions.size() - 1) {
38 element << separator << ' ';
41 const auto element_str = element.str();
42 const int line_length = line.tellp();
43 constexpr auto max_line_length = 75;
44 if (line_length + element_str.length() <= max_line_length) {
49 const auto line_str = line.str();
50 if (line_str.ends_with(last_separator)) {
51 ofs << std::string_view(line_str).substr(0, line_str.length() - 2) << '\n';
53 line.clear(std::stringstream::goodbit);
54 line << spoiler_indent << element_str;
56 ofs << line_str << '\n';
58 line.clear(std::stringstream::goodbit);
59 line << " " << element_str;
63 ofs << line.str() << '\n';
67 * @brief アーティファクト情報を出力するためにダミー生成を行う
68 * @param fa_id 生成するアーティファクトID
69 * @return 生成したアーティファクト (連番で埋まっているので不存在例外は吐かない)
71 static ItemEntity make_fake_artifact(FixedArtifactId fa_id)
73 const auto &artifact = ArtifactList::get_instance().get_artifact(fa_id);
74 ItemEntity item(artifact.bi_key);
76 item.pval = artifact.pval;
77 item.ac = artifact.ac;
78 item.damage_dice = artifact.damage_dice;
79 item.to_a = artifact.to_a;
80 item.to_h = artifact.to_h;
81 item.to_d = artifact.to_d;
82 item.weight = artifact.weight;
87 * @brief アーティファクト一件をスポイラー出力する /
88 * Create a spoiler file entry for an artifact
89 * @param art_ptr アーティファクト情報をまとめた構造体の参照ポインタ
91 static void spoiler_print_art(const ArtifactsDumpInfo *art_ptr, std::ofstream &ofs)
93 const auto *pval_ptr = &art_ptr->pval_info;
94 ofs << art_ptr->description << '\n';
95 if (!pval_ptr->pval_desc.empty()) {
97 ss << pval_ptr->pval_desc << _("の修正:", " to");
98 spoiler_outlist(ss.str(), pval_ptr->pval_affects, item_separator, ofs);
101 spoiler_outlist(_("対:", "Slay"), art_ptr->slays, item_separator, ofs);
102 spoiler_outlist(_("武器属性:", ""), art_ptr->brands, list_separator, ofs);
103 spoiler_outlist(_("免疫:", "Immunity to"), art_ptr->immunities, item_separator, ofs);
104 spoiler_outlist(_("耐性:", "Resist"), art_ptr->resistances, item_separator, ofs);
105 spoiler_outlist(_("弱点:", "Vulnerable"), art_ptr->vulnerabilities, item_separator, ofs);
106 spoiler_outlist(_("維持:", "Sustain"), art_ptr->sustenances, item_separator, ofs);
107 spoiler_outlist("", art_ptr->misc_magic, list_separator, ofs);
109 if (!art_ptr->addition.empty()) {
110 ofs << format(_("%s追加: %s\n", "%sAdditional %s\n"), spoiler_indent.data(), art_ptr->addition.data());
113 if (!art_ptr->activation.empty()) {
114 ofs << format(_("%s発動: %s\n", "%sActivates for %s\n"), spoiler_indent.data(), art_ptr->activation.data());
117 ofs << format("%s%s\n\n", spoiler_indent.data(), art_ptr->misc_desc.data());
121 * @brief アーティファクト情報のスポイラー出力を行うメインルーチン
122 * @details エラーコードと実際のエラー処理が不一致だが、後でまとめて修正する.
124 SpoilerOutputResultType spoil_fixed_artifact()
126 const auto path = path_build(ANGBAND_DIR_USER, "artifact.txt");
127 std::ofstream ofs(path);
129 return SpoilerOutputResultType::FILE_OPEN_FAILED;
132 std::stringstream ss;
133 ss << "Artifact Spoilers for Hengband Version " << AngbandSystem::get_instance().build_version_expression(VersionExpression::FULL);
134 spoiler_underline(ss.str(), ofs);
135 for (const auto &[tval_list, name] : group_artifact_list) {
136 spoiler_blanklines(2, ofs);
137 spoiler_underline(name, ofs);
138 spoiler_blanklines(1, ofs);
140 for (auto tval : tval_list) {
141 for (const auto &[fa_id, artifact] : ArtifactList::get_instance()) {
142 if (artifact.bi_key.tval() != tval) {
146 const auto item = make_fake_artifact(fa_id);
148 const auto artifacts_list = object_analyze(&dummy, &item);
149 spoiler_print_art(&artifacts_list, ofs);
154 return ofs.good() ? SpoilerOutputResultType::SUCCESSFUL : SpoilerOutputResultType::FILE_CLOSE_FAILED;