void CASW_Drone_Movement::CategorizePosition()
{
	Vector point, bumpOrigin;
	trace_t pm;

	point = bumpOrigin = mv->GetAbsOrigin();
	point.z -= 2;
	bumpOrigin.z += 2;

	// Shooting up really fast.  Definitely not on ground.
	if ( mv->m_vecVelocity[2] > 140 || 
		( mv->m_vecVelocity[2] > 0.0f && m_pNPC->GetMoveType() == MOVETYPE_LADDER ) )   
	{
		SetGroundEntity( (CBaseEntity *)NULL );
	}
	else
	{
		// Try and move down.
		UTIL_TraceEntity( m_pNPC, bumpOrigin, point, MASK_NPCSOLID, &pm );
		//TraceBBox( bumpOrigin, point, MASK_NPCSOLID, m_pNPC->GetCollisionGroup(), pm );
		
		// Moving up two units got us stuck in something, start tracing down exactly at our
		//  current origin (since CheckStuck allowed us to get here, that pos is valid)
		if ( pm.startsolid )
		{
			bumpOrigin = mv->GetAbsOrigin();
			UTIL_TraceEntity( m_pNPC, bumpOrigin, point, MASK_NPCSOLID, &pm );
			//TraceBBox( bumpOrigin, point, MASK_NPCSOLID, m_pNPC->GetCollisionGroup(), pm );
		}

		// If we hit a steep plane, we are not on ground
		if ( pm.plane.normal[2] < 0.7)
		{
			SetGroundEntity( (CBaseEntity *)NULL );	// too steep
			// probably want to add a check for a +z velocity too!
			if ( ( mv->m_vecVelocity.z > 0.0f ) && ( m_pNPC->GetMoveType() != MOVETYPE_NOCLIP ) )
			{
				m_surfaceFriction = 0.25f;
			}
		}
		else
		{
			SetGroundEntity( pm.m_pEnt );  // Otherwise, point to index of ent under us.
		}

		// If we are on something...
		if (m_pNPC->GetGroundEntity() != NULL)
		{
			
			// If we could make the move, drop us down that 1 pixel
			if (!pm.startsolid && !pm.allsolid )
			{
				if( pm.fraction )
				{
					mv->SetAbsOrigin( pm.endpos );
				}
			}
		}		
	}
}
Exemplo n.º 2
0
//-----------------------------------------------------------------------------
// Drops an entity onto the floor
//-----------------------------------------------------------------------------
int UTIL_DropToFloor( CBaseEntity *pEntity, unsigned int mask, CBaseEntity *pIgnore)
{
    // Assume no ground
    //pEntity->SetGroundEntity( NULL );

    Assert( pEntity );

    trace_t	trace;
    // HACK: is this really the only sure way to detect crossing a terrain boundry?
    UTIL_TraceEntity( pEntity, VFuncs::GetAbsOrigin(pEntity), VFuncs::GetAbsOrigin(pEntity), mask, pIgnore, VFuncs::GetCollisionGroup(pEntity), &trace );
    if (trace.fraction == 0.0)
        return -1;

    UTIL_TraceEntity( pEntity, VFuncs::GetAbsOrigin(pEntity), VFuncs::GetAbsOrigin(pEntity) - Vector(0,0,256), mask, pIgnore, VFuncs::GetCollisionGroup(pEntity), &trace );

    if (trace.allsolid)
        return -1;

    if (trace.fraction == 1)
        return 0;

    VFuncs::Teleport(pEntity, &trace.endpos, NULL, NULL);
    //pEntity->SetAbsOrigin( trace.endpos );
    //pEntity->SetGroundEntity( trace.m_pEnt );

    return 1;
}
Exemplo n.º 3
0
void TerrainMod_Add( TerrainModType type, const CTerrainModParams &params )
{
	if ( IsXbox() )
	{
		return;
	}

	// Move players out of the way so they don't get stuck on the terrain.
	float playerStartHeights[MAX_PLAYERS];

	int i;
	int nPlayers = MIN( MAX_PLAYERS, gpGlobals->maxClients );
	for( i=0; i < nPlayers; i++ )
	{
		CBasePlayer *pPlayer = UTIL_PlayerByIndex( i+1 );
	
		if( !pPlayer )
			continue;

		playerStartHeights[i] = pPlayer->GetAbsOrigin().z;

		// Cast a ray upwards to see if we can move the player out of the way.
		trace_t trace;
		UTIL_TraceEntity( 
			pPlayer, pPlayer->GetAbsOrigin(),
			pPlayer->GetAbsOrigin() + Vector( 0, 0, params.m_flRadius*2 ),
			MASK_SOLID,
			&trace );

		pPlayer->SetLocalOrigin( trace.endpos );
	}
	
	// Apply the mod.
	engine->ApplyTerrainMod( type, params );
	
	// Move players back down.
	for( i=0; i < nPlayers; i++ )
	{
		CBasePlayer *pPlayer = UTIL_PlayerByIndex( i+1 );
	
		if( !pPlayer )
			continue;
		
		// Cast a ray upwards to see if we can move the player out of the way.
		trace_t trace;
		UTIL_TraceEntity( 
			pPlayer,
			pPlayer->GetAbsOrigin(),
			Vector( pPlayer->GetAbsOrigin().x, pPlayer->GetAbsOrigin().y, playerStartHeights[i] ),
			MASK_SOLID,
			&trace );

		pPlayer->SetLocalOrigin( trace.endpos );
	}
}
static void RestoreEntityTo( CBaseEntity *pEntity, const Vector &vWantedPos )
{
	int nMask = pEntity->IsPlayer() ? MASK_PLAYERSOLID : MASK_NPCSOLID;
	int nCollisionGroup = pEntity->IsPlayer() ? COLLISION_GROUP_PLAYER_MOVEMENT : COLLISION_GROUP_NPC;

	// Try to move to the wanted position from our current position.
	trace_t tr;
	VPROF_BUDGET( "RestorePlayerTo", "CTFLagCompensationManager" );
	UTIL_TraceEntity( pEntity, vWantedPos, vWantedPos, nMask, pEntity, nCollisionGroup, &tr );
	if ( tr.startsolid || tr.allsolid )
	{
		if ( sv_unlag_debug.GetBool() )
		{
			CBasePlayer *pPlayer = ToBasePlayer( pEntity );

			if ( pPlayer )
			{
				DevMsg( "RestorePlayerTo() could not restore player position for client \"%s\" ( %.1f %.1f %.1f )\n",
					pPlayer->GetPlayerName(), vWantedPos.x, vWantedPos.y, vWantedPos.z );
			}
			else
			{
				DevMsg( "RestoreEntityTo() could not restore entity position for %s ( %.1f %.1f %.1f )\n",
					pEntity->GetClassname(), vWantedPos.x, vWantedPos.y, vWantedPos.z );
			}
		}

		UTIL_TraceEntity( pEntity, pEntity->GetLocalOrigin(), vWantedPos, nMask, pEntity, nCollisionGroup, &tr );
		if ( tr.startsolid || tr.allsolid )
		{
			// In this case, the guy got stuck back wherever we lag compensated him to. Nasty.

			if ( sv_unlag_debug.GetBool() )
				DevMsg( " restore failed entirely\n" );
		}
		else
		{
			// We can get to a valid place, but not all the way back to where we were.
			Vector vPos;
			VectorLerp( pEntity->GetLocalOrigin(), vWantedPos, tr.fraction * g_flFractionScale, vPos );
			UTIL_SetOrigin( pEntity, vPos, true );

			if ( sv_unlag_debug.GetBool() )
				DevMsg( " restore got most of the way\n" );
		}
	}
	else
	{
		// Cool, the player can go back to whence he came.
		UTIL_SetOrigin( pEntity, tr.endpos, true );
	}
}
//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
Vector CAI_BasePhysicsFlyingBot::VelocityToAvoidObstacles(float flInterval)
{
	// --------------------------------
	//  Avoid banging into stuff
	// --------------------------------
	trace_t tr;
	Vector vTravelDir = m_vCurrentVelocity*flInterval;
	Vector endPos = GetAbsOrigin() + vTravelDir;
	UTIL_TraceEntity( this, GetAbsOrigin(), endPos, MASK_NPCSOLID|CONTENTS_WATER, &tr);
	if (tr.fraction != 1.0)
	{	
		// Bounce off in normal 
		Vector vBounce = tr.plane.normal * 0.5 * m_vCurrentVelocity.Length();
		return (vBounce);
	}
	
	// --------------------------------
	// Try to remain above the ground.
	// --------------------------------
	float flMinGroundDist = MinGroundDist();
	UTIL_TraceLine(GetAbsOrigin(), GetAbsOrigin() + Vector(0, 0, -flMinGroundDist), 
		MASK_NPCSOLID_BRUSHONLY|CONTENTS_WATER, BaseEntity(), COLLISION_GROUP_NONE, &tr);
	if (tr.fraction < 1)
	{
		// Clamp veloctiy
		if (tr.fraction < 0.1)
		{
			tr.fraction = 0.1;
		}

		return Vector(0, 0, 50/tr.fraction);
	}
	return vec3_origin;
}
void CASW_Drone_Movement::FinishGravity( void )
{
	/*
	float ent_gravity;

	if ( m_pNPC->GetGravity() )
		ent_gravity = m_pNPC->GetGravity();
	else
		ent_gravity = 1.0;

	ent_gravity = 3.0;

	// Get the correct velocity for the end of the dt 
  	mv->m_vecVelocity[2] -= (ent_gravity * sv_gravity.GetFloat() * m_flInterval * 0.5);
	*/
	// push the drone down by gravity
	Vector dest = mv->GetAbsOrigin();
	dest[2] = mv->GetAbsOrigin()[2] + mv->m_vecVelocity.z * m_flInterval;
	trace_t pm;
	UTIL_TraceEntity( m_pNPC, mv->GetAbsOrigin(), dest, MASK_NPCSOLID, &pm );
	if (!pm.startsolid && !pm.allsolid)
	{
		dest[2] = mv->GetAbsOrigin()[2] + mv->m_vecVelocity.z * m_flInterval * pm.fraction;
		mv->SetAbsOrigin( dest );
	}
}
Exemplo n.º 7
0
// Overridden for Gargantua because his swing starts lower as
// a percentage of his height (otherwise he swings over the
// players head)
//=========================================================
CBaseEntity* CNPC_Gargantua::GargantuaCheckTraceHullAttack(float flDist, int iDamage, int iDmgType)
{
	trace_t tr;

	Vector vForward, vUp;
	AngleVectors( GetAbsAngles(), &vForward, NULL, &vUp );

	Vector vecStart = GetAbsOrigin();
	vecStart.z += 64;
	Vector vecEnd = vecStart + ( vForward * flDist) - ( vUp * flDist * 0.3);

	//UTIL_TraceHull( vecStart, vecEnd, dont_ignore_monsters, head_hull, ENT(pev), &tr );

	UTIL_TraceEntity( this, GetAbsOrigin(), vecEnd, MASK_SOLID, &tr );
	
	if ( tr.m_pEnt )
	{
		CBaseEntity *pEntity = tr.m_pEnt;

		if ( iDamage > 0 )
		{
			CTakeDamageInfo info( this, this, iDamage, iDmgType );
			CalculateMeleeDamageForce( &info, vForward, tr.endpos );
			pEntity->TakeDamage( info );
		}

		return pEntity;
	}

	return NULL;
}
Exemplo n.º 8
0
void CSatchelCharge::SatchelThink( void )
{
	// If attached resize so player can pick up off wall
	if (m_bIsAttached)
	{
		UTIL_SetSize(this, Vector( -2, -2, -6), Vector(2, 2, 6));
	}

	// See if I can lose my owner (has dropper moved out of way?)
	// Want do this so owner can shoot the satchel charge
	if (GetOwnerEntity())
	{
		trace_t tr;
		Vector	vUpABit = GetAbsOrigin();
		vUpABit.z += 5.0;

		CBaseEntity* saveOwner	= GetOwnerEntity();
		SetOwnerEntity( NULL );
		UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr );
		if ( tr.startsolid || tr.fraction != 1.0 )
		{
			SetOwnerEntity( saveOwner );
		}
	}
	
	// Bounce movement code gets this think stuck occasionally so check if I've 
	// succeeded in moving, otherwise kill my motions.
	else if ((GetAbsOrigin() - m_vLastPosition).LengthSqr()<1)
	{
		SetAbsVelocity( vec3_origin );

		QAngle angVel = GetLocalAngularVelocity();
		angVel.y  = 0;
		SetLocalAngularVelocity( angVel );

		// Clear think function
		SetThink(NULL);
		return;
	}
	m_vLastPosition= GetAbsOrigin();

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

	if (!IsInWorld())
	{
		UTIL_Remove( this );
		return;
	}

	// Is it attached to a wall?
	if (m_bIsAttached)
	{
		return;
	}
}
Exemplo n.º 9
0
void CTripmineGrenade::BeamBreakThink( void  )
{
	// See if I can go solid yet (has dropper moved out of way?)
	if (IsSolidFlagSet( FSOLID_NOT_SOLID ))
	{
		trace_t tr;
		Vector	vUpBit = GetAbsOrigin();
		vUpBit.z += 5.0;

		UTIL_TraceEntity( this, GetAbsOrigin(), vUpBit, MASK_SHOT, &tr );
		if ( !tr.startsolid && (tr.fraction == 1.0) )
		{
			RemoveSolidFlags( FSOLID_NOT_SOLID );
		}
	}

	trace_t tr;

	// NOT MASK_SHOT because we want only simple hit boxes
	UTIL_TraceLine( GetAbsOrigin(), m_vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

	// ALERT( at_console, "%f : %f\n", tr.flFraction, m_flBeamLength );

	// respawn detect. 
	if ( !m_pBeam )
	{
		MakeBeam( );
		if ( tr.m_pEnt )
			m_hOwner = tr.m_pEnt;	// reset owner too
	}


	CBaseEntity *pEntity = tr.m_pEnt;
	CBaseCombatCharacter *pBCC  = ToBaseCombatCharacter( pEntity );

	bool bAttachMoved = false;
	if ( m_bAttached && m_hAttachEntity.Get() != NULL )
	{
		if ( m_hAttachEntity.Get()->GetAbsOrigin() != m_vAttachedPosition )
			bAttachMoved = true;
	}

	// Also blow up if the attached entity goes away, ie: a crate
	if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001 || ( m_bAttached && m_hAttachEntity.Get() == NULL) || bAttachMoved )
	{
		m_iHealth = 0;
		if (m_pConstraint)
			m_pConstraint->Deactivate();

		Event_Killed( CTakeDamageInfo( (CBaseEntity*)m_hOwner, this, 100, GIB_NORMAL ) );
		return;
	}

	SetNextThink( gpGlobals->curtime + 0.05f );
}
//=========================================================
// RunTask 
//=========================================================
void CNPC_HAssassin::RunTask ( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_ASSASSIN_FALL_TO_GROUND:
		GetMotor()->SetIdealYawAndUpdate( GetEnemyLKP() );

		if ( IsSequenceFinished() )
		{
			if ( GetAbsVelocity().z > 0)
			{
				SetActivity( ACT_ASSASSIN_FLY_UP );
			}
			else if ( HasCondition ( COND_SEE_ENEMY ))
			{
				SetActivity( ACT_ASSASSIN_FLY_ATTACK );
				SetCycle( 0 );
			}
			else
			{
				SetActivity( ACT_ASSASSIN_FLY_DOWN );
				SetCycle( 0 );
			}
						
			ResetSequenceInfo( );
		}

		if ( GetFlags() & FL_ONGROUND)
		{
			TaskComplete( );
		}
		else if( gpGlobals->curtime > m_flWaitFinished || GetAbsVelocity().z == 0.0 )
		{
			// I've waited two seconds and haven't hit the ground. Try to force it.
			trace_t trace;
			UTIL_TraceEntity( this, GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 1 ), MASK_NPCSOLID, this, COLLISION_GROUP_NONE, &trace );

			if( trace.DidHitWorld() )
			{
				SetGroundEntity( trace.m_pEnt );
			}
			else
			{
				// Try again in a couple of seconds.
				m_flWaitFinished = gpGlobals->curtime + 2.0f;
			}
		}
		break;
	default: 
		BaseClass::RunTask ( pTask );
		break;
	}
}
Exemplo n.º 11
0
void CTripwireGrenade::RopeBreakThink( void  )
{
	// See if I can go solid yet (has dropper moved out of way?)
	if (IsSolidFlagSet(FSOLID_NOT_SOLID))
	{
		trace_t tr;
		Vector	vUpBit = GetAbsOrigin();
		vUpBit.z += 5.0;

		UTIL_TraceEntity( this, GetAbsOrigin(), vUpBit, MASK_SHOT, &tr );
		if ( !tr.startsolid && (tr.fraction == 1.0) )
		{
			RemoveSolidFlags( FSOLID_NOT_SOLID );
		}
	}

	// Check if rope had gotten beyond it's max length
	float flRopeLength = (GetAbsOrigin()-m_pHook->GetAbsOrigin()).Length();
	if (flRopeLength > TGRENADE_MAX_ROPE_LEN)
	{
		// Shoot missiles at hook
		m_iHealth = 0;
		BreakRope();
		m_vTargetPos = m_pHook->GetAbsOrigin();
		CrossProduct ( m_vecDir, Vector(0,0,1), m_vTargetOffset );
		m_vTargetOffset *=TGRENADE_MISSILE_OFFSET; 
		SetThink(FireThink);
		FireThink();
	}

	// Check to see if can see hook
	// NOT MASK_SHOT because we want only simple hit boxes
	trace_t tr;
	UTIL_TraceLine( GetAbsOrigin(), m_pHook->GetAbsOrigin(), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

	// If can't see hook
	CBaseEntity *pEntity = tr.m_pEnt;
	if (tr.fraction != 1.0 && pEntity != m_pHook)
	{
		// Shoot missiles at place where rope was intersected
		m_iHealth = 0;
		BreakRope();
		m_vTargetPos = tr.endpos;
		CrossProduct ( m_vecDir, Vector(0,0,1), m_vTargetOffset );
		m_vTargetOffset *=TGRENADE_MISSILE_OFFSET; 
		SetThink(FireThink);
		FireThink();
		return;
	}

	SetNextThink( gpGlobals->curtime + 0.1f );
}
Exemplo n.º 12
0
static void RestoreEntityTo( CAI_BaseNPC *pEntity, const Vector &vWantedPos )
{
	// Try to move to the wanted position from our current position.
	trace_t tr;
	VPROF_BUDGET( "RestoreEntityTo", "CLagCompensationManager" );
	UTIL_TraceEntity( pEntity, vWantedPos, vWantedPos, MASK_NPCSOLID, pEntity, COLLISION_GROUP_NPC, &tr );
	if ( tr.startsolid || tr.allsolid )
	{
		if ( sv_unlag_debug.GetBool() )
		{
			DevMsg( "RestorepEntityTo() could not restore entity position for %s ( %.1f %.1f %.1f )\n",
					pEntity->GetClassname(), vWantedPos.x, vWantedPos.y, vWantedPos.z );
		}

		UTIL_TraceEntity( pEntity, pEntity->GetLocalOrigin(), vWantedPos, MASK_NPCSOLID, pEntity, COLLISION_GROUP_NPC, &tr );
		if ( tr.startsolid || tr.allsolid )
		{
			// In this case, the guy got stuck back wherever we lag compensated him to. Nasty.

			if ( sv_unlag_debug.GetBool() )
				DevMsg( " restore failed entirely\n" );
		}
		else
		{
			// We can get to a valid place, but not all the way back to where we were.
			Vector vPos;
			VectorLerp( pEntity->GetLocalOrigin(), vWantedPos, tr.fraction * g_flFractionScale, vPos );
			UTIL_SetOrigin( pEntity, vPos, true );

			if ( sv_unlag_debug.GetBool() )
				DevMsg( " restore got most of the way\n" );
		}
	}
	else
	{
		// Cool, the entity can go back to whence he came.
		UTIL_SetOrigin( pEntity, tr.endpos, true );
	}
}
Exemplo n.º 13
0
void CTripmineGrenade::BeamBreakThink( void  )
{
	// See if I can go solid yet (has dropper moved out of way?)
	if (IsSolidFlagSet( FSOLID_NOT_SOLID ))
	{
		trace_t tr;
		Vector	vUpBit = GetAbsOrigin();
		vUpBit.z += 5.0;

		UTIL_TraceEntity( this, GetAbsOrigin(), vUpBit, MASK_SHOT, &tr );
		if ( !tr.startsolid && (tr.fraction == 1.0) )
		{
			RemoveSolidFlags( FSOLID_NOT_SOLID );
		}
	}

	trace_t tr;

	// NOT MASK_SHOT because we want only simple hit boxes
	UTIL_TraceLine( GetAbsOrigin(), m_vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

	// ALERT( at_console, "%f : %f\n", tr.flFraction, m_flBeamLength );

	// respawn detect. 
	if ( !m_pBeam )
	{
		MakeBeam( );
		if ( tr.m_pEnt )
			m_hOwner = tr.m_pEnt;	// reset owner too
	}


	CBaseEntity *pEntity = tr.m_pEnt;
	CBaseCombatCharacter *pBCC  = ToBaseCombatCharacter( pEntity );
	
	if (pBCC && pBCC->GetTeamNumber() != m_nTeam && pBCC->m_floatCloakFactor < 1.0f)
	//if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001)
	{
		m_iHealth = 0;
		Event_Killed( CTakeDamageInfo( (CBaseEntity*)m_hOwner, this, 100, GIB_NORMAL ) );
		

		return;
	}

	SetNextThink( gpGlobals->curtime + 0.05f );
}
Exemplo n.º 14
0
//=========================================================
// Spawn
//=========================================================
void CGenericNPC::Spawn()
{
	Precache();

	SetModel( STRING( GetModelName() ) );

/*
	if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) )
		UTIL_SetSize(this, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
	else
		UTIL_SetSize(this, VEC_HULL_MIN, VEC_HULL_MAX);
*/

	if ( FStrEq( STRING( GetModelName() ), "models/player.mdl" ) || FStrEq( STRING( GetModelName() ), "models/holo.mdl" ) )
		UTIL_SetSize(this, VEC_HULL_MIN, VEC_HULL_MAX);
	else
		UTIL_SetSize(this, NAI_Hull::Mins(HULL_HUMAN), NAI_Hull::Maxs(HULL_HUMAN));

	SetSolid( SOLID_BBOX );
	AddSolidFlags( FSOLID_NOT_STANDABLE );
	SetMoveType( MOVETYPE_STEP );
	m_bloodColor		= BLOOD_COLOR_RED;
	m_iHealth			= 8;
	m_flFieldOfView		= 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result )
	m_NPCState			= NPC_STATE_NONE;
	
	CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS );

	NPCInit();
	if ( !HasSpawnFlags(SF_GENERICNPC_NOTSOLID) )
	{
		trace_t tr;
		UTIL_TraceEntity( this, GetAbsOrigin(), GetAbsOrigin(), MASK_SOLID, &tr );
		if ( tr.startsolid )
		{
			Msg("Placed npc_generic in solid!!! (%s)\n", STRING(GetModelName()) );
			m_spawnflags |= SF_GENERICNPC_NOTSOLID;
		}
	}

	if ( HasSpawnFlags(SF_GENERICNPC_NOTSOLID) )
	{
		AddSolidFlags( FSOLID_NOT_SOLID );
		m_takedamage = DAMAGE_NO;
		VPhysicsDestroyObject();
	}
}
Exemplo n.º 15
0
bool CASW_Parasite::HasHeadroom()
{
	trace_t tr;
	UTIL_TraceEntity( this, GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, 1 ), MASK_NPCSOLID, this, GetCollisionGroup(), &tr );

