void CTriggerCamera::Move( void )
{
	// Not moving on a path, return
	if (!m_pGoalEnt) return;

	// Subtract movement from the previous frame
	pev->frags -= pev->speed * gpGlobals->frametime;

	// Have we moved enough to reach the target?
	if ( pev->frags <= 0 )
	{
		// Fire the passtarget if there is one
		if ( m_pGoalEnt->pev->message )
		{
			UTIL_FireTargets( m_pGoalEnt->pev->message, this, this, USE_TOGGLE, 0 );
			if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_FIREONCE ) )
				m_pGoalEnt->pev->message = 0;
		}

		if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_TELEPORT ) )
		{
			m_pGoalEnt = m_pGoalEnt->GetNext();
			if ( m_pGoalEnt ) UTIL_AssignOrigin( this, m_pGoalEnt->pev->origin ); 
		}
		if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_WAITFORTRIG ) )
		{
			//strange feature...
		}
		
		// Time to go to the next target
		m_pGoalEnt = m_pGoalEnt->GetNext();

		// Set up next corner
		if ( !m_pGoalEnt ) UTIL_SetVelocity( this, g_vecZero );
		else
		{
			pev->message = m_pGoalEnt->pev->targetname; //save last corner
			pev->armorvalue = m_pGoalEnt->pev->speed;

			Vector delta = m_pGoalEnt->pev->origin - pev->origin;
			pev->frags = delta.Length();
			pev->movedir = delta.Normalize();
			m_flDelay = gpGlobals->time + m_pGoalEnt->GetDelay();
		}
	}

	if ( m_flDelay > gpGlobals->time )
		pev->speed = UTIL_Approach( 0, pev->speed, 500 * gpGlobals->frametime );
	else pev->speed = UTIL_Approach( pev->armorvalue, pev->speed, 500 * gpGlobals->frametime );
	
	if( !pTarget ) UTIL_WatchTarget( this, m_pGoalEnt ); // watch for track

	float fraction = 2 * gpGlobals->frametime;
	UTIL_SetVelocity( this, ((pev->movedir * pev->speed) * fraction) + (pev->velocity * ( 1 - fraction )));
}
Beispiel #2
0
void CWateryDeathLeech::LeechThink( void )
{
	if ( IsMarkedForDeletion() )
		 return;

	StudioFrameAdvance();
	SetNextThink( gpGlobals->curtime + 0.1 );

	if ( m_iFadeState != 0 )
	{
		float dt = gpGlobals->frametime;
		if ( dt > 0.1f )
		{
			dt = 0.1f;
		}
		m_nRenderMode = kRenderTransTexture;
		int speed = max(1,256*dt); // fade out over 1 second

		if ( m_iFadeState == -1 )
			 SetRenderColorA( UTIL_Approach( 0, m_clrRender->a, speed ) );
		else
			 SetRenderColorA( UTIL_Approach( 255, m_clrRender->a, speed ) );

		if ( m_clrRender->a == 0 )
		{
			UTIL_Remove(this);
		}
		else if ( m_clrRender->a == 255 )
		{
			m_iFadeState = 0;
		}
		else
		{
			SetNextThink( gpGlobals->curtime );
		}
	}


	if ( GetOwnerEntity() )
	{
		if ( GetOwnerEntity()->GetWaterLevel() < 3 )
		{
			AddEffects( EF_NODRAW );
		}
		else
		{
			RemoveEffects( EF_NODRAW );
		}

		SetAbsOrigin( GetOwnerEntity()->GetAbsOrigin() + GetOwnerEntity()->GetViewOffset() );
	}
}
Beispiel #3
0
void CNPC_HL1Barney::SUB_LVFadeOut( void  )
{
	if( VPhysicsGetObject() )
	{
		if( VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD || GetEFlags() & EFL_IS_BEING_LIFTED_BY_BARNACLE )
		{
			// Try again in a few seconds.
			SetNextThink( gpGlobals->curtime + 5 );
			SetRenderColorA( 255 );
			return;
		}
	}

	float dt = gpGlobals->frametime;
	if ( dt > 0.1f )
	{
		dt = 0.1f;
	}
	m_nRenderMode = kRenderTransTexture;
	int speed = max(3,256*dt); // fade out over 3 seconds
	SetRenderColorA( UTIL_Approach( 0, m_clrRender->a, speed ) );
	NetworkStateChanged();

	if ( m_clrRender->a == 0 )
	{
		UTIL_Remove(this);
	}
	else
	{
		SetNextThink( gpGlobals->curtime );
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponGaussGun::ItemPostFrame()
{
	//Get the view kick
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	if ( !pPlayer )
		return;

	if ( pPlayer->m_afButtonReleased & IN_ATTACK2 )
	{
		if ( m_bCharging )
			ChargedFire();
	}

#ifndef CLIENT_DLL
	m_flCoilVelocity	= UTIL_Approach( m_flCoilMaxVelocity, m_flCoilVelocity, 10.0f );
	m_flCoilAngle		= UTIL_AngleMod( m_flCoilAngle + ( m_flCoilVelocity * gpGlobals->frametime ) );

	static float fanAngle = 0.0f;

	fanAngle = UTIL_AngleMod( fanAngle + 2 );

	//Update spinning bits
	SetBoneController( 0, fanAngle );
	SetBoneController( 1, m_flCoilAngle );
#endif
	
	BaseClass::ItemPostFrame();
}
Beispiel #5
0
void CGargantua::EyeUpdate( void )
{
	if ( m_pEyeGlow )
	{
		m_pEyeGlow->pev->renderamt = UTIL_Approach( m_eyeBrightness, m_pEyeGlow->pev->renderamt, 26 );
		if ( m_pEyeGlow->pev->renderamt == 0 )
			m_pEyeGlow->pev->effects |= EF_NODRAW;
		else
			m_pEyeGlow->pev->effects &= ~EF_NODRAW;
		UTIL_SetOrigin( m_pEyeGlow, GetAbsOrigin() );
	}
}
Beispiel #6
0
void CGargantua::EyeUpdate( void )
{
	if ( m_pEyeGlow )
	{
		m_pEyeGlow->SetRenderAmount( UTIL_Approach( m_eyeBrightness, m_pEyeGlow->GetRenderAmount(), 26 ) );
		if ( m_pEyeGlow->GetRenderAmount() == 0 )
			m_pEyeGlow->GetEffects() |= EF_NODRAW;
		else
			m_pEyeGlow->GetEffects().ClearFlags( EF_NODRAW );
		m_pEyeGlow->SetAbsOrigin( GetAbsOrigin() );
	}
}
void CPropVehicleManhack::UpdateHead( void )
{
	float yaw = GetPoseParameter( "head_yaw" );
	float pitch = GetPoseParameter( "head_pitch" );

	// If we should be watching our enemy, turn our head
	CNPC_Manhack *pManhack=GetManhack();
	
	if (pManhack != NULL) 
	{
		Vector vehicleEyeOrigin;
		QAngle vehicleEyeAngles;
		GetAttachment( "vehicle_driver_eyes", vehicleEyeOrigin, vehicleEyeAngles );

		// FIXME: cache this
		Vector vBodyDir;
		AngleVectors( vehicleEyeAngles, &vBodyDir );

		Vector	manhackDir = pManhack->GetAbsOrigin() - vehicleEyeOrigin;
		VectorNormalize( manhackDir );
		
		float angle = UTIL_VecToYaw( vBodyDir );
		float angleDiff = UTIL_VecToYaw( manhackDir );
		angleDiff = UTIL_AngleDiff( angleDiff, angle + yaw );

		SetPoseParameter( "head_yaw", UTIL_Approach( yaw + angleDiff, yaw, 1 ) );

		angle = UTIL_VecToPitch( vBodyDir );
		angleDiff = UTIL_VecToPitch( manhackDir );
		angleDiff = UTIL_AngleDiff( angleDiff, angle + pitch );

		SetPoseParameter( "head_pitch", UTIL_Approach( pitch + angleDiff, pitch, 1 ) );
	}
	else
	{
		// Otherwise turn the head back to its normal position
		SetPoseParameter( "head_yaw",	UTIL_Approach( 0, yaw, 10 ) );
		SetPoseParameter( "head_pitch", UTIL_Approach( 0, pitch, 10 ) );
	}
}
void CFlyingMonster::MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval )
{
	if ( pev->movetype == MOVETYPE_FLY )
	{
		if ( gpGlobals->time - m_stopTime > 1.0 )
		{
			if ( m_IdealActivity != m_movementActivity )
			{
				m_IdealActivity = m_movementActivity;
				m_flGroundSpeed = m_flightSpeed = 200;
			}
		}
		Vector vecMove = pev->origin + (( vecDir + (m_vecTravel * m_momentum) ).Normalize() * (m_flGroundSpeed * flInterval));

		if ( m_IdealActivity != m_movementActivity )
		{
			m_flightSpeed = UTIL_Approach( 100, m_flightSpeed, 75 * gpGlobals->frametime );
			if ( m_flightSpeed < 100 )
				m_stopTime = gpGlobals->time;
		}
		else
			m_flightSpeed = UTIL_Approach( 20, m_flightSpeed, 300 * gpGlobals->frametime );
		
		if ( CheckLocalMove ( pev->origin, vecMove, pTargetEnt, NULL ) )
		{
			m_vecTravel = (vecMove - pev->origin);
			m_vecTravel = m_vecTravel.Normalize();
			UTIL_MoveToOrigin(ENT(pev), vecMove, (m_flGroundSpeed * flInterval), MOVE_STRAFE);
		}
		else
		{
			m_IdealActivity = GetStoppedActivity();
			m_stopTime = gpGlobals->time;
			m_vecTravel = g_vecZero;
		}
	}
	else
		CBaseMonster::MoveExecute( pTargetEnt, vecDir, flInterval );
}
void CPhysMotor::Think( void )
{
	// angular acceleration is always positive - it should be treated as a magnitude - the controller 
	// will apply it in the proper direction
	Assert(m_angularAcceleration>=0);

	m_motor.m_speed = UTIL_Approach( m_targetSpeed, m_motor.m_speed, m_angularAcceleration*(gpGlobals->curtime-m_lastTime) );
	m_lastTime = gpGlobals->curtime;
	if ( m_motor.m_speed != m_targetSpeed )
	{
		SetNextThink( gpGlobals->curtime );
	}
}
void CNPC_Gargantua::EyeUpdate( void )
{
	if ( m_pEyeGlow )
	{
		m_pEyeGlow->SetBrightness( UTIL_Approach( m_eyeBrightness, m_pEyeGlow->GetBrightness(), 26 ), 0.5f );
		if ( m_pEyeGlow->GetBrightness() == 0 )
		{
			m_pEyeGlow->AddEffects( EF_NODRAW );
		}
		else
		{
			m_pEyeGlow->RemoveEffects( EF_NODRAW );
		}
	}
}
void CNPC_Gargantua::EyeUpdate( void )
{
	if ( m_pEyeGlow )
	{
		m_pEyeGlow->SetBrightness( UTIL_Approach( m_eyeBrightness, m_pEyeGlow->GetBrightness(), 26 ), 0.5f );
		if ( m_pEyeGlow->GetBrightness() == 0 )
		{
			m_pEyeGlow->m_fEffects |= EF_NODRAW;
		}
		else
		{
			m_pEyeGlow->m_fEffects &= ~EF_NODRAW;
		}
	}
}
Beispiel #12
0
float CIchthyosaur :: ChangePitch( int speed )
{
	if ( pev->movetype == MOVETYPE_FLY )
	{
		float diff = FlPitchDiff();
		float target = 0;
		if ( m_IdealActivity != GetStoppedActivity() )
		{
			if (diff < -20)
				target = 45;
			else if (diff > 20)
				target = -45;
		}
		pev->angles.x = UTIL_Approach(target, pev->angles.x, 220.0 * 0.1 );
	}
	return 0;
}
float CFlyingMonster :: ChangeYaw( int speed )
{
	if ( pev->movetype == MOVETYPE_FLY )
	{
		float diff = FlYawDiff();
		float target = 0;

		if ( m_IdealActivity != GetStoppedActivity() )
		{
			if ( diff < -20 )
				target = 90;
			else if ( diff > 20 )
				target = -90;
		}
		pev->angles.z = UTIL_Approach( target, pev->angles.z, 220.0 * gpGlobals->frametime );
	}
	return CBaseMonster::ChangeYaw( speed );
}
Beispiel #14
0
float CIchthyosaur::ChangeYaw( int speed )
{
	if ( pev->movetype == MOVETYPE_FLY )
	{
		float diff = FlYawDiff();
		float target = 0;

		if ( m_IdealActivity != GetStoppedActivity() )
		{
			if ( diff < -20 )
				target = 20;
			else if ( diff > 20 )
				target = -20;
		}
		pev->angles.z = UTIL_Approach( target, pev->angles.z, 220.0 * 0.1 );
	}
	return CFlyingMonster::ChangeYaw( speed );
}
Beispiel #15
0
//-----------------------------------------------------------------------------
// Purpose: Aim Gun at a target
//-----------------------------------------------------------------------------
void CASW_PropJeep::AimGunAt( Vector *endPos, float flInterval )
{
	Vector	aimPos = *endPos;

	// See if the gun should be allowed to aim
	if ( IsOverturned() || m_bEngineLocked || m_bHasGun == false )
	{
		SetPoseParameter( JEEP_GUN_YAW, 0 );
		SetPoseParameter( JEEP_GUN_PITCH, 0 );
		SetPoseParameter( JEEP_GUN_SPIN, 0 );
		return;

		// Make the gun go limp and look "down"
		Vector	v_forward, v_up;
		AngleVectors( GetLocalAngles(), NULL, &v_forward, &v_up );
		aimPos = WorldSpaceCenter() + ( v_forward * -32.0f ) - Vector( 0, 0, 128.0f );
	}

	matrix3x4_t gunMatrix;
	GetAttachment( LookupAttachment("gun_ref"), gunMatrix );

	// transform the enemy into gun space
	Vector localEnemyPosition;
	VectorITransform( aimPos, gunMatrix, localEnemyPosition );

	// do a look at in gun space (essentially a delta-lookat)
	QAngle localEnemyAngles;
	VectorAngles( localEnemyPosition, localEnemyAngles );
	
	// convert to +/- 180 degrees
	localEnemyAngles.x = UTIL_AngleDiff( localEnemyAngles.x, 0 );	
	localEnemyAngles.y = UTIL_AngleDiff( localEnemyAngles.y, 0 );

	float targetYaw = m_aimYaw + localEnemyAngles.y;
	float targetPitch = m_aimPitch + localEnemyAngles.x;
	
	// Constrain our angles
	float newTargetYaw	= clamp( targetYaw, -CANNON_MAX_LEFT_YAW, CANNON_MAX_RIGHT_YAW );
	float newTargetPitch = clamp( targetPitch, -CANNON_MAX_DOWN_PITCH, CANNON_MAX_UP_PITCH );

	// If the angles have been clamped, we're looking outside of our valid range
	if ( fabs(newTargetYaw-targetYaw) > 1e-4 || fabs(newTargetPitch-targetPitch) > 1e-4 )
	{
		m_bUnableToFire = true;
	}

	targetYaw = newTargetYaw;
	targetPitch = newTargetPitch;

	// Exponentially approach the target
	float yawSpeed = 8;
	float pitchSpeed = 8;

	m_aimYaw = UTIL_Approach( targetYaw, m_aimYaw, yawSpeed );
	m_aimPitch = UTIL_Approach( targetPitch, m_aimPitch, pitchSpeed );

	SetPoseParameter( JEEP_GUN_YAW, -m_aimYaw);
	SetPoseParameter( JEEP_GUN_PITCH, -m_aimPitch );

	InvalidateBoneCache();

	// read back to avoid drift when hitting limits
	// as long as the velocity is less than the delta between the limit and 180, this is fine.
	m_aimPitch = -GetPoseParameter( JEEP_GUN_PITCH );
	m_aimYaw = -GetPoseParameter( JEEP_GUN_YAW );

	// Now draw crosshair for actual aiming point
	Vector	vecMuzzle, vecMuzzleDir;
	QAngle	vecMuzzleAng;

	GetAttachment( "Muzzle", vecMuzzle, vecMuzzleAng );
	AngleVectors( vecMuzzleAng, &vecMuzzleDir );

	trace_t	tr;
	UTIL_TraceLine( vecMuzzle, vecMuzzle + (vecMuzzleDir * MAX_TRACE_LENGTH), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );

		// see if we hit something, if so, adjust endPos to hit location
	if ( tr.fraction < 1.0 )
	{
		m_vecGunCrosshair = vecMuzzle + ( vecMuzzleDir * MAX_TRACE_LENGTH * tr.fraction );
	}
}
//------------------------------------------------------------------------------
// Purpose : 
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CNPC_CombineDropship::Flight( void )
{
	// Only run pose params in some flight states
	bool bRunPoseParams = ( m_iLandState == LANDING_NO || 
							m_iLandState == LANDING_LEVEL_OUT || 
							m_iLandState == LANDING_LIFTOFF ||
							m_iLandState == LANDING_SWOOPING );

	if ( bRunPoseParams )
	{
		if( GetFlags() & FL_ONGROUND )
		{
			//This would be really bad.
			RemoveFlag( FL_ONGROUND );
		}

		// NDebugOverlay::Line(GetLocalOrigin(), GetDesiredPosition(), 0,0,255, true, 0.1);

		Vector deltaPos = GetDesiredPosition() - GetLocalOrigin();

		// calc desired acceleration
		float dt = 1.0f;

		Vector	accel;
		float	accelRate = DROPSHIP_ACCEL_RATE;
		float	maxSpeed = m_flMaxSpeed;

		if ( m_lifeState == LIFE_DYING )
		{
			accelRate *= 5.0;
			maxSpeed *= 5.0;
		}

		float flDist = min( GetAbsVelocity().Length() + accelRate, maxSpeed );

		// Only decelerate to our goal if we're going to hit it
		if ( deltaPos.Length() > flDist * dt )
		{
			float scale = flDist * dt / deltaPos.Length();
			deltaPos = deltaPos * scale;
		}
		
		// If we're swooping, floor it
		if ( m_iLandState == LANDING_SWOOPING )
		{
			VectorNormalize( deltaPos );
			deltaPos *= maxSpeed;
		}
		
		// calc goal linear accel to hit deltaPos in dt time.
		accel.x = 2.0 * (deltaPos.x - GetAbsVelocity().x * dt) / (dt * dt);
		accel.y = 2.0 * (deltaPos.y - GetAbsVelocity().y * dt) / (dt * dt);
		accel.z = 2.0 * (deltaPos.z - GetAbsVelocity().z * dt + 0.5 * 384 * dt * dt) / (dt * dt);
		
		//NDebugOverlay::Line(GetLocalOrigin(), GetLocalOrigin() + deltaPos, 255,0,0, true, 0.1);
		//NDebugOverlay::Line(GetLocalOrigin(), GetLocalOrigin() + accel, 0,255,0, true, 0.1);

		// don't fall faster than 0.2G or climb faster than 2G
		if ( m_iLandState != LANDING_SWOOPING )
		{
			accel.z = clamp( accel.z, 384 * 0.2, 384 * 2.0 );
		}

		Vector forward, right, up;
		GetVectors( &forward, &right, &up );

		Vector goalUp = accel;
		VectorNormalize( goalUp );

		// calc goal orientation to hit linear accel forces
		float goalPitch = RAD2DEG( asin( DotProduct( forward, goalUp ) ) );
		float goalYaw = UTIL_VecToYaw( m_vecDesiredFaceDir );
		float goalRoll = RAD2DEG( asin( DotProduct( right, goalUp ) ) );

		// clamp goal orientations
		goalPitch = clamp( goalPitch, -45, 60 );
		goalRoll = clamp( goalRoll, -45, 45 );

		// calc angular accel needed to hit goal pitch in dt time.
		dt = 0.6;
		QAngle goalAngAccel;
		goalAngAccel.x = 2.0 * (AngleDiff( goalPitch, AngleNormalize( GetLocalAngles().x ) ) - GetLocalAngularVelocity().x * dt) / (dt * dt);
		goalAngAccel.y = 2.0 * (AngleDiff( goalYaw, AngleNormalize( GetLocalAngles().y ) ) - GetLocalAngularVelocity().y * dt) / (dt * dt);
		goalAngAccel.z = 2.0 * (AngleDiff( goalRoll, AngleNormalize( GetLocalAngles().z ) ) - GetLocalAngularVelocity().z * dt) / (dt * dt);

		goalAngAccel.x = clamp( goalAngAccel.x, -300, 300 );
		//goalAngAccel.y = clamp( goalAngAccel.y, -60, 60 );
		goalAngAccel.y = clamp( goalAngAccel.y, -120, 120 );
		goalAngAccel.z = clamp( goalAngAccel.z, -300, 300 );

		// limit angular accel changes to simulate mechanical response times
		dt = 0.1;
		QAngle angAccelAccel;
		angAccelAccel.x = (goalAngAccel.x - m_vecAngAcceleration.x) / dt;
		angAccelAccel.y = (goalAngAccel.y - m_vecAngAcceleration.y) / dt;
		angAccelAccel.z = (goalAngAccel.z - m_vecAngAcceleration.z) / dt;

		angAccelAccel.x = clamp( angAccelAccel.x, -1000, 1000 );
		angAccelAccel.y = clamp( angAccelAccel.y, -1000, 1000 );
		angAccelAccel.z = clamp( angAccelAccel.z, -1000, 1000 );

		m_vecAngAcceleration += angAccelAccel * 0.1;

		// Msg( "pitch %6.1f (%6.1f:%6.1f)  ", goalPitch, GetLocalAngles().x, m_vecAngVelocity.x );
		// Msg( "roll %6.1f (%6.1f:%6.1f) : ", goalRoll, GetLocalAngles().z, m_vecAngVelocity.z );
		// Msg( "%6.1f %6.1f %6.1f  :  ", goalAngAccel.x, goalAngAccel.y, goalAngAccel.z );
		// Msg( "%6.0f %6.0f %6.0f\n", angAccelAccel.x, angAccelAccel.y, angAccelAccel.z );

		ApplySidewaysDrag( right );
		ApplyGeneralDrag();
		
		QAngle angVel = GetLocalAngularVelocity();
		angVel += m_vecAngAcceleration * 0.1;

		//angVel.y = clamp( angVel.y, -60, 60 );
		//angVel.y = clamp( angVel.y, -120, 120 );
		angVel.y = clamp( angVel.y, -120, 120 );

		SetLocalAngularVelocity( angVel );

		m_flForce = m_flForce * 0.8 + (accel.z + fabs( accel.x ) * 0.1 + fabs( accel.y ) * 0.1) * 0.1 * 0.2;

		Vector vecImpulse = m_flForce * up;
		
		if ( m_lifeState == LIFE_DYING )
		{
			vecImpulse.z = -38.4;  // 64ft/sec
		}
		else
		{
			vecImpulse.z -= 38.4;  // 32ft/sec
		}
		
		// Find our acceleration direction
		Vector	vecAccelDir = vecImpulse;
		VectorNormalize( vecAccelDir );

		// Find our current velocity
		Vector	vecVelDir = GetAbsVelocity();
		VectorNormalize( vecVelDir );

		// Level out our plane of movement
		vecAccelDir.z	= 0.0f;
		vecVelDir.z		= 0.0f;
		forward.z		= 0.0f;
		right.z			= 0.0f;

		// Find out how "fast" we're moving in relation to facing and acceleration
		float speed = m_flForce * DotProduct( vecVelDir, vecAccelDir );// * DotProduct( forward, vecVelDir );

		// Use the correct pose params
		char *sBodyAccel;
		char *sBodySway;
		if ( m_hContainer || m_iLandState == LANDING_SWOOPING )
		{
			sBodyAccel = "cargo_body_accel";
			sBodySway = "cargo_body_sway";
			SetPoseParameter( "body_accel", 0 );
			SetPoseParameter( "body_sway", 0 );
		}
		else
		{
			sBodyAccel = "body_accel";
			sBodySway = "body_sway";
			SetPoseParameter( "cargo_body_accel", 0 );
			SetPoseParameter( "cargo_body_sway", 0 );
		}

		// Apply the acceleration blend to the fins
		float finAccelBlend = SimpleSplineRemapVal( speed, -60, 60, -1, 1 );
		float curFinAccel = GetPoseParameter( sBodyAccel );
		
		curFinAccel = UTIL_Approach( finAccelBlend, curFinAccel, 0.5f );

		SetPoseParameter( sBodyAccel, curFinAccel );

		speed = m_flForce * DotProduct( vecVelDir, right );

		// Apply the spin sway to the fins
		float finSwayBlend = SimpleSplineRemapVal( speed, -60, 60, -1, 1 );
		float curFinSway = GetPoseParameter( sBodySway );

		curFinSway = UTIL_Approach( finSwayBlend, curFinSway, 0.5f );
		SetPoseParameter( sBodySway, curFinSway );

		// Add in our velocity pulse for this frame
		ApplyAbsVelocityImpulse( vecImpulse );

		//Msg("FinAccel: %f, Finsway: %f\n", curFinAccel, curFinSway );
	}
	else
	{
		SetPoseParameter( "body_accel", 0 );
		SetPoseParameter( "body_sway", 0 );
		SetPoseParameter( "cargo_body_accel", 0 );
		SetPoseParameter( "cargo_body_sway", 0 );
	}
}
//------------------------------------------------------------------------------
// Purpose : 
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CNPC_CombineDropship::PrescheduleThink( void )
{
	BaseClass::PrescheduleThink();
	
	// keep track of think time deltas for burn calc below
	float dt = gpGlobals->curtime - m_flLastTime;
	m_flLastTime = gpGlobals->curtime;

	switch( m_iLandState )
	{
	case LANDING_NO:
		{
			if ( IsActivityFinished() && (GetActivity() != ACT_DROPSHIP_FLY_IDLE_EXAGG && GetActivity() != ACT_DROPSHIP_FLY_IDLE_CARGO) )
			{
				if ( m_hContainer )
				{
					SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_CARGO );
				}
				else
				{
					SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_EXAGG );
				}
			}

			DoRotorWash();
		}
		break;

	case LANDING_LEVEL_OUT:
		{
			// Approach the drop point
			Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin());
			float flDistance = vecToTarget.Length();

			// If we're slowing, make it look like we're slowing
			/*
			if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE )
			{
				SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE );
			}
			*/

			// Are we there yet?
			float flSpeed = GetAbsVelocity().Length();
			if ( flDistance < 70 && flSpeed < 100 )
			{
				m_flLandingSpeed = flSpeed;
				m_iLandState = LANDING_DESCEND;
				// save off current angles so we can work them out over time
				QAngle angles = GetLocalAngles();
				m_existPitch = angles.x;
				m_existRoll = angles.z;

			}

			DoRotorWash();
		}
		break;

	case LANDING_DESCEND:
		{
			float	flAltitude;

			SetLocalAngularVelocity( vec3_angle );

			// Ensure we land on the drop point
			Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin());
			float flDistance = vecToTarget.Length();
			float flRampedSpeed = m_flLandingSpeed * (flDistance / 70);
			Vector vecVelocity = (flRampedSpeed / flDistance) * vecToTarget;
			vecVelocity.z = -75;
			SetAbsVelocity( vecVelocity );

			flAltitude = GetAltitude();			

			if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE )
			{
				SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE );
			}

			if ( flAltitude < 72 )
			{
				QAngle angles = GetLocalAngles();

				// Level out quickly.
				angles.x = UTIL_Approach( 0.0, angles.x, 0.2 );
				angles.z = UTIL_Approach( 0.0, angles.z, 0.2 );

				SetLocalAngles( angles );
			}
			else
			{
				// randomly move as if buffeted by ground effects
				// gently flatten ship from starting pitch/yaw
				m_existPitch = UTIL_Approach( 0.0, m_existPitch, 1 );
				m_existRoll = UTIL_Approach( 0.0, m_existRoll, 1 );

				QAngle angles = GetLocalAngles();
				angles.x = m_existPitch + ( sin( gpGlobals->curtime * 3.5f ) * DROPSHIP_MAX_LAND_TILT );
				angles.z = m_existRoll + ( sin( gpGlobals->curtime * 3.75f ) * DROPSHIP_MAX_LAND_TILT );
				SetLocalAngles( angles );

				// figure out where to face (nav point)
				Vector targetDir = GetDesiredPosition() - GetAbsOrigin();
//				NDebugOverlay::Cross3D( m_pGoalEnt->GetAbsOrigin(), -Vector(2,2,2), Vector(2,2,2), 255, 0, 0, false, 20 );

				QAngle targetAngles = GetAbsAngles();
				targetAngles.y += UTIL_AngleDiff(UTIL_VecToYaw( targetDir ), targetAngles.y);
				// orient ship towards path corner on the way down
				angles = GetAbsAngles();
				angles.y = UTIL_Approach(targetAngles.y, angles.y, 2 );
				SetAbsAngles( angles );
			}

			if ( flAltitude <= 0.5f )
			{
				m_iLandState = LANDING_TOUCHDOWN;

				// upon landing, make sure ship is flat
				QAngle angles = GetLocalAngles();
				angles.x = 0;
				angles.z = 0;
				SetLocalAngles( angles );

				// TODO: Release cargo anim
				SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE );
			}

			DoRotorWash();

			// place danger sounds 1 foot above ground to get troops to scatter if they are below dropship
			Vector vecBottom = GetAbsOrigin();
			vecBottom.z += WorldAlignMins().z;
			Vector vecSpot = vecBottom + Vector(0, 0, -1) * (GetAltitude() - 12 );
			CSoundEnt::InsertSound( SOUND_DANGER, vecSpot, 400, 0.2, this, 0 );
			CSoundEnt::InsertSound( SOUND_PHYSICS_DANGER, vecSpot, 400, 0.2, this, 1 );
