// utility functions for projectile_attack double player::get_weapon_dispersion(item *weapon) { int weapon_skill_level = 0; if(weapon->is_gunmod()) { it_gunmod* firing = dynamic_cast<it_gunmod *>(weapon->type); weapon_skill_level = skillLevel(firing->skill_used); } else { it_gun* firing = dynamic_cast<it_gun *>(weapon->type); weapon_skill_level = skillLevel(firing->skill_used); } double dispersion = 0.; // Measured in quarter-degrees. // Up to 0.75 degrees for each skill point < 8. if (weapon_skill_level < 8) { dispersion += rng(0, 3 * (8 - weapon_skill_level)); } // Up to 0.25 deg per each skill point < 9. if (skillLevel("gun") < 9) { dispersion += rng(0, 9 - skillLevel("gun")); } dispersion += rng(0, ranged_dex_mod()); dispersion += rng(0, ranged_per_mod()); dispersion += rng(0, 2 * encumb(bp_arms)) + rng(0, 4 * encumb(bp_eyes)); dispersion += rng(0, weapon->curammo->dispersion); // item::dispersion() doesn't support gunmods. dispersion += rng(0, weapon->dispersion()); int adj_recoil = recoil + driving_recoil; dispersion += rng(int(adj_recoil / 4), adj_recoil); // this is what the total bonus USED to look like // rng(0,x) on each term in the sum // 3 * skill + skill + 2 * dex + 2 * per // - 2*p.encumb(bp_arms) - 4*p.encumb(bp_eyes) - 5/8 * recoil // old targeting bionic suddenly went from 0.8 to 0.65 when LONG_RANGE was // crossed, so increasing range by 1 would actually increase accuracy by a // lot. This is kind of a compromise if (has_bionic("bio_targeting")) dispersion *= 0.75; if ((is_underwater() && !weapon->has_flag("UNDERWATER_GUN")) || // Range is effectively four times longer when shooting unflagged guns underwater. (!is_underwater() && weapon->has_flag("UNDERWATER_GUN"))) { // Range is effectively four times longer when shooting flagged guns out of water. dispersion *= 4; } if (dispersion < 0) { return 0; } return dispersion; }
int Character::aim_per_time( const item& gun, int recoil ) const { int penalty = 0; // Range [0 - 10] after adjustment penalty += skill_dispersion( gun, false ) / 60; // Ranges [0 - 12] after adjustment penalty += ranged_dex_mod() / 15; // Range [0 - 10] penalty += gun.aim_speed( recoil ); // @todo consider character status effects // always improve by at least 1MOC penalty = std::max( 1, 32 - penalty ); // improvement capped by max aim level of the gun sight being used. return std::min( penalty, recoil - gun.sight_dispersion( recoil ) ); }