void CAI_Stalker::Hit(SHit* pHDS) { //хит может меняться в зависимости от ранга (новички получают больше хита, чем ветераны) SHit HDS = *pHDS; HDS.add_wound = true; float hit_power = HDS.power * m_fRankImmunity; if(m_boneHitProtection && HDS.hit_type == ALife::eHitTypeFireWound) { float BoneArmor = m_boneHitProtection->getBoneArmor(HDS.bone()); float ap = HDS.armor_piercing; if(!fis_zero(BoneArmor, EPS)) { if(ap > BoneArmor) { float d_hit_power = (ap - BoneArmor) / ap; if(d_hit_power < m_boneHitProtection->m_fHitFracNpc) d_hit_power = m_boneHitProtection->m_fHitFracNpc; hit_power *= d_hit_power; VERIFY(hit_power>=0.0f); } else { hit_power *= m_boneHitProtection->m_fHitFracNpc; HDS.add_wound = false; } } if ( wounded() ) //уже лежит => добивание { hit_power = 1000.f; } } HDS.power = hit_power; if (g_Alive()) { bool already_critically_wounded = critically_wounded(); if (!already_critically_wounded) { const CCoverPoint *cover = agent_manager().member().member(this).cover(); if ( !invulnerable() && cover && HDS.initiator() && ( HDS.initiator()->ID() != ID() ) && !fis_zero( HDS.damage() ) && brain().affect_cover() ) { agent_manager().location().add( xr_new<CDangerCoverLocation>(cover,Device.dwTimeGlobal,DANGER_INTERVAL,DANGER_DISTANCE) ); } } const CEntityAlive *entity_alive = smart_cast<const CEntityAlive*>(HDS.initiator()); if (entity_alive && !wounded()) { if (is_relation_enemy(entity_alive)) sound().play (eStalkerSoundInjuring); // else // sound().play (eStalkerSoundInjuringByFriend); } int weapon_type = -1; if (best_weapon()) weapon_type = best_weapon()->object().ef_weapon_type(); if ( !wounded() && !already_critically_wounded) { bool became_critically_wounded = update_critical_wounded(HDS.boneID,HDS.power); if ( !became_critically_wounded && animation().script_animations().empty() && (HDS.bone() != BI_NONE) ) { Fvector D; float yaw, pitch; D.getHP (yaw,pitch); #pragma todo("Dima to Dima : forward-back bone impulse direction has been determined incorrectly!") float power_factor = m_power_fx_factor * HDS.damage() / 100.f; clamp (power_factor,0.f,1.f); //IKinematicsAnimated *tpKinematics = smart_cast<IKinematicsAnimated*>(Visual()); IKinematics *tpKinematics = smart_cast<IKinematics*>(Visual()); #ifdef DEBUG tpKinematics->LL_GetBoneInstance (HDS.bone()); if (HDS.bone() >= tpKinematics->LL_BoneCount()) { Msg ("tpKinematics has no bone_id %d",HDS.bone()); HDS._dump (); } #endif // int fx_index = iFloor(tpKinematics->LL_GetBoneInstance(HDS.bone()).get_param(1) + (angle_difference(movement().m_body.current.yaw,-yaw) <= PI_DIV_2 ? 0 : 1)); // if (fx_index != -1) // animation().play_fx (power_factor,fx_index); } else { if (!already_critically_wounded && became_critically_wounded) { if (HDS.who) { CAI_Stalker *stalker = smart_cast<CAI_Stalker*>(HDS.who); if ( stalker && stalker->g_Alive() ) stalker->on_critical_wound_initiator (this); } } } } } if ( g_Alive() && ( !m_hit_callback || m_hit_callback( &HDS ) ) ) { float const damage_factor = invulnerable() ? 0.f : 100.f; memory().hit().add ( damage_factor*HDS.damage(), HDS.direction(), HDS.who, HDS.boneID ); } //conditions().health() = 1.f; inherited::Hit ( &HDS ); }