#if 0
	if( tr.fraction == 1.0f )
	{
		Msg("Headroom\n");
	}
	else
	{
		Msg("NO Headroom\n");
	}
#endif

	return (tr.fraction == 1.0);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CAI_RappelBehavior::BeginRappel()
{
	// Send the message to begin rappeling!
	SetCondition( COND_BEGIN_RAPPEL );

	m_vecRopeAnchor = GetOuter()->GetAbsOrigin();

	trace_t tr;

	UTIL_TraceEntity( GetOuter(), GetAbsOrigin(), GetAbsOrigin()-Vector(0,0,4096), MASK_SHOT, GetOuter(), COLLISION_GROUP_NONE, &tr );

	if( tr.m_pEnt != NULL && tr.m_pEnt->IsNPC() )
	{
		Vector forward;
		GetOuter()->GetVectors( &forward, NULL, NULL );

		CSoundEnt::InsertSound( SOUND_DANGER, tr.m_pEnt->EarPosition() - forward * 12.0f, 32, 0.2f, GetOuter() );
	}
}
Exemplo n.º 17
0
//------------------------------------------------------------------------------
// Searches along the direction ray in steps of "step" to see if 
// the entity position is passible.
// Used for putting the player in valid space when toggling off noclip mode.
//------------------------------------------------------------------------------
int FindPassableSpace( CBaseEntity *pPlayer, const Vector& direction, float step, Vector& oldorigin )
{
    int i;
    for ( i = 0; i < 100; i++ )
    {
        Vector origin = VFuncs::GetAbsOrigin(pPlayer);
        VectorMA( origin, step, direction, origin );
        VFuncs::SetAbsOrigin(pPlayer,  origin );

        trace_t trace;
        UTIL_TraceEntity( pPlayer, VFuncs::GetAbsOrigin(pPlayer), VFuncs::GetAbsOrigin(pPlayer), MASK_PLAYERSOLID, &trace );
        if ( trace.startsolid == 0)
        {
            VectorCopy( VFuncs::GetAbsOrigin(pPlayer), oldorigin );
            return 1;
        }
    }
    return 0;
}
Exemplo n.º 18
0
void CASW_Drone_Movement::WalkMove()
{
	// Add in any base velocity to the current velocity.
	VectorAdd (mv->m_vecVelocity, m_pNPC->GetBaseVelocity(), mv->m_vecVelocity );

	// if we're barely moving, then zero the velocity and stop
	float spd = VectorLength( mv->m_vecVelocity );
	if ( spd < 1.0f || m_flInterval <= 0)
	{
		mv->m_vecVelocity.Init();
		// Now pull the base velocity back out.   Base velocity is set if you are on a moving object, like a conveyor (or maybe another monster?)
		VectorSubtract( mv->m_vecVelocity, m_pNPC->GetBaseVelocity(), mv->m_vecVelocity );
		return;
	}

	// first try just moving to the destination	
	Vector dest;
	dest[0] = mv->GetAbsOrigin()[0] + mv->m_vecVelocity[0]*m_flInterval;
	dest[1] = mv->GetAbsOrigin()[1] + mv->m_vecVelocity[1]*m_flInterval;
	dest[2] = mv->GetAbsOrigin()[2];
	trace_t pm;
	UTIL_TraceEntity( m_pNPC, mv->GetAbsOrigin(), dest, MASK_NPCSOLID, &pm );
	//TraceBBox( mv->GetAbsOrigin(), dest, MASK_NPCSOLID, m_pNPC->GetCollisionGroup(), pm );

	// if we made it all the way there, then set that as our new origin and return
	if ( pm.fraction == 1 )
	{
		mv->SetAbsOrigin( pm.endpos );
		m_pNPC->PhysicsTouchTriggers();
		// Now pull the base velocity back out.   Base velocity is set if you are on a moving object, like a conveyor (or maybe another monster?)
		VectorSubtract( mv->m_vecVelocity, m_pNPC->GetBaseVelocity(), mv->m_vecVelocity );
		return;
	}

	// if NPC started the move on the ground, then try to move up/down steps
	if ( m_pNPC->GetGroundEntity() != NULL )
	{
		StepMove( dest, pm );		
	}

	// Now pull the base velocity back out.   Base velocity is set if you are on a moving object, like a conveyor (or maybe another monster?)
	VectorSubtract( mv->m_vecVelocity, m_pNPC->GetBaseVelocity(), mv->m_vecVelocity );
}
Exemplo n.º 19
0
//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CGrenade_Molotov::MolotovThink( void )
{
	// See if I can lose my owner (has dropper moved out of way?)
	// Want do this so owner can throw the brickbat
	if (GetOwnerEntity())
	{
		trace_t tr;
		Vector	vUpABit = GetAbsOrigin();
		vUpABit.z += 5.0;

		CBaseEntity* saveOwner	= GetOwnerEntity();
		SetOwnerEntity( NULL );
		UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr );
		if ( tr.startsolid || tr.fraction != 1.0 )
		{
			SetOwnerEntity( saveOwner );
		}
	}
	SetNextThink( gpGlobals->curtime + 0.1f );
}
Exemplo n.º 20
0
void CPlayerPickupController::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	if ( ToBasePlayer(pActivator) == m_pPlayer )
	{
		CBaseEntity *pAttached = m_grabController.GetAttached();

		if ( !pAttached || useType == USE_OFF || m_grabController.ComputeError() > 12 || (m_pPlayer->m_nButtons & (IN_ATTACK|IN_ATTACK2)) )
		{
			Shutdown();
			return;
		}
		else if ( useType == USE_SET )
		{
			// update position
			matrix3x4_t tmp;
			ComputePlayerMatrix( tmp );
			Vector position;
			QAngle angles;
			VectorTransform( m_positionPlayerSpace, tmp, position );
			angles = TransformAnglesToWorldSpace( m_anglesPlayerSpace, tmp );
			CheckObjectPosition( position, angles, pAttached->GetAbsOrigin() );

			// check to see if object is still sitting on something
			trace_t tr;
			Vector down = Vector( 0, 0, -6 );
			UTIL_TraceEntity( pAttached, position, position + down, MASK_SOLID, &tr );
			// if trace made it then there's nothing left to sit on, break the tie
			if ( tr.fraction == 1 )
			{
				Shutdown();
				return;
			}
			else
			{
				m_grabController.SetTargetPosition( position, angles );
			}
		}
	}
}
Exemplo n.º 21
0
//-----------------------------------------------------------------------------
// Purpose: Check that the selected position is buildable
//-----------------------------------------------------------------------------
bool CBaseObject::IsPlacementPosValid( void )
{
	bool bValid = CalculatePlacementPos();

	if ( !bValid )
	{
		return false;
	}

	CTFPlayer *pPlayer = GetOwner();

	if ( !pPlayer )
	{
		return false;
	}

#ifndef CLIENT_DLL
	if ( !EstimateValidBuildPos() )
		return false;
#endif

	// Verify that the entire object can fit here
	// Important! here we want to collide with players and other buildings, but not dropped weapons
	trace_t tr;
	UTIL_TraceEntity( this, m_vecBuildOrigin, m_vecBuildOrigin, MASK_SOLID, NULL, COLLISION_GROUP_PLAYER, &tr );

	if ( tr.fraction < 1.0f )
		return false;

	// Make sure we can see the final position
	UTIL_TraceLine( pPlayer->EyePosition(), m_vecBuildOrigin + Vector(0,0,m_vecBuildMaxs[2] * 0.5), MASK_PLAYERSOLID_BRUSHONLY, pPlayer, COLLISION_GROUP_NONE, &tr );
	if ( tr.fraction < 1.0 )
	{
		return false;
	}

	return true;
}
Exemplo n.º 22
0
//-----------------------------------------------------------------------------
// trace line rules
//-----------------------------------------------------------------------------
float CGameRules::WeaponTraceEntity( CBaseEntity *pEntity, const Vector &vecStart, const Vector &vecEnd,
					 unsigned int mask, trace_t *ptr )
{
	UTIL_TraceEntity( pEntity, vecStart, vecEnd, mask, ptr );
	return 1.0f;
}
Exemplo n.º 23
0
int CASW_Drone_Movement::TryMove( Vector *pFirstDest, trace_t *pFirstTrace )
{
	int			bumpcount, numbumps;
	Vector		dir;
	float		d;
	int			numplanes;
	Vector		planes[MAX_CLIP_PLANES];
	Vector		primal_velocity, original_velocity;
	Vector      new_velocity;
	int			i, j;
	trace_t	pm;
	Vector		end;
	float		time_left, allFraction;
	int			blocked;		
	
	numbumps  = 4;           // Bump up to four times
	
	blocked   = 0;           // Assume not blocked
	numplanes = 0;           //  and not sliding along any planes

	VectorCopy (mv->m_vecVelocity, original_velocity);  // Store original velocity
	VectorCopy (mv->m_vecVelocity, primal_velocity);
	
	allFraction = 0;
	time_left = m_flInterval;   // Total time for this movement operation.

	new_velocity.Init();

	// set the last wall normal z high, so any planes found are 'more upright'
	m_LastHitWallNormal.z = 2.0f;

	for (bumpcount=0 ; bumpcount < numbumps; bumpcount++)
	{
		if ( mv->m_vecVelocity.Length() == 0.0 )
			break;

		// Assume we can move all the way from the current origin to the
		//  end point.
		VectorMA( mv->GetAbsOrigin(), time_left, mv->m_vecVelocity, end );

		// See if we can make it from origin to end point.
		if ( g_bMovementOptimizations )
		{
			// If their velocity Z is 0, then we can avoid an extra trace here during WalkMove.
			if ( pFirstDest && end == *pFirstDest )
				pm = *pFirstTrace;
			else
				UTIL_TraceEntity( m_pNPC, mv->GetAbsOrigin(), end, MASK_NPCSOLID, &pm );
				//TraceBBox( mv->GetAbsOrigin(), end, MASK_NPCSOLID, m_pNPC->GetCollisionGroup(), pm );
		}
		else
		{
			UTIL_TraceEntity( m_pNPC, mv->GetAbsOrigin(), end, MASK_NPCSOLID, &pm );
			//TraceBBox( mv->GetAbsOrigin(), end, MASK_NPCSOLID, m_pNPC->GetCollisionGroup(), pm );
		}

		allFraction += pm.fraction;
		
		// If we started in a solid object, or we were in solid space
		//  the whole way, zero out our velocity and return that we
		//  are blocked by floor and wall.
		if (pm.allsolid)
		{	
			// entity is trapped in another solid
			VectorCopy (vec3_origin, mv->m_vecVelocity);
			return 4;
		}

		if (pm.fraction < 1.0f)	// we've hit something, store the most wall-ish normal
		{
			// store the most upright plane
			if (m_LastHitWallNormal.z > pm.plane.normal.z)
				VectorCopy(pm.plane.normal, m_LastHitWallNormal);
		}

		// If we moved some portion of the total distance, then
		//  copy the end position into the pmove.origin and 
		//  zero the plane counter.
		if( pm.fraction > 0 )
		{	
			// actually covered some distance
			mv->SetAbsOrigin(pm.endpos);
			VectorCopy (mv->m_vecVelocity, original_velocity);
			numplanes = 0;
		}

		// If we covered the entire distance, we are done
		//  and can return.
		if (pm.fraction == 1)
		{
			 break;		// moved the entire distance
		}

		// Save entity that blocked us (since fraction was < 1.0)
		//  for contact
		// Add it if it's not already in the list!!!
		//MoveHelper( )->AddToTouched( pm, mv->m_vecVelocity );

		// If the plane we hit has a high z component in the normal, then
		//  it's probably a floor
		if (pm.plane.normal[2] > 0.7)
		{
			blocked |= 1;		// floor
		}
		
		// If the plane has a zero z component in the normal, then it's a 
		//  step or wall
		if (!pm.plane.normal[2])
		{
			blocked |= 2;		// step / wall
		}

		// Reduce amount of m_flFrameTime left by total time left * fraction
		//  that we covered.
		time_left -= time_left * pm.fraction;

		// Did we run out of planes to clip against?
		if (numplanes >= MAX_CLIP_PLANES)
		{	
			// this shouldn't really happen
			//  Stop our movement if so.
			VectorCopy (vec3_origin, mv->m_vecVelocity);
			//Con_DPrintf("Too many planes 4\n");

			break;
		}

		// Set up next clipping plane
		VectorCopy (pm.plane.normal, planes[numplanes]);
		numplanes++;

		// modify original_velocity so it parallels all of the clip planes
		//

		// relfect npc velocity 
		// Only give this a try for first impact plane because you can get yourself stuck in an acute corner by jumping in place
		//  and pressing forward and nobody was really using this bounce/reflection feature anyway...
		if ( numplanes == 1 &&
			m_pNPC->GetMoveType() == MOVETYPE_WALK &&
			m_pNPC->GetGroundEntity() == NULL )	
		{
			for ( i = 0; i < numplanes; i++ )
			{
				if ( planes[i][2] > 0.7  )
				{
					// floor or slope
					ClipVelocity( original_velocity, planes[i], new_velocity, 1 );
					VectorCopy( new_velocity, original_velocity );
				}
				else
				{
					ClipVelocity( original_velocity, planes[i], new_velocity, 1.0 + sv_bounce.GetFloat() * (1 - m_surfaceFriction) );
				}
			}

			VectorCopy( new_velocity, mv->m_vecVelocity );
			VectorCopy( new_velocity, original_velocity );
		}
		else
		{
			for (i=0 ; i < numplanes ; i++)
			{
				ClipVelocity (
					original_velocity,
					planes[i],
					mv->m_vecVelocity,
					1);

				for (j=0 ; j<numplanes ; j++)
					if (j != i)
					{
						// Are we now moving against this plane?
						if (mv->m_vecVelocity.Dot(planes[j]) < 0)
							break;	// not ok
					}
				if (j == numplanes)  // Didn't have to clip, so we're ok
					break;
			}
			
			// Did we go all the way through plane set
			if (i != numplanes)
			{	// go along this plane
				// pmove.velocity is set in clipping call, no need to set again.
				;  
			}
			else
			{	// go along the crease
				if (numplanes != 2)
				{
					VectorCopy (vec3_origin, mv->m_vecVelocity);
					break;
				}
				CrossProduct (planes[0], planes[1], dir);
				d = dir.Dot(mv->m_vecVelocity);
				VectorScale (dir, d, mv->m_vecVelocity );
			}

			//
			// if original velocity is against the original velocity, stop dead
			// to avoid tiny occilations in sloping corners
			//
			d = mv->m_vecVelocity.Dot(primal_velocity);
			if (d <= 0)
			{
				//Con_DPrintf("Back\n");
				VectorCopy (vec3_origin, mv->m_vecVelocity);
				break;
			}
		}
	}

	if ( allFraction == 0 )
	{
		VectorCopy (vec3_origin, mv->m_vecVelocity);
	}

	return blocked;
}
Exemplo n.º 24
0
//-----------------------------------------------------------------------------
// Purpose: Does the basic move attempting to climb up step heights.  It uses
//          the mv->m_vecAbsOrigin and mv->m_vecVelocity.  It returns a new
//          new mv->m_vecAbsOrigin, mv->m_vecVelocity, and mv->m_outStepHeight.
//-----------------------------------------------------------------------------
void CASW_Drone_Movement::StepMove( Vector &vecDestination, trace_t &trace )
{
//	CheckStuck();
	Vector vecEndPos;
	VectorCopy( vecDestination, vecEndPos );

	// Try sliding forward both on ground and up 16 pixels
	//  take the move that goes farthest
	Vector vecPos, vecVel;
	VectorCopy( mv->GetAbsOrigin(), vecPos );
	VectorCopy( mv->m_vecVelocity, vecVel );

	// Slide move down.
	Vector downWallNormal;
	TryMove( &vecEndPos, &trace );
	downWallNormal = m_LastHitWallNormal;
	
	// Down results.
	Vector vecDownPos, vecDownVel;
	VectorCopy( mv->GetAbsOrigin(), vecDownPos );
	VectorCopy( mv->m_vecVelocity, vecDownVel );
	
	// Reset original values.
	mv->SetAbsOrigin( vecPos );
	VectorCopy( vecVel, mv->m_vecVelocity );
	
	// Move up a stair height.
	VectorCopy( mv->GetAbsOrigin(), vecEndPos );
	vecEndPos.z += STEP_SIZE;	
	
	UTIL_TraceEntity( m_pNPC, mv->GetAbsOrigin(), vecEndPos, MASK_NPCSOLID, &trace );
	//TraceBBox( mv->GetAbsOrigin(), vecEndPos, MASK_NPCSOLID, m_pNPC->GetCollisionGroup(), trace );
	if ( !trace.startsolid && !trace.allsolid )
	{
		mv->SetAbsOrigin( trace.endpos );
	}
	
	// Slide move up.
	Vector upWallNormal;
	TryMove(NULL, NULL);
	upWallNormal = m_LastHitWallNormal;
	
	// Move down a stair (attempt to).
	VectorCopy( mv->GetAbsOrigin(), vecEndPos );
	vecEndPos.z -= STEP_SIZE;
		
	UTIL_TraceEntity( m_pNPC, mv->GetAbsOrigin(), vecEndPos, MASK_NPCSOLID, &trace );
	//TraceBBox( mv->GetAbsOrigin(), vecEndPos, MASK_NPCSOLID, m_pNPC->GetCollisionGroup(), trace );
	
	// If we are not on the ground any more then use the original movement attempt.
	if ( trace.plane.normal[2] < 0.7 )
	{
		mv->SetAbsOrigin( vecDownPos );
		VectorCopy( vecDownVel, mv->m_vecVelocity );
		VectorCopy( downWallNormal, m_LastHitWallNormal );
		float flStepDist = mv->GetAbsOrigin().z - vecPos.z;
		if ( flStepDist > 0.0f )
		{
			mv->m_outStepHeight += flStepDist;
		}

		return;
	}
	
	// If the trace ended up in empty space, copy the end over to the origin.
	if ( !trace.startsolid && !trace.allsolid )
	{
		mv->SetAbsOrigin( trace.endpos );
	}
	
	// Copy this origin to up.
	Vector vecUpPos;
	VectorCopy( mv->GetAbsOrigin(), vecUpPos );
	VectorCopy( upWallNormal, m_LastHitWallNormal);
	
	// decide which one went farther
	float flDownDist = ( vecDownPos.x - vecPos.x ) * ( vecDownPos.x - vecPos.x ) + ( vecDownPos.y - vecPos.y ) * ( vecDownPos.y - vecPos.y );
	float flUpDist = ( vecUpPos.x - vecPos.x ) * ( vecUpPos.x - vecPos.x ) + ( vecUpPos.y - vecPos.y ) * ( vecUpPos.y - vecPos.y );
	if ( flDownDist > flUpDist )
	{
		mv->SetAbsOrigin( vecDownPos );
		VectorCopy( vecDownVel, mv->m_vecVelocity );
		VectorCopy( downWallNormal, m_LastHitWallNormal);
	}
	else 
	{
		// copy z value from slide move
		mv->m_vecVelocity.z = vecDownVel.z;
	}
	
	float flStepDist = mv->GetAbsOrigin().z - vecPos.z;
	if ( flStepDist > 0 )
	{
		mv->m_outStepHeight += flStepDist;
	}
}
Exemplo n.º 25
0
void CLagCompensationManager::BacktrackEntity( CAI_BaseNPC *pEntity, float flTargetTime )
{
	Vector org, mins, maxs;
	QAngle ang;

	VPROF_BUDGET( "BacktrackEntity", "CLagCompensationManager" );

	// get track history of this entity
	int index = pEntity->GetAIIndex();
	CUtlFixedLinkedList< LagRecord > *track = &m_EntityTrack[ index ];

	// check if we have at leat one entry
	if ( track->Count() <= 0 )
		return;

	int curr = track->Head();

	LagRecord *prevRecord = NULL;
	LagRecord *record = NULL;

	Vector prevOrg = pEntity->GetLocalOrigin();
	
	// Walk context looking for any invalidating event
	while( track->IsValidIndex(curr) )
	{
		// remember last record
		prevRecord = record;

		// get next record
		record = &track->Element( curr );

		if ( !(record->m_fFlags & LC_ALIVE) )
		{
			// entity must be alive, lost track
			return;
		}

		Vector delta = record->m_vecOrigin - prevOrg;
		if ( delta.LengthSqr() > LAG_COMPENSATION_TELEPORTED_DISTANCE_SQR )
		{
			// lost track, moved too far (may have teleported)
			return; 
		}

		// did we find a context smaller than target time ?
		if ( record->m_flSimulationTime <= flTargetTime )
			break; // hurra, stop

		prevOrg = record->m_vecOrigin;

		// go one step back in time
		curr = track->Next( curr );
	}

	Assert( record );

	if ( !record )
	{
		if ( sv_unlag_debug.GetBool() )
		{
			DevMsg( "No valid positions in history for BacktrackEntity ( %s )\n", pEntity->GetClassname() );
		}

		return; // that should never happen
	}

	float frac = 0.0f;
	if ( prevRecord && 
		 (record->m_flSimulationTime < flTargetTime) &&
		 (record->m_flSimulationTime < prevRecord->m_flSimulationTime) )
	{
		// we didn't find the exact time but have a valid previous record
		// so interpolate between these two records;

		Assert( prevRecord->m_flSimulationTime > record->m_flSimulationTime );
		Assert( flTargetTime < prevRecord->m_flSimulationTime );

		// calc fraction between both records
		frac = ( flTargetTime - record->m_flSimulationTime ) / 
			( prevRecord->m_flSimulationTime - record->m_flSimulationTime );

		Assert( frac > 0 && frac < 1 ); // should never extrapolate

		ang  = Lerp( frac, record->m_vecAngles, prevRecord->m_vecAngles );
		org  = Lerp( frac, record->m_vecOrigin, prevRecord->m_vecOrigin  );
		mins = Lerp( frac, record->m_vecMins, prevRecord->m_vecMins  );
		maxs = Lerp( frac, record->m_vecMaxs, prevRecord->m_vecMaxs );
	}
	else
	{
		// we found the exact record or no other record to interpolate with
		// just copy these values since they are the best we have
		ang  = record->m_vecAngles;
		org  = record->m_vecOrigin;
		mins = record->m_vecMins;
		maxs = record->m_vecMaxs;
	}

	// See if this is still a valid position for us to teleport to
	if ( sv_unlag_fixstuck.GetBool() )
	{
		// Try to move to the wanted position from our current position.
		trace_t tr;
		UTIL_TraceEntity( pEntity, org, org, MASK_NPCSOLID, &tr );
		if ( tr.startsolid || tr.allsolid )
		{
			if ( sv_unlag_debug.GetBool() )
				DevMsg( "WARNING: BackupEntity trying to back entity into a bad position - %s\n", pEntity->GetClassname() );

			CBasePlayer *pHitPlayer = dynamic_cast<CBasePlayer *>( tr.m_pEnt );

			// don't lag compensate the current player
			if ( pHitPlayer && ( pHitPlayer != m_pCurrentPlayer ) )	
			{
				// If we haven't backtracked this player, do it now
				// this deliberately ignores WantsLagCompensationOnEntity.
				if ( !m_RestorePlayer.Get( pHitPlayer->entindex() - 1 ) )
				{
					// prevent recursion - save a copy of m_RestorePlayer,
					// pretend that this player is off-limits
					int pl_index = pEntity->entindex() - 1;

					// Temp turn this flag on
					m_RestorePlayer.Set( pl_index );

					BacktrackPlayer( pHitPlayer, flTargetTime );

					// Remove the temp flag
					m_RestorePlayer.Clear( pl_index );
				}				
			}
			else
			{
				CAI_BaseNPC *pHitEntity = dynamic_cast<CAI_BaseNPC *>( tr.m_pEnt );
				if ( pHitEntity )
				{
					CAI_BaseNPC *pNPC = NULL;
					CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs();
					int nAIs = g_AI_Manager.NumAIs();
					for ( int i = 0; i < nAIs; i++ ) // we'll have to find this entity's index though :(
					{
						pNPC = ppAIs[i];
						if ( pNPC == pHitEntity )
							break;
					}
					// If we haven't backtracked this player, do it now
					// this deliberately ignores WantsLagCompensationOnEntity.
					if ( pNPC && !m_RestoreEntity.Get( pNPC->GetAIIndex() ) )
					{
						// prevent recursion - save a copy of m_RestoreEntity,
						// pretend that this player is off-limits

						// Temp turn this flag on
						m_RestoreEntity.Set( pNPC->GetAIIndex() );

						BacktrackEntity( pHitEntity, flTargetTime );

						// Remove the temp flag
						m_RestoreEntity.Clear( pNPC->GetAIIndex() );
					}
				}
			}

			// now trace us back as far as we can go
			UTIL_TraceEntity( pEntity, pEntity->GetLocalOrigin(), org, MASK_NPCSOLID, &tr );

			if ( tr.startsolid || tr.allsolid )
			{
				// Our starting position is bogus

				if ( sv_unlag_debug.GetBool() )
					DevMsg( "Backtrack failed completely, bad starting position\n" );
			}
			else
			{
				// We can get to a valid place, but not all the way to the target
				Vector vPos;
				VectorLerp( pEntity->GetLocalOrigin(), org, tr.fraction * g_flFractionScale, vPos );
				
				// This is as close as we're going to get
				org = vPos;

				if ( sv_unlag_debug.GetBool() )
					DevMsg( "Backtrack got most of the way\n" );
			}
		}
	}
	
	// See if this represents a change for the entity
	int flags = 0;
	LagRecord *restore = &m_EntityRestoreData[ index ];
	LagRecord *change  = &m_EntityChangeData[ index ];

	QAngle angdiff = pEntity->GetLocalAngles() - ang;
	Vector orgdiff = pEntity->GetLocalOrigin() - org;

	// Always remember the pristine simulation time in case we need to restore it.
	restore->m_flSimulationTime = pEntity->GetSimulationTime();

	if ( angdiff.LengthSqr() > LAG_COMPENSATION_EPS_SQR )
	{
		flags |= LC_ANGLES_CHANGED;
		restore->m_vecAngles = pEntity->GetLocalAngles();
		pEntity->SetLocalAngles( ang );
		change->m_vecAngles = ang;
	}

	// Use absolute equality here
	if ( ( mins != pEntity->WorldAlignMins() ) ||
		 ( maxs != pEntity->WorldAlignMaxs() ) )
	{
		flags |= LC_SIZE_CHANGED;
		restore->m_vecMins = pEntity->WorldAlignMins() ;
		restore->m_vecMaxs = pEntity->WorldAlignMaxs();
		pEntity->SetSize( mins, maxs );
		change->m_vecMins = mins;
		change->m_vecMaxs = maxs;
	}

	// Note, do origin at end since it causes a relink into the k/d tree
	if ( orgdiff.LengthSqr() > LAG_COMPENSATION_EPS_SQR )
	{
		flags |= LC_ORIGIN_CHANGED;
		restore->m_vecOrigin = pEntity->GetLocalOrigin();
		pEntity->SetLocalOrigin( org );
		change->m_vecOrigin = org;
	}

	// Sorry for the loss of the optimization for the case of people
	// standing still, but you breathe even on the server.
	// This is quicker than actually comparing all bazillion floats.
	flags |= LC_ANIMATION_CHANGED;
	restore->m_masterSequence = pEntity->GetSequence();
	restore->m_masterCycle = pEntity->GetCycle();

	bool interpolationAllowed = false;
	if( prevRecord && (record->m_masterSequence == prevRecord->m_masterSequence) )
	{
		// If the master state changes, all layers will be invalid too, so don't interp (ya know, interp barely ever happens anyway)
		interpolationAllowed = true;
	}
	
	////////////////////////
	// First do the master settings
	bool interpolatedMasters = false;
	if( frac > 0.0f && interpolationAllowed )
	{
		interpolatedMasters = true;
		pEntity->SetSequence( Lerp( frac, record->m_masterSequence, prevRecord->m_masterSequence ) );
		pEntity->SetCycle( Lerp( frac, record->m_masterCycle, prevRecord->m_masterCycle ) );

		if( record->m_masterCycle > prevRecord->m_masterCycle )
		{
			// the older record is higher in frame than the newer, it must have wrapped around from 1 back to 0
			// add one to the newer so it is lerping from .9 to 1.1 instead of .9 to .1, for example.
			float newCycle = Lerp( frac, record->m_masterCycle, prevRecord->m_masterCycle + 1 );
			pEntity->SetCycle(newCycle < 1 ? newCycle : newCycle - 1 );// and make sure .9 to 1.2 does not end up 1.05
		}
		else
		{
			pEntity->SetCycle( Lerp( frac, record->m_masterCycle, prevRecord->m_masterCycle ) );
		}
	}
	if( !interpolatedMasters )
	{
		pEntity->SetSequence(record->m_masterSequence);
		pEntity->SetCycle(record->m_masterCycle);
	}

	////////////////////////
	// Now do all the layers
	int layerCount = pEntity->GetNumAnimOverlays();
	for( int layerIndex = 0; layerIndex < layerCount; ++layerIndex )
	{
		CAnimationLayer *currentLayer = pEntity->GetAnimOverlay(layerIndex);
		if( currentLayer )
		{
			restore->m_layerRecords[layerIndex].m_cycle = currentLayer->m_flCycle;
			restore->m_layerRecords[layerIndex].m_order = currentLayer->m_nOrder;
			restore->m_layerRecords[layerIndex].m_sequence = currentLayer->m_nSequence;
			restore->m_layerRecords[layerIndex].m_weight = currentLayer->m_flWeight;

			bool interpolated = false;
			if( (frac > 0.0f)  &&  interpolationAllowed )
			{
				LayerRecord &recordsLayerRecord = record->m_layerRecords[layerIndex];
				LayerRecord &prevRecordsLayerRecord = prevRecord->m_layerRecords[layerIndex];
				if( (recordsLayerRecord.m_order == prevRecordsLayerRecord.m_order)
					&& (recordsLayerRecord.m_sequence == prevRecordsLayerRecord.m_sequence)
					)
				{
					// We can't interpolate across a sequence or order change
					interpolated = true;
					if( recordsLayerRecord.m_cycle > prevRecordsLayerRecord.m_cycle )
					{
						// the older record is higher in frame than the newer, it must have wrapped around from 1 back to 0
						// add one to the newer so it is lerping from .9 to 1.1 instead of .9 to .1, for example.
						float newCycle = Lerp( frac, recordsLayerRecord.m_cycle, prevRecordsLayerRecord.m_cycle + 1 );
						currentLayer->m_flCycle = newCycle < 1 ? newCycle : newCycle - 1;// and make sure .9 to 1.2 does not end up 1.05
					}
					else
					{
						currentLayer->m_flCycle = Lerp( frac, recordsLayerRecord.m_cycle, prevRecordsLayerRecord.m_cycle  );
					}
					currentLayer->m_nOrder = recordsLayerRecord.m_order;
					currentLayer->m_nSequence = recordsLayerRecord.m_sequence;
					currentLayer->m_flWeight = Lerp( frac, recordsLayerRecord.m_weight, prevRecordsLayerRecord.m_weight  );
				}
			}
			if( !interpolated )
			{
				//Either no interp, or interp failed.  Just use record.
				currentLayer->m_flCycle = record->m_layerRecords[layerIndex].m_cycle;
				currentLayer->m_nOrder = record->m_layerRecords[layerIndex].m_order;
				currentLayer->m_nSequence = record->m_layerRecords[layerIndex].m_sequence;
				currentLayer->m_flWeight = record->m_layerRecords[layerIndex].m_weight;
			}
		}
	}
	
	if ( !flags )
		return; // we didn't change anything

	if ( sv_lagflushbonecache.GetBool() )
		pEntity->InvalidateBoneCache();

	/*char text[256]; Q_snprintf( text, sizeof(text), "time %.2f", flTargetTime );
	pEntity->DrawServerHitboxes( 10 );
	NDebugOverlay::Text( org, text, false, 10 );
	NDebugOverlay::EntityBounds( pEntity, 255, 0, 0, 32, 10 ); */

	m_RestoreEntity.Set( index ); //remember that we changed this entity
	m_bNeedToRestore = true;  // we changed at least one player / entity
	restore->m_fFlags = flags; // we need to restore these flags
	change->m_fFlags = flags; // we have changed these flags

	if( sv_showlagcompensation.GetInt() == 1 )
	{
		pEntity->DrawServerHitboxes(4, true);
	}
}
Exemplo n.º 26
0
void CC4::PrimaryAttack()
{
	bool	PlaceBomb = false;
	CCSPlayer *pPlayer = GetPlayerOwner();
	if ( !pPlayer )
		return;

	int onGround = FBitSet( pPlayer->GetFlags(), FL_ONGROUND );
	CBaseEntity *groundEntity = (onGround) ? pPlayer->GetGroundEntity() : NULL;
	if ( groundEntity )
	{
		// Don't let us stand on players, breakables, or pushaway physics objects to plant
		if ( groundEntity->IsPlayer() ||
			IsPushableEntity( groundEntity ) ||
#ifndef CLIENT_DLL
			IsBreakableEntity( groundEntity ) ||
#endif // !CLIENT_DLL
			IsPushAwayEntity( groundEntity ) )
		{
			onGround = false;
		}
	}

	if( m_bStartedArming == false && m_bBombPlanted == false )
	{
		if( pPlayer->m_bInBombZone && onGround )
		{
			m_bStartedArming = true;
			m_fArmedTime = gpGlobals->curtime + WEAPON_C4_ARM_TIME;
			m_bBombPlacedAnimation = false;


#if !defined( CLIENT_DLL )			
			// init the beep flags
			int i;
			for( i=0;i<NUM_BEEPS;i++ )
				m_bPlayedArmingBeeps[i] = false;

			// freeze the player in place while planting
			pPlayer->SetMaxSpeed( 1 );

			// player "arming bomb" animation
			pPlayer->SetAnimation( PLAYER_ATTACK1 );
	
			pPlayer->SetNextAttack( gpGlobals->curtime );

			IGameEvent * event = gameeventmanager->CreateEvent( "bomb_beginplant" );
			if( event )
			{
				event->SetInt("userid", pPlayer->GetUserID() );
				event->SetInt("site", pPlayer->m_iBombSiteIndex );
				event->SetInt( "priority", 8 );
				gameeventmanager->FireEvent( event );
			}
#endif

			SendWeaponAnim( ACT_VM_PRIMARYATTACK );

			FX_PlantBomb( pPlayer->entindex(), pPlayer->Weapon_ShootPosition() );
		}
		else
		{
			if ( !pPlayer->m_bInBombZone )
			{
				ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_At_Bomb_Spot");
			}
			else
			{
				ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground");
			}

			m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
			return;
		}
	}
	else
	{
		if ( !onGround || !pPlayer->m_bInBombZone )
		{
			if( !pPlayer->m_bInBombZone )
			{
				ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Arming_Cancelled" );
			}
			else
			{
				ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground" );
			}

			m_flNextPrimaryAttack = gpGlobals->curtime + 1.5;
			m_bStartedArming = false;

#if !defined( CLIENT_DLL )
			// release the player from being frozen, we've somehow left the bomb zone
			pPlayer->ResetMaxSpeed();

			pPlayer->SetProgressBarTime( 0 );

			//pPlayer->SetAnimation( PLAYER_HOLDBOMB );

			IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortplant" );
			if( event )
			{
				event->SetInt("userid", pPlayer->GetUserID() );
				event->SetInt("site", pPlayer->m_iBombSiteIndex );
				event->SetInt( "priority", 8 );
				gameeventmanager->FireEvent( event );
			}

#endif
			if(m_bBombPlacedAnimation == true) //this means the placement animation is canceled
			{
				SendWeaponAnim( ACT_VM_DRAW );
			}
			else
			{
				SendWeaponAnim( ACT_VM_IDLE );
			}
			
			return;
		}
		else
		{
#ifndef CLIENT_DLL
			PlayArmingBeeps();
#endif

			if( gpGlobals->curtime >= m_fArmedTime ) //the c4 is ready to be armed
			{
				//check to make sure the player is still in the bomb target area
				PlaceBomb = true;
			}
			else if( ( gpGlobals->curtime >= (m_fArmedTime - 0.75) ) && ( !m_bBombPlacedAnimation ) )
			{
				//call the c4 Placement animation 
				m_bBombPlacedAnimation = true;

				SendWeaponAnim( ACT_VM_SECONDARYATTACK );
				
#if !defined( CLIENT_DLL )
				// player "place" animation
				//pPlayer->SetAnimation( PLAYER_HOLDBOMB );
#endif
			}
		}
	}

	if ( PlaceBomb && m_bStartedArming )
	{
		m_bStartedArming = false;
		m_fArmedTime = 0;
		
		if( pPlayer->m_bInBombZone )
		{
#if !defined( CLIENT_DLL )

			CPlantedC4 *pC4 = CPlantedC4::ShootSatchelCharge( pPlayer, pPlayer->GetAbsOrigin(), pPlayer->GetAbsAngles() );

			if ( pC4 )
			{
				pC4->SetBombSiteIndex( pPlayer->m_iBombSiteIndex );

				trace_t tr;
				UTIL_TraceEntity( pC4, GetAbsOrigin(), GetAbsOrigin() + Vector(0,0,-200), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
				pC4->SetAbsOrigin( tr.endpos );

				CBombTarget *pBombTarget = (CBombTarget*)UTIL_EntityByIndex( pPlayer->m_iBombSiteIndex );
				
				if ( pBombTarget )
				{
					CBaseEntity *pAttachPoint = gEntList.FindEntityByName( NULL, pBombTarget->GetBombMountTarget() );

					if ( pAttachPoint )
					{
						pC4->SetAbsOrigin( pAttachPoint->GetAbsOrigin() );
						pC4->SetAbsAngles( pAttachPoint->GetAbsAngles() );
						pC4->SetParent( pAttachPoint );
					}

					variant_t emptyVariant;
					pBombTarget->AcceptInput( "BombPlanted", pC4, pC4, emptyVariant, 0 );
				}
			}

			IGameEvent * event = gameeventmanager->CreateEvent( "bomb_planted" );
			if( event )
			{
				event->SetInt("userid", pPlayer->GetUserID() );
				event->SetInt("site", pPlayer->m_iBombSiteIndex );
				event->SetInt("posx", pPlayer->GetAbsOrigin().x );
				event->SetInt("posy", pPlayer->GetAbsOrigin().y );
				event->SetInt( "priority", 8 );
				gameeventmanager->FireEvent( event );
			}

			// Fire a beep event also so the bots have a chance to hear the bomb
			event = gameeventmanager->CreateEvent( "bomb_beep" );

			if ( event )
			{
				event->SetInt( "entindex", entindex() );
				gameeventmanager->FireEvent( event );
			}

			pPlayer->SetProgressBarTime( 0 );

			CSGameRules()->m_bBombDropped = false;
			CSGameRules()->m_bBombPlanted = true;

			// Play the plant sound.
			Vector plantPosition = pPlayer->GetAbsOrigin() + Vector( 0, 0, 5 );
			CPASAttenuationFilter filter( plantPosition );
			EmitSound( filter, entindex(), "c4.plant" );

			// release the player from being frozen
			pPlayer->ResetMaxSpeed();

			// No more c4!
			pPlayer->Weapon_Drop( this, NULL, NULL );
			UTIL_Remove( this );
#endif
			//don't allow the planting to start over again next frame.
			m_bBombPlanted = true;

			return;
		}
		else
		{
			ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Activated_At_Bomb_Spot" );

#if !defined( CLIENT_DLL )
			//pPlayer->SetAnimation( PLAYER_HOLDBOMB );

			// release the player from being frozen
			pPlayer->ResetMaxSpeed();

			IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortplant" );
			if( event )
			{
				event->SetInt("userid", pPlayer->GetUserID() );
				event->SetInt("site", pPlayer->m_iBombSiteIndex );
				event->SetInt( "priority", 8 );
				gameeventmanager->FireEvent( event );
			}
#endif

			m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
			return;
		}
	}

	m_flNextPrimaryAttack = gpGlobals->curtime + 0.3;
	SetWeaponIdleTime( gpGlobals->curtime + SharedRandomFloat("C4IdleTime", 10, 15 ) );
}
Exemplo n.º 27
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pTask - 
//-----------------------------------------------------------------------------
void CNPC_Bug_Builder::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_BBUG_GET_PATH_TO_FLEE:
		{
			// Always tell our bughole that we're under attack
			if ( m_hMyBugHole )
			{
				m_hMyBugHole->IncomingFleeingBug( this );
			}

			// If we have no squad, or we couldn't get a path to our squadmate, move to our bughole
			if ( m_hMyBugHole )
			{
				SetTarget( m_hMyBugHole );
				AI_NavGoal_t goal( GOALTYPE_TARGETENT, vec3_origin, ACT_RUN );
				if ( GetNavigator()->SetGoal( goal ) )
				{
					TaskComplete();
					return;
				}
			}

			TaskComplete();
		}
		break;

	case TASK_BBUG_GET_PATH_TO_BUGHOLE:
		{
			// Get a path back to my bughole
			// If we have no squad, or we couldn't get a path to our squadmate, look for a bughole
			if ( m_hMyBugHole )
			{
				SetTarget( m_hMyBugHole );
				AI_NavGoal_t goal( GOALTYPE_TARGETENT, vec3_origin, ACT_RUN );
				if ( GetNavigator()->SetGoal( goal ) )
				{
					TaskComplete();
					return;
				}
			}

			TaskFail( "Couldn't get to bughole." );
		}
		break;

	case TASK_BBUG_HOLE_REMOVE:
		{
			TaskComplete();

			// Crawl inside the bughole and remove myself
			AddEffects( EF_NODRAW );
			AddSolidFlags( FSOLID_NOT_SOLID );
			Event_Killed( CTakeDamageInfo( this, this, 200, DMG_CRUSH ) );

			// Tell the bughole
			if ( m_hMyBugHole )
			{
				m_hMyBugHole->BugReturned();
			}
		}
		break;

	case TASK_BBUG_GET_PATH_TO_DAWDLE:
		{
			// Get a dawdle point ahead of us
			Vector vecForward, vecTarget;
			AngleVectors( GetAbsAngles(), &vecForward );
			VectorMA( GetAbsOrigin(), random->RandomFloat( DAWDLE_MIN_DIST, DAWDLE_MAX_DIST ), vecForward, vecTarget );

			// See how far we could move ahead
			trace_t tr;
			UTIL_TraceEntity( this, GetAbsOrigin(), vecTarget, MASK_SOLID, &tr);
			float flDistance = tr.fraction * (vecTarget - GetAbsOrigin()).Length();
			if ( flDistance >= DAWDLE_MIN_DIST )
			{
				AI_NavGoal_t goal( tr.endpos );
				GetNavigator()->SetGoal( goal );
			}

			TaskComplete();
		}
		break;

	case TASK_BBUG_FACE_DAWDLE:
		{
			// Turn a random amount to the right
			float flYaw = GetMotor()->GetIdealYaw();
			flYaw = flYaw + random->RandomFloat( 45, 135 );
			GetMotor()->SetIdealYaw( UTIL_AngleMod(flYaw) );
			SetTurnActivity();
			break;
		}
		break;

	default:
		BaseClass::StartTask( pTask );
		break;
	}
}
//SecobMod__Information  On a player touching this, portalize them!
//------------------------------------------------------------------------------
// A small wrapper around SV_Move that never clips against the supplied entity.
//------------------------------------------------------------------------------
static bool TestEntityPosition ( CBaseEntity *pOther )
{	
	trace_t	trace;
	UTIL_TraceEntity( pOther, pOther->GetAbsOrigin(), pOther->GetAbsOrigin(), MASK_PLAYERSOLID, &trace );
	return (trace.startsolid == 0);
}
bool CNPC_Controller::OverrideMove( float flInterval )
{
	if (m_flGroundSpeed == 0)
	{
		m_flGroundSpeed = 100;
	}

	// ----------------------------------------------
	//	Select move target 
	// ----------------------------------------------
	CBaseEntity *pMoveTarget = NULL;
	if (GetTarget() != NULL )
	{
		pMoveTarget = GetTarget();
	}
	else if (GetEnemy() != NULL )
	{
		pMoveTarget		= GetEnemy();
	}

	// ----------------------------------------------
	//	Select move target position 
	// ----------------------------------------------
	Vector vMoveTargetPos(0,0,0);
	if (GetTarget())
	{
		vMoveTargetPos = GetTarget()->GetAbsOrigin();
	}
	else if (GetEnemy() != NULL)
	{
		vMoveTargetPos = GetEnemy()->GetAbsOrigin();
	}

	// -----------------------------------------
	//  See if we can fly there directly
	// -----------------------------------------
	if (pMoveTarget /*|| HaveInspectTarget()*/)
	{
		trace_t tr;

		if (pMoveTarget)
		{
			UTIL_TraceEntity( this, GetAbsOrigin(), vMoveTargetPos, 
				MASK_NPCSOLID_BRUSHONLY, pMoveTarget, GetCollisionGroup(), &tr);
		}
		else
		{
			UTIL_TraceEntity( this, GetAbsOrigin(), vMoveTargetPos, MASK_NPCSOLID_BRUSHONLY, &tr);
		}
/*
		float fTargetDist = (1-tr.fraction)*(GetAbsOrigin() - vMoveTargetPos).Length();
		if (fTargetDist > 50)
		{
			//SetCondition( COND_SCANNER_FLY_BLOCKED );
		}
		else
		{
			//SetCondition( COND_SCANNER_FLY_CLEAR );
		}
*/
	}

	// -----------------------------------------------------------------
	// If I have a route, keep it updated and move toward target
	// ------------------------------------------------------------------
	if (GetNavigator()->IsGoalActive())
	{
		if ( OverridePathMove( flInterval ) )
			return true;
	}
	else
	{
		//do nothing
		Stop();
		TaskComplete();
	}

	return true;
}
Exemplo n.º 30
0
//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CGrenade_Brickbat::BrickbatThink( void )
{
	// -----------------------------------------------------------
	// Might be physically simulated so get my velocity manually
	// -----------------------------------------------------------
	Vector vVelocity;
	AngularImpulse vAngVel;
	GetVelocity(&vVelocity,&vAngVel);

	// See if I can lose my owner (has dropper moved out of way?)
	// Want do this so owner can throw the brickbat
	if (GetOwnerEntity())
	{
		trace_t tr;
		Vector	vUpABit = GetAbsOrigin();
		vUpABit.z += 5.0;

		CBaseEntity* saveOwner = GetOwnerEntity();
		SetOwnerEntity( NULL );
		UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr );
		if ( tr.startsolid || tr.fraction != 1.0 )
		{
			SetOwnerEntity( saveOwner );
		}
	}

	// ---------------------------------------------------------------
	//	Make sure we're not resting on a living thing's bounding box
	// ---------------------------------------------------------------
	if (vVelocity.Length() < 0.01)
	{
		trace_t tr;
		UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

		if ( tr.fraction < 1.0 && tr.m_pEnt)
		{
			CBaseEntity *pEntity = tr.m_pEnt;
			if (pEntity->GetFlags() & (FL_CLIENT | FL_NPC))
			{
				// --------------------
				// Bounce me off 
				// --------------------
				Vector vNewVel;
				vNewVel.y = 100;
				vNewVel.x = random->RandomInt(-100,100);
				vNewVel.z = random->RandomInt(-100,100);

				// If physically simulated
				IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
				if ( pPhysicsObject )
				{
					pPhysicsObject->AddVelocity( &vNewVel, &vAngVel );
				}
				// Otherwise
				else
				{
					SetAbsVelocity( vNewVel );
				}
			}
		}
	}

	if (vVelocity.Length() < 0.01)
	{
		SpawnBrickbatWeapon();
	}
	SetNextThink( gpGlobals->curtime + 0.1f );
}