OSDN Git Service

Merge pull request #2725 from Hourier/Move-Feature-to-System
[hengbandforosx/hengbandosx.git] / src / player / player-status.cpp
1 #include "player/player-status.h"
2 #include "artifact/fixed-art-types.h"
3 #include "autopick/autopick-reader-writer.h"
4 #include "autopick/autopick.h"
5 #include "avatar/avatar.h"
6 #include "cmd-action/cmd-pet.h"
7 #include "cmd-action/cmd-spell.h"
8 #include "cmd-io/cmd-dump.h"
9 #include "cmd-item/cmd-magiceat.h"
10 #include "combat/attack-power-table.h"
11 #include "core/asking-player.h"
12 #include "core/player-redraw-types.h"
13 #include "core/player-update-types.h"
14 #include "core/stuff-handler.h"
15 #include "core/window-redrawer.h"
16 #include "dungeon/dungeon-flag-types.h"
17 #include "effect/effect-characteristics.h"
18 #include "floor/cave.h"
19 #include "floor/floor-events.h"
20 #include "floor/floor-leaver.h"
21 #include "floor/floor-save.h"
22 #include "floor/floor-util.h"
23 #include "game-option/birth-options.h"
24 #include "grid/feature.h"
25 #include "grid/grid.h"
26 #include "inventory/inventory-object.h"
27 #include "io/input-key-acceptor.h"
28 #include "io/write-diary.h"
29 #include "main/sound-definitions-table.h"
30 #include "main/sound-of-music.h"
31 #include "market/arena-info-table.h"
32 #include "mind/mind-force-trainer.h"
33 #include "mind/mind-ninja.h"
34 #include "monster-floor/monster-lite.h"
35 #include "monster-floor/monster-remover.h"
36 #include "monster-race/monster-race-hook.h"
37 #include "monster-race/monster-race.h"
38 #include "monster-race/race-flags1.h"
39 #include "monster-race/race-flags2.h"
40 #include "monster-race/race-flags7.h"
41 #include "monster/monster-update.h"
42 #include "monster/smart-learn-types.h"
43 #include "mutation/mutation-calculator.h"
44 #include "mutation/mutation-flag-types.h"
45 #include "mutation/mutation-investor-remover.h"
46 #include "object-enchant/object-ego.h"
47 #include "object-enchant/special-object-flags.h"
48 #include "object-enchant/tr-types.h"
49 #include "object-enchant/trc-types.h"
50 #include "object-hook/hook-armor.h"
51 #include "object/object-flags.h"
52 #include "object/object-info.h"
53 #include "object/object-mark-types.h"
54 #include "perception/object-perception.h"
55 #include "pet/pet-util.h"
56 #include "player-ability/player-charisma.h"
57 #include "player-ability/player-constitution.h"
58 #include "player-ability/player-dexterity.h"
59 #include "player-ability/player-intelligence.h"
60 #include "player-ability/player-strength.h"
61 #include "player-ability/player-wisdom.h"
62 #include "player-base/player-class.h"
63 #include "player-base/player-race.h"
64 #include "player-info/alignment.h"
65 #include "player-info/class-info.h"
66 #include "player-info/equipment-info.h"
67 #include "player-info/mimic-info-table.h"
68 #include "player-info/monk-data-type.h"
69 #include "player-info/samurai-data-type.h"
70 #include "player-info/sniper-data-type.h"
71 #include "player-status/player-basic-statistics.h"
72 #include "player-status/player-hand-types.h"
73 #include "player-status/player-infravision.h"
74 #include "player-status/player-speed.h"
75 #include "player-status/player-stealth.h"
76 #include "player/attack-defense-types.h"
77 #include "player/digestion-processor.h"
78 #include "player/patron.h"
79 #include "player/player-damage.h"
80 #include "player/player-move.h"
81 #include "player/player-personality-types.h"
82 #include "player/player-personality.h"
83 #include "player/player-skill.h"
84 #include "player/player-status-flags.h"
85 #include "player/player-status-table.h"
86 #include "player/player-view.h"
87 #include "player/race-info-table.h"
88 #include "player/special-defense-types.h"
89 #include "realm/realm-hex-numbers.h"
90 #include "realm/realm-names-table.h"
91 #include "realm/realm-song-numbers.h"
92 #include "specific-object/bow.h"
93 #include "specific-object/torch.h"
94 #include "spell-realm/spells-hex.h"
95 #include "spell-realm/spells-song.h"
96 #include "spell/range-calc.h"
97 #include "spell/spells-describer.h"
98 #include "spell/spells-execution.h"
99 #include "spell/spells-status.h"
100 #include "spell/technic-info-table.h"
101 #include "status/action-setter.h"
102 #include "status/base-status.h"
103 #include "sv-definition/sv-lite-types.h"
104 #include "sv-definition/sv-weapon-types.h"
105 #include "system/dungeon-info.h"
106 #include "system/floor-type-definition.h"
107 #include "system/grid-type-definition.h"
108 #include "system/monster-race-definition.h"
109 #include "system/monster-type-definition.h"
110 #include "system/object-type-definition.h"
111 #include "system/player-type-definition.h"
112 #include "system/terrain-type-definition.h"
113 #include "term/screen-processor.h"
114 #include "timed-effect/player-acceleration.h"
115 #include "timed-effect/player-stun.h"
116 #include "timed-effect/timed-effects.h"
117 #include "util/bit-flags-calculator.h"
118 #include "util/enum-converter.h"
119 #include "util/quarks.h"
120 #include "util/string-processor.h"
121 #include "view/display-messages.h"
122 #include "world/world.h"
123
124 static const int extra_magic_glove_reduce_mana = 1;
125
126 static bool is_martial_arts_mode(PlayerType *player_ptr);
127
128 static ACTION_SKILL_POWER calc_disarming(PlayerType *player_ptr);
129 static ACTION_SKILL_POWER calc_device_ability(PlayerType *player_ptr);
130 static ACTION_SKILL_POWER calc_saving_throw(PlayerType *player_ptr);
131 static ACTION_SKILL_POWER calc_search(PlayerType *player_ptr);
132 static ACTION_SKILL_POWER calc_search_freq(PlayerType *player_ptr);
133 static ACTION_SKILL_POWER calc_to_hit_melee(PlayerType *player_ptr);
134 static ACTION_SKILL_POWER calc_to_hit_shoot(PlayerType *player_ptr);
135 static ACTION_SKILL_POWER calc_to_hit_throw(PlayerType *player_ptr);
136 static ACTION_SKILL_POWER calc_skill_dig(PlayerType *player_ptr);
137 static bool is_heavy_wield(PlayerType *player_ptr, int i);
138 static int16_t calc_num_blow(PlayerType *player_ptr, int i);
139 static int16_t calc_to_magic_chance(PlayerType *player_ptr);
140 static ARMOUR_CLASS calc_base_ac(PlayerType *player_ptr);
141 static ARMOUR_CLASS calc_to_ac(PlayerType *player_ptr, bool is_real_value);
142 static int16_t calc_double_weapon_penalty(PlayerType *player_ptr, INVENTORY_IDX slot);
143 static bool is_riding_two_hands(PlayerType *player_ptr);
144 static int16_t calc_riding_bow_penalty(PlayerType *player_ptr);
145 static void put_equipment_warning(PlayerType *player_ptr);
146
147 static short calc_to_damage(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value);
148 static int16_t calc_to_hit(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value);
149
150 static int16_t calc_to_hit_bow(PlayerType *player_ptr, bool is_real_value);
151
152 static int16_t calc_to_damage_misc(PlayerType *player_ptr);
153 static int16_t calc_to_hit_misc(PlayerType *player_ptr);
154
155 static DICE_NUMBER calc_to_weapon_dice_num(PlayerType *player_ptr, INVENTORY_IDX slot);
156 static player_hand main_attack_hand(PlayerType *player_ptr);
157
158 /*** Player information ***/
159
160 /*!
161  * @brief 遅延描画更新 / Delayed visual update
162  * @details update_view(), update_lite(), update_mon_lite() においてのみ更新すること / Only used if update_view(), update_lite() or update_mon_lite() was called
163  * @param player_ptr 主観となるプレイヤー構造体参照ポインタ
164  * @todo 将来独自インターフェース実装にはz-term系に追い出すべきか?
165  */
166 static void delayed_visual_update(PlayerType *player_ptr)
167 {
168     auto *floor_ptr = player_ptr->current_floor_ptr;
169     for (int i = 0; i < floor_ptr->redraw_n; i++) {
170         POSITION y = floor_ptr->redraw_y[i];
171         POSITION x = floor_ptr->redraw_x[i];
172         grid_type *g_ptr;
173         g_ptr = &floor_ptr->grid_array[y][x];
174         if (none_bits(g_ptr->info, CAVE_REDRAW)) {
175             continue;
176         }
177
178         if (any_bits(g_ptr->info, CAVE_NOTE)) {
179             note_spot(player_ptr, y, x);
180         }
181
182         lite_spot(player_ptr, y, x);
183         if (g_ptr->m_idx) {
184             update_monster(player_ptr, g_ptr->m_idx, false);
185         }
186
187         reset_bits(g_ptr->info, (CAVE_NOTE | CAVE_REDRAW));
188     }
189
190     floor_ptr->redraw_n = 0;
191 }
192
193 /*!
194  * @brief 射撃武器がプレイヤーにとって重すぎるかどうかの判定 /
195  * @param o_ptr 判定する射撃武器のアイテム情報参照ポインタ
196  * @return 重すぎるならばTRUE
197  */
198 static bool is_heavy_shoot(PlayerType *player_ptr, ObjectType *o_ptr)
199 {
200     return calc_bow_weight_limit(player_ptr) < (o_ptr->weight / 10);
201 }
202
203 /*!
204  * @brief 所持品総重量を計算する
205  * @param player_ptr プレイヤーへの参照ポインタ
206  * @return 総重量
207  */
208 WEIGHT calc_inventory_weight(PlayerType *player_ptr)
209 {
210     WEIGHT weight = 0;
211
212     ObjectType *o_ptr;
213     for (int i = 0; i < INVEN_TOTAL; i++) {
214         o_ptr = &player_ptr->inventory_list[i];
215         if (!o_ptr->k_idx) {
216             continue;
217         }
218         weight += o_ptr->weight * o_ptr->number;
219     }
220     return weight;
221 }
222
223 static void update_ability_scores(PlayerType *player_ptr)
224 {
225     PlayerStrength player_str(player_ptr);
226     PlayerIntelligence player_int(player_ptr);
227     PlayerWisdom player_wis(player_ptr);
228     PlayerDexterity player_dex(player_ptr);
229     PlayerConstitution player_con(player_ptr);
230     PlayerCharisma player_chr(player_ptr);
231     PlayerBasicStatistics *player_stats[] = { &player_str, &player_int, &player_wis, &player_dex, &player_con, &player_chr };
232     for (auto i = 0; i < A_MAX; ++i) {
233         player_ptr->stat_add[i] = player_stats[i]->modification_value();
234         player_stats[i]->update_value();
235     }
236 }
237
238 /*!
239  * @brief プレイヤーの全ステータスを更新する /
240  * Calculate the players current "state", taking into account
241  * not only race/class intrinsics, but also objects being worn
242  * and temporary spell effects.
243  * @details
244  * <pre>
245  * See also update_max_mana() and update_max_hitpoints().
246  *
247  * Take note of the new "speed code", in particular, a very strong
248  * player will start slowing down as soon as he reaches 150 pounds,
249  * but not until he reaches 450 pounds will he be half as fast as
250  * a normal kobold.  This both hurts and helps the player, hurts
251  * because in the old days a player could just avoid 300 pounds,
252  * and helps because now carrying 300 pounds is not very painful.
253  *
254  * The "weapon" and "bow" do *not* add to the bonuses to hit or to
255  * damage, since that would affect non-combat things.  These values
256  * are actually added in later, at the appropriate place.
257  *
258  * This function induces various "status" messages.
259  * </pre>
260  * @todo ここで計算していた各値は一部の状態変化メッセージ処理を除き、今後必要な時に適示計算する形に移行するためほぼすべて削られる。
261  */
262 static void update_bonuses(PlayerType *player_ptr)
263 {
264     auto empty_hands_status = empty_hands(player_ptr, true);
265     ObjectType *o_ptr;
266
267     /* Save the old vision stuff */
268     BIT_FLAGS old_telepathy = player_ptr->telepathy;
269     BIT_FLAGS old_esp_animal = player_ptr->esp_animal;
270     BIT_FLAGS old_esp_undead = player_ptr->esp_undead;
271     BIT_FLAGS old_esp_demon = player_ptr->esp_demon;
272     BIT_FLAGS old_esp_orc = player_ptr->esp_orc;
273     BIT_FLAGS old_esp_troll = player_ptr->esp_troll;
274     BIT_FLAGS old_esp_giant = player_ptr->esp_giant;
275     BIT_FLAGS old_esp_dragon = player_ptr->esp_dragon;
276     BIT_FLAGS old_esp_human = player_ptr->esp_human;
277     BIT_FLAGS old_esp_evil = player_ptr->esp_evil;
278     BIT_FLAGS old_esp_good = player_ptr->esp_good;
279     BIT_FLAGS old_esp_nonliving = player_ptr->esp_nonliving;
280     BIT_FLAGS old_esp_unique = player_ptr->esp_unique;
281     BIT_FLAGS old_see_inv = player_ptr->see_inv;
282     BIT_FLAGS old_mighty_throw = player_ptr->mighty_throw;
283     int16_t old_speed = player_ptr->pspeed;
284
285     ARMOUR_CLASS old_dis_ac = player_ptr->dis_ac;
286     ARMOUR_CLASS old_dis_to_a = player_ptr->dis_to_a;
287
288     player_ptr->xtra_might = has_xtra_might(player_ptr);
289     player_ptr->esp_evil = has_esp_evil(player_ptr);
290     player_ptr->esp_animal = has_esp_animal(player_ptr);
291     player_ptr->esp_undead = has_esp_undead(player_ptr);
292     player_ptr->esp_demon = has_esp_demon(player_ptr);
293     player_ptr->esp_orc = has_esp_orc(player_ptr);
294     player_ptr->esp_troll = has_esp_troll(player_ptr);
295     player_ptr->esp_giant = has_esp_giant(player_ptr);
296     player_ptr->esp_dragon = has_esp_dragon(player_ptr);
297     player_ptr->esp_human = has_esp_human(player_ptr);
298     player_ptr->esp_good = has_esp_good(player_ptr);
299     player_ptr->esp_nonliving = has_esp_nonliving(player_ptr);
300     player_ptr->esp_unique = has_esp_unique(player_ptr);
301     player_ptr->telepathy = has_esp_telepathy(player_ptr);
302     player_ptr->bless_blade = has_bless_blade(player_ptr);
303     player_ptr->easy_2weapon = has_easy2_weapon(player_ptr);
304     player_ptr->down_saving = has_down_saving(player_ptr);
305     player_ptr->yoiyami = has_no_ac(player_ptr);
306     player_ptr->mighty_throw = has_mighty_throw(player_ptr);
307     player_ptr->dec_mana = has_dec_mana(player_ptr);
308     player_ptr->see_nocto = has_see_nocto(player_ptr);
309     player_ptr->warning = has_warning(player_ptr);
310     player_ptr->anti_magic = has_anti_magic(player_ptr);
311     player_ptr->anti_tele = has_anti_tele(player_ptr);
312     player_ptr->easy_spell = has_easy_spell(player_ptr);
313     player_ptr->heavy_spell = has_heavy_spell(player_ptr);
314     player_ptr->hold_exp = has_hold_exp(player_ptr);
315     player_ptr->see_inv = has_see_inv(player_ptr);
316     player_ptr->free_act = has_free_act(player_ptr);
317     player_ptr->levitation = has_levitation(player_ptr);
318     player_ptr->can_swim = has_can_swim(player_ptr);
319     player_ptr->slow_digest = has_slow_digest(player_ptr);
320     player_ptr->regenerate = has_regenerate(player_ptr);
321     update_curses(player_ptr);
322     player_ptr->impact = has_impact(player_ptr);
323     player_ptr->earthquake = has_earthquake(player_ptr);
324     update_extra_blows(player_ptr);
325
326     player_ptr->lite = has_lite(player_ptr);
327
328     if (!PlayerClass(player_ptr).monk_stance_is(MonkStanceType::NONE)) {
329         if (none_bits(empty_hands_status, EMPTY_HAND_MAIN)) {
330             set_action(player_ptr, ACTION_NONE);
331         }
332     }
333
334     update_ability_scores(player_ptr);
335     o_ptr = &player_ptr->inventory_list[INVEN_BOW];
336     if (o_ptr->k_idx) {
337         player_ptr->tval_ammo = bow_tval_ammo(o_ptr);
338         player_ptr->num_fire = calc_num_fire(player_ptr, o_ptr);
339     }
340
341     for (int i = 0; i < 2; i++) {
342         player_ptr->is_icky_wield[i] = is_wielding_icky_weapon(player_ptr, i);
343         player_ptr->is_icky_riding_wield[i] = is_wielding_icky_riding_weapon(player_ptr, i);
344         player_ptr->heavy_wield[i] = is_heavy_wield(player_ptr, i);
345         player_ptr->num_blow[i] = calc_num_blow(player_ptr, i);
346         player_ptr->to_dd[i] = calc_to_weapon_dice_num(player_ptr, INVEN_MAIN_HAND + i);
347         player_ptr->to_ds[i] = 0;
348     }
349
350     player_ptr->pspeed = PlayerSpeed(player_ptr).get_value();
351     player_ptr->see_infra = PlayerInfravision(player_ptr).get_value();
352     player_ptr->skill_stl = PlayerStealth(player_ptr).get_value();
353     player_ptr->skill_dis = calc_disarming(player_ptr);
354     player_ptr->skill_dev = calc_device_ability(player_ptr);
355     player_ptr->skill_sav = calc_saving_throw(player_ptr);
356     player_ptr->skill_srh = calc_search(player_ptr);
357     player_ptr->skill_fos = calc_search_freq(player_ptr);
358     player_ptr->skill_thn = calc_to_hit_melee(player_ptr);
359     player_ptr->skill_thb = calc_to_hit_shoot(player_ptr);
360     player_ptr->skill_tht = calc_to_hit_throw(player_ptr);
361     player_ptr->riding_ryoute = is_riding_two_hands(player_ptr);
362     player_ptr->to_d[0] = calc_to_damage(player_ptr, INVEN_MAIN_HAND, true);
363     player_ptr->to_d[1] = calc_to_damage(player_ptr, INVEN_SUB_HAND, true);
364     player_ptr->dis_to_d[0] = calc_to_damage(player_ptr, INVEN_MAIN_HAND, false);
365     player_ptr->dis_to_d[1] = calc_to_damage(player_ptr, INVEN_SUB_HAND, false);
366     player_ptr->to_h[0] = calc_to_hit(player_ptr, INVEN_MAIN_HAND, true);
367     player_ptr->to_h[1] = calc_to_hit(player_ptr, INVEN_SUB_HAND, true);
368     player_ptr->dis_to_h[0] = calc_to_hit(player_ptr, INVEN_MAIN_HAND, false);
369     player_ptr->dis_to_h[1] = calc_to_hit(player_ptr, INVEN_SUB_HAND, false);
370     player_ptr->to_h_b = calc_to_hit_bow(player_ptr, true);
371     player_ptr->dis_to_h_b = calc_to_hit_bow(player_ptr, false);
372     player_ptr->to_d_m = calc_to_damage_misc(player_ptr);
373     player_ptr->to_h_m = calc_to_hit_misc(player_ptr);
374     player_ptr->skill_dig = calc_skill_dig(player_ptr);
375     player_ptr->to_m_chance = calc_to_magic_chance(player_ptr);
376     player_ptr->ac = calc_base_ac(player_ptr);
377     player_ptr->to_a = calc_to_ac(player_ptr, true);
378     player_ptr->dis_ac = calc_base_ac(player_ptr);
379     player_ptr->dis_to_a = calc_to_ac(player_ptr, false);
380
381     if (old_mighty_throw != player_ptr->mighty_throw) {
382         player_ptr->window_flags |= PW_INVEN;
383     }
384
385     if (player_ptr->telepathy != old_telepathy) {
386         set_bits(player_ptr->update, PU_MONSTERS);
387     }
388
389     if ((player_ptr->esp_animal != old_esp_animal) || (player_ptr->esp_undead != old_esp_undead) || (player_ptr->esp_demon != old_esp_demon) || (player_ptr->esp_orc != old_esp_orc) || (player_ptr->esp_troll != old_esp_troll) || (player_ptr->esp_giant != old_esp_giant) || (player_ptr->esp_dragon != old_esp_dragon) || (player_ptr->esp_human != old_esp_human) || (player_ptr->esp_evil != old_esp_evil) || (player_ptr->esp_good != old_esp_good) || (player_ptr->esp_nonliving != old_esp_nonliving) || (player_ptr->esp_unique != old_esp_unique)) {
390         set_bits(player_ptr->update, PU_MONSTERS);
391     }
392
393     if (player_ptr->see_inv != old_see_inv) {
394         set_bits(player_ptr->update, PU_MONSTERS);
395     }
396
397     if (player_ptr->pspeed != old_speed) {
398         set_bits(player_ptr->redraw, PR_SPEED);
399     }
400
401     if ((player_ptr->dis_ac != old_dis_ac) || (player_ptr->dis_to_a != old_dis_to_a)) {
402         set_bits(player_ptr->redraw, PR_ARMOR);
403         set_bits(player_ptr->window_flags, PW_PLAYER);
404     }
405
406     if (w_ptr->character_xtra) {
407         return;
408     }
409
410     put_equipment_warning(player_ptr);
411     check_no_flowed(player_ptr);
412 }
413
414 /*!
415  * @brief プレイヤーの最大HPを更新する /
416  * Update the players maximal hit points
417  * Adjust current hitpoints if necessary
418  * @details
419  */
420 static void update_max_hitpoints(PlayerType *player_ptr)
421 {
422     int bonus = ((int)(adj_con_mhp[player_ptr->stat_index[A_CON]]) - 128) * player_ptr->lev / 4;
423     int mhp = player_ptr->player_hp[player_ptr->lev - 1];
424
425     byte tmp_hitdie;
426     PlayerClass pc(player_ptr);
427     auto is_sorcerer = pc.equals(PlayerClassType::SORCERER);
428     if (player_ptr->mimic_form != MimicKindType::NONE) {
429         auto r_mhp = mimic_info.at(player_ptr->mimic_form).r_mhp;
430         if (is_sorcerer) {
431             tmp_hitdie = r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
432         } else {
433             tmp_hitdie = r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
434         }
435
436         mhp = mhp * tmp_hitdie / player_ptr->hitdie;
437     }
438
439     if (is_sorcerer) {
440         if (player_ptr->lev < 30) {
441             mhp = (mhp * (45 + player_ptr->lev) / 100);
442         } else {
443             mhp = (mhp * 75 / 100);
444         }
445         bonus = (bonus * 65 / 100);
446     }
447
448     mhp += bonus;
449
450     if (pc.equals(PlayerClassType::BERSERKER)) {
451         mhp = mhp * (110 + (((player_ptr->lev + 40) * (player_ptr->lev + 40) - 1550) / 110)) / 100;
452     }
453
454     if (mhp < player_ptr->lev + 1) {
455         mhp = player_ptr->lev + 1;
456     }
457     if (is_hero(player_ptr)) {
458         mhp += 10;
459     }
460     if (is_shero(player_ptr)) {
461         mhp += 30;
462     }
463     if (player_ptr->tsuyoshi) {
464         mhp += 50;
465     }
466     if (SpellHex(player_ptr).is_spelling_specific(HEX_XTRA_MIGHT)) {
467         mhp += 15;
468     }
469     if (SpellHex(player_ptr).is_spelling_specific(HEX_BUILDING)) {
470         mhp += 60;
471     }
472     if (player_ptr->mhp == mhp) {
473         return;
474     }
475
476     if (player_ptr->chp >= mhp) {
477         player_ptr->chp = mhp;
478         player_ptr->chp_frac = 0;
479     }
480
481 #ifdef JP
482     if (player_ptr->level_up_message && (mhp > player_ptr->mhp)) {
483         msg_format("最大ヒット・ポイントが %d 増加した!", (mhp - player_ptr->mhp));
484     }
485 #endif
486     player_ptr->mhp = mhp;
487
488     player_ptr->redraw |= PR_HP;
489     player_ptr->window_flags |= PW_PLAYER;
490 }
491
492 /*!
493  * @brief プレイヤーの現在学習可能な魔法数を計算し、増減に応じて魔法の忘却、再学習を処置する。 /
494  * Calculate number of spells player should have, and forget,
495  * or remember, spells until that number is properly reflected.
496  * @details
497  * Note that this function induces various "status" messages,
498  * which must be bypasses until the character is created.
499  */
500 static void update_num_of_spells(PlayerType *player_ptr)
501 {
502     if ((mp_ptr->spell_book == ItemKindType::NONE) || !w_ptr->character_generated || w_ptr->character_xtra) {
503         return;
504     }
505
506     PlayerClass pc(player_ptr);
507     if (pc.is_every_magic()) {
508         player_ptr->new_spells = 0;
509         return;
510     }
511
512     concptr p = spell_category_name(mp_ptr->spell_book);
513     int levels = player_ptr->lev - mp_ptr->spell_first + 1;
514     if (levels < 0) {
515         levels = 0;
516     }
517
518     int num_allowed = (adj_mag_study[player_ptr->stat_index[mp_ptr->spell_stat]] * levels / 2);
519     int bonus = 0;
520     if (!pc.equals(PlayerClassType::SAMURAI) && (mp_ptr->spell_book != ItemKindType::LIFE_BOOK)) {
521         bonus = 4;
522     }
523
524     if (pc.equals(PlayerClassType::SAMURAI)) {
525         num_allowed = 32;
526     } else if (player_ptr->realm2 == REALM_NONE) {
527         num_allowed = (num_allowed + 1) / 2;
528         if (num_allowed > (32 + bonus)) {
529             num_allowed = 32 + bonus;
530         }
531     } else if (pc.equals(PlayerClassType::MAGE) || pc.equals(PlayerClassType::PRIEST)) {
532         if (num_allowed > (96 + bonus)) {
533             num_allowed = 96 + bonus;
534         }
535     } else {
536         if (num_allowed > (80 + bonus)) {
537             num_allowed = 80 + bonus;
538         }
539     }
540
541     int num_boukyaku = 0;
542     for (int j = 0; j < 64; j++) {
543         if ((j < 32) ? any_bits(player_ptr->spell_forgotten1, (1UL << j)) : any_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)))) {
544             num_boukyaku++;
545         }
546     }
547
548     player_ptr->new_spells = num_allowed + player_ptr->add_spells + num_boukyaku - player_ptr->learned_spells;
549     for (int i = 63; i >= 0; i--) {
550         if (!player_ptr->spell_learned1 && !player_ptr->spell_learned2) {
551             break;
552         }
553
554         int j = player_ptr->spell_order[i];
555         if (j >= 99) {
556             continue;
557         }
558
559         const magic_type *s_ptr;
560         if (!is_magic((j < 32) ? player_ptr->realm1 : player_ptr->realm2)) {
561             if (j < 32) {
562                 s_ptr = &technic_info[player_ptr->realm1 - MIN_TECHNIC][j];
563             } else {
564                 s_ptr = &technic_info[player_ptr->realm2 - MIN_TECHNIC][j % 32];
565             }
566         } else if (j < 32) {
567             s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
568         } else {
569             s_ptr = &mp_ptr->info[player_ptr->realm2 - 1][j % 32];
570         }
571
572         if (s_ptr->slevel <= player_ptr->lev) {
573             continue;
574         }
575
576         bool is_spell_learned = (j < 32) ? any_bits(player_ptr->spell_learned1, (1UL << j)) : any_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
577         if (!is_spell_learned) {
578             continue;
579         }
580
581         int16_t which;
582         if (j < 32) {
583             set_bits(player_ptr->spell_forgotten1, (1UL << j));
584             which = player_ptr->realm1;
585         } else {
586             set_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
587             which = player_ptr->realm2;
588         }
589
590         if (j < 32) {
591             reset_bits(player_ptr->spell_learned1, (1UL << j));
592             which = player_ptr->realm1;
593         } else {
594             reset_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
595             which = player_ptr->realm2;
596         }
597
598 #ifdef JP
599         msg_format("%sの%sを忘れてしまった。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
600 #else
601         msg_format("You have forgotten the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
602 #endif
603         player_ptr->new_spells++;
604     }
605
606     /* Forget spells if we know too many spells */
607     for (int i = 63; i >= 0; i--) {
608         if (player_ptr->new_spells >= 0) {
609             break;
610         }
611         if (!player_ptr->spell_learned1 && !player_ptr->spell_learned2) {
612             break;
613         }
614
615         int j = player_ptr->spell_order[i];
616         if (j >= 99) {
617             continue;
618         }
619
620         bool is_spell_learned = (j < 32) ? any_bits(player_ptr->spell_learned1, (1UL << j)) : any_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
621         if (!is_spell_learned) {
622             continue;
623         }
624
625         int16_t which;
626         if (j < 32) {
627             set_bits(player_ptr->spell_forgotten1, (1UL << j));
628             which = player_ptr->realm1;
629         } else {
630             set_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
631             which = player_ptr->realm2;
632         }
633
634         if (j < 32) {
635             reset_bits(player_ptr->spell_learned1, (1UL << j));
636             which = player_ptr->realm1;
637         } else {
638             reset_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
639             which = player_ptr->realm2;
640         }
641
642 #ifdef JP
643         msg_format("%sの%sを忘れてしまった。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
644 #else
645         msg_format("You have forgotten the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
646 #endif
647         player_ptr->new_spells++;
648     }
649
650     /* Check for spells to remember */
651     for (int i = 0; i < 64; i++) {
652         if (player_ptr->new_spells <= 0) {
653             break;
654         }
655         if (!player_ptr->spell_forgotten1 && !player_ptr->spell_forgotten2) {
656             break;
657         }
658         int j = player_ptr->spell_order[i];
659         if (j >= 99) {
660             break;
661         }
662
663         const magic_type *s_ptr;
664         if (!is_magic((j < 32) ? player_ptr->realm1 : player_ptr->realm2)) {
665             if (j < 32) {
666                 s_ptr = &technic_info[player_ptr->realm1 - MIN_TECHNIC][j];
667             } else {
668                 s_ptr = &technic_info[player_ptr->realm2 - MIN_TECHNIC][j % 32];
669             }
670         } else if (j < 32) {
671             s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
672         } else {
673             s_ptr = &mp_ptr->info[player_ptr->realm2 - 1][j % 32];
674         }
675
676         if (s_ptr->slevel > player_ptr->lev) {
677             continue;
678         }
679
680         bool is_spell_learned = (j < 32) ? any_bits(player_ptr->spell_forgotten1, (1UL << j)) : any_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
681         if (!is_spell_learned) {
682             continue;
683         }
684
685         int16_t which;
686         if (j < 32) {
687             reset_bits(player_ptr->spell_forgotten1, (1UL << j));
688             which = player_ptr->realm1;
689         } else {
690             reset_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
691             which = player_ptr->realm2;
692         }
693
694         if (j < 32) {
695             set_bits(player_ptr->spell_learned1, (1UL << j));
696             which = player_ptr->realm1;
697         } else {
698             set_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
699             which = player_ptr->realm2;
700         }
701
702 #ifdef JP
703         msg_format("%sの%sを思い出した。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
704 #else
705         msg_format("You have remembered the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
706 #endif
707         player_ptr->new_spells--;
708     }
709
710     if (player_ptr->realm2 == REALM_NONE) {
711         int k = 0;
712         for (int j = 0; j < 32; j++) {
713             const magic_type *s_ptr;
714             if (!is_magic(player_ptr->realm1)) {
715                 s_ptr = &technic_info[player_ptr->realm1 - MIN_TECHNIC][j];
716             } else {
717                 s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
718             }
719
720             if (s_ptr->slevel > player_ptr->lev) {
721                 continue;
722             }
723
724             if (any_bits(player_ptr->spell_learned1, (1UL << j))) {
725                 continue;
726             }
727
728             k++;
729         }
730
731         if (k > 32) {
732             k = 32;
733         }
734         if ((player_ptr->new_spells > k) && ((mp_ptr->spell_book == ItemKindType::LIFE_BOOK) || (mp_ptr->spell_book == ItemKindType::HISSATSU_BOOK))) {
735             player_ptr->new_spells = (int16_t)k;
736         }
737     }
738
739     if (player_ptr->new_spells < 0) {
740         player_ptr->new_spells = 0;
741     }
742
743     if (player_ptr->old_spells == player_ptr->new_spells) {
744         return;
745     }
746
747     if (player_ptr->new_spells) {
748 #ifdef JP
749         if (player_ptr->new_spells < 10) {
750             msg_format("あと %d つの%sを学べる。", player_ptr->new_spells, p);
751         } else {
752             msg_format("あと %d 個の%sを学べる。", player_ptr->new_spells, p);
753         }
754 #else
755         msg_format("You can learn %d more %s%s.", player_ptr->new_spells, p, (player_ptr->new_spells != 1) ? "s" : "");
756 #endif
757     }
758
759     player_ptr->old_spells = player_ptr->new_spells;
760     set_bits(player_ptr->redraw, PR_STUDY);
761     set_bits(player_ptr->window_flags, PW_OBJECT);
762 }
763
764 /*!
765  * @brief プレイヤーの最大MPを更新する /
766  * Update maximum mana.  You do not need to know any spells.
767  * Note that mana is lowered by heavy (or inappropriate) armor.
768  * @details
769  * This function induces status messages.
770  */
771 static void update_max_mana(PlayerType *player_ptr)
772 {
773     if ((mp_ptr->spell_book == ItemKindType::NONE) && mp_ptr->spell_first == SPELL_FIRST_NO_SPELL) {
774         return;
775     }
776
777     int levels;
778     PlayerClass pc(player_ptr);
779     auto use_direct_level = pc.equals(PlayerClassType::MINDCRAFTER);
780     use_direct_level |= pc.equals(PlayerClassType::MIRROR_MASTER);
781     use_direct_level |= pc.equals(PlayerClassType::BLUE_MAGE);
782     use_direct_level |= pc.equals(PlayerClassType::ELEMENTALIST);
783     if (use_direct_level) {
784         levels = player_ptr->lev;
785     } else {
786         if (mp_ptr->spell_first > player_ptr->lev) {
787             player_ptr->msp = 0;
788             set_bits(player_ptr->redraw, PR_MANA);
789             return;
790         }
791
792         levels = (player_ptr->lev - mp_ptr->spell_first) + 1;
793     }
794
795     int msp;
796     if (pc.equals(PlayerClassType::SAMURAI)) {
797         msp = (adj_mag_mana[player_ptr->stat_index[mp_ptr->spell_stat]] + 10) * 2;
798         if (msp) {
799             msp += (msp * rp_ptr->r_adj[mp_ptr->spell_stat] / 20);
800         }
801     } else {
802         msp = adj_mag_mana[player_ptr->stat_index[mp_ptr->spell_stat]] * (levels + 3) / 4;
803         if (msp) {
804             msp++;
805         }
806         if (msp) {
807             msp += (msp * rp_ptr->r_adj[mp_ptr->spell_stat] / 20);
808         }
809         if (msp && (player_ptr->ppersonality == PERSONALITY_MUNCHKIN)) {
810             msp += msp / 2;
811         }
812         if (msp && pc.equals(PlayerClassType::HIGH_MAGE)) {
813             msp += msp / 4;
814         }
815         if (msp && pc.equals(PlayerClassType::SORCERER)) {
816             msp += msp * (25 + player_ptr->lev) / 100;
817         }
818     }
819
820     if (any_bits(mp_ptr->spell_xtra, extra_magic_glove_reduce_mana)) {
821         player_ptr->cumber_glove = false;
822         ObjectType *o_ptr;
823         o_ptr = &player_ptr->inventory_list[INVEN_ARMS];
824         auto flgs = object_flags(o_ptr);
825         if (o_ptr->k_idx && flgs.has_not(TR_FREE_ACT) && flgs.has_not(TR_DEC_MANA) && flgs.has_not(TR_EASY_SPELL) && !((flgs.has(TR_MAGIC_MASTERY)) && (o_ptr->pval > 0)) && !((flgs.has(TR_DEX)) && (o_ptr->pval > 0))) {
826             player_ptr->cumber_glove = true;
827             msp = (3 * msp) / 4;
828         }
829     }
830
831     player_ptr->cumber_armor = false;
832
833     int cur_wgt = 0;
834     if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval > ItemKindType::SWORD) {
835         cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight;
836     }
837     if (player_ptr->inventory_list[INVEN_SUB_HAND].tval > ItemKindType::SWORD) {
838         cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight;
839     }
840     cur_wgt += player_ptr->inventory_list[INVEN_BODY].weight;
841     cur_wgt += player_ptr->inventory_list[INVEN_HEAD].weight;
842     cur_wgt += player_ptr->inventory_list[INVEN_OUTER].weight;
843     cur_wgt += player_ptr->inventory_list[INVEN_ARMS].weight;
844     cur_wgt += player_ptr->inventory_list[INVEN_FEET].weight;
845
846     switch (player_ptr->pclass) {
847     case PlayerClassType::MAGE:
848     case PlayerClassType::HIGH_MAGE:
849     case PlayerClassType::BLUE_MAGE:
850     case PlayerClassType::MONK:
851     case PlayerClassType::FORCETRAINER:
852     case PlayerClassType::SORCERER:
853     case PlayerClassType::ELEMENTALIST: {
854         if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
855             cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight;
856         }
857         if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
858             cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight;
859         }
860         break;
861     }
862     case PlayerClassType::PRIEST:
863     case PlayerClassType::BARD:
864     case PlayerClassType::TOURIST: {
865         if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
866             cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight * 2 / 3;
867         }
868         if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
869             cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight * 2 / 3;
870         }
871         break;
872     }
873     case PlayerClassType::MINDCRAFTER:
874     case PlayerClassType::BEASTMASTER:
875     case PlayerClassType::MIRROR_MASTER: {
876         if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
877             cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight / 2;
878         }
879         if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
880             cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 2;
881         }
882         break;
883     }
884     case PlayerClassType::ROGUE:
885     case PlayerClassType::RANGER:
886     case PlayerClassType::RED_MAGE:
887     case PlayerClassType::WARRIOR_MAGE: {
888         if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
889             cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight / 3;
890         }
891         if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
892             cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 3;
893         }
894         break;
895     }
896     case PlayerClassType::PALADIN:
897     case PlayerClassType::CHAOS_WARRIOR: {
898         if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
899             cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight / 5;
900         }
901         if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
902             cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 5;
903         }
904         break;
905     }
906     default: {
907         break;
908     }
909     }
910
911     int max_wgt = mp_ptr->spell_weight;
912     if ((cur_wgt - max_wgt) > 0) {
913         player_ptr->cumber_armor = true;
914         switch (player_ptr->pclass) {
915         case PlayerClassType::MAGE:
916         case PlayerClassType::HIGH_MAGE:
917         case PlayerClassType::BLUE_MAGE:
918         case PlayerClassType::ELEMENTALIST: {
919             msp -= msp * (cur_wgt - max_wgt) / 600;
920             break;
921         }
922         case PlayerClassType::PRIEST:
923         case PlayerClassType::MINDCRAFTER:
924         case PlayerClassType::BEASTMASTER:
925         case PlayerClassType::BARD:
926         case PlayerClassType::FORCETRAINER:
927         case PlayerClassType::TOURIST:
928         case PlayerClassType::MIRROR_MASTER: {
929             msp -= msp * (cur_wgt - max_wgt) / 800;
930             break;
931         }
932         case PlayerClassType::SORCERER: {
933             msp -= msp * (cur_wgt - max_wgt) / 900;
934             break;
935         }
936         case PlayerClassType::ROGUE:
937         case PlayerClassType::RANGER:
938         case PlayerClassType::MONK:
939         case PlayerClassType::RED_MAGE: {
940             msp -= msp * (cur_wgt - max_wgt) / 1000;
941             break;
942         }
943         case PlayerClassType::PALADIN:
944         case PlayerClassType::CHAOS_WARRIOR:
945         case PlayerClassType::WARRIOR_MAGE: {
946             msp -= msp * (cur_wgt - max_wgt) / 1200;
947             break;
948         }
949         case PlayerClassType::SAMURAI: {
950             player_ptr->cumber_armor = false;
951             break;
952         }
953         default: {
954             msp -= msp * (cur_wgt - max_wgt) / 800;
955             break;
956         }
957         }
958     }
959
960     if (msp < 0) {
961         msp = 0;
962     }
963
964     if (player_ptr->msp != msp) {
965         if ((player_ptr->csp >= msp) && !pc.equals(PlayerClassType::SAMURAI)) {
966             player_ptr->csp = msp;
967             player_ptr->csp_frac = 0;
968         }
969
970 #ifdef JP
971         if (player_ptr->level_up_message && (msp > player_ptr->msp)) {
972             msg_format("最大マジック・ポイントが %d 増加した!", (msp - player_ptr->msp));
973         }
974 #endif
975         player_ptr->msp = msp;
976         set_bits(player_ptr->redraw, PR_MANA);
977         set_bits(player_ptr->window_flags, (PW_PLAYER | PW_SPELL));
978     }
979
980     if (w_ptr->character_xtra) {
981         return;
982     }
983
984     if (player_ptr->old_cumber_glove != player_ptr->cumber_glove) {
985         if (player_ptr->cumber_glove) {
986             msg_print(_("手が覆われて呪文が唱えにくい感じがする。", "Your covered hands feel unsuitable for spellcasting."));
987         } else {
988             msg_print(_("この手の状態なら、ぐっと呪文が唱えやすい感じだ。", "Your hands feel more suitable for spellcasting."));
989         }
990
991         player_ptr->old_cumber_glove = player_ptr->cumber_glove;
992     }
993
994     if (player_ptr->old_cumber_armor == player_ptr->cumber_armor) {
995         return;
996     }
997
998     if (player_ptr->cumber_armor) {
999         msg_print(_("装備の重さで動きが鈍くなってしまっている。", "The weight of your equipment encumbers your movement."));
1000     } else {
1001         msg_print(_("ぐっと楽に体を動かせるようになった。", "You feel able to move more freely."));
1002     }
1003
1004     player_ptr->old_cumber_armor = player_ptr->cumber_armor;
1005 }
1006
1007 /*!
1008  * @brief 装備中の射撃武器の威力倍率を返す /
1009  * calcurate the fire rate of target object
1010  * @param o_ptr 計算する射撃武器のアイテム情報参照ポインタ
1011  * @return 射撃倍率の値(100で1.00倍)
1012  */
1013 int16_t calc_num_fire(PlayerType *player_ptr, ObjectType *o_ptr)
1014 {
1015     int extra_shots = 0;
1016
1017     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1018         ObjectType *q_ptr;
1019         q_ptr = &player_ptr->inventory_list[i];
1020         if (!q_ptr->k_idx) {
1021             continue;
1022         }
1023
1024         if (i == INVEN_BOW) {
1025             continue;
1026         }
1027
1028         auto flgs = object_flags(q_ptr);
1029         if (flgs.has(TR_XTRA_SHOTS)) {
1030             extra_shots++;
1031         }
1032     }
1033
1034     auto flgs = object_flags(o_ptr);
1035     if (flgs.has(TR_XTRA_SHOTS)) {
1036         extra_shots++;
1037     }
1038
1039     int num = 0;
1040     if (o_ptr->k_idx == 0) {
1041         return (int16_t)num;
1042     }
1043
1044     num = 100;
1045     num += (extra_shots * 100);
1046
1047     if (is_heavy_shoot(player_ptr, o_ptr)) {
1048         return (int16_t)num;
1049     }
1050
1051     ItemKindType tval_ammo = bow_tval_ammo(o_ptr);
1052     PlayerClass pc(player_ptr);
1053     if (pc.equals(PlayerClassType::RANGER) && (tval_ammo == ItemKindType::ARROW)) {
1054         num += (player_ptr->lev * 4);
1055     }
1056
1057     if (pc.equals(PlayerClassType::CAVALRY) && (tval_ammo == ItemKindType::ARROW)) {
1058         num += (player_ptr->lev * 3);
1059     }
1060
1061     if (pc.equals(PlayerClassType::ARCHER)) {
1062         if (tval_ammo == ItemKindType::ARROW) {
1063             num += ((player_ptr->lev * 5) + 50);
1064         } else if ((tval_ammo == ItemKindType::BOLT) || (tval_ammo == ItemKindType::SHOT)) {
1065             num += (player_ptr->lev * 4);
1066         }
1067     }
1068
1069     if (pc.equals(PlayerClassType::WARRIOR) && (tval_ammo <= ItemKindType::BOLT) && (tval_ammo >= ItemKindType::SHOT)) {
1070         num += (player_ptr->lev * 2);
1071     }
1072
1073     if (pc.equals(PlayerClassType::ROGUE) && (tval_ammo == ItemKindType::SHOT)) {
1074         num += (player_ptr->lev * 4);
1075     }
1076
1077     return (int16_t)num;
1078 }
1079
1080 /*!
1081  * @brief 解除能力計算
1082  * @param player_ptr プレイヤーへの参照ポインタ
1083  * @return 解除能力
1084  * @details
1085  * * 種族/職業/性格による加算
1086  * * 職業と性格とレベルによる追加加算
1087  * * 器用さに応じたadj_dex_disテーブルによる加算
1088  * * 知力に応じたadj_int_disテーブルによる加算
1089  */
1090 static ACTION_SKILL_POWER calc_disarming(PlayerType *player_ptr)
1091 {
1092     ACTION_SKILL_POWER pow;
1093     const player_race_info *tmp_rp_ptr;
1094
1095     if (player_ptr->mimic_form != MimicKindType::NONE) {
1096         tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1097     } else {
1098         tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1099     }
1100
1101     const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1102     const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1103
1104     pow = tmp_rp_ptr->r_dis + c_ptr->c_dis + a_ptr->a_dis;
1105     pow += ((cp_ptr->x_dis * player_ptr->lev / 10) + (ap_ptr->a_dis * player_ptr->lev / 50));
1106     pow += adj_dex_dis[player_ptr->stat_index[A_DEX]];
1107     pow += adj_int_dis[player_ptr->stat_index[A_INT]];
1108     return pow;
1109 }
1110
1111 /*!
1112  * @brief 魔道具使用能力計算
1113  * @param player_ptr プレイヤーへの参照ポインタ
1114  * @return 魔道具使用能力
1115  * @details
1116  * * 種族/職業/性格による加算
1117  * * 職業と性格とレベルによる追加加算
1118  * * 装備による加算(TR_MAGIC_MASTERYを持っていたら+pval*8)
1119  * * 知力に応じたadj_int_devテーブルによる加算
1120  * * 狂戦士化による減算(-20)
1121  */
1122 static ACTION_SKILL_POWER calc_device_ability(PlayerType *player_ptr)
1123 {
1124     ACTION_SKILL_POWER pow;
1125     const player_race_info *tmp_rp_ptr;
1126
1127     if (player_ptr->mimic_form != MimicKindType::NONE) {
1128         tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1129     } else {
1130         tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1131     }
1132
1133     const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1134     const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1135
1136     pow = tmp_rp_ptr->r_dev + c_ptr->c_dev + a_ptr->a_dev;
1137     pow += ((c_ptr->x_dev * player_ptr->lev / 10) + (ap_ptr->a_dev * player_ptr->lev / 50));
1138
1139     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1140         ObjectType *o_ptr;
1141         o_ptr = &player_ptr->inventory_list[i];
1142         if (!o_ptr->k_idx) {
1143             continue;
1144         }
1145         auto flgs = object_flags(o_ptr);
1146         if (flgs.has(TR_MAGIC_MASTERY)) {
1147             pow += 8 * o_ptr->pval;
1148         }
1149     }
1150
1151     pow += adj_int_dev[player_ptr->stat_index[A_INT]];
1152
1153     if (is_shero(player_ptr)) {
1154         pow -= 20;
1155     }
1156     return pow;
1157 }
1158
1159 /*!
1160  * @brief 魔法防御計算
1161  * @param player_ptr プレイヤーへの参照ポインタ
1162  * @return 魔法防御
1163  * @details
1164  * * 種族/職業/性格による加算
1165  * * 職業と性格とレベルによる追加加算
1166  * * 変異MUT3_MAGIC_RESによる加算(15 + レベル / 5)
1167  * * 呪力耐性の装備による加算(30)
1168  * * 祝福された装備による加算(5 + レベル / 10)
1169  * * 賢さによるadj_wis_savテーブル加算
1170  * * 呪力弱点の装備による減算(-10)
1171  * * 呪力弱点の装備が強力に呪われているときさらに減算(-20)
1172  * * 狂戦士化による減算(-30)
1173  * * 反魔法持ちで大なり上書き(90+レベル未満ならその値に上書き)
1174  * * クターのつぶれ状態なら(10に上書き)
1175  * * 生命の「究極の耐性」や regist_magic,magicdef持ちなら大なり上書き(95+レベル未満ならその値に上書き)
1176  * * 呪いのdown_savingがかかっているなら半減
1177  */
1178 static ACTION_SKILL_POWER calc_saving_throw(PlayerType *player_ptr)
1179 {
1180     ACTION_SKILL_POWER pow;
1181     const player_race_info *tmp_rp_ptr;
1182
1183     if (player_ptr->mimic_form != MimicKindType::NONE) {
1184         tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1185     } else {
1186         tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1187     }
1188
1189     const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1190     const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1191
1192     pow = tmp_rp_ptr->r_sav + c_ptr->c_sav + a_ptr->a_sav;
1193     pow += ((cp_ptr->x_sav * player_ptr->lev / 10) + (ap_ptr->a_sav * player_ptr->lev / 50));
1194
1195     if (player_ptr->muta.has(PlayerMutationType::MAGIC_RES)) {
1196         pow += (15 + (player_ptr->lev / 5));
1197     }
1198
1199     if (has_resist_curse(player_ptr)) {
1200         pow += 30;
1201     }
1202
1203     if (player_ptr->bless_blade) {
1204         pow += 6 + (player_ptr->lev - 1) / 10;
1205     }
1206
1207     pow += adj_wis_sav[player_ptr->stat_index[A_WIS]];
1208
1209     if (has_vuln_curse(player_ptr)) {
1210         pow -= 10;
1211     }
1212
1213     if (has_heavy_vuln_curse(player_ptr)) {
1214         pow -= 20;
1215     }
1216
1217     if (is_shero(player_ptr)) {
1218         pow -= 30;
1219     }
1220
1221     if (player_ptr->anti_magic && (pow < (90 + player_ptr->lev))) {
1222         pow = 90 + player_ptr->lev;
1223     }
1224
1225     if (player_ptr->tsubureru) {
1226         pow = 10;
1227     }
1228
1229     if ((player_ptr->ult_res || player_ptr->resist_magic || player_ptr->magicdef) && (pow < (95 + player_ptr->lev))) {
1230         pow = 95 + player_ptr->lev;
1231     }
1232
1233     if (player_ptr->down_saving) {
1234         pow /= 2;
1235     }
1236
1237     return pow;
1238 }
1239
1240 /*!
1241  * @brief 探索深度計算
1242  * @param player_ptr プレイヤーへの参照ポインタ
1243  * @return 探索深度
1244  * @details
1245  * * 種族/職業/性格による加算
1246  * * 職業とレベルによる追加加算
1247  * * 各装備による加算(TR_SEARCHがあれば+pval*5)
1248  * * 狂戦士化による減算(-15)
1249  * * 変異(MUT3_XTRA_EYES)による加算(+15)
1250  */
1251 static ACTION_SKILL_POWER calc_search(PlayerType *player_ptr)
1252 {
1253     ACTION_SKILL_POWER pow;
1254     const player_race_info *tmp_rp_ptr;
1255
1256     if (player_ptr->mimic_form != MimicKindType::NONE) {
1257         tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1258     } else {
1259         tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1260     }
1261
1262     const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1263     const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1264
1265     pow = tmp_rp_ptr->r_srh + c_ptr->c_srh + a_ptr->a_srh;
1266     pow += (c_ptr->x_srh * player_ptr->lev / 10);
1267
1268     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1269         ObjectType *o_ptr;
1270         o_ptr = &player_ptr->inventory_list[i];
1271         if (!o_ptr->k_idx) {
1272             continue;
1273         }
1274         auto flgs = object_flags(o_ptr);
1275         if (flgs.has(TR_SEARCH)) {
1276             pow += (o_ptr->pval * 5);
1277         }
1278     }
1279
1280     if (player_ptr->muta.has(PlayerMutationType::XTRA_EYES)) {
1281         pow += 15;
1282     }
1283
1284     if (is_shero(player_ptr)) {
1285         pow -= 15;
1286     }
1287
1288     return pow;
1289 }
1290
1291 /*!
1292  * @brief 探索頻度計算
1293  * @param player_ptr プレイヤーへの参照ポインタ
1294  * @return 探索頻度
1295  * @details
1296  * * 種族/職業/性格による加算
1297  * * 職業とレベルによる追加加算
1298  * * 各装備による加算(TR_SEARCHがあれば+pval*5)
1299  * * 狂戦士化による減算(-15)
1300  * * 変異(MUT3_XTRA_EYES)による加算(+15)
1301  */
1302 static ACTION_SKILL_POWER calc_search_freq(PlayerType *player_ptr)
1303 {
1304     ACTION_SKILL_POWER pow;
1305     const player_race_info *tmp_rp_ptr;
1306
1307     if (player_ptr->mimic_form != MimicKindType::NONE) {
1308         tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1309     } else {
1310         tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1311     }
1312
1313     const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1314     const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1315
1316     pow = tmp_rp_ptr->r_fos + c_ptr->c_fos + a_ptr->a_fos;
1317     pow += (c_ptr->x_fos * player_ptr->lev / 10);
1318
1319     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1320         ObjectType *o_ptr;
1321         o_ptr = &player_ptr->inventory_list[i];
1322         if (!o_ptr->k_idx) {
1323             continue;
1324         }
1325         auto flgs = object_flags(o_ptr);
1326         if (flgs.has(TR_SEARCH)) {
1327             pow += (o_ptr->pval * 5);
1328         }
1329     }
1330
1331     if (is_shero(player_ptr)) {
1332         pow -= 15;
1333     }
1334
1335     if (player_ptr->muta.has(PlayerMutationType::XTRA_EYES)) {
1336         pow += 15;
1337     }
1338
1339     return pow;
1340 }
1341
1342 /*!
1343  * @brief 打撃命中能力計算
1344  * @param player_ptr プレイヤーへの参照ポインタ
1345  * @return 打撃命中能力
1346  * @details
1347  * * 種族/職業/性格による加算とレベルによる追加加算
1348  */
1349 static ACTION_SKILL_POWER calc_to_hit_melee(PlayerType *player_ptr)
1350 {
1351     ACTION_SKILL_POWER pow;
1352     const player_race_info *tmp_rp_ptr;
1353     const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1354     const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1355
1356     if (player_ptr->mimic_form != MimicKindType::NONE) {
1357         tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1358     } else {
1359         tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1360     }
1361
1362     pow = tmp_rp_ptr->r_thn + c_ptr->c_thn + a_ptr->a_thn;
1363     pow += ((c_ptr->x_thn * player_ptr->lev / 10) + (a_ptr->a_thn * player_ptr->lev / 50));
1364     return pow;
1365 }
1366
1367 /*!
1368  * @brief 射撃命中能力計算
1369  * @param player_ptr プレイヤーへの参照ポインタ
1370  * @return 射撃命中能力
1371  * @details
1372  * * 種族/職業/性格による加算とレベルによる追加加算
1373  */
1374 static ACTION_SKILL_POWER calc_to_hit_shoot(PlayerType *player_ptr)
1375 {
1376     ACTION_SKILL_POWER pow;
1377     const player_race_info *tmp_rp_ptr;
1378     const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1379     const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1380
1381     if (player_ptr->mimic_form != MimicKindType::NONE) {
1382         tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1383     } else {
1384         tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1385     }
1386
1387     pow = tmp_rp_ptr->r_thb + c_ptr->c_thb + a_ptr->a_thb;
1388     pow += ((c_ptr->x_thb * player_ptr->lev / 10) + (a_ptr->a_thb * player_ptr->lev / 50));
1389     return pow;
1390 }
1391
1392 /*!
1393  * @brief 投擲命中能力計算
1394  * @param player_ptr プレイヤーへの参照ポインタ
1395  * @return 投擲命中能力
1396  * @details
1397  * * 種族/職業/性格による加算とレベルによる追加加算
1398  * * 狂戦士による減算(-20)
1399  */
1400 static ACTION_SKILL_POWER calc_to_hit_throw(PlayerType *player_ptr)
1401 {
1402     ACTION_SKILL_POWER pow;
1403     const player_race_info *tmp_rp_ptr;
1404     const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1405     const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1406
1407     if (player_ptr->mimic_form != MimicKindType::NONE) {
1408         tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1409     } else {
1410         tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1411     }
1412
1413     pow = tmp_rp_ptr->r_thb + c_ptr->c_thb + a_ptr->a_thb;
1414     pow += ((c_ptr->x_thb * player_ptr->lev / 10) + (a_ptr->a_thb * player_ptr->lev / 50));
1415
1416     if (is_shero(player_ptr)) {
1417         pow -= 20;
1418     }
1419
1420     return pow;
1421 }
1422
1423 /*!
1424  * @brief 掘削能力計算
1425  * @param player_ptr プレイヤーへの参照ポインタ
1426  * @return 掘削能力値
1427  * @details
1428  * * エントが素手の場合のプラス修正
1429  * * 狂戦士化時のプラス修正
1430  * * 腕力によるテーブルプラス修正
1431  * * 職業狂戦士のプラス修正
1432  * * 装備の特性によるプラス修正
1433  * * 武器重量によるプラス修正
1434  * * 最終算出値に1を保証
1435  */
1436 static ACTION_SKILL_POWER calc_skill_dig(PlayerType *player_ptr)
1437 {
1438     ObjectType *o_ptr;
1439
1440     ACTION_SKILL_POWER pow;
1441
1442     pow = 0;
1443
1444     if (PlayerRace(player_ptr).equals(PlayerRaceType::ENT) && !player_ptr->inventory_list[INVEN_MAIN_HAND].k_idx) {
1445         pow += player_ptr->lev * 10;
1446     }
1447
1448     if (is_shero(player_ptr)) {
1449         pow += 30;
1450     }
1451
1452     pow += adj_str_dig[player_ptr->stat_index[A_STR]];
1453
1454     if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
1455         pow += (100 + player_ptr->lev * 8);
1456     }
1457
1458     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1459         o_ptr = &player_ptr->inventory_list[i];
1460         if (!o_ptr->k_idx) {
1461             continue;
1462         }
1463         auto flgs = object_flags(o_ptr);
1464         if (flgs.has(TR_TUNNEL)) {
1465             pow += (o_ptr->pval * 20);
1466         }
1467     }
1468
1469     for (int i = 0; i < 2; i++) {
1470         o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + i];
1471         if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i) && !player_ptr->heavy_wield[i]) {
1472             pow += (o_ptr->weight / 10);
1473         }
1474     }
1475
1476     if (is_shero(player_ptr)) {
1477         pow += 30;
1478     }
1479
1480     if (pow < 1) {
1481         pow = 1;
1482     }
1483
1484     return pow;
1485 }
1486
1487 static bool is_martial_arts_mode(PlayerType *player_ptr)
1488 {
1489     PlayerClass pc(player_ptr);
1490     auto has_martial_arts = pc.equals(PlayerClassType::MONK);
1491     has_martial_arts |= pc.equals(PlayerClassType::FORCETRAINER);
1492     has_martial_arts |= pc.equals(PlayerClassType::BERSERKER);
1493     return has_martial_arts && any_bits(empty_hands(player_ptr, true), EMPTY_HAND_MAIN) && !can_attack_with_sub_hand(player_ptr);
1494 }
1495
1496 static bool is_heavy_wield(PlayerType *player_ptr, int i)
1497 {
1498     const auto *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + i];
1499
1500     return has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i) && (calc_weapon_weight_limit(player_ptr) < o_ptr->weight / 10);
1501 }
1502
1503 static int16_t calc_num_blow(PlayerType *player_ptr, int i)
1504 {
1505     ObjectType *o_ptr;
1506     int16_t num_blow = 1;
1507
1508     o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + i];
1509     auto flgs = object_flags(o_ptr);
1510     PlayerClass pc(player_ptr);
1511     if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
1512         if (o_ptr->k_idx && !player_ptr->heavy_wield[i]) {
1513             int str_index, dex_index;
1514             int num = 0, wgt = 0, mul = 0, div = 0;
1515
1516             auto &info = class_info[enum2i(player_ptr->pclass)];
1517             num = info.num;
1518             wgt = info.wgt;
1519             mul = info.mul;
1520
1521             if (pc.equals(PlayerClassType::CAVALRY) && player_ptr->riding && flgs.has(TR_RIDING)) {
1522                 num = 5;
1523                 wgt = 70;
1524                 mul = 4;
1525             }
1526
1527             if (SpellHex(player_ptr).is_spelling_specific(HEX_XTRA_MIGHT) || SpellHex(player_ptr).is_spelling_specific(HEX_BUILDING)) {
1528                 num++;
1529                 wgt /= 2;
1530                 mul += 2;
1531             }
1532
1533             div = ((o_ptr->weight < wgt) ? wgt : o_ptr->weight);
1534             str_index = (adj_str_blow[player_ptr->stat_index[A_STR]] * mul / div);
1535
1536             if (has_two_handed_weapons(player_ptr) && !has_disable_two_handed_bonus(player_ptr, 0)) {
1537                 str_index += pc.equals(PlayerClassType::WARRIOR) || pc.equals(PlayerClassType::BERSERKER) ? (player_ptr->lev / 23 + 1) : 1;
1538             }
1539             if (pc.equals(PlayerClassType::NINJA)) {
1540                 str_index = std::max(0, str_index - 1);
1541             }
1542             if (str_index > 11) {
1543                 str_index = 11;
1544             }
1545
1546             dex_index = (adj_dex_blow[player_ptr->stat_index[A_DEX]]);
1547             if (dex_index > 11) {
1548                 dex_index = 11;
1549             }
1550
1551             num_blow = blows_table[str_index][dex_index];
1552             if (num_blow > num) {
1553                 num_blow = (int16_t)num;
1554             }
1555
1556             num_blow += (int16_t)player_ptr->extra_blows[i];
1557             if (pc.equals(PlayerClassType::WARRIOR)) {
1558                 num_blow += (player_ptr->lev / 40);
1559             } else if (pc.equals(PlayerClassType::BERSERKER)) {
1560                 num_blow += (player_ptr->lev / 23);
1561             } else if (pc.equals(PlayerClassType::ROGUE) && (o_ptr->weight < 50) && (player_ptr->stat_index[A_DEX] >= 30)) {
1562                 num_blow++;
1563             }
1564
1565             if (PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::FUUJIN)) {
1566                 num_blow -= 1;
1567             }
1568
1569             if ((o_ptr->tval == ItemKindType::SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) {
1570                 num_blow = 1;
1571             }
1572
1573             if (num_blow < 1) {
1574                 num_blow = 1;
1575             }
1576         }
1577     }
1578
1579     if (i != 0) {
1580         return num_blow;
1581     }
1582     /* Different calculation for monks with empty hands */
1583     if (is_martial_arts_mode(player_ptr)) {
1584         int blow_base = player_ptr->lev + adj_dex_blow[player_ptr->stat_index[A_DEX]];
1585         num_blow = 0;
1586
1587         if (pc.equals(PlayerClassType::FORCETRAINER)) {
1588             if (blow_base > 18) {
1589                 num_blow++;
1590             }
1591             if (blow_base > 31) {
1592                 num_blow++;
1593             }
1594             if (blow_base > 44) {
1595                 num_blow++;
1596             }
1597             if (blow_base > 58) {
1598                 num_blow++;
1599             }
1600         } else {
1601             if (blow_base > 12) {
1602                 num_blow++;
1603             }
1604             if (blow_base > 22) {
1605                 num_blow++;
1606             }
1607             if (blow_base > 31) {
1608                 num_blow++;
1609             }
1610             if (blow_base > 39) {
1611                 num_blow++;
1612             }
1613             if (blow_base > 46) {
1614                 num_blow++;
1615             }
1616             if (blow_base > 53) {
1617                 num_blow++;
1618             }
1619             if (blow_base > 59) {
1620                 num_blow++;
1621             }
1622         }
1623
1624         if (heavy_armor(player_ptr) && !pc.equals(PlayerClassType::BERSERKER)) {
1625             num_blow /= 2;
1626         }
1627
1628         if (pc.monk_stance_is(MonkStanceType::GENBU)) {
1629             num_blow -= 2;
1630             if (pc.equals(PlayerClassType::MONK) && (player_ptr->lev > 42)) {
1631                 num_blow--;
1632             }
1633             if (num_blow < 0) {
1634                 num_blow = 0;
1635             }
1636         } else if (pc.monk_stance_is(MonkStanceType::SUZAKU)) {
1637             num_blow /= 2;
1638         }
1639
1640         num_blow += 1 + player_ptr->extra_blows[0];
1641     }
1642
1643     if (has_not_ninja_weapon(player_ptr, i)) {
1644         num_blow /= 2;
1645         if (num_blow < 1) {
1646             num_blow = 1;
1647         }
1648     }
1649
1650     return num_blow;
1651 }
1652
1653 /*!
1654  * @brief 魔法失敗値計算
1655  * @param player_ptr プレイヤーへの参照ポインタ
1656  * @return 魔法失敗値
1657  * @details
1658  * * 性格なまけものなら加算(+10)
1659  * * 性格きれものなら減算(-3)
1660  * * 性格ちからじまんとがまんづよいなら加算(+1)
1661  * * 性格チャージマンなら加算(+5)
1662  * * 装備品にTRC::HARD_SPELLがあるなら加算(軽い呪いなら+3/重い呪いなら+10)
1663  */
1664 static int16_t calc_to_magic_chance(PlayerType *player_ptr)
1665 {
1666     int16_t chance = 0;
1667
1668     if (player_ptr->ppersonality == PERSONALITY_LAZY) {
1669         chance += 10;
1670     }
1671     if (player_ptr->ppersonality == PERSONALITY_SHREWD) {
1672         chance -= 3;
1673     }
1674     if ((player_ptr->ppersonality == PERSONALITY_PATIENT) || (player_ptr->ppersonality == PERSONALITY_MIGHTY)) {
1675         chance++;
1676     }
1677     if (player_ptr->ppersonality == PERSONALITY_CHARGEMAN) {
1678         chance += 5;
1679     }
1680
1681     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1682         ObjectType *o_ptr;
1683         o_ptr = &player_ptr->inventory_list[i];
1684         if (!o_ptr->k_idx) {
1685             continue;
1686         }
1687
1688         if (o_ptr->curse_flags.has(CurseTraitType::HARD_SPELL)) {
1689             if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
1690                 chance += 10;
1691             } else {
1692                 chance += 3;
1693             }
1694         }
1695     }
1696     return chance;
1697 }
1698
1699 static ARMOUR_CLASS calc_base_ac(PlayerType *player_ptr)
1700 {
1701     ARMOUR_CLASS ac = 0;
1702     if (player_ptr->yoiyami) {
1703         return 0;
1704     }
1705
1706     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1707         ObjectType *o_ptr;
1708         o_ptr = &player_ptr->inventory_list[i];
1709         if (!o_ptr->k_idx) {
1710             continue;
1711         }
1712         ac += o_ptr->ac;
1713     }
1714
1715     const auto o_ptr_mh = &player_ptr->inventory_list[INVEN_MAIN_HAND];
1716     const auto o_ptr_sh = &player_ptr->inventory_list[INVEN_SUB_HAND];
1717     if (o_ptr_mh->is_armour() || o_ptr_sh->is_armour()) {
1718         ac += player_ptr->skill_exp[PlayerSkillKindType::SHIELD] * (1 + player_ptr->lev / 22) / 2000;
1719     }
1720
1721     return ac;
1722 }
1723
1724 static ARMOUR_CLASS calc_to_ac(PlayerType *player_ptr, bool is_real_value)
1725 {
1726     ARMOUR_CLASS ac = 0;
1727     if (player_ptr->yoiyami) {
1728         return 0;
1729     }
1730
1731     ac += ((int)(adj_dex_ta[player_ptr->stat_index[A_DEX]]) - 128);
1732
1733     switch (player_ptr->mimic_form) {
1734     case MimicKindType::NONE:
1735         break;
1736     case MimicKindType::DEMON:
1737         ac += 10;
1738         break;
1739     case MimicKindType::DEMON_LORD:
1740         ac += 20;
1741         break;
1742     case MimicKindType::VAMPIRE:
1743         ac += 10;
1744         break;
1745     }
1746
1747     PlayerClass pc(player_ptr);
1748     if (pc.equals(PlayerClassType::BERSERKER)) {
1749         ac += 10 + player_ptr->lev / 2;
1750     }
1751
1752     if (pc.equals(PlayerClassType::SORCERER)) {
1753         ac -= 50;
1754     }
1755
1756     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1757         ObjectType *o_ptr;
1758         o_ptr = &player_ptr->inventory_list[i];
1759         auto flags = object_flags(o_ptr);
1760         if (!o_ptr->k_idx) {
1761             continue;
1762         }
1763         if (is_real_value || o_ptr->is_known()) {
1764             ac += o_ptr->to_a;
1765         }
1766
1767         if (o_ptr->curse_flags.has(CurseTraitType::LOW_AC) || object_flags(o_ptr).has(TR_LOW_AC)) {
1768             if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
1769                 if (is_real_value || o_ptr->is_fully_known()) {
1770                     ac -= 30;
1771                 }
1772             } else {
1773                 if (is_real_value || o_ptr->is_fully_known()) {
1774                     ac -= 10;
1775                 }
1776             }
1777         }
1778
1779         if ((i == INVEN_SUB_HAND) && flags.has(TR_SUPPORTIVE)) {
1780             ac += 5;
1781         }
1782     }
1783
1784     PlayerRace pr(player_ptr);
1785     if (pr.equals(PlayerRaceType::GOLEM) || pr.equals(PlayerRaceType::ANDROID)) {
1786         ac += 10 + (player_ptr->lev * 2 / 5);
1787     }
1788
1789     if (set_quick_and_tiny(player_ptr)) {
1790         ac += 10;
1791     }
1792
1793     if (set_musasi(player_ptr)) {
1794         ac += 10;
1795     }
1796
1797     if (set_icing_and_twinkle(player_ptr)) {
1798         ac += 5;
1799     }
1800
1801     if (player_ptr->muta.has(PlayerMutationType::WART_SKIN)) {
1802         ac += 5;
1803     }
1804
1805     if (player_ptr->muta.has(PlayerMutationType::SCALES)) {
1806         ac += 10;
1807     }
1808
1809     if (player_ptr->muta.has(PlayerMutationType::IRON_SKIN)) {
1810         ac += 25;
1811     }
1812
1813     if (pc.is_martial_arts_pro() && !heavy_armor(player_ptr)) {
1814         if (!(player_ptr->inventory_list[INVEN_BODY].k_idx)) {
1815             ac += (player_ptr->lev * 3) / 2;
1816         }
1817         if (!(player_ptr->inventory_list[INVEN_OUTER].k_idx) && (player_ptr->lev > 15)) {
1818             ac += ((player_ptr->lev - 13) / 3);
1819         }
1820         if (!(player_ptr->inventory_list[INVEN_SUB_HAND].k_idx) && (player_ptr->lev > 10)) {
1821             ac += ((player_ptr->lev - 8) / 3);
1822         }
1823         if (!(player_ptr->inventory_list[INVEN_HEAD].k_idx) && (player_ptr->lev > 4)) {
1824             ac += (player_ptr->lev - 2) / 3;
1825         }
1826         if (!(player_ptr->inventory_list[INVEN_ARMS].k_idx)) {
1827             ac += (player_ptr->lev / 2);
1828         }
1829         if (!(player_ptr->inventory_list[INVEN_FEET].k_idx)) {
1830             ac += (player_ptr->lev / 3);
1831         }
1832     }
1833
1834     if (player_ptr->realm1 == REALM_HEX) {
1835         if (SpellHex(player_ptr).is_spelling_specific(HEX_ICE_ARMOR)) {
1836             ac += 30;
1837         }
1838
1839         for (int i = INVEN_MAIN_HAND; i <= INVEN_FEET; i++) {
1840             auto *o_ptr = &player_ptr->inventory_list[i];
1841             if (!o_ptr->k_idx) {
1842                 continue;
1843             }
1844             if (!o_ptr->is_armour()) {
1845                 continue;
1846             }
1847             if (!o_ptr->is_cursed()) {
1848                 continue;
1849             }
1850             if (o_ptr->curse_flags.has(CurseTraitType::CURSED)) {
1851                 ac += 5;
1852             }
1853             if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
1854                 ac += 7;
1855             }
1856             if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
1857                 ac += 13;
1858             }
1859         }
1860     }
1861
1862     if (pc.monk_stance_is(MonkStanceType::GENBU)) {
1863         ac += (player_ptr->lev * player_ptr->lev) / 50;
1864     } else if (pc.monk_stance_is(MonkStanceType::BYAKKO)) {
1865         ac -= 40;
1866     } else if (pc.monk_stance_is(MonkStanceType::SEIRYU)) {
1867         ac -= 50;
1868     } else if (pc.samurai_stance_is(SamuraiStanceType::KOUKIJIN)) {
1869         ac -= 50;
1870     }
1871
1872     if (player_ptr->ult_res || (pc.samurai_stance_is(SamuraiStanceType::MUSOU))) {
1873         ac += 100;
1874     } else if (player_ptr->tsubureru || player_ptr->shield || player_ptr->magicdef) {
1875         ac += 50;
1876     }
1877
1878     if (is_blessed(player_ptr)) {
1879         ac += 5;
1880     }
1881
1882     if (is_shero(player_ptr)) {
1883         ac -= 10;
1884     }
1885
1886     if (pc.equals(PlayerClassType::NINJA)) {
1887         if ((!player_ptr->inventory_list[INVEN_MAIN_HAND].k_idx || can_attack_with_main_hand(player_ptr)) && (!player_ptr->inventory_list[INVEN_SUB_HAND].k_idx || can_attack_with_sub_hand(player_ptr))) {
1888             ac += player_ptr->lev / 2 + 5;
1889         }
1890     }
1891
1892     return ac;
1893 }
1894
1895 /*!
1896  * @brief 二刀流ペナルティ量計算
1897  * @param player_ptr プレイヤーへの参照ポインタ
1898  * @param slot ペナルティ量を計算する武器スロット
1899  * @return 二刀流ペナルティ量
1900  * @details
1901  * * 二刀流にしていなければ0
1902  * * 特別セットによる軽減
1903  * * EASY2_WEAPONによる軽減
1904  * * SUPPORTIVEを左に装備した場合の軽減
1905  * * 武蔵セットによる免除
1906  * * 竿状武器による増加
1907  */
1908 int16_t calc_double_weapon_penalty(PlayerType *player_ptr, INVENTORY_IDX slot)
1909 {
1910     int penalty = 0;
1911
1912     if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND) && has_melee_weapon(player_ptr, INVEN_SUB_HAND)) {
1913         auto flags = object_flags(&player_ptr->inventory_list[INVEN_SUB_HAND]);
1914
1915         penalty = ((100 - player_ptr->skill_exp[PlayerSkillKindType::TWO_WEAPON] / 160) - (130 - player_ptr->inventory_list[slot].weight) / 8);
1916         if (set_quick_and_tiny(player_ptr) || set_icing_and_twinkle(player_ptr) || set_anubis_and_chariot(player_ptr)) {
1917             penalty = penalty / 2 - 5;
1918         }
1919
1920         for (uint i = FLAG_CAUSE_INVEN_MAIN_HAND; i < FLAG_CAUSE_MAX; i <<= 1) {
1921             if (penalty > 0 && any_bits(player_ptr->easy_2weapon, i)) {
1922                 penalty /= 2;
1923             }
1924         }
1925
1926         if (flags.has(TR_SUPPORTIVE)) {
1927             penalty = std::max(0, penalty - 10);
1928         }
1929
1930         if (set_musasi(player_ptr)) {
1931             penalty = std::min(0, penalty);
1932         }
1933
1934         if (player_ptr->inventory_list[slot].tval == ItemKindType::POLEARM) {
1935             penalty += 10;
1936         }
1937     }
1938     return (int16_t)penalty;
1939 }
1940
1941 static bool is_riding_two_hands(PlayerType *player_ptr)
1942 {
1943     if (!player_ptr->riding) {
1944         return false;
1945     }
1946
1947     if (has_two_handed_weapons(player_ptr) || (empty_hands(player_ptr, false) == EMPTY_HAND_NONE)) {
1948         return true;
1949     } else if (any_bits(player_ptr->pet_extra_flags, PF_TWO_HANDS)) {
1950         switch (player_ptr->pclass) {
1951         case PlayerClassType::MONK:
1952         case PlayerClassType::FORCETRAINER:
1953         case PlayerClassType::BERSERKER:
1954             if ((empty_hands(player_ptr, false) != EMPTY_HAND_NONE) && !has_melee_weapon(player_ptr, INVEN_MAIN_HAND) && !has_melee_weapon(player_ptr, INVEN_SUB_HAND)) {
1955                 return true;
1956             }
1957
1958         default:
1959             break;
1960         }
1961     }
1962
1963     return false;
1964 }
1965
1966 static int16_t calc_riding_bow_penalty(PlayerType *player_ptr)
1967 {
1968     auto *floor_ptr = player_ptr->current_floor_ptr;
1969     if (!player_ptr->riding) {
1970         return 0;
1971     }
1972
1973     int16_t penalty = 0;
1974
1975     if (PlayerClass(player_ptr).is_tamer()) {
1976         if (player_ptr->tval_ammo != ItemKindType::ARROW) {
1977             penalty = 5;
1978         }
1979     } else {
1980         penalty = monraces_info[floor_ptr->m_list[player_ptr->riding].r_idx].level - player_ptr->skill_exp[PlayerSkillKindType::RIDING] / 80;
1981         penalty += 30;
1982         if (penalty < 30) {
1983             penalty = 30;
1984         }
1985     }
1986
1987     if (player_ptr->tval_ammo == ItemKindType::BOLT) {
1988         penalty *= 2;
1989     }
1990
1991     return penalty;
1992 }
1993
1994 void put_equipment_warning(PlayerType *player_ptr)
1995 {
1996     bool heavy_shoot = is_heavy_shoot(player_ptr, &player_ptr->inventory_list[INVEN_BOW]);
1997     if (player_ptr->old_heavy_shoot != heavy_shoot) {
1998         if (heavy_shoot) {
1999             msg_print(_("こんな重い弓を装備しているのは大変だ。", "You have trouble wielding such a heavy bow."));
2000         } else if (player_ptr->inventory_list[INVEN_BOW].k_idx) {
2001             msg_print(_("この弓なら装備していても辛くない。", "You have no trouble wielding your bow."));
2002         } else {
2003             msg_print(_("重い弓を装備からはずして体が楽になった。", "You feel relieved to put down your heavy bow."));
2004         }
2005         player_ptr->old_heavy_shoot = heavy_shoot;
2006     }
2007
2008     for (int i = 0; i < 2; i++) {
2009         if (player_ptr->old_heavy_wield[i] != player_ptr->heavy_wield[i]) {
2010             if (player_ptr->heavy_wield[i]) {
2011                 msg_print(_("こんな重い武器を装備しているのは大変だ。", "You have trouble wielding such a heavy weapon."));
2012             } else if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
2013                 msg_print(_("これなら装備していても辛くない。", "You have no trouble wielding your weapon."));
2014             } else if (player_ptr->heavy_wield[1 - i]) {
2015                 msg_print(_("まだ武器が重い。", "You still have trouble wielding a heavy weapon."));
2016             } else {
2017                 msg_print(_("重い武器を装備からはずして体が楽になった。", "You feel relieved to put down your heavy weapon."));
2018             }
2019
2020             player_ptr->old_heavy_wield[i] = player_ptr->heavy_wield[i];
2021         }
2022
2023         if (player_ptr->old_riding_wield[i] != player_ptr->is_icky_riding_wield[i]) {
2024             if (player_ptr->is_icky_riding_wield[i]) {
2025                 msg_print(_("この武器は乗馬中に使うにはむかないようだ。", "This weapon is not suitable for use while riding."));
2026             } else if (!player_ptr->riding) {
2027                 msg_print(_("この武器は徒歩で使いやすい。", "This weapon is suitable for use on foot."));
2028             } else if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
2029                 msg_print(_("これなら乗馬中にぴったりだ。", "This weapon is suitable for use while riding."));
2030             }
2031
2032             player_ptr->old_riding_wield[i] = player_ptr->is_icky_riding_wield[i];
2033         }
2034
2035         if (player_ptr->old_icky_wield[i] == player_ptr->is_icky_wield[i]) {
2036             continue;
2037         }
2038
2039         if (player_ptr->is_icky_wield[i]) {
2040             msg_print(_("今の装備はどうも自分にふさわしくない気がする。", "You do not feel comfortable with your weapon."));
2041             if (w_ptr->is_loading_now) {
2042                 chg_virtue(player_ptr, V_FAITH, -1);
2043             }
2044         } else if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
2045             msg_print(_("今の装備は自分にふさわしい気がする。", "You feel comfortable with your weapon."));
2046         } else {
2047             msg_print(_("装備をはずしたら随分と気が楽になった。", "You feel more comfortable after removing your weapon."));
2048         }
2049
2050         player_ptr->old_icky_wield[i] = player_ptr->is_icky_wield[i];
2051     }
2052
2053     if (player_ptr->riding && (player_ptr->old_riding_ryoute != player_ptr->riding_ryoute)) {
2054         if (player_ptr->riding_ryoute) {
2055 #ifdef JP
2056             msg_format("%s馬を操れない。", (empty_hands(player_ptr, false) == EMPTY_HAND_NONE) ? "両手がふさがっていて" : "");
2057 #else
2058             msg_print("You are using both hand for fighting, and you can't control the pet you're riding.");
2059 #endif
2060         } else {
2061 #ifdef JP
2062             msg_format("%s馬を操れるようになった。", (empty_hands(player_ptr, false) == EMPTY_HAND_NONE) ? "手が空いて" : "");
2063 #else
2064             msg_print("You began to control the pet you're riding with one hand.");
2065 #endif
2066         }
2067
2068         player_ptr->old_riding_ryoute = player_ptr->riding_ryoute;
2069     }
2070
2071     PlayerClass pc(player_ptr);
2072     if ((pc.is_martial_arts_pro() || pc.equals(PlayerClassType::NINJA)) && (heavy_armor(player_ptr) != player_ptr->monk_notify_aux)) {
2073         if (heavy_armor(player_ptr)) {
2074             msg_print(_("装備が重くてバランスを取れない。", "The weight of your armor disrupts your balance."));
2075             if (w_ptr->is_loading_now) {
2076                 chg_virtue(player_ptr, V_HARMONY, -1);
2077             }
2078         } else {
2079             msg_print(_("バランスがとれるようになった。", "You regain your balance."));
2080         }
2081
2082         player_ptr->monk_notify_aux = heavy_armor(player_ptr);
2083     }
2084 }
2085
2086 static short calc_to_damage(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value)
2087 {
2088     auto *o_ptr = &player_ptr->inventory_list[slot];
2089     auto flgs = object_flags(o_ptr);
2090
2091     player_hand calc_hand = PLAYER_HAND_OTHER;
2092     if (slot == INVEN_MAIN_HAND) {
2093         calc_hand = PLAYER_HAND_MAIN;
2094     }
2095     if (slot == INVEN_SUB_HAND) {
2096         calc_hand = PLAYER_HAND_SUB;
2097     }
2098
2099     auto damage = 0;
2100     damage += ((int)(adj_str_td[player_ptr->stat_index[A_STR]]) - 128);
2101
2102     if (is_shero(player_ptr)) {
2103         damage += 3 + (player_ptr->lev / 5);
2104     }
2105
2106     auto player_stun = player_ptr->effects()->stun();
2107     damage -= player_stun->get_damage_penalty();
2108     PlayerClass pc(player_ptr);
2109     if (pc.equals(PlayerClassType::PRIEST) && (flgs.has_not(TR_BLESSED)) && ((o_ptr->tval == ItemKindType::SWORD) || (o_ptr->tval == ItemKindType::POLEARM))) {
2110         damage -= 2;
2111     } else if (pc.equals(PlayerClassType::BERSERKER)) {
2112         damage += player_ptr->lev / 6;
2113         if (((calc_hand == PLAYER_HAND_MAIN) && !can_attack_with_sub_hand(player_ptr)) || has_two_handed_weapons(player_ptr)) {
2114             damage += player_ptr->lev / 6;
2115         }
2116     } else if (pc.equals(PlayerClassType::SORCERER)) {
2117         if (!((o_ptr->tval == ItemKindType::HAFTED) && ((o_ptr->sval == SV_WIZSTAFF) || (o_ptr->sval == SV_NAMAKE_HAMMER)))) {
2118             damage -= 200;
2119         } else {
2120             damage -= 10;
2121         }
2122     } else if (pc.equals(PlayerClassType::FORCETRAINER)) {
2123         // 練気術師は格闘ダメージに (気)/5 の修正を得る。
2124         if (is_martial_arts_mode(player_ptr) && calc_hand == PLAYER_HAND_MAIN) {
2125             damage += get_current_ki(player_ptr) / 5;
2126         }
2127     }
2128
2129     if ((player_ptr->realm1 == REALM_HEX) && o_ptr->is_cursed()) {
2130         if (SpellHex(player_ptr).is_spelling_specific(HEX_RUNESWORD)) {
2131             if (o_ptr->curse_flags.has(CurseTraitType::CURSED)) {
2132                 damage += 5;
2133             }
2134             if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2135                 damage += 7;
2136             }
2137             if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
2138                 damage += 13;
2139             }
2140         }
2141     }
2142
2143     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2144         int bonus_to_d = 0;
2145         o_ptr = &player_ptr->inventory_list[i];
2146         if (!o_ptr->k_idx || o_ptr->tval == ItemKindType::CAPTURE || (i == INVEN_MAIN_HAND && has_melee_weapon(player_ptr, i)) || (i == INVEN_SUB_HAND && has_melee_weapon(player_ptr, i)) || i == INVEN_BOW) {
2147             continue;
2148         }
2149
2150         if (!o_ptr->is_known() && !is_real_value) {
2151             continue;
2152         }
2153         bonus_to_d = o_ptr->to_d;
2154
2155         if (pc.equals(PlayerClassType::NINJA)) {
2156             if (o_ptr->to_d > 0) {
2157                 bonus_to_d = (o_ptr->to_d + 1) / 2;
2158             }
2159         }
2160
2161         switch (player_melee_type(player_ptr)) {
2162         case MELEE_TYPE_BAREHAND_TWO: /* fall through */
2163         case MELEE_TYPE_WEAPON_TWOHAND:
2164             if (calc_hand == main_attack_hand(player_ptr)) {
2165                 damage += (int16_t)bonus_to_d;
2166             }
2167             break;
2168
2169         case MELEE_TYPE_BAREHAND_MAIN: /* fall through */
2170         case MELEE_TYPE_WEAPON_MAIN:
2171             if ((calc_hand == PLAYER_HAND_MAIN) && (i != INVEN_SUB_RING)) {
2172                 damage += (int16_t)bonus_to_d;
2173             }
2174             break;
2175
2176         case MELEE_TYPE_BAREHAND_SUB: /* fall through */
2177         case MELEE_TYPE_WEAPON_SUB:
2178             if ((calc_hand == PLAYER_HAND_SUB) && (i != INVEN_MAIN_RING)) {
2179                 damage += (int16_t)bonus_to_d;
2180             }
2181             break;
2182
2183         case MELEE_TYPE_WEAPON_DOUBLE:
2184             if (calc_hand == PLAYER_HAND_MAIN) {
2185                 if (i == INVEN_MAIN_RING) {
2186                     damage += (int16_t)bonus_to_d;
2187                 } else if (i != INVEN_SUB_RING) {
2188                     damage += (bonus_to_d > 0) ? (bonus_to_d + 1) / 2 : bonus_to_d;
2189                 }
2190             }
2191             if (calc_hand == PLAYER_HAND_SUB) {
2192                 if (i == INVEN_SUB_RING) {
2193                     damage += (int16_t)bonus_to_d;
2194                 } else if (i != INVEN_MAIN_RING) {
2195                     damage += (bonus_to_d > 0) ? bonus_to_d / 2 : bonus_to_d;
2196                 }
2197             }
2198             break;
2199
2200         case MELEE_TYPE_SHIELD_DOUBLE:
2201             break;
2202
2203         default:
2204             break;
2205         }
2206     }
2207
2208     if (main_attack_hand(player_ptr) == calc_hand) {
2209         if ((is_martial_arts_mode(player_ptr) && empty_hands(player_ptr, false) == (EMPTY_HAND_MAIN | EMPTY_HAND_SUB)) || !has_disable_two_handed_bonus(player_ptr, calc_hand)) {
2210             int bonus_to_d = 0;
2211             bonus_to_d = ((int)(adj_str_td[player_ptr->stat_index[A_STR]]) - 128) / 2;
2212             damage += std::max<int>(bonus_to_d, 1);
2213         }
2214     }
2215
2216     if (is_martial_arts_mode(player_ptr) && (!heavy_armor(player_ptr) || !pc.equals(PlayerClassType::BERSERKER))) {
2217         damage += (player_ptr->lev / 6);
2218     }
2219
2220     // 朱雀の構えをとっているとき、格闘ダメージに -(レベル)/6 の修正を得る。
2221     if (PlayerClass(player_ptr).monk_stance_is(MonkStanceType::SUZAKU)) {
2222         if (is_martial_arts_mode(player_ptr) && calc_hand == PLAYER_HAND_MAIN) {
2223             damage -= (player_ptr->lev / 6);
2224         }
2225     }
2226
2227     return static_cast<short>(damage);
2228 }
2229
2230 /*!
2231  * @brief 武器の命中修正を計算する。 / Calculate hit bonus from a wielded weapon.
2232  * @details
2233  * 'slot' MUST be INVEN_MAIN_HAND or INVEM_SUB_HAND.
2234  */
2235 static short calc_to_hit(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value)
2236 {
2237     auto hit = 0;
2238
2239     /* Base bonuses */
2240     hit += ((int)(adj_dex_th[player_ptr->stat_index[A_DEX]]) - 128);
2241     hit += ((int)(adj_str_th[player_ptr->stat_index[A_STR]]) - 128);
2242
2243     /* Temporary bonuses */
2244     if (is_blessed(player_ptr)) {
2245         hit += 10;
2246     }
2247
2248     if (is_hero(player_ptr)) {
2249         hit += 12;
2250     }
2251
2252     if (is_shero(player_ptr)) {
2253         hit += 12;
2254     }
2255
2256     auto player_stun = player_ptr->effects()->stun();
2257     hit -= player_stun->get_damage_penalty();
2258     player_hand calc_hand = PLAYER_HAND_OTHER;
2259     if (slot == INVEN_MAIN_HAND) {
2260         calc_hand = PLAYER_HAND_MAIN;
2261     }
2262     if (slot == INVEN_SUB_HAND) {
2263         calc_hand = PLAYER_HAND_SUB;
2264     }
2265
2266     /* Default hand bonuses */
2267     if (main_attack_hand(player_ptr) == calc_hand) {
2268         switch (player_melee_type(player_ptr)) {
2269         case MELEE_TYPE_BAREHAND_MAIN:
2270             if (player_ptr->riding) {
2271                 break;
2272             }
2273             /* fall through */
2274         case MELEE_TYPE_BAREHAND_SUB:
2275             if (player_ptr->riding) {
2276                 break;
2277             }
2278             /* fall through */
2279         case MELEE_TYPE_BAREHAND_TWO:
2280             hit += (player_ptr->skill_exp[PlayerSkillKindType::MARTIAL_ARTS] - PlayerSkill::weapon_exp_at(PlayerSkillRank::BEGINNER)) / 200;
2281             break;
2282
2283         default:
2284             break;
2285         }
2286
2287         if ((is_martial_arts_mode(player_ptr) && empty_hands(player_ptr, false) == (EMPTY_HAND_MAIN | EMPTY_HAND_SUB)) || !has_disable_two_handed_bonus(player_ptr, calc_hand)) {
2288             int bonus_to_h = 0;
2289             bonus_to_h = ((int)(adj_str_th[player_ptr->stat_index[A_STR]]) - 128) + ((int)(adj_dex_th[player_ptr->stat_index[A_DEX]]) - 128);
2290             hit += std::max<int>(bonus_to_h, 1);
2291         }
2292     }
2293
2294     /* Bonuses and penalties by weapon */
2295     PlayerClass pc(player_ptr);
2296     if (has_melee_weapon(player_ptr, slot)) {
2297         auto *o_ptr = &player_ptr->inventory_list[slot];
2298         auto flgs = object_flags(o_ptr);
2299
2300         /* Traind bonuses */
2301         hit += (player_ptr->weapon_exp[o_ptr->tval][o_ptr->sval] - PlayerSkill::weapon_exp_at(PlayerSkillRank::BEGINNER)) / 200;
2302
2303         /* Weight penalty */
2304         if (calc_weapon_weight_limit(player_ptr) < o_ptr->weight / 10) {
2305             hit += 2 * (calc_weapon_weight_limit(player_ptr) - o_ptr->weight / 10);
2306         }
2307
2308         /* Low melee penalty */
2309         if ((o_ptr->is_fully_known() || is_real_value) && o_ptr->curse_flags.has(CurseTraitType::LOW_MELEE)) {
2310             if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2311                 hit -= 15;
2312             } else {
2313                 hit -= 5;
2314             }
2315         }
2316
2317         /* Riding bonus and penalty */
2318         if (player_ptr->riding > 0) {
2319             if (o_ptr->is_lance()) {
2320                 hit += 15;
2321             } else if (flgs.has_not(TR_RIDING)) {
2322                 short penalty;
2323                 if (PlayerClass(player_ptr).is_tamer()) {
2324                     penalty = 5;
2325                 } else {
2326                     penalty = monraces_info[player_ptr->current_floor_ptr->m_list[player_ptr->riding].r_idx].level - player_ptr->skill_exp[PlayerSkillKindType::RIDING] / 80;
2327                     penalty += 30;
2328                     if (penalty < 30) {
2329                         penalty = 30;
2330                     }
2331                 }
2332
2333                 hit -= penalty;
2334             }
2335         }
2336
2337         /* Class penalties */
2338         if (pc.equals(PlayerClassType::PRIEST) && (flgs.has_not(TR_BLESSED)) && ((o_ptr->tval == ItemKindType::SWORD) || (o_ptr->tval == ItemKindType::POLEARM))) {
2339             hit -= 2;
2340         } else if (pc.equals(PlayerClassType::BERSERKER)) {
2341             hit += player_ptr->lev / 5;
2342             if (((calc_hand == PLAYER_HAND_MAIN) && !can_attack_with_sub_hand(player_ptr)) || has_two_handed_weapons(player_ptr)) {
2343                 hit += player_ptr->lev / 5;
2344             }
2345         } else if (pc.equals(PlayerClassType::SORCERER)) {
2346             if (!((o_ptr->tval == ItemKindType::HAFTED) && ((o_ptr->sval == SV_WIZSTAFF) || (o_ptr->sval == SV_NAMAKE_HAMMER)))) {
2347                 hit -= 200;
2348             } else {
2349                 hit -= 30;
2350             }
2351         }
2352
2353         if (has_not_ninja_weapon(player_ptr, (int)calc_hand) || has_not_monk_weapon(player_ptr, (int)calc_hand)) {
2354             hit -= 40;
2355         }
2356
2357         /* Hex realm bonuses */
2358         if ((player_ptr->realm1 == REALM_HEX) && o_ptr->is_cursed()) {
2359             if (o_ptr->curse_flags.has(CurseTraitType::CURSED)) {
2360                 hit += 5;
2361             }
2362             if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2363                 hit += 7;
2364             }
2365             if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
2366                 hit += 13;
2367             }
2368             if (o_ptr->curse_flags.has(CurseTraitType::TY_CURSE)) {
2369                 hit += 5;
2370             }
2371         }
2372     }
2373
2374     /* Bonuses from inventory */
2375     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2376         auto *o_ptr = &player_ptr->inventory_list[i];
2377
2378         /* Ignore empty hands, handed weapons, bows and capture balls */
2379         if (!o_ptr->k_idx || o_ptr->tval == ItemKindType::CAPTURE || (i == INVEN_MAIN_HAND && has_melee_weapon(player_ptr, i)) || (i == INVEN_SUB_HAND && has_melee_weapon(player_ptr, i)) || i == INVEN_BOW) {
2380             continue;
2381         }
2382
2383         /* Fake value does not include unknown objects' value */
2384         if (!o_ptr->is_known() && !is_real_value) {
2385             continue;
2386         }
2387
2388         int bonus_to_h = o_ptr->to_h;
2389
2390         /* When wields only a weapon */
2391         if (pc.equals(PlayerClassType::NINJA)) {
2392             if (o_ptr->to_h > 0) {
2393                 bonus_to_h = (o_ptr->to_h + 1) / 2;
2394             }
2395         }
2396
2397         switch (player_melee_type(player_ptr)) {
2398         case MELEE_TYPE_BAREHAND_TWO: /* fall through */
2399         case MELEE_TYPE_WEAPON_TWOHAND:
2400             if (calc_hand == main_attack_hand(player_ptr)) {
2401                 hit += (int16_t)bonus_to_h;
2402             }
2403             break;
2404
2405         case MELEE_TYPE_BAREHAND_MAIN: /* fall through */
2406         case MELEE_TYPE_WEAPON_MAIN:
2407             if ((calc_hand == PLAYER_HAND_MAIN) && (i != INVEN_SUB_RING)) {
2408                 hit += (int16_t)bonus_to_h;
2409             }
2410             break;
2411
2412         case MELEE_TYPE_BAREHAND_SUB: /* fall through */
2413         case MELEE_TYPE_WEAPON_SUB:
2414             if ((calc_hand == PLAYER_HAND_SUB) && (i != INVEN_MAIN_RING)) {
2415                 hit += (int16_t)bonus_to_h;
2416             }
2417             break;
2418
2419         case MELEE_TYPE_WEAPON_DOUBLE:
2420             if (calc_hand == PLAYER_HAND_MAIN) {
2421                 if (i == INVEN_MAIN_RING) {
2422                     hit += (int16_t)bonus_to_h;
2423                 } else if (i != INVEN_SUB_RING) {
2424                     hit += (bonus_to_h > 0) ? (bonus_to_h + 1) / 2 : bonus_to_h;
2425                 }
2426             }
2427             if (calc_hand == PLAYER_HAND_SUB) {
2428                 if (i == INVEN_SUB_RING) {
2429                     hit += (int16_t)bonus_to_h;
2430                 } else if (i != INVEN_MAIN_RING) {
2431                     hit += (bonus_to_h > 0) ? bonus_to_h / 2 : bonus_to_h;
2432                 }
2433             }
2434             break;
2435
2436         case MELEE_TYPE_SHIELD_DOUBLE:
2437             break;
2438
2439         default:
2440             break;
2441         }
2442     }
2443
2444     /* Martial arts bonus */
2445     if (is_martial_arts_mode(player_ptr) && (!heavy_armor(player_ptr) || !pc.equals(PlayerClassType::BERSERKER))) {
2446         hit += (player_ptr->lev / 3);
2447     }
2448
2449     /* Two handed combat penalty */
2450     hit -= calc_double_weapon_penalty(player_ptr, slot);
2451
2452     // 朱雀の構えをとっているとき、格闘命中に -(レベル)/3 の修正を得る。
2453     if (PlayerClass(player_ptr).monk_stance_is(MonkStanceType::SUZAKU)) {
2454         if (is_martial_arts_mode(player_ptr) && calc_hand == PLAYER_HAND_MAIN) {
2455             hit -= (player_ptr->lev / 3);
2456         }
2457     }
2458
2459     return static_cast<short>(hit);
2460 }
2461
2462 static int16_t calc_to_hit_bow(PlayerType *player_ptr, bool is_real_value)
2463 {
2464     int16_t pow = 0;
2465
2466     pow += ((int)(adj_dex_th[player_ptr->stat_index[A_DEX]]) - 128);
2467     pow += ((int)(adj_str_th[player_ptr->stat_index[A_STR]]) - 128);
2468
2469     {
2470         ObjectType *o_ptr;
2471         o_ptr = &player_ptr->inventory_list[INVEN_BOW];
2472         if (o_ptr->k_idx) {
2473             if (o_ptr->curse_flags.has(CurseTraitType::LOW_MELEE)) {
2474                 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2475                     pow -= 15;
2476                 } else {
2477                     pow -= 5;
2478                 }
2479             }
2480         }
2481     }
2482
2483     auto player_stun = player_ptr->effects()->stun();
2484     pow -= player_stun->get_damage_penalty();
2485     if (is_blessed(player_ptr)) {
2486         pow += 10;
2487     }
2488
2489     if (is_hero(player_ptr)) {
2490         pow += 12;
2491     }
2492
2493     if (is_shero(player_ptr)) {
2494         pow -= 12;
2495     }
2496
2497     auto *o_ptr = &player_ptr->inventory_list[INVEN_BOW];
2498
2499     if (is_heavy_shoot(player_ptr, o_ptr)) {
2500         pow += 2 * (calc_bow_weight_limit(player_ptr) - o_ptr->weight / 10);
2501     }
2502
2503     if (o_ptr->k_idx) {
2504         if (o_ptr->k_idx && !is_heavy_shoot(player_ptr, &player_ptr->inventory_list[INVEN_BOW])) {
2505             if (PlayerClass(player_ptr).equals(PlayerClassType::SNIPER) && (player_ptr->tval_ammo == ItemKindType::BOLT)) {
2506                 pow += (10 + (player_ptr->lev / 5));
2507             }
2508         }
2509     }
2510
2511     // 武器以外の装備による修正
2512     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2513         int bonus_to_h;
2514         o_ptr = &player_ptr->inventory_list[i];
2515         if (!o_ptr->k_idx || o_ptr->tval == ItemKindType::CAPTURE || (i == INVEN_MAIN_HAND && has_melee_weapon(player_ptr, i)) || (i == INVEN_SUB_HAND && has_melee_weapon(player_ptr, i)) || i == INVEN_BOW) {
2516             continue;
2517         }
2518
2519         bonus_to_h = o_ptr->to_h;
2520
2521         if (PlayerClass(player_ptr).equals(PlayerClassType::NINJA)) {
2522             if (o_ptr->to_h > 0) {
2523                 bonus_to_h = (o_ptr->to_h + 1) / 2;
2524             }
2525         }
2526
2527         if (is_real_value || o_ptr->is_known()) {
2528             pow += (int16_t)bonus_to_h;
2529         }
2530     }
2531
2532     pow -= calc_riding_bow_penalty(player_ptr);
2533
2534     return pow;
2535 }
2536
2537 static int16_t calc_to_damage_misc(PlayerType *player_ptr)
2538 {
2539     ObjectType *o_ptr;
2540
2541     int16_t to_dam = 0;
2542
2543     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2544         o_ptr = &player_ptr->inventory_list[i];
2545         if (!o_ptr->k_idx) {
2546             continue;
2547         }
2548
2549         int bonus_to_d = o_ptr->to_d;
2550         if (PlayerClass(player_ptr).equals(PlayerClassType::NINJA)) {
2551             if (o_ptr->to_d > 0) {
2552                 bonus_to_d = (o_ptr->to_d + 1) / 2;
2553             }
2554         }
2555         to_dam += (int16_t)bonus_to_d;
2556     }
2557
2558     if (is_shero(player_ptr)) {
2559         to_dam += 3 + (player_ptr->lev / 5);
2560     }
2561
2562     auto player_stun = player_ptr->effects()->stun();
2563     to_dam -= player_stun->get_damage_penalty();
2564     to_dam += ((int)(adj_str_td[player_ptr->stat_index[A_STR]]) - 128);
2565     return to_dam;
2566 }
2567
2568 static int16_t calc_to_hit_misc(PlayerType *player_ptr)
2569 {
2570     ObjectType *o_ptr;
2571
2572     int16_t to_hit = 0;
2573
2574     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2575         o_ptr = &player_ptr->inventory_list[i];
2576         if (!o_ptr->k_idx) {
2577             continue;
2578         }
2579
2580         int bonus_to_h = o_ptr->to_h;
2581         if (PlayerClass(player_ptr).equals(PlayerClassType::NINJA)) {
2582             if (o_ptr->to_h > 0) {
2583                 bonus_to_h = (o_ptr->to_h + 1) / 2;
2584             }
2585         }
2586         to_hit += (int16_t)bonus_to_h;
2587     }
2588
2589     if (is_blessed(player_ptr)) {
2590         to_hit += 10;
2591     }
2592
2593     if (is_hero(player_ptr)) {
2594         to_hit += 12;
2595     }
2596
2597     if (is_shero(player_ptr)) {
2598         to_hit += 12;
2599     }
2600
2601     auto player_stun = player_ptr->effects()->stun();
2602     to_hit -= player_stun->get_damage_penalty();
2603     to_hit += ((int)(adj_dex_th[player_ptr->stat_index[A_DEX]]) - 128);
2604     to_hit += ((int)(adj_str_th[player_ptr->stat_index[A_STR]]) - 128);
2605
2606     return to_hit;
2607 }
2608
2609 static DICE_NUMBER calc_to_weapon_dice_num(PlayerType *player_ptr, INVENTORY_IDX slot)
2610 {
2611     auto *o_ptr = &player_ptr->inventory_list[slot];
2612     return (player_ptr->riding > 0) && o_ptr->is_lance() ? 2 : 0;
2613 }
2614
2615 /*!
2616  * @brief プレイヤーの所持重量制限を計算する /
2617  * Computes current weight limit.
2618  * @return 制限重量(ポンド)
2619  */
2620 WEIGHT calc_weight_limit(PlayerType *player_ptr)
2621 {
2622     WEIGHT i = (WEIGHT)adj_str_wgt[player_ptr->stat_index[A_STR]] * 50;
2623     if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
2624         i = i * 3 / 2;
2625     }
2626     return i;
2627 }
2628
2629 /*!
2630  * @brief update のフラグに応じた更新をまとめて行う / Handle "update"
2631  * @details 更新処理の対象はプレイヤーの能力修正/光源寿命/HP/MP/魔法の学習状態、他多数の外界の状態判定。
2632  */
2633 void update_creature(PlayerType *player_ptr)
2634 {
2635     if (!player_ptr->update) {
2636         return;
2637     }
2638
2639     auto *floor_ptr = player_ptr->current_floor_ptr;
2640     if (any_bits(player_ptr->update, (PU_AUTODESTROY))) {
2641         reset_bits(player_ptr->update, PU_AUTODESTROY);
2642         autopick_delayed_alter(player_ptr);
2643     }
2644
2645     if (any_bits(player_ptr->update, (PU_COMBINE))) {
2646         reset_bits(player_ptr->update, PU_COMBINE);
2647         combine_pack(player_ptr);
2648     }
2649
2650     if (any_bits(player_ptr->update, (PU_REORDER))) {
2651         reset_bits(player_ptr->update, PU_REORDER);
2652         reorder_pack(player_ptr);
2653     }
2654
2655     if (any_bits(player_ptr->update, (PU_BONUS))) {
2656         reset_bits(player_ptr->update, PU_BONUS);
2657         PlayerAlignment(player_ptr).update_alignment();
2658         PlayerSkill ps(player_ptr);
2659         ps.apply_special_weapon_skill_max_values();
2660         ps.limit_weapon_skills_by_max_value();
2661         update_bonuses(player_ptr);
2662     }
2663
2664     if (any_bits(player_ptr->update, (PU_TORCH))) {
2665         reset_bits(player_ptr->update, PU_TORCH);
2666         update_lite_radius(player_ptr);
2667     }
2668
2669     if (any_bits(player_ptr->update, (PU_HP))) {
2670         reset_bits(player_ptr->update, PU_HP);
2671         update_max_hitpoints(player_ptr);
2672     }
2673
2674     if (any_bits(player_ptr->update, (PU_MANA))) {
2675         reset_bits(player_ptr->update, PU_MANA);
2676         update_max_mana(player_ptr);
2677     }
2678
2679     if (any_bits(player_ptr->update, (PU_SPELLS))) {
2680         reset_bits(player_ptr->update, PU_SPELLS);
2681         update_num_of_spells(player_ptr);
2682     }
2683
2684     if (!w_ptr->character_generated) {
2685         return;
2686     }
2687     if (w_ptr->character_icky_depth > 0) {
2688         return;
2689     }
2690     if (any_bits(player_ptr->update, (PU_UN_LITE))) {
2691         reset_bits(player_ptr->update, PU_UN_LITE);
2692         forget_lite(floor_ptr);
2693     }
2694
2695     if (any_bits(player_ptr->update, (PU_UN_VIEW))) {
2696         reset_bits(player_ptr->update, PU_UN_VIEW);
2697         forget_view(floor_ptr);
2698     }
2699
2700     if (any_bits(player_ptr->update, (PU_VIEW))) {
2701         reset_bits(player_ptr->update, PU_VIEW);
2702         update_view(player_ptr);
2703     }
2704
2705     if (any_bits(player_ptr->update, (PU_LITE))) {
2706         reset_bits(player_ptr->update, PU_LITE);
2707         update_lite(player_ptr);
2708     }
2709
2710     if (any_bits(player_ptr->update, (PU_FLOW))) {
2711         reset_bits(player_ptr->update, PU_FLOW);
2712         update_flow(player_ptr);
2713     }
2714
2715     if (any_bits(player_ptr->update, (PU_DISTANCE))) {
2716         reset_bits(player_ptr->update, PU_DISTANCE);
2717
2718         update_monsters(player_ptr, true);
2719     }
2720
2721     if (any_bits(player_ptr->update, (PU_MON_LITE))) {
2722         reset_bits(player_ptr->update, PU_MON_LITE);
2723         update_mon_lite(player_ptr);
2724     }
2725
2726     if (any_bits(player_ptr->update, (PU_DELAY_VIS))) {
2727         reset_bits(player_ptr->update, PU_DELAY_VIS);
2728         delayed_visual_update(player_ptr);
2729     }
2730
2731     if (any_bits(player_ptr->update, (PU_MONSTERS))) {
2732         reset_bits(player_ptr->update, PU_MONSTERS);
2733         update_monsters(player_ptr, false);
2734     }
2735 }
2736
2737 /*!
2738  * @brief プレイヤーが魔道書を一冊も持っていないかを判定する
2739  * @return 魔道書を一冊も持っていないならTRUEを返す
2740  */
2741 bool player_has_no_spellbooks(PlayerType *player_ptr)
2742 {
2743     ObjectType *o_ptr;
2744     for (int i = 0; i < INVEN_PACK; i++) {
2745         o_ptr = &player_ptr->inventory_list[i];
2746         if (o_ptr->k_idx && check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval)) {
2747             return false;
2748         }
2749     }
2750
2751     auto *floor_ptr = player_ptr->current_floor_ptr;
2752     for (const auto this_o_idx : floor_ptr->grid_array[player_ptr->y][player_ptr->x].o_idx_list) {
2753         o_ptr = &floor_ptr->o_list[this_o_idx];
2754         if (o_ptr->k_idx && any_bits(o_ptr->marked, OM_FOUND) && check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval)) {
2755             return false;
2756         }
2757     }
2758
2759     return true;
2760 }
2761
2762 /*!
2763  * @brief プレイヤーを指定座標に配置する / Place the player in the dungeon XXX XXX
2764  * @param x 配置先X座標
2765  * @param y 配置先Y座標
2766  * @return 配置に成功したらTRUE
2767  */
2768 bool player_place(PlayerType *player_ptr, POSITION y, POSITION x)
2769 {
2770     if (player_ptr->current_floor_ptr->grid_array[y][x].m_idx != 0) {
2771         return false;
2772     }
2773
2774     /* Save player location */
2775     player_ptr->y = y;
2776     player_ptr->x = x;
2777     return true;
2778 }
2779
2780 /*!
2781  * @brief 種族アンバライトが出血時パターンの上に乗った際のペナルティ処理
2782  */
2783 void wreck_the_pattern(PlayerType *player_ptr)
2784 {
2785     auto *floor_ptr = player_ptr->current_floor_ptr;
2786     int pattern_type = terrains_info[floor_ptr->grid_array[player_ptr->y][player_ptr->x].feat].subtype;
2787     if (pattern_type == PATTERN_TILE_WRECKED) {
2788         return;
2789     }
2790
2791     msg_print(_("パターンを血で汚してしまった!", "You bleed on the Pattern!"));
2792     msg_print(_("何か恐ろしい事が起こった!", "Something terrible happens!"));
2793
2794     if (!is_invuln(player_ptr)) {
2795         take_hit(player_ptr, DAMAGE_NOESCAPE, damroll(10, 8), _("パターン損壊", "corrupting the Pattern"));
2796     }
2797
2798     int to_ruin = randint1(45) + 35;
2799     while (to_ruin--) {
2800         POSITION r_y, r_x;
2801         scatter(player_ptr, &r_y, &r_x, player_ptr->y, player_ptr->x, 4, PROJECT_NONE);
2802
2803         if (pattern_tile(floor_ptr, r_y, r_x) && (terrains_info[floor_ptr->grid_array[r_y][r_x].feat].subtype != PATTERN_TILE_WRECKED)) {
2804             cave_set_feat(player_ptr, r_y, r_x, feat_pattern_corrupted);
2805         }
2806     }
2807
2808     cave_set_feat(player_ptr, player_ptr->y, player_ptr->x, feat_pattern_corrupted);
2809 }
2810
2811 /*!
2812  * @brief プレイヤーの経験値について整合性のためのチェックと調整を行う /
2813  * Advance experience levels and print experience
2814  */
2815 void check_experience(PlayerType *player_ptr)
2816 {
2817     if (player_ptr->exp < 0) {
2818         player_ptr->exp = 0;
2819     }
2820     if (player_ptr->max_exp < 0) {
2821         player_ptr->max_exp = 0;
2822     }
2823     if (player_ptr->max_max_exp < 0) {
2824         player_ptr->max_max_exp = 0;
2825     }
2826
2827     if (player_ptr->exp > PY_MAX_EXP) {
2828         player_ptr->exp = PY_MAX_EXP;
2829     }
2830     if (player_ptr->max_exp > PY_MAX_EXP) {
2831         player_ptr->max_exp = PY_MAX_EXP;
2832     }
2833     if (player_ptr->max_max_exp > PY_MAX_EXP) {
2834         player_ptr->max_max_exp = PY_MAX_EXP;
2835     }
2836
2837     if (player_ptr->exp > player_ptr->max_exp) {
2838         player_ptr->max_exp = player_ptr->exp;
2839     }
2840     if (player_ptr->max_exp > player_ptr->max_max_exp) {
2841         player_ptr->max_max_exp = player_ptr->max_exp;
2842     }
2843
2844     set_bits(player_ptr->redraw, PR_EXP);
2845     handle_stuff(player_ptr);
2846
2847     PlayerRace pr(player_ptr);
2848     bool android = pr.equals(PlayerRaceType::ANDROID);
2849     PLAYER_LEVEL old_lev = player_ptr->lev;
2850     while ((player_ptr->lev > 1) && (player_ptr->exp < ((android ? player_exp_a : player_exp)[player_ptr->lev - 2] * player_ptr->expfact / 100L))) {
2851         player_ptr->lev--;
2852         set_bits(player_ptr->update, PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
2853         set_bits(player_ptr->redraw, PR_LEV | PR_TITLE);
2854         set_bits(player_ptr->window_flags, PW_PLAYER);
2855         handle_stuff(player_ptr);
2856     }
2857
2858     bool level_reward = false;
2859     bool level_mutation = false;
2860     bool level_inc_stat = false;
2861     while ((player_ptr->lev < PY_MAX_LEVEL) && (player_ptr->exp >= ((android ? player_exp_a : player_exp)[player_ptr->lev - 1] * player_ptr->expfact / 100L))) {
2862         player_ptr->lev++;
2863         if (player_ptr->lev > player_ptr->max_plv) {
2864             player_ptr->max_plv = player_ptr->lev;
2865
2866             if (PlayerClass(player_ptr).equals(PlayerClassType::CHAOS_WARRIOR) || player_ptr->muta.has(PlayerMutationType::CHAOS_GIFT)) {
2867                 level_reward = true;
2868             }
2869             if (pr.equals(PlayerRaceType::BEASTMAN)) {
2870                 if (one_in_(5)) {
2871                     level_mutation = true;
2872                 }
2873             }
2874             level_inc_stat = true;
2875
2876             exe_write_diary(player_ptr, DIARY_LEVELUP, player_ptr->lev, nullptr);
2877         }
2878
2879         sound(SOUND_LEVEL);
2880         msg_format(_("レベル %d にようこそ。", "Welcome to level %d."), player_ptr->lev);
2881         set_bits(player_ptr->update, (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS));
2882         set_bits(player_ptr->redraw, (PR_LEV | PR_TITLE | PR_EXP));
2883         set_bits(player_ptr->window_flags, (PW_PLAYER | PW_SPELL | PW_INVEN));
2884         player_ptr->level_up_message = true;
2885         handle_stuff(player_ptr);
2886
2887         player_ptr->level_up_message = false;
2888         if (level_inc_stat) {
2889             if (!(player_ptr->max_plv % 10)) {
2890                 int choice;
2891                 screen_save();
2892                 while (true) {
2893                     int n;
2894                     char tmp[32];
2895
2896                     cnv_stat(player_ptr->stat_max[0], tmp);
2897                     prt(format(_("        a) 腕力 (現在値 %s)", "        a) Str (cur %s)"), tmp), 2, 14);
2898                     cnv_stat(player_ptr->stat_max[1], tmp);
2899                     prt(format(_("        b) 知能 (現在値 %s)", "        b) Int (cur %s)"), tmp), 3, 14);
2900                     cnv_stat(player_ptr->stat_max[2], tmp);
2901                     prt(format(_("        c) 賢さ (現在値 %s)", "        c) Wis (cur %s)"), tmp), 4, 14);
2902                     cnv_stat(player_ptr->stat_max[3], tmp);
2903                     prt(format(_("        d) 器用 (現在値 %s)", "        d) Dex (cur %s)"), tmp), 5, 14);
2904                     cnv_stat(player_ptr->stat_max[4], tmp);
2905                     prt(format(_("        e) 耐久 (現在値 %s)", "        e) Con (cur %s)"), tmp), 6, 14);
2906                     cnv_stat(player_ptr->stat_max[5], tmp);
2907                     prt(format(_("        f) 魅力 (現在値 %s)", "        f) Chr (cur %s)"), tmp), 7, 14);
2908
2909                     prt("", 8, 14);
2910                     prt(_("        どの能力値を上げますか?", "        Which stat do you want to raise?"), 1, 14);
2911
2912                     while (true) {
2913                         choice = inkey();
2914                         if ((choice >= 'a') && (choice <= 'f')) {
2915                             break;
2916                         }
2917                     }
2918                     for (n = 0; n < A_MAX; n++) {
2919                         if (n != choice - 'a') {
2920                             prt("", n + 2, 14);
2921                         }
2922                     }
2923                     if (get_check(_("よろしいですか?", "Are you sure? "))) {
2924                         break;
2925                     }
2926                 }
2927                 do_inc_stat(player_ptr, choice - 'a');
2928                 screen_load();
2929             } else if (!(player_ptr->max_plv % 2)) {
2930                 do_inc_stat(player_ptr, randint0(6));
2931             }
2932         }
2933
2934         if (level_mutation) {
2935             msg_print(_("あなたは変わった気がする...", "You feel different..."));
2936             (void)gain_mutation(player_ptr, 0);
2937             level_mutation = false;
2938         }
2939
2940         /*
2941          * 報酬でレベルが上ると再帰的に check_experience(player_ptr) が
2942          * 呼ばれるので順番を最後にする。
2943          */
2944         if (level_reward) {
2945             patron_list[player_ptr->chaos_patron].gain_level_reward(player_ptr, 0);
2946             level_reward = false;
2947         }
2948
2949         set_bits(player_ptr->update, PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
2950         set_bits(player_ptr->redraw, (PR_LEV | PR_TITLE));
2951         set_bits(player_ptr->window_flags, (PW_PLAYER | PW_SPELL));
2952         handle_stuff(player_ptr);
2953     }
2954
2955     if (old_lev != player_ptr->lev) {
2956         autopick_load_pref(player_ptr, false);
2957     }
2958 }
2959
2960 /*!
2961  * @brief 現在の修正後能力値を3~17及び18/xxx形式に変換する / Converts stat num into a six-char (right justified) string
2962  * @param val 能力値
2963  * @param out_val 出力先文字列ポインタ
2964  */
2965 void cnv_stat(int val, char *out_val)
2966 {
2967     if (val <= 18) {
2968         sprintf(out_val, "    %2d", val);
2969         return;
2970     }
2971
2972     int bonus = (val - 18);
2973     if (bonus >= 220) {
2974         sprintf(out_val, "18/%3s", "***");
2975     } else if (bonus >= 100) {
2976         sprintf(out_val, "18/%03d", bonus);
2977     } else {
2978         sprintf(out_val, " 18/%02d", bonus);
2979     }
2980 }
2981
2982 /*!
2983  * @brief 能力値現在値から3~17及び18/xxx様式に基づく加減算を行う。
2984  * Modify a stat value by a "modifier", return new value
2985  * @param value 現在値
2986  * @param amount 加減算値
2987  * @return 加減算後の値
2988  * @details
2989  * <pre>
2990  * Stats go up: 3,4,...,17,18,18/10,18/20,...,18/220
2991  * Or even: 18/13, 18/23, 18/33, ..., 18/220
2992  * Stats go down: 18/220, 18/210,..., 18/10, 18, 17, ..., 3
2993  * Or even: 18/13, 18/03, 18, 17, ..., 3
2994  * </pre>
2995  */
2996 int16_t modify_stat_value(int value, int amount)
2997 {
2998     if (amount > 0) {
2999         for (int i = 0; i < amount; i++) {
3000             if (value < 18) {
3001                 value++;
3002             } else {
3003                 value += 10;
3004             }
3005         }
3006     } else if (amount < 0) {
3007         for (int i = 0; i < (0 - amount); i++) {
3008             if (value >= 18 + 10) {
3009                 value -= 10;
3010             } else if (value > 18) {
3011                 value = 18;
3012             } else if (value > 3) {
3013                 value--;
3014             }
3015         }
3016     }
3017
3018     return (int16_t)value;
3019 }
3020
3021 /*!
3022  * @brief スコアを計算する /
3023  * Hack -- Calculates the total number of points earned         -JWT-
3024  * @details
3025  */
3026 long calc_score(PlayerType *player_ptr)
3027 {
3028     int arena_win = std::min<int>(player_ptr->arena_number, MAX_ARENA_MONS);
3029
3030     int mult = 100;
3031     if (!preserve_mode) {
3032         mult += 10;
3033     }
3034     if (!autoroller) {
3035         mult += 10;
3036     }
3037     if (!smart_learn) {
3038         mult -= 20;
3039     }
3040     if (smart_cheat) {
3041         mult += 30;
3042     }
3043     if (ironman_shops) {
3044         mult += 50;
3045     }
3046     if (ironman_small_levels) {
3047         mult += 10;
3048     }
3049     if (ironman_empty_levels) {
3050         mult += 20;
3051     }
3052     if (!powerup_home) {
3053         mult += 50;
3054     }
3055     if (ironman_rooms) {
3056         mult += 100;
3057     }
3058     if (ironman_nightmare) {
3059         mult += 100;
3060     }
3061
3062     if (mult < 5) {
3063         mult = 5;
3064     }
3065
3066     DEPTH max_dl = 0;
3067     for (const auto &d_ref : dungeons_info) {
3068         if (max_dl < max_dlv[d_ref.idx]) {
3069             max_dl = max_dlv[d_ref.idx];
3070         }
3071     }
3072
3073     uint32_t point_l = (player_ptr->max_max_exp + (100 * max_dl));
3074     uint32_t point_h = point_l / 0x10000L;
3075     point_l = point_l % 0x10000L;
3076     point_h *= mult;
3077     point_l *= mult;
3078     point_h += point_l / 0x10000L;
3079     point_l %= 0x10000L;
3080
3081     point_l += ((point_h % 100) << 16);
3082     point_h /= 100;
3083     point_l /= 100;
3084
3085     uint32_t point = (point_h << 16) + (point_l);
3086     if (player_ptr->arena_number >= 0) {
3087         point += (arena_win * arena_win * (arena_win > 29 ? 1000 : 100));
3088     }
3089
3090     if (ironman_downward) {
3091         point *= 2;
3092     }
3093     if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
3094         if (PlayerRace(player_ptr).equals(PlayerRaceType::SPECTRE)) {
3095             point = point / 5;
3096         }
3097     }
3098
3099     if ((player_ptr->ppersonality == PERSONALITY_MUNCHKIN) && point) {
3100         point = 1;
3101         if (w_ptr->total_winner) {
3102             point = 2;
3103         }
3104     }
3105
3106     return point;
3107 }
3108
3109 /*!
3110  * @param player_ptr プレイヤーへの参照ポインタ
3111  * @return 祝福状態ならばTRUE
3112  */
3113 bool is_blessed(PlayerType *player_ptr)
3114 {
3115     return player_ptr->blessed || music_singing(player_ptr, MUSIC_BLESS) || SpellHex(player_ptr).is_spelling_specific(HEX_BLESS);
3116 }
3117
3118 bool is_tim_esp(PlayerType *player_ptr)
3119 {
3120     auto sniper_data = PlayerClass(player_ptr).get_specific_data<sniper_data_type>();
3121     auto sniper_concent = sniper_data ? sniper_data->concent : 0;
3122     return player_ptr->tim_esp || music_singing(player_ptr, MUSIC_MIND) || (sniper_concent >= CONCENT_TELE_THRESHOLD);
3123 }
3124
3125 bool is_tim_stealth(PlayerType *player_ptr)
3126 {
3127     return player_ptr->tim_stealth || music_singing(player_ptr, MUSIC_STEALTH);
3128 }
3129
3130 bool is_time_limit_esp(PlayerType *player_ptr)
3131 {
3132     auto sniper_data = PlayerClass(player_ptr).get_specific_data<sniper_data_type>();
3133     auto sniper_concent = sniper_data ? sniper_data->concent : 0;
3134     return player_ptr->tim_esp || music_singing(player_ptr, MUSIC_MIND) || (sniper_concent >= CONCENT_TELE_THRESHOLD);
3135 }
3136
3137 bool is_time_limit_stealth(PlayerType *player_ptr)
3138 {
3139     return player_ptr->tim_stealth || music_singing(player_ptr, MUSIC_STEALTH);
3140 }
3141
3142 /*!
3143  * @brief 口を使う継続的な処理を中断する
3144  * @param player_ptr プレイヤーへの参照ポインタ
3145  */
3146 void stop_mouth(PlayerType *player_ptr)
3147 {
3148     if (music_singing_any(player_ptr)) {
3149         stop_singing(player_ptr);
3150     }
3151
3152     if (SpellHex(player_ptr).is_spelling_any()) {
3153         (void)SpellHex(player_ptr).stop_all_spells();
3154     }
3155 }
3156
3157 bool is_fast(PlayerType *player_ptr)
3158 {
3159     return player_ptr->effects()->acceleration()->is_fast() || music_singing(player_ptr, MUSIC_SPEED) || music_singing(player_ptr, MUSIC_SHERO);
3160 }
3161
3162 bool is_invuln(PlayerType *player_ptr)
3163 {
3164     return player_ptr->invuln || music_singing(player_ptr, MUSIC_INVULN);
3165 }
3166
3167 bool is_hero(PlayerType *player_ptr)
3168 {
3169     return player_ptr->hero || music_singing(player_ptr, MUSIC_HERO) || music_singing(player_ptr, MUSIC_SHERO);
3170 }
3171
3172 bool is_shero(PlayerType *player_ptr)
3173 {
3174     return player_ptr->shero || PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER);
3175 }
3176
3177 bool is_echizen(PlayerType *player_ptr)
3178 {
3179     return (player_ptr->ppersonality == PERSONALITY_COMBAT) || (player_ptr->inventory_list[INVEN_BOW].fixed_artifact_idx == FixedArtifactId::CRIMSON);
3180 }
3181
3182 bool is_chargeman(PlayerType *player_ptr)
3183 {
3184     return player_ptr->ppersonality == PERSONALITY_CHARGEMAN;
3185 }
3186
3187 WEIGHT calc_weapon_weight_limit(PlayerType *player_ptr)
3188 {
3189     WEIGHT weight = adj_str_hold[player_ptr->stat_index[A_STR]];
3190
3191     if (has_two_handed_weapons(player_ptr)) {
3192         weight *= 2;
3193     }
3194
3195     return weight;
3196 }
3197
3198 WEIGHT calc_bow_weight_limit(PlayerType *player_ptr)
3199 {
3200     WEIGHT weight = adj_str_hold[player_ptr->stat_index[A_STR]];
3201
3202     return weight;
3203 }
3204
3205 static player_hand main_attack_hand(PlayerType *player_ptr)
3206 {
3207     switch (player_melee_type(player_ptr)) {
3208     case MELEE_TYPE_BAREHAND_TWO:
3209         return PLAYER_HAND_MAIN;
3210     case MELEE_TYPE_BAREHAND_MAIN:
3211         return PLAYER_HAND_MAIN;
3212     case MELEE_TYPE_BAREHAND_SUB:
3213         return PLAYER_HAND_SUB;
3214     case MELEE_TYPE_WEAPON_MAIN:
3215         return PLAYER_HAND_MAIN;
3216     case MELEE_TYPE_WEAPON_SUB:
3217         return PLAYER_HAND_SUB;
3218     case MELEE_TYPE_WEAPON_TWOHAND:
3219         return has_melee_weapon(player_ptr, INVEN_MAIN_HAND) ? PLAYER_HAND_MAIN : PLAYER_HAND_SUB;
3220     case MELEE_TYPE_WEAPON_DOUBLE:
3221         return PLAYER_HAND_MAIN;
3222     case MELEE_TYPE_SHIELD_DOUBLE:
3223         return PLAYER_HAND_MAIN;
3224     }
3225     return PLAYER_HAND_MAIN;
3226 }
3227
3228 bool set_quick_and_tiny(PlayerType *player_ptr)
3229 {
3230     auto is_quickly_tiny = player_ptr->inventory_list[INVEN_MAIN_HAND].fixed_artifact_idx == FixedArtifactId::QUICKTHORN;
3231     is_quickly_tiny &= player_ptr->inventory_list[INVEN_SUB_HAND].fixed_artifact_idx == FixedArtifactId::TINYTHORN;
3232     return is_quickly_tiny;
3233 }
3234
3235 bool set_musasi(PlayerType *player_ptr)
3236 {
3237     auto is_musasi = player_ptr->inventory_list[INVEN_MAIN_HAND].fixed_artifact_idx == FixedArtifactId::MUSASI_KATANA;
3238     is_musasi &= player_ptr->inventory_list[INVEN_SUB_HAND].fixed_artifact_idx == FixedArtifactId::MUSASI_WAKIZASI;
3239     return is_musasi;
3240 }
3241
3242 bool set_icing_and_twinkle(PlayerType *player_ptr)
3243 {
3244     auto can_call_ice_wind_saga = player_ptr->inventory_list[INVEN_MAIN_HAND].fixed_artifact_idx == FixedArtifactId::ICINGDEATH;
3245     can_call_ice_wind_saga &= player_ptr->inventory_list[INVEN_SUB_HAND].fixed_artifact_idx == FixedArtifactId::TWINKLE;
3246     return can_call_ice_wind_saga;
3247 }
3248
3249 bool set_anubis_and_chariot(PlayerType *player_ptr)
3250 {
3251     auto is_anubis_chariot = player_ptr->inventory_list[INVEN_MAIN_HAND].fixed_artifact_idx == FixedArtifactId::ANUBIS;
3252     is_anubis_chariot &= player_ptr->inventory_list[INVEN_SUB_HAND].fixed_artifact_idx == FixedArtifactId::SILVER_CHARIOT;
3253     return is_anubis_chariot;
3254 }