void CPHDestroyable::Destroy(u16 source_id/*=u16(-1)*/,LPCSTR section/*="ph_skeleton_object"*/) { if(!CanDestroy())return ; m_notificate_objects.clear(); CPhysicsShellHolder *obj =PPhysicsShellHolder() ; CPHSkeleton *phs= obj->PHSkeleton(); if(phs)phs->SetNotNeedSave(); if(obj->PPhysicsShell()) obj->PPhysicsShell()->Enable() ; obj->processing_activate(); if(source_id==obj->ID()) { m_flags.set(fl_released,FALSE); } xr_vector<shared_str>::iterator i=m_destroyed_obj_visual_names.begin(),e=m_destroyed_obj_visual_names.end(); if (IsGameTypeSingle()) { for(;e!=i;i++) GenSpawnReplace(source_id,section,*i); }; /////////////////////////////////////////////////////////////////////////// m_flags.set(fl_destroyed,TRUE); return; }
void CMosquitoBald::Affect(SZoneObjectInfo* O) { CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>(O->object); if(!pGameObject) return; if(O->zone_ignore) return; Fvector P; XFORM().transform_tiny(P,CFORM()->getSphere().P); Fvector hit_dir; hit_dir.set( ::Random.randF(-.5f,.5f), ::Random.randF(.0f,1.f), ::Random.randF(-.5f,.5f)); hit_dir.normalize(); Fvector position_in_bone_space; VERIFY(!pGameObject->getDestroy()); float dist = pGameObject->Position().distance_to(P) - pGameObject->Radius(); float power = Power(dist>0.f?dist:0.f, Radius()); float impulse = m_fHitImpulseScale*power*pGameObject->GetMass(); if(power > 0.01f) { position_in_bone_space.set(0.f,0.f,0.f); CreateHit(pGameObject->ID(),ID(),hit_dir,power,0,position_in_bone_space,impulse,m_eHitTypeBlowout); PlayHitParticles(pGameObject); } }
void CMosquitoBald::Affect(SZoneObjectInfo* O) { CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>(O->object); if(!pGameObject) return; if(O->zone_ignore) return; Fvector P; XFORM().transform_tiny(P,CFORM()->getSphere().P); #ifdef DEBUG char l_pow[255]; sprintf_s(l_pow, "zone hit. %.1f", Power(pGameObject->Position().distance_to(P))); if(bDebug) Msg("%s %s",*pGameObject->cName(), l_pow); #endif Fvector hit_dir; hit_dir.set(::Random.randF(-.5f,.5f), ::Random.randF(.0f,1.f), ::Random.randF(-.5f,.5f)); hit_dir.normalize(); Fvector position_in_bone_space; VERIFY(!pGameObject->getDestroy()); float dist = pGameObject->Position().distance_to(P) - pGameObject->Radius(); float power = Power(dist>0.f?dist:0.f); float impulse = m_fHitImpulseScale*power*pGameObject->GetMass(); //статистика по объекту O->total_damage += power; O->hit_num++; if(power > 0.01f) { m_dwDeltaTime = 0; position_in_bone_space.set(0.f,0.f,0.f); CreateHit(pGameObject->ID(),ID(),hit_dir,power,0,position_in_bone_space,impulse,m_eHitTypeBlowout); PlayHitParticles(pGameObject); } }
void CMosquitoBald::UpdateSecondaryHit() { if(m_dwAffectFrameNum == Device.dwFrame) return; m_dwAffectFrameNum = Device.dwFrame; if(Device.dwPrecacheFrame) return; OBJECT_INFO_VEC_IT it; for(it = m_ObjectInfoMap.begin(); m_ObjectInfoMap.end() != it; ++it) { if(!(*it).object->getDestroy()) { CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>((&(*it))->object); if(!pGameObject) return; if((&(*it))->zone_ignore) return; Fvector P; XFORM().transform_tiny(P,CFORM()->getSphere().P); Fvector hit_dir; hit_dir.set( ::Random.randF(-.5f,.5f), ::Random.randF(.0f,1.f), ::Random.randF(-.5f,.5f)); hit_dir.normalize(); Fvector position_in_bone_space; VERIFY(!pGameObject->getDestroy()); float dist = pGameObject->Position().distance_to(P) - pGameObject->Radius(); float power = m_fSecondaryHitPower * RelativePower(dist>0.f?dist:0.f, Radius()); if(power<0.0f) return; float impulse = m_fHitImpulseScale*power*pGameObject->GetMass(); position_in_bone_space.set(0.f,0.f,0.f); CreateHit(pGameObject->ID(),ID(),hit_dir,power,0,position_in_bone_space,impulse,m_eHitTypeBlowout); } } }
void CAmebaZone::Affect(SZoneObjectInfo* O) { CPhysicsShellHolder *pGameObject = smart_cast<CPhysicsShellHolder*>(O->object); if(!pGameObject) return; if(O->zone_ignore) return; #ifdef DEBUG char l_pow[255]; sprintf_s(l_pow, "zone hit. %.1f", Power(distance_to_center(O->object))); if(bDebug) Msg("%s %s",*pGameObject->cName(), l_pow); #endif Fvector hit_dir; hit_dir.set(::Random.randF(-.5f,.5f), ::Random.randF(.0f,1.f), ::Random.randF(-.5f,.5f)); hit_dir.normalize(); Fvector position_in_bone_space; float power = Power(distance_to_center(O->object)); float impulse = m_fHitImpulseScale*power*pGameObject->GetMass(); //статистика по объекту O->total_damage += power; O->hit_num++; if(power > 0.01f) { m_dwDeltaTime = 0; position_in_bone_space.set(0.f,0.f,0.f); CreateHit(pGameObject->ID(),ID(),hit_dir,power,0,position_in_bone_space,impulse,m_eHitTypeBlowout); PlayHitParticles(pGameObject); } }
void CActor::ActorUse() { if (m_holder) { CGameObject* GO = smart_cast<CGameObject*>(m_holder); NET_Packet P; CGameObject::u_EventGen (P, GEG_PLAYER_DETACH_HOLDER, ID()); P.w_u16 (GO->ID()); CGameObject::u_EventSend (P); return; } if(character_physics_support()->movement()->PHCapture()) character_physics_support()->movement()->PHReleaseObject(); if(m_pUsableObject && NULL==m_pObjectWeLookingAt->cast_inventory_item()) { m_pUsableObject->use(this); } if ( m_pInvBoxWeLookingAt && m_pInvBoxWeLookingAt->nonscript_usable() ) { CUIGameSP* pGameSP = smart_cast<CUIGameSP*>(CurrentGameUI()); if ( pGameSP ) //single { if ( !m_pInvBoxWeLookingAt->closed() ) { pGameSP->StartCarBody( this, m_pInvBoxWeLookingAt ); } } return; } if(!m_pUsableObject||m_pUsableObject->nonscript_usable()) { if(m_pPersonWeLookingAt) { CEntityAlive* pEntityAliveWeLookingAt = smart_cast<CEntityAlive*>(m_pPersonWeLookingAt); VERIFY(pEntityAliveWeLookingAt); if (IsGameTypeSingle()) { if(pEntityAliveWeLookingAt->g_Alive()) { TryToTalk(); }else { //только если находимся в режиме single CUIGameSP* pGameSP = smart_cast<CUIGameSP*>(CurrentGameUI()); if ( pGameSP ) { if ( !m_pPersonWeLookingAt->deadbody_closed_status() ) { if(pEntityAliveWeLookingAt->AlreadyDie() && pEntityAliveWeLookingAt->GetLevelDeathTime()+3000 < Device.dwTimeGlobal) // 99.9% dead pGameSP->StartCarBody(this, m_pPersonWeLookingAt ); } } } } } collide::rq_result& RQ = HUD().GetCurrentRayQuery(); CPhysicsShellHolder* object = smart_cast<CPhysicsShellHolder*>(RQ.O); u16 element = BI_NONE; if(object) element = (u16)RQ.element; if(object && Level().IR_GetKeyState(DIK_LSHIFT)) { bool b_allow = !!pSettings->line_exist("ph_capture_visuals",object->cNameVisual()); if(b_allow && !character_physics_support()->movement()->PHCapture()) { character_physics_support()->movement()->PHCaptureObject( object, element ); } } else { if (object && smart_cast<CHolderCustom*>(object)) { NET_Packet P; CGameObject::u_EventGen (P, GEG_PLAYER_ATTACH_HOLDER, ID()); P.w_u16 (object->ID()); CGameObject::u_EventSend (P); return; } } } }
void CBlackGraviArtefact::GraviStrike() { xr_list<s16> elements_list; xr_list<Fvector> bone_position_list; Fvector object_pos ; Fvector strike_dir ; rq_storage.r_clear (); for(GAME_OBJECT_LIST_it it = m_GameObjectList.begin(); m_GameObjectList.end() != it; ++it) { CPhysicsShellHolder* pGameObject = *it; if(pGameObject->Visual()) pGameObject->Center(object_pos); else object_pos.set(pGameObject->Position()); strike_dir.sub(object_pos, Position()); float distance = strike_dir.magnitude(); float impulse = 100.f*m_fStrikeImpulse * (1.f - (distance/m_fRadius)* (distance/m_fRadius)); if(impulse > .001f) { //? BOOL enabled = getEnabled(); //? setEnabled (FALSE); impulse *= CExplosive::ExplosionEffect (rq_storage,NULL,pGameObject, Position(),m_fRadius); //? setEnabled (enabled); } float hit_power ; CEntityAlive* pEntityAlive = smart_cast<CEntityAlive*>(pGameObject); if(pGameObject->m_pPhysicsShell) hit_power = 0; else if(pEntityAlive && pEntityAlive->g_Alive() && pEntityAlive->character_physics_support()->movement()->CharacterExist()) hit_power = 0; else hit_power = impulse; if(impulse > .001f) { while(!elements_list.empty()) { s16 element = elements_list.front(); Fvector bone_pos = bone_position_list.front(); NET_Packet P; SHit HS; HS.GenHeader(GE_HIT, pGameObject->ID()); // u_EventGen (P,GE_HIT, pGameObject->ID()); HS.whoID =ID(); // P.w_u16 (ID()); HS.weaponID = ID(); // P.w_u16 (ID()); HS.dir = strike_dir; // P.w_dir (strike_dir); HS.power = hit_power; // P.w_float (hit_power); HS.boneID = element; // P.w_s16 (element); HS.p_in_bone_space = bone_pos; // P.w_vec3 (bone_pos); HS.impulse = impulse; // P.w_float (impulse); HS.hit_type = (ALife::eHitTypeWound); // P.w_u16 (u16(ALife::eHitTypeWound)); HS.Write_Packet(P); u_EventSend (P); elements_list.pop_front(); bone_position_list.pop_front(); } } } }
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 CActor::ActorUse() { //mstate_real = 0; PickupModeOn(); if (m_holder) { CGameObject* GO = smart_cast<CGameObject*>(m_holder); NET_Packet P; CGameObject::u_EventGen (P, GEG_PLAYER_DETACH_HOLDER, ID()); P.w_u32 (GO->ID()); CGameObject::u_EventSend (P); return; } if(character_physics_support()->movement()->PHCapture()) character_physics_support()->movement()->PHReleaseObject(); if(m_pUsableObject)m_pUsableObject->use(this); if(m_pInvBoxWeLookingAt && m_pInvBoxWeLookingAt->nonscript_usable()) { CUIGameSP* pGameSP = smart_cast<CUIGameSP*>(HUD().GetUI()->UIGame()); if(pGameSP) pGameSP->StartCarBody(this, m_pInvBoxWeLookingAt ); return; } if(!m_pUsableObject||m_pUsableObject->nonscript_usable()) { if(m_pPersonWeLookingAt) { CEntityAlive* pEntityAliveWeLookingAt = smart_cast<CEntityAlive*>(m_pPersonWeLookingAt); VERIFY(pEntityAliveWeLookingAt); if (GameID()==GAME_SINGLE) { if(pEntityAliveWeLookingAt->g_Alive()) { TryToTalk(); } //обыск трупа else if(!Level().IR_GetKeyState(DIK_LSHIFT)) { //только если находимся в режиме single CUIGameSP* pGameSP = smart_cast<CUIGameSP*>(HUD().GetUI()->UIGame()); if(pGameSP)pGameSP->StartCarBody(this, m_pPersonWeLookingAt ); } } } collide::rq_result& RQ = HUD().GetCurrentRayQuery(); CPhysicsShellHolder* object = smart_cast<CPhysicsShellHolder*>(RQ.O); u16 element = BI_NONE; if(object) element = (u16)RQ.element; if(object && Level().IR_GetKeyState(DIK_LSHIFT)) { bool b_allow = !!pSettings->line_exist("ph_capture_visuals",object->cNameVisual()); if(b_allow && !character_physics_support()->movement()->PHCapture()) { character_physics_support()->movement()->PHCaptureObject(object,element); } } else { if (object && smart_cast<CHolderCustom*>(object)) { NET_Packet P; CGameObject::u_EventGen (P, GEG_PLAYER_ATTACH_HOLDER, ID()); P.w_u32 (object->ID()); CGameObject::u_EventSend (P); return; } } } }