Exemplo n.º 1
0
static void GetTalosInput(CPlayerRotation * pPlayerRotation, const CPlayer& rPlayer, float& x, float& z, const Vec3 playerView[4], float fFrameTime)
{
	//Do I need to reproject the view to actually get the positioning correct? Shouldn't be.
	const Vec3 playerFwd = playerView[1];
	const Vec3 playerRgt = playerView[0];
	const Vec3 playerUp = playerView[2];
	const Vec3 playerViewPos = playerView[3];


	Vec3 playerPos = playerViewPos;

	IPhysicalEntity * pPhysicalEntity = rPlayer.GetEntity()->GetPhysics();
	if(pPhysicalEntity)
	{
		pe_status_dynamics dyn_status;
		pPhysicalEntity->GetStatus(&dyn_status);		
		playerPos = playerViewPos + (dyn_status.v * fFrameTime * 2.0f);
	}

	Vec3 follow_target_dir(ZERO);

	EntityId follow_target_id = 0;
	static EntityId s_follow_target_id = 0;

	CGameRules * pGameRules = g_pGame->GetGameRules();
	int playerTeam = pGameRules->GetTeam(rPlayer.GetEntity()->GetId());
	float cloakedPlayerMultiplier = g_pGameCVars->pl_aim_cloaked_multiplier;
	const bool multipleTeams = pGameRules->GetTeamCount() > 0;

	const TAutoaimTargets& aaTargets = g_pGame->GetAutoAimManager().GetAutoAimTargets();
	const int targetCount = aaTargets.size();
	float fBestTargetDistance = FLT_MAX;

	for (int i = 0; i < targetCount; ++i)
	{
		const SAutoaimTarget& target = aaTargets[i];

		if(multipleTeams &&  (pGameRules->GetTeam(target.entityId) == playerTeam))
		{
			continue;
		}

		Vec3 targetPos = target.secondaryAimPosition;
		
		IEntity * pEntity = gEnv->pEntitySystem->GetEntity(target.entityId);
		if(pEntity)
		{
			IPhysicalEntity * pPhysicalEntity2 = pEntity->GetPhysics();
			if(pPhysicalEntity2)
			{
				pe_status_dynamics dyn_status;
				pPhysicalEntity2->GetStatus(&dyn_status);		
				targetPos = targetPos + (dyn_status.v * fFrameTime);
			}
		}

		Vec3 targetDistVec = (targetPos - playerPos);
		float distance = targetDistVec.GetLength();

		if (distance <= 0.01f)
			continue;

		Vec3 dirToTarget = targetDistVec / distance;

		// fast reject everything behind player, too far away or too near from line of view
		// sort rest by angle to crosshair and distance from player

		const int kAutoaimVisibilityLatency = 1;
		if (!g_pGame->GetPlayerVisTable()->CanLocalPlayerSee(target.entityId, kAutoaimVisibilityLatency))
		{
			// Since both player and target entities are ignored, and the ray still intersected something, there's something in the way.
			// Need to profile this and see if it's faster to do the below checks before doing the linetest. It's fairly expensive but
			// linetests generally are as well... - Richard
			continue;
		}

		const float angleDot = dirToTarget.dot(-playerRgt);
		const float angle = (RAD2DEG(acos_tpl(angleDot)) - 90.f);
		const float absAngle = fabsf(angle);

		const float angleDotV = playerUp.dot(dirToTarget);
		const float angleToTargetV = (RAD2DEG(acos_tpl(angleDotV)) - 90.f);
		const float absAngleV = fabsf(angleToTargetV);

		if ( s_follow_target_id == target.entityId )
		{
			follow_target_id = target.entityId;
			follow_target_dir = dirToTarget;
			break;
		}
		else if(distance < fBestTargetDistance)
		{
			fBestTargetDistance = distance;
			follow_target_id = target.entityId;
			follow_target_dir = dirToTarget;
		}
	}

	if(follow_target_id != 0)
	{
		//Player up is the normal of the plane that we are rotating around - (Correct? Or do we want to project both the player direction and the target direction onto the X/Y plane?)
		Vec3 vProjectedTargetHorz = playerUp.cross(follow_target_dir.cross(playerUp));
		Vec3 vProjectedTargetVert = playerRgt.cross(follow_target_dir.cross(playerRgt));

		float horzDot = vProjectedTargetHorz.GetNormalized().dot(playerFwd);
		float vertDot = vProjectedTargetVert.GetNormalized().dot(playerFwd);

		const float directionDotHorz = follow_target_dir.dot(playerRgt);
		const float directionDotVert = follow_target_dir.dot(playerUp);
		
		const float angle						= acos_tpl(horzDot);
		const float angleToTargetV	= acos_tpl(vertDot);		

		const float fHorzFinalAngle = (float)__fsel(directionDotHorz, -angle, angle);
		const float fVertFinalAngle = (float)__fsel(directionDotVert, angleToTargetV, -angleToTargetV);

		//CryWatch("Angle to target: %.6f", RAD2DEG(angle));
		//CryWatch("Final Angle to target: %.6f", RAD2DEG(fHorzFinalAngle));

		x = x + fVertFinalAngle;
		z = z + fHorzFinalAngle;
	}

	s_follow_target_id  = follow_target_id;

	return;
}
Exemplo n.º 2
0
void CSmokeManager::CullOtherSmokeEffectsInProximityWhenGrenadeHasLanded(SSmokeInstance& smokeInstance, IEntity* pGrenade)
{
    if(pGrenade && (smokeInstance.state == eSIS_Active_PhysicsAwake))
        {
            IPhysicalEntity* pPhysEnt = pGrenade->GetPhysics();
            if(pPhysEnt)
                {
                    pe_status_awake psa;
                    if(pPhysEnt->GetStatus(&psa) == false)
                        {
                            // Was awake, now asleep...
                            SSmokeInstance* pOldestSmokeInstanceToDelete = NULL;
                            const int kNumActiveSmokeInstances = m_numActiveSmokeInstances;
                            uint32 otherSmokeInstanceProximityCount = 0;
                            SSmokeInstance* pOtherSmokeInstance = NULL;

                            PrefetchLine(m_smokeInstances, 0);
                            PrefetchLine(m_smokeInstances, 128);

                            // Find oldest smoke grenade effect in proximity
                            for(int i=0; i<kNumActiveSmokeInstances; i++)
                                {
                                    pOtherSmokeInstance = &m_smokeInstances[i];

                                    if(pOtherSmokeInstance != &smokeInstance)
                                        {
                                            PrefetchLine(pOtherSmokeInstance, 128);

                                            const float fDistanceSq = Distance::Point_PointSq(smokeInstance.vPositon, pOtherSmokeInstance->vPositon);

                                            const float fCombinedRadiusSq = sqr(smokeInstance.fMaxRadius) + sqr(pOtherSmokeInstance->fMaxRadius);
                                            if(fDistanceSq < fCombinedRadiusSq)
                                                {
                                                    otherSmokeInstanceProximityCount++;
                                                    if(pOldestSmokeInstanceToDelete == NULL || (pOldestSmokeInstanceToDelete->fTimer < pOtherSmokeInstance->fTimer))
                                                        {
                                                            pOldestSmokeInstanceToDelete = pOtherSmokeInstance;
                                                        }
                                                }
                                        }
                                }

                            // Delete old smoke effect in proximity if there are too many
                            if(pOldestSmokeInstanceToDelete && (otherSmokeInstanceProximityCount >= kMaxSmokeEffectsInSameArea))
                                {
                                    IEntity * pGrenadeToDeleteParticleEmitterFor = gEnv->pEntitySystem->GetEntity(pOldestSmokeInstanceToDelete->grenadeId);
                                    if(pGrenadeToDeleteParticleEmitterFor)
                                        {
                                            int slotCount = pGrenadeToDeleteParticleEmitterFor->GetSlotCount();
                                            for(int i=0; i<slotCount; i++)
                                                {
                                                    IParticleEmitter* pParticleEmitter = pGrenadeToDeleteParticleEmitterFor->GetParticleEmitter(i);
                                                    if(pParticleEmitter)
                                                        {
                                                            pParticleEmitter->Activate(false);
                                                        }
                                                }
                                        }
                                    pOldestSmokeInstanceToDelete->state = eSIS_ForDeletion;
                                }

                            smokeInstance.state = eSIS_Active_PhysicsAsleep;
                        }
                }
        }
}
//////////////////////////////////////////////////////////////////////////
// IsMountedWeaponUsableWithTarget
// A piece of game-code moved from CryAction when scriptbind_AI moved to the AI system
//////////////////////////////////////////////////////////////////////////
int CScriptBind_Game::IsMountedWeaponUsableWithTarget(IFunctionHandler *pH)
{
	int paramCount = pH->GetParamCount();

	if(paramCount < 2)
	{
		//gEnv->pAISystem->Warning("<CScriptBind> ", "IsMountedWeaponUsableWithTarget(): too few parameters.");
		GameWarning("%s: too few parameters.", __FUNCTION__);
		return pH->EndFunction();
	}

	GET_ENTITY(1);

	if(!pEntity)
	{
		//gEnv->pAISystem->Warning("<CScriptBind> ", "IsMountedWeaponUsableWithTarget(): wrong entity id in parameter 1.");
		GameWarning("%s: wrong entity id in parameter 1.", __FUNCTION__);
		return pH->EndFunction();
	}

	IAIObject *pAI = pEntity->GetAI();

	if (!pAI)
	{
		//gEnv->pAISystem->Warning("<CScriptBind> ", "IsMountedWeaponUsableWithTarget(): Entity '%s' does not have AI.", pEntity->GetName());
		GameWarning("%s: Entity '%s' does not have AI.", __FUNCTION__,  pEntity->GetName());
		return pH->EndFunction();
	}

	EntityId itemEntityId;
	ScriptHandle hdl2;

	if(!pH->GetParam(2, hdl2))
	{
		//gEnv->pAISystem->Warning("<CScriptBind> ", "IsMountedWeaponUsableWithTarget(): wrong parameter 2 format.");
		GameWarning("%s: wrong parameter 2 format.", __FUNCTION__);
		return pH->EndFunction();
	}

	itemEntityId = (EntityId) hdl2.n;

	if (!itemEntityId)
	{
		//gEnv->pAISystem->Warning("<CScriptBind> ", "IsMountedWeaponUsableWithTarget(): wrong entity id in parameter 2.");
		GameWarning("%s: wrong entity id in parameter 2.", __FUNCTION__);
		return pH->EndFunction();
	}

	IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework();
	IItem *pItem = pGameFramework->GetIItemSystem()->GetItem(itemEntityId);

	if (!pItem)
	{
		//gEnv->pAISystem->Warning("<CScriptBind> ", "entity in parameter 2 is not an item/weapon");
		GameWarning("%s: entity in parameter 2 is not an item/weapon.", __FUNCTION__);
		return pH->EndFunction();
	}

	float minDist = 7;
	bool bSkipTargetCheck = false;
	Vec3 targetPos(ZERO);

	if(paramCount > 2)
	{
		for(int i = 3; i <= paramCount ; i++)
		{
			if(pH->GetParamType(i) == svtBool)
			{
				pH->GetParam(i, bSkipTargetCheck);
			}
			else if(pH->GetParamType(i) == svtNumber)
			{
				pH->GetParam(i, minDist);
			}
			else if(pH->GetParamType(i) == svtObject)
			{
				pH->GetParam(i, targetPos);
			}
		}
	}

	IAIActor *pAIActor = CastToIAIActorSafe(pAI);

	if (!pAIActor)
	{
		GameWarning("%s: entity '%s' in parameter 1 is not an AI actor.", __FUNCTION__, pEntity->GetName());
		return pH->EndFunction();
	}

	IEntity *pItemEntity = pItem->GetEntity();

	if(!pItemEntity)
	{
		return pH->EndFunction();
	}

	if(!pItem->GetOwnerId())
	{
		// weapon is not used, check if it is on a vehicle
		IEntity *pParentEntity = pItemEntity->GetParent();

		if(pParentEntity)
		{
			IAIObject *pParentAI = pParentEntity->GetAI();

			if(pParentAI && pParentAI->GetAIType() == AIOBJECT_VEHICLE)
			{
				// (MATT) Feature was cut and code was tricky, hence ignore weapons in vehicles  {2008/02/15:11:08:51}
				return pH->EndFunction();
			}
		}
	}
	else if( pItem->GetOwnerId() != pEntity->GetId()) // item is used by someone else?
	{
		return pH->EndFunction(false);
	}

	// check target
	if(bSkipTargetCheck)
	{
		return pH->EndFunction(true);
	}

	IAIObject *pTarget = pAIActor->GetAttentionTarget();

	if(targetPos.IsZero())
	{
		if(!pTarget)
		{
			return pH->EndFunction();
		}

		targetPos = pTarget->GetPos();
	}

	Vec3 targetDir(targetPos - pItemEntity->GetWorldPos());
	Vec3 targetDirXY(targetDir.x, targetDir.y, 0);
	float length2D = targetDirXY.GetLength();

	if(length2D < minDist || length2D <= 0)
	{
		return pH->EndFunction();
	}

	targetDirXY /= length2D;//normalize
	Vec3 mountedAngleLimits(pItem->GetMountedAngleLimits());
	float yawRange = DEG2RAD(mountedAngleLimits.z);

	if(yawRange > 0 && yawRange < gf_PI)
	{
		float deltaYaw = pItem->GetMountedDir().Dot(targetDirXY);

		if(deltaYaw < cosf(yawRange))
		{
			return pH->EndFunction(false);
		}
	}

	float minPitch = DEG2RAD(mountedAngleLimits.x);
	float maxPitch = DEG2RAD(mountedAngleLimits.y);
	//maxPitch = (maxPitch - minPitch)/2;
	//minPitch = -maxPitch;
	float pitch = atanf(targetDir.z / length2D);

	if ( pitch < minPitch || pitch > maxPitch )
	{
		return pH->EndFunction(false);
	}

	if(pTarget)
	{
		IEntity *pTargetEntity = pTarget->GetEntity();

		if(pTargetEntity)
		{
			// check target distance and where he's going
			IPhysicalEntity *phys = pTargetEntity->GetPhysics();

			if(phys)
			{
				pe_status_dynamics	dyn;
				phys->GetStatus(&dyn);
				Vec3 velocity ( dyn.v);
				velocity.z = 0;
				float speed = velocity.GetLength2D();

				if(speed > 0)
				{
					//velocity /= speed;
					if(length2D < minDist * 0.75f && velocity.Dot(targetDirXY) <= 0)
					{
						return pH->EndFunction(false);
					}
				}
			}
		}
	}

	return pH->EndFunction(true);
}
Exemplo n.º 4
0
void CTornado::UpdateFlow()
{
	IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem();
	assert(pVehicleSystem);

	float frameTime(gEnv->pTimer->GetFrameTime());

	IPhysicalWorld *ppWorld = gEnv->pPhysicalWorld;

	Vec3 pos(GetEntity()->GetWorldPos());

	//first, check the entities in range
	m_nextEntitiesCheck -= frameTime;
	if (m_nextEntitiesCheck<0.0f)
	{
		m_nextEntitiesCheck = 1.0f;
		
		Vec3 radiusVec(m_radius,m_radius,0);
		
		IPhysicalEntity **ppList = NULL;

		int	numEnts = ppWorld->GetEntitiesInBox(pos-radiusVec,pos+radiusVec+Vec3(0,0,m_cloudHeight*0.5f),ppList,ent_sleeping_rigid|ent_rigid|ent_living);

		m_spinningEnts.clear();
		for (int i=0;i<numEnts;++i)
		{
			// add check for spectating players...
			EntityId id = ppWorld->GetPhysicalEntityId(ppList[i]);
			CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
			if(!pActor || !pActor->GetSpectatorMode())
			{
				m_spinningEnts.push_back(id);
			}
		}
		//OutputDistance();
	}

	//mess entities around
	for (size_t i=0;i<m_spinningEnts.size();++i)
	{
		IPhysicalEntity *ppEnt = ppWorld->GetPhysicalEntityById(m_spinningEnts[i]);
		if (ppEnt)
		{
			pe_status_pos spos;
			pe_status_dynamics sdyn;

			if (!ppEnt->GetStatus(&spos) || !ppEnt->GetStatus(&sdyn))
				continue;
		
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(spos.pos,2.0f,ColorB(255,0,255,255));
						
			Vec3 delta(pos - spos.pos);
			delta.z = 0.0f;

			float dLen(delta.len());
			float forceMult(max(0.0f,(m_radius-dLen)/m_radius));

			if (dLen>0.001f)
				delta /= dLen;
			else
				delta.zero();

			Vec3 upVector(0,0,1);

			float spinImpulse(m_spinImpulse);
			float attractionImpulse(m_attractionImpulse);
			float upImpulse(m_upImpulse);

			if (ppEnt->GetType() == PE_LIVING)
			{
				upImpulse *= 0.75f;
				attractionImpulse *= 0.35f;
				spinImpulse *= 1.5f;
			}

			
			if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(m_spinningEnts[i]))
			{
				IVehicleMovement* pMovement = pVehicle->GetMovement();

				if (pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
				{
					SVehicleMovementEventParams params;
					params.fValue = forceMult;
					pMovement->OnEvent(IVehicleMovement::eVME_Turbulence, params);
				}
			}

			Vec3 spinForce( (delta % upVector) * spinImpulse );
			Vec3 attractionForce(delta * attractionImpulse);
			Vec3 upForce(0,0,upImpulse);

			pe_action_impulse aimpulse;

			aimpulse.impulse = (spinForce + attractionForce + upForce) * (forceMult * sdyn.mass * frameTime);
			aimpulse.angImpulse = (upVector + (delta % upVector)) * (gf_PI * 0.33f * forceMult * sdyn.mass * frameTime);

			aimpulse.iApplyTime = 0;
			ppEnt->Action(&aimpulse);

			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(spos.pos,ColorB(255,0,255,255),spos.pos+aimpulse.impulse.GetNormalizedSafe(ZERO),ColorB(255,0,255,255));
		}
	}
}
Exemplo n.º 5
0
void CAVMine::ProcessEvent(SEntityEvent &event)
{
	if (m_frozen)
		return;

	switch(event.event)
	{
		case ENTITY_EVENT_ENTERAREA:
		{
			IEntity * pEntity = gEnv->pEntitySystem->GetEntity(event.nParam[0]);
			CGameRules* pGR = g_pGame->GetGameRules();
			if(pEntity && pGR)
			{
				// if this is a team game, mines aren't set off by their own team
				if(pGR->GetTeamCount() > 0 && (m_teamId != 0 && pGR->GetTeam(pEntity->GetId()) == m_teamId))
					break;

				// otherwise, not set off by the player who dropped them.
				if(pGR->GetTeamCount() == 0 && m_ownerId == pEntity->GetId())
					break;

				// or a vehicle that player might happen to be in
				IVehicle* pVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(event.nParam[0]);
				if(pVehicle && pVehicle->GetSeatForPassenger(m_ownerId))
					break;

				IPhysicalEntity *pPhysics = pEntity->GetPhysics();
				if(pPhysics)
				{
					pe_status_dynamics physStatus;
					if(0 != pPhysics->GetStatus(&physStatus))
					{
						// only count moving objects
						if(physStatus.v.GetLengthSquared() > 0.1f)
							m_currentWeight += physStatus.mass;

						if (m_currentWeight > m_triggerWeight)
							Explode(true);
					}
				}
			}
			break;
		}
		

		case ENTITY_EVENT_LEAVEAREA:
		{
			IEntity * pEntity = gEnv->pEntitySystem->GetEntity(event.nParam[0]);
			if(pEntity)
			{
				IPhysicalEntity *pPhysics = pEntity->GetPhysics();
				if(pPhysics)
				{
					pe_status_dynamics physStatus;
					if(0 != pPhysics->GetStatus(&physStatus))
					{
						m_currentWeight -= physStatus.mass;

						if(m_currentWeight < 0)
							m_currentWeight = 0;
					}
				}
			}
			break;
		}

		default:
			break;
	}

	return CProjectile::ProcessEvent(event);
}
//------------------------------------------------------------------------
float CGameRulesCommonDamageHandling::GetCollisionEnergy( const IEntity *pVictim, const CGameRules::SCollisionHitInfo& colHitInfo ) const
{
	float m1 = colHitInfo.target_mass;
	float m0 = 0.f;

	IPhysicalEntity *phys = pVictim->GetPhysics();
	if(phys)
	{
		pe_status_dynamics	dyn;
		phys->GetStatus(&dyn);
		m0 = dyn.mass;
	}

	IEntity *pOffender = gEnv->pEntitySystem->GetEntity(colHitInfo.targetId);
	bool bCollider = (pOffender || m1 > 0.001f);

	const bool debugColl = DebugCollisions();
	if (debugColl)
	{
		CryLog("GetCollisionEnergy %s (%.1f) <-> %s (%.1f)", pVictim?pVictim->GetName():"[no entity]", m0, pOffender?pOffender->GetName():"[no entity]", m1);
	}

	float v0Sq = 0.f, v1Sq = 0.f;

	if (bCollider)	// non-static
	{
		m0 = min(m0, m1);

		Vec3 v0normal, v1normal, vrel;
		Vec3 tempNormal = colHitInfo.normal;

		float v0dotN = colHitInfo.velocity.dot(colHitInfo.normal);
		v0normal = tempNormal.scale(v0dotN);

		float v1dotN = colHitInfo.target_velocity.dot(colHitInfo.normal);;  // "target" is the offender
		v1normal = tempNormal.scale(v1dotN);

		vrel = v0normal.sub(v1normal);
		float vrelSq = vrel.len2();

		v0Sq = min( sqr(v0dotN), vrelSq );
		v1Sq = min( sqr(v1dotN), vrelSq );

		if (debugColl)
		{
			IPersistantDebug* pPD = g_pGame->GetIGameFramework()->GetIPersistantDebug();

			pPD->Begin("CollDamage", false);
			pPD->AddSphere(colHitInfo.pos, 0.15f, Col_Red, 5.f);
			pPD->AddDirection(colHitInfo.pos, 1.5f, tempNormal.scale(sgn(v0dotN)), Col_Green, 5.f);
			pPD->AddDirection(colHitInfo.pos, 1.5f, tempNormal.scale(sgn(v1dotN)), Col_Red, 5.f);

			if ((v0Sq > 2*2) || (v1Sq > 2*2))
			{
				CryLog("normal velocities: rel %.1f, <%s> %.1f / <%s> %.1f", sqrt(vrelSq), pVictim?pVictim->GetName():"none", v0dotN, pOffender?pOffender->GetName():"none", v1dotN); 
				CryLog("target_type: %i, target_velocity: %.2f %.2f %.2f", colHitInfo.target_type, colHitInfo.target_velocity.x, colHitInfo.target_velocity.y, colHitInfo.target_velocity.z);
			}
		}
	}
	else
	{
		v0Sq = sqr(colHitInfo.velocity.dot(colHitInfo.normal));

		if (debugColl && v0Sq>5*5)
		{
			IPersistantDebug* pPD = g_pGame->GetIGameFramework()->GetIPersistantDebug();

			pPD->Begin("CollDamage", false);
			pPD->AddDirection(colHitInfo.pos, 1.5f, colHitInfo.normal, Col_Green, 5.f);
			string debugText;
			debugText.Format("z: %f", colHitInfo.velocity.z);
			pPD->Add2DText(debugText.c_str(), 1.5f, Col_White, 5.f);
		}
	}

	float colliderEnergyScale = 1.f;
	if (pVictim != NULL && pOffender != NULL)
	{
		if(IActor* pVictimActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pVictim->GetId()))
		{
			colliderEnergyScale = !pVictimActor->IsPlayer() ?	GetAIPlayerAgainstColliderEnergyScale(*pOffender) :
																GetPlayerAgainstColliderEnergyScale(*pOffender);
			
			if (debugColl)
			{
				CryLog("colliderEnergyScale: %.1f", colliderEnergyScale);
			}
		}
	}

	const float energy0 = 0.5f * m0 * v0Sq;
	const float energy1 = 0.5f * m1 * v1Sq * colliderEnergyScale;

	return energy0 + energy1;
}
Exemplo n.º 7
0
//------------------------------------------------------------------------
bool CGameRules::OnInitiate(SHostMigrationInfo& hostMigrationInfo, uint32& state)
{
	if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session))
	{
		return true;
	}

	CryLog("[Host Migration]: CGameRules::OnInitiate() Saving character for host migration started");

	m_hostMigrationClientHasRejoined = false;

	IEntityScriptProxy* pScriptProxy = static_cast<IEntityScriptProxy*>(GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT));
	if (pScriptProxy)
	{
		if (string(pScriptProxy->GetState())  == "InGame")
		{
			m_hostMigrationTimeSinceGameStarted = (m_cachedServerTime - m_gameStartedTime);
		}
	}

	HostMigrationStopAddingPlayers();

	if (gEnv->IsClient())
	{
		if (!m_pHostMigrationParams)
		{
			m_pHostMigrationParams = new SHostMigrationClientRequestParams();
			m_pHostMigrationClientParams = new SHostMigrationClientControlledParams();
		}

		IActor *pPlayer = g_pGame->GetIGameFramework()->GetClientActor();
		if (pPlayer)
		{
			m_pHostMigrationClientParams->m_viewQuat = pPlayer->GetViewRotation();
			m_pHostMigrationClientParams->m_position = pPlayer->GetEntity()->GetPos();

			pe_status_living livStat;
			IPhysicalEntity *pPhysicalEntity = pPlayer->GetEntity()->GetPhysics();
			if (pPhysicalEntity != NULL && (pPhysicalEntity->GetType() == PE_LIVING) && (pPhysicalEntity->GetStatus(&livStat) > 0))
			{
				m_pHostMigrationClientParams->m_velocity = livStat.velUnconstrained;
				m_pHostMigrationClientParams->m_hasValidVelocity = true;
				CryLog("    velocity={%f,%f,%f}", m_pHostMigrationClientParams->m_velocity.x, m_pHostMigrationClientParams->m_velocity.y, m_pHostMigrationClientParams->m_velocity.z);
			}

			IInventory *pInventory = pPlayer->GetInventory();

			m_pHostMigrationClientParams->m_numExpectedItems = 0;

			int numAmmoTypes = 0;
			m_pHostMigrationClientParams->m_pAmmoParams = new SHostMigrationClientControlledParams::SAmmoParams[numAmmoTypes];
			m_pHostMigrationClientParams->m_numAmmoParams = numAmmoTypes;

			/*CryLog("  player has %i different ammo types", numAmmoTypes);
			for (int i = 0; i < numAmmoTypes; ++ i)
			{
				IEntityClass *pAmmoType = pInventory->GetAmmoType(i);
				int ammoCount = pInventory->GetAmmoCount(pAmmoType);

				m_pHostMigrationClientParams->m_pAmmoParams[i].m_pAmmoClass = pAmmoType;
				m_pHostMigrationClientParams->m_pAmmoParams[i].m_count = ammoCount;

				CryLog("    %s : %i", pAmmoType->GetName(), ammoCount);
			}*

			EntityId holseredItemId = pInventory->GetHolsteredItem();
			if (holseredItemId)
			{
				IEntity *pHolsteredEntity = gEnv->pEntitySystem->GetEntity(holseredItemId);
				if (pHolsteredEntity)
				{
					m_pHostMigrationClientParams->m_pHolsteredItemClass = pHolsteredEntity->GetClass();
				}
			}*/

			IMovementController *pMovementController = pPlayer->GetMovementController();
			if(pMovementController)
			{
				SMovementState movementState;
				pMovementController->GetMovementState(movementState);

				m_pHostMigrationClientParams->m_aimDirection = movementState.aimDirection;
			}

			/*CItem *pItem = static_cast<CItem*>(pPlayer->GetCurrentItem());
			if (pItem)
			{
				m_pHostMigrationClientParams->m_pSelectedItemClass = pItem->GetEntity()->GetClass();
				CryLog("  currently using item '%s", pItem->GetEntity()->GetName());
			}*/
		}
		else
		{
			CRY_ASSERT_MESSAGE(false, "Failed to find client actor when initiating a host migration");
			gEnv->pNetwork->TerminateHostMigration(hostMigrationInfo.m_session);
			return false;
		}
	}

	g_pGame->SetHostMigrationState(CGame::eHMS_WaitingForPlayers);

	CCCPOINT(HostMigration_OnInitiate);
	return true;
}
//////////////////////////////////////////////////////////////////////////
// NOTE: This function must be thread-safe. Before adding stuff contact MarcoC.
void CVehicleMovementHelicopter::ProcessMovement(const float deltaTime)
{
    FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

    IPhysicalEntity* pPhysics = GetPhysics();
    assert(pPhysics);

    if (m_arcade.m_handling.maxSpeedForward>0.f) // Use the new handling code
        {
            CryAutoCriticalSection lk(m_lock);

            if (!m_isEnginePowered)
                return;

            CVehicleMovementBase::ProcessMovement(deltaTime);
            SVehiclePhysicsStatus* physStatus = &m_physStatus[k_physicsThread];

            if(m_bApplyNoiseAsVelocity)
                {
                    physStatus->v -= m_pNoise->m_posDifference;
                    physStatus->w -= m_pNoise->m_angDifference;

                    m_pNoise->Update(deltaTime);
                }


            ///////////////////////////////////////////////////////////////
            // Pass on the movement request to the active physics handler
            // NB: m_physStatus is update by this call
            SVehiclePhysicsHelicopterProcessParams params;
            params.pPhysics = pPhysics;
            params.pPhysStatus = physStatus;
            params.pInputAction = &m_inputAction;
            params.dt = deltaTime;
            params.haveDriver = (m_actorId!=0)||m_remotePilot;
            params.isAI = m_movementAction.isAI;
            params.aiRequiredVel = m_CurrentVel;

            m_arcade.ProcessMovement(params);

            // Network error adjustment
            m_netPosAdjust *= max(0.f, 1.f-deltaTime*k_netErrorPosScale);
            physStatus->v += m_netPosAdjust * k_netErrorPosScale;

            if(m_bApplyNoiseAsVelocity)
                {
                    physStatus->v += m_pNoise->m_posDifference;
                    physStatus->w += m_pNoise->m_angDifference;
                }

            //===============================================
            // Commit the velocity back to the physics engine
            //===============================================
            // if (fabsf(m_movementAction.rotateYaw)>0.05f || vel.GetLengthSquared()>0.001f || m_chassis.vel.GetLengthSquared()>0.001f || angVel.GetLengthSquared()>0.001f || angVel.GetLengthSquared()>0.001f)
            {
                pe_action_set_velocity setVelocity;
                setVelocity.v = physStatus->v;
                setVelocity.w = physStatus->w;
                pPhysics->Action(&setVelocity, 1);
            }
            ///////////////////////////////////////////////////////////////
        }
    else
        {
            if (m_isEnginePowered && pPhysics)
                {
                    m_movementAction.isAI = true;

                    pe_status_pos psp;
                    pe_status_dynamics psd;
                    if (!pPhysics->GetStatus(&psp) || !pPhysics->GetStatus(&psd))
                        return;
                    UpdatePhysicsStatus(&m_physStatus[k_physicsThread], &psp, &psd);

                    ProcessAI(deltaTime);
                }
        }
}
//------------------------------------------------------------------------
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];
            _snprintf(buf, sizeof(buf), "%s_%02i", name.c_str(), p);
            buf[sizeof(buf)-1] = '\0';
                        
            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!",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);
      }
    }
  }  
}
Exemplo n.º 10
0
void CAVMine::ProcessEvent(SEntityEvent &event)
{
	if (m_frozen)
		return;

	switch(event.event)
	{
		case ENTITY_EVENT_ENTERAREA:
		{
			IEntity * pEntity = gEnv->pEntitySystem->GetEntity((EntityId)event.nParam[0]);
			CGameRules* pGR = g_pGame->GetGameRules();
			if(pEntity && pGR)
			{
				// if this is a team game, mines aren't set off by their own team
				if(pGR->GetTeamCount() > 0 && (m_teamId != 0 && pGR->GetTeam(pEntity->GetId()) == m_teamId))
					break;

				IPhysicalEntity *pPhysics = pEntity->GetPhysics();
				if(pPhysics)
				{
					pe_status_dynamics physStatus;
					if(0 != pPhysics->GetStatus(&physStatus))
					{
						// only count moving objects
						if(physStatus.v.GetLengthSquared() > 0.1f)
							m_currentWeight += physStatus.mass;

						if (m_currentWeight > m_triggerWeight)
							Explode(true);
					}
				}
			}
			break;
		}
		

		case ENTITY_EVENT_LEAVEAREA:
		{
			IEntity * pEntity = gEnv->pEntitySystem->GetEntity((EntityId)event.nParam[0]);
			if(pEntity)
			{
				IPhysicalEntity *pPhysics = pEntity->GetPhysics();
				if(pPhysics)
				{
					pe_status_dynamics physStatus;
					if(0 != pPhysics->GetStatus(&physStatus))
					{
						m_currentWeight -= physStatus.mass;

						if(m_currentWeight < 0)
							m_currentWeight = 0;
					}
				}
			}
			break;
		}

		default:
			break;
	}

	return CProjectile::ProcessEvent(event);
}
Exemplo n.º 11
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();
}
Exemplo n.º 12
0
//------------------------------------------------------------------------
Vec3 CGunTurret::PredictTargetPos(IEntity *pTarget, bool sec)//sec - weapon to use
{
	pTarget = ResolveTarget(pTarget);
	Vec3 tpos = GetTargetPos(pTarget);

	if(m_turretparams.search_only || m_turretparams.prediction == 0.f)
		return tpos;

	IPhysicalEntity *pe = pTarget->GetPhysics();
	pe_status_dynamics dyn;

	if(!pe || !pe->GetStatus(&dyn))
		return tpos;

	Vec3 vel = dyn.v;
	Vec3 acc = dyn.a;
	float a = acc.len();

	if(a < 0.01f)
		a = 0.f;
	else
		acc /= a;

	Vec3 vpos = GetWeaponPos();
	Vec3 dist = tpos-vpos;
	float d = dist.len();

	if(d < 0.01f)
		return tpos;

	dist /= d;
	float d_speed = vel*dist;

	float speed = 800.0f;
	const SAmmoParams *ammo = g_pGame->GetWeaponSystem()->GetAmmoParams(GetFireMode(0)->GetAmmoType());

	if(!ammo)
		return tpos;

	if(ammo->physicalizationType == ePT_None)
		return tpos;

	speed = ammo->speed;

	float time_to = d/max(1.f, speed-d_speed);

	// MR: clamped acc prediction to reduce jerkyness when targetting objects that are able
	// to do near-instant velocity changes (like players)
	a = min(a, 25.f);

	Vec3 delta = vel*(time_to) + 0.5f*a*acc*time_to*time_to;
	delta *= m_turretparams.prediction;

	if(g_pGameCVars->i_debug_turrets == eGTD_Prediction)
	{
		IPersistantDebug *pDebug = gEnv->pGame->GetIGameFramework()->GetIPersistantDebug();
		pDebug->Begin("CGunTurret::PredictTargetPos", false);
		pDebug->AddSphere(tpos+delta, 0.2f, ColorF(1,0,0,1), 1.f);
		gEnv->pRenderer->DrawLabel(vpos, 1.4f, "Predict %s: speed %.1f (dspeed %.1f), acc %.1f, time %.1f", pTarget->GetName(), vel.len(), d_speed, a, time_to);
	}

	return tpos+delta;
}
//------------------------------------------------------------------------
bool CGameRules::OnInitiate(SHostMigrationInfo &hostMigrationInfo, uint32 &state)
{
	if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session))
	{
		return true;
	}

	CryLog("[Host Migration]: CGameRules::OnInitiate() Saving character for host migration started");
	m_hostMigrationClientHasRejoined = false;
	IEntityScriptProxy *pScriptProxy = static_cast<IEntityScriptProxy *>(GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT));

	if (pScriptProxy)
	{
		if (string(pScriptProxy->GetState())  == "InGame")
		{
			m_hostMigrationTimeSinceGameStarted = (m_cachedServerTime - m_gameStartedTime);
		}
	}

	HostMigrationStopAddingPlayers();

	if (gEnv->IsClient())
	{
		if (!m_pHostMigrationParams)
		{
			m_pHostMigrationParams = new SHostMigrationClientRequestParams();
			m_pHostMigrationClientParams = new SHostMigrationClientControlledParams();
		}

		CPlayer *pPlayer = static_cast<CPlayer *>(g_pGame->GetIGameFramework()->GetClientActor());

		if (pPlayer)
		{
			m_pHostMigrationClientParams->m_viewQuat = pPlayer->GetViewRotation();
			m_pHostMigrationClientParams->m_position = pPlayer->GetEntity()->GetPos();
			pe_status_living livStat;
			IPhysicalEntity *pPhysicalEntity = pPlayer->GetEntity()->GetPhysics();

			if (pPhysicalEntity != NULL && (pPhysicalEntity->GetType() == PE_LIVING) && (pPhysicalEntity->GetStatus(&livStat) > 0))
			{
				m_pHostMigrationClientParams->m_velocity = livStat.velUnconstrained;
				m_pHostMigrationClientParams->m_hasValidVelocity = true;
				CryLog("    velocity={%f,%f,%f}", m_pHostMigrationClientParams->m_velocity.x, m_pHostMigrationClientParams->m_velocity.y, m_pHostMigrationClientParams->m_velocity.z);
			}

			IMovementController *pMovementController = pPlayer->GetMovementController();
			SMovementState movementState;
			pMovementController->GetMovementState(movementState);
			m_pHostMigrationClientParams->m_aimDirection = movementState.aimDirection;
		}
		else
		{
			CRY_ASSERT_MESSAGE(false, "Failed to find client actor when initiating a host migration");
			gEnv->pNetwork->TerminateHostMigration(hostMigrationInfo.m_session);
			return false;
		}
	}

	g_pGame->SetHostMigrationState(CGame::eHMS_WaitingForPlayers);
	CCCPOINT(HostMigration_OnInitiate);
	return true;
}