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"
124 static const int extra_magic_glove_reduce_mana = 1;
126 static bool is_martial_arts_mode(PlayerType *player_ptr);
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);
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);
150 static int16_t calc_to_hit_bow(PlayerType *player_ptr, bool is_real_value);
152 static int16_t calc_to_damage_misc(PlayerType *player_ptr);
153 static int16_t calc_to_hit_misc(PlayerType *player_ptr);
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);
158 /*** Player information ***/
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系に追い出すべきか?
166 static void delayed_visual_update(PlayerType *player_ptr)
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];
173 g_ptr = &floor_ptr->grid_array[y][x];
174 if (none_bits(g_ptr->info, CAVE_REDRAW)) {
178 if (any_bits(g_ptr->info, CAVE_NOTE)) {
179 note_spot(player_ptr, y, x);
182 lite_spot(player_ptr, y, x);
184 update_monster(player_ptr, g_ptr->m_idx, false);
187 reset_bits(g_ptr->info, (CAVE_NOTE | CAVE_REDRAW));
190 floor_ptr->redraw_n = 0;
194 * @brief 射撃武器がプレイヤーにとって重すぎるかどうかの判定 /
195 * @param o_ptr 判定する射撃武器のアイテム情報参照ポインタ
196 * @return 重すぎるならばTRUE
198 static bool is_heavy_shoot(PlayerType *player_ptr, ObjectType *o_ptr)
200 return calc_bow_weight_limit(player_ptr) < (o_ptr->weight / 10);
205 * @param player_ptr プレイヤーへの参照ポインタ
208 WEIGHT calc_inventory_weight(PlayerType *player_ptr)
213 for (int i = 0; i < INVEN_TOTAL; i++) {
214 o_ptr = &player_ptr->inventory_list[i];
218 weight += o_ptr->weight * o_ptr->number;
223 static void update_ability_scores(PlayerType *player_ptr)
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();
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.
245 * See also update_max_mana() and update_max_hitpoints().
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.
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.
258 * This function induces various "status" messages.
260 * @todo ここで計算していた各値は一部の状態変化メッセージ処理を除き、今後必要な時に適示計算する形に移行するためほぼすべて削られる。
262 static void update_bonuses(PlayerType *player_ptr)
264 auto empty_hands_status = empty_hands(player_ptr, true);
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;
285 ARMOUR_CLASS old_dis_ac = player_ptr->dis_ac;
286 ARMOUR_CLASS old_dis_to_a = player_ptr->dis_to_a;
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);
326 player_ptr->lite = has_lite(player_ptr);
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);
334 update_ability_scores(player_ptr);
335 o_ptr = &player_ptr->inventory_list[INVEN_BOW];
337 player_ptr->tval_ammo = bow_tval_ammo(o_ptr);
338 player_ptr->num_fire = calc_num_fire(player_ptr, o_ptr);
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;
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);
381 if (old_mighty_throw != player_ptr->mighty_throw) {
382 player_ptr->window_flags |= PW_INVEN;
385 if (player_ptr->telepathy != old_telepathy) {
386 set_bits(player_ptr->update, PU_MONSTERS);
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);
393 if (player_ptr->see_inv != old_see_inv) {
394 set_bits(player_ptr->update, PU_MONSTERS);
397 if (player_ptr->pspeed != old_speed) {
398 set_bits(player_ptr->redraw, PR_SPEED);
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);
406 if (w_ptr->character_xtra) {
410 put_equipment_warning(player_ptr);
411 check_no_flowed(player_ptr);
415 * @brief プレイヤーの最大HPを更新する /
416 * Update the players maximal hit points
417 * Adjust current hitpoints if necessary
420 static void update_max_hitpoints(PlayerType *player_ptr)
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];
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;
431 tmp_hitdie = r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
433 tmp_hitdie = r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
436 mhp = mhp * tmp_hitdie / player_ptr->hitdie;
440 if (player_ptr->lev < 30) {
441 mhp = (mhp * (45 + player_ptr->lev) / 100);
443 mhp = (mhp * 75 / 100);
445 bonus = (bonus * 65 / 100);
450 if (pc.equals(PlayerClassType::BERSERKER)) {
451 mhp = mhp * (110 + (((player_ptr->lev + 40) * (player_ptr->lev + 40) - 1550) / 110)) / 100;
454 if (mhp < player_ptr->lev + 1) {
455 mhp = player_ptr->lev + 1;
457 if (is_hero(player_ptr)) {
460 if (is_shero(player_ptr)) {
463 if (player_ptr->tsuyoshi) {
466 if (SpellHex(player_ptr).is_spelling_specific(HEX_XTRA_MIGHT)) {
469 if (SpellHex(player_ptr).is_spelling_specific(HEX_BUILDING)) {
472 if (player_ptr->mhp == mhp) {
476 if (player_ptr->chp >= mhp) {
477 player_ptr->chp = mhp;
478 player_ptr->chp_frac = 0;
482 if (player_ptr->level_up_message && (mhp > player_ptr->mhp)) {
483 msg_format("最大ヒット・ポイントが %d 増加した!", (mhp - player_ptr->mhp));
486 player_ptr->mhp = mhp;
488 player_ptr->redraw |= PR_HP;
489 player_ptr->window_flags |= PW_PLAYER;
493 * @brief プレイヤーの現在学習可能な魔法数を計算し、増減に応じて魔法の忘却、再学習を処置する。 /
494 * Calculate number of spells player should have, and forget,
495 * or remember, spells until that number is properly reflected.
497 * Note that this function induces various "status" messages,
498 * which must be bypasses until the character is created.
500 static void update_num_of_spells(PlayerType *player_ptr)
502 if ((mp_ptr->spell_book == ItemKindType::NONE) || !w_ptr->character_generated || w_ptr->character_xtra) {
506 PlayerClass pc(player_ptr);
507 if (pc.is_every_magic()) {
508 player_ptr->new_spells = 0;
512 concptr p = spell_category_name(mp_ptr->spell_book);
513 int levels = player_ptr->lev - mp_ptr->spell_first + 1;
518 int num_allowed = (adj_mag_study[player_ptr->stat_index[mp_ptr->spell_stat]] * levels / 2);
520 if (!pc.equals(PlayerClassType::SAMURAI) && (mp_ptr->spell_book != ItemKindType::LIFE_BOOK)) {
524 if (pc.equals(PlayerClassType::SAMURAI)) {
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;
531 } else if (pc.equals(PlayerClassType::MAGE) || pc.equals(PlayerClassType::PRIEST)) {
532 if (num_allowed > (96 + bonus)) {
533 num_allowed = 96 + bonus;
536 if (num_allowed > (80 + bonus)) {
537 num_allowed = 80 + bonus;
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)))) {
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) {
554 int j = player_ptr->spell_order[i];
559 const magic_type *s_ptr;
560 if (!is_magic((j < 32) ? player_ptr->realm1 : player_ptr->realm2)) {
562 s_ptr = &technic_info[player_ptr->realm1 - MIN_TECHNIC][j];
564 s_ptr = &technic_info[player_ptr->realm2 - MIN_TECHNIC][j % 32];
567 s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
569 s_ptr = &mp_ptr->info[player_ptr->realm2 - 1][j % 32];
572 if (s_ptr->slevel <= player_ptr->lev) {
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) {
583 set_bits(player_ptr->spell_forgotten1, (1UL << j));
584 which = player_ptr->realm1;
586 set_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
587 which = player_ptr->realm2;
591 reset_bits(player_ptr->spell_learned1, (1UL << j));
592 which = player_ptr->realm1;
594 reset_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
595 which = player_ptr->realm2;
599 msg_format("%sの%sを忘れてしまった。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
601 msg_format("You have forgotten the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
603 player_ptr->new_spells++;
606 /* Forget spells if we know too many spells */
607 for (int i = 63; i >= 0; i--) {
608 if (player_ptr->new_spells >= 0) {
611 if (!player_ptr->spell_learned1 && !player_ptr->spell_learned2) {
615 int j = player_ptr->spell_order[i];
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) {
627 set_bits(player_ptr->spell_forgotten1, (1UL << j));
628 which = player_ptr->realm1;
630 set_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
631 which = player_ptr->realm2;
635 reset_bits(player_ptr->spell_learned1, (1UL << j));
636 which = player_ptr->realm1;
638 reset_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
639 which = player_ptr->realm2;
643 msg_format("%sの%sを忘れてしまった。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
645 msg_format("You have forgotten the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
647 player_ptr->new_spells++;
650 /* Check for spells to remember */
651 for (int i = 0; i < 64; i++) {
652 if (player_ptr->new_spells <= 0) {
655 if (!player_ptr->spell_forgotten1 && !player_ptr->spell_forgotten2) {
658 int j = player_ptr->spell_order[i];
663 const magic_type *s_ptr;
664 if (!is_magic((j < 32) ? player_ptr->realm1 : player_ptr->realm2)) {
666 s_ptr = &technic_info[player_ptr->realm1 - MIN_TECHNIC][j];
668 s_ptr = &technic_info[player_ptr->realm2 - MIN_TECHNIC][j % 32];
671 s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
673 s_ptr = &mp_ptr->info[player_ptr->realm2 - 1][j % 32];
676 if (s_ptr->slevel > player_ptr->lev) {
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) {
687 reset_bits(player_ptr->spell_forgotten1, (1UL << j));
688 which = player_ptr->realm1;
690 reset_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
691 which = player_ptr->realm2;
695 set_bits(player_ptr->spell_learned1, (1UL << j));
696 which = player_ptr->realm1;
698 set_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
699 which = player_ptr->realm2;
703 msg_format("%sの%sを思い出した。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
705 msg_format("You have remembered the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
707 player_ptr->new_spells--;
710 if (player_ptr->realm2 == REALM_NONE) {
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];
717 s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
720 if (s_ptr->slevel > player_ptr->lev) {
724 if (any_bits(player_ptr->spell_learned1, (1UL << j))) {
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;
739 if (player_ptr->new_spells < 0) {
740 player_ptr->new_spells = 0;
743 if (player_ptr->old_spells == player_ptr->new_spells) {
747 if (player_ptr->new_spells) {
749 if (player_ptr->new_spells < 10) {
750 msg_format("あと %d つの%sを学べる。", player_ptr->new_spells, p);
752 msg_format("あと %d 個の%sを学べる。", player_ptr->new_spells, p);
755 msg_format("You can learn %d more %s%s.", player_ptr->new_spells, p, (player_ptr->new_spells != 1) ? "s" : "");
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);
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.
769 * This function induces status messages.
771 static void update_max_mana(PlayerType *player_ptr)
773 if ((mp_ptr->spell_book == ItemKindType::NONE) && mp_ptr->spell_first == SPELL_FIRST_NO_SPELL) {
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;
786 if (mp_ptr->spell_first > player_ptr->lev) {
788 set_bits(player_ptr->redraw, PR_MANA);
792 levels = (player_ptr->lev - mp_ptr->spell_first) + 1;
796 if (pc.equals(PlayerClassType::SAMURAI)) {
797 msp = (adj_mag_mana[player_ptr->stat_index[mp_ptr->spell_stat]] + 10) * 2;
799 msp += (msp * rp_ptr->r_adj[mp_ptr->spell_stat] / 20);
802 msp = adj_mag_mana[player_ptr->stat_index[mp_ptr->spell_stat]] * (levels + 3) / 4;
807 msp += (msp * rp_ptr->r_adj[mp_ptr->spell_stat] / 20);
809 if (msp && (player_ptr->ppersonality == PERSONALITY_MUNCHKIN)) {
812 if (msp && pc.equals(PlayerClassType::HIGH_MAGE)) {
815 if (msp && pc.equals(PlayerClassType::SORCERER)) {
816 msp += msp * (25 + player_ptr->lev) / 100;
820 if (any_bits(mp_ptr->spell_xtra, extra_magic_glove_reduce_mana)) {
821 player_ptr->cumber_glove = false;
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;
831 player_ptr->cumber_armor = false;
834 if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval > ItemKindType::SWORD) {
835 cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight;
837 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval > ItemKindType::SWORD) {
838 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight;
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;
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;
857 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
858 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight;
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;
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;
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;
879 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
880 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 2;
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;
891 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
892 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 3;
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;
901 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
902 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 5;
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;
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;
932 case PlayerClassType::SORCERER: {
933 msp -= msp * (cur_wgt - max_wgt) / 900;
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;
943 case PlayerClassType::PALADIN:
944 case PlayerClassType::CHAOS_WARRIOR:
945 case PlayerClassType::WARRIOR_MAGE: {
946 msp -= msp * (cur_wgt - max_wgt) / 1200;
949 case PlayerClassType::SAMURAI: {
950 player_ptr->cumber_armor = false;
954 msp -= msp * (cur_wgt - max_wgt) / 800;
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;
971 if (player_ptr->level_up_message && (msp > player_ptr->msp)) {
972 msg_format("最大マジック・ポイントが %d 増加した!", (msp - player_ptr->msp));
975 player_ptr->msp = msp;
976 set_bits(player_ptr->redraw, PR_MANA);
977 set_bits(player_ptr->window_flags, (PW_PLAYER | PW_SPELL));
980 if (w_ptr->character_xtra) {
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."));
988 msg_print(_("この手の状態なら、ぐっと呪文が唱えやすい感じだ。", "Your hands feel more suitable for spellcasting."));
991 player_ptr->old_cumber_glove = player_ptr->cumber_glove;
994 if (player_ptr->old_cumber_armor == player_ptr->cumber_armor) {
998 if (player_ptr->cumber_armor) {
999 msg_print(_("装備の重さで動きが鈍くなってしまっている。", "The weight of your equipment encumbers your movement."));
1001 msg_print(_("ぐっと楽に体を動かせるようになった。", "You feel able to move more freely."));
1004 player_ptr->old_cumber_armor = player_ptr->cumber_armor;
1008 * @brief 装備中の射撃武器の威力倍率を返す /
1009 * calcurate the fire rate of target object
1010 * @param o_ptr 計算する射撃武器のアイテム情報参照ポインタ
1011 * @return 射撃倍率の値(100で1.00倍)
1013 int16_t calc_num_fire(PlayerType *player_ptr, ObjectType *o_ptr)
1015 int extra_shots = 0;
1017 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1019 q_ptr = &player_ptr->inventory_list[i];
1020 if (!q_ptr->k_idx) {
1024 if (i == INVEN_BOW) {
1028 auto flgs = object_flags(q_ptr);
1029 if (flgs.has(TR_XTRA_SHOTS)) {
1034 auto flgs = object_flags(o_ptr);
1035 if (flgs.has(TR_XTRA_SHOTS)) {
1040 if (o_ptr->k_idx == 0) {
1041 return (int16_t)num;
1045 num += (extra_shots * 100);
1047 if (is_heavy_shoot(player_ptr, o_ptr)) {
1048 return (int16_t)num;
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);
1057 if (pc.equals(PlayerClassType::CAVALRY) && (tval_ammo == ItemKindType::ARROW)) {
1058 num += (player_ptr->lev * 3);
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);
1069 if (pc.equals(PlayerClassType::WARRIOR) && (tval_ammo <= ItemKindType::BOLT) && (tval_ammo >= ItemKindType::SHOT)) {
1070 num += (player_ptr->lev * 2);
1073 if (pc.equals(PlayerClassType::ROGUE) && (tval_ammo == ItemKindType::SHOT)) {
1074 num += (player_ptr->lev * 4);
1077 return (int16_t)num;
1082 * @param player_ptr プレイヤーへの参照ポインタ
1086 * * 職業と性格とレベルによる追加加算
1087 * * 器用さに応じたadj_dex_disテーブルによる加算
1088 * * 知力に応じたadj_int_disテーブルによる加算
1090 static ACTION_SKILL_POWER calc_disarming(PlayerType *player_ptr)
1092 ACTION_SKILL_POWER pow;
1093 const player_race_info *tmp_rp_ptr;
1095 if (player_ptr->mimic_form != MimicKindType::NONE) {
1096 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1098 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1101 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1102 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
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]];
1113 * @param player_ptr プレイヤーへの参照ポインタ
1117 * * 職業と性格とレベルによる追加加算
1118 * * 装備による加算(TR_MAGIC_MASTERYを持っていたら+pval*8)
1119 * * 知力に応じたadj_int_devテーブルによる加算
1122 static ACTION_SKILL_POWER calc_device_ability(PlayerType *player_ptr)
1124 ACTION_SKILL_POWER pow;
1125 const player_race_info *tmp_rp_ptr;
1127 if (player_ptr->mimic_form != MimicKindType::NONE) {
1128 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1130 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1133 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1134 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
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));
1139 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1141 o_ptr = &player_ptr->inventory_list[i];
1142 if (!o_ptr->k_idx) {
1145 auto flgs = object_flags(o_ptr);
1146 if (flgs.has(TR_MAGIC_MASTERY)) {
1147 pow += 8 * o_ptr->pval;
1151 pow += adj_int_dev[player_ptr->stat_index[A_INT]];
1153 if (is_shero(player_ptr)) {
1161 * @param player_ptr プレイヤーへの参照ポインタ
1165 * * 職業と性格とレベルによる追加加算
1166 * * 変異MUT3_MAGIC_RESによる加算(15 + レベル / 5)
1167 * * 呪力耐性の装備による加算(30)
1168 * * 祝福された装備による加算(5 + レベル / 10)
1169 * * 賢さによるadj_wis_savテーブル加算
1170 * * 呪力弱点の装備による減算(-10)
1171 * * 呪力弱点の装備が強力に呪われているときさらに減算(-20)
1173 * * 反魔法持ちで大なり上書き(90+レベル未満ならその値に上書き)
1174 * * クターのつぶれ状態なら(10に上書き)
1175 * * 生命の「究極の耐性」や regist_magic,magicdef持ちなら大なり上書き(95+レベル未満ならその値に上書き)
1176 * * 呪いのdown_savingがかかっているなら半減
1178 static ACTION_SKILL_POWER calc_saving_throw(PlayerType *player_ptr)
1180 ACTION_SKILL_POWER pow;
1181 const player_race_info *tmp_rp_ptr;
1183 if (player_ptr->mimic_form != MimicKindType::NONE) {
1184 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1186 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1189 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1190 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
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));
1195 if (player_ptr->muta.has(PlayerMutationType::MAGIC_RES)) {
1196 pow += (15 + (player_ptr->lev / 5));
1199 if (has_resist_curse(player_ptr)) {
1203 if (player_ptr->bless_blade) {
1204 pow += 6 + (player_ptr->lev - 1) / 10;
1207 pow += adj_wis_sav[player_ptr->stat_index[A_WIS]];
1209 if (has_vuln_curse(player_ptr)) {
1213 if (has_heavy_vuln_curse(player_ptr)) {
1217 if (is_shero(player_ptr)) {
1221 if (player_ptr->anti_magic && (pow < (90 + player_ptr->lev))) {
1222 pow = 90 + player_ptr->lev;
1225 if (player_ptr->tsubureru) {
1229 if ((player_ptr->ult_res || player_ptr->resist_magic || player_ptr->magicdef) && (pow < (95 + player_ptr->lev))) {
1230 pow = 95 + player_ptr->lev;
1233 if (player_ptr->down_saving) {
1242 * @param player_ptr プレイヤーへの参照ポインタ
1247 * * 各装備による加算(TR_SEARCHがあれば+pval*5)
1249 * * 変異(MUT3_XTRA_EYES)による加算(+15)
1251 static ACTION_SKILL_POWER calc_search(PlayerType *player_ptr)
1253 ACTION_SKILL_POWER pow;
1254 const player_race_info *tmp_rp_ptr;
1256 if (player_ptr->mimic_form != MimicKindType::NONE) {
1257 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1259 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1262 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1263 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
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);
1268 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1270 o_ptr = &player_ptr->inventory_list[i];
1271 if (!o_ptr->k_idx) {
1274 auto flgs = object_flags(o_ptr);
1275 if (flgs.has(TR_SEARCH)) {
1276 pow += (o_ptr->pval * 5);
1280 if (player_ptr->muta.has(PlayerMutationType::XTRA_EYES)) {
1284 if (is_shero(player_ptr)) {
1293 * @param player_ptr プレイヤーへの参照ポインタ
1298 * * 各装備による加算(TR_SEARCHがあれば+pval*5)
1300 * * 変異(MUT3_XTRA_EYES)による加算(+15)
1302 static ACTION_SKILL_POWER calc_search_freq(PlayerType *player_ptr)
1304 ACTION_SKILL_POWER pow;
1305 const player_race_info *tmp_rp_ptr;
1307 if (player_ptr->mimic_form != MimicKindType::NONE) {
1308 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1310 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1313 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1314 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
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);
1319 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1321 o_ptr = &player_ptr->inventory_list[i];
1322 if (!o_ptr->k_idx) {
1325 auto flgs = object_flags(o_ptr);
1326 if (flgs.has(TR_SEARCH)) {
1327 pow += (o_ptr->pval * 5);
1331 if (is_shero(player_ptr)) {
1335 if (player_ptr->muta.has(PlayerMutationType::XTRA_EYES)) {
1344 * @param player_ptr プレイヤーへの参照ポインタ
1347 * * 種族/職業/性格による加算とレベルによる追加加算
1349 static ACTION_SKILL_POWER calc_to_hit_melee(PlayerType *player_ptr)
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];
1356 if (player_ptr->mimic_form != MimicKindType::NONE) {
1357 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1359 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
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));
1369 * @param player_ptr プレイヤーへの参照ポインタ
1372 * * 種族/職業/性格による加算とレベルによる追加加算
1374 static ACTION_SKILL_POWER calc_to_hit_shoot(PlayerType *player_ptr)
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];
1381 if (player_ptr->mimic_form != MimicKindType::NONE) {
1382 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1384 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
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));
1394 * @param player_ptr プレイヤーへの参照ポインタ
1397 * * 種族/職業/性格による加算とレベルによる追加加算
1400 static ACTION_SKILL_POWER calc_to_hit_throw(PlayerType *player_ptr)
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];
1407 if (player_ptr->mimic_form != MimicKindType::NONE) {
1408 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1410 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
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));
1416 if (is_shero(player_ptr)) {
1425 * @param player_ptr プレイヤーへの参照ポインタ
1436 static ACTION_SKILL_POWER calc_skill_dig(PlayerType *player_ptr)
1440 ACTION_SKILL_POWER pow;
1444 if (PlayerRace(player_ptr).equals(PlayerRaceType::ENT) && !player_ptr->inventory_list[INVEN_MAIN_HAND].k_idx) {
1445 pow += player_ptr->lev * 10;
1448 if (is_shero(player_ptr)) {
1452 pow += adj_str_dig[player_ptr->stat_index[A_STR]];
1454 if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
1455 pow += (100 + player_ptr->lev * 8);
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) {
1463 auto flgs = object_flags(o_ptr);
1464 if (flgs.has(TR_TUNNEL)) {
1465 pow += (o_ptr->pval * 20);
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);
1476 if (is_shero(player_ptr)) {
1487 static bool is_martial_arts_mode(PlayerType *player_ptr)
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);
1496 static bool is_heavy_wield(PlayerType *player_ptr, int i)
1498 const auto *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + i];
1500 return has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i) && (calc_weapon_weight_limit(player_ptr) < o_ptr->weight / 10);
1503 static int16_t calc_num_blow(PlayerType *player_ptr, int i)
1506 int16_t num_blow = 1;
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;
1516 auto &info = class_info[enum2i(player_ptr->pclass)];
1521 if (pc.equals(PlayerClassType::CAVALRY) && player_ptr->riding && flgs.has(TR_RIDING)) {
1527 if (SpellHex(player_ptr).is_spelling_specific(HEX_XTRA_MIGHT) || SpellHex(player_ptr).is_spelling_specific(HEX_BUILDING)) {
1533 div = ((o_ptr->weight < wgt) ? wgt : o_ptr->weight);
1534 str_index = (adj_str_blow[player_ptr->stat_index[A_STR]] * mul / div);
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;
1539 if (pc.equals(PlayerClassType::NINJA)) {
1540 str_index = std::max(0, str_index - 1);
1542 if (str_index > 11) {
1546 dex_index = (adj_dex_blow[player_ptr->stat_index[A_DEX]]);
1547 if (dex_index > 11) {
1551 num_blow = blows_table[str_index][dex_index];
1552 if (num_blow > num) {
1553 num_blow = (int16_t)num;
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)) {
1565 if (PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::FUUJIN)) {
1569 if ((o_ptr->tval == ItemKindType::SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) {
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]];
1587 if (pc.equals(PlayerClassType::FORCETRAINER)) {
1588 if (blow_base > 18) {
1591 if (blow_base > 31) {
1594 if (blow_base > 44) {
1597 if (blow_base > 58) {
1601 if (blow_base > 12) {
1604 if (blow_base > 22) {
1607 if (blow_base > 31) {
1610 if (blow_base > 39) {
1613 if (blow_base > 46) {
1616 if (blow_base > 53) {
1619 if (blow_base > 59) {
1624 if (heavy_armor(player_ptr) && !pc.equals(PlayerClassType::BERSERKER)) {
1628 if (pc.monk_stance_is(MonkStanceType::GENBU)) {
1630 if (pc.equals(PlayerClassType::MONK) && (player_ptr->lev > 42)) {
1636 } else if (pc.monk_stance_is(MonkStanceType::SUZAKU)) {
1640 num_blow += 1 + player_ptr->extra_blows[0];
1643 if (has_not_ninja_weapon(player_ptr, i)) {
1655 * @param player_ptr プレイヤーへの参照ポインタ
1658 * * 性格なまけものなら加算(+10)
1660 * * 性格ちからじまんとがまんづよいなら加算(+1)
1661 * * 性格チャージマンなら加算(+5)
1662 * * 装備品にTRC::HARD_SPELLがあるなら加算(軽い呪いなら+3/重い呪いなら+10)
1664 static int16_t calc_to_magic_chance(PlayerType *player_ptr)
1668 if (player_ptr->ppersonality == PERSONALITY_LAZY) {
1671 if (player_ptr->ppersonality == PERSONALITY_SHREWD) {
1674 if ((player_ptr->ppersonality == PERSONALITY_PATIENT) || (player_ptr->ppersonality == PERSONALITY_MIGHTY)) {
1677 if (player_ptr->ppersonality == PERSONALITY_CHARGEMAN) {
1681 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1683 o_ptr = &player_ptr->inventory_list[i];
1684 if (!o_ptr->k_idx) {
1688 if (o_ptr->curse_flags.has(CurseTraitType::HARD_SPELL)) {
1689 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
1699 static ARMOUR_CLASS calc_base_ac(PlayerType *player_ptr)
1701 ARMOUR_CLASS ac = 0;
1702 if (player_ptr->yoiyami) {
1706 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1708 o_ptr = &player_ptr->inventory_list[i];
1709 if (!o_ptr->k_idx) {
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;
1724 static ARMOUR_CLASS calc_to_ac(PlayerType *player_ptr, bool is_real_value)
1726 ARMOUR_CLASS ac = 0;
1727 if (player_ptr->yoiyami) {
1731 ac += ((int)(adj_dex_ta[player_ptr->stat_index[A_DEX]]) - 128);
1733 switch (player_ptr->mimic_form) {
1734 case MimicKindType::NONE:
1736 case MimicKindType::DEMON:
1739 case MimicKindType::DEMON_LORD:
1742 case MimicKindType::VAMPIRE:
1747 PlayerClass pc(player_ptr);
1748 if (pc.equals(PlayerClassType::BERSERKER)) {
1749 ac += 10 + player_ptr->lev / 2;
1752 if (pc.equals(PlayerClassType::SORCERER)) {
1756 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1758 o_ptr = &player_ptr->inventory_list[i];
1759 auto flags = object_flags(o_ptr);
1760 if (!o_ptr->k_idx) {
1763 if (is_real_value || o_ptr->is_known()) {
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()) {
1773 if (is_real_value || o_ptr->is_fully_known()) {
1779 if ((i == INVEN_SUB_HAND) && flags.has(TR_SUPPORTIVE)) {
1784 PlayerRace pr(player_ptr);
1785 if (pr.equals(PlayerRaceType::GOLEM) || pr.equals(PlayerRaceType::ANDROID)) {
1786 ac += 10 + (player_ptr->lev * 2 / 5);
1789 if (set_quick_and_tiny(player_ptr)) {
1793 if (set_musasi(player_ptr)) {
1797 if (set_icing_and_twinkle(player_ptr)) {
1801 if (player_ptr->muta.has(PlayerMutationType::WART_SKIN)) {
1805 if (player_ptr->muta.has(PlayerMutationType::SCALES)) {
1809 if (player_ptr->muta.has(PlayerMutationType::IRON_SKIN)) {
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;
1817 if (!(player_ptr->inventory_list[INVEN_OUTER].k_idx) && (player_ptr->lev > 15)) {
1818 ac += ((player_ptr->lev - 13) / 3);
1820 if (!(player_ptr->inventory_list[INVEN_SUB_HAND].k_idx) && (player_ptr->lev > 10)) {
1821 ac += ((player_ptr->lev - 8) / 3);
1823 if (!(player_ptr->inventory_list[INVEN_HEAD].k_idx) && (player_ptr->lev > 4)) {
1824 ac += (player_ptr->lev - 2) / 3;
1826 if (!(player_ptr->inventory_list[INVEN_ARMS].k_idx)) {
1827 ac += (player_ptr->lev / 2);
1829 if (!(player_ptr->inventory_list[INVEN_FEET].k_idx)) {
1830 ac += (player_ptr->lev / 3);
1834 if (player_ptr->realm1 == REALM_HEX) {
1835 if (SpellHex(player_ptr).is_spelling_specific(HEX_ICE_ARMOR)) {
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) {
1844 if (!o_ptr->is_armour()) {
1847 if (!o_ptr->is_cursed()) {
1850 if (o_ptr->curse_flags.has(CurseTraitType::CURSED)) {
1853 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
1856 if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
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)) {
1866 } else if (pc.monk_stance_is(MonkStanceType::SEIRYU)) {
1868 } else if (pc.samurai_stance_is(SamuraiStanceType::KOUKIJIN)) {
1872 if (player_ptr->ult_res || (pc.samurai_stance_is(SamuraiStanceType::MUSOU))) {
1874 } else if (player_ptr->tsubureru || player_ptr->shield || player_ptr->magicdef) {
1878 if (is_blessed(player_ptr)) {
1882 if (is_shero(player_ptr)) {
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;
1896 * @brief 二刀流ペナルティ量計算
1897 * @param player_ptr プレイヤーへの参照ポインタ
1898 * @param slot ペナルティ量を計算する武器スロット
1903 * * EASY2_WEAPONによる軽減
1904 * * SUPPORTIVEを左に装備した場合の軽減
1908 int16_t calc_double_weapon_penalty(PlayerType *player_ptr, INVENTORY_IDX slot)
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]);
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;
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)) {
1926 if (flags.has(TR_SUPPORTIVE)) {
1927 penalty = std::max(0, penalty - 10);
1930 if (set_musasi(player_ptr)) {
1931 penalty = std::min(0, penalty);
1934 if (player_ptr->inventory_list[slot].tval == ItemKindType::POLEARM) {
1938 return (int16_t)penalty;
1941 static bool is_riding_two_hands(PlayerType *player_ptr)
1943 if (!player_ptr->riding) {
1947 if (has_two_handed_weapons(player_ptr) || (empty_hands(player_ptr, false) == EMPTY_HAND_NONE)) {
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)) {
1966 static int16_t calc_riding_bow_penalty(PlayerType *player_ptr)
1968 auto *floor_ptr = player_ptr->current_floor_ptr;
1969 if (!player_ptr->riding) {
1973 int16_t penalty = 0;
1975 if (PlayerClass(player_ptr).is_tamer()) {
1976 if (player_ptr->tval_ammo != ItemKindType::ARROW) {
1980 penalty = monraces_info[floor_ptr->m_list[player_ptr->riding].r_idx].level - player_ptr->skill_exp[PlayerSkillKindType::RIDING] / 80;
1987 if (player_ptr->tval_ammo == ItemKindType::BOLT) {
1994 void put_equipment_warning(PlayerType *player_ptr)
1996 bool heavy_shoot = is_heavy_shoot(player_ptr, &player_ptr->inventory_list[INVEN_BOW]);
1997 if (player_ptr->old_heavy_shoot != 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."));
2003 msg_print(_("重い弓を装備からはずして体が楽になった。", "You feel relieved to put down your heavy bow."));
2005 player_ptr->old_heavy_shoot = heavy_shoot;
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."));
2017 msg_print(_("重い武器を装備からはずして体が楽になった。", "You feel relieved to put down your heavy weapon."));
2020 player_ptr->old_heavy_wield[i] = player_ptr->heavy_wield[i];
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."));
2032 player_ptr->old_riding_wield[i] = player_ptr->is_icky_riding_wield[i];
2035 if (player_ptr->old_icky_wield[i] == player_ptr->is_icky_wield[i]) {
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);
2044 } else if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
2045 msg_print(_("今の装備は自分にふさわしい気がする。", "You feel comfortable with your weapon."));
2047 msg_print(_("装備をはずしたら随分と気が楽になった。", "You feel more comfortable after removing your weapon."));
2050 player_ptr->old_icky_wield[i] = player_ptr->is_icky_wield[i];
2053 if (player_ptr->riding && (player_ptr->old_riding_ryoute != player_ptr->riding_ryoute)) {
2054 if (player_ptr->riding_ryoute) {
2056 msg_format("%s馬を操れない。", (empty_hands(player_ptr, false) == EMPTY_HAND_NONE) ? "両手がふさがっていて" : "");
2058 msg_print("You are using both hand for fighting, and you can't control the pet you're riding.");
2062 msg_format("%s馬を操れるようになった。", (empty_hands(player_ptr, false) == EMPTY_HAND_NONE) ? "手が空いて" : "");
2064 msg_print("You began to control the pet you're riding with one hand.");
2068 player_ptr->old_riding_ryoute = player_ptr->riding_ryoute;
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);
2079 msg_print(_("バランスがとれるようになった。", "You regain your balance."));
2082 player_ptr->monk_notify_aux = heavy_armor(player_ptr);
2086 static short calc_to_damage(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value)
2088 auto *o_ptr = &player_ptr->inventory_list[slot];
2089 auto flgs = object_flags(o_ptr);
2091 player_hand calc_hand = PLAYER_HAND_OTHER;
2092 if (slot == INVEN_MAIN_HAND) {
2093 calc_hand = PLAYER_HAND_MAIN;
2095 if (slot == INVEN_SUB_HAND) {
2096 calc_hand = PLAYER_HAND_SUB;
2100 damage += ((int)(adj_str_td[player_ptr->stat_index[A_STR]]) - 128);
2102 if (is_shero(player_ptr)) {
2103 damage += 3 + (player_ptr->lev / 5);
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))) {
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;
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)))) {
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;
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)) {
2134 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2137 if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
2143 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
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) {
2150 if (!o_ptr->is_known() && !is_real_value) {
2153 bonus_to_d = o_ptr->to_d;
2155 if (pc.equals(PlayerClassType::NINJA)) {
2156 if (o_ptr->to_d > 0) {
2157 bonus_to_d = (o_ptr->to_d + 1) / 2;
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;
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;
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;
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;
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;
2200 case MELEE_TYPE_SHIELD_DOUBLE:
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)) {
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);
2216 if (is_martial_arts_mode(player_ptr) && (!heavy_armor(player_ptr) || !pc.equals(PlayerClassType::BERSERKER))) {
2217 damage += (player_ptr->lev / 6);
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);
2227 return static_cast<short>(damage);
2231 * @brief 武器の命中修正を計算する。 / Calculate hit bonus from a wielded weapon.
2233 * 'slot' MUST be INVEN_MAIN_HAND or INVEM_SUB_HAND.
2235 static short calc_to_hit(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value)
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);
2243 /* Temporary bonuses */
2244 if (is_blessed(player_ptr)) {
2248 if (is_hero(player_ptr)) {
2252 if (is_shero(player_ptr)) {
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;
2262 if (slot == INVEN_SUB_HAND) {
2263 calc_hand = PLAYER_HAND_SUB;
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) {
2274 case MELEE_TYPE_BAREHAND_SUB:
2275 if (player_ptr->riding) {
2279 case MELEE_TYPE_BAREHAND_TWO:
2280 hit += (player_ptr->skill_exp[PlayerSkillKindType::MARTIAL_ARTS] - PlayerSkill::weapon_exp_at(PlayerSkillRank::BEGINNER)) / 200;
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)) {
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);
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);
2300 /* Traind bonuses */
2301 hit += (player_ptr->weapon_exp[o_ptr->tval][o_ptr->sval] - PlayerSkill::weapon_exp_at(PlayerSkillRank::BEGINNER)) / 200;
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);
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)) {
2317 /* Riding bonus and penalty */
2318 if (player_ptr->riding > 0) {
2319 if (o_ptr->is_lance()) {
2321 } else if (flgs.has_not(TR_RIDING)) {
2323 if (PlayerClass(player_ptr).is_tamer()) {
2326 penalty = monraces_info[player_ptr->current_floor_ptr->m_list[player_ptr->riding].r_idx].level - player_ptr->skill_exp[PlayerSkillKindType::RIDING] / 80;
2337 /* Class penalties */
2338 if (pc.equals(PlayerClassType::PRIEST) && (flgs.has_not(TR_BLESSED)) && ((o_ptr->tval == ItemKindType::SWORD) || (o_ptr->tval == ItemKindType::POLEARM))) {
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;
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)))) {
2353 if (has_not_ninja_weapon(player_ptr, (int)calc_hand) || has_not_monk_weapon(player_ptr, (int)calc_hand)) {
2357 /* Hex realm bonuses */
2358 if ((player_ptr->realm1 == REALM_HEX) && o_ptr->is_cursed()) {
2359 if (o_ptr->curse_flags.has(CurseTraitType::CURSED)) {
2362 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2365 if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
2368 if (o_ptr->curse_flags.has(CurseTraitType::TY_CURSE)) {
2374 /* Bonuses from inventory */
2375 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2376 auto *o_ptr = &player_ptr->inventory_list[i];
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) {
2383 /* Fake value does not include unknown objects' value */
2384 if (!o_ptr->is_known() && !is_real_value) {
2388 int bonus_to_h = o_ptr->to_h;
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;
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;
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;
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;
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;
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;
2436 case MELEE_TYPE_SHIELD_DOUBLE:
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);
2449 /* Two handed combat penalty */
2450 hit -= calc_double_weapon_penalty(player_ptr, slot);
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);
2459 return static_cast<short>(hit);
2462 static int16_t calc_to_hit_bow(PlayerType *player_ptr, bool is_real_value)
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);
2471 o_ptr = &player_ptr->inventory_list[INVEN_BOW];
2473 if (o_ptr->curse_flags.has(CurseTraitType::LOW_MELEE)) {
2474 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2483 auto player_stun = player_ptr->effects()->stun();
2484 pow -= player_stun->get_damage_penalty();
2485 if (is_blessed(player_ptr)) {
2489 if (is_hero(player_ptr)) {
2493 if (is_shero(player_ptr)) {
2497 auto *o_ptr = &player_ptr->inventory_list[INVEN_BOW];
2499 if (is_heavy_shoot(player_ptr, o_ptr)) {
2500 pow += 2 * (calc_bow_weight_limit(player_ptr) - o_ptr->weight / 10);
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));
2512 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
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) {
2519 bonus_to_h = o_ptr->to_h;
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;
2527 if (is_real_value || o_ptr->is_known()) {
2528 pow += (int16_t)bonus_to_h;
2532 pow -= calc_riding_bow_penalty(player_ptr);
2537 static int16_t calc_to_damage_misc(PlayerType *player_ptr)
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) {
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;
2555 to_dam += (int16_t)bonus_to_d;
2558 if (is_shero(player_ptr)) {
2559 to_dam += 3 + (player_ptr->lev / 5);
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);
2568 static int16_t calc_to_hit_misc(PlayerType *player_ptr)
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) {
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;
2586 to_hit += (int16_t)bonus_to_h;
2589 if (is_blessed(player_ptr)) {
2593 if (is_hero(player_ptr)) {
2597 if (is_shero(player_ptr)) {
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);
2609 static DICE_NUMBER calc_to_weapon_dice_num(PlayerType *player_ptr, INVENTORY_IDX slot)
2611 auto *o_ptr = &player_ptr->inventory_list[slot];
2612 return (player_ptr->riding > 0) && o_ptr->is_lance() ? 2 : 0;
2616 * @brief プレイヤーの所持重量制限を計算する /
2617 * Computes current weight limit.
2620 WEIGHT calc_weight_limit(PlayerType *player_ptr)
2622 WEIGHT i = (WEIGHT)adj_str_wgt[player_ptr->stat_index[A_STR]] * 50;
2623 if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
2630 * @brief update のフラグに応じた更新をまとめて行う / Handle "update"
2631 * @details 更新処理の対象はプレイヤーの能力修正/光源寿命/HP/MP/魔法の学習状態、他多数の外界の状態判定。
2633 void update_creature(PlayerType *player_ptr)
2635 if (!player_ptr->update) {
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);
2645 if (any_bits(player_ptr->update, (PU_COMBINE))) {
2646 reset_bits(player_ptr->update, PU_COMBINE);
2647 combine_pack(player_ptr);
2650 if (any_bits(player_ptr->update, (PU_REORDER))) {
2651 reset_bits(player_ptr->update, PU_REORDER);
2652 reorder_pack(player_ptr);
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);
2664 if (any_bits(player_ptr->update, (PU_TORCH))) {
2665 reset_bits(player_ptr->update, PU_TORCH);
2666 update_lite_radius(player_ptr);
2669 if (any_bits(player_ptr->update, (PU_HP))) {
2670 reset_bits(player_ptr->update, PU_HP);
2671 update_max_hitpoints(player_ptr);
2674 if (any_bits(player_ptr->update, (PU_MANA))) {
2675 reset_bits(player_ptr->update, PU_MANA);
2676 update_max_mana(player_ptr);
2679 if (any_bits(player_ptr->update, (PU_SPELLS))) {
2680 reset_bits(player_ptr->update, PU_SPELLS);
2681 update_num_of_spells(player_ptr);
2684 if (!w_ptr->character_generated) {
2687 if (w_ptr->character_icky_depth > 0) {
2690 if (any_bits(player_ptr->update, (PU_UN_LITE))) {
2691 reset_bits(player_ptr->update, PU_UN_LITE);
2692 forget_lite(floor_ptr);
2695 if (any_bits(player_ptr->update, (PU_UN_VIEW))) {
2696 reset_bits(player_ptr->update, PU_UN_VIEW);
2697 forget_view(floor_ptr);
2700 if (any_bits(player_ptr->update, (PU_VIEW))) {
2701 reset_bits(player_ptr->update, PU_VIEW);
2702 update_view(player_ptr);
2705 if (any_bits(player_ptr->update, (PU_LITE))) {
2706 reset_bits(player_ptr->update, PU_LITE);
2707 update_lite(player_ptr);
2710 if (any_bits(player_ptr->update, (PU_FLOW))) {
2711 reset_bits(player_ptr->update, PU_FLOW);
2712 update_flow(player_ptr);
2715 if (any_bits(player_ptr->update, (PU_DISTANCE))) {
2716 reset_bits(player_ptr->update, PU_DISTANCE);
2718 update_monsters(player_ptr, true);
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);
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);
2731 if (any_bits(player_ptr->update, (PU_MONSTERS))) {
2732 reset_bits(player_ptr->update, PU_MONSTERS);
2733 update_monsters(player_ptr, false);
2738 * @brief プレイヤーが魔道書を一冊も持っていないかを判定する
2739 * @return 魔道書を一冊も持っていないならTRUEを返す
2741 bool player_has_no_spellbooks(PlayerType *player_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)) {
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)) {
2763 * @brief プレイヤーを指定座標に配置する / Place the player in the dungeon XXX XXX
2766 * @return 配置に成功したらTRUE
2768 bool player_place(PlayerType *player_ptr, POSITION y, POSITION x)
2770 if (player_ptr->current_floor_ptr->grid_array[y][x].m_idx != 0) {
2774 /* Save player location */
2781 * @brief 種族アンバライトが出血時パターンの上に乗った際のペナルティ処理
2783 void wreck_the_pattern(PlayerType *player_ptr)
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) {
2791 msg_print(_("パターンを血で汚してしまった!", "You bleed on the Pattern!"));
2792 msg_print(_("何か恐ろしい事が起こった!", "Something terrible happens!"));
2794 if (!is_invuln(player_ptr)) {
2795 take_hit(player_ptr, DAMAGE_NOESCAPE, damroll(10, 8), _("パターン損壊", "corrupting the Pattern"));
2798 int to_ruin = randint1(45) + 35;
2801 scatter(player_ptr, &r_y, &r_x, player_ptr->y, player_ptr->x, 4, PROJECT_NONE);
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);
2808 cave_set_feat(player_ptr, player_ptr->y, player_ptr->x, feat_pattern_corrupted);
2812 * @brief プレイヤーの経験値について整合性のためのチェックと調整を行う /
2813 * Advance experience levels and print experience
2815 void check_experience(PlayerType *player_ptr)
2817 if (player_ptr->exp < 0) {
2818 player_ptr->exp = 0;
2820 if (player_ptr->max_exp < 0) {
2821 player_ptr->max_exp = 0;
2823 if (player_ptr->max_max_exp < 0) {
2824 player_ptr->max_max_exp = 0;
2827 if (player_ptr->exp > PY_MAX_EXP) {
2828 player_ptr->exp = PY_MAX_EXP;
2830 if (player_ptr->max_exp > PY_MAX_EXP) {
2831 player_ptr->max_exp = PY_MAX_EXP;
2833 if (player_ptr->max_max_exp > PY_MAX_EXP) {
2834 player_ptr->max_max_exp = PY_MAX_EXP;
2837 if (player_ptr->exp > player_ptr->max_exp) {
2838 player_ptr->max_exp = player_ptr->exp;
2840 if (player_ptr->max_exp > player_ptr->max_max_exp) {
2841 player_ptr->max_max_exp = player_ptr->max_exp;
2844 set_bits(player_ptr->redraw, PR_EXP);
2845 handle_stuff(player_ptr);
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))) {
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);
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))) {
2863 if (player_ptr->lev > player_ptr->max_plv) {
2864 player_ptr->max_plv = player_ptr->lev;
2866 if (PlayerClass(player_ptr).equals(PlayerClassType::CHAOS_WARRIOR) || player_ptr->muta.has(PlayerMutationType::CHAOS_GIFT)) {
2867 level_reward = true;
2869 if (pr.equals(PlayerRaceType::BEASTMAN)) {
2871 level_mutation = true;
2874 level_inc_stat = true;
2876 exe_write_diary(player_ptr, DIARY_LEVELUP, player_ptr->lev, nullptr);
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);
2887 player_ptr->level_up_message = false;
2888 if (level_inc_stat) {
2889 if (!(player_ptr->max_plv % 10)) {
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);
2910 prt(_(" どの能力値を上げますか?", " Which stat do you want to raise?"), 1, 14);
2914 if ((choice >= 'a') && (choice <= 'f')) {
2918 for (n = 0; n < A_MAX; n++) {
2919 if (n != choice - 'a') {
2923 if (get_check(_("よろしいですか?", "Are you sure? "))) {
2927 do_inc_stat(player_ptr, choice - 'a');
2929 } else if (!(player_ptr->max_plv % 2)) {
2930 do_inc_stat(player_ptr, randint0(6));
2934 if (level_mutation) {
2935 msg_print(_("あなたは変わった気がする...", "You feel different..."));
2936 (void)gain_mutation(player_ptr, 0);
2937 level_mutation = false;
2941 * 報酬でレベルが上ると再帰的に check_experience(player_ptr) が
2945 patron_list[player_ptr->chaos_patron].gain_level_reward(player_ptr, 0);
2946 level_reward = false;
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);
2955 if (old_lev != player_ptr->lev) {
2956 autopick_load_pref(player_ptr, false);
2961 * @brief 現在の修正後能力値を3~17及び18/xxx形式に変換する / Converts stat num into a six-char (right justified) string
2963 * @param out_val 出力先文字列ポインタ
2965 void cnv_stat(int val, char *out_val)
2968 sprintf(out_val, " %2d", val);
2972 int bonus = (val - 18);
2974 sprintf(out_val, "18/%3s", "***");
2975 } else if (bonus >= 100) {
2976 sprintf(out_val, "18/%03d", bonus);
2978 sprintf(out_val, " 18/%02d", bonus);
2983 * @brief 能力値現在値から3~17及び18/xxx様式に基づく加減算を行う。
2984 * Modify a stat value by a "modifier", return new value
2986 * @param amount 加減算値
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
2996 int16_t modify_stat_value(int value, int amount)
2999 for (int i = 0; i < amount; i++) {
3006 } else if (amount < 0) {
3007 for (int i = 0; i < (0 - amount); i++) {
3008 if (value >= 18 + 10) {
3010 } else if (value > 18) {
3012 } else if (value > 3) {
3018 return (int16_t)value;
3023 * Hack -- Calculates the total number of points earned -JWT-
3026 long calc_score(PlayerType *player_ptr)
3028 int arena_win = std::min<int>(player_ptr->arena_number, MAX_ARENA_MONS);
3031 if (!preserve_mode) {
3043 if (ironman_shops) {
3046 if (ironman_small_levels) {
3049 if (ironman_empty_levels) {
3052 if (!powerup_home) {
3055 if (ironman_rooms) {
3058 if (ironman_nightmare) {
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];
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;
3078 point_h += point_l / 0x10000L;
3079 point_l %= 0x10000L;
3081 point_l += ((point_h % 100) << 16);
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));
3090 if (ironman_downward) {
3093 if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
3094 if (PlayerRace(player_ptr).equals(PlayerRaceType::SPECTRE)) {
3099 if ((player_ptr->ppersonality == PERSONALITY_MUNCHKIN) && point) {
3101 if (w_ptr->total_winner) {
3110 * @param player_ptr プレイヤーへの参照ポインタ
3111 * @return 祝福状態ならばTRUE
3113 bool is_blessed(PlayerType *player_ptr)
3115 return player_ptr->blessed || music_singing(player_ptr, MUSIC_BLESS) || SpellHex(player_ptr).is_spelling_specific(HEX_BLESS);
3118 bool is_tim_esp(PlayerType *player_ptr)
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);
3125 bool is_tim_stealth(PlayerType *player_ptr)
3127 return player_ptr->tim_stealth || music_singing(player_ptr, MUSIC_STEALTH);
3130 bool is_time_limit_esp(PlayerType *player_ptr)
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);
3137 bool is_time_limit_stealth(PlayerType *player_ptr)
3139 return player_ptr->tim_stealth || music_singing(player_ptr, MUSIC_STEALTH);
3143 * @brief 口を使う継続的な処理を中断する
3144 * @param player_ptr プレイヤーへの参照ポインタ
3146 void stop_mouth(PlayerType *player_ptr)
3148 if (music_singing_any(player_ptr)) {
3149 stop_singing(player_ptr);
3152 if (SpellHex(player_ptr).is_spelling_any()) {
3153 (void)SpellHex(player_ptr).stop_all_spells();
3157 bool is_fast(PlayerType *player_ptr)
3159 return player_ptr->effects()->acceleration()->is_fast() || music_singing(player_ptr, MUSIC_SPEED) || music_singing(player_ptr, MUSIC_SHERO);
3162 bool is_invuln(PlayerType *player_ptr)
3164 return player_ptr->invuln || music_singing(player_ptr, MUSIC_INVULN);
3167 bool is_hero(PlayerType *player_ptr)
3169 return player_ptr->hero || music_singing(player_ptr, MUSIC_HERO) || music_singing(player_ptr, MUSIC_SHERO);
3172 bool is_shero(PlayerType *player_ptr)
3174 return player_ptr->shero || PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER);
3177 bool is_echizen(PlayerType *player_ptr)
3179 return (player_ptr->ppersonality == PERSONALITY_COMBAT) || (player_ptr->inventory_list[INVEN_BOW].fixed_artifact_idx == FixedArtifactId::CRIMSON);
3182 bool is_chargeman(PlayerType *player_ptr)
3184 return player_ptr->ppersonality == PERSONALITY_CHARGEMAN;
3187 WEIGHT calc_weapon_weight_limit(PlayerType *player_ptr)
3189 WEIGHT weight = adj_str_hold[player_ptr->stat_index[A_STR]];
3191 if (has_two_handed_weapons(player_ptr)) {
3198 WEIGHT calc_bow_weight_limit(PlayerType *player_ptr)
3200 WEIGHT weight = adj_str_hold[player_ptr->stat_index[A_STR]];
3205 static player_hand main_attack_hand(PlayerType *player_ptr)
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;
3225 return PLAYER_HAND_MAIN;
3228 bool set_quick_and_tiny(PlayerType *player_ptr)
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;
3235 bool set_musasi(PlayerType *player_ptr)
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;
3242 bool set_icing_and_twinkle(PlayerType *player_ptr)
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;
3249 bool set_anubis_and_chariot(PlayerType *player_ptr)
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;