void CArtefact::UpdateWorkload (u32 dt) { VERIFY(!physics_world()->Processing()); // particles - velocity Fvector vel = {0, 0, 0}; if (H_Parent()) { CPhysicsShellHolder* pPhysicsShellHolder = smart_cast<CPhysicsShellHolder*>(H_Parent()); if(pPhysicsShellHolder) pPhysicsShellHolder->PHGetLinearVell(vel); } CParticlesPlayer::SetParentVel (vel); // UpdateLights (); if(m_activationObj && m_activationObj->IsInProgress()) { CPHUpdateObject::Activate (); m_activationObj->UpdateActivation (); return; } // custom-logic if(!CAttachableItem::enabled()) UpdateCLChild (); }
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::InitServerObject(CSE_Abstract* D) { CPhysicsShellHolder *obj =PPhysicsShellHolder() ; CSE_ALifeDynamicObjectVisual *l_tpALifeDynamicObject = smart_cast<CSE_ALifeDynamicObjectVisual*>(D); VERIFY (l_tpALifeDynamicObject); l_tpALifeDynamicObject->m_tGraphID =obj->ai_location().game_vertex_id(); l_tpALifeDynamicObject->m_tNodeID = obj->ai_location().level_vertex_id(); // l_tpALifePhysicObject->startup_animation=m_startup_anim; D->set_name_replace (""); //. D->s_gameid = u8(GameID()); D->s_RP = 0xff; D->ID = 0xffff; D->ID_Phantom = 0xffff; D->o_Position = obj->Position(); if (ai().get_alife()) l_tpALifeDynamicObject->m_tGraphID = ai().game_graph().current_level_vertex(); else l_tpALifeDynamicObject->m_tGraphID = 0xffff; obj->XFORM().getXYZ (D->o_Angle); D->s_flags.assign (M_SPAWN_OBJECT_LOCAL); D->RespawnTime = 0; }
void CPhysicsShellHolder::correct_spawn_pos() { VERIFY (PPhysicsShell()); if( H_Parent() ) { CPhysicsShellHolder * P = smart_cast<CPhysicsShellHolder*>(H_Parent()); if( P && P->has_shell_collision_place(this) ) return; } Fvector size; Fvector c; get_box (PPhysicsShell(),XFORM(),size,c); R_ASSERT2( _valid( c ), make_string( "object: %s model: %s ", cName().c_str(), cNameVisual().c_str() ) ); R_ASSERT2( _valid( size ), make_string( "object: %s model: %s ", cName().c_str(), cNameVisual().c_str() ) ); R_ASSERT2( _valid( XFORM() ), make_string( "object: %s model: %s ", cName().c_str(), cNameVisual().c_str() ) ); CPHActivationShape activation_shape; activation_shape.Create (c,size,this); activation_shape.set_rotation (XFORM()); PPhysicsShell()->DisableCollision (); activation_shape.Activate (size,1,1.f,M_PI/8.f); //// VERIFY (valid_pos(activation_shape.Position(),phBoundaries)); // if (!valid_pos(activation_shape.Position(),phBoundaries)) { // CPHActivationShape activation_shape; // activation_shape.Create (c,size,this); // activation_shape.set_rotation (XFORM()); // activation_shape.Activate (size,1,1.f,M_PI/8.f); //// VERIFY (valid_pos(activation_shape.Position(),phBoundaries)); // } PPhysicsShell()->EnableCollision (); Fvector ap = activation_shape.Position(); #ifdef DEBUG if (!valid_pos(ap,phBoundaries)) { Msg("not valid position %f,%f,%f",ap.x,ap.y,ap.z); Msg("size %f,%f,%f",size.x,size.y,size.z); Msg("Object: %s",Name()); Msg("Visual: %s",*(cNameVisual())); Msg("Object pos %f,%f,%f",Position().x,Position().y,Position().z); } #endif // DEBUG VERIFY (valid_pos(activation_shape.Position(),phBoundaries)); Fmatrix trans; trans.identity (); trans.c.sub (ap,c); PPhysicsShell()->TransformPosition (trans); PPhysicsShell()->GetGlobalTransformDynamic(&XFORM()); activation_shape.Destroy (); }
void CPHSkeleton::UnsplitSingle(CPHSkeleton* SO) { //Msg("%o,received has %d,",this,m_unsplited_shels.size()); if (0==m_unsplited_shels.size()) return; //. hack CPhysicsShellHolder* obj = PPhysicsShellHolder(); CPhysicsShellHolder* O =SO->PPhysicsShellHolder(); VERIFY2(m_unsplited_shels.size(),"NO_SHELLS !!"); VERIFY2(!O->m_pPhysicsShell,"this has shell already!!!"); CPhysicsShell* newPhysicsShell=m_unsplited_shels.front().first; O->m_pPhysicsShell=newPhysicsShell; VERIFY(_valid(newPhysicsShell->mXFORM)); IKinematics *newKinematics=smart_cast<IKinematics*>(O->Visual()); IKinematics *pKinematics =smart_cast<IKinematics*>(obj->Visual()); Flags64 mask0,mask1; u16 split_bone=m_unsplited_shels.front().second; mask1.assign(pKinematics->LL_GetBonesVisible());//source bones mask pKinematics->LL_SetBoneVisible(split_bone,FALSE,TRUE); pKinematics->CalculateBones_Invalidate (); pKinematics->CalculateBones (TRUE); mask0.assign(pKinematics->LL_GetBonesVisible());//first part mask VERIFY2(mask0.flags,"mask0 -Zero"); mask0.invert(); mask1.and(mask0.flags);//second part mask newKinematics->LL_SetBoneRoot (split_bone); VERIFY2(mask1.flags,"mask1 -Zero"); newKinematics->LL_SetBonesVisible (mask1.flags); newKinematics->CalculateBones_Invalidate (); newKinematics->CalculateBones (TRUE); newPhysicsShell->set_Kinematics(newKinematics); VERIFY(_valid(newPhysicsShell->mXFORM)); newPhysicsShell->ResetCallbacks(split_bone,mask1); VERIFY(_valid(newPhysicsShell->mXFORM)); newPhysicsShell->ObjectInRoot().identity(); if(!newPhysicsShell->isEnabled())O->processing_deactivate(); newPhysicsShell->set_PhysicsRefObject(O); m_unsplited_shels.erase(m_unsplited_shels.begin()); O->setVisible(TRUE); O->setEnabled(TRUE); SO->CopySpawnInit (); CopySpawnInit (); VERIFY3(CheckObjectSize(pKinematics),*(O->cNameVisual()),"Object unsplit whith no size"); VERIFY3(CheckObjectSize(newKinematics),*(O->cNameVisual()),"Object unsplit whith no size"); }
void CBaseGraviZone ::Affect(SZoneObjectInfo* O) { CPhysicsShellHolder* GO = smart_cast<CPhysicsShellHolder*>(O->object); if(!GO) return; ////////////////////////////////////////////////////////////////////////// // зат¤гиваем объет по направлению к центру зоны Fvector throw_in_dir; Fvector zone_center; ThrowInCenter(zone_center); throw_in_dir.sub(zone_center, GO->Position()); float dist = throw_in_dir.magnitude(); float dist_to_radius = dist/Radius(); if(!fis_zero(dist)) { throw_in_dir.mul(1.f/dist); } else throw_in_dir.set(0.f,1.f,0.f); //--------------------------------------------------------- bool CanApplyPhisImpulse = GO->Local() == TRUE; /* if (EA && EA->g_Alive()) { CanApplyPhisImpulse &= (Level().CurrentControlEntity() && Level().CurrentControlEntity() == EA); };*/ //--------------------------------------------------------- if( CheckAffectField(GO,dist_to_radius)&& CanApplyPhisImpulse) { AffectPull(GO,throw_in_dir,dist); } else { ////////////////////////////////////////////////////////////////////////// // выброс аномалии //если врем¤ выброса еще не пришло if(m_dwBlowoutExplosionTime<(u32)m_iPreviousStateTime || m_dwBlowoutExplosionTime>=(u32)m_iStateTime) { AffectPull(GO,throw_in_dir,BlowoutRadiusPercent(GO)*Radius()); return; } AffectThrow(O,GO,throw_in_dir,dist); } }
void CIKLimbsController::Destroy(CGameObject* O) { #ifdef _DEBUG CPhysicsShellHolder* Sh = smart_cast<CPhysicsShellHolder*>(O); VERIFY(Sh); CIKLimbsController* ik = Sh->character_ik_controller(); VERIFY( ik ); VERIFY( ik == this ); #endif O->remove_visual_callback(IKVisualCallback); xr_vector<CIKLimb>::iterator i = _bone_chains.begin(), e = _bone_chains.end(); for(;e!=i;++i) i->Destroy(); _bone_chains.clear(); }
void _stdcall CIKLimbsController:: IKVisualCallback( IKinematics* K ) { //if (Device.Paused()) // return; #ifdef DEBUG if( ph_dbg_draw_mask1.test( phDbgIKOff ) ) return; #endif CGameObject* O=( ( CGameObject* )K->GetUpdateCallbackParam()); CPhysicsShellHolder* Sh = smart_cast<CPhysicsShellHolder*>( O ); VERIFY( Sh ); CIKLimbsController* ik = Sh->character_ik_controller( ); VERIFY( ik ); ik->Calculate( ); }
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; } }
void CPhysicsShellHolder::activate_physic_shell() { VERIFY (!m_pPhysicsShell); create_physic_shell (); Fvector l_fw, l_up; l_fw.set (XFORM().k); l_up.set (XFORM().j); l_fw.mul (2.f); l_up.mul (2.f); Fmatrix l_p1, l_p2; l_p1.set (XFORM()); l_p2.set (XFORM()); l_fw.mul (2.f); l_p2.c.add (l_fw); m_pPhysicsShell->Activate (l_p1, 0, l_p2); if(H_Parent()&&H_Parent()->Visual()) { smart_cast<IKinematics*>(H_Parent()->Visual())->CalculateBones_Invalidate (); smart_cast<IKinematics*>(H_Parent()->Visual())->CalculateBones (TRUE); } smart_cast<IKinematics*>(Visual())->CalculateBones_Invalidate (); smart_cast<IKinematics*>(Visual())->CalculateBones(TRUE); if(!IsGameTypeSingle()) { if(!smart_cast<CCustomRocket*>(this)&&!smart_cast<CGrenade*>(this)) PPhysicsShell()->SetIgnoreDynamic(); } // XFORM().set (l_p1); correct_spawn_pos(); m_pPhysicsShell->set_LinearVel(l_fw); m_pPhysicsShell->GetGlobalTransformDynamic(&XFORM()); if(H_Parent()&&H_Parent()->Visual()) { smart_cast<IKinematics*>(H_Parent()->Visual())->CalculateBones_Invalidate (); smart_cast<IKinematics*>(H_Parent()->Visual())->CalculateBones (TRUE); } CPhysicsShellHolder* P = smart_cast<CPhysicsShellHolder*>( H_Parent() ); if( P ) P->on_child_shell_activate( this ); }
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 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); }
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 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 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 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); } }
static void interactive_motion_diag( LPCSTR message, const CBlend &b, CPhysicsShell *s, float time_left ) { #ifdef DEBUG if(!death_anim_debug) return; const MotionID & m = b.motionID; VERIFY( m.valid() ); VERIFY( s ); IKinematicsAnimated* KA = smart_cast<IKinematicsAnimated*>( s->PKinematics( ) ); VERIFY( KA ); CPhysicsShellHolder* O = smart_cast<CPhysicsShellHolder*>(s->get_ElementByStoreOrder( 0 )->PhysicsRefObject()); VERIFY( O ); LPCSTR motion_name = KA->LL_MotionDefName_dbg( m ).first; Msg( "death anims - interactive_motion:- %s, motion: %s, blend time %f , total blend time %f , time left: %f , obj: %s, model: %s ", message, motion_name, b.timeCurrent, b.timeTotal, time_left, O->cName().c_str(), O->cNameVisual().c_str()); #endif }
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 CPseudoGigant::on_threaten_execute() { // разбросить объекты m_nearest.clear_not_free (); Level().ObjectSpace.GetNearest (m_nearest,Position(), 15.f, NULL); for (u32 i=0;i<m_nearest.size();i++) { CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[i]); if (!obj || !obj->m_pPhysicsShell) continue; Fvector dir; Fvector pos; pos.set(obj->Position()); pos.y += 2.f; dir.sub(pos, Position()); dir.normalize(); obj->m_pPhysicsShell->applyImpulse(dir,20 * obj->m_pPhysicsShell->getMass()); } // играть звук Fvector pos; pos.set (Position()); pos.y += 0.1f; m_sound_threaten_hit.play_at_pos(this,pos); // играть партиклы PlayParticles(m_kick_particles, pos, Direction()); CActor *pA = const_cast<CActor *>(smart_cast<const CActor *>(EnemyMan.get_enemy())); if (!pA) return; if ((pA->MovingState() & ACTOR_DEFS::mcJump) != 0) return; float dist_to_enemy = pA->Position().distance_to(Position()); float hit_value; hit_value = m_kick_damage - m_kick_damage * dist_to_enemy / m_threaten_dist_max; clamp (hit_value,0.f,1.f); // запустить эффектор Actor()->Cameras().AddCamEffector(xr_new<CMonsterEffectorHit>(m_threaten_effector.ce_time,m_threaten_effector.ce_amplitude * hit_value,m_threaten_effector.ce_period_number,m_threaten_effector.ce_power * hit_value)); Actor()->Cameras().AddPPEffector(xr_new<CMonsterEffector>(m_threaten_effector.ppi, m_threaten_effector.time, m_threaten_effector.time_attack, m_threaten_effector.time_release, hit_value)); // развернуть камеру if (pA->cam_Active()) { pA->cam_Active()->Move(Random.randI(2) ? kRIGHT : kLEFT, Random.randF(0.3f * hit_value)); pA->cam_Active()->Move(Random.randI(2) ? kUP : kDOWN, Random.randF(0.3f * hit_value)); } Actor()->lock_accel_for (m_time_kick_actor_slow_down); // Нанести хит NET_Packet l_P; SHit HS; HS.GenHeader (GE_HIT, pA->ID()); // u_EventGen (l_P,GE_HIT, pA->ID()); HS.whoID = (ID()); // l_P.w_u16 (ID()); HS.weaponID = (ID()); // l_P.w_u16 (ID()); HS.dir = (Fvector().set(0.f,1.f,0.f)); // l_P.w_dir (Fvector().set(0.f,1.f,0.f)); HS.power = (hit_value); // l_P.w_float (m_kick_damage); HS.boneID = (smart_cast<IKinematics*>(pA->Visual())->LL_GetBoneRoot()); // l_P.w_s16 (smart_cast<IKinematics*>(pA->Visual())->LL_GetBoneRoot()); HS.p_in_bone_space = (Fvector().set(0.f,0.f,0.f)); // l_P.w_vec3 (Fvector().set(0.f,0.f,0.f)); HS.impulse = (80 * pA->character_physics_support()->movement()->GetMass()); // l_P.w_float (20 * pA->movement_control()->GetMass()); HS.hit_type = ( ALife::eHitTypeStrike); // l_P.w_u16 ( u16(ALife::eHitTypeWound) ); HS.Write_Packet (l_P); u_EventSend (l_P); }
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; }
void CActor::UpdateCL () { if(m_feel_touch_characters>0) { for(xr_vector<CObject*>::iterator it = feel_touch.begin(); it != feel_touch.end(); it++) { CPhysicsShellHolder *sh = smart_cast<CPhysicsShellHolder*>(*it); if(sh&&sh->character_physics_support()) { sh->character_physics_support()->movement()->UpdateObjectBox(character_physics_support()->movement()->PHCharacter()); } } } if(m_holder) m_holder->UpdateEx( currentFOV() ); m_snd_noise -= 0.3f*Device.fTimeDelta; VERIFY2 (_valid(renderable.xform),*cName()); inherited::UpdateCL(); VERIFY2 (_valid(renderable.xform),*cName()); m_pPhysics_support->in_UpdateCL (); VERIFY2 (_valid(renderable.xform),*cName()); if (g_Alive()) PickupModeUpdate (); PickupModeUpdate_COD(); m_bZoomAimingMode = false; CWeapon* pWeapon = smart_cast<CWeapon*>(inventory().ActiveItem()); Device.Statistic->TEST1.Begin (); cam_Update(float(Device.dwTimeDelta)/1000.0f, currentFOV()); Device.Statistic->TEST1.End (); if(Level().CurrentEntity() && this->ID()==Level().CurrentEntity()->ID() ) { psHUD_Flags.set( HUD_CROSSHAIR_RT2, true ); psHUD_Flags.set( HUD_DRAW_RT, true ); } if(pWeapon ) { if(pWeapon->IsZoomed()) { float full_fire_disp = pWeapon->GetFireDispersion(true); CEffectorZoomInertion* S = smart_cast<CEffectorZoomInertion*> (Cameras().GetCamEffector(eCEZoom)); if(S) S->SetParams(full_fire_disp); m_bZoomAimingMode = true; } if(Level().CurrentEntity() && this->ID()==Level().CurrentEntity()->ID() ) { float fire_disp_full = pWeapon->GetFireDispersion(true); HUD().SetCrosshairDisp(fire_disp_full, 0.02f); HUD().ShowCrosshair(pWeapon->use_crosshair()); psHUD_Flags.set( HUD_CROSSHAIR_RT2, pWeapon->show_crosshair() ); psHUD_Flags.set( HUD_DRAW_RT, pWeapon->show_indicators() ); } } else { if(Level().CurrentEntity() && this->ID()==Level().CurrentEntity()->ID() ) { HUD().SetCrosshairDisp(0.f); HUD().ShowCrosshair(false); } } UpdateDefferedMessages(); if (g_Alive()) CStepManager::update(); spatial.type |=STYPE_REACTTOSOUND; if(m_sndShockEffector) { if (this == Level().CurrentViewEntity()) { m_sndShockEffector->Update(); if(!m_sndShockEffector->InWork()) xr_delete(m_sndShockEffector); } else xr_delete(m_sndShockEffector); } }
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 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; } } } }
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 CBurer::UpdateGraviObject() { if ( !m_gravi_object.active ) { return; } if ( !m_gravi_object.enemy || (m_gravi_object.enemy && m_gravi_object.enemy->getDestroy()) ) { m_gravi_object.deactivate(); return; } if ( m_gravi_object.from_pos.distance_to(m_gravi_object.cur_pos) > m_gravi_object.from_pos.distance_to(m_gravi_object.target_pos) ) { m_gravi_object.deactivate(); return; } float dt = float(Device.dwTimeGlobal - m_gravi_object.time_last_update); float dist = dt * float(m_gravi.speed)/1000.f; if (dist < m_gravi.step) return; Fvector new_pos; Fvector dir; dir.sub(m_gravi_object.target_pos,m_gravi_object.cur_pos); dir.normalize(); new_pos.mad(m_gravi_object.cur_pos,dir,dist); // Trace to enemy Fvector enemy_center; m_gravi_object.enemy->Center(enemy_center); dir.sub(enemy_center, new_pos); dir.normalize(); float trace_dist = float(m_gravi.step); collide::rq_result l_rq; if (Level().ObjectSpace.RayPick(new_pos, dir, trace_dist, collide::rqtBoth, l_rq, NULL)) { const CObject *enemy = smart_cast<const CObject *>(m_gravi_object.enemy); if ((l_rq.O == enemy) && (l_rq.range < trace_dist)) { // check for visibility bool b_enemy_visible = false; xr_vector<CObject *> visible_objects; feel_vision_get(visible_objects); // find object for (u32 i = 0; i<visible_objects.size(); i++) { if (visible_objects[i] == enemy) { b_enemy_visible = true; break; } } if (b_enemy_visible) { Fvector impulse_dir; impulse_dir.set(0.0f,0.0f,1.0f); impulse_dir.normalize(); HitEntity(m_gravi_object.enemy, m_gravi.hit_power, m_gravi.impulse_to_enemy, impulse_dir, ALife::eHitTypeStrike, false); m_gravi_object.deactivate(); return; } } } m_gravi_object.cur_pos = new_pos; m_gravi_object.time_last_update = Device.dwTimeGlobal; // --------------------------------------------------------------------- // draw particle CParticlesObject* ps = CParticlesObject::Create(particle_gravi_wave,TRUE); // вычислить позицию и направленность партикла Fmatrix pos; pos.identity(); pos.k.set(dir); Fvector::generate_orthonormal_basis_normalized(pos.k,pos.j,pos.i); // установить позицию pos.translate_over(m_gravi_object.cur_pos); ps->UpdateParent(pos, zero_vel); ps->Play(false); // hit objects m_nearest.clear_not_free (); Level().ObjectSpace.GetNearest (m_nearest,m_gravi_object.cur_pos, m_gravi.radius, NULL); //xr_vector<CObject*> &m_nearest = Level().ObjectSpace.q_nearest; for (u32 i=0;i<m_nearest.size();i++) { CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[i]); if (!obj || !obj->m_pPhysicsShell) continue; Fvector dir; dir.sub(obj->Position(), m_gravi_object.cur_pos); dir.normalize(); obj->m_pPhysicsShell->applyImpulse(dir,m_gravi.impulse_to_objects * obj->m_pPhysicsShell->getMass()); } // играть звук Fvector snd_pos = m_gravi_object.cur_pos; snd_pos.y += 0.5f; if (sound_gravi_wave._feedback()) { sound_gravi_wave.set_position (snd_pos); } else ::Sound->play_at_pos (sound_gravi_wave,0,snd_pos); }