//void CCar::Hit(float P,Fvector &dir,CObject * who,s16 element,Fvector p_in_object_space, float impulse, ALife::EHitType hit_type) void CCar::Hit (SHit* pHDS) { SHit HDS = *pHDS; //if(CDelayedActionFuse::isActive()||Initiator()==u16(-1)&&HDS.hit_type==ALife::eHitTypeStrike) //{ // HDS.power=0.f; //} //if(HDS.who->ID()!=ID()) //{ // CExplosive::SetInitiator(HDS.who->ID()); //} WheelHit(HDS.damage(),HDS.bone(),HDS.hit_type); DoorHit(HDS.damage(),HDS.bone(),HDS.hit_type); float hitScale=1.f,woundScale=1.f; if(HDS.hit_type!=ALife::eHitTypeStrike) CDamageManager::HitScale(HDS.bone(), hitScale, woundScale); HDS.power *= GetHitImmunity(HDS.hit_type)*hitScale; inherited::Hit(&HDS); if(!CDelayedActionFuse::isActive()) { CDelayedActionFuse::CheckCondition(GetfHealth()); } CDamagableItem::HitEffect(); // if(Owner()&&Owner()->ID()==Level().CurrentEntity()->ID()) // CurrentGameUI()->UIMainIngameWnd->CarPanel().SetCarHealth(GetfHealth()); }
//void CHangingLamp::Hit(float P,Fvector &dir, CObject* who,s16 element, // Fvector p_in_object_space, float impulse, ALife::EHitType hit_type) void CHangingLamp::Hit (SHit* pHDS) { SHit HDS = *pHDS; callback(GameObject::eHit)( lua_game_object(), HDS.power, HDS.dir, smart_cast<const CGameObject*>(HDS.who)->lua_game_object(), HDS.bone() ); #ifdef HLAMP_AFFECT_IMMUNITIES HDS.power = CHitImmunity::AffectHit(HDS.power,HDS.hit_type); inherited::Hit(pHDS); #endif BOOL bWasAlive = Alive () || light_render->get_active(); if(m_pPhysicsShell) m_pPhysicsShell->applyHit(pHDS->p_in_bone_space,pHDS->dir,pHDS->impulse,pHDS->boneID,pHDS->hit_type); if (!bWasAlive) return; if (pHDS->boneID==light_bone) SetHealth ( 0.f ); else { float damage = pHDS->damage() * 100.f; Msg("DEBUG: %s health = %.3f, damage = %.3f", Name_script(), GetHealth(), damage); SetHealth(GetHealth() - damage); } if (bWasAlive && (!Alive())) TurnOff (); }
void CCar::PHHit(SHit &H) { if(!m_pPhysicsShell) return; if(m_bone_steer==H.bone()) return; if(CPHUpdateObject::IsActive()) { Fvector vimpulse;vimpulse.set(H.direction()); vimpulse.mul( H.phys_impulse( ) ); vimpulse.y *=GravityFactorImpulse(); float mag=vimpulse.magnitude(); if(!fis_zero(mag)) { vimpulse.mul(1.f/mag); m_pPhysicsShell->applyHit(H.bone_space_position(),vimpulse,mag,H.bone(),H.type()); } } else { m_pPhysicsShell->applyHit( H.bone_space_position(), H.direction(), H.phys_impulse(), H.bone(), H.type() ); } }
void type_motion_diagnostic( LPCSTR message, type_motion::edirection dr, const CEntityAlive& ea, const SHit& H, const MotionID &m ) { #ifdef DEBUG if(! death_anim_debug ) return; IKinematicsAnimated *KA = smart_cast<IKinematicsAnimated*>( ea.Visual() ); VERIFY( KA ); IKinematics *K = smart_cast<IKinematics*>( ea.Visual() ); LPCSTR bone_name = "not_definite"; if( H.bone() != BI_NONE ) { CBoneData& bd = K->LL_GetData( H.bone() ); bone_name = bd.name.c_str(); } LPCSTR motion_name = "not_set"; if( m.valid() ) motion_name = KA->LL_MotionDefName_dbg( m ).first; Msg( "death anims: %s, dir: %s, motion: %s, obj: %s, model: %s, bone: %s " ,message ,motion_dirs[ dr ].name, motion_name, ea.cName().c_str(), ea.cNameVisual().c_str(), bone_name ); #endif }
//void CDestroyablePhysicsObject::Hit (float P,Fvector &dir,CObject *who,s16 element,Fvector p_in_object_space, float impulse, ALife::EHitType hit_type) void CDestroyablePhysicsObject::Hit (SHit* pHDS) { SHit HDS = *pHDS; callback(GameObject::eHit)( lua_game_object(), HDS.power, HDS.dir, smart_cast<const CGameObject*>(HDS.who)->lua_game_object(), HDS.bone() ); HDS.power=CHitImmunity::AffectHit(HDS.power,HDS.hit_type); float hit_scale=1.f,wound_scale=1.f; CDamageManager::HitScale(HDS.bone(),hit_scale,wound_scale); HDS.power*=hit_scale; // inherited::Hit(P,dir,who,element,p_in_object_space,impulse,hit_type); inherited::Hit(&HDS); m_fHealth-=HDS.power; if(m_fHealth<=0.f) { // CPHDestroyable::SetFatalHit(SHit(P,dir,who,element,p_in_object_space,impulse,hit_type)); CPHDestroyable::SetFatalHit(HDS); if(CPHDestroyable::CanDestroy())Destroy(); } }
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; }
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; }
void CCharacterPhysicsSupport::in_Hit( SHit &H, bool is_killing ) { m_sv_hit = H; m_hit_valide_time = Device.dwTimeGlobal + hit_valide_time; if( m_EntityAlife.use_simplified_visual ( ) || esRemoved == m_eState ) return; if( m_flags.test( fl_block_hit ) ) { VERIFY2( !m_EntityAlife.g_Alive( ), make_string("entity [%s][%d] is dead", m_EntityAlife.Name(), m_EntityAlife.ID()).c_str()); if( Device.dwTimeGlobal - m_EntityAlife.GetLevelDeathTime( ) >= 2000 ) m_flags.set(fl_block_hit,FALSE); else return; } //is_killing = is_killing || ( m_eState==esAlive && !m_EntityAlife.g_Alive( ) ); if( m_EntityAlife.g_Alive( ) && is_killing && H.type( ) == ALife::eHitTypeExplosion && H.damage( ) > 70.f ) CPHDestroyable::Destroy( ); if( ( !m_EntityAlife.g_Alive() || is_killing ) ) m_character_shell_control.set_kill_hit( H ); if(!m_pPhysicsShell&&is_killing) KillHit( H ); if( m_flags.test(fl_use_hit_anims) && Type() != etBitting && !m_flags.test(fl_death_anim_on) ) //&& Type() == etStalker { m_hit_animations.PlayHitMotion( H.direction( ), H.bone_space_position(), H.bone( ), m_EntityAlife ); } if( !( m_pPhysicsShell && m_pPhysicsShell->isActive( ) ) ) { if( !is_killing && m_EntityAlife.g_Alive( ) ) m_PhysicMovementControl->ApplyHit( H.direction( ), H.phys_impulse( ), H.type( ) ); } else { #ifdef DEBUG if( is_killing && death_anim_debug && !is_imotion( m_interactive_motion ) ) { Msg( "death anim: applied fatal impulse dir: (%f,%f,%f), value: (%f) ", H.dir.x,H.dir.y,H.dir.z, H.impulse ); } #endif m_pPhysicsShell->applyHit( H.bone_space_position( ), H.direction( ), H.phys_impulse( ), H.bone(), H.type( ) ); } }
void CActor::Hit (SHit* pHDS) { pHDS->aim_bullet = false; SHit HDS = *pHDS; if( HDS.hit_type<ALife::eHitTypeBurn || HDS.hit_type >= ALife::eHitTypeMax ) { string256 err; sprintf (err, "Unknown/unregistered hit type [%d]", HDS.hit_type); R_ASSERT2 (0, err ); } #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgCharacterControl)) { DBG_OpenCashedDraw(); Fvector to;to.add(Position(),Fvector().mul(HDS.dir,HDS.phys_impulse())); DBG_DrawLine(Position(),to,D3DCOLOR_XRGB(124,124,0)); DBG_ClosedCashedDraw(500); } #endif bool bPlaySound = true; if (!g_Alive()) bPlaySound = false; if (!IsGameTypeSingle() && !g_pGamePersistent->bDedicatedServer) { game_PlayerState* ps = Game().GetPlayerByGameID(ID()); if (ps && ps->testFlag(GAME_PLAYER_FLAG_INVINCIBLE)) { bPlaySound = false; if (Device.dwFrame != last_hit_frame && HDS.bone() != BI_NONE) { // вычислить позицию и направленность партикла Fmatrix pos; CParticlesPlayer::MakeXFORM(this,HDS.bone(),HDS.dir,HDS.p_in_bone_space,pos); // установить particles CParticlesObject* ps = NULL; if (eacFirstEye == cam_active && this == Level().CurrentEntity()) ps = CParticlesObject::Create(invincibility_fire_shield_1st,TRUE); else ps = CParticlesObject::Create(invincibility_fire_shield_3rd,TRUE); ps->UpdateParent(pos,Fvector().set(0.f,0.f,0.f)); GamePersistent().ps_needtoplay.push_back(ps); }; }; last_hit_frame = Device.dwFrame; }; if( !g_pGamePersistent->bDedicatedServer && !sndHit[HDS.hit_type].empty() && (ALife::eHitTypeTelepatic != HDS.hit_type)) { ref_sound& S = sndHit[HDS.hit_type][Random.randI(sndHit[HDS.hit_type].size())]; bool b_snd_hit_playing = sndHit[HDS.hit_type].end() != std::find_if(sndHit[HDS.hit_type].begin(), sndHit[HDS.hit_type].end(), playing_pred()); if(ALife::eHitTypeExplosion == HDS.hit_type) { if (this == Level().CurrentControlEntity()) { S.set_volume(10.0f); if(!m_sndShockEffector){ m_sndShockEffector = xr_new<SndShockEffector>(); m_sndShockEffector->Start(this, float(S._handle()->length_ms()), HDS.damage() ); } } else bPlaySound = false; } if (bPlaySound && !b_snd_hit_playing) { Fvector point = Position(); point.y += CameraHeight(); S.play_at_pos (this, point); }; } //slow actor, only when he gets hit if(HDS.hit_type == ALife::eHitTypeWound || HDS.hit_type == ALife::eHitTypeStrike) { hit_slowmo = HDS.damage(); clamp (hit_slowmo,0.0f,1.f); } else hit_slowmo = 0.f; //--------------------------------------------------------------- if (Level().CurrentViewEntity() == this && !g_pGamePersistent->bDedicatedServer && HDS.hit_type == ALife::eHitTypeFireWound) { CObject* pLastHitter = Level().Objects.net_Find(m_iLastHitterID); CObject* pLastHittingWeapon = Level().Objects.net_Find(m_iLastHittingWeaponID); HitSector(pLastHitter, pLastHittingWeapon); }; if ((mstate_real&mcSprint) && Level().CurrentControlEntity() == this && HDS.hit_type != ALife::eHitTypeTelepatic && HDS.hit_type != ALife::eHitTypeRadiation ) { // mstate_real &=~mcSprint; mstate_wishful &=~mcSprint; }; if(!g_pGamePersistent->bDedicatedServer) { HitMark (HDS.damage(), HDS.dir, HDS.who, HDS.bone(), HDS.p_in_bone_space, HDS.impulse, HDS.hit_type); } switch (GameID()) { case GAME_SINGLE: { float hit_power = HitArtefactsOnBelt(HDS.damage(), HDS.hit_type); if (GodMode())//psActorFlags.test(AF_GODMODE)) { HDS.power = 0.0f; // inherited::Hit(0.f,dir,who,element,position_in_bone_space,impulse, hit_type); inherited::Hit(&HDS); return; } else { //inherited::Hit (hit_power,dir,who,element,position_in_bone_space, impulse, hit_type); HDS.power = hit_power; inherited::Hit(&HDS); }; } break; default: { m_bWasBackStabbed = false; if (HDS.hit_type == ALife::eHitTypeWound_2 && Check_for_BackStab_Bone(HDS.bone())) { // convert impulse into local coordinate system Fmatrix mInvXForm; mInvXForm.invert (XFORM()); Fvector vLocalDir; mInvXForm.transform_dir (vLocalDir,HDS.dir); vLocalDir.invert (); Fvector a = {0,0,1}; float res = a.dotproduct(vLocalDir); if (res < -0.707) { game_PlayerState* ps = Game().GetPlayerByGameID(ID()); if (!ps || !ps->testFlag(GAME_PLAYER_FLAG_INVINCIBLE)) m_bWasBackStabbed = true; } }; float hit_power = 0; if (m_bWasBackStabbed) hit_power = 100000; else hit_power = HitArtefactsOnBelt(HDS.damage(), HDS.hit_type); HDS.power = hit_power; inherited::Hit (&HDS); //inherited::Hit (hit_power,dir,who,element,position_in_bone_space, impulse, hit_type, 0.0f); } break; } }
void CAI_Stalker::Hit (SHit* pHDS) { // pHDS->power *= .1f; //хит может меняться в зависимости от ранга (новички получают больше хита, чем ветераны) SHit HDS = *pHDS; HDS.power *= m_fRankImmunity; if (m_boneHitProtection && HDS.hit_type == ALife::eHitTypeFireWound){ float BoneArmour = m_boneHitProtection->getBoneArmour(HDS.bone()); float NewHitPower = HDS.damage() - BoneArmour; if (NewHitPower < HDS.power*m_boneHitProtection->m_fHitFrac) HDS.power = HDS.power*m_boneHitProtection->m_fHitFrac; else HDS.power = NewHitPower; if (wounded()) HDS.power = 1000.f; } if (g_Alive()) { bool already_critically_wounded = critically_wounded(); if (!already_critically_wounded) { const CCoverPoint *cover = agent_manager().member().member(this).cover(); if (cover && pHDS->initiator() && (pHDS->initiator()->ID() != ID()) && !fis_zero(pHDS->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*>(pHDS->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() && (pHDS->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*pHDS->damage()/100.f; clamp (power_factor,0.f,1.f); CKinematicsAnimated *tpKinematics = smart_cast<CKinematicsAnimated*>(Visual()); #ifdef DEBUG tpKinematics->LL_GetBoneInstance (pHDS->bone()); if (pHDS->bone() >= tpKinematics->LL_BoneCount()) { Msg ("tpKinematics has no bone_id %d",pHDS->bone()); pHDS->_dump (); } #endif int fx_index = iFloor(tpKinematics->LL_GetBoneInstance(pHDS->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->on_critical_wound_initiator (this); } } } } } inherited::Hit (&HDS); }
void CGameObject::OnEvent (NET_Packet& P, u16 type) { switch (type) { case GE_HIT: case GE_HIT_STATISTIC: { /* u16 id,weapon_id; Fvector dir; float power, impulse; s16 element; Fvector position_in_bone_space; u16 hit_type; float ap = 0.0f; P.r_u16 (id); P.r_u16 (weapon_id); P.r_dir (dir); P.r_float (power); P.r_s16 (element); P.r_vec3 (position_in_bone_space); P.r_float (impulse); P.r_u16 (hit_type); //hit type if ((ALife::EHitType)hit_type == ALife::eHitTypeFireWound) { P.r_float (ap); } CObject* Hitter = Level().Objects.net_Find(id); CObject* Weapon = Level().Objects.net_Find(weapon_id); SHit HDS = SHit(power, dir, Hitter, element, position_in_bone_space, impulse, (ALife::EHitType)hit_type, ap); */ SHit HDS; HDS.PACKET_TYPE = type; HDS.Read_Packet_Cont(P); // Msg("Hit received: %d[%d,%d]", HDS.whoID, HDS.weaponID, HDS.BulletID); CObject* Hitter = Level().Objects.net_Find(HDS.whoID); CObject* Weapon = Level().Objects.net_Find(HDS.weaponID); HDS.who = Hitter; if (!HDS.who) { Msg("! ERROR: hitter object [%d] is NULL on client.", HDS.whoID); } //------------------------------------------------------- switch (HDS.PACKET_TYPE) { case GE_HIT_STATISTIC: { if (GameID() != eGameIDSingle) Game().m_WeaponUsageStatistic->OnBullet_Check_Request(&HDS); }break; default: { }break; } SetHitInfo(Hitter, Weapon, HDS.bone(), HDS.p_in_bone_space, HDS.dir); Hit (&HDS); //--------------------------------------------------------------------------- if (GameID() != eGameIDSingle) { Game().m_WeaponUsageStatistic->OnBullet_Check_Result(false); game_cl_mp* mp_game = smart_cast<game_cl_mp*>(&Game()); if (mp_game->get_reward_generator()) mp_game->get_reward_generator()->OnBullet_Hit(Hitter, this, Weapon, HDS.boneID); } //--------------------------------------------------------------------------- } break; case GE_DESTROY: { if ( H_Parent() ) { Msg( "! ERROR (GameObject): GE_DESTROY arrived to object[%d][%s], that has parent[%d][%s], frame[%d]", ID(), cNameSect().c_str(), H_Parent()->ID(), H_Parent()->cName().c_str(), Device.dwFrame ); // This object will be destroy on call function <H_Parent::Destroy> // or it will be call <H_Parent::Reject> ==> H_Parent = NULL // !!! ___ it is necessary to be check! break; } #ifdef MP_LOGGING Msg("--- Object: GE_DESTROY of [%d][%s]", ID(), cNameSect().c_str()); #endif // MP_LOGGING setDestroy (TRUE); // MakeMeCrow (); } break; } }
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 ); }
void CPhysicsShellHolder::PHHit( SHit &H ) { if(H.phys_impulse() >0) if(m_pPhysicsShell) m_pPhysicsShell->applyHit(H.bone_space_position(),H.direction(),H.phys_impulse(),H.bone(),H.type()); }