OSDN Git Service

1c807dffc4407cde97829a59fe6b1d6cdab74d51
[hengbandforosx/hengbandosx.git] / src / market / building-craft-weapon.cpp
1 #include "market/building-craft-weapon.h"
2 #include "artifact/fixed-art-types.h"
3 #include "combat/attack-accuracy.h"
4 #include "combat/shoot.h"
5 #include "core/player-update-types.h"
6 #include "core/stuff-handler.h"
7 #include "flavor/flavor-describer.h"
8 #include "flavor/object-flavor-types.h"
9 #include "floor/floor-object.h"
10 #include "inventory/inventory-slot-types.h"
11 #include "io/input-key-acceptor.h"
12 #include "market/building-util.h"
13 #include "object-enchant/tr-types.h"
14 #include "object-hook/hook-weapon.h"
15 #include "object/item-tester-hooker.h"
16 #include "object/item-use-flags.h"
17 #include "object/object-flags.h"
18 #include "player-base/player-class.h"
19 #include "realm/realm-hex-numbers.h"
20 #include "spell-realm/spells-hex.h"
21 #include "sv-definition/sv-weapon-types.h"
22 #include "system/object-type-definition.h"
23 #include "system/player-type-definition.h"
24 #include "term/screen-processor.h"
25 #include "term/term-color-types.h"
26 #include "util/bit-flags-calculator.h"
27 #include "view/display-messages.h"
28 #include "world/world.h"
29
30 /*!
31  * @brief 攻撃時スレイによるダメージ期待値修正計算 / critical happens at i / 10000
32  * @param dam 基本ダメージ
33  * @param mult スレイ倍率(掛け算部分)
34  * @param div スレイ倍率(割り算部分)
35  * @param force 理力特別計算フラグ
36  * @return ダメージ期待値
37  */
38 static HIT_POINT calc_slaydam(HIT_POINT dam, int mult, int div, bool force)
39 {
40     int tmp;
41     if (force) {
42         tmp = dam * 60;
43         tmp *= mult * 3;
44         tmp /= div * 2;
45         tmp += dam * 60 * 2;
46         tmp /= 60;
47         return tmp;
48     }
49
50     tmp = dam * 60;
51     tmp *= mult;
52     tmp /= div;
53     tmp /= 60;
54     return tmp;
55 }
56
57 /*!
58  * @brief 攻撃時の期待値計算(スレイ→重量クリティカル→切れ味効果)
59  * @param player_ptr プレイヤーへの参照ポインタ
60  * @param dam 基本ダメージ
61  * @param mult スレイ倍率(掛け算部分)
62  * @param div スレイ倍率(割り算部分)
63  * @param force 理力特別計算フラグ
64  * @param weight 重量
65  * @param plus 武器ダメージ修正
66  * @param meichuu 命中値
67  * @param dokubari 毒針処理か否か
68  * @param impact 強撃か否か
69  * @param vorpal_mult 切れ味倍率(掛け算部分)
70  * @param vorpal_div 切れ味倍率(割り算部分)
71  * @return ダメージ期待値
72  */
73 static uint32_t calc_expect_dice(
74     PlayerType *player_ptr, uint32_t dam, int mult, int div, bool force, WEIGHT weight, int plus, int16_t meichuu, bool dokubari, bool impact, int vorpal_mult, int vorpal_div)
75 {
76     dam = calc_slaydam(dam, mult, div, force);
77     dam = calc_expect_crit(player_ptr, weight, plus, dam, meichuu, dokubari, impact);
78     dam = calc_slaydam(dam, vorpal_mult, vorpal_div, false);
79     return dam;
80 }
81
82 /*!
83  * @brief 武器の各条件毎のダメージ期待値を表示する。
84  * @param r 表示行
85  * @param c 表示列
86  * @param mindice ダイス部分最小値
87  * @param maxdice ダイス部分最大値
88  * @param blows 攻撃回数
89  * @param dam_bonus ダメージ修正値
90  * @param attr 条件内容
91  * @param color 条件内容の表示色
92  * @details
93  * Display the damage figure of an object\n
94  * (used by compare_weapon_aux)\n
95  * \n
96  * Only accurate for the current weapon, because it includes\n
97  * the current +dam of the player.\n
98  */
99 static void show_weapon_dmg(int r, int c, int mindice, int maxdice, int blows, int dam_bonus, concptr attr, byte color)
100 {
101     c_put_str(color, attr, r, c);
102     GAME_TEXT tmp_str[80];
103     int mindam = blows * (mindice + dam_bonus);
104     int maxdam = blows * (maxdice + dam_bonus);
105     sprintf(tmp_str, _("1ターン: %d-%d ダメージ", "Attack: %d-%d damage"), mindam, maxdam);
106     put_str(tmp_str, r, c + 8);
107 }
108
109 /*!
110  * @brief 武器一つ毎のダメージ情報を表示する。
111  * @param o_ptr オブジェクトの構造体の参照ポインタ。
112  * @param col 表示する行の上端
113  * @param r 表示する列の左端
114  * @details
115  * Show the damage figures for the various monster types\n
116  * \n
117  * Only accurate for the current weapon, because it includes\n
118  * the current number of blows for the player.\n
119  */
120 static void compare_weapon_aux(PlayerType *player_ptr, ObjectType *o_ptr, int col, int r)
121 {
122     int blow = player_ptr->num_blow[0];
123     bool force = false;
124     bool dokubari = false;
125
126     int eff_dd = o_ptr->dd + player_ptr->to_dd[0];
127     int eff_ds = o_ptr->ds + player_ptr->to_ds[0];
128
129     int mindice = eff_dd;
130     int maxdice = eff_ds * eff_dd;
131     int mindam = 0;
132     int maxdam = 0;
133     int vorpal_mult = 1;
134     int vorpal_div = 1;
135     int dmg_bonus = o_ptr->to_d + player_ptr->to_d[0];
136
137     auto flgs = object_flags(o_ptr);
138     if ((o_ptr->tval == ItemKindType::SWORD) && (o_ptr->sval == SV_POISON_NEEDLE))
139         dokubari = true;
140
141     bool impact = flgs.has(TR_IMPACT) || (player_ptr->impact != 0);
142     mindam = calc_expect_crit(player_ptr, o_ptr->weight, o_ptr->to_h, mindice, player_ptr->to_h[0], dokubari, impact);
143     maxdam = calc_expect_crit(player_ptr, o_ptr->weight, o_ptr->to_h, maxdice, player_ptr->to_h[0], dokubari, impact);
144     show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("会心:", "Critical:"), TERM_L_RED);
145     if ((flgs.has(TR_VORPAL) || SpellHex(player_ptr).is_spelling_specific(HEX_RUNESWORD))) {
146         if ((o_ptr->name1 == ART_VORPAL_BLADE) || (o_ptr->name1 == ART_CHAINSWORD)) {
147             vorpal_mult = 5;
148             vorpal_div = 3;
149         } else {
150             vorpal_mult = 11;
151             vorpal_div = 9;
152         }
153
154         mindam = calc_expect_dice(player_ptr, mindice, 1, 1, false, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
155         maxdam = calc_expect_dice(player_ptr, maxdice, 1, 1, false, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
156         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("切れ味:", "Vorpal:"), TERM_L_RED);
157     }
158
159     if (!PlayerClass(player_ptr).equals(PlayerClassType::SAMURAI) && flgs.has(TR_FORCE_WEAPON) && (player_ptr->csp > (o_ptr->dd * o_ptr->ds / 5))) {
160         force = true;
161
162         mindam = calc_expect_dice(player_ptr, mindice, 1, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
163         maxdam = calc_expect_dice(player_ptr, maxdice, 1, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
164         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("理力:", "Force  :"), TERM_L_BLUE);
165     }
166
167     if (flgs.has(TR_KILL_ANIMAL)) {
168         mindam = calc_expect_dice(player_ptr, mindice, 4, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
169         maxdam = calc_expect_dice(player_ptr, maxdice, 4, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
170         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("動物:", "Animals:"), TERM_YELLOW);
171     } else if (flgs.has(TR_SLAY_ANIMAL)) {
172         mindam = calc_expect_dice(player_ptr, mindice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
173         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
174         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("動物:", "Animals:"), TERM_YELLOW);
175     }
176
177     if (flgs.has(TR_KILL_EVIL)) {
178         mindam = calc_expect_dice(player_ptr, mindice, 7, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
179         maxdam = calc_expect_dice(player_ptr, maxdice, 7, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
180         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("邪悪:", "Evil:"), TERM_YELLOW);
181     } else if (flgs.has(TR_SLAY_EVIL)) {
182         mindam = calc_expect_dice(player_ptr, mindice, 2, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
183         maxdam = calc_expect_dice(player_ptr, maxdice, 2, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
184         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("邪悪:", "Evil:"), TERM_YELLOW);
185     }
186
187     if (flgs.has(TR_KILL_GOOD)) {
188         mindam = calc_expect_dice(player_ptr, mindice, 7, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
189         maxdam = calc_expect_dice(player_ptr, maxdice, 7, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
190         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("善良:", "Good:"), TERM_YELLOW);
191     } else if (flgs.has(TR_SLAY_GOOD)) {
192         mindam = calc_expect_dice(player_ptr, mindice, 2, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
193         maxdam = calc_expect_dice(player_ptr, maxdice, 2, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
194         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("善良:", "Good:"), TERM_YELLOW);
195     }
196
197     if (flgs.has(TR_KILL_HUMAN)) {
198         mindam = calc_expect_dice(player_ptr, mindice, 4, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
199         maxdam = calc_expect_dice(player_ptr, maxdice, 4, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
200         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("人間:", "Human:"), TERM_YELLOW);
201     } else if (flgs.has(TR_SLAY_HUMAN)) {
202         mindam = calc_expect_dice(player_ptr, mindice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
203         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
204         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("人間:", "Human:"), TERM_YELLOW);
205     }
206
207     if (flgs.has(TR_KILL_UNDEAD)) {
208         mindam = calc_expect_dice(player_ptr, mindice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
209         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
210         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("不死:", "Undead:"), TERM_YELLOW);
211     } else if (flgs.has(TR_SLAY_UNDEAD)) {
212         mindam = calc_expect_dice(player_ptr, mindice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
213         maxdam = calc_expect_dice(player_ptr, maxdice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
214         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("不死:", "Undead:"), TERM_YELLOW);
215     }
216
217     if (flgs.has(TR_KILL_DEMON)) {
218         mindam = calc_expect_dice(player_ptr, mindice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
219         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
220         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("悪魔:", "Demons:"), TERM_YELLOW);
221     } else if (flgs.has(TR_SLAY_DEMON)) {
222         mindam = calc_expect_dice(player_ptr, mindice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
223         maxdam = calc_expect_dice(player_ptr, maxdice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
224         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("悪魔:", "Demons:"), TERM_YELLOW);
225     }
226
227     if (flgs.has(TR_KILL_ORC)) {
228         mindam = calc_expect_dice(player_ptr, mindice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
229         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
230         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("オーク:", "Orcs:"), TERM_YELLOW);
231     } else if (flgs.has(TR_SLAY_ORC)) {
232         mindam = calc_expect_dice(player_ptr, mindice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
233         maxdam = calc_expect_dice(player_ptr, maxdice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
234         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("オーク:", "Orcs:"), TERM_YELLOW);
235     }
236
237     if (flgs.has(TR_KILL_TROLL)) {
238         mindam = calc_expect_dice(player_ptr, mindice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
239         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
240         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("トロル:", "Trolls:"), TERM_YELLOW);
241     } else if (flgs.has(TR_SLAY_TROLL)) {
242         mindam = calc_expect_dice(player_ptr, mindice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
243         maxdam = calc_expect_dice(player_ptr, maxdice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
244         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("トロル:", "Trolls:"), TERM_YELLOW);
245     }
246
247     if (flgs.has(TR_KILL_GIANT)) {
248         mindam = calc_expect_dice(player_ptr, mindice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
249         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
250         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("巨人:", "Giants:"), TERM_YELLOW);
251     } else if (flgs.has(TR_SLAY_GIANT)) {
252         mindam = calc_expect_dice(player_ptr, mindice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
253         maxdam = calc_expect_dice(player_ptr, maxdice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
254         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("巨人:", "Giants:"), TERM_YELLOW);
255     }
256
257     if (flgs.has(TR_KILL_DRAGON)) {
258         mindam = calc_expect_dice(player_ptr, mindice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
259         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
260         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("竜:", "Dragons:"), TERM_YELLOW);
261     } else if (flgs.has(TR_SLAY_DRAGON)) {
262         mindam = calc_expect_dice(player_ptr, mindice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
263         maxdam = calc_expect_dice(player_ptr, maxdice, 3, 1, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
264         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("竜:", "Dragons:"), TERM_YELLOW);
265     }
266
267     if (flgs.has(TR_BRAND_ACID)) {
268         mindam = calc_expect_dice(player_ptr, mindice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
269         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
270         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("酸属性:", "Acid:"), TERM_RED);
271     }
272
273     if (flgs.has(TR_BRAND_ELEC)) {
274         mindam = calc_expect_dice(player_ptr, mindice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
275         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
276         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("電属性:", "Elec:"), TERM_RED);
277     }
278
279     if (flgs.has(TR_BRAND_FIRE)) {
280         mindam = calc_expect_dice(player_ptr, mindice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
281         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
282         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("炎属性:", "Fire:"), TERM_RED);
283     }
284
285     if (flgs.has(TR_BRAND_COLD)) {
286         mindam = calc_expect_dice(player_ptr, mindice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
287         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
288         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("冷属性:", "Cold:"), TERM_RED);
289     }
290
291     if (flgs.has(TR_BRAND_POIS)) {
292         mindam = calc_expect_dice(player_ptr, mindice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
293         maxdam = calc_expect_dice(player_ptr, maxdice, 5, 2, force, o_ptr->weight, o_ptr->to_h, player_ptr->to_h[0], dokubari, impact, vorpal_mult, vorpal_div);
294         show_weapon_dmg(r++, col, mindam, maxdam, blow, dmg_bonus, _("毒属性:", "Poison:"), TERM_RED);
295     }
296 }
297
298 /*!
299  * @brief 武器匠における武器一つ毎の完全情報を表示する。
300  * @param PlayerType プレイヤーへの参照ポインタ
301  * @param o_ptr オブジェクトの構造体の参照ポインタ。
302  * @param row 表示する列の左端
303  * @param col 表示する行の上端
304  * @details
305  * Displays all info about a weapon
306  *
307  * Only accurate for the current weapon, because it includes
308  * various info about the player's +to_dam and number of blows.
309  */
310 static void list_weapon(PlayerType *player_ptr, ObjectType *o_ptr, TERM_LEN row, TERM_LEN col)
311 {
312     GAME_TEXT o_name[MAX_NLEN];
313     GAME_TEXT tmp_str[80];
314
315     DICE_NUMBER eff_dd = o_ptr->dd + player_ptr->to_dd[0];
316     DICE_SID eff_ds = o_ptr->ds + player_ptr->to_ds[0];
317     auto hit_reliability = player_ptr->skill_thn + (player_ptr->to_h[0] + o_ptr->to_h) * BTH_PLUS_ADJ;
318
319     describe_flavor(player_ptr, o_name, o_ptr, OD_NAME_ONLY);
320     c_put_str(TERM_YELLOW, o_name, row, col);
321     sprintf(tmp_str, _("攻撃回数: %d", "Number of Blows: %d"), player_ptr->num_blow[0]);
322     put_str(tmp_str, row + 1, col);
323
324     sprintf(tmp_str, _("命中率:  0  50 100 150 200 (敵のAC)", "To Hit:  0  50 100 150 200 (AC)"));
325     put_str(tmp_str, row + 2, col);
326     sprintf(tmp_str, "        %2d  %2d  %2d  %2d  %2d (%%)", (int)hit_chance(player_ptr, hit_reliability, 0), (int)hit_chance(player_ptr, hit_reliability, 50),
327         (int)hit_chance(player_ptr, hit_reliability, 100), (int)hit_chance(player_ptr, hit_reliability, 150), (int)hit_chance(player_ptr, hit_reliability, 200));
328     put_str(tmp_str, row + 3, col);
329     c_put_str(TERM_YELLOW, _("可能なダメージ:", "Possible Damage:"), row + 5, col);
330
331     sprintf(tmp_str, _("攻撃一回につき %d-%d", "One Strike: %d-%d damage"), (int)(eff_dd + o_ptr->to_d + player_ptr->to_d[0]),
332         (int)(eff_ds * eff_dd + o_ptr->to_d + player_ptr->to_d[0]));
333     put_str(tmp_str, row + 6, col + 1);
334
335     sprintf(tmp_str, _("1ターンにつき %d-%d", "One Attack: %d-%d damage"), (int)(player_ptr->num_blow[0] * (eff_dd + o_ptr->to_d + player_ptr->to_d[0])),
336         (int)(player_ptr->num_blow[0] * (eff_ds * eff_dd + o_ptr->to_d + player_ptr->to_d[0])));
337     put_str(tmp_str, row + 7, col + 1);
338 }
339
340 /*!
341  * @brief 武器匠鑑定1回分(オブジェクト2種)の処理。/ Compare weapons
342  * @details
343  * Copies the weapons to compare into the weapon-slot and\n
344  * compares the values for both weapons.\n
345  * 武器1つだけで比較をしないなら費用は半額になる。
346  * @param bcost 基本鑑定費用
347  * @return 最終的にかかった費用
348  */
349 PRICE compare_weapons(PlayerType *player_ptr, PRICE bcost)
350 {
351     ObjectType *o_ptr[2];
352     ObjectType orig_weapon;
353     ObjectType *i_ptr;
354     TERM_LEN row = 2;
355     TERM_LEN wid = 38, mgn = 2;
356     bool old_character_xtra = w_ptr->character_xtra;
357     char ch;
358     PRICE total = 0;
359     PRICE cost = 0; /* First time no price */
360
361     screen_save();
362     clear_bldg(0, 22);
363     i_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND];
364     (&orig_weapon)->copy_from(i_ptr);
365
366     concptr q = _("第一の武器は?", "What is your first weapon? ");
367     concptr s = _("比べるものがありません。", "You have nothing to compare.");
368
369     OBJECT_IDX item;
370     o_ptr[0] = choose_object(player_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | IGNORE_BOTHHAND_SLOT), FuncItemTester(&ObjectType::is_orthodox_melee_weapons));
371     if (!o_ptr[0]) {
372         screen_load();
373         return 0;
374     }
375
376     int n = 1;
377     total = bcost;
378
379     while (true) {
380         clear_bldg(0, 22);
381         w_ptr->character_xtra = true;
382         for (int i = 0; i < n; i++) {
383             int col = (wid * i + mgn);
384             if (o_ptr[i] != i_ptr)
385                 i_ptr->copy_from(o_ptr[i]);
386
387             player_ptr->update |= PU_BONUS;
388             handle_stuff(player_ptr);
389
390             list_weapon(player_ptr, o_ptr[i], row, col);
391             compare_weapon_aux(player_ptr, o_ptr[i], col, row + 8);
392             i_ptr->copy_from(&orig_weapon);
393         }
394
395         player_ptr->update |= PU_BONUS;
396         handle_stuff(player_ptr);
397
398         w_ptr->character_xtra = old_character_xtra;
399 #ifdef JP
400         put_str(format("[ 比較対象: 's'で変更 ($%d) ]", cost), 1, (wid + mgn));
401         put_str("(一番高いダメージが適用されます。複数の倍打効果は足し算されません。)", row + 4, 0);
402         prt("現在の技量から判断すると、あなたの武器は以下のような威力を発揮します:", 0, 0);
403 #else
404         put_str(format("[ 's' Select secondary weapon($%d) ]", cost), 1, (wid + mgn));
405         put_str("(Only highest damage applies per monster. Special damage not cumulative.)", row + 4, 0);
406         prt("Based on your current abilities, here is what your weapons will do", 0, 0);
407 #endif
408
409         flush();
410         ch = inkey();
411         if (ch != 's')
412             break;
413
414         if (total + cost > player_ptr->au) {
415             msg_print(_("お金が足りません!", "You don't have enough money!"));
416             msg_print(nullptr);
417             continue;
418         }
419
420         q = _("第二の武器は?", "What is your second weapon? ");
421         s = _("比べるものがありません。", "You have nothing to compare.");
422         OBJECT_IDX item2;
423         ObjectType *i2_ptr = choose_object(player_ptr, &item2, q, s, (USE_EQUIP | USE_INVEN | IGNORE_BOTHHAND_SLOT), FuncItemTester(&ObjectType::is_orthodox_melee_weapons));
424         if (!i2_ptr)
425             continue;
426
427         if (i2_ptr == o_ptr[0] || (n == 2 && i2_ptr == o_ptr[1])) {
428             msg_print(_("表示中の武器は選べません!", "Select a different weapon than those displayed."));
429             msg_print(nullptr);
430             continue;
431         }
432
433         o_ptr[1] = i2_ptr;
434         total += cost;
435         cost = bcost / 2;
436         n = 2;
437     }
438
439     screen_load();
440     return total;
441 }