//			NDebugOverlay::Cross3D( vecSpot, -Vector(4,4,4), Vector(4,4,4), 255, 0, 255, false, 10.0f );

			// now check to see if player is below us, if so, cause heat damage to them (i.e. get them to move)
			trace_t tr;
			Vector vecBBoxMin = CRATE_BBOX_MIN;		// use flat box for check
			vecBBoxMin.z = -5;
			Vector vecBBoxMax = CRATE_BBOX_MAX;
			vecBBoxMax.z = 5;
			Vector pEndPoint = vecBottom + Vector(0, 0, -1) * ( GetAltitude() - 12 );
			AI_TraceHull( vecBottom, pEndPoint, vecBBoxMin, vecBBoxMax, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

			if ( tr.fraction < 1.0f )
			{
				if ( tr.GetEntityIndex() == 1 )			// player???
				{
					CTakeDamageInfo info( this, this, 20 * dt, DMG_BURN );
					CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
					pPlayer->TakeDamage( info );
				}
			}

		}
		break;

	case LANDING_TOUCHDOWN:
		{
			if ( IsActivityFinished() && ( GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) )
			{
				SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE );
			}

			m_iLandState = LANDING_UNLOADING;
			m_flTroopDeployPause = gpGlobals->curtime + DROPSHIP_PAUSE_B4_TROOP_UNLOAD;
			m_flTimeTakeOff = m_flTroopDeployPause + DROPSHIP_DEPLOY_TIME;
		}
		break;

	case LANDING_UNLOADING:
		{
			// pause before dropping troops
			if ( gpGlobals->curtime > m_flTroopDeployPause )
			{
				if ( m_hContainer )	// don't drop troops if we don't have a crate any more
				{
					SpawnTroops();
					m_flTroopDeployPause = m_flTimeTakeOff + 2;	// only drop once
				}
			}
			// manage engine wash and volume
			if ( m_flTimeTakeOff - gpGlobals->curtime < 0.5f )
			{
				m_engineThrust = UTIL_Approach( 1.0f, m_engineThrust, 0.1f );
				DoRotorWash();
			}
			else
			{
				float idleVolume = 0.2f;
				m_engineThrust = UTIL_Approach( idleVolume, m_engineThrust, 0.04f );
				if ( m_engineThrust > idleVolume ) 
				{
					DoRotorWash();				// make sure we're kicking up dust/water as long as engine thrust is up
				}
			}

			if( gpGlobals->curtime > m_flTimeTakeOff )
			{
				m_iLandState = LANDING_LIFTOFF;
				SetActivity( (Activity)ACT_DROPSHIP_LIFTOFF );
				m_engineThrust = 1.0f;			// ensure max volume once we're airborne
				if ( m_bIsFiring )
				{
					StopCannon();				// kill cannon sounds if they are on
				}

				// detach container from ship
				if ( m_hContainer && m_leaveCrate )
				{
					m_hContainer->SetParent(NULL);
					m_hContainer->SetMoveType( (MoveType_t)m_iContainerMoveType );

					// If the container has a physics object, remove it's shadow
					IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject();
					if ( pPhysicsObject )
					{
						pPhysicsObject->RemoveShadowController();
					}

					m_hContainer = NULL;
				}
			}
		}
		break;

	case LANDING_LIFTOFF:
		{
			// give us some clearance before changing back to larger hull -- keeps ship from getting stuck on
			// things like the player, etc since we "pop" the hull...
			if ( GetAltitude() > 120 )		
			{
				m_OnFinishedDropoff.FireOutput( this, this );

				m_iLandState = LANDING_NO;

				// change bounding box back to normal ship hull
				Vector vecBBMin, vecBBMax;
				ExtractBbox( SelectHeaviestSequence( ACT_DROPSHIP_DEPLOY_IDLE ), vecBBMin, vecBBMax ); 
				UTIL_SetSize( this, vecBBMin, vecBBMax );
				Relink();
			}
		}
		break;

	case LANDING_SWOOPING:
		{
			// Did we lose our pickup target?
			if ( !m_hPickupTarget )
			{
				m_iLandState = LANDING_NO;
			}
			else
			{
				// Decrease altitude and speed to hit the target point.
				Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin());
				float flDistance = vecToTarget.Length();

				// Start cheating when we get near it
				if ( flDistance < 50 )
				{
					/*
					if ( flDistance > 10 )
					{
						// Cheat and ensure we touch the target
						float flSpeed = GetAbsVelocity().Length();
						Vector vecVelocity = vecToTarget;
						VectorNormalize( vecVelocity );
						SetAbsVelocity( vecVelocity * min(flSpeed,flDistance) );
					}
					else
					*/
					{
						// Grab the target
						m_hContainer = m_hPickupTarget;
						m_hPickupTarget = NULL;
						m_iContainerMoveType = m_hContainer->GetMoveType();

						// If the container has a physics object, move it to shadow
						IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject();
						if ( pPhysicsObject )
						{
							pPhysicsObject->SetShadow( Vector(1e4,1e4,1e4), AngularImpulse(1e4,1e4,1e4), false, false );
							pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 );
						}

						int iIndex = 0;//LookupAttachment("Cargo");
						/*
						Vector vecOrigin;
						QAngle vecAngles;
						GetAttachment( iIndex, vecOrigin, vecAngles );
						m_hContainer->SetAbsOrigin( vecOrigin );
						m_hContainer->SetAbsAngles( vec3_angle );
						*/
						m_hContainer->SetAbsOrigin( GetAbsOrigin() );
						m_hContainer->SetParent(this, iIndex);
						m_hContainer->SetMoveType( MOVETYPE_PUSH );
						m_hContainer->RemoveFlag( FL_ONGROUND );
						m_hContainer->Relink();
						m_hContainer->SetAbsAngles( vec3_angle );

						m_OnFinishedPickup.FireOutput( this, this );
						m_iLandState = LANDING_NO;
					}
				}
			}

			DoRotorWash();
		}
		break;
	}

	DoCombatStuff();

	if ( GetActivity() != GetIdealActivity() )
	{
		//Msg( "setactivity" );
		SetActivity( GetIdealActivity() );
	}
}
//-----------------------------------------------------------------------------
// Purpose: Crane rotates around with +left and +right, and extends/retracts 
//			the cable with +forward and +back.
//-----------------------------------------------------------------------------
void CPropCrane::DriveCrane( int iDriverButtons, int iButtonsPressed, float flNPCSteering )
{
	bool bWasExtending = m_bExtending;

	// Handle rotation of the crane
	if ( iDriverButtons & IN_MOVELEFT )
	{
		// NPCs may cheat and set the steering
		if ( flNPCSteering )
		{
			m_flTurn = flNPCSteering;
		}
		else
		{
			// Try adding some randomness to make it feel shaky? 
			float flTurnAdd = m_flTurnAccel;
			// If we're turning back on ourselves, use decel speed
			if ( m_flTurn < 0 )
			{
				flTurnAdd = MAX( flTurnAdd, m_flTurnDecel );
			}

			m_flTurn = UTIL_Approach( m_flMaxTurnSpeed, m_flTurn, flTurnAdd * gpGlobals->frametime );
		}
		m_iTurning = TURNING_LEFT;
	}
	else if ( iDriverButtons & IN_MOVERIGHT )
	{
		// NPCs may cheat and set the steering
		if ( flNPCSteering )
		{
			m_flTurn = flNPCSteering;
		}
		else
		{
			// Try adding some randomness to make it feel shaky?
			float flTurnAdd = m_flTurnAccel;
			// If we're turning back on ourselves, increase the rate
			if ( m_flTurn > 0 )
			{
				flTurnAdd = MAX( flTurnAdd, m_flTurnDecel );
			}
			m_flTurn = UTIL_Approach( -m_flMaxTurnSpeed, m_flTurn, flTurnAdd * gpGlobals->frametime );
		}
		m_iTurning = TURNING_RIGHT;
	}
	else
	{
		m_flTurn = UTIL_Approach( 0, m_flTurn, m_flTurnDecel * gpGlobals->frametime );
		m_iTurning = TURNING_NOT;
	}

	if ( m_hPlayer )
	{
		float maxTurn = GetMaxTurnRate();
		static float maxRumble = 0.35f;
		static float minRumble = 0.1f;
		float rumbleRange = maxRumble - minRumble;
		float rumble;

		float factor = fabs(m_flTurn) / maxTurn;
		factor = MIN( factor, 1.0f );
		rumble = minRumble + (rumbleRange * factor);

		m_hPlayer->RumbleEffect( RUMBLE_FLAT_BOTH, (int)(rumble * 100), RUMBLE_FLAG_UPDATE_SCALE );
	}

	SetLocalAngularVelocity( QAngle(0,m_flTurn * 10,0) );

	// Handle extension / retraction of the arm
	if ( iDriverButtons & IN_FORWARD )
	{
		m_flExtensionRate = UTIL_Approach( m_flMaxExtensionSpeed, m_flExtensionRate, m_flExtensionAccel * gpGlobals->frametime );
		m_bExtending = true;
	}
	else if ( iDriverButtons & IN_BACK )
	{
		m_flExtensionRate = UTIL_Approach( -m_flMaxExtensionSpeed, m_flExtensionRate, m_flExtensionAccel * gpGlobals->frametime );
		m_bExtending = true;
	}
	else
	{
		m_flExtensionRate = UTIL_Approach( 0, m_flExtensionRate, m_flExtensionDecel * gpGlobals->frametime );
		m_bExtending = false;
	}

	//Msg("Turn: %f\nExtensionRate: %f\n", m_flTurn, m_flExtensionRate );

	//If we're holding down an attack button, update our state
	if ( iButtonsPressed & (IN_ATTACK | IN_ATTACK2) )
	{
		// If we have something on the magnet, turn the magnet off
		if ( m_hCraneMagnet->GetTotalMassAttachedObjects() )
		{
			TurnMagnetOff();
		}
		else if ( !m_bDropping && m_flNextDropAllowedTime < gpGlobals->curtime )
		{
			TurnMagnetOn();

			// Drop the magnet till it hits something
			m_bDropping = true;
			m_hCraneMagnet->ResetHasHitSomething();
			m_hCraneTip->m_pSpring->SetSpringConstant( CRANE_SPRING_CONSTANT_LOWERING );

			m_ServerVehicle.PlaySound( VS_MISC1 );
		}
	}

	float flSpeedPercentage = clamp( fabs(m_flTurn) / m_flMaxTurnSpeed, 0, 1 );
	vbs_sound_update_t params;
	params.Defaults();
	params.bThrottleDown = (m_iTurning != TURNING_NOT);
	params.flCurrentSpeedFraction = flSpeedPercentage;
	params.flWorldSpaceSpeed = 0;

	m_ServerVehicle.SoundUpdate( params );

	// Play sounds for arm extension / retraction
	if ( m_bExtending && !bWasExtending )
	{
		m_ServerVehicle.StopSound( VS_ENGINE2_STOP );
		m_ServerVehicle.PlaySound( VS_ENGINE2_START );
	}
	else if ( !m_bExtending && bWasExtending )
	{
		m_ServerVehicle.StopSound( VS_ENGINE2_START );
		m_ServerVehicle.PlaySound( VS_ENGINE2_STOP );
	}
}
//-----------------------------------------------------------------------------
// Purpose: Crane rotates around with +left and +right, and extends/retracts 
//			the cable with +forward and +back.
//-----------------------------------------------------------------------------
void CPropCannon::DriveCannon( int iDriverButtons, int iButtonsPressed )
{
	bool bWasExtending = m_bExtending;

	// Handle rotation of the crane
	if ( iDriverButtons & IN_MOVELEFT )
	{
		// Try adding some randomness to make it feel shaky? 
		float flTurnAdd = m_flTurnAccel;
		// If we're turning back on ourselves, use decel speed
		if ( m_flTurn < 0 )
		{
			flTurnAdd = MAX( flTurnAdd, m_flTurnDecel );
		}

		m_flTurn = UTIL_Approach( m_flMaxTurnSpeed, m_flTurn, flTurnAdd * gpGlobals->frametime );

		m_iTurning = CANNON_TURNING_LEFT;
	}
	else if ( iDriverButtons & IN_MOVERIGHT )
	{
		// Try adding some randomness to make it feel shaky?
		float flTurnAdd = m_flTurnAccel;
		// If we're turning back on ourselves, increase the rate
		if ( m_flTurn > 0 )
		{
			flTurnAdd = MAX( flTurnAdd, m_flTurnDecel );
		}
		m_flTurn = UTIL_Approach( -m_flMaxTurnSpeed, m_flTurn, flTurnAdd * gpGlobals->frametime );

		m_iTurning = CANNON_TURNING_RIGHT;
	}
	else
	{
		m_flTurn = UTIL_Approach( 0, m_flTurn, m_flTurnDecel * gpGlobals->frametime );
		m_iTurning = CANNON_TURNING_NOT;
	}

	SetLocalAngularVelocity( QAngle(0,m_flTurn * 10,0) );

	// Handle extension / retraction of the arm
	if ( iDriverButtons & IN_FORWARD )
	{
		m_flExtensionRate = UTIL_Approach( m_flMaxExtensionSpeed, m_flExtensionRate, m_flExtensionAccel * gpGlobals->frametime );
		m_bExtending = true;
	}
	else if ( iDriverButtons & IN_BACK )
	{
		m_flExtensionRate = UTIL_Approach( -m_flMaxExtensionSpeed, m_flExtensionRate, m_flExtensionAccel * gpGlobals->frametime );
		m_bExtending = true;
	}
	else
	{
		m_flExtensionRate = UTIL_Approach( 0, m_flExtensionRate, m_flExtensionDecel * gpGlobals->frametime );
		m_bExtending = false;
	}

	//Msg("Turn: %f\nExtensionRate: %f\n", m_flTurn, m_flExtensionRate );

	//If we're holding down an attack button, update our state
	if ( iButtonsPressed & (IN_ATTACK | IN_ATTACK2) )
	{
		if ( m_flNextAttackTime <= gpGlobals->curtime )
		{
			LaunchProjectile();
		}
	}

	float flSpeedPercentage = clamp( fabs(m_flTurn) / m_flMaxTurnSpeed, 0, 1 );
	vbs_sound_update_t params;
	params.Defaults();
	params.bThrottleDown = (m_iTurning != CANNON_TURNING_NOT);
	params.flCurrentSpeedFraction = flSpeedPercentage;
	params.flWorldSpaceSpeed = 0;

	m_ServerVehicle.SoundUpdate( params );

	// Play sounds for arm extension / retraction
	if ( m_bExtending && !bWasExtending )
	{
		m_ServerVehicle.StopSound( VS_ENGINE2_STOP );
		m_ServerVehicle.PlaySound( VS_ENGINE2_START );
	}
	else if ( !m_bExtending && bWasExtending )
	{
		m_ServerVehicle.StopSound( VS_ENGINE2_START );
		m_ServerVehicle.PlaySound( VS_ENGINE2_STOP );
	}
}
Beispiel #20
0
void CLeech::UpdateMotion( void )
{
	float flapspeed = (pev->speed - m_flAccelerate) / LEECH_ACCELERATE;
	m_flAccelerate = m_flAccelerate * 0.8 + pev->speed * 0.2;

	if (flapspeed < 0) 
		flapspeed = -flapspeed;
	flapspeed += 1.0;
	if (flapspeed < 0.5) 
		flapspeed = 0.5;
	if (flapspeed > 1.9) 
		flapspeed = 1.9;

	pev->framerate = flapspeed;

	if ( !m_fPathBlocked )
		pev->avelocity.y = pev->ideal_yaw;
	else
		pev->avelocity.y = pev->ideal_yaw * m_obstacle;

	if ( pev->avelocity.y > 150 )
		m_IdealActivity = ACT_TURN_LEFT;
	else if ( pev->avelocity.y < -150 )
		m_IdealActivity = ACT_TURN_RIGHT;
	else
		m_IdealActivity = ACT_SWIM;

	// lean
	float targetPitch, delta;
	delta = m_height - pev->origin.z;

	if ( delta < -10 )
		targetPitch = -30;
	else if ( delta > 10 )
		targetPitch = 30;
	else
		targetPitch = 0;

	pev->angles.x = UTIL_Approach( targetPitch, pev->angles.x, 60 * LEECH_FRAMETIME );

	// bank
	pev->avelocity.z = - (pev->angles.z + (pev->avelocity.y * 0.25));

	if ( m_MonsterState == MONSTERSTATE_COMBAT && HasConditions( bits_COND_CAN_MELEE_ATTACK1 ) )
		m_IdealActivity = ACT_MELEE_ATTACK1;

	// Out of water check
	if ( !pev->waterlevel )
	{
		pev->movetype = MOVETYPE_TOSS;
		m_IdealActivity = ACT_TWITCH;
		pev->velocity = g_vecZero;

		// Animation will intersect the floor if either of these is non-zero
		pev->angles.z = 0;
		pev->angles.x = 0;

		if ( pev->framerate < 1.0 )
			pev->framerate = 1.0;
	}
	else if ( pev->movetype == MOVETYPE_TOSS )
	{
		pev->movetype = MOVETYPE_FLY;
		pev->flags &= ~FL_ONGROUND;
		RecalculateWaterlevel();
		m_waterTime = gpGlobals->time + 2;	// Recalc again soon, water may be rising
	}

	if ( m_Activity != m_IdealActivity )
	{
		SetActivity ( m_IdealActivity );
	}
	float flInterval = StudioFrameAdvance();
	DispatchAnimEvents ( flInterval );

#if DEBUG_BEAMS
	if ( !m_pb )
		m_pb = CBeam::BeamCreate( "sprites/laserbeam.spr", 5 );
	if ( !m_pt )
		m_pt = CBeam::BeamCreate( "sprites/laserbeam.spr", 5 );
	m_pb->PointsInit( pev->origin, pev->origin + gpGlobals->v_forward * LEECH_CHECK_DIST );
	m_pt->PointsInit( pev->origin, pev->origin - gpGlobals->v_right * (pev->avelocity.y*0.25) );
	if ( m_fPathBlocked )
	{
		float color = m_obstacle * 30;
		if ( m_obstacle == 1.0 )
			color = 0;
		if ( color > 255 )
			color = 255;
		m_pb->SetColor( 255, (int)color, (int)color );
	}
	else
		m_pb->SetColor( 255, 255, 0 );
	m_pt->SetColor( 0, 0, 255 );
#endif
}
void CWeaponGravityGun::EffectUpdate( void )
{
	Vector start, angles, forward, right;
	trace_t tr;

	CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
	if ( !pOwner )
		return;

	m_viewModelIndex = pOwner->entindex();
	// Make sure I've got a view model
	CBaseViewModel *vm = pOwner->GetViewModel();
	if ( vm )
	{
		m_viewModelIndex = vm->entindex();
	}

	pOwner->EyeVectors( &forward, &right, NULL );

	start = pOwner->Weapon_ShootPosition();
	Vector end = start + forward * 4096;

	UTIL_TraceLine( start, end, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr );
	end = tr.endpos;
	float distance = tr.fraction * 4096;
	if ( tr.fraction != 1 )
	{
		// too close to the player, drop the object
		if ( distance < 36 )
		{
			DetachObject();
			return;
		}
	}

	if ( m_hObject == NULL && tr.DidHitNonWorldEntity() )
	{
		CBaseEntity *pEntity = tr.m_pEnt;
		// inform the object what was hit
		ClearMultiDamage();
		pEntity->DispatchTraceAttack( CTakeDamageInfo( pOwner, pOwner, 0, DMG_PHYSGUN ), forward, &tr );
		ApplyMultiDamage();
		AttachObject( pEntity, start, tr.endpos, distance );
		m_lastYaw = pOwner->EyeAngles().y;
	}

	// Add the incremental player yaw to the target transform
	matrix3x4_t curMatrix, incMatrix, nextMatrix;
	QAngle ang(0.0f, pOwner->EyeAngles().y - m_lastYaw, 0.0f);
	AngleMatrix( m_gravCallback.m_targetRotation, curMatrix );
	AngleMatrix( ang, incMatrix );
	ConcatTransforms( incMatrix, curMatrix, nextMatrix );
	MatrixAngles( nextMatrix, m_gravCallback.m_targetRotation );
	m_lastYaw = pOwner->EyeAngles().y;

	CBaseEntity *pObject = m_hObject;
	if ( pObject )
	{
		if ( m_useDown )
		{
			if ( pOwner->m_afButtonPressed & IN_USE )
			{
				m_useDown = false;
			}
		}
		else 
		{
			if ( pOwner->m_afButtonPressed & IN_USE )
			{
				m_useDown = true;
			}
		}

		if ( m_useDown )
		{
			pOwner->SetPhysicsFlag( PFLAG_DIROVERRIDE, true );
			if ( pOwner->m_nButtons & IN_FORWARD )
			{
				m_distance = UTIL_Approach( 1024, m_distance, gpGlobals->frametime * 100 );
			}
			if ( pOwner->m_nButtons & IN_BACK )
			{
				m_distance = UTIL_Approach( 40, m_distance, gpGlobals->frametime * 100 );
			}
		}

		if ( pOwner->m_nButtons & IN_WEAPON1 )
		{
			m_distance = UTIL_Approach( 1024, m_distance, m_distance * 0.1 );
		}
		if ( pOwner->m_nButtons & IN_WEAPON2 )
		{
			m_distance = UTIL_Approach( 40, m_distance, m_distance * 0.1 );
		}

		// Send the object a physics damage message (0 damage). Some objects interpret this 
		// as something else being in control of their physics temporarily.
		pObject->TakeDamage( CTakeDamageInfo( this, pOwner, 0, DMG_PHYSGUN ) );

		Vector newPosition = start + forward * m_distance;
		// 24 is a little larger than 16 * sqrt(2) (extent of player bbox)
		// HACKHACK: We do this so we can "ignore" the player and the object we're manipulating
		// If we had a filter for tracelines, we could simply filter both ents and start from "start"
		Vector awayfromPlayer = start + forward * 24;

		UTIL_TraceLine( start, awayfromPlayer, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr );
		if ( tr.fraction == 1 )
		{
			UTIL_TraceLine( awayfromPlayer, newPosition, MASK_SOLID, pObject, COLLISION_GROUP_NONE, &tr );
			Vector dir = tr.endpos - newPosition;
			float distance = VectorNormalize(dir);
			float maxDist = m_gravCallback.m_maxVel * gpGlobals->frametime;
			if ( distance >  maxDist )
			{
				newPosition += dir * maxDist;
		}
		else
		{
			newPosition = tr.endpos;
		}
		}
		else
		{
			newPosition = tr.endpos;
		}

		CreatePelletAttraction( phys_gunglueradius.GetFloat(), pObject );
			
		// If I'm looking more than 20 degrees away from the glue point, then give up
		// This lets the player "gesture" for the glue to let go.
		Vector pelletDir = m_gravCallback.m_worldPosition - start;
		VectorNormalize(pelletDir);
		if ( DotProduct( pelletDir, forward ) < 0.939 )	// 0.939 ~= cos(20deg)
			{
			// lose attach for 2 seconds if you're too far away
			m_glueTime = gpGlobals->curtime + 1;
			}

		if ( m_pelletHeld >= 0 && gpGlobals->curtime > m_glueTime )
		{
			CGravityPellet *pPelletAttract = m_activePellets[m_pelletAttract].pellet;

			g_pEffects->Sparks( pPelletAttract->GetAbsOrigin() );
		}

		m_gravCallback.SetTargetPosition( newPosition );
		Vector dir = (newPosition - pObject->GetLocalOrigin());
		m_movementLength = dir.Length();
	}
	else
	{
		m_gravCallback.SetTargetPosition( end );
	}
	if ( m_pelletHeld >= 0 && gpGlobals->curtime > m_glueTime )
	{
		Vector worldNormal, worldPos;
		GetPelletWorldCoords( m_pelletAttract, &worldPos, &worldNormal );

		m_gravCallback.SetAutoAlign( m_activePellets[m_pelletHeld].localNormal, m_activePellets[m_pelletHeld].pellet->GetLocalOrigin(), worldNormal, worldPos );
	}
	else
	{
		m_gravCallback.ClearAutoAlign();
	}
}
Beispiel #22
0
void CIchthyosaur::Swim( )
{
	int retValue = 0;

	Vector start = pev->origin;

	Vector Angles;
	Vector Forward, Right, Up;

	if (FBitSet( pev->flags, FL_ONGROUND))
	{
		pev->angles.x = 0;
		pev->angles.y += RANDOM_FLOAT( -45, 45 );
		ClearBits( pev->flags, FL_ONGROUND );

		Angles = Vector( -pev->angles.x, pev->angles.y, pev->angles.z );
		UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up);

		pev->velocity = Forward * 200 + Up * 200;

		return;
	}

	if (m_bOnAttack && m_flightSpeed < m_flMaxSpeed)
	{
		m_flightSpeed += 40;
	}
	if (m_flightSpeed < 180)
	{
		if (m_IdealActivity == ACT_RUN)
			SetActivity( ACT_WALK );
		if (m_IdealActivity == ACT_WALK)
			pev->framerate = m_flightSpeed / 150.0;
		// ALERT( at_console, "walk %.2f\n", pev->framerate );
	}
	else
	{
		if (m_IdealActivity == ACT_WALK)
			SetActivity( ACT_RUN );
		if (m_IdealActivity == ACT_RUN)
			pev->framerate = m_flightSpeed / 150.0;
		// ALERT( at_console, "run  %.2f\n", pev->framerate );
	}

