Exemple #1
0
// 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 ) );
}