void CPolterTele::tele_find_objects(xr_vector<CObject*> &objects, const Fvector &pos) { m_nearest.clear_not_free (); Level().ObjectSpace.GetNearest (m_nearest, pos, m_pmt_radius, NULL); for (u32 i=0;i<m_nearest.size();i++) { CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[i]); CCustomMonster *custom_monster = smart_cast<CCustomMonster *>(m_nearest[i]); if (!obj || !obj->PPhysicsShell() || !obj->PPhysicsShell()->isActive()|| custom_monster || (obj->spawn_ini() && obj->spawn_ini()->section_exist("ph_heavy")) || (obj->m_pPhysicsShell->getMass() < m_pmt_object_min_mass) || (obj->m_pPhysicsShell->getMass() > m_pmt_object_max_mass) || (obj == m_object) || m_object->CTelekinesis::is_active_object(obj) || !obj->m_pPhysicsShell->get_ApplyByGravity()) continue; Fvector center; Actor()->Center(center); if (trace_object(obj, center) || trace_object(obj, get_head_position(Actor()))) objects.push_back(obj); } }
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 CControlManagerCustom::check_jump_over_physics() { if (!m_man->path_builder().is_moving_on_path()) return; if (!m_man->check_start_conditions(ControlCom::eControlJump)) return; if (!m_object->check_start_conditions(ControlCom::eControlJump)) return; if (m_object->GetScriptControl()) return; Fvector prev_pos = m_object->Position(); float dist_sum = 0.f; for(u32 i = m_man->path_builder().detail().curr_travel_point_index(); i<m_man->path_builder().detail().path().size();i++) { const DetailPathManager::STravelPathPoint &travel_point = m_man->path_builder().detail().path()[i]; // получить список объектов вокруг врага m_nearest.clear_not_free (); Level().ObjectSpace.GetNearest (m_nearest,travel_point.position, m_object->Radius(), NULL); for (u32 k=0;k<m_nearest.size();k++) { CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[k]); if (!obj || !obj->PPhysicsShell() || !obj->PPhysicsShell()->isActive() || (obj->Radius() < 0.5f)) continue; if (m_object->Position().distance_to(obj->Position()) < MAX_DIST_SUM / 2) continue; Fvector dir = Fvector().sub(travel_point.position, m_object->Position()); // проверка на Field-Of-View float my_h = m_object->Direction().getH(); float h = dir.getH(); float from = angle_normalize(my_h - deg(8)); float to = angle_normalize(my_h + deg(8)); if (!is_angle_between(h, from, to)) continue; dir = Fvector().sub(obj->Position(), m_object->Position()); // вычислить целевую позицию для прыжка Fvector target; obj->Center(target); target.y += obj->Radius(); // -------------------------------------------------------- m_jump->setup_data().flags.set (SControlJumpData::ePrepareSkip, true); m_jump->setup_data().target_object = 0; m_jump->setup_data().target_position = target; jump(m_jump->setup_data()); return; } dist_sum += prev_pos.distance_to(travel_point.position); if (dist_sum > MAX_DIST_SUM) break; prev_pos = travel_point.position; } }
bool CBaseGraviZone ::IdleState() { bool result = inherited::IdleState(); m_dwTeleTime += Device.dwTimeDelta; if(!result) { if(m_dwTeleTime> m_dwTimeToTele) { for(OBJECT_INFO_VEC_IT it = m_ObjectInfoMap.begin(); m_ObjectInfoMap.end() != it; ++it) { CPhysicsShellHolder * GO = smart_cast<CPhysicsShellHolder *>( (*it).object ); if(GO && GO->PPhysicsShell() && Telekinesis().is_active_object(GO)) { Telekinesis().deactivate(GO); StopTeleParticles(GO); } } } if(m_dwTeleTime> m_dwTimeToTele + m_dwTelePause) { m_dwTeleTime = 0; for(OBJECT_INFO_VEC_IT it = m_ObjectInfoMap.begin(); m_ObjectInfoMap.end() != it; ++it) { CPhysicsShellHolder * GO = smart_cast<CPhysicsShellHolder *>( (*it).object ); if(GO && GO->PPhysicsShell() && !Telekinesis().is_active_object(GO)) { Telekinesis().activate(GO, 0.1f, m_fTeleHeight, m_dwTimeToTele); PlayTeleParticles(GO); } } } } else Telekinesis().deactivate(); return result; }
void CPHDestroyable::PhysicallyRemoveSelf() { CPhysicsShellHolder *obj =PPhysicsShellHolder() ; CActor *A =smart_cast<CActor*>(obj) ; if(A) { A->character_physics_support()->SetRemoved(); } else { //obj->PPhysicsShell()->PureStep(); obj->PPhysicsShell()->Disable(); obj->PPhysicsShell()->DisableCollision(); } obj->setVisible(FALSE); obj->setEnabled(FALSE); }
void CPHCollisionDamageReceiver::Init() { CPhysicsShellHolder *sh =PPhysicsShellHolder (); IKinematics *K =smart_cast<IKinematics*>(sh->Visual()); CInifile *ini=K->LL_UserData(); if(ini->section_exist("collision_damage")) { CInifile::Sect& data = ini->r_section("collision_damage"); for (CInifile::SectCIt I=data.Data.begin(); I!=data.Data.end(); I++){ const CInifile::Item& item = *I; u16 index = K->LL_BoneID(*item.first); R_ASSERT3(index != BI_NONE, "Wrong bone name", *item.first); BoneInsert(index,float(atof(*item.second))); CODEGeom* og= sh->PPhysicsShell()->get_GeomByID(index); //R_ASSERT3(og, "collision damage bone has no physics collision", *item.first); if(og)og->add_obj_contact_cb(CollisionCallback); } } }
void CPHShellSimpleCreator::CreatePhysicsShell() { CPhysicsShellHolder* owner = smart_cast<CPhysicsShellHolder*>(this); VERIFY(owner); if (!owner->Visual()) return; CKinematics* pKinematics = smart_cast<CKinematics*>(owner->Visual()); VERIFY (pKinematics); if(owner->PPhysicsShell()) return; owner->PPhysicsShell() = P_create_Shell(); #ifdef DEBUG owner->PPhysicsShell()->dbg_obj=owner; #endif owner->m_pPhysicsShell->build_FromKinematics (pKinematics,0); owner->PPhysicsShell()->set_PhysicsRefObject (owner); //m_pPhysicsShell->SmoothElementsInertia(0.3f); owner->PPhysicsShell()->mXFORM.set (owner->XFORM()); owner->PPhysicsShell()->SetAirResistance (0.001f, 0.02f); }
bool CPHSkeleton::Spawn(CSE_Abstract *D) { CSE_PHSkeleton *po = smart_cast<CSE_PHSkeleton*>(D); VERIFY (po); m_flags = po->_flags; CSE_Visual *visual = smart_cast<CSE_Visual*>(D); VERIFY (visual); m_startup_anim = visual->startup_animation; if(po->_flags.test(CSE_PHSkeleton::flSpawnCopy)) { CPHSkeleton* source=smart_cast<CPHSkeleton*>(Level().Objects.net_Find(po->source_id)); R_ASSERT2(source,"no source"); source->UnsplitSingle(this); m_flags.set (CSE_PHSkeleton::flSpawnCopy,FALSE); po->_flags.set (CSE_PHSkeleton::flSpawnCopy,FALSE); po->source_id =BI_NONE; return true; } else { CPhysicsShellHolder *obj = PPhysicsShellHolder(); IKinematics *K = NULL; if (obj->Visual()) { K= smart_cast<IKinematics*>(obj->Visual()); if(K) { K->LL_SetBoneRoot(po->saved_bones.root_bone); K->LL_SetBonesVisible(po->saved_bones.bones_mask); } } SpawnInitPhysics(D); RestoreNetState(po); if(obj->PPhysicsShell()&&obj->PPhysicsShell()->isFullActive()) obj->PPhysicsShell()->GetGlobalTransformDynamic(&obj->XFORM()); CPHDestroyableNotificate::spawn_notificate(D); if(K) { CInifile* ini=K->LL_UserData(); if(ini&&ini->section_exist("collide")) { if(ini->line_exist("collide","not_collide_parts")) { CGID gr= CPHCollideValidator::RegisterGroup(); obj->PPhysicsShell()->RegisterToCLGroup(gr); } } if(ini&&ini->section_exist("collide_parts")) { if(ini->line_exist("collide_parts","small_object")) { obj->PPhysicsShell()->SetSmall(); } if(ini->line_exist("collide_parts","ignore_small_objects")) { obj->PPhysicsShell()->SetIgnoreSmall(); } } } } return false; }