OSDN Git Service

Merge pull request #2461 from sikabane-works/release/3.0.0Alpha57
[hengbandforosx/hengbandosx.git] / src / wizard / items-spoiler.cpp
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-kind.h"
8 #include "object/object-value.h"
9 #include "system/angband-version.h"
10 #include "system/object-type-definition.h"
11 #include "system/player-type-definition.h"
12 #include "util/angband-files.h"
13 #include "view/display-messages.h"
14 #include "wizard/spoiler-util.h"
15
16 #include <algorithm>
17
18 /*!
19  * @brief ベースアイテムの各情報を文字列化する /
20  * Describe the kind
21  * @param player_ptr プレイヤーへの参照ポインタ
22  * @param buf 名称を返すバッファ参照ポインタ
23  * @param dam ダメージダイス記述を返すバッファ参照ポインタ
24  * @param wgt 重量記述を返すバッファ参照ポインタ
25  * @param lev 生成階記述を返すバッファ参照ポインタ
26  * @param chance 生成機会を返すバッファ参照ポインタ
27  * @param val 価値を返すバッファ参照ポインタ
28  * @param k ベースアイテムID
29  */
30 static void kind_info(PlayerType *player_ptr, char *buf, char *dam, char *wgt, char *chance, DEPTH *lev, PRICE *val, KIND_OBJECT_IDX k)
31 {
32     ObjectType forge;
33     auto *q_ptr = &forge;
34     q_ptr->prep(k);
35     q_ptr->ident |= IDENT_KNOWN;
36     q_ptr->pval = 0;
37     q_ptr->to_a = 0;
38     q_ptr->to_h = 0;
39     q_ptr->to_d = 0;
40     *lev = k_info[q_ptr->k_idx].level;
41     *val = object_value(q_ptr);
42     if (!buf || !dam || !chance || !wgt) {
43         return;
44     }
45
46     describe_flavor(player_ptr, buf, q_ptr, OD_NAME_ONLY | OD_STORE);
47     strcpy(dam, "");
48     switch (q_ptr->tval) {
49     case ItemKindType::SHOT:
50     case ItemKindType::BOLT:
51     case ItemKindType::ARROW:
52         sprintf(dam, "%dd%d", q_ptr->dd, q_ptr->ds);
53         break;
54     case ItemKindType::HAFTED:
55     case ItemKindType::POLEARM:
56     case ItemKindType::SWORD:
57     case ItemKindType::DIGGING:
58         sprintf(dam, "%dd%d", q_ptr->dd, q_ptr->ds);
59         break;
60     case ItemKindType::BOOTS:
61     case ItemKindType::GLOVES:
62     case ItemKindType::CLOAK:
63     case ItemKindType::CROWN:
64     case ItemKindType::HELM:
65     case ItemKindType::SHIELD:
66     case ItemKindType::SOFT_ARMOR:
67     case ItemKindType::HARD_ARMOR:
68     case ItemKindType::DRAG_ARMOR:
69         sprintf(dam, "%d", q_ptr->ac);
70         break;
71     default:
72         break;
73     }
74
75     strcpy(chance, "");
76     for (int i = 0; i < 4; i++) {
77         char chance_aux[20] = "";
78         if (k_info[q_ptr->k_idx].chance[i] > 0) {
79             sprintf(chance_aux, "%s%3dF:%+4d", (i != 0 ? "/" : ""), (int)k_info[q_ptr->k_idx].locale[i], 100 / k_info[q_ptr->k_idx].chance[i]);
80             strcat(chance, chance_aux);
81         }
82     }
83
84     sprintf(wgt, "%3d.%d", (int)(q_ptr->weight / 10), (int)(q_ptr->weight % 10));
85 }
86
87 /*!
88  * @brief 各ベースアイテムの情報を一行毎に記述する /
89  * Create a spoiler file for items
90  * @param fname ファイル名
91  */
92 SpoilerOutputResultType spoil_obj_desc(concptr fname)
93 {
94     char buf[1024];
95     path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
96     spoiler_file = angband_fopen(buf, "w");
97     if (!spoiler_file) {
98         return SpoilerOutputResultType::SPOILER_OUTPUT_FAIL_FOPEN;
99     }
100
101     char title[200];
102     put_version(title);
103     fprintf(spoiler_file, "Spoiler File -- Basic Items (%s)\n\n\n", title);
104     fprintf(spoiler_file, "%-37s%8s%7s%5s %40s%9s\n", "Description", "Dam/AC", "Wgt", "Lev", "Chance", "Cost");
105     fprintf(spoiler_file, "%-37s%8s%7s%5s %40s%9s\n", "-------------------------------------", "------", "---", "---", "----------------", "----");
106
107     for (const auto &[tval_list, name] : group_item_list) {
108         std::vector<KIND_OBJECT_IDX> whats;
109         for (auto tval : tval_list) {
110             for (const auto &k_ref : k_info) {
111                 if ((k_ref.tval == tval) && k_ref.gen_flags.has_not(ItemGenerationTraitType::INSTA_ART)) {
112                     whats.push_back(k_ref.idx);
113                 }
114             }
115         }
116         if (whats.empty()) {
117             continue;
118         }
119
120         std::stable_sort(whats.begin(), whats.end(), [](auto k1_idx, auto k2_idx) {
121             PlayerType dummy;
122             DEPTH d1, d2;
123             PRICE p1, p2;
124             kind_info(&dummy, nullptr, nullptr, nullptr, nullptr, &d1, &p1, k1_idx);
125             kind_info(&dummy, nullptr, nullptr, nullptr, nullptr, &d2, &p2, k2_idx);
126             return (p1 != p2) ? p1 < p2 : d1 < d2;
127         });
128
129         fprintf(spoiler_file, "\n\n%s\n\n", name);
130         for (const auto &k_idx : whats) {
131             DEPTH e;
132             PRICE v;
133             char wgt[80];
134             char chance[80];
135             char dam[80];
136             PlayerType dummy;
137             kind_info(&dummy, buf, dam, wgt, chance, &e, &v, k_idx);
138             fprintf(spoiler_file, "  %-35s%8s%7s%5d %-40s%9ld\n", buf, dam, wgt, static_cast<int>(e), chance, static_cast<long>(v));
139         }
140     }
141
142     return ferror(spoiler_file) || angband_fclose(spoiler_file) ? SpoilerOutputResultType::SPOILER_OUTPUT_FAIL_FCLOSE
143                                                                 : SpoilerOutputResultType::SPOILER_OUTPUT_SUCCESS;
144 }