Пример #1
0
void shoot_monster(game *g, player &p, monster &mon, int &dam, double goodhit, item* weapon)
{
 // Gunmods don't have a type, so use the player weapon type.
 it_gun* firing = dynamic_cast<it_gun*>(p.weapon.type);
 std::string message;
 bool u_see_mon = g->u_see(&(mon));
 int adjusted_damage = dam;
 if (mon.has_flag(MF_HARDTOSHOOT) && !one_in(10 - 10 * (.8 - goodhit)) && // Maxes out at 50% chance with perfect hit
     weapon->curammo->phase != LIQUID && !weapon->curammo->ammo_effects.count("SHOT") &&
     !weapon->curammo->ammo_effects.count("BOUNCE")) {
  if (u_see_mon)
   g->add_msg(_("The shot passes through the %s without hitting."),
           mon.name().c_str());
  goodhit = 1;
 } else { // Not HARDTOSHOOT
// Armor blocks BEFORE any critical effects.
  int zarm = mon.armor_cut();
  zarm -= weapon->curammo->pierce;
  if (weapon->curammo->phase == LIQUID)
   zarm = 0;
  else if (weapon->curammo->ammo_effects.count("SHOT")) // Shot doesn't penetrate armor well
   zarm *= rng(2, 3);
  if (zarm > 0)
   adjusted_damage -= zarm;
  if (adjusted_damage <= 0) {
   if (u_see_mon)
    g->add_msg(_("The shot reflects off the %s!"),
            mon.name_with_armor().c_str());
   adjusted_damage = 0;
   goodhit = 1;
  }
  if (goodhit <= .1 && !mon.has_flag(MF_NOHEAD)) {
      message = _("Headshot!");
      adjusted_damage = rng(5 * adjusted_damage, 8 * adjusted_damage);
      p.practice(g->turn, firing->skill_used, 5);
  } else if (goodhit <= .2) {
      message = _("Critical!");
      adjusted_damage = rng(adjusted_damage * 2, adjusted_damage * 3);
      p.practice(g->turn, firing->skill_used, 3);
  } else if (goodhit <= .4) {
      message = _("Good hit!");
      adjusted_damage = rng(adjusted_damage , adjusted_damage * 2);
      p.practice(g->turn, firing->skill_used, 2);
  } else if (goodhit <= .6) {
      adjusted_damage = rng(adjusted_damage / 2, adjusted_damage);
      p.practice(g->turn, firing->skill_used, 1);
  } else if (goodhit <= .8) {
      message = _("Grazing hit.");
      adjusted_damage = rng(0, adjusted_damage);
  } else {
      adjusted_damage = 0;
  }

  if(item(weapon->curammo, 0).has_flag("NOGIB"))
  {
      adjusted_damage = std::min(adjusted_damage, mon.hp+10);
  }

// Find the zombie at (x, y) and hurt them, MAYBE kill them!
    if (adjusted_damage > 0) {
        switch (mon.type->size) {
            case MS_TINY:
                mon.moves -= rng(0, adjusted_damage * 5);
                break;
            case MS_SMALL:
                mon.moves -= rng(0, adjusted_damage * 3);
                break;
            case MS_MEDIUM:
                mon.moves -= rng(0, adjusted_damage);
                break;
            case MS_LARGE:
                mon.moves -= rng(0, adjusted_damage / 3);
                break;
            case MS_HUGE:
                mon.moves -= rng(0, adjusted_damage / 5);
                break;
        }
        if (&p == &(g->u) && u_see_mon) {
            g->add_msg(_("%s You hit the %s for %d damage."), message.c_str(), mon.name().c_str(), adjusted_damage);
        } else if (u_see_mon) {
            g->add_msg(_("%s %s shoots the %s."), message.c_str(), p.name.c_str(), mon.name().c_str());
        }
        bool bMonDead = mon.hurt(adjusted_damage, dam);
        if( u_see_mon ) {
            hit_animation(mon.posx - g->u.posx + VIEWX - g->u.view_offset_x,
                     mon.posy - g->u.posy + VIEWY - g->u.view_offset_y,
                     red_background(mon.type->color), (bMonDead) ? '%' : mon.symbol());
        }

        if (bMonDead) {
            g->kill_mon(g->mon_at(mon.posx, mon.posy), (&p == &(g->u)));
        } else if (!weapon->curammo->ammo_effects.empty()) {
            g->hit_monster_with_flags(mon, weapon->curammo->ammo_effects);
        }
        adjusted_damage = 0;
    }
 }
 dam = adjusted_damage;
}
Пример #2
0
void shoot_monster(game *g, player &p, monster &mon, int &dam, double goodhit, item* weapon)
{
 // Gunmods don't have a type, so use the player weapon type.
 it_gun* firing = dynamic_cast<it_gun*>(p.weapon.type);
 std::string message;
 bool u_see_mon = g->u_see(&(mon));
 if (mon.has_flag(MF_HARDTOSHOOT) && !one_in(4) &&
     weapon->curammo->phase != LIQUID &&
     weapon->curammo->accuracy >= 4) { // Buckshot hits anyway
  if (u_see_mon)
   g->add_msg("The shot passes through the %s without hitting.",
           mon.name().c_str());
  goodhit = 1;
 } else { // Not HARDTOSHOOT
// Armor blocks BEFORE any critical effects.
  int zarm = mon.armor_cut();
  zarm -= weapon->curammo->pierce;
  if (weapon->curammo->phase == LIQUID)
   zarm = 0;
  else if (weapon->curammo->accuracy < 4) // Shot doesn't penetrate armor well
   zarm *= rng(2, 4);
  if (zarm > 0)
   dam -= zarm;
  if (dam <= 0) {
   if (u_see_mon)
    g->add_msg("The shot reflects off the %s!",
            mon.name_with_armor().c_str());
   dam = 0;
   goodhit = 1;
  }
  if (goodhit < .1 && !mon.has_flag(MF_NOHEAD)) {
   message = "Headshot!";
   dam = rng(5 * dam, 8 * dam);
   p.practice(g->turn, firing->skill_used, 5);
  } else if (goodhit < .2) {
   message = "Critical!";
   dam = rng(dam * 2, dam * 3);
   p.practice(g->turn, firing->skill_used, 2);
  } else if (goodhit < .4) {
   dam = rng(int(dam * .9), int(dam * 1.5));
   p.practice(g->turn, firing->skill_used, rng(0, 2));
  } else if (goodhit <= .7) {
   message = "Grazing hit.";
   dam = rng(0, dam);
  } else
   dam = 0;
// Find the zombie at (x, y) and hurt them, MAYBE kill them!
  if (dam > 0) {
   mon.moves -= dam * 5;
   if (&p == &(g->u) && u_see_mon)
    g->add_msg("%s You hit the %s for %d damage.", message.c_str(), mon.name().c_str(), dam);
   else if (u_see_mon)
    g->add_msg("%s %s shoots the %s.", message.c_str(), p.name.c_str(), mon.name().c_str());

   bool bMonDead = mon.hurt(dam);
   hit_animation(mon.posx - g->u.posx + VIEWX - g->u.view_offset_x,
                 mon.posy - g->u.posy + VIEWY - g->u.view_offset_y,
                 red_background(mon.type->color), (bMonDead) ? '%' : mon.symbol());

   if (bMonDead)
    g->kill_mon(g->mon_at(mon.posx, mon.posy), (&p == &(g->u)));
   else if (weapon->curammo->ammo_effects != 0)
    g->hit_monster_with_flags(mon, weapon->curammo->ammo_effects);

   dam = 0;
  }
 }
}
Пример #3
0
void shoot_monster(player &p, monster &mon, int &dam, double goodhit,
                   item* weapon, const std::set<std::string> &effects)
{
// Gunmods don't have a type, so use the player weapon type.
    it_gun* firing = dynamic_cast<it_gun*>(p.weapon.type);
    std::string message;
    bool u_see_mon = g->u_see(&(mon));
    int adjusted_damage = dam;
    if (mon.has_flag(MF_HARDTOSHOOT) && !one_in(10 - 10 * (.8 - goodhit)) && // Maxes out at 50% chance with perfect hit
    weapon->curammo->phase != LIQUID && !effects.count("SHOT") && !effects.count("BOUNCE")) {
        if (u_see_mon)
            g->add_msg(_("The shot passes through the %s without hitting."),
            mon.name().c_str());
    } else { // Not HARDTOSHOOT
        // Bounce applies whether it does damage or not.
        if (effects.count("BOUNCE")) {
            mon.add_effect("bounced", 1);
        }
        // Armor blocks BEFORE any critical effects.
        int zarm = mon.get_armor_cut(bp_torso);
        zarm -= weapon->gun_pierce();
        if (weapon->curammo->phase == LIQUID)
            zarm = 0;
        else if (effects.count("SHOT")) // Shot doesn't penetrate armor well
            zarm *= rng(2, 3);
        if (zarm > 0)
            adjusted_damage -= zarm;
        if (adjusted_damage <= 0) {
            if (u_see_mon)
                g->add_msg(_("The shot reflects off the %s!"),
                mon.name_with_armor().c_str());
            adjusted_damage = 0;
            goodhit = 1;
        }
        if (goodhit <= .1 && !mon.has_flag(MF_NOHEAD)) {
            message = _("Headshot!");
            adjusted_damage = rng(5 * adjusted_damage, 8 * adjusted_damage);
            p.practice(g->turn, firing->skill_used, 5);
            p.lifetime_stats()->headshots++;
        } else if (goodhit <= .2) {
            message = _("Critical!");
            adjusted_damage = rng(adjusted_damage * 2, adjusted_damage * 3);
            p.practice(g->turn, firing->skill_used, 3);
        } else if (goodhit <= .4) {
            message = _("Good hit!");
            adjusted_damage = rng(adjusted_damage , adjusted_damage * 2);
            p.practice(g->turn, firing->skill_used, 2);
        } else if (goodhit <= .6) {
            adjusted_damage = rng(adjusted_damage / 2, adjusted_damage);
            p.practice(g->turn, firing->skill_used, 1);
        } else if (goodhit <= .8) {
            message = _("Grazing hit.");
            adjusted_damage = rng(0, adjusted_damage);
        } else {
            adjusted_damage = 0;
        }

        if(item(weapon->curammo, 0).has_flag("NOGIB"))
        {
            adjusted_damage = std::min(adjusted_damage, mon.hp+10);
        }

// Find the zombie at (x, y) and hurt them, MAYBE kill them!
        if (adjusted_damage > 0) {
            switch (mon.type->size) {
            case MS_TINY:
                mon.moves -= rng(0, adjusted_damage * 5);
                break;
            case MS_SMALL:
                mon.moves -= rng(0, adjusted_damage * 3);
                break;
            case MS_MEDIUM:
                mon.moves -= rng(0, adjusted_damage);
                break;
            case MS_LARGE:
                mon.moves -= rng(0, adjusted_damage / 3);
                break;
            case MS_HUGE:
                mon.moves -= rng(0, adjusted_damage / 5);
                break;
            }

            if (&p == &(g->u) && u_see_mon) {
                g->add_msg(_("%s You hit the %s for %d damage."), message.c_str(), mon.name().c_str(), adjusted_damage);
            } else if (u_see_mon) {
                g->add_msg(_("%s %s shoots the %s."), message.c_str(), p.name.c_str(), mon.name().c_str());
            }
            g->hit_monster_with_flags(mon, effects);
            damage_instance d;
            d.add_damage(DT_CUT, adjusted_damage, weapon->gun_pierce(),
                    effects.count("SHOT")?rng(2,3):1); // Shot doesn't penetrate armor well
            mon.deal_damage(&p, bp_torso, -1, d);
            if( u_see_mon ) {
                g->draw_hit_mon(mon.posx(), mon.posy(), mon, mon.is_dead_state());
            }
        }
    }
    dam = adjusted_damage;
}