void Officer::RenderFlag( float _predictionTime )
{
    float timeIndex = g_gameTime + m_id.GetUniqueId() * 10;
    float size = 20.0f;

    Vector3 up = g_upVector;
    Vector3 front = m_front * -1;
    front.y = 0;
    front.Normalise();

    if( m_orders != OrderNone )
    {
        up.RotateAround( front * sinf(timeIndex*2) * 0.3f );
    }

    Vector3 entityUp = g_upVector;
    Vector3 entityRight(m_front ^ entityUp);
    Vector3 entityFront = entityUp ^ entityRight;
    Matrix34 mat( entityFront, entityUp, m_pos + m_vel * _predictionTime );
    Vector3 flagPos = m_flagMarker->GetWorldMatrix(mat).pos;

    int texId = -1;
    if      ( m_orders == OrderNone )                   texId = g_app->m_resource->GetTexture( "icons/banner_none.bmp" );
    else if ( m_orders == OrderGoto )                   texId = g_app->m_resource->GetTexture( "icons/banner_goto.bmp" );
    else if ( m_orders == OrderFollow && !m_absorb )    texId = g_app->m_resource->GetTexture( "icons/banner_follow.bmp" );
    else if ( m_orders == OrderFollow && m_absorb )     texId = g_app->m_resource->GetTexture( "icons/banner_absorb.bmp" );

    m_flag.SetTexture( texId );
    m_flag.SetPosition( flagPos );
    m_flag.SetOrientation( front, up );
    m_flag.SetSize( size );
    m_flag.Render();
}
bool Officer::RenderPixelEffect( float _predictionTime )
{
    if( !m_enabled || m_dead ) return false;

    //
    // Calculate where we are

    Vector3 predictedPos = m_pos + m_vel * _predictionTime;
    if( m_onGround && m_inWater==-1 )
    {
        predictedPos.y = g_app->m_location->m_landscape.m_heightMap->GetValue( predictedPos.x, predictedPos.z );
    }
    Vector3 entityUp = g_upVector;
    Vector3 entityRight(m_front ^ entityUp);
    Vector3 entityFront = entityUp ^ entityRight;

    Matrix34 mat( entityFront, entityUp, predictedPos );

    //
    // If we are damaged, flicked in and out based on our health

    if( m_renderDamaged )
    {
        float timeIndex = g_gameTime + m_id.GetUniqueId() * 10;
        float thefrand = frand();
        if      ( thefrand > 0.7f ) mat.f *= ( 1.0f - sinf(timeIndex) * 0.5f );
        else if ( thefrand > 0.4f ) mat.u *= ( 1.0f - sinf(timeIndex) * 0.2f );
        else                        mat.r *= ( 1.0f - sinf(timeIndex) * 0.5f );
        glEnable( GL_BLEND );
        glBlendFunc( GL_ONE, GL_ONE );
    }


    //
    // Render our shape

    g_app->m_renderer->SetObjectLighting();
    glDisable       (GL_TEXTURE_2D);
    glShadeModel    (GL_SMOOTH);

    m_shape->Render( _predictionTime, mat );

    glShadeModel    (GL_FLAT);
    glEnable        (GL_TEXTURE_2D);
    glBlendFunc     ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    g_app->m_renderer->UnsetObjectLighting();


    g_app->m_renderer->MarkUsedCells(m_shape, mat);

    return true;
}
예제 #3
0
void CPlayerStateGround::OnPrePhysicsUpdate( CPlayer& player, const SActorFrameMovementParams &movement, float frameTime, const bool isHeavyWeapon, const bool isPlayer )
{
	const Matrix34A baseMtx = Matrix34A(player.GetBaseQuat());
	Matrix34A baseMtxZ(baseMtx * Matrix33::CreateScale(Vec3Constants<float>::fVec3_OneZ));
	baseMtxZ.SetTranslation(Vec3Constants<float>::fVec3_Zero);

	const CAutoAimManager& autoAimManager = g_pGame->GetAutoAimManager();
	const EntityId closeCombatTargetId = autoAimManager.GetCloseCombatSnapTarget();
	const IActor* pCloseCombatTarget = isPlayer && closeCombatTargetId && player.IsClient() ? g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(closeCombatTargetId) : NULL;

	if (pCloseCombatTarget)
	{
		ProcessAlignToTarget(autoAimManager, player, pCloseCombatTarget);
	}
	else
	{
		// This is to restore inertia if the ProcessAlignToTarget set it previously.
		if( m_inertiaIsZero )
		{
			CPlayerStateUtil::RestorePlayerPhysics( player );

			m_inertiaIsZero = false;
		}

		//process movement
		const bool isRemote = isPlayer && !player.IsClient();

		Vec3 move(ZERO);
		CPlayerStateUtil::CalculateGroundOrJumpMovement( player, movement, isHeavyWeapon, move );
		player.GetMoveRequest().type = eCMT_Normal;






		//apply movement
		Vec3 desiredVel(ZERO);
		Vec3 entityPos = player.GetEntity()->GetWorldPos();
		Vec3 entityRight(player.GetBaseQuat().GetColumn0());

		hwvec3 xmDesiredVel = HWV3Zero();

		hwmtx33 xmBaseMtxZ;
		HWMtx33LoadAligned(xmBaseMtxZ, baseMtxZ);
		hwmtx33 xmBaseMtxZOpt = HWMtx33GetOptimized(xmBaseMtxZ);

		hwvec3 xmMove					= HWVLoadVecUnaligned(&move);	
		simdf fGroundNormalZ;

#ifdef STATE_DEBUG
		bool debugJumping = (g_pGameCVars->pl_debug_jumping != 0);
#endif

		const SPlayerStats& stats = *player.GetActorStats();

		{
			xmDesiredVel = xmMove;

			Vec3 groundNormal = player.GetActorPhysics().groundNormal;

			if(!gEnv->bMultiplayer)
			{
				if (player.IsAIControlled())
					fGroundNormalZ = SIMDFLoadFloat(square(groundNormal.z));
				else
					fGroundNormalZ = SIMDFLoadFloat(groundNormal.z);
			}
			else
			{
				//If the hill steepness is greater than our minimum threshold
				if(groundNormal.z > 1.f - cosf(g_pGameCVars->pl_movement.mp_slope_speed_multiplier_minHill))
				{
					//Check if we are trying to move up or downhill
					groundNormal.z = 0.f;
					groundNormal.Normalize();

					Vec3 moveDir = move;
					moveDir.z = 0.f;
					moveDir.Normalize();

					float normalDotMove = groundNormal.Dot(moveDir);
					//Apply speed multiplier based on moving up/down hill and hill steepness
					float multiplier = normalDotMove < 0.f ? g_pGameCVars->pl_movement.mp_slope_speed_multiplier_uphill : g_pGameCVars->pl_movement.mp_slope_speed_multiplier_downhill;
					fGroundNormalZ = SIMDFLoadFloat(1.f - (1.f - player.GetActorPhysics().groundNormal.z) * multiplier);
				}
				else
				{
					fGroundNormalZ = SIMDFLoadFloat(1.0f);
				}
			}

			const float depthHi = g_pGameCVars->cl_shallowWaterDepthHi;
			const float depthLo = g_pGameCVars->cl_shallowWaterDepthLo;
			const float relativeBottomDepth = player.m_playerStateSwim_WaterTestProxy.GetRelativeBottomDepth();

			if( relativeBottomDepth > depthLo )
			{ // Shallow water speed slowdown
				float shallowWaterMultiplier = 1.0f;

				shallowWaterMultiplier = isPlayer
					? g_pGameCVars->cl_shallowWaterSpeedMulPlayer
					: g_pGameCVars->cl_shallowWaterSpeedMulAI;

				shallowWaterMultiplier = max(shallowWaterMultiplier, 0.1f);
				assert(shallowWaterMultiplier <= 1.0f);


				float shallowWaterDepthSpan = (depthHi - depthLo);
				shallowWaterDepthSpan = max(0.1f, shallowWaterDepthSpan);

				float slowdownFraction = (relativeBottomDepth - depthLo) / shallowWaterDepthSpan;
				slowdownFraction = clamp_tpl(slowdownFraction, 0.0f, 1.0f);
				shallowWaterMultiplier = LERP(1.0f, shallowWaterMultiplier, slowdownFraction);

				//avoid branch if m_stats.relativeBottomDepth <= 0.0f;
				shallowWaterMultiplier = (float)__fsel(-relativeBottomDepth, 1.0f, shallowWaterMultiplier);

				simdf vfShallowWaterMultiplier = SIMDFLoadFloat(shallowWaterMultiplier);

				xmDesiredVel = HWVMultiplySIMDF(xmDesiredVel, vfShallowWaterMultiplier);
			}
		}





		// Slow down on sloped terrain, simply proportional to the slope. 
		xmDesiredVel = HWVMultiplySIMDF(xmDesiredVel, fGroundNormalZ);

		//be sure desired velocity is flat to the ground
		hwvec3 vDesiredVelVert = HWMtx33RotateVecOpt(xmBaseMtxZOpt, xmDesiredVel);

		xmDesiredVel = HWVSub(xmDesiredVel, vDesiredVelVert);

		HWVSaveVecUnaligned(&desiredVel, xmDesiredVel);

		if (isPlayer)
		{
			Vec3 modifiedSlopeNormal = player.GetActorPhysics().groundNormal;
			float h = Vec2(modifiedSlopeNormal.x, modifiedSlopeNormal.y).GetLength(); // TODO: OPT: sqrt(x*x+y*y)
			float v = modifiedSlopeNormal.z;
			float slopeAngleCur = RAD2DEG(atan2_tpl(h, v));

			const float divisorH = (float)__fsel(-h, 1.0f, h);
			const float divisorV = (float)__fsel(-v, 1.0f, v);

			const float invV = __fres(divisorV);
			const float invH = __fres(divisorH);

			const float slopeAngleHor = 10.0f;
			const float slopeAngleVer = 50.0f;
			float slopeAngleFraction = clamp_tpl((slopeAngleCur - slopeAngleHor) * __fres(slopeAngleVer - slopeAngleHor), 0.0f, 1.0f);

			slopeAngleFraction = slopeAngleFraction * slopeAngleFraction * slopeAngleFraction;

			float slopeAngleMod = LERP(0.0f, 90.0f, slopeAngleFraction);

			float s, c;

			sincos_tpl(DEG2RAD(slopeAngleMod), &s, &c);

			const float hMultiplier = (float)__fsel(-h, 1.0f, s * invH);
			const float vMultiplier = (float)__fsel(-v, 1.0f, c * invV);

			modifiedSlopeNormal.x *= hMultiplier;
			modifiedSlopeNormal.y *= hMultiplier;
			modifiedSlopeNormal.z *= vMultiplier;

			//Normalize the slope normal if possible
			const float fSlopeNormalLength = modifiedSlopeNormal.len();
			const float fSlopeNormalLengthSafe = (float)__fsel(fSlopeNormalLength - 0.000001f, fSlopeNormalLength, 1.0f);
			modifiedSlopeNormal = modifiedSlopeNormal * __fres(fSlopeNormalLengthSafe);

			float alignment = min(modifiedSlopeNormal * desiredVel, 0.0f);

			// Also affect air control (but not as much), to prevent jumping up against steep slopes.

			alignment *= (float)__fsel(-fabsf(stats.onGround), LERP(0.7f, 1.0f, 1.0f - clamp_tpl(modifiedSlopeNormal.z * 100.0f, 0.0f, 1.0f)), 1.0f);

			modifiedSlopeNormal.z = modifiedSlopeNormal.z;

			desiredVel -= modifiedSlopeNormal * alignment;


#ifdef STATE_DEBUG
			if (debugJumping)
			{
				player.DebugGraph_AddValue("GroundSlope", slopeAngleCur);
				player.DebugGraph_AddValue("GroundSlopeMod", slopeAngleMod);
			}
#endif
		}





		Vec3 newVelocity = desiredVel;

		const float fNewSpeed = newVelocity.len();

		const float fVelocityMultiplier = (float)__fsel(fNewSpeed - 22.0f, __fres(fNewSpeed+FLT_EPSILON) * 22.0f, 1.0f);

		// TODO: Maybe we should tell physics about this new velocity ? Or maybe SPlayerStats::velocity ? (stephenn).
		player.GetMoveRequest().velocity = newVelocity * (stats.flashBangStunMult * fVelocityMultiplier);

#ifdef STATE_DEBUG
		if(g_pGameCVars->pl_debug_movement > 0)
		{
			const char* filter = g_pGameCVars->pl_debug_filter->GetString();
			const char* name = player.GetEntity()->GetName();
			if ((strcmp(filter, "0") == 0) || (strcmp(filter, name) == 0))
			{
				float white[] = {1.0f,1.0f,1.0f,1.0f};
				gEnv->pRenderer->Draw2dLabel(20, 450, 2.0f, white, false, "Speed: %.3f m/s", player.GetMoveRequest().velocity.len());

				if(g_pGameCVars->pl_debug_movement > 1)
				{
					gEnv->pRenderer->Draw2dLabel(35, 470, 1.8f, white, false, "Stance Speed: %.3f m/s - (%sSprinting)", player.GetStanceMaxSpeed(player.GetStance()), player.IsSprinting() ? "" : "Not ");
				}
			}
		}
#endif


























	}

	if( isPlayer )
	{
		CheckForVaultTrigger(player, frameTime);
	}
}