/*
	if (!m_pBeam)
	{
		m_pBeam = CBeam::BeamCreate( "sprites/laserbeam.spr", 80 );
		m_pBeam->PointEntInit( pev->origin + m_SaveVelocity, entindex( ) );
		m_pBeam->SetEndAttachment( 1 );
		m_pBeam->SetColor( 255, 180, 96 );
		m_pBeam->SetBrightness( 192 );
	}
*/
#define PROBE_LENGTH 150
	Angles = UTIL_VecToAngles( m_SaveVelocity );
	Angles.x = -Angles.x;
	UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up);

	Vector f, u, l, r, d;
	f = DoProbe(start + PROBE_LENGTH   * Forward);
	r = DoProbe(start + PROBE_LENGTH/3 * Forward+Right);
	l = DoProbe(start + PROBE_LENGTH/3 * Forward-Right);
	u = DoProbe(start + PROBE_LENGTH/3 * Forward+Up);
	d = DoProbe(start + PROBE_LENGTH/3 * Forward-Up);

	Vector SteeringVector = f+r+l+u+d;
	m_SaveVelocity = (m_SaveVelocity + SteeringVector/2).Normalize();

	Angles = Vector( -pev->angles.x, pev->angles.y, pev->angles.z );
	UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up);
	// ALERT( at_console, "%f : %f\n", Angles.x, Forward.z );

	float flDot = DotProduct( Forward, m_SaveVelocity );
	if (flDot > 0.5)
		pev->velocity = m_SaveVelocity = m_SaveVelocity * m_flightSpeed;
	else if (flDot > 0)
		pev->velocity = m_SaveVelocity = m_SaveVelocity * m_flightSpeed * (flDot + 0.5);
	else
		pev->velocity = m_SaveVelocity = m_SaveVelocity * 80;

	// ALERT( at_console, "%.0f %.0f\n", m_flightSpeed, pev->velocity.Length() );


	// ALERT( at_console, "Steer %f %f %f\n", SteeringVector.x, SteeringVector.y, SteeringVector.z );

