//------------------------------------------------------------------------
void CVehicleMovementHelicopter::PreProcessMovement(const float deltaTime)
{
	IPhysicalEntity *pPhysics = GetPhysics();
	assert(pPhysics);

	float gravity;

	pe_simulation_params paramsSim;

	if(pPhysics->GetParams(&paramsSim))
		gravity = abs(paramsSim.gravity.z);
	else
		gravity = 9.8f;

	m_engineForce = gravity * m_enginePower;

	const Matrix33 tm(m_PhysPos.q);
	const Ang3 angles = Ang3::GetAnglesXYZ(tm);

	m_workingUpDir = m_engineUpDir;
	//m_workingUpDir += (m_rotorDiskTiltScale * Vec3(m_actionRoll, -m_actionPitch, 0.0f));
	m_workingUpDir += (m_rotorDiskTiltScale * Vec3(angles.y, -angles.x, 0.0f));
	m_workingUpDir = tm * m_workingUpDir;
	m_workingUpDir.NormalizeSafe();

	if(m_noHoveringTimer > 0.0f)
		m_noHoveringTimer -= deltaTime;

}
Exemple #2
0
void CBaseGrabHandler::IgnoreCollision(EntityId eID,unsigned int flags,bool ignore)
{
	IEntity *pGrab = gEnv->pEntitySystem->GetEntity(eID);
	IPhysicalEntity *ppGrab = pGrab ? pGrab->GetPhysics() : NULL;

	if(!ppGrab) return;

	if(ignore)
	{
		// NOTE Dez 14, 2006: <pvl> this whole block just fills in
		// a request structure and passes it to physics
		IEntity *pEnt = m_pActor->GetEntity();

		pe_action_add_constraint ac;
		ac.flags = constraint_inactive|constraint_ignore_buddy;
		ac.pBuddy = pEnt->GetPhysics();
		ac.pt[0].Set(0,0,0);

		ICharacterInstance *pCharacter = pEnt->GetCharacter(0);
		IPhysicalEntity *pPhysEnt = pCharacter?pCharacter->GetISkeletonPose()->GetCharacterPhysics(-1):NULL;

		if(pPhysEnt)
		{
			pe_simulation_params sp;
			pPhysEnt->GetParams(&sp);

			if(sp.iSimClass <= 2)
				ac.pBuddy = pPhysEnt;
		}

		ppGrab->Action(&ac);
	}
	else
	{
		// NOTE Dez 14, 2006: <pvl> the same as the other branch - just
		// fill in a request and pass it to the physics engine
		pe_action_update_constraint uc;
		uc.bRemove = 1;

		ppGrab->Action(&uc);
	}

	// NOTE Dez 14, 2006: <pvl> flag manipulation is basically a legacy
	// code - probably not used anymore, scheduled for removal.
	if(flags)
	{
		pe_params_part pp;
		pp.flagsAND = pp.flagsColliderAND = ~flags;
		pp.flagsOR = pp.flagsColliderOR = flags * (ignore?0:1);

		pe_status_nparts status_nparts;

		for(pp.ipart = ppGrab->GetStatus(&status_nparts)-1; pp.ipart>=0; pp.ipart--)
			ppGrab->SetParams(&pp);
	}
}
bool CStickyProjectile::IsValid() const
{
	if (!IsStuck())
		return false;

	if(m_parentId == 0)
		return true;

	pe_params_part part;
	part.partid = m_stuckPartId;
	IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_parentId);
	if(pEntity)
	{
		if (pEntity->IsHidden())
		{
			return false;
		}
		if(ICharacterInstance* pCharacter = pEntity->GetCharacter(0))
		{
			if(ISkeletonPose* pSkel = pCharacter->GetISkeletonPose())
			{
				IPhysicalEntity* pSkelPhysics = pSkel->GetCharacterPhysics();
				if (pSkelPhysics)
				{
					return pSkelPhysics->GetParams(&part) != 0;
				}
			}
		}
		else
		{
			IPhysicalEntity* pPhysics = pEntity->GetPhysics();
			if (pPhysics)
			{
				return pPhysics->GetParams(&part) != 0;
			}
		}
	}

	return false;
}
void CPlayerStateFly::OnExit( CPlayer& player )
{
    player.CreateScriptEvent("printhud",0,"FlyMode/NoClip OFF");

    pe_player_dynamics simPar;

    IPhysicalEntity* piPhysics = player.GetEntity()->GetPhysics();
    if (!piPhysics || piPhysics->GetParams(&simPar) == 0)
        {
            return;
        }

    CPlayerStateUtil::PhySetNoFly( player, simPar.gravity );
}
Exemple #5
0
//-----------------------------------------------------------------------
void CSpectacularKill::DeathBlow(CActor& targetActor)
{
	CRY_ASSERT_MESSAGE(m_isBusy, "spectacular kill should be in progress when triggering the death blow");
	if (!m_isBusy)
		return;

	if (targetActor.IsDead())
		return;

	Vec3 targetDir = targetActor.GetEntity()->GetForwardDir();

	{
		HitInfo hitInfo;
		hitInfo.shooterId = m_pOwner->GetEntityId();
		hitInfo.targetId = targetActor.GetEntityId();
		hitInfo.damage = 99999.0f; // CERTAIN_DEATH
		hitInfo.dir = targetDir;
		hitInfo.normal = -hitInfo.dir; // this has to be in an opposite direction from the hitInfo.dir or the hit is ignored as a 'backface' hit
		hitInfo.type = CGameRules::EHitType::StealthKill;

		g_pGame->GetGameRules()->ClientHit(hitInfo);
	}

	// WARNING: RagDollize resets the entity's rotation!
	//  [7/30/2010 davidr] FixMe: If the entity isn't dead here (because is immortal or any other reason) ragdollizing it will
	// leave it on an inconsistent state (usually only reproducible on debug scenarios)
	targetActor.GetGameObject()->SetAspectProfile(eEA_Physics, eAP_Ragdoll);

	// Give a small nudge in the hit direction to make the target fall over
	const SSpectacularKillParams* pSpectacularKillParams = GetParamsForClass(targetActor.GetEntity()->GetClass());
	CRY_ASSERT(pSpectacularKillParams);
	if (pSpectacularKillParams && (pSpectacularKillParams->impulseScale > 0.0f) && (pSpectacularKillParams->impulseBone != -1))
	{
		const float killDeathBlowVelocity = pSpectacularKillParams->impulseScale; // desired velocity after impulse in meters per second

		IPhysicalEntity* pTargetPhysics = targetActor.GetEntity()->GetPhysics();
		if (pTargetPhysics)
		{
			pe_simulation_params simulationParams;
			pTargetPhysics->GetParams(&simulationParams);

			pe_action_impulse impulse;
			impulse.partid = pSpectacularKillParams->impulseBone;
			impulse.impulse = targetDir*killDeathBlowVelocity*simulationParams.mass; // RagDollize reset the entity's rotation so I have to use the value I cached earlier
			pTargetPhysics->Action(&impulse);
		}
	}

	m_deathBlowState = eDBS_Done;
}
void CGameRealtimeRemoteUpdateListener::CameraSync()
{
	IGame *pGame = gEnv->pGame;
	if(!pGame)
		return;

	IGameFramework *pGameFramework=pGame->GetIGameFramework();
	if(!pGameFramework)
		return;

	IViewSystem *pViewSystem=pGameFramework->GetIViewSystem();	
	if(!pViewSystem)
		return;

	IView *pView=pViewSystem->GetActiveView();
	if(!pView)
		return;

	IEntity *pEntity = gEnv->pEntitySystem->GetEntity(pView->GetLinkedId());
	if(!pEntity)
		return;

	IActor *pPlayer=pGameFramework->GetClientActor();
	if ( !pPlayer )
		return;

	IEntity * pPlayerEntity = pPlayer->GetEntity();
	if (!pPlayerEntity)
		return;

	IPhysicalEntity * piPlayerPhysics = pPlayerEntity->GetPhysics();
	if ( !piPlayerPhysics )
		return;

	pe_player_dimensions dim;
	piPlayerPhysics->GetParams( &dim );

	//TODO: only GDCE2011, in the future make this game magic constant be gone in LiveCreate 2.0
	// game player view code has a complex position code path, the sync position should be
	// honoured by game code when live creaate camera sync is enabled
	m_Position.z -= 1.62f;
	pEntity->SetPos(m_Position);
	pPlayerEntity->Hide(false);
	pViewSystem->SetOverrideCameraRotation(true,Quat::CreateRotationVDir(m_ViewDirection));

	pPlayerEntity->Hide(true);
	SEntityUpdateContext ctx;
	pPlayer->Update( ctx, 0 );
	m_bCameraSync = true;
}
bool CCannonBall::RayTraceGeometry( const EventPhysCollision* pCollision, const Vec3& pos, const Vec3& hitDirection, SBackHitInfo* pBackHitInfo )
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	bool exitPointFound = false;

	IPhysicalEntity* pCollider = pCollision->pEntity[1];
	assert(pCollider);

	pe_params_part partParams;
	partParams.partid = pCollision->partid[1];
	pe_status_pos posStatus;

	if (pCollider->GetParams(&partParams) && pCollider->GetStatus(&posStatus))
	{
		if (partParams.pPhysGeom && partParams.pPhysGeom->pGeom)
		{
			geom_world_data geomWorldData;
			geomWorldData.R = Matrix33(posStatus.q*partParams.q);
			geomWorldData.offset = posStatus.pos + (posStatus.q * partParams.pos);
			geomWorldData.scale = posStatus.scale * partParams.scale;

			geom_contact *pContacts;
			intersection_params intersectionParams;
			IGeometry* pRayGeometry = s_pRayWrapper->GetRay(pos, hitDirection);
			const Vec3 hitDirectionNormalized = hitDirection.GetNormalized();

			{ WriteLockCond lock; 
			const int contactCount = partParams.pPhysGeom->pGeom->IntersectLocked(pRayGeometry,&geomWorldData,0,&intersectionParams,pContacts,lock);
			if (contactCount > 0)
			{
				float bestDistance = 10.0f;
				
				for (int i = (contactCount-1); (i >= 0) && (pContacts[i].t < bestDistance) && ((pContacts[i].n*hitDirectionNormalized) < 0); i--)
				{
					bestDistance = (float)pContacts[i].t;
					pBackHitInfo->pt = pContacts[i].pt;
					exitPointFound = true;
				}
			}
			} // lock
		}
	}

	s_pRayWrapper->ResetRay();

	return exitPointFound;
}
void CIntersectionAssistanceUnit::DebugUpdate() const
{
    if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled)
        {
            IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_subjectEntityId);
            if(pEntity)
                {
                    IPhysicalEntity *pPhysical = pEntity->GetPhysics();
                    if(pPhysical)
                        {
                            const float fFontSize = 1.2f;
                            float drawColor[4] = {1.0f, 1.0f, 1.0f, 1.0f};

                            string sMsg(string().Format(" Entity ID: [%d]", m_subjectEntityId));
                            sMsg += string().Format("\n Entity Name: [%s]", pEntity->GetName());

                            sMsg += string().Format("\n EmbedTimer: [%.3f]", m_embedTimer);
                            sMsg += string().Format("\n EmbedState: [%s]",(m_embedState == eES_None) ? "NONE" : (m_embedState == eES_Evaluating) ? "EVALUATING" : (m_embedState == eES_ReEvaluating) ? "REEVALUATING" : (m_embedState == eES_NotEmbedded) ? "NOT EMBEDDED" : (m_embedState == eES_Embedded) ? "EMBEDDED" : "UNKNOWN");

                            Vec3 vCurrTrans = m_entityStartingWPos - pEntity->GetWorldPos();
                            sMsg += string().Format("\n Translation: < %.3f, %.3f, %.3f >", vCurrTrans.x, vCurrTrans.y, vCurrTrans.z );
                            sMsg += string().Format("\n Trans magnitude: < %.3f >", vCurrTrans.GetLength() );
                            sMsg += string().Format("\n Trans per sec: < %.3f >", vCurrTrans.GetLength() / g_pGameCVars->pl_pickAndThrow.intersectionAssistTimePeriod );

                            sMsg += string().Format("\n Collision count: %u", m_collisionCount );

                            // RENDER
                            Vec3 vDrawPos = pEntity->GetWorldPos() + Vec3(0.0f,0.0f,0.6f);
                            gEnv->pRenderer->DrawLabelEx(vDrawPos, fFontSize, drawColor, true, true, sMsg.c_str());

                            // Box
                            pe_params_bbox bbox;
                            if(pPhysical->GetParams(&bbox))
                                {
                                    ColorB colDefault = ColorB( 127,127,127 );
                                    ColorB embedded = ColorB(255, 0, 0);
                                    ColorB notEmbedded = ColorB(0, 255, 0);

                                    gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB( AABB(bbox.BBox[0],bbox.BBox[1]), Matrix34(IDENTITY), false, (m_embedState == eES_Embedded) ? embedded : (m_embedState == eES_NotEmbedded) ? notEmbedded : colDefault, eBBD_Faceted);
                                }
                        }
                }

        }
}
//------------------------------------------------------------------------
void CVehicleActionEntityAttachment::Update(const float deltaTime)
{
	if(m_isAttached)
		return;

	IEntitySystem *pEntitySystem = gEnv->pEntitySystem;
	assert(pEntitySystem);

	IEntity *pEntity = pEntitySystem->GetEntity(m_entityId);

	if(!pEntity)
		return;

	IPhysicalEntity *pPhysEntity = pEntity->GetPhysics();

	if(!pPhysEntity)
		return;

	pe_simulation_params paramsSim;
	float gravity;

	if(pPhysEntity->GetParams(&paramsSim))
		gravity = abs(paramsSim.gravity.z);
	else
		gravity = 9.82f;

	pe_status_dynamics dyn;

	if(pPhysEntity->GetStatus(&dyn))
	{
		pe_action_impulse impulse;
		impulse.impulse  = Matrix33(pEntity->GetWorldTM()) * Vec3(0.0f, 0.0f, 1.0f) * g_parachuteForce * gravity;
		impulse.impulse = impulse.impulse - dyn.v;
		impulse.impulse *= dyn.mass * deltaTime;
		impulse.iSource = 3;

		pPhysEntity->Action(&impulse);
	}

	m_timer -= deltaTime;

	if(m_timer <= 0.0f || dyn.v.z >= 0.0f)
		m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_NoUpdate);
}
Exemple #10
0
void CPlayerStateSwim::OnEnter( CPlayer& player )
{
	player.m_playerStateSwim_WaterTestProxy.OnEnterWater(player);
	
	IPhysicalEntity* pPhysEnt = player.GetEntity()->GetPhysics();
	if (pPhysEnt != NULL)
	{
		// get current gravity before setting to zero.
		pe_player_dynamics simPar;
		if( pPhysEnt->GetParams(&simPar) != 0 )
		{
			m_gravity = simPar.gravity;
		}
		CPlayerStateUtil::PhySetFly( player );
	}

	m_lastWaterLevel = player.m_playerStateSwim_WaterTestProxy.GetWaterLevel();
	m_lastWaterLevelTime = player.m_playerStateSwim_WaterTestProxy.GetWaterLevelTimeUpdated();

	player.m_stats.inAir = 0.0f;

	if (player.IsClient())
	{
		ICameraMode::AnimationSettings animationSettings;
		animationSettings.positionFactor = 1.0f;
		animationSettings.rotationFactor = GetSwimParams().m_stateSwim_animCameraFactor;
		
		player.GetPlayerCamera()->SetCameraModeWithAnimationBlendFactors( eCameraMode_PartialAnimationControlled, animationSettings, "Entering swim state" );
		player.SendMusicLogicEvent(eMUSICLOGICEVENT_PLAYER_SWIM_ENTER);

		if (!player.IsCinematicFlagActive(SPlayerStats::eCinematicFlag_HolsterWeapon))
			player.HolsterItem(true);

		if (gEnv->bMultiplayer)	// any left hand holding in SP?
		{
			player.HideLeftHandObject(true);
		}
	}

	// Record 'Swim' telemetry stats.
	CStatsRecordingMgr::TryTrackEvent(&player, eGSE_Swim, true);
}
void CPlayerStateFly::OnEnter( CPlayer& player )
{
    pe_player_dynamics simPar;

    IPhysicalEntity* piPhysics = player.GetEntity()->GetPhysics();
    if (!piPhysics || piPhysics->GetParams(&simPar) == 0)
        {
            return;
        }

    player.m_actorPhysics.velocity = player.m_actorPhysics.velocityUnconstrained.Set(0,0,0);
    player.m_actorPhysics.speed = player.m_stats.speedFlat = 0.0f;
    player.m_actorPhysics.groundMaterialIdx = -1;
    player.m_actorPhysics.gravity = simPar.gravity;

    player.m_stats.fallSpeed = 0.0f;
    player.m_stats.inFiring = 0;

    CPlayerStateUtil::PhySetFly( player );
}
//------------------------------------------------------------------------
void CVehiclePartAnimated::FlagSkeleton(ISkeletonPose* pSkeletonPose,IDefaultSkeleton &rIDefaultSkeleton)
{
	if (!pSkeletonPose)
		return;

	IPhysicalEntity* pPhysics = GetEntity()->GetPhysics();
	if (!pPhysics)
		return;

	string name;
	int    idWater       = rIDefaultSkeleton.GetJointIDByName("proxy_water");
	uint32 buoyancyParts = (idWater != -1) ? 1 : 0;

	uint32 jointCount = rIDefaultSkeleton.GetJointCount();
	for (uint32 i = 0; i < jointCount; ++i)
	{
		int physId = pSkeletonPose->GetPhysIdOnJoint(i);

		if (physId >= 0)
		{
			CheckColltypeHeavy(physId);
			name = rIDefaultSkeleton.GetJointNameByID(i);

			// when water proxy available, remove float from all others
			// if no water proxy, we leave only "proxy" parts floating
			if (idWater != -1)
			{
				if (i == idWater)
				{
					SetFlags(physId, geom_collides, false);
					SetFlagsCollider(physId, 0);
				}
				else
					SetFlags(physId, geom_floats, false);
			}
			else
			{
				if (name.find("proxy") != string::npos)
					++buoyancyParts;
				else
					SetFlags(physId, geom_floats, false);
			}

			// all objects which have a corresponding *_proxy on the skeleton
			// are set to ray collision only
			if (name.find("_proxy") == string::npos)
			{
				name.append("_proxy");
				int proxyId = rIDefaultSkeleton.GetJointIDByName(name.c_str());

				if (proxyId != -1)
				{
					// remove ray collision from hull proxy(s)
					SetFlags(pSkeletonPose->GetPhysIdOnJoint(proxyId), geom_colltype_ray | geom_colltype13, false);

					// get StatObj from main part, to connect proxies foreignData with it
					IStatObj* pStatObj = pSkeletonPose->GetStatObjOnJoint(i);

					if (pStatObj)
					{
						pe_params_part params;
						params.partid = proxyId;
						if (pPhysics->GetParams(&params))
						{
							if (params.pPhysGeom && params.pPhysGeom->pGeom)
								params.pPhysGeom->pGeom->SetForeignData(pStatObj, 0);
						}
					}

					for (int p = 2; p < 6; ++p)
					{
						// check additional proxies, by naming convention _02, .. _05
						char buf[64];
						cry_sprintf(buf, "%s_%02i", name.c_str(), p);

						proxyId = rIDefaultSkeleton.GetJointIDByName(buf);
						if (proxyId == -1)
							break;

						int proxyPhysId = pSkeletonPose->GetPhysIdOnJoint(proxyId);
						if (proxyPhysId == -1)
							continue;

						SetFlags(proxyPhysId, geom_colltype_ray | geom_colltype13, false);

						// connect proxies to main StatObj (needed for bullet tests, decals)
						if (pStatObj)
						{
							pe_params_part params;
							params.partid = proxyPhysId;
							if (pPhysics->GetParams(&params))
							{
								if (params.pPhysGeom && params.pPhysGeom->pGeom)
									params.pPhysGeom->pGeom->SetForeignData(pStatObj, 0);
							}
						}
					}

					// set ray-collision only on the part
					SetFlags(physId, geom_collides | geom_floats, false);
					SetFlags(physId, geom_colltype_ray | geom_colltype13, true);
					SetFlagsCollider(physId, 0);
				}
			}
		}
	}

	if (buoyancyParts == 0)
	{
		// as fallback, use part with largest volume for buoyancy
		int   partId = -1;
		float maxV   = 0.f;

		pe_status_nparts nparts;
		int              numParts = pPhysics->GetStatus(&nparts);

		for (int i = 0; i < numParts; ++i)
		{
			pe_params_part params;
			params.ipart = i;
			if (pPhysics->GetParams(&params))
			{
				float v = (params.pPhysGeomProxy) ? params.pPhysGeomProxy->V : params.pPhysGeom->V;
				if (v > maxV)
				{
					partId = params.partid;
					maxV   = v;
				}
			}
		}

		if (partId != -1)
			SetFlags(partId, geom_floats, true);
		else
			GameWarning("[CVehiclePartAnimated]: <%s> has no buoyancy parts! (Check material for correct physicalization setup properties)",GetEntity()->GetName());
	}

	int jointId, physId;
	if ((jointId = rIDefaultSkeleton.GetJointIDByName("proxy_skirt")) != -1)
	{
		if ((physId = pSkeletonPose->GetPhysIdOnJoint(jointId)) != -1)
		{
			SetFlags(physId, geom_collides | geom_floats, false);
			SetFlags(physId, geom_colltype_ray | geom_colltype13 | geom_colltype_player | geom_colltype_foliage, true);
			SetFlagsCollider(physId, 0);
		}
	}

	// remove collision flags from all _proxy geoms by debug cvar
	// useful for seeing through, testing ray proxies etc
	if (VehicleCVars().v_disable_hull > 0)
	{
		for (uint32 i = 0; i < rIDefaultSkeleton.GetJointCount(); ++i)
		{
			if (strstr(rIDefaultSkeleton.GetJointNameByID(i), "_proxy"))
			{
				SetFlags(pSkeletonPose->GetPhysIdOnJoint(i), geom_collides | geom_floats, false);
				SetFlagsCollider(pSkeletonPose->GetPhysIdOnJoint(i), 0);
			}
		}
	}
}
void CVehicleDamageBehaviorBlowTire::DamagePlayers()
{
	// check for the nasty case when the player is shooting at the vehicle tires while prone 
	// under or behind the car, In that case the player should get killed by the vehicle, 
	// otherwise he gets stuck forever. Note that he should only get killed when the tier
	// is actually destroyed and not by collision resulting by the impulse added by just 
	// shooting at the tiers. Unfortunately using physics for doing this check is not reliable
	// enough so we have to check it explicitly
	
	IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy*)m_pVehicle->GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);
	if (!pPhysicsProxy)
		return;

	AABB bbox;
	pPhysicsProxy->GetWorldBounds( bbox );

	IPhysicalWorld *pWorld = gEnv->pSystem->GetIPhysicalWorld();
	IPhysicalEntity **ppColliders;
	// check entities in collision with the car
	int cnt = pWorld->GetEntitiesInBox( bbox.min,bbox.max, ppColliders,ent_living);
	for (int i = 0; i < cnt; i++)
	{

		IEntity *pEntity = gEnv->pEntitySystem->GetEntityFromPhysics( ppColliders[i] );
		if (!pEntity)
			continue;
		
		// skip the vehicle itself
		if (pEntity==m_pVehicle->GetEntity())
			continue;

		IPhysicalEntity *pPhysEnt = pEntity->GetPhysics();
		if (!pPhysEnt) 
			continue;

		IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId());            
		if(!pActor)
			continue;

		//Jan M.: the player is killed when he entered the vehicle while prone although he is still passenger!
		if(m_pVehicle == pActor->GetLinkedVehicle())
			continue;

		//the player must be prone under the vehicle
		IAnimatedCharacter * animatedCharacter=pActor->GetAnimatedCharacter();
		if (!animatedCharacter)
			continue;

		int stance = animatedCharacter->GetCurrentStance();
		if (stance!=STANCE_PRONE)
			continue;

		pe_player_dimensions dim;
		if (!pPhysEnt->GetParams(&dim))
			continue;
		// position returned is at entity's feet, add head position from physics
		Vec3 vPos1=pEntity->GetPos();
		vPos1.z = vPos1.z + dim.heightHead;

		float fZ=bbox.GetCenter().z;
		if (vPos1.z>fZ)
			continue; // not under the vehicle

		// at this point we have a collision with the car moving down and the guy prone under the car, it is safe
		// to assume he has been squished so let's kill him.
		if (gEnv->bServer && pActor->GetHealth()>0)
		{
			// adding a server hit to make it working in MP
			IGameRules *pGameRules = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem()->GetCurrentGameRules();
			if (pGameRules)
			{
				HitInfo hit;

				EntityId shooterId=m_pVehicle->GetEntityId();
				if (m_pVehicle->GetDriver())
					shooterId=m_pVehicle->GetDriver()->GetEntityId();					

				hit.targetId = pEntity->GetId();      
				hit.shooterId = shooterId;
				hit.weaponId = m_pVehicle->GetEntityId();
				hit.damage = 1000.f;
				hit.type = 0;
				hit.pos = pActor->GetEntity()->GetWorldPos();

				pGameRules->ServerHit(hit); 
			}  
		} 
	} //i
}
Exemple #14
0
//------------------------------------------------------------------------
int CScriptBind_Actor::GetCloseColliderParts(IFunctionHandler *pH, int characterSlot, Vec3 hitPos, float radius)
{
  // find nearest physic. parts to explosion center
  // for now we just return the closest part (using the AABB)  
  
  CActor *pActor = GetActor(pH);  
	if (!pActor)
		return pH->EndFunction();

  IEntity* pEntity = pActor->GetEntity();

  ICharacterInstance* pChar = pEntity->GetCharacter(characterSlot);

  if (pChar && pChar->GetISkeletonPose()->GetCharacterPhysics())  
  { 
    IPhysicalEntity* pPhysics = pChar->GetISkeletonPose()->GetCharacterPhysics();
    
    pe_status_nparts nparts;
    int numParts = pPhysics->GetStatus(&nparts);    

    float minLenSq = radius*radius + 0.1f;
    int minLenPart = -1;
    
    pe_status_pos status;

    for (int i=0; i<numParts; ++i)
    {
      status.ipart = i;
      if (pPhysics->GetStatus(&status))
      { 
        AABB box(status.pos+status.BBox[0], status.pos+status.BBox[1]);
             
        // if hitpos inside AABB, return
        if (box.IsContainPoint(hitPos))
        {
          minLenPart = i;          
          break;
        }

        // else find closest distance 
        float lenSq = Distance::Point_AABBSq(hitPos, box);
        if (lenSq < minLenSq)
        {
          minLenSq = lenSq;
          minLenPart = i;          
        }
      }      
    }

    // get material from selected part
    static ISurfaceTypeManager* pSurfaceMan = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager();

    if (minLenPart != -1)
    {
	     pe_params_part params;
      params.ipart = minLenPart;
      if (pPhysics->GetParams(&params))
      { 
        phys_geometry* pGeom = params.pPhysGeomProxy ? params.pPhysGeomProxy : params.pPhysGeom;
        if (pGeom->surface_idx > 0 &&  pGeom->surface_idx < params.nMats)
				{
					if (ISurfaceType *pSurfaceType=pSurfaceMan->GetSurfaceType(pGeom->pMatMapping[pGeom->surface_idx]))
						return pH->EndFunction(params.partid, pSurfaceType->GetName(), pSurfaceType->GetType());
				}
      }

      return pH->EndFunction(params.partid);
    }    
  }
  return pH->EndFunction();
}
Exemple #15
0
void CPlayerStateUtil::UpdatePlayerPhysicsStats( CPlayer& player, SActorPhysics& actorPhysics, float frameTime )
{
	const int currentFrameID = gEnv->pRenderer->GetFrameID();
	if( actorPhysics.lastFrameUpdate < currentFrameID )
	{
		pe_status_living livStat;
		if( !CPlayerStateUtil::GetPhysicsLivingStat( player, &livStat ) )
		{
			return;
		}

		SPlayerStats& stats = *player.GetActorStats();

		const Vec3 newVelocity = livStat.vel-livStat.velGround;
		actorPhysics.velocityDelta = newVelocity - actorPhysics.velocity;
		actorPhysics.velocity = newVelocity;
		actorPhysics.velocityUnconstrainedLast = actorPhysics.velocityUnconstrained;
		actorPhysics.velocityUnconstrained = livStat.velUnconstrained;
		actorPhysics.flags.SetFlags( SActorPhysics::EActorPhysicsFlags_WasFlying, actorPhysics.flags.AreAnyFlagsActive(SActorPhysics::EActorPhysicsFlags_Flying) );
		actorPhysics.flags.SetFlags( SActorPhysics::EActorPhysicsFlags_Flying, livStat.bFlying > 0 );
		actorPhysics.flags.SetFlags( SActorPhysics::EActorPhysicsFlags_Stuck, livStat.bStuck > 0 );

		Vec3 flatVel(player.m_pPlayerRotation->GetBaseQuat().GetInverted()*newVelocity);
		flatVel.z = 0;
		stats.speedFlat = flatVel.len();

		if(player.IsInAir())
		{
			stats.maxAirSpeed = max(stats.maxAirSpeed, newVelocity.GetLengthFast());
		}
		else
		{
			stats.maxAirSpeed = 0.f;
		}
		float fSpeedFlatSelector = stats.speedFlat - 0.1f;


		const float groundNormalBlend = clamp(frameTime * 6.666f, 0.0f, 1.0f);
		actorPhysics.groundNormal = LERP(actorPhysics.groundNormal, livStat.groundSlope, groundNormalBlend);

		if (livStat.groundSurfaceIdxAux > 0)
			actorPhysics.groundMaterialIdx = livStat.groundSurfaceIdxAux;
		else
			actorPhysics.groundMaterialIdx = livStat.groundSurfaceIdx;

		actorPhysics.groundHeight = livStat.groundHeight;

		EntityId newGroundColliderId = 0;
		if (livStat.pGroundCollider)
		{
			IEntity* pEntity = gEnv->pEntitySystem->GetEntityFromPhysics(livStat.pGroundCollider);
			newGroundColliderId = pEntity ? pEntity->GetId() : 0;
		}

		if( newGroundColliderId != actorPhysics.groundColliderId )
		{
			if( actorPhysics.groundColliderId )
			{
				if( IGameObject* pGameObject = gEnv->pGame->GetIGameFramework()->GetGameObject( actorPhysics.groundColliderId ) )
				{
					SGameObjectEvent event( eGFE_StoodOnChange, eGOEF_ToExtensions );
					event.ptr = &player;
					event.paramAsBool  = false;
					pGameObject->SendEvent(event);
				}
			}

			if( newGroundColliderId )
			{
				if( IGameObject* pGameObject = gEnv->pGame->GetIGameFramework()->GetGameObject( newGroundColliderId ) )
				{
					SGameObjectEvent event( eGFE_StoodOnChange, eGOEF_ToExtensions );
					event.ptr = &player;
					event.paramAsBool  = true;
					pGameObject->SendEvent(event);
				}
			}

			actorPhysics.groundColliderId = newGroundColliderId;
		}

		IPhysicalEntity *pPhysEnt = player.GetEntity()->GetPhysics();
		if( pPhysEnt )
		{
			pe_status_dynamics dynStat;
			pPhysEnt->GetStatus(&dynStat);

			actorPhysics.angVelocity = dynStat.w;
			actorPhysics.mass = dynStat.mass;

			pe_player_dynamics simPar;
			if (pPhysEnt->GetParams(&simPar) != 0)
			{
				actorPhysics.gravity = simPar.gravity;
			}
		}

		actorPhysics.lastFrameUpdate = currentFrameID;

#ifdef PLAYER_MOVEMENT_DEBUG_ENABLED
	player.GetMovementDebug().DebugGraph_AddValue("PhysVelo", livStat.vel.GetLength());
	player.GetMovementDebug().DebugGraph_AddValue("PhysVeloX", livStat.vel.x);
	player.GetMovementDebug().DebugGraph_AddValue("PhysVeloY", livStat.vel.y);
	player.GetMovementDebug().DebugGraph_AddValue("PhysVeloZ", livStat.vel.z);

	player.GetMovementDebug().DebugGraph_AddValue("PhysVeloUn", livStat.velUnconstrained.GetLength());
	player.GetMovementDebug().DebugGraph_AddValue("PhysVeloUnX", livStat.velUnconstrained.x);
	player.GetMovementDebug().DebugGraph_AddValue("PhysVeloUnY", livStat.velUnconstrained.y);
	player.GetMovementDebug().DebugGraph_AddValue("PhysVeloUnZ", livStat.velUnconstrained.z);

	player.GetMovementDebug().DebugGraph_AddValue("PhysVelReq", livStat.velRequested.GetLength());
	player.GetMovementDebug().DebugGraph_AddValue("PhysVelReqX", livStat.velRequested.x);
	player.GetMovementDebug().DebugGraph_AddValue("PhysVelReqY", livStat.velRequested.y);
	player.GetMovementDebug().DebugGraph_AddValue("PhysVelReqZ", livStat.velRequested.z);

	player.GetMovementDebug().LogVelocityStats(player.GetEntity(), livStat, stats.downwardsImpactVelocity, stats.fallSpeed);
#endif
	}
}
Exemple #16
0
//-----------------------------------------------
//This function is only executed on the server
void CC4Projectile::Stick(EventPhysCollision *pCollision)
{
	assert(pCollision);
	int trgId = 1;
	IPhysicalEntity *pTarget = pCollision->pEntity[trgId];

	if(pTarget == GetEntity()->GetPhysics())
	{
		trgId = 0;
		pTarget = pCollision->pEntity[trgId];
	}

	//Do not stick to breakable glass
	if(ISurfaceType *pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(pCollision->idmat[trgId]))
	{
		if(pSurfaceType->GetBreakability()==1)
		{
			m_notStick = true;
			return;
		}
	}

	IEntity *pTargetEntity = pTarget ? gEnv->pEntitySystem->GetEntityFromPhysics(pTarget) : 0;

	if(pTarget && (!pTargetEntity || (pTargetEntity->GetId() != m_ownerId)))
	{
		//Special cases
		if(pTargetEntity)
		{
			//Stick to actors using a character attachment
			CActor *pActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()));

			//Not in MP
			if(pActor && gEnv->bMultiplayer)
			{
				m_notStick = true;
				return;
			}

			if(pActor && pActor->GetHealth()>0)
			{
				if(pActor->GetActorSpecies()!=eGCT_HUMAN)
				{
					m_notStick = true;
					return;
				}

				if(StickToCharacter(true,pTargetEntity))
				{
					GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None);
					m_stuck = true;
				}

				m_notStick = true;
				return;
			}

			//Do not stick to small objects...
			if(!pActor)
			{
				pe_params_part pPart;
				pPart.ipart = 0;

				if(pTarget->GetParams(&pPart) && pPart.pPhysGeom && pPart.pPhysGeom->V<0.15f)
				{
					m_notStick = true;
					return;
				}
			}

		}
		else if(pTarget->GetType()==PE_LIVING)
		{
			m_notStick = true;
			return;
		}

		if(!pTargetEntity)
			StickToStaticObject(pCollision,pTarget);
		else
		{
			//Do not attach to items
			if(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pTargetEntity->GetId()))
			{
				m_notStick = true;
				return;
			}

			Matrix34 mat = pTargetEntity->GetWorldTM();
			mat.Invert();
			Vec3 pos = mat.TransformPoint(pCollision->pt);
			mat.SetIdentity();
			mat.SetRotation33(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI));
			mat.SetTranslation(pos);

			//Dephysicalize and stick
			GetGameObject()->SetAspectProfile(eEA_Physics, ePT_None);

			StickToEntity(pTargetEntity,mat);

			if(gEnv->bMultiplayer)
			{
				Quat rot(Matrix33::CreateOrientation(-pCollision->n,GetEntity()->GetWorldTM().TransformVector(Vec3(0,0,1)),gf_PI*0.5f));
				GetGameObject()->InvokeRMI(CC4Projectile::ClStickToEntity(),ProjectileStickToEntity(pTargetEntity->GetId(),pos,rot),eRMI_ToAllClients);
			}
		}

		m_stuck = true;
	}
}
//------------------------------------------------------------------------
void CVehicleMovementVTOL::ProcessActions(const float deltaTime)
{
	FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	UpdateDamages(deltaTime);
	UpdateEngine(deltaTime);

	m_velDamp = 0.25f;

	m_playerControls.ProcessActions(deltaTime);

	Limit(m_forwardAction, -1.0f, 1.0f);
	Limit(m_strafeAction, -1.0f, 1.0f);

	m_actionYaw = 0.0f;

	Vec3 worldPos = m_pEntity->GetWorldPos();

	IPhysicalEntity* pPhysics = GetPhysics();

	// get the current state

	// roll pitch + yaw

	Matrix34 worldTM = m_pRotorPart ? m_pRotorPart->GetWorldTM() : m_pEntity->GetWorldTM();
//	if (m_pRotorPart)
//		worldTM = m_pRotorPart->GetWorldTM();
//	else
//		worldTM = m_pEntity->GetWorldTM();

	Vec3 specialPos = worldTM.GetTranslation();
	Ang3 angles = Ang3::GetAnglesXYZ(Matrix33(worldTM));

	Matrix33 tm;
	tm.SetRotationXYZ((angles));

	// +ve pitch means nose up
	const float& currentPitch = angles.x;
	// +ve roll means to the left
	const float& currentRoll = angles.y;
	// +ve direction mean rotation anti-clockwise about the z axis - 0 means along y
	float currentDir = angles.z;

	const float maxPitchAngle = 60.0f;
	
	float pitchDeg = RAD2DEG(currentPitch);
	if (pitchDeg >= (maxPitchAngle * 0.75f))
	{
		float mult = pitchDeg / (maxPitchAngle);
		
		if (mult > 1.0f && m_desiredPitch < 0.0f)
		{
			m_desiredPitch *= 0.0f;
			m_actionPitch *= 0.0f;
			m_desiredPitch += 0.2f * mult;
		}
		else if (m_desiredPitch < 0.0f)
		{
			m_desiredPitch *= (1.0f - mult);
			m_desiredPitch += 0.05f;
		}
	}
	else if (pitchDeg <= (-maxPitchAngle * 0.75f))
	{
		float mult = abs(pitchDeg) / (maxPitchAngle);

		if (mult > 1.0f && m_desiredPitch > 0.0f)
		{
			m_desiredPitch *= 0.0f;
			m_actionPitch *= 0.0f;
			m_desiredPitch += 0.2f * mult;
		}
		else if (m_desiredPitch > 0.0f)
		{
			m_desiredPitch *= (1.0f - mult);
			m_desiredPitch -= 0.05f;
		}
	}

	if (currentRoll >= DEG2RAD(m_maxRollAngle * 0.7f) && m_desiredRoll > 0.001f)
	{
		float r = currentRoll / DEG2RAD(m_maxRollAngle);
		r = min(1.0f, r * 1.0f);
		r = 1.0f - r;
		m_desiredRoll *= r;
		m_desiredRoll = min(1.0f, m_desiredRoll);
	}
	else if (currentRoll <= DEG2RAD(-m_maxRollAngle * 0.7f) && m_desiredRoll < 0.001f)
	{
		float r = abs(currentRoll) / DEG2RAD(m_maxRollAngle);
		r = min(1.0f, r * 1.0f);
		r = 1.0f - r;
		m_desiredRoll *= r;
		m_desiredRoll = max(-1.0f, m_desiredRoll);
	}

	Vec3 currentFwdDir2D = m_currentFwdDir;
	currentFwdDir2D.z = 0.0f;
	currentFwdDir2D.NormalizeSafe();

	Vec3 currentLeftDir2D(-currentFwdDir2D.y, currentFwdDir2D.x, 0.0f);

	Vec3 currentVel = m_PhysDyn.v;
	Vec3 currentVel2D = currentVel;
	currentVel2D.z = 0.0f;

	float currentHeight = worldPos.z;
	float currentFwdSpeed = currentVel.Dot(currentFwdDir2D);

	ProcessActions_AdjustActions(deltaTime);

	float inputMult = m_basicSpeedFraction;

	// desired things
	float turnDecreaseScale = m_yawDecreaseWithSpeed / (m_yawDecreaseWithSpeed + fabs(currentFwdSpeed));

	Vec3 desired_vel2D = 
		currentFwdDir2D * m_forwardAction * m_maxFwdSpeed * inputMult + 
		currentLeftDir2D * m_strafeAction * m_maxLeftSpeed * inputMult;

	// calculate the angle changes

	Vec3 desiredVelChange2D = desired_vel2D - currentVel2D;

	float desiredTiltAngle = m_tiltPerVelDifference * desiredVelChange2D.GetLength();
	Limit(desiredTiltAngle, -m_maxTiltAngle, m_maxTiltAngle);

	float goal = abs(m_desiredPitch) + abs(m_desiredRoll);
	goal *= 1.5f;
	Interpolate(m_playerAcceleration, goal, 0.25f, deltaTime);
	Limit(m_playerAcceleration, 0.0f, 5.0f);

	//static float g_angleLift = 4.0f;

	if (abs(m_liftAction) > 0.001f && abs(m_forwardAction) < 0.001)
	{
//		float pitch = RAD2DEG(currentPitch);

		if (m_liftPitchAngle < 0.0f && m_liftAction > 0.0f)
			m_liftPitchAngle = 0.0f;
		else if (m_liftPitchAngle > 0.0f && m_liftAction < 0.0f)
			m_liftPitchAngle = 0.0f;

		Interpolate(m_liftPitchAngle, 1.25f * m_liftAction, 0.75f, deltaTime);

		if (m_liftPitchAngle < 1.0f && m_liftPitchAngle > -1.0f)
			m_desiredPitch += 0.05f * m_liftAction;
	}
	else if (m_liftAction < 0.001f && abs(m_liftPitchAngle) > 0.001)
	{
		Interpolate(m_liftPitchAngle, 0.0f, 1.0f, deltaTime);
		m_desiredPitch += 0.05f * -m_liftPitchAngle;
	}

	/* todo
	else if (m_liftAction < -0.001f)
	{
		m_desiredPitch += min(0.0f, (DEG2RAD(-5.0f) - currentPitch)) * 0.5f * m_liftAction;
	}*/

	if (!iszero(m_desiredPitch))
	{
		m_actionPitch -= m_desiredPitch * m_pitchInputConst;
		Limit(m_actionPitch, -m_maxYawRate, m_maxYawRate);
	}

	float rollAccel = 1.0f;
	if (abs(currentRoll + m_desiredRoll) < abs(currentRoll))
		rollAccel *= 1.25f;

	m_actionRoll += m_pitchActionPerTilt * m_desiredRoll * rollAccel * (m_playerAcceleration + 1.0f);
	Limit(m_actionRoll, -10.0f, 10.0f);
	Limit(m_actionPitch, -10.0f, 10.0f);

	// roll as we turn
	if (!m_strafeAction)
	{
		m_actionYaw += m_yawPerRoll * currentRoll;
	}

	if (abs(m_strafeAction) > 0.001f)
	{
		float side = 0.0f;
		side = min(1.0f, max(-1.0f, m_strafeAction));

		float roll = DEG2RAD(m_extraRollForTurn * 0.25f * side) - (currentRoll);
		m_actionRoll += max(0.0f, abs(roll)) * side * 1.0f;
	}

	float relaxRollTolerance = 0.0f;

	if (abs(m_turnAction) > 0.01f || abs(m_PhysDyn.w.z) > DEG2RAD(3.0f))
	{
		m_actionYaw += -m_turnAction * m_yawInputConst * GetDamageMult();

		float side = 0.0f;
		if (abs(m_turnAction) > 0.01f)
			side = min(1.0f, max(-1.0f, m_turnAction));

		float roll = DEG2RAD(m_extraRollForTurn * side) - (currentRoll);
		m_actionRoll += max(0.0f, abs(roll)) * side * m_rollForTurnForce;

		roll *= max(1.0f, abs(m_PhysDyn.w.z));

		m_actionRoll += roll;

		Limit(m_actionYaw, -m_maxYawRate, m_maxYawRate);
	}

	m_desiredDir = currentDir;
	m_lastDir = currentDir;

	float boost = Boosting() ? m_boostMult : 1.0f;
	float liftActionMax = 1.0f;

	if (m_pAltitudeLimitVar)
	{
		float altitudeLimit = m_pAltitudeLimitVar->GetFVal();

		if (!iszero(altitudeLimit))
		{
			float altitudeLowerOffset;

			if (m_pAltitudeLimitLowerOffsetVar)
			{
				float r = 1.0f - min(1.0f, max(0.0f, m_pAltitudeLimitLowerOffsetVar->GetFVal()));
				altitudeLowerOffset = r * altitudeLimit;
			}
			else
				altitudeLowerOffset = altitudeLimit;

			float mult = 1.0f;

			if (currentHeight >= altitudeLimit)
			{
				if (m_liftAction > 0.f)
				{
					mult = 0.0f;
				}
			}
			else if (currentHeight >= altitudeLowerOffset)
			{
				float zone = altitudeLimit - altitudeLowerOffset;
				mult = (altitudeLimit - currentHeight) / (zone);
			}

			m_liftAction *= mult;

			if (currentPitch > DEG2RAD(0.0f))
			{
				if (m_forwardAction > 0.0f)
					m_forwardAction *= mult;

				if (m_actionPitch > 0.0f)
				{
					m_actionPitch *= mult;
					m_actionPitch += -currentPitch;
				}
			}

			m_desiredHeight = min(altitudeLowerOffset, currentHeight);
		}
	}
	else
	{
		m_desiredHeight = currentHeight;
	}

	if (abs(m_liftAction) > 0.001f)
	{
		m_liftAction = min(liftActionMax, max(-0.2f, m_liftAction));

		m_hoveringPower = (m_powerInputConst * m_liftAction) * boost;
		m_noHoveringTimer = 0.0f;
	}
	else if (!m_isTouchingGround)
	{
		if (m_noHoveringTimer <= 0.0f)
		{
			float gravity;

			pe_simulation_params paramsSim;
			if (pPhysics->GetParams(&paramsSim))
				gravity = abs(paramsSim.gravity.z);
			else
				gravity = 9.2f;

			float upDirZ = m_workingUpDir.z;

			if (abs(m_forwardAction) > 0.01 && upDirZ > 0.0f)
				upDirZ = 1.0f;
			else if (upDirZ > 0.8f)
				upDirZ = 1.0f;

			float upPower = upDirZ;
			upPower -= min(1.0f, abs(m_forwardAction) * abs(angles.x));

			float turbulenceMult = 1.0f - min(m_turbulenceMultMax, m_turbulence);
			Vec3& impulse = m_control.impulse;
			impulse += Vec3(0.0f, 0.0f, upPower) * gravity * turbulenceMult * GetDamageMult();
			impulse.z -= m_PhysDyn.v.z * turbulenceMult;
		}
		else
		{
			m_noHoveringTimer -= deltaTime;
		}
	}

	if (m_pStabilizeVTOL)
	{
		float stabilizeTime = m_pStabilizeVTOL->GetFVal();

		if (stabilizeTime > 0.0f)
		{
			if (m_relaxTimer < 6.0f)
				m_relaxTimer += deltaTime;
			else
			{
				float r = currentRoll - relaxRollTolerance;
				r = min(1.0f, max(-1.0f, r));

				m_actionRoll += -r * m_relaxForce * (m_relaxTimer / 6.0f);
			}

		}
	}

	if (m_netActionSync.PublishActions( CNetworkMovementHelicopter(this) ))
		m_pVehicle->GetGameObject()->ChangedNetworkState(eEA_GameClientDynamic);
}
//------------------------------------------------------------------------
void CVehicleMovementVTOL::PreProcessMovement(const float deltaTime)
{
	CVehicleMovementHelicopter::PreProcessMovement(deltaTime);

	if (abs(m_forwardAction) > 0.0f && m_timeOnTheGround <= 0.01f)
		SetHorizontalMode(1.0f);
	else
		SetHorizontalMode(0.0f);

	if (m_forwardAction > 0.0f && m_timeOnTheGround <= 0.01f)
	{
		m_wingsTimer += deltaTime;
		m_wingsTimer = min(m_wingsTimer, m_timeUntilWingsRotate);
	}
	else
	{
		m_wingsTimer -= deltaTime * 0.65f;
		m_wingsTimer = max(m_wingsTimer, 0.0f);
	}

	Interpolate(m_wingsAnimTime, 1.0f - (m_wingsTimer / m_timeUntilWingsRotate), m_wingsSpeed, deltaTime);

	if (!m_isVTOLMovement)
		return;
	
	IPhysicalEntity* pPhysics = GetPhysics();
	assert(pPhysics);

	float gravity;
	pe_simulation_params paramsSim;
	if (pPhysics->GetParams(&paramsSim))
		gravity = abs(paramsSim.gravity.z);
	else
		gravity = 9.2f;

	float vertical = 1.0f - m_horizontal;

	//m_engineForce = max(1.0f, gravity * vertical) * m_enginePower * max(0.25f, vertical);
	m_engineForce = 0.0f;
	m_engineForce += gravity * vertical * m_enginePower;
	m_engineForce += m_horizontal * m_enginePower;

	Matrix33 tm( m_PhysPos.q);
	Ang3 angles = Ang3::GetAnglesXYZ(tm);

 	m_workingUpDir = m_engineUpDir; //Vec3(0.0f, 0.0f, 1.0f);
	
	m_workingUpDir += (vertical * m_rotorDiskTiltScale * Vec3(angles.y, -angles.x, 0.0f));
	m_workingUpDir += (m_horizontal * m_rotorDiskTiltScale * Vec3(0.0f, 0.0f, angles.z));

	m_workingUpDir = tm * m_workingUpDir;
	m_workingUpDir.z += 0.25f;
	m_workingUpDir.NormalizeSafe();

	float strafe = m_strafeAction * m_strafeForce;

	if (m_noHoveringTimer <= 0.0f)
	{
		Vec3 forwardImpulse;

		float turbulenceMult = 1.0f - min(m_turbulenceMultMax, m_turbulence);

		forwardImpulse = m_currentFwdDir * m_enginePower * m_horizFwdForce * m_horizontal
			* (m_forwardAction + (Boosting() * m_boostForce)) * GetDamageMult() * turbulenceMult;

		if (m_forwardAction < 0.0f)
			forwardImpulse *= m_forwardInverseMult;

		forwardImpulse += m_currentUpDir * m_liftAction * m_enginePower * gravity;
		Vec3 fakeLeftDir = tm * Vec3(-1.0f, 0.0f, 0.0f);
		fakeLeftDir.z = 0.0f;
		forwardImpulse += fakeLeftDir * -strafe * m_enginePower * m_horizLeftForce * turbulenceMult;

 		float horizDamp = 0.25f;
		static float vertDamp = 0.0f;

		if ( m_movementAction.isAI )
			horizDamp *= abs(m_turnAction * 4.0f) + 1.0f;
		else
			horizDamp = m_velDamp;

 		m_control.impulse += forwardImpulse;
		m_control.impulse.x -= m_PhysDyn.v.x * horizDamp * turbulenceMult;
		m_control.impulse.y -= m_PhysDyn.v.y * horizDamp * turbulenceMult;
		m_control.impulse.z -= m_PhysDyn.v.z * vertDamp * turbulenceMult;
	}

	m_workingUpDir.z += 0.45f * m_liftAction;
	m_workingUpDir.NormalizeSafe();


	return;
}
void CGameRealtimeRemoteUpdateListener::CameraSync()
{
	IGame *pGame = gEnv->pGame;
	if(!pGame)
		return;

	IGameFramework *pGameFramework=pGame->GetIGameFramework();
	if(!pGameFramework)
		return;

	IViewSystem *pViewSystem=pGameFramework->GetIViewSystem();	
	if(!pViewSystem)
		return;

	IView *pView=pViewSystem->GetActiveView();
	if(!pView)
		return;

	IEntity *pEntity = gEnv->pEntitySystem->GetEntity(pView->GetLinkedId());
	if(!pEntity)
		return;

	CPlayer *pPlayer=static_cast<CPlayer *>(pGameFramework->GetClientActor());
	if ( !pPlayer )
		return;

	IEntity * pPlayerEntity = pPlayer->GetEntity();
	if (!pPlayerEntity)
		return;

	IPhysicalEntity * piPlayerPhysics = pPlayerEntity->GetPhysics();
	if ( !piPlayerPhysics )
		return;

	pe_player_dimensions dim;
	piPlayerPhysics->GetParams( &dim );

	// if delta from head to center of character is zero, then we need to recompute it
	if( m_headPositionDelta.GetLength() == 0 )
	{
		Vec3 camPos  = pViewSystem->GetActiveView()->GetCurrentParams()->position;
		const Vec3& entPos = pEntity->GetPos();
		m_headPositionDelta = camPos - entPos;
	}
	
	// offset the camera position by the current delta to put the head eye position to center of character
	m_Position -= m_headPositionDelta;

	pPlayerEntity->Hide(false);
	pEntity->SetPos(m_Position);
	pViewSystem->SetOverrideCameraRotation(true,Quat::CreateRotationVDir(m_ViewDirection));

#ifndef _RELEASE
	if ( m_bCameraSync == false && m_nPreviousFlyMode != eCameraModes_fly_mode_noclip ) 
	{
		m_nPreviousFlyMode=pPlayer->GetFlyMode();
		pPlayer->SetFlyMode(eCameraModes_fly_mode_noclip);
	}
#endif

	pPlayerEntity->Hide(true);
	m_bCameraSync = true;
}
//------------------------------------------------------------------------
void CVehiclePartAnimated::SetDrivingProxy(bool bDrive)
{
	IVehicleMovement* pMovement = m_pVehicle->GetMovement();
	if (!(pMovement && pMovement->UseDrivingProxy()))
		return;

	if (0 == m_hullMatId[bDrive]) // 0 means, nothin to do
		return;

	if (!m_pCharInstance)
		return;

	ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose();
	if (!pSkeletonPose)
		return;
	IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
	IPhysicalEntity*  pPhysics          = m_pVehicle->GetEntity()->GetPhysics();
	if (!pPhysics)
		return;

	int id = rIDefaultSkeleton.GetJointIDByName("hull_proxy");

	if (id < 0)
	{
		m_hullMatId[0] = m_hullMatId[1] = 0;
		return;
	}

	int partid = pSkeletonPose->GetPhysIdOnJoint(id);

	if (partid == -1)
		return;

	pe_params_part params;
	params.partid = partid;
	params.ipart  = -1;
	if (!pPhysics->GetParams(&params) || !params.nMats)
		return;

	phys_geometry* pGeom = params.pPhysGeom;
	if (pGeom && pGeom->surface_idx < pGeom->nMats)
	{
		ISurfaceTypeManager* pSurfaceMan = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager();

		// initialize once
		if (m_hullMatId[0] < 0)
		{
			int         idDriving = 0;
			int         idOrig    = pGeom->pMatMapping[pGeom->surface_idx];
			const char* matOrig   = pSurfaceMan->GetSurfaceType(idOrig)->GetName();

			if (strstr(matOrig, "mat_metal"))
				idDriving = pSurfaceMan->GetSurfaceTypeByName("mat_metal_nofric")->GetId();
			else
			{
				string mat(matOrig);
				mat.append("_nofric");

				idDriving = pSurfaceMan->GetSurfaceTypeByName(mat.c_str(), NULL, false)->GetId();
			}

			//if (pDebug->GetIVal())
			//CryLog("%s looking up driving surface replacement for %s (id %i) -> got id %i", m_pVehicle->GetEntity()->GetName(), matOrig, idOrig, idDriving);

			if (idDriving > 0)
			{
				// store old and new id
				m_hullMatId[0] = idOrig;
				m_hullMatId[1] = idDriving;

				/*if (pDebug->GetIVal())
				   {
				   const char* matDriving = pSurfaceMan->GetSurfaceType(idDriving)->GetName();
				   CryLog("%s storing hull matId for swapping: %i (%s) -> %i (%s)", m_pVehicle->GetEntity()->GetName(), m_hullMatId[0], matOrig, m_hullMatId[1], matDriving);
				   }*/
			}
			else
				m_hullMatId[0] = m_hullMatId[1] = 0;
		}

		// only swap if materials available
		if (m_hullMatId[bDrive] > 0)
		{
#if ENABLE_VEHICLE_DEBUG
			if (VehicleCVars().v_debugdraw == eVDB_Parts)
				CryLog("%s swapping hull proxy from %i (%s) to matId %i (%s)", m_pVehicle->GetEntity()->GetName(), m_hullMatId[bDrive ^ 1], pSurfaceMan->GetSurfaceType(m_hullMatId[bDrive ^ 1])->GetName(), m_hullMatId[bDrive], pSurfaceMan->GetSurfaceType(m_hullMatId[bDrive])->GetName());
#endif

			for (int n = 0; n < pGeom->nMats; ++n)
			{
				pGeom->pMatMapping[n] = m_hullMatId[bDrive];
			}
		}
	}
}
Exemple #21
0
void CPlayerStateJump::StartJump( CPlayer& player, const bool isHeavyWeapon, const float fVerticalSpeedModifier )
{
	const SActorPhysics& actorPhysics = player.GetActorPhysics();
	const SPlayerStats& stats = *player.GetActorStats();
	const float onGroundTime = 0.2f;

	float g = actorPhysics.gravity.len();

	const float jumpHeightScale = 1.0f;
	const float jumpHeight = player.GetActorParams().jumpHeight * jumpHeightScale;

	float playerZ = player.GetEntity()->GetWorldPos().z;
	float expectedJumpEndHeight = playerZ + jumpHeight;

	pe_player_dimensions dimensions;
	IPhysicalEntity *pPhysics = player.GetEntity()->GetPhysics();
	if (pPhysics && pPhysics->GetParams(&dimensions))
	{
		float physicsBottom = dimensions.heightCollider - dimensions.sizeCollider.z;
		if (dimensions.bUseCapsule)
		{
			physicsBottom -= dimensions.sizeCollider.x;
		}
		expectedJumpEndHeight += physicsBottom;
	}

	float jumpSpeed = 0.0f;

 	if (g > 0.0f)
	{
		jumpSpeed = sqrt_tpl(2.0f*jumpHeight*(1.0f/g)) * g;

		if( isHeavyWeapon )
		{
			jumpSpeed *= g_pGameCVars->pl_movement.nonCombat_heavy_weapon_speed_scale;
		}
	}

	//this is used to easily find steep ground
	float slopeDelta = (Vec3Constants<float>::fVec3_OneZ - actorPhysics.groundNormal).len();

	SetJumpState(player, JState_Jump);

	Vec3 jumpVec(ZERO);

	bool bNormalJump = true;
	
	player.PlaySound(CPlayer::ESound_Jump);

	OnSpecialMove(player, IPlayerEventListener::eSM_Jump);

	CCCPOINT_IF( player.IsClient(),   PlayerMovement_LocalPlayerNormalJump);
	CCCPOINT_IF(!player.IsClient(), PlayerMovement_NonLocalPlayerNormalJump);

	{
		// This was causing the vertical jumping speed to be much slower.
		float verticalMult = max(1.0f - m_jumpLock, 0.3f);

		const Quat baseQuat = player.GetBaseQuat();
		jumpVec += baseQuat.GetColumn2() * jumpSpeed * verticalMult;
		jumpVec.z += fVerticalSpeedModifier;

#ifdef STATE_DEBUG
		if (g_pGameCVars->pl_debugInterpolation > 1)
		{
			CryWatch("Jumping: vec from player BaseQuat only = (%f, %f, %f)", jumpVec.x, jumpVec.y, jumpVec.z);
		}
#endif
		
		if (g_pGameCVars->pl_adjustJumpAngleWithFloorNormal && actorPhysics.groundNormal.len2() > 0.0f)
		{
			float vertical = clamp_tpl((actorPhysics.groundNormal.z - 0.25f) / 0.5f, 0.0f, 1.0f);
			Vec3 modifiedJumpDirection = LERP(actorPhysics.groundNormal, Vec3(0,0,1), vertical);
			jumpVec = modifiedJumpDirection * jumpVec.len();
		}

#ifdef STATE_DEBUG
		if (g_pGameCVars->pl_debugInterpolation > 1)
		{
			CryWatch("Jumping (%f, %f, %f)", jumpVec.x, jumpVec.y, jumpVec.z);
		}
#endif
	}

	NETINPUT_TRACE(player.GetEntityId(), jumpVec);

	FinalizeVelocity( player, jumpVec );

	if (!player.IsRemote())
	{
		player.HasJumped(player.GetMoveRequest().velocity);
	}

	IPhysicalEntity* pPhysEnt = player.GetEntity()->GetPhysics();
	if (pPhysEnt != NULL)
	{
		SAnimatedCharacterParams params = player.m_pAnimatedCharacter->GetParams();
		pe_player_dynamics pd;
		pd.kAirControl = player.GetAirControl()* g_pGameCVars->pl_jump_control.air_control_scale;
		pd.kAirResistance = player.GetAirResistance() * g_pGameCVars->pl_jump_control.air_resistance_scale;

		params.inertia = player.GetInertia() * g_pGameCVars->pl_jump_control.air_inertia_scale;

		if(player.IsRemote() && (g_pGameCVars->pl_velocityInterpAirControlScale > 0))
		{
			pd.kAirControl = g_pGameCVars->pl_velocityInterpAirControlScale;
		}

		pPhysEnt->SetParams(&pd);

		// Let Animated character handle the inertia
		player.SetAnimatedCharacterParams(params);
	}

#if 0
	if (debugJumping)
	{
		Vec3 entityPos = m_player.GetEntity()->GetWorldPos();
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(entityPos, ColorB(255,255,255,255), entityPos, ColorB(255,255,0,255), 2.0f);
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(entityPos+Vec3(0,0,2), ColorB(255,255,255,255), entityPos+Vec3(0,0,2) + desiredVel, ColorB(0,255,0,255), 2.0f);
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(entityPos, ColorB(255,255,255,255), entityPos + jumpVec, ColorB(0,255,255,255), 2.0f);
		gEnv->pRenderer->DrawLabel(entityPos - entityRight * 1.0f + Vec3(0,0,3.0f), 1.5f, "Velo[%2.3f = %2.3f, %2.3f, %2.3f]", m_request.velocity.len(), m_request.velocity.x, m_request.velocity.y, m_request.velocity.z);
	}
#endif

	m_expectedJumpEndHeight = expectedJumpEndHeight;
	m_bSprintJump = player.IsSprinting();
}
void CVehicleWeaponControlled::Update(SEntityUpdateContext& ctx, int update)
{
	IVehicle *pVehicle = m_vehicleId ? gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId) : NULL; 
  if (!m_vehicleId && GetEntity()->GetParent())
  {
    IEntity *entity = GetEntity();
    
    if (entity)
    {
      IEntity *parent = entity->GetParent();
      if (parent)
      {
				m_vehicleId = parent->GetId();
        pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(parent->GetId());
      }
    }
  }



  if (pVehicle)
  {
		IVehiclePart *pPart = pVehicle->GetWeaponParentPart(GetEntityId());
		if(pPart)
		{
			if(IVehiclePart *pParentPart = pPart->GetParent())
			{
				CRY_ASSERT(pVehicle->GetEntity());

				if(ICharacterInstance *characterInst = pVehicle->GetEntity()->GetCharacter(pParentPart->GetSlot()))
				{
					if(ISkeletonPose* pose = characterInst->GetISkeletonPose())
					{
						IDefaultSkeleton& rIDefaultSkeleton = characterInst->GetIDefaultSkeleton();
						int16 joint = rIDefaultSkeleton.GetJointIDByName(pPart->GetName());
						const QuatT &jQuat = pose->GetAbsJointByID(joint);

						Matrix34 localT(jQuat);
						localT.SetTranslation(jQuat.t/* - Vec3(0.0f, 0.75f, 0.0f)*/);

						Matrix34 vehicleWorldTm = pVehicle->GetEntity()->GetWorldTM();
						Matrix34 mat = vehicleWorldTm * localT;
						Vec3 vehicleSide2 = pPart->GetParent()->GetLocalTM(true, true).GetTranslation();

						CPlayer *pl = this->GetOwnerPlayer();

						Matrix33 mat2;
						if (!m_destination.IsEquivalent(ZERO))
						{
							Vec3 diff = GetDestination() - mat.GetTranslation(); //pPart->GetWorldTM().GetTranslation();
							diff.Normalize();

							Matrix33 loc(mat);
							loc.Invert();

							Vec3 diffLocal = loc.TransformVector(diff);

							Matrix33 desMat;
							desMat.SetRotationVDir(diffLocal, 0.0f);

							Vec3 test = GetEntity()->GetLocalTM().GetColumn0();

							Ang3 testTM(desMat);

							float za = testTM.x - m_Angles.x;
							za = (za < 0.0f) ? -gf_PI : gf_PI;
							za *= 0.05f * ctx.fFrameTime;

							m_Angles.x += za;
							Limit(m_Angles.x, -gf_PI * 0.33f, gf_PI * 0.33f);

							if (testTM.z > m_Angles.z + 0.05f)
							{
								m_Angles.z += gf_PI * factor1 * ctx.fFrameTime;        
							}
							else if (testTM.z < m_Angles.z - 0.05f)
							{
								m_Angles.z -= gf_PI * factor1 * ctx.fFrameTime;        
							}
							else
							{
								m_Angles.z = testTM.z;
							}

							Limit(m_Angles.z, -gf_PI * 0.33f, gf_PI * 0.33f);
							mat2.SetRotationXYZ(m_Angles);
						}
						else
						{
							if (!m_FireBlocked)
							{
								m_Angles.x = m_Angles.x - ctx.fFrameTime * factor2 * m_Angles.x;
								m_Angles.z = m_Angles.z - ctx.fFrameTime * factor2 * m_Angles.z;
							}
							mat2.SetRotationXYZ(m_Angles);
						}

						mat = mat * mat2; 


						GetEntity()->SetWorldTM(mat);


						if (pl)
						{
							Matrix34 worldGunMat = vehicleWorldTm * localT;

							if (!pl->IsDead())
							{

								Vec3 trans = worldGunMat.GetTranslation() - worldGunMat.GetColumn2() * 0.7f;
								worldGunMat.SetTranslation(trans);

								pl->GetEntity()->SetWorldTM(worldGunMat);


								float dot = mat.GetColumn1().dot(worldGunMat.GetColumn0());
								Update3PAnim(pl, 0.5f - dot * 0.5f, ctx.fFrameTime, mat);
							}
							else
							{

								ICharacterInstance* pCharacter = pl->GetEntity()->GetCharacter(0);
								int boneId = pCharacter ? pCharacter->GetIDefaultSkeleton().GetJointIDByName("Spine03") : 7;

								pl->LinkToMountedWeapon(0);
								if (IVehicleSeat* seat = pVehicle->GetSeatForPassenger(pl->GetEntityId()))
								{
									seat->Exit(false, true);
								}

								Matrix33 rot(worldGunMat);
								Vec3 offset(0.0f, 0.0f, 0.70f);
								Vec3 transformedOff = rot.TransformVector(offset);
								Vec3 trans = worldGunMat.GetTranslation();
								trans -= transformedOff;
								worldGunMat.SetTranslation(trans);
								pl->GetEntity()->SetWorldTM(worldGunMat);
								pl->GetEntity()->SetPos(worldGunMat.GetTranslation()); //worldGunMat.GetTranslation());
								pl->RagDollize(true);

								if (boneId > -1)
								{
									IPhysicalEntity *physEnt = pl->GetEntity()->GetPhysics();
									if (physEnt)
									{
										pe_simulation_params simulationParams;
										physEnt->GetParams(&simulationParams);

										pe_params_pos pos;
										pos.pos = GetEntity()->GetPos();
										physEnt->SetParams(&pos);

										pe_action_impulse impulse;
										impulse.ipart = boneId;
										impulse.angImpulse = Vec3(0.0f, 0.0f, 1.0f);
										impulse.impulse = worldGunMat.GetColumn1() * -1.5f * simulationParams.mass;
										physEnt->Action(&impulse);
									}
								}

								StopUse(GetOwnerId());

								SetOwnerId(0);
								StopFire();

								m_FireBlocked = true;
							} // IsDead
						} // pl
					} // pose
				} // characterInst
			} // pParentPart
		} // pPart
	} // pVehicle

  Base::Update(ctx, update);
  RequireUpdate(eIUS_General);
}