Example #1
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBasePlayer::SetStepSoundTime( stepsoundtimes_t iStepSoundTime, bool bWalking )
{
	switch ( iStepSoundTime )
	{
	case STEPSOUNDTIME_NORMAL:
	case STEPSOUNDTIME_WATER_FOOT:
		m_flStepSoundTime = bWalking ? 600 : 300;
		break;

	case STEPSOUNDTIME_ON_LADDER:
		m_flStepSoundTime = 500;
		break;

	case STEPSOUNDTIME_WATER_KNEE:
		m_flStepSoundTime = 600;
		break;

	default:
		Assert(0);
		break;
	}

	// UNDONE: need defined numbers for run, walk, crouch, crouch run velocities!!!!	
	if ( ( GetFlags() & FL_DUCKING) || ( GetMoveType() == MOVETYPE_LADDER ) )
	{
		m_flStepSoundTime += 100;
	}
}
bool CSDKPlayer::CanAttack( void )
{
#if defined ( SDK_USE_SPRINTING )
	#if !defined ( SDK_SHOOT_WHILE_SPRINTING )
		if ( IsSprinting() ) 
			return false;
	#endif // SDK_SHOOT_WHILE_SPRINTING
#endif // SDK_USE_SPRINTING

#if !defined ( SDK_SHOOT_ON_LADDERS )
	if ( GetMoveType() == MOVETYPE_LADDER )
		return false;
#endif //SDK_SHOOT_ON_LADDERS

#if !defined ( SDK_SHOOT_WHILE_JUMPING )
	if ( m_Shared.IsJumping() )
		return false;
#endif  //SDK_SHOOT_WHILE_JUMPING

#if defined ( SDK_USE_PRONE )
	// cannot attack while prone moving.
	if ( m_Shared.IsProne() && GetAbsVelocity().LengthSqr() > 1 )
	{
		return false;
	}

	if( m_Shared.IsGoingProne() || m_Shared.IsGettingUpFromProne() )
	{
		return false;
	}
#endif // SDK_USE_PRONE

	return true;
}
void CSDKPlayer::GetStepSoundVelocities( float *velwalk, float *velrun )
{
	BaseClass::GetStepSoundVelocities(velwalk, velrun);

	if (!( ( GetFlags() & FL_DUCKING) || ( GetMoveType() == MOVETYPE_LADDER ) ))
		*velwalk = 110;
}
int CHL2MP_Player::OnTakeDamage( const CTakeDamageInfo &inputInfo )
{
#ifndef GE_DLL
    //return here if the player is in the respawn grace period vs. slams.
    if ( gpGlobals->curtime < m_flSlamProtectTime &&  (inputInfo.GetDamageType() == DMG_BLAST ) )
        return 0;
    m_vecTotalBulletForce += inputInfo.GetDamageForce();
    gamestats->Event_PlayerDamage( this, inputInfo );
#else
    CBaseEntity *attacker = inputInfo.GetAttacker();
    Vector force = inputInfo.GetDamageForce();
    if ( force == vec3_origin && attacker )
    {
        Vector vecDir = vec3_origin;
        if ( inputInfo.GetInflictor() && GetMoveType() == MOVETYPE_WALK && !attacker->IsSolidFlagSet(FSOLID_TRIGGER) )
        {
            vecDir = inputInfo.GetInflictor()->WorldSpaceCenter() - Vector ( 0, 0, 10 ) - WorldSpaceCenter();
            VectorNormalize( vecDir );
            force = vecDir * -DamageForce( WorldAlignSize(), inputInfo.GetBaseDamage() );
        }
    }
    m_vecTotalBulletForce += force;
#endif

    return BaseClass::OnTakeDamage( inputInfo );
}
Example #5
0
//=========================================================
// WaitTillLand - in order to emit their meaty scent from
// the proper location, gibs should wait until they stop 
// bouncing to emit their scent. That's what this function
// does.
//=========================================================
void CGib::WaitTillLand ( void )
{
	if (!IsInWorld())
	{
		UTIL_Remove( this );
		return;
	}

	if ( GetAbsVelocity() == vec3_origin )
	{
		SetRenderAlpha( 255 );
		m_nRenderMode = kRenderTransTexture;
		if ( GetMoveType() != MOVETYPE_VPHYSICS )
		{
			AddSolidFlags( FSOLID_NOT_SOLID );
		}
		SetLocalAngularVelocity( vec3_angle );

		SetNextThink( gpGlobals->curtime + m_lifeTime );
		SetThink ( &CGib::SUB_FadeOut );

		if ( GetSprite() )
		{
			CSprite *pSprite = dynamic_cast<CSprite*>( GetSprite() );

			if ( pSprite )
			{
				//Adrian - Why am I doing this? Check InitPointGib for the answer!
				if ( m_lifeTime == 0 )
					m_lifeTime = random->RandomFloat( 1, 3 );

				pSprite->FadeAndDie( m_lifeTime );
			}
		}

		if ( GetFlame() )
		{
			CEntityFlame *pFlame = dynamic_cast< CEntityFlame*>( GetFlame() );

			if ( pFlame )
			{
				pFlame->SetLifetime( 1.0f );
			}
		}

		// If you bleed, you stink!
		if ( m_bloodColor != DONT_BLEED )
		{
			// ok, start stinkin!
			// FIXME: It's too easy to fill up the sound queue with all these meat sounds
			// CSoundEnt::InsertSound ( SOUND_MEAT, GetAbsOrigin(), 384, 25 );
		}
	}
	else
	{
		// wait and check again in another half second.
		SetNextThink( gpGlobals->curtime + 0.5f );
	}
}
Example #6
0
//-----------------------------------------------------------------------------
// Purpose: Determine view roll, including data kick
//-----------------------------------------------------------------------------
void CBasePlayer::CalcViewRoll( QAngle& eyeAngles )
{
	if ( GetMoveType() == MOVETYPE_NOCLIP )
		return;

	float side = CalcRoll( GetAbsAngles(), GetAbsVelocity(), sv_rollangle.GetFloat(), sv_rollspeed.GetFloat() );
	eyeAngles[ROLL] += side;
}
//-----------------------------------------------------------------------------
// Purpose: Helper to remove from ladder
//-----------------------------------------------------------------------------
void C_BaseHLPlayer::ExitLadder()
{
	if ( MOVETYPE_LADDER != GetMoveType() )
		return;
	
	SetMoveType( MOVETYPE_WALK );
	SetMoveCollide( MOVECOLLIDE_DEFAULT );
	// Remove from ladder
	m_HL2Local.m_hLadder = NULL;
}
Example #8
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Eli::PrescheduleThink( void )
{
	BaseClass::PrescheduleThink();

	// Figure out if Eli has just been removed from his parent
	if ( GetMoveType() == MOVETYPE_NONE && !GetMoveParent() )
	{
		SetupWithoutParent();
		SetupVPhysicsHull();
	}
}
void CStickyBomb::Touch( CBaseEntity *pOther )
{
	// Don't stick if already stuck
	if ( GetMoveType() == MOVETYPE_FLYGRAVITY )
	{
		trace_t tr = GetTouchTrace();
		// stickies don't stick to each other or sky
		if ( FClassnameIs(pOther, "grenade_stickybomb") || (tr.surface.flags & SURF_SKY) )
		{
			// bounce
			Vector vecNewVelocity;
			PhysicsClipVelocity( GetAbsVelocity(), tr.plane.normal, vecNewVelocity, 1.0 );
			SetAbsVelocity( vecNewVelocity );
		}
		else 
		{
			SetAbsVelocity( vec3_origin );
			SetMoveType( MOVETYPE_NONE );
			if ( pOther->entindex() != 0 )
			{
				// set up notification if the parent is deleted before we explode
				g_pNotify->AddEntity( this, pOther );

				if ( (tr.surface.flags & SURF_HITBOX) && modelinfo->GetModelType( pOther->GetModel() ) == mod_studio )
				{
					CBaseAnimating *pOtherAnim = dynamic_cast<CBaseAnimating *>(pOther);
					if ( pOtherAnim )
					{
						matrix3x4_t bombWorldSpace;
						MatrixCopy( EntityToWorldTransform(), bombWorldSpace );

						// get the bone info so we can follow the bone
						FollowEntity( pOther );
						SetOwnerEntity( pOther );
						m_boneIndexAttached = pOtherAnim->GetHitboxBone( tr.hitbox );
						matrix3x4_t boneToWorld;
						pOtherAnim->GetBoneTransform( m_boneIndexAttached, boneToWorld );

						// transform my current position/orientation into the hit bone's space
						// UNDONE: Eventually we need to intersect with the mesh here
						// REVISIT: maybe do something like the decal code to find a spot on
						//			the mesh.
						matrix3x4_t worldToBone, localMatrix;
						MatrixInvert( boneToWorld, worldToBone );
						ConcatTransforms( worldToBone, bombWorldSpace, localMatrix );
						MatrixAngles( localMatrix, m_boneAngles.GetForModify(), m_bonePosition.GetForModify() );
						return;
					}
				}
				SetParent( pOther );
			}
		}
	}
}
BOOL KMovableObject::UnFix()
{
    BOOL bResult = false;

    KGLOG_PROCESS_ERROR(GetMoveType() == mosFixed);

    TurnToMoveType(mosFree);

    bResult = true;
Exit0:
    return bResult;
}
void CTFBaseRocket::Simulate( void )
{
    // Make sure the rocket is facing movement direction.
    if ( GetMoveType() == MOVETYPE_FLYGRAVITY )
    {
        QAngle angForward;
        VectorAngles( GetAbsVelocity(), angForward );
        SetAbsAngles( angForward );
    }

    BaseClass::Simulate();
}
Example #12
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBasePlayer::GetStepSoundVelocities( float *velwalk, float *velrun )
{
	// UNDONE: need defined numbers for run, walk, crouch, crouch run velocities!!!!	
	if ( ( GetFlags() & FL_DUCKING) || ( GetMoveType() == MOVETYPE_LADDER ) )
	{
		*velwalk = 60;		// These constants should be based on cl_movespeedkey * cl_forwardspeed somehow
		*velrun = 80;		
	}
	else
	{
		*velwalk = 90;
		*velrun = 220;
	}
}
Example #13
0
void Monai::GetPositionMon(float time){	
	//GetMoveType(time);
	if(!g_bChangePattern){
		GetMoveType(time);
	}
	if(!g_bChangeThread){
		Type(pMon->GetmType(),time);
	}else{
		pCheckResult->StartSorting();
		g_bChangeThread = FALSE;
		g_bChangePattern = FALSE;
	}
	/*
	if(!bNaton&&time - g_fNormalAttack>5.0f){
		vLength = pMon->GetPosition()-pCha->GetPosition(); 
		if(D3DXVec3Length(&vLength)<MON_REAL_SIZE+MON_ATTACK_RANGE){
			g_bNormalAttack = FALSE;
		}
		if(!g_bNormalAttack){
			pAniModel->SetCurrentAnimation(0);
			fAniMotionTime = 0.01f;
			g_fNormalAttackStart = time;
			g_bNormalAttack = TRUE;
			bNaton = TRUE;
		}else{
			if(time - g_fNormalAttackStart>2.0f){
				pCha->SetLife(-1);
			}else{
				g_bNormalAttack = FALSE;
				bNaton = FALSE;
			}
		}
	}
	
	*///if(!g_bChangeThread){
	//	Type(pMon->GetmType(),time);
	//}else{
	//	if(g_bChangePattern){
	//		pCheckResult->start();
	//		g_bChangePattern = FALSE;
	//	}else{
	//		if(pCheckResult->NowChange()){
	//			pCheckResult->SetChange(FALSE);
	//			g_bChangeThread = FALSE;
	//		}
	//	}
	//}
}
void CBaseGolem::UpdateAI()
{
	switch(GetMoveType())
	{
	case RAND_MOVE:
		{
			CAI_Handler::GetInstance()->RandomMove(this);
		}
		break;
	case TARGET_MOVE:
		{
			CAI_Handler::GetInstance()->MoveToPos(this);
		}
		break;
	}
}
bool CDODPlayer::CanAttack( void )
{
	if ( IsSprinting() ) 
		return false;

	if ( GetMoveType() == MOVETYPE_LADDER )
		return false;

	if ( m_Shared.IsJumping() )
		return false;

	if ( m_Shared.IsDefusing() )
		return false;

	// cannot attack while prone moving. except if you have a bazooka
	if ( m_Shared.IsProne() && GetAbsVelocity().LengthSqr() > 1 )
	{
		return false;
	}

	if( m_Shared.IsGoingProne() || m_Shared.IsGettingUpFromProne() )
	{
		return false;
	}

	CDODGameRules *rules = DODGameRules();

	Assert( rules );

	DODRoundState state = rules->State_Get();

	if ( dod_bonusround.GetBool() )
	{
		if ( GetTeamNumber() == TEAM_ALLIES )
		{ 
			return ( state == STATE_RND_RUNNING || state == STATE_ALLIES_WIN );
		}
		else
		{
			return ( state == STATE_RND_RUNNING || state == STATE_AXIS_WIN );
		}
	}
	else
        return ( state == STATE_RND_RUNNING );
}
void CBasePlayer::AvoidPhysicsProps( CUserCmd *pCmd )
{
#ifndef _XBOX
	// Don't avoid if noclipping or in movetype none
	switch ( GetMoveType() )
	{
	case MOVETYPE_NOCLIP:
	case MOVETYPE_NONE:
		return;
	default:
		break;
	}

	if ( !IsObserver() )
		return;

	AvoidPushawayProps( this, pCmd );
#endif
}
Example #17
0
std::string GetMoveUci(const Move move)
{
	std::string result;
	result += GetSquareSAN(GetFrom(move));
	result += GetSquareSAN(GetTo(move));

	if (GetMoveType(move) == MoveTypePromotion)
	{
		switch (GetPromotionMoveType(move))
		{
		case KNIGHT: result += "n"; break;
		case BISHOP: result += "b"; break;
		case ROOK: result += "r"; break;
		case QUEEN: result += "q"; break;
		}
	}

	return result;
}
Example #18
0
void CSDKPlayer::State_PreThink_DEATH_ANIM()
{
	// If the anim is done playing, go to the next state (waiting for a keypress to 
	// either respawn the guy or put him into observer mode).
	if ( GetFlags() & FL_ONGROUND )
	{
		float flForward = GetAbsVelocity().Length() - 20;
		if (flForward <= 0)
		{
			SetAbsVelocity( vec3_origin );
		}
		else
		{
			Vector vAbsVel = GetAbsVelocity();
			VectorNormalize( vAbsVel );
			vAbsVel *= flForward;
			SetAbsVelocity( vAbsVel );
		}
	}

	if ( gpGlobals->curtime >= (m_flDeathTime + SDK_PLAYER_DEATH_TIME ) )	// let the death cam stay going up to min spawn time.
	{
		m_lifeState = LIFE_DEAD;

		StopAnimation();

		AddEffects( EF_NOINTERP );

		if ( GetMoveType() != MOVETYPE_NONE && (GetFlags() & FL_ONGROUND) )
			SetMoveType( MOVETYPE_NONE );
	}

	//Tony; if we're now dead, and not changing classes, spawn
	if ( m_lifeState == LIFE_DEAD )
	{
#if defined ( SDK_USE_PLAYERCLASSES )
		//Tony; if the class menu is open, don't respawn them, wait till they're done.
		if (IsClassMenuOpen())
			return;
#endif
		State_Transition( STATE_ACTIVE );
	}
}
//------------------------------------------------------------------------------
// Purpose : Override to return correct velocity
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CAI_BasePhysicsFlyingBot::GetVelocity(Vector *vVelocity, AngularImpulse *vAngVelocity)
{
	Assert( GetMoveType() == MOVETYPE_VPHYSICS );
	if ( VPhysicsGetObject() )
	{
		VPhysicsGetObject()->GetVelocity( vVelocity, vAngVelocity );
	}
	else
	{
		if ( vVelocity )
		{
			vVelocity->Init();
		}
		if ( vAngVelocity )
		{
			vAngVelocity->Init();
		}
	}
}
Example #20
0
bool CBliinkPlayer::CanAttack( void )
{
#if defined ( SDK_USE_SPRINTING )
	#if !defined ( SDK_SHOOT_WHILE_SPRINTING )
		if ( IsSprinting() ) 
			return false;
	#endif // SDK_SHOOT_WHILE_SPRINTING
#endif // SDK_USE_SPRINTING

#if !defined ( SDK_SHOOT_ON_LADDERS )
	if ( GetMoveType() == MOVETYPE_LADDER )
		return false;
#endif //SDK_SHOOT_ON_LADDERS

#if !defined ( SDK_SHOOT_WHILE_JUMPING )
	if ( m_Shared.IsJumping() )
		return false;
#endif  //SDK_SHOOT_WHILE_JUMPING

	return true;
}
Example #21
0
void CDHLProjectile::ReceiveMessage( int classID, bf_read &msg )
{
	if ( classID != GetClientClass()->m_ClassID )
	{
		// message is for subclass
		BaseClass::ReceiveMessage( classID, msg );
		return;
	}
	int iType = msg.ReadByte();

	//Server is letting us know that we're about to be deleted
	if ( iType == MSG_NOTIFY_REMOVAL )
	{
		if ( !m_bCollided )
		{
			Vector vecDir = vec3_origin;
			if ( GetAbsVelocity() != vec3_origin )
				vecDir = GetAbsVelocity();
			else
				vecDir = m_vecProjectileVelocity;
			VectorNormalize( vecDir );

			Vector vecStartPos = GetMoveType() == MOVETYPE_CUSTOM ? GetLocalOrigin() : m_vecProjectileOrigin;

			//Try to plant a decal
			trace_t decaltr;
			UTIL_TraceLine( vecStartPos, vecStartPos + (vecDir * 120.0), MASK_SHOT, this, //Pretty long distance, but seems necessary in practice
				COLLISION_GROUP_NONE, &decaltr );
			//DebugDrawLine( decaltr.startpos, decaltr.endpos, 255, 0, 0, false, 3.0f );
			if ( decaltr.DidHit() )
			{
				OnTouch( decaltr, true );
			}

			m_bCollided = true;
		}

	}
}
Example #22
0
void CUnitBase::PhysicsSimulate( void )
{
#ifdef CLIENT_DLL
	if (ShouldPredict())
	{
		m_nSimulationTick = gpGlobals->tickcount;
		return;
	}
#else
	//NDebugOverlay::Box( GetAbsOrigin(), Vector(-16, -16, -16), Vector(16, 24, 16), 0, 255, 0, 255, 0.1f);
#endif // CLIENT_DLL

	if( GetMoveType() != MOVETYPE_WALK )
	{
		BaseClass::PhysicsSimulate();
		return;
	}

	// Run all but the base think function
	PhysicsRunThink( THINK_FIRE_ALL_BUT_BASE );
	PhysicsRunThink( THINK_FIRE_BASE_ONLY );
}
//------------------------------------------------------------------------------
// If we hit water, then stop
//------------------------------------------------------------------------------
void CQUAGrenadeHelicopter::PhysicsSimulate( void )
{
	Vector vecPrevPosition = GetAbsOrigin();
	
	BaseClass::PhysicsSimulate();

	if (!m_bActivated && (GetMoveType() != MOVETYPE_VPHYSICS))
	{
		if ( GetWaterLevel() > 1 )
		{
			SetAbsVelocity( vec3_origin );
			SetMoveType( MOVETYPE_NONE );
			BecomeActive();
		}

		// Stuck condition, can happen pretty often
		if ( vecPrevPosition == GetAbsOrigin() )
		{
			SetAbsVelocity( vec3_origin );
			SetMoveType( MOVETYPE_NONE );
			BecomeActive();
		}
	}
}
void CSnark::HuntThink( void )
{
	if (!IsInWorld())
	{
		SetTouch( NULL );
		UTIL_Remove( this );
		return;
	}
	
	StudioFrameAdvance( );
	SetNextThink( gpGlobals->curtime + 0.1f );

	// explode when ready
	if ( gpGlobals->curtime >= m_flDie )
	{
		g_vecAttackDir = GetAbsVelocity();
		VectorNormalize( g_vecAttackDir );
		m_iHealth = -1;
		CTakeDamageInfo	info( this, this, 1, DMG_GENERIC );
		Event_Killed( info );
		return;
	}

	// float
	if ( GetWaterLevel() != 0)
	{
		if ( GetMoveType() == MOVETYPE_FLYGRAVITY )
		{
			SetMoveType( MOVETYPE_FLY, MOVECOLLIDE_FLY_BOUNCE );
		}

		Vector vecVel = GetAbsVelocity();
		vecVel *= 0.9;
		vecVel.z += 8.0;
		SetAbsVelocity( vecVel );
	}
	else if ( GetMoveType() == MOVETYPE_FLY )
	{
		SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
	}

	// return if not time to hunt
	if ( m_flNextHunt > gpGlobals->curtime )
		return;

	m_flNextHunt = gpGlobals->curtime + 2.0;
	
	Vector vecFlat = GetAbsVelocity();
	vecFlat.z = 0;
	VectorNormalize( vecFlat );

	if ( GetEnemy() == NULL || !GetEnemy()->IsAlive() )
	{
		// find target, bounce a bit towards it.
		GetSenses()->Look( 512 );
		SetEnemy( BestEnemy() );
	}

	// squeek if it's about time blow up
	if ( (m_flDie - gpGlobals->curtime <= 0.5) && (m_flDie - gpGlobals->curtime >= 0.3) )
	{
		CPASAttenuationFilter filter( this );
		enginesound->EmitSound( filter, entindex(), CHAN_VOICE, "squeek/sqk_die1.wav", 1, ATTN_NORM, 0, 100 + random->RandomInt( 0, 0x3F ) );
		CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 256, 0.25 );
	}

	// higher pitch as squeeker gets closer to detonation time
	float flpitch = 155.0 - 60.0 * ( (m_flDie - gpGlobals->curtime) / SQUEEK_DETONATE_DELAY );
	if ( flpitch < 80 )
		flpitch = 80;

	if ( GetEnemy() != NULL )
	{
		if ( FVisible( GetEnemy() ) )
		{
			m_vecTarget = GetEnemy()->EyePosition() - GetAbsOrigin();
			VectorNormalize( m_vecTarget );
		}

		float flVel = GetAbsVelocity().Length();
		float flAdj = 50.0 / ( flVel + 10.0 );

		if ( flAdj > 1.2 )
			flAdj = 1.2;
		
		// ALERT( at_console, "think : enemy\n");

		// ALERT( at_console, "%.0f %.2f %.2f %.2f\n", flVel, m_vecTarget.x, m_vecTarget.y, m_vecTarget.z );

		SetAbsVelocity( GetAbsVelocity() * flAdj + (m_vecTarget * 300) );
	}

	if ( GetFlags() & FL_ONGROUND )
	{
		SetLocalAngularVelocity( QAngle( 0, 0, 0 ) );
	}
	else
	{
		QAngle angVel = GetLocalAngularVelocity();
		if ( angVel == QAngle( 0, 0, 0 ) )
		{
			angVel.x = random->RandomFloat( -100, 100 );
			angVel.z = random->RandomFloat( -100, 100 );
			SetLocalAngularVelocity( angVel );
		}
	}

	if ( ( GetAbsOrigin() - m_posPrev ).Length() < 1.0 )
	{
		Vector vecVel = GetAbsVelocity();
		vecVel.x = random->RandomFloat( -100, 100 );
		vecVel.y = random->RandomFloat( -100, 100 );
		SetAbsVelocity( vecVel );
	}

	m_posPrev = GetAbsOrigin();

	QAngle angles;
	VectorAngles( GetAbsVelocity(), angles );
	angles.z = 0;
	angles.x = 0;
	SetAbsAngles( angles );
}
//-----------------------------------------------------------------------------
// Client-side obstacle avoidance
//-----------------------------------------------------------------------------
void C_BaseHLPlayer::PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd )
{
	// Don't avoid if noclipping or in movetype none
	switch ( GetMoveType() )
	{
	case MOVETYPE_NOCLIP:
	case MOVETYPE_NONE:
	case MOVETYPE_OBSERVER:
		return;
	default:
		break;
	}

	// Try to steer away from any objects/players we might interpenetrate
	Vector size = WorldAlignSize();

	float radius = 0.7f * sqrt( size.x * size.x + size.y * size.y );
	float curspeed = GetLocalVelocity().Length2D();

	//int slot = 1;
	//engine->Con_NPrintf( slot++, "speed %f\n", curspeed );
	//engine->Con_NPrintf( slot++, "radius %f\n", radius );

	// If running, use a larger radius
	float factor = 1.0f;

	if ( curspeed > 150.0f )
	{
		curspeed = MIN( 2048.0f, curspeed );
		factor = ( 1.0f + ( curspeed - 150.0f ) / 150.0f );

		//engine->Con_NPrintf( slot++, "scaleup (%f) to radius %f\n", factor, radius * factor );

		radius = radius * factor;
	}

	Vector currentdir;
	Vector rightdir;

	QAngle vAngles = pCmd->viewangles;
	vAngles.x = 0;

	AngleVectors( vAngles, &currentdir, &rightdir, NULL );
		
	bool istryingtomove = false;
	bool ismovingforward = false;
	if ( fabs( pCmd->forwardmove ) > 0.0f || 
		fabs( pCmd->sidemove ) > 0.0f )
	{
		istryingtomove = true;
		if ( pCmd->forwardmove > 1.0f )
		{
			ismovingforward = true;
		}
	}

	if ( istryingtomove == true )
		 radius *= 1.3f;

	CPlayerAndObjectEnumerator avoid( radius );
	partition->EnumerateElementsInSphere( PARTITION_CLIENT_SOLID_EDICTS, GetAbsOrigin(), radius, false, &avoid );

	// Okay, decide how to avoid if there's anything close by
	int c = avoid.GetObjectCount();
	if ( c <= 0 )
		return;

	//engine->Con_NPrintf( slot++, "moving %s forward %s\n", istryingtomove ? "true" : "false", ismovingforward ? "true" : "false"  );

	float adjustforwardmove = 0.0f;
	float adjustsidemove	= 0.0f;

	for ( int i = 0; i < c; i++ )
	{
		C_AI_BaseNPC *obj = dynamic_cast< C_AI_BaseNPC *>(avoid.GetObject( i ));

		if( !obj )
			continue;

		Vector vecToObject = obj->GetAbsOrigin() - GetAbsOrigin();

		float flDist = vecToObject.Length2D();
		
		// Figure out a 2D radius for the object
		Vector vecWorldMins, vecWorldMaxs;
		obj->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs );
		Vector objSize = vecWorldMaxs - vecWorldMins;

		float objectradius = 0.5f * sqrt( objSize.x * objSize.x + objSize.y * objSize.y );

		//Don't run this code if the NPC is not moving UNLESS we are in stuck inside of them.
		if ( !obj->IsMoving() && flDist > objectradius )
			  continue;

		if ( flDist > objectradius && obj->IsEffectActive( EF_NODRAW ) )
		{
			obj->RemoveEffects( EF_NODRAW );
		}

		Vector vecNPCVelocity;
		obj->EstimateAbsVelocity( vecNPCVelocity );
		float flNPCSpeed = VectorNormalize( vecNPCVelocity );

		Vector vPlayerVel = GetAbsVelocity();
		VectorNormalize( vPlayerVel );

		float flHit1, flHit2;
		Vector vRayDir = vecToObject;
		VectorNormalize( vRayDir );

		float flVelProduct = DotProduct( vecNPCVelocity, vPlayerVel );
		float flDirProduct = DotProduct( vRayDir, vPlayerVel );

		if ( !IntersectInfiniteRayWithSphere(
				GetAbsOrigin(),
				vRayDir,
				obj->GetAbsOrigin(),
				radius,
				&flHit1,
				&flHit2 ) )
			continue;

        Vector dirToObject = -vecToObject;
		VectorNormalize( dirToObject );

		float fwd = 0;
		float rt = 0;

		float sidescale = 2.0f;
		float forwardscale = 1.0f;
		bool foundResult = false;

		Vector vMoveDir = vecNPCVelocity;
		if ( flNPCSpeed > 0.001f )
		{
			// This NPC is moving. First try deflecting the player left or right relative to the NPC's velocity.
			// Start with whatever side they're on relative to the NPC's velocity.
			Vector vecNPCTrajectoryRight = CrossProduct( vecNPCVelocity, Vector( 0, 0, 1) );
			int iDirection = ( vecNPCTrajectoryRight.Dot( dirToObject ) > 0 ) ? 1 : -1;
			for ( int nTries = 0; nTries < 2; nTries++ )
			{
				Vector vecTryMove = vecNPCTrajectoryRight * iDirection;
				VectorNormalize( vecTryMove );
				
				Vector vTestPosition = GetAbsOrigin() + vecTryMove * radius * 2;

				if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
				{
					fwd = currentdir.Dot( vecTryMove );
					rt = rightdir.Dot( vecTryMove );
					
					//Msg( "PUSH DEFLECT fwd=%f, rt=%f\n", fwd, rt );
					
					foundResult = true;
					break;
				}
				else
				{
					// Try the other direction.
					iDirection *= -1;
				}
			}
		}
		else
		{
			// the object isn't moving, so try moving opposite the way it's facing
			Vector vecNPCForward;
			obj->GetVectors( &vecNPCForward, NULL, NULL );
			
			Vector vTestPosition = GetAbsOrigin() - vecNPCForward * radius * 2;
			if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
			{
				fwd = currentdir.Dot( -vecNPCForward );
				rt = rightdir.Dot( -vecNPCForward );

				if ( flDist < objectradius )
				{
					obj->AddEffects( EF_NODRAW );
				}

				//Msg( "PUSH AWAY FACE fwd=%f, rt=%f\n", fwd, rt );

				foundResult = true;
			}
		}

		if ( !foundResult )
		{
			// test if we can move in the direction the object is moving
			Vector vTestPosition = GetAbsOrigin() + vMoveDir * radius * 2;
			if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
			{
				fwd = currentdir.Dot( vMoveDir );
				rt = rightdir.Dot( vMoveDir );

				if ( flDist < objectradius )
				{
					obj->AddEffects( EF_NODRAW );
				}

				//Msg( "PUSH ALONG fwd=%f, rt=%f\n", fwd, rt );

				foundResult = true;
			}
			else
			{
				// try moving directly away from the object
				Vector vTestPosition = GetAbsOrigin() - dirToObject * radius * 2;
				if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
				{
					fwd = currentdir.Dot( -dirToObject );
					rt = rightdir.Dot( -dirToObject );
					foundResult = true;

					//Msg( "PUSH AWAY fwd=%f, rt=%f\n", fwd, rt );
				}
			}
		}

		if ( !foundResult )
		{
			// test if we can move through the object
			Vector vTestPosition = GetAbsOrigin() - vMoveDir * radius * 2;
			fwd = currentdir.Dot( -vMoveDir );
			rt = rightdir.Dot( -vMoveDir );

			if ( flDist < objectradius )
			{
				obj->AddEffects( EF_NODRAW );
			}

			//Msg( "PUSH THROUGH fwd=%f, rt=%f\n", fwd, rt );

			foundResult = true;
		}

		// If running, then do a lot more sideways veer since we're not going to do anything to
		//  forward velocity
		if ( istryingtomove )
		{
			sidescale = 6.0f;
		}

		if ( flVelProduct > 0.0f && flDirProduct > 0.0f )
		{
			sidescale = 0.1f;
		}

		float force = 1.0f;
		float forward = forwardscale * fwd * force * AVOID_SPEED;
		float side = sidescale * rt * force * AVOID_SPEED;

		adjustforwardmove	+= forward;
		adjustsidemove		+= side;
	}

	pCmd->forwardmove	+= adjustforwardmove;
	pCmd->sidemove		+= adjustsidemove;
	
	// Clamp the move to within legal limits, preserving direction. This is a little
	// complicated because we have different limits for forward, back, and side

	//Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );

	float flForwardScale = 1.0f;
	if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) )
	{
		flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove;
	}
	else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) )
	{
		flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove );
	}
	
	float flSideScale = 1.0f;
	if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) )
	{
		flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove );
	}
	
	float flScale = MIN( flForwardScale, flSideScale );
	pCmd->forwardmove *= flScale;
	pCmd->sidemove *= flScale;

	//Msg( "POSTCLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
}
//-----------------------------------------------------------------------------
// Purpose: Give the buster a slight attraction to striders.
//			Ported back from the magnade.
//-----------------------------------------------------------------------------
void CWeaponStriderBuster::BusterFlyThink()
{
	if (IsAttachedToStrider())
		return; // early out. Think no more.

	// If we're nosediving, forget about magnetism.
	if ( m_bNoseDiving )
	{
		if ( VPhysicsGetObject() )
			VPhysicsGetObject()->ApplyForceCenter( Vector( 0, 0, striderbuster_dive_force.GetFloat() ) );
		SetNextThink(gpGlobals->curtime + 0.01f);
		return;
	}

	// seek?	
	const float magradius = 38.0 * sk_striderbuster_magnet_multiplier.GetFloat(); // radius of strider hull times multiplier
	if (magradius > 0 &&
		GetMoveType() == MOVETYPE_VPHYSICS &&
		VPhysicsGetObject()
		)
	{
		// find the nearest enemy.
		CBaseEntity *pList[16];
		Vector origin = GetAbsOrigin();

		// do a find in box ( a little faster than sphere )
		int count;
		{
			Vector mins,maxs;
			mins = origin; 
			mins -= magradius;
			
			maxs = origin; 
			maxs += magradius;

			count = UTIL_EntitiesInBox(pList, 16, mins, maxs, FL_NPC); 
		}

		float magradiusSq = Square( magradius );	
		float nearestDistSq = magradiusSq + 1;
		int bestFit = -1;
		Vector toTarget; // will be garbage unless something good is found
		CNPC_Strider *pBestStrider  = NULL;

		for ( int ii = 0 ; ii < count ; ++ii )
		{
			CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(pList[ii]);
			if ( pStrider && !pStrider->CarriedByDropship() ) // ShouldStickToEntity() doesn't work because the strider NPC isn't what we glue to
			{
				// get distance squared
				VectorSubtract( pStrider->GetAdjustedOrigin(), GetAbsOrigin(), toTarget );

				//NDebugOverlay::Line( GetAbsOrigin(), GetAbsOrigin() + toTarget, 128, 0, 128, false, 0.1 );

				float dSq = toTarget.LengthSqr();
				if (dSq < nearestDistSq)
				{
					bestFit = ii; nearestDistSq = dSq;
					pBestStrider = pStrider;
				}
			}
		}

		if (bestFit >= 0) // we found something and should attract towards it. (hysterisis later?)
		{
			if ( striderbuster_debugseek.GetBool() )
			{
				NDebugOverlay::Circle( GetAbsOrigin() + toTarget, magradius, 255, 255, 255, 255, true, .1 );
				NDebugOverlay::Cross3D( GetAbsOrigin() + toTarget, magradius, 255, 255, 255, true, .1 );
			}

			// force magnitude. 
			float magnitude = GetMass() * striderbuster_magnetic_force_strider.GetFloat();
			int falloff = striderbuster_falloff_power.GetInt();
			switch (falloff) 
			{
			case 1:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / nearestDistSq) ); // dividing through by distance squared normalizes toTarget and gives a linear falloff
				break;
			case 2:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / (nearestDistSq * sqrtf(nearestDistSq))) ); // dividing through by distance cubed normalizes toTarget and gives a quadratic falloff
				break;
			case 3:
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / (nearestDistSq * nearestDistSq)) ); // dividing through by distance fourth normalizes toTarget and gives a cubic falloff
				break;
			case 4:
				{
					Vector toTarget;
					pBestStrider->GetAttachment( "buster_target", toTarget );

					if ( striderbuster_debugseek.GetBool() )
					{
						NDebugOverlay::Cross3D( toTarget, magradius, 255, 0, 255, true, .1 );
						NDebugOverlay::Cross3D( toTarget, magradius, 255, 0, 255, true, .1 );
					}

					toTarget -= GetAbsOrigin();
					toTarget.NormalizeInPlace();
					VPhysicsGetObject()->ApplyForceCenter( toTarget * magnitude );

				}
				break;
			default: // arbitrary powers
				VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude * powf(nearestDistSq,(falloff+1.0f)/2)) );  // square root for distance instead of squared, add one to normalize toTarget 
				break;
			}
		}

		SetNextThink(gpGlobals->curtime + 0.01f);
	}
}
Example #27
0
void CBasePlayer::UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity )
{
	bool bWalking;
	float fvol;
	Vector knee;
	Vector feet;
	float height;
	float speed;
	float velrun;
	float velwalk;
	int	fLadder;

	if ( m_flStepSoundTime > 0 )
	{
		m_flStepSoundTime -= 1000.0f * gpGlobals->frametime;
		if ( m_flStepSoundTime < 0 )
		{
			m_flStepSoundTime = 0;
		}
	}

	if ( m_flStepSoundTime > 0 )
		return;

	if ( GetFlags() & (FL_FROZEN|FL_ATCONTROLS))
		return;

	if ( GetMoveType() == MOVETYPE_NOCLIP || GetMoveType() == MOVETYPE_OBSERVER )
		return;

	if ( !sv_footsteps.GetFloat() )
		return;

	speed = VectorLength( vecVelocity );
	float groundspeed = Vector2DLength( vecVelocity.AsVector2D() );

	// determine if we are on a ladder
	fLadder = ( GetMoveType() == MOVETYPE_LADDER );

	GetStepSoundVelocities( &velwalk, &velrun );

	bool onground = ( GetFlags() & FL_ONGROUND );
	bool movingalongground = ( groundspeed > 0.0001f );
	bool moving_fast_enough =  ( speed >= velwalk );

#ifdef PORTAL
	// In Portal we MUST play footstep sounds even when the player is moving very slowly
	// This is used to count the number of footsteps they take in the challenge mode
	// -Jeep
	moving_fast_enough = true;
#endif

	// To hear step sounds you must be either on a ladder or moving along the ground AND
	// You must be moving fast enough

	if ( !moving_fast_enough || !(fLadder || ( onground && movingalongground )) )
			return;

//	MoveHelper()->PlayerSetAnimation( PLAYER_WALK );

	bWalking = speed < velrun;		

	VectorCopy( vecOrigin, knee );
	VectorCopy( vecOrigin, feet );

	height = GetPlayerMaxs()[ 2 ] - GetPlayerMins()[ 2 ];

	knee[2] = vecOrigin[2] + 0.2 * height;

	// find out what we're stepping in or on...
	if ( fLadder )
	{
		psurface = GetLadderSurface(vecOrigin);
		fvol = 0.5;

		SetStepSoundTime( STEPSOUNDTIME_ON_LADDER, bWalking );
	}
	else if ( GetWaterLevel() == WL_Waist )
	{
		static int iSkipStep = 0;

		if ( iSkipStep == 0 )
		{
			iSkipStep++;
			return;
		}

		if ( iSkipStep++ == 3 )
		{
			iSkipStep = 0;
		}
		psurface = physprops->GetSurfaceData( physprops->GetSurfaceIndex( "wade" ) );
		fvol = 0.65;
		SetStepSoundTime( STEPSOUNDTIME_WATER_KNEE, bWalking );
	}
	else if ( GetWaterLevel() == WL_Feet )
	{
		psurface = physprops->GetSurfaceData( physprops->GetSurfaceIndex( "water" ) );
		fvol = bWalking ? 0.2 : 0.5;

		SetStepSoundTime( STEPSOUNDTIME_WATER_FOOT, bWalking );
	}
	else
	{
		if ( !psurface )
			return;

		SetStepSoundTime( STEPSOUNDTIME_NORMAL, bWalking );

		switch ( psurface->game.material )
		{
		default:
		case CHAR_TEX_CONCRETE:						
			fvol = bWalking ? 0.2 : 0.5;
			break;

		case CHAR_TEX_METAL:	
			fvol = bWalking ? 0.2 : 0.5;
			break;

		case CHAR_TEX_DIRT:
			fvol = bWalking ? 0.25 : 0.55;
			break;

		case CHAR_TEX_VENT:	
			fvol = bWalking ? 0.4 : 0.7;
			break;

		case CHAR_TEX_GRATE:
			fvol = bWalking ? 0.2 : 0.5;
			break;

		case CHAR_TEX_TILE:	
			fvol = bWalking ? 0.2 : 0.5;
			break;

		case CHAR_TEX_SLOSH:
			fvol = bWalking ? 0.2 : 0.5;
			break;
		}
	}
	
	// play the sound
	// 65% volume if ducking
	if ( GetFlags() & FL_DUCKING )
	{
		fvol *= 0.65;
	}

	PlayStepSound( feet, psurface, fvol, false );
}
Example #28
0
void CBasePlayer::UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity )
{
	int	fWalking;
	float fvol;
	Vector knee;
	Vector feet;
	float height;
	float speed;
	float velrun;
	float velwalk;
	float flduck;
	int	fLadder;

	if ( m_flStepSoundTime > 0 )
	{
		m_flStepSoundTime -= 1000.0f * gpGlobals->frametime;
		if ( m_flStepSoundTime < 0 )
		{
			m_flStepSoundTime = 0;
		}
	}

	if ( m_flStepSoundTime > 0 )
		return;

	if ( GetFlags() & (FL_FROZEN|FL_ATCONTROLS))
		return;

	if ( GetMoveType() == MOVETYPE_NOCLIP || GetMoveType() == MOVETYPE_OBSERVER )
		return;

	if ( !sv_footsteps.GetFloat() )
		return;

	speed = VectorLength( vecVelocity );
	float groundspeed = Vector2DLength( vecVelocity.AsVector2D() );

	// determine if we are on a ladder
	fLadder = ( GetMoveType() == MOVETYPE_LADDER );

	// UNDONE: need defined numbers for run, walk, crouch, crouch run velocities!!!!	
	if ( ( GetFlags() & FL_DUCKING) || fLadder )
	{
		velwalk = 60;		// These constants should be based on cl_movespeedkey * cl_forwardspeed somehow
		velrun = 80;		
		flduck = 100;
	}
	else
	{
		velwalk = 90;
		velrun = 220;
		flduck = 0;
	}

	bool onground = ( GetFlags() & FL_ONGROUND );
	bool movingalongground = ( groundspeed > 0.0f );
	bool moving_fast_enough =  ( speed >= velwalk );

	// To hear step sounds you must be either on a ladder or moving along the ground AND
	// You must be moving fast enough

	if ( !moving_fast_enough || !(fLadder || ( onground && movingalongground )) )
			return;

//	MoveHelper()->PlayerSetAnimation( PLAYER_WALK );

	fWalking = speed < velrun;		

	VectorCopy( vecOrigin, knee );
	VectorCopy( vecOrigin, feet );

	height = GetPlayerMaxs()[ 2 ] - GetPlayerMins()[ 2 ];

	knee[2] = vecOrigin[2] + 0.2 * height;

	// find out what we're stepping in or on...
	if ( fLadder )
	{
#ifdef CLIENT_DLL
		psurface = GetFootstepSurface( vecOrigin, "ladder" );
#else
		psurface = physprops->GetSurfaceData( physprops->GetSurfaceIndex( "ladder" ) );
#endif
		fvol = 0.5;
		m_flStepSoundTime = 350;
	}
	else if ( enginetrace->GetPointContents( knee ) & MASK_WATER )
	{
		static int iSkipStep = 0;

		if ( iSkipStep == 0 )
		{
			iSkipStep++;
			return;
		}

		if ( iSkipStep++ == 3 )
		{
			iSkipStep = 0;
		}
		psurface = physprops->GetSurfaceData( physprops->GetSurfaceIndex( "wade" ) );
		fvol = 0.65;
		m_flStepSoundTime = 600;
	}
	else if ( enginetrace->GetPointContents( feet ) & MASK_WATER )
	{
		psurface = physprops->GetSurfaceData( physprops->GetSurfaceIndex( "water" ) );
		fvol = fWalking ? 0.2 : 0.5;
		m_flStepSoundTime = fWalking ? 400 : 300;		
	}
	else
	{
		if ( !psurface )
			return;

		m_flStepSoundTime = fWalking ? 400 : 300;
		switch ( psurface->game.material )
		{
		default:
		case CHAR_TEX_CONCRETE:						
			fvol = fWalking ? 0.2 : 0.5;
			break;

		case CHAR_TEX_METAL:	
			fvol = fWalking ? 0.2 : 0.5;
			break;

		case CHAR_TEX_DIRT:
			fvol = fWalking ? 0.25 : 0.55;
			break;

		case CHAR_TEX_VENT:	
			fvol = fWalking ? 0.4 : 0.7;
			break;

		case CHAR_TEX_GRATE:
			fvol = fWalking ? 0.2 : 0.5;
			break;

		case CHAR_TEX_TILE:	
			fvol = fWalking ? 0.2 : 0.5;
			break;

		case CHAR_TEX_SLOSH:
			fvol = fWalking ? 0.2 : 0.5;
			break;
		}
	}
	
	m_flStepSoundTime += flduck; // slower step time if ducking

	// play the sound
	// 65% volume if ducking
	if ( GetFlags() & FL_DUCKING )
	{
		fvol *= 0.65;
	}

	PlayStepSound( feet, psurface, fvol, false );
}
Example #29
0
std::string GetMoveSAN(Position &position, const Move move)
{
	const Square from = GetFrom(move);
	const Square to = GetTo(move);

	const Move moveType = GetMoveType(move);

	std::string result;
	if (moveType == MoveTypeCastle)
	{
		if (GetColumn(to) > FILE_E)
		{
			result = "O-O";
		}
		else
		{
			result = "O-O-O";
		}
	}
	else
	{
		// Piece that is moving
		const PieceType fromPieceType = GetPieceType(position.Board[from]);
		switch (fromPieceType)
		{
		case PAWN: break;
		case KNIGHT: result += "N"; break;
		case BISHOP: result += "B"; break;
		case ROOK: result += "R"; break;
		case QUEEN: result += "Q"; break;
		case KING: result += "K"; break;
		}

		Move legalMoves[256];
		int legalMoveCount = GenerateLegalMoves(position, legalMoves);

		// Do we need to disambiguate?
		bool dupe = false, rowDiff = true, columnDiff = true;
		for (int i = 0; i < legalMoveCount; i++)
		{
			if (GetFrom(legalMoves[i]) != from &&
				GetTo(legalMoves[i]) == to &&
				GetPieceType(position.Board[GetFrom(legalMoves[i])]) == fromPieceType)
			{
				dupe = true;
				if (GetRow(GetFrom(legalMoves[i])) == GetRow(from))
				{
					rowDiff = false;
				}
				if (GetColumn(GetFrom(legalMoves[i])) == GetColumn(from))
				{
					columnDiff = false;
				}
			}
		}

		if (dupe)
		{
			if (columnDiff)
			{
				result += GetSquareSAN(from)[0];
			}
			else if (rowDiff)
			{
				result += GetSquareSAN(from)[1];
			}
			else
			{
				result += GetSquareSAN(from);
			}
		}
		else if (fromPieceType == PAWN && position.Board[to] != PIECE_NONE)
		{
			// Pawn captures need a row
			result += GetSquareSAN(from)[0];
		}
		
		// Capture?
		if (position.Board[to] != PIECE_NONE ||
			moveType == MoveTypeEnPassent)
		{
			result += "x";
		}

		// Target square
		result += GetSquareSAN(to);
	}

	if (moveType == MoveTypePromotion)
	{
		switch (GetPromotionMoveType(move))
		{
		case KNIGHT: result += "=N"; break;
		case BISHOP: result += "=B"; break;
		case ROOK: result += "=R"; break;
		case QUEEN: result += "=Q"; break;
		}
	}

	MoveUndo moveUndo;
	position.MakeMove(move, moveUndo);

	if (position.IsInCheck())
	{
		Move checkEscapes[64];
		result += GenerateCheckEscapeMoves(position, checkEscapes) == 0 ? "#" : "+";
	}

	position.UnmakeMove(move, moveUndo);

	return result;
}
Example #30
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : flInterval - 
//			 - 
//			*pTraceResult - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CAI_BaseNPC::AutoMovement( float flInterval, CBaseEntity *pTarget, AIMoveTrace_t *pTraceResult )
{
	bool ignored;
	Vector newPos;
	QAngle newAngles;

	if (flInterval <= 0.0)
		return true;

	m_ScheduleState.bTaskRanAutomovement = true;

	if (GetIntervalMovement( flInterval, ignored, newPos, newAngles ))
	{
		// DevMsg( "%.2f : (%.1f) %.1f %.1f %.1f\n", gpGlobals->curtime, (newPos - GetLocalOrigin()).Length(), newPos.x, newPos.y, newAngles.y );
	
		if ( m_hCine )
		{
			m_hCine->ModifyScriptedAutoMovement( &newPos );
		}

		if (GetMoveType() == MOVETYPE_STEP)
		{
			if (!(GetFlags() & FL_FLY))
			{
				if ( !pTarget )
				{
					pTarget = GetNavTargetEntity();
				}

				// allow NPCs to adjust the automatic movement
				if ( ModifyAutoMovement( newPos ) )
				{
					// Set our motor's speed here
					Vector vecOriginalPosition = GetAbsOrigin();
					bool bResult = false;
					if (!TaskIsComplete())
					{
						bResult = ( GetMotor()->MoveGroundStep( newPos, pTarget, newAngles.y, false, true, pTraceResult ) == AIM_SUCCESS );
					}

					Vector change = GetAbsOrigin() - vecOriginalPosition;
					if (flInterval != 0)
					{
						change /= flInterval;
					}

					GetMotor()->SetMoveVel(change);

					return bResult;
				}

				return ( GetMotor()->MoveGroundStep( newPos, pTarget, newAngles.y, false, true, pTraceResult ) == AIM_SUCCESS );
			}
			else
			{
				// FIXME: here's no direct interface to a fly motor, plus this needs to support a state where going through the world is okay.
				// FIXME: add callbacks into the script system for validation
				// FIXME: add function on scripts to force only legal movements
				// FIXME: GetIntervalMovement deals in Local space, nor global.  Currently now way to communicate that through these interfaces.
				SetLocalOrigin( newPos );
				SetLocalAngles( newAngles );
				return true;
			}
		}
		else if (GetMoveType() == MOVETYPE_FLY)
		{
			Vector dist = newPos - GetLocalOrigin();

			VectorScale( dist, 1.0 / flInterval, dist );

			SetLocalVelocity( dist );
			return true;
		}
	}
	return false;
}