Beispiel #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));
 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;
  }
 }
}
Beispiel #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));
 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;
}