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 "dungeon/dungeon.h"
18 #include "effect/effect-characteristics.h"
19 #include "floor/cave.h"
20 #include "floor/floor-events.h"
21 #include "floor/floor-leaver.h"
22 #include "floor/floor-save.h"
23 #include "floor/floor-util.h"
24 #include "game-option/birth-options.h"
25 #include "grid/feature.h"
26 #include "grid/grid.h"
27 #include "inventory/inventory-object.h"
28 #include "io/input-key-acceptor.h"
29 #include "io/write-diary.h"
30 #include "main/sound-definitions-table.h"
31 #include "main/sound-of-music.h"
32 #include "market/arena-info-table.h"
33 #include "mind/mind-force-trainer.h"
34 #include "mind/mind-ninja.h"
35 #include "monster-floor/monster-lite.h"
36 #include "monster-floor/monster-remover.h"
37 #include "monster-race/monster-race-hook.h"
38 #include "monster-race/monster-race.h"
39 #include "monster-race/race-flags1.h"
40 #include "monster-race/race-flags2.h"
41 #include "monster-race/race-flags7.h"
42 #include "monster/monster-update.h"
43 #include "monster/smart-learn-types.h"
44 #include "mutation/mutation-calculator.h"
45 #include "mutation/mutation-flag-types.h"
46 #include "mutation/mutation-investor-remover.h"
47 #include "object-enchant/object-ego.h"
48 #include "object-enchant/special-object-flags.h"
49 #include "object-enchant/tr-types.h"
50 #include "object-enchant/trc-types.h"
51 #include "object-hook/hook-armor.h"
52 #include "object/object-flags.h"
53 #include "object/object-info.h"
54 #include "object/object-mark-types.h"
55 #include "perception/object-perception.h"
56 #include "pet/pet-util.h"
57 #include "player-ability/player-charisma.h"
58 #include "player-ability/player-constitution.h"
59 #include "player-ability/player-dexterity.h"
60 #include "player-ability/player-intelligence.h"
61 #include "player-ability/player-strength.h"
62 #include "player-ability/player-wisdom.h"
63 #include "player-base/player-class.h"
64 #include "player-base/player-race.h"
65 #include "player-info/alignment.h"
66 #include "player-info/class-info.h"
67 #include "player-info/equipment-info.h"
68 #include "player-info/mimic-info-table.h"
69 #include "player-info/monk-data-type.h"
70 #include "player-info/samurai-data-type.h"
71 #include "player-info/sniper-data-type.h"
72 #include "player-status/player-basic-statistics.h"
73 #include "player-status/player-hand-types.h"
74 #include "player-status/player-infravision.h"
75 #include "player-status/player-speed.h"
76 #include "player-status/player-stealth.h"
77 #include "player/attack-defense-types.h"
78 #include "player/digestion-processor.h"
79 #include "player/patron.h"
80 #include "player/player-damage.h"
81 #include "player/player-move.h"
82 #include "player/player-personality-types.h"
83 #include "player/player-personality.h"
84 #include "player/player-skill.h"
85 #include "player/player-status-flags.h"
86 #include "player/player-status-table.h"
87 #include "player/player-view.h"
88 #include "player/race-info-table.h"
89 #include "player/special-defense-types.h"
90 #include "realm/realm-hex-numbers.h"
91 #include "realm/realm-names-table.h"
92 #include "realm/realm-song-numbers.h"
93 #include "specific-object/bow.h"
94 #include "specific-object/torch.h"
95 #include "spell-realm/spells-hex.h"
96 #include "spell-realm/spells-song.h"
97 #include "spell/range-calc.h"
98 #include "spell/spells-describer.h"
99 #include "spell/spells-execution.h"
100 #include "spell/spells-status.h"
101 #include "spell/technic-info-table.h"
102 #include "status/action-setter.h"
103 #include "status/base-status.h"
104 #include "sv-definition/sv-lite-types.h"
105 #include "sv-definition/sv-weapon-types.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 "term/screen-processor.h"
113 #include "timed-effect/player-acceleration.h"
114 #include "timed-effect/player-stun.h"
115 #include "timed-effect/timed-effects.h"
116 #include "util/bit-flags-calculator.h"
117 #include "util/enum-converter.h"
118 #include "util/quarks.h"
119 #include "util/string-processor.h"
120 #include "view/display-messages.h"
121 #include "world/world.h"
123 static const int extra_magic_glove_reduce_mana = 1;
125 static bool is_martial_arts_mode(PlayerType *player_ptr);
127 static ACTION_SKILL_POWER calc_disarming(PlayerType *player_ptr);
128 static ACTION_SKILL_POWER calc_device_ability(PlayerType *player_ptr);
129 static ACTION_SKILL_POWER calc_saving_throw(PlayerType *player_ptr);
130 static ACTION_SKILL_POWER calc_search(PlayerType *player_ptr);
131 static ACTION_SKILL_POWER calc_search_freq(PlayerType *player_ptr);
132 static ACTION_SKILL_POWER calc_to_hit_melee(PlayerType *player_ptr);
133 static ACTION_SKILL_POWER calc_to_hit_shoot(PlayerType *player_ptr);
134 static ACTION_SKILL_POWER calc_to_hit_throw(PlayerType *player_ptr);
135 static ACTION_SKILL_POWER calc_skill_dig(PlayerType *player_ptr);
136 static bool is_heavy_wield(PlayerType *player_ptr, int i);
137 static int16_t calc_num_blow(PlayerType *player_ptr, int i);
138 static int16_t calc_to_magic_chance(PlayerType *player_ptr);
139 static ARMOUR_CLASS calc_base_ac(PlayerType *player_ptr);
140 static ARMOUR_CLASS calc_to_ac(PlayerType *player_ptr, bool is_real_value);
141 static int16_t calc_double_weapon_penalty(PlayerType *player_ptr, INVENTORY_IDX slot);
142 static bool is_riding_two_hands(PlayerType *player_ptr);
143 static int16_t calc_riding_bow_penalty(PlayerType *player_ptr);
144 static void put_equipment_warning(PlayerType *player_ptr);
146 static short calc_to_damage(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value);
147 static int16_t calc_to_hit(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value);
149 static int16_t calc_to_hit_bow(PlayerType *player_ptr, bool is_real_value);
151 static int16_t calc_to_damage_misc(PlayerType *player_ptr);
152 static int16_t calc_to_hit_misc(PlayerType *player_ptr);
154 static DICE_NUMBER calc_to_weapon_dice_num(PlayerType *player_ptr, INVENTORY_IDX slot);
155 static player_hand main_attack_hand(PlayerType *player_ptr);
157 /*** Player information ***/
160 * @brief 遅延描画更新 / Delayed visual update
161 * @details update_view(), update_lite(), update_mon_lite() においてのみ更新すること / Only used if update_view(), update_lite() or update_mon_lite() was called
162 * @param player_ptr 主観となるプレイヤー構造体参照ポインタ
163 * @todo 将来独自インターフェース実装にはz-term系に追い出すべきか?
165 static void delayed_visual_update(PlayerType *player_ptr)
167 auto *floor_ptr = player_ptr->current_floor_ptr;
168 for (int i = 0; i < floor_ptr->redraw_n; i++) {
169 POSITION y = floor_ptr->redraw_y[i];
170 POSITION x = floor_ptr->redraw_x[i];
172 g_ptr = &floor_ptr->grid_array[y][x];
173 if (none_bits(g_ptr->info, CAVE_REDRAW)) {
177 if (any_bits(g_ptr->info, CAVE_NOTE)) {
178 note_spot(player_ptr, y, x);
181 lite_spot(player_ptr, y, x);
183 update_monster(player_ptr, g_ptr->m_idx, false);
186 reset_bits(g_ptr->info, (CAVE_NOTE | CAVE_REDRAW));
189 floor_ptr->redraw_n = 0;
193 * @brief 射撃武器がプレイヤーにとって重すぎるかどうかの判定 /
194 * @param o_ptr 判定する射撃武器のアイテム情報参照ポインタ
195 * @return 重すぎるならばTRUE
197 static bool is_heavy_shoot(PlayerType *player_ptr, ObjectType *o_ptr)
199 return calc_bow_weight_limit(player_ptr) < (o_ptr->weight / 10);
204 * @param player_ptr プレイヤーへの参照ポインタ
207 WEIGHT calc_inventory_weight(PlayerType *player_ptr)
212 for (int i = 0; i < INVEN_TOTAL; i++) {
213 o_ptr = &player_ptr->inventory_list[i];
217 weight += o_ptr->weight * o_ptr->number;
222 static void update_ability_scores(PlayerType *player_ptr)
224 PlayerStrength player_str(player_ptr);
225 PlayerIntelligence player_int(player_ptr);
226 PlayerWisdom player_wis(player_ptr);
227 PlayerDexterity player_dex(player_ptr);
228 PlayerConstitution player_con(player_ptr);
229 PlayerCharisma player_chr(player_ptr);
230 PlayerBasicStatistics *player_stats[] = { &player_str, &player_int, &player_wis, &player_dex, &player_con, &player_chr };
231 for (auto i = 0; i < A_MAX; ++i) {
232 player_ptr->stat_add[i] = player_stats[i]->modification_value();
233 player_stats[i]->update_value();
238 * @brief プレイヤーの全ステータスを更新する /
239 * Calculate the players current "state", taking into account
240 * not only race/class intrinsics, but also objects being worn
241 * and temporary spell effects.
244 * See also update_max_mana() and update_max_hitpoints().
246 * Take note of the new "speed code", in particular, a very strong
247 * player will start slowing down as soon as he reaches 150 pounds,
248 * but not until he reaches 450 pounds will he be half as fast as
249 * a normal kobold. This both hurts and helps the player, hurts
250 * because in the old days a player could just avoid 300 pounds,
251 * and helps because now carrying 300 pounds is not very painful.
253 * The "weapon" and "bow" do *not* add to the bonuses to hit or to
254 * damage, since that would affect non-combat things. These values
255 * are actually added in later, at the appropriate place.
257 * This function induces various "status" messages.
259 * @todo ここで計算していた各値は一部の状態変化メッセージ処理を除き、今後必要な時に適示計算する形に移行するためほぼすべて削られる。
261 static void update_bonuses(PlayerType *player_ptr)
263 auto empty_hands_status = empty_hands(player_ptr, true);
266 /* Save the old vision stuff */
267 BIT_FLAGS old_telepathy = player_ptr->telepathy;
268 BIT_FLAGS old_esp_animal = player_ptr->esp_animal;
269 BIT_FLAGS old_esp_undead = player_ptr->esp_undead;
270 BIT_FLAGS old_esp_demon = player_ptr->esp_demon;
271 BIT_FLAGS old_esp_orc = player_ptr->esp_orc;
272 BIT_FLAGS old_esp_troll = player_ptr->esp_troll;
273 BIT_FLAGS old_esp_giant = player_ptr->esp_giant;
274 BIT_FLAGS old_esp_dragon = player_ptr->esp_dragon;
275 BIT_FLAGS old_esp_human = player_ptr->esp_human;
276 BIT_FLAGS old_esp_evil = player_ptr->esp_evil;
277 BIT_FLAGS old_esp_good = player_ptr->esp_good;
278 BIT_FLAGS old_esp_nonliving = player_ptr->esp_nonliving;
279 BIT_FLAGS old_esp_unique = player_ptr->esp_unique;
280 BIT_FLAGS old_see_inv = player_ptr->see_inv;
281 BIT_FLAGS old_mighty_throw = player_ptr->mighty_throw;
282 int16_t old_speed = player_ptr->pspeed;
284 ARMOUR_CLASS old_dis_ac = player_ptr->dis_ac;
285 ARMOUR_CLASS old_dis_to_a = player_ptr->dis_to_a;
287 player_ptr->xtra_might = has_xtra_might(player_ptr);
288 player_ptr->esp_evil = has_esp_evil(player_ptr);
289 player_ptr->esp_animal = has_esp_animal(player_ptr);
290 player_ptr->esp_undead = has_esp_undead(player_ptr);
291 player_ptr->esp_demon = has_esp_demon(player_ptr);
292 player_ptr->esp_orc = has_esp_orc(player_ptr);
293 player_ptr->esp_troll = has_esp_troll(player_ptr);
294 player_ptr->esp_giant = has_esp_giant(player_ptr);
295 player_ptr->esp_dragon = has_esp_dragon(player_ptr);
296 player_ptr->esp_human = has_esp_human(player_ptr);
297 player_ptr->esp_good = has_esp_good(player_ptr);
298 player_ptr->esp_nonliving = has_esp_nonliving(player_ptr);
299 player_ptr->esp_unique = has_esp_unique(player_ptr);
300 player_ptr->telepathy = has_esp_telepathy(player_ptr);
301 player_ptr->bless_blade = has_bless_blade(player_ptr);
302 player_ptr->easy_2weapon = has_easy2_weapon(player_ptr);
303 player_ptr->down_saving = has_down_saving(player_ptr);
304 player_ptr->yoiyami = has_no_ac(player_ptr);
305 player_ptr->mighty_throw = has_mighty_throw(player_ptr);
306 player_ptr->dec_mana = has_dec_mana(player_ptr);
307 player_ptr->see_nocto = has_see_nocto(player_ptr);
308 player_ptr->warning = has_warning(player_ptr);
309 player_ptr->anti_magic = has_anti_magic(player_ptr);
310 player_ptr->anti_tele = has_anti_tele(player_ptr);
311 player_ptr->easy_spell = has_easy_spell(player_ptr);
312 player_ptr->heavy_spell = has_heavy_spell(player_ptr);
313 player_ptr->hold_exp = has_hold_exp(player_ptr);
314 player_ptr->see_inv = has_see_inv(player_ptr);
315 player_ptr->free_act = has_free_act(player_ptr);
316 player_ptr->levitation = has_levitation(player_ptr);
317 player_ptr->can_swim = has_can_swim(player_ptr);
318 player_ptr->slow_digest = has_slow_digest(player_ptr);
319 player_ptr->regenerate = has_regenerate(player_ptr);
320 update_curses(player_ptr);
321 player_ptr->impact = has_impact(player_ptr);
322 player_ptr->earthquake = has_earthquake(player_ptr);
323 update_extra_blows(player_ptr);
325 player_ptr->lite = has_lite(player_ptr);
327 if (!PlayerClass(player_ptr).monk_stance_is(MonkStanceType::NONE)) {
328 if (none_bits(empty_hands_status, EMPTY_HAND_MAIN)) {
329 set_action(player_ptr, ACTION_NONE);
333 update_ability_scores(player_ptr);
334 o_ptr = &player_ptr->inventory_list[INVEN_BOW];
336 player_ptr->tval_ammo = bow_tval_ammo(o_ptr);
337 player_ptr->num_fire = calc_num_fire(player_ptr, o_ptr);
340 for (int i = 0; i < 2; i++) {
341 player_ptr->is_icky_wield[i] = is_wielding_icky_weapon(player_ptr, i);
342 player_ptr->is_icky_riding_wield[i] = is_wielding_icky_riding_weapon(player_ptr, i);
343 player_ptr->heavy_wield[i] = is_heavy_wield(player_ptr, i);
344 player_ptr->num_blow[i] = calc_num_blow(player_ptr, i);
345 player_ptr->to_dd[i] = calc_to_weapon_dice_num(player_ptr, INVEN_MAIN_HAND + i);
346 player_ptr->to_ds[i] = 0;
349 player_ptr->pspeed = PlayerSpeed(player_ptr).get_value();
350 player_ptr->see_infra = PlayerInfravision(player_ptr).get_value();
351 player_ptr->skill_stl = PlayerStealth(player_ptr).get_value();
352 player_ptr->skill_dis = calc_disarming(player_ptr);
353 player_ptr->skill_dev = calc_device_ability(player_ptr);
354 player_ptr->skill_sav = calc_saving_throw(player_ptr);
355 player_ptr->skill_srh = calc_search(player_ptr);
356 player_ptr->skill_fos = calc_search_freq(player_ptr);
357 player_ptr->skill_thn = calc_to_hit_melee(player_ptr);
358 player_ptr->skill_thb = calc_to_hit_shoot(player_ptr);
359 player_ptr->skill_tht = calc_to_hit_throw(player_ptr);
360 player_ptr->riding_ryoute = is_riding_two_hands(player_ptr);
361 player_ptr->to_d[0] = calc_to_damage(player_ptr, INVEN_MAIN_HAND, true);
362 player_ptr->to_d[1] = calc_to_damage(player_ptr, INVEN_SUB_HAND, true);
363 player_ptr->dis_to_d[0] = calc_to_damage(player_ptr, INVEN_MAIN_HAND, false);
364 player_ptr->dis_to_d[1] = calc_to_damage(player_ptr, INVEN_SUB_HAND, false);
365 player_ptr->to_h[0] = calc_to_hit(player_ptr, INVEN_MAIN_HAND, true);
366 player_ptr->to_h[1] = calc_to_hit(player_ptr, INVEN_SUB_HAND, true);
367 player_ptr->dis_to_h[0] = calc_to_hit(player_ptr, INVEN_MAIN_HAND, false);
368 player_ptr->dis_to_h[1] = calc_to_hit(player_ptr, INVEN_SUB_HAND, false);
369 player_ptr->to_h_b = calc_to_hit_bow(player_ptr, true);
370 player_ptr->dis_to_h_b = calc_to_hit_bow(player_ptr, false);
371 player_ptr->to_d_m = calc_to_damage_misc(player_ptr);
372 player_ptr->to_h_m = calc_to_hit_misc(player_ptr);
373 player_ptr->skill_dig = calc_skill_dig(player_ptr);
374 player_ptr->to_m_chance = calc_to_magic_chance(player_ptr);
375 player_ptr->ac = calc_base_ac(player_ptr);
376 player_ptr->to_a = calc_to_ac(player_ptr, true);
377 player_ptr->dis_ac = calc_base_ac(player_ptr);
378 player_ptr->dis_to_a = calc_to_ac(player_ptr, false);
380 if (old_mighty_throw != player_ptr->mighty_throw) {
381 player_ptr->window_flags |= PW_INVEN;
384 if (player_ptr->telepathy != old_telepathy) {
385 set_bits(player_ptr->update, PU_MONSTERS);
388 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)) {
389 set_bits(player_ptr->update, PU_MONSTERS);
392 if (player_ptr->see_inv != old_see_inv) {
393 set_bits(player_ptr->update, PU_MONSTERS);
396 if (player_ptr->pspeed != old_speed) {
397 set_bits(player_ptr->redraw, PR_SPEED);
400 if ((player_ptr->dis_ac != old_dis_ac) || (player_ptr->dis_to_a != old_dis_to_a)) {
401 set_bits(player_ptr->redraw, PR_ARMOR);
402 set_bits(player_ptr->window_flags, PW_PLAYER);
405 if (w_ptr->character_xtra) {
409 put_equipment_warning(player_ptr);
410 check_no_flowed(player_ptr);
414 * @brief プレイヤーの最大HPを更新する /
415 * Update the players maximal hit points
416 * Adjust current hitpoints if necessary
419 static void update_max_hitpoints(PlayerType *player_ptr)
421 int bonus = ((int)(adj_con_mhp[player_ptr->stat_index[A_CON]]) - 128) * player_ptr->lev / 4;
422 int mhp = player_ptr->player_hp[player_ptr->lev - 1];
425 PlayerClass pc(player_ptr);
426 auto is_sorcerer = pc.equals(PlayerClassType::SORCERER);
427 if (player_ptr->mimic_form != MimicKindType::NONE) {
428 auto r_mhp = mimic_info.at(player_ptr->mimic_form).r_mhp;
430 tmp_hitdie = r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
432 tmp_hitdie = r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
435 mhp = mhp * tmp_hitdie / player_ptr->hitdie;
439 if (player_ptr->lev < 30) {
440 mhp = (mhp * (45 + player_ptr->lev) / 100);
442 mhp = (mhp * 75 / 100);
444 bonus = (bonus * 65 / 100);
449 if (pc.equals(PlayerClassType::BERSERKER)) {
450 mhp = mhp * (110 + (((player_ptr->lev + 40) * (player_ptr->lev + 40) - 1550) / 110)) / 100;
453 if (mhp < player_ptr->lev + 1) {
454 mhp = player_ptr->lev + 1;
456 if (is_hero(player_ptr)) {
459 if (is_shero(player_ptr)) {
462 if (player_ptr->tsuyoshi) {
465 if (SpellHex(player_ptr).is_spelling_specific(HEX_XTRA_MIGHT)) {
468 if (SpellHex(player_ptr).is_spelling_specific(HEX_BUILDING)) {
471 if (player_ptr->mhp == mhp) {
475 if (player_ptr->chp >= mhp) {
476 player_ptr->chp = mhp;
477 player_ptr->chp_frac = 0;
481 if (player_ptr->level_up_message && (mhp > player_ptr->mhp)) {
482 msg_format("最大ヒット・ポイントが %d 増加した!", (mhp - player_ptr->mhp));
485 player_ptr->mhp = mhp;
487 player_ptr->redraw |= PR_HP;
488 player_ptr->window_flags |= PW_PLAYER;
492 * @brief プレイヤーの現在学習可能な魔法数を計算し、増減に応じて魔法の忘却、再学習を処置する。 /
493 * Calculate number of spells player should have, and forget,
494 * or remember, spells until that number is properly reflected.
496 * Note that this function induces various "status" messages,
497 * which must be bypasses until the character is created.
499 static void update_num_of_spells(PlayerType *player_ptr)
501 if ((mp_ptr->spell_book == ItemKindType::NONE) || !w_ptr->character_generated || w_ptr->character_xtra) {
505 PlayerClass pc(player_ptr);
506 if (pc.is_every_magic()) {
507 player_ptr->new_spells = 0;
511 concptr p = spell_category_name(mp_ptr->spell_book);
512 int levels = player_ptr->lev - mp_ptr->spell_first + 1;
517 int num_allowed = (adj_mag_study[player_ptr->stat_index[mp_ptr->spell_stat]] * levels / 2);
519 if (!pc.equals(PlayerClassType::SAMURAI) && (mp_ptr->spell_book != ItemKindType::LIFE_BOOK)) {
523 if (pc.equals(PlayerClassType::SAMURAI)) {
525 } else if (player_ptr->realm2 == REALM_NONE) {
526 num_allowed = (num_allowed + 1) / 2;
527 if (num_allowed > (32 + bonus)) {
528 num_allowed = 32 + bonus;
530 } else if (pc.equals(PlayerClassType::MAGE) || pc.equals(PlayerClassType::PRIEST)) {
531 if (num_allowed > (96 + bonus)) {
532 num_allowed = 96 + bonus;
535 if (num_allowed > (80 + bonus)) {
536 num_allowed = 80 + bonus;
540 int num_boukyaku = 0;
541 for (int j = 0; j < 64; j++) {
542 if ((j < 32) ? any_bits(player_ptr->spell_forgotten1, (1UL << j)) : any_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)))) {
547 player_ptr->new_spells = num_allowed + player_ptr->add_spells + num_boukyaku - player_ptr->learned_spells;
548 for (int i = 63; i >= 0; i--) {
549 if (!player_ptr->spell_learned1 && !player_ptr->spell_learned2) {
553 int j = player_ptr->spell_order[i];
558 const magic_type *s_ptr;
559 if (!is_magic((j < 32) ? player_ptr->realm1 : player_ptr->realm2)) {
561 s_ptr = &technic_info[player_ptr->realm1 - MIN_TECHNIC][j];
563 s_ptr = &technic_info[player_ptr->realm2 - MIN_TECHNIC][j % 32];
566 s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
568 s_ptr = &mp_ptr->info[player_ptr->realm2 - 1][j % 32];
571 if (s_ptr->slevel <= player_ptr->lev) {
575 bool is_spell_learned = (j < 32) ? any_bits(player_ptr->spell_learned1, (1UL << j)) : any_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
576 if (!is_spell_learned) {
582 set_bits(player_ptr->spell_forgotten1, (1UL << j));
583 which = player_ptr->realm1;
585 set_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
586 which = player_ptr->realm2;
590 reset_bits(player_ptr->spell_learned1, (1UL << j));
591 which = player_ptr->realm1;
593 reset_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
594 which = player_ptr->realm2;
598 msg_format("%sの%sを忘れてしまった。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
600 msg_format("You have forgotten the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
602 player_ptr->new_spells++;
605 /* Forget spells if we know too many spells */
606 for (int i = 63; i >= 0; i--) {
607 if (player_ptr->new_spells >= 0) {
610 if (!player_ptr->spell_learned1 && !player_ptr->spell_learned2) {
614 int j = player_ptr->spell_order[i];
619 bool is_spell_learned = (j < 32) ? any_bits(player_ptr->spell_learned1, (1UL << j)) : any_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
620 if (!is_spell_learned) {
626 set_bits(player_ptr->spell_forgotten1, (1UL << j));
627 which = player_ptr->realm1;
629 set_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
630 which = player_ptr->realm2;
634 reset_bits(player_ptr->spell_learned1, (1UL << j));
635 which = player_ptr->realm1;
637 reset_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
638 which = player_ptr->realm2;
642 msg_format("%sの%sを忘れてしまった。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
644 msg_format("You have forgotten the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
646 player_ptr->new_spells++;
649 /* Check for spells to remember */
650 for (int i = 0; i < 64; i++) {
651 if (player_ptr->new_spells <= 0) {
654 if (!player_ptr->spell_forgotten1 && !player_ptr->spell_forgotten2) {
657 int j = player_ptr->spell_order[i];
662 const magic_type *s_ptr;
663 if (!is_magic((j < 32) ? player_ptr->realm1 : player_ptr->realm2)) {
665 s_ptr = &technic_info[player_ptr->realm1 - MIN_TECHNIC][j];
667 s_ptr = &technic_info[player_ptr->realm2 - MIN_TECHNIC][j % 32];
670 s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
672 s_ptr = &mp_ptr->info[player_ptr->realm2 - 1][j % 32];
675 if (s_ptr->slevel > player_ptr->lev) {
679 bool is_spell_learned = (j < 32) ? any_bits(player_ptr->spell_forgotten1, (1UL << j)) : any_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
680 if (!is_spell_learned) {
686 reset_bits(player_ptr->spell_forgotten1, (1UL << j));
687 which = player_ptr->realm1;
689 reset_bits(player_ptr->spell_forgotten2, (1UL << (j - 32)));
690 which = player_ptr->realm2;
694 set_bits(player_ptr->spell_learned1, (1UL << j));
695 which = player_ptr->realm1;
697 set_bits(player_ptr->spell_learned2, (1UL << (j - 32)));
698 which = player_ptr->realm2;
702 msg_format("%sの%sを思い出した。", exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME), p);
704 msg_format("You have remembered the %s of %s.", p, exe_spell(player_ptr, which, j % 32, SpellProcessType::NAME));
706 player_ptr->new_spells--;
709 if (player_ptr->realm2 == REALM_NONE) {
711 for (int j = 0; j < 32; j++) {
712 const magic_type *s_ptr;
713 if (!is_magic(player_ptr->realm1)) {
714 s_ptr = &technic_info[player_ptr->realm1 - MIN_TECHNIC][j];
716 s_ptr = &mp_ptr->info[player_ptr->realm1 - 1][j];
719 if (s_ptr->slevel > player_ptr->lev) {
723 if (any_bits(player_ptr->spell_learned1, (1UL << j))) {
733 if ((player_ptr->new_spells > k) && ((mp_ptr->spell_book == ItemKindType::LIFE_BOOK) || (mp_ptr->spell_book == ItemKindType::HISSATSU_BOOK))) {
734 player_ptr->new_spells = (int16_t)k;
738 if (player_ptr->new_spells < 0) {
739 player_ptr->new_spells = 0;
742 if (player_ptr->old_spells == player_ptr->new_spells) {
746 if (player_ptr->new_spells) {
748 if (player_ptr->new_spells < 10) {
749 msg_format("あと %d つの%sを学べる。", player_ptr->new_spells, p);
751 msg_format("あと %d 個の%sを学べる。", player_ptr->new_spells, p);
754 msg_format("You can learn %d more %s%s.", player_ptr->new_spells, p, (player_ptr->new_spells != 1) ? "s" : "");
758 player_ptr->old_spells = player_ptr->new_spells;
759 set_bits(player_ptr->redraw, PR_STUDY);
760 set_bits(player_ptr->window_flags, PW_OBJECT);
764 * @brief プレイヤーの最大MPを更新する /
765 * Update maximum mana. You do not need to know any spells.
766 * Note that mana is lowered by heavy (or inappropriate) armor.
768 * This function induces status messages.
770 static void update_max_mana(PlayerType *player_ptr)
772 if ((mp_ptr->spell_book == ItemKindType::NONE) && mp_ptr->spell_first == SPELL_FIRST_NO_SPELL) {
777 PlayerClass pc(player_ptr);
778 auto use_direct_level = pc.equals(PlayerClassType::MINDCRAFTER);
779 use_direct_level |= pc.equals(PlayerClassType::MIRROR_MASTER);
780 use_direct_level |= pc.equals(PlayerClassType::BLUE_MAGE);
781 use_direct_level |= pc.equals(PlayerClassType::ELEMENTALIST);
782 if (use_direct_level) {
783 levels = player_ptr->lev;
785 if (mp_ptr->spell_first > player_ptr->lev) {
787 set_bits(player_ptr->redraw, PR_MANA);
791 levels = (player_ptr->lev - mp_ptr->spell_first) + 1;
795 if (pc.equals(PlayerClassType::SAMURAI)) {
796 msp = (adj_mag_mana[player_ptr->stat_index[mp_ptr->spell_stat]] + 10) * 2;
798 msp += (msp * rp_ptr->r_adj[mp_ptr->spell_stat] / 20);
801 msp = adj_mag_mana[player_ptr->stat_index[mp_ptr->spell_stat]] * (levels + 3) / 4;
806 msp += (msp * rp_ptr->r_adj[mp_ptr->spell_stat] / 20);
808 if (msp && (player_ptr->ppersonality == PERSONALITY_MUNCHKIN)) {
811 if (msp && pc.equals(PlayerClassType::HIGH_MAGE)) {
814 if (msp && pc.equals(PlayerClassType::SORCERER)) {
815 msp += msp * (25 + player_ptr->lev) / 100;
819 if (any_bits(mp_ptr->spell_xtra, extra_magic_glove_reduce_mana)) {
820 player_ptr->cumber_glove = false;
822 o_ptr = &player_ptr->inventory_list[INVEN_ARMS];
823 auto flgs = object_flags(o_ptr);
824 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))) {
825 player_ptr->cumber_glove = true;
830 player_ptr->cumber_armor = false;
833 if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval > ItemKindType::SWORD) {
834 cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight;
836 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval > ItemKindType::SWORD) {
837 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight;
839 cur_wgt += player_ptr->inventory_list[INVEN_BODY].weight;
840 cur_wgt += player_ptr->inventory_list[INVEN_HEAD].weight;
841 cur_wgt += player_ptr->inventory_list[INVEN_OUTER].weight;
842 cur_wgt += player_ptr->inventory_list[INVEN_ARMS].weight;
843 cur_wgt += player_ptr->inventory_list[INVEN_FEET].weight;
845 switch (player_ptr->pclass) {
846 case PlayerClassType::MAGE:
847 case PlayerClassType::HIGH_MAGE:
848 case PlayerClassType::BLUE_MAGE:
849 case PlayerClassType::MONK:
850 case PlayerClassType::FORCETRAINER:
851 case PlayerClassType::SORCERER:
852 case PlayerClassType::ELEMENTALIST: {
853 if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
854 cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight;
856 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
857 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight;
861 case PlayerClassType::PRIEST:
862 case PlayerClassType::BARD:
863 case PlayerClassType::TOURIST: {
864 if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
865 cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight * 2 / 3;
867 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
868 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight * 2 / 3;
872 case PlayerClassType::MINDCRAFTER:
873 case PlayerClassType::BEASTMASTER:
874 case PlayerClassType::MIRROR_MASTER: {
875 if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
876 cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight / 2;
878 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
879 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 2;
883 case PlayerClassType::ROGUE:
884 case PlayerClassType::RANGER:
885 case PlayerClassType::RED_MAGE:
886 case PlayerClassType::WARRIOR_MAGE: {
887 if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
888 cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight / 3;
890 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
891 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 3;
895 case PlayerClassType::PALADIN:
896 case PlayerClassType::CHAOS_WARRIOR: {
897 if (player_ptr->inventory_list[INVEN_MAIN_HAND].tval <= ItemKindType::SWORD) {
898 cur_wgt += player_ptr->inventory_list[INVEN_MAIN_HAND].weight / 5;
900 if (player_ptr->inventory_list[INVEN_SUB_HAND].tval <= ItemKindType::SWORD) {
901 cur_wgt += player_ptr->inventory_list[INVEN_SUB_HAND].weight / 5;
910 int max_wgt = mp_ptr->spell_weight;
911 if ((cur_wgt - max_wgt) > 0) {
912 player_ptr->cumber_armor = true;
913 switch (player_ptr->pclass) {
914 case PlayerClassType::MAGE:
915 case PlayerClassType::HIGH_MAGE:
916 case PlayerClassType::BLUE_MAGE:
917 case PlayerClassType::ELEMENTALIST: {
918 msp -= msp * (cur_wgt - max_wgt) / 600;
921 case PlayerClassType::PRIEST:
922 case PlayerClassType::MINDCRAFTER:
923 case PlayerClassType::BEASTMASTER:
924 case PlayerClassType::BARD:
925 case PlayerClassType::FORCETRAINER:
926 case PlayerClassType::TOURIST:
927 case PlayerClassType::MIRROR_MASTER: {
928 msp -= msp * (cur_wgt - max_wgt) / 800;
931 case PlayerClassType::SORCERER: {
932 msp -= msp * (cur_wgt - max_wgt) / 900;
935 case PlayerClassType::ROGUE:
936 case PlayerClassType::RANGER:
937 case PlayerClassType::MONK:
938 case PlayerClassType::RED_MAGE: {
939 msp -= msp * (cur_wgt - max_wgt) / 1000;
942 case PlayerClassType::PALADIN:
943 case PlayerClassType::CHAOS_WARRIOR:
944 case PlayerClassType::WARRIOR_MAGE: {
945 msp -= msp * (cur_wgt - max_wgt) / 1200;
948 case PlayerClassType::SAMURAI: {
949 player_ptr->cumber_armor = false;
953 msp -= msp * (cur_wgt - max_wgt) / 800;
963 if (player_ptr->msp != msp) {
964 if ((player_ptr->csp >= msp) && !pc.equals(PlayerClassType::SAMURAI)) {
965 player_ptr->csp = msp;
966 player_ptr->csp_frac = 0;
970 if (player_ptr->level_up_message && (msp > player_ptr->msp)) {
971 msg_format("最大マジック・ポイントが %d 増加した!", (msp - player_ptr->msp));
974 player_ptr->msp = msp;
975 set_bits(player_ptr->redraw, PR_MANA);
976 set_bits(player_ptr->window_flags, (PW_PLAYER | PW_SPELL));
979 if (w_ptr->character_xtra) {
983 if (player_ptr->old_cumber_glove != player_ptr->cumber_glove) {
984 if (player_ptr->cumber_glove) {
985 msg_print(_("手が覆われて呪文が唱えにくい感じがする。", "Your covered hands feel unsuitable for spellcasting."));
987 msg_print(_("この手の状態なら、ぐっと呪文が唱えやすい感じだ。", "Your hands feel more suitable for spellcasting."));
990 player_ptr->old_cumber_glove = player_ptr->cumber_glove;
993 if (player_ptr->old_cumber_armor == player_ptr->cumber_armor) {
997 if (player_ptr->cumber_armor) {
998 msg_print(_("装備の重さで動きが鈍くなってしまっている。", "The weight of your equipment encumbers your movement."));
1000 msg_print(_("ぐっと楽に体を動かせるようになった。", "You feel able to move more freely."));
1003 player_ptr->old_cumber_armor = player_ptr->cumber_armor;
1007 * @brief 装備中の射撃武器の威力倍率を返す /
1008 * calcurate the fire rate of target object
1009 * @param o_ptr 計算する射撃武器のアイテム情報参照ポインタ
1010 * @return 射撃倍率の値(100で1.00倍)
1012 int16_t calc_num_fire(PlayerType *player_ptr, ObjectType *o_ptr)
1014 int extra_shots = 0;
1016 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1018 q_ptr = &player_ptr->inventory_list[i];
1019 if (!q_ptr->k_idx) {
1023 if (i == INVEN_BOW) {
1027 auto flgs = object_flags(q_ptr);
1028 if (flgs.has(TR_XTRA_SHOTS)) {
1033 auto flgs = object_flags(o_ptr);
1034 if (flgs.has(TR_XTRA_SHOTS)) {
1039 if (o_ptr->k_idx == 0) {
1040 return (int16_t)num;
1044 num += (extra_shots * 100);
1046 if (is_heavy_shoot(player_ptr, o_ptr)) {
1047 return (int16_t)num;
1050 ItemKindType tval_ammo = bow_tval_ammo(o_ptr);
1051 PlayerClass pc(player_ptr);
1052 if (pc.equals(PlayerClassType::RANGER) && (tval_ammo == ItemKindType::ARROW)) {
1053 num += (player_ptr->lev * 4);
1056 if (pc.equals(PlayerClassType::CAVALRY) && (tval_ammo == ItemKindType::ARROW)) {
1057 num += (player_ptr->lev * 3);
1060 if (pc.equals(PlayerClassType::ARCHER)) {
1061 if (tval_ammo == ItemKindType::ARROW) {
1062 num += ((player_ptr->lev * 5) + 50);
1063 } else if ((tval_ammo == ItemKindType::BOLT) || (tval_ammo == ItemKindType::SHOT)) {
1064 num += (player_ptr->lev * 4);
1068 if (pc.equals(PlayerClassType::WARRIOR) && (tval_ammo <= ItemKindType::BOLT) && (tval_ammo >= ItemKindType::SHOT)) {
1069 num += (player_ptr->lev * 2);
1072 if (pc.equals(PlayerClassType::ROGUE) && (tval_ammo == ItemKindType::SHOT)) {
1073 num += (player_ptr->lev * 4);
1076 return (int16_t)num;
1081 * @param player_ptr プレイヤーへの参照ポインタ
1085 * * 職業と性格とレベルによる追加加算
1086 * * 器用さに応じたadj_dex_disテーブルによる加算
1087 * * 知力に応じたadj_int_disテーブルによる加算
1089 static ACTION_SKILL_POWER calc_disarming(PlayerType *player_ptr)
1091 ACTION_SKILL_POWER pow;
1092 const player_race_info *tmp_rp_ptr;
1094 if (player_ptr->mimic_form != MimicKindType::NONE) {
1095 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1097 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1100 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1101 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1103 pow = tmp_rp_ptr->r_dis + c_ptr->c_dis + a_ptr->a_dis;
1104 pow += ((cp_ptr->x_dis * player_ptr->lev / 10) + (ap_ptr->a_dis * player_ptr->lev / 50));
1105 pow += adj_dex_dis[player_ptr->stat_index[A_DEX]];
1106 pow += adj_int_dis[player_ptr->stat_index[A_INT]];
1112 * @param player_ptr プレイヤーへの参照ポインタ
1116 * * 職業と性格とレベルによる追加加算
1117 * * 装備による加算(TR_MAGIC_MASTERYを持っていたら+pval*8)
1118 * * 知力に応じたadj_int_devテーブルによる加算
1121 static ACTION_SKILL_POWER calc_device_ability(PlayerType *player_ptr)
1123 ACTION_SKILL_POWER pow;
1124 const player_race_info *tmp_rp_ptr;
1126 if (player_ptr->mimic_form != MimicKindType::NONE) {
1127 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1129 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1132 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1133 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1135 pow = tmp_rp_ptr->r_dev + c_ptr->c_dev + a_ptr->a_dev;
1136 pow += ((c_ptr->x_dev * player_ptr->lev / 10) + (ap_ptr->a_dev * player_ptr->lev / 50));
1138 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1140 o_ptr = &player_ptr->inventory_list[i];
1141 if (!o_ptr->k_idx) {
1144 auto flgs = object_flags(o_ptr);
1145 if (flgs.has(TR_MAGIC_MASTERY)) {
1146 pow += 8 * o_ptr->pval;
1150 pow += adj_int_dev[player_ptr->stat_index[A_INT]];
1152 if (is_shero(player_ptr)) {
1160 * @param player_ptr プレイヤーへの参照ポインタ
1164 * * 職業と性格とレベルによる追加加算
1165 * * 変異MUT3_MAGIC_RESによる加算(15 + レベル / 5)
1166 * * 呪力耐性の装備による加算(30)
1167 * * 祝福された装備による加算(5 + レベル / 10)
1168 * * 賢さによるadj_wis_savテーブル加算
1169 * * 呪力弱点の装備による減算(-10)
1170 * * 呪力弱点の装備が強力に呪われているときさらに減算(-20)
1172 * * 反魔法持ちで大なり上書き(90+レベル未満ならその値に上書き)
1173 * * クターのつぶれ状態なら(10に上書き)
1174 * * 生命の「究極の耐性」や regist_magic,magicdef持ちなら大なり上書き(95+レベル未満ならその値に上書き)
1175 * * 呪いのdown_savingがかかっているなら半減
1177 static ACTION_SKILL_POWER calc_saving_throw(PlayerType *player_ptr)
1179 ACTION_SKILL_POWER pow;
1180 const player_race_info *tmp_rp_ptr;
1182 if (player_ptr->mimic_form != MimicKindType::NONE) {
1183 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1185 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1188 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1189 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1191 pow = tmp_rp_ptr->r_sav + c_ptr->c_sav + a_ptr->a_sav;
1192 pow += ((cp_ptr->x_sav * player_ptr->lev / 10) + (ap_ptr->a_sav * player_ptr->lev / 50));
1194 if (player_ptr->muta.has(PlayerMutationType::MAGIC_RES)) {
1195 pow += (15 + (player_ptr->lev / 5));
1198 if (has_resist_curse(player_ptr)) {
1202 if (player_ptr->bless_blade) {
1203 pow += 6 + (player_ptr->lev - 1) / 10;
1206 pow += adj_wis_sav[player_ptr->stat_index[A_WIS]];
1208 if (has_vuln_curse(player_ptr)) {
1212 if (has_heavy_vuln_curse(player_ptr)) {
1216 if (is_shero(player_ptr)) {
1220 if (player_ptr->anti_magic && (pow < (90 + player_ptr->lev))) {
1221 pow = 90 + player_ptr->lev;
1224 if (player_ptr->tsubureru) {
1228 if ((player_ptr->ult_res || player_ptr->resist_magic || player_ptr->magicdef) && (pow < (95 + player_ptr->lev))) {
1229 pow = 95 + player_ptr->lev;
1232 if (player_ptr->down_saving) {
1241 * @param player_ptr プレイヤーへの参照ポインタ
1246 * * 各装備による加算(TR_SEARCHがあれば+pval*5)
1248 * * 変異(MUT3_XTRA_EYES)による加算(+15)
1250 static ACTION_SKILL_POWER calc_search(PlayerType *player_ptr)
1252 ACTION_SKILL_POWER pow;
1253 const player_race_info *tmp_rp_ptr;
1255 if (player_ptr->mimic_form != MimicKindType::NONE) {
1256 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1258 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1261 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1262 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1264 pow = tmp_rp_ptr->r_srh + c_ptr->c_srh + a_ptr->a_srh;
1265 pow += (c_ptr->x_srh * player_ptr->lev / 10);
1267 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1269 o_ptr = &player_ptr->inventory_list[i];
1270 if (!o_ptr->k_idx) {
1273 auto flgs = object_flags(o_ptr);
1274 if (flgs.has(TR_SEARCH)) {
1275 pow += (o_ptr->pval * 5);
1279 if (player_ptr->muta.has(PlayerMutationType::XTRA_EYES)) {
1283 if (is_shero(player_ptr)) {
1292 * @param player_ptr プレイヤーへの参照ポインタ
1297 * * 各装備による加算(TR_SEARCHがあれば+pval*5)
1299 * * 変異(MUT3_XTRA_EYES)による加算(+15)
1301 static ACTION_SKILL_POWER calc_search_freq(PlayerType *player_ptr)
1303 ACTION_SKILL_POWER pow;
1304 const player_race_info *tmp_rp_ptr;
1306 if (player_ptr->mimic_form != MimicKindType::NONE) {
1307 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1309 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1312 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1313 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1315 pow = tmp_rp_ptr->r_fos + c_ptr->c_fos + a_ptr->a_fos;
1316 pow += (c_ptr->x_fos * player_ptr->lev / 10);
1318 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1320 o_ptr = &player_ptr->inventory_list[i];
1321 if (!o_ptr->k_idx) {
1324 auto flgs = object_flags(o_ptr);
1325 if (flgs.has(TR_SEARCH)) {
1326 pow += (o_ptr->pval * 5);
1330 if (is_shero(player_ptr)) {
1334 if (player_ptr->muta.has(PlayerMutationType::XTRA_EYES)) {
1343 * @param player_ptr プレイヤーへの参照ポインタ
1346 * * 種族/職業/性格による加算とレベルによる追加加算
1348 static ACTION_SKILL_POWER calc_to_hit_melee(PlayerType *player_ptr)
1350 ACTION_SKILL_POWER pow;
1351 const player_race_info *tmp_rp_ptr;
1352 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1353 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1355 if (player_ptr->mimic_form != MimicKindType::NONE) {
1356 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1358 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1361 pow = tmp_rp_ptr->r_thn + c_ptr->c_thn + a_ptr->a_thn;
1362 pow += ((c_ptr->x_thn * player_ptr->lev / 10) + (a_ptr->a_thn * player_ptr->lev / 50));
1368 * @param player_ptr プレイヤーへの参照ポインタ
1371 * * 種族/職業/性格による加算とレベルによる追加加算
1373 static ACTION_SKILL_POWER calc_to_hit_shoot(PlayerType *player_ptr)
1375 ACTION_SKILL_POWER pow;
1376 const player_race_info *tmp_rp_ptr;
1377 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1378 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1380 if (player_ptr->mimic_form != MimicKindType::NONE) {
1381 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1383 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1386 pow = tmp_rp_ptr->r_thb + c_ptr->c_thb + a_ptr->a_thb;
1387 pow += ((c_ptr->x_thb * player_ptr->lev / 10) + (a_ptr->a_thb * player_ptr->lev / 50));
1393 * @param player_ptr プレイヤーへの参照ポインタ
1396 * * 種族/職業/性格による加算とレベルによる追加加算
1399 static ACTION_SKILL_POWER calc_to_hit_throw(PlayerType *player_ptr)
1401 ACTION_SKILL_POWER pow;
1402 const player_race_info *tmp_rp_ptr;
1403 const player_class_info *c_ptr = &class_info[enum2i(player_ptr->pclass)];
1404 const player_personality *a_ptr = &personality_info[player_ptr->ppersonality];
1406 if (player_ptr->mimic_form != MimicKindType::NONE) {
1407 tmp_rp_ptr = &mimic_info.at(player_ptr->mimic_form);
1409 tmp_rp_ptr = &race_info[enum2i(player_ptr->prace)];
1412 pow = tmp_rp_ptr->r_thb + c_ptr->c_thb + a_ptr->a_thb;
1413 pow += ((c_ptr->x_thb * player_ptr->lev / 10) + (a_ptr->a_thb * player_ptr->lev / 50));
1415 if (is_shero(player_ptr)) {
1424 * @param player_ptr プレイヤーへの参照ポインタ
1435 static ACTION_SKILL_POWER calc_skill_dig(PlayerType *player_ptr)
1439 ACTION_SKILL_POWER pow;
1443 if (PlayerRace(player_ptr).equals(PlayerRaceType::ENT) && !player_ptr->inventory_list[INVEN_MAIN_HAND].k_idx) {
1444 pow += player_ptr->lev * 10;
1447 if (is_shero(player_ptr)) {
1451 pow += adj_str_dig[player_ptr->stat_index[A_STR]];
1453 if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
1454 pow += (100 + player_ptr->lev * 8);
1457 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1458 o_ptr = &player_ptr->inventory_list[i];
1459 if (!o_ptr->k_idx) {
1462 auto flgs = object_flags(o_ptr);
1463 if (flgs.has(TR_TUNNEL)) {
1464 pow += (o_ptr->pval * 20);
1468 for (int i = 0; i < 2; i++) {
1469 o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + i];
1470 if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i) && !player_ptr->heavy_wield[i]) {
1471 pow += (o_ptr->weight / 10);
1475 if (is_shero(player_ptr)) {
1486 static bool is_martial_arts_mode(PlayerType *player_ptr)
1488 PlayerClass pc(player_ptr);
1489 auto has_martial_arts = pc.equals(PlayerClassType::MONK);
1490 has_martial_arts |= pc.equals(PlayerClassType::FORCETRAINER);
1491 has_martial_arts |= pc.equals(PlayerClassType::BERSERKER);
1492 return has_martial_arts && any_bits(empty_hands(player_ptr, true), EMPTY_HAND_MAIN) && !can_attack_with_sub_hand(player_ptr);
1495 static bool is_heavy_wield(PlayerType *player_ptr, int i)
1497 const auto *o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + i];
1499 return has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i) && (calc_weapon_weight_limit(player_ptr) < o_ptr->weight / 10);
1502 static int16_t calc_num_blow(PlayerType *player_ptr, int i)
1505 int16_t num_blow = 1;
1507 o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + i];
1508 auto flgs = object_flags(o_ptr);
1509 PlayerClass pc(player_ptr);
1510 if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
1511 if (o_ptr->k_idx && !player_ptr->heavy_wield[i]) {
1512 int str_index, dex_index;
1513 int num = 0, wgt = 0, mul = 0, div = 0;
1515 auto &info = class_info[enum2i(player_ptr->pclass)];
1520 if (pc.equals(PlayerClassType::CAVALRY) && player_ptr->riding && flgs.has(TR_RIDING)) {
1526 if (SpellHex(player_ptr).is_spelling_specific(HEX_XTRA_MIGHT) || SpellHex(player_ptr).is_spelling_specific(HEX_BUILDING)) {
1532 div = ((o_ptr->weight < wgt) ? wgt : o_ptr->weight);
1533 str_index = (adj_str_blow[player_ptr->stat_index[A_STR]] * mul / div);
1535 if (has_two_handed_weapons(player_ptr) && !has_disable_two_handed_bonus(player_ptr, 0)) {
1536 str_index += pc.equals(PlayerClassType::WARRIOR) || pc.equals(PlayerClassType::BERSERKER) ? (player_ptr->lev / 23 + 1) : 1;
1538 if (pc.equals(PlayerClassType::NINJA)) {
1539 str_index = std::max(0, str_index - 1);
1541 if (str_index > 11) {
1545 dex_index = (adj_dex_blow[player_ptr->stat_index[A_DEX]]);
1546 if (dex_index > 11) {
1550 num_blow = blows_table[str_index][dex_index];
1551 if (num_blow > num) {
1552 num_blow = (int16_t)num;
1555 num_blow += (int16_t)player_ptr->extra_blows[i];
1556 if (pc.equals(PlayerClassType::WARRIOR)) {
1557 num_blow += (player_ptr->lev / 40);
1558 } else if (pc.equals(PlayerClassType::BERSERKER)) {
1559 num_blow += (player_ptr->lev / 23);
1560 } else if (pc.equals(PlayerClassType::ROGUE) && (o_ptr->weight < 50) && (player_ptr->stat_index[A_DEX] >= 30)) {
1564 if (PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::FUUJIN)) {
1568 if ((o_ptr->tval == ItemKindType::SWORD) && (o_ptr->sval == SV_POISON_NEEDLE)) {
1581 /* Different calculation for monks with empty hands */
1582 if (is_martial_arts_mode(player_ptr)) {
1583 int blow_base = player_ptr->lev + adj_dex_blow[player_ptr->stat_index[A_DEX]];
1586 if (pc.equals(PlayerClassType::FORCETRAINER)) {
1587 if (blow_base > 18) {
1590 if (blow_base > 31) {
1593 if (blow_base > 44) {
1596 if (blow_base > 58) {
1600 if (blow_base > 12) {
1603 if (blow_base > 22) {
1606 if (blow_base > 31) {
1609 if (blow_base > 39) {
1612 if (blow_base > 46) {
1615 if (blow_base > 53) {
1618 if (blow_base > 59) {
1623 if (heavy_armor(player_ptr) && !pc.equals(PlayerClassType::BERSERKER)) {
1627 if (pc.monk_stance_is(MonkStanceType::GENBU)) {
1629 if (pc.equals(PlayerClassType::MONK) && (player_ptr->lev > 42)) {
1635 } else if (pc.monk_stance_is(MonkStanceType::SUZAKU)) {
1639 num_blow += 1 + player_ptr->extra_blows[0];
1642 if (has_not_ninja_weapon(player_ptr, i)) {
1654 * @param player_ptr プレイヤーへの参照ポインタ
1657 * * 性格なまけものなら加算(+10)
1659 * * 性格ちからじまんとがまんづよいなら加算(+1)
1660 * * 性格チャージマンなら加算(+5)
1661 * * 装備品にTRC::HARD_SPELLがあるなら加算(軽い呪いなら+3/重い呪いなら+10)
1663 static int16_t calc_to_magic_chance(PlayerType *player_ptr)
1667 if (player_ptr->ppersonality == PERSONALITY_LAZY) {
1670 if (player_ptr->ppersonality == PERSONALITY_SHREWD) {
1673 if ((player_ptr->ppersonality == PERSONALITY_PATIENT) || (player_ptr->ppersonality == PERSONALITY_MIGHTY)) {
1676 if (player_ptr->ppersonality == PERSONALITY_CHARGEMAN) {
1680 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1682 o_ptr = &player_ptr->inventory_list[i];
1683 if (!o_ptr->k_idx) {
1687 if (o_ptr->curse_flags.has(CurseTraitType::HARD_SPELL)) {
1688 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
1698 static ARMOUR_CLASS calc_base_ac(PlayerType *player_ptr)
1700 ARMOUR_CLASS ac = 0;
1701 if (player_ptr->yoiyami) {
1705 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1707 o_ptr = &player_ptr->inventory_list[i];
1708 if (!o_ptr->k_idx) {
1714 const auto o_ptr_mh = &player_ptr->inventory_list[INVEN_MAIN_HAND];
1715 const auto o_ptr_sh = &player_ptr->inventory_list[INVEN_SUB_HAND];
1716 if (o_ptr_mh->is_armour() || o_ptr_sh->is_armour()) {
1717 ac += player_ptr->skill_exp[PlayerSkillKindType::SHIELD] * (1 + player_ptr->lev / 22) / 2000;
1723 static ARMOUR_CLASS calc_to_ac(PlayerType *player_ptr, bool is_real_value)
1725 ARMOUR_CLASS ac = 0;
1726 if (player_ptr->yoiyami) {
1730 ac += ((int)(adj_dex_ta[player_ptr->stat_index[A_DEX]]) - 128);
1732 switch (player_ptr->mimic_form) {
1733 case MimicKindType::NONE:
1735 case MimicKindType::DEMON:
1738 case MimicKindType::DEMON_LORD:
1741 case MimicKindType::VAMPIRE:
1746 PlayerClass pc(player_ptr);
1747 if (pc.equals(PlayerClassType::BERSERKER)) {
1748 ac += 10 + player_ptr->lev / 2;
1751 if (pc.equals(PlayerClassType::SORCERER)) {
1755 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
1757 o_ptr = &player_ptr->inventory_list[i];
1758 auto flags = object_flags(o_ptr);
1759 if (!o_ptr->k_idx) {
1762 if (is_real_value || o_ptr->is_known()) {
1766 if (o_ptr->curse_flags.has(CurseTraitType::LOW_AC) || object_flags(o_ptr).has(TR_LOW_AC)) {
1767 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
1768 if (is_real_value || o_ptr->is_fully_known()) {
1772 if (is_real_value || o_ptr->is_fully_known()) {
1778 if ((i == INVEN_SUB_HAND) && flags.has(TR_SUPPORTIVE)) {
1783 PlayerRace pr(player_ptr);
1784 if (pr.equals(PlayerRaceType::GOLEM) || pr.equals(PlayerRaceType::ANDROID)) {
1785 ac += 10 + (player_ptr->lev * 2 / 5);
1788 if (set_quick_and_tiny(player_ptr)) {
1792 if (set_musasi(player_ptr)) {
1796 if (set_icing_and_twinkle(player_ptr)) {
1800 if (player_ptr->muta.has(PlayerMutationType::WART_SKIN)) {
1804 if (player_ptr->muta.has(PlayerMutationType::SCALES)) {
1808 if (player_ptr->muta.has(PlayerMutationType::IRON_SKIN)) {
1812 if (pc.is_martial_arts_pro() && !heavy_armor(player_ptr)) {
1813 if (!(player_ptr->inventory_list[INVEN_BODY].k_idx)) {
1814 ac += (player_ptr->lev * 3) / 2;
1816 if (!(player_ptr->inventory_list[INVEN_OUTER].k_idx) && (player_ptr->lev > 15)) {
1817 ac += ((player_ptr->lev - 13) / 3);
1819 if (!(player_ptr->inventory_list[INVEN_SUB_HAND].k_idx) && (player_ptr->lev > 10)) {
1820 ac += ((player_ptr->lev - 8) / 3);
1822 if (!(player_ptr->inventory_list[INVEN_HEAD].k_idx) && (player_ptr->lev > 4)) {
1823 ac += (player_ptr->lev - 2) / 3;
1825 if (!(player_ptr->inventory_list[INVEN_ARMS].k_idx)) {
1826 ac += (player_ptr->lev / 2);
1828 if (!(player_ptr->inventory_list[INVEN_FEET].k_idx)) {
1829 ac += (player_ptr->lev / 3);
1833 if (player_ptr->realm1 == REALM_HEX) {
1834 if (SpellHex(player_ptr).is_spelling_specific(HEX_ICE_ARMOR)) {
1838 for (int i = INVEN_MAIN_HAND; i <= INVEN_FEET; i++) {
1839 auto *o_ptr = &player_ptr->inventory_list[i];
1840 if (!o_ptr->k_idx) {
1843 if (!o_ptr->is_armour()) {
1846 if (!o_ptr->is_cursed()) {
1849 if (o_ptr->curse_flags.has(CurseTraitType::CURSED)) {
1852 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
1855 if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
1861 if (pc.monk_stance_is(MonkStanceType::GENBU)) {
1862 ac += (player_ptr->lev * player_ptr->lev) / 50;
1863 } else if (pc.monk_stance_is(MonkStanceType::BYAKKO)) {
1865 } else if (pc.monk_stance_is(MonkStanceType::SEIRYU)) {
1867 } else if (pc.samurai_stance_is(SamuraiStanceType::KOUKIJIN)) {
1871 if (player_ptr->ult_res || (pc.samurai_stance_is(SamuraiStanceType::MUSOU))) {
1873 } else if (player_ptr->tsubureru || player_ptr->shield || player_ptr->magicdef) {
1877 if (is_blessed(player_ptr)) {
1881 if (is_shero(player_ptr)) {
1885 if (pc.equals(PlayerClassType::NINJA)) {
1886 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))) {
1887 ac += player_ptr->lev / 2 + 5;
1895 * @brief 二刀流ペナルティ量計算
1896 * @param player_ptr プレイヤーへの参照ポインタ
1897 * @param slot ペナルティ量を計算する武器スロット
1902 * * EASY2_WEAPONによる軽減
1903 * * SUPPORTIVEを左に装備した場合の軽減
1907 int16_t calc_double_weapon_penalty(PlayerType *player_ptr, INVENTORY_IDX slot)
1911 if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND) && has_melee_weapon(player_ptr, INVEN_SUB_HAND)) {
1912 auto flags = object_flags(&player_ptr->inventory_list[INVEN_SUB_HAND]);
1914 penalty = ((100 - player_ptr->skill_exp[PlayerSkillKindType::TWO_WEAPON] / 160) - (130 - player_ptr->inventory_list[slot].weight) / 8);
1915 if (set_quick_and_tiny(player_ptr) || set_icing_and_twinkle(player_ptr) || set_anubis_and_chariot(player_ptr)) {
1916 penalty = penalty / 2 - 5;
1919 for (uint i = FLAG_CAUSE_INVEN_MAIN_HAND; i < FLAG_CAUSE_MAX; i <<= 1) {
1920 if (penalty > 0 && any_bits(player_ptr->easy_2weapon, i)) {
1925 if (flags.has(TR_SUPPORTIVE)) {
1926 penalty = std::max(0, penalty - 10);
1929 if (set_musasi(player_ptr)) {
1930 penalty = std::min(0, penalty);
1933 if (player_ptr->inventory_list[slot].tval == ItemKindType::POLEARM) {
1937 return (int16_t)penalty;
1940 static bool is_riding_two_hands(PlayerType *player_ptr)
1942 if (!player_ptr->riding) {
1946 if (has_two_handed_weapons(player_ptr) || (empty_hands(player_ptr, false) == EMPTY_HAND_NONE)) {
1948 } else if (any_bits(player_ptr->pet_extra_flags, PF_TWO_HANDS)) {
1949 switch (player_ptr->pclass) {
1950 case PlayerClassType::MONK:
1951 case PlayerClassType::FORCETRAINER:
1952 case PlayerClassType::BERSERKER:
1953 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)) {
1965 static int16_t calc_riding_bow_penalty(PlayerType *player_ptr)
1967 auto *floor_ptr = player_ptr->current_floor_ptr;
1968 if (!player_ptr->riding) {
1972 int16_t penalty = 0;
1974 if (PlayerClass(player_ptr).is_tamer()) {
1975 if (player_ptr->tval_ammo != ItemKindType::ARROW) {
1979 penalty = monraces_info[floor_ptr->m_list[player_ptr->riding].r_idx].level - player_ptr->skill_exp[PlayerSkillKindType::RIDING] / 80;
1986 if (player_ptr->tval_ammo == ItemKindType::BOLT) {
1993 void put_equipment_warning(PlayerType *player_ptr)
1995 bool heavy_shoot = is_heavy_shoot(player_ptr, &player_ptr->inventory_list[INVEN_BOW]);
1996 if (player_ptr->old_heavy_shoot != heavy_shoot) {
1998 msg_print(_("こんな重い弓を装備しているのは大変だ。", "You have trouble wielding such a heavy bow."));
1999 } else if (player_ptr->inventory_list[INVEN_BOW].k_idx) {
2000 msg_print(_("この弓なら装備していても辛くない。", "You have no trouble wielding your bow."));
2002 msg_print(_("重い弓を装備からはずして体が楽になった。", "You feel relieved to put down your heavy bow."));
2004 player_ptr->old_heavy_shoot = heavy_shoot;
2007 for (int i = 0; i < 2; i++) {
2008 if (player_ptr->old_heavy_wield[i] != player_ptr->heavy_wield[i]) {
2009 if (player_ptr->heavy_wield[i]) {
2010 msg_print(_("こんな重い武器を装備しているのは大変だ。", "You have trouble wielding such a heavy weapon."));
2011 } else if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
2012 msg_print(_("これなら装備していても辛くない。", "You have no trouble wielding your weapon."));
2013 } else if (player_ptr->heavy_wield[1 - i]) {
2014 msg_print(_("まだ武器が重い。", "You still have trouble wielding a heavy weapon."));
2016 msg_print(_("重い武器を装備からはずして体が楽になった。", "You feel relieved to put down your heavy weapon."));
2019 player_ptr->old_heavy_wield[i] = player_ptr->heavy_wield[i];
2022 if (player_ptr->old_riding_wield[i] != player_ptr->is_icky_riding_wield[i]) {
2023 if (player_ptr->is_icky_riding_wield[i]) {
2024 msg_print(_("この武器は乗馬中に使うにはむかないようだ。", "This weapon is not suitable for use while riding."));
2025 } else if (!player_ptr->riding) {
2026 msg_print(_("この武器は徒歩で使いやすい。", "This weapon is suitable for use on foot."));
2027 } else if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
2028 msg_print(_("これなら乗馬中にぴったりだ。", "This weapon is suitable for use while riding."));
2031 player_ptr->old_riding_wield[i] = player_ptr->is_icky_riding_wield[i];
2034 if (player_ptr->old_icky_wield[i] == player_ptr->is_icky_wield[i]) {
2038 if (player_ptr->is_icky_wield[i]) {
2039 msg_print(_("今の装備はどうも自分にふさわしくない気がする。", "You do not feel comfortable with your weapon."));
2040 if (w_ptr->is_loading_now) {
2041 chg_virtue(player_ptr, V_FAITH, -1);
2043 } else if (has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
2044 msg_print(_("今の装備は自分にふさわしい気がする。", "You feel comfortable with your weapon."));
2046 msg_print(_("装備をはずしたら随分と気が楽になった。", "You feel more comfortable after removing your weapon."));
2049 player_ptr->old_icky_wield[i] = player_ptr->is_icky_wield[i];
2052 if (player_ptr->riding && (player_ptr->old_riding_ryoute != player_ptr->riding_ryoute)) {
2053 if (player_ptr->riding_ryoute) {
2055 msg_format("%s馬を操れない。", (empty_hands(player_ptr, false) == EMPTY_HAND_NONE) ? "両手がふさがっていて" : "");
2057 msg_print("You are using both hand for fighting, and you can't control the pet you're riding.");
2061 msg_format("%s馬を操れるようになった。", (empty_hands(player_ptr, false) == EMPTY_HAND_NONE) ? "手が空いて" : "");
2063 msg_print("You began to control the pet you're riding with one hand.");
2067 player_ptr->old_riding_ryoute = player_ptr->riding_ryoute;
2070 PlayerClass pc(player_ptr);
2071 if ((pc.is_martial_arts_pro() || pc.equals(PlayerClassType::NINJA)) && (heavy_armor(player_ptr) != player_ptr->monk_notify_aux)) {
2072 if (heavy_armor(player_ptr)) {
2073 msg_print(_("装備が重くてバランスを取れない。", "The weight of your armor disrupts your balance."));
2074 if (w_ptr->is_loading_now) {
2075 chg_virtue(player_ptr, V_HARMONY, -1);
2078 msg_print(_("バランスがとれるようになった。", "You regain your balance."));
2081 player_ptr->monk_notify_aux = heavy_armor(player_ptr);
2085 static short calc_to_damage(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value)
2087 auto *o_ptr = &player_ptr->inventory_list[slot];
2088 auto flgs = object_flags(o_ptr);
2090 player_hand calc_hand = PLAYER_HAND_OTHER;
2091 if (slot == INVEN_MAIN_HAND) {
2092 calc_hand = PLAYER_HAND_MAIN;
2094 if (slot == INVEN_SUB_HAND) {
2095 calc_hand = PLAYER_HAND_SUB;
2099 damage += ((int)(adj_str_td[player_ptr->stat_index[A_STR]]) - 128);
2101 if (is_shero(player_ptr)) {
2102 damage += 3 + (player_ptr->lev / 5);
2105 auto player_stun = player_ptr->effects()->stun();
2106 damage -= player_stun->get_damage_penalty();
2107 PlayerClass pc(player_ptr);
2108 if (pc.equals(PlayerClassType::PRIEST) && (flgs.has_not(TR_BLESSED)) && ((o_ptr->tval == ItemKindType::SWORD) || (o_ptr->tval == ItemKindType::POLEARM))) {
2110 } else if (pc.equals(PlayerClassType::BERSERKER)) {
2111 damage += player_ptr->lev / 6;
2112 if (((calc_hand == PLAYER_HAND_MAIN) && !can_attack_with_sub_hand(player_ptr)) || has_two_handed_weapons(player_ptr)) {
2113 damage += player_ptr->lev / 6;
2115 } else if (pc.equals(PlayerClassType::SORCERER)) {
2116 if (!((o_ptr->tval == ItemKindType::HAFTED) && ((o_ptr->sval == SV_WIZSTAFF) || (o_ptr->sval == SV_NAMAKE_HAMMER)))) {
2121 } else if (pc.equals(PlayerClassType::FORCETRAINER)) {
2122 // 練気術師は格闘ダメージに (気)/5 の修正を得る。
2123 if (is_martial_arts_mode(player_ptr) && calc_hand == PLAYER_HAND_MAIN) {
2124 damage += get_current_ki(player_ptr) / 5;
2128 if ((player_ptr->realm1 == REALM_HEX) && o_ptr->is_cursed()) {
2129 if (SpellHex(player_ptr).is_spelling_specific(HEX_RUNESWORD)) {
2130 if (o_ptr->curse_flags.has(CurseTraitType::CURSED)) {
2133 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2136 if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
2142 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2144 o_ptr = &player_ptr->inventory_list[i];
2145 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) {
2149 if (!o_ptr->is_known() && !is_real_value) {
2152 bonus_to_d = o_ptr->to_d;
2154 if (pc.equals(PlayerClassType::NINJA)) {
2155 if (o_ptr->to_d > 0) {
2156 bonus_to_d = (o_ptr->to_d + 1) / 2;
2160 switch (player_melee_type(player_ptr)) {
2161 case MELEE_TYPE_BAREHAND_TWO: /* fall through */
2162 case MELEE_TYPE_WEAPON_TWOHAND:
2163 if (calc_hand == main_attack_hand(player_ptr)) {
2164 damage += (int16_t)bonus_to_d;
2168 case MELEE_TYPE_BAREHAND_MAIN: /* fall through */
2169 case MELEE_TYPE_WEAPON_MAIN:
2170 if ((calc_hand == PLAYER_HAND_MAIN) && (i != INVEN_SUB_RING)) {
2171 damage += (int16_t)bonus_to_d;
2175 case MELEE_TYPE_BAREHAND_SUB: /* fall through */
2176 case MELEE_TYPE_WEAPON_SUB:
2177 if ((calc_hand == PLAYER_HAND_SUB) && (i != INVEN_MAIN_RING)) {
2178 damage += (int16_t)bonus_to_d;
2182 case MELEE_TYPE_WEAPON_DOUBLE:
2183 if (calc_hand == PLAYER_HAND_MAIN) {
2184 if (i == INVEN_MAIN_RING) {
2185 damage += (int16_t)bonus_to_d;
2186 } else if (i != INVEN_SUB_RING) {
2187 damage += (bonus_to_d > 0) ? (bonus_to_d + 1) / 2 : bonus_to_d;
2190 if (calc_hand == PLAYER_HAND_SUB) {
2191 if (i == INVEN_SUB_RING) {
2192 damage += (int16_t)bonus_to_d;
2193 } else if (i != INVEN_MAIN_RING) {
2194 damage += (bonus_to_d > 0) ? bonus_to_d / 2 : bonus_to_d;
2199 case MELEE_TYPE_SHIELD_DOUBLE:
2207 if (main_attack_hand(player_ptr) == calc_hand) {
2208 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 bonus_to_d = ((int)(adj_str_td[player_ptr->stat_index[A_STR]]) - 128) / 2;
2211 damage += std::max<int>(bonus_to_d, 1);
2215 if (is_martial_arts_mode(player_ptr) && (!heavy_armor(player_ptr) || !pc.equals(PlayerClassType::BERSERKER))) {
2216 damage += (player_ptr->lev / 6);
2219 // 朱雀の構えをとっているとき、格闘ダメージに -(レベル)/6 の修正を得る。
2220 if (PlayerClass(player_ptr).monk_stance_is(MonkStanceType::SUZAKU)) {
2221 if (is_martial_arts_mode(player_ptr) && calc_hand == PLAYER_HAND_MAIN) {
2222 damage -= (player_ptr->lev / 6);
2226 return static_cast<short>(damage);
2230 * @brief 武器の命中修正を計算する。 / Calculate hit bonus from a wielded weapon.
2232 * 'slot' MUST be INVEN_MAIN_HAND or INVEM_SUB_HAND.
2234 static short calc_to_hit(PlayerType *player_ptr, INVENTORY_IDX slot, bool is_real_value)
2239 hit += ((int)(adj_dex_th[player_ptr->stat_index[A_DEX]]) - 128);
2240 hit += ((int)(adj_str_th[player_ptr->stat_index[A_STR]]) - 128);
2242 /* Temporary bonuses */
2243 if (is_blessed(player_ptr)) {
2247 if (is_hero(player_ptr)) {
2251 if (is_shero(player_ptr)) {
2255 auto player_stun = player_ptr->effects()->stun();
2256 hit -= player_stun->get_damage_penalty();
2257 player_hand calc_hand = PLAYER_HAND_OTHER;
2258 if (slot == INVEN_MAIN_HAND) {
2259 calc_hand = PLAYER_HAND_MAIN;
2261 if (slot == INVEN_SUB_HAND) {
2262 calc_hand = PLAYER_HAND_SUB;
2265 /* Default hand bonuses */
2266 if (main_attack_hand(player_ptr) == calc_hand) {
2267 switch (player_melee_type(player_ptr)) {
2268 case MELEE_TYPE_BAREHAND_MAIN:
2269 if (player_ptr->riding) {
2273 case MELEE_TYPE_BAREHAND_SUB:
2274 if (player_ptr->riding) {
2278 case MELEE_TYPE_BAREHAND_TWO:
2279 hit += (player_ptr->skill_exp[PlayerSkillKindType::MARTIAL_ARTS] - PlayerSkill::weapon_exp_at(PlayerSkillRank::BEGINNER)) / 200;
2286 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 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);
2289 hit += std::max<int>(bonus_to_h, 1);
2293 /* Bonuses and penalties by weapon */
2294 PlayerClass pc(player_ptr);
2295 if (has_melee_weapon(player_ptr, slot)) {
2296 auto *o_ptr = &player_ptr->inventory_list[slot];
2297 auto flgs = object_flags(o_ptr);
2299 /* Traind bonuses */
2300 hit += (player_ptr->weapon_exp[o_ptr->tval][o_ptr->sval] - PlayerSkill::weapon_exp_at(PlayerSkillRank::BEGINNER)) / 200;
2302 /* Weight penalty */
2303 if (calc_weapon_weight_limit(player_ptr) < o_ptr->weight / 10) {
2304 hit += 2 * (calc_weapon_weight_limit(player_ptr) - o_ptr->weight / 10);
2307 /* Low melee penalty */
2308 if ((o_ptr->is_fully_known() || is_real_value) && o_ptr->curse_flags.has(CurseTraitType::LOW_MELEE)) {
2309 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2316 /* Riding bonus and penalty */
2317 if (player_ptr->riding > 0) {
2318 if (o_ptr->is_lance()) {
2320 } else if (flgs.has_not(TR_RIDING)) {
2322 if (PlayerClass(player_ptr).is_tamer()) {
2325 penalty = monraces_info[player_ptr->current_floor_ptr->m_list[player_ptr->riding].r_idx].level - player_ptr->skill_exp[PlayerSkillKindType::RIDING] / 80;
2336 /* Class penalties */
2337 if (pc.equals(PlayerClassType::PRIEST) && (flgs.has_not(TR_BLESSED)) && ((o_ptr->tval == ItemKindType::SWORD) || (o_ptr->tval == ItemKindType::POLEARM))) {
2339 } else if (pc.equals(PlayerClassType::BERSERKER)) {
2340 hit += player_ptr->lev / 5;
2341 if (((calc_hand == PLAYER_HAND_MAIN) && !can_attack_with_sub_hand(player_ptr)) || has_two_handed_weapons(player_ptr)) {
2342 hit += player_ptr->lev / 5;
2344 } else if (pc.equals(PlayerClassType::SORCERER)) {
2345 if (!((o_ptr->tval == ItemKindType::HAFTED) && ((o_ptr->sval == SV_WIZSTAFF) || (o_ptr->sval == SV_NAMAKE_HAMMER)))) {
2352 if (has_not_ninja_weapon(player_ptr, (int)calc_hand) || has_not_monk_weapon(player_ptr, (int)calc_hand)) {
2356 /* Hex realm bonuses */
2357 if ((player_ptr->realm1 == REALM_HEX) && o_ptr->is_cursed()) {
2358 if (o_ptr->curse_flags.has(CurseTraitType::CURSED)) {
2361 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2364 if (o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE)) {
2367 if (o_ptr->curse_flags.has(CurseTraitType::TY_CURSE)) {
2373 /* Bonuses from inventory */
2374 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2375 auto *o_ptr = &player_ptr->inventory_list[i];
2377 /* Ignore empty hands, handed weapons, bows and capture balls */
2378 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) {
2382 /* Fake value does not include unknown objects' value */
2383 if (!o_ptr->is_known() && !is_real_value) {
2387 int bonus_to_h = o_ptr->to_h;
2389 /* When wields only a weapon */
2390 if (pc.equals(PlayerClassType::NINJA)) {
2391 if (o_ptr->to_h > 0) {
2392 bonus_to_h = (o_ptr->to_h + 1) / 2;
2396 switch (player_melee_type(player_ptr)) {
2397 case MELEE_TYPE_BAREHAND_TWO: /* fall through */
2398 case MELEE_TYPE_WEAPON_TWOHAND:
2399 if (calc_hand == main_attack_hand(player_ptr)) {
2400 hit += (int16_t)bonus_to_h;
2404 case MELEE_TYPE_BAREHAND_MAIN: /* fall through */
2405 case MELEE_TYPE_WEAPON_MAIN:
2406 if ((calc_hand == PLAYER_HAND_MAIN) && (i != INVEN_SUB_RING)) {
2407 hit += (int16_t)bonus_to_h;
2411 case MELEE_TYPE_BAREHAND_SUB: /* fall through */
2412 case MELEE_TYPE_WEAPON_SUB:
2413 if ((calc_hand == PLAYER_HAND_SUB) && (i != INVEN_MAIN_RING)) {
2414 hit += (int16_t)bonus_to_h;
2418 case MELEE_TYPE_WEAPON_DOUBLE:
2419 if (calc_hand == PLAYER_HAND_MAIN) {
2420 if (i == INVEN_MAIN_RING) {
2421 hit += (int16_t)bonus_to_h;
2422 } else if (i != INVEN_SUB_RING) {
2423 hit += (bonus_to_h > 0) ? (bonus_to_h + 1) / 2 : bonus_to_h;
2426 if (calc_hand == PLAYER_HAND_SUB) {
2427 if (i == INVEN_SUB_RING) {
2428 hit += (int16_t)bonus_to_h;
2429 } else if (i != INVEN_MAIN_RING) {
2430 hit += (bonus_to_h > 0) ? bonus_to_h / 2 : bonus_to_h;
2435 case MELEE_TYPE_SHIELD_DOUBLE:
2443 /* Martial arts bonus */
2444 if (is_martial_arts_mode(player_ptr) && (!heavy_armor(player_ptr) || !pc.equals(PlayerClassType::BERSERKER))) {
2445 hit += (player_ptr->lev / 3);
2448 /* Two handed combat penalty */
2449 hit -= calc_double_weapon_penalty(player_ptr, slot);
2451 // 朱雀の構えをとっているとき、格闘命中に -(レベル)/3 の修正を得る。
2452 if (PlayerClass(player_ptr).monk_stance_is(MonkStanceType::SUZAKU)) {
2453 if (is_martial_arts_mode(player_ptr) && calc_hand == PLAYER_HAND_MAIN) {
2454 hit -= (player_ptr->lev / 3);
2458 return static_cast<short>(hit);
2461 static int16_t calc_to_hit_bow(PlayerType *player_ptr, bool is_real_value)
2465 pow += ((int)(adj_dex_th[player_ptr->stat_index[A_DEX]]) - 128);
2466 pow += ((int)(adj_str_th[player_ptr->stat_index[A_STR]]) - 128);
2470 o_ptr = &player_ptr->inventory_list[INVEN_BOW];
2472 if (o_ptr->curse_flags.has(CurseTraitType::LOW_MELEE)) {
2473 if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
2482 auto player_stun = player_ptr->effects()->stun();
2483 pow -= player_stun->get_damage_penalty();
2484 if (is_blessed(player_ptr)) {
2488 if (is_hero(player_ptr)) {
2492 if (is_shero(player_ptr)) {
2496 auto *o_ptr = &player_ptr->inventory_list[INVEN_BOW];
2498 if (is_heavy_shoot(player_ptr, o_ptr)) {
2499 pow += 2 * (calc_bow_weight_limit(player_ptr) - o_ptr->weight / 10);
2503 if (o_ptr->k_idx && !is_heavy_shoot(player_ptr, &player_ptr->inventory_list[INVEN_BOW])) {
2504 if (PlayerClass(player_ptr).equals(PlayerClassType::SNIPER) && (player_ptr->tval_ammo == ItemKindType::BOLT)) {
2505 pow += (10 + (player_ptr->lev / 5));
2511 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2513 o_ptr = &player_ptr->inventory_list[i];
2514 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) {
2518 bonus_to_h = o_ptr->to_h;
2520 if (PlayerClass(player_ptr).equals(PlayerClassType::NINJA)) {
2521 if (o_ptr->to_h > 0) {
2522 bonus_to_h = (o_ptr->to_h + 1) / 2;
2526 if (is_real_value || o_ptr->is_known()) {
2527 pow += (int16_t)bonus_to_h;
2531 pow -= calc_riding_bow_penalty(player_ptr);
2536 static int16_t calc_to_damage_misc(PlayerType *player_ptr)
2542 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2543 o_ptr = &player_ptr->inventory_list[i];
2544 if (!o_ptr->k_idx) {
2548 int bonus_to_d = o_ptr->to_d;
2549 if (PlayerClass(player_ptr).equals(PlayerClassType::NINJA)) {
2550 if (o_ptr->to_d > 0) {
2551 bonus_to_d = (o_ptr->to_d + 1) / 2;
2554 to_dam += (int16_t)bonus_to_d;
2557 if (is_shero(player_ptr)) {
2558 to_dam += 3 + (player_ptr->lev / 5);
2561 auto player_stun = player_ptr->effects()->stun();
2562 to_dam -= player_stun->get_damage_penalty();
2563 to_dam += ((int)(adj_str_td[player_ptr->stat_index[A_STR]]) - 128);
2567 static int16_t calc_to_hit_misc(PlayerType *player_ptr)
2573 for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
2574 o_ptr = &player_ptr->inventory_list[i];
2575 if (!o_ptr->k_idx) {
2579 int bonus_to_h = o_ptr->to_h;
2580 if (PlayerClass(player_ptr).equals(PlayerClassType::NINJA)) {
2581 if (o_ptr->to_h > 0) {
2582 bonus_to_h = (o_ptr->to_h + 1) / 2;
2585 to_hit += (int16_t)bonus_to_h;
2588 if (is_blessed(player_ptr)) {
2592 if (is_hero(player_ptr)) {
2596 if (is_shero(player_ptr)) {
2600 auto player_stun = player_ptr->effects()->stun();
2601 to_hit -= player_stun->get_damage_penalty();
2602 to_hit += ((int)(adj_dex_th[player_ptr->stat_index[A_DEX]]) - 128);
2603 to_hit += ((int)(adj_str_th[player_ptr->stat_index[A_STR]]) - 128);
2608 static DICE_NUMBER calc_to_weapon_dice_num(PlayerType *player_ptr, INVENTORY_IDX slot)
2610 auto *o_ptr = &player_ptr->inventory_list[slot];
2611 return (player_ptr->riding > 0) && o_ptr->is_lance() ? 2 : 0;
2615 * @brief プレイヤーの所持重量制限を計算する /
2616 * Computes current weight limit.
2619 WEIGHT calc_weight_limit(PlayerType *player_ptr)
2621 WEIGHT i = (WEIGHT)adj_str_wgt[player_ptr->stat_index[A_STR]] * 50;
2622 if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
2629 * @brief update のフラグに応じた更新をまとめて行う / Handle "update"
2630 * @details 更新処理の対象はプレイヤーの能力修正/光源寿命/HP/MP/魔法の学習状態、他多数の外界の状態判定。
2632 void update_creature(PlayerType *player_ptr)
2634 if (!player_ptr->update) {
2638 auto *floor_ptr = player_ptr->current_floor_ptr;
2639 if (any_bits(player_ptr->update, (PU_AUTODESTROY))) {
2640 reset_bits(player_ptr->update, PU_AUTODESTROY);
2641 autopick_delayed_alter(player_ptr);
2644 if (any_bits(player_ptr->update, (PU_COMBINE))) {
2645 reset_bits(player_ptr->update, PU_COMBINE);
2646 combine_pack(player_ptr);
2649 if (any_bits(player_ptr->update, (PU_REORDER))) {
2650 reset_bits(player_ptr->update, PU_REORDER);
2651 reorder_pack(player_ptr);
2654 if (any_bits(player_ptr->update, (PU_BONUS))) {
2655 reset_bits(player_ptr->update, PU_BONUS);
2656 PlayerAlignment(player_ptr).update_alignment();
2657 PlayerSkill ps(player_ptr);
2658 ps.apply_special_weapon_skill_max_values();
2659 ps.limit_weapon_skills_by_max_value();
2660 update_bonuses(player_ptr);
2663 if (any_bits(player_ptr->update, (PU_TORCH))) {
2664 reset_bits(player_ptr->update, PU_TORCH);
2665 update_lite_radius(player_ptr);
2668 if (any_bits(player_ptr->update, (PU_HP))) {
2669 reset_bits(player_ptr->update, PU_HP);
2670 update_max_hitpoints(player_ptr);
2673 if (any_bits(player_ptr->update, (PU_MANA))) {
2674 reset_bits(player_ptr->update, PU_MANA);
2675 update_max_mana(player_ptr);
2678 if (any_bits(player_ptr->update, (PU_SPELLS))) {
2679 reset_bits(player_ptr->update, PU_SPELLS);
2680 update_num_of_spells(player_ptr);
2683 if (!w_ptr->character_generated) {
2686 if (w_ptr->character_icky_depth > 0) {
2689 if (any_bits(player_ptr->update, (PU_UN_LITE))) {
2690 reset_bits(player_ptr->update, PU_UN_LITE);
2691 forget_lite(floor_ptr);
2694 if (any_bits(player_ptr->update, (PU_UN_VIEW))) {
2695 reset_bits(player_ptr->update, PU_UN_VIEW);
2696 forget_view(floor_ptr);
2699 if (any_bits(player_ptr->update, (PU_VIEW))) {
2700 reset_bits(player_ptr->update, PU_VIEW);
2701 update_view(player_ptr);
2704 if (any_bits(player_ptr->update, (PU_LITE))) {
2705 reset_bits(player_ptr->update, PU_LITE);
2706 update_lite(player_ptr);
2709 if (any_bits(player_ptr->update, (PU_FLOW))) {
2710 reset_bits(player_ptr->update, PU_FLOW);
2711 update_flow(player_ptr);
2714 if (any_bits(player_ptr->update, (PU_DISTANCE))) {
2715 reset_bits(player_ptr->update, PU_DISTANCE);
2717 update_monsters(player_ptr, true);
2720 if (any_bits(player_ptr->update, (PU_MON_LITE))) {
2721 reset_bits(player_ptr->update, PU_MON_LITE);
2722 update_mon_lite(player_ptr);
2725 if (any_bits(player_ptr->update, (PU_DELAY_VIS))) {
2726 reset_bits(player_ptr->update, PU_DELAY_VIS);
2727 delayed_visual_update(player_ptr);
2730 if (any_bits(player_ptr->update, (PU_MONSTERS))) {
2731 reset_bits(player_ptr->update, PU_MONSTERS);
2732 update_monsters(player_ptr, false);
2737 * @brief プレイヤーが魔道書を一冊も持っていないかを判定する
2738 * @return 魔道書を一冊も持っていないならTRUEを返す
2740 bool player_has_no_spellbooks(PlayerType *player_ptr)
2743 for (int i = 0; i < INVEN_PACK; i++) {
2744 o_ptr = &player_ptr->inventory_list[i];
2745 if (o_ptr->k_idx && check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval)) {
2750 auto *floor_ptr = player_ptr->current_floor_ptr;
2751 for (const auto this_o_idx : floor_ptr->grid_array[player_ptr->y][player_ptr->x].o_idx_list) {
2752 o_ptr = &floor_ptr->o_list[this_o_idx];
2753 if (o_ptr->k_idx && any_bits(o_ptr->marked, OM_FOUND) && check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval)) {
2762 * @brief プレイヤーを指定座標に配置する / Place the player in the dungeon XXX XXX
2765 * @return 配置に成功したらTRUE
2767 bool player_place(PlayerType *player_ptr, POSITION y, POSITION x)
2769 if (player_ptr->current_floor_ptr->grid_array[y][x].m_idx != 0) {
2773 /* Save player location */
2780 * @brief 種族アンバライトが出血時パターンの上に乗った際のペナルティ処理
2782 void wreck_the_pattern(PlayerType *player_ptr)
2784 auto *floor_ptr = player_ptr->current_floor_ptr;
2785 int pattern_type = terrains_info[floor_ptr->grid_array[player_ptr->y][player_ptr->x].feat].subtype;
2786 if (pattern_type == PATTERN_TILE_WRECKED) {
2790 msg_print(_("パターンを血で汚してしまった!", "You bleed on the Pattern!"));
2791 msg_print(_("何か恐ろしい事が起こった!", "Something terrible happens!"));
2793 if (!is_invuln(player_ptr)) {
2794 take_hit(player_ptr, DAMAGE_NOESCAPE, damroll(10, 8), _("パターン損壊", "corrupting the Pattern"));
2797 int to_ruin = randint1(45) + 35;
2800 scatter(player_ptr, &r_y, &r_x, player_ptr->y, player_ptr->x, 4, PROJECT_NONE);
2802 if (pattern_tile(floor_ptr, r_y, r_x) && (terrains_info[floor_ptr->grid_array[r_y][r_x].feat].subtype != PATTERN_TILE_WRECKED)) {
2803 cave_set_feat(player_ptr, r_y, r_x, feat_pattern_corrupted);
2807 cave_set_feat(player_ptr, player_ptr->y, player_ptr->x, feat_pattern_corrupted);
2811 * @brief プレイヤーの経験値について整合性のためのチェックと調整を行う /
2812 * Advance experience levels and print experience
2814 void check_experience(PlayerType *player_ptr)
2816 if (player_ptr->exp < 0) {
2817 player_ptr->exp = 0;
2819 if (player_ptr->max_exp < 0) {
2820 player_ptr->max_exp = 0;
2822 if (player_ptr->max_max_exp < 0) {
2823 player_ptr->max_max_exp = 0;
2826 if (player_ptr->exp > PY_MAX_EXP) {
2827 player_ptr->exp = PY_MAX_EXP;
2829 if (player_ptr->max_exp > PY_MAX_EXP) {
2830 player_ptr->max_exp = PY_MAX_EXP;
2832 if (player_ptr->max_max_exp > PY_MAX_EXP) {
2833 player_ptr->max_max_exp = PY_MAX_EXP;
2836 if (player_ptr->exp > player_ptr->max_exp) {
2837 player_ptr->max_exp = player_ptr->exp;
2839 if (player_ptr->max_exp > player_ptr->max_max_exp) {
2840 player_ptr->max_max_exp = player_ptr->max_exp;
2843 set_bits(player_ptr->redraw, PR_EXP);
2844 handle_stuff(player_ptr);
2846 PlayerRace pr(player_ptr);
2847 bool android = pr.equals(PlayerRaceType::ANDROID);
2848 PLAYER_LEVEL old_lev = player_ptr->lev;
2849 while ((player_ptr->lev > 1) && (player_ptr->exp < ((android ? player_exp_a : player_exp)[player_ptr->lev - 2] * player_ptr->expfact / 100L))) {
2851 set_bits(player_ptr->update, PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
2852 set_bits(player_ptr->redraw, PR_LEV | PR_TITLE);
2853 set_bits(player_ptr->window_flags, PW_PLAYER);
2854 handle_stuff(player_ptr);
2857 bool level_reward = false;
2858 bool level_mutation = false;
2859 bool level_inc_stat = false;
2860 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 if (player_ptr->lev > player_ptr->max_plv) {
2863 player_ptr->max_plv = player_ptr->lev;
2865 if (PlayerClass(player_ptr).equals(PlayerClassType::CHAOS_WARRIOR) || player_ptr->muta.has(PlayerMutationType::CHAOS_GIFT)) {
2866 level_reward = true;
2868 if (pr.equals(PlayerRaceType::BEASTMAN)) {
2870 level_mutation = true;
2873 level_inc_stat = true;
2875 exe_write_diary(player_ptr, DIARY_LEVELUP, player_ptr->lev, nullptr);
2879 msg_format(_("レベル %d にようこそ。", "Welcome to level %d."), player_ptr->lev);
2880 set_bits(player_ptr->update, (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS));
2881 set_bits(player_ptr->redraw, (PR_LEV | PR_TITLE | PR_EXP));
2882 set_bits(player_ptr->window_flags, (PW_PLAYER | PW_SPELL | PW_INVEN));
2883 player_ptr->level_up_message = true;
2884 handle_stuff(player_ptr);
2886 player_ptr->level_up_message = false;
2887 if (level_inc_stat) {
2888 if (!(player_ptr->max_plv % 10)) {
2895 cnv_stat(player_ptr->stat_max[0], tmp);
2896 prt(format(_(" a) 腕力 (現在値 %s)", " a) Str (cur %s)"), tmp), 2, 14);
2897 cnv_stat(player_ptr->stat_max[1], tmp);
2898 prt(format(_(" b) 知能 (現在値 %s)", " b) Int (cur %s)"), tmp), 3, 14);
2899 cnv_stat(player_ptr->stat_max[2], tmp);
2900 prt(format(_(" c) 賢さ (現在値 %s)", " c) Wis (cur %s)"), tmp), 4, 14);
2901 cnv_stat(player_ptr->stat_max[3], tmp);
2902 prt(format(_(" d) 器用 (現在値 %s)", " d) Dex (cur %s)"), tmp), 5, 14);
2903 cnv_stat(player_ptr->stat_max[4], tmp);
2904 prt(format(_(" e) 耐久 (現在値 %s)", " e) Con (cur %s)"), tmp), 6, 14);
2905 cnv_stat(player_ptr->stat_max[5], tmp);
2906 prt(format(_(" f) 魅力 (現在値 %s)", " f) Chr (cur %s)"), tmp), 7, 14);
2909 prt(_(" どの能力値を上げますか?", " Which stat do you want to raise?"), 1, 14);
2913 if ((choice >= 'a') && (choice <= 'f')) {
2917 for (n = 0; n < A_MAX; n++) {
2918 if (n != choice - 'a') {
2922 if (get_check(_("よろしいですか?", "Are you sure? "))) {
2926 do_inc_stat(player_ptr, choice - 'a');
2928 } else if (!(player_ptr->max_plv % 2)) {
2929 do_inc_stat(player_ptr, randint0(6));
2933 if (level_mutation) {
2934 msg_print(_("あなたは変わった気がする...", "You feel different..."));
2935 (void)gain_mutation(player_ptr, 0);
2936 level_mutation = false;
2940 * 報酬でレベルが上ると再帰的に check_experience(player_ptr) が
2944 patron_list[player_ptr->chaos_patron].gain_level_reward(player_ptr, 0);
2945 level_reward = false;
2948 set_bits(player_ptr->update, PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
2949 set_bits(player_ptr->redraw, (PR_LEV | PR_TITLE));
2950 set_bits(player_ptr->window_flags, (PW_PLAYER | PW_SPELL));
2951 handle_stuff(player_ptr);
2954 if (old_lev != player_ptr->lev) {
2955 autopick_load_pref(player_ptr, false);
2960 * @brief 現在の修正後能力値を3~17及び18/xxx形式に変換する / Converts stat num into a six-char (right justified) string
2962 * @param out_val 出力先文字列ポインタ
2964 void cnv_stat(int val, char *out_val)
2967 sprintf(out_val, " %2d", val);
2971 int bonus = (val - 18);
2973 sprintf(out_val, "18/%3s", "***");
2974 } else if (bonus >= 100) {
2975 sprintf(out_val, "18/%03d", bonus);
2977 sprintf(out_val, " 18/%02d", bonus);
2982 * @brief 能力値現在値から3~17及び18/xxx様式に基づく加減算を行う。
2983 * Modify a stat value by a "modifier", return new value
2985 * @param amount 加減算値
2989 * Stats go up: 3,4,...,17,18,18/10,18/20,...,18/220
2990 * Or even: 18/13, 18/23, 18/33, ..., 18/220
2991 * Stats go down: 18/220, 18/210,..., 18/10, 18, 17, ..., 3
2992 * Or even: 18/13, 18/03, 18, 17, ..., 3
2995 int16_t modify_stat_value(int value, int amount)
2998 for (int i = 0; i < amount; i++) {
3005 } else if (amount < 0) {
3006 for (int i = 0; i < (0 - amount); i++) {
3007 if (value >= 18 + 10) {
3009 } else if (value > 18) {
3011 } else if (value > 3) {
3017 return (int16_t)value;
3022 * Hack -- Calculates the total number of points earned -JWT-
3025 long calc_score(PlayerType *player_ptr)
3027 int arena_win = std::min<int>(player_ptr->arena_number, MAX_ARENA_MONS);
3030 if (!preserve_mode) {
3042 if (ironman_shops) {
3045 if (ironman_small_levels) {
3048 if (ironman_empty_levels) {
3051 if (!powerup_home) {
3054 if (ironman_rooms) {
3057 if (ironman_nightmare) {
3066 for (const auto &d_ref : dungeons_info) {
3067 if (max_dl < max_dlv[d_ref.idx]) {
3068 max_dl = max_dlv[d_ref.idx];
3072 uint32_t point_l = (player_ptr->max_max_exp + (100 * max_dl));
3073 uint32_t point_h = point_l / 0x10000L;
3074 point_l = point_l % 0x10000L;
3077 point_h += point_l / 0x10000L;
3078 point_l %= 0x10000L;
3080 point_l += ((point_h % 100) << 16);
3084 uint32_t point = (point_h << 16) + (point_l);
3085 if (player_ptr->arena_number >= 0) {
3086 point += (arena_win * arena_win * (arena_win > 29 ? 1000 : 100));
3089 if (ironman_downward) {
3092 if (PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER)) {
3093 if (PlayerRace(player_ptr).equals(PlayerRaceType::SPECTRE)) {
3098 if ((player_ptr->ppersonality == PERSONALITY_MUNCHKIN) && point) {
3100 if (w_ptr->total_winner) {
3109 * @param player_ptr プレイヤーへの参照ポインタ
3110 * @return 祝福状態ならばTRUE
3112 bool is_blessed(PlayerType *player_ptr)
3114 return player_ptr->blessed || music_singing(player_ptr, MUSIC_BLESS) || SpellHex(player_ptr).is_spelling_specific(HEX_BLESS);
3117 bool is_tim_esp(PlayerType *player_ptr)
3119 auto sniper_data = PlayerClass(player_ptr).get_specific_data<sniper_data_type>();
3120 auto sniper_concent = sniper_data ? sniper_data->concent : 0;
3121 return player_ptr->tim_esp || music_singing(player_ptr, MUSIC_MIND) || (sniper_concent >= CONCENT_TELE_THRESHOLD);
3124 bool is_tim_stealth(PlayerType *player_ptr)
3126 return player_ptr->tim_stealth || music_singing(player_ptr, MUSIC_STEALTH);
3129 bool is_time_limit_esp(PlayerType *player_ptr)
3131 auto sniper_data = PlayerClass(player_ptr).get_specific_data<sniper_data_type>();
3132 auto sniper_concent = sniper_data ? sniper_data->concent : 0;
3133 return player_ptr->tim_esp || music_singing(player_ptr, MUSIC_MIND) || (sniper_concent >= CONCENT_TELE_THRESHOLD);
3136 bool is_time_limit_stealth(PlayerType *player_ptr)
3138 return player_ptr->tim_stealth || music_singing(player_ptr, MUSIC_STEALTH);
3142 * @brief 口を使う継続的な処理を中断する
3143 * @param player_ptr プレイヤーへの参照ポインタ
3145 void stop_mouth(PlayerType *player_ptr)
3147 if (music_singing_any(player_ptr)) {
3148 stop_singing(player_ptr);
3151 if (SpellHex(player_ptr).is_spelling_any()) {
3152 (void)SpellHex(player_ptr).stop_all_spells();
3156 bool is_fast(PlayerType *player_ptr)
3158 return player_ptr->effects()->acceleration()->is_fast() || music_singing(player_ptr, MUSIC_SPEED) || music_singing(player_ptr, MUSIC_SHERO);
3161 bool is_invuln(PlayerType *player_ptr)
3163 return player_ptr->invuln || music_singing(player_ptr, MUSIC_INVULN);
3166 bool is_hero(PlayerType *player_ptr)
3168 return player_ptr->hero || music_singing(player_ptr, MUSIC_HERO) || music_singing(player_ptr, MUSIC_SHERO);
3171 bool is_shero(PlayerType *player_ptr)
3173 return player_ptr->shero || PlayerClass(player_ptr).equals(PlayerClassType::BERSERKER);
3176 bool is_echizen(PlayerType *player_ptr)
3178 return (player_ptr->ppersonality == PERSONALITY_COMBAT) || (player_ptr->inventory_list[INVEN_BOW].fixed_artifact_idx == FixedArtifactId::CRIMSON);
3181 bool is_chargeman(PlayerType *player_ptr)
3183 return player_ptr->ppersonality == PERSONALITY_CHARGEMAN;
3186 WEIGHT calc_weapon_weight_limit(PlayerType *player_ptr)
3188 WEIGHT weight = adj_str_hold[player_ptr->stat_index[A_STR]];
3190 if (has_two_handed_weapons(player_ptr)) {
3197 WEIGHT calc_bow_weight_limit(PlayerType *player_ptr)
3199 WEIGHT weight = adj_str_hold[player_ptr->stat_index[A_STR]];
3204 static player_hand main_attack_hand(PlayerType *player_ptr)
3206 switch (player_melee_type(player_ptr)) {
3207 case MELEE_TYPE_BAREHAND_TWO:
3208 return PLAYER_HAND_MAIN;
3209 case MELEE_TYPE_BAREHAND_MAIN:
3210 return PLAYER_HAND_MAIN;
3211 case MELEE_TYPE_BAREHAND_SUB:
3212 return PLAYER_HAND_SUB;
3213 case MELEE_TYPE_WEAPON_MAIN:
3214 return PLAYER_HAND_MAIN;
3215 case MELEE_TYPE_WEAPON_SUB:
3216 return PLAYER_HAND_SUB;
3217 case MELEE_TYPE_WEAPON_TWOHAND:
3218 return has_melee_weapon(player_ptr, INVEN_MAIN_HAND) ? PLAYER_HAND_MAIN : PLAYER_HAND_SUB;
3219 case MELEE_TYPE_WEAPON_DOUBLE:
3220 return PLAYER_HAND_MAIN;
3221 case MELEE_TYPE_SHIELD_DOUBLE:
3222 return PLAYER_HAND_MAIN;
3224 return PLAYER_HAND_MAIN;
3227 bool set_quick_and_tiny(PlayerType *player_ptr)
3229 auto is_quickly_tiny = player_ptr->inventory_list[INVEN_MAIN_HAND].fixed_artifact_idx == FixedArtifactId::QUICKTHORN;
3230 is_quickly_tiny &= player_ptr->inventory_list[INVEN_SUB_HAND].fixed_artifact_idx == FixedArtifactId::TINYTHORN;
3231 return is_quickly_tiny;
3234 bool set_musasi(PlayerType *player_ptr)
3236 auto is_musasi = player_ptr->inventory_list[INVEN_MAIN_HAND].fixed_artifact_idx == FixedArtifactId::MUSASI_KATANA;
3237 is_musasi &= player_ptr->inventory_list[INVEN_SUB_HAND].fixed_artifact_idx == FixedArtifactId::MUSASI_WAKIZASI;
3241 bool set_icing_and_twinkle(PlayerType *player_ptr)
3243 auto can_call_ice_wind_saga = player_ptr->inventory_list[INVEN_MAIN_HAND].fixed_artifact_idx == FixedArtifactId::ICINGDEATH;
3244 can_call_ice_wind_saga &= player_ptr->inventory_list[INVEN_SUB_HAND].fixed_artifact_idx == FixedArtifactId::TWINKLE;
3245 return can_call_ice_wind_saga;
3248 bool set_anubis_and_chariot(PlayerType *player_ptr)
3250 auto is_anubis_chariot = player_ptr->inventory_list[INVEN_MAIN_HAND].fixed_artifact_idx == FixedArtifactId::ANUBIS;
3251 is_anubis_chariot &= player_ptr->inventory_list[INVEN_SUB_HAND].fixed_artifact_idx == FixedArtifactId::SILVER_CHARIOT;
3252 return is_anubis_chariot;