bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const { if( H.initiator() != Level().CurrentControlEntity()) return false; if(H.type() == ALife::eHitTypeExplosion) { edirection dr = dir( ea, H, angle ); m = motion( dr ); type_motion_diagnostic( "type_motion6: 7. √ранта", dr, ea, H, m ); return true; } CObject* O = Level().Objects.net_Find( H.weaponID ); if(!O) { m = MotionID(); return false; } if( smart_cast<CExplosive*>( O ) != 0 ) { edirection dr = dir( ea, H, angle ); m = motion( dr ); type_motion_diagnostic( "type_motion6: 7. √ранта - осколок", dr, ea, H, m ); return true; } return false; }
bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const { m = MotionID(); if( H.initiator() != Level().CurrentControlEntity()) return false; VERIFY( ea.Visual( ) ); IKinematics *K = ea.Visual()->dcast_PKinematics(); VERIFY( K ); if( !is_bone_head( *K, H.bone() )) return false; //CAI_Stalker* s = ea.cast_stalker (); CCharacterPhysicsSupport* chs = ea.character_physics_support(); if( !chs || chs->Type( ) == CCharacterPhysicsSupport::etBitting ) return false; VERIFY( chs->movement() ); const Fvector stalker_velocity = chs->movement()->GetVelocity(); const float stalker_speed = stalker_velocity.magnitude(); const float min_stalker_speed = 3.65f; if(stalker_speed < min_stalker_speed ) return false; const Fvector stalker_velocity_dir = Fvector().mul( stalker_velocity, 1.f/stalker_speed ); const Fvector dir_to_actor = Fvector().sub( H.initiator()->Position(), ea.Position() ).normalize_safe(); const float front_angle_cos = _cos( deg2rad ( 20.f ) ); if( stalker_velocity_dir.dotproduct(dir_to_actor) < front_angle_cos ) return false; if( type_motion::front != type_motion::dir( ea, H, angle ) ) return false; Fvector p; if( Fvector().sub( H.initiator()->Position(), global_hit_position( p, ea, H ) ).magnitude() > 30.f ) return false; m = motion( front ); type_motion_diagnostic( " type_motion0: 1. = »нерционное движение вперед от попадани¤ в голову ", front, ea, H, m ); return true; }
bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const { m = MotionID(); if( H.initiator() != Level().CurrentControlEntity()) return false; CObject* O = Level().Objects.net_Find( H.weaponID ); if(!O) return false; //static_cast<CGameObject*>(O)->cast_weapon() CWeaponShotgun* s = smart_cast< CWeaponShotgun* >( static_cast<CGameObject*>(O) ); if(!s) return false; Fvector p; const float max_distance = 20.f; if(Fvector().sub(H.initiator()->Position(),global_hit_position( p, ea, H )).magnitude() > max_distance) return false; edirection dr = dir( ea, H, angle ); m = motion( dr ); type_motion_diagnostic( " type_motion2: 3. Ўотган ", dr, ea, H, m ); return true; }
bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const { m = MotionID(); if( H.initiator() != Level().CurrentControlEntity()) return false; VERIFY( ea.Visual( ) ); IKinematics *K = ea.Visual()->dcast_PKinematics(); VERIFY( K ); if( is_bone_head( *K, H.bone() ) ) { edirection dr = dir( ea, H, angle ); m = motion( dr ); type_motion_diagnostic( " type_motion3: 4. ’едшот (по веро¤тности), кроме 5 (4)", dr, ea, H, m ); return true; } return false; }
bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const { if( H.initiator() != Level().CurrentControlEntity()) return false; m = MotionID(); VERIFY( ea.Visual( ) ); IKinematics *K = ea.Visual()->dcast_PKinematics(); VERIFY( K ); if(is_snipper( H.weaponID ) && !is_bone_head( *K, H.bone() )) { edirection dr = dir( ea, H, angle ); m = motion( dr ); type_motion_diagnostic( "type_motion5: 6. —найперка в тело", dr, ea, H, m ); return true; } return false; }
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 ); }