X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fcombat%2Fshoot.cpp;h=eedd564ad949c2576b1e6ee875dc5120bb032ff9;hb=b1cd34b06beceec44e506cfd9d83ed64fe12fea0;hp=3996a7c83f8a7e3bec23d3c1c7e2e77e2fae230e;hpb=227bc980e5e9e2dca14e2a37fee38620f6eef087;p=hengbandforosx%2Fhengbandosx.git diff --git a/src/combat/shoot.cpp b/src/combat/shoot.cpp index 3996a7c83..eedd564ad 100644 --- a/src/combat/shoot.cpp +++ b/src/combat/shoot.cpp @@ -46,7 +46,9 @@ #include "object/object-info.h" #include "object/object-kind.h" #include "object/object-mark-types.h" +#include "player-base/player-class.h" #include "player-info/class-info.h" +#include "player-info/sniper-data-type.h" #include "player-status/player-energy.h" #include "player/player-personality-types.h" #include "player/player-skill.h" @@ -91,9 +93,9 @@ static MULTIPLY calc_shot_damage_with_slay( /* Some "weapons" and "ammo" do extra damage */ switch (arrow_ptr->tval) { - case TV_SHOT: - case TV_ARROW: - case TV_BOLT: { + case ItemKindType::SHOT: + case ItemKindType::ARROW: + case ItemKindType::BOLT: { if ((flags.has(TR_SLAY_ANIMAL)) && any_bits(race_ptr->flags3, RF3_ANIMAL)) { if (is_original_ap_and_seen(player_ptr, monster_ptr)) { set_bits(race_ptr->r_flags3, RF3_ANIMAL); @@ -399,8 +401,6 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S uint16_t path_g[512]; /* For calcuration of path length */ - int msec = delay_factor * delay_factor * delay_factor; - /* STICK TO */ bool stick_to = false; @@ -429,9 +429,9 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S /* Actually "fire" the object */ bonus = (player_ptr->to_h_b + o_ptr->to_h + j_ptr->to_h); if ((j_ptr->sval == SV_LIGHT_XBOW) || (j_ptr->sval == SV_HEAVY_XBOW)) - chance = (player_ptr->skill_thb + (player_ptr->weapon_exp[0][j_ptr->sval] / 400 + bonus) * BTH_PLUS_ADJ); + chance = (player_ptr->skill_thb + (player_ptr->weapon_exp[j_ptr->tval][j_ptr->sval] / 400 + bonus) * BTH_PLUS_ADJ); else - chance = (player_ptr->skill_thb + ((player_ptr->weapon_exp[0][j_ptr->sval] - (WEAPON_EXP_MASTER / 2)) / 200 + bonus) * BTH_PLUS_ADJ); + chance = (player_ptr->skill_thb + ((player_ptr->weapon_exp[j_ptr->tval][j_ptr->sval] - (PlayerSkill::weapon_exp_at(EXP_LEVEL_MASTER) / 2)) / 200 + bonus) * BTH_PLUS_ADJ); PlayerEnergy(player_ptr).set_player_turn_energy(bow_energy(j_ptr->sval)); tmul = bow_tmul(j_ptr->sval); @@ -446,13 +446,13 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S tdam_base *= tmul; tdam_base /= 100; + auto sniper_data = PlayerClass(player_ptr).get_specific_data(); + auto sniper_concent = sniper_data ? sniper_data->concent : 0; + /* Base range */ tdis = 13 + tmul / 80; if ((j_ptr->sval == SV_LIGHT_XBOW) || (j_ptr->sval == SV_HEAVY_XBOW)) { - if (player_ptr->concent) - tdis -= (5 - (player_ptr->concent + 1) / 2); - else - tdis -= 5; + tdis -= (5 - (sniper_concent + 1) / 2); } project_length = tdis + 1; @@ -502,7 +502,7 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S /* Sniper - Difficult to shot twice at 1 turn */ if (snipe_type == SP_DOUBLE) - player_ptr->concent = (player_ptr->concent + 1) / 2; + sniper_concent = (sniper_concent + 1) / 2; /* Sniper - Repeat shooting when double shots */ for (i = 0; i < ((snipe_type == SP_DOUBLE) ? 2 : 1); i++) { @@ -578,11 +578,11 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S byte a = object_attr(q_ptr); /* Draw, Hilite, Fresh, Pause, Erase */ - if (msec > 0) { + if (delay_factor > 0) { print_rel(player_ptr, c, a, ny, nx); move_cursor_relative(ny, nx); term_fresh(); - term_xtra(TERM_XTRA_DELAY, msec); + term_xtra(TERM_XTRA_DELAY, delay_factor); lite_spot(player_ptr, ny, nx); term_fresh(); } @@ -591,8 +591,8 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S /* The player cannot see the missile */ else { /* Pause anyway, for consistancy **/ - if (msec > 0) { - term_xtra(TERM_XTRA_DELAY, msec); + if (delay_factor > 0) { + term_xtra(TERM_XTRA_DELAY, delay_factor); } } @@ -637,30 +637,11 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S } if ((r_ptr->level + 10) > player_ptr->lev) { - int now_exp = player_ptr->weapon_exp[0][j_ptr->sval]; - if (now_exp < s_info[player_ptr->pclass].w_max[0][j_ptr->sval]) { - SUB_EXP amount = 0; - if (now_exp < WEAPON_EXP_BEGINNER) - amount = 80; - else if (now_exp < WEAPON_EXP_SKILLED) - amount = 25; - else if ((now_exp < WEAPON_EXP_EXPERT) && (player_ptr->lev > 19)) - amount = 10; - else if (player_ptr->lev > 34) - amount = 2; - player_ptr->weapon_exp[0][j_ptr->sval] += amount; - set_bits(player_ptr->update, PU_BONUS); - } + PlayerSkill(player_ptr).gain_range_weapon_exp(j_ptr); } if (player_ptr->riding) { - if ((player_ptr->skill_exp[SKILL_RIDING] < s_info[player_ptr->pclass].s_max[SKILL_RIDING]) - && ((player_ptr->skill_exp[SKILL_RIDING] - (RIDING_EXP_BEGINNER * 2)) / 200 - < r_info[player_ptr->current_floor_ptr->m_list[player_ptr->riding].r_idx].level) - && one_in_(2)) { - player_ptr->skill_exp[SKILL_RIDING] += 1; - set_bits(player_ptr->update, PU_BONUS); - } + PlayerSkill(player_ptr).gain_riding_skill_exp_on_range_attack(); } /* Did we hit it (penalize range) */ @@ -670,8 +651,7 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S auto base_dam = tdam; //!< @note 補正前の与えるダメージ(無傷、全ての耐性など) /* Get extra damage from concentration */ - if (player_ptr->concent) - tdam = boost_concentration_damage(player_ptr, tdam); + tdam = boost_concentration_damage(player_ptr, tdam); /* Handle unseen monster */ if (!visible) { @@ -696,7 +676,7 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S } if (snipe_type == SP_NEEDLE) { - if ((randint1(randint1(r_ptr->level / (3 + player_ptr->concent)) + (8 - player_ptr->concent)) == 1) + if ((randint1(randint1(r_ptr->level / (3 + sniper_concent)) + (8 - sniper_concent)) == 1) && none_bits(r_ptr->flags1, RF1_UNIQUE) && none_bits(r_ptr->flags7, RF7_UNIQUE2)) { GAME_TEXT m_name[MAX_NLEN]; @@ -732,7 +712,7 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S uint16_t flg = (PROJECT_STOP | PROJECT_JUMP | PROJECT_KILL | PROJECT_GRID); sound(SOUND_EXPLODE); /* No explode sound - use breath fire instead */ - project(player_ptr, 0, ((player_ptr->concent + 1) / 2 + 1), ny, nx, base_dam, GF_MISSILE, flg); + project(player_ptr, 0, ((sniper_concent + 1) / 2 + 1), ny, nx, base_dam, GF_MISSILE, flg); break; } @@ -752,7 +732,7 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S /* No death */ else { /* STICK TO */ - if (q_ptr->is_fixed_artifact() && (player_ptr->pclass != CLASS_SNIPER || player_ptr->concent == 0)) { + if (q_ptr->is_fixed_artifact() && (sniper_concent == 0)) { GAME_TEXT m_name[MAX_NLEN]; monster_desc(player_ptr, m_name, m_ptr, 0); @@ -811,11 +791,11 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S update_monster(player_ptr, m_idx, true); - if (msec > 0) { + if (delay_factor > 0) { lite_spot(player_ptr, ny, nx); lite_spot(player_ptr, oy, ox); term_fresh(); - term_xtra(TERM_XTRA_DELAY, msec); + term_xtra(TERM_XTRA_DELAY, delay_factor); } x = nx; @@ -828,10 +808,8 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S } /* Sniper */ - if (snipe_type == SP_PIERCE) { - if (player_ptr->concent < 1) - break; - player_ptr->concent--; + if (snipe_type == SP_PIERCE && sniper_concent > 0) { + sniper_concent--; continue; } @@ -841,7 +819,7 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S } /* Chance of breakage (during attacks) */ - j = (hit_body ? breakage_chance(player_ptr, q_ptr, player_ptr->pclass == CLASS_ARCHER, snipe_type) : 0); + j = (hit_body ? breakage_chance(player_ptr, q_ptr, player_ptr->pclass == PlayerClassType::ARCHER, snipe_type) : 0); if (stick_to) { MONSTER_IDX m_idx = player_ptr->current_floor_ptr->grid_array[y][x].m_idx; @@ -882,8 +860,7 @@ void exe_fire(player_type *player_ptr, INVENTORY_IDX item, object_type *j_ptr, S } /* Sniper - Loose his/her concentration after any shot */ - if (player_ptr->concent) - reset_concentration(player_ptr, false); + reset_concentration(player_ptr, false); } /*! @@ -905,8 +882,11 @@ bool test_hit_fire(player_type *player_ptr, int chance, monster_type *m_ptr, int /* Percentile dice */ k = randint1(100); + auto sniper_data = PlayerClass(player_ptr).get_specific_data(); + auto sniper_concent = sniper_data ? sniper_data->concent : 0; + /* Snipers with high-concentration reduce instant miss percentage.*/ - k += player_ptr->concent; + k += sniper_concent; /* Hack -- Instant miss or hit */ if (k <= 5) @@ -914,7 +894,7 @@ bool test_hit_fire(player_type *player_ptr, int chance, monster_type *m_ptr, int if (k > 95) return true; - if (player_ptr->pseikaku == PERSONALITY_LAZY) + if (player_ptr->ppersonality == PERSONALITY_LAZY) if (one_in_(20)) return false; @@ -923,10 +903,7 @@ bool test_hit_fire(player_type *player_ptr, int chance, monster_type *m_ptr, int return false; ac = r_ptr->ac; - if (player_ptr->concent) { - ac *= (8 - player_ptr->concent); - ac /= 8; - } + ac = ac * (8 - sniper_concent) / 8; if (m_ptr->r_idx == MON_GOEMON && !monster_csleep_remaining(m_ptr)) ac *= 3; @@ -966,19 +943,21 @@ HIT_POINT critical_shot(player_type *player_ptr, WEIGHT weight, int plus_ammo, i /* Extract "shot" power */ i = player_ptr->to_h_b + plus_ammo; - if (player_ptr->tval_ammo == TV_BOLT) - i = (player_ptr->skill_thb + (player_ptr->weapon_exp[0][j_ptr->sval] / 400 + i) * BTH_PLUS_ADJ); + if (player_ptr->tval_ammo == ItemKindType::BOLT) + i = (player_ptr->skill_thb + (player_ptr->weapon_exp[j_ptr->tval][j_ptr->sval] / 400 + i) * BTH_PLUS_ADJ); else - i = (player_ptr->skill_thb + ((player_ptr->weapon_exp[0][j_ptr->sval] - (WEAPON_EXP_MASTER / 2)) / 200 + i) * BTH_PLUS_ADJ); + i = (player_ptr->skill_thb + ((player_ptr->weapon_exp[j_ptr->tval][j_ptr->sval] - (PlayerSkill::weapon_exp_at(EXP_LEVEL_MASTER) / 2)) / 200 + i) * BTH_PLUS_ADJ); + + auto sniper_data = PlayerClass(player_ptr).get_specific_data(); + auto sniper_concent = sniper_data ? sniper_data->concent : 0; /* Snipers can shot more critically with crossbows */ - if (player_ptr->concent) - i += ((i * player_ptr->concent) / 5); - if ((player_ptr->pclass == CLASS_SNIPER) && (player_ptr->tval_ammo == TV_BOLT)) + i += ((i * sniper_concent) / 5); + if ((player_ptr->pclass == PlayerClassType::SNIPER) && (player_ptr->tval_ammo == ItemKindType::BOLT)) i *= 2; /* Good bow makes more critical */ - i += plus_bow * 8 * (player_ptr->concent ? player_ptr->concent + 5 : 5); + i += plus_bow * 8 * (sniper_concent + 5); /* Critical hit */ if (randint1(10000) <= i) { @@ -1115,19 +1094,21 @@ HIT_POINT calc_crit_ratio_shot(player_type *player_ptr, HIT_POINT plus_ammo, HIT /* Extract "shot" power */ i = player_ptr->to_h_b + plus_ammo; - if (player_ptr->tval_ammo == TV_BOLT) - i = (player_ptr->skill_thb + (player_ptr->weapon_exp[0][j_ptr->sval] / 400 + i) * BTH_PLUS_ADJ); + if (player_ptr->tval_ammo == ItemKindType::BOLT) + i = (player_ptr->skill_thb + (player_ptr->weapon_exp[j_ptr->tval][j_ptr->sval] / 400 + i) * BTH_PLUS_ADJ); else - i = (player_ptr->skill_thb + ((player_ptr->weapon_exp[0][j_ptr->sval] - (WEAPON_EXP_MASTER / 2)) / 200 + i) * BTH_PLUS_ADJ); + i = (player_ptr->skill_thb + ((player_ptr->weapon_exp[j_ptr->tval][j_ptr->sval] - (PlayerSkill::weapon_exp_at(EXP_LEVEL_MASTER) / 2)) / 200 + i) * BTH_PLUS_ADJ); + + auto sniper_data = PlayerClass(player_ptr).get_specific_data(); + auto sniper_concent = sniper_data ? sniper_data->concent : 0; /* Snipers can shot more critically with crossbows */ - if (player_ptr->concent) - i += ((i * player_ptr->concent) / 5); - if ((player_ptr->pclass == CLASS_SNIPER) && (player_ptr->tval_ammo == TV_BOLT)) + i += ((i * sniper_concent) / 5); + if ((player_ptr->pclass == PlayerClassType::SNIPER) && (player_ptr->tval_ammo == ItemKindType::BOLT)) i *= 2; /* Good bow makes more critical */ - i += plus_bow * 8 * (player_ptr->concent ? player_ptr->concent + 5 : 5); + i += plus_bow * 8 * (sniper_concent + 5); if (i < 0) i = 0; @@ -1152,11 +1133,11 @@ HIT_POINT calc_expect_crit_shot(player_type *player_ptr, WEIGHT weight, int plus k = 0; num = 0; - crit = MIN(500, 900 / weight); + crit = std::min(500, 900 / weight); num += dam * 3 / 2 * crit; k = crit; - crit = MIN(500, 1350 / weight); + crit = std::min(500, 1350 / weight); crit -= k; num += dam * 2 * crit; k += crit; @@ -1216,7 +1197,7 @@ HIT_POINT calc_expect_crit(player_type *player_ptr, WEIGHT weight, int plus, HIT num += calc_weight_expect_dam(dam, weight); } - int pow = (player_ptr->pclass == CLASS_NINJA) ? 4444 : 5000; + int pow = (player_ptr->pclass == PlayerClassType::NINJA) ? 4444 : 5000; if (impact) pow /= 2;