1 #include "wizard/items-spoiler.h"
2 #include "flavor/flavor-describer.h"
3 #include "flavor/object-flavor-types.h"
4 #include "io/files-util.h"
5 #include "object-enchant/special-object-flags.h"
6 #include "object-enchant/trg-types.h"
7 #include "object/object-value.h"
8 #include "system/angband-version.h"
9 #include "system/baseitem-info.h"
10 #include "system/item-entity.h"
11 #include "system/player-type-definition.h"
12 #include "term/z-form.h"
13 #include "util/angband-files.h"
14 #include "view/display-messages.h"
15 #include "wizard/spoiler-util.h"
20 * @brief アイテムの生成階層と価格を得る
25 static std::pair<DEPTH, PRICE> get_info(const ItemEntity &item)
27 const auto level = item.get_baseitem().level;
28 const auto price = item.get_price();
29 return { level, price };
33 * @brief アイテムのダメージもしくはACの文字列表記を得る
36 * @return ダメージもしくはACの文字列表記
38 static std::string describe_dam_or_ac(const ItemEntity &item)
40 switch (item.bi_key.tval()) {
41 case ItemKindType::SHOT:
42 case ItemKindType::BOLT:
43 case ItemKindType::ARROW:
44 return format("%dd%d", item.dd, item.ds);
45 case ItemKindType::HAFTED:
46 case ItemKindType::POLEARM:
47 case ItemKindType::SWORD:
48 case ItemKindType::DIGGING:
49 return format("%dd%d", item.dd, item.ds);
50 case ItemKindType::BOOTS:
51 case ItemKindType::GLOVES:
52 case ItemKindType::CLOAK:
53 case ItemKindType::CROWN:
54 case ItemKindType::HELM:
55 case ItemKindType::SHIELD:
56 case ItemKindType::SOFT_ARMOR:
57 case ItemKindType::HARD_ARMOR:
58 case ItemKindType::DRAG_ARMOR:
59 return format("%d", item.ac);
66 * @brief アイテムの生成確率の文字列表記を得る
71 static std::string describe_chance(const ItemEntity &item)
75 const auto &baseitem = item.get_baseitem();
76 for (auto i = 0U; i < baseitem.alloc_tables.size(); i++) {
77 const auto &[level, chance] = baseitem.alloc_tables[i];
79 ss << format("%s%3dF:%+4d", (i != 0 ? "/" : ""), level, 100 / chance);
87 * @brief アイテムの重量の文字列表記を得る
90 * @return アイテムの重量の文字列表記
92 static std::string describe_weight(const ItemEntity &item)
94 return format("%3d.%d", (int)(item.weight / 10), (int)(item.weight % 10));
98 * @brief obj-desc.txt出力用にベースアイテムIDからItemEntityオブジェクトを生成する
100 * @param bi_id ベースアイテムID
101 * @return obj-desc.txt出力用に使用するItemEntityオブジェクト
103 static ItemEntity prepare_item_for_obj_desc(short bi_id)
107 item.ident |= IDENT_KNOWN;
116 * @brief 各ベースアイテムの情報を一行毎に記述する
118 SpoilerOutputResultType spoil_obj_desc()
120 const auto &path = path_build(ANGBAND_DIR_USER, "obj-desc.txt");
121 std::ofstream ofs(path);
123 return SpoilerOutputResultType::FILE_OPEN_FAILED;
126 ofs << format("Spoiler File -- Basic Items (%s)\n\n\n", get_version().data());
127 ofs << format("%-37s%8s%7s%5s %40s%9s\n", "Description", "Dam/AC", "Wgt", "Lev", "Chance", "Cost");
128 ofs << format("%-37s%8s%7s%5s %40s%9s\n", "-------------------------------------", "------", "---", "---", "----------------", "----");
130 for (const auto &[tval_list, name] : group_item_list) {
131 std::vector<short> whats;
132 for (auto tval : tval_list) {
133 for (const auto &baseitem : baseitems_info) {
134 if ((baseitem.bi_key.tval() == tval) && baseitem.gen_flags.has_not(ItemGenerationTraitType::INSTA_ART)) {
135 whats.push_back(baseitem.idx);
143 std::stable_sort(whats.begin(), whats.end(), [](auto bi_id1, auto bi_id2) {
144 const auto item1 = prepare_item_for_obj_desc(bi_id1);
145 const auto item2 = prepare_item_for_obj_desc(bi_id2);
146 const auto [depth1, price1] = get_info(item1);
147 const auto [depth2, price2] = get_info(item2);
148 return (price1 != price2) ? price1 < price2 : depth1 < depth2;
153 for (const auto &bi_id : whats) {
155 const auto item = prepare_item_for_obj_desc(bi_id);
156 const auto item_name = describe_flavor(&dummy, &item, OD_NAME_ONLY | OD_STORE);
157 const auto [depth, price] = get_info(item);
158 const auto dam_or_ac = describe_dam_or_ac(item);
159 const auto weight = describe_weight(item);
160 const auto chance = describe_chance(item);
161 ofs << format(" %-35s%8s%7s%5d %-40s%9d\n", item_name.data(), dam_or_ac.data(), weight.data(), depth, chance.data(), price);
165 return ofs.good() ? SpoilerOutputResultType::SUCCESSFUL : SpoilerOutputResultType::FILE_CLOSE_FAILED;