CActorDeathEffector::CActorDeathEffector (CActorCondition* parent, LPCSTR sect) // -(( :m_pParent(parent) { Actor()->SetWeaponHideState(INV_STATE_BLOCK_ALL,true); hide_indicators (); AddEffector (Actor(), effActorDeath, sect); disable_input (); LPCSTR snd = pSettings->r_string(sect, "snd"); m_death_sound.create (snd,st_Effect,0); m_death_sound.play_at_pos(0,Fvector().set(0,0,0),sm_2D); SBaseEffector* pe = Actor()->Cameras().GetPPEffector((EEffectorPPType)effActorDeath); pe->m_on_b_remove_callback = SBaseEffector::CB_ON_B_REMOVE(this, &CActorDeathEffector::OnPPEffectorReleased); m_b_actual = true; m_start_health = m_pParent->health(); }
void CControllerAura::update_frame() { if (m_hit_state == eNone) return; switch (m_hit_state){ case eEffectoring: if (m_time_started + m_pmt_hit_delay < time()) { // launch effector AddEffector (Actor(), effControllerAura, "effector_controller_aura"); m_hit_state = eHit; m_time_started = time(); } break; case eHit: if (m_time_started + m_pmt_pp_hit_delay < time()) { m_object->Hit_Psy (Actor(), aura_damage); m_hit_state = eEffectoring; } break; } }
void CControllerAura::update_schedule() { if (!m_object->g_Alive()) return; float dist_to_actor = Actor()->Position().distance_to(m_object->Position()); if ((dist_to_actor > aura_radius + FAKE_MIN_ADD_DIST) && (dist_to_actor < aura_radius + FAKE_MAX_ADD_DIST)) { // first time? if (m_time_fake_aura == 0) { m_time_fake_aura = time() + 5000 + Random.randI(FAKE_AURA_DELAY); if (active()) { m_effector->switch_off (); m_effector = 0; } } else { if (active()) { // check to stop if (m_time_fake_aura < time()) { m_effector->switch_off (); m_effector = 0; m_time_fake_aura = time() + 5000 + Random.randI(FAKE_AURA_DELAY); } } else { // check to start if (m_time_fake_aura < time()) { m_effector = new CPPEffectorControllerAura(m_state, 5000, aura_sound.left, aura_sound.right); Actor()->Cameras().AddPPEffector (m_effector); m_time_fake_aura = time() + 5000 + Random.randI(FAKE_AURA_DURATION); } } } } else { m_time_fake_aura = 0; bool need_be_active = (dist_to_actor < aura_radius); if (active()) { if (!need_be_active) { m_effector->switch_off (); m_effector = 0; m_hit_state = eNone; } else { } } else { if (need_be_active) { // create effector m_effector = new CPPEffectorControllerAura(m_state, 5000, aura_sound.left, aura_sound.right); Actor()->Cameras().AddPPEffector (m_effector); m_hit_state = eEffectoring; m_time_started = time(); } else { } } } if (active()) { CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effControllerAura2); if(!ce) AddEffector(Actor(), effControllerAura2, "effector_controller_aura2", 0.15f); }else{ CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effControllerAura2); if(ce) RemoveEffector(Actor(), effControllerAura2); } }
void CBaseMonster::HitEntity(const CEntity *pEntity, float fDamage, float impulse, Fvector &dir, ALife::EHitType hit_type, bool draw_hit_marks) { if (!g_Alive()) return; if (!pEntity || pEntity->getDestroy()) return; if (!EnemyMan.get_enemy()) return; if (EnemyMan.get_enemy() == pEntity) { Fvector position_in_bone_space; position_in_bone_space.set(0.f,0.f,0.f); // перевод из локальных координат в мировые вектора направления импульса Fvector hit_dir; XFORM().transform_dir (hit_dir,dir); hit_dir.normalize (); CEntity *pEntityNC = const_cast<CEntity*>(pEntity); VERIFY (pEntityNC); NET_Packet l_P; SHit HS; HS.GenHeader(GE_HIT, pEntityNC->ID()); // u_EventGen (l_P,GE_HIT, pEntityNC->ID()); HS.whoID = (ID()); // l_P.w_u16 (ID()); HS.weaponID = (ID()); // l_P.w_u16 (ID()); HS.dir = (hit_dir); // l_P.w_dir (hit_dir); HS.power = (fDamage); // l_P.w_float (fDamage); HS.boneID = (smart_cast<IKinematics*>(pEntityNC->Visual())->LL_GetBoneRoot());// l_P.w_s16 (smart_cast<IKinematics*>(pEntityNC->Visual())->LL_GetBoneRoot()); HS.p_in_bone_space = (position_in_bone_space); // l_P.w_vec3 (position_in_bone_space); HS.impulse = (impulse); // l_P.w_float (impulse); HS.hit_type = hit_type; // l_P.w_u16 ( u16(ALife::eHitTypeWound) ); HS.Write_Packet(l_P); u_EventSend (l_P); if (pEntityNC == Actor() && draw_hit_marks) { START_PROFILE("BaseMonster/Animation/HitEntity"); SDrawStaticStruct* s = CurrentGameUI()->AddCustomStatic("monster_claws", false); float h1,p1; Device.vCameraDirection.getHP (h1,p1); Fvector hd = hit_dir; hd.mul (-1); float d = -h1 + hd.getH (); s->wnd()->SetHeading (d); Fvector2 wnd_pos = s->wnd()->GetWndPos(); wnd_pos.y += 400.0f*_cos(d); wnd_pos.x += 500.0f*_sin(d); s->wnd()->SetWndPos(wnd_pos); STOP_PROFILE; //SetAttackEffector (); float time_to_lock = fDamage * MAX_LOCK_TIME; clamp (time_to_lock, 0.f, MAX_LOCK_TIME); Actor()->lock_accel_for (int(time_to_lock * 1000)); ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effBigMonsterHit); if(!ce) { const shared_str& eff_sect = pSettings->r_string(cNameSect(), "actor_hit_effect"); if(eff_sect.c_str()) { int id = -1; Fvector cam_pos,cam_dir,cam_norm; Actor()->cam_Active()->Get (cam_pos,cam_dir,cam_norm); cam_dir.normalize_safe (); dir.normalize_safe (); float ang_diff = angle_difference (cam_dir.getH(), dir.getH()); Fvector cp; cp.crossproduct (cam_dir,dir); bool bUp =(cp.y>0.0f); Fvector cross; cross.crossproduct (cam_dir, dir); VERIFY (ang_diff>=0.0f && ang_diff<=PI); float _s1 = PI_DIV_8; float _s2 = _s1+PI_DIV_4; float _s3 = _s2+PI_DIV_4; float _s4 = _s3+PI_DIV_4; if(ang_diff<=_s1){ id = 2; }else { if(ang_diff>_s1 && ang_diff<=_s2){ id = (bUp)?5:7; }else if(ang_diff>_s2 && ang_diff<=_s3){ id = (bUp)?3:1; }else if(ang_diff>_s3 && ang_diff<=_s4){ id = (bUp)?4:6; }else if(ang_diff>_s4){ id = 0; }else{ VERIFY(0); } } string64 sect_name; xr_sprintf (sect_name,"%s_%d",eff_sect.c_str(), id); AddEffector (Actor(), effBigMonsterHit, sect_name, fDamage); } } ////////////////////////////////////////////////////////////////////////// } Morale.on_attack_success(); m_time_last_attack_success = Device.dwTimeGlobal; } }
void CActor::HitMark (float P, Fvector dir, CObject* who, s16 element, Fvector position_in_bone_space, float impulse, ALife::EHitType hit_type) { // hit marker if ( (hit_type==ALife::eHitTypeFireWound||hit_type==ALife::eHitTypeWound_2) && g_Alive() && Local() && /*(this!=who) && */(Level().CurrentEntity()==this) ) { HUD().Hit(0, P, dir); { CEffectorCam* ce = Cameras().GetCamEffector((ECamEffectorType)effFireHit); if(!ce) { int id = -1; Fvector cam_pos,cam_dir,cam_norm; cam_Active()->Get (cam_pos,cam_dir,cam_norm); cam_dir.normalize_safe (); dir.normalize_safe (); float ang_diff = angle_difference (cam_dir.getH(), dir.getH()); Fvector cp; cp.crossproduct (cam_dir,dir); bool bUp =(cp.y>0.0f); Fvector cross; cross.crossproduct (cam_dir, dir); VERIFY (ang_diff>=0.0f && ang_diff<=PI); float _s1 = PI_DIV_8; float _s2 = _s1+PI_DIV_4; float _s3 = _s2+PI_DIV_4; float _s4 = _s3+PI_DIV_4; if(ang_diff<=_s1){ id = 2; }else if(ang_diff>_s1 && ang_diff<=_s2){ id = (bUp)?5:7; }else if(ang_diff>_s2 && ang_diff<=_s3){ id = (bUp)?3:1; }else if(ang_diff>_s3 && ang_diff<=_s4){ id = (bUp)?4:6; }else if(ang_diff>_s4){ id = 0; }else{ VERIFY(0); } string64 sect_name; sprintf(sect_name,"effector_fire_hit_%d",id); AddEffector(this, effFireHit, sect_name, P/100.0f); } } } }
void CExplosive::Explode() { VERIFY(0xffff != Initiator()); VERIFY(m_explosion_flags.test(flReadyToExplode));//m_bReadyToExplode VERIFY(!ph_world->Processing()); //m_bExploding = true; m_explosion_flags.set(flExploding,TRUE); cast_game_object()->processing_activate(); Fvector& pos = m_vExplodePos; Fvector& dir = m_vExplodeDir; #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_OpenCashedDraw(); DBG_DrawPoint(pos,0.3f,D3DCOLOR_XRGB(255,0,0)); } #endif // Msg("---------CExplosive Explode [%d] frame[%d]",cast_game_object()->ID(), Device.dwFrame); OnBeforeExplosion(); //играем звук взрыва Sound->play_at_pos(sndExplode, 0, pos, false); //показываем эффекты m_wallmark_manager.PlaceWallmarks (pos); Fvector vel; smart_cast<CPhysicsShellHolder*>(cast_game_object())->PHGetLinearVell(vel); Fmatrix explode_matrix; explode_matrix.identity(); explode_matrix.j.set(dir); Fvector::generate_orthonormal_basis(explode_matrix.j, explode_matrix.i, explode_matrix.k); explode_matrix.c.set(pos); CParticlesObject* pStaticPG; pStaticPG = CParticlesObject::Create(*m_sExplodeParticles,!m_bDynamicParticles); if (m_bDynamicParticles) m_pExpParticle = pStaticPG; pStaticPG->UpdateParent(explode_matrix,vel); pStaticPG->Play(); //включаем подсветку от взрыва StartLight(); //trace frags Fvector frag_dir; ////////////////////////////// //осколки ////////////////////////////// //------------------------------------- bool SendHits = false; if (OnServer()) SendHits = true; else SendHits = false; for(int i = 0; i < m_iFragsNum; ++i){ frag_dir.random_dir (); frag_dir.normalize (); CCartridge cartridge; cartridge.m_kDist = 1.f; cartridge.m_kHit = 1.f; cartridge.m_kImpulse = 1.f; cartridge.m_kPierce = 1.f; cartridge.fWallmarkSize = fWallmarkSize; cartridge.bullet_material_idx = GMLib.GetMaterialIdx(WEAPON_MATERIAL_NAME); cartridge.m_flags.set (CCartridge::cfTracer,FALSE); Level().BulletManager().AddBullet( pos, frag_dir, m_fFragmentSpeed, m_fFragHit, m_fFragHitImpulse, Initiator(), cast_game_object()->ID(), m_eHitTypeFrag, m_fFragsRadius, cartridge, SendHits ); } if (cast_game_object()->Remote()) return; ///////////////////////////////// //взрывная волна //////////////////////////////// //--------------------------------------------------------------------- xr_vector<ISpatial*> ISpatialResult; g_SpatialSpace->q_sphere(ISpatialResult,0,STYPE_COLLIDEABLE,pos,m_fBlastRadius); m_blasted_objects.clear (); for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++) { ISpatial* spatial = ISpatialResult[o_it]; // feel_touch_new(spatial->dcast_CObject()); CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>(spatial->dcast_CObject()); if(pGameObject && cast_game_object()->ID() != pGameObject->ID()) m_blasted_objects.push_back(pGameObject); } GetExplosionBox(m_vExplodeSize); START_PROFILE("explosive/activate explosion box") ActivateExplosionBox(m_vExplodeSize,m_vExplodePos); STOP_PROFILE //--------------------------------------------------------------------- #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_ClosedCashedDraw(100000); } #endif ////////////////////////////////////////////////////////////////////////// // Explode Effector ////////////// CGameObject* GO = smart_cast<CGameObject*>(Level().CurrentEntity()); CActor* pActor = smart_cast<CActor*>(GO); if(pActor) { float dist_to_actor = pActor->Position().distance_to(pos); float max_dist = EFFECTOR_RADIUS; if (dist_to_actor < max_dist) AddEffector (pActor, effExplodeHit, effector.effect_sect_name, (max_dist - dist_to_actor) / max_dist ); } }
void CActorCondition::UpdateCondition() { if(psActorFlags.test(AF_GODMODE_RT)) { UpdateSatiety(); UpdateBoosters(); m_fAlcohol += m_fV_Alcohol*m_fDeltaTime; clamp (m_fAlcohol, 0.0f, 1.0f); if(IsGameTypeSingle()) { CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effAlcohol); if(ce) RemoveEffector(m_object,effAlcohol); } } if (GodMode()) return; if (!object().g_Alive()) return; if (!object().Local() && m_object != Level().CurrentViewEntity()) return; float base_weight = object().MaxCarryWeight(); float cur_weight = object().inventory().TotalWeight(); if ((object().mstate_real&mcAnyMove)) { ConditionWalk( cur_weight / base_weight, isActorAccelerated( object().mstate_real,object().IsZoomAimingMode() ), (object().mstate_real&mcSprint) != 0 ); } else { ConditionStand( cur_weight / base_weight ); } if ( IsGameTypeSingle() ) { float k_max_power = 1.0f; if( true ) { k_max_power = 1.0f + _min(cur_weight, base_weight) / base_weight + _max(0.0f, (cur_weight - base_weight) / 10.0f); } else { k_max_power = 1.0f; } SetMaxPower (GetMaxPower() - m_fPowerLeakSpeed * m_fDeltaTime * k_max_power); } m_fAlcohol += m_fV_Alcohol*m_fDeltaTime; clamp (m_fAlcohol, 0.0f, 1.0f); if ( IsGameTypeSingle() ) { CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effAlcohol); if ((m_fAlcohol>0.0001f) ){ if(!ce){ AddEffector(m_object,effAlcohol, "effector_alcohol", GET_KOEFF_FUNC(this, &CActorCondition::GetAlcohol)); } }else{ if(ce) RemoveEffector(m_object,effAlcohol); } string512 pp_sect_name; shared_str ln = Level().name(); if(ln.size()) { CEffectorPP* ppe = object().Cameras().GetPPEffector((EEffectorPPType)effPsyHealth); strconcat (sizeof(pp_sect_name),pp_sect_name, "effector_psy_health", "_", *ln); if(!pSettings->section_exist(pp_sect_name)) xr_strcpy (pp_sect_name, "effector_psy_health"); if ( !fsimilar(GetPsyHealth(), 1.0f, 0.05f) ) { if(!ppe) { AddEffector(m_object,effPsyHealth, pp_sect_name, GET_KOEFF_FUNC(this, &CActorCondition::GetPsy)); } }else { if(ppe) RemoveEffector(m_object,effPsyHealth); } } //- if(fis_zero(GetPsyHealth())) //- SetHealth( 0.0f ); }; UpdateSatiety(); UpdateBoosters(); inherited::UpdateCondition(); if( IsGameTypeSingle() ) UpdateTutorialThresholds(); if(GetHealth()<0.05f && m_death_effector==NULL && IsGameTypeSingle()) { if(pSettings->section_exist("actor_death_effector")) m_death_effector = xr_new<CActorDeathEffector>(this, "actor_death_effector"); } if(m_death_effector && m_death_effector->IsActual()) { m_death_effector->UpdateCL (); if(!m_death_effector->IsActual()) m_death_effector->Stop(); } AffectDamage_InjuriousMaterialAndMonstersInfluence(); }