void CExplosive::OnAfterExplosion() { if(m_pExpParticle){ m_pExpParticle->Stop(); CParticlesObject::Destroy(m_pExpParticle); m_pExpParticle = NULL; } //ликвидировать сам объект if (cast_game_object()->Local()) cast_game_object()->DestroyObject(); }
void CExplosive::ExplodeWaveProcessObject(collide::rq_results& storage, CPhysicsShellHolder*l_pGO) { Fvector l_goPos; if(l_pGO->Visual()) l_pGO->Center (l_goPos); else return; //мне непонятно зачем наносить хит от взрыва по объектам не имеющим вижуал - поэтому игнорируем #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_OpenCashedDraw(); } #endif float l_effect=ExplosionEffect(storage,this,l_pGO,m_vExplodePos,m_fBlastRadius); float l_impuls = m_fBlastHitImpulse * l_effect; float l_hit = m_fBlastHit * l_effect; if(l_impuls > .001f||l_hit> 0.001) { Fvector l_dir;l_dir.sub(l_goPos,m_vExplodePos); float rmag=_sqrt(m_fUpThrowFactor*m_fUpThrowFactor+1.f+2.f*m_fUpThrowFactor*l_dir.y); l_dir.y += m_fUpThrowFactor; //rmag -модуль l_dir после l_dir.y += m_fUpThrowFactor, модуль=_sqrt(l_dir^2+y^2+2.*(l_dir,y)),y=(0,m_fUpThrowFactor,0) (до этого модуль l_dir =1) l_dir.mul(1.f/rmag);//перенормировка NET_Packet P; SHit HS; HS.GenHeader(GE_HIT, l_pGO->ID()); // cast_game_object()->u_EventGen (P,GE_HIT,l_pGO->ID()); HS.whoID =Initiator(); // P.w_u16 (Initiator()); HS.weaponID = cast_game_object()->ID(); // P.w_u16 (cast_game_object()->ID()); HS.dir = l_dir; // P.w_dir (l_dir); HS.power = l_hit; // P.w_float (l_hit); HS.p_in_bone_space = l_goPos; // P.w_vec3 (l_goPos); HS.impulse = l_impuls; // P.w_float (l_impuls); HS.hit_type = (m_eHitTypeBlast); // P.w_u16 (u16(m_eHitTypeBlast)); HS.boneID = 0; // P.w_s16 (0); HS.Write_Packet(P); cast_game_object()->u_EventSend (P); } #ifdef DEBUG if(ph_dbg_draw_mask.test(phDbgDrawExplosions)) { DBG_ClosedCashedDraw(100000); } #endif }
void CExplosive::OnAfterExplosion() { if(m_pExpParticle){ m_pExpParticle->Stop(); CParticlesObject::Destroy(m_pExpParticle); m_pExpParticle = NULL; } //ликвидировать сам объект if (cast_game_object()->Local()) cast_game_object()->DestroyObject(); // NET_Packet P; // cast_game_object()->u_EventGen (P,GE_DESTROY,cast_game_object()->ID()); // // Msg ("ge_destroy: [%d] - %s",ID(),*cName()); // if (cast_game_object()->Local()) cast_game_object()->u_EventSend (P); }
void CExplosive::ActivateExplosionBox(const Fvector &size,Fvector &in_out_pos) { CPhysicsShellHolder *self_obj=smart_cast<CPhysicsShellHolder*>(cast_game_object()); CPhysicsShell* self_shell=self_obj->PPhysicsShell(); if(self_shell&&self_shell->isActive())self_shell->DisableCollision(); ActivateShapeExplosive( self_obj, size, m_vExplodeSize, in_out_pos ); if(self_shell&&self_shell->isActive())self_shell->EnableCollision(); }
void CExplosive::Load(CInifile *ini,LPCSTR section) { m_fBlastHit = ini->r_float(section,"blast"); m_fBlastRadius = ini->r_float(section,"blast_r"); m_fBlastHitImpulse = ini->r_float(section,"blast_impulse"); m_iFragsNum = ini->r_s32(section,"frags"); m_fFragsRadius = ini->r_float(section,"frags_r"); m_fFragHit = ini->r_float(section,"frag_hit"); m_fFragHitImpulse = ini->r_float(section,"frag_hit_impulse"); m_eHitTypeBlast = ALife::g_tfString2HitType(ini->r_string(section, "hit_type_blast")); m_eHitTypeFrag = ALife::g_tfString2HitType(ini->r_string(section, "hit_type_frag")); m_fUpThrowFactor = ini->r_float(section,"up_throw_factor"); fWallmarkSize = ini->r_float(section,"wm_size"); R_ASSERT (fWallmarkSize>0); m_sExplodeParticles = ini->r_string(section,"explode_particles"); sscanf (ini->r_string(section,"light_color"), "%f,%f,%f", &m_LightColor.r, &m_LightColor.g, &m_LightColor.b); m_fLightRange = ini->r_float(section,"light_range"); m_fLightTime = ini->r_float(section,"light_time"); //трассы для разлета осколков m_fFragmentSpeed = ini->r_float (section,"fragment_speed" ); LPCSTR snd_name = ini->r_string(section,"snd_explode"); sndExplode.create (snd_name, st_Effect,m_eSoundExplode); m_fExplodeDurationMax = ini->r_float(section, "explode_duration"); effector.effect_sect_name= ini->r_string("explode_effector","effect_sect_name"); // if( ini->line_exist(section,"wallmark_section") ) // { m_wallmark_manager.m_owner = cast_game_object(); // m_wallmark_manager.Load(pSettings,ini->r_string(section,"wallmark_section")); // } m_bHideInExplosion = TRUE; if (ini->line_exist(section, "hide_in_explosion")) { m_bHideInExplosion = ini->r_bool(section, "hide_in_explosion"); m_fExplodeHideDurationMax = 0; if (ini->line_exist(section, "explode_hide_duration")) { m_fExplodeHideDurationMax = ini->r_float(section, "explode_hide_duration"); } } m_bDynamicParticles = FALSE; if (ini->line_exist(section, "dynamic_explosion_particles")) m_bDynamicParticles = ini->r_bool(section, "dynamic_explosion_particles"); }
void CExplosive::GenExplodeEvent (const Fvector& pos, const Fvector& normal) { if (OnClient() || cast_game_object()->Remote()) return; // if( m_bExplodeEventSent ) // return; VERIFY(!m_explosion_flags.test(flExplodEventSent));//!m_bExplodeEventSent VERIFY(0xffff != Initiator()); NET_Packet P; cast_game_object()->u_EventGen (P,GE_GRENADE_EXPLODE,cast_game_object()->ID()); P.w_u16 (Initiator()); P.w_vec3 (pos); P.w_vec3 (normal); cast_game_object()->u_EventSend (P); //m_bExplodeEventSent = true; m_explosion_flags.set(flExplodEventSent,TRUE); }
void CExplosive::UpdateExplosionParticles () { if (!m_bDynamicParticles || m_pExpParticle == NULL || !m_pExpParticle->IsPlaying()) return; CGameObject *GO=cast_game_object(); if (!GO) return; Fmatrix ParticleMatrix = m_pExpParticle->XFORM(); Fvector Vel; Vel.sub(GO->Position(), ParticleMatrix.c); ParticleMatrix.c.set(GO->Position()); m_pExpParticle->UpdateParent(ParticleMatrix, Vel); }
void CExplosive::FindNormal(Fvector& normal) { collide::rq_result RQ; Fvector pos, dir; dir.set(0,-1.f,0); cast_game_object()->Center(pos); BOOL result = Level().ObjectSpace.RayPick(pos, dir, cast_game_object()->Radius(), collide::rqtBoth, RQ, NULL); if(!result || RQ.O){ normal.set(0,1,0); //если лежим на статике //найти треугольник и вычислить нормаль по нему }else { Fvector* pVerts = Level().ObjectSpace.GetStaticVerts(); CDB::TRI* pTri = Level().ObjectSpace.GetStaticTris() + RQ.element; normal.mknormal (pVerts[pTri->verts[0]],pVerts[pTri->verts[1]],pVerts[pTri->verts[2]]); } }
void CExplosive::UpdateCL() { //VERIFY(!this->getDestroy()); VERIFY(!ph_world->Processing()); if(!m_explosion_flags.test(flExploding)) return;// !m_bExploding if(m_explosion_flags.test(flExploded)) { CGameObject* go=cast_game_object(); go->processing_deactivate(); m_explosion_flags.set(flExploding,FALSE);//m_bExploding = false; OnAfterExplosion(); return; } //время вышло, убираем объект взрывчатки if(m_fExplodeDuration < 0.f&&m_blasted_objects.empty()) { m_explosion_flags.set(flExploded,TRUE); StopLight(); // Msg("---------CExplosive OnAfterExplosion [%d] frame[%d]",cast_game_object()->ID(), Device.dwFrame); } else { m_fExplodeDuration -= Device.fTimeDelta; if (!m_bHideInExplosion && !m_bAlreadyHidden) { if (m_fExplodeHideDurationMax <= (m_fExplodeDurationMax - m_fExplodeDuration)) { HideExplosive(); } } UpdateExplosionPos(); UpdateExplosionParticles(); ExplodeWaveProcess(); //обновить подсветку взрыва if(m_pLight && m_pLight->get_active() && m_fLightTime>0) { if(m_fExplodeDuration > (m_fExplodeDurationMax - m_fLightTime)) { float scale = (m_fExplodeDuration - (m_fExplodeDurationMax - m_fLightTime))/m_fLightTime; m_pLight->set_color(m_LightColor.r*scale, m_LightColor.g*scale, m_LightColor.b*scale); m_pLight->set_range(m_fLightRange*scale); } else StopLight(); } } }
CCustomMonster::CCustomMonster() : // this is non-polymorphic call of the virtual function cast_entity_alive // just to remove warning C4355 if we use this instead Feel::Vision ( cast_game_object() ) { m_sound_user_data_visitor = 0; m_memory_manager = 0; m_movement_manager = 0; m_sound_player = 0; m_already_dead = false; m_invulnerable = false; m_moving_object = 0; }
void CExplosive::HideExplosive() { CGameObject *GO=cast_game_object(); GO->setVisible(FALSE); GO->setEnabled(FALSE); CPhysicsShell* phshell=(smart_cast<CPhysicsShellHolder*>(GO))->PPhysicsShell(); if(phshell) { phshell->Disable(); phshell->DisableCollision(); } m_bAlreadyHidden = true; };
void CExplosive::ActivateExplosionBox(const Fvector &size,Fvector &in_out_pos) { CPhysicsShellHolder *self_obj=smart_cast<CPhysicsShellHolder*>(cast_game_object()); CPhysicsShell* self_shell=self_obj->PPhysicsShell(); if(self_shell&&self_shell->isActive())self_shell->DisableCollision(); CPHActivationShape activation_shape;//Fvector start_box;m_PhysicMovementControl.Box().getsize(start_box); activation_shape.Create(in_out_pos,size,self_obj); dBodySetGravityMode(activation_shape.ODEBody(),0); activation_shape.Activate(size,1,1.f,M_PI/8.f); in_out_pos.set(activation_shape.Position()); activation_shape.Size(m_vExplodeSize); activation_shape.Destroy(); if(self_shell&&self_shell->isActive())self_shell->EnableCollision(); }
u16 CExplosive::Initiator() { u16 initiator=CurrentParentID(); if(initiator==u16(-1))initiator=cast_game_object()->ID(); return initiator; }
void CExplosive::GetExplVelocity(Fvector &v) { smart_cast<CPhysicsShellHolder*>(cast_game_object())->PHGetLinearVell(v); }
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 ); } }