/*
	m_pBeam->SetStartPos( pev->origin + pev->velocity );
	m_pBeam->RelinkBeam( );
*/

	// ALERT( at_console, "speed %f\n", m_flightSpeed );
	
	Angles = UTIL_VecToAngles( m_SaveVelocity );

	// Smooth Pitch
	//
	if (Angles.x > 180)
		Angles.x = Angles.x - 360;
	pev->angles.x = UTIL_Approach(Angles.x, pev->angles.x, 50 * 0.1 );
	if (pev->angles.x < -80) pev->angles.x = -80;
	if (pev->angles.x >  80) pev->angles.x =  80;

	// Smooth Yaw and generate Roll
	//
	float turn = 360;
	// ALERT( at_console, "Y %.0f %.0f\n", Angles.y, pev->angles.y );

	if (fabs(Angles.y - pev->angles.y) < fabs(turn))
	{
		turn = Angles.y - pev->angles.y;
	}
	if (fabs(Angles.y - pev->angles.y + 360) < fabs(turn))
	{
		turn = Angles.y - pev->angles.y + 360;
	}
	if (fabs(Angles.y - pev->angles.y - 360) < fabs(turn))
	{
		turn = Angles.y - pev->angles.y - 360;
	}

	float speed = m_flightSpeed * 0.1;

	// ALERT( at_console, "speed %.0f %f\n", turn, speed );
	if (fabs(turn) > speed)
	{
		if (turn < 0.0)
		{
			turn = -speed;
		}
		else
		{
			turn = speed;
		}
	}
	pev->angles.y += turn;
	pev->angles.z -= turn;
	pev->angles.y = fmod((pev->angles.y + 360.0), 360.0);

	static float yaw_adj;

	yaw_adj = yaw_adj * 0.8 + turn;

	// ALERT( at_console, "yaw %f : %f\n", turn, yaw_adj );

	SetBoneController( 0, -yaw_adj / 4.0 );

	// Roll Smoothing
	//
	turn = 360;
	if (fabs(Angles.z - pev->angles.z) < fabs(turn))
	{
		turn = Angles.z - pev->angles.z;
	}
	if (fabs(Angles.z - pev->angles.z + 360) < fabs(turn))
	{
		turn = Angles.z - pev->angles.z + 360;
	}
	if (fabs(Angles.z - pev->angles.z - 360) < fabs(turn))
	{
		turn = Angles.z - pev->angles.z - 360;
	}
	speed = m_flightSpeed/2 * 0.1;
	if (fabs(turn) < speed)
	{
		pev->angles.z += turn;
	}
	else
	{
		if (turn < 0.0)
		{
			pev->angles.z -= speed;
		}
		else
		{
			pev->angles.z += speed;
		}
	}
	if (pev->angles.z < -20) pev->angles.z = -20;
	if (pev->angles.z >  20) pev->angles.z =  20;

	UTIL_MakeVectorsPrivate( Vector( -Angles.x, Angles.y, Angles.z ), Forward, Right, Up);

	// UTIL_MoveToOrigin ( ENT(pev), pev->origin + Forward * speed, speed, MOVE_STRAFE );
}
void CASW_Broadcast_Camera::Move()
{
	/*
	if ( HasSpawnFlags( SF_CAMERA_PLAYER_INTERRUPT ) )
	{
		if ( m_hPlayer )
		{
			CBasePlayer *pPlayer = ToBasePlayer( m_hPlayer );

			if ( pPlayer  )
			{
				int buttonsChanged = m_nPlayerButtons ^ pPlayer->m_nButtons;

				if ( buttonsChanged && pPlayer->m_nButtons )
				{
					 Disable();
					 return;
				}

				m_nPlayerButtons = pPlayer->m_nButtons;
			}
		}
	}
	*/
	
	// Not moving on a path, return
	if (!m_pPath)
		return;

	// Subtract movement from the previous frame
	//m_moveDistance -= m_flSpeed * gpGlobals->frametime;
	m_moveDistance -= VectorNormalize(GetAbsOrigin() - m_vecLastPos);

	// Have we moved enough to reach the target?
	if ( m_moveDistance <= 0 )
	{
		variant_t emptyVariant;
		m_pPath->AcceptInput( "InPass", this, this, emptyVariant, 0 );
		// Time to go to the next target
		m_pPath = m_pPath->GetNextTarget();

		// Set up next corner
		if ( !m_pPath )
		{
			SetAbsVelocity( vec3_origin );
		}
		else 
		{
			if ( m_pPath->m_flSpeed != 0 )
				m_targetSpeed = m_pPath->m_flSpeed;

			m_vecMoveDir = m_pPath->GetLocalOrigin() - GetLocalOrigin();
			m_moveDistance = VectorNormalize( m_vecMoveDir );
			m_flStopTime = gpGlobals->curtime + m_pPath->GetDelay();
		}
	}

	if ( m_flStopTime > gpGlobals->curtime )
		m_flSpeed = UTIL_Approach( 0, m_flSpeed, m_deceleration * gpGlobals->frametime );
	else
		m_flSpeed = UTIL_Approach( m_targetSpeed, m_flSpeed, m_acceleration * gpGlobals->frametime );

	float fraction = 2 * gpGlobals->frametime;

	SetAbsVelocity( ((m_vecMoveDir * m_flSpeed) * fraction) + (GetAbsVelocity() * (1-fraction)) );

	m_vecLastPos = GetAbsOrigin();
}
Beispiel #24
0
void CLeech::SwimThink( void )
{
	TraceResult		tr;
	float			flLeftSide;
	float			flRightSide;
	float			targetSpeed;
	float			targetYaw = 0;
	CBaseEntity		*pTarget;

	if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) )
	{
		pev->nextthink = gpGlobals->time + RANDOM_FLOAT(1,1.5);
		pev->velocity = g_vecZero;
		return;
	}
	else
		pev->nextthink = gpGlobals->time + 0.1;

	targetSpeed = LEECH_SWIM_SPEED;

	if ( m_waterTime < gpGlobals->time )
		RecalculateWaterlevel();

	if ( m_stateTime < gpGlobals->time )
		SwitchLeechState();

	ClearConditions( bits_COND_CAN_MELEE_ATTACK1 );
	switch( m_MonsterState )
	{
	case MONSTERSTATE_COMBAT:
		pTarget = m_hEnemy;
		if ( !pTarget )
			SwitchLeechState();
		else
		{
			// Chase the enemy's eyes
			m_height = pTarget->pev->origin.z + pTarget->pev->view_ofs.z - 5;
			// Clip to viable water area
			if ( m_height < m_bottom )
				m_height = m_bottom;
			else if ( m_height > m_top )
				m_height = m_top;
			Vector location = pTarget->pev->origin - pev->origin;
			location.z += (pTarget->pev->view_ofs.z);
			if ( location.Length() < 40 )
				SetConditions( bits_COND_CAN_MELEE_ATTACK1 );
			// Turn towards target ent
			targetYaw = UTIL_VecToYaw( location );

			targetYaw = UTIL_AngleDiff( targetYaw, UTIL_AngleMod( pev->angles.y ) );

			if ( targetYaw < (-LEECH_TURN_RATE*0.75) )
				targetYaw = (-LEECH_TURN_RATE*0.75);
			else if ( targetYaw > (LEECH_TURN_RATE*0.75) )
				targetYaw = (LEECH_TURN_RATE*0.75);
			else
				targetSpeed *= 2;
		}

		break;

	default:
		if ( m_zTime < gpGlobals->time )
		{
			float newHeight = RANDOM_FLOAT( m_bottom, m_top );
			m_height = 0.5 * m_height + 0.5 * newHeight;
			m_zTime = gpGlobals->time + RANDOM_FLOAT( 1, 4 );
		}
		if ( RANDOM_LONG( 0, 100 ) < 10 )
			targetYaw = RANDOM_LONG( -30, 30 );
		pTarget = NULL;
		// oldorigin test
		if ( (pev->origin - pev->oldorigin).Length() < 1 )
		{
			// If leech didn't move, there must be something blocking it, so try to turn
			m_sideTime = 0;
		}

		break;
	}

	m_obstacle = ObstacleDistance( pTarget );
	pev->oldorigin = pev->origin;
	if ( m_obstacle < 0.1 )
		m_obstacle = 0.1;

	// is the way ahead clear?
	if ( m_obstacle == 1.0 )
	{
		// if the leech is turning, stop the trend.
		if ( m_flTurning != 0 )
		{
			m_flTurning = 0;
		}

		m_fPathBlocked = FALSE;
		pev->speed = UTIL_Approach( targetSpeed, pev->speed, LEECH_SWIM_ACCEL * LEECH_FRAMETIME );
		pev->velocity = gpGlobals->v_forward * pev->speed;

	}
	else
	{
		m_obstacle = 1.0 / m_obstacle;
		// IF we get this far in the function, the leader's path is blocked!
		m_fPathBlocked = TRUE;

		if ( m_flTurning == 0 )// something in the way and leech is not already turning to avoid
		{
			Vector vecTest;
			// measure clearance on left and right to pick the best dir to turn
			vecTest = pev->origin + (gpGlobals->v_right * LEECH_SIZEX) + (gpGlobals->v_forward * LEECH_CHECK_DIST);
			UTIL_TraceLine(pev->origin, vecTest, missile, edict(), &tr);
			flRightSide = tr.flFraction;

			vecTest = pev->origin + (gpGlobals->v_right * -LEECH_SIZEX) + (gpGlobals->v_forward * LEECH_CHECK_DIST);
			UTIL_TraceLine(pev->origin, vecTest, missile, edict(), &tr);
			flLeftSide = tr.flFraction;

			// turn left, right or random depending on clearance ratio
			float delta = (flRightSide - flLeftSide);
			if ( delta > 0.1 || (delta > -0.1 && RANDOM_LONG(0,100)<50) )
				m_flTurning = -LEECH_TURN_RATE;
			else
				m_flTurning = LEECH_TURN_RATE;
		}
		pev->speed = UTIL_Approach( -(LEECH_SWIM_SPEED*0.5), pev->speed, LEECH_SWIM_DECEL * LEECH_FRAMETIME * m_obstacle );
		pev->velocity = gpGlobals->v_forward * pev->speed;
	}
	pev->ideal_yaw = m_flTurning + targetYaw;
	UpdateMotion();
}