OSDN Git Service

5dea21c9dd2b4f54b4cbaba94a667e2e7f2265a4
[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-enchant/object-smith.h"
14 #include "object/object-kind-hook.h"
15 #include "object/object-kind.h"
16 #include "player-base/player-class.h"
17 #include "player-info/bluemage-data-type.h"
18 #include "player-info/magic-eater-data-type.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 typedef struct {
29     EnumClassFlagGroup<RF_ABILITY> ability_flags;
30 } learnt_spell_table;
31
32 /*!
33  * @brief 魔力喰いを持つクラスの情報をダンプする
34  * @param player_ptr プレイヤーへの参照ポインタ
35  * @param fff ファイルポインタ
36  */
37 static void dump_magic_eater(player_type *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             KIND_OBJECT_IDX k_idx = lookup_kind(tval, i);
69             if (!k_idx)
70                 continue;
71
72             char buf[128];
73             snprintf(buf, sizeof(buf), "%23s (%2d)", k_info[k_idx].name.c_str(), item.count);
74             desc_list.emplace_back(buf);
75         }
76
77         if (desc_list.size() <= 0) {
78             fputs(_("  (なし)\n", "  (none)\n"), fff);
79             continue;
80         }
81
82         uint i;
83         for (i = 0; i < desc_list.size(); i++) {
84             fputs(desc_list[i].c_str(), fff);
85             if (i % 3 < 2)
86                 fputs("    ", fff);
87             else
88                 fputs("\n", fff);
89         }
90
91         if (i % 3 > 0)
92             fputs("\n", fff);
93     }
94 }
95
96 /*!
97  * @brief 鍛冶師のエッセンス情報をダンプする
98  * @param player_ptr プレイヤーへの参照ポインタ
99  * @param fff ファイルポインタ
100  */
101 static void dump_smith(player_type *player_ptr, FILE *fff)
102 {
103     fprintf(fff, _("\n\n  [手に入れたエッセンス]\n\n", "\n\n  [Get Essence]\n\n"));
104     fprintf(fff, _("エッセンス   個数     エッセンス   個数     エッセンス   個数", "Essence      Num      Essence      Num      Essence      Num "));
105
106     auto essences = Smith::get_essence_list();
107     auto n = essences.size();
108     std::vector<int> amounts;
109     std::transform(essences.begin(), essences.end(), std::back_inserter(amounts),
110         [smith = Smith(player_ptr)](SmithEssence e) { return smith.get_essence_num_of_posessions(e); });
111
112     auto row = n / 3 + 1;
113     for (auto i = 0U; i < row; i++) {
114         fprintf(fff, "\n");
115         fprintf(fff, "%-11s %5d     ", Smith::get_essence_name(essences[i]), amounts[i]);
116         if (i + row < n)
117             fprintf(fff, "%-11s %5d     ", Smith::get_essence_name(essences[i + row]), amounts[i + row]);
118         if (i + row * 2 < n)
119             fprintf(fff, "%-11s %5d", Smith::get_essence_name(essences[i + row * 2]), amounts[i + row * 2]);
120     }
121
122     fputs("\n", fff);
123 }
124
125 /*!
126  * @brief ダンプする情報に学習済魔法の種類を追加する
127  * @param p ダンプ用のバッファ
128  * @param col 行数
129  * @param spell_type 魔法の種類
130  * @param learnt_spell_ptr 学習済魔法のテーブル
131  */
132 static void add_monster_spell_type(char p[][80], int col, BlueMagicType spell_type, learnt_spell_table *learnt_spell_ptr)
133 {
134     learnt_spell_ptr->ability_flags.clear();
135     set_rf_masks(learnt_spell_ptr->ability_flags, spell_type);
136     switch (spell_type) {
137     case BlueMagicType::BOLT:
138         strcat(p[col], _("\n     [ボルト型]\n", "\n     [Bolt  Type]\n"));
139         break;
140
141     case BlueMagicType::BALL:
142         strcat(p[col], _("\n     [ボール型]\n", "\n     [Ball  Type]\n"));
143         break;
144
145     case BlueMagicType::BREATH:
146         strcat(p[col], _("\n     [ブレス型]\n", "\n     [  Breath  ]\n"));
147         break;
148
149     case BlueMagicType::SUMMON:
150         strcat(p[col], _("\n     [召喚魔法]\n", "\n     [Summonning]\n"));
151         break;
152
153     case BlueMagicType::OTHER:
154         strcat(p[col], _("\n     [ その他 ]\n", "\n     [Other Type]\n"));
155         break;
156     }
157 }
158
159 /*!
160  * @brief 青魔道士の学習済魔法をダンプする
161  * @param player_ptr プレイヤーへの参照ポインタ
162  * @param fff ファイルポインタ
163  */
164 static void dump_blue_mage(player_type *player_ptr, FILE *fff)
165 {
166     const auto bluemage_data = PlayerClass(player_ptr).get_specific_data<bluemage_data_type>();
167     if (!bluemage_data) {
168         return;
169     }
170
171     char p[60][80];
172     for (int i = 0; i < 60; i++) {
173         p[i][0] = '\0';
174     }
175
176     int col = 0;
177     strcat(p[col], _("\n\n  [学習済みの青魔法]\n", "\n\n  [Learned Blue Magic]\n"));
178
179     for (auto spell_type : BLUE_MAGIC_TYPE_LIST) {
180         col++;
181         learnt_spell_table learnt_magic;
182         add_monster_spell_type(p, col, spell_type, &learnt_magic);
183         learnt_magic.ability_flags &= bluemage_data->learnt_blue_magics;
184
185         std::vector<RF_ABILITY> learnt_spells;
186         EnumClassFlagGroup<RF_ABILITY>::get_flags(learnt_magic.ability_flags, std::back_inserter(learnt_spells));
187
188         col++;
189         bool pcol = false;
190         strcat(p[col], "       ");
191
192         for (auto spell : learnt_spells) {
193             pcol = true;
194             int l1 = strlen(p[col]);
195             int l2 = strlen(monster_powers_short.at(spell));
196             if ((l1 + l2) >= 75) {
197                 strcat(p[col], "\n");
198                 col++;
199                 strcat(p[col], "       ");
200             }
201
202             strcat(p[col], monster_powers_short.at(spell));
203             strcat(p[col], ", ");
204         }
205
206         if (!pcol) {
207             strcat(p[col], _("なし", "None"));
208             strcat(p[col], "\n");
209             continue;
210         }
211
212         if (p[col][strlen(p[col]) - 2] == ',') {
213             p[col][strlen(p[col]) - 2] = '\0';
214         } else {
215             p[col][strlen(p[col]) - 10] = '\0';
216         }
217
218         strcat(p[col], "\n");
219     }
220
221     for (int i = 0; i <= col; i++) {
222         fputs(p[i], fff);
223     }
224 }
225
226 /*!
227  * @brief プレイヤーの職業能力情報をファイルにダンプする
228  * @param player_ptr プレイヤーへの参照ポインタ
229  * @param fff ファイルポインタ
230  */
231 void dump_aux_class_special(player_type *player_ptr, FILE *fff)
232 {
233     switch (player_ptr->pclass) {
234     case CLASS_MAGIC_EATER: {
235         dump_magic_eater(player_ptr, fff);
236         return;
237     }
238     case CLASS_SMITH: {
239         dump_smith(player_ptr, fff);
240         return;
241     }
242     case CLASS_BLUE_MAGE: {
243         dump_blue_mage(player_ptr, fff);
244         return;
245     }
246     default:
247         return;
248     }
249 }