void bite_actor::on_damage( monster &z, Creature &target, dealt_damage_instance &dealt ) const { melee_actor::on_damage( z, target, dealt ); if( one_in( no_infection_chance - dealt.total_damage() ) ) { const body_part hit = dealt.bp_hit; if( target.has_effect( effect_bite, hit ) ) { target.add_effect( effect_bite, 400, hit, true ); } else if( target.has_effect( effect_infected, hit ) ) { target.add_effect( effect_infected, 250, hit, true ); } else { target.add_effect( effect_bite, 1, hit, true ); } } }
void bite_actor::on_damage( monster &z, Creature &target, dealt_damage_instance &dealt ) const { melee_actor::on_damage( z, target, dealt ); if( target.has_effect( effect_grabbed ) && one_in( no_infection_chance - dealt.total_damage() ) ) { const body_part hit = dealt.bp_hit; if( target.has_effect( effect_bite, hit ) ) { target.add_effect( effect_bite, 40_minutes, hit, true ); } else if( target.has_effect( effect_infected, hit ) ) { target.add_effect( effect_infected, 25_minutes, hit, true ); } else { target.add_effect( effect_bite, 1_turns, hit, true ); } } if( target.has_trait( trait_id( "TOXICFLESH" ) ) ) { z.add_effect( effect_poison, 5_minutes ); z.add_effect( effect_badpoison, 5_minutes ); } }
int Creature::deal_projectile_attack(Creature *source, double missed_by, const projectile &proj, dealt_damage_instance &dealt_dam) { bool u_see_this = g->u_see(this); body_part bp_hit; int side = rng(0, 1); // do 10,speed because speed could potentially be > 10000 if (dodge_roll() >= dice(10, proj.speed)) { if (is_player()) g->add_msg(_("You dodge %s's projectile!"), skin_name().c_str()); else if (u_see_this) g->add_msg(_("%s dodges %s's projectile."), disp_name().c_str(), source->disp_name().c_str()); return 0; } double hit_value = missed_by + rng_float(-0.5, 0.5); // headshots considered elsewhere if (hit_value <= 0.4) { bp_hit = bp_torso; } else if (one_in(4)) { bp_hit = bp_legs; } else { bp_hit = bp_arms; } double monster_speed_penalty = std::max(double(get_speed()) / 80., 1.0); double goodhit = missed_by / monster_speed_penalty; double damage_mult = 1.0; if (goodhit <= .1) { g->add_msg_if_player(source, _("Headshot!")); damage_mult *= rng_float(5, 8); bp_hit = bp_head; // headshot hits the head, of course } else if (goodhit <= .2) { g->add_msg_if_player(source, _("Critical!")); damage_mult *= rng_float(2, 3); } else if (goodhit <= .4) { g->add_msg_if_player(source, _("Good hit!")); damage_mult *= rng_float(1, 2); } else if (goodhit <= .6) { damage_mult *= rng_float(0.5, 1); } else if (goodhit <= .8) { g->add_msg_if_player(source, _("Grazing hit.")); damage_mult *= rng_float(0, 1); } else { damage_mult *= 0; } // copy it, since we're mutating damage_instance impact = proj.impact; impact.mult_damage(damage_mult); dealt_dam = deal_damage(source, bp_hit, side, impact); dealt_dam.bp_hit = bp_hit; if(u_see_this) { if (damage_mult == 0) { if(source != NULL) { g->add_msg(source->is_player() ? _("You miss!") : _("The shot misses!")); } } else if (dealt_dam.total_damage() == 0) { g->add_msg(_("The shot reflects off the %s!"), skin_name().c_str()); } else if (source != NULL) { if (source->is_player()) { g->add_msg(_("You hit the %s for %d damage."), disp_name().c_str(), dealt_dam.total_damage()); } else if (u_see_this) { g->add_msg(_("%s shoots %s."), source->disp_name().c_str(), disp_name().c_str()); } } } return 0; }
int Creature::deal_projectile_attack(Creature *source, double missed_by, const projectile &proj, dealt_damage_instance &dealt_dam) { bool u_see_this = g->u_see(this); body_part bp_hit; int side = rng(0, 1); // do 10,speed because speed could potentially be > 10000 if (dodge_roll() >= dice(10, proj.speed)) { if (is_player()) add_msg(_("You dodge %s projectile!"), source->disp_name(true).c_str()); else if (u_see_this) add_msg(_("%s dodges %s projectile."), disp_name().c_str(), source->disp_name(true).c_str()); return 0; } // Bounce applies whether it does damage or not. if (proj.proj_effects.count("BOUNCE")) { add_effect("bounced", 1); } double hit_value = missed_by + rng_float(-0.5, 0.5); // headshots considered elsewhere if (hit_value <= 0.4) { bp_hit = bp_torso; } else if (one_in(4)) { bp_hit = bp_legs; } else { bp_hit = bp_arms; } double monster_speed_penalty = std::max(double(get_speed()) / 80., 1.0); double goodhit = missed_by / monster_speed_penalty; double damage_mult = 1.0; std::string message = ""; game_message_type gmtSCTcolor = m_neutral; if (goodhit <= .1) { message = _("Headshot!"); source->add_msg_if_player(m_good, message.c_str()); gmtSCTcolor = m_headshot; damage_mult *= rng_float(2.45, 3.35); bp_hit = bp_head; // headshot hits the head, of course } else if (goodhit <= .2) { message = _("Critical!"); source->add_msg_if_player(m_good, message.c_str()); gmtSCTcolor = m_critical; damage_mult *= rng_float(1.75, 2.3); } else if (goodhit <= .4) { message = _("Good hit!"); source->add_msg_if_player(m_good, message.c_str()); gmtSCTcolor = m_good; damage_mult *= rng_float(1, 1.5); } else if (goodhit <= .6) { damage_mult *= rng_float(0.5, 1); } else if (goodhit <= .8) { message = _("Grazing hit."); source->add_msg_if_player(m_good, message.c_str()); gmtSCTcolor = m_grazing; damage_mult *= rng_float(0, .25); } else { damage_mult *= 0; } // copy it, since we're mutating damage_instance impact = proj.impact; if( item(proj.ammo->id, 0).has_flag("NOGIB") ) { impact.add_effect("NOGIB"); } impact.mult_damage(damage_mult); dealt_dam = deal_damage(source, bp_hit, side, impact); dealt_dam.bp_hit = bp_hit; // Apply ammo effects to target. const std::string target_material = get_material(); if (proj.proj_effects.count("FLAME")) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood" ) ) { add_effect("onfire", rng(8, 20)); } else if (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) { add_effect("onfire", rng(5, 10)); } } else if (proj.proj_effects.count("INCENDIARY") ) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood") ) { add_effect("onfire", rng(2, 6)); } else if ( (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) && one_in(4) ) { add_effect("onfire", rng(1, 4)); } } else if (proj.proj_effects.count("IGNITE")) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood") ) { add_effect("onfire", rng(6, 6)); } else if (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) { add_effect("onfire", rng(10, 10)); } } int stun_strength = 0; if (proj.proj_effects.count("BEANBAG")) { stun_strength = 4; } if(proj.proj_effects.count("WHIP")) { stun_strength = rng(4, 10); } if (proj.proj_effects.count("LARGE_BEANBAG")) { stun_strength = 16; } if( stun_strength > 0 ) { switch( get_size() ) { case MS_TINY: stun_strength *= 4; break; case MS_SMALL: stun_strength *= 2; break; case MS_MEDIUM: default: break; case MS_LARGE: stun_strength /= 2; break; case MS_HUGE: stun_strength /= 4; break; } add_effect( "stunned", rng(stun_strength / 2, stun_strength) ); } if(u_see_this) { if (damage_mult == 0) { if(source != NULL) { add_msg(source->is_player() ? _("You miss!") : _("The shot misses!")); } } else if (dealt_dam.total_damage() == 0) { add_msg(_("The shot reflects off %s %s!"), disp_name(true).c_str(), skin_name().c_str()); } else if (source != NULL) { if (source->is_player()) { //player hits monster ranged nc_color color; std::string health_bar = ""; get_HP_Bar(dealt_dam.total_damage(), this->get_hp_max(), color, health_bar, true); SCT.add(this->xpos(), this->ypos(), direction_from(0, 0, this->xpos() - source->xpos(), this->ypos() - source->ypos()), health_bar, m_good, message, gmtSCTcolor); if (this->get_hp() > 0) { get_HP_Bar(this->get_hp(), this->get_hp_max(), color, health_bar, true); SCT.add(this->xpos(), this->ypos(), direction_from(0, 0, this->xpos() - source->xpos(), this->ypos() - source->ypos()), health_bar, m_good, "hp", m_neutral, "hp"); } else { SCT.removeCreatureHP(); } add_msg(m_good, _("You hit the %s for %d damage."), disp_name().c_str(), dealt_dam.total_damage()); } else if(this->is_player()) { //monster hits player ranged add_msg_if_player( m_bad, _( "You were hit in the %s for %d damage." ), body_part_name( bp_hit, side ).c_str( ), dealt_dam.total_damage( ) ); } else if( u_see_this ) { add_msg(_("%s shoots %s."), source->disp_name().c_str(), disp_name().c_str()); } } } return 0; }