OSDN Git Service

[Refactor] format 関数の戻り値を std::string にする
[hengbandforosx/hengbandosx.git] / src / io-dump / special-class-dump.cpp
1 /*!
2  * @brief 一部職業でのみダンプする能力の出力処理
3  * @date 2020/03/07
4  * @author Hourier
5  */
6
7 #include "io-dump/special-class-dump.h"
8 #include "blue-magic/blue-magic-checker.h"
9 #include "cmd-item/cmd-magiceat.h"
10 #include "mind/mind-blue-mage.h"
11 #include "monster-race/race-ability-flags.h"
12 #include "mspell/monster-power-table.h"
13 #include "object/object-kind-hook.h"
14 #include "player-base/player-class.h"
15 #include "player-info/bluemage-data-type.h"
16 #include "player-info/magic-eater-data-type.h"
17 #include "smith/object-smith.h"
18 #include "system/baseitem-info.h"
19 #include "system/player-type-definition.h"
20 #include "util/enum-converter.h"
21 #include "util/flag-group.h"
22
23 #include <algorithm>
24 #include <iterator>
25 #include <string>
26 #include <vector>
27
28 struct learnt_spell_table {
29     EnumClassFlagGroup<MonsterAbilityType> ability_flags;
30 };
31
32 /*!
33  * @brief 魔力喰いを持つクラスの情報をダンプする
34  * @param player_ptr プレイヤーへの参照ポインタ
35  * @param fff ファイルポインタ
36  */
37 static void dump_magic_eater(PlayerType *player_ptr, FILE *fff)
38 {
39     auto magic_eater_data = PlayerClass(player_ptr).get_specific_data<magic_eater_data_type>();
40     if (!magic_eater_data) {
41         return;
42     }
43
44     fprintf(fff, _("\n\n  [取り込んだ魔法道具]\n", "\n\n  [Magic devices eaten]\n"));
45
46     for (auto tval : { ItemKindType::STAFF, ItemKindType::WAND, ItemKindType::ROD }) {
47         switch (tval) {
48         case ItemKindType::STAFF:
49             fprintf(fff, _("\n[杖]\n", "\n[Staffs]\n"));
50             break;
51         case ItemKindType::WAND:
52             fprintf(fff, _("\n[魔法棒]\n", "\n[Wands]\n"));
53             break;
54         case ItemKindType::ROD:
55             fprintf(fff, _("\n[ロッド]\n", "\n[Rods]\n"));
56             break;
57         default:
58             break;
59         }
60
61         const auto &item_group = magic_eater_data->get_item_group(tval);
62         std::vector<std::string> desc_list;
63         for (auto i = 0U; i < item_group.size(); ++i) {
64             auto &item = item_group[i];
65             if (item.count == 0) {
66                 continue;
67             }
68
69             auto bi_id = lookup_baseitem_id({ tval, i });
70             if (!bi_id) {
71                 continue;
72             }
73
74             char buf[128];
75             snprintf(buf, sizeof(buf), "%23s (%2d)", baseitems_info[bi_id].name.data(), item.count);
76             desc_list.emplace_back(buf);
77         }
78
79         if (desc_list.size() <= 0) {
80             fputs(_("  (なし)\n", "  (none)\n"), fff);
81             continue;
82         }
83
84         uint i;
85         for (i = 0; i < desc_list.size(); i++) {
86             fputs(desc_list[i].data(), fff);
87             if (i % 3 < 2) {
88                 fputs("    ", fff);
89             } else {
90                 fputs("\n", fff);
91             }
92         }
93
94         if (i % 3 > 0) {
95             fputs("\n", fff);
96         }
97     }
98 }
99
100 /*!
101  * @brief 鍛冶師のエッセンス情報をダンプする
102  * @param player_ptr プレイヤーへの参照ポインタ
103  * @param fff ファイルポインタ
104  */
105 static void dump_smith(PlayerType *player_ptr, FILE *fff)
106 {
107     fprintf(fff, _("\n\n  [手に入れたエッセンス]\n\n", "\n\n  [Get Essence]\n\n"));
108     fprintf(fff, _("エッセンス   個数     エッセンス   個数     エッセンス   個数", "Essence      Num      Essence      Num      Essence      Num "));
109
110     auto essences = Smith::get_essence_list();
111     auto n = essences.size();
112     std::vector<int> amounts;
113     std::transform(essences.begin(), essences.end(), std::back_inserter(amounts),
114         [smith = Smith(player_ptr)](SmithEssenceType e) { return smith.get_essence_num_of_posessions(e); });
115
116     auto row = n / 3 + 1;
117     for (auto i = 0U; i < row; i++) {
118         fprintf(fff, "\n");
119         fprintf(fff, "%-11s %5d     ", Smith::get_essence_name(essences[i]), amounts[i]);
120         if (i + row < n) {
121             fprintf(fff, "%-11s %5d     ", Smith::get_essence_name(essences[i + row]), amounts[i + row]);
122         }
123         if (i + row * 2 < n) {
124             fprintf(fff, "%-11s %5d", Smith::get_essence_name(essences[i + row * 2]), amounts[i + row * 2]);
125         }
126     }
127
128     fputs("\n", fff);
129 }
130
131 /*!
132  * @brief ダンプする情報に学習済魔法の種類を追加する
133  * @param p ダンプ用のバッファ
134  * @param col 行数
135  * @param SpellProcessType 魔法の種類
136  * @param learnt_spell_ptr 学習済魔法のテーブル
137  */
138 static void add_monster_spell_type(char p[][80], int col, BlueMagicType SpellProcessType, learnt_spell_table *learnt_spell_ptr)
139 {
140     learnt_spell_ptr->ability_flags.clear();
141     set_rf_masks(learnt_spell_ptr->ability_flags, SpellProcessType);
142     switch (SpellProcessType) {
143     case BlueMagicType::BOLT:
144         strcat(p[col], _("\n     [ボルト型]\n", "\n     [Bolt  Type]\n"));
145         break;
146
147     case BlueMagicType::BALL:
148         strcat(p[col], _("\n     [ボール型]\n", "\n     [Ball  Type]\n"));
149         break;
150
151     case BlueMagicType::BREATH:
152         strcat(p[col], _("\n     [ブレス型]\n", "\n     [  Breath  ]\n"));
153         break;
154
155     case BlueMagicType::SUMMON:
156         strcat(p[col], _("\n     [召喚魔法]\n", "\n     [Summonning]\n"));
157         break;
158
159     case BlueMagicType::OTHER:
160         strcat(p[col], _("\n     [ その他 ]\n", "\n     [Other Type]\n"));
161         break;
162     }
163 }
164
165 /*!
166  * @brief 青魔道士の学習済魔法をダンプする
167  * @param player_ptr プレイヤーへの参照ポインタ
168  * @param fff ファイルポインタ
169  */
170 static void dump_blue_mage(PlayerType *player_ptr, FILE *fff)
171 {
172     const auto bluemage_data = PlayerClass(player_ptr).get_specific_data<bluemage_data_type>();
173     if (!bluemage_data) {
174         return;
175     }
176
177     char p[60][80];
178     for (int i = 0; i < 60; i++) {
179         p[i][0] = '\0';
180     }
181
182     int col = 0;
183     strcat(p[col], _("\n\n  [学習済みの青魔法]\n", "\n\n  [Learned Blue Magic]\n"));
184
185     for (auto SpellProcessType : BLUE_MAGIC_TYPE_LIST) {
186         col++;
187         learnt_spell_table learnt_magic;
188         add_monster_spell_type(p, col, SpellProcessType, &learnt_magic);
189         learnt_magic.ability_flags &= bluemage_data->learnt_blue_magics;
190
191         std::vector<MonsterAbilityType> learnt_spells;
192         EnumClassFlagGroup<MonsterAbilityType>::get_flags(learnt_magic.ability_flags, std::back_inserter(learnt_spells));
193
194         col++;
195         bool pcol = false;
196         strcat(p[col], "       ");
197
198         for (auto spell : learnt_spells) {
199             pcol = true;
200             int l1 = strlen(p[col]);
201             int l2 = strlen(monster_powers_short.at(spell));
202             if ((l1 + l2) >= 75) {
203                 strcat(p[col], "\n");
204                 col++;
205                 strcat(p[col], "       ");
206             }
207
208             strcat(p[col], monster_powers_short.at(spell));
209             strcat(p[col], ", ");
210         }
211
212         if (!pcol) {
213             strcat(p[col], _("なし", "None"));
214             strcat(p[col], "\n");
215             continue;
216         }
217
218         if (p[col][strlen(p[col]) - 2] == ',') {
219             p[col][strlen(p[col]) - 2] = '\0';
220         } else {
221             p[col][strlen(p[col]) - 10] = '\0';
222         }
223
224         strcat(p[col], "\n");
225     }
226
227     for (int i = 0; i <= col; i++) {
228         fputs(p[i], fff);
229     }
230 }
231
232 /*!
233  * @brief プレイヤーの職業能力情報をファイルにダンプする
234  * @param player_ptr プレイヤーへの参照ポインタ
235  * @param fff ファイルポインタ
236  */
237 void dump_aux_class_special(PlayerType *player_ptr, FILE *fff)
238 {
239     switch (player_ptr->pclass) {
240     case PlayerClassType::MAGIC_EATER: {
241         dump_magic_eater(player_ptr, fff);
242         return;
243     }
244     case PlayerClassType::SMITH: {
245         dump_smith(player_ptr, fff);
246         return;
247     }
248     case PlayerClassType::BLUE_MAGE: {
249         dump_blue_mage(player_ptr, fff);
250         return;
251     }
252     default:
253         return;
254     }
255 }