void CActor::OnRender () { if (!bDebug) return; if ((dbg_net_Draw_Flags.is_any((1<<5)))) character_physics_support()->movement()->dbg_Draw (); OnRender_Network(); inherited::OnRender(); }
bool CActor::CanAccelerate () { bool can_accel = !conditions().IsLimping() && !character_physics_support()->movement()->PHCapture() && // && !m_bZoomAimingMode // && !(mstate_real&mcLookout) (m_time_lock_accel < Device.dwTimeGlobal) ; return can_accel; }
void CPoltergeist::Hide() { if (state_invisible) return; state_invisible = true; setVisible (false); m_current_position = Position (); character_physics_support()->movement()->DestroyCharacter(); ability()->on_hide (); }
void CCustomMonster::reload (LPCSTR section) { sound().reload (section); CEntityAlive::reload (section); if (character_physics_support()) material().reload (section); movement().reload (section); load_killer_clsids (section); m_far_plane_factor = READ_IF_EXISTS(pSettings,r_float,section,"far_plane_factor",1.f); m_fog_density_factor = READ_IF_EXISTS(pSettings,r_float,section,"fog_density_factor",.05f); m_panic_threshold = pSettings->r_float(section,"panic_threshold"); }
void CActor::OnRender () { #ifdef DEBUG if (inventory().ActiveItem()) inventory().ActiveItem()->OnRender(); #endif if (!bDebug) return; if ((dbg_net_Draw_Flags.is_any(dbg_draw_actor_phys))) character_physics_support()->movement()->dbg_Draw (); OnRender_Network(); inherited::OnRender(); }
BOOL CActorMP::net_Relevant () { if (OnClient()) { if (!g_Alive()) return (false); if (m_i_am_dead) return (false); } if (character_physics_support()->IsRemoved()) return (false); actor_mp_state state; fill_state (state); return (m_state_holder.relevant(state)); }
bool CActor::g_LadderOrient() { Fvector leader_norm; character_physics_support()->movement()->GroundNormal(leader_norm); if(_abs(leader_norm.y)>M_SQRT1_2) return false; //leader_norm.y=0.f; float mag=leader_norm.magnitude(); if(mag<EPS_L) return false; leader_norm.div(mag); leader_norm.invert(); Fmatrix M;M.set(Fidentity); M.k.set(leader_norm); M.j.set(0.f,1.f,0.f); generate_orthonormal_basis1(M.k,M.j,M.i); M.i.invert(); //M.j.invert(); //Fquaternion q1,q2,q3; //q1.set(XFORM()); //q2.set(M); //q3.slerp(q1,q2,dt); //Fvector angles1,angles2,angles3; //XFORM().getHPB(angles1.x,angles1.y,angles1.z); //M.getHPB(angles2.x,angles2.y,angles2.z); ////angle_lerp(angles3.x,angles1.x,angles2.x,dt); ////angle_lerp(angles3.y,angles1.y,angles2.y,dt); ////angle_lerp(angles3.z,angles1.z,angles2.z,dt); //angles3.lerp(angles1,angles2,dt); ////angle_lerp(angles3.y,angles1.y,angles2.y,dt); ////angle_lerp(angles3.z,angles1.z,angles2.z,dt); //angle_lerp(angles3.x,angles1.x,angles2.x,dt); //XFORM().setHPB(angles3.x,angles3.y,angles3.z); Fvector position; position.set(Position()); //XFORM().rotation(q3); VERIFY2(_valid(M),"Invalide matrix in g_LadderOrient"); XFORM().set(M); VERIFY2(_valid(position),"Invalide position in g_LadderOrient"); Position().set(position); VERIFY(_valid(XFORM())); return true; }
void CCustomMonster::reinit () { CScriptEntity::reinit (); CEntityAlive::reinit (); if (character_physics_support()) material().reinit (); movement().reinit (); sound().reinit (); m_client_update_delta = 0; m_last_client_update_time = Device.dwTimeGlobal; eye_pp_stage = 0; m_dwLastUpdateTime = 0xffffffff; m_tEyeShift.set (0,0,0); m_fEyeShiftYaw = 0.f; NET_WasExtrapolating = FALSE; ////////////////////////////////////////////////////////////////////////// // Critical Wounds ////////////////////////////////////////////////////////////////////////// m_critical_wound_type = u32(-1); m_last_hit_time = 0; m_critical_wound_accumulator = 0.f; m_critical_wound_threshold = pSettings->r_float(cNameSect(),"critical_wound_threshold"); m_critical_wound_decrease_quant = pSettings->r_float(cNameSect(),"critical_wound_decrease_quant"); if (m_critical_wound_threshold >= 0) load_critical_wound_bones (); ////////////////////////////////////////////////////////////////////////// m_update_rotation_on_frame = true; m_movement_enabled_before_animation_controller = true; }
CPHDestroyable* CActor::ph_destroyable () { return smart_cast<CPHDestroyable*>(character_physics_support()); }
void CActor::g_cl_ValidateMState(float dt, u32 mstate_wf) { // Lookout if (mstate_wf&mcLookout) mstate_real |= mstate_wf&mcLookout; else mstate_real &= ~mcLookout; if (mstate_real&(mcJump|mcFall|mcLanding|mcLanding2)) mstate_real &= ~mcLookout; // закончить приземление if (mstate_real&(mcLanding|mcLanding2)){ m_fLandingTime -= dt; if (m_fLandingTime<=0.f){ mstate_real &=~ (mcLanding|mcLanding2); mstate_real &=~ (mcFall|mcJump); } } // закончить падение if (character_physics_support()->movement()->gcontact_Was){ if (mstate_real&mcFall){ if (character_physics_support()->movement()->GetContactSpeed()>4.f){ if (fis_zero(character_physics_support()->movement()->gcontact_HealthLost)){ m_fLandingTime = s_fLandingTime1; mstate_real |= mcLanding; }else{ m_fLandingTime = s_fLandingTime2; mstate_real |= mcLanding2; } } } m_bJumpKeyPressed = TRUE; m_fJumpTime = s_fJumpTime; mstate_real &=~ (mcFall|mcJump); } if ((mstate_wf&mcJump)==0) m_bJumpKeyPressed = FALSE; // Зажало-ли меня/уперся - не двигаюсь if (((character_physics_support()->movement()->GetVelocityActual()<0.2f)&&(!(mstate_real&(mcFall|mcJump)))) || character_physics_support()->movement()->bSleep) { mstate_real &=~ mcAnyMove; } if (character_physics_support()->movement()->Environment()==CPHMovementControl::peOnGround || character_physics_support()->movement()->Environment()==CPHMovementControl::peAtWall) { // если на земле гарантированно снимать флажок Jump if (((s_fJumpTime-m_fJumpTime)>s_fJumpGroundTime)&&(mstate_real&mcJump)) { mstate_real &=~ mcJump; m_fJumpTime = s_fJumpTime; } } if(character_physics_support()->movement()->Environment()==CPHMovementControl::peAtWall) { if(!(mstate_real & mcClimb)) { mstate_real |=mcClimb; mstate_real &=~mcSprint; cam_SetLadder(); } } else { if (mstate_real & mcClimb) { cam_UnsetLadder(); } mstate_real &=~mcClimb; }; if (mstate_wf != mstate_real){ if ((mstate_real&mcCrouch)&&((0==(mstate_wf&mcCrouch)) || mstate_real&mcClimb)){ if (character_physics_support()->movement()->ActivateBoxDynamic(0)){ mstate_real &= ~mcCrouch; } } } if(!CanAccelerate()&&isActorAccelerated(mstate_real, IsZoomAimingMode())) { mstate_real ^=mcAccel; }; if (this == Level().CurrentControlEntity()) { bool bOnClimbNow = !!(mstate_real&mcClimb); bool bOnClimbOld = !!(mstate_old&mcClimb); if (bOnClimbNow != bOnClimbOld ) { SetWeaponHideState (INV_STATE_LADDER, bOnClimbNow ); }; /* if ((mstate_real&mcSprint) != (mstate_old&mcSprint)) { CHudItem* pHudItem = smart_cast<CHudItem*>(inventory().ActiveItem()); if (pHudItem) pHudItem->onMovementChanged(mcSprint); }; */ }; };
void CActor::g_cl_CheckControls(u32 mstate_wf, Fvector &vControlAccel, float &Jump, float dt) { mstate_old = mstate_real; vControlAccel.set (0,0,0); if (!(mstate_real&mcFall) && (character_physics_support()->movement()->Environment()==CPHMovementControl::peInAir)) { m_fFallTime -= dt; if (m_fFallTime<=0.f){ m_fFallTime = s_fFallTime; mstate_real |= mcFall; mstate_real &=~ mcJump; } } if(!CanMove()) { if(mstate_wf&mcAnyMove) { StopAnyMove(); mstate_wf &= ~mcAnyMove; mstate_wf &= ~mcJump; } //character_physics_support()->movement()->EnableCharacter(); //return; } // update player accel if (mstate_wf&mcFwd) vControlAccel.z += 1; if (mstate_wf&mcBack) vControlAccel.z += -1; if (mstate_wf&mcLStrafe) vControlAccel.x += -1; if (mstate_wf&mcRStrafe) vControlAccel.x += 1; if (character_physics_support()->movement()->Environment()==CPHMovementControl::peOnGround || character_physics_support()->movement()->Environment()==CPHMovementControl::peAtWall ) { // crouch if ((0==(mstate_real&mcCrouch))&&(mstate_wf&mcCrouch)) { if(mstate_real&mcClimb) { mstate_wf&=~mcCrouch; } else { character_physics_support()->movement()->EnableCharacter(); bool Crouched = false; if (isActorAccelerated(mstate_wf, IsZoomAimingMode())) Crouched = character_physics_support()->movement()->ActivateBoxDynamic(1); else Crouched = character_physics_support()->movement()->ActivateBoxDynamic(2); if (Crouched) mstate_real |= mcCrouch; } } // jump m_fJumpTime -= dt; if ( CanJump() && (mstate_wf&mcJump) ) { mstate_real |= mcJump; m_bJumpKeyPressed = TRUE; Jump = m_fJumpSpeed; m_fJumpTime = s_fJumpTime; //уменьшить силу игрока из-за выполненого прыжка if (!GodMode()) conditions().ConditionJump(inventory().TotalWeight() / MaxCarryWeight()); } /* if(m_bJumpKeyPressed) Jump = m_fJumpSpeed; */ // mask input into "real" state u32 move = mcAnyMove|mcAccel; if (((mstate_real&mcCrouch))) { if (!isActorAccelerated(mstate_real, IsZoomAimingMode()) && isActorAccelerated(mstate_wf, IsZoomAimingMode())) { character_physics_support()->movement()->EnableCharacter(); if(!character_physics_support()->movement()->ActivateBoxDynamic(1))move &=~mcAccel; } if (isActorAccelerated(mstate_real, IsZoomAimingMode()) && !isActorAccelerated(mstate_wf, IsZoomAimingMode())) { character_physics_support()->movement()->EnableCharacter(); if(character_physics_support()->movement()->ActivateBoxDynamic(2))mstate_real &=~mcAccel; } } if ((mstate_wf&mcSprint) && !CanSprint()) { mstate_wf &= ~mcSprint; } mstate_real &= (~move); mstate_real |= (mstate_wf & move); if(mstate_wf&mcSprint) mstate_real|=mcSprint; else mstate_real&=~mcSprint; if(!(mstate_real&(mcFwd|mcLStrafe|mcRStrafe))||mstate_real&(mcCrouch|mcClimb)|| !isActorAccelerated(mstate_wf, IsZoomAimingMode())) { mstate_real&=~mcSprint; mstate_wishful&=~mcSprint; } // check player move state if (mstate_real&mcAnyMove) { BOOL bAccelerated = isActorAccelerated(mstate_real, IsZoomAimingMode())&&CanAccelerate(); // correct "mstate_real" if opposite keys pressed if (_abs(vControlAccel.z)<EPS) mstate_real &= ~(mcFwd+mcBack ); if (_abs(vControlAccel.x)<EPS) mstate_real &= ~(mcLStrafe+mcRStrafe); // normalize and analyze crouch and run float scale = vControlAccel.magnitude(); if (scale>EPS) { scale = m_fWalkAccel/scale; if (bAccelerated) if (mstate_real&mcBack) scale *= m_fRunBackFactor; else scale *= m_fRunFactor; else if (mstate_real&mcBack) scale *= m_fWalkBackFactor; if (mstate_real&mcCrouch) scale *= m_fCrouchFactor; if (mstate_real&mcClimb) scale *= m_fClimbFactor; if (mstate_real&mcSprint) scale *= m_fSprintFactor; if (mstate_real&(mcLStrafe|mcRStrafe) && !(mstate_real&mcCrouch)) { if (bAccelerated) scale *= m_fRun_StrafeFactor; else scale *= m_fWalk_StrafeFactor; } vControlAccel.mul (scale); }else{ // mstate_real &= ~mcAnyMove; } } }else{ // mstate_real &=~ mcAnyMove; } //------------------------------------------------------------------------------- //transform local dir to world dir Fmatrix mOrient; mOrient.rotateY (-r_model_yaw); mOrient.transform_dir(vControlAccel); //XFORM().transform_dir(vControlAccel); /* if(mstate_real&mcClimb&&mstate_real&mcAnyMove&& inventory().ActiveItem()&&inventory().ActiveItem()->HandDependence()==hd2Hand) { //inventory().ActiveItem()->Deactivate(); inventory().Activate(NO_ACTIVE_SLOT); } */ }
void CActor::NoClipFly(int cmd) { Fvector cur_pos;// = Position(); cur_pos.set(0,0,0); float scale = 1.0f; if(pInput->iGetAsyncKeyState(DIK_LSHIFT)) scale = 0.25f; else if(pInput->iGetAsyncKeyState(DIK_LMENU)) scale = 4.0f; switch(cmd) { case kJUMP: cur_pos.y += 0.1f; break; case kCROUCH: cur_pos.y -= 0.1f; break; case kFWD: cur_pos.z += 0.1f; break; case kBACK: cur_pos.z -= 0.1f; break; case kL_STRAFE: cur_pos.x -= 0.1f; break; case kR_STRAFE: cur_pos.x += 0.1f; break; case kCAM_1: cam_Set(eacFirstEye); break; case kCAM_2: cam_Set(eacLookAt); break; case kCAM_3: cam_Set(eacFreeLook); break; case kNIGHT_VISION: SwitchNightVision(); break; case kTORCH: SwitchTorch(); break; case kDETECTOR: { PIItem det_active = inventory().ItemFromSlot(DETECTOR_SLOT); if(det_active) { CCustomDetector* det = smart_cast<CCustomDetector*>(det_active); det->ToggleDetector(g_player_hud->attached_item(0)!=NULL); return; } } break; case kUSE: ActorUse(); break; } cur_pos.mul(scale); Fmatrix mOrient; mOrient.rotateY(-(cam_Active()->GetWorldYaw())); mOrient.transform_dir(cur_pos); Position().add(cur_pos); character_physics_support()->movement()->SetPosition(Position()); }
void CBaseMonster::update_pos_by_grouping_behaviour () { if ( !m_grouping_behaviour ) { return; } Fvector acc = get_steer_manager()->calc_acceleration(); acc.y = 0; // remove vertical component if ( !m_last_grouping_behaviour_update_tick ) { m_last_grouping_behaviour_update_tick = Device.dwTimeGlobal; } const float dt = 0.001f * (Device.dwTimeGlobal - m_last_grouping_behaviour_update_tick); m_last_grouping_behaviour_update_tick = Device.dwTimeGlobal; const Fvector old_pos = Position(); Fvector offs = acc*dt; const float offs_mag = magnitude(offs); if ( offs_mag < 0.000001f ) { // too little force applied, ignore it and save cpu return; } // this control maximum offset // higher values allow stronger forces, but can lead to jingling const float max_offs = 0.005f; if ( offs_mag > max_offs ) { offs.set_length(0.005f); } Fvector new_pos = old_pos + offs; const u32 old_vertex = ai_location().level_vertex_id(); u32 new_vertex = ai().level_graph().check_position_in_direction(old_vertex, old_pos, new_pos); if ( !ai().level_graph().valid_vertex_id(new_vertex) ) { // aiming out of ai-map, ignore return; } // use physics simulation to slide along obstacles character_physics_support()->movement()->VirtualMoveTo(new_pos, new_pos); if ( !ai().level_graph().valid_vertex_position(new_pos) ) { // aiming out of ai-map, ignore return; } new_vertex = ai().level_graph().check_position_in_direction(old_vertex, old_pos, new_pos); if ( !ai().level_graph().valid_vertex_id(new_vertex) ) { return; } // finally, new position is valid on the ai-map, we can use it character_physics_support()->movement()->SetPosition(new_pos); Position() = new_pos; ai_location().level_vertex(new_vertex); }
void CActor::shedule_Update (u32 DT) { setSVU(OnServer()); //установить режим показа HUD для текущего активного слота CHudItem* pHudItem = smart_cast<CHudItem*>(inventory().ActiveItem()); if(pHudItem && !pHudItem->object().getDestroy()) pHudItem->SetHUDmode(HUDview()); //обновление инвентаря UpdateInventoryOwner (DT); if (GameID() == GAME_SINGLE) GameTaskManager().UpdateTasks (); if(m_holder || !getEnabled() || !Ready()) { m_sDefaultObjAction = NULL; inherited::shedule_Update (DT); /* if (OnServer()) { Check_Weapon_ShowHideState(); }; */ return; } // clamp (DT,0u,100u); float dt = float(DT)/1000.f; // Check controls, create accel, prelimitary setup "mstate_real" //----------- for E3 ----------------------------- // if (Local() && (OnClient() || Level().CurrentEntity()==this)) if (Level().CurrentControlEntity() == this && (!Level().IsDemoPlay() || Level().IsServerDemo())) //------------------------------------------------ { g_cl_CheckControls (mstate_wishful,NET_SavedAccel,NET_Jump,dt); { /* if (mstate_real & mcJump) { NET_Packet P; u_EventGen(P, GE_ACTOR_JUMPING, ID()); P.w_sdir(NET_SavedAccel); P.w_float(NET_Jump); u_EventSend(P); } */ } g_cl_Orientate (mstate_real,dt); g_Orientate (mstate_real,dt); g_Physics (NET_SavedAccel,NET_Jump,dt); g_cl_ValidateMState (dt,mstate_wishful); g_SetAnimation (mstate_real); // Check for game-contacts Fvector C; float R; //m_PhysicMovementControl->GetBoundingSphere (C,R); Center(C); R=Radius(); feel_touch_update (C,R); // Dropping if (b_DropActivated) { f_DropPower += dt*0.1f; clamp (f_DropPower,0.f,1.f); } else { f_DropPower = 0.f; } if (!Level().IsDemoPlay()) { //----------------------------------------------------- mstate_wishful &=~mcAccel; mstate_wishful &=~mcLStrafe; mstate_wishful &=~mcRStrafe; mstate_wishful &=~mcLLookout; mstate_wishful &=~mcRLookout; mstate_wishful &=~mcFwd; mstate_wishful &=~mcBack; extern bool g_bAutoClearCrouch; if (g_bAutoClearCrouch) mstate_wishful &=~mcCrouch; //----------------------------------------------------- } } else { make_Interpolation(); if (NET.size()) { // NET_SavedAccel = NET_Last.p_accel; // mstate_real = mstate_wishful = NET_Last.mstate; g_sv_Orientate (mstate_real,dt ); g_Orientate (mstate_real,dt ); g_Physics (NET_SavedAccel,NET_Jump,dt ); if (!m_bInInterpolation) g_cl_ValidateMState (dt,mstate_wishful); g_SetAnimation (mstate_real); if (NET_Last.mstate & mcCrouch) { if (isActorAccelerated(mstate_real, IsZoomAimingMode())) character_physics_support()->movement()->ActivateBox(1, true); else character_physics_support()->movement()->ActivateBox(2, true); } else character_physics_support()->movement()->ActivateBox(0, true); } mstate_old = mstate_real; } if (this == Level().CurrentViewEntity()) { UpdateMotionIcon (mstate_real); }; NET_Jump = 0; inherited::shedule_Update (DT); //эффектор включаемый при ходьбе if (!pCamBobbing) { pCamBobbing = xr_new<CEffectorBobbing> (); Cameras().AddCamEffector (pCamBobbing); } pCamBobbing->SetState (mstate_real, conditions().IsLimping(), IsZoomAimingMode()); //звук тяжелого дыхания при уталости и хромании if(this==Level().CurrentControlEntity() && !g_pGamePersistent->bDedicatedServer ) { if(conditions().IsLimping() && g_Alive()){ if(!m_HeavyBreathSnd._feedback()){ m_HeavyBreathSnd.play_at_pos(this, Fvector().set(0,ACTOR_HEIGHT,0), sm_Looped | sm_2D); }else{ m_HeavyBreathSnd.set_position(Fvector().set(0,ACTOR_HEIGHT,0)); } }else if(m_HeavyBreathSnd._feedback()){ m_HeavyBreathSnd.stop (); } float bs = conditions().BleedingSpeed(); if(bs>0.6f) { Fvector snd_pos; snd_pos.set(0,ACTOR_HEIGHT,0); if(!m_BloodSnd._feedback()) m_BloodSnd.play_at_pos(this, snd_pos, sm_Looped | sm_2D); else m_BloodSnd.set_position(snd_pos); float v = bs+0.25f; m_BloodSnd.set_volume (v); }else{ if(m_BloodSnd._feedback()) m_BloodSnd.stop(); } } //если в режиме HUD, то сама модель актера не рисуется if(!character_physics_support()->IsRemoved()) setVisible (!HUDview ()); //что актер видит перед собой collide::rq_result& RQ = HUD().GetCurrentRayQuery(); if(!input_external_handler_installed() && RQ.O && RQ.range<inventory().GetTakeDist()) { m_pObjectWeLookingAt = smart_cast<CGameObject*>(RQ.O); CGameObject *game_object = smart_cast<CGameObject*>(RQ.O); m_pUsableObject = smart_cast<CUsableScriptObject*>(game_object); m_pInvBoxWeLookingAt = smart_cast<CInventoryBox*>(game_object); inventory().m_pTarget = smart_cast<PIItem>(game_object); m_pPersonWeLookingAt = smart_cast<CInventoryOwner*>(game_object); m_pVehicleWeLookingAt = smart_cast<CHolderCustom*>(game_object); CEntityAlive* pEntityAlive = smart_cast<CEntityAlive*>(game_object); if (GameID() == GAME_SINGLE ) { if (m_pUsableObject && m_pUsableObject->tip_text()) { m_sDefaultObjAction = CStringTable().translate( m_pUsableObject->tip_text() ); } else { if (m_pPersonWeLookingAt && pEntityAlive->g_Alive()) m_sDefaultObjAction = m_sCharacterUseAction; else if (pEntityAlive && !pEntityAlive->g_Alive()) { bool b_allow_drag = !!pSettings->line_exist("ph_capture_visuals",pEntityAlive->cNameVisual()); if(b_allow_drag) m_sDefaultObjAction = m_sDeadCharacterUseOrDragAction; else m_sDefaultObjAction = m_sDeadCharacterUseAction; }else if (m_pVehicleWeLookingAt) m_sDefaultObjAction = m_sCarCharacterUseAction; else if (inventory().m_pTarget && inventory().m_pTarget->CanTake() ) m_sDefaultObjAction = m_sInventoryItemUseAction; //. else if (m_pInvBoxWeLookingAt) //. m_sDefaultObjAction = m_sInventoryBoxUseAction; else m_sDefaultObjAction = NULL; } } } else { inventory().m_pTarget = NULL; m_pPersonWeLookingAt = NULL; m_sDefaultObjAction = NULL; m_pUsableObject = NULL; m_pObjectWeLookingAt = NULL; m_pVehicleWeLookingAt = NULL; m_pInvBoxWeLookingAt = NULL; } // UpdateSleep (); //для свойст артефактов, находящихся на поясе UpdateArtefactsOnBelt (); m_pPhysics_support->in_shedule_Update (DT); Check_for_AutoPickUp (); };
float CActor::GetMass () { return g_Alive()?character_physics_support()->movement()->GetMass():m_pPhysicsShell?m_pPhysicsShell->getMass():0; }
void CActor::Load (LPCSTR section ) { // Msg ("Loading actor: %s",section); inherited::Load (section); material().Load (section); CInventoryOwner::Load (section); memory().Load (section); m_location_manager->Load (section); if (GameID() == GAME_SINGLE) OnDifficultyChanged (); ////////////////////////////////////////////////////////////////////////// ISpatial* self = smart_cast<ISpatial*> (this); if (self) { self->spatial.type |= STYPE_VISIBLEFORAI; self->spatial.type &= ~STYPE_REACTTOSOUND; } ////////////////////////////////////////////////////////////////////////// // m_PhysicMovementControl: General //m_PhysicMovementControl->SetParent (this); Fbox bb;Fvector vBOX_center,vBOX_size; // m_PhysicMovementControl: BOX vBOX_center= pSettings->r_fvector3 (section,"ph_box2_center" ); vBOX_size = pSettings->r_fvector3 (section,"ph_box2_size" ); bb.set (vBOX_center,vBOX_center); bb.grow(vBOX_size); character_physics_support()->movement()->SetBox (2,bb); // m_PhysicMovementControl: BOX vBOX_center= pSettings->r_fvector3 (section,"ph_box1_center" ); vBOX_size = pSettings->r_fvector3 (section,"ph_box1_size" ); bb.set (vBOX_center,vBOX_center); bb.grow(vBOX_size); character_physics_support()->movement()->SetBox (1,bb); // m_PhysicMovementControl: BOX vBOX_center= pSettings->r_fvector3 (section,"ph_box0_center" ); vBOX_size = pSettings->r_fvector3 (section,"ph_box0_size" ); bb.set (vBOX_center,vBOX_center); bb.grow(vBOX_size); character_physics_support()->movement()->SetBox (0,bb); //// m_PhysicMovementControl: Foots //Fvector vFOOT_center= pSettings->r_fvector3 (section,"ph_foot_center" ); //Fvector vFOOT_size = pSettings->r_fvector3 (section,"ph_foot_size" ); //bb.set (vFOOT_center,vFOOT_center); bb.grow(vFOOT_size); ////m_PhysicMovementControl->SetFoots (vFOOT_center,vFOOT_size); // m_PhysicMovementControl: Crash speed and mass float cs_min = pSettings->r_float (section,"ph_crash_speed_min" ); float cs_max = pSettings->r_float (section,"ph_crash_speed_max" ); float mass = pSettings->r_float (section,"ph_mass" ); character_physics_support()->movement()->SetCrashSpeeds (cs_min,cs_max); character_physics_support()->movement()->SetMass (mass); if(pSettings->line_exist(section,"stalker_restrictor_radius")) character_physics_support()->movement()->SetActorRestrictorRadius(CPHCharacter::rtStalker,pSettings->r_float(section,"stalker_restrictor_radius")); if(pSettings->line_exist(section,"stalker_small_restrictor_radius")) character_physics_support()->movement()->SetActorRestrictorRadius(CPHCharacter::rtStalkerSmall,pSettings->r_float(section,"stalker_small_restrictor_radius")); if(pSettings->line_exist(section,"medium_monster_restrictor_radius")) character_physics_support()->movement()->SetActorRestrictorRadius(CPHCharacter::rtMonsterMedium,pSettings->r_float(section,"medium_monster_restrictor_radius")); character_physics_support()->movement()->Load(section); m_fWalkAccel = pSettings->r_float(section,"walk_accel"); m_fJumpSpeed = pSettings->r_float(section,"jump_speed"); m_fRunFactor = pSettings->r_float(section,"run_coef"); m_fRunBackFactor = pSettings->r_float(section,"run_back_coef"); m_fWalkBackFactor = pSettings->r_float(section,"walk_back_coef"); m_fCrouchFactor = pSettings->r_float(section,"crouch_coef"); m_fClimbFactor = pSettings->r_float(section,"climb_coef"); m_fSprintFactor = pSettings->r_float(section,"sprint_koef"); m_fWalk_StrafeFactor = READ_IF_EXISTS(pSettings, r_float, section, "walk_strafe_coef", 1.0f); m_fRun_StrafeFactor = READ_IF_EXISTS(pSettings, r_float, section, "run_strafe_coef", 1.0f); m_fCamHeightFactor = pSettings->r_float(section,"camera_height_factor"); character_physics_support()->movement() ->SetJumpUpVelocity(m_fJumpSpeed); float AirControlParam = pSettings->r_float (section,"air_control_param" ); character_physics_support()->movement() ->SetAirControlParam(AirControlParam); m_fPickupInfoRadius = pSettings->r_float(section,"pickup_info_radius"); m_fSleepTimeFactor = pSettings->r_float(section,"sleep_time_factor"); character_physics_support()->in_Load (section); //загрузить параметры эффектора // LoadShootingEffector ("shooting_effector"); LoadSleepEffector ("sleep_effector"); //загрузить параметры смещения firepoint m_vMissileOffset = pSettings->r_fvector3(section,"missile_throw_offset"); //Weapons = xr_new<CWeaponList> (this); if(!g_pGamePersistent->bDedicatedServer) { LPCSTR hit_snd_sect = pSettings->r_string(section,"hit_sounds"); for(int hit_type=0; hit_type<(int)ALife::eHitTypeMax; ++hit_type) { LPCSTR hit_name = ALife::g_cafHitType2String((ALife::EHitType)hit_type); LPCSTR hit_snds = pSettings->r_string(hit_snd_sect, hit_name); int cnt = _GetItemCount(hit_snds); string128 tmp; VERIFY (cnt!=0); for(int i=0; i<cnt;++i) { sndHit[hit_type].push_back (ref_sound()); sndHit[hit_type].back().create (_GetItem(hit_snds,i,tmp),st_Effect,sg_SourceType); } char buf[256]; ::Sound->create (sndDie[0], strconcat(buf,*cName(),"\\die0"), st_Effect,SOUND_TYPE_MONSTER_DYING); ::Sound->create (sndDie[1], strconcat(buf,*cName(),"\\die1"), st_Effect,SOUND_TYPE_MONSTER_DYING); ::Sound->create (sndDie[2], strconcat(buf,*cName(),"\\die2"), st_Effect,SOUND_TYPE_MONSTER_DYING); ::Sound->create (sndDie[3], strconcat(buf,*cName(),"\\die3"), st_Effect,SOUND_TYPE_MONSTER_DYING); m_HeavyBreathSnd.create (pSettings->r_string(section,"heavy_breath_snd"), st_Effect,SOUND_TYPE_MONSTER_INJURING); m_BloodSnd.create (pSettings->r_string(section,"heavy_blood_snd"), st_Effect,SOUND_TYPE_MONSTER_INJURING); } } if( psActorFlags.test(AF_PSP) ) cam_Set (eacLookAt); else cam_Set (eacFirstEye); // sheduler shedule.t_min = shedule.t_max = 1; // настройки дисперсии стрельбы m_fDispBase = pSettings->r_float (section,"disp_base" ); m_fDispBase = deg2rad(m_fDispBase); m_fDispAim = pSettings->r_float (section,"disp_aim" ); m_fDispAim = deg2rad(m_fDispAim); m_fDispVelFactor = pSettings->r_float (section,"disp_vel_factor" ); m_fDispAccelFactor = pSettings->r_float (section,"disp_accel_factor" ); m_fDispCrouchFactor = pSettings->r_float (section,"disp_crouch_factor"); m_fDispCrouchNoAccelFactor = pSettings->r_float (section,"disp_crouch_no_acc_factor"); LPCSTR default_outfit = READ_IF_EXISTS(pSettings,r_string,section,"default_outfit",0); SetDefaultVisualOutfit (default_outfit); invincibility_fire_shield_1st = READ_IF_EXISTS(pSettings,r_string,section,"Invincibility_Shield_1st",0); invincibility_fire_shield_3rd = READ_IF_EXISTS(pSettings,r_string,section,"Invincibility_Shield_3rd",0); //----------------------------------------- m_AutoPickUp_AABB = READ_IF_EXISTS(pSettings,r_fvector3,section,"AutoPickUp_AABB",Fvector().set(0.02f, 0.02f, 0.02f)); m_AutoPickUp_AABB_Offset = READ_IF_EXISTS(pSettings,r_fvector3,section,"AutoPickUp_AABB_offs",Fvector().set(0, 0, 0)); CStringTable string_table; m_sCharacterUseAction = "character_use"; m_sDeadCharacterUseAction = "dead_character_use"; m_sDeadCharacterUseOrDragAction = "dead_character_use_or_drag"; m_sCarCharacterUseAction = "car_character_use"; m_sInventoryItemUseAction = "inventory_item_use"; m_sInventoryBoxUseAction = "inventory_box_use"; //--------------------------------------------------------------------- m_sHeadShotParticle = READ_IF_EXISTS(pSettings,r_string,section,"HeadShotParticle",0); }
void CActor::cam_Update(float dt, float fFOV) { if(m_holder) return; if(mstate_real & mcClimb&&cam_active!=eacFreeLook) camUpdateLadder(dt); Fvector point={0,CameraHeight(),0}, dangle={0,0,0}; Fmatrix xform,xformR; xform.setXYZ (0,r_torso.yaw,0); xform.translate_over(XFORM().c); // lookout if (this == Level().CurrentControlEntity()) { if (!fis_zero(r_torso_tgt_roll)){ Fvector src_pt,tgt_pt; float radius = point.y*0.5f; float alpha = r_torso_tgt_roll/2.f; float dZ = ((PI_DIV_2-((PI+alpha)/2))); calc_point (tgt_pt,radius,0,alpha); src_pt.set (0,tgt_pt.y,0); // init valid angle float valid_angle = alpha; // xform with roll xformR.setXYZ (-r_torso.pitch,r_torso.yaw,-dZ); Fmatrix33 mat; mat.i = xformR.i; mat.j = xformR.j; mat.k = xformR.k; // get viewport params float w,h; float c = viewport_near(w,h); w/=2.f;h/=2.f; // find tris Fbox box; box.invalidate (); box.modify (src_pt); box.modify (tgt_pt); box.grow (c); // query Fvector bc,bd ; Fbox xf ; xf.xform (box,xform) ; xf.get_CD (bc,bd) ; xrXRC xrc ; xrc.box_options (0) ; xrc.box_query (Level().ObjectSpace.GetStaticModel(), bc, bd) ; u32 tri_count = xrc.r_count(); if (tri_count) { float da = 0.f; BOOL bIntersect = FALSE; Fvector ext = {w,h,VIEWPORT_NEAR/2}; if (test_point(xrc,xform,mat,ext,radius,alpha)){ da = PI/1000.f; if (!fis_zero(r_torso.roll)) da *= r_torso.roll/_abs(r_torso.roll); float angle = 0.f; for (; _abs(angle)<_abs(alpha); angle+=da) if (test_point(xrc,xform,mat,ext,radius,angle)) { bIntersect=TRUE; break; } valid_angle = bIntersect?angle:alpha; } } r_torso.roll = valid_angle*2.f; r_torso_tgt_roll = r_torso.roll; } else { r_torso_tgt_roll = 0.f; r_torso.roll = 0.f; } } if (!fis_zero(r_torso.roll)) { float radius = point.y*0.5f; float valid_angle = r_torso.roll/2.f; calc_point (point,radius,0,valid_angle); dangle.z = (PI_DIV_2-((PI+valid_angle)/2)); } float flCurrentPlayerY = xform.c.y; // Smooth out stair step ups if ((character_physics_support()->movement()->Environment()==peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){ fPrevCamPos += dt*1.5f; if (fPrevCamPos > flCurrentPlayerY) fPrevCamPos = flCurrentPlayerY; if (flCurrentPlayerY-fPrevCamPos>0.2f) fPrevCamPos = flCurrentPlayerY-0.2f; point.y += fPrevCamPos-flCurrentPlayerY; }else{ fPrevCamPos = flCurrentPlayerY; } float _viewport_near = VIEWPORT_NEAR; // calc point xform.transform_tiny (point); CCameraBase* C = cam_Active(); if(eacFirstEye == cam_active) { // CCameraBase* C = cameras[eacFirstEye]; xrXRC xrc ; xrc.box_options (0) ; xrc.box_query (Level().ObjectSpace.GetStaticModel(), point, Fvector().set(VIEWPORT_NEAR,VIEWPORT_NEAR,VIEWPORT_NEAR) ); u32 tri_count = xrc.r_count(); if (tri_count) { _viewport_near = 0.01f; } else { xr_vector<ISpatial*> ISpatialResult; g_SpatialSpacePhysic->q_box(ISpatialResult, 0, STYPE_PHYSIC, point, Fvector().set(VIEWPORT_NEAR,VIEWPORT_NEAR,VIEWPORT_NEAR)); for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++) { CPHShell* pCPHS= smart_cast<CPHShell*>(ISpatialResult[o_it]); if (pCPHS) { _viewport_near = 0.01f; break; } } } } /* { CCameraBase* C = cameras[eacFirstEye]; float oobox_size = 2*VIEWPORT_NEAR; Fmatrix _rot; _rot.k = C->vDirection; _rot.c = C->vPosition; _rot.i.crossproduct (C->vNormal, _rot.k); _rot.j.crossproduct (_rot.k, _rot.i); Fvector vbox; vbox.set (oobox_size, oobox_size, oobox_size); Level().debug_renderer().draw_aabb (C->vPosition, 0.05f, 0.051f, 0.05f, D3DCOLOR_XRGB(0,255,0)); Level().debug_renderer().draw_obb (_rot, Fvector().div(vbox,2.0f), D3DCOLOR_XRGB(255,0,0)); dMatrix3 d_rot; PHDynamicData::FMXtoDMX (_rot, d_rot); CPHActivationShape activation_shape; activation_shape.Create (point, vbox, this); dBodySetRotation (activation_shape.ODEBody(), d_rot); CPHCollideValidator::SetDynamicNotCollide(activation_shape); activation_shape.Activate (vbox,1,1.f,0.0F); point.set (activation_shape.Position()); activation_shape.Destroy (); } */ C->Update (point,dangle); C->f_fov = fFOV; if(eacFirstEye != cam_active) { cameras[eacFirstEye]->Update (point,dangle); cameras[eacFirstEye]->f_fov = fFOV; } if( psActorFlags.test(AF_PSP) ) { Cameras().Update (C); }else { Cameras().Update (cameras[eacFirstEye]); } fCurAVelocity = vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta; vPrevCamDir = cameras[eacFirstEye]->vDirection; if (Level().CurrentEntity() == this) { Level().Cameras().Update (C); if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){ Cameras().ApplyDevice (_viewport_near); } } }
bool CPhysicsShellHolder::has_shell_collision_place( const CPhysicsShellHolder* obj ) const { if(character_physics_support()) return character_physics_support()->has_shell_collision_place( obj ); return false; }
float CActor::CameraHeight() { Fvector R; character_physics_support()->movement()->Box().getsize (R); return m_fCamHeightFactor*( R.y - cammera_into_collision_shift ); }
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 CActor::cam_Update(float dt, float fFOV) { if(m_holder) return; if( (mstate_real & mcClimb) && (cam_active!=eacFreeLook) ) camUpdateLadder(dt); on_weapon_shot_update(); float y_shift =0; if( GamePersistent().GameType() != eGameIDSingle && ik_cam_shift && character_physics_support() && character_physics_support()->ik_controller() ) { y_shift = character_physics_support()->ik_controller()->Shift(); float cam_smooth_k = 1.f; if(_abs(y_shift-current_ik_cam_shift)>ik_cam_shift_tolerance) { cam_smooth_k = 1.f - ik_cam_shift_speed * dt/0.01f; } if(_abs(y_shift)<ik_cam_shift_tolerance/2.f) cam_smooth_k = 1.f - ik_cam_shift_speed * 1.f/0.01f * dt; clamp( cam_smooth_k, 0.f, 1.f ); current_ik_cam_shift = cam_smooth_k * current_ik_cam_shift + y_shift * ( 1.f - cam_smooth_k ); } else current_ik_cam_shift = 0; Fvector point = {0,CameraHeight() + current_ik_cam_shift,0}; Fvector dangle = {0,0,0}; Fmatrix xform; xform.setXYZ (0,r_torso.yaw,0); xform.translate_over(XFORM().c); // lookout if (this == Level().CurrentControlEntity()) cam_Lookout( xform, point.y ); if (!fis_zero(r_torso.roll)) { float radius = point.y*0.5f; float valid_angle = r_torso.roll/2.f; calc_point (point,radius,0,valid_angle); dangle.z = (PI_DIV_2-((PI+valid_angle)/2)); } float flCurrentPlayerY = xform.c.y; // Smooth out stair step ups if ((character_physics_support()->movement()->Environment()==CPHMovementControl::peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){ fPrevCamPos += dt*1.5f; if (fPrevCamPos > flCurrentPlayerY) fPrevCamPos = flCurrentPlayerY; if (flCurrentPlayerY-fPrevCamPos>0.2f) fPrevCamPos = flCurrentPlayerY-0.2f; point.y += fPrevCamPos-flCurrentPlayerY; }else{ fPrevCamPos = flCurrentPlayerY; } float _viewport_near = VIEWPORT_NEAR; // calc point xform.transform_tiny (point); CCameraBase* C = cam_Active(); C->Update (point,dangle); C->f_fov = fFOV; if(eacFirstEye != cam_active) { cameras[eacFirstEye]->Update (point,dangle); cameras[eacFirstEye]->f_fov = fFOV; } if (Level().CurrentEntity() == this) { collide_camera( *cameras[eacFirstEye], _viewport_near, this ); } if( psActorFlags.test(AF_PSP) ) { Cameras().UpdateFromCamera (C); }else { Cameras().UpdateFromCamera (cameras[eacFirstEye]); } fCurAVelocity = vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta; vPrevCamDir = cameras[eacFirstEye]->vDirection; #ifdef DEBUG if( dbg_draw_camera_collision ) { dbg_draw_viewport( *cameras[eacFirstEye], _viewport_near ); dbg_draw_viewport( Cameras(), _viewport_near ); } #endif if (Level().CurrentEntity() == this) { Level().Cameras().UpdateFromCamera (C); if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){ Cameras().ApplyDevice (_viewport_near); } } }
bool CActor::is_on_ground() { return (character_physics_support()->movement()->Environment() != CPHMovementControl::peInAir); }
float CActor::CameraHeight() { Fvector R; character_physics_support()->movement()->Box().getsize (R); return m_fCamHeightFactor*R.y; }
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::g_cl_CheckControls(u32 mstate_wf, Fvector &vControlAccel, float &Jump, float dt) { float cam_eff_factor = 0.0f; mstate_old = mstate_real; vControlAccel.set (0,0,0); if (!(mstate_real&mcFall) && (character_physics_support()->movement()->Environment()==CPHMovementControl::peInAir)) { m_fFallTime -= dt; if (m_fFallTime<=0.f) { m_fFallTime = s_fFallTime; mstate_real |= mcFall; mstate_real &=~ mcJump; } } if(!CanMove()) { if(mstate_wf&mcAnyMove) { StopAnyMove(); mstate_wf &= ~mcAnyMove; mstate_wf &= ~mcJump; } } // update player accel if (mstate_wf&mcFwd) vControlAccel.z += 1; if (mstate_wf&mcBack) vControlAccel.z += -1; if (mstate_wf&mcLStrafe) vControlAccel.x += -1; if (mstate_wf&mcRStrafe) vControlAccel.x += 1; CPHMovementControl::EEnvironment curr_env = character_physics_support()->movement()->Environment(); if(curr_env==CPHMovementControl::peOnGround || curr_env==CPHMovementControl::peAtWall) { // crouch if ((0==(mstate_real&mcCrouch))&&(mstate_wf&mcCrouch)) { if(mstate_real&mcClimb) { mstate_wf&=~mcCrouch; } else { character_physics_support()->movement()->EnableCharacter(); bool Crouched = false; if(isActorAccelerated(mstate_wf, IsZoomAimingMode())) Crouched = character_physics_support()->movement()->ActivateBoxDynamic(1); else Crouched = character_physics_support()->movement()->ActivateBoxDynamic(2); if(Crouched) mstate_real |= mcCrouch; } } // jump m_fJumpTime -= dt; if( CanJump() && (mstate_wf&mcJump) ) { mstate_real |= mcJump; m_bJumpKeyPressed = TRUE; Jump = m_fJumpSpeed; m_fJumpTime = s_fJumpTime; //уменьшить силу игрока из-за выполненого прыжка if (!GodMode()) conditions().ConditionJump(inventory().TotalWeight() / MaxCarryWeight()); } // mask input into "real" state u32 move = mcAnyMove|mcAccel; if(mstate_real&mcCrouch) { if (!isActorAccelerated(mstate_real, IsZoomAimingMode()) && isActorAccelerated(mstate_wf, IsZoomAimingMode())) { character_physics_support()->movement()->EnableCharacter(); if(!character_physics_support()->movement()->ActivateBoxDynamic(1))move &=~mcAccel; } if (isActorAccelerated(mstate_real, IsZoomAimingMode()) && !isActorAccelerated(mstate_wf, IsZoomAimingMode())) { character_physics_support()->movement()->EnableCharacter(); if(character_physics_support()->movement()->ActivateBoxDynamic(2))mstate_real &=~mcAccel; } } if ((mstate_wf&mcSprint) && !CanSprint()) mstate_wf &= ~mcSprint; mstate_real &= (~move); mstate_real |= (mstate_wf & move); if(mstate_wf&mcSprint) mstate_real|=mcSprint; else mstate_real&=~mcSprint; if(!(mstate_real&(mcFwd|mcLStrafe|mcRStrafe))||mstate_real&(mcCrouch|mcClimb)|| !isActorAccelerated(mstate_wf, IsZoomAimingMode())) { mstate_real&=~mcSprint; mstate_wishful&=~mcSprint; } // check player move state if(mstate_real&mcAnyMove) { BOOL bAccelerated = isActorAccelerated(mstate_real, IsZoomAimingMode())&&CanAccelerate(); // correct "mstate_real" if opposite keys pressed if (_abs(vControlAccel.z)<EPS) mstate_real &= ~(mcFwd+mcBack ); if (_abs(vControlAccel.x)<EPS) mstate_real &= ~(mcLStrafe+mcRStrafe); // normalize and analyze crouch and run float scale = vControlAccel.magnitude(); if(scale>EPS) { scale = m_fWalkAccel/scale; if (bAccelerated) if (mstate_real&mcBack) scale *= m_fRunBackFactor; else scale *= m_fRunFactor; else if (mstate_real&mcBack) scale *= m_fWalkBackFactor; if (mstate_real&mcCrouch) scale *= m_fCrouchFactor; if (mstate_real&mcClimb) scale *= m_fClimbFactor; if (mstate_real&mcSprint) scale *= m_fSprintFactor; if (mstate_real&(mcLStrafe|mcRStrafe) && !(mstate_real&mcCrouch)) { if (bAccelerated) scale *= m_fRun_StrafeFactor; else scale *= m_fWalk_StrafeFactor; } vControlAccel.mul (scale); cam_eff_factor = scale; }//scale>EPS }//(mstate_real&mcAnyMove) }//peOnGround || peAtWall if(IsGameTypeSingle() && cam_eff_factor>EPS) { LPCSTR state_anm = NULL; if(mstate_real&mcSprint && !(mstate_old&mcSprint) ) state_anm = "sprint"; else if(mstate_real&mcLStrafe && !(mstate_old&mcLStrafe) ) state_anm = "strafe_left"; else if(mstate_real&mcRStrafe && !(mstate_old&mcRStrafe) ) state_anm = "strafe_right"; else if(mstate_real&mcFwd && !(mstate_old&mcFwd) ) state_anm = "move_fwd"; else if(mstate_real&mcBack && !(mstate_old&mcBack) ) state_anm = "move_back"; if(state_anm) { //play moving cam effect CActor* control_entity = static_cast_checked<CActor*>(Level().CurrentControlEntity()); R_ASSERT2 (control_entity, "current control entity is NULL"); CEffectorCam* ec = control_entity->Cameras().GetCamEffector(eCEActorMoving); if(NULL==ec) { string_path eff_name; xr_sprintf (eff_name, sizeof(eff_name), "%s.anm", state_anm); string_path ce_path; string_path anm_name; strconcat (sizeof(anm_name), anm_name, "camera_effects\\actor_move\\", eff_name); if (FS.exist( ce_path, "$game_anims$", anm_name)) { CAnimatorCamLerpEffectorConst* e = xr_new<CAnimatorCamLerpEffectorConst>(); float max_scale = 70.0f; float factor = cam_eff_factor/max_scale; e->SetFactor (factor); e->SetType (eCEActorMoving); e->SetHudAffect (false); e->SetCyclic (false); e->Start (anm_name); control_entity->Cameras().AddCamEffector(e); } } } } //transform local dir to world dir Fmatrix mOrient; mOrient.rotateY (-r_model_yaw); mOrient.transform_dir(vControlAccel); }
void CCustomMonster::Load (LPCSTR section) { inherited::Load (section); if (character_physics_support()) { material().Load (section); character_physics_support()->movement()->Load (section); } memory().Load (section); movement().Load (section); ////////////////////////////////////////////////////////////////////////// /////////// // m_PhysicMovementControl: General //Fbox bb; //// m_PhysicMovementControl: BOX //Fvector vBOX0_center= pSettings->r_fvector3 (section,"ph_box0_center" ); //Fvector vBOX0_size = pSettings->r_fvector3 (section,"ph_box0_size" ); //bb.set (vBOX0_center,vBOX0_center); bb.grow(vBOX0_size); //m_PhysicMovementControl->SetBox (0,bb); //// m_PhysicMovementControl: BOX //Fvector vBOX1_center= pSettings->r_fvector3 (section,"ph_box1_center" ); //Fvector vBOX1_size = pSettings->r_fvector3 (section,"ph_box1_size" ); //bb.set (vBOX1_center,vBOX1_center); bb.grow(vBOX1_size); //m_PhysicMovementControl->SetBox (1,bb); //// m_PhysicMovementControl: Foots //Fvector vFOOT_center= pSettings->r_fvector3 (section,"ph_foot_center" ); //Fvector vFOOT_size = pSettings->r_fvector3 (section,"ph_foot_size" ); //bb.set (vFOOT_center,vFOOT_center); bb.grow(vFOOT_size); //m_PhysicMovementControl->SetFoots (vFOOT_center,vFOOT_size); //// m_PhysicMovementControl: Crash speed and mass //float cs_min = pSettings->r_float (section,"ph_crash_speed_min" ); //float cs_max = pSettings->r_float (section,"ph_crash_speed_max" ); //float mass = pSettings->r_float (section,"ph_mass" ); //m_PhysicMovementControl->SetCrashSpeeds (cs_min,cs_max); //m_PhysicMovementControl->SetMass (mass); // m_PhysicMovementControl: Frictions /* float af, gf, wf; af = pSettings->r_float (section,"ph_friction_air" ); gf = pSettings->r_float (section,"ph_friction_ground"); wf = pSettings->r_float (section,"ph_friction_wall" ); m_PhysicMovementControl->SetFriction (af,wf,gf); // BOX activate m_PhysicMovementControl->ActivateBox (0); */ //////// Position().y += EPS_L; // m_current = 0; eye_fov = pSettings->r_float(section,"eye_fov"); eye_range = pSettings->r_float(section,"eye_range"); // Health & Armor // fArmor = 0; // Msg ("! cmonster size: %d",sizeof(*this)); }
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 CBaseMonster::add_debug_info (debug::text_tree& root_s) { if ( !g_Alive() ) { return; } typedef debug::text_tree TextTree; //----------------------------------------------- // General //----------------------------------------------- TextTree& general_s = root_s.find_or_add("General"); detail::add_debug_info(general_s, this); TextTree& current_visual_s = general_s.add_line("Current_Visual"); current_visual_s.add_line(*cNameVisual()); general_s.add_line("Health", conditions().GetHealth()); general_s.add_line("Morale", Morale.get_morale()); general_s.add_line("Angry", m_bAngry); general_s.add_line("Growling", m_bGrowling); general_s.add_line("Aggressive", m_bAggressive); general_s.add_line("Sleep", m_bSleep); TextTree& perceptors_s = general_s.find_or_add("Perceptors"); TextTree& visuals_s = perceptors_s.find_or_add("Visual"); float object_range, object_fov; update_range_fov (object_range,object_fov,eye_range,deg2rad(eye_fov)); visuals_s.add_line("Eye_Range", object_range); visuals_s.add_line("FOV", rad2deg(object_fov)); CActor* actor = smart_cast<CActor*>(Level().Objects.net_Find(0)); if ( !actor ) { actor = g_debug_actor; } if ( actor ) { visuals_s.add_line("Actor_Visible", memory().visual().visible_now(actor)); } //----------------------------------------------- // Sounds //----------------------------------------------- TextTree& sounds_s = perceptors_s.find_or_add("Sounds"); sounds_s.add_line("Num_Sounds", SoundMemory.GetNumSounds()); if ( SoundMemory.IsRememberSound() ) { TextTree& last_s = sounds_s.add_line("Last"); SoundElem last_sound; bool last_dangerous; SoundMemory.GetSound(last_sound, last_dangerous); detail::add_debug_info(last_s, last_sound, last_dangerous); if ( SoundMemory.GetNumSounds() > 1 ) { SoundElem first_sound; bool first_dangerous; SoundMemory.GetFirstSound(first_sound, first_dangerous); TextTree& first_s = sounds_s.add_line("First"); detail::add_debug_info(first_s, first_sound, first_dangerous); } } else { sounds_s.add_text("no"); } //----------------------------------------------- // Hits //----------------------------------------------- TextTree& hit_s = perceptors_s.add_line("Hits", HitMemory.get_num_hits()); // Hit if ( HitMemory.is_hit() ) { TextTree& last_hit_object_s = hit_s.add_line("Object"); detail::add_debug_info(last_hit_object_s, smart_cast<CEntity*>(HitMemory.get_last_hit_object())); hit_s.add_line("Time", HitMemory.get_last_hit_time()); hit_s.add_line("Pos", HitMemory.get_last_hit_position()); hit_s.add_line("Dir", HitMemory.get_last_hit_dir()); } //----------------------------------------------- // Corpses //----------------------------------------------- TextTree& corpse_s = general_s.find_or_add("Corpse_Man"); corpse_s.add_line("Current_Corpse", CorpseMan.get_corpse() ? *CorpseMan.get_corpse()->cName() : "none"); corpse_s.add_line("Satiety", make_xrstr("%.2f", GetSatiety())); //----------------------------------------------- // Group behavious //----------------------------------------------- TextTree& group_s = general_s.find_or_add("Group_Behaviour"); group_s.add_line("Team", g_Team()); TextTree& squad_s = group_s.add_line("Squad", g_Squad()); CMonsterSquad* squad = monster_squad().get_squad(this); if ( squad ) { squad_s.add_line("SquadActive", squad->SquadActive()); squad_s.add_line("Im_Leader", squad->GetLeader() == this); detail::add_debug_info(squad_s.add_line("Leader"), squad->GetLeader()); int num_alive = squad->squad_alife_count(); if ( !num_alive && g_Alive() ) { num_alive++; } squad_s.add_line("Alive_Count", num_alive); TextTree& squad_command_s = squad_s.add_line("My_Squad_Command"); squad_command_s.add_line("Command_Type", squad->GetCommand(this).type); TextTree& squad_goal_s = squad_s.add_line("My_Squad_Goal"); squad_goal_s.add_line("Goal_Type", squad->GetGoal(this).type); detail::add_debug_info(squad_goal_s.add_line("Goal_Entity"), squad->GetGoal(this).entity); } group_s.add_line("Group", g_Group()); //----------------------------------------------- // Brain (Fsm & Script) //----------------------------------------------- TextTree& brain_s = root_s.find_or_add("Brain"); TextTree& fsm_s = brain_s.find_or_add("Fsm"); StateMan->add_debug_info(fsm_s); TextTree& script_control_s = brain_s.add_line("Script_Control_Name"); if ( !m_bScriptControl ) { script_control_s.add_text("-"); } else { script_control_s.add_text(GetScriptControlName()); TextTree& cur_script_action_s = brain_s.add_line("Current_Script_Action"); if ( m_tpCurrentEntityAction ) { detail::add_debug_info(cur_script_action_s, m_tpCurrentEntityAction); } else { cur_script_action_s.add_text("-"); } TextTree& next_script_action_s = brain_s.add_line("Next_Script_Action"); if ( m_tpActionQueue.size() ) { detail::add_debug_info(next_script_action_s, m_tpActionQueue.front()); } else { next_script_action_s.add_text("-"); } } //----------------------------------------------- // Control Manager //----------------------------------------------- control().add_debug_info( brain_s.add_line("Control_Manager") ); TextTree& map_home_s = brain_s.add_line("Map_Home"); map_home_s.add_line("min", Home->get_min_radius()); map_home_s.add_line("mid", Home->get_mid_radius()); map_home_s.add_line("max", Home->get_max_radius()); if ( EnemyMan.get_enemy() ) { map_home_s.add_line("Enemy_At_Min", Home->at_min_home( EnemyMan.get_enemy()->Position() )); map_home_s.add_line("Enemy_At_Mid", Home->at_mid_home( EnemyMan.get_enemy()->Position() )); map_home_s.add_line("Enemy_At_Max", Home->at_home ( EnemyMan.get_enemy()->Position() )); map_home_s.add_line("Dist_To_Enemy", Position().distance_to( EnemyMan.get_enemy()->Position() )); } //----------------------------------------------- // Enemies //----------------------------------------------- TextTree& enemies_s = general_s.find_or_add("Enemies"); enemies_s.add_text(EnemyMemory.get_enemies_count()); if ( actor ) { enemies_s.add_line("Actor_Is_Enemy", EnemyMan.is_enemy(actor)); } TextTree& current_enemy_s = enemies_s.find_or_add("Current_Enemy"); if ( EnemyMan.get_enemy() ) { detail::add_enemy_debug_info(current_enemy_s, this, EnemyMan.get_enemy()); current_enemy_s.add_line("Time_Last_Seen", EnemyMan.get_enemy_time_last_seen()); current_enemy_s.add_line("See_Duration", EnemyMan.see_enemy_duration()); } else { current_enemy_s.add_text("0"); } int index = 1; for ( ENEMIES_MAP::const_iterator i = EnemyMemory.get_memory().begin(), e = EnemyMemory.get_memory().end(); i!=e; ++i ) { const CEntityAlive* p_enemy = (*i).first; if ( p_enemy != EnemyMan.get_enemy() ) { TextTree& enemy_s = enemies_s.add_line(make_xrstr("Enemy %i", index++)); detail::add_enemy_debug_info(enemy_s, this, p_enemy); } } //----------------------------------------------- // Animations //----------------------------------------------- TextTree& controller_s = root_s.find_or_add("Controllers"); TextTree& animation_s = controller_s.find_or_add("Animations"); TextTree& current_animation_s = animation_s.add_line(*anim().cur_anim_info().name); CBlend* p_blend = control().animation().current_blend(); if ( !p_blend ) { p_blend = anim().cur_anim_info().blend; } if ( p_blend ) { detail::add_debug_info(current_animation_s, p_blend); current_animation_s.add_line("Script_Animation?", p_blend->motionID == m_tpScriptAnimation); } else { current_animation_s.add_text("0"); } //----------------------------------------------- // Movement //----------------------------------------------- TextTree& movement_s = controller_s.find_or_add("Movement"); movement_s.add_line("Actual", control().path_builder().actual()); movement_s.add_line("Enabled", control().path_builder().enabled()); CEntityAlive *entity = smart_cast<CEntityAlive *>(Level().CurrentEntity()); if ( entity && entity->character_physics_support()->movement() ) { movement_s.add_line("Velocity", entity->character_physics_support()->movement()->GetVelocityActual()); } movement_s.add_line("Position").add_line(Position()); movement_s.add_line("Level_Vertex_ID", ai_location().level_vertex_id()); movement_s.add_line("Game_Vertex_ID", ai_location().game_vertex_id()); detail::add_debug_info(movement_s.add_line("Orientation_Current"), movement().body_orientation().current); detail::add_debug_info(movement_s.add_line("Orientation_Target"), movement().body_orientation().target); movement_s.add_line("Rotation_Speed", movement().body_orientation().speed); const char* pc_path_type = "undefined"; switch ( movement().path_type() ) { case MovementManager::ePathTypePatrolPath: pc_path_type = "Patrol_Path"; break; case MovementManager::ePathTypeGamePath: pc_path_type = "Game_Path"; break; case MovementManager::ePathTypeLevelPath: pc_path_type = "Level_Path"; break; } movement_s.add_line("Path_Type", pc_path_type); if ( movement().path_type() == MovementManager::ePathTypePatrolPath ) { movement_s.add_line("Path_Name", *movement().patrol().path_name()); movement_s.add_line("Completed", movement().patrol().completed()); movement_s.add_line("Current_Point", movement().patrol().get_current_point_index()); if ( movement().patrol().get_path() && movement().patrol().get_path()->vertex(movement().patrol().get_current_point_index()) ) { movement_s.add_line("Extrapolate", movement().patrol().extrapolate_path()); } else { movement_s.add_line("Extrapolate", "unknown"); } } if ( movement().path_type() == MovementManager::ePathTypeGamePath ) { movement_s.add_line("Completed", movement().game_path().completed()); movement_s.add_line("Path_Size", movement().game_path().path().size()); movement_s.add_line("Current_Point", movement().game_path().intermediate_index()); } TextTree& level_s = movement_s.add_line("Level"); level_s.add_line("Path_Size", movement().level_path().path().size()); level_s.add_line("Start_Vertex", movement().level_path().path().empty() ? -1 : movement().level_path().path().front()); level_s.add_line("End_Vertex", movement().level_path().path().empty() ? -1 : movement().level_path().path().back()); if ( !movement().detail().path().empty() ) { TextTree& detail_s = movement_s.add_line("Detail"); detail_s.add_line("Velocities", movement().detail().velocities().size()); detail_s.add_line("Extrapolate", movement().detail().extrapolate_length()); detail_s.add_line("Path_Size", movement().detail().path().size()); detail_s.add_line("Start_Point").add_line(movement().detail().path().front().position); detail_s.add_line("Dest_Point").add_line(movement().detail().path().back().position); TextTree& current_point_s = detail_s.add_line("Current_Point"); current_point_s.add_line("Index", movement().detail().curr_travel_point_index()); current_point_s.add_line("Position").add_line(movement().detail().path()[movement().detail().curr_travel_point_index()].position); CDetailPathManager::STravelParams current_velocity = movement().detail().velocity(movement().detail().path()[movement().detail().curr_travel_point_index()].velocity); detail_s.add_line("linear", current_velocity.linear_velocity); detail_s.add_line("angular", rad2deg(current_velocity.real_angular_velocity)); detail_s.add_line("speed(calc)", movement().speed()); detail_s.add_line("speed(physics)", movement().speed(character_physics_support()->movement())); } if ( movement().detail().use_dest_orientation() ) { movement_s.add_line("Orientation", movement().detail().dest_direction()); } else { movement_s.add_line("Orientation", "no"); } TextTree& atackdist_s = controller_s.find_or_add("Attack_Distance"); atackdist_s.add_line("Mind_Dist", make_xrstr("%.3f", MeleeChecker.get_min_distance())); atackdist_s.add_line("Max_Dist", make_xrstr("%.3f", MeleeChecker.get_max_distance())); atackdist_s.add_line("As_Step", make_xrstr("%.3f", MeleeChecker.dbg_as_step())); atackdist_s.add_line("As_MinDist", make_xrstr("%.3f", MeleeChecker.dbg_as_min_dist())); TextTree& restrictions_s = movement_s.add_line("Restrictions"); if ( movement().restrictions().out_restrictions().size() || movement().restrictions().in_restrictions().size() || movement().restrictions().base_out_restrictions().size() || movement().restrictions().base_in_restrictions().size() ) { detail::add_debug_info_restrictions(restrictions_s.add_line("out"), *movement().restrictions().out_restrictions()); detail::add_debug_info_restrictions(restrictions_s.add_line("in"), *movement().restrictions().in_restrictions()); detail::add_debug_info_restrictions(restrictions_s.add_line("base_out"), *movement().restrictions().base_out_restrictions()); detail::add_debug_info_restrictions(restrictions_s.add_line("base_in"), *movement().restrictions().base_in_restrictions()); restrictions_s.add_line("Actor_Accessible?", actor ? movement().restrictions().accessible(actor->Position()) : false); } else { restrictions_s.add_text("-"); } //----------------------------------------------- // Sound Player //----------------------------------------------- TextTree& sound_player_s = controller_s.find_or_add("Sound_Player"); sound_player_s.add_line("Num_Sounds", sound().objects().size()); typedef CSoundPlayer::SOUND_COLLECTIONS::const_iterator SoundIterator; u32 object_count = 0; for ( SoundIterator i=sound().objects().begin(), e=sound().objects().end(); i!=e; ++i ) { object_count += (*i).second.second->m_sounds.size(); } TextTree& now_playing_s = sound_player_s.add_line("Objects", object_count); typedef xr_vector<CSoundPlayer::CSoundSingle>::const_iterator SoundSingleIterator; index = 1; for ( SoundSingleIterator i=sound().playing_sounds().begin(), e=sound().playing_sounds().end(); i!=e; ++i ) { xr_string source = (*i).m_sound->_handle() ? (*i).m_sound->_handle()->file_name() : "no source"; xr_string status = "not yet started"; if ( Device.dwTimeGlobal >= (*i).m_start_time ) { status = (*i).m_sound->_feedback() ? "playing" : "already played"; } TextTree& current_sound_s = now_playing_s.add_line(make_xrstr("Sound %i", index++)); current_sound_s.add_line(source); current_sound_s.add_line(status); } }
void CActor::cam_Update(float dt, float fFOV) { if(m_holder) return; if( (mstate_real & mcClimb) && (cam_active!=eacFreeLook) ) camUpdateLadder(dt); on_weapon_shot_update(); // Alex ADD: smooth crouch fix if (!CurrentHeight)CurrentHeight = CameraHeight(); float HeightInterpolationSpeed = 9.f; if (CurrentHeight != CameraHeight() && !Device.dwPrecacheFrame) { CurrentHeight = (CurrentHeight * (1.0f - HeightInterpolationSpeed*dt)) + (CameraHeight() * HeightInterpolationSpeed*dt); } Fvector point = { 0, CurrentHeight, 0 }; //Fvector point = {0,CameraHeight(),0}; Fvector dangle = {0,0,0}; Fmatrix xform; xform.setXYZ (0,r_torso.yaw,0); xform.translate_over(XFORM().c); // lookout if (this == Level().CurrentControlEntity()) cam_Lookout( xform, point.y ); if (!fis_zero(r_torso.roll)) { float radius = point.y*0.5f; float valid_angle = r_torso.roll/2.f; calc_point (point,radius,0,valid_angle); dangle.z = (PI_DIV_2-((PI+valid_angle)/2)); } float flCurrentPlayerY = xform.c.y; // Smooth out stair step ups if ((character_physics_support()->movement()->Environment()==peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){ fPrevCamPos += dt*1.5f; if (fPrevCamPos > flCurrentPlayerY) fPrevCamPos = flCurrentPlayerY; if (flCurrentPlayerY-fPrevCamPos>0.2f) fPrevCamPos = flCurrentPlayerY-0.2f; point.y += fPrevCamPos-flCurrentPlayerY; }else{ fPrevCamPos = flCurrentPlayerY; } float _viewport_near = VIEWPORT_NEAR; // calc point xform.transform_tiny (point); CCameraBase* C = cam_Active(); C->Update (point,dangle); C->f_fov = fFOV; if(eacFirstEye != cam_active) { cameras[eacFirstEye]->Update (point,dangle); cameras[eacFirstEye]->f_fov = fFOV; } if (Level().CurrentEntity() == this) collide_camera( *cameras[eacFirstEye], _viewport_near ); if( psActorFlags.test(AF_PSP) ) { Cameras().UpdateFromCamera (C); }else { Cameras().UpdateFromCamera (cameras[eacFirstEye]); } fCurAVelocity = vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta; vPrevCamDir = cameras[eacFirstEye]->vDirection; #ifdef DEBUG if( dbg_draw_camera_collision ) { dbg_draw_viewport( *cameras[eacFirstEye], _viewport_near ); dbg_draw_viewport( Cameras(), _viewport_near ); } #endif if (Level().CurrentEntity() == this) { Level().Cameras().UpdateFromCamera (C); if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){ Cameras().ApplyDevice (_viewport_near